(** * Additional notions over maps *)
Definition Disjoint (m m' : t elt) :=
forall k, ~(In k m /\ In k m').
Definition Partition (m m1 m2 : t elt) :=
Disjoint m1 m2 /\
(forall k e, MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2).
(** * Emulation of some functions lacking in the interface *)
Definition filter (f : key -> elt -> bool)(m : t elt) :=
fold (fun k e m => if f k e then add k e m else m) m (empty _).
Definition for_all (f : key -> elt -> bool)(m : t elt) :=
fold (fun k e b => if f k e then b else false) m true.
Definition exists_ (f : key -> elt -> bool)(m : t elt) :=
fold (fun k e b => if f k e then true else b) m false.
Definition partition (f : key -> elt -> bool)(m : t elt) :=
(filter f m, filter (fun k e => negb (f k e)) m).
(** [update] adds to [m1] all the bindings of [m2]. It can be seen as an [union] operator which gives priority to its 2nd argument in case of binding conflit. *)
Definition update (m1 m2 : t elt) := fold (@add _) m2 m1.
(** [restrict] keeps from [m1] only the bindings whose key is in [m2]. It can be seen as an [inter] operator, with priority to its 1st argument in case of binding conflit. *)
Definition restrict (m1 m2 : t elt) := filter (fun k _ => mem k m2) m1.
(** [diff] erases from [m1] all bindings whose key is in [m2]. *)
Definition diff (m1 m2 : t elt) := filter (fun k _ => negb (mem k m2)) m1.
Section Specs.
Variable f : key -> elt -> bool.
Hypothesis Hf : Proper (E.eq==>eq==>eq) f.

Lemma exists_iff : forall m,
exists_ f m = true <->
(exists p, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true).