Section ForNotations.
Notation NoDup := (NoDupA X.eq).
Notation In := (InA X.eq).
(* TODO: modify proofs in order to avoid these hints *)
Let eqr:= (@Equivalence_Reflexive _ _ X.eq_equiv).
Let eqsym:= (@Equivalence_Symmetric _ _ X.eq_equiv).
Let eqtrans:= (@Equivalence_Transitive _ _ X.eq_equiv).
Hint Resolve eqr eqtrans : core.
Hint Immediate eqsym : core.
Definition IsOk := NoDup.
Class Ok (s:t) : Prop := ok : NoDup s.
Hint Unfold Ok : core.
Hint Resolve ok : core.
Instance NoDup_Ok s (nd : NoDup s) : Ok s := { ok := nd }.
Ltac inv_ok := match goal with
| H:Ok (_ :: _) |- _ => inversion_clear H; inv_ok
| H:Ok nil |- _ => clear H; inv_ok
| H:NoDup ?l |- _ => change (Ok l) in H; inv_ok
| _ => idtac
end.
Ltac inv := invlist InA; inv_ok.
Ltac constructors := repeat constructor.
Fixpoint isok l := match l with
| nil => true
| a::l => negb (mem a l) && isok l
end.
Definition Equal s s' := forall a : elt, In a s <-> In a s'.
Definition Subset s s' := forall a : elt, In a s -> In a s'.
Definition Empty s := forall a : elt, ~ In a s.
Definition For_all (P : elt -> Prop) s := forall x, In x s -> P x.
Definition Exists (P : elt -> Prop) s := exists x, In x s /\ P x.
Global Instance isok_Ok l : isok l = true -> Ok l | 10.
Global Instance add_ok s x `(Ok s) : Ok (add x s).
Global Instance remove_ok s x `(Ok s) : Ok (remove x s).
Global Instance union_ok : forall s s' `(Ok s, Ok s'), Ok (union s s').
Global Instance inter_ok s s' `(Ok s, Ok s') : Ok (inter s s').
Global Instance diff_ok : forall s s' `(Ok s, Ok s'), Ok (diff s s').
Definition choose_spec1 :
forall (s : t) (x : elt), choose s = Some x -> In x s.
Definition choose_spec2 : forall s : t, choose s = None -> Empty s.

Lemma filter_spec :
forall (s : t) (x : elt) (f : elt -> bool),
Proper (X.eq==>eq) f ->
(In x (filter f s) <-> In x s /\ f x = true).