(*===========================================================
                   top, bottom
 
============================================================*)

(* top AND bottom :*)

Fixpoint top
   (m:fmap)(k:dim)(z:dart){struct m}:dart:=
 match m with
     V => nil
  |  I m0 x _ _ =>
       if eq_dart_dec x z then z
       else top m0 k z
  |  L m0 k0 x y =>
       if eq_dim_dec k0 k
       then
         if eq_dart_dec x (top m0 k0 z) 
         then top m0 k0 y
	 else top m0 k0 z
       else top m0 k z
 end.Fixpoint bottom
   (m:fmap)(k:dim)(z:dart){struct m}:dart:=
 match m with
     V => nil
  |  I m0 x _ _ =>
       if eq_dart_dec x z then z
       else bottom m0 k z
  |  L m0 k0 x y =>
       if (eq_dim_dec k0 k)
       then
         if eq_dart_dec y (bottom m0 k0 z)
         then bottom m0 k0 x
	 else bottom m0 k0 z
       else bottom m0 k z
 end.

(* Specifications: *)
Lemma top_nil : forall (m:fmap)(k:dim), inv_hmap m -> top m k nil = nil.
Lemma bottom_nil : forall (m:fmap)(k:dim), inv_hmap m -> bottom m k nil = nil.
Lemma not_exd_top : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> ~exd m z -> top m k z = nil.
Lemma not_exd_bottom : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> ~exd m z -> bottom m k z = nil.
Lemma exd_top:forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> exd m (top m k z).
Lemma exd_bottom:forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> exd m (bottom m k z).
Lemma nosucc_top : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> ~succ m k z -> top m k z = z.
Lemma nopred_bottom : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> ~pred m k z -> bottom m k z = z.
Lemma top_bottom_bis:forall(m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> top m k (bottom m k z) = top m k z.
Lemma bottom_top_bis:forall(m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> bottom m k (top m k z) = bottom m k z.
Lemma cA_bottom : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> ~succ m k z -> cA m k z = bottom m k z.
Lemma cA_1_top : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> ~pred m k z -> cA_1 m k z = top m k z.
Lemma cA_eq_aux : forall(m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> cA m k z = if succ_dec m k z then A m k z else bottom m k z.
Lemma cA_eq : forall(m:fmap)(k:dim)(z:dart), inv_hmap m -> cA m k z = if succ_dec m k z then A m k z else bottom m k z.
Lemma cA_1_eq_aux : forall(m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> cA_1 m k z = if pred_dec m k z then A_1 m k z else top m k z.
Lemma cA_1_eq : forall(m:fmap)(k:dim)(z:dart), inv_hmap m -> cA_1 m k z = if pred_dec m k z then A_1 m k z else top m k z.
Lemma top_bottom : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> ~succ m k z -> top m k (bottom m k z) = z.
Lemma bottom_top : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> ~pred m k z -> bottom m k (top m k z) = z.
Lemma top_A : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> succ m k z -> top m k (A m k z) = top m k z.
Lemma bottom_A : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> succ m k z -> bottom m k (A m k z) = bottom m k z.
Lemma bottom_A_1 : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> pred m k z -> bottom m k (A_1 m k z) = bottom m k z.
Lemma top_A_1 : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> pred m k z -> top m k (A_1 m k z) = top m k z.
Lemma not_succ_top : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> ~succ m k (top m k z).
Lemma not_pred_bottom : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> ~pred m k (bottom m k z).
Lemma top_top_1 : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> ~ succ m k z -> top m k (top m k z) = top m k z.
Lemma top_top_2 : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> succ m k z -> top m k (top m k z) = top m k z.
Lemma top_top : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> top m k (top m k z) = top m k z.
Lemma bottom_bottom_1 : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> ~ pred m k z -> bottom m k (bottom m k z) = bottom m k z.
Lemma bottom_bottom_2 : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> pred m k z -> bottom m k (bottom m k z) = bottom m k z.
Lemma bottom_bottom : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> bottom m k (bottom m k z) = bottom m k z.
Lemma succ_bottom:forall (m:fmap)(k:dim)(x:dart), inv_hmap m -> succ m k x -> bottom m k x <> A m k x.
Lemma pred_top :forall (m:fmap)(k:dim)(x:dart), inv_hmap m -> pred m k x -> top m k x <> A_1 m k x.
Lemma cA_top:forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> cA m k (top m k z) = bottom m k z.
Lemma cA_1_bottom:forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> exd m z -> cA_1 m k (bottom m k z) = top m k z.
Lemma top_top_bottom:forall(m:fmap)(k:dim)(x y:dart), inv_hmap m -> exd m x -> exd m y -> ~pred m k y -> top m k x = top m k y -> bottom m k x = y.
Lemma bottom_bottom_top:forall(m:fmap)(k:dim)(x y:dart), inv_hmap m -> exd m x -> exd m y -> ~succ m k y -> bottom m k x = bottom m k y -> top m k x = y.
Lemma top_top_bottom_bottom:forall(m:fmap)(k:dim)(x y:dart), inv_hmap m -> exd m x -> exd m y -> top m k x = top m k y -> bottom m k x = bottom m k y.
Lemma bottom_bottom_top_top:forall(m:fmap)(k:dim)(x y:dart), inv_hmap m -> exd m x -> exd m y -> bottom m k x = bottom m k y -> top m k x = top m k y.
Lemma cA_cA_1_B : forall (m:fmap)(k:dim)(x z:dart), inv_hmap m -> succ m k x -> cA (B m k x) k z = (if eq_dart_dec x z then bottom m k x else if eq_dart_dec (top m k x) z then A m k x else cA m k z) /\ cA_1 (B m k x) k z = (if eq_dart_dec (A m k x) z then top m k x else if eq_dart_dec (bottom m k x) z then x else cA_1 m k z).
Lemma cA_B : forall (m:fmap)(k:dim)(x z:dart), inv_hmap m -> succ m k x -> cA (B m k x) k z = (if eq_dart_dec x z then bottom m k x else if eq_dart_dec (top m k x) z then A m k x else cA m k z).
Lemma cA_1_B : forall (m:fmap)(k:dim)(x z:dart), inv_hmap m -> succ m k x -> cA_1 (B m k x) k z = (if eq_dart_dec (A m k x) z then top m k x else if eq_dart_dec (bottom m k x) z then x else cA_1 m k z).
Lemma cA_cA_1_B_bis : forall (m:fmap)(k:dim)(x z:dart), inv_hmap m -> ~succ m k x -> cA (B m k x) k z = cA m k z /\ cA_1 (B m k x) k z = cA_1 m k z.
Lemma cA_B_bis : forall (m:fmap)(k:dim)(x z:dart), inv_hmap m -> ~succ m k x -> cA (B m k x) k z = cA m k z.
Lemma cA_1_B_bis : forall (m:fmap)(k:dim)(x z:dart), inv_hmap m -> ~succ m k x -> cA_1 (B m k x) k z = cA_1 m k z.
Lemma cA_cA_1_B_ter : forall (m:fmap)(k j:dim)(x z:dart), inv_hmap m -> k <> j -> cA (B m k x) j z = cA m j z /\ cA_1 (B m k x) j z = cA_1 m j z.
Lemma cA_B_ter : forall (m:fmap)(k j:dim)(x z:dart), inv_hmap m -> k <> j -> cA (B m k x) j z = cA m j z.
Lemma cA_1_B_ter : forall (m:fmap)(k j:dim)(x z:dart), inv_hmap m -> k <> j -> cA_1 (B m k x) j z = cA_1 m j z.
Lemma inv_hmap_B : forall (m:fmap)(k:dim)(z:dart), inv_hmap m -> inv_hmap (B m k z).
Lemma B_1_eq : forall (m:fmap)(k:dim)(x:dart), inv_hmap m -> B_1 m k x = B m k (A_1 m k x).
Lemma inv_hmap_B_1 : forall (m:fmap)(k:dim)(x:dart), inv_hmap m -> inv_hmap (B_1 m k x).