(*========================================================== ============================================================ TOPOLOGICAL FMAPS, HMAPS - WITH TAGS AND EMBEDDINGS PROOF OF THE JORDAN THEOREM  PART 10: FORMALIZATION AND PROOF OF JCT WITH A 2008 NEW RING FORMALIZATION  expf, genus, planar / B, RINGS, JCT   OK: COMPLETE!! ============================================================ ==========================================================*)
(* cd Desktop/JORDAN_2008 coqtop -opt *)
(* ABOUT ... min: Load Jordan1. Load Jordan2. Load Jordan3. Load Jordan4. Load Jordan5. Load Jordan6. Load Jordan7. Load Jordan8. Load Jordan9. *)
Require Export Jordan9.
Open Scope Z_scope.
(*============================================================ genus, planar / L_B0, B0, planarity criterion / B0 =============================================================*)
(* OK: *)
(* OK: *)
(* OK!: *)
(* PLANARITY CRITERION / B0: OK! *)
(* DISCONNECTION CRITERION: VERY USEFUL *)
(*==========================================================  2008 JORDAN NEW FORMALIZATION:  ==========================================================*)
(* ======================================================= EQUIVALENCE AND top/bottom =========================================================*)
(* OK: *)
(* SPECIALIZATIONS: *)
(* OK: *)
(* OK: *)
(*========================================================== PROPERTIES ON B ===========================================================*)
(*=========================================================== expe AND bottom ============================================================*)
(* expo and between in an edge: *)
Definition expe(m:fmap)(z t:dart):=
MA0.expo m z t.
Definition betweene(m:fmap)(z v t:dart):=
MA0.between m z v t.
(* TO HAVE expe_bottom: *)
(* THEN, SIMILARLY (OK): *)
(* FINALLY: *)
(*=========================================================== expe, betweene_dec, between_bottom_B0 AND MA0.between_dec ============================================================*)
(* Decidability of betweene, in Prop: *)
(* IT SEEMS TO HAVE A PROBLEM WITH :  MA0.expo1_dec : forall (m : fmap) (z t : dart), inv_hmap m -> exd m z -> {MA0.expo1 m z t} + {~ MA0.expo1 m z t} *)
(* WE ALSO HAVE (EASILY): *)
(* OK! BY INDUCTION ON j: *)
(* THEN, BY INDUCTION ON j: *)
(* THEN, WE HAVE (OK!): *)
(* THEN (OK): *)
(* USEFUL LEMMAS: *)
(* OK: *)
(* OK!!: *)
(* OK!!: *)
(* FINALLY, THE EXPECTED RESULT (OK): *)
(* COROLLARY: OK *)
(* OK: *)
(* DECIDABILITY OF MA0.between: COULD BE GENERALIZED *)
(* OK !! *)
(*========================================================== CHANGING THE OPENING IN AN ORBIT BY L_B: exd, inv_hmap, planar, cA, cA_1, bottom, cF, cF_1, top, expf, expe, eqc... ==========================================================*)
(* OK! *)
(* IDEM, SYMMETRIC: *)
(* OK: USEFULL?  Lemma cA_cA_1_L_B_top_bot:forall(m:fmap)(k:dim)(x:dart), inv_hmap m -> succ m k x -> (forall z:dart, exd m z -> cA (L (B m k x) k (top m k x) (bottom m k x)) k z = cA m k z) -> (forall z:dart, exd m z -> cA_1 (L (B m k x) k (top m k x) (bottom m k x)) k z = cA_1 m k z). *)
(* OK: *)
(* OK! *)
(* OK !! *)
(* OK!! *)
(* OK! *)
(* OK: *)
(* OK!! *)
(*========================================================== (PRE-)DOUBLE-LINKS AND BREAKING ===========================================================*)
(* BREAKING A PRE-DOUBLE-LINK (x x'): GENERAL *)
Definition Br1(m:fmap)(x x':dart):fmap:=
if succ_dec m zero x
then if succ_dec m zero x'
then B (L (B m zero x)
zero (top m zero x) (bottom m zero x)) zero x'
else B m zero x
else B m zero x'.
(* OK !! *)
(* TO BE A DOUBLE-LINK: *)
Definition double_link(m:fmap)(x x':dart):Prop:=
x <> x' /\ expe m x x'.
(* cA0 / Br1 : *)
(* SYMMETRICALLY: *)
(* IDEM, WITH cF, cF_1 / Br1: *)
(* GREAT!! *)
(* THE SYMMETRIC: *)
(* OK!! VERY IMPORTANT: *)
(*========================================================== LISTS AND RINGS (OF DOUBLE-LINKS) ==========================================================*)
(* dart*dart LISTS : *)
Inductive list:Set :=
lam : list | cons : dart->dart->list->list.
Definition emptyl(l:list):Prop:=
match l with
lam => True
| _ => False
end.
Fixpoint isin1(l:list)(z:dart){struct l}:Prop:=
match l with
lam => False
| cons x x' l0 => x = z \/ isin1 l0 z
end.
Fixpoint isin2(l:list)(z:dart){struct l}:Prop:=
match l with
lam => False
| cons x x' l0 => x' = z \/ isin2 l0 z
end.
Fixpoint len(l:list):nat:=
match l with
lam => 0%nat
| cons _ _ l0 => ((len l0) + 1)%nat
end.
Definition first(l:list):dart*dart :=
match l with
lam => (nil,nil)
| cons x x' _ => (x,x')
end.
Definition tail(l:list):list :=
match l with
lam => lam
| cons _ _ l0 => l0
end.
Fixpoint last(l:list):dart*dart :=
match l with
lam => (nil,nil)
| cons x x' l0 =>
match l0 with
lam => (x, x')
| cons _ _ l1 => last l0
end
end.
Fixpoint nth(l:list)(k:nat){struct l}:dart*dart :=
match l with
lam => (nil,nil)
| cons x x' l0 =>
match k with
0%nat => (nil,nil)
| S 0%nat => (x,x')
| S (S k0) => nth l0 (S k0)
end
end.
Fixpoint double_link_list(m:fmap)(l:list){struct l}:Prop:=
match l with
lam => True
| cons x x' l0 => double_link m x x'
/\ double_link_list m l0
end.
(* BREAKING THE 0-LINKS IN A MAP m ALONG A DOUBLE-LINK LIST l: *)
Fixpoint Br(m:fmap)(l:list){struct l}:fmap:=
match l with
lam => m
| cons x x' l0 => Br (Br1 m x x') l0
end.
(* OK: *)
(* planar_Br: IN THE FOLLOWING *)
(* OK: *)
(* OK: *)
(* OK: *)
(*======================================================== "NEW" RINGS: ==========================================================*)
(* THE ELEMENTS OF l ARE DOUBLE_LINKS: double_link_list m l *)
(* THE DARTS OF l DO NOT BELONG TO THE EDGE OF x *)
Fixpoint distinct_edge_list
(m:fmap)(x:dart)(l:list){struct l}:Prop:=
match l with
lam => True
| cons xs _ l0 =>
distinct_edge_list m x l0 /\ ~expe m x xs
end.
(* CONDITION (0): THE EDGES OF l ARE DISTINCTS: *)
Fixpoint pre_ring0(m:fmap)(l:list){struct l}:Prop:=
match l with
lam => True
| cons x _ l0 => pre_ring0 m l0 /\
distinct_edge_list m x l0
end.
(*�TWO double_links (x,x'), (xs,xs') ARE ADJACENT BY A FACE:*)
Definition face_adjacent(m:fmap)(x x' xs xs':dart):=
let y':= cA m zero x' in
let ys:= cA m zero xs in
expf m y' ys.
(*�CONDITION (1) OF CONTINUITY: SUCCESSIVE double_link IN l ARE face_adjacent:*)
Fixpoint pre_ring1(m:fmap)(l:list){struct l}:Prop:=
match l with
lam => True
| cons x x' l0 =>
match l0 with
lam => True
| cons xs xs' l' =>
pre_ring1 m l0 /\ face_adjacent m x x' xs xs'
end
end.
(* CONDITION (2) OF CLOSURE: THE FIST AND LAST FACES ARE ADJACENT *)
Definition pre_ring2(m:fmap)(l:list):Prop:=
match l with
lam => True
| cons x x' l0 =>
match (last l) with (xs,xs') =>
face_adjacent m xs xs' x x'
end
end.
(* CONDITION (3) OF SIMPLICITY: THE FACES OF y' AND ys ARE DISTINCT : *)
Definition distinct_faces(m:fmap)(x x' xs xs':dart):Prop:=
let y := cA m zero x in
let ys:= cA m zero xs in
~expf m y ys.
(* THE FACE OF y' IS DISTINCT FROM ALL FACES OF l: *)
Fixpoint distinct_face_list
(m:fmap)(x x':dart)(l:list){struct l}:Prop:=
match l with
lam => True
| cons xs xs' l0 => distinct_face_list m x x' l0
/\ distinct_faces m x x' xs xs'
end.
(* RING SIMPLICITY: *)
Fixpoint pre_ring3(m:fmap)(l:list){struct l}:Prop:=
match l with
lam => True
| cons x x' l0 =>
pre_ring3 m l0 /\ distinct_face_list m x x' l0
end.
(*TO BE A RING: *)
Definition ring(m:fmap)(l:list):Prop:=
~emptyl l /\ double_link_list m l /\
pre_ring0 m l /\
pre_ring1 m l /\
pre_ring2 m l /\
pre_ring3 m l.
(*============================================================ FIRST PROPERTIES WITH Jordan FOR A RING OF LENGTH 1 =============================================================*)
(* OK !! *)
(* ANCIEN VERSION, WITHOUT nc_Br1: Lemma Jordan1:forall(m:fmap)(x x':dart), inv_hmap m -> planar m -> let l:= cons x x' lam in ring m l -> nc (Br m l) = nc m + 1. *)
(*======================================================= PRELIMINARIES FOR THE GENERAL CASE =======================================================*)
(* OK: *)
(* OK: *)
(*============================================================ NEW pre_ring0 PROPERTIES: OK =============================================================*)
(* SIMILAR TO expe_bottom_z ABOVE: OK : *)
(* THEN: *)
(* OK: *)
(* NEW: OK (WITH THE LEMMAS ABOVE) *)
(* OK: *)
(* OK:  *)
(* OK!: *)
(* pre_ring0_Br1 is defined *)
(*============================================================ NEW double_link_list PROPERTIES: OK! =============================================================*)
(* OK! *)
(* OK! *)
(* double_link_list_Br1 is defined *)
(* OK!! *)
(*============================================================ NEW pre_ring1 PROPERTIES: OK =============================================================*)
(* NEW, OK!! *)
(* OK!!: *)
(* NEW, OK!!: *)
(* pre_ring1_Br1 is defined *)
(*============================================================ NEW pre_ring2 PROPERTIES : OK =============================================================*)
(* NEW, OK: VERY USEFUL *)
(* OK: USEFUL *)

Lemma distinct_last_darts:
forall(m:fmap)(l:list)(x x' xf xf':dart),
inv_hmap m ->
double_link_list m (cons x x' (cons xf xf' l)) ->
pre_ring0 m (cons x x' (cons xf xf' l)) ->
let (xl, xl') := last (cons xf xf' l) in
(x <> xl' /\ x' <> xl').