Theory FaceDivision

(*  Author:     Gertrud Bauer, Tobias Nipkow
*)

section‹Subdividing a Face›

theory FaceDivision
imports Graph
begin

definition split_face :: "face ⇒ vertex ⇒ vertex ⇒ vertex list ⇒ face × face" where
 "split_face f ram1 ram2 newVs ≡ let vs = vertices f;
     f1 = [ram1] @ between vs ram1 ram2 @ [ram2];
     f2 = [ram2] @ between vs ram2 ram1 @ [ram1] in
     (Face (rev newVs @ f1) Nonfinal,
     Face (f2 @ newVs) Nonfinal)"


definition replacefacesAt :: "nat list ⇒ face ⇒ face list ⇒ face list list ⇒ face list list" where
 "replacefacesAt ns f fs F ≡ mapAt ns (replace f fs) F"


definition makeFaceFinalFaceList :: "face ⇒ face list ⇒ face list" where
  "makeFaceFinalFaceList f fs ≡ replace f [setFinal f] fs"

definition makeFaceFinal :: "face ⇒ graph ⇒ graph" where
 "makeFaceFinal f g ≡
     Graph (makeFaceFinalFaceList f (faces g))
           (countVertices g)
           [makeFaceFinalFaceList f fs. fs ← faceListAt g]
           (heights g)"


definition heightsNewVertices :: "nat ⇒ nat ⇒ nat ⇒ nat list" where
 "heightsNewVertices h1 h2 n ≡ [min (h1 + i + 1) (h2 + n - i). i ← [0 ..< n]]"

definition splitFace
 :: "graph ⇒ vertex ⇒ vertex ⇒ face ⇒ vertex list ⇒ face × face × graph" where
 "splitFace g ram1 ram2 oldF newVs ≡
     let fs = faces g;
     n = countVertices g;
     Fs = faceListAt g;
     h = heights g;
     vs1 = between (vertices oldF) ram1 ram2;
     vs2 = between (vertices oldF) ram2 ram1;
     (f1, f2) = split_face oldF ram1 ram2 newVs;
     Fs = replacefacesAt vs1 oldF [f1] Fs;
     Fs = replacefacesAt vs2 oldF [f2] Fs;
     Fs = replacefacesAt [ram1] oldF [f2, f1] Fs;
     Fs = replacefacesAt [ram2] oldF [f1, f2] Fs;
     Fs = Fs @ replicate |newVs| [f1, f2] in
     (f1, f2, Graph ((replace oldF [f2] fs)@ [f1])
                        (n + |newVs| )
                        Fs
                        (h @ heightsNewVertices (h!ram1)(h!ram2) |newVs| ))"



primrec subdivFace' :: "graph ⇒ face ⇒ vertex ⇒ nat ⇒ vertex option list ⇒ graph" where
  "subdivFace' g f u n [] = makeFaceFinal f g"
| "subdivFace' g f u n (vo#vos) =
     (case vo of None ⇒ subdivFace' g f u (Suc n) vos
         | (Some v) ⇒
            if f∙u = v ∧ n = 0
            then subdivFace' g f v 0 vos
            else let ws = [countVertices g  ..< countVertices g + n];
            (f1, f2, g') = splitFace g u v f ws in
            subdivFace' g' f2 v 0 vos)"

definition subdivFace :: "graph ⇒ face ⇒ vertex option list ⇒ graph" where
"subdivFace g f vos ≡ subdivFace' g f (the(hd vos)) 0 (tl vos)"

end