Section ForNotations.
Definition inf x l :=
match l with
| nil => true
| y::_ => match X.compare x y with Lt => true | _ => false end
end.
Fixpoint isok l :=
match l with
| nil => true
| x::l => inf x l && isok l
end.
Notation Sort l := (isok l = true).
Notation Inf := (lelistA X.lt).
Notation In := (InA X.eq).
Existing Instance X.eq_equiv.
Hint Extern 20 => solve [order] : core.
Definition IsOk s := Sort s.
Class Ok (s:t) : Prop := ok : Sort s.
Hint Resolve ok : core.
Hint Unfold Ok : core.
Instance Sort_Ok s `(Hs : Sort s) : Ok s := { ok := Hs }.
Hint Extern 1 (Ok _) => rewrite <- isok_iff : core.
Ltac inv_ok := match goal with
| H:sort X.lt (_ :: _) |- _ => inversion_clear H; inv_ok
| H:sort X.lt nil |- _ => clear H; inv_ok
| H:sort X.lt ?l |- _ => change (Ok l) in H; inv_ok
| H:Ok _ |- _ => rewrite <- isok_iff in H; inv_ok
| |- Ok _ => rewrite <- isok_iff
| _ => idtac
end.
Ltac inv := invlist InA; inv_ok; invlist lelistA.
Ltac constructors := repeat constructor.
Ltac sort_inf_in := match goal with
| H:Inf ?x ?l, H':In ?y ?l |- _ =>
cut (X.lt x y); [ intro | apply Sort_Inf_In with l; auto]
| _ => fail
end.
Global Instance isok_Ok s `(isok s = true) : Ok s | 10.
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 : t) := exists x, In x s /\ P x.
Hint Resolve add_inf : core.
Global Instance add_ok s x : forall `(Ok s), Ok (add x s).
Hint Resolve remove_inf : core.
Global Instance remove_ok s x : forall `(Ok s), Ok (remove x s).
Global Instance singleton_ok x : Ok (singleton x).
Ltac induction2 :=
simple induction s;
[ simpl; auto; try solve [ intros; inv ]
| intros x l Hrec; simple induction s';
[ simpl; auto; try solve [ intros; inv ]
| intros x' l' Hrec'; simpl; elim_compare x x'; intros; inv; auto ]].
Hint Resolve union_inf : core.
Global Instance union_ok s s' : forall `(Ok s, Ok s'), Ok (union s s').
Hint Resolve inter_inf : core.
Global Instance inter_ok s s' : forall `(Ok s, Ok s'), Ok (inter s s').
Hint Resolve diff_inf : core.
Global Instance diff_ok s s' : forall `(Ok s, Ok s'), Ok (diff s s').
Global Instance empty_ok : Ok empty.
Definition choose_spec1 :
forall (s : t) (x : elt), choose s = Some x -> In x s := min_elt_spec1.
Definition choose_spec2 :
forall s : t, choose s = None -> Empty s := min_elt_spec3.

Lemma fold_spec :
forall (s : t) (A : Type) (i : A) (f : elt -> A -> A),
fold f s i = fold_left (flip f) (elements s) i.