diff options
author | filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2003-06-13 12:12:08 +0000 |
---|---|---|
committer | filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2003-06-13 12:12:08 +0000 |
commit | f314c2a91775739f581ab8bacbeb58f57e2d4871 (patch) | |
tree | 8aaf92ed9e400d27cb4d37abca015eb4cf062e4a /theories/FSets/FSetProperties.v | |
parent | fb7e6748d9b02fff8da1335dc3f4dedeb23a8f5d (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/FSetProperties.v')
-rw-r--r-- | theories/FSets/FSetProperties.v | 1483 |
1 files changed, 1483 insertions, 0 deletions
diff --git a/theories/FSets/FSetProperties.v b/theories/FSets/FSetProperties.v new file mode 100644 index 000000000..226205877 --- /dev/null +++ b/theories/FSets/FSetProperties.v @@ -0,0 +1,1483 @@ +(***********************************************************************) +(* 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 module proves many properties of finite sets that + are consequences of the axiomatization in [FSetInterface] *) + +Require Omega. + +Import nat_scope. +Open Scope nat_scope. + +Require Export FSetInterface. +Require Export Bool. +Require Export Sumbool. +Require Export Zerob. +Set Implicit Arguments. + +(* For proving (Setoid_Theory ? (eq ?)) *) +Tactic Definition ST := + Constructor; Intros;[ Trivial | Symmetry; Trivial | EApply trans_eq; EAuto ]. +Hint st : core := Extern 1 (Setoid_Theory ? (eq ?)) ST. + +Definition gen_st : (A:Set)(Setoid_Theory ? (eq A)). +Auto. +Qed. + + +Module Properties [M:S]. + Import M. + Import Logic. (* for unmasking eq. *) + Import Peano. (* for unmasking lt *) + + Module ME := MoreOrderedType E. + + Section Old_Spec_Now_Properties. + + Variable s,s' : t. + Variable x,y,z : elt. + + Lemma mem_eq: + (E.eq x y) -> (mem x s)=(mem y s). + Proof. + Intros; Apply bool_1. + Generalize (!mem_1 s x) (!mem_1 s y) (!mem_2 s x) (!mem_2 s y). + Intuition. + EAuto. + Apply H0; Apply In_1 with y; Auto. + Qed. + + Lemma equal_mem_1: + ((a:elt)(mem a s)=(mem a s')) -> (equal s s')=true. + Proof. + Intros; Apply equal_1; Unfold Equal; Intuition; EAuto. + Qed. + + Lemma equal_mem_2: + (equal s s')=true -> (a:elt)(mem a s)=(mem a s'). + Proof. + Intros; Apply bool_1. + Intros; Cut (Equal s s'); [Clear H; Unfold Equal|Auto]. + Intros H; Generalize (H a); Intuition. + Qed. + + Lemma subset_mem_1: + ((a:elt)(mem a s)=true->(mem a s')=true) -> (subset s s')=true. + Proof. + Intros; Apply subset_1; Unfold Subset; Intuition; EAuto. + Qed. + + Lemma subset_mem_2: + (subset s s')=true -> (a:elt)(mem a s)=true -> (mem a s')=true. + Proof. + Intros; Apply bool_1. + Cut (Subset s s'); [Clear H; Unfold Subset|Auto]. + Intros H; Generalize (H a); Intuition. + Qed. + + Lemma empty_mem: (mem x empty)=false. + Proof. + Apply not_true_is_false; Intro; Absurd (In x empty); Auto. + Qed. + + Lemma is_empty_equal_empty: (is_empty s)=(equal s empty). + Proof. + Generalize empty_1 (!is_empty_1 s) (!is_empty_2 s) + (!equal_1 s empty) (!equal_2 s empty). + Unfold Empty Equal. + Case (is_empty s); Case (equal s empty); Intuition. + Clear H3 H1. + Symmetry; Apply H2; Intuition. + Generalize (H4 a); Intuition. + Generalize (H a); Intuition. + Clear H1 H3. + Apply H0; Intuition. + Generalize (H4 a); Intuition. + Generalize (H a); Intuition. + Qed. + + Lemma choose_mem_1: (choose s)=(Some ? x) -> (mem x s)=true. + Proof. + Auto. + Qed. + + Lemma choose_mem_2: (choose s)=(None ?) -> (is_empty s)=true. + Proof. + Auto. + Qed. + + Lemma add_mem_1: (mem x (add x s))=true. + Proof. + Auto. + Qed. + + Lemma add_mem_2: + ~ (E.eq x y) -> (mem y (add x s))=(mem y s). + Proof. + Intros; Apply bool_1; Intuition; EAuto. + Qed. + + Lemma remove_mem_1: (mem x (remove x s))=false. + Proof. + Apply not_true_is_false; Intro; Absurd (In x (remove x s)); Auto. + Qed. + + Lemma remove_mem_2: + ~ (E.eq x y) -> (mem y (remove x s))=(mem y s). + Proof. + Intros; Apply bool_1; Intuition; EAuto. + Qed. + + Lemma singleton_equal_add: + (equal (singleton x) (add x empty))=true. + Proof. + Apply equal_1; Unfold Equal; Intuition. + Apply In_1 with x; Auto. + Assert (E.eq a x); Auto. + Elim (ME.eq_dec a x); Auto. + Intros; Assert (In a empty). + EApply add_3; EAuto. + Generalize (empty_1 H0); Intuition. + Qed. + + Lemma union_mem: + (mem x (union s s'))=(orb (mem x s) (mem x s')). + Proof. + Apply bool_1; Intuition. + Elim (!union_1 s s' x); Intuition. + Elim (orb_prop ? ? H); Intuition. + Qed. + + Lemma inter_mem: + (mem x (inter s s'))=(andb (mem x s) (mem x s')). + Proof. + Apply bool_1; Intuition. + Apply andb_true_intro; Intuition EAuto. + Elim (andb_prop ?? H); Intuition. + Qed. + + Lemma diff_mem: + (mem x (diff s s'))=(andb (mem x s) (negb (mem x s'))). + Proof. + Generalize (!diff_1 s s' x) (!diff_2 s s' x) (!diff_3 s s' x). + LetTac s0 := (diff s s'). + Generalize (!mem_1 s x) (!mem_1 s' x) (!mem_1 s0 x) + (!mem_2 s x) (!mem_2 s' x) (!mem_2 s0 x). + Case (mem x s); Case (mem x s'); Case (mem x s0); Intuition. + Qed. + + Section Cardinal. + + Lemma Add_add : + (s:t)(x:elt)(Add x s (add x s)). + Proof. + Unfold Add; Intros; Intuition. + Elim (ME.eq_dec x0 y0); Intros; Auto. + Right. + EApply add_3; EAuto. + Apply In_1 with x0; Auto. + Qed. + + Lemma Add_remove : (s:t)(x:elt)(In x s) -> (Add x (remove x s) s). + Proof. + Intros; Unfold Add; Intuition. + Elim (ME.eq_dec x0 y0); Intros; Auto. + Apply In_1 with x0; Auto. + EAuto. + Qed. + + Hints Resolve Add_add Add_remove. + + Lemma Equal_remove : (s,s':t)(x:elt)(In x s)->(Equal s s')-> + (Equal (remove x s) (remove x s')). + Proof. + Unfold Equal; Intros. + Elim (ME.eq_dec x0 a); Intros; Auto. + Split; Intros. + Absurd (In x0 (remove x0 s0)); Auto; Apply In_1 with a; Auto. + Absurd (In x0 (remove x0 s'0)); Auto; Apply In_1 with a; Auto. + Elim (H0 a); Intros. + Split; Intros; Apply remove_2; Auto; + [Apply H1|Apply H2]; EApply remove_3;EAuto. + Save. + + Hints Resolve Equal_remove. + + Lemma cardinal_inv_1 : (s:t)(cardinal s)=O -> (Empty s). + Proof. + Intros; Generalize (!choose_1 s0) (!choose_2 s0). + Elim (choose s0); Intuition. + Clear H1; Assert (In a s0); Auto. + Rewrite (!cardinal_2 (remove a s0) s0 a) in H; Auto. + Inversion H. + Save. + Hints Resolve cardinal_inv_1. + + Lemma cardinal_inv_2 : + (s:t)(n:nat)(cardinal s)=(S n) -> (EX x:elt | (In x s)). + Proof. + Intros; Generalize (!choose_1 s0) (!choose_2 s0). + Elim (choose s0); Intuition. + Exists a; Auto. + Intros; Rewrite cardinal_1 in H; Auto; Inversion H. + Qed. + + Lemma Equal_cardinal_aux : (n:nat)(s,s':t)(cardinal s)=n -> + (Equal s s')->(cardinal s)=(cardinal s'). + Proof. + Induction n. + Intros. + Rewrite H. + Symmetry. + Apply cardinal_1. + Generalize (cardinal_inv_1 H) H0. + Unfold Empty Equal; Intuition. + Generalize (H1 a) (H2 a); Intuition. + Intros. + Elim (cardinal_inv_2 H0); Intros. + Assert (In x0 s'0). + Generalize (H1 x0); Intuition. + Generalize H0. + Rewrite (!cardinal_2 (remove x0 s0) s0 x0);Auto. + Rewrite (!cardinal_2 (remove x0 s'0) s'0 x0); Auto. + Qed. + + Lemma Equal_cardinal : (s,s':t)(Equal s s')->(cardinal s)=(cardinal s'). + Proof. + Intros; EApply Equal_cardinal_aux; EAuto. + Qed. + + End Cardinal. + + Hints Resolve Add_add Add_remove Equal_remove + cardinal_inv_1 Equal_cardinal. + + Lemma cardinal_induction : (P : t -> Prop) + ((s:t)(Empty s)->(P s)) -> + ((s,s':t)(P s) -> (x:elt)~(In x s) -> (Add x s s') -> (P s')) -> + (n:nat)(s:t)(cardinal s)=n -> (P s). + Proof. + Induction n. + Intros; Apply H; Auto. + Intros; Elim (cardinal_inv_2 H2); Intros. + Apply H0 with (remove x0 s0) x0; Auto. + Apply H1; Auto. + Assert (S (cardinal (remove x0 s0))) = (S n0); Auto. + Rewrite <- H2; Symmetry. + EApply cardinal_2; EAuto. + Qed. + + Lemma set_induction : (P : t -> Prop) + ((s:t)(Empty s)->(P s)) -> + ((s,s':t)(P s) -> (x:elt)~(In x s) -> (Add x s s') -> (P s')) -> + (s:t)(P s). + Proof. + Intros; EApply cardinal_induction; EAuto. + Qed. + + Section Fold. + + Variable A:Set. + Variable eqA:A->A->Prop. + Variable st:(Setoid_Theory ? eqA). + Variable i:A. + Variable f:elt->A->A. + Variable Comp:(compat_op E.eq eqA f). + Variable Assoc:(transpose eqA f). + + Lemma fold_empty: (eqA (fold f empty i) i). + Proof. + Apply fold_1; Auto. + Qed. + + Lemma fold_equal: + (equal s s')=true -> (eqA (fold f s i) (fold f s' i)). + Proof. + Pattern s; Apply set_induction; Intros. + Apply (Seq_trans ?? st) with i; Auto. + Apply fold_1; Auto. + Apply Seq_sym; Auto; Apply fold_1; Auto. + Apply cardinal_inv_1; Rewrite <- (Equal_cardinal (equal_2 H0)); Auto. + Apply (Seq_trans ?? st) with (f x0 (fold f s0 i)); Auto. + Apply fold_2 with eqA:=eqA; Auto. + Apply Seq_sym; Auto; Apply fold_2 with eqA := eqA; Auto. + Generalize (equal_2 H2) H1; Unfold Add Equal; Intros; + Elim (H4 y0); Elim (H3 y0); Intuition. + Qed. + + Lemma fold_add: + (mem x s)=false -> (eqA (fold f (add x s) i) (f x (fold f s i))). + Proof. + Intros; Apply fold_2 with eqA:=eqA; Auto. + Intro; Rewrite mem_1 in H; Auto; Discriminate H. + Qed. + + End Fold. + + Lemma cardinal_fold: (cardinal s)=(fold [_]S s O). + Proof. + Pattern s; Apply set_induction; Intros. + Rewrite cardinal_1; Auto; Symmetry; Apply fold_1;Auto. + Rewrite (!cardinal_2 s0 s'0 x0);Auto. + Rewrite H; Symmetry; Change S with ([_]S x0). + Apply fold_2 with eqA:=(eq nat); Auto. + Qed. + + Section Filter. + + Variable f:elt->bool. + Variable Comp: (compat_bool E.eq f). + + Lemma filter_mem: (mem x (filter f s))=(andb (mem x s) (f x)). + Proof. + Apply bool_1; Intuition. + Apply andb_true_intro; Intuition; EAuto. + Elim (andb_prop ?? H); Intuition. + Qed. + + Lemma for_all_filter: + (for_all f s)=(is_empty (filter [x](negb (f x)) s)). + Proof. + Assert Comp' : (compat_bool E.eq [x](negb (f x))). + Generalize Comp; Unfold compat_bool; Intros; Apply (f_equal ?? negb); Auto. + Apply bool_1; Intuition. + Apply is_empty_1. + Unfold Empty; Intros. + Intro. + Assert (In a s); EAuto. + Generalize (filter_2 Comp' H0). + Generalize (for_all_2 Comp H H1); Auto. + Intros Eq; Rewrite Eq; Intuition. + Apply for_all_1; Unfold For_all; Intros; Auto. + Apply bool_3. + Red; Intros. + Elim (is_empty_2 H 3!x0); Auto. + Qed. + + Lemma exists_filter: + (exists f s)=(negb (is_empty (filter f s))). + Proof. + Apply bool_1; Intuition. + Elim (exists_2 Comp H); Intuition. + Apply bool_6. + Red; Intros; Apply (is_empty_2 H0 3!x0); Auto. + Generalize (!choose_1 (filter f s)) (!choose_2 (filter f s)). + Case (choose (filter f s)). + Intros. + Clear H1. + Apply exists_1; Auto. + Exists e; Generalize (H0 e); Intuition; EAuto. + Intros. + Clear H0. + Rewrite (!is_empty_1 (filter f s)) in H; Auto. + Discriminate H. + Qed. + + Lemma partition_filter_1: + (equal (fst ? ? (partition f s)) (filter f s))=true. + Proof. + Auto. + Qed. + + Lemma partition_filter_2: + (equal (snd ? ? (partition f s)) (filter [x](negb (f x)) s))=true. + Proof. + Auto. + Qed. + + End Filter. + End Old_Spec_Now_Properties. + + Hints Immediate + empty_mem + is_empty_equal_empty + add_mem_1 + remove_mem_1 + singleton_equal_add + union_mem + inter_mem + diff_mem + cardinal_fold + filter_mem + for_all_filter + exists_filter : set. + + Hints Resolve + equal_mem_1 + subset_mem_1 + choose_mem_1 + choose_mem_2 + add_mem_2 + remove_mem_2 : set. + +Section MoreProperties. + +(*s Properties of [equal] *) + +Lemma equal_refl: (s:t)(equal s s)=true. +Proof. +Auto with set. +Qed. + +Lemma equal_sym: (s,s':t)(equal s s')=(equal s' s). +Proof. +Intros. +Apply bool_eq_ind;Intros. +Rewrite equal_mem_1;Auto. +Symmetry;Apply equal_mem_2;Auto. +Apply (bool_eq_ind (equal s s'));Intros;Auto. +Rewrite equal_mem_1 in H;Auto. +Symmetry;Apply equal_mem_2;Auto. +Qed. + +Lemma equal_trans: + (s,u,v:t)(equal s u)=true -> (equal u v)=true -> (equal s v)=true. +Proof. +Intros. +Apply equal_mem_1;Intros. +Rewrite (equal_mem_2 H). +Apply equal_mem_2;Assumption. +Qed. + +Lemma equal_equal: + (s,t_,u:t)(equal s t_)=true -> (equal s u)=(equal t_ u). +Proof. +Intros. +Apply bool_eq_ind;Intros. +Apply equal_trans with t_;Auto with set. +Symmetry; Apply bool_eq_ind;Intros;Auto. +Rewrite <- H0. +Apply equal_trans with s;Auto with set. +Rewrite equal_sym;Auto. +Qed. + +Lemma equal_cardinal: + (s,s':t)(equal s s')=true -> (cardinal s)=(cardinal s'). +Proof. +Intros; Apply Equal_cardinal; Auto. +Qed. + +Hints Resolve equal_refl equal_cardinal equal_equal:set. +Hints Immediate equal_sym :set. + +(* Properties of [subset] *) + +Lemma subset_refl: (s:t)(subset s s)=true. +Proof. +Auto with set. +Qed. + +Lemma subset_antisym: + (s,s':t)(subset s s')=true -> (subset s' s)=true -> (equal s s')=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Apply bool_eq_ind;Intros. +EApply subset_mem_2;EAuto. +Apply (bool_eq_ind (mem a s));Intros;Auto. +Rewrite <- (subset_mem_2 H H2);Assumption. +Qed. + +Lemma subset_trans: + (s,t_,u:t)(subset s t_)=true -> (subset t_ u)=true -> (subset s u)=true. +Proof. +Intros. +Apply subset_mem_1;Intros. +Apply subset_mem_2 with t_;Intros;Auto. +Apply subset_mem_2 with s;Auto. +Qed. + +Lemma subset_equal: + (s,s':t)(equal s s')=true -> (subset s s')=true. +Proof. +Intros. +Apply subset_mem_1;Intros. +Rewrite <- (equal_mem_2 H);Auto. +Qed. + +Hints Resolve subset_refl subset_equal subset_antisym :set. + +(*s Properties of [empty] *) + +Lemma empty_cardinal: (cardinal empty)=O. +Proof. +Rewrite cardinal_fold; Auto with set. +Apply fold_1; Auto. +Qed. + +Hints Immediate empty_cardinal :set. + +(*s Properties of [choose] *) + +Lemma choose_mem_3: + (s:t)(is_empty s)=false -> {x:elt|(choose s)=(Some ? x)/\(mem x s)=true}. +Proof. +Intros. +Generalize (!choose_mem_1 s). +Generalize (!choose_mem_2 s). +Case (choose s);Intros. +Exists e;Auto. +LApply H0;Trivial;Intros. +Rewrite H in H2;Discriminate H2. +Qed. + +Lemma choose_mem_4: (choose empty)=(None ?). +Proof. +Generalize (!choose_mem_1 empty). +Case (!choose empty);Intros;Auto. +Absurd true=false;Auto with bool. +Rewrite <- (H e);Auto with set. +Qed. + +(*s Properties of [add] *) + +Lemma add_mem_3: + (s:t)(x,y:elt)(mem y s)=true -> (mem y (add x s))=true. +Proof. +Auto. +Qed. + +Lemma add_equal: + (s:t)(x:elt)(mem x s)=true -> (equal (add x s) s)=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Elim (ME.eq_dec x a); Intros; Auto with set. +Rewrite <- mem_eq with x:=x;Auto. +Rewrite <- (mem_eq s a0);Auto. +Rewrite H;Auto with set. +Qed. + +Hints Resolve add_mem_3 add_equal :set. + +Lemma add_fold: + (A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory ? eqA)) + (f:elt->A->A)(i:A)(compat_op E.eq eqA f) -> (transpose eqA f) -> + (s:t)(x:elt)(mem x s)=true -> (eqA (fold f (add x s) i) (fold f s i)). +Proof. +Intros; Apply fold_equal with eqA:=eqA; Auto with set. +Qed. + +Lemma add_cardinal_1: + (s:t)(x:elt)(mem x s)=true -> (cardinal (add x s))=(cardinal s). +Proof. +Auto with set. +Qed. + +Lemma add_cardinal_2: + (s:t)(x:elt)(mem x s)=false -> (cardinal (add x s))=(S (cardinal s)). +Proof. +Intros. +Do 2 Rewrite cardinal_fold. +Change S with ([_]S x); Apply fold_add with eqA:=(eq nat); Auto. +Qed. + +(*s Properties of [remove] *) + +Lemma remove_mem_3: + (s:t)(x,y:elt)(mem y (remove x s))=true -> (mem y s)=true. +Proof. +Intros s x y;Elim (ME.eq_dec x y); Intro e. +Rewrite <- mem_eq with x:=x;Auto. +Rewrite <- (mem_eq s e);Auto. +Rewrite (remove_mem_1 s x);Intro H;Discriminate H. +Intros;Rewrite <- H;Symmetry;Auto with set. +Qed. + +Lemma remove_equal: + (s:t)(x:elt)(mem x s)=false -> (equal (remove x s) s)=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Elim (ME.eq_dec x a); Intros;Auto with set. +Rewrite <- mem_eq with x:=x;Auto. +Rewrite <- (mem_eq s a0);Auto;Rewrite H;Auto with set. +Qed. + +Hints Resolve remove_mem_3 remove_equal :set. + +Lemma add_remove: + (s:t)(x:elt)(mem x s)=true -> (equal (add x (remove x s)) s)=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Elim (ME.eq_dec x a); Intros;Auto with set. +Rewrite <- mem_eq with x:=x;Auto. +Rewrite <- (mem_eq s a0);Auto;Rewrite H;Auto with set. +Transitivity (mem a (remove x s));Auto with set. +Qed. + +Lemma remove_add: + (s:t)(x:elt)(mem x s)=false -> (equal (remove x (add x s)) s)=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Elim (ME.eq_dec x a); Intros;Auto with set. +Rewrite <- mem_eq with x:=x;Auto. +Rewrite <- (mem_eq s a0);Auto;Rewrite H;Auto with set. +Transitivity (mem a (add x s));Auto with set. +Qed. + +Hints Immediate add_remove remove_add :set. + +Lemma remove_fold_1: + (A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory ? eqA)) + (f:elt->A->A)(i:A)(compat_op E.eq eqA f) -> (transpose eqA f) -> + (s:t)(x:elt)(mem x s)=true -> + (eqA (f x (fold f (remove x s) i)) (fold f s i)). +Proof. +Intros. +Apply Seq_sym; Auto. +Apply fold_2 with eqA:=eqA; Auto. +Apply Add_remove; Auto. +Qed. + +Lemma remove_fold_2: + (A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory ? eqA)) + (f:elt->A->A)(i:A) (compat_op E.eq eqA f) -> (transpose eqA f) -> + (s:t)(x:elt)(mem x s)=false -> + (eqA (fold f (remove x s) i) (fold f s i)). +Proof. +Intros. +Apply fold_equal with eqA:=eqA; Auto with set. +Qed. + +Lemma remove_cardinal_1: + (s:t)(x:elt)(mem x s)=true -> (S (cardinal (remove x s)))=(cardinal s). +Proof. +Intros. +Do 2 Rewrite cardinal_fold. +Change S with ([_]S x). +Apply remove_fold_1 with eqA:=(eq nat); Auto. +Qed. + +Lemma remove_cardinal_2: + (s:t)(x:elt)(mem x s)=false -> (cardinal (remove x s))=(cardinal s). +Proof. +Auto with set. +Qed. + +(* Properties of [is_empty] *) + +Lemma is_empty_cardinal: (s:t)(is_empty s)=(zerob (cardinal s)). +Proof. +Intros. +Apply (bool_eq_ind (is_empty s));Intros. +Rewrite (equal_cardinal 1!s 2!empty). +Rewrite empty_cardinal;Simpl;Trivial. +Rewrite <- H;Symmetry;Auto with set. +Elim (choose_mem_3 H);Intros. +Elim p;Intros. +Rewrite <- (remove_cardinal_1 H1). +Simpl;Trivial. +Qed. + +(*s Properties of [singleton] *) + +Lemma singleton_mem_1: (x:elt)(mem x (singleton x))=true. +Proof. +Intros. +Rewrite (equal_mem_2 (singleton_equal_add x));Auto with set. +Qed. + +Lemma singleton_mem_2: (x,y:elt)~(E.eq x y) -> (mem y (singleton x))=false. +Proof. +Intros. +Rewrite (equal_mem_2 (singleton_equal_add x)). +Rewrite <- (empty_mem y);Auto with set. +Qed. + +Lemma singleton_mem_3: (x,y:elt)(mem y (singleton x))=true -> (E.eq x y). +Proof. +Intros. +Elim (ME.eq_dec x y);Intros;Auto. +Qed. + +Lemma singleton_cardinal: (x:elt)(cardinal (singleton x))=(S O). +Proof. +Intros. +Rewrite (equal_cardinal (singleton_equal_add x)). +Rewrite add_cardinal_2;Auto with set. +Qed. + +(* General recursion principes based on [cardinal] *) + +Lemma cardinal_set_rec: (P:t->Set) + ((s,s':t)(equal s s')=true -> (P s) -> (P s')) -> + ((s:t)(x:elt)(mem x s)=false -> (P s) -> (P (add x s))) -> + (P empty) -> (n:nat)(s:t)(cardinal s)=n -> (P s). +Proof. +NewInduction n; Intro s; Generalize (is_empty_cardinal s); + Intros eq1 eq2; Rewrite eq2 in eq1; Simpl in eq1. +Rewrite is_empty_equal_empty in eq1. +Rewrite equal_sym in eq1. +Apply (H empty s eq1);Auto. +Elim (choose_mem_3 eq1);Intros;Elim p;Clear p;Intros. +Apply (H (add x (remove x s)) s);Auto with set. +Apply H0;Auto with set. +Apply IHn. +Rewrite <- (remove_cardinal_1 H3) in eq2. +Inversion eq2;Trivial. +Qed. + +Lemma set_rec: (P:t->Set) + ((s,s':t)(equal s s')=true -> (P s) -> (P s')) -> + ((s:t)(x:elt)(mem x s)=false -> (P s) -> (P (add x s))) -> + (P empty) -> (s:t)(P s). +Proof. +Intros;EApply cardinal_set_rec;EAuto. +Qed. + +Lemma cardinal_set_ind: (P:t->Prop) + ((s,s':t)(equal s s')=true -> (P s) -> (P s')) -> + ((s:t)(x:elt)(mem x s)=false -> (P s) -> (P (add x s))) -> + (P empty) -> (n:nat)(s:t)(cardinal s)=n -> (P s). +Proof. +NewInduction n; Intro s; Generalize (is_empty_cardinal s); + Intros eq1 eq2; Rewrite eq2 in eq1; Simpl in eq1. +Rewrite is_empty_equal_empty in eq1. +Rewrite equal_sym in eq1. +Apply (H empty s eq1);Auto. +Elim (choose_mem_3 eq1);Intros;Elim p;Clear p;Intros. +Apply (H (add x (remove x s)) s);Auto with set. +Apply H0;Auto with set. +Apply IHn. +Rewrite <- (remove_cardinal_1 H3) in eq2. +Inversion eq2;Trivial. +Qed. + +Lemma set_ind: (P:t->Prop) + ((s,s':t)(equal s s')=true -> (P s) -> (P s')) -> + ((s:t)(x:elt)(mem x s)=false -> (P s) -> (P (add x s))) -> + (P empty) -> (s:t)(P s). +Proof. +Intros;EApply cardinal_set_ind;EAuto. +Qed. + +(*s Properties of [fold] *) + +Lemma fold_commutes: + (A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory ? eqA)) + (f:elt->A->A)(i:A)(compat_op E.eq eqA f) -> (transpose eqA f) -> (s:t)(x:elt) + (eqA (fold f s (f x i)) (f x (fold f s i))). +Proof. +Intros; Pattern s; Apply set_ind. +Intros. +Apply (Seq_trans ?? st) with (fold f s0 (f x i)). +Apply fold_equal with eqA:=eqA; Auto with set. +Rewrite equal_sym; Auto. +Apply (Seq_trans ?? st) with (f x (fold f s0 i)); Auto. +Apply H; Auto. +Apply fold_equal with eqA:=eqA; Auto. +Intros. +Apply (Seq_trans ?? st) with (f x0 (fold f s0 (f x i))). +Apply fold_add with eqA:=eqA; Auto. +Apply (Seq_trans ?? st) with (f x0 (f x (fold f s0 i))). +Apply H; Auto. +Apply (Seq_trans ?? st) with (f x (f x0 (fold f s0 i))). +Apply H0; Auto. +Apply H; Auto. +Apply Seq_sym; Auto. +Apply fold_add with eqA:=eqA; Auto. +Apply (Seq_trans ?? st) with (f x i). +Apply fold_empty; Auto. +Apply Seq_sym; Auto. +Apply H; Auto. +Apply fold_empty; Auto. +Qed. + +Lemma fold_plus: + (s:t)(p:nat)(fold [_]S s p)=(fold [_]S s O)+p. +Proof. +Assert st := (gen_st nat). +Assert fe: (compat_op E.eq (eq ?) [_:elt]S). Unfold compat_op; Auto. +Assert fp: (transpose (eq ?) [_:elt]S). Unfold transpose;Auto. +Intros s p;Pattern s;Apply set_ind. +Intros; Rewrite <- (fold_equal st p fe fp H). +Rewrite <- (fold_equal st O fe fp H);Assumption. +Intros. +Assert (p:nat)(fold [_]S (add x s0) p) = (S (fold [_]S s0 p)). +Change S with ([_]S x). +Intros; Apply fold_add with eqA:=(eq nat); Auto. +Rewrite (H1 p). +Rewrite (H1 O). +Rewrite H0. +Simpl; Auto. +Intros; Do 2 Rewrite (fold_empty st);Auto. +Qed. + +(*s Properties of [union] *) + +Lemma union_sym: + (s,s':t)(equal (union s s') (union s' s))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 2 Rewrite union_mem;Auto with bool. +Qed. + +Lemma union_subset_equal: + (s,s':t)(subset s s')=true->(equal (union s s') s')=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Rewrite union_mem. +Apply (bool_eq_ind (mem a s));Intros;Simpl;Auto with set. +Rewrite (subset_mem_2 H H0);Auto. +Qed. + +Lemma union_equal_1: + (s,s',s'':t)(equal s s')=true-> + (equal (union s s'') (union s' s''))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 2 (Rewrite union_mem;Idtac). +Rewrite (equal_mem_2 H a);Auto. +Qed. + +Lemma union_equal_2: + (s,s',s'':t)(equal s' s'')=true-> + (equal (union s s') (union s s''))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 2 (Rewrite union_mem;Idtac). +Rewrite (equal_mem_2 H a);Auto. +Qed. + +Lemma union_assoc: + (s,s',s'':t) + (equal (union (union s s') s'') (union s (union s' s'')))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 4 Rewrite union_mem. +Rewrite orb_assoc;Auto. +Qed. + +Lemma add_union_singleton: + (s:t)(x:elt)(equal (add x s) (union (singleton x) s))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Rewrite union_mem. +Elim (ME.eq_dec x a);Intros. +Rewrite <- (mem_eq (add x s) a0). +Rewrite <- (mem_eq (singleton x) a0). +Rewrite <- (mem_eq s a0). +Rewrite add_mem_1;Rewrite singleton_mem_1;Simpl;Auto. +Rewrite singleton_mem_2;Simpl;Auto with set. +Qed. + +Lemma union_add: + (s,s':t)(x:elt) + (equal (union (add x s) s') (add x (union s s')))=true. +Proof. +Intros;Apply equal_trans with (union (union (singleton x) s) s'). +Apply union_equal_1;Apply add_union_singleton. +Apply equal_trans with (union (singleton x) (union s s')). +Apply union_assoc. +Rewrite equal_sym;Apply add_union_singleton. +Qed. + +(* caracterisation of [union] via [subset] *) + +Lemma union_subset_1: + (s,s':t)(subset s (union s s'))=true. +Proof. +Intros;Apply subset_mem_1;Intros;Rewrite union_mem;Rewrite H;Auto. +Qed. + +Lemma union_subset_2: + (s,s':t)(subset s' (union s s'))=true. +Proof. +Intros;Apply subset_mem_1;Intros;Rewrite union_mem;Rewrite H;Apply orb_b_true. +Qed. + +Lemma union_subset_3: + (s,s',s'':t)(subset s s'')=true -> (subset s' s'')=true -> + (subset (union s s') s'')=true. +Proof. +Intros;Apply subset_mem_1;Intros;Rewrite union_mem in H1. +Elim (orb_true_elim ? ? H1);Intros. +Apply (subset_mem_2 H a0). +Apply (subset_mem_2 H0 b). +Qed. + +(*s Properties of [inter] *) + +Lemma inter_sym: + (s,s':t)(equal (inter s s') (inter s' s))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 2 Rewrite inter_mem. +Auto with bool. +Qed. + +Lemma inter_subset_equal: + (s,s':t)(subset s s')=true->(equal (inter s s') s)=true. +Proof. +Intros. +Apply equal_mem_1;Intros. +Rewrite inter_mem. +Apply (bool_eq_ind (mem a s));Intros;Simpl;Auto. +Rewrite (subset_mem_2 H H0);Auto. +Qed. + +Lemma inter_equal_1: + (s,s',s'':t)(equal s s')=true-> + (equal (inter s s'') (inter s' s''))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 2 (Rewrite inter_mem;Idtac). +Rewrite (equal_mem_2 H a);Auto. +Qed. + +Lemma inter_equal_2: + (s,s',s'':t)(equal s' s'')=true-> + (equal (inter s s') (inter s s''))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 2 (Rewrite inter_mem;Idtac). +Rewrite (equal_mem_2 H a);Auto. +Qed. + +Lemma inter_assoc: + (s,s',s'':t) + (equal (inter (inter s s') s'') (inter s (inter s' s'')))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Do 4 Rewrite inter_mem. +Rewrite andb_assoc;Auto. +Qed. + +Lemma union_inter_1: + (s,s',s'':t) + (equal (inter (union s s') s'') (union (inter s s'') (inter s' s'')))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Rewrite union_mem. +Do 3 Rewrite inter_mem. +Rewrite union_mem. +Apply demorgan2. +Qed. + +Lemma union_inter_2: + (s,s',s'':t) + (equal (union (inter s s') s'') (inter (union s s'') (union s' s'')))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Rewrite union_mem. +Do 2 Rewrite inter_mem. +Do 2 Rewrite union_mem. +Apply demorgan4. +Qed. + +Lemma inter_add_1: + (s,s':t)(x:elt)(mem x s')=true -> + (equal (inter (add x s) s') (add x (inter s s')))=true. +Proof. +Intros;Apply equal_trans with (inter (union (singleton x) s) s'). +Apply inter_equal_1;Apply add_union_singleton. +Apply equal_trans with (union (inter (singleton x) s') (inter s s')). +Apply union_inter_1. +Apply equal_trans with (union (singleton x) (inter s s')). +Apply union_equal_1. +Apply inter_subset_equal. +Apply subset_mem_1;Intros. +Rewrite <- (mem_eq s' (singleton_mem_3 H0));Auto. +Rewrite equal_sym;Apply add_union_singleton. +Qed. + +Lemma inter_add_2: + (s,s':t)(x:elt)(mem x s')=false -> + (equal (inter (add x s) s') (inter s s'))=true. +Proof. +Intros;Apply equal_trans with (inter (union (singleton x) s) s'). +Apply inter_equal_1;Apply add_union_singleton. +Apply equal_trans with (union (inter (singleton x) s') (inter s s')). +Apply union_inter_1. +Apply union_subset_equal. +Apply subset_mem_1;Intros. +Rewrite inter_mem in H0. +Elim (andb_prop ? ? H0);Intros. +Absurd (mem a s')=true;Auto. +Rewrite <- (mem_eq s' (singleton_mem_3 H1));Auto. +Rewrite H;Auto with bool. +Qed. + +(* caracterisation of [union] via [subset] *) + +Lemma inter_subset_1: + (s,s':t)(subset (inter s s') s)=true. +Proof. +Intros;Apply subset_mem_1;Intros;Rewrite inter_mem in H;Elim (andb_prop ? ? H);Auto. +Qed. + +Lemma inter_subset_2: + (s,s':t)(subset (inter s s') s')=true. +Proof. +Intros;Apply subset_mem_1;Intros;Rewrite inter_mem in H;Elim (andb_prop ? ? H);Auto. +Qed. + +Lemma inter_subset_3: + (s,s',s'':t)(subset s'' s)=true -> (subset s'' s')=true -> + (subset s'' (inter s s'))=true. +Intros;Apply subset_mem_1;Intros;Rewrite inter_mem. +Rewrite (subset_mem_2 H H1);Rewrite (subset_mem_2 H0 H1);Auto. +Qed. + +(*s Properties of [union],[inter],[fold] and [cardinal] *) + +Lemma fold_union_inter: + (A:Set) + (f:elt->A->A)(i:A)(compat_op E.eq (eq ?) f) -> (transpose (eq ?) f) -> + (s,s':t)(fold f (union s s') (fold f (inter s s') i)) + = (fold f s (fold f s' i)). +Proof. +Intro A. +LetTac st := (gen_st A). +Intros;Pattern s;Apply set_ind. +Intros; Rewrite <- (fold_equal st i H H0 (inter_equal_1 s' H1)). +Rewrite <- (fold_equal st (fold f s' i) H H0 H1). +Rewrite <- (fold_equal st (fold f (inter s0 s') i) H H0 (union_equal_1 s' H1));Auto. +Intros. +Rewrite + (fold_equal st (fold f (inter (add x s0) s') i) H H0 (union_add s0 s' x)). +Generalize (refl_equal ? (mem x s')); Pattern -1 (mem x s'); Case (mem x s');Intros. +Rewrite (fold_equal st i H H0 (inter_add_1 s0 H3)). +Cut (mem x (inter s0 s'))=false;Intros. +Cut (mem x (union s0 s'))=true;Intros. +Rewrite (fold_add st i H H0 H4). +Rewrite (fold_commutes st);Auto. +Rewrite (fold_equal st (fold f (inter s0 s') i) H H0 (add_equal H5)). +Rewrite (fold_add st (fold f s' i) H H0 H1). +Rewrite H2;Auto. +Rewrite union_mem;Rewrite H3;Apply orb_b_true. +Rewrite inter_mem;Rewrite H1;Simpl;Auto. +Rewrite (fold_equal st i H H0 (inter_add_2 s0 H3)). +Cut (mem x (union s0 s'))=false;Intros. +Rewrite (fold_add st (fold f (inter s0 s') i) H H0 H4). +Rewrite (fold_add st (fold f s' i) H H0 H1). +Rewrite H2;Auto. +Rewrite union_mem;Rewrite H3; Rewrite H1;Auto. +Cut (subset empty s')=true;Intros. +Rewrite (fold_equal st i H H0 (inter_subset_equal H1)). +Do 2 Rewrite (fold_empty st);Apply fold_equal with eqA:=(eq A);Auto. +Apply union_subset_equal;Auto. +Apply subset_mem_1;Intros. +Rewrite empty_mem in H1;Absurd true=false;Auto with bool. +Qed. + +Lemma union_inter_cardinal: + (s,s':t)(cardinal (union s s'))+(cardinal (inter s s')) + = (cardinal s)+(cardinal s'). +Proof. +Intros. +Do 4 Rewrite cardinal_fold. +Do 2 Rewrite <- fold_plus. +Apply fold_union_inter;Auto. +Qed. + +Lemma fold_union: + (A:Set)(f:elt->A->A)(i:A)(compat_op E.eq (eq A) f) -> (transpose (eq A) f) -> + (s,s':t)((x:elt)(andb (mem x s) (mem x s'))=false) -> + (fold f (union s s') i)=(fold f s (fold f s' i)). +Proof. +Intros. +Assert st:= (gen_st A). +Rewrite <- (fold_union_inter i H H0 s s'). +Cut (equal (inter s s') empty)=true;Intros. +Rewrite (fold_equal st i H H0 H2). +Rewrite (fold_empty st);Auto. +Apply equal_mem_1;Intros. +Rewrite inter_mem; Rewrite empty_mem;Auto. +Qed. + +Lemma union_cardinal: + (s,s':t)((x:elt)(andb (mem x s) (mem x s'))=false) -> + (cardinal (union s s'))=(cardinal s)+(cardinal s'). +Proof. +Intros. +Do 3 Rewrite cardinal_fold. +Rewrite fold_union;Auto. +Apply fold_plus;Auto. +Qed. + +(*s Properties of [diff] *) + +Lemma diff_subset: + (s,s':t)(subset (diff s s') s)=true. +Proof. +Intros. +Apply subset_mem_1;Intros. +Rewrite diff_mem in H. +Elim (andb_prop ? ? H);Auto. +Qed. + +Lemma diff_subset_equal: + (s,s':t)(subset s s')=true->(equal (diff s s') empty)=true. +Proof. +Intros. +Apply equal_mem_1;Intros. +Rewrite empty_mem. +Rewrite diff_mem. +Generalize (!subset_mem_2 ?? H a). +Case (mem a s);Simpl;Intros;Auto. +Rewrite H0;Auto. +Qed. + +Lemma remove_inter_singleton: + (s:t)(x:elt)(equal (remove x s) (diff s (singleton x)))=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Rewrite diff_mem. +Elim (ME.eq_dec x a); Intros. +Rewrite <- (mem_eq (remove x s) a0). +Rewrite <- (mem_eq s a0). +Rewrite <- (mem_eq (singleton x) a0). +Rewrite remove_mem_1;Rewrite singleton_mem_1;Rewrite andb_b_false;Auto. +Rewrite singleton_mem_2;Auto;Simpl;Rewrite andb_b_true;Auto with set. +Qed. + +Lemma diff_inter_empty: + (s,s':t)(equal (inter (diff s s') (inter s s')) empty)=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Rewrite empty_mem;Do 2 Rewrite inter_mem;Rewrite diff_mem. +Case (mem a s);Case (mem a s');Simpl;Auto. +Qed. + +Lemma diff_inter_all: +(s,s':t)(equal (union (diff s s') (inter s s')) s)=true. +Proof. +Intros;Apply equal_mem_1;Intros. +Rewrite union_mem;Rewrite inter_mem;Rewrite diff_mem. +Case (mem a s);Case (mem a s');Simpl;Auto. +Qed. + +Lemma fold_diff_inter: + (A:Set)(f:elt->A->A)(i:A)(compat_op E.eq (eq A) f) -> (transpose (eq A) f) -> + (s,s':t)(fold f (diff s s') (fold f (inter s s') i))=(fold f s i). +Proof. +Intros. +Assert st := (gen_st A). +Rewrite <- (fold_union_inter i H H0 (diff s s') (inter s s')). +Rewrite (fold_equal st i H H0 (diff_inter_empty s s')). +Rewrite (fold_empty st). +Apply fold_equal with eqA:=(eq A);Auto. +Apply diff_inter_all. +Qed. + +Lemma diff_inter_cardinal: + (s,s':t)(cardinal (diff s s'))+(cardinal (inter s s'))=(cardinal s). +Proof. +Intros. +Do 3 Rewrite cardinal_fold. +Rewrite <- fold_plus. +Apply fold_diff_inter; Auto. +Qed. + +Lemma subset_cardinal: + (s,s':t)(subset s s')=true -> (le (cardinal s) (cardinal s')). +Proof. +Intros. +Rewrite <- (diff_inter_cardinal s' s). +Rewrite (equal_cardinal (inter_sym s' s)). +Rewrite (equal_cardinal (inter_subset_equal H)); Auto with arith. +Qed. + +(*s Properties of [for_all] *) + +Section For_all. + +Variable f : elt->bool. +Variable Comp : (compat_bool E.eq f). + +Local Comp' : (compat_bool E.eq [x](negb (f x))). +Proof. +Generalize Comp; Unfold compat_bool; Intros; Apply (f_equal ?? negb);Auto. +Qed. + +Lemma for_all_mem_1: + (s:t)((x:elt)(mem x s)=true->(f x)=true) -> (for_all f s)=true. +Proof. +Intros. +Rewrite for_all_filter; Auto. +Rewrite is_empty_equal_empty. +Apply equal_mem_1;Intros. +Rewrite filter_mem; Auto. +Rewrite empty_mem. +Generalize (H a); Case (mem a s);Intros;Auto. +Rewrite H0;Auto. +Qed. + +Lemma for_all_mem_2: + (s:t)(for_all f s)=true -> (x:elt)(mem x s)=true -> (f x)=true. +Proof. +Intros. +Rewrite for_all_filter in H; Auto. +Rewrite is_empty_equal_empty in H. +Generalize (equal_mem_2 H x). +Rewrite filter_mem; Auto. +Rewrite empty_mem. +Rewrite H0; Simpl;Intros. +Replace true with (negb false);Auto;Apply negb_sym;Auto. +Qed. + +Lemma for_all_mem_3: + (s:t)(x:elt)(mem x s)=true -> (f x)=false -> (for_all f s)=false. +Proof. +Intros. +Apply (bool_eq_ind (for_all f s));Intros;Auto. +Rewrite for_all_filter in H1; Auto. +Rewrite is_empty_equal_empty in H1. +Generalize (equal_mem_2 H1 x). +Rewrite filter_mem; Auto. +Rewrite empty_mem. +Rewrite H. +Rewrite H0. +Simpl;Auto. +Qed. + +Lemma for_all_mem_4: + (s:t)(for_all f s)=false -> {x:elt | (mem x s)=true /\ (f x)=false}. +Intros. +Rewrite for_all_filter in H; Auto. +Elim (choose_mem_3 H);Intros;Elim p;Intros. +Exists x. +Rewrite filter_mem in H1; Auto. +Elim (andb_prop ? ? H1). +Split;Auto. +Replace false with (negb true);Auto;Apply negb_sym;Auto. +Qed. + +End For_all. + +(*s Properties of [exists] *) + +Section Exists. + +Variable f : elt->bool. +Variable Comp : (compat_bool E.eq f). + +Local Comp' : (compat_bool E.eq [x](negb (f x))). +Proof. +Generalize Comp; Unfold compat_bool; Intros; Apply (f_equal ?? negb);Auto. +Qed. + +Lemma for_all_exists: + (s:t)(exists f s)=(negb (for_all [x](negb (f x)) s)). +Proof. +Intros. +Rewrite for_all_filter; Auto. +Rewrite exists_filter; Auto. +Apply (f_equal ? ? negb). +Do 2 Rewrite is_empty_equal_empty. +Apply equal_equal. +Apply equal_mem_1;Intros. +Do 2 (Rewrite filter_mem; Auto). +Rewrite negb_elim;Auto. +Generalize Comp'; Unfold compat_bool; Intros; Apply (f_equal ? ? negb); Auto. +Qed. + +Lemma exists_mem_1: + (s:t)((x:elt)(mem x s)=true->(f x)=false) -> (exists f s)=false. +Proof. +Intros. +Rewrite for_all_exists; Auto. +Rewrite for_all_mem_1;Auto with bool. +Intros;Generalize (H x H0);Intros. +Symmetry;Apply negb_sym;Simpl;Auto. +Qed. + +Lemma exists_mem_2: + (s:t)(exists f s)=false -> (x:elt)(mem x s)=true -> (f x)=false. +Proof. +Intros. +Rewrite for_all_exists in H. +Replace false with (negb true);Auto;Apply negb_sym;Symmetry. +Rewrite (for_all_mem_2 1![x](negb (f x)) Comp' 3!s);Simpl;Auto. +Replace true with (negb false);Auto;Apply negb_sym;Auto. +Qed. + +Lemma exists_mem_3: + (s:t)(x:elt)(mem x s)=true -> (f x)=true -> (exists f s)=true. +Proof. +Intros. +Rewrite for_all_exists. +Symmetry;Apply negb_sym;Simpl. +Apply for_all_mem_3 with x;Auto. +Rewrite H0;Auto. +Qed. + +Lemma exists_mem_4: + (s:t)(exists f s)=true -> {x:elt | (mem x s)=true /\ (f x)=true}. +Proof. +Intros. +Rewrite for_all_exists in H. +Elim (for_all_mem_4 1![x](negb (f x)) Comp' 3!s);Intros. +Elim p;Intros. +Exists x;Split;Auto. +Replace true with (negb false);Auto;Apply negb_sym;Auto. +Replace false with (negb true);Auto;Apply negb_sym;Auto. +Qed. + +End Exists. + +Section Sum. + + +Definition sum := [f:elt -> nat; s:t](fold [x](plus (f x)) s 0). + +Definition compat_nat := [A:Set][eqA:A->A->Prop][f:A->nat] + (x,x':A)(eqA x x') -> (f x)=(f x'). +Hints Unfold compat_nat. + +Lemma sum_plus : + (f,g:elt ->nat)(compat_nat E.eq f) -> (compat_nat E.eq g) -> + (s:t)(sum [x]((f x)+(g x)) s) = (sum f s)+(sum g s). +Proof. +Unfold sum. +Intros f g Hf Hg. +Assert fc : (compat_op E.eq (eq ?) [x:elt](plus (f x))). Auto. +Assert ft : (transpose (eq ?) [x:elt](plus (f x))). Red; Intros; Omega. +Assert gc : (compat_op E.eq (eq ?) [x:elt](plus (g x))). Auto. +Assert gt : (transpose (eq ?) [x:elt](plus (g x))). Red; Intros; Omega. +Assert fgc : (compat_op E.eq (eq ?) [x:elt](plus ((f x)+(g x)))). Auto. +Assert fgt : (transpose (eq ?) [x:elt](plus ((f x)+(g x)))). Red; Intros; Omega. +Assert st := (gen_st nat). +Intros s;Pattern s; Apply set_ind. +Intros. +Rewrite <- (fold_equal st O fc ft H). +Rewrite <- (fold_equal st O gc gt H). +Rewrite <- (fold_equal st O fgc fgt H); Auto. +Assert fold_add' := [s:t; t:elt](!fold_add s t ?? st). +Intros; Do 3 (Rewrite fold_add';Auto). +Rewrite H0;Simpl;Omega. +Intros; Do 3 Rewrite (fold_empty st);Auto. +Qed. + +Lemma filter_equal : (f:elt -> bool)(compat_bool E.eq f) -> + (s,s':t)(Equal s s') -> (Equal (filter f s) (filter f s')). +Proof. +Unfold Equal; Split; Intros; Elim (H0 a); Intros; Apply filter_3; EAuto. +Qed. + +Lemma add_filter_1 : (f:elt -> bool)(compat_bool E.eq f) -> + (s,s':t)(x:elt) (f x)=true -> (Add x s s') -> (Add x (filter f s) (filter f s')). +Proof. +Unfold Add; Split; Intros; Elim (H1 y); Clear H1; Intros. +Elim H1; [ Auto | Right; EAuto | EAuto ]. +Apply filter_3; Auto. +Elim H2; Intros. +Intuition. +Apply H3; Right; EAuto. +Elim H2; Intros. +Rewrite <- H0; Auto. +EAuto. +Qed. + +Lemma add_filter_2 : (f:elt -> bool)(compat_bool E.eq f) -> + (s,s':t)(x:elt) (f x)=false -> (Add x s s') -> (Equal (filter f s) (filter f s')). +Proof. +Unfold Add Equal; Split; Intros; Elim (H1 a); Clear H1; Intros. +Elim H1; Intros. +Absurd true=false; Auto with bool. +Rewrite <- H0. +Rewrite <- (filter_2 H H2); Auto. +Apply filter_3; EAuto. +Apply H3; Right; EAuto. + +Elim H1; Intros. +Absurd true=false; Auto with bool. +Rewrite <- H0. +Rewrite <- (filter_2 H H2); Auto. +EAuto. +EAuto. +Qed. + +Lemma sum_filter : (f:elt -> bool)(compat_bool E.eq f) -> + (s:t)(sum [x](if (f x) then 1 else 0) s) = (cardinal (filter f s)). +Proof. +Unfold sum; Intros f Hf. +Assert st := (gen_st nat). +Assert fold_add' := [s:t; t:elt](!fold_add s t ?? st). +Assert cc : (compat_op E.eq (eq ?) [x:elt](plus (if (f x) then 1 else 0))). + Unfold compat_op; Intros. + Rewrite (Hf x x' H); Auto. +Assert ct : (transpose (eq ?) [x:elt](plus (if (f x) then 1 else 0))). + Unfold transpose; Intros; Omega. +Intros s;Pattern s; Apply set_ind. +Intros. +Rewrite <- (fold_equal st O cc ct H). +Rewrite <- (Equal_cardinal (filter_equal Hf (equal_2 H))); Auto. +Intros; Rewrite fold_add'; Auto. +Generalize (!add_filter_1 f Hf s0 (add x s0) x) (!add_filter_2 f Hf s0 (add x s0) x) . +Assert ~(In x (filter f s0)). + Intro H1; Rewrite (mem_1 (filter_1 Hf H1)) in H; Discriminate H. +Case (f x); Simpl; Intuition. +Rewrite (cardinal_2 H1 (H4 (Add_add s0 x))); Auto. +Rewrite <- (Equal_cardinal (H4 (Add_add s0 x))); Auto. +Intros; Rewrite (fold_empty st);Auto. +Rewrite cardinal_1; Auto. +Unfold Empty; Intuition. +Elim (!empty_1 a); EAuto. +Qed. + +Lemma fold_compat : + (A:Set)(eqA:A->A->Prop)(st:(Setoid_Theory ? eqA)) + (f,g:elt->A->A) + (compat_op E.eq eqA f) -> (transpose eqA f) -> + (compat_op E.eq eqA g) -> (transpose eqA g) -> + (i:A)(s:t)((x:elt)(In x s) -> (y:A)(eqA (f x y) (g x y))) -> + (eqA (fold f s i) (fold g s i)). +Proof. +Intros A eqA st f g fc ft gc gt i. +Intro s; Pattern s; Apply set_ind; Intros. +Apply (Seq_trans ?? st) with (fold f s0 i). +Apply fold_equal with eqA:=eqA; Auto. +Rewrite equal_sym; Auto. +Apply (Seq_trans ?? st) with (fold g s0 i). +Apply H0; Intros; Apply H1; Auto. +Elim (equal_2 H x); Intuition. +Apply fold_equal with eqA:=eqA; Auto. +Apply (Seq_trans ?? st) with (f x (fold f s0 i)). +Apply fold_add with eqA:=eqA; Auto. +Apply (Seq_trans ?? st) with (g x (fold f s0 i)). +Apply H1; Auto with set. +Apply (Seq_trans ?? st) with (g x (fold g s0 i)). +Apply gc; Auto. +Apply Seq_sym; Auto; Apply fold_add with eqA:=eqA; Auto. +Apply (Seq_trans ?? st) with i; [Idtac | Apply Seq_sym; Auto]; Apply fold_empty; Auto. +Qed. + +Lemma sum_compat : + (f,g:elt->nat)(compat_nat E.eq f) -> (compat_nat E.eq g) -> + (s:t)((x:elt)(In x s) -> (f x)=(g x)) -> (sum f s)=(sum g s). +Intros. +Unfold sum; Apply (!fold_compat ? (eq nat)); Auto. +Unfold transpose; Intros; Omega. +Unfold transpose; Intros; Omega. +Qed. + +End Sum. + +Lemma filter_orb: (f,g:elt->bool)(compat_bool E.eq f) -> (compat_bool E.eq g) -> + (s:t)(Equal (filter [x:elt](orb (f x) (g x)) s) (union (filter f s) (filter g s))). +Proof. +Intros. +Assert (compat_bool E.eq [x](orb (f x) (g x))). + Unfold compat_bool; Intros. + Rewrite (H x y H1). + Rewrite (H0 x y H1); Auto. +Unfold Equal; Split; Intros. +Assert H3 := (filter_1 H1 H2). +Assert H4 := (filter_2 H1 H2). +Elim (orb_prop ?? H4); Intros; EAuto. +Elim (union_1 H2); Intros. +Apply filter_3; [ Auto | EAuto | Rewrite (filter_2 H H3); Auto ]. +Apply filter_3; [ Auto | EAuto | Rewrite (filter_2 H0 H3); Auto with bool]. +Qed. + +End MoreProperties. +Hints Unfold compat_nat. + +End Properties. |