(***********************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* false | y :: l => if X.eq_dec x y then true else mem x l end. Fixpoint add (x : elt) (s : t) {struct s} : t := match s with | nil => x :: nil | y :: l => if X.eq_dec x y then s else y :: add x l end. Definition singleton (x : elt) : t := x :: nil. Fixpoint remove (x : elt) (s : t) {struct s} : t := match s with | nil => nil | y :: l => if X.eq_dec x y then l else y :: remove x l end. Fixpoint fold (B : Set) (f : elt -> B -> B) (s : t) {struct s} : B -> B := fun i => match s with | nil => i | x :: l => fold f l (f x i) end. Definition union (s : t) : t -> t := fold add s. Definition diff (s s' : t) : t := fold remove s' s. Definition inter (s s': t) : t := fold (fun x s => if mem x s' then add x s else s) s nil. Definition subset (s s' : t) : bool := is_empty (diff s s'). Definition equal (s s' : t) : bool := andb (subset s s') (subset s' s). Fixpoint filter (f : elt -> bool) (s : t) {struct s} : t := match s with | nil => nil | x :: l => if f x then x :: filter f l else filter f l end. Fixpoint for_all (f : elt -> bool) (s : t) {struct s} : bool := match s with | nil => true | x :: l => if f x then for_all f l else false end. Fixpoint exists_ (f : elt -> bool) (s : t) {struct s} : bool := match s with | nil => false | x :: l => if f x then true else exists_ f l end. Fixpoint partition (f : elt -> bool) (s : t) {struct s} : t * t := match s with | nil => (nil, nil) | x :: l => let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2) end. Definition cardinal (s : t) : nat := length s. Definition elements (s : t) : list elt := s. Definition choose (s : t) : option elt := match s with | nil => None | x::_ => Some x end. (** ** Proofs of set operation specifications. *) Section ForNotations. Notation NoDup := (NoDupA X.eq). Notation In := (InA X.eq). 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. Lemma In_eq : forall (s : t) (x y : elt), X.eq x y -> In x s -> In y s. Proof. intros s x y; do 2 setoid_rewrite InA_alt; firstorder eauto. Qed. Hint Immediate In_eq. Lemma mem_1 : forall (s : t)(x : elt), In x s -> mem x s = true. Proof. induction s; intros. inversion H. simpl; destruct (X.eq_dec x a); trivial. inversion_clear H; auto. Qed. Lemma mem_2 : forall (s : t) (x : elt), mem x s = true -> In x s. Proof. induction s. intros; inversion H. intros x; simpl. destruct (X.eq_dec x a); firstorder; discriminate. Qed. Lemma add_1 : forall (s : t) (Hs : NoDup s) (x y : elt), X.eq x y -> In y (add x s). Proof. induction s. simpl; intuition. simpl; intros; case (X.eq_dec x a); intuition; inversion_clear Hs; firstorder. eauto. Qed. Lemma add_2 : forall (s : t) (Hs : NoDup s) (x y : elt), In y s -> In y (add x s). Proof. induction s. simpl; intuition. simpl; intros; case (X.eq_dec x a); intuition. inversion_clear Hs; eauto; inversion_clear H; intuition. Qed. Lemma add_3 : forall (s : t) (Hs : NoDup s) (x y : elt), ~ X.eq x y -> In y (add x s) -> In y s. Proof. induction s. simpl; intuition. inversion_clear H0; firstorder; absurd (X.eq x y); auto. simpl; intros Hs x y; case (X.eq_dec x a); intros; inversion_clear H0; inversion_clear Hs; firstorder; absurd (X.eq x y); auto. Qed. Lemma add_unique : forall (s : t) (Hs : NoDup s)(x:elt), NoDup (add x s). Proof. induction s. simpl; intuition. constructor; auto. intro H0; inversion H0. intros. inversion_clear Hs. simpl. destruct (X.eq_dec x a). constructor; auto. constructor; auto. intro H1; apply H. eapply add_3; eauto. Qed. Lemma remove_1 : forall (s : t) (Hs : NoDup s) (x y : elt), X.eq x y -> ~ In y (remove x s). Proof. simple induction s. simpl; red; intros; inversion H0. simpl; intros; case (X.eq_dec x a); intuition; inversion_clear Hs. elim H2. apply In_eq with y; eauto. inversion_clear H1; eauto. Qed. Lemma remove_2 : forall (s : t) (Hs : NoDup s) (x y : elt), ~ X.eq x y -> In y s -> In y (remove x s). Proof. simple induction s. simpl; intuition. simpl; intros; case (X.eq_dec x a); intuition; inversion_clear Hs; inversion_clear H1; auto. absurd (X.eq x y); eauto. Qed. Lemma remove_3 : forall (s : t) (Hs : NoDup s) (x y : elt), In y (remove x s) -> In y s. Proof. simple induction s. simpl; intuition. simpl; intros a l Hrec Hs x y; case (X.eq_dec x a); intuition. inversion_clear Hs; inversion_clear H; firstorder. Qed. Lemma remove_unique : forall (s : t) (Hs : NoDup s) (x : elt), NoDup (remove x s). Proof. simple induction s. simpl; intuition. simpl; intros; case (X.eq_dec x a); intuition; inversion_clear Hs; auto. constructor; auto. intro H2; elim H0. eapply remove_3; eauto. Qed. Lemma singleton_unique : forall x : elt, NoDup (singleton x). Proof. unfold singleton; simpl; constructor; auto; intro H; inversion H. Qed. Lemma singleton_1 : forall x y : elt, In y (singleton x) -> X.eq x y. Proof. unfold singleton; simpl; intuition. inversion_clear H; auto; inversion H0. Qed. Lemma singleton_2 : forall x y : elt, X.eq x y -> In y (singleton x). Proof. unfold singleton; simpl; intuition. Qed. Lemma empty_unique : NoDup empty. Proof. unfold empty; constructor. Qed. Lemma empty_1 : Empty empty. Proof. unfold Empty, empty; intuition; inversion H. Qed. Lemma is_empty_1 : forall 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 : forall s : t, is_empty s = true -> Empty s. Proof. unfold Empty; intro s; case s; simpl; intuition; inversion H0. Qed. Lemma elements_1 : forall (s : t) (x : elt), In x s -> In x (elements s). Proof. unfold elements; auto. Qed. Lemma elements_2 : forall (s : t) (x : elt), In x (elements s) -> In x s. Proof. unfold elements; auto. Qed. Lemma elements_3 : forall (s : t) (Hs : NoDup s), NoDup (elements s). Proof. unfold elements; auto. Qed. Lemma fold_1 : forall (s : t) (Hs : NoDup s) (A : Set) (i : A) (f : elt -> A -> A), fold f s i = fold_left (fun a e => f e a) (elements s) i. Proof. induction s; simpl; auto; intros. inversion_clear Hs; auto. Qed. Lemma union_unique : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s'), NoDup (union s s'). Proof. unfold union; induction s; simpl; auto; intros. inversion_clear Hs. apply IHs; auto. apply add_unique; auto. Qed. Lemma union_1 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x (union s s') -> In x s \/ In x s'. Proof. unfold union; induction s; simpl; auto; intros. inversion_clear Hs. destruct (X.eq_dec x a). left; auto. destruct (IHs (add a s') H1 (add_unique Hs' a) x); intuition. right; eapply add_3; eauto. Qed. Lemma union_0 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x s \/ In x s' -> In x (union s s'). Proof. unfold union; induction s; simpl; auto; intros. inversion_clear H; auto. inversion_clear H0. inversion_clear Hs. apply IHs; auto. apply add_unique; auto. destruct H. inversion_clear H; auto. right; apply add_1; auto. right; apply add_2; auto. Qed. Lemma union_2 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x s -> In x (union s s'). Proof. intros; apply union_0; auto. Qed. Lemma union_3 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x s' -> In x (union s s'). Proof. intros; apply union_0; auto. Qed. Lemma inter_unique : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s'), NoDup (inter s s'). Proof. unfold inter; intros s. set (acc := nil (A:=elt)). assert (NoDup acc) by (unfold acc; auto). clearbody acc; generalize H; clear H; generalize acc; clear acc. induction s; simpl; auto; intros. inversion_clear Hs. apply IHs; auto. destruct (mem a s'); intros; auto. apply add_unique; auto. Qed. Lemma inter_0 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x (inter s s') -> In x s /\ In x s'. Proof. unfold inter; intros. set (acc := nil (A:=elt)) in *. assert (NoDup acc) by (unfold acc; auto). cut ((In x s /\ In x s') \/ In x acc). destruct 1; auto. inversion H1. clearbody acc. generalize H0 H Hs' Hs; clear H0 H Hs Hs'. generalize acc x s'; clear acc x s'. induction s; simpl; auto; intros. inversion_clear Hs. case_eq (mem a s'); intros H3; rewrite H3 in H; simpl in H. destruct (IHs _ _ _ (add_unique H0 a) H); auto. left; intuition. destruct (X.eq_dec x a); auto. left; intuition. apply In_eq with a; eauto. apply mem_2; auto. right; eapply add_3; eauto. destruct (IHs _ _ _ H0 H); auto. left; intuition. Qed. Lemma inter_1 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x (inter s s') -> In x s. Proof. intros; cut (In x s /\ In x s'); [ intuition | apply inter_0; auto ]. Qed. Lemma inter_2 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x (inter s s') -> In x s'. Proof. intros; cut (In x s /\ In x s'); [ intuition | apply inter_0; auto ]. Qed. Lemma inter_3 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x s -> In x s' -> In x (inter s s'). Proof. intros s s' Hs Hs' x. cut (((In x s /\ In x s')\/ In x (nil (A:=elt))) -> In x (inter s s')). intuition. unfold inter. set (acc := nil (A:=elt)) in *. assert (NoDup acc) by (unfold acc; auto). clearbody acc. generalize H Hs' Hs; clear H Hs Hs'. generalize acc x s'; clear acc x s'. induction s; simpl; auto; intros. destruct H0; auto. destruct H0; inversion H0. inversion_clear Hs. case_eq (mem a s'); intros H3; apply IHs; auto. apply add_unique; auto. destruct H0. destruct H0. inversion_clear H0. right; apply add_1; auto. left; auto. right; apply add_2; auto. destruct H0; auto. destruct H0. inversion_clear H0; auto. absurd (In x s'); auto. red; intros. rewrite (mem_1 (In_eq H5 H0)) in H3. discriminate. Qed. Lemma diff_unique : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s'), NoDup (diff s s'). Proof. unfold diff; intros s s' Hs; generalize s Hs; clear Hs s. induction s'; simpl; auto; intros. inversion_clear Hs'. apply IHs'; auto. apply remove_unique; auto. Qed. Lemma diff_0 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x (diff s s') -> In x s /\ ~ In x s'. Proof. unfold diff; intros s s' Hs; generalize s Hs; clear Hs s. induction s'; simpl; auto; intros. inversion_clear Hs'. split; auto; intro H1; inversion H1. inversion_clear Hs'. destruct (IHs' (remove a s) (remove_unique Hs a) H1 x H). split. eapply remove_3; eauto. red; intros. inversion_clear H4; auto. destruct (remove_1 Hs (X.eq_sym H5) H2). Qed. Lemma diff_1 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x (diff s s') -> In x s. Proof. intros; cut (In x s /\ ~ In x s'); [ intuition | apply diff_0; auto]. Qed. Lemma diff_2 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x (diff s s') -> ~ In x s'. Proof. intros; cut (In x s /\ ~ In x s'); [ intuition | apply diff_0; auto]. Qed. Lemma diff_3 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s') (x : elt), In x s -> ~ In x s' -> In x (diff s s'). Proof. unfold diff; intros s s' Hs; generalize s Hs; clear Hs s. induction s'; simpl; auto; intros. inversion_clear Hs'. apply IHs'; auto. apply remove_unique; auto. apply remove_2; auto. Qed. Lemma subset_1 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s'), Subset s s' -> subset s s' = true. Proof. unfold subset, Subset; intros. apply is_empty_1. unfold Empty; intros. intro. destruct (diff_2 Hs Hs' H0). apply H. eapply diff_1; eauto. Qed. Lemma subset_2 : forall (s s' : t)(Hs : NoDup s) (Hs' : NoDup s'), subset s s' = true -> Subset s s'. Proof. unfold subset, Subset; intros. generalize (is_empty_2 H); clear H; unfold Empty; intros. generalize (@mem_1 s' a) (@mem_2 s' a); destruct (mem a s'). intuition. intros. destruct (H a). apply diff_3; intuition. Qed. Lemma equal_1 : forall (s s' : t) (Hs : NoDup s) (Hs' : NoDup s'), Equal s s' -> equal s s' = true. Proof. unfold Equal, equal; intros. apply andb_true_intro; split; apply subset_1; firstorder. Qed. Lemma equal_2 : forall (s s' : t)(Hs : NoDup s) (Hs' : NoDup s'), equal s s' = true -> Equal s s'. Proof. unfold Equal, equal; intros. destruct (andb_prop _ _ H); clear H. split; apply subset_2; auto. Qed. Definition choose_1 : forall (s : t) (x : elt), choose s = Some x -> In x s. Proof. destruct s; simpl; intros; inversion H; auto. Qed. Definition choose_2 : forall s : t, choose s = None -> Empty s. Proof. destruct s; simpl; intros. intros x H0; inversion H0. inversion H. Qed. Lemma cardinal_1 : forall (s : t) (Hs : NoDup s), cardinal s = length (elements s). Proof. auto. Qed. Lemma filter_1 : forall (s : t) (x : elt) (f : elt -> bool), In x (filter f s) -> In x s. Proof. simple induction s; simpl. intros; inversion H. intros x l Hrec a f. case (f x); simpl. inversion_clear 1. constructor; auto. constructor 2; apply (Hrec a f); trivial. constructor 2; apply (Hrec a f); trivial. Qed. Lemma filter_2 : forall (s : t) (x : elt) (f : elt -> bool), compat_bool X.eq f -> In x (filter f s) -> f x = true. Proof. simple induction s; simpl. intros; inversion H0. intros x l Hrec a f Hf. generalize (Hf x); case (f x); simpl; auto. inversion_clear 2; auto. symmetry; auto. Qed. Lemma filter_3 : forall (s : t) (x : elt) (f : elt -> bool), compat_bool X.eq f -> In x s -> f x = true -> In x (filter f s). Proof. simple induction s; simpl. intros; inversion H0. intros x l Hrec a f Hf. generalize (Hf x); case (f x); simpl. inversion_clear 2; auto. inversion_clear 2; auto. rewrite <- (H a (X.eq_sym H1)); intros; discriminate. Qed. Lemma filter_unique : forall (s : t) (Hs : NoDup s) (f : elt -> bool), NoDup (filter f s). Proof. simple induction s; simpl. auto. intros x l Hrec Hs f; inversion_clear Hs. case (f x); auto. constructor; auto. intro H1; apply H. eapply filter_1; eauto. Qed. Lemma for_all_1 : forall (s : t) (f : elt -> bool), compat_bool X.eq f -> For_all (fun x => f x = true) s -> for_all f s = true. Proof. simple induction s; simpl; auto; unfold For_all. intros x l Hrec f Hf. generalize (Hf x); case (f x); simpl. auto. intros; rewrite (H x); auto. Qed. Lemma for_all_2 : forall (s : t) (f : elt -> bool), compat_bool X.eq f -> for_all f s = true -> For_all (fun x => f x = true) s. Proof. simple 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_clear H; auto. rewrite (Hf a x); auto. Qed. Lemma exists_1 : forall (s : t) (f : elt -> bool), compat_bool X.eq f -> Exists (fun x => f x = true) s -> exists_ f s = true. Proof. simple 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. auto. destruct 2 as [a (A1,A2)]. inversion_clear A1. rewrite <- (H a (X.eq_sym H0)) in A2; discriminate. apply Hrec; auto. exists a; auto. Qed. Lemma exists_2 : forall (s : t) (f : elt -> bool), compat_bool X.eq f -> exists_ f s = true -> Exists (fun x => f x = true) s. Proof. simple induction s; simpl; auto; unfold Exists. intros; discriminate. intros x l Hrec f Hf. case_eq (f x); intros. exists x; auto. destruct (Hrec f Hf H0) as [a (A1,A2)]. exists a; auto. Qed. Lemma partition_1 : forall (s : t) (f : elt -> bool), compat_bool X.eq f -> Equal (fst (partition f s)) (filter f s). Proof. simple induction s; simpl; auto; unfold Equal. firstorder. 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; firstorder; inversion H0; intros; firstorder. Qed. Lemma partition_2 : forall (s : t) (f : elt -> bool), compat_bool X.eq f -> Equal (snd (partition f s)) (filter (fun x => negb (f x)) s). Proof. simple induction s; simpl; auto; unfold Equal. firstorder. 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; firstorder; inversion H0; intros; firstorder. Qed. Lemma partition_aux_1 : forall (s : t) (Hs : NoDup s) (f : elt -> bool)(x:elt), In x (fst (partition f s)) -> In x s. Proof. induction s; simpl; auto; intros. inversion_clear Hs. generalize (IHs H1 f x). destruct (f a); destruct (partition f s); simpl in *; auto. inversion_clear H; auto. Qed. Lemma partition_aux_2 : forall (s : t) (Hs : NoDup s) (f : elt -> bool)(x:elt), In x (snd (partition f s)) -> In x s. Proof. induction s; simpl; auto; intros. inversion_clear Hs. generalize (IHs H1 f x). destruct (f a); destruct (partition f s); simpl in *; auto. inversion_clear H; auto. Qed. Lemma partition_unique_1 : forall (s : t) (Hs : NoDup s) (f : elt -> bool), NoDup (fst (partition f s)). Proof. simple induction s; simpl. auto. intros x l Hrec Hs f; inversion_clear Hs. generalize (@partition_aux_1 _ H0 f x). generalize (Hrec H0 f). case (f x); case (partition f l); simpl; auto. Qed. Lemma partition_unique_2 : forall (s : t) (Hs : NoDup s) (f : elt -> bool), NoDup (snd (partition f s)). Proof. simple induction s; simpl. auto. intros x l Hrec Hs f; inversion_clear Hs. generalize (@partition_aux_2 _ H0 f x). generalize (Hrec H0 f). case (f x); case (partition f l); simpl; auto. Qed. Definition eq : t -> t -> Prop := Equal. Lemma eq_refl : forall s : t, eq s s. Proof. unfold eq, Equal; intuition. Qed. Lemma eq_sym : forall s s' : t, eq s s' -> eq s' s. Proof. unfold eq, Equal; firstorder. Qed. Lemma eq_trans : forall s s' s'' : t, eq s s' -> eq s' s'' -> eq s s''. Proof. unfold eq, Equal; firstorder. Qed. End ForNotations. End Raw. (** * Encapsulation Now, in order to really provide a functor implementing [S], we need to encapsulate everything into a type of lists without redundancy. *) Module Make (X: DecidableType) <: S with Module E := X. Module Raw := Raw X. Module E := X. Record slist : Set := {this :> Raw.t; unique : NoDupA E.eq this}. Definition t := slist. Definition elt := E.t. Definition In (x : elt) (s : t) : Prop := InA E.eq x s.(this). Definition Equal (s s':t) : Prop := forall a : elt, In a s <-> In a s'. Definition Subset (s s':t) : Prop := forall a : elt, In a s -> In a s'. Definition Empty (s:t) : Prop := forall a : elt, ~ In a s. Definition For_all (P : elt -> Prop) (s : t) : Prop := forall x : elt, In x s -> P x. Definition Exists (P : elt -> Prop) (s : t) : Prop := exists x : elt, In x s /\ P x. Definition mem (x : elt) (s : t) : bool := Raw.mem x s. Definition add (x : elt)(s : t) : t := Build_slist (Raw.add_unique (unique s) x). Definition remove (x : elt)(s : t) : t := Build_slist (Raw.remove_unique (unique s) x). Definition singleton (x : elt) : t := Build_slist (Raw.singleton_unique x). Definition union (s s' : t) : t := Build_slist (Raw.union_unique (unique s) (unique s')). Definition inter (s s' : t) : t := Build_slist (Raw.inter_unique (unique s) (unique s')). Definition diff (s s' : t) : t := Build_slist (Raw.diff_unique (unique s) (unique s')). Definition equal (s s' : t) : bool := Raw.equal s s'. Definition subset (s s' : t) : bool := Raw.subset s s'. Definition empty : t := Build_slist Raw.empty_unique. Definition is_empty (s : t) : bool := Raw.is_empty s. Definition elements (s : t) : list elt := Raw.elements s. Definition choose (s:t) : option elt := Raw.choose s. Definition fold (B : Set) (f : elt -> B -> B) (s : t) : B -> B := Raw.fold (B:=B) f s. Definition cardinal (s : t) : nat := Raw.cardinal s. Definition filter (f : elt -> bool) (s : t) : t := Build_slist (Raw.filter_unique (unique s) f). Definition for_all (f : elt -> bool) (s : t) : bool := Raw.for_all f s. Definition exists_ (f : elt -> bool) (s : t) : bool := Raw.exists_ f s. Definition partition (f : elt -> bool) (s : t) : t * t := let p := Raw.partition f s in (Build_slist (this:=fst p) (Raw.partition_unique_1 (unique s) f), Build_slist (this:=snd p) (Raw.partition_unique_2 (unique s) f)). Section Spec. Variable s s' : t. Variable x y : elt. Lemma In_1 : E.eq x y -> In x s -> In y s. Proof. exact (fun H H' => Raw.In_eq H H'). Qed. Lemma mem_1 : In x s -> mem x s = true. Proof. exact (fun H => Raw.mem_1 H). Qed. Lemma mem_2 : mem x s = true -> In x s. Proof. exact (fun H => Raw.mem_2 H). Qed. Lemma equal_1 : Equal s s' -> equal s s' = true. Proof. exact (Raw.equal_1 s.(unique) s'.(unique)). Qed. Lemma equal_2 : equal s s' = true -> Equal s s'. Proof. exact (Raw.equal_2 s.(unique) s'.(unique)). Qed. Lemma subset_1 : Subset s s' -> subset s s' = true. Proof. exact (Raw.subset_1 s.(unique) s'.(unique)). Qed. Lemma subset_2 : subset s s' = true -> Subset s s'. Proof. exact (Raw.subset_2 s.(unique) s'.(unique)). Qed. Lemma empty_1 : Empty empty. Proof. exact Raw.empty_1. Qed. Lemma is_empty_1 : Empty s -> is_empty s = true. Proof. exact (fun H => Raw.is_empty_1 H). Qed. Lemma is_empty_2 : is_empty s = true -> Empty s. Proof. exact (fun H => Raw.is_empty_2 H). Qed. Lemma add_1 : E.eq x y -> In y (add x s). Proof. exact (fun H => Raw.add_1 s.(unique) H). Qed. Lemma add_2 : In y s -> In y (add x s). Proof. exact (fun H => Raw.add_2 s.(unique) x H). Qed. Lemma add_3 : ~ E.eq x y -> In y (add x s) -> In y s. Proof. exact (fun H => Raw.add_3 s.(unique) H). Qed. Lemma remove_1 : E.eq x y -> ~ In y (remove x s). Proof. exact (fun H => Raw.remove_1 s.(unique) H). Qed. Lemma remove_2 : ~ E.eq x y -> In y s -> In y (remove x s). Proof. exact (fun H H' => Raw.remove_2 s.(unique) H H'). Qed. Lemma remove_3 : In y (remove x s) -> In y s. Proof. exact (fun H => Raw.remove_3 s.(unique) H). Qed. Lemma singleton_1 : In y (singleton x) -> E.eq x y. Proof. exact (fun H => Raw.singleton_1 H). Qed. Lemma singleton_2 : E.eq x y -> In y (singleton x). Proof. exact (fun H => Raw.singleton_2 H). Qed. Lemma union_1 : In x (union s s') -> In x s \/ In x s'. Proof. exact (fun H => Raw.union_1 s.(unique) s'.(unique) H). Qed. Lemma union_2 : In x s -> In x (union s s'). Proof. exact (fun H => Raw.union_2 s.(unique) s'.(unique) H). Qed. Lemma union_3 : In x s' -> In x (union s s'). Proof. exact (fun H => Raw.union_3 s.(unique) s'.(unique) H). Qed. Lemma inter_1 : In x (inter s s') -> In x s. Proof. exact (fun H => Raw.inter_1 s.(unique) s'.(unique) H). Qed. Lemma inter_2 : In x (inter s s') -> In x s'. Proof. exact (fun H => Raw.inter_2 s.(unique) s'.(unique) H). Qed. Lemma inter_3 : In x s -> In x s' -> In x (inter s s'). Proof. exact (fun H => Raw.inter_3 s.(unique) s'.(unique) H). Qed. Lemma diff_1 : In x (diff s s') -> In x s. Proof. exact (fun H => Raw.diff_1 s.(unique) s'.(unique) H). Qed. Lemma diff_2 : In x (diff s s') -> ~ In x s'. Proof. exact (fun H => Raw.diff_2 s.(unique) s'.(unique) H). Qed. Lemma diff_3 : In x s -> ~ In x s' -> In x (diff s s'). Proof. exact (fun H => Raw.diff_3 s.(unique) s'.(unique) H). Qed. Lemma fold_1 : forall (A : Set) (i : A) (f : elt -> A -> A), fold f s i = fold_left (fun a e => f e a) (elements s) i. Proof. exact (Raw.fold_1 s.(unique)). Qed. Lemma cardinal_1 : cardinal s = length (elements s). Proof. exact (Raw.cardinal_1 s.(unique)). Qed. Section Filter. Variable f : elt -> bool. Lemma filter_1 : compat_bool E.eq f -> In x (filter f s) -> In x s. Proof. exact (fun H => @Raw.filter_1 s x f). Qed. Lemma filter_2 : compat_bool E.eq f -> In x (filter f s) -> f x = true. Proof. exact (@Raw.filter_2 s x f). Qed. Lemma filter_3 : compat_bool E.eq f -> In x s -> f x = true -> In x (filter f s). Proof. exact (@Raw.filter_3 s x f). Qed. Lemma for_all_1 : compat_bool E.eq f -> For_all (fun x => f x = true) s -> for_all f s = true. Proof. exact (@Raw.for_all_1 s f). Qed. Lemma for_all_2 : compat_bool E.eq f -> for_all f s = true -> For_all (fun x => f x = true) s. Proof. exact (@Raw.for_all_2 s f). Qed. Lemma exists_1 : compat_bool E.eq f -> Exists (fun x => f x = true) s -> exists_ f s = true. Proof. exact (@Raw.exists_1 s f). Qed. Lemma exists_2 : compat_bool E.eq f -> exists_ f s = true -> Exists (fun x => f x = true) s. Proof. exact (@Raw.exists_2 s f). Qed. Lemma partition_1 : compat_bool E.eq f -> Equal (fst (partition f s)) (filter f s). Proof. exact (@Raw.partition_1 s f). Qed. Lemma partition_2 : compat_bool E.eq f -> Equal (snd (partition f s)) (filter (fun x => negb (f x)) s). Proof. exact (@Raw.partition_2 s f). Qed. End Filter. Lemma elements_1 : In x s -> InA E.eq x (elements s). Proof. exact (fun H => Raw.elements_1 H). Qed. Lemma elements_2 : InA E.eq x (elements s) -> In x s. Proof. exact (fun H => Raw.elements_2 H). Qed. Lemma elements_3 : NoDupA E.eq (elements s). Proof. exact (Raw.elements_3 s.(unique)). Qed. Lemma choose_1 : choose s = Some x -> In x s. Proof. exact (fun H => Raw.choose_1 H). Qed. Lemma choose_2 : choose s = None -> Empty s. Proof. exact (fun H => Raw.choose_2 H). Qed. End Spec. End Make.