(** [fold] can be used to reconstruct the same initial set. *)

(* Specifications: *)
Lemma fold_identity : forall m : t elt, Equal (fold (@add _) m (empty _)) m.
Section Fold_More.
Lemma fold_identity : forall s, fold add s empty [=] s.
(** ** Alternative (weaker) specifications for [fold] *)
(** When [FSets] was first designed, the order in which Ocaml's [Set.fold] takes the set elements was unspecified. This specification reflects this fact: *)
Lemma fold_0 :
forall s (A : Type) (i : A) (f : elt -> A -> A),
exists l : list elt,
NoDup l /\
(forall x : elt, In x s <-> InA x l) /\
fold f s i = fold_right f i l.
Lemma fold_identity : forall s, fold add s empty [=] s.
(** ** Alternative (weaker) specifications for [fold] *)
(** When [MSets] was first designed, the order in which Ocaml's [Set.fold] takes the set elements was unspecified. This specification reflects this fact: *)
Lemma fold_0 :
forall s (A : Type) (i : A) (f : elt -> A -> A),
exists l : list elt,
NoDup l /\
(forall x : elt, In x s <-> InA x l) /\
fold f s i = fold_right f i l.