End my_MapFold.
(* Next we show the assumptions in the previous section are satisfied if M is a set of maps, neutral is the empty map, op is MapMerge and R is eqmap *)

(* Specifications: *)
(* eqmap is an equivalence relation *)
Lemma eqmap_equiv : forall A : Set, equiv _ (eqmap A).
(* MapMerge is associative *)
Lemma MapMerge_assoc :
forall (A : Set) (a b c : Map A),
eqmap _ (MapMerge _ (MapMerge _ a b) c) (MapMerge _ a (MapMerge _ b c)).
(* M0 is the left identity *)
Lemma MapMerge_neutral_left :
forall (A : Set) (m : Map A), eqmap _ (MapMerge _ (M0 A) m) m.
(* M0 is the right identity *)
Lemma MapMerge_neutral_right :
forall (A : Set) (m : Map A), eqmap _ (MapMerge _ m (M0 _)) m.
(* MapMerge preserves the eqmap relation *)
Lemma MapMerge_eq :
forall (A : Set) (a a1 b b1 : Map A),
eqmap _ a a1 -> eqmap _ b b1 -> eqmap _ (MapMerge _ a b) (MapMerge _ a1 b1).
(* The net result : a semantics for MapCollect in terms of lists *)
Lemma myMapFold_as_fold_2 :
forall (A B : Set) (f : ad -> A -> Map B) (m : Map A),
eqmap _ (MapFold _ (Map B) (M0 _) (MapMerge _) f m)
(fold_right
(fun (r : ad * A) (m : Map B) =>
let (a, y) := r in MapMerge _ (f a y) m) (M0 _)
(alist_of_Map _ m)).
Lemma my_alist_of_map_lemma_1 :
forall (A : Set) (m : Map A) (a : ad) (y : A),
MapGet _ m a = Some y -> In (a, y) (alist_of_Map _ m).
Lemma my_alist_of_map_lemma_2 :
forall (A : Set) (m : Map A) (pf fp : ad -> ad),
(forall a : ad, fp (pf a) = a) ->
forall (a : ad) (y : A),
In (a, y)
(MapFold1 _ _ (anil _) (aapp _)
(fun (a : ad) (y : A) => acons _ (a, y) (anil _)) pf m) ->
MapGet _ m (fp a) = Some y /\ pf (fp a) = a.
Lemma my_alist_of_map_lemma_3 :
forall (A : Set) (m : Map A) (a : ad) (y : A),
In (a, y) (alist_of_Map _ m) -> MapGet _ m a = Some y.