(* Specifications: *)
Lemma MapCard_M0 : MapCard A (M0 A) = 0.
Lemma MapCard_M1 : forall (a:ad) (y:A), MapCard A (M1 A a y) = 1.
Lemma MapCard_is_O : forall m:Map A, MapCard A m = 0 -> forall a:ad, MapGet A m a = None.
Lemma MapCard_is_not_O : forall (m:Map A) (a:ad) (y:A), MapGet A m a = Some y -> {n : nat | MapCard A m = S n}.
Lemma MapCard_is_one : forall m:Map A, MapCard A m = 1 -> {a : ad & {y : A | MapGet A m a = Some y}}.
Lemma MapCard_is_one_unique : forall m:Map A, MapCard A m = 1 -> forall (a a':ad) (y y':A), MapGet A m a = Some y -> MapGet A m a' = Some y' -> a = a' /\ y = y'.
Lemma length_as_fold : forall (C:Type) (l:list C), length l = fold_right (fun (_:C) (n:nat) => S n) 0 l.
Lemma length_as_fold_2 : forall l:alist A, length l = fold_right (fun (r:ad * A) (n:nat) => let (a, y) := r in 1 + n) 0 l.
Lemma MapCard_as_Fold_1 : forall (m:Map A) (pf:ad -> ad), MapCard A m = MapFold1 A nat 0 plus (fun (_:ad) (_:A) => 1) pf m.
Lemma MapCard_as_Fold : forall m:Map A, MapCard A m = MapFold A nat 0 plus (fun (_:ad) (_:A) => 1) m.
Lemma MapCard_as_length : forall m:Map A, MapCard A m = length (alist_of_Map A m).
Lemma MapCard_Put1_equals_2 : forall (p:positive) (a a':ad) (y y':A), MapCard A (MapPut1 A a y a' y' p) = 2.
Lemma MapCard_Put_sum : forall (m m':Map A) (a:ad) (y:A) (n n':nat), m' = MapPut A m a y -> n = MapCard A m -> n' = MapCard A m' -> {n' = n} + {n' = S n}.
Lemma MapCard_Put_lb : forall (m:Map A) (a:ad) (y:A), MapCard A (MapPut A m a y) >= MapCard A m.
Lemma MapCard_Put_ub : forall (m:Map A) (a:ad) (y:A), MapCard A (MapPut A m a y) <= S (MapCard A m).
Lemma MapCard_Put_1 : forall (m:Map A) (a:ad) (y:A), MapCard A (MapPut A m a y) = MapCard A m -> {y : A | MapGet A m a = Some y}.
Lemma MapCard_Put_2 : forall (m:Map A) (a:ad) (y:A), MapCard A (MapPut A m a y) = S (MapCard A m) -> MapGet A m a = None.
Lemma MapCard_Put_1_conv : forall (m:Map A) (a:ad) (y y':A), MapGet A m a = Some y -> MapCard A (MapPut A m a y') = MapCard A m.
Lemma MapCard_Put_2_conv : forall (m:Map A) (a:ad) (y:A), MapGet A m a = None -> MapCard A (MapPut A m a y) = S (MapCard A m).
Lemma MapCard_ext : forall m m':Map A, eqm A (MapGet A m) (MapGet A m') -> MapCard A m = MapCard A m'.
Lemma MapCard_Dom : forall m:Map A, MapCard A m = MapCard unit (MapDom A m).
Lemma MapCard_Dom_Put_behind : forall (m:Map A) (a:ad) (y:A), MapDom A (MapPut_behind A m a y) = MapDom A (MapPut A m a y).
Lemma MapCard_Put_behind_Put : forall (m:Map A) (a:ad) (y:A), MapCard A (MapPut_behind A m a y) = MapCard A (MapPut A m a y).
Lemma MapCard_Put_behind_sum : forall (m m':Map A) (a:ad) (y:A) (n n':nat), m' = MapPut_behind A m a y -> n = MapCard A m -> n' = MapCard A m' -> {n' = n} + {n' = S n}.
Lemma MapCard_makeM2 : forall m m':Map A, MapCard A (makeM2 A m m') = MapCard A m + MapCard A m'.
Lemma MapCard_Remove_sum : forall (m m':Map A) (a:ad) (n n':nat), m' = MapRemove A m a -> n = MapCard A m -> n' = MapCard A m' -> {n = n'} + {n = S n'}.
Lemma MapCard_Remove_ub : forall (m:Map A) (a:ad), MapCard A (MapRemove A m a) <= MapCard A m.
Lemma MapCard_Remove_lb : forall (m:Map A) (a:ad), S (MapCard A (MapRemove A m a)) >= MapCard A m.
Lemma MapCard_Remove_1 : forall (m:Map A) (a:ad), MapCard A (MapRemove A m a) = MapCard A m -> MapGet A m a = None.
Lemma MapCard_Remove_2 : forall (m:Map A) (a:ad), S (MapCard A (MapRemove A m a)) = MapCard A m -> {y : A | MapGet A m a = Some y}.
Lemma MapCard_Remove_1_conv : forall (m:Map A) (a:ad), MapGet A m a = None -> MapCard A (MapRemove A m a) = MapCard A m.
Lemma MapCard_Remove_2_conv : forall (m:Map A) (a:ad) (y:A), MapGet A m a = Some y -> S (MapCard A (MapRemove A m a)) = MapCard A m.
Lemma MapMerge_Restr_Card : forall m m':Map A, MapCard A m + MapCard A m' = MapCard A (MapMerge A m m') + MapCard A (MapDomRestrTo A A m m').
Lemma MapMerge_disjoint_Card : forall m m':Map A, MapDisjoint A A m m' -> MapCard A (MapMerge A m m') = MapCard A m + MapCard A m'.
Lemma MapSplit_Card : forall (m:Map A) (m':Map B), MapCard A m = MapCard A (MapDomRestrTo A B m m') + MapCard A (MapDomRestrBy A B m m').
Lemma MapMerge_Card_ub : forall m m':Map A, MapCard A (MapMerge A m m') <= MapCard A m + MapCard A m'.
Lemma MapDomRestrTo_Card_ub_l : forall (m:Map A) (m':Map B), MapCard A (MapDomRestrTo A B m m') <= MapCard A m.
Lemma MapDomRestrBy_Card_ub_l : forall (m:Map A) (m':Map B), MapCard A (MapDomRestrBy A B m m') <= MapCard A m.
Lemma MapMerge_Card_disjoint : forall m m':Map A, MapCard A (MapMerge A m m') = MapCard A m + MapCard A m' -> MapDisjoint A A m m'.
Lemma MapCard_is_Sn : forall (m:Map A) (n:nat), MapCard _ m = S n -> {a : ad | in_dom _ a m = true}.
Lemma MapSubset_card_eq_1 : forall (n:nat) (m:Map A) (m':Map B), MapSubset _ _ m m' -> MapCard _ m = n -> MapCard _ m' = n -> MapSubset _ _ m' m.
Lemma MapDomRestrTo_Card_ub_r : forall (m:Map A) (m':Map B), MapCard A (MapDomRestrTo A B m m') <= MapCard B m'.
Lemma MapMerge_Card_lb_l : forall m m':Map A, MapCard A (MapMerge A m m') >= MapCard A m.
Lemma MapMerge_Card_lb_r : forall m m':Map A, MapCard A (MapMerge A m m') >= MapCard A m'.
Lemma MapDomRestrBy_Card_lb : forall (m:Map A) (m':Map B), MapCard B m' + MapCard A (MapDomRestrBy A B m m') >= MapCard A m.
Lemma MapSubset_Card_le : forall (m:Map A) (m':Map B), MapSubset A B m m' -> MapCard A m <= MapCard B m'.
Lemma MapSubset_card_eq : forall (m:Map A) (m':Map B), MapSubset _ _ m m' -> MapCard _ m' <= MapCard _ m -> eqmap _ (MapDom _ m) (MapDom _ m').
Lemma eqm_sym : forall f f':ad -> option A, eqm A f f' -> eqm A f' f.
Lemma eqm_refl : forall f:ad -> option A, eqm A f f.
Lemma eqm_trans : forall f f' f'':ad -> option A, eqm A f f' -> eqm A f' f'' -> eqm A f f''.
Lemma MapFold_ext : forall (f:ad -> A -> M) (m m':Map A), eqmap A m m' -> MapFold _ _ neutral op f m = MapFold _ _ neutral op f m'.
Lemma MapFold_ext_f_1 : forall (m:Map A) (f g:ad -> A -> M) (pf:ad -> ad), (forall (a:ad) (y:A), MapGet _ m a = Some y -> f (pf a) y = g (pf a) y) -> MapFold1 _ _ neutral op f pf m = MapFold1 _ _ neutral op g pf m.
Lemma MapFold_ext_f : forall (f g:ad -> A -> M) (m:Map A), (forall (a:ad) (y:A), MapGet _ m a = Some y -> f a y = g a y) -> MapFold _ _ neutral op f m = MapFold _ _ neutral op g m.
Lemma MapFold1_as_Fold_1 : forall (m:Map A) (f f':ad -> A -> M) (pf pf':ad -> ad), (forall (a:ad) (y:A), f (pf a) y = f' (pf' a) y) -> MapFold1 _ _ neutral op f pf m = MapFold1 _ _ neutral op f' pf' m.
Lemma MapFold1_as_Fold : forall (f:ad -> A -> M) (pf:ad -> ad) (m:Map A), MapFold1 _ _ neutral op f pf m = MapFold _ _ neutral op (fun (a:ad) (y:A) => f (pf a) y) m.
Lemma MapFold1_ext : forall (f:ad -> A -> M) (m m':Map A), eqmap A m m' -> forall pf:ad -> ad, MapFold1 _ _ neutral op f pf m = MapFold1 _ _ neutral op f pf m'.
Lemma MapFold_Put_disjoint_1 : forall (p:positive) (f:ad -> A -> M) (pf:ad -> ad) (a1 a2:ad) (y1 y2:A), Nxor a1 a2 = Npos p -> MapFold1 A M neutral op f pf (MapPut1 A a1 y1 a2 y2 p) = op (f (pf a1) y1) (f (pf a2) y2).
Lemma MapFold_Put_disjoint_2 : forall (f:ad -> A -> M) (m:Map A) (a:ad) (y:A) (pf:ad -> ad), MapGet A m a = None -> MapFold1 A M neutral op f pf (MapPut A m a y) = op (f (pf a) y) (MapFold1 A M neutral op f pf m).
Lemma MapFold_Put_disjoint : forall (f:ad -> A -> M) (m:Map A) (a:ad) (y:A), MapGet A m a = None -> MapFold A M neutral op f (MapPut A m a y) = op (f a y) (MapFold A M neutral op f m).
Lemma MapFold_Put_behind_disjoint_2 : forall (f:ad -> A -> M) (m:Map A) (a:ad) (y:A) (pf:ad -> ad), MapGet A m a = None -> MapFold1 A M neutral op f pf (MapPut_behind A m a y) = op (f (pf a) y) (MapFold1 A M neutral op f pf m).
Lemma MapFold_Put_behind_disjoint : forall (f:ad -> A -> M) (m:Map A) (a:ad) (y:A), MapGet A m a = None -> MapFold A M neutral op f (MapPut_behind A m a y) = op (f a y) (MapFold A M neutral op f m).
Lemma MapFold_Merge_disjoint_1 : forall (f:ad -> A -> M) (m1 m2:Map A) (pf:ad -> ad), MapDisjoint A A m1 m2 -> MapFold1 A M neutral op f pf (MapMerge A m1 m2) = op (MapFold1 A M neutral op f pf m1) (MapFold1 A M neutral op f pf m2).
Lemma MapFold_Merge_disjoint : forall (f:ad -> A -> M) (m1 m2:Map A), MapDisjoint A A m1 m2 -> MapFold A M neutral op f (MapMerge A m1 m2) = op (MapFold A M neutral op f m1) (MapFold A M neutral op f m2).
Lemma MapFold_distr_r_1 : forall (f:ad -> A -> M) (m:Map A) (c:N) (pf:ad -> ad), times (MapFold1 A M neutral op f pf m) c = MapFold1 A M' neutral' op' (fun (a:ad) (y:A) => times (f a y) c) pf m.
Lemma MapFold_distr_r : forall (f:ad -> A -> M) (m:Map A) (c:N), times (MapFold A M neutral op f m) c = MapFold A M' neutral' op' (fun (a:ad) (y:A) => times (f a y) c) m.
Lemma MapFold_distr_l : forall (f:ad -> A -> M) (m:Map A) (c:N), times c (MapFold A M neutral op f m) = MapFold A M' neutral' op' (fun (a:ad) (y:A) => times c (f a y)) m.
Lemma MapFold_orb_1 : forall (f:ad -> A -> bool) (m:Map A) (pf:ad -> ad), MapFold1 A bool false orb f pf m = match MapSweep1 A f pf m with | Some _ => true | _ => false end.
Lemma MapFold_orb : forall (f:ad -> A -> bool) (m:Map A), MapFold A bool false orb f m = match MapSweep A f m with | Some _ => true | _ => false end.
Lemma MapPut_as_Merge_c : forall m:Map A, mapcanon A m -> forall (a:ad) (y:A), MapPut A m a y = MapMerge A m (M1 A a y).
Lemma MapPut_behind_as_Merge_c : forall m:Map A, mapcanon A m -> forall (a:ad) (y:A), MapPut_behind A m a y = MapMerge A (M1 A a y) m.
Lemma MapMerge_empty_m_c : forall m:Map A, MapMerge A (M0 A) m = m.
Lemma MapMerge_assoc_c : forall m m' m'':Map A, mapcanon A m -> mapcanon A m' -> mapcanon A m'' -> MapMerge A (MapMerge A m m') m'' = MapMerge A m (MapMerge A m' m'').
Lemma MapMerge_idempotent_c : forall m:Map A, mapcanon A m -> MapMerge A m m = m.
Lemma MapMerge_RestrTo_l_c : forall m m' m'':Map A, mapcanon A m -> mapcanon A m'' -> MapMerge A (MapDomRestrTo A A m m') m'' = MapDomRestrTo A A (MapMerge A m m'') (MapMerge A m' m'').
Lemma MapRemove_as_RestrBy_c : forall m:Map A, mapcanon A m -> forall (a:ad) (y:B), MapRemove A m a = MapDomRestrBy A B m (M1 B a y).
Lemma MapDomRestrTo_assoc_c : forall (m:Map A) (m':Map B) (m'':Map C), mapcanon A m -> MapDomRestrTo A C (MapDomRestrTo A B m m') m'' = MapDomRestrTo A B m (MapDomRestrTo B C m' m'').
Lemma MapDomRestrTo_idempotent_c : forall m:Map A, mapcanon A m -> MapDomRestrTo A A m m = m.
Lemma MapDomRestrTo_Dom_c : forall (m:Map A) (m':Map B), mapcanon A m -> MapDomRestrTo A B m m' = MapDomRestrTo A unit m (MapDom B m').
Lemma MapDomRestrBy_Dom_c : forall (m:Map A) (m':Map B), mapcanon A m -> MapDomRestrBy A B m m' = MapDomRestrBy A unit m (MapDom B m').
Lemma MapDomRestrBy_By_c : forall (m:Map A) (m' m'':Map B), mapcanon A m -> MapDomRestrBy A B (MapDomRestrBy A B m m') m'' = MapDomRestrBy A B m (MapMerge B m' m'').
Lemma MapDomRestrBy_By_comm_c : forall (m:Map A) (m':Map B) (m'':Map C), mapcanon A m -> MapDomRestrBy A C (MapDomRestrBy A B m m') m'' = MapDomRestrBy A B (MapDomRestrBy A C m m'') m'.
Lemma MapDomRestrBy_To_c : forall (m:Map A) (m':Map B) (m'':Map C), mapcanon A m -> MapDomRestrBy A C (MapDomRestrTo A B m m') m'' = MapDomRestrTo A B m (MapDomRestrBy B C m' m'').
Lemma MapDomRestrBy_To_comm_c : forall (m:Map A) (m':Map B) (m'':Map C), mapcanon A m -> MapDomRestrBy A C (MapDomRestrTo A B m m') m'' = MapDomRestrTo A B (MapDomRestrBy A C m m'') m'.
Lemma MapDomRestrTo_By_c : forall (m:Map A) (m':Map B) (m'':Map C), mapcanon A m -> MapDomRestrTo A C (MapDomRestrBy A B m m') m'' = MapDomRestrTo A C m (MapDomRestrBy C B m'' m').
Lemma MapDomRestrTo_By_comm_c : forall (m:Map A) (m':Map B) (m'':Map C), mapcanon A m -> MapDomRestrTo A C (MapDomRestrBy A B m m') m'' = MapDomRestrBy A B (MapDomRestrTo A C m m'') m'.
Lemma MapDomRestrTo_To_comm_c : forall (m:Map A) (m':Map B) (m'':Map C), mapcanon A m -> MapDomRestrTo A C (MapDomRestrTo A B m m') m'' = MapDomRestrTo A B (MapDomRestrTo A C m m'') m'.
Lemma MapMerge_DomRestrTo_c : forall (m m':Map A) (m'':Map B), mapcanon A m -> mapcanon A m' -> MapDomRestrTo A B (MapMerge A m m') m'' = MapMerge A (MapDomRestrTo A B m m'') (MapDomRestrTo A B m' m'').
Lemma MapMerge_DomRestrBy_c : forall (m m':Map A) (m'':Map B), mapcanon A m -> mapcanon A m' -> MapDomRestrBy A B (MapMerge A m m') m'' = MapMerge A (MapDomRestrBy A B m m'') (MapDomRestrBy A B m' m'').
Lemma MapDelta_nilpotent_c : forall m:Map A, mapcanon A m -> MapDelta A m m = M0 A.
Lemma MapDelta_as_Merge_c : forall m m':Map A, mapcanon A m -> mapcanon A m' -> MapDelta A m m' = MapMerge A (MapDomRestrBy A A m m') (MapDomRestrBy A A m' m).
Lemma MapDelta_as_DomRestrBy_c : forall m m':Map A, mapcanon A m -> mapcanon A m' -> MapDelta A m m' = MapDomRestrBy A A (MapMerge A m m') (MapDomRestrTo A A m m').
Lemma MapDelta_as_DomRestrBy_2_c : forall m m':Map A, mapcanon A m -> mapcanon A m' -> MapDelta A m m' = MapDomRestrBy A A (MapMerge A m m') (MapDomRestrTo A A m' m).
Lemma MapDelta_sym_c : forall m m':Map A, mapcanon A m -> mapcanon A m' -> MapDelta A m m' = MapDelta A m' m.
Lemma MapDom_Split_1_c : forall (m:Map A) (m':Map B), mapcanon A m -> m = MapMerge A (MapDomRestrTo A B m m') (MapDomRestrBy A B m m').
Lemma MapDom_Split_2_c : forall (m:Map A) (m':Map B), mapcanon A m -> m = MapMerge A (MapDomRestrBy A B m m') (MapDomRestrTo A B m m').
Lemma MapDom_Split_3_c : forall (m:Map A) (m':Map B), mapcanon A m -> MapDomRestrTo A A (MapDomRestrTo A B m m') (MapDomRestrBy A B m m') = M0 A.
Lemma Map_of_alist_of_Map_c : forall m:Map A, mapcanon A m -> Map_of_alist A (alist_of_Map A m) = m.
Lemma alist_of_Map_of_alist_c : forall l:alist A, alist_sorted_2 A l -> alist_of_Map A (Map_of_alist A l) = l.
Lemma MapSubset_antisym_c : forall (m:Map A) (m':Map B), mapcanon A m -> mapcanon B m' -> MapSubset A B m m' -> MapSubset B A m' m -> MapDom A m = MapDom B m'.
Lemma FSubset_antisym_c : forall s s':FSet, mapcanon unit s -> mapcanon unit s' -> MapSubset _ _ s s' -> MapSubset _ _ s' s -> s = s'.
Lemma MapDisjoint_empty_c : forall m:Map A, mapcanon A m -> MapDisjoint A A m m -> m = M0 A.
Lemma MapDelta_disjoint_c : forall m m':Map A, mapcanon A m -> mapcanon A m' -> MapDisjoint A A m m' -> MapDelta A m m' = MapMerge A m m'.
Lemma FSetDelta_assoc_c : forall s s' s'':FSet, mapcanon unit s -> mapcanon unit s' -> mapcanon unit s'' -> MapDelta _ (MapDelta _ s s') s'' = MapDelta _ s (MapDelta _ s' s'').
Lemma FSet_ext_c : forall s s':FSet, mapcanon unit s -> mapcanon unit s' -> (forall a:ad, in_FSet a s = in_FSet a s') -> s = s'.
Lemma FSetUnion_comm_c : forall s s':FSet, mapcanon unit s -> mapcanon unit s' -> FSetUnion s s' = FSetUnion s' s.
Lemma FSetUnion_assoc_c : forall s s' s'':FSet, mapcanon unit s -> mapcanon unit s' -> mapcanon unit s'' -> FSetUnion (FSetUnion s s') s'' = FSetUnion s (FSetUnion s' s'').
Lemma FSetUnion_M0_s_c : forall s:FSet, FSetUnion (M0 unit) s = s.
Lemma FSetUnion_s_M0_c : forall s:FSet, FSetUnion s (M0 unit) = s.
Lemma FSetUnion_idempotent : forall s:FSet, mapcanon unit s -> FSetUnion s s = s.
Lemma FSetInter_comm_c : forall s s':FSet, mapcanon unit s -> mapcanon unit s' -> FSetInter s s' = FSetInter s' s.
Lemma FSetInter_assoc_c : forall s s' s'':FSet, mapcanon unit s -> FSetInter (FSetInter s s') s'' = FSetInter s (FSetInter s' s'').
Lemma FSetInter_M0_s_c : forall s:FSet, FSetInter (M0 unit) s = M0 unit.
Lemma FSetInter_s_M0_c : forall s:FSet, FSetInter s (M0 unit) = M0 unit.
Lemma FSetInter_idempotent : forall s:FSet, mapcanon unit s -> FSetInter s s = s.
Lemma FSetUnion_Inter_l_c : forall s s' s'':FSet, mapcanon unit s -> mapcanon unit s'' -> FSetUnion (FSetInter s s') s'' = FSetInter (FSetUnion s s'') (FSetUnion s' s'').
Lemma FSetUnion_Inter_r : forall s s' s'':FSet, mapcanon unit s -> mapcanon unit s' -> FSetUnion s (FSetInter s' s'') = FSetInter (FSetUnion s s') (FSetUnion s s'').
Lemma FSetInter_Union_l_c : forall s s' s'':FSet, mapcanon unit s -> mapcanon unit s' -> FSetInter (FSetUnion s s') s'' = FSetUnion (FSetInter s s'') (FSetInter s' s'').
Lemma FSetInter_Union_r : forall s s' s'':FSet, mapcanon unit s -> mapcanon unit s' -> FSetInter s (FSetUnion s' s'') = FSetUnion (FSetInter s s') (FSetInter s s'').