aboutsummaryrefslogtreecommitdiffhomepage
path: root/theories/FSets/FSetList.v
diff options
context:
space:
mode:
authorGravatar filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7>2003-06-13 12:12:08 +0000
committerGravatar filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7>2003-06-13 12:12:08 +0000
commitf314c2a91775739f581ab8bacbeb58f57e2d4871 (patch)
tree8aaf92ed9e400d27cb4d37abca015eb4cf062e4a /theories/FSets/FSetList.v
parentfb7e6748d9b02fff8da1335dc3f4dedeb23a8f5d (diff)
FSets, mais pas compile' par make world
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@4150 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'theories/FSets/FSetList.v')
-rw-r--r--theories/FSets/FSetList.v1218
1 files changed, 1218 insertions, 0 deletions
diff --git a/theories/FSets/FSetList.v b/theories/FSets/FSetList.v
new file mode 100644
index 000000000..0c8e8287b
--- /dev/null
+++ b/theories/FSets/FSetList.v
@@ -0,0 +1,1218 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(** This file propose an implementation of the AbstractSet non-dependant
+ interface by strictly ordered list. *)
+
+Require Export FSetInterface.
+
+Set Implicit Arguments.
+
+(* Usual syntax for lists.
+ CAVEAT: the Coq cast "::" will no longer be available. *)
+Notation "[]" := (nil ?) (at level 1).
+Notation "a :: l" := (cons a l) (at level 1, l at next level).
+
+(** In a first time, we provide sets as lists which are not necessarily sorted.
+ The specs are proved under the additional condition of being sorted.
+ And the functions outputting sets are proved to preserve this invariant. *)
+
+Module Raw [X : OrderedType].
+
+ Module E := X.
+ Module ME := MoreOrderedType X.
+
+ Definition elt := E.t.
+ Definition t := (list elt).
+
+ Definition empty : t := [].
+
+ Definition is_empty : t -> bool := [l]if l then true else [_,_]false.
+
+ (** The set operations. *)
+
+ Fixpoint mem [x:elt; s:t] : bool := Cases s of
+ nil => false
+ | (cons y l) => Cases (E.compare x y) of
+ (Lt _) => false
+ | (Eq _) => true
+ | (Gt _) => (mem x l)
+ end
+ end.
+
+ Fixpoint add [x:elt; s:t] : t := Cases s of
+ nil => x::[]
+ | (cons y l) => Cases (E.compare x y) of
+ (Lt _) => x::s
+ | (Eq _) => s
+ | (Gt _) => y::(add x l)
+ end
+ end.
+
+ Definition singleton : elt -> t := [x] x::[].
+
+ Fixpoint remove [x:elt; s:t] : t := Cases s of
+ nil => []
+ | (cons y l) => Cases (E.compare x y) of
+ (Lt _) => s
+ | (Eq _) => l
+ | (Gt _) => y::(remove x l)
+ end
+ end.
+
+ Fixpoint union [s:t] : t -> t := Cases s of
+ nil => [s']s'
+ | (cons x l) =>
+ Fix union_aux { union_aux / 1 : t -> t := [s']Cases s' of
+ nil => s
+ | (cons x' l') => Cases (E.compare x x') of
+ (Lt _ ) => x::(union l s')
+ | (Eq _ ) => x::(union l l')
+ | (Gt _) => x'::(union_aux l')
+ end
+ end}
+ end.
+
+ Fixpoint inter [s:t] : t -> t := Cases s of
+ nil => [_] []
+ | (cons x l) =>
+ Fix inter_aux { inter_aux / 1 : t -> t := [s']Cases s' of
+ nil => []
+ | (cons x' l') => Cases (E.compare x x') of
+ (Lt _ ) => (inter l s')
+ | (Eq _ ) => x::(inter l l')
+ | (Gt _) => (inter_aux l')
+ end
+ end}
+ end.
+
+ Fixpoint diff [s:t] : t -> t := Cases s of
+ nil => [_] []
+ | (cons x l) =>
+ Fix diff_aux { diff_aux / 1 : t -> t := [s']Cases s' of
+ nil => s
+ | (cons x' l') => Cases (E.compare x x') of
+ (Lt _ ) => x::(diff l s')
+ | (Eq _ ) => (diff l l')
+ | (Gt _) => (diff_aux l')
+ end
+ end}
+ end.
+
+ Fixpoint equal [s:t] : t -> bool := [s':t]Cases s s' of
+ nil nil => true
+ | (cons x l) (cons x' l') => Cases (E.compare x x') of
+ (Eq _) => (equal l l')
+ | _ => false
+ end
+ | _ _ => false
+ end.
+
+ Fixpoint subset [s,s':t] : bool := Cases s s' of
+ nil _ => true
+ | (cons x l) (cons x' l') => Cases (E.compare x x') of
+ (Lt _) => false
+ | (Eq _) => (subset l l')
+ | (Gt _) => (subset s l')
+ end
+ | _ _ => false
+ end.
+
+ Fixpoint fold [B:Set; f:elt->B->B; s:t] : B -> B := [i]Cases s of
+ nil => i
+ | (cons x l) => (f x (fold f l i))
+ end.
+
+ Fixpoint filter [f:elt->bool; s:t] : t := Cases s of
+ nil => []
+ | (cons x l) => if (f x) then x::(filter f l) else (filter f l)
+ end.
+
+ Fixpoint for_all [f:elt->bool; s:t] : bool := Cases s of
+ nil => true
+ | (cons x l) => if (f x) then (for_all f l) else false
+ end.
+
+ Fixpoint exists [f:elt->bool; s:t] : bool := Cases s of
+ nil => false
+ | (cons x l) => if (f x) then true else (exists f l)
+ end.
+
+ Fixpoint partition [f:elt->bool; s:t] : t*t := Cases s of
+ nil => ([],[])
+ | (cons x l) => let (s1,s2) = (partition f l) in
+ if (f x) then (x::s1,s2) else (s1,x::s2)
+ end.
+
+ Definition cardinal : t -> nat := [s](fold [_]S s O).
+
+ Definition elements : t -> (list elt) := [x]x.
+
+ Definition min_elt : t -> (option elt) := [s]Cases s of
+ nil => (None ?)
+ | (cons x _) => (Some ? x)
+ end.
+
+ Fixpoint max_elt [s:t] : (option elt) := Cases s of
+ nil => (None ?)
+ | (cons x nil) => (Some ? x)
+ | (cons _ l) => (max_elt l)
+ end.
+
+ Definition choose := min_elt.
+
+ (** Proofs of set operation specifications. *)
+
+ Definition In : elt -> t -> Prop := (InList E.eq).
+ Notation "'Sort' l" := (sort E.lt l) (at level 10, l at level 8).
+ Notation "'Inf' x l" := (lelistA E.lt x l) (at level 10, x,l at level 8).
+ Notation "'In' x l" := (InList E.eq x l) (at level 10, x,l at level 8).
+
+ Definition Equal := [s,s'](a:elt)(In a s)<->(In a s').
+ Definition Subset := [s,s'](a:elt)(In a s)->(In a s').
+ Definition Add := [x:elt;s,s':t](y:elt)(In y s') <-> ((E.eq y x)\/(In y s)).
+ Definition Empty := [s](a:elt)~(In a s).
+ Definition For_all := [P:elt->Prop; s:t](x:elt)(In x s)->(P x).
+ Definition Exists := [P:elt->Prop; s:t](EX x:elt | (In x s)/\(P x)).
+
+ Definition In_eq: (s:t)(x,y:elt)(E.eq x y) -> (In x s) -> (In y s) := ME.In_eq.
+ Definition Inf_lt : (s:t)(x,y:elt)(E.lt x y) -> (Inf y s) -> (Inf x s) := ME.Inf_lt.
+ Definition Inf_eq : (s:t)(x,y:elt)(E.eq x y) -> (Inf y s) -> (Inf x s) := ME.Inf_eq.
+ Definition In_sort : (s:t)(x,a:elt)(Inf a s) -> (In x s) -> (Sort s) -> (E.lt a x) := ME.In_sort.
+ Hints Resolve Inf_lt Inf_eq.
+ Hints Immediate In_eq.
+
+ Lemma mem_1: (s:t)(Hs:(Sort s))(x:elt)(In x s) -> (mem x s)=true.
+ Proof.
+ Induction s; Intros.
+ Inversion H.
+ Inversion_clear Hs.
+ Inversion_clear H0.
+ Simpl; Replace E.compare with X.compare; Auto.
+ Elim (!ME.elim_compare_eq x a); [Intros A B; Rewrite B; Auto | Auto].
+ Simpl; Replace E.compare with X.compare; Auto.
+ Elim (!ME.elim_compare_gt x a); [Intros A B; Rewrite B; Auto | Auto].
+ EApply In_sort; EAuto.
+ Qed.
+
+ Lemma mem_2: (s:t)(x:elt)(mem x s)=true -> (In x s).
+ Proof.
+ Induction s.
+ Intros; Inversion H.
+ Intros a l Hrec x.
+ Simpl; Elim (E.compare x a); Ground.
+ Inversion H.
+ Qed.
+
+ Lemma add_Inf : (s:t)(x,a:elt)(Inf a s)->(E.lt a x)->(Inf a (add x s)).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros; Case (E.compare x a); Intuition; Inversion H0; Intuition.
+ Qed.
+ Hints Resolve add_Inf.
+
+ Lemma add_sort : (s:t)(Hs:(Sort s))(x:elt)(Sort (add x s)).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros; Case (E.compare x a); Intuition; Inversion_clear Hs; Auto.
+ Qed.
+
+ Lemma add_1 : (s:t)(Hs:(Sort s))(x:elt)(In x (add x s)).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros; Case (E.compare x a); Intuition; Inversion_clear Hs; Ground.
+ Qed.
+
+ Lemma add_2 : (s:t)(Hs:(Sort s))(x,y:elt)(In y s) -> (In y (add x s)).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros; Case (E.compare x a); Intuition.
+ Inversion_clear Hs; Inversion_clear H0; EAuto.
+ Qed.
+
+ Lemma add_3 : (s:t)(Hs:(Sort s))(x,y:elt)
+ ~(E.eq x y) -> (In y (add x s)) -> (In y s).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Inversion_clear H0; Ground; Absurd (E.eq x y); Auto.
+ Simpl; Intros a l Hrec Hs x y; Case (E.compare x a); Intros;
+ Inversion_clear H0; Inversion_clear Hs; Ground; Absurd (E.eq x y); Auto.
+ Qed.
+
+ Lemma remove_Inf : (s:t)(Hs:(Sort s))(x,a:elt)(Inf a s)->
+ (Inf a (remove x s)).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros; Case (E.compare x a); Intuition; Inversion_clear H0; Ground.
+ Inversion_clear Hs; Ground; EAuto.
+ Qed.
+ Hints Resolve remove_Inf.
+
+ Lemma remove_sort : (s:t)(Hs:(Sort s))(x:elt)(Sort (remove x s)).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros; Case (E.compare x a); Intuition; Inversion_clear Hs; Auto.
+ Qed.
+
+ Lemma remove_1 : (s:t)(Hs:(Sort s))(x:elt)~(In x (remove x s)).
+ Proof.
+ Induction s.
+ Simpl; Red; Intros; Inversion H.
+ Simpl; Intros; Case (E.compare x a); Intuition; Inversion_clear Hs.
+ Inversion_clear H0.
+ Absurd (E.eq x a); Auto.
+ Absurd (E.lt a x); Auto; EApply In_sort; EAuto.
+ Absurd (E.lt a x); Auto; EApply In_sort; EAuto.
+ Inversion_clear H0; Ground.
+ Absurd (E.eq x a); Auto.
+ Qed.
+
+ Lemma remove_2 : (s:t)(Hs:(Sort s))(x,y:elt)
+ ~(E.eq x y) -> (In y s) -> (In y (remove x s)).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros; Case (E.compare x a); Intuition;
+ Inversion_clear Hs; Inversion_clear H1; Auto.
+ Absurd (E.eq x y); EAuto.
+ Qed.
+
+ Lemma remove_3 : (s:t)(Hs:(Sort s))(x,y:elt)(In y (remove x s)) -> (In y s).
+ Proof.
+ Induction s.
+ Simpl; Intuition.
+ Simpl; Intros a l Hrec Hs x y; Case (E.compare x a); Intuition.
+ Inversion_clear Hs; Inversion_clear H; Ground.
+ Qed.
+
+ Lemma singleton_sort : (x:elt)(Sort (singleton x)).
+ Proof.
+ Unfold singleton; Simpl; Ground.
+ Qed.
+
+ Lemma singleton_1 : (x,y:elt)(In y (singleton x)) -> (E.eq x y).
+ Proof.
+ Unfold singleton; Simpl; Intuition.
+ Inversion_clear H; Auto; Inversion H0.
+ Qed.
+
+ Lemma singleton_2 : (x,y:elt)(E.eq x y) -> (In y (singleton x)).
+ Proof.
+ Unfold singleton; Simpl; Intuition.
+ Qed.
+
+ Tactic Definition DoubleInd :=
+ Induction s;
+ [Simpl; Auto; Try Solve [ Intros; Inversion H ] |
+ Intros x l Hrec;
+ Induction s';
+ [Simpl; Auto; Try Solve [ Intros; Inversion H ] |
+ Intros x' l' Hrec' Hs Hs'; Inversion Hs; Inversion Hs'; Subst; Simpl]].
+
+ Lemma union_Inf : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(a:elt)
+ (Inf a s) -> (Inf a s') -> (Inf a (union s s')).
+ Proof.
+ DoubleInd.
+ Intros i His His'; Inversion_clear His; Inversion_clear His'.
+ Case (E.compare x x'); Ground.
+ Qed.
+ Hints Resolve union_Inf.
+
+ Lemma union_sort : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(Sort (union s s')).
+ Proof.
+ DoubleInd; Case (E.compare x x'); Intuition; Constructor; Auto.
+ EAuto.
+ Change (Inf x' (union x::l l')); Ground.
+ Qed.
+
+ Lemma union_1 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x (union s s')) -> (In x s)\/(In x s').
+ Proof.
+ DoubleInd; Case (E.compare x x'); Intuition; Inversion_clear H; Intuition.
+ Elim (Hrec (x'::l') H1 Hs' x0); Intuition.
+ Elim (Hrec l' H1 H5 x0); Intuition.
+ Elim (H0 x0); Intuition.
+ Qed.
+
+ Lemma union_2 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x s) -> (In x (union s s')).
+ Proof.
+ DoubleInd.
+ Intros i Hi; Case (E.compare x x'); Intuition; Inversion_clear Hi; Auto.
+ Qed.
+
+ Lemma union_3 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x s') -> (In x (union s s')).
+ Proof.
+ DoubleInd.
+ Intros i Hi; Case (E.compare x x'); Inversion_clear Hi; Intuition; EAuto.
+ Qed.
+
+ Lemma inter_Inf : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(a:elt)
+ (Inf a s) -> (Inf a s') -> (Inf a (inter s s')).
+ Proof.
+ DoubleInd.
+ Intros i His His'; Inversion His; Inversion His'; Subst.
+ Case (E.compare x x'); Intuition; EAuto.
+ Qed.
+ Hints Resolve inter_Inf.
+
+ Lemma inter_sort : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(Sort (inter s s')).
+ Proof.
+ DoubleInd; Case (E.compare x x'); EAuto.
+ Qed.
+
+ Lemma inter_1 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x (inter s s')) -> (In x s).
+ Proof.
+ DoubleInd; Case (E.compare x x'); Intuition.
+ EAuto.
+ Inversion_clear H; EAuto.
+ Qed.
+
+ Lemma inter_2 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x (inter s s')) -> (In x s').
+ Proof.
+ DoubleInd; Case (E.compare x x'); Intuition; Inversion_clear H; EAuto.
+ Qed.
+
+ Lemma inter_3 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x s) -> (In x s') -> (In x (inter s s')).
+ Proof.
+ DoubleInd.
+ Intros i His His'; Elim (E.compare x x'); Intuition.
+
+ Inversion_clear His.
+ Absurd (E.lt i x); EAuto.
+ Apply In_sort with (x'::l'); Auto.
+ Constructor; EApply ME.eq_lt; EAuto.
+ EApply In_eq; EAuto.
+ EApply In_eq; EAuto.
+
+ Inversion_clear His; [ EAuto | Inversion_clear His' ]; EAuto.
+
+ Change (In i (inter x::l l')).
+ Inversion_clear His'.
+ Absurd (E.lt i x'); EAuto.
+ Apply In_sort with (x::l); Auto.
+ Constructor; EApply ME.eq_lt; EAuto.
+ EApply In_eq; EAuto.
+ EApply In_eq; EAuto.
+ Qed.
+
+ Lemma diff_Inf : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(a:elt)
+ (Inf a s) -> (Inf a s') -> (Inf a (diff s s')).
+ Proof.
+ DoubleInd.
+ Intros i His His'; Inversion His; Inversion His'.
+ Case (E.compare x x'); Intuition;EAuto.
+ Qed.
+ Hints Resolve diff_Inf.
+
+ Lemma diff_sort : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(Sort (diff s s')).
+ Proof.
+ DoubleInd; Case (E.compare x x'); EAuto.
+ Qed.
+
+ Lemma diff_1 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x (diff s s')) -> (In x s).
+ Proof.
+ DoubleInd; Case (E.compare x x'); Intuition.
+ Inversion_clear H; EAuto.
+ EAuto.
+ Qed.
+
+ Lemma diff_2 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x (diff s s')) -> ~(In x s').
+ Proof.
+ DoubleInd.
+ Intros; Intro Abs; Inversion Abs.
+ Case (E.compare x x'); Intuition.
+
+ Inversion_clear H.
+ Absurd (E.lt x x); EAuto.
+ Apply In_sort with (x'::l'); Auto.
+ EApply In_eq; EAuto.
+ EAuto.
+
+ Inversion_clear H3.
+ Generalize (diff_1 H1 H5 H); Intros.
+ Absurd (E.lt x x0); EAuto.
+ Apply In_sort with l; EAuto.
+ EAuto.
+
+ Inversion_clear H3.
+ Generalize (diff_1 Hs H5 H); Intros.
+ Absurd (E.lt x' x'); EAuto.
+ Apply In_sort with (x::l); Auto.
+ EApply In_eq; EAuto.
+ EAuto.
+ Qed.
+
+ Lemma diff_3 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ (In x s) -> ~(In x s') -> (In x (diff s s')).
+ Proof.
+ DoubleInd.
+ Intros i His His'; Elim (E.compare x x'); Intuition; Inversion_clear His.
+ EAuto.
+ EAuto.
+ Elim His'; EAuto.
+ EAuto.
+ Qed.
+
+ Lemma equal_1: (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))
+ (Equal s s') -> (equal s s')=true.
+ Proof.
+ Induction s; Unfold Equal.
+ Intro s'; Case s'; Auto.
+ Simpl; Intuition.
+ Elim (H e); Intros; Assert A : (In e []); Auto; Inversion A.
+ Intros x l Hrec s'.
+ Case s'.
+ Intros; Elim (H x); Intros; Assert A : (In x []); Auto; Inversion A.
+ Intros x' l' Hs Hs'; Inversion Hs; Inversion Hs'; Subst.
+ Simpl; Case (E.compare x); Intros; Auto.
+
+ Elim (H x); Intros.
+ Assert A : (In x x'::l'); Auto; Inversion_clear A.
+ Absurd (E.eq x x'); EAuto.
+ Absurd (E.lt x' x); Auto.
+ Apply In_sort with l';EAuto.
+
+ Apply Hrec; Intuition; Elim (H a); Intros.
+ Assert A : (In a x'::l'); Auto; Inversion_clear A; Auto.
+ Absurd (E.lt x' x); Auto.
+ Apply In_sort with l;Auto;
+ [ Apply Inf_eq with x;Auto | Apply In_eq with a; EAuto ].
+ Assert A : (In a x::l); Auto; Inversion_clear A; Auto.
+ Absurd (E.lt x x'); Auto.
+ Apply In_sort with l';Auto;
+ [ Apply Inf_eq with x';Auto | Apply In_eq with a; EAuto ].
+
+ Elim (H x'); Intros.
+ Assert A : (In x' x::l); Auto; Inversion_clear A.
+ Absurd (E.eq x' x); EAuto.
+ Absurd (E.lt x x'); Auto.
+ Apply In_sort with l;EAuto.
+ Qed.
+
+ Lemma equal_2: (s,s':t)(equal s s')=true -> (Equal s s').
+ Proof.
+ Induction s; Unfold Equal.
+ Intro s'; Case s'; Intros.
+ Intuition.
+ Simpl in H; Discriminate H.
+ Intros x l Hrec s'.
+ Case s'.
+ Intros; Simpl in H; Discriminate H.
+ Intros x' l'; Simpl; Case (E.compare x); Intros; Auto.
+ Discriminate H.
+ Elim (Hrec l' H a); Intuition; Inversion_clear H2; EAuto.
+ Discriminate H.
+ Qed.
+
+ Lemma subset_1: (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))
+ (Subset s s') -> (subset s s')=true.
+ Proof.
+ Intros s s'; Generalize s' s; Clear s s'.
+ Induction s'; Unfold Subset.
+ Intro s; Case s; Auto.
+ Intros; Elim (H e); Intros; Assert A : (In e []); Auto; Inversion A.
+ Intros x' l' Hrec s; Case s.
+ Simpl; Auto.
+ Intros x l Hs Hs'; Inversion Hs; Inversion Hs'; Subst.
+ Simpl; Case (E.compare x); Intros; Auto.
+
+ Assert A : (In x x'::l'); Auto; Inversion_clear A.
+ Absurd (E.eq x x'); EAuto.
+ Absurd (E.lt x' x); Auto.
+ Apply In_sort with l';EAuto.
+
+ Apply Hrec; Intuition.
+ Assert A : (In a x'::l'); Auto; Inversion_clear A; Auto.
+ Absurd (E.lt x' x); Auto.
+ Apply In_sort with l;Auto; [ Apply Inf_eq with x;Auto | Apply In_eq with a; EAuto ].
+
+ Apply Hrec; Intuition.
+ Assert A : (In a x'::l'); Auto; Inversion_clear A; Auto.
+ Inversion_clear H0.
+ Absurd (E.lt x' x); EAuto.
+ Absurd (E.lt x x'); Auto.
+ Apply In_sort with l;EAuto.
+ Qed.
+
+ Lemma subset_2: (s,s':t)(subset s s')=true -> (Subset s s').
+ Proof.
+ Intros s s'; Generalize s' s; Clear s s'.
+ Induction s'; Unfold Subset.
+ Intro s; Case s; Auto.
+ Simpl; Intros; Discriminate H.
+ Intros x' l' Hrec s; Case s.
+ Intros; Inversion H0.
+ Intros x l; Simpl; Case (E.compare x); Intros; Auto.
+ Discriminate H.
+ Inversion_clear H0; EAuto.
+ EAuto.
+ Qed.
+
+ Lemma empty_sort : (Sort empty).
+ Proof.
+ Unfold empty; Constructor.
+ Qed.
+
+ Lemma empty_1 : (Empty empty).
+ Proof.
+ Unfold Empty empty; Intuition; Inversion H.
+ Qed.
+
+ Lemma is_empty_1 : (s:t)(Empty s) -> (is_empty s)=true.
+ Proof.
+ Unfold Empty; Intro s; Case s; Simpl; Intuition.
+ Elim (H e); Auto.
+ Qed.
+
+ Lemma is_empty_2 : (s:t)(is_empty s)=true -> (Empty s).
+ Proof.
+ Unfold Empty; Intro s; Case s; Simpl; Intuition; Inversion H0.
+ Qed.
+
+ Lemma elements_1: (s:t)(x:elt)(In x s) -> (InList E.eq x (elements s)).
+ Proof.
+ Unfold elements; Auto.
+ Qed.
+
+ Lemma elements_2: (s:t)(x:elt)(InList E.eq x (elements s)) -> (In x s).
+ Proof.
+ Unfold elements; Auto.
+ Qed.
+
+ Lemma elements_3: (s:t)(Hs:(Sort s))(sort E.lt (elements s)).
+ Proof.
+ Unfold elements; Auto.
+ Qed.
+
+ Lemma min_elt_1: (s:t)(x:elt)(min_elt s) = (Some ? x) -> (In x s).
+ Proof.
+ Intro s; Case s; Simpl; Intros; Inversion H; Auto.
+ Qed.
+
+ Lemma min_elt_2: (s:t)(Hs:(Sort s))(x,y:elt)
+ (min_elt s) = (Some ? x) -> (In y s) -> ~(E.lt y x).
+ Proof.
+ Induction s; Simpl.
+ Intros; Inversion H.
+ Intros a l; Case l; Intros; Inversion H0; Inversion_clear H1; Subst.
+ EAuto.
+ Inversion H2.
+ EAuto.
+ Inversion_clear Hs.
+ Inversion_clear H3.
+ Intro; Absurd (E.lt y e); EAuto.
+ Qed.
+
+ Lemma min_elt_3: (s:t)(min_elt s) = (None ?) -> (Empty s).
+ Proof.
+ Unfold Empty; Intro s; Case s; Simpl; Intuition; Inversion H; Inversion H0.
+ Qed.
+
+ Lemma max_elt_1: (s:t)(x:elt)(max_elt s) = (Some ? x) -> (In x s).
+ Proof.
+ Induction s; Simpl.
+ Intros; Inversion H.
+ Intros x l; Case l; Simpl.
+ Intuition.
+ Inversion H0; Auto.
+ EAuto.
+ Qed.
+
+ Lemma max_elt_2: (s:t)(Hs:(Sort s))(x,y:elt)
+ (max_elt s) = (Some ? x) -> (In y s) -> ~(E.lt x y).
+ Proof.
+ Induction s; Simpl.
+ Intros; Inversion H.
+ Intros x l; Case l; Simpl.
+ Intuition.
+ Inversion H0; Subst.
+ Inversion_clear H1.
+ Absurd (E.eq y x0); Auto.
+ Inversion H3.
+ Intros; Inversion_clear Hs; Inversion_clear H3; Inversion_clear H1.
+ Assert ~(E.lt x0 e).
+ EApply H; EAuto.
+ Intro.
+ Elim H1; Apply E.lt_trans with x; Auto; EApply ME.lt_eq; EAuto.
+ EApply H;EAuto.
+ Qed.
+
+ Lemma max_elt_3: (s:t)(max_elt s) = (None ?) -> (Empty s).
+ Proof.
+ Unfold Empty; Induction s; Simpl.
+ Red; Intros; Inversion H0.
+ Intros x l; Case l; Simpl; Intros.
+ Inversion H0.
+ Elim (H H0 e); Auto.
+ Qed.
+
+ Definition choose_1:
+ (s:t)(x:elt)(choose s)=(Some ? x) -> (In x s)
+ := min_elt_1.
+
+ Definition choose_2: (s:t)(choose s)=(None ?) -> (Empty s)
+ := min_elt_3.
+
+ Lemma fold_1 : (s:t)(A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory A eqA))(i:A)(f:elt->A->A)
+ (Empty s) -> (eqA (fold f s i) i).
+ Proof.
+ Unfold Empty; Intro s; Case s; Intros; Simpl; Intuition; Elim (H e); Auto.
+ Qed.
+
+ Lemma fold_equal :
+ (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory A eqA))
+ (i:A)(f:elt->A->A)(compat_op E.eq eqA f) -> (transpose eqA f) -> (Equal s s') ->
+ (eqA (fold f s i) (fold f s' i)).
+ Proof.
+ Induction s; Unfold Equal; Simpl.
+
+ Intro s'; Case s'; Intuition.
+ Intros.
+ Elim (H1 e); Intuition.
+ Assert X : (In e []); Auto; Inversion X.
+
+ Intros x l Hrec s'; Case s'.
+ Intros.
+ Elim (H1 x); Intuition.
+ Assert X : (In x []); Auto; Inversion X.
+ Simpl; Intros x' l' Hs Hs' a; Intros.
+ Inversion_clear Hs; Inversion_clear Hs'.
+ Assert (E.eq x x').
+ Assert (In x x'::l').
+ Elim (H1 x); Auto.
+ Assert (In x' x::l).
+ Elim (H1 x'); Auto.
+ Inversion_clear H6; Auto.
+ Inversion_clear H7; Auto.
+ Absurd (E.lt x x').
+ Apply ME.lt_not_gt.
+ Apply In_sort with l'; EAuto.
+ Apply In_sort with l; EAuto.
+ Apply H; Auto.
+ Apply (Hrec l' H2 H4 a eqA); Auto.
+ (* To prove (Equal l l') *)
+ Intuition.
+ Elim (H1 a0); Intros.
+ Assert (In a0 x'::l'). Auto.
+ Inversion_clear H10; Auto.
+ Intros; Absurd (E.lt x x'); EAuto.
+ Apply In_sort with l; EAuto.
+ Elim (H1 a0); Intros.
+ Assert (In a0 x::l). Auto.
+ Inversion_clear H10; Auto.
+ Intros; Absurd (E.lt x' x); EAuto.
+ Apply In_sort with l'; EAuto.
+ Qed.
+
+ Lemma fold_2 :
+ (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)(A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory A 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))).
+ Proof.
+ Induction s; Unfold Add; Simpl.
+
+ Intro s'; Case s'.
+ Intros.
+ Elim (H2 x); Intuition.
+ Assert X : (In x []); Auto; Inversion X.
+ Simpl; Intros.
+ Inversion_clear Hs'.
+ Apply H; Auto.
+ Elim (H2 e);Intuition.
+ Elim H5; Auto.
+ Intros X; Inversion X.
+ Apply fold_1; Auto.
+ Unfold Empty; Intuition.
+ Assert (y:elt)(In y e::l) -> (E.eq y x).
+ Intros; Elim (H2 y); Intuition; Inversion H7.
+ Assert (E.eq a x); [Ground | Idtac].
+ Assert (E.eq e x); [Ground | Idtac].
+ Absurd (E.lt a e); EAuto.
+ Apply In_sort with l; EAuto. Apply In_eq with a; EAuto.
+
+ Intros x l Hrec s'; Case s'.
+ Intros.
+ Elim (H2 x0); Intuition.
+ Assert X : (In x0 []); Auto; Inversion X.
+ Simpl; Intros x' l' Hs Hs' a; Intros.
+ Inversion Hs; Inversion Hs'.
+ Assert (In a x'::l');[Ground|Idtac].
+ (* 2 cases: x'=a or x'<a *)
+ (* first, x'=a *)
+ Inversion_clear H11.
+ Apply H; Auto.
+ Change (eqA (fold f l' i) (fold f (x::l) i)).
+ Apply (!fold_equal l' (x::l) H9 Hs A eqA); Auto.
+ (* To prove that (Equal l' (x::l)) *)
+ Unfold Equal.
+ Intuition.
+ Elim (H2 a2); Intros.
+ Elim H13; Auto.
+ Intros.
+ Absurd (E.lt x' a2); EAuto; Apply In_sort with l'; EAuto.
+ Elim (H2 a2); Intros.
+ Assert (In a2 x'::l'); Auto.
+ Inversion_clear H15; Auto.
+ Elim H1; Apply In_eq with a2; EAuto.
+ (* second, x'<a *)
+ Assert (E.lt x' a).
+ Apply In_sort with l'; EAuto.
+ Assert ~(E.eq a x).
+ Intro; Elim H1; Auto.
+ Assert (E.eq x x').
+ Assert (In x x'::l').
+ Elim (H2 x); Auto.
+ Assert (In x' x::l).
+ Elim (H2 x'); Intuition.
+ Elim H15; Auto.
+ Intros; Absurd (E.eq x' a); EAuto.
+ Inversion_clear H14; Auto.
+ Inversion_clear H15; Auto.
+ Absurd (E.lt x x').
+ Apply ME.lt_not_gt.
+ Apply In_sort with l'; EAuto.
+ Apply In_sort with l; EAuto.
+ Apply (Seq_trans ? ? st) with (f x (f a (fold f l i))).
+ 2: Apply H0.
+ Apply H; Auto.
+ Apply (Hrec l' H5 H9 a A eqA); Clear Hrec; Auto.
+ (* To prove (Add a l l') *)
+ Intuition.
+ Elim (H2 y); Intros.
+ Elim H16; Auto; Intros.
+ Inversion_clear H18.
+ Absurd (E.lt x' y); EAuto; Apply In_sort with l'; EAuto.
+ Right; Auto.
+ Apply In_eq with a; Auto.
+ Elim (H2 y); Intuition.
+ Assert (In y x'::l'); Auto.
+ Inversion_clear H17; Auto.
+ Absurd (E.lt x y); EAuto; Apply In_sort with l; EAuto.
+ Qed.
+
+ Lemma cardinal_1 : (s:t)(Empty s) -> (cardinal s)=O.
+ Proof.
+ Unfold cardinal; Intros; Apply fold_1; Auto.
+ Intuition EAuto; Transitivity y; Auto.
+ Qed.
+
+ Lemma cardinal_2 : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(x:elt)
+ ~(In x s) -> (Add x s s') -> (cardinal s') = (S (cardinal s)).
+ Proof.
+ Unfold cardinal; Intros.
+ Assert (compat_op E.eq (eq ?) [_]S).
+ Unfold compat_op; Auto.
+ Assert (transpose (eq ?) [_:elt]S).
+ Unfold transpose; Auto.
+ Refine (!fold_2 s s' Hs Hs' x nat (eq ?) ? O [_]S H1 H2 H H0).
+ Intuition EAuto; Transitivity y; Auto.
+ Qed.
+
+ Lemma filter_Inf :
+ (s:t)(Hs:(Sort s))(x:elt)(f:elt->bool)(Inf x s) -> (Inf x (filter f s)).
+ Proof.
+ Induction s; Simpl.
+ Intuition.
+ Intros x l Hrec Hs a f Ha; Inversion_clear Hs; Inversion Ha.
+ Case (f x); [Constructor; Auto | EAuto].
+ Qed.
+
+ Lemma filter_sort : (s:t)(Hs:(Sort s))(f:elt->bool)(Sort (filter f s)).
+ Proof.
+ Induction s; Simpl.
+ Auto.
+ Intros x l Hrec Hs f; Inversion_clear Hs.
+ Case (f x); Auto.
+ Constructor; Auto.
+ Apply filter_Inf; Auto.
+ Qed.
+
+ Lemma filter_1: (s:t)(x:elt)(f:elt->bool)(compat_bool E.eq f) ->
+ (In x (filter f s)) -> (In x s).
+ Proof.
+ Induction s; Simpl.
+ Intros; Inversion H0.
+ Intros x l Hrec a f Hf.
+ Case (f x); Simpl; Ground.
+ Inversion H; Ground.
+ Qed.
+
+ Lemma filter_2:
+ (s:t)(x:elt)(f:elt->bool)(compat_bool E.eq f) ->(In x (filter f s)) ->
+ (f x)=true.
+ Proof.
+ Induction s; Simpl.
+ Intros; Inversion H0.
+ Intros x l Hrec a f Hf.
+ Generalize (Hf x); Case (f x); Simpl; Ground.
+ Inversion H0; Ground.
+ Symmetry; Ground.
+ Qed.
+
+ Lemma filter_3:
+ (s:t)(x:elt)(f:elt->bool)(compat_bool E.eq f) ->
+ (In x s) -> (f x)=true -> (In x (filter f s)).
+ Proof.
+ Induction s; Simpl.
+ Intros; Inversion H0.
+ Intros x l Hrec a f Hf.
+ Generalize (Hf x); Case (f x); Simpl; Ground; Inversion H0; Ground.
+ Rewrite <- (H a) in H1; Auto; Discriminate H1.
+ Qed.
+
+ Lemma for_all_1:
+ (s:t)(f:elt->bool)(compat_bool E.eq f) ->
+ (For_all [x](f x)=true s) -> (for_all f s)=true.
+ Proof.
+ Induction s; Simpl; Auto; Unfold For_all.
+ Intros x l Hrec f Hf.
+ Generalize (Hf x); Case (f x); Simpl; Ground.
+ Rewrite (H x); Auto.
+ Qed.
+
+ Lemma for_all_2:
+ (s:t)(f:elt->bool)(compat_bool E.eq f) -> (for_all f s)=true ->
+ (For_all [x](f x)=true s).
+ Proof.
+ Induction s; Simpl; Auto; Unfold For_all.
+ Intros; Inversion H1.
+ Intros x l Hrec f Hf.
+ Intros A a; Intros.
+ Assert (f x)=true.
+ Generalize A; Case (f x); Auto.
+ Rewrite H0 in A; Simpl in A.
+ Inversion H; Ground.
+ Rewrite (Hf a x); Auto.
+ Qed.
+
+ Lemma exists_1:
+ (s:t)(f:elt->bool)(compat_bool E.eq f) -> (Exists [x](f x)=true s) ->
+ (exists f s)=true.
+ Proof.
+ Induction s; Simpl; Auto; Unfold Exists.
+ Intros.
+ Elim H0; Intuition.
+ Inversion H2.
+ Intros x l Hrec f Hf.
+ Generalize (Hf x); Case (f x); Simpl; Ground.
+ Inversion_clear H0.
+ Absurd (false=true); Auto with bool.
+ Rewrite (H x); Auto.
+ Rewrite <- H1.
+ Ground.
+ Ground.
+ Qed.
+
+ Lemma exists_2:
+ (s:t)(f:elt->bool)(compat_bool E.eq f) -> (exists f s)=true ->
+ (Exists [x](f x)=true s).
+ Proof.
+ Induction s; Simpl; Auto; Unfold Exists.
+ Intros; Discriminate.
+ Intros x l Hrec f Hf.
+ Generalize (refl_equal ? (f x)); Pattern -1 (f x); Case (f x).
+ Intros; Exists x; Auto.
+ Intros; Elim (Hrec f); Auto; Ground.
+ Qed.
+
+ Lemma partition_Inf_1 :
+ (s:t)(Hs:(Sort s))(f:elt->bool)(x:elt)(Inf x s) ->
+ (Inf x (fst ? ? (partition f s))).
+ Proof.
+ Induction s; Simpl.
+ Intuition.
+ Intros x l Hrec Hs f a Ha; Inversion_clear Hs; Inversion Ha.
+ Generalize (Hrec H f a).
+ Case (f x); Case (partition f l); Simpl.
+ Intros; Constructor; Auto.
+ EAuto.
+ Qed.
+
+ Lemma partition_Inf_2 :
+ (s:t)(Hs:(Sort s))(f:elt->bool)(x:elt)(Inf x s) ->
+ (Inf x (snd ? ? (partition f s))).
+ Proof.
+ Induction s; Simpl.
+ Intuition.
+ Intros x l Hrec Hs f a Ha; Inversion_clear Hs; Inversion Ha.
+ Generalize (Hrec H f a).
+ Case (f x); Case (partition f l); Simpl.
+ EAuto.
+ Intros; Constructor; Auto.
+ Qed.
+
+ Lemma partition_sort_1 : (s:t)(Hs:(Sort s))(f:elt->bool)
+ (Sort (fst ? ? (partition f s))).
+ Proof.
+ Induction s; Simpl.
+ Auto.
+ Intros x l Hrec Hs f; Inversion_clear Hs.
+ Generalize (Hrec H f); Generalize (partition_Inf_1 H f).
+ Case (f x); Case (partition f l); Simpl; Auto.
+ Qed.
+
+ Lemma partition_sort_2 : (s:t)(Hs:(Sort s))(f:elt->bool)
+ (Sort (snd ? ? (partition f s))).
+ Proof.
+ Induction s; Simpl.
+ Auto.
+ Intros x l Hrec Hs f; Inversion_clear Hs.
+ Generalize (Hrec H f); Generalize (partition_Inf_2 H f).
+ Case (f x); Case (partition f l); Simpl; Auto.
+ Qed.
+
+ Lemma partition_1:
+ (s:t)(f:elt->bool)(compat_bool E.eq f) ->
+ (Equal (fst ? ? (partition f s)) (filter f s)).
+ Proof.
+ Induction s; Simpl; Auto; Unfold Equal.
+ Ground.
+ Intros x l Hrec f Hf.
+ Generalize (Hrec f Hf); Clear Hrec.
+ Case (partition f l); Intros s1 s2; Simpl; Intros.
+ Case (f x); Simpl; Ground; Inversion H0; Intros; Ground.
+ Qed.
+
+ Lemma partition_2:
+ (s:t)(f:elt->bool)(compat_bool E.eq f) ->
+ (Equal (snd ? ? (partition f s)) (filter [x](negb (f x)) s)).
+ Proof.
+ Induction s; Simpl; Auto; Unfold Equal.
+ Ground.
+ Intros x l Hrec f Hf.
+ Generalize (Hrec f Hf); Clear Hrec.
+ Case (partition f l); Intros s1 s2; Simpl; Intros.
+ Case (f x); Simpl; Ground; Inversion H0; Intros; Ground.
+ Qed.
+
+ Definition eq : t -> t -> Prop := Equal.
+
+ Lemma eq_refl: (s:t)(eq s s).
+ Proof.
+ Unfold eq Equal; Intuition.
+ Qed.
+
+ Lemma eq_sym: (s,s':t)(eq s s') -> (eq s' s).
+ Proof.
+ Unfold eq Equal; Ground.
+ Qed.
+
+ Lemma eq_trans: (s,s',s'':t)(eq s s') -> (eq s' s'') -> (eq s s'').
+ Proof.
+ Unfold eq Equal; Ground.
+ Qed.
+
+ Inductive lt : t -> t -> Prop :=
+ lt_nil : (x:elt)(s:t)(lt [] (x::s))
+ | lt_cons_lt : (x,y:elt)(s,s':t)(E.lt x y) -> (lt (x::s) (y::s'))
+ | lt_cons_eq : (x,y:elt)(s,s':t)(E.eq x y) -> (lt s s') -> (lt (x::s) (y::s')).
+ Hint lt := Constructors lt.
+
+ Lemma lt_trans : (s,s',s'':t)(lt s s') -> (lt s' s'') -> (lt s s'').
+ Proof.
+ Intros s s' s'' H; Generalize s''; Clear s''; Elim H.
+ Intros x l s'' H'; Inversion_clear H'; Auto.
+ Intros x x' l l' E s'' H'; Inversion_clear H'; Auto.
+ EAuto.
+ Constructor 2; Apply ME.lt_eq with x'; Auto.
+ Intros.
+ Inversion_clear H3.
+ Constructor 2; Apply ME.eq_lt with y; Auto.
+ Constructor 3; EAuto.
+ Qed.
+
+ Lemma lt_not_eq : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(lt s s') -> ~(eq s s').
+ Proof.
+ Unfold eq Equal.
+ Intros s s' Hs Hs' H; Generalize Hs Hs'; Clear Hs Hs'; Elim H; Intros; Intro.
+ Elim (H0 x); Intros.
+ Assert X : (In x []); Auto; Inversion X.
+ Inversion_clear Hs; Inversion_clear Hs'.
+ Elim (H1 x); Intros.
+ Assert X : (In x y::s'0); Auto; Inversion_clear X.
+ Absurd (E.eq x y); EAuto.
+ Absurd (E.lt y x); Auto.
+ EApply In_sort; EAuto.
+ Inversion_clear Hs; Inversion_clear Hs'.
+ Elim H2; Auto; Intuition.
+ Elim (H3 a); Intros.
+ Assert X: (In a y::s'0); Auto; Inversion_clear X; Auto.
+ Absurd (E.lt x a); EAuto.
+ EApply In_sort with s0; EAuto.
+ Elim (H3 a); Intros.
+ Assert X: (In a x::s0); Auto; Inversion_clear X; Auto.
+ Absurd (E.lt y a); EAuto.
+ EApply In_sort with s'0; EAuto.
+ Qed.
+
+ Definition compare : (s,s':t)(Hs:(Sort s))(Hs':(Sort s'))(Compare lt eq s s').
+ Proof.
+ Induction s.
+ Intros; Case s'.
+ Constructor 2; Apply eq_refl.
+ Constructor 1; Auto.
+ Intros a l Hrec s'; Case s'.
+ Constructor 3; Auto.
+ Intros a' l' Hs Hs'.
+ Case (E.compare a a'); [ Constructor 1 | Idtac | Constructor 3 ]; Auto.
+ Elim (Hrec l'); [ Constructor 1 | Constructor 2 | Constructor 3 | Inversion Hs | Inversion Hs']; Auto.
+ Generalize e; Unfold eq Equal; Intuition;
+ Inversion_clear H; EAuto; Elim (e1 a0); Auto.
+ Defined.
+
+End Raw.
+
+(** Now, in order to really provide a functor implementing S, we
+ need to encapsulate everything into a type of strictly ordered lists. *)
+
+Module Make [X:OrderedType] <: S with Module E := X.
+
+ Module E := X.
+ Module Raw := (Raw X).
+
+ Record slist : Set := { this :> Raw.t ; sorted : (sort E.lt this) }.
+ Definition t := slist.
+ Definition elt := X.t.
+
+ Definition In := [x:elt;s:t](Raw.In x s).
+ Definition Equal := [s,s'](a:elt)(In a s)<->(In a s').
+ Definition Subset := [s,s'](a:elt)(In a s)->(In a s').
+ Definition Add := [x:elt;s,s':t](y:elt)(In y s') <-> ((E.eq y x)\/(In y s)).
+ Definition Empty := [s](a:elt)~(In a s).
+ Definition For_all := [P:elt->Prop; s:t](x:elt)(In x s)->(P x).
+ Definition Exists := [P:elt->Prop; s:t](EX x:elt | (In x s)/\(P x)).
+
+ Definition In_1 := [s:t](!Raw.In_eq s).
+
+ Definition mem := [x:elt;s:t](Raw.mem x s).
+ Definition mem_1 := [s:t](Raw.mem_1 (sorted s)).
+ Definition mem_2 := [s:t](!Raw.mem_2 s).
+
+ Definition add := [x,s](Build_slist (Raw.add_sort (sorted s) x)).
+ Definition add_1 := [s:t](Raw.add_1 (sorted s)).
+ Definition add_2 := [s:t](Raw.add_2 (sorted s)).
+ Definition add_3 := [s:t](Raw.add_3 (sorted s)).
+
+ Definition remove := [x,s](Build_slist (Raw.remove_sort (sorted s) x)).
+ Definition remove_1 := [s:t](Raw.remove_1 (sorted s)).
+ Definition remove_2 := [s:t](Raw.remove_2 (sorted s)).
+ Definition remove_3 := [s:t](Raw.remove_3 (sorted s)).
+
+ Definition singleton := [x](Build_slist (Raw.singleton_sort x)).
+ Definition singleton_1 := Raw.singleton_1.
+ Definition singleton_2 := Raw.singleton_2.
+
+ Definition union := [s,s':t](Build_slist (Raw.union_sort (sorted s) (sorted s'))).
+ Definition union_1 := [s,s':t](Raw.union_1 (sorted s) (sorted s')).
+ Definition union_2 := [s,s':t](Raw.union_2 (sorted s) (sorted s')).
+ Definition union_3 := [s,s':t](Raw.union_3 (sorted s) (sorted s')).
+
+ Definition inter :=[s,s':t](Build_slist (Raw.inter_sort (sorted s) (sorted s'))).
+ Definition inter_1 := [s,s':t](Raw.inter_1 (sorted s) (sorted s')).
+ Definition inter_2 := [s,s':t](Raw.inter_2 (sorted s) (sorted s')).
+ Definition inter_3 := [s,s':t](Raw.inter_3 (sorted s) (sorted s')).
+
+ Definition diff :=[s,s':t](Build_slist (Raw.diff_sort (sorted s) (sorted s'))).
+ Definition diff_1 := [s,s':t](Raw.diff_1 (sorted s) (sorted s')).
+ Definition diff_2 := [s,s':t](Raw.diff_2 (sorted s) (sorted s')).
+ Definition diff_3 := [s,s':t](Raw.diff_3 (sorted s) (sorted s')).
+
+ Definition equal := [s,s':t](Raw.equal s s').
+ Definition equal_1 := [s,s':t](Raw.equal_1 (sorted s) (sorted s')).
+ Definition equal_2 := [s,s':t](!Raw.equal_2 s s').
+
+ Definition subset := [s,s':t](Raw.subset s s').
+ Definition subset_1 := [s,s':t](Raw.subset_1 (sorted s) (sorted s')).
+ Definition subset_2 := [s,s':t](!Raw.subset_2 s s').
+
+ Definition empty := (Build_slist Raw.empty_sort).
+ Definition empty_1 := Raw.empty_1.
+
+ Definition is_empty := [s:t](Raw.is_empty s).
+ Definition is_empty_1 := [s:t](!Raw.is_empty_1 s).
+ Definition is_empty_2 := [s:t](!Raw.is_empty_2 s).
+
+ Definition elements := [s:t](Raw.elements s).
+ Definition elements_1 := [s:t](!Raw.elements_1 s).
+ Definition elements_2 := [s:t](!Raw.elements_2 s).
+ Definition elements_3 := [s:t](Raw.elements_3 (sorted s)).
+
+ Definition min_elt := [s:t](Raw.min_elt s).
+ Definition min_elt_1 := [s:t](!Raw.min_elt_1 s).
+ Definition min_elt_2 := [s:t](Raw.min_elt_2 (sorted s)).
+ Definition min_elt_3 := [s:t](!Raw.min_elt_3 s).
+
+ Definition max_elt := [s:t](Raw.max_elt s).
+ Definition max_elt_1 := [s:t](!Raw.max_elt_1 s).
+ Definition max_elt_2 := [s:t](Raw.max_elt_2 (sorted s)).
+ Definition max_elt_3 := [s:t](!Raw.max_elt_3 s).
+
+ Definition choose := min_elt.
+ Definition choose_1 := min_elt_1.
+ Definition choose_2 := min_elt_3.
+
+ Definition fold := [B:Set; f: elt->B->B; s:t](!Raw.fold B f s).
+ Definition fold_1 := [s:t](!Raw.fold_1 s).
+ Definition fold_2 := [s,s':t](Raw.fold_2 (sorted s) (sorted s')).
+
+ Definition cardinal := [s:t](Raw.cardinal s).
+ Definition cardinal_1 := [s:t](!Raw.cardinal_1 s).
+ Definition cardinal_2 := [s,s':t](Raw.cardinal_2 (sorted s) (sorted s')).
+
+ Definition filter := [f: elt->bool; s:t](Build_slist (Raw.filter_sort (sorted s) f)).
+ Definition filter_1 := [s:t](!Raw.filter_1 s).
+ Definition filter_2 := [s:t](!Raw.filter_2 s).
+ Definition filter_3 := [s:t](!Raw.filter_3 s).
+
+ Definition for_all := [f:elt->bool; s:t](Raw.for_all f s).
+ Definition for_all_1 := [s:t](!Raw.for_all_1 s).
+ Definition for_all_2 := [s:t](!Raw.for_all_2 s).
+
+ Definition exists := [f:elt->bool; s:t](Raw.exists f s).
+ Definition exists_1 := [s:t](!Raw.exists_1 s).
+ Definition exists_2 := [s:t](!Raw.exists_2 s).
+
+ Definition partition := [f:elt->bool; s:t]
+ let p = (Raw.partition f s) in
+ ((!Build_slist (fst ?? p) (Raw.partition_sort_1 (sorted s) f)),
+ (!Build_slist (snd ?? p) (Raw.partition_sort_2 (sorted s) f))).
+ Definition partition_1 := [s:t](!Raw.partition_1 s).
+ Definition partition_2 := [s:t](!Raw.partition_2 s).
+
+ Definition eq := [s,s':t](Raw.eq s s').
+ Definition eq_refl := [s:t](Raw.eq_refl s).
+ Definition eq_sym := [s,s':t](!Raw.eq_sym s s').
+ Definition eq_trans := [s,s',s'':t](!Raw.eq_trans s s' s'').
+
+ Definition lt := [s,s':t](Raw.lt s s').
+ Definition lt_trans := [s,s',s'':t](!Raw.lt_trans s s' s'').
+ Definition lt_not_eq := [s,s':t](Raw.lt_not_eq (sorted s) (sorted s')).
+
+ Definition compare : (s,s':t)(Compare lt eq s s').
+ Proof.
+ Intros; Elim (Raw.compare (sorted s) (sorted s'));
+ [Constructor 1 | Constructor 2 | Constructor 3]; Auto.
+ Defined.
+
+End Make.