Section Elt.
Variable elt:Type.
Definition Add x (e:elt) m m' := forall y, find y m' = find y (add x e m).
Notation eqke := (@eq_key_elt elt).
Notation eqk := (@eq_key elt).
Instance eqk_equiv : Equivalence eqk.
(** Complements about InA, NoDupA and findA *)
(** * Elements *)
(** * Conversions between maps and association lists. *)
Definition uncurry {U V W : Type} (f : U -> V -> W) : U*V -> W :=
fun p => f (fst p) (snd p).
Definition of_list :=
List.fold_right (uncurry (@add _)) (empty elt).
Definition to_list := elements.
(** * Fold *)
(** Alternative specification via [fold_right] *)
(** ** Induction principles about fold contributed by S. Lescuyer *)
(** In the following lemma, the step hypothesis is deliberately restricted to the precise map m we are considering. *)
(** Same, with [empty] and [add] instead of [Empty] and [Add]. In this case, [P] must be compatible with equality of sets *)
(** [fold_rec_weak] is a weaker principle than [fold_rec_bis] : the step hypothesis must here be applicable anywhere. At the same time, it looks more like an induction principle, and hence can be easier to use. *)

Lemma fold_rel :
forall (A B:Type)(R : A -> B -> Type)
(f : key -> elt -> A -> A)(g : key -> elt -> B -> B)(i : A)(j : B)
(m : t elt),
R i j ->
(forall k e a b, MapsTo k e m -> R a b -> R (f k e a) (g k e b)) ->
R (fold f m i) (fold g m j).