(*========================================================
                     "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.

(* Specifications: *)
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.
Lemma expf_expf_B:forall (m:fmap)(x z t:dart), inv_hmap m -> succ m zero x -> let y := A m zero x in let x0 := bottom m zero x in ~expf m y x0 -> expf m z t -> expf (B m zero x) z t.
Lemma ring1_ring3_connect: forall(m:fmap)(x x' xs xs':dart)(l:list), let l1:= cons x x' (cons xs xs' l) in let y := cA m zero x in let y' := cA m zero x' in inv_hmap m -> planar m -> double_link_list m l1 -> pre_ring1 m l1 -> pre_ring3 m l1 -> ~ expf m y y'.
Lemma expe_top_z:forall(m:fmap)(z:dart), inv_hmap m -> exd m z -> expe m z (top m zero z).
Lemma expe_top_A:forall(m:fmap)(z:dart), inv_hmap m -> succ m zero z -> expe m (top m zero z) (A m zero z).
Lemma expe_B_i: forall(m:fmap)(x z:dart)(i:nat), inv_hmap m -> succ m zero x -> exd m z -> let t := Iter (MA0.f (B m zero x)) i z in expe m z t.
Lemma expe_B_expe: forall(m:fmap)(x z t:dart), inv_hmap m -> expe (B m zero x) z t -> expe m z t.
Lemma expe_Br1_expe :forall(m:fmap)(x x' z t:dart), inv_hmap m -> expe (Br1 m x x') z t -> expe m z t.
Lemma distinct_edge_list_Br1: forall(m:fmap)(x x' xs xs':dart)(l:list), inv_hmap m -> planar m -> pre_ring0 m (cons x x' (cons xs xs' l)) -> distinct_edge_list (Br1 m x x') xs l.
Lemma pre_ring0_Br1_aux: forall(m:fmap)(x x':dart)(l:list), inv_hmap m -> planar m -> pre_ring0 m (cons x x' l) -> pre_ring0 (Br1 m x x') l.
Lemma pre_ring0_Br1: forall(m:fmap)(l:list), inv_hmap m -> planar m -> pre_ring0 m l -> let (x,x') := first l in pre_ring0 (Br1 m x x') (tail l).
Lemma expe_expe_B0: forall(m:fmap)(x z t:dart), inv_hmap m -> exd m x -> let m0 := B m zero x in ~ expe m x z -> expe m z t-> expe m0 z t.
Lemma double_link_list_Br1_aux: forall(m:fmap)(x x':dart)(l:list), inv_hmap m -> double_link_list m (cons x x' l) -> pre_ring0 m (cons x x' l) -> double_link_list (Br1 m x x') l.
Lemma double_link_list_Br1: forall(m:fmap)(l:list), inv_hmap m -> double_link_list m l -> pre_ring0 m l -> let (x,x') := first l in double_link_list (Br1 m x x') (tail l).
Lemma planar_Br:forall(l:list)(m:fmap), inv_hmap m -> planar m -> pre_ring0 m l -> double_link_list m l -> planar (Br m l).
Lemma expf_Br1:forall(m:fmap)(x x' z t:dart), inv_hmap m -> planar m -> double_link m x x' -> let y:= cA m zero x in let y':= cA m zero x' in ~expf m y y' -> (expf m z t -> expf (Br1 m x x') z t).
Lemma pre_ring1_Br1_aux: forall(m:fmap)(x x':dart)(l:list), inv_hmap m -> planar m -> let y:= cA m zero x in let y':= cA m zero x' in double_link_list m (cons x x' l) -> pre_ring0 m (cons x x' l) -> pre_ring1 m l -> ~expf m y y' -> pre_ring1 (Br1 m x x') l.
Lemma pre_ring1_Br1: forall(m:fmap)(l:list), inv_hmap m -> planar m -> double_link_list m l -> pre_ring0 m l -> pre_ring1 m l -> let (x,x') := first l in let y := cA m zero x in let y' := cA m zero x' in ~expf m y y' -> pre_ring1 (Br1 m x x') (tail l).
Lemma expf_Br1_link:forall (m : fmap) (x x': dart), inv_hmap m -> planar m -> double_link m x x' -> let y :=cA m zero x in let y':=cA m zero x' in ~expf m y y' -> expf (Br1 m x x') y y'.
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').
Lemma pre_ring2_Br1: forall(m:fmap)(l:list), inv_hmap m -> planar m -> double_link_list m l -> pre_ring0 m l -> pre_ring1 m l -> pre_ring2 m l -> let (x,x') := first l in let y := cA m zero x in let y' := cA m zero x' in ~expf m y y' -> pre_ring2 (Br1 m x x') (tail l).
Lemma betweenf_expf1:forall(m:fmap)(z v t:dart), inv_hmap m -> exd m z -> betweenf m z v t -> (expf m v z /\ expf m v t).
Lemma not_expf_B:forall (m:fmap)(x z t:dart), inv_hmap m -> planar m -> succ m zero x -> let y := A m zero x in let x0 := bottom m zero x in (~expf m y z /\ ~expf m x0 z \/ ~expf m y t /\ ~expf m x0 t) -> ~expf m z t -> ~expf (B m zero x) z t.
Lemma not_expf_Br1:forall (m:fmap)(x x' z t:dart), inv_hmap m -> planar m -> double_link m x x' -> let y := cA m zero x in let y' := cA m zero x' in (~expf m y z /\ ~expf m y' z \/ ~expf m y t /\ ~expf m y' t) -> ~expf m z t -> ~expf (Br1 m x x') z t.
Lemma distinct_face_list_Br1_aux: forall(m:fmap)(x x' xs xs':dart)(l:list), inv_hmap m -> planar m -> let l1 := cons x x' (cons xs xs' l) in double_link_list m l1 -> pre_ring0 m l1 -> face_adjacent m x x' xs xs' -> pre_ring3 m l1 -> distinct_face_list (Br1 m x x') xs xs' l.
Lemma distinct_faces_Br1: forall(m:fmap)(x x' xs xs' z z' zs zs':dart)(l:list), inv_hmap m -> planar m -> let l1:= cons x x' (cons xs xs' (cons z z' (cons zs zs' l))) in double_link_list m l1 -> pre_ring0 m l1 -> pre_ring3 m l1 -> face_adjacent m x x' xs xs' -> distinct_faces (Br1 m x x') z z' zs zs'.
Lemma distinct_face_list_Br1_aux_bis: forall(m:fmap)(x x' xs xs' xf xf':dart)(l:list), inv_hmap m -> planar m -> let l1 := cons x x' (cons xs xs' (cons xf xf' l)) in double_link_list m l1 -> pre_ring0 m l1 -> face_adjacent m x x' xs xs' -> pre_ring3 m l1 -> distinct_face_list (Br1 m x x') xf xf' l.
Lemma pre_ring3_Br1_aux: forall(m:fmap)(x x' xs xs':dart)(l:list), inv_hmap m -> planar m -> let l1 := cons x x' (cons xs xs' l) in double_link_list m l1 -> pre_ring0 m l1 -> face_adjacent m x x' xs xs' -> pre_ring3 m l1 -> pre_ring3 (Br1 m x x') (cons xs xs' l).
Lemma pre_ring3_Br1_aux_bis: forall(m:fmap)(x x' xs xs':dart)(l:list), inv_hmap m -> planar m -> let l1 := cons x x' (cons xs xs' l) in double_link_list m l1 -> pre_ring0 m l1 -> pre_ring1 m l1 -> pre_ring3 m l1 -> pre_ring3 (Br1 m x x') (cons xs xs' l).
Lemma pre_ring3_Br1: forall(m:fmap)(l:list), inv_hmap m -> planar m -> let (x,x') := first l in double_link_list m l -> pre_ring0 m l -> pre_ring1 m l -> pre_ring3 m l -> pre_ring3 (Br1 m x x') (tail l).
Lemma ring_Br1_aux: forall(m:fmap)(l:list), inv_hmap m -> planar m -> let x:= fst (first l) in let x' := snd (first l) in let y := cA m zero x in let y' := cA m zero x' in let m1 := Br1 m x x' in ~expf m y y' -> ring m l -> (emptyl (tail l) \/ ring m1 (tail l)).
Lemma ring_Br1: forall(m:fmap)(l:list), inv_hmap m -> planar m -> let x:= fst (first l) in let x' := snd (first l) in let m1 := Br1 m x x' in ring m l -> (emptyl (tail l) \/ ring m1 (tail l)).
Theorem Jordan: forall(l:list)(m:fmap), inv_hmap m -> planar m -> ring m l -> nc (Br m l) = nc m + 1.