(** As noticed by P. Casteran, asking for the general [SetoidList.transpose]
      here is too restrictive. Think for instance of [f] being [M.add] :
      in general, [M.add k e (M.add k e' m)] is not equivalent to
      [M.add k e' (M.add k e m)]. Fortunately, we will never encounter this
      situation during a real [fold], since the keys received by this [fold]
      are unique. Hence we can ask the transposition property to hold only
      for non-equal keys.

      This idea could be push slightly further, by asking the transposition
      property to hold only for (non-equal) keys living in the map given to
      [fold]. Please contact us if you need such a version.

      FSets could also benefit from a restricted [transpose], but for this
      case the gain is unclear. *)

  Definition transpose_neqkey :=
    forall k k' e e' a, ~E.eq k k' ->
      eqA (f k e (f k' e' a)) (f k' e' (f k e a)).

(* Specifications: *)
Lemma fold_commutes : forall i m k e, ~In k m -> eqA (fold f m (f k e i)) (f k e (fold f m i)).
Lemma fold_Equal : forall m1 m2 i, Equal m1 m2 -> eqA (fold f m1 i) (fold f m2 i).
Lemma fold_Equal2 : forall m1 m2 i j, Equal m1 m2 -> eqA i j -> eqA (fold f m1 i) (fold f m2 j).
Lemma fold_Add : forall m1 m2 k e i, ~In k m1 -> Add k e m1 m2 -> eqA (fold f m2 i) (f k e (fold f m1 i)).
Lemma fold_add : forall m k e i, ~In k m -> eqA (fold f (add k e m) i) (f k e (fold f m i)).
Lemma cardinal_fold : forall m : t elt, cardinal m = fold (fun _ _ => S) m 0.
Lemma cardinal_Empty : forall m : t elt, Empty m <-> cardinal m = 0.
Lemma Equal_cardinal : forall m m' : t elt, Equal m m' -> cardinal m = cardinal m'.
Lemma cardinal_1 : forall m : t elt, Empty m -> cardinal m = 0.
Lemma cardinal_2 : forall m m' x e, ~ In x m -> Add x e m m' -> cardinal m' = S (cardinal m).
Lemma cardinal_Add_In: forall m m' x e, In x m -> Add x e m m' -> cardinal m' = cardinal m.
Lemma cardinal_inv_1 : forall m : t elt, cardinal m = 0 -> Empty m.
Lemma cardinal_inv_2 : forall m n, cardinal m = S n -> { p : key*elt | MapsTo (fst p) (snd p) m }.
Lemma cardinal_inv_2b : forall m, cardinal m <> 0 -> { p : key*elt | MapsTo (fst p) (snd p) m }.