diff --git a/src/ZF/Nat.thy b/src/ZF/Nat.thy --- a/src/ZF/Nat.thy +++ b/src/ZF/Nat.thy @@ -1,302 +1,297 @@ (* Title: ZF/Nat.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\The Natural numbers As a Least Fixed Point\ theory Nat imports OrdQuant Bool begin definition nat :: i where "nat == lfp(Inf, %X. {0} \ {succ(i). i \ X})" definition quasinat :: "i => o" where "quasinat(n) == n=0 | (\m. n = succ(m))" definition (*Has an unconditional succ case, which is used in "recursor" below.*) nat_case :: "[i, i=>i, i]=>i" where "nat_case(a,b,k) == THE y. k=0 & y=a | (\x. k=succ(x) & y=b(x))" definition nat_rec :: "[i, i, [i,i]=>i]=>i" where "nat_rec(k,a,b) == wfrec(Memrel(nat), k, %n f. nat_case(a, %m. b(m, f`m), n))" (*Internalized relations on the naturals*) definition Le :: i where "Le == {:nat*nat. x \ y}" definition Lt :: i where "Lt == {:nat*nat. x < y}" definition Ge :: i where "Ge == {:nat*nat. y \ x}" definition Gt :: i where "Gt == {:nat*nat. y < x}" definition greater_than :: "i=>i" where "greater_than(n) == {i \ nat. n < i}" text\No need for a less-than operator: a natural number is its list of predecessors!\ lemma nat_bnd_mono: "bnd_mono(Inf, %X. {0} \ {succ(i). i \ X})" apply (rule bnd_monoI) apply (cut_tac infinity, blast, blast) done (* @{term"nat = {0} \ {succ(x). x \ nat}"} *) lemmas nat_unfold = nat_bnd_mono [THEN nat_def [THEN def_lfp_unfold]] (** Type checking of 0 and successor **) lemma nat_0I [iff,TC]: "0 \ nat" apply (subst nat_unfold) apply (rule singletonI [THEN UnI1]) done lemma nat_succI [intro!,TC]: "n \ nat ==> succ(n) \ nat" apply (subst nat_unfold) apply (erule RepFunI [THEN UnI2]) done lemma nat_1I [iff,TC]: "1 \ nat" by (rule nat_0I [THEN nat_succI]) lemma nat_2I [iff,TC]: "2 \ nat" by (rule nat_1I [THEN nat_succI]) lemma bool_subset_nat: "bool \ nat" by (blast elim!: boolE) lemmas bool_into_nat = bool_subset_nat [THEN subsetD] subsection\Injectivity Properties and Induction\ (*Mathematical induction*) lemma nat_induct [case_names 0 succ, induct set: nat]: "[| n \ nat; P(0); !!x. [| x \ nat; P(x) |] ==> P(succ(x)) |] ==> P(n)" by (erule def_induct [OF nat_def nat_bnd_mono], blast) lemma natE: assumes "n \ nat" obtains ("0") "n=0" | (succ) x where "x \ nat" "n=succ(x)" using assms by (rule nat_unfold [THEN equalityD1, THEN subsetD, THEN UnE]) auto lemma nat_into_Ord [simp]: "n \ nat ==> Ord(n)" by (erule nat_induct, auto) (* @{term"i \ nat ==> 0 \ i"}; same thing as @{term"0 nat ==> i \ i"}; same thing as @{term"i nat ==> ~ Limit(a)" by (induct a rule: nat_induct, auto) lemma succ_natD: "succ(i): nat ==> i \ nat" by (rule Ord_trans [OF succI1], auto) lemma nat_succ_iff [iff]: "succ(n): nat \ n \ nat" by (blast dest!: succ_natD) lemma nat_le_Limit: "Limit(i) ==> nat \ i" apply (rule subset_imp_le) apply (simp_all add: Limit_is_Ord) apply (rule subsetI) apply (erule nat_induct) apply (erule Limit_has_0 [THEN ltD]) apply (blast intro: Limit_has_succ [THEN ltD] ltI Limit_is_Ord) done (* [| succ(i): k; k \ nat |] ==> i \ k *) lemmas succ_in_naturalD = Ord_trans [OF succI1 _ nat_into_Ord] lemma lt_nat_in_nat: "[| m nat |] ==> m \ nat" apply (erule ltE) apply (erule Ord_trans, assumption, simp) done lemma le_in_nat: "[| m \ n; n \ nat |] ==> m \ nat" by (blast dest!: lt_nat_in_nat) subsection\Variations on Mathematical Induction\ (*complete induction*) lemmas complete_induct = Ord_induct [OF _ Ord_nat, case_names less, consumes 1] -lemmas complete_induct_rule = - complete_induct [rule_format, case_names less, consumes 1] - - -lemma nat_induct_from_lemma [rule_format]: - "[| n \ nat; m \ nat; - !!x. [| x \ nat; m \ x; P(x) |] ==> P(succ(x)) |] - ==> m \ n \ P(m) \ P(n)" -apply (erule nat_induct) -apply (simp_all add: distrib_simps le0_iff le_succ_iff) -done +lemma complete_induct_rule [case_names less, consumes 1]: + "i \ nat \ (\x. x \ nat \ (\y. y \ x \ P(y)) \ P(x)) \ P(i)" + using complete_induct [of i P] by simp (*Induction starting from m rather than 0*) lemma nat_induct_from: - "[| m \ n; m \ nat; n \ nat; - P(m); - !!x. [| x \ nat; m \ x; P(x) |] ==> P(succ(x)) |] - ==> P(n)" -apply (blast intro: nat_induct_from_lemma) -done + assumes "m \ n" "m \ nat" "n \ nat" + and "P(m)" + and "!!x. [| x \ nat; m \ x; P(x) |] ==> P(succ(x))" + shows "P(n)" +proof - + from assms(3) have "m \ n \ P(m) \ P(n)" + by (rule nat_induct) (use assms(5) in \simp_all add: distrib_simps le_succ_iff\) + with assms(1,2,4) show ?thesis by blast +qed (*Induction suitable for subtraction and less-than*) lemma diff_induct [case_names 0 0_succ succ_succ, consumes 2]: "[| m \ nat; n \ nat; !!x. x \ nat ==> P(x,0); !!y. y \ nat ==> P(0,succ(y)); !!x y. [| x \ nat; y \ nat; P(x,y) |] ==> P(succ(x),succ(y)) |] ==> P(m,n)" apply (erule_tac x = m in rev_bspec) apply (erule nat_induct, simp) apply (rule ballI) apply (rename_tac i j) apply (erule_tac n=j in nat_induct, auto) done (** Induction principle analogous to trancl_induct **) lemma succ_lt_induct_lemma [rule_format]: "m \ nat ==> P(m,succ(m)) \ (\x\nat. P(m,x) \ P(m,succ(x))) \ (\n\nat. m P(m,n))" apply (erule nat_induct) apply (intro impI, rule nat_induct [THEN ballI]) prefer 4 apply (intro impI, rule nat_induct [THEN ballI]) apply (auto simp add: le_iff) done lemma succ_lt_induct: "[| m nat; P(m,succ(m)); !!x. [| x \ nat; P(m,x) |] ==> P(m,succ(x)) |] ==> P(m,n)" by (blast intro: succ_lt_induct_lemma lt_nat_in_nat) subsection\quasinat: to allow a case-split rule for \<^term>\nat_case\\ text\True if the argument is zero or any successor\ lemma [iff]: "quasinat(0)" by (simp add: quasinat_def) lemma [iff]: "quasinat(succ(x))" by (simp add: quasinat_def) lemma nat_imp_quasinat: "n \ nat ==> quasinat(n)" by (erule natE, simp_all) lemma non_nat_case: "~ quasinat(x) ==> nat_case(a,b,x) = 0" by (simp add: quasinat_def nat_case_def) lemma nat_cases_disj: "k=0 | (\y. k = succ(y)) | ~ quasinat(k)" apply (case_tac "k=0", simp) apply (case_tac "\m. k = succ(m)") apply (simp_all add: quasinat_def) done lemma nat_cases: "[|k=0 ==> P; !!y. k = succ(y) ==> P; ~ quasinat(k) ==> P|] ==> P" by (insert nat_cases_disj [of k], blast) (** nat_case **) lemma nat_case_0 [simp]: "nat_case(a,b,0) = a" by (simp add: nat_case_def) lemma nat_case_succ [simp]: "nat_case(a,b,succ(n)) = b(n)" by (simp add: nat_case_def) lemma nat_case_type [TC]: "[| n \ nat; a \ C(0); !!m. m \ nat ==> b(m): C(succ(m)) |] ==> nat_case(a,b,n) \ C(n)" by (erule nat_induct, auto) lemma split_nat_case: "P(nat_case(a,b,k)) \ ((k=0 \ P(a)) & (\x. k=succ(x) \ P(b(x))) & (~ quasinat(k) \ P(0)))" apply (rule nat_cases [of k]) apply (auto simp add: non_nat_case) done subsection\Recursion on the Natural Numbers\ (** nat_rec is used to define eclose and transrec, then becomes obsolete. The operator rec, from arith.thy, has fewer typing conditions **) lemma nat_rec_0: "nat_rec(0,a,b) = a" apply (rule nat_rec_def [THEN def_wfrec, THEN trans]) apply (rule wf_Memrel) apply (rule nat_case_0) done lemma nat_rec_succ: "m \ nat ==> nat_rec(succ(m),a,b) = b(m, nat_rec(m,a,b))" apply (rule nat_rec_def [THEN def_wfrec, THEN trans]) apply (rule wf_Memrel) apply (simp add: vimage_singleton_iff) done (** The union of two natural numbers is a natural number -- their maximum **) lemma Un_nat_type [TC]: "[| i \ nat; j \ nat |] ==> i \ j \ nat" apply (rule Un_least_lt [THEN ltD]) apply (simp_all add: lt_def) done lemma Int_nat_type [TC]: "[| i \ nat; j \ nat |] ==> i \ j \ nat" apply (rule Int_greatest_lt [THEN ltD]) apply (simp_all add: lt_def) done (*needed to simplify unions over nat*) lemma nat_nonempty [simp]: "nat \ 0" by blast text\A natural number is the set of its predecessors\ lemma nat_eq_Collect_lt: "i \ nat ==> {j\nat. j \ Le \ x \ y & x \ nat & y \ nat" by (force simp add: Le_def) end diff --git a/src/ZF/Ordinal.thy b/src/ZF/Ordinal.thy --- a/src/ZF/Ordinal.thy +++ b/src/ZF/Ordinal.thy @@ -1,764 +1,765 @@ (* Title: ZF/Ordinal.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Transitive Sets and Ordinals\ theory Ordinal imports WF Bool equalities begin definition Memrel :: "i=>i" where "Memrel(A) == {z\A*A . \x y. z= & x\y }" definition Transset :: "i=>o" where "Transset(i) == \x\i. x<=i" definition Ord :: "i=>o" where "Ord(i) == Transset(i) & (\x\i. Transset(x))" definition lt :: "[i,i] => o" (infixl \<\ 50) (*less-than on ordinals*) where "ij & Ord(j)" definition Limit :: "i=>o" where "Limit(i) == Ord(i) & 0y. y succ(y)\\ 50) where "x \ y == x < succ(y)" subsection\Rules for Transset\ subsubsection\Three Neat Characterisations of Transset\ lemma Transset_iff_Pow: "Transset(A) <-> A<=Pow(A)" by (unfold Transset_def, blast) lemma Transset_iff_Union_succ: "Transset(A) <-> \(succ(A)) = A" apply (unfold Transset_def) apply (blast elim!: equalityE) done lemma Transset_iff_Union_subset: "Transset(A) <-> \(A) \ A" by (unfold Transset_def, blast) subsubsection\Consequences of Downwards Closure\ lemma Transset_doubleton_D: "[| Transset(C); {a,b}: C |] ==> a\C & b\C" by (unfold Transset_def, blast) lemma Transset_Pair_D: "[| Transset(C); \C |] ==> a\C & b\C" apply (simp add: Pair_def) apply (blast dest: Transset_doubleton_D) done lemma Transset_includes_domain: "[| Transset(C); A*B \ C; b \ B |] ==> A \ C" by (blast dest: Transset_Pair_D) lemma Transset_includes_range: "[| Transset(C); A*B \ C; a \ A |] ==> B \ C" by (blast dest: Transset_Pair_D) subsubsection\Closure Properties\ lemma Transset_0: "Transset(0)" by (unfold Transset_def, blast) lemma Transset_Un: "[| Transset(i); Transset(j) |] ==> Transset(i \ j)" by (unfold Transset_def, blast) lemma Transset_Int: "[| Transset(i); Transset(j) |] ==> Transset(i \ j)" by (unfold Transset_def, blast) lemma Transset_succ: "Transset(i) ==> Transset(succ(i))" by (unfold Transset_def, blast) lemma Transset_Pow: "Transset(i) ==> Transset(Pow(i))" by (unfold Transset_def, blast) lemma Transset_Union: "Transset(A) ==> Transset(\(A))" by (unfold Transset_def, blast) lemma Transset_Union_family: "[| !!i. i\A ==> Transset(i) |] ==> Transset(\(A))" by (unfold Transset_def, blast) lemma Transset_Inter_family: "[| !!i. i\A ==> Transset(i) |] ==> Transset(\(A))" by (unfold Inter_def Transset_def, blast) lemma Transset_UN: "(!!x. x \ A ==> Transset(B(x))) ==> Transset (\x\A. B(x))" by (rule Transset_Union_family, auto) lemma Transset_INT: "(!!x. x \ A ==> Transset(B(x))) ==> Transset (\x\A. B(x))" by (rule Transset_Inter_family, auto) subsection\Lemmas for Ordinals\ lemma OrdI: "[| Transset(i); !!x. x\i ==> Transset(x) |] ==> Ord(i)" by (simp add: Ord_def) lemma Ord_is_Transset: "Ord(i) ==> Transset(i)" by (simp add: Ord_def) lemma Ord_contains_Transset: "[| Ord(i); j\i |] ==> Transset(j) " by (unfold Ord_def, blast) lemma Ord_in_Ord: "[| Ord(i); j\i |] ==> Ord(j)" by (unfold Ord_def Transset_def, blast) (*suitable for rewriting PROVIDED i has been fixed*) lemma Ord_in_Ord': "[| j\i; Ord(i) |] ==> Ord(j)" by (blast intro: Ord_in_Ord) (* Ord(succ(j)) ==> Ord(j) *) lemmas Ord_succD = Ord_in_Ord [OF _ succI1] lemma Ord_subset_Ord: "[| Ord(i); Transset(j); j<=i |] ==> Ord(j)" by (simp add: Ord_def Transset_def, blast) lemma OrdmemD: "[| j\i; Ord(i) |] ==> j<=i" by (unfold Ord_def Transset_def, blast) lemma Ord_trans: "[| i\j; j\k; Ord(k) |] ==> i\k" by (blast dest: OrdmemD) lemma Ord_succ_subsetI: "[| i\j; Ord(j) |] ==> succ(i) \ j" by (blast dest: OrdmemD) subsection\The Construction of Ordinals: 0, succ, Union\ lemma Ord_0 [iff,TC]: "Ord(0)" by (blast intro: OrdI Transset_0) lemma Ord_succ [TC]: "Ord(i) ==> Ord(succ(i))" by (blast intro: OrdI Transset_succ Ord_is_Transset Ord_contains_Transset) lemmas Ord_1 = Ord_0 [THEN Ord_succ] lemma Ord_succ_iff [iff]: "Ord(succ(i)) <-> Ord(i)" by (blast intro: Ord_succ dest!: Ord_succD) lemma Ord_Un [intro,simp,TC]: "[| Ord(i); Ord(j) |] ==> Ord(i \ j)" apply (unfold Ord_def) apply (blast intro!: Transset_Un) done lemma Ord_Int [TC]: "[| Ord(i); Ord(j) |] ==> Ord(i \ j)" apply (unfold Ord_def) apply (blast intro!: Transset_Int) done text\There is no set of all ordinals, for then it would contain itself\ lemma ON_class: "~ (\i. i\X <-> Ord(i))" proof (rule notI) assume X: "\i. i \ X \ Ord(i)" have "\x y. x\X \ y\x \ y\X" by (simp add: X, blast intro: Ord_in_Ord) hence "Transset(X)" by (auto simp add: Transset_def) moreover have "\x. x \ X \ Transset(x)" by (simp add: X Ord_def) ultimately have "Ord(X)" by (rule OrdI) hence "X \ X" by (simp add: X) thus "False" by (rule mem_irrefl) qed subsection\< is 'less Than' for Ordinals\ lemma ltI: "[| i\j; Ord(j) |] ==> ij; Ord(i); Ord(j) |] ==> P |] ==> P" apply (unfold lt_def) apply (blast intro: Ord_in_Ord) done lemma ltD: "i i\j" by (erule ltE, assumption) lemma not_lt0 [simp]: "~ i<0" by (unfold lt_def, blast) lemma lt_Ord: "j Ord(j)" by (erule ltE, assumption) lemma lt_Ord2: "j Ord(i)" by (erule ltE, assumption) (* @{term"ja \ j ==> Ord(j)"} *) lemmas le_Ord2 = lt_Ord2 [THEN Ord_succD] (* i<0 ==> R *) lemmas lt0E = not_lt0 [THEN notE, elim!] lemma lt_trans [trans]: "[| i i ~ (j j P *) lemmas lt_asym = lt_not_sym [THEN swap] lemma lt_irrefl [elim!]: "i P" by (blast intro: lt_asym) lemma lt_not_refl: "~ iRecall that \<^term>\i \ j\ abbreviates \<^term>\i !!\ lemma le_iff: "i \ j <-> i i < succ(j)*) lemma leI: "i i \ j" by (simp add: le_iff) lemma le_eqI: "[| i=j; Ord(j) |] ==> i \ j" by (simp add: le_iff) lemmas le_refl = refl [THEN le_eqI] lemma le_refl_iff [iff]: "i \ i <-> Ord(i)" by (simp (no_asm_simp) add: lt_not_refl le_iff) lemma leCI: "(~ (i=j & Ord(j)) ==> i i \ j" by (simp add: le_iff, blast) lemma leE: "[| i \ j; i P; [| i=j; Ord(j) |] ==> P |] ==> P" by (simp add: le_iff, blast) lemma le_anti_sym: "[| i \ j; j \ i |] ==> i=j" apply (simp add: le_iff) apply (blast elim: lt_asym) done lemma le0_iff [simp]: "i \ 0 <-> i=0" by (blast elim!: leE) lemmas le0D = le0_iff [THEN iffD1, dest!] subsection\Natural Deduction Rules for Memrel\ (*The lemmas MemrelI/E give better speed than [iff] here*) lemma Memrel_iff [simp]: " \ Memrel(A) <-> a\b & a\A & b\A" by (unfold Memrel_def, blast) lemma MemrelI [intro!]: "[| a \ b; a \ A; b \ A |] ==> \ Memrel(A)" by auto lemma MemrelE [elim!]: "[| \ Memrel(A); [| a \ A; b \ A; a\b |] ==> P |] ==> P" by auto lemma Memrel_type: "Memrel(A) \ A*A" by (unfold Memrel_def, blast) lemma Memrel_mono: "A<=B ==> Memrel(A) \ Memrel(B)" by (unfold Memrel_def, blast) lemma Memrel_0 [simp]: "Memrel(0) = 0" by (unfold Memrel_def, blast) lemma Memrel_1 [simp]: "Memrel(1) = 0" by (unfold Memrel_def, blast) lemma relation_Memrel: "relation(Memrel(A))" by (simp add: relation_def Memrel_def) (*The membership relation (as a set) is well-founded. Proof idea: show A<=B by applying the foundation axiom to A-B *) lemma wf_Memrel: "wf(Memrel(A))" apply (unfold wf_def) apply (rule foundation [THEN disjE, THEN allI], erule disjI1, blast) done text\The premise \<^term>\Ord(i)\ does not suffice.\ lemma trans_Memrel: "Ord(i) ==> trans(Memrel(i))" by (unfold Ord_def Transset_def trans_def, blast) text\However, the following premise is strong enough.\ lemma Transset_trans_Memrel: "\j\i. Transset(j) ==> trans(Memrel(i))" by (unfold Transset_def trans_def, blast) (*If Transset(A) then Memrel(A) internalizes the membership relation below A*) lemma Transset_Memrel_iff: "Transset(A) ==> \ Memrel(A) <-> a\b & b\A" by (unfold Transset_def, blast) subsection\Transfinite Induction\ (*Epsilon induction over a transitive set*) lemma Transset_induct: "[| i \ k; Transset(k); !!x.[| x \ k; \y\x. P(y) |] ==> P(x) |] ==> P(i)" apply (simp add: Transset_def) apply (erule wf_Memrel [THEN wf_induct2], blast+) done (*Induction over an ordinal*) -lemmas Ord_induct [consumes 2] = Transset_induct [rule_format, OF _ Ord_is_Transset] +lemma Ord_induct [consumes 2]: + "i \ k \ Ord(k) \ (\x. x \ k \ (\y. y \ x \ P(y)) \ P(x)) \ P(i)" + using Transset_induct [OF _ Ord_is_Transset, of i k P] by simp (*Induction over the class of ordinals -- a useful corollary of Ord_induct*) - -lemma trans_induct [rule_format, consumes 1, case_names step]: - "[| Ord(i); - !!x.[| Ord(x); \y\x. P(y) |] ==> P(x) |] - ==> P(i)" -apply (rule Ord_succ [THEN succI1 [THEN Ord_induct]], assumption) -apply (blast intro: Ord_succ [THEN Ord_in_Ord]) -done +lemma trans_induct [consumes 1, case_names step]: + "Ord(i) \ (\x. Ord(x) \ (\y. y \ x \ P(y)) \ P(x)) \ P(i)" + apply (rule Ord_succ [THEN succI1 [THEN Ord_induct]], assumption) + apply (blast intro: Ord_succ [THEN Ord_in_Ord]) + done section\Fundamental properties of the epsilon ordering (< on ordinals)\ subsubsection\Proving That < is a Linear Ordering on the Ordinals\ lemma Ord_linear: "Ord(i) \ Ord(j) \ i\j | i=j | j\i" proof (induct i arbitrary: j rule: trans_induct) case (step i) note step_i = step show ?case using \Ord(j)\ proof (induct j rule: trans_induct) case (step j) thus ?case using step_i by (blast dest: Ord_trans) qed qed text\The trichotomy law for ordinals\ lemma Ord_linear_lt: assumes o: "Ord(i)" "Ord(j)" obtains (lt) "i i" apply (rule_tac i = i and j = j in Ord_linear_lt) apply (blast intro: leI le_eqI sym o) + done lemma Ord_linear_le: assumes o: "Ord(i)" "Ord(j)" obtains (le) "i \ j" | (ge) "j \ i" apply (rule_tac i = i and j = j in Ord_linear_lt) apply (blast intro: leI le_eqI o) + done lemma le_imp_not_lt: "j \ i ==> ~ i j \ i" by (rule_tac i = i and j = j in Ord_linear2, auto) subsubsection \Some Rewrite Rules for \<\, \\\\ lemma Ord_mem_iff_lt: "Ord(j) ==> i\j <-> i ~ i j \ i" by (blast dest: le_imp_not_lt not_lt_imp_le) lemma not_le_iff_lt: "[| Ord(i); Ord(j) |] ==> ~ i \ j <-> j 0 \ i" by (erule not_lt_iff_le [THEN iffD1], auto) lemma Ord_0_lt: "[| Ord(i); i\0 |] ==> 0 i\0 <-> 0Results about Less-Than or Equals\ (** For ordinals, @{term"j\i"} implies @{term"j \ i"} (less-than or equals) **) lemma zero_le_succ_iff [iff]: "0 \ succ(x) <-> Ord(x)" by (blast intro: Ord_0_le elim: ltE) lemma subset_imp_le: "[| j<=i; Ord(i); Ord(j) |] ==> j \ i" apply (rule not_lt_iff_le [THEN iffD1], assumption+) apply (blast elim: ltE mem_irrefl) done lemma le_imp_subset: "i \ j ==> i<=j" by (blast dest: OrdmemD elim: ltE leE) lemma le_subset_iff: "j \ i <-> j<=i & Ord(i) & Ord(j)" by (blast dest: subset_imp_le le_imp_subset elim: ltE) lemma le_succ_iff: "i \ succ(j) <-> i \ j | i=succ(j) & Ord(i)" apply (simp (no_asm) add: le_iff) apply blast done (*Just a variant of subset_imp_le*) lemma all_lt_imp_le: "[| Ord(i); Ord(j); !!x. x x j \ i" by (blast intro: not_lt_imp_le dest: lt_irrefl) subsubsection\Transitivity Laws\ lemma lt_trans1: "[| i \ j; j i k |] ==> i j; j \ k |] ==> i \ k" by (blast intro: lt_trans1) lemma succ_leI: "i succ(i) \ j" apply (rule not_lt_iff_le [THEN iffD1]) apply (blast elim: ltE leE lt_asym)+ done (*Identical to succ(i) < succ(j) ==> i j ==> i j <-> i succ(j) ==> i \ j" by (blast dest!: succ_leE) lemma lt_subset_trans: "[| i \ j; j i 0 i j" apply auto apply (blast intro: lt_trans le_refl dest: lt_Ord) apply (frule lt_Ord) apply (rule not_le_iff_lt [THEN iffD1]) apply (blast intro: lt_Ord2) apply blast apply (simp add: lt_Ord lt_Ord2 le_iff) apply (blast dest: lt_asym) done lemma Ord_succ_mem_iff: "Ord(j) ==> succ(i) \ succ(j) <-> i\j" apply (insert succ_le_iff [of i j]) apply (simp add: lt_def) done subsubsection\Union and Intersection\ lemma Un_upper1_le: "[| Ord(i); Ord(j) |] ==> i \ i \ j" by (rule Un_upper1 [THEN subset_imp_le], auto) lemma Un_upper2_le: "[| Ord(i); Ord(j) |] ==> j \ i \ j" by (rule Un_upper2 [THEN subset_imp_le], auto) (*Replacing k by succ(k') yields the similar rule for le!*) lemma Un_least_lt: "[| i i \ j < k" apply (rule_tac i = i and j = j in Ord_linear_le) apply (auto simp add: Un_commute le_subset_iff subset_Un_iff lt_Ord) done lemma Un_least_lt_iff: "[| Ord(i); Ord(j) |] ==> i \ j < k <-> i i \ j \ k <-> i\k & j\k" apply (insert Un_least_lt_iff [of i j k]) apply (simp add: lt_def) done (*Replacing k by succ(k') yields the similar rule for le!*) lemma Int_greatest_lt: "[| i i \ j < k" apply (rule_tac i = i and j = j in Ord_linear_le) apply (auto simp add: Int_commute le_subset_iff subset_Int_iff lt_Ord) done lemma Ord_Un_if: "[| Ord(i); Ord(j) |] ==> i \ j = (if j succ(i \ j) = succ(i) \ succ(j)" by (simp add: Ord_Un_if lt_Ord le_Ord2) lemma lt_Un_iff: "[| Ord(i); Ord(j) |] ==> k < i \ j <-> k < i | k < j" apply (simp add: Ord_Un_if not_lt_iff_le) apply (blast intro: leI lt_trans2)+ done lemma le_Un_iff: "[| Ord(i); Ord(j) |] ==> k \ i \ j <-> k \ i | k \ j" by (simp add: succ_Un_distrib lt_Un_iff [symmetric]) lemma Un_upper1_lt: "[|k < i; Ord(j)|] ==> k < i \ j" by (simp add: lt_Un_iff lt_Ord2) lemma Un_upper2_lt: "[|k < j; Ord(i)|] ==> k < i \ j" by (simp add: lt_Un_iff lt_Ord2) (*See also Transset_iff_Union_succ*) lemma Ord_Union_succ_eq: "Ord(i) ==> \(succ(i)) = i" by (blast intro: Ord_trans) subsection\Results about Limits\ lemma Ord_Union [intro,simp,TC]: "[| !!i. i\A ==> Ord(i) |] ==> Ord(\(A))" apply (rule Ord_is_Transset [THEN Transset_Union_family, THEN OrdI]) apply (blast intro: Ord_contains_Transset)+ done lemma Ord_UN [intro,simp,TC]: "[| !!x. x\A ==> Ord(B(x)) |] ==> Ord(\x\A. B(x))" by (rule Ord_Union, blast) lemma Ord_Inter [intro,simp,TC]: "[| !!i. i\A ==> Ord(i) |] ==> Ord(\(A))" apply (rule Transset_Inter_family [THEN OrdI]) apply (blast intro: Ord_is_Transset) apply (simp add: Inter_def) apply (blast intro: Ord_contains_Transset) done lemma Ord_INT [intro,simp,TC]: "[| !!x. x\A ==> Ord(B(x)) |] ==> Ord(\x\A. B(x))" by (rule Ord_Inter, blast) (* No < version of this theorem: consider that @{term"(\i\nat.i)=nat"}! *) lemma UN_least_le: "[| Ord(i); !!x. x\A ==> b(x) \ i |] ==> (\x\A. b(x)) \ i" apply (rule le_imp_subset [THEN UN_least, THEN subset_imp_le]) apply (blast intro: Ord_UN elim: ltE)+ done lemma UN_succ_least_lt: "[| jA ==> b(x) (\x\A. succ(b(x))) < i" apply (rule ltE, assumption) apply (rule UN_least_le [THEN lt_trans2]) apply (blast intro: succ_leI)+ done lemma UN_upper_lt: "[| a\A; i < b(a); Ord(\x\A. b(x)) |] ==> i < (\x\A. b(x))" by (unfold lt_def, blast) lemma UN_upper_le: "[| a \ A; i \ b(a); Ord(\x\A. b(x)) |] ==> i \ (\x\A. b(x))" apply (frule ltD) apply (rule le_imp_subset [THEN subset_trans, THEN subset_imp_le]) apply (blast intro: lt_Ord UN_upper)+ done lemma lt_Union_iff: "\i\A. Ord(i) ==> (j < \(A)) <-> (\i\A. j J; i\j; Ord(\(J)) |] ==> i \ \J" apply (subst Union_eq_UN) apply (rule UN_upper_le, auto) done lemma le_implies_UN_le_UN: "[| !!x. x\A ==> c(x) \ d(x) |] ==> (\x\A. c(x)) \ (\x\A. d(x))" apply (rule UN_least_le) apply (rule_tac [2] UN_upper_le) apply (blast intro: Ord_UN le_Ord2)+ done lemma Ord_equality: "Ord(i) ==> (\y\i. succ(y)) = i" by (blast intro: Ord_trans) (*Holds for all transitive sets, not just ordinals*) lemma Ord_Union_subset: "Ord(i) ==> \(i) \ i" by (blast intro: Ord_trans) subsection\Limit Ordinals -- General Properties\ lemma Limit_Union_eq: "Limit(i) ==> \(i) = i" apply (unfold Limit_def) apply (fast intro!: ltI elim!: ltE elim: Ord_trans) done lemma Limit_is_Ord: "Limit(i) ==> Ord(i)" apply (unfold Limit_def) apply (erule conjunct1) done lemma Limit_has_0: "Limit(i) ==> 0 < i" apply (unfold Limit_def) apply (erule conjunct2 [THEN conjunct1]) done lemma Limit_nonzero: "Limit(i) ==> i \ 0" by (drule Limit_has_0, blast) lemma Limit_has_succ: "[| Limit(i); j succ(j) < i" by (unfold Limit_def, blast) lemma Limit_succ_lt_iff [simp]: "Limit(i) ==> succ(j) < i <-> (j 1 < i" by (blast intro: Limit_has_0 Limit_has_succ) lemma increasing_LimitI: "[| 0x\l. \y\l. x Limit(l)" apply (unfold Limit_def, simp add: lt_Ord2, clarify) apply (drule_tac i=y in ltD) apply (blast intro: lt_trans1 [OF _ ltI] lt_Ord2) done lemma non_succ_LimitI: assumes i: "0y. succ(y) \ i" shows "Limit(i)" proof - have Oi: "Ord(i)" using i by (simp add: lt_def) { fix y assume yi: "y y" using yi by (blast dest: le_imp_not_lt) hence "succ(y) < i" using nsucc [of y] by (blast intro: Ord_linear_lt [OF Osy Oi]) } thus ?thesis using i Oi by (auto simp add: Limit_def) qed lemma succ_LimitE [elim!]: "Limit(succ(i)) ==> P" apply (rule lt_irrefl) apply (rule Limit_has_succ, assumption) apply (erule Limit_is_Ord [THEN Ord_succD, THEN le_refl]) done lemma not_succ_Limit [simp]: "~ Limit(succ(i))" by blast lemma Limit_le_succD: "[| Limit(i); i \ succ(j) |] ==> i \ j" by (blast elim!: leE) subsubsection\Traditional 3-Way Case Analysis on Ordinals\ lemma Ord_cases_disj: "Ord(i) ==> i=0 | (\j. Ord(j) & i=succ(j)) | Limit(i)" by (blast intro!: non_succ_LimitI Ord_0_lt) lemma Ord_cases: assumes i: "Ord(i)" obtains ("0") "i=0" | (succ) j where "Ord(j)" "i=succ(j)" | (limit) "Limit(i)" by (insert Ord_cases_disj [OF i], auto) lemma trans_induct3_raw: "[| Ord(i); P(0); !!x. [| Ord(x); P(x) |] ==> P(succ(x)); !!x. [| Limit(x); \y\x. P(y) |] ==> P(x) |] ==> P(i)" apply (erule trans_induct) apply (erule Ord_cases, blast+) done -lemmas trans_induct3 = trans_induct3_raw [rule_format, case_names 0 succ limit, consumes 1] +lemma trans_induct3 [case_names 0 succ limit, consumes 1]: + "Ord(i) \ P(0) \ (\x. Ord(x) \ P(x) \ P(succ(x))) \ (\x. Limit(x) \ (\y. y \ x \ P(y)) \ P(x)) \ P(i)" + using trans_induct3_raw [of i P] by simp text\A set of ordinals is either empty, contains its own union, or its union is a limit ordinal.\ lemma Union_le: "[| !!x. x\I ==> x\j; Ord(j) |] ==> \(I) \ j" by (auto simp add: le_subset_iff Union_least) lemma Ord_set_cases: assumes I: "\i\I. Ord(i)" shows "I=0 \ \(I) \ I \ (\(I) \ I \ Limit(\(I)))" proof (cases "\(I)" rule: Ord_cases) show "Ord(\I)" using I by (blast intro: Ord_Union) next assume "\I = 0" thus ?thesis by (simp, blast intro: subst_elem) next fix j assume j: "Ord(j)" and UIj:"\(I) = succ(j)" { assume "\i\I. i\j" hence "\(I) \ j" by (simp add: Union_le j) hence False by (simp add: UIj lt_not_refl) } then obtain i where i: "i \ I" "succ(j) \ i" using I j by (atomize, auto simp add: not_le_iff_lt) have "\(I) \ succ(j)" using UIj j by auto hence "i \ succ(j)" using i by (simp add: le_subset_iff Union_subset_iff) hence "succ(j) = i" using i by (blast intro: le_anti_sym) hence "succ(j) \ I" by (simp add: i) thus ?thesis by (simp add: UIj) next assume "Limit(\I)" thus ?thesis by auto qed text\If the union of a set of ordinals is a successor, then it is an element of that set.\ lemma Ord_Union_eq_succD: "[|\x\X. Ord(x); \X = succ(j)|] ==> succ(j) \ X" by (drule Ord_set_cases, auto) -lemma Limit_Union [rule_format]: "[| I \ 0; \i\I. Limit(i) |] ==> Limit(\I)" +lemma Limit_Union [rule_format]: "[| I \ 0; (\i. i\I \ Limit(i)) |] ==> Limit(\I)" apply (simp add: Limit_def lt_def) apply (blast intro!: equalityI) done end diff --git a/src/ZF/WF.thy b/src/ZF/WF.thy --- a/src/ZF/WF.thy +++ b/src/ZF/WF.thy @@ -1,371 +1,372 @@ (* Title: ZF/WF.thy Author: Tobias Nipkow and Lawrence C Paulson Copyright 1994 University of Cambridge Derived first for transitive relations, and finally for arbitrary WF relations via wf_trancl and trans_trancl. It is difficult to derive this general case directly, using r^+ instead of r. In is_recfun, the two occurrences of the relation must have the same form. Inserting r^+ in the_recfun or wftrec yields a recursion rule with r^+ -`` {a} instead of r-``{a}. This recursion rule is stronger in principle, but harder to use, especially to prove wfrec_eclose_eq in epsilon.ML. Expanding out the definition of wftrec in wfrec would yield a mess. *) section\Well-Founded Recursion\ theory WF imports Trancl begin definition wf :: "i=>o" where (*r is a well-founded relation*) "wf(r) == \Z. Z=0 | (\x\Z. \y. :r \ ~ y \ Z)" definition wf_on :: "[i,i]=>o" (\wf[_]'(_')\) where (*r is well-founded on A*) "wf_on(A,r) == wf(r \ A*A)" definition is_recfun :: "[i, i, [i,i]=>i, i] =>o" where "is_recfun(r,a,H,f) == (f = (\x\r-``{a}. H(x, restrict(f, r-``{x}))))" definition the_recfun :: "[i, i, [i,i]=>i] =>i" where "the_recfun(r,a,H) == (THE f. is_recfun(r,a,H,f))" definition wftrec :: "[i, i, [i,i]=>i] =>i" where "wftrec(r,a,H) == H(a, the_recfun(r,a,H))" definition wfrec :: "[i, i, [i,i]=>i] =>i" where (*public version. Does not require r to be transitive*) "wfrec(r,a,H) == wftrec(r^+, a, %x f. H(x, restrict(f,r-``{x})))" definition wfrec_on :: "[i, i, i, [i,i]=>i] =>i" (\wfrec[_]'(_,_,_')\) where "wfrec[A](r,a,H) == wfrec(r \ A*A, a, H)" subsection\Well-Founded Relations\ subsubsection\Equivalences between \<^term>\wf\ and \<^term>\wf_on\\ lemma wf_imp_wf_on: "wf(r) ==> wf[A](r)" by (unfold wf_def wf_on_def, force) lemma wf_on_imp_wf: "[|wf[A](r); r \ A*A|] ==> wf(r)" by (simp add: wf_on_def subset_Int_iff) lemma wf_on_field_imp_wf: "wf[field(r)](r) ==> wf(r)" by (unfold wf_def wf_on_def, fast) lemma wf_iff_wf_on_field: "wf(r) \ wf[field(r)](r)" by (blast intro: wf_imp_wf_on wf_on_field_imp_wf) lemma wf_on_subset_A: "[| wf[A](r); B<=A |] ==> wf[B](r)" by (unfold wf_on_def wf_def, fast) lemma wf_on_subset_r: "[| wf[A](r); s<=r |] ==> wf[A](s)" by (unfold wf_on_def wf_def, fast) lemma wf_subset: "[|wf(s); r<=s|] ==> wf(r)" by (simp add: wf_def, fast) subsubsection\Introduction Rules for \<^term>\wf_on\\ text\If every non-empty subset of \<^term>\A\ has an \<^term>\r\-minimal element then we have \<^term>\wf[A](r)\.\ lemma wf_onI: assumes prem: "!!Z u. [| Z<=A; u \ Z; \x\Z. \y\Z. :r |] ==> False" shows "wf[A](r)" apply (unfold wf_on_def wf_def) apply (rule equals0I [THEN disjCI, THEN allI]) apply (rule_tac Z = Z in prem, blast+) done text\If \<^term>\r\ allows well-founded induction over \<^term>\A\ then we have \<^term>\wf[A](r)\. Premise is equivalent to \<^prop>\!!B. \x\A. (\y. : r \ y \ B) \ x \ B ==> A<=B\\ lemma wf_onI2: assumes prem: "!!y B. [| \x\A. (\y\A. :r \ y \ B) \ x \ B; y \ A |] ==> y \ B" shows "wf[A](r)" apply (rule wf_onI) apply (rule_tac c=u in prem [THEN DiffE]) prefer 3 apply blast apply fast+ done subsubsection\Well-founded Induction\ text\Consider the least \<^term>\z\ in \<^term>\domain(r)\ such that \<^term>\P(z)\ does not hold...\ lemma wf_induct_raw: "[| wf(r); !!x.[| \y. : r \ P(y) |] ==> P(x) |] ==> P(a)" apply (unfold wf_def) apply (erule_tac x = "{z \ domain(r). ~ P(z)}" in allE) apply blast done lemmas wf_induct = wf_induct_raw [rule_format, consumes 1, case_names step, induct set: wf] text\The form of this rule is designed to match \wfI\\ lemma wf_induct2: "[| wf(r); a \ A; field(r)<=A; !!x.[| x \ A; \y. : r \ P(y) |] ==> P(x) |] ==> P(a)" apply (erule_tac P="a \ A" in rev_mp) apply (erule_tac a=a in wf_induct, blast) done lemma field_Int_square: "field(r \ A*A) \ A" by blast lemma wf_on_induct_raw [consumes 2, induct set: wf_on]: "[| wf[A](r); a \ A; !!x.[| x \ A; \y\A. : r \ P(y) |] ==> P(x) |] ==> P(a)" apply (unfold wf_on_def) apply (erule wf_induct2, assumption) apply (rule field_Int_square, blast) done -lemmas wf_on_induct = - wf_on_induct_raw [rule_format, consumes 2, case_names step, induct set: wf_on] - +lemma wf_on_induct [consumes 2, case_names step, induct set: wf_on]: + "wf[A](r) \ a \ A \ (\x. x \ A \ (\y. y \ A \ \y, x\ \ r \ P(y)) \ P(x)) \ P(a)" + using wf_on_induct_raw [of A r a P] by simp text\If \<^term>\r\ allows well-founded induction then we have \<^term>\wf(r)\.\ lemma wfI: "[| field(r)<=A; !!y B. [| \x\A. (\y\A. :r \ y \ B) \ x \ B; y \ A|] ==> y \ B |] ==> wf(r)" apply (rule wf_on_subset_A [THEN wf_on_field_imp_wf]) apply (rule wf_onI2) prefer 2 apply blast apply blast done subsection\Basic Properties of Well-Founded Relations\ lemma wf_not_refl: "wf(r) ==> \ r" by (erule_tac a=a in wf_induct, blast) lemma wf_not_sym [rule_format]: "wf(r) ==> \x. :r \ \ r" by (erule_tac a=a in wf_induct, blast) (* @{term"[| wf(r); \ r; ~P ==> \ r |] ==> P"} *) lemmas wf_asym = wf_not_sym [THEN swap] lemma wf_on_not_refl: "[| wf[A](r); a \ A |] ==> \ r" by (erule_tac a=a in wf_on_induct, assumption, blast) -lemma wf_on_not_sym [rule_format]: - "[| wf[A](r); a \ A |] ==> \b\A. :r \ \r" +lemma wf_on_not_sym: + "[| wf[A](r); a \ A |] ==> (\b. b\A \ :r \ \r)" +apply (atomize (full), intro impI) apply (erule_tac a=a in wf_on_induct, assumption, blast) done lemma wf_on_asym: "[| wf[A](r); ~Z ==> \ r; \ r ==> Z; ~Z ==> a \ A; ~Z ==> b \ A |] ==> Z" by (blast dest: wf_on_not_sym) (*Needed to prove well_ordI. Could also reason that wf[A](r) means wf(r \ A*A); thus wf( (r \ A*A)^+ ) and use wf_not_refl *) lemma wf_on_chain3: "[| wf[A](r); :r; :r; :r; a \ A; b \ A; c \ A |] ==> P" apply (subgoal_tac "\y\A. \z\A. :r \ :r \ :r \ P", blast) apply (erule_tac a=a in wf_on_induct, assumption, blast) done text\transitive closure of a WF relation is WF provided \<^term>\A\ is downward closed\ lemma wf_on_trancl: "[| wf[A](r); r-``A \ A |] ==> wf[A](r^+)" apply (rule wf_onI2) apply (frule bspec [THEN mp], assumption+) apply (erule_tac a = y in wf_on_induct, assumption) apply (blast elim: tranclE, blast) done lemma wf_trancl: "wf(r) ==> wf(r^+)" apply (simp add: wf_iff_wf_on_field) apply (rule wf_on_subset_A) apply (erule wf_on_trancl) apply blast apply (rule trancl_type [THEN field_rel_subset]) done text\\<^term>\r-``{a}\ is the set of everything under \<^term>\a\ in \<^term>\r\\ lemmas underI = vimage_singleton_iff [THEN iffD2] lemmas underD = vimage_singleton_iff [THEN iffD1] subsection\The Predicate \<^term>\is_recfun\\ lemma is_recfun_type: "is_recfun(r,a,H,f) ==> f \ r-``{a} -> range(f)" apply (unfold is_recfun_def) apply (erule ssubst) apply (rule lamI [THEN rangeI, THEN lam_type], assumption) done lemmas is_recfun_imp_function = is_recfun_type [THEN fun_is_function] lemma apply_recfun: "[| is_recfun(r,a,H,f); :r |] ==> f`x = H(x, restrict(f,r-``{x}))" apply (unfold is_recfun_def) txt\replace f only on the left-hand side\ apply (erule_tac P = "%x. t(x) = u" for t u in ssubst) apply (simp add: underI) done lemma is_recfun_equal [rule_format]: "[| wf(r); trans(r); is_recfun(r,a,H,f); is_recfun(r,b,H,g) |] ==> :r \ :r \ f`x=g`x" apply (frule_tac f = f in is_recfun_type) apply (frule_tac f = g in is_recfun_type) apply (simp add: is_recfun_def) apply (erule_tac a=x in wf_induct) apply (intro impI) apply (elim ssubst) apply (simp (no_asm_simp) add: vimage_singleton_iff restrict_def) apply (rule_tac t = "%z. H (x, z)" for x in subst_context) apply (subgoal_tac "\y\r-``{x}. \z. :f \ :g") apply (blast dest: transD) apply (simp add: apply_iff) apply (blast dest: transD intro: sym) done lemma is_recfun_cut: "[| wf(r); trans(r); is_recfun(r,a,H,f); is_recfun(r,b,H,g); :r |] ==> restrict(f, r-``{b}) = g" apply (frule_tac f = f in is_recfun_type) apply (rule fun_extension) apply (blast dest: transD intro: restrict_type2) apply (erule is_recfun_type, simp) apply (blast dest: transD intro: is_recfun_equal) done subsection\Recursion: Main Existence Lemma\ lemma is_recfun_functional: "[| wf(r); trans(r); is_recfun(r,a,H,f); is_recfun(r,a,H,g) |] ==> f=g" by (blast intro: fun_extension is_recfun_type is_recfun_equal) lemma the_recfun_eq: "[| is_recfun(r,a,H,f); wf(r); trans(r) |] ==> the_recfun(r,a,H) = f" apply (unfold the_recfun_def) apply (blast intro: is_recfun_functional) done (*If some f satisfies is_recfun(r,a,H,-) then so does the_recfun(r,a,H) *) lemma is_the_recfun: "[| is_recfun(r,a,H,f); wf(r); trans(r) |] ==> is_recfun(r, a, H, the_recfun(r,a,H))" by (simp add: the_recfun_eq) lemma unfold_the_recfun: "[| wf(r); trans(r) |] ==> is_recfun(r, a, H, the_recfun(r,a,H))" apply (rule_tac a=a in wf_induct, assumption) apply (rename_tac a1) apply (rule_tac f = "\y\r-``{a1}. wftrec (r,y,H)" in is_the_recfun) apply typecheck apply (unfold is_recfun_def wftrec_def) \ \Applying the substitution: must keep the quantified assumption!\ apply (rule lam_cong [OF refl]) apply (drule underD) apply (fold is_recfun_def) apply (rule_tac t = "%z. H(x, z)" for x in subst_context) apply (rule fun_extension) apply (blast intro: is_recfun_type) apply (rule lam_type [THEN restrict_type2]) apply blast apply (blast dest: transD) apply atomize apply (frule spec [THEN mp], assumption) apply (subgoal_tac " \ r") apply (drule_tac x1 = xa in spec [THEN mp], assumption) apply (simp add: vimage_singleton_iff apply_recfun is_recfun_cut) apply (blast dest: transD) done subsection\Unfolding \<^term>\wftrec(r,a,H)\\ lemma the_recfun_cut: "[| wf(r); trans(r); :r |] ==> restrict(the_recfun(r,a,H), r-``{b}) = the_recfun(r,b,H)" by (blast intro: is_recfun_cut unfold_the_recfun) (*NOT SUITABLE FOR REWRITING: it is recursive!*) lemma wftrec: "[| wf(r); trans(r) |] ==> wftrec(r,a,H) = H(a, \x\r-``{a}. wftrec(r,x,H))" apply (unfold wftrec_def) apply (subst unfold_the_recfun [unfolded is_recfun_def]) apply (simp_all add: vimage_singleton_iff [THEN iff_sym] the_recfun_cut) done subsubsection\Removal of the Premise \<^term>\trans(r)\\ (*NOT SUITABLE FOR REWRITING: it is recursive!*) lemma wfrec: "wf(r) ==> wfrec(r,a,H) = H(a, \x\r-``{a}. wfrec(r,x,H))" apply (unfold wfrec_def) apply (erule wf_trancl [THEN wftrec, THEN ssubst]) apply (rule trans_trancl) apply (rule vimage_pair_mono [THEN restrict_lam_eq, THEN subst_context]) apply (erule r_into_trancl) apply (rule subset_refl) done (*This form avoids giant explosions in proofs. NOTE USE OF == *) lemma def_wfrec: "[| !!x. h(x)==wfrec(r,x,H); wf(r) |] ==> h(a) = H(a, \x\r-``{a}. h(x))" apply simp apply (elim wfrec) done lemma wfrec_type: "[| wf(r); a \ A; field(r)<=A; !!x u. [| x \ A; u \ Pi(r-``{x}, B) |] ==> H(x,u) \ B(x) |] ==> wfrec(r,a,H) \ B(a)" apply (rule_tac a = a in wf_induct2, assumption+) apply (subst wfrec, assumption) apply (simp add: lam_type underD) done lemma wfrec_on: "[| wf[A](r); a \ A |] ==> wfrec[A](r,a,H) = H(a, \x\(r-``{a}) \ A. wfrec[A](r,x,H))" apply (unfold wf_on_def wfrec_on_def) apply (erule wfrec [THEN trans]) apply (simp add: vimage_Int_square cons_subset_iff) done text\Minimal-element characterization of well-foundedness\ lemma wf_eq_minimal: "wf(r) \ (\Q x. x \ Q \ (\z\Q. \y. :r \ y\Q))" by (unfold wf_def, blast) end diff --git a/src/ZF/equalities.thy b/src/ZF/equalities.thy --- a/src/ZF/equalities.thy +++ b/src/ZF/equalities.thy @@ -1,984 +1,984 @@ (* Title: ZF/equalities.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1992 University of Cambridge *) section\Basic Equalities and Inclusions\ theory equalities imports pair begin text\These cover union, intersection, converse, domain, range, etc. Philippe de Groote proved many of the inclusions.\ lemma in_mono: "A\B ==> x\A \ x\B" by blast lemma the_eq_0 [simp]: "(THE x. False) = 0" by (blast intro: the_0) subsection\Bounded Quantifiers\ text \\medskip The following are not added to the default simpset because (a) they duplicate the body and (b) there are no similar rules for \Int\.\ lemma ball_Un: "(\x \ A\B. P(x)) \ (\x \ A. P(x)) & (\x \ B. P(x))" by blast lemma bex_Un: "(\x \ A\B. P(x)) \ (\x \ A. P(x)) | (\x \ B. P(x))" by blast lemma ball_UN: "(\z \ (\x\A. B(x)). P(z)) \ (\x\A. \z \ B(x). P(z))" by blast lemma bex_UN: "(\z \ (\x\A. B(x)). P(z)) \ (\x\A. \z\B(x). P(z))" by blast subsection\Converse of a Relation\ lemma converse_iff [simp]: "\ converse(r) \ \r" by (unfold converse_def, blast) lemma converseI [intro!]: "\r ==> \converse(r)" by (unfold converse_def, blast) lemma converseD: " \ converse(r) ==> \ r" by (unfold converse_def, blast) lemma converseE [elim!]: "[| yx \ converse(r); !!x y. [| yx=; \r |] ==> P |] ==> P" by (unfold converse_def, blast) lemma converse_converse: "r\Sigma(A,B) ==> converse(converse(r)) = r" by blast lemma converse_type: "r\A*B ==> converse(r)\B*A" by blast lemma converse_prod [simp]: "converse(A*B) = B*A" by blast lemma converse_empty [simp]: "converse(0) = 0" by blast lemma converse_subset_iff: "A \ Sigma(X,Y) ==> converse(A) \ converse(B) \ A \ B" by blast subsection\Finite Set Constructions Using \<^term>\cons\\ lemma cons_subsetI: "[| a\C; B\C |] ==> cons(a,B) \ C" by blast lemma subset_consI: "B \ cons(a,B)" by blast lemma cons_subset_iff [iff]: "cons(a,B)\C \ a\C & B\C" by blast (*A safe special case of subset elimination, adding no new variables [| cons(a,B) \ C; [| a \ C; B \ C |] ==> R |] ==> R *) lemmas cons_subsetE = cons_subset_iff [THEN iffD1, THEN conjE] lemma subset_empty_iff: "A\0 \ A=0" by blast lemma subset_cons_iff: "C\cons(a,B) \ C\B | (a\C & C-{a} \ B)" by blast (* cons_def refers to Upair; reversing the equality LOOPS in rewriting!*) lemma cons_eq: "{a} \ B = cons(a,B)" by blast lemma cons_commute: "cons(a, cons(b, C)) = cons(b, cons(a, C))" by blast lemma cons_absorb: "a: B ==> cons(a,B) = B" by blast lemma cons_Diff: "a: B ==> cons(a, B-{a}) = B" by blast lemma Diff_cons_eq: "cons(a,B) - C = (if a\C then B-C else cons(a,B-C))" by auto -lemma equal_singleton [rule_format]: "[| a: C; \y\C. y=b |] ==> C = {b}" +lemma equal_singleton: "[| a: C; \y. y \C \ y=b |] ==> C = {b}" by blast lemma [simp]: "cons(a,cons(a,B)) = cons(a,B)" by blast (** singletons **) lemma singleton_subsetI: "a\C ==> {a} \ C" by blast lemma singleton_subsetD: "{a} \ C ==> a\C" by blast (** succ **) lemma subset_succI: "i \ succ(i)" by blast (*But if j is an ordinal or is transitive, then @{term"i\j"} implies @{term"i\j"}! See @{text"Ord_succ_subsetI}*) lemma succ_subsetI: "[| i\j; i\j |] ==> succ(i)\j" by (unfold succ_def, blast) lemma succ_subsetE: "[| succ(i) \ j; [| i\j; i\j |] ==> P |] ==> P" by (unfold succ_def, blast) lemma succ_subset_iff: "succ(a) \ B \ (a \ B & a \ B)" by (unfold succ_def, blast) subsection\Binary Intersection\ (** Intersection is the greatest lower bound of two sets **) lemma Int_subset_iff: "C \ A \ B \ C \ A & C \ B" by blast lemma Int_lower1: "A \ B \ A" by blast lemma Int_lower2: "A \ B \ B" by blast lemma Int_greatest: "[| C\A; C\B |] ==> C \ A \ B" by blast lemma Int_cons: "cons(a,B) \ C \ cons(a, B \ C)" by blast lemma Int_absorb [simp]: "A \ A = A" by blast lemma Int_left_absorb: "A \ (A \ B) = A \ B" by blast lemma Int_commute: "A \ B = B \ A" by blast lemma Int_left_commute: "A \ (B \ C) = B \ (A \ C)" by blast lemma Int_assoc: "(A \ B) \ C = A \ (B \ C)" by blast (*Intersection is an AC-operator*) lemmas Int_ac= Int_assoc Int_left_absorb Int_commute Int_left_commute lemma Int_absorb1: "B \ A ==> A \ B = B" by blast lemma Int_absorb2: "A \ B ==> A \ B = A" by blast lemma Int_Un_distrib: "A \ (B \ C) = (A \ B) \ (A \ C)" by blast lemma Int_Un_distrib2: "(B \ C) \ A = (B \ A) \ (C \ A)" by blast lemma subset_Int_iff: "A\B \ A \ B = A" by (blast elim!: equalityE) lemma subset_Int_iff2: "A\B \ B \ A = A" by (blast elim!: equalityE) lemma Int_Diff_eq: "C\A ==> (A-B) \ C = C-B" by blast lemma Int_cons_left: "cons(a,A) \ B = (if a \ B then cons(a, A \ B) else A \ B)" by auto lemma Int_cons_right: "A \ cons(a, B) = (if a \ A then cons(a, A \ B) else A \ B)" by auto lemma cons_Int_distrib: "cons(x, A \ B) = cons(x, A) \ cons(x, B)" by auto subsection\Binary Union\ (** Union is the least upper bound of two sets *) lemma Un_subset_iff: "A \ B \ C \ A \ C & B \ C" by blast lemma Un_upper1: "A \ A \ B" by blast lemma Un_upper2: "B \ A \ B" by blast lemma Un_least: "[| A\C; B\C |] ==> A \ B \ C" by blast lemma Un_cons: "cons(a,B) \ C = cons(a, B \ C)" by blast lemma Un_absorb [simp]: "A \ A = A" by blast lemma Un_left_absorb: "A \ (A \ B) = A \ B" by blast lemma Un_commute: "A \ B = B \ A" by blast lemma Un_left_commute: "A \ (B \ C) = B \ (A \ C)" by blast lemma Un_assoc: "(A \ B) \ C = A \ (B \ C)" by blast (*Union is an AC-operator*) lemmas Un_ac = Un_assoc Un_left_absorb Un_commute Un_left_commute lemma Un_absorb1: "A \ B ==> A \ B = B" by blast lemma Un_absorb2: "B \ A ==> A \ B = A" by blast lemma Un_Int_distrib: "(A \ B) \ C = (A \ C) \ (B \ C)" by blast lemma subset_Un_iff: "A\B \ A \ B = B" by (blast elim!: equalityE) lemma subset_Un_iff2: "A\B \ B \ A = B" by (blast elim!: equalityE) lemma Un_empty [iff]: "(A \ B = 0) \ (A = 0 & B = 0)" by blast lemma Un_eq_Union: "A \ B = \({A, B})" by blast subsection\Set Difference\ lemma Diff_subset: "A-B \ A" by blast lemma Diff_contains: "[| C\A; C \ B = 0 |] ==> C \ A-B" by blast lemma subset_Diff_cons_iff: "B \ A - cons(c,C) \ B\A-C & c \ B" by blast lemma Diff_cancel: "A - A = 0" by blast lemma Diff_triv: "A \ B = 0 ==> A - B = A" by blast lemma empty_Diff [simp]: "0 - A = 0" by blast lemma Diff_0 [simp]: "A - 0 = A" by blast lemma Diff_eq_0_iff: "A - B = 0 \ A \ B" by (blast elim: equalityE) (*NOT SUITABLE FOR REWRITING since {a} == cons(a,0)*) lemma Diff_cons: "A - cons(a,B) = A - B - {a}" by blast (*NOT SUITABLE FOR REWRITING since {a} == cons(a,0)*) lemma Diff_cons2: "A - cons(a,B) = A - {a} - B" by blast lemma Diff_disjoint: "A \ (B-A) = 0" by blast lemma Diff_partition: "A\B ==> A \ (B-A) = B" by blast lemma subset_Un_Diff: "A \ B \ (A - B)" by blast lemma double_complement: "[| A\B; B\C |] ==> B-(C-A) = A" by blast lemma double_complement_Un: "(A \ B) - (B-A) = A" by blast lemma Un_Int_crazy: "(A \ B) \ (B \ C) \ (C \ A) = (A \ B) \ (B \ C) \ (C \ A)" apply blast done lemma Diff_Un: "A - (B \ C) = (A-B) \ (A-C)" by blast lemma Diff_Int: "A - (B \ C) = (A-B) \ (A-C)" by blast lemma Un_Diff: "(A \ B) - C = (A - C) \ (B - C)" by blast lemma Int_Diff: "(A \ B) - C = A \ (B - C)" by blast lemma Diff_Int_distrib: "C \ (A-B) = (C \ A) - (C \ B)" by blast lemma Diff_Int_distrib2: "(A-B) \ C = (A \ C) - (B \ C)" by blast (*Halmos, Naive Set Theory, page 16.*) lemma Un_Int_assoc_iff: "(A \ B) \ C = A \ (B \ C) \ C\A" by (blast elim!: equalityE) subsection\Big Union and Intersection\ (** Big Union is the least upper bound of a set **) lemma Union_subset_iff: "\(A) \ C \ (\x\A. x \ C)" by blast lemma Union_upper: "B\A ==> B \ \(A)" by blast lemma Union_least: "[| !!x. x\A ==> x\C |] ==> \(A) \ C" by blast lemma Union_cons [simp]: "\(cons(a,B)) = a \ \(B)" by blast lemma Union_Un_distrib: "\(A \ B) = \(A) \ \(B)" by blast lemma Union_Int_subset: "\(A \ B) \ \(A) \ \(B)" by blast lemma Union_disjoint: "\(C) \ A = 0 \ (\B\C. B \ A = 0)" by (blast elim!: equalityE) lemma Union_empty_iff: "\(A) = 0 \ (\B\A. B=0)" by blast lemma Int_Union2: "\(B) \ A = (\C\B. C \ A)" by blast (** Big Intersection is the greatest lower bound of a nonempty set **) lemma Inter_subset_iff: "A\0 ==> C \ \(A) \ (\x\A. C \ x)" by blast lemma Inter_lower: "B\A ==> \(A) \ B" by blast lemma Inter_greatest: "[| A\0; !!x. x\A ==> C\x |] ==> C \ \(A)" by blast (** Intersection of a family of sets **) lemma INT_lower: "x\A ==> (\x\A. B(x)) \ B(x)" by blast lemma INT_greatest: "[| A\0; !!x. x\A ==> C\B(x) |] ==> C \ (\x\A. B(x))" by force lemma Inter_0 [simp]: "\(0) = 0" by (unfold Inter_def, blast) lemma Inter_Un_subset: "[| z\A; z\B |] ==> \(A) \ \(B) \ \(A \ B)" by blast (* A good challenge: Inter is ill-behaved on the empty set *) lemma Inter_Un_distrib: "[| A\0; B\0 |] ==> \(A \ B) = \(A) \ \(B)" by blast lemma Union_singleton: "\({b}) = b" by blast lemma Inter_singleton: "\({b}) = b" by blast lemma Inter_cons [simp]: "\(cons(a,B)) = (if B=0 then a else a \ \(B))" by force subsection\Unions and Intersections of Families\ lemma subset_UN_iff_eq: "A \ (\i\I. B(i)) \ A = (\i\I. A \ B(i))" by (blast elim!: equalityE) lemma UN_subset_iff: "(\x\A. B(x)) \ C \ (\x\A. B(x) \ C)" by blast lemma UN_upper: "x\A ==> B(x) \ (\x\A. B(x))" by (erule RepFunI [THEN Union_upper]) lemma UN_least: "[| !!x. x\A ==> B(x)\C |] ==> (\x\A. B(x)) \ C" by blast lemma Union_eq_UN: "\(A) = (\x\A. x)" by blast lemma Inter_eq_INT: "\(A) = (\x\A. x)" by (unfold Inter_def, blast) lemma UN_0 [simp]: "(\i\0. A(i)) = 0" by blast lemma UN_singleton: "(\x\A. {x}) = A" by blast lemma UN_Un: "(\i\ A \ B. C(i)) = (\i\ A. C(i)) \ (\i\B. C(i))" by blast lemma INT_Un: "(\i\I \ J. A(i)) = (if I=0 then \j\J. A(j) else if J=0 then \i\I. A(i) else ((\i\I. A(i)) \ (\j\J. A(j))))" by (simp, blast intro!: equalityI) lemma UN_UN_flatten: "(\x \ (\y\A. B(y)). C(x)) = (\y\A. \x\ B(y). C(x))" by blast (*Halmos, Naive Set Theory, page 35.*) lemma Int_UN_distrib: "B \ (\i\I. A(i)) = (\i\I. B \ A(i))" by blast lemma Un_INT_distrib: "I\0 ==> B \ (\i\I. A(i)) = (\i\I. B \ A(i))" by auto lemma Int_UN_distrib2: "(\i\I. A(i)) \ (\j\J. B(j)) = (\i\I. \j\J. A(i) \ B(j))" by blast lemma Un_INT_distrib2: "[| I\0; J\0 |] ==> (\i\I. A(i)) \ (\j\J. B(j)) = (\i\I. \j\J. A(i) \ B(j))" by auto lemma UN_constant [simp]: "(\y\A. c) = (if A=0 then 0 else c)" by force lemma INT_constant [simp]: "(\y\A. c) = (if A=0 then 0 else c)" by force lemma UN_RepFun [simp]: "(\y\ RepFun(A,f). B(y)) = (\x\A. B(f(x)))" by blast lemma INT_RepFun [simp]: "(\x\RepFun(A,f). B(x)) = (\a\A. B(f(a)))" by (auto simp add: Inter_def) lemma INT_Union_eq: "0 \ A ==> (\x\ \(A). B(x)) = (\y\A. \x\y. B(x))" apply (subgoal_tac "\x\A. x\0") prefer 2 apply blast apply (force simp add: Inter_def ball_conj_distrib) done lemma INT_UN_eq: "(\x\A. B(x) \ 0) ==> (\z\ (\x\A. B(x)). C(z)) = (\x\A. \z\ B(x). C(z))" apply (subst INT_Union_eq, blast) apply (simp add: Inter_def) done (** Devlin, Fundamentals of Contemporary Set Theory, page 12, exercise 5: Union of a family of unions **) lemma UN_Un_distrib: "(\i\I. A(i) \ B(i)) = (\i\I. A(i)) \ (\i\I. B(i))" by blast lemma INT_Int_distrib: "I\0 ==> (\i\I. A(i) \ B(i)) = (\i\I. A(i)) \ (\i\I. B(i))" by (blast elim!: not_emptyE) lemma UN_Int_subset: "(\z\I \ J. A(z)) \ (\z\I. A(z)) \ (\z\J. A(z))" by blast (** Devlin, page 12, exercise 5: Complements **) lemma Diff_UN: "I\0 ==> B - (\i\I. A(i)) = (\i\I. B - A(i))" by (blast elim!: not_emptyE) lemma Diff_INT: "I\0 ==> B - (\i\I. A(i)) = (\i\I. B - A(i))" by (blast elim!: not_emptyE) (** Unions and Intersections with General Sum **) (*Not suitable for rewriting: LOOPS!*) lemma Sigma_cons1: "Sigma(cons(a,B), C) = ({a}*C(a)) \ Sigma(B,C)" by blast (*Not suitable for rewriting: LOOPS!*) lemma Sigma_cons2: "A * cons(b,B) = A*{b} \ A*B" by blast lemma Sigma_succ1: "Sigma(succ(A), B) = ({A}*B(A)) \ Sigma(A,B)" by blast lemma Sigma_succ2: "A * succ(B) = A*{B} \ A*B" by blast lemma SUM_UN_distrib1: "(\x \ (\y\A. C(y)). B(x)) = (\y\A. \x\C(y). B(x))" by blast lemma SUM_UN_distrib2: "(\i\I. \j\J. C(i,j)) = (\j\J. \i\I. C(i,j))" by blast lemma SUM_Un_distrib1: "(\i\I \ J. C(i)) = (\i\I. C(i)) \ (\j\J. C(j))" by blast lemma SUM_Un_distrib2: "(\i\I. A(i) \ B(i)) = (\i\I. A(i)) \ (\i\I. B(i))" by blast (*First-order version of the above, for rewriting*) lemma prod_Un_distrib2: "I * (A \ B) = I*A \ I*B" by (rule SUM_Un_distrib2) lemma SUM_Int_distrib1: "(\i\I \ J. C(i)) = (\i\I. C(i)) \ (\j\J. C(j))" by blast lemma SUM_Int_distrib2: "(\i\I. A(i) \ B(i)) = (\i\I. A(i)) \ (\i\I. B(i))" by blast (*First-order version of the above, for rewriting*) lemma prod_Int_distrib2: "I * (A \ B) = I*A \ I*B" by (rule SUM_Int_distrib2) (*Cf Aczel, Non-Well-Founded Sets, page 115*) lemma SUM_eq_UN: "(\i\I. A(i)) = (\i\I. {i} * A(i))" by blast lemma times_subset_iff: "(A'*B' \ A*B) \ (A' = 0 | B' = 0 | (A'\A) & (B'\B))" by blast lemma Int_Sigma_eq: "(\x \ A'. B'(x)) \ (\x \ A. B(x)) = (\x \ A' \ A. B'(x) \ B(x))" by blast (** Domain **) lemma domain_iff: "a: domain(r) \ (\y. \ r)" by (unfold domain_def, blast) lemma domainI [intro]: "\ r ==> a: domain(r)" by (unfold domain_def, blast) lemma domainE [elim!]: "[| a \ domain(r); !!y. \ r ==> P |] ==> P" by (unfold domain_def, blast) lemma domain_subset: "domain(Sigma(A,B)) \ A" by blast lemma domain_of_prod: "b\B ==> domain(A*B) = A" by blast lemma domain_0 [simp]: "domain(0) = 0" by blast lemma domain_cons [simp]: "domain(cons(,r)) = cons(a, domain(r))" by blast lemma domain_Un_eq [simp]: "domain(A \ B) = domain(A) \ domain(B)" by blast lemma domain_Int_subset: "domain(A \ B) \ domain(A) \ domain(B)" by blast lemma domain_Diff_subset: "domain(A) - domain(B) \ domain(A - B)" by blast lemma domain_UN: "domain(\x\A. B(x)) = (\x\A. domain(B(x)))" by blast lemma domain_Union: "domain(\(A)) = (\x\A. domain(x))" by blast (** Range **) lemma rangeI [intro]: "\ r ==> b \ range(r)" apply (unfold range_def) apply (erule converseI [THEN domainI]) done lemma rangeE [elim!]: "[| b \ range(r); !!x. \ r ==> P |] ==> P" by (unfold range_def, blast) lemma range_subset: "range(A*B) \ B" apply (unfold range_def) apply (subst converse_prod) apply (rule domain_subset) done lemma range_of_prod: "a\A ==> range(A*B) = B" by blast lemma range_0 [simp]: "range(0) = 0" by blast lemma range_cons [simp]: "range(cons(,r)) = cons(b, range(r))" by blast lemma range_Un_eq [simp]: "range(A \ B) = range(A) \ range(B)" by blast lemma range_Int_subset: "range(A \ B) \ range(A) \ range(B)" by blast lemma range_Diff_subset: "range(A) - range(B) \ range(A - B)" by blast lemma domain_converse [simp]: "domain(converse(r)) = range(r)" by blast lemma range_converse [simp]: "range(converse(r)) = domain(r)" by blast (** Field **) lemma fieldI1: "\ r ==> a \ field(r)" by (unfold field_def, blast) lemma fieldI2: "\ r ==> b \ field(r)" by (unfold field_def, blast) lemma fieldCI [intro]: "(~ \r ==> \ r) ==> a \ field(r)" apply (unfold field_def, blast) done lemma fieldE [elim!]: "[| a \ field(r); !!x. \ r ==> P; !!x. \ r ==> P |] ==> P" by (unfold field_def, blast) lemma field_subset: "field(A*B) \ A \ B" by blast lemma domain_subset_field: "domain(r) \ field(r)" apply (unfold field_def) apply (rule Un_upper1) done lemma range_subset_field: "range(r) \ field(r)" apply (unfold field_def) apply (rule Un_upper2) done lemma domain_times_range: "r \ Sigma(A,B) ==> r \ domain(r)*range(r)" by blast lemma field_times_field: "r \ Sigma(A,B) ==> r \ field(r)*field(r)" by blast lemma relation_field_times_field: "relation(r) ==> r \ field(r)*field(r)" by (simp add: relation_def, blast) lemma field_of_prod: "field(A*A) = A" by blast lemma field_0 [simp]: "field(0) = 0" by blast lemma field_cons [simp]: "field(cons(,r)) = cons(a, cons(b, field(r)))" by blast lemma field_Un_eq [simp]: "field(A \ B) = field(A) \ field(B)" by blast lemma field_Int_subset: "field(A \ B) \ field(A) \ field(B)" by blast lemma field_Diff_subset: "field(A) - field(B) \ field(A - B)" by blast lemma field_converse [simp]: "field(converse(r)) = field(r)" by blast (** The Union of a set of relations is a relation -- Lemma for fun_Union **) lemma rel_Union: "(\x\S. \A B. x \ A*B) ==> \(S) \ domain(\(S)) * range(\(S))" by blast (** The Union of 2 relations is a relation (Lemma for fun_Un) **) lemma rel_Un: "[| r \ A*B; s \ C*D |] ==> (r \ s) \ (A \ C) * (B \ D)" by blast lemma domain_Diff_eq: "[| \ r; c\b |] ==> domain(r-{}) = domain(r)" by blast lemma range_Diff_eq: "[| \ r; c\a |] ==> range(r-{}) = range(r)" by blast subsection\Image of a Set under a Function or Relation\ lemma image_iff: "b \ r``A \ (\x\A. \r)" by (unfold image_def, blast) lemma image_singleton_iff: "b \ r``{a} \ \r" by (rule image_iff [THEN iff_trans], blast) lemma imageI [intro]: "[| \ r; a\A |] ==> b \ r``A" by (unfold image_def, blast) lemma imageE [elim!]: "[| b: r``A; !!x.[| \ r; x\A |] ==> P |] ==> P" by (unfold image_def, blast) lemma image_subset: "r \ A*B ==> r``C \ B" by blast lemma image_0 [simp]: "r``0 = 0" by blast lemma image_Un [simp]: "r``(A \ B) = (r``A) \ (r``B)" by blast lemma image_UN: "r `` (\x\A. B(x)) = (\x\A. r `` B(x))" by blast lemma Collect_image_eq: "{z \ Sigma(A,B). P(z)} `` C = (\x \ A. {y \ B(x). x \ C & P()})" by blast lemma image_Int_subset: "r``(A \ B) \ (r``A) \ (r``B)" by blast lemma image_Int_square_subset: "(r \ A*A)``B \ (r``B) \ A" by blast lemma image_Int_square: "B\A ==> (r \ A*A)``B = (r``B) \ A" by blast (*Image laws for special relations*) lemma image_0_left [simp]: "0``A = 0" by blast lemma image_Un_left: "(r \ s)``A = (r``A) \ (s``A)" by blast lemma image_Int_subset_left: "(r \ s)``A \ (r``A) \ (s``A)" by blast subsection\Inverse Image of a Set under a Function or Relation\ lemma vimage_iff: "a \ r-``B \ (\y\B. \r)" by (unfold vimage_def image_def converse_def, blast) lemma vimage_singleton_iff: "a \ r-``{b} \ \r" by (rule vimage_iff [THEN iff_trans], blast) lemma vimageI [intro]: "[| \ r; b\B |] ==> a \ r-``B" by (unfold vimage_def, blast) lemma vimageE [elim!]: "[| a: r-``B; !!x.[| \ r; x\B |] ==> P |] ==> P" apply (unfold vimage_def, blast) done lemma vimage_subset: "r \ A*B ==> r-``C \ A" apply (unfold vimage_def) apply (erule converse_type [THEN image_subset]) done lemma vimage_0 [simp]: "r-``0 = 0" by blast lemma vimage_Un [simp]: "r-``(A \ B) = (r-``A) \ (r-``B)" by blast lemma vimage_Int_subset: "r-``(A \ B) \ (r-``A) \ (r-``B)" by blast (*NOT suitable for rewriting*) lemma vimage_eq_UN: "f -``B = (\y\B. f-``{y})" by blast lemma function_vimage_Int: "function(f) ==> f-``(A \ B) = (f-``A) \ (f-``B)" by (unfold function_def, blast) lemma function_vimage_Diff: "function(f) ==> f-``(A-B) = (f-``A) - (f-``B)" by (unfold function_def, blast) lemma function_image_vimage: "function(f) ==> f `` (f-`` A) \ A" by (unfold function_def, blast) lemma vimage_Int_square_subset: "(r \ A*A)-``B \ (r-``B) \ A" by blast lemma vimage_Int_square: "B\A ==> (r \ A*A)-``B = (r-``B) \ A" by blast (*Invese image laws for special relations*) lemma vimage_0_left [simp]: "0-``A = 0" by blast lemma vimage_Un_left: "(r \ s)-``A = (r-``A) \ (s-``A)" by blast lemma vimage_Int_subset_left: "(r \ s)-``A \ (r-``A) \ (s-``A)" by blast (** Converse **) lemma converse_Un [simp]: "converse(A \ B) = converse(A) \ converse(B)" by blast lemma converse_Int [simp]: "converse(A \ B) = converse(A) \ converse(B)" by blast lemma converse_Diff [simp]: "converse(A - B) = converse(A) - converse(B)" by blast lemma converse_UN [simp]: "converse(\x\A. B(x)) = (\x\A. converse(B(x)))" by blast (*Unfolding Inter avoids using excluded middle on A=0*) lemma converse_INT [simp]: "converse(\x\A. B(x)) = (\x\A. converse(B(x)))" apply (unfold Inter_def, blast) done subsection\Powerset Operator\ lemma Pow_0 [simp]: "Pow(0) = {0}" by blast lemma Pow_insert: "Pow (cons(a,A)) = Pow(A) \ {cons(a,X) . X: Pow(A)}" apply (rule equalityI, safe) apply (erule swap) apply (rule_tac a = "x-{a}" in RepFun_eqI, auto) done lemma Un_Pow_subset: "Pow(A) \ Pow(B) \ Pow(A \ B)" by blast lemma UN_Pow_subset: "(\x\A. Pow(B(x))) \ Pow(\x\A. B(x))" by blast lemma subset_Pow_Union: "A \ Pow(\(A))" by blast lemma Union_Pow_eq [simp]: "\(Pow(A)) = A" by blast lemma Union_Pow_iff: "\(A) \ Pow(B) \ A \ Pow(Pow(B))" by blast lemma Pow_Int_eq [simp]: "Pow(A \ B) = Pow(A) \ Pow(B)" by blast lemma Pow_INT_eq: "A\0 ==> Pow(\x\A. B(x)) = (\x\A. Pow(B(x)))" by (blast elim!: not_emptyE) subsection\RepFun\ lemma RepFun_subset: "[| !!x. x\A ==> f(x) \ B |] ==> {f(x). x\A} \ B" by blast lemma RepFun_eq_0_iff [simp]: "{f(x).x\A}=0 \ A=0" by blast lemma RepFun_constant [simp]: "{c. x\A} = (if A=0 then 0 else {c})" by force subsection\Collect\ lemma Collect_subset: "Collect(A,P) \ A" by blast lemma Collect_Un: "Collect(A \ B, P) = Collect(A,P) \ Collect(B,P)" by blast lemma Collect_Int: "Collect(A \ B, P) = Collect(A,P) \ Collect(B,P)" by blast lemma Collect_Diff: "Collect(A - B, P) = Collect(A,P) - Collect(B,P)" by blast lemma Collect_cons: "{x\cons(a,B). P(x)} = (if P(a) then cons(a, {x\B. P(x)}) else {x\B. P(x)})" by (simp, blast) lemma Int_Collect_self_eq: "A \ Collect(A,P) = Collect(A,P)" by blast lemma Collect_Collect_eq [simp]: "Collect(Collect(A,P), Q) = Collect(A, %x. P(x) & Q(x))" by blast lemma Collect_Int_Collect_eq: "Collect(A,P) \ Collect(A,Q) = Collect(A, %x. P(x) & Q(x))" by blast lemma Collect_Union_eq [simp]: "Collect(\x\A. B(x), P) = (\x\A. Collect(B(x), P))" by blast lemma Collect_Int_left: "{x\A. P(x)} \ B = {x \ A \ B. P(x)}" by blast lemma Collect_Int_right: "A \ {x\B. P(x)} = {x \ A \ B. P(x)}" by blast lemma Collect_disj_eq: "{x\A. P(x) | Q(x)} = Collect(A, P) \ Collect(A, Q)" by blast lemma Collect_conj_eq: "{x\A. P(x) & Q(x)} = Collect(A, P) \ Collect(A, Q)" by blast lemmas subset_SIs = subset_refl cons_subsetI subset_consI Union_least UN_least Un_least Inter_greatest Int_greatest RepFun_subset Un_upper1 Un_upper2 Int_lower1 Int_lower2 ML \ val subset_cs = claset_of (\<^context> delrules [@{thm subsetI}, @{thm subsetCE}] addSIs @{thms subset_SIs} addIs [@{thm Union_upper}, @{thm Inter_lower}] addSEs [@{thm cons_subsetE}]); val ZF_cs = claset_of (\<^context> delrules [@{thm equalityI}]); \ end diff --git a/src/ZF/func.thy b/src/ZF/func.thy --- a/src/ZF/func.thy +++ b/src/ZF/func.thy @@ -1,611 +1,611 @@ (* Title: ZF/func.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1991 University of Cambridge *) section\Functions, Function Spaces, Lambda-Abstraction\ theory func imports equalities Sum begin subsection\The Pi Operator: Dependent Function Space\ lemma subset_Sigma_imp_relation: "r \ Sigma(A,B) ==> relation(r)" by (simp add: relation_def, blast) lemma relation_converse_converse [simp]: "relation(r) ==> converse(converse(r)) = r" by (simp add: relation_def, blast) lemma relation_restrict [simp]: "relation(restrict(r,A))" by (simp add: restrict_def relation_def, blast) lemma Pi_iff: "f \ Pi(A,B) \ function(f) & f<=Sigma(A,B) & A<=domain(f)" by (unfold Pi_def, blast) (*For upward compatibility with the former definition*) lemma Pi_iff_old: "f \ Pi(A,B) \ f<=Sigma(A,B) & (\x\A. \!y. : f)" by (unfold Pi_def function_def, blast) lemma fun_is_function: "f \ Pi(A,B) ==> function(f)" by (simp only: Pi_iff) lemma function_imp_Pi: "[|function(f); relation(f)|] ==> f \ domain(f) -> range(f)" by (simp add: Pi_iff relation_def, blast) lemma functionI: "[| !!x y y'. [| :r; :r |] ==> y=y' |] ==> function(r)" by (simp add: function_def, blast) (*Functions are relations*) lemma fun_is_rel: "f \ Pi(A,B) ==> f \ Sigma(A,B)" by (unfold Pi_def, blast) lemma Pi_cong: "[| A=A'; !!x. x \ A' ==> B(x)=B'(x) |] ==> Pi(A,B) = Pi(A',B')" by (simp add: Pi_def cong add: Sigma_cong) (*Sigma_cong, Pi_cong NOT given to Addcongs: they cause flex-flex pairs and the "Check your prover" error. Most Sigmas and Pis are abbreviated as * or -> *) (*Weakening one function type to another; see also Pi_type*) lemma fun_weaken_type: "[| f \ A->B; B<=D |] ==> f \ A->D" by (unfold Pi_def, best) subsection\Function Application\ lemma apply_equality2: "[| : f; : f; f \ Pi(A,B) |] ==> b=c" by (unfold Pi_def function_def, blast) lemma function_apply_equality: "[| : f; function(f) |] ==> f`a = b" by (unfold apply_def function_def, blast) lemma apply_equality: "[| : f; f \ Pi(A,B) |] ==> f`a = b" apply (unfold Pi_def) apply (blast intro: function_apply_equality) done (*Applying a function outside its domain yields 0*) lemma apply_0: "a \ domain(f) ==> f`a = 0" by (unfold apply_def, blast) lemma Pi_memberD: "[| f \ Pi(A,B); c \ f |] ==> \x\A. c = " apply (frule fun_is_rel) apply (blast dest: apply_equality) done lemma function_apply_Pair: "[| function(f); a \ domain(f)|] ==> : f" apply (simp add: function_def, clarify) apply (subgoal_tac "f`a = y", blast) apply (simp add: apply_def, blast) done lemma apply_Pair: "[| f \ Pi(A,B); a \ A |] ==> : f" apply (simp add: Pi_iff) apply (blast intro: function_apply_Pair) done (*Conclusion is flexible -- use rule_tac or else apply_funtype below!*) lemma apply_type [TC]: "[| f \ Pi(A,B); a \ A |] ==> f`a \ B(a)" by (blast intro: apply_Pair dest: fun_is_rel) (*This version is acceptable to the simplifier*) lemma apply_funtype: "[| f \ A->B; a \ A |] ==> f`a \ B" by (blast dest: apply_type) lemma apply_iff: "f \ Pi(A,B) ==> : f \ a \ A & f`a = b" apply (frule fun_is_rel) apply (blast intro!: apply_Pair apply_equality) done (*Refining one Pi type to another*) lemma Pi_type: "[| f \ Pi(A,C); !!x. x \ A ==> f`x \ B(x) |] ==> f \ Pi(A,B)" apply (simp only: Pi_iff) apply (blast dest: function_apply_equality) done (*Such functions arise in non-standard datatypes, ZF/ex/Ntree for instance*) lemma Pi_Collect_iff: "(f \ Pi(A, %x. {y \ B(x). P(x,y)})) \ f \ Pi(A,B) & (\x\A. P(x, f`x))" by (blast intro: Pi_type dest: apply_type) lemma Pi_weaken_type: "[| f \ Pi(A,B); !!x. x \ A ==> B(x)<=C(x) |] ==> f \ Pi(A,C)" by (blast intro: Pi_type dest: apply_type) (** Elimination of membership in a function **) lemma domain_type: "[| \ f; f \ Pi(A,B) |] ==> a \ A" by (blast dest: fun_is_rel) lemma range_type: "[| \ f; f \ Pi(A,B) |] ==> b \ B(a)" by (blast dest: fun_is_rel) lemma Pair_mem_PiD: "[| : f; f \ Pi(A,B) |] ==> a \ A & b \ B(a) & f`a = b" by (blast intro: domain_type range_type apply_equality) subsection\Lambda Abstraction\ lemma lamI: "a \ A ==> \ (\x\A. b(x))" apply (unfold lam_def) apply (erule RepFunI) done lemma lamE: "[| p: (\x\A. b(x)); !!x.[| x \ A; p= |] ==> P |] ==> P" by (simp add: lam_def, blast) lemma lamD: "[| : (\x\A. b(x)) |] ==> c = b(a)" by (simp add: lam_def) lemma lam_type [TC]: "[| !!x. x \ A ==> b(x): B(x) |] ==> (\x\A. b(x)) \ Pi(A,B)" by (simp add: lam_def Pi_def function_def, blast) lemma lam_funtype: "(\x\A. b(x)) \ A -> {b(x). x \ A}" by (blast intro: lam_type) lemma function_lam: "function (\x\A. b(x))" by (simp add: function_def lam_def) lemma relation_lam: "relation (\x\A. b(x))" by (simp add: relation_def lam_def) lemma beta_if [simp]: "(\x\A. b(x)) ` a = (if a \ A then b(a) else 0)" by (simp add: apply_def lam_def, blast) lemma beta: "a \ A ==> (\x\A. b(x)) ` a = b(a)" by (simp add: apply_def lam_def, blast) lemma lam_empty [simp]: "(\x\0. b(x)) = 0" by (simp add: lam_def) lemma domain_lam [simp]: "domain(Lambda(A,b)) = A" by (simp add: lam_def, blast) (*congruence rule for lambda abstraction*) lemma lam_cong [cong]: "[| A=A'; !!x. x \ A' ==> b(x)=b'(x) |] ==> Lambda(A,b) = Lambda(A',b')" by (simp only: lam_def cong add: RepFun_cong) lemma lam_theI: "(!!x. x \ A ==> \!y. Q(x,y)) ==> \f. \x\A. Q(x, f`x)" apply (rule_tac x = "\x\A. THE y. Q (x,y)" in exI) apply simp apply (blast intro: theI) done lemma lam_eqE: "[| (\x\A. f(x)) = (\x\A. g(x)); a \ A |] ==> f(a)=g(a)" by (fast intro!: lamI elim: equalityE lamE) (*Empty function spaces*) lemma Pi_empty1 [simp]: "Pi(0,A) = {0}" by (unfold Pi_def function_def, blast) (*The singleton function*) lemma singleton_fun [simp]: "{} \ {a} -> {b}" by (unfold Pi_def function_def, blast) lemma Pi_empty2 [simp]: "(A->0) = (if A=0 then {0} else 0)" by (unfold Pi_def function_def, force) lemma fun_space_empty_iff [iff]: "(A->X)=0 \ X=0 & (A \ 0)" apply auto apply (fast intro!: equals0I intro: lam_type) done subsection\Extensionality\ (*Semi-extensionality!*) lemma fun_subset: "[| f \ Pi(A,B); g \ Pi(C,D); A<=C; !!x. x \ A ==> f`x = g`x |] ==> f<=g" by (force dest: Pi_memberD intro: apply_Pair) lemma fun_extension: "[| f \ Pi(A,B); g \ Pi(A,D); !!x. x \ A ==> f`x = g`x |] ==> f=g" by (blast del: subsetI intro: subset_refl sym fun_subset) lemma eta [simp]: "f \ Pi(A,B) ==> (\x\A. f`x) = f" apply (rule fun_extension) apply (auto simp add: lam_type apply_type beta) done lemma fun_extension_iff: "[| f \ Pi(A,B); g \ Pi(A,C) |] ==> (\a\A. f`a = g`a) \ f=g" by (blast intro: fun_extension) (*thm by Mark Staples, proof by lcp*) lemma fun_subset_eq: "[| f \ Pi(A,B); g \ Pi(A,C) |] ==> f \ g \ (f = g)" by (blast dest: apply_Pair intro: fun_extension apply_equality [symmetric]) (*Every element of Pi(A,B) may be expressed as a lambda abstraction!*) lemma Pi_lamE: assumes major: "f \ Pi(A,B)" and minor: "!!b. [| \x\A. b(x):B(x); f = (\x\A. b(x)) |] ==> P" shows "P" apply (rule minor) apply (rule_tac [2] eta [symmetric]) apply (blast intro: major apply_type)+ done subsection\Images of Functions\ lemma image_lam: "C \ A ==> (\x\A. b(x)) `` C = {b(x). x \ C}" by (unfold lam_def, blast) lemma Repfun_function_if: "function(f) ==> {f`x. x \ C} = (if C \ domain(f) then f``C else cons(0,f``C))" apply simp apply (intro conjI impI) apply (blast dest: function_apply_equality intro: function_apply_Pair) apply (rule equalityI) apply (blast intro!: function_apply_Pair apply_0) apply (blast dest: function_apply_equality intro: apply_0 [symmetric]) done (*For this lemma and the next, the right-hand side could equivalently be written \x\C. {f`x} *) lemma image_function: "[| function(f); C \ domain(f) |] ==> f``C = {f`x. x \ C}" by (simp add: Repfun_function_if) lemma image_fun: "[| f \ Pi(A,B); C \ A |] ==> f``C = {f`x. x \ C}" apply (simp add: Pi_iff) apply (blast intro: image_function) done lemma image_eq_UN: assumes f: "f \ Pi(A,B)" "C \ A" shows "f``C = (\x\C. {f ` x})" by (auto simp add: image_fun [OF f]) lemma Pi_image_cons: "[| f \ Pi(A,B); x \ A |] ==> f `` cons(x,y) = cons(f`x, f``y)" by (blast dest: apply_equality apply_Pair) subsection\Properties of \<^term>\restrict(f,A)\\ lemma restrict_subset: "restrict(f,A) \ f" by (unfold restrict_def, blast) lemma function_restrictI: "function(f) ==> function(restrict(f,A))" by (unfold restrict_def function_def, blast) lemma restrict_type2: "[| f \ Pi(C,B); A<=C |] ==> restrict(f,A) \ Pi(A,B)" by (simp add: Pi_iff function_def restrict_def, blast) lemma restrict: "restrict(f,A) ` a = (if a \ A then f`a else 0)" by (simp add: apply_def restrict_def, blast) lemma restrict_empty [simp]: "restrict(f,0) = 0" by (unfold restrict_def, simp) lemma restrict_iff: "z \ restrict(r,A) \ z \ r & (\x\A. \y. z = \x, y\)" by (simp add: restrict_def) lemma restrict_restrict [simp]: "restrict(restrict(r,A),B) = restrict(r, A \ B)" by (unfold restrict_def, blast) lemma domain_restrict [simp]: "domain(restrict(f,C)) = domain(f) \ C" apply (unfold restrict_def) apply (auto simp add: domain_def) done lemma restrict_idem: "f \ Sigma(A,B) ==> restrict(f,A) = f" by (simp add: restrict_def, blast) (*converse probably holds too*) lemma domain_restrict_idem: "[| domain(r) \ A; relation(r) |] ==> restrict(r,A) = r" by (simp add: restrict_def relation_def, blast) lemma domain_restrict_lam [simp]: "domain(restrict(Lambda(A,f),C)) = A \ C" apply (unfold restrict_def lam_def) apply (rule equalityI) apply (auto simp add: domain_iff) done lemma restrict_if [simp]: "restrict(f,A) ` a = (if a \ A then f`a else 0)" by (simp add: restrict apply_0) lemma restrict_lam_eq: "A<=C ==> restrict(\x\C. b(x), A) = (\x\A. b(x))" by (unfold restrict_def lam_def, auto) lemma fun_cons_restrict_eq: "f \ cons(a, b) -> B ==> f = cons(, restrict(f, b))" apply (rule equalityI) prefer 2 apply (blast intro: apply_Pair restrict_subset [THEN subsetD]) apply (auto dest!: Pi_memberD simp add: restrict_def lam_def) done subsection\Unions of Functions\ (** The Union of a set of COMPATIBLE functions is a function **) lemma function_Union: "[| \x\S. function(x); \x\S. \y\S. x<=y | y<=x |] ==> function(\(S))" by (unfold function_def, blast) lemma fun_Union: "[| \f\S. \C D. f \ C->D; \f\S. \y\S. f<=y | y<=f |] ==> \(S) \ domain(\(S)) -> range(\(S))" apply (unfold Pi_def) apply (blast intro!: rel_Union function_Union) done -lemma gen_relation_Union [rule_format]: - "\f\F. relation(f) \ relation(\(F))" +lemma gen_relation_Union: + "(\f. f\F \ relation(f)) \ relation(\(F))" by (simp add: relation_def) (** The Union of 2 disjoint functions is a function **) lemmas Un_rls = Un_subset_iff SUM_Un_distrib1 prod_Un_distrib2 subset_trans [OF _ Un_upper1] subset_trans [OF _ Un_upper2] lemma fun_disjoint_Un: "[| f \ A->B; g \ C->D; A \ C = 0 |] ==> (f \ g) \ (A \ C) -> (B \ D)" (*Prove the product and domain subgoals using distributive laws*) apply (simp add: Pi_iff extension Un_rls) apply (unfold function_def, blast) done lemma fun_disjoint_apply1: "a \ domain(g) ==> (f \ g)`a = f`a" by (simp add: apply_def, blast) lemma fun_disjoint_apply2: "c \ domain(f) ==> (f \ g)`c = g`c" by (simp add: apply_def, blast) subsection\Domain and Range of a Function or Relation\ lemma domain_of_fun: "f \ Pi(A,B) ==> domain(f)=A" by (unfold Pi_def, blast) lemma apply_rangeI: "[| f \ Pi(A,B); a \ A |] ==> f`a \ range(f)" by (erule apply_Pair [THEN rangeI], assumption) lemma range_of_fun: "f \ Pi(A,B) ==> f \ A->range(f)" by (blast intro: Pi_type apply_rangeI) subsection\Extensions of Functions\ lemma fun_extend: "[| f \ A->B; c\A |] ==> cons(,f) \ cons(c,A) -> cons(b,B)" apply (frule singleton_fun [THEN fun_disjoint_Un], blast) apply (simp add: cons_eq) done lemma fun_extend3: "[| f \ A->B; c\A; b \ B |] ==> cons(,f) \ cons(c,A) -> B" by (blast intro: fun_extend [THEN fun_weaken_type]) lemma extend_apply: "c \ domain(f) ==> cons(,f)`a = (if a=c then b else f`a)" by (auto simp add: apply_def) lemma fun_extend_apply [simp]: "[| f \ A->B; c\A |] ==> cons(,f)`a = (if a=c then b else f`a)" apply (rule extend_apply) apply (simp add: Pi_def, blast) done lemmas singleton_apply = apply_equality [OF singletonI singleton_fun, simp] (*For Finite.ML. Inclusion of right into left is easy*) lemma cons_fun_eq: "c \ A ==> cons(c,A) -> B = (\f \ A->B. \b\B. {cons(, f)})" apply (rule equalityI) apply (safe elim!: fun_extend3) (*Inclusion of left into right*) apply (subgoal_tac "restrict (x, A) \ A -> B") prefer 2 apply (blast intro: restrict_type2) apply (rule UN_I, assumption) apply (rule apply_funtype [THEN UN_I]) apply assumption apply (rule consI1) apply (simp (no_asm)) apply (rule fun_extension) apply assumption apply (blast intro: fun_extend) apply (erule consE, simp_all) done lemma succ_fun_eq: "succ(n) -> B = (\f \ n->B. \b\B. {cons(, f)})" by (simp add: succ_def mem_not_refl cons_fun_eq) subsection\Function Updates\ definition update :: "[i,i,i] => i" where "update(f,a,b) == \x\cons(a, domain(f)). if(x=a, b, f`x)" nonterminal updbinds and updbind syntax (* Let expressions *) "_updbind" :: "[i, i] => updbind" (\(2_ :=/ _)\) "" :: "updbind => updbinds" (\_\) "_updbinds" :: "[updbind, updbinds] => updbinds" (\_,/ _\) "_Update" :: "[i, updbinds] => i" (\_/'((_)')\ [900,0] 900) translations "_Update (f, _updbinds(b,bs))" == "_Update (_Update(f,b), bs)" "f(x:=y)" == "CONST update(f,x,y)" lemma update_apply [simp]: "f(x:=y) ` z = (if z=x then y else f`z)" apply (simp add: update_def) apply (case_tac "z \ domain(f)") apply (simp_all add: apply_0) done lemma update_idem: "[| f`x = y; f \ Pi(A,B); x \ A |] ==> f(x:=y) = f" apply (unfold update_def) apply (simp add: domain_of_fun cons_absorb) apply (rule fun_extension) apply (best intro: apply_type if_type lam_type, assumption, simp) done (* [| f \ Pi(A, B); x \ A |] ==> f(x := f`x) = f *) declare refl [THEN update_idem, simp] lemma domain_update [simp]: "domain(f(x:=y)) = cons(x, domain(f))" by (unfold update_def, simp) lemma update_type: "[| f \ Pi(A,B); x \ A; y \ B(x) |] ==> f(x:=y) \ Pi(A, B)" apply (unfold update_def) apply (simp add: domain_of_fun cons_absorb apply_funtype lam_type) done subsection\Monotonicity Theorems\ subsubsection\Replacement in its Various Forms\ (*Not easy to express monotonicity in P, since any "bigger" predicate would have to be single-valued*) lemma Replace_mono: "A<=B ==> Replace(A,P) \ Replace(B,P)" by (blast elim!: ReplaceE) lemma RepFun_mono: "A<=B ==> {f(x). x \ A} \ {f(x). x \ B}" by blast lemma Pow_mono: "A<=B ==> Pow(A) \ Pow(B)" by blast lemma Union_mono: "A<=B ==> \(A) \ \(B)" by blast lemma UN_mono: "[| A<=C; !!x. x \ A ==> B(x)<=D(x) |] ==> (\x\A. B(x)) \ (\x\C. D(x))" by blast (*Intersection is ANTI-monotonic. There are TWO premises! *) lemma Inter_anti_mono: "[| A<=B; A\0 |] ==> \(B) \ \(A)" by blast lemma cons_mono: "C<=D ==> cons(a,C) \ cons(a,D)" by blast lemma Un_mono: "[| A<=C; B<=D |] ==> A \ B \ C \ D" by blast lemma Int_mono: "[| A<=C; B<=D |] ==> A \ B \ C \ D" by blast lemma Diff_mono: "[| A<=C; D<=B |] ==> A-B \ C-D" by blast subsubsection\Standard Products, Sums and Function Spaces\ lemma Sigma_mono [rule_format]: "[| A<=C; !!x. x \ A \ B(x) \ D(x) |] ==> Sigma(A,B) \ Sigma(C,D)" by blast lemma sum_mono: "[| A<=C; B<=D |] ==> A+B \ C+D" by (unfold sum_def, blast) (*Note that B->A and C->A are typically disjoint!*) lemma Pi_mono: "B<=C ==> A->B \ A->C" by (blast intro: lam_type elim: Pi_lamE) lemma lam_mono: "A<=B ==> Lambda(A,c) \ Lambda(B,c)" apply (unfold lam_def) apply (erule RepFun_mono) done subsubsection\Converse, Domain, Range, Field\ lemma converse_mono: "r<=s ==> converse(r) \ converse(s)" by blast lemma domain_mono: "r<=s ==> domain(r)<=domain(s)" by blast lemmas domain_rel_subset = subset_trans [OF domain_mono domain_subset] lemma range_mono: "r<=s ==> range(r)<=range(s)" by blast lemmas range_rel_subset = subset_trans [OF range_mono range_subset] lemma field_mono: "r<=s ==> field(r)<=field(s)" by blast lemma field_rel_subset: "r \ A*A ==> field(r) \ A" by (erule field_mono [THEN subset_trans], blast) subsubsection\Images\ lemma image_pair_mono: "[| !! x y. :r ==> :s; A<=B |] ==> r``A \ s``B" by blast lemma vimage_pair_mono: "[| !! x y. :r ==> :s; A<=B |] ==> r-``A \ s-``B" by blast lemma image_mono: "[| r<=s; A<=B |] ==> r``A \ s``B" by blast lemma vimage_mono: "[| r<=s; A<=B |] ==> r-``A \ s-``B" by blast lemma Collect_mono: "[| A<=B; !!x. x \ A ==> P(x) \ Q(x) |] ==> Collect(A,P) \ Collect(B,Q)" by blast (*Used in intr_elim.ML and in individual datatype definitions*) lemmas basic_monos = subset_refl imp_refl disj_mono conj_mono ex_mono Collect_mono Part_mono in_mono (* Useful with simp; contributed by Clemens Ballarin. *) lemma bex_image_simp: "[| f \ Pi(X, Y); A \ X |] ==> (\x\f``A. P(x)) \ (\x\A. P(f`x))" apply safe apply rule prefer 2 apply assumption apply (simp add: apply_equality) apply (blast intro: apply_Pair) done lemma ball_image_simp: "[| f \ Pi(X, Y); A \ X |] ==> (\x\f``A. P(x)) \ (\x\A. P(f`x))" apply safe apply (blast intro: apply_Pair) apply (drule bspec) apply assumption apply (simp add: apply_equality) done end