Fixpoint Map_of_alist (l:alist) : Map A :=
match l with
| nil => M0 A
| (a, y) :: l' => MapPut A (Map_of_alist l') a y
end.

(* Specifications: *)
Lemma Map_of_alist_semantics :
forall l:alist, eqm A (alist_semantics l) (MapGet A (Map_of_alist l)).
Lemma Map_of_alist_of_Map :
forall m:Map A, eqmap A (Map_of_alist (alist_of_Map m)) m.
Lemma alist_of_Map_of_alist :
forall l:alist,
eqm A (alist_semantics (alist_of_Map (Map_of_alist l)))
(alist_semantics l).
Lemma fold_right_aapp :
forall (M:Type) (neutral:M) (op:M -> M -> M),
(forall a b c:M, op (op a b) c = op a (op b c)) ->
(forall a:M, op neutral a = a) ->
forall (f:ad -> A -> M) (l l':alist),
fold_right (fun (r:ad * A) (m:M) => let (a, y) := r in op (f a y) m)
neutral (aapp l l') =
op
(fold_right
(fun (r:ad * A) (m:M) => let (a, y) := r in op (f a y) m) neutral
l)
(fold_right
(fun (r:ad * A) (m:M) => let (a, y) := r in op (f a y) m) neutral
l').
Lemma MapFold_as_fold_1 :
forall (M:Type) (neutral:M) (op:M -> M -> M),
(forall a b c:M, op (op a b) c = op a (op b c)) ->
(forall a:M, op neutral a = a) ->
(forall a:M, op a neutral = a) ->
forall (f:ad -> A -> M) (m:Map A) (pf:ad -> ad),
MapFold1 M neutral op f pf m =
fold_right (fun (r:ad * A) (m:M) => let (a, y) := r in op (f a y) m)
neutral
(MapFold1 alist anil aapp (fun (a:ad) (y:A) => acons (a, y) anil) pf
m).
Lemma MapFold_as_fold :
forall (M:Type) (neutral:M) (op:M -> M -> M),
(forall a b c:M, op (op a b) c = op a (op b c)) ->
(forall a:M, op neutral a = a) ->
(forall a:M, op a neutral = a) ->
forall (f:ad -> A -> M) (m:Map A),
MapFold M neutral op f m =
fold_right (fun (r:ad * A) (m:M) => let (a, y) := r in op (f a y) m)
neutral (alist_of_Map m).
Lemma alist_MapMerge_semantics :
forall m m':Map A,
eqm A (alist_semantics (aapp (alist_of_Map m') (alist_of_Map m)))
(alist_semantics (alist_of_Map (MapMerge A m m'))).
Lemma alist_MapMerge_semantics_disjoint :
forall m m':Map A,
eqmap A (MapDomRestrTo A A m m') (M0 A) ->
eqm A (alist_semantics (aapp (alist_of_Map m) (alist_of_Map m')))
(alist_semantics (alist_of_Map (MapMerge A m m'))).
Lemma alist_semantics_disjoint_comm :
forall l l':alist,
eqmap A (MapDomRestrTo A A (Map_of_alist l) (Map_of_alist l')) (M0 A) ->
eqm A (alist_semantics (aapp l l')) (alist_semantics (aapp l' l)).