Section Fold.
(** Alternative specification via [fold_right] *)
Notation NoDup := (NoDupA E.eq).
Notation InA := (InA E.eq).
(** ** Induction principles for fold (contributed by S. Lescuyer) *)
(** In the following lemma, the step hypothesis is deliberately restricted to the precise set s 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 to any [x]. At the same time, it looks more like an induction principle, and hence can be easier to use. *)
(** From the induction principle on [fold], we can deduce some general induction principles on sets. *)
(** [fold] can be used to reconstruct the same initial set. *)
(** ** 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: *)
(** An alternate (and previous) specification for [fold] was based on the recursive structure of a set. It is now lemmas [fold_1] and [fold_2]. *)

Lemma fold_2 :
forall s s' x (A : Type) (eqA : A -> A -> Prop)
(st : Equivalence eqA) (i : A) (f : elt -> A -> A),
compat_op E.eq eqA f ->
transpose eqA f ->
~ In x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i)).