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

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').