Module Type Ops (E : OrderedType) := WOps E <+ HasOrdOps.Module Type S := Sets.Definition elt := E.t.Record t_ := Mkt {this :> M.t; is_ok : M.Ok this}.Record t_ := Mkt {this :> M.t; is_ok : M.Ok this}.Record t_ := Mkt {this :> M.t; is_ok : M.Ok this}.Record t_ := Mkt {this :> M.t; is_ok : M.Ok this}.Definition t := t_.Definition In (x : elt)(s : t) := M.In x (this s).Definition Equal (s s' : t) := forall a : elt, In a s <-> In a s'.Definition Subset (s s' : t) := forall a : elt, In a s -> In a s'.Definition Empty (s : t) := forall a : elt, ~ In a s.Definition For_all (P : elt -> Prop)(s : t) := forall x, In x s -> P x.Definition Exists (P : elt -> Prop)(s : t) := exists x, In x s /\ P x.Definition mem (x : elt)(s : t) := M.mem x s.Definition add (x : elt)(s : t) : t := Mkt (M.add x s).Definition remove (x : elt)(s : t) : t := Mkt (M.remove x s).Definition singleton (x : elt) : t := Mkt (M.singleton x).Definition union (s s' : t) : t := Mkt (M.union s s').Definition inter (s s' : t) : t := Mkt (M.inter s s').Definition diff (s s' : t) : t := Mkt (M.diff s s').Definition equal (s s' : t) := M.equal s s'.Definition subset (s s' : t) := M.subset s s'.Definition empty : t := Mkt M.empty.Definition is_empty (s : t) := M.is_empty s.Definition elements (s : t) : list elt := M.elements s.Definition choose (s : t) : option elt := M.choose s.Definition fold (A : Type)(f : elt -> A -> A)(s : t) : A -> A := M.fold f s.Definition cardinal (s : t) := M.cardinal s.Definition filter (f : elt -> bool)(s : t) : t := Mkt (M.filter f s).Definition for_all (f : elt -> bool)(s : t) := M.for_all f s.Definition exists_ (f : elt -> bool)(s : t) := M.exists_ f s.Definition partition (f : elt -> bool)(s : t) : t * t :=
   let p := M.partition f s in (Mkt (fst p), Mkt (snd p)).#[global]
 Instance In_compat : Proper (E.eq==>eq==>iff) In.Definition eq : t -> t -> Prop := Equal.#[global]
 Instance eq_equiv : Equivalence eq.Definition eq_dec : forall (s s':t), { eq s s' }+{ ~eq s s' }.Notation compatb := (Proper (E.eq==>Logic.eq)) (only parsing).

(* Specifications: *)
Lemma mem_spec : mem x s = true <-> In x s.
Lemma equal_spec : equal s s' = true <-> Equal s s'.
Lemma subset_spec : subset s s' = true <-> Subset s s'.
Lemma empty_spec : Empty empty.
Lemma is_empty_spec : is_empty s = true <-> Empty s.
Lemma add_spec : In y (add x s) <-> E.eq y x \/ In y s.
Lemma remove_spec : In y (remove x s) <-> In y s /\ ~E.eq y x.
Lemma singleton_spec : In y (singleton x) <-> E.eq y x.
Lemma union_spec : In x (union s s') <-> In x s \/ In x s'.
Lemma inter_spec : In x (inter s s') <-> In x s /\ In x s'.
Lemma diff_spec : In x (diff s s') <-> In x s /\ ~In x s'.
Lemma fold_spec : forall (A : Type) (i : A) (f : elt -> A -> A), fold f s i = fold_left (fun a e => f e a) (elements s) i.
Lemma cardinal_spec : cardinal s = length (elements s).
Lemma filter_spec : compatb f -> (In x (filter f s) <-> In x s /\ f x = true).
Lemma for_all_spec : compatb f -> (for_all f s = true <-> For_all (fun x => f x = true) s).
Lemma exists_spec : compatb f -> (exists_ f s = true <-> Exists (fun x => f x = true) s).
Lemma partition_spec1 : compatb f -> Equal (fst (partition f s)) (filter f s).
Lemma partition_spec2 : compatb f -> Equal (snd (partition f s)) (filter (fun x => negb (f x)) s).
Lemma elements_spec1 : InA E.eq x (elements s) <-> In x s.
Lemma elements_spec2w : NoDupA E.eq (elements s).
Lemma choose_spec1 : choose s = Some x -> In x s.
Lemma choose_spec2 : choose s = None -> Empty s.