diff --git a/src/ZF/AC/AC15_WO6.thy b/src/ZF/AC/AC15_WO6.thy --- a/src/ZF/AC/AC15_WO6.thy +++ b/src/ZF/AC/AC15_WO6.thy @@ -1,289 +1,289 @@ (* Title: ZF/AC/AC15_WO6.thy Author: Krzysztof Grabczewski The proofs needed to state that AC10, ..., AC15 are equivalent to the rest. We need the following: WO1 \ AC10(n) \ AC11 \ AC12 \ AC15 \ WO6 In order to add the formulations AC13 and AC14 we need: AC10(succ(n)) \ AC13(n) \ AC14 \ AC15 or AC1 \ AC13(1); AC13(m) \ AC13(n) \ AC14 \ AC15 (m\n) So we don't have to prove all implications of both cases. Moreover we don't need to prove AC13(1) \ AC1 and AC11 \ AC14 as Rubin \ Rubin do. *) theory AC15_WO6 imports HH Cardinal_aux begin (* ********************************************************************** *) (* Lemmas used in the proofs in which the conclusion is AC13, AC14 *) (* or AC15 *) (* - cons_times_nat_not_Finite *) (* - ex_fun_AC13_AC15 *) (* ********************************************************************** *) lemma lepoll_Sigma: "A\0 \ B \ A*B" -apply (unfold lepoll_def) + unfolding lepoll_def apply (erule not_emptyE) apply (rule_tac x = "\z \ B. \x,z\" in exI) apply (fast intro!: snd_conv lam_injective) done lemma cons_times_nat_not_Finite: "0\A \ \B \ {cons(0,x*nat). x \ A}. \Finite(B)" apply clarify apply (rule nat_not_Finite [THEN notE] ) apply (subgoal_tac "x \ 0") apply (blast intro: lepoll_Sigma [THEN lepoll_Finite])+ done lemma lemma1: "\\(C)=A; a \ A\ \ \B \ C. a \ B \ B \ A" by fast lemma lemma2: "\pairwise_disjoint(A); B \ A; C \ A; a \ B; a \ C\ \ B=C" by (unfold pairwise_disjoint_def, blast) lemma lemma3: "\B \ {cons(0, x*nat). x \ A}. pairwise_disjoint(f`B) \ sets_of_size_between(f`B, 2, n) \ \(f`B)=B \ \B \ A. \! u. u \ f`cons(0, B*nat) \ u \ cons(0, B*nat) \ 0 \ u \ 2 \ u \ u \ n" -apply (unfold sets_of_size_between_def) + unfolding sets_of_size_between_def apply (rule ballI) apply (erule_tac x="cons(0, B*nat)" in ballE) apply (blast dest: lemma1 intro!: lemma2, blast) done lemma lemma4: "\A \ i; Ord(i)\ \ {P(a). a \ A} \ i" -apply (unfold lepoll_def) + unfolding lepoll_def apply (erule exE) apply (rule_tac x = "\x \ RepFun(A,P). \ j. \a\A. x=P(a) \ f`a=j" in exI) apply (rule_tac d = "\y. P (converse (f) `y) " in lam_injective) apply (erule RepFunE) apply (frule inj_is_fun [THEN apply_type], assumption) apply (fast intro: LeastI2 elim!: Ord_in_Ord inj_is_fun [THEN apply_type]) apply (erule RepFunE) apply (rule LeastI2) apply fast apply (fast elim!: Ord_in_Ord inj_is_fun [THEN apply_type]) apply (fast elim: sym left_inverse [THEN ssubst]) done lemma lemma5_1: "\B \ A; 2 \ u(B)\ \ (\x \ A. {fst(x). x \ u(x)-{0}})`B \ 0" apply simp apply (fast dest: lepoll_Diff_sing elim: lepoll_trans [THEN succ_lepoll_natE] ssubst intro!: lepoll_refl) done lemma lemma5_2: "\B \ A; u(B) \ cons(0, B*nat)\ \ (\x \ A. {fst(x). x \ u(x)-{0}})`B \ B" apply auto done lemma lemma5_3: "\n \ nat; B \ A; 0 \ u(B); u(B) \ succ(n)\ \ (\x \ A. {fst(x). x \ u(x)-{0}})`B \ n" apply simp apply (fast elim!: Diff_lepoll [THEN lemma4 [OF _ nat_into_Ord]]) done lemma ex_fun_AC13_AC15: "\\B \ {cons(0, x*nat). x \ A}. pairwise_disjoint(f`B) \ sets_of_size_between(f`B, 2, succ(n)) \ \(f`B)=B; n \ nat\ \ \f. \B \ A. f`B \ 0 \ f`B \ B \ f`B \ n" by (fast del: subsetI notI dest!: lemma3 theI intro!: lemma5_1 lemma5_2 lemma5_3) (* ********************************************************************** *) (* The target proofs *) (* ********************************************************************** *) (* ********************************************************************** *) (* AC10(n) \ AC11 *) (* ********************************************************************** *) theorem AC10_AC11: "\n \ nat; 1\n; AC10(n)\ \ AC11" by (unfold AC10_def AC11_def, blast) (* ********************************************************************** *) (* AC11 \ AC12 *) (* ********************************************************************** *) theorem AC11_AC12: "AC11 \ AC12" by (unfold AC10_def AC11_def AC11_def AC12_def, blast) (* ********************************************************************** *) (* AC12 \ AC15 *) (* ********************************************************************** *) theorem AC12_AC15: "AC12 \ AC15" apply (unfold AC12_def AC15_def) apply (blast del: ballI intro!: cons_times_nat_not_Finite ex_fun_AC13_AC15) done (* ********************************************************************** *) (* AC15 \ WO6 *) (* ********************************************************************** *) lemma OUN_eq_UN: "Ord(x) \ (\aa \ x. F(a))" by (fast intro!: ltI dest!: ltD) lemma AC15_WO6_aux1: "\x \ Pow(A)-{0}. f`x\0 \ f`x \ x \ f`x \ m \ (\i<\ x. HH(f,A,x)={A}. HH(f,A,i)) = A" apply (simp add: Ord_Least [THEN OUN_eq_UN]) apply (rule equalityI) apply (fast dest!: less_Least_subset_x) apply (blast del: subsetI intro!: f_subsets_imp_UN_HH_eq_x [THEN Diff_eq_0_iff [THEN iffD1]]) done lemma AC15_WO6_aux2: "\x \ Pow(A)-{0}. f`x\0 \ f`x \ x \ f`x \ m \ \x < (\ x. HH(f,A,x)={A}). HH(f,A,x) \ m" apply (rule oallI) apply (drule ltD [THEN less_Least_subset_x]) apply (frule HH_subset_imp_eq) apply (erule ssubst) apply (blast dest!: HH_subset_x_imp_subset_Diff_UN [THEN not_emptyI2]) (*but can't use del: DiffE despite the obvious conflict*) done theorem AC15_WO6: "AC15 \ WO6" apply (unfold AC15_def WO6_def) apply (rule allI) apply (erule_tac x = "Pow (A) -{0}" in allE) apply (erule impE, fast) apply (elim bexE conjE exE) apply (rule bexI) apply (rule conjI, assumption) apply (rule_tac x = "\ i. HH (f,A,i) ={A}" in exI) apply (rule_tac x = "\j \ (\ i. HH (f,A,i) ={A}) . HH (f,A,j) " in exI) apply (simp_all add: ltD) apply (fast intro!: Ord_Least lam_type [THEN domain_of_fun] elim!: less_Least_subset_x AC15_WO6_aux1 AC15_WO6_aux2) done (* ********************************************************************** *) (* The proof needed in the first case, not in the second *) (* ********************************************************************** *) (* ********************************************************************** *) (* AC10(n) \ AC13(n-1) if 2\n *) (* *) (* Because of the change to the formal definition of AC10(n) we prove *) (* the following obviously equivalent theorem \ *) (* AC10(n) implies AC13(n) for (1\n) *) (* ********************************************************************** *) theorem AC10_AC13: "\n \ nat; 1\n; AC10(n)\ \ AC13(n)" apply (unfold AC10_def AC13_def, safe) apply (erule allE) apply (erule impE [OF _ cons_times_nat_not_Finite], assumption) apply (fast elim!: impE [OF _ cons_times_nat_not_Finite] dest!: ex_fun_AC13_AC15) done (* ********************************************************************** *) (* The proofs needed in the second case, not in the first *) (* ********************************************************************** *) (* ********************************************************************** *) (* AC1 \ AC13(1) *) (* ********************************************************************** *) lemma AC1_AC13: "AC1 \ AC13(1)" apply (unfold AC1_def AC13_def) apply (rule allI) apply (erule allE) apply (rule impI) apply (drule mp, assumption) apply (elim exE) apply (rule_tac x = "\x \ A. {f`x}" in exI) apply (simp add: singleton_eqpoll_1 [THEN eqpoll_imp_lepoll]) done (* ********************************************************************** *) (* AC13(m) \ AC13(n) for m \ n *) (* ********************************************************************** *) lemma AC13_mono: "\m\n; AC13(m)\ \ AC13(n)" -apply (unfold AC13_def) + unfolding AC13_def apply (drule le_imp_lepoll) apply (fast elim!: lepoll_trans) done (* ********************************************************************** *) (* The proofs necessary for both cases *) (* ********************************************************************** *) (* ********************************************************************** *) (* AC13(n) \ AC14 if 1 \ n *) (* ********************************************************************** *) theorem AC13_AC14: "\n \ nat; 1\n; AC13(n)\ \ AC14" by (unfold AC13_def AC14_def, auto) (* ********************************************************************** *) (* AC14 \ AC15 *) (* ********************************************************************** *) theorem AC14_AC15: "AC14 \ AC15" by (unfold AC13_def AC14_def AC15_def, fast) (* ********************************************************************** *) (* The redundant proofs; however cited by Rubin \ Rubin *) (* ********************************************************************** *) (* ********************************************************************** *) (* AC13(1) \ AC1 *) (* ********************************************************************** *) lemma lemma_aux: "\A\0; A \ 1\ \ \a. A={a}" by (fast elim!: not_emptyE lepoll_1_is_sing) lemma AC13_AC1_lemma: "\B \ A. f(B)\0 \ f(B)<=B \ f(B) \ 1 \ (\x \ A. THE y. f(x)={y}) \ (\X \ A. X)" apply (rule lam_type) apply (drule bspec, assumption) apply (elim conjE) apply (erule lemma_aux [THEN exE], assumption) apply (simp add: the_equality) done theorem AC13_AC1: "AC13(1) \ AC1" apply (unfold AC13_def AC1_def) apply (fast elim!: AC13_AC1_lemma) done (* ********************************************************************** *) (* AC11 \ AC14 *) (* ********************************************************************** *) theorem AC11_AC14: "AC11 \ AC14" apply (unfold AC11_def AC14_def) apply (fast intro!: AC10_AC13) done end diff --git a/src/ZF/AC/AC16_WO4.thy b/src/ZF/AC/AC16_WO4.thy --- a/src/ZF/AC/AC16_WO4.thy +++ b/src/ZF/AC/AC16_WO4.thy @@ -1,578 +1,578 @@ (* Title: ZF/AC/AC16_WO4.thy Author: Krzysztof Grabczewski The proof of AC16(n, k) \ WO4(n-k) Tidied (using locales) by LCP *) theory AC16_WO4 imports AC16_lemmas begin (* ********************************************************************** *) (* The case of finite set *) (* ********************************************************************** *) lemma lemma1: "\Finite(A); 0 nat\ \ \a f. Ord(a) \ domain(f) = a \ (\b (\b m)" -apply (unfold Finite_def) + unfolding Finite_def apply (erule bexE) apply (drule eqpoll_sym [THEN eqpoll_def [THEN def_imp_iff, THEN iffD1]]) apply (erule exE) apply (rule_tac x = n in exI) apply (rule_tac x = "\i \ n. {f`i}" in exI) apply (simp add: ltD bij_def surj_def) apply (fast intro!: ltI nat_into_Ord lam_funtype [THEN domain_of_fun] singleton_eqpoll_1 [THEN eqpoll_imp_lepoll, THEN lepoll_trans] nat_1_lepoll_iff [THEN iffD2] elim!: apply_type ltE) done (* ********************************************************************** *) (* The case of infinite set *) (* ********************************************************************** *) (* well_ord(x,r) \ well_ord({{y,z}. y \ x}, Something(x,z)) **) lemmas well_ord_paired = paired_bij [THEN bij_is_inj, THEN well_ord_rvimage] lemma lepoll_trans1: "\A \ B; \ A \ C\ \ \ B \ C" by (blast intro: lepoll_trans) (* ********************************************************************** *) (* There exists a well ordered set y such that ... *) (* ********************************************************************** *) lemmas lepoll_paired = paired_eqpoll [THEN eqpoll_sym, THEN eqpoll_imp_lepoll] lemma lemma2: "\y R. well_ord(y,R) \ x \ y = 0 \ \y \ z \ \Finite(y)" apply (rule_tac x = "{{a,x}. a \ nat \ Hartog (z) }" in exI) apply (rule well_ord_Un [OF Ord_nat [THEN well_ord_Memrel] Ord_Hartog [THEN well_ord_Memrel], THEN exE]) apply (blast intro!: Ord_Hartog well_ord_Memrel well_ord_paired lepoll_trans1 [OF _ not_Hartog_lepoll_self] lepoll_trans [OF subset_imp_lepoll lepoll_paired] elim!: nat_not_Finite [THEN notE] elim: mem_asym dest!: Un_upper1 [THEN subset_imp_lepoll, THEN lepoll_Finite] lepoll_paired [THEN lepoll_Finite]) done lemma infinite_Un: "\Finite(B) \ \Finite(A \ B)" by (blast intro: subset_Finite) (* ********************************************************************** *) (* There is a v \ s(u) such that k \ x \ y (in our case succ(k)) *) (* The idea of the proof is the following \ *) (* Suppose not, i.e. every element of s(u) has exactly k-1 elements of y *) (* Thence y is less than or equipollent to {v \ Pow(x). v \ n#-k} *) (* We have obtained this result in two steps \ *) (* 1. y is less than or equipollent to {v \ s(u). a \ v} *) (* where a is certain k-2 element subset of y *) (* 2. {v \ s(u). a \ v} is less than or equipollent *) (* to {v \ Pow(x). v \ n-k} *) (* ********************************************************************** *) (*Proof simplified by LCP*) lemma succ_not_lepoll_lemma: "\\(\x \ A. f`x=y); f \ inj(A, B); y \ B\ \ (\a \ succ(A). if(a=A, y, f`a)) \ inj(succ(A), B)" apply (rule_tac d = "\z. if (z=y, A, converse (f) `z) " in lam_injective) apply (force simp add: inj_is_fun [THEN apply_type]) (*this preliminary simplification prevents looping somehow*) apply (simp (no_asm_simp)) apply force done lemma succ_not_lepoll_imp_eqpoll: "\\A \ B; A \ B\ \ succ(A) \ B" apply (unfold lepoll_def eqpoll_def bij_def surj_def) apply (fast elim!: succ_not_lepoll_lemma inj_is_fun) done (* ********************************************************************** *) (* There is a k-2 element subset of y *) (* ********************************************************************** *) lemmas ordertype_eqpoll = ordermap_bij [THEN exI [THEN eqpoll_def [THEN def_imp_iff, THEN iffD2]]] lemma cons_cons_subset: "\a \ y; b \ y-a; u \ x\ \ cons(b, cons(u, a)) \ Pow(x \ y)" by fast lemma cons_cons_eqpoll: "\a \ k; a \ y; b \ y-a; u \ x; x \ y = 0\ \ cons(b, cons(u, a)) \ succ(succ(k))" by (fast intro!: cons_eqpoll_succ) lemma set_eq_cons: "\succ(k) \ A; k \ B; B \ A; a \ A-B; k \ nat\ \ A = cons(a, B)" apply (rule equalityI) prefer 2 apply fast apply (rule Diff_eq_0_iff [THEN iffD1]) apply (rule equals0I) apply (drule eqpoll_sym [THEN eqpoll_imp_lepoll]) apply (drule eqpoll_sym [THEN cons_eqpoll_succ], fast) apply (drule cons_eqpoll_succ, fast) apply (fast elim!: lepoll_trans [THEN lepoll_trans, THEN succ_lepoll_natE, OF eqpoll_sym [THEN eqpoll_imp_lepoll] subset_imp_lepoll]) done lemma cons_eqE: "\cons(x,a) = cons(y,a); x \ a\ \ x = y " by (fast elim!: equalityE) lemma eq_imp_Int_eq: "A = B \ A \ C = B \ C" by blast (* ********************************************************************** *) (* some arithmetic *) (* ********************************************************************** *) lemma eqpoll_sum_imp_Diff_lepoll_lemma [rule_format]: "\k \ nat; m \ nat\ \ \A B. A \ k #+ m \ k \ B \ B \ A \ A-B \ m" apply (induct_tac "k") apply (simp add: add_0) apply (blast intro: eqpoll_imp_lepoll lepoll_trans Diff_subset [THEN subset_imp_lepoll]) apply (intro allI impI) apply (rule succ_lepoll_imp_not_empty [THEN not_emptyE], fast) apply (erule_tac x = "A - {xa}" in allE) apply (erule_tac x = "B - {xa}" in allE) apply (erule impE) apply (simp add: add_succ) apply (fast intro!: Diff_sing_eqpoll lepoll_Diff_sing) apply (subgoal_tac "A - {xa} - (B - {xa}) = A - B", simp) apply blast done lemma eqpoll_sum_imp_Diff_lepoll: "\A \ succ(k #+ m); B \ A; succ(k) \ B; k \ nat; m \ nat\ \ A-B \ m" apply (simp only: add_succ [symmetric]) apply (blast intro: eqpoll_sum_imp_Diff_lepoll_lemma) done (* ********************************************************************** *) (* similar properties for \ *) (* ********************************************************************** *) lemma eqpoll_sum_imp_Diff_eqpoll_lemma [rule_format]: "\k \ nat; m \ nat\ \ \A B. A \ k #+ m \ k \ B \ B \ A \ A-B \ m" apply (induct_tac "k") apply (force dest!: eqpoll_sym [THEN eqpoll_imp_lepoll, THEN lepoll_0_is_0]) apply (intro allI impI) apply (rule succ_lepoll_imp_not_empty [THEN not_emptyE]) apply (fast elim!: eqpoll_imp_lepoll) apply (erule_tac x = "A - {xa}" in allE) apply (erule_tac x = "B - {xa}" in allE) apply (erule impE) apply (force intro: eqpoll_sym intro!: Diff_sing_eqpoll) apply (subgoal_tac "A - {xa} - (B - {xa}) = A - B", simp) apply blast done lemma eqpoll_sum_imp_Diff_eqpoll: "\A \ succ(k #+ m); B \ A; succ(k) \ B; k \ nat; m \ nat\ \ A-B \ m" apply (simp only: add_succ [symmetric]) apply (blast intro: eqpoll_sum_imp_Diff_eqpoll_lemma) done (* ********************************************************************** *) (* LL can be well ordered *) (* ********************************************************************** *) lemma subsets_lepoll_0_eq_unit: "{x \ Pow(X). x \ 0} = {0}" by (fast dest!: lepoll_0_is_0 intro!: lepoll_refl) lemma subsets_lepoll_succ: "n \ nat \ {z \ Pow(y). z \ succ(n)} = {z \ Pow(y). z \ n} \ {z \ Pow(y). z \ succ(n)}" by (blast intro: leI le_imp_lepoll nat_into_Ord lepoll_trans eqpoll_imp_lepoll dest!: lepoll_succ_disj) lemma Int_empty: "n \ nat \ {z \ Pow(y). z \ n} \ {z \ Pow(y). z \ succ(n)} = 0" by (blast intro: eqpoll_sym [THEN eqpoll_imp_lepoll, THEN lepoll_trans] succ_lepoll_natE) locale AC16 = fixes x and y and k and l and m and t_n and R and MM and LL and GG and s defines k_def: "k \ succ(l)" and MM_def: "MM \ {v \ t_n. succ(k) \ v \ y}" and LL_def: "LL \ {v \ y. v \ MM}" and GG_def: "GG \ \v \ LL. (THE w. w \ MM \ v \ w) - v" and s_def: "s(u) \ {v \ t_n. u \ v \ k \ v \ y}" assumes all_ex: "\z \ {z \ Pow(x \ y) . z \ succ(k)}. \! w. w \ t_n \ z \ w " and disjoint[iff]: "x \ y = 0" and "includes": "t_n \ {v \ Pow(x \ y). v \ succ(k #+ m)}" and WO_R[iff]: "well_ord(y,R)" and lnat[iff]: "l \ nat" and mnat[iff]: "m \ nat" and mpos[iff]: "0 Finite(y)" and noLepoll: "\ y \ {v \ Pow(x). v \ m}" begin lemma knat [iff]: "k \ nat" by (simp add: k_def) (* ********************************************************************** *) (* 1. y is less than or equipollent to {v \ s(u). a \ v} *) (* where a is certain k-2 element subset of y *) (* ********************************************************************** *) lemma Diff_Finite_eqpoll: "\l \ a; a \ y\ \ y - a \ y" apply (insert WO_R Infinite lnat) apply (rule eqpoll_trans) apply (rule Diff_lesspoll_eqpoll_Card) apply (erule well_ord_cardinal_eqpoll [THEN eqpoll_sym]) apply (blast intro: lesspoll_trans1 intro!: Card_cardinal Card_cardinal [THEN Card_is_Ord, THEN nat_le_infinite_Ord, THEN le_imp_lepoll] dest: well_ord_cardinal_eqpoll eqpoll_sym eqpoll_imp_lepoll n_lesspoll_nat [THEN lesspoll_trans2] well_ord_cardinal_eqpoll [THEN eqpoll_sym, THEN eqpoll_imp_lepoll, THEN lepoll_infinite])+ done lemma s_subset: "s(u) \ t_n" by (unfold s_def, blast) lemma sI: "\w \ t_n; cons(b,cons(u,a)) \ w; a \ y; b \ y-a; l \ a\ \ w \ s(u)" apply (unfold s_def succ_def k_def) apply (blast intro!: eqpoll_imp_lepoll [THEN cons_lepoll_cong] intro: subset_imp_lepoll lepoll_trans) done lemma in_s_imp_u_in: "v \ s(u) \ u \ v" by (unfold s_def, blast) lemma ex1_superset_a: "\l \ a; a \ y; b \ y - a; u \ x\ \ \! c. c \ s(u) \ a \ c \ b \ c" apply (rule all_ex [simplified k_def, THEN ballE]) apply (erule ex1E) apply (rule_tac a = w in ex1I, blast intro: sI) apply (blast dest: s_subset [THEN subsetD] in_s_imp_u_in) apply (blast del: PowI intro!: cons_cons_subset eqpoll_sym [THEN cons_cons_eqpoll]) done lemma the_eq_cons: "\\v \ s(u). succ(l) \ v \ y; l \ a; a \ y; b \ y - a; u \ x\ \ (THE c. c \ s(u) \ a \ c \ b \ c) \ y = cons(b, a)" apply (frule ex1_superset_a [THEN theI], assumption+) apply (rule set_eq_cons) apply (fast+) done lemma y_lepoll_subset_s: "\\v \ s(u). succ(l) \ v \ y; l \ a; a \ y; u \ x\ \ y \ {v \ s(u). a \ v}" apply (rule Diff_Finite_eqpoll [THEN eqpoll_sym, THEN eqpoll_imp_lepoll, THEN lepoll_trans], fast+) apply (rule_tac f3 = "\b \ y-a. THE c. c \ s (u) \ a \ c \ b \ c" in exI [THEN lepoll_def [THEN def_imp_iff, THEN iffD2]]) apply (simp add: inj_def) apply (rule conjI) apply (rule lam_type) apply (frule ex1_superset_a [THEN theI], fast+, clarify) apply (rule cons_eqE [of _ a]) apply (drule_tac A = "THE c. P (c)" and C = y for P in eq_imp_Int_eq) apply (simp_all add: the_eq_cons) done (* ********************************************************************** *) (* back to the second part *) (* ********************************************************************** *) (*relies on the disjointness of x, y*) lemma x_imp_not_y [dest]: "a \ x \ a \ y" by (blast dest: disjoint [THEN equalityD1, THEN subsetD, OF IntI]) lemma w_Int_eq_w_Diff: "w \ x \ y \ w \ (x - {u}) = w - cons(u, w \ y)" by blast lemma w_Int_eqpoll_m: "\w \ {v \ s(u). a \ v}; l \ a; u \ x; \v \ s(u). succ(l) \ v \ y\ \ w \ (x - {u}) \ m" apply (erule CollectE) apply (subst w_Int_eq_w_Diff) apply (fast dest!: s_subset [THEN subsetD] "includes" [simplified k_def, THEN subsetD]) apply (blast dest: s_subset [THEN subsetD] "includes" [simplified k_def, THEN subsetD] dest: eqpoll_sym [THEN cons_eqpoll_succ, THEN eqpoll_sym] in_s_imp_u_in intro!: eqpoll_sum_imp_Diff_eqpoll) done (* ********************************************************************** *) (* 2. {v \ s(u). a \ v} is less than or equipollent *) (* to {v \ Pow(x). v \ n-k} *) (* ********************************************************************** *) lemma eqpoll_m_not_empty: "a \ m \ a \ 0" apply (insert mpos) apply (fast elim!: zero_lt_natE dest!: eqpoll_succ_imp_not_empty) done lemma cons_cons_in: "\z \ xa \ (x - {u}); l \ a; a \ y; u \ x\ \ \! w. w \ t_n \ cons(z, cons(u, a)) \ w" apply (rule all_ex [THEN bspec]) -apply (unfold k_def) + unfolding k_def apply (fast intro!: cons_eqpoll_succ elim: eqpoll_sym) done lemma subset_s_lepoll_w: "\\v \ s(u). succ(l) \ v \ y; a \ y; l \ a; u \ x\ \ {v \ s(u). a \ v} \ {v \ Pow(x). v \ m}" apply (rule_tac f3 = "\w \ {v \ s (u) . a \ v}. w \ (x - {u})" in exI [THEN lepoll_def [THEN def_imp_iff, THEN iffD2]]) apply (simp add: inj_def) apply (intro conjI lam_type CollectI) apply fast apply (blast intro: w_Int_eqpoll_m) apply (intro ballI impI) (** LEVEL 8 **) apply (rule w_Int_eqpoll_m [THEN eqpoll_m_not_empty, THEN not_emptyE]) apply (blast, assumption+) apply (drule equalityD1 [THEN subsetD], assumption) apply (frule cons_cons_in, assumption+) apply (blast dest: ex1_two_eq intro: s_subset [THEN subsetD] in_s_imp_u_in)+ done (* ********************************************************************** *) (* well_ord_subsets_lepoll_n *) (* ********************************************************************** *) lemma well_ord_subsets_eqpoll_n: "n \ nat \ \S. well_ord({z \ Pow(y) . z \ succ(n)}, S)" apply (rule WO_R [THEN well_ord_infinite_subsets_eqpoll_X, THEN eqpoll_def [THEN def_imp_iff, THEN iffD1], THEN exE]) apply (fast intro: bij_is_inj [THEN well_ord_rvimage])+ done lemma well_ord_subsets_lepoll_n: "n \ nat \ \R. well_ord({z \ Pow(y). z \ n}, R)" apply (induct_tac "n") apply (force intro!: well_ord_unit simp add: subsets_lepoll_0_eq_unit) apply (erule exE) apply (rule well_ord_subsets_eqpoll_n [THEN exE], assumption) apply (simp add: subsets_lepoll_succ) apply (drule well_ord_radd, assumption) apply (erule Int_empty [THEN disj_Un_eqpoll_sum, THEN eqpoll_def [THEN def_imp_iff, THEN iffD1], THEN exE]) apply (fast elim!: bij_is_inj [THEN well_ord_rvimage]) done lemma LL_subset: "LL \ {z \ Pow(y). z \ succ(k #+ m)}" apply (unfold LL_def MM_def) apply (insert "includes") apply (blast intro: subset_imp_lepoll eqpoll_imp_lepoll lepoll_trans) done lemma well_ord_LL: "\S. well_ord(LL,S)" apply (rule well_ord_subsets_lepoll_n [THEN exE, of "succ(k#+m)"]) apply simp apply (blast intro: well_ord_subset [OF _ LL_subset]) done (* ********************************************************************** *) (* every element of LL is a contained in exactly one element of MM *) (* ********************************************************************** *) lemma unique_superset_in_MM: "v \ LL \ \! w. w \ MM \ v \ w" apply (unfold MM_def LL_def, safe, fast) apply (rule lepoll_imp_eqpoll_subset [THEN exE], assumption) apply (rule_tac x = x in all_ex [THEN ballE]) apply (blast intro: eqpoll_sym)+ done (* ********************************************************************** *) (* The function GG satisfies the conditions of WO4 *) (* ********************************************************************** *) (* ********************************************************************** *) (* The union of appropriate values is the whole x *) (* ********************************************************************** *) lemma Int_in_LL: "w \ MM \ w \ y \ LL" by (unfold LL_def, fast) lemma in_LL_eq_Int: "v \ LL \ v = (THE x. x \ MM \ v \ x) \ y" apply (unfold LL_def, clarify) apply (subst unique_superset_in_MM [THEN the_equality2]) apply (auto simp add: Int_in_LL) done lemma unique_superset1: "a \ LL \ (THE x. x \ MM \ a \ x) \ MM" by (erule unique_superset_in_MM [THEN theI, THEN conjunct1]) lemma the_in_MM_subset: "v \ LL \ (THE x. x \ MM \ v \ x) \ x \ y" apply (drule unique_superset1) -apply (unfold MM_def) + unfolding MM_def apply (fast dest!: unique_superset1 "includes" [THEN subsetD]) done lemma GG_subset: "v \ LL \ GG ` v \ x" -apply (unfold GG_def) + unfolding GG_def apply (frule the_in_MM_subset) apply (frule in_LL_eq_Int) apply (force elim: equalityE) done lemma nat_lepoll_ordertype: "nat \ ordertype(y, R)" apply (rule nat_le_infinite_Ord [THEN le_imp_lepoll]) apply (rule Ord_ordertype [OF WO_R]) apply (rule ordertype_eqpoll [THEN eqpoll_imp_lepoll, THEN lepoll_infinite]) apply (rule WO_R) apply (rule Infinite) done lemma ex_subset_eqpoll_n: "n \ nat \ \z. z \ y \ n \ z" apply (erule nat_lepoll_imp_ex_eqpoll_n) apply (rule lepoll_trans [OF nat_lepoll_ordertype]) apply (rule ordertype_eqpoll [THEN eqpoll_sym, THEN eqpoll_imp_lepoll]) apply (rule WO_R) done lemma exists_proper_in_s: "u \ x \ \v \ s(u). succ(k) \ v \ y" apply (rule ccontr) apply (subgoal_tac "\v \ s (u) . k \ v \ y") prefer 2 apply (simp add: s_def, blast intro: succ_not_lepoll_imp_eqpoll) -apply (unfold k_def) + unfolding k_def apply (insert all_ex "includes" lnat) apply (rule ex_subset_eqpoll_n [THEN exE], assumption) apply (rule noLepoll [THEN notE]) apply (blast intro: lepoll_trans [OF y_lepoll_subset_s subset_s_lepoll_w]) done lemma exists_in_MM: "u \ x \ \w \ MM. u \ w" apply (erule exists_proper_in_s [THEN bexE]) apply (unfold MM_def s_def, fast) done lemma exists_in_LL: "u \ x \ \w \ LL. u \ GG`w" apply (rule exists_in_MM [THEN bexE], assumption) apply (rule bexI) apply (erule_tac [2] Int_in_LL) -apply (unfold GG_def) + unfolding GG_def apply (simp add: Int_in_LL) apply (subst unique_superset_in_MM [THEN the_equality2]) apply (fast elim!: Int_in_LL)+ done lemma OUN_eq_x: "well_ord(LL,S) \ (\b MM \ w \ succ(k #+ m)" -apply (unfold MM_def) + unfolding MM_def apply (fast dest: "includes" [THEN subsetD]) done lemma in_LL_eqpoll_n: "w \ LL \ succ(k) \ w" by (unfold LL_def MM_def, fast) lemma in_LL: "w \ LL \ w \ (THE x. x \ MM \ w \ x)" by (erule subset_trans [OF in_LL_eq_Int [THEN equalityD1] Int_lower1]) lemma all_in_lepoll_m: "well_ord(LL,S) \ \b m" -apply (unfold GG_def) + unfolding GG_def apply (rule oallI) apply (simp add: ltD ordermap_bij [THEN bij_converse_bij, THEN bij_is_fun, THEN apply_type]) apply (insert "includes") apply (rule eqpoll_sum_imp_Diff_lepoll) apply (blast del: subsetI dest!: ltD intro!: eqpoll_sum_imp_Diff_lepoll in_LL_eqpoll_n intro: in_LL unique_superset1 [THEN in_MM_eqpoll_n] ordermap_bij [THEN bij_converse_bij, THEN bij_is_fun, THEN apply_type])+ done lemma "conclusion": "\a f. Ord(a) \ domain(f) = a \ (\b (\b m)" apply (rule well_ord_LL [THEN exE]) apply (rename_tac S) apply (rule_tac x = "ordertype (LL,S)" in exI) apply (rule_tac x = "\b \ ordertype(LL,S). GG ` (converse (ordermap (LL,S)) ` b)" in exI) apply (simp add: ltD) apply (blast intro: lam_funtype [THEN domain_of_fun] Ord_ordertype OUN_eq_x all_in_lepoll_m [THEN ospec]) done end (* ********************************************************************** *) (* The main theorem AC16(n, k) \ WO4(n-k) *) (* ********************************************************************** *) theorem AC16_WO4: "\AC_Equiv.AC16(k #+ m, k); 0 < k; 0 < m; k \ nat; m \ nat\ \ WO4(m)" apply (unfold AC_Equiv.AC16_def WO4_def) apply (rule allI) apply (case_tac "Finite (A)") apply (rule lemma1, assumption+) apply (cut_tac lemma2) apply (elim exE conjE) apply (erule_tac x = "A \ y" in allE) apply (frule infinite_Un, drule mp, assumption) apply (erule zero_lt_natE, assumption, clarify) apply (blast intro: AC16.conclusion [OF AC16.intro]) done end diff --git a/src/ZF/AC/AC16_lemmas.thy b/src/ZF/AC/AC16_lemmas.thy --- a/src/ZF/AC/AC16_lemmas.thy +++ b/src/ZF/AC/AC16_lemmas.thy @@ -1,236 +1,236 @@ (* Title: ZF/AC/AC16_lemmas.thy Author: Krzysztof Grabczewski Lemmas used in the proofs concerning AC16 *) theory AC16_lemmas imports AC_Equiv Hartog Cardinal_aux begin lemma cons_Diff_eq: "a\A \ cons(a,A)-{a}=A" by fast lemma nat_1_lepoll_iff: "1\X \ (\x. x \ X)" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule iffI) apply (fast intro: inj_is_fun [THEN apply_type]) apply (erule exE) apply (rule_tac x = "\a \ 1. x" in exI) apply (fast intro!: lam_injective) done lemma eqpoll_1_iff_singleton: "X\1 \ (\x. X={x})" apply (rule iffI) apply (erule eqpollE) apply (drule nat_1_lepoll_iff [THEN iffD1]) apply (fast intro!: lepoll_1_is_sing) apply (fast intro!: singleton_eqpoll_1) done lemma cons_eqpoll_succ: "\x\n; y\x\ \ cons(y,x)\succ(n)" -apply (unfold succ_def) + unfolding succ_def apply (fast elim!: cons_eqpoll_cong mem_irrefl) done lemma subsets_eqpoll_1_eq: "{Y \ Pow(X). Y\1} = {{x}. x \ X}" apply (rule equalityI) apply (rule subsetI) apply (erule CollectE) apply (drule eqpoll_1_iff_singleton [THEN iffD1]) apply (fast intro!: RepFunI) apply (rule subsetI) apply (erule RepFunE) apply (rule CollectI, fast) apply (fast intro!: singleton_eqpoll_1) done lemma eqpoll_RepFun_sing: "X\{{x}. x \ X}" apply (unfold eqpoll_def bij_def) apply (rule_tac x = "\x \ X. {x}" in exI) apply (rule IntI) apply (unfold inj_def surj_def, simp) apply (fast intro!: lam_type RepFunI intro: singleton_eq_iff [THEN iffD1], simp) apply (fast intro!: lam_type) done lemma subsets_eqpoll_1_eqpoll: "{Y \ Pow(X). Y\1}\X" apply (rule subsets_eqpoll_1_eq [THEN ssubst]) apply (rule eqpoll_RepFun_sing [THEN eqpoll_sym]) done lemma InfCard_Least_in: "\InfCard(x); y \ x; y \ succ(z)\ \ (\ i. i \ y) \ y" apply (erule eqpoll_sym [THEN eqpoll_imp_lepoll, THEN succ_lepoll_imp_not_empty, THEN not_emptyE]) apply (fast intro: LeastI dest!: InfCard_is_Card [THEN Card_is_Ord] elim: Ord_in_Ord) done lemma subsets_lepoll_lemma1: "\InfCard(x); n \ nat\ \ {y \ Pow(x). y\succ(succ(n))} \ x*{y \ Pow(x). y\succ(n)}" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule_tac x = "\y \ {y \ Pow(x) . y\succ (succ (n))}. <\ i. i \ y, y-{\ i. i \ y}>" in exI) apply (rule_tac d = "\z. cons (fst(z), snd(z))" in lam_injective) apply (blast intro!: Diff_sing_eqpoll intro: InfCard_Least_in) apply (simp, blast intro: InfCard_Least_in) done lemma set_of_Ord_succ_Union: "(\y \ z. Ord(y)) \ z \ succ(\(z))" apply (rule subsetI) apply (case_tac "\y \ z. y \ x", blast ) apply (simp, erule bexE) apply (rule_tac i=y and j=x in Ord_linear_le) apply (blast dest: le_imp_subset elim: leE ltE)+ done lemma subset_not_mem: "j \ i \ i \ j" by (fast elim!: mem_irrefl) lemma succ_Union_not_mem: "(\y. y \ z \ Ord(y)) \ succ(\(z)) \ z" apply (rule set_of_Ord_succ_Union [THEN subset_not_mem], blast) done lemma Union_cons_eq_succ_Union: "\(cons(succ(\(z)),z)) = succ(\(z))" by fast lemma Un_Ord_disj: "\Ord(i); Ord(j)\ \ i \ j = i | i \ j = j" by (fast dest!: le_imp_subset elim: Ord_linear_le) lemma Union_eq_Un: "x \ X \ \(X) = x \ \(X-{x})" by fast lemma Union_in_lemma [rule_format]: "n \ nat \ \z. (\y \ z. Ord(y)) \ z\n \ z\0 \ \(z) \ z" apply (induct_tac "n") apply (fast dest!: eqpoll_imp_lepoll [THEN lepoll_0_is_0]) apply (intro allI impI) apply (erule natE) apply (fast dest!: eqpoll_1_iff_singleton [THEN iffD1] intro!: Union_singleton, clarify) apply (elim not_emptyE) apply (erule_tac x = "z-{xb}" in allE) apply (erule impE) apply (fast elim!: Diff_sing_eqpoll Diff_sing_eqpoll [THEN eqpoll_succ_imp_not_empty]) apply (subgoal_tac "xb \ \(z - {xb}) \ z") apply (simp add: Union_eq_Un [symmetric]) apply (frule bspec, assumption) apply (drule bspec) apply (erule Diff_subset [THEN subsetD]) apply (drule Un_Ord_disj, assumption, auto) done lemma Union_in: "\\x \ z. Ord(x); z\n; z\0; n \ nat\ \ \(z) \ z" by (blast intro: Union_in_lemma) lemma succ_Union_in_x: "\InfCard(x); z \ Pow(x); z\n; n \ nat\ \ succ(\(z)) \ x" apply (rule Limit_has_succ [THEN ltE]) prefer 3 apply assumption apply (erule InfCard_is_Limit) apply (case_tac "z=0") apply (simp, fast intro!: InfCard_is_Limit [THEN Limit_has_0]) apply (rule ltI [OF PowD [THEN subsetD] InfCard_is_Card [THEN Card_is_Ord]], assumption) apply (blast intro: Union_in InfCard_is_Card [THEN Card_is_Ord, THEN Ord_in_Ord])+ done lemma succ_lepoll_succ_succ: "\InfCard(x); n \ nat\ \ {y \ Pow(x). y\succ(n)} \ {y \ Pow(x). y\succ(succ(n))}" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule_tac x = "\z \ {y\Pow(x). y\succ(n)}. cons(succ(\(z)), z)" in exI) apply (rule_tac d = "\z. z-{\(z) }" in lam_injective) apply (blast intro!: succ_Union_in_x succ_Union_not_mem intro: cons_eqpoll_succ Ord_in_Ord dest!: InfCard_is_Card [THEN Card_is_Ord]) apply (simp only: Union_cons_eq_succ_Union) apply (rule cons_Diff_eq) apply (fast dest!: InfCard_is_Card [THEN Card_is_Ord] elim: Ord_in_Ord intro!: succ_Union_not_mem) done lemma subsets_eqpoll_X: "\InfCard(X); n \ nat\ \ {Y \ Pow(X). Y\succ(n)} \ X" apply (induct_tac "n") apply (rule subsets_eqpoll_1_eqpoll) apply (rule eqpollI) apply (rule subsets_lepoll_lemma1 [THEN lepoll_trans], assumption+) apply (rule eqpoll_trans [THEN eqpoll_imp_lepoll]) apply (erule eqpoll_refl [THEN prod_eqpoll_cong]) apply (erule InfCard_square_eqpoll) apply (fast elim: eqpoll_sym [THEN eqpoll_imp_lepoll, THEN lepoll_trans] intro!: succ_lepoll_succ_succ) done lemma image_vimage_eq: "\f \ surj(A,B); y \ B\ \ f``(converse(f)``y) = y" -apply (unfold surj_def) + unfolding surj_def apply (fast dest: apply_equality2 elim: apply_iff [THEN iffD2]) done lemma vimage_image_eq: "\f \ inj(A,B); y \ A\ \ converse(f)``(f``y) = y" by (fast elim!: inj_is_fun [THEN apply_Pair] dest: inj_equality) lemma subsets_eqpoll: "A\B \ {Y \ Pow(A). Y\n}\{Y \ Pow(B). Y\n}" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (erule exE) apply (rule_tac x = "\X \ {Y \ Pow (A) . \f. f \ bij (Y, n) }. f``X" in exI) apply (rule_tac d = "\Z. converse (f) ``Z" in lam_bijective) apply (fast intro!: bij_is_inj [THEN restrict_bij, THEN bij_converse_bij, THEN comp_bij] elim!: bij_is_fun [THEN fun_is_rel, THEN image_subset]) apply (blast intro!: bij_is_inj [THEN restrict_bij] comp_bij bij_converse_bij bij_is_fun [THEN fun_is_rel, THEN image_subset]) apply (fast elim!: bij_is_inj [THEN vimage_image_eq]) apply (fast elim!: bij_is_surj [THEN image_vimage_eq]) done lemma WO2_imp_ex_Card: "WO2 \ \a. Card(a) \ X\a" -apply (unfold WO2_def) + unfolding WO2_def apply (drule spec [of _ X]) apply (blast intro: Card_cardinal eqpoll_trans well_ord_Memrel [THEN well_ord_cardinal_eqpoll, THEN eqpoll_sym]) done lemma lepoll_infinite: "\X\Y; \Finite(X)\ \ \Finite(Y)" by (blast intro: lepoll_Finite) lemma infinite_Card_is_InfCard: "\\Finite(X); Card(X)\ \ InfCard(X)" -apply (unfold InfCard_def) + unfolding InfCard_def apply (fast elim!: Card_is_Ord [THEN nat_le_infinite_Ord]) done lemma WO2_infinite_subsets_eqpoll_X: "\WO2; n \ nat; \Finite(X)\ \ {Y \ Pow(X). Y\succ(n)}\X" apply (drule WO2_imp_ex_Card) apply (elim allE exE conjE) apply (frule eqpoll_imp_lepoll [THEN lepoll_infinite], assumption) apply (drule infinite_Card_is_InfCard, assumption) apply (blast intro: subsets_eqpoll subsets_eqpoll_X eqpoll_sym eqpoll_trans) done lemma well_ord_imp_ex_Card: "well_ord(X,R) \ \a. Card(a) \ X\a" by (fast elim!: well_ord_cardinal_eqpoll [THEN eqpoll_sym] intro!: Card_cardinal) lemma well_ord_infinite_subsets_eqpoll_X: "\well_ord(X,R); n \ nat; \Finite(X)\ \ {Y \ Pow(X). Y\succ(n)}\X" apply (drule well_ord_imp_ex_Card) apply (elim allE exE conjE) apply (frule eqpoll_imp_lepoll [THEN lepoll_infinite], assumption) apply (drule infinite_Card_is_InfCard, assumption) apply (blast intro: subsets_eqpoll subsets_eqpoll_X eqpoll_sym eqpoll_trans) done end diff --git a/src/ZF/AC/AC17_AC1.thy b/src/ZF/AC/AC17_AC1.thy --- a/src/ZF/AC/AC17_AC1.thy +++ b/src/ZF/AC/AC17_AC1.thy @@ -1,301 +1,301 @@ (* Title: ZF/AC/AC17_AC1.thy Author: Krzysztof Grabczewski The equivalence of AC0, AC1 and AC17 Also, the proofs needed to show that each of AC2, AC3, ..., AC6 is equivalent to AC0 and AC1. *) theory AC17_AC1 imports HH begin (** AC0 is equivalent to AC1. AC0 comes from Suppes, AC1 from Rubin \ Rubin **) lemma AC0_AC1_lemma: "\f:(\X \ A. X); D \ A\ \ \g. g:(\X \ D. X)" by (fast intro!: lam_type apply_type) lemma AC0_AC1: "AC0 \ AC1" apply (unfold AC0_def AC1_def) apply (blast intro: AC0_AC1_lemma) done lemma AC1_AC0: "AC1 \ AC0" by (unfold AC0_def AC1_def, blast) (**** The proof of AC1 \ AC17 ****) lemma AC1_AC17_lemma: "f \ (\X \ Pow(A) - {0}. X) \ f \ (Pow(A) - {0} -> A)" apply (rule Pi_type, assumption) apply (drule apply_type, assumption, fast) done lemma AC1_AC17: "AC1 \ AC17" apply (unfold AC1_def AC17_def) apply (rule allI) apply (rule ballI) apply (erule_tac x = "Pow (A) -{0}" in allE) apply (erule impE, fast) apply (erule exE) apply (rule bexI) apply (erule_tac [2] AC1_AC17_lemma) apply (rule apply_type, assumption) apply (fast dest!: AC1_AC17_lemma elim!: apply_type) done (**** The proof of AC17 \ AC1 ****) (* *********************************************************************** *) (* more properties of HH *) (* *********************************************************************** *) lemma UN_eq_imp_well_ord: "\x - (\j \ \ i. HH(\X \ Pow(x)-{0}. {f`X}, x, i) = {x}. HH(\X \ Pow(x)-{0}. {f`X}, x, j)) = 0; f \ Pow(x)-{0} -> x\ \ \r. well_ord(x,r)" apply (rule exI) apply (erule well_ord_rvimage [OF bij_Least_HH_x [THEN bij_converse_bij, THEN bij_is_inj] Ord_Least [THEN well_ord_Memrel]], assumption) done (* *********************************************************************** *) (* theorems closer to the proof *) (* *********************************************************************** *) lemma not_AC1_imp_ex: "\AC1 \ \A. \f \ Pow(A)-{0} -> A. \u \ Pow(A)-{0}. f`u \ u" -apply (unfold AC1_def) + unfolding AC1_def apply (erule swap) apply (rule allI) apply (erule swap) apply (rule_tac x = "\(A)" in exI) apply (blast intro: lam_type) done lemma AC17_AC1_aux1: "\\f \ Pow(x) - {0} -> x. \u \ Pow(x) - {0}. f`u\u; \f \ Pow(x)-{0}->x. x - (\a \ (\ i. HH(\X \ Pow(x)-{0}. {f`X},x,i)={x}). HH(\X \ Pow(x)-{0}. {f`X},x,a)) = 0\ \ P" apply (erule bexE) apply (erule UN_eq_imp_well_ord [THEN exE], assumption) apply (erule ex_choice_fun_Pow [THEN exE]) apply (erule ballE) apply (fast intro: apply_type del: DiffE) apply (erule notE) apply (rule Pi_type, assumption) apply (blast dest: apply_type) done lemma AC17_AC1_aux2: "\ (\f \ Pow(x)-{0}->x. x - F(f) = 0) \ (\f \ Pow(x)-{0}->x . x - F(f)) \ (Pow(x) -{0} -> x) -> Pow(x) - {0}" by (fast intro!: lam_type dest!: Diff_eq_0_iff [THEN iffD1]) lemma AC17_AC1_aux3: "\f`Z \ Z; Z \ Pow(x)-{0}\ \ (\X \ Pow(x)-{0}. {f`X})`Z \ Pow(Z)-{0}" by auto lemma AC17_AC1_aux4: "\f \ F. f`((\f \ F. Q(f))`f) \ (\f \ F. Q(f))`f \ \f \ F. f`Q(f) \ Q(f)" by simp lemma AC17_AC1: "AC17 \ AC1" -apply (unfold AC17_def) + unfolding AC17_def apply (rule classical) apply (erule not_AC1_imp_ex [THEN exE]) apply (case_tac "\f \ Pow(x)-{0} -> x. x - (\a \ (\ i. HH (\X \ Pow (x) -{0}. {f`X},x,i) ={x}) . HH (\X \ Pow (x) -{0}. {f`X},x,a)) = 0") apply (erule AC17_AC1_aux1, assumption) apply (drule AC17_AC1_aux2) apply (erule allE) apply (drule bspec, assumption) apply (drule AC17_AC1_aux4) apply (erule bexE) apply (drule apply_type, assumption) apply (simp add: HH_Least_eq_x del: Diff_iff ) apply (drule AC17_AC1_aux3, assumption) apply (fast dest!: subst_elem [OF _ HH_Least_eq_x [symmetric]] f_subset_imp_HH_subset elim!: mem_irrefl) done (* ********************************************************************** AC1 \ AC2 \ AC1 AC1 \ AC4 \ AC3 \ AC1 AC4 \ AC5 \ AC4 AC1 \ AC6 ************************************************************************* *) (* ********************************************************************** *) (* AC1 \ AC2 *) (* ********************************************************************** *) lemma AC1_AC2_aux1: "\f:(\X \ A. X); B \ A; 0\A\ \ {f`B} \ B \ {f`C. C \ A}" by (fast elim!: apply_type) lemma AC1_AC2_aux2: "\pairwise_disjoint(A); B \ A; C \ A; D \ B; D \ C\ \ f`B = f`C" by (unfold pairwise_disjoint_def, fast) lemma AC1_AC2: "AC1 \ AC2" apply (unfold AC1_def AC2_def) apply (rule allI) apply (rule impI) apply (elim asm_rl conjE allE exE impE, assumption) apply (intro exI ballI equalityI) prefer 2 apply (rule AC1_AC2_aux1, assumption+) apply (fast elim!: AC1_AC2_aux2 elim: apply_type) done (* ********************************************************************** *) (* AC2 \ AC1 *) (* ********************************************************************** *) lemma AC2_AC1_aux1: "0\A \ 0 \ {B*{B}. B \ A}" by (fast dest!: sym [THEN Sigma_empty_iff [THEN iffD1]]) lemma AC2_AC1_aux2: "\X*{X} \ C = {y}; X \ A\ \ (THE y. X*{X} \ C = {y}): X*A" apply (rule subst_elem [of y]) apply (blast elim!: equalityE) apply (auto simp add: singleton_eq_iff) done lemma AC2_AC1_aux3: "\D \ {E*{E}. E \ A}. \y. D \ C = {y} \ (\x \ A. fst(THE z. (x*{x} \ C = {z}))) \ (\X \ A. X)" apply (rule lam_type) apply (drule bspec, blast) apply (blast intro: AC2_AC1_aux2 fst_type) done lemma AC2_AC1: "AC2 \ AC1" apply (unfold AC1_def AC2_def pairwise_disjoint_def) apply (intro allI impI) apply (elim allE impE) prefer 2 apply (fast elim!: AC2_AC1_aux3) apply (blast intro!: AC2_AC1_aux1) done (* ********************************************************************** *) (* AC1 \ AC4 *) (* ********************************************************************** *) lemma empty_notin_images: "0 \ {R``{x}. x \ domain(R)}" by blast lemma AC1_AC4: "AC1 \ AC4" apply (unfold AC1_def AC4_def) apply (intro allI impI) apply (drule spec, drule mp [OF _ empty_notin_images]) apply (best intro!: lam_type elim!: apply_type) done (* ********************************************************************** *) (* AC4 \ AC3 *) (* ********************************************************************** *) lemma AC4_AC3_aux1: "f \ A->B \ (\z \ A. {z}*f`z) \ A*\(B)" by (fast dest!: apply_type) lemma AC4_AC3_aux2: "domain(\z \ A. {z}*f(z)) = {a \ A. f(a)\0}" by blast lemma AC4_AC3_aux3: "x \ A \ (\z \ A. {z}*f(z))``{x} = f(x)" by fast lemma AC4_AC3: "AC4 \ AC3" apply (unfold AC3_def AC4_def) apply (intro allI ballI) apply (elim allE impE) apply (erule AC4_AC3_aux1) apply (simp add: AC4_AC3_aux2 AC4_AC3_aux3 cong add: Pi_cong) done (* ********************************************************************** *) (* AC3 \ AC1 *) (* ********************************************************************** *) lemma AC3_AC1_lemma: "b\A \ (\x \ {a \ A. id(A)`a\b}. id(A)`x) = (\x \ A. x)" apply (simp add: id_def cong add: Pi_cong) apply (rule_tac b = A in subst_context, fast) done lemma AC3_AC1: "AC3 \ AC1" apply (unfold AC1_def AC3_def) apply (fast intro!: id_type elim: AC3_AC1_lemma [THEN subst]) done (* ********************************************************************** *) (* AC4 \ AC5 *) (* ********************************************************************** *) lemma AC4_AC5: "AC4 \ AC5" apply (unfold range_def AC4_def AC5_def) apply (intro allI ballI) apply (elim allE impE) apply (erule fun_is_rel [THEN converse_type]) apply (erule exE) apply (rename_tac g) apply (rule_tac x=g in bexI) apply (blast dest: apply_equality range_type) apply (blast intro: Pi_type dest: apply_type fun_is_rel) done (* ********************************************************************** *) (* AC5 \ AC4, Rubin \ Rubin, p. 11 *) (* ********************************************************************** *) lemma AC5_AC4_aux1: "R \ A*B \ (\x \ R. fst(x)) \ R -> A" by (fast intro!: lam_type fst_type) lemma AC5_AC4_aux2: "R \ A*B \ range(\x \ R. fst(x)) = domain(R)" by (unfold lam_def, force) lemma AC5_AC4_aux3: "\\f \ A->C. P(f,domain(f)); A=B\ \ \f \ B->C. P(f,B)" apply (erule bexE) apply (frule domain_of_fun, fast) done lemma AC5_AC4_aux4: "\R \ A*B; g \ C->R; \x \ C. (\z \ R. fst(z))` (g`x) = x\ \ (\x \ C. snd(g`x)): (\x \ C. R``{x})" apply (rule lam_type) apply (force dest: apply_type) done lemma AC5_AC4: "AC5 \ AC4" apply (unfold AC4_def AC5_def, clarify) apply (elim allE ballE) apply (drule AC5_AC4_aux3 [OF _ AC5_AC4_aux2], assumption) apply (fast elim!: AC5_AC4_aux4) apply (blast intro: AC5_AC4_aux1) done (* ********************************************************************** *) (* AC1 \ AC6 *) (* ********************************************************************** *) lemma AC1_iff_AC6: "AC1 \ AC6" by (unfold AC1_def AC6_def, blast) end diff --git a/src/ZF/AC/AC18_AC19.thy b/src/ZF/AC/AC18_AC19.thy --- a/src/ZF/AC/AC18_AC19.thy +++ b/src/ZF/AC/AC18_AC19.thy @@ -1,103 +1,103 @@ (* Title: ZF/AC/AC18_AC19.thy Author: Krzysztof Grabczewski The proof of AC1 \ AC18 \ AC19 \ AC1 *) theory AC18_AC19 imports AC_Equiv begin definition uu :: "i \ i" where "uu(a) \ {c \ {0}. c \ a}" (* ********************************************************************** *) (* AC1 \ AC18 *) (* ********************************************************************** *) lemma PROD_subsets: "\f \ (\b \ {P(a). a \ A}. b); \a \ A. P(a)<=Q(a)\ \ (\a \ A. f`P(a)) \ (\a \ A. Q(a))" by (rule lam_type, drule apply_type, auto) lemma lemma_AC18: "\\A. 0 \ A \ (\f. f \ (\X \ A. X)); A \ 0\ \ (\a \ A. \b \ B(a). X(a, b)) \ (\f \ \a \ A. B(a). \a \ A. X(a, f`a))" apply (rule subsetI) apply (erule_tac x = "{{b \ B (a) . x \ X (a,b) }. a \ A}" in allE) apply (erule impE, fast) apply (erule exE) apply (rule UN_I) apply (fast elim!: PROD_subsets) apply (simp, fast elim!: not_emptyE dest: apply_type [OF _ RepFunI]) done lemma AC1_AC18: "AC1 \ PROP AC18" -apply (unfold AC1_def) + unfolding AC1_def apply (rule AC18.intro) apply (fast elim!: lemma_AC18 apply_type intro!: equalityI INT_I UN_I) done (* ********************************************************************** *) (* AC18 \ AC19 *) (* ********************************************************************** *) theorem (in AC18) AC19 -apply (unfold AC19_def) + unfolding AC19_def apply (intro allI impI) apply (rule AC18 [of _ "\x. x", THEN mp], blast) done (* ********************************************************************** *) (* AC19 \ AC1 *) (* ********************************************************************** *) lemma RepRep_conj: "\A \ 0; 0 \ A\ \ {uu(a). a \ A} \ 0 \ 0 \ {uu(a). a \ A}" apply (unfold uu_def, auto) apply (blast dest!: sym [THEN RepFun_eq_0_iff [THEN iffD1]]) done lemma lemma1_1: "\c \ a; x = c \ {0}; x \ a\ \ x - {0} \ a" apply clarify apply (rule subst_elem, assumption) apply (fast elim: notE subst_elem) done lemma lemma1_2: "\f`(uu(a)) \ a; f \ (\B \ {uu(a). a \ A}. B); a \ A\ \ f`(uu(a))-{0} \ a" apply (unfold uu_def, fast elim!: lemma1_1 dest!: apply_type) done lemma lemma1: "\f. f \ (\B \ {uu(a). a \ A}. B) \ \f. f \ (\B \ A. B)" apply (erule exE) apply (rule_tac x = "\a\A. if (f` (uu(a)) \ a, f` (uu(a)), f` (uu(a))-{0})" in exI) apply (rule lam_type) apply (simp add: lemma1_2) done lemma lemma2_1: "a\0 \ 0 \ (\b \ uu(a). b)" by (unfold uu_def, auto) lemma lemma2: "\A\0; 0\A\ \ (\x \ {uu(a). a \ A}. \b \ x. b) \ 0" apply (erule not_emptyE) apply (rule_tac a = 0 in not_emptyI) apply (fast intro!: lemma2_1) done lemma AC19_AC1: "AC19 \ AC1" apply (unfold AC19_def AC1_def, clarify) apply (case_tac "A=0", force) apply (erule_tac x = "{uu (a) . a \ A}" in allE) apply (erule impE) apply (erule RepRep_conj, assumption) apply (rule lemma1) apply (drule lemma2, assumption, auto) done end diff --git a/src/ZF/AC/AC7_AC9.thy b/src/ZF/AC/AC7_AC9.thy --- a/src/ZF/AC/AC7_AC9.thy +++ b/src/ZF/AC/AC7_AC9.thy @@ -1,169 +1,169 @@ (* Title: ZF/AC/AC7_AC9.thy Author: Krzysztof Grabczewski The proofs needed to state that AC7, AC8 and AC9 are equivalent to the previous instances of AC. *) theory AC7_AC9 imports AC_Equiv begin (* ********************************************************************** *) (* Lemmas used in the proofs AC7 \ AC6 and AC9 \ AC1 *) (* - Sigma_fun_space_not0 *) (* - Sigma_fun_space_eqpoll *) (* ********************************************************************** *) lemma Sigma_fun_space_not0: "\0\A; B \ A\ \ (nat->\(A)) * B \ 0" by (blast dest!: Sigma_empty_iff [THEN iffD1] Union_empty_iff [THEN iffD1]) lemma inj_lemma: "C \ A \ (\g \ (nat->\(A))*C. (\n \ nat. if(n=0, snd(g), fst(g)`(n #- 1)))) \ inj((nat->\(A))*C, (nat->\(A)) ) " -apply (unfold inj_def) + unfolding inj_def apply (rule CollectI) apply (fast intro!: lam_type if_type apply_type fst_type snd_type, auto) apply (rule fun_extension, assumption+) apply (drule lam_eqE [OF _ nat_succI], assumption, simp) apply (drule lam_eqE [OF _ nat_0I], simp) done lemma Sigma_fun_space_eqpoll: "\C \ A; 0\A\ \ (nat->\(A)) * C \ (nat->\(A))" apply (rule eqpollI) apply (simp add: lepoll_def) apply (fast intro!: inj_lemma) apply (fast elim!: prod_lepoll_self not_sym [THEN not_emptyE] subst_elem elim: swap) done (* ********************************************************************** *) (* AC6 \ AC7 *) (* ********************************************************************** *) lemma AC6_AC7: "AC6 \ AC7" by (unfold AC6_def AC7_def, blast) (* ********************************************************************** *) (* AC7 \ AC6, Rubin \ Rubin p. 12, Theorem 2.8 *) (* The case of the empty family of sets added in order to complete *) (* the proof. *) (* ********************************************************************** *) lemma lemma1_1: "y \ (\B \ A. Y*B) \ (\B \ A. snd(y`B)) \ (\B \ A. B)" by (fast intro!: lam_type snd_type apply_type) lemma lemma1_2: "y \ (\B \ {Y*C. C \ A}. B) \ (\B \ A. y`(Y*B)) \ (\B \ A. Y*B)" apply (fast intro!: lam_type apply_type) done lemma AC7_AC6_lemma1: "(\B \ {(nat->\(A))*C. C \ A}. B) \ 0 \ (\B \ A. B) \ 0" by (fast intro!: equals0I lemma1_1 lemma1_2) lemma AC7_AC6_lemma2: "0 \ A \ 0 \ {(nat -> \(A)) * C. C \ A}" by (blast dest: Sigma_fun_space_not0) lemma AC7_AC6: "AC7 \ AC6" apply (unfold AC6_def AC7_def) apply (rule allI) apply (rule impI) apply (case_tac "A=0", simp) apply (rule AC7_AC6_lemma1) apply (erule allE) apply (blast del: notI intro!: AC7_AC6_lemma2 intro: eqpoll_sym eqpoll_trans Sigma_fun_space_eqpoll) done (* ********************************************************************** *) (* AC1 \ AC8 *) (* ********************************************************************** *) lemma AC1_AC8_lemma1: "\B \ A. \B1 B2. B=\B1,B2\ \ B1 \ B2 \ 0 \ { bij(fst(B),snd(B)). B \ A }" apply (unfold eqpoll_def, auto) done lemma AC1_AC8_lemma2: "\f \ (\X \ RepFun(A,p). X); D \ A\ \ (\x \ A. f`p(x))`D \ p(D)" apply (simp, fast elim!: apply_type) done lemma AC1_AC8: "AC1 \ AC8" apply (unfold AC1_def AC8_def) apply (fast dest: AC1_AC8_lemma1 AC1_AC8_lemma2) done (* ********************************************************************** *) (* AC8 \ AC9 *) (* - this proof replaces the following two from Rubin \ Rubin: *) (* AC8 \ AC1 and AC1 \ AC9 *) (* ********************************************************************** *) lemma AC8_AC9_lemma: "\B1 \ A. \B2 \ A. B1 \ B2 \ \B \ A*A. \B1 B2. B=\B1,B2\ \ B1 \ B2" by fast lemma AC8_AC9: "AC8 \ AC9" apply (unfold AC8_def AC9_def) apply (intro allI impI) apply (erule allE) apply (erule impE, erule AC8_AC9_lemma, force) done (* ********************************************************************** *) (* AC9 \ AC1 *) (* The idea of this proof comes from "Equivalents of the Axiom of Choice" *) (* by Rubin \ Rubin. But (x * y) is not necessarily equipollent to *) (* (x * y) \ {0} when y is a set of total functions acting from nat to *) (* \(A) -- therefore we have used the set (y * nat) instead of y. *) (* ********************************************************************** *) lemma snd_lepoll_SigmaI: "b \ B \ X \ B \ X" by (blast intro: lepoll_trans prod_lepoll_self eqpoll_imp_lepoll prod_commute_eqpoll) lemma nat_lepoll_lemma: "\0 \ A; B \ A\ \ nat \ ((nat \ \(A)) \ B) \ nat" by (blast dest: Sigma_fun_space_not0 intro: snd_lepoll_SigmaI) lemma AC9_AC1_lemma1: "\0\A; A\0; C = {((nat->\(A))*B)*nat. B \ A} \ {cons(0,((nat->\(A))*B)*nat). B \ A}; B1 \ C; B2 \ C\ \ B1 \ B2" by (blast intro!: nat_lepoll_lemma Sigma_fun_space_eqpoll nat_cons_eqpoll [THEN eqpoll_trans] prod_eqpoll_cong [OF _ eqpoll_refl] intro: eqpoll_trans eqpoll_sym ) lemma AC9_AC1_lemma2: "\B1 \ {(F*B)*N. B \ A} \ {cons(0,(F*B)*N). B \ A}. \B2 \ {(F*B)*N. B \ A} \ {cons(0,(F*B)*N). B \ A}. f`\B1,B2\ \ bij(B1, B2) \ (\B \ A. snd(fst((f`)`0))) \ (\X \ A. X)" apply (intro lam_type snd_type fst_type) apply (rule apply_type [OF _ consI1]) apply (fast intro!: fun_weaken_type bij_is_fun) done lemma AC9_AC1: "AC9 \ AC1" apply (unfold AC1_def AC9_def) apply (intro allI impI) apply (erule allE) apply (case_tac "A\0") apply (blast dest: AC9_AC1_lemma1 AC9_AC1_lemma2, force) done end diff --git a/src/ZF/AC/AC_Equiv.thy b/src/ZF/AC/AC_Equiv.thy --- a/src/ZF/AC/AC_Equiv.thy +++ b/src/ZF/AC/AC_Equiv.thy @@ -1,224 +1,224 @@ (* Title: ZF/AC/AC_Equiv.thy Author: Krzysztof Grabczewski Axioms AC1 -- AC19 come from "Equivalents of the Axiom of Choice, II" by H. Rubin and J.E. Rubin, 1985. Axiom AC0 comes from "Axiomatic Set Theory" by P. Suppes, 1972. Some Isabelle proofs of equivalences of these axioms are formalizations of proofs presented by the Rubins. The others are based on the Rubins' proofs, but slightly changed. *) theory AC_Equiv imports ZF begin (*obviously not ZFC*) (* Well Ordering Theorems *) definition "WO1 \ \A. \R. well_ord(A,R)" definition "WO2 \ \A. \a. Ord(a) \ A\a" definition "WO3 \ \A. \a. Ord(a) \ (\b. b \ a \ A\b)" definition "WO4(m) \ \A. \a f. Ord(a) \ domain(f)=a \ (\b (\b m)" definition "WO5 \ \m \ nat. 1\m \ WO4(m)" definition "WO6 \ \A. \m \ nat. 1\m \ (\a f. Ord(a) \ domain(f)=a \ (\b (\b m))" definition "WO7 \ \A. Finite(A) \ (\R. well_ord(A,R) \ well_ord(A,converse(R)))" definition "WO8 \ \A. (\f. f \ (\X \ A. X)) \ (\R. well_ord(A,R))" definition (* Auxiliary concepts needed below *) pairwise_disjoint :: "i \ o" where "pairwise_disjoint(A) \ \A1 \ A. \A2 \ A. A1 \ A2 \ 0 \ A1=A2" definition sets_of_size_between :: "[i, i, i] \ o" where "sets_of_size_between(A,m,n) \ \B \ A. m \ B \ B \ n" (* Axioms of Choice *) definition "AC0 \ \A. \f. f \ (\X \ Pow(A)-{0}. X)" definition "AC1 \ \A. 0\A \ (\f. f \ (\X \ A. X))" definition "AC2 \ \A. 0\A \ pairwise_disjoint(A) \ (\C. \B \ A. \y. B \ C = {y})" definition "AC3 \ \A B. \f \ A->B. \g. g \ (\x \ {a \ A. f`a\0}. f`x)" definition "AC4 \ \R A B. (R \ A*B \ (\f. f \ (\x \ domain(R). R``{x})))" definition "AC5 \ \A B. \f \ A->B. \g \ range(f)->A. \x \ domain(g). f`(g`x) = x" definition "AC6 \ \A. 0\A \ (\B \ A. B)\0" definition "AC7 \ \A. 0\A \ (\B1 \ A. \B2 \ A. B1\B2) \ (\B \ A. B) \ 0" definition "AC8 \ \A. (\B \ A. \B1 B2. B=\B1,B2\ \ B1\B2) \ (\f. \B \ A. f`B \ bij(fst(B),snd(B)))" definition "AC9 \ \A. (\B1 \ A. \B2 \ A. B1\B2) \ (\f. \B1 \ A. \B2 \ A. f`\B1,B2\ \ bij(B1,B2))" definition "AC10(n) \ \A. (\B \ A. \Finite(B)) \ (\f. \B \ A. (pairwise_disjoint(f`B) \ sets_of_size_between(f`B, 2, succ(n)) \ \(f`B)=B))" definition "AC11 \ \n \ nat. 1\n \ AC10(n)" definition "AC12 \ \A. (\B \ A. \Finite(B)) \ (\n \ nat. 1\n \ (\f. \B \ A. (pairwise_disjoint(f`B) \ sets_of_size_between(f`B, 2, succ(n)) \ \(f`B)=B)))" definition "AC13(m) \ \A. 0\A \ (\f. \B \ A. f`B\0 \ f`B \ B \ f`B \ m)" definition "AC14 \ \m \ nat. 1\m \ AC13(m)" definition "AC15 \ \A. 0\A \ (\m \ nat. 1\m \ (\f. \B \ A. f`B\0 \ f`B \ B \ f`B \ m))" definition "AC16(n, k) \ \A. \Finite(A) \ (\T. T \ {X \ Pow(A). X\succ(n)} \ (\X \ {X \ Pow(A). X\succ(k)}. \! Y. Y \ T \ X \ Y))" definition "AC17 \ \A. \g \ (Pow(A)-{0} -> A) -> Pow(A)-{0}. \f \ Pow(A)-{0} -> A. f`(g`f) \ g`f" locale AC18 = assumes AC18: "A\0 \ (\a \ A. B(a) \ 0) \ ((\a \ A. \b \ B(a). X(a,b)) = (\f \ \a \ A. B(a). \a \ A. X(a, f`a)))" \ \AC18 cannot be expressed within the object-logic\ definition "AC19 \ \A. A\0 \ 0\A \ ((\a \ A. \b \ a. b) = (\f \ (\B \ A. B). \a \ A. f`a))" (* ********************************************************************** *) (* Theorems concerning ordinals *) (* ********************************************************************** *) (* lemma for ordertype_Int *) lemma rvimage_id: "rvimage(A,id(A),r) = r \ A*A" -apply (unfold rvimage_def) + unfolding rvimage_def apply (rule equalityI, safe) apply (drule_tac P = "\a. :r" in id_conv [THEN subst], assumption) apply (drule_tac P = "\a. \a,ya\:r" in id_conv [THEN subst], (assumption+)) apply (fast intro: id_conv [THEN ssubst]) done (* used only in Hartog.ML *) lemma ordertype_Int: "well_ord(A,r) \ ordertype(A, r \ A*A) = ordertype(A,r)" apply (rule_tac P = "\a. ordertype (A,a) =ordertype (A,r) " in rvimage_id [THEN subst]) apply (erule id_bij [THEN bij_ordertype_vimage]) done lemma lam_sing_bij: "(\x \ A. {x}) \ bij(A, {{x}. x \ A})" apply (rule_tac d = "\z. THE x. z={x}" in lam_bijective) apply (auto simp add: the_equality) done lemma inj_strengthen_type: "\f \ inj(A, B); \a. a \ A \ f`a \ C\ \ f \ inj(A,C)" by (unfold inj_def, blast intro: Pi_type) (* ********************************************************************** *) (* Another elimination rule for \! *) (* ********************************************************************** *) lemma ex1_two_eq: "\\! x. P(x); P(x); P(y)\ \ x=y" by blast (* ********************************************************************** *) (* Lemmas used in the proofs like WO? \ AC? *) (* ********************************************************************** *) lemma first_in_B: "\well_ord(\(A),r); 0 \ A; B \ A\ \ (THE b. first(b,B,r)) \ B" by (blast dest!: well_ord_imp_ex1_first [THEN theI, THEN first_def [THEN def_imp_iff, THEN iffD1]]) lemma ex_choice_fun: "\well_ord(\(A), R); 0 \ A\ \ \f. f \ (\X \ A. X)" by (fast elim!: first_in_B intro!: lam_type) lemma ex_choice_fun_Pow: "well_ord(A, R) \ \f. f \ (\X \ Pow(A)-{0}. X)" by (fast elim!: well_ord_subset [THEN ex_choice_fun]) (* ********************************************************************** *) (* Lemmas needed to state when a finite relation is a function. *) (* The criteria are cardinalities of the relation and its domain. *) (* Used in WO6WO1.ML *) (* ********************************************************************** *) (*Using AC we could trivially prove, for all u, domain(u) \ u*) lemma lepoll_m_imp_domain_lepoll_m: "\m \ nat; u \ m\ \ domain(u) \ m" -apply (unfold lepoll_def) + unfolding lepoll_def apply (erule exE) apply (rule_tac x = "\x \ domain(u). \ i. \y. \x,y\ \ u \ f`\x,y\ = i" in exI) apply (rule_tac d = "\y. fst (converse(f) ` y) " in lam_injective) apply (fast intro: LeastI2 nat_into_Ord [THEN Ord_in_Ord] inj_is_fun [THEN apply_type]) apply (erule domainE) apply (frule inj_is_fun [THEN apply_type], assumption) apply (rule LeastI2) apply (auto elim!: nat_into_Ord [THEN Ord_in_Ord]) done lemma rel_domain_ex1: "\succ(m) \ domain(r); r \ succ(m); m \ nat\ \ function(r)" apply (unfold function_def, safe) apply (rule ccontr) apply (fast elim!: lepoll_trans [THEN succ_lepoll_natE] lepoll_m_imp_domain_lepoll_m [OF _ Diff_sing_lepoll] elim: domain_Diff_eq [OF _ not_sym, THEN subst]) done lemma rel_is_fun: "\succ(m) \ domain(r); r \ succ(m); m \ nat; r \ A*B; A=domain(r)\ \ r \ A->B" by (simp add: Pi_iff rel_domain_ex1) end diff --git a/src/ZF/AC/Cardinal_aux.thy b/src/ZF/AC/Cardinal_aux.thy --- a/src/ZF/AC/Cardinal_aux.thy +++ b/src/ZF/AC/Cardinal_aux.thy @@ -1,196 +1,196 @@ (* Title: ZF/AC/Cardinal_aux.thy Author: Krzysztof Grabczewski Auxiliary lemmas concerning cardinalities. *) theory Cardinal_aux imports AC_Equiv begin lemma Diff_lepoll: "\A \ succ(m); B \ A; B\0\ \ A-B \ m" apply (rule not_emptyE, assumption) apply (blast intro: lepoll_trans [OF subset_imp_lepoll Diff_sing_lepoll]) done (* ********************************************************************** *) (* Lemmas involving ordinals and cardinalities used in the proofs *) (* concerning AC16 and DC *) (* ********************************************************************** *) (* j=|A| *) lemma lepoll_imp_ex_le_eqpoll: "\A \ i; Ord(i)\ \ \j. j \ i \ A \ j" by (blast intro!: lepoll_cardinal_le well_ord_Memrel well_ord_cardinal_eqpoll [THEN eqpoll_sym] dest: lepoll_well_ord) (* j=|A| *) lemma lesspoll_imp_ex_lt_eqpoll: "\A \ i; Ord(i)\ \ \j. j A \ j" by (unfold lesspoll_def, blast dest!: lepoll_imp_ex_le_eqpoll elim!: leE) lemma Un_eqpoll_Inf_Ord: assumes A: "A \ i" and B: "B \ i" and NFI: "\ Finite(i)" and i: "Ord(i)" shows "A \ B \ i" proof (rule eqpollI) have AB: "A \ B" using A B by (blast intro: eqpoll_sym eqpoll_trans) have "2 \ nat" by (rule subset_imp_lepoll) (rule OrdmemD [OF nat_2I Ord_nat]) also have "... \ i" by (simp add: nat_le_infinite_Ord le_imp_lepoll NFI i)+ also have "... \ A" by (blast intro: eqpoll_sym A) finally have "2 \ A" . have ICI: "InfCard(|i|)" by (simp add: Inf_Card_is_InfCard Finite_cardinal_iff NFI i) have "A \ B \ A + B" by (rule Un_lepoll_sum) also have "... \ A \ B" by (rule lepoll_imp_sum_lepoll_prod [OF AB [THEN eqpoll_imp_lepoll] \2 \ A\]) also have "... \ i \ i" by (blast intro: prod_eqpoll_cong eqpoll_imp_lepoll A B) also have "... \ i" by (blast intro: well_ord_InfCard_square_eq well_ord_Memrel ICI i) finally show "A \ B \ i" . next have "i \ A" by (blast intro: A eqpoll_sym) also have "... \ A \ B" by (blast intro: subset_imp_lepoll) finally show "i \ A \ B" . qed schematic_goal paired_bij: "?f \ bij({{y,z}. y \ x}, x)" apply (rule RepFun_bijective) apply (simp add: doubleton_eq_iff, blast) done lemma paired_eqpoll: "{{y,z}. y \ x} \ x" by (unfold eqpoll_def, fast intro!: paired_bij) lemma ex_eqpoll_disjoint: "\B. B \ A \ B \ C = 0" by (fast intro!: paired_eqpoll equals0I elim: mem_asym) (*Finally we reach this result. Surely there's a simpler proof?*) lemma Un_lepoll_Inf_Ord: "\A \ i; B \ i; \Finite(i); Ord(i)\ \ A \ B \ i" apply (rule_tac A1 = i and C1 = i in ex_eqpoll_disjoint [THEN exE]) apply (erule conjE) apply (drule lepoll_trans) apply (erule eqpoll_sym [THEN eqpoll_imp_lepoll]) apply (rule Un_lepoll_Un [THEN lepoll_trans], (assumption+)) apply (blast intro: eqpoll_refl Un_eqpoll_Inf_Ord eqpoll_imp_lepoll) done lemma Least_in_Ord: "\P(i); i \ j; Ord(j)\ \ (\ i. P(i)) \ j" apply (erule Least_le [THEN leE]) apply (erule Ord_in_Ord, assumption) apply (erule ltE) apply (fast dest: OrdmemD) apply (erule subst_elem, assumption) done lemma Diff_first_lepoll: "\well_ord(x,r); y \ x; y \ succ(n); n \ nat\ \ y - {THE b. first(b,y,r)} \ n" apply (case_tac "y=0", simp add: empty_lepollI) apply (fast intro!: Diff_sing_lepoll the_first_in) done lemma UN_subset_split: "(\x \ X. P(x)) \ (\x \ X. P(x)-Q(x)) \ (\x \ X. Q(x))" by blast lemma UN_sing_lepoll: "Ord(a) \ (\x \ a. {P(x)}) \ a" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule_tac x = "\z \ (\x \ a. {P (x) }) . (\ i. P (i) =z) " in exI) apply (rule_tac d = "\z. P (z) " in lam_injective) apply (fast intro!: Least_in_Ord) apply (fast intro: LeastI elim!: Ord_in_Ord) done lemma UN_fun_lepoll_lemma [rule_format]: "\well_ord(T, R); \Finite(a); Ord(a); n \ nat\ \ \f. (\b \ a. f`b \ n \ f`b \ T) \ (\b \ a. f`b) \ a" apply (induct_tac "n") apply (rule allI) apply (rule impI) apply (rule_tac b = "\b \ a. f`b" in subst) apply (rule_tac [2] empty_lepollI) apply (rule equals0I [symmetric], clarify) apply (fast dest: lepoll_0_is_0 [THEN subst]) apply (rule allI) apply (rule impI) apply (erule_tac x = "\x \ a. f`x - {THE b. first (b,f`x,R) }" in allE) apply (erule impE, simp) apply (fast intro!: Diff_first_lepoll, simp) apply (rule UN_subset_split [THEN subset_imp_lepoll, THEN lepoll_trans]) apply (fast intro: Un_lepoll_Inf_Ord UN_sing_lepoll) done lemma UN_fun_lepoll: "\\b \ a. f`b \ n \ f`b \ T; well_ord(T, R); \Finite(a); Ord(a); n \ nat\ \ (\b \ a. f`b) \ a" by (blast intro: UN_fun_lepoll_lemma) lemma UN_lepoll: "\\b \ a. F(b) \ n \ F(b) \ T; well_ord(T, R); \Finite(a); Ord(a); n \ nat\ \ (\b \ a. F(b)) \ a" apply (rule rev_mp) apply (rule_tac f="\b \ a. F (b)" in UN_fun_lepoll) apply auto done lemma UN_eq_UN_Diffs: "Ord(a) \ (\b \ a. F(b)) = (\b \ a. F(b) - (\c \ b. F(c)))" apply (rule equalityI) prefer 2 apply fast apply (rule subsetI) apply (erule UN_E) apply (rule UN_I) apply (rule_tac P = "\z. x \ F (z) " in Least_in_Ord, (assumption+)) apply (rule DiffI, best intro: Ord_in_Ord LeastI, clarify) apply (erule_tac P = "\z. x \ F (z) " and i = c in less_LeastE) apply (blast intro: Ord_Least ltI) done lemma lepoll_imp_eqpoll_subset: "a \ X \ \Y. Y \ X \ a \ Y" apply (unfold lepoll_def eqpoll_def, clarify) apply (blast intro: restrict_bij dest: inj_is_fun [THEN fun_is_rel, THEN image_subset]) done (* ********************************************************************** *) (* Diff_lesspoll_eqpoll_Card *) (* ********************************************************************** *) lemma Diff_lesspoll_eqpoll_Card_lemma: "\A\a; \Finite(a); Card(a); B \ a; A-B \ a\ \ P" apply (elim lesspoll_imp_ex_lt_eqpoll [THEN exE] Card_is_Ord conjE) apply (frule_tac j=xa in Un_upper1_le [OF lt_Ord lt_Ord], assumption) apply (frule_tac j=xa in Un_upper2_le [OF lt_Ord lt_Ord], assumption) apply (drule Un_least_lt, assumption) apply (drule eqpoll_imp_lepoll [THEN lepoll_trans], rule le_imp_lepoll, assumption)+ apply (case_tac "Finite(x \ xa)") txt\finite case\ apply (drule Finite_Un [OF lepoll_Finite lepoll_Finite], assumption+) apply (drule subset_Un_Diff [THEN subset_imp_lepoll, THEN lepoll_Finite]) apply (fast dest: eqpoll_sym [THEN eqpoll_imp_lepoll, THEN lepoll_Finite]) txt\infinite case\ apply (drule Un_lepoll_Inf_Ord, (assumption+)) apply (blast intro: le_Ord2) apply (drule lesspoll_trans1 [OF subset_Un_Diff [THEN subset_imp_lepoll, THEN lepoll_trans] lt_Card_imp_lesspoll], assumption+) apply (simp add: lesspoll_def) done lemma Diff_lesspoll_eqpoll_Card: "\A \ a; \Finite(a); Card(a); B \ a\ \ A - B \ a" apply (rule ccontr) apply (rule Diff_lesspoll_eqpoll_Card_lemma, (assumption+)) apply (blast intro: lesspoll_def [THEN def_imp_iff, THEN iffD2] subset_imp_lepoll eqpoll_imp_lepoll lepoll_trans) done end diff --git a/src/ZF/AC/DC.thy b/src/ZF/AC/DC.thy --- a/src/ZF/AC/DC.thy +++ b/src/ZF/AC/DC.thy @@ -1,585 +1,585 @@ (* Title: ZF/AC/DC.thy Author: Krzysztof Grabczewski The proofs concerning the Axiom of Dependent Choice. *) theory DC imports AC_Equiv Hartog Cardinal_aux begin lemma RepFun_lepoll: "Ord(a) \ {P(b). b \ a} \ a" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule_tac x = "\z \ RepFun (a,P) . \ i. z=P (i) " in exI) apply (rule_tac d="\z. P (z)" in lam_injective) apply (fast intro!: Least_in_Ord) apply (rule sym) apply (fast intro: LeastI Ord_in_Ord) done text\Trivial in the presence of AC, but here we need a wellordering of X\ lemma image_Ord_lepoll: "\f \ X->Y; Ord(X)\ \ f``X \ X" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule_tac x = "\x \ f``X. \ y. f`y = x" in exI) apply (rule_tac d = "\z. f`z" in lam_injective) apply (fast intro!: Least_in_Ord apply_equality, clarify) apply (rule LeastI) apply (erule apply_equality, assumption+) apply (blast intro: Ord_in_Ord) done lemma range_subset_domain: "\R \ X*X; \g. g \ X \ \u. \g,u\ \ R\ \ range(R) \ domain(R)" by blast lemma cons_fun_type: "g \ n->X \ cons(\n,x\, g) \ succ(n) -> cons(x, X)" -apply (unfold succ_def) + unfolding succ_def apply (fast intro!: fun_extend elim!: mem_irrefl) done lemma cons_fun_type2: "\g \ n->X; x \ X\ \ cons(\n,x\, g) \ succ(n) -> X" by (erule cons_absorb [THEN subst], erule cons_fun_type) lemma cons_image_n: "n \ nat \ cons(\n,x\, g)``n = g``n" by (fast elim!: mem_irrefl) lemma cons_val_n: "g \ n->X \ cons(\n,x\, g)`n = x" by (fast intro!: apply_equality elim!: cons_fun_type) lemma cons_image_k: "k \ n \ cons(\n,x\, g)``k = g``k" by (fast elim: mem_asym) lemma cons_val_k: "\k \ n; g \ n->X\ \ cons(\n,x\, g)`k = g`k" by (fast intro!: apply_equality consI2 elim!: cons_fun_type apply_Pair) lemma domain_cons_eq_succ: "domain(f)=x \ domain(cons(\x,y\, f)) = succ(x)" by (simp add: domain_cons succ_def) lemma restrict_cons_eq: "g \ n->X \ restrict(cons(\n,x\, g), n) = g" apply (simp add: restrict_def Pi_iff) apply (blast intro: elim: mem_irrefl) done lemma succ_in_succ: "\Ord(k); i \ k\ \ succ(i) \ succ(k)" apply (rule Ord_linear [of "succ(i)" "succ(k)", THEN disjE]) apply (fast elim: Ord_in_Ord mem_irrefl mem_asym)+ done lemma restrict_eq_imp_val_eq: "\restrict(f, domain(g)) = g; x \ domain(g)\ \ f`x = g`x" by (erule subst, simp add: restrict) lemma domain_eq_imp_fun_type: "\domain(f)=A; f \ B->C\ \ f \ A->C" by (frule domain_of_fun, fast) lemma ex_in_domain: "\R \ A * B; R \ 0\ \ \x. x \ domain(R)" by (fast elim!: not_emptyE) definition DC :: "i \ o" where "DC(a) \ \X R. R \ Pow(X)*X \ (\Y \ Pow(X). Y \ a \ (\x \ X. \Y,x\ \ R)) \ (\f \ a->X. \b \ R)" definition DC0 :: o where "DC0 \ \A B R. R \ A*B \ R\0 \ range(R) \ domain(R) \ (\f \ nat->domain(R). \n \ nat. :R)" definition ff :: "[i, i, i, i] \ i" where "ff(b, X, Q, R) \ transrec(b, \c r. THE x. first(x, {x \ X. \ R}, Q))" locale DC0_imp = fixes XX and RR and X and R assumes all_ex: "\Y \ Pow(X). Y \ nat \ (\x \ X. \Y, x\ \ R)" defines XX_def: "XX \ (\n \ nat. {f \ n->X. \k \ n. \ R})" and RR_def: "RR \ {\z1,z2\:XX*XX. domain(z2)=succ(domain(z1)) \ restrict(z2, domain(z1)) = z1}" begin (* ********************************************************************** *) (* DC \ DC(omega) *) (* *) (* The scheme of the proof: *) (* *) (* Assume DC. Let R and X satisfy the premise of DC(omega). *) (* *) (* Define XX and RR as follows: *) (* *) (* XX = (\n \ nat. {f \ n->X. \k \ n. \ R}) *) (* f RR g iff domain(g)=succ(domain(f)) \ *) (* restrict(g, domain(f)) = f *) (* *) (* Then RR satisfies the hypotheses of DC. *) (* So applying DC: *) (* *) (* \f \ nat->XX. \n \ nat. f`n RR f`succ(n) *) (* *) (* Thence *) (* *) (* ff = {. n \ nat} *) (* *) (* is the desired function. *) (* *) (* ********************************************************************** *) lemma lemma1_1: "RR \ XX*XX" by (unfold RR_def, fast) lemma lemma1_2: "RR \ 0" apply (unfold RR_def XX_def) apply (rule all_ex [THEN ballE]) apply (erule_tac [2] notE [OF _ empty_subsetI [THEN PowI]]) apply (erule_tac impE [OF _ nat_0I [THEN n_lesspoll_nat]]) apply (erule bexE) apply (rule_tac a = "<0, {\0, x\}>" in not_emptyI) apply (rule CollectI) apply (rule SigmaI) apply (rule nat_0I [THEN UN_I]) apply (simp (no_asm_simp) add: nat_0I [THEN UN_I]) apply (rule nat_1I [THEN UN_I]) apply (force intro!: singleton_fun [THEN Pi_type] simp add: singleton_0 [symmetric]) apply (simp add: singleton_0) done lemma lemma1_3: "range(RR) \ domain(RR)" apply (unfold RR_def XX_def) apply (rule range_subset_domain, blast, clarify) apply (frule fun_is_rel [THEN image_subset, THEN PowI, THEN all_ex [THEN bspec]]) apply (erule impE[OF _ lesspoll_trans1[OF image_Ord_lepoll [OF _ nat_into_Ord] n_lesspoll_nat]], assumption+) apply (erule bexE) apply (rule_tac x = "cons (\n,x\, g) " in exI) apply (rule CollectI) apply (force elim!: cons_fun_type2 simp add: cons_image_n cons_val_n cons_image_k cons_val_k) apply (simp add: domain_of_fun succ_def restrict_cons_eq) done lemma lemma2: "\\n \ nat. \ RR; f \ nat -> XX; n \ nat\ \ \k \ nat. f`succ(n) \ k -> X \ n \ k \ \ R" apply (induct_tac "n") apply (drule apply_type [OF _ nat_1I]) apply (drule bspec [OF _ nat_0I]) apply (simp add: XX_def, safe) apply (rule rev_bexI, assumption) apply (subgoal_tac "0 \ y", force) apply (force simp add: RR_def intro: ltD elim!: nat_0_le [THEN leE]) (** LEVEL 7, other subgoal **) apply (drule bspec [OF _ nat_succI], assumption) apply (subgoal_tac "f ` succ (succ (x)) \ succ (k) ->X") apply (drule apply_type [OF _ nat_succI [THEN nat_succI]], assumption) apply (simp (no_asm_use) add: XX_def RR_def) apply safe apply (frule_tac a="succ(k)" in domain_of_fun [symmetric, THEN trans], assumption) apply (frule_tac a=y in domain_of_fun [symmetric, THEN trans], assumption) apply (fast elim!: nat_into_Ord [THEN succ_in_succ] dest!: bspec [OF _ nat_into_Ord [THEN succ_in_succ]]) apply (drule domain_of_fun) apply (simp add: XX_def RR_def, clarify) apply (blast dest: domain_of_fun [symmetric, THEN trans] ) done lemma lemma3_1: "\\n \ nat. \ RR; f \ nat -> XX; m \ nat\ \ {f`succ(x)`x. x \ m} = {f`succ(m)`x. x \ m}" apply (subgoal_tac "\x \ m. f`succ (m) `x = f`succ (x) `x") apply simp apply (induct_tac "m", blast) apply (rule ballI) apply (erule succE) apply (rule restrict_eq_imp_val_eq) apply (drule bspec [OF _ nat_succI], assumption) apply (simp add: RR_def) apply (drule lemma2, assumption+) apply (fast dest!: domain_of_fun) apply (drule_tac x = xa in bspec, assumption) apply (erule sym [THEN trans, symmetric]) apply (rule restrict_eq_imp_val_eq [symmetric]) apply (drule bspec [OF _ nat_succI], assumption) apply (simp add: RR_def) apply (drule lemma2, assumption+) apply (blast dest!: domain_of_fun intro: nat_into_Ord OrdmemD [THEN subsetD]) done lemma lemma3: "\\n \ nat. \ RR; f \ nat -> XX; m \ nat\ \ (\x \ nat. f`succ(x)`x) `` m = f`succ(m)``m" apply (erule natE, simp) apply (subst image_lam) apply (fast elim!: OrdmemD [OF nat_succI Ord_nat]) apply (subst lemma3_1, assumption+) apply fast apply (fast dest!: lemma2 elim!: image_fun [symmetric, OF _ OrdmemD [OF _ nat_into_Ord]]) done end theorem DC0_imp_DC_nat: "DC0 \ DC(nat)" apply (unfold DC_def DC0_def, clarify) apply (elim allE) apply (erule impE) (*these three results comprise Lemma 1*) apply (blast intro!: DC0_imp.lemma1_1 [OF DC0_imp.intro] DC0_imp.lemma1_2 [OF DC0_imp.intro] DC0_imp.lemma1_3 [OF DC0_imp.intro]) apply (erule bexE) apply (rule_tac x = "\n \ nat. f`succ (n) `n" in rev_bexI) apply (rule lam_type, blast dest!: DC0_imp.lemma2 [OF DC0_imp.intro] intro: fun_weaken_type) apply (rule oallI) apply (frule DC0_imp.lemma2 [OF DC0_imp.intro], assumption) apply (blast intro: fun_weaken_type) apply (erule ltD) (** LEVEL 11: last subgoal **) apply (subst DC0_imp.lemma3 [OF DC0_imp.intro], assumption+) apply (fast elim!: fun_weaken_type) apply (erule ltD) apply (force simp add: lt_def) done (* ************************************************************************ DC(omega) \ DC The scheme of the proof: Assume DC(omega). Let R and x satisfy the premise of DC. Define XX and RR as follows: XX = (\n \ nat. {f \ succ(n)->domain(R). \k \ n. \ R}) RR = {\z1,z2\:Fin(XX)*XX. (domain(z2)=succ(\f \ z1. domain(f)) \ (\f \ z1. restrict(z2, domain(f)) = f)) | (\ (\g \ XX. domain(g)=succ(\f \ z1. domain(f)) \ (\f \ z1. restrict(g, domain(f)) = f)) \ z2={\0,x\})} Then XX and RR satisfy the hypotheses of DC(omega). So applying DC: \f \ nat->XX. \n \ nat. f``n RR f`n Thence ff = {. n \ nat} is the desired function. ************************************************************************* *) lemma singleton_in_funs: "x \ X \ {\0,x\} \ (\n \ nat. {f \ succ(n)->X. \k \ n. \ R})" apply (rule nat_0I [THEN UN_I]) apply (force simp add: singleton_0 [symmetric] intro!: singleton_fun [THEN Pi_type]) done locale imp_DC0 = fixes XX and RR and x and R and f and allRR defines XX_def: "XX \ (\n \ nat. {f \ succ(n)->domain(R). \k \ n. \ R})" and RR_def: "RR \ {\z1,z2\:Fin(XX)*XX. (domain(z2)=succ(\f \ z1. domain(f)) \ (\f \ z1. restrict(z2, domain(f)) = f)) | (\ (\g \ XX. domain(g)=succ(\f \ z1. domain(f)) \ (\f \ z1. restrict(g, domain(f)) = f)) \ z2={\0,x\})}" and allRR_def: "allRR \ \b \ {\z1,z2\\Fin(XX)*XX. (domain(z2)=succ(\f \ z1. domain(f)) \ (\f \ z1. domain(f)) = b \ (\f \ z1. restrict(z2,domain(f)) = f))}" begin lemma lemma4: "\range(R) \ domain(R); x \ domain(R)\ \ RR \ Pow(XX)*XX \ (\Y \ Pow(XX). Y \ nat \ (\x \ XX. \Y,x\:RR))" apply (rule conjI) apply (force dest!: FinD [THEN PowI] simp add: RR_def) apply (rule impI [THEN ballI]) apply (drule Finite_Fin [OF lesspoll_nat_is_Finite PowD], assumption) apply (case_tac "\g \ XX. domain (g) = succ(\f \ Y. domain(f)) \ (\f\Y. restrict(g, domain(f)) = f)") apply (simp add: RR_def, blast) apply (safe del: domainE) apply (unfold XX_def RR_def) apply (rule rev_bexI, erule singleton_in_funs) apply (simp add: nat_0I [THEN rev_bexI] cons_fun_type2) done lemma UN_image_succ_eq: "\f \ nat->X; n \ nat\ \ (\x \ f``succ(n). P(x)) = P(f`n) \ (\x \ f``n. P(x))" by (simp add: image_fun OrdmemD) lemma UN_image_succ_eq_succ: "\(\x \ f``n. P(x)) = y; P(f`n) = succ(y); f \ nat -> X; n \ nat\ \ (\x \ f``succ(n). P(x)) = succ(y)" by (simp add: UN_image_succ_eq, blast) lemma apply_domain_type: "\h \ succ(n) -> D; n \ nat; domain(h)=succ(y)\ \ h`y \ D" by (fast elim: apply_type dest!: trans [OF sym domain_of_fun]) lemma image_fun_succ: "\h \ nat -> X; n \ nat\ \ h``succ(n) = cons(h`n, h``n)" by (simp add: image_fun OrdmemD) lemma f_n_type: "\domain(f`n) = succ(k); f \ nat -> XX; n \ nat\ \ f`n \ succ(k) -> domain(R)" -apply (unfold XX_def) + unfolding XX_def apply (drule apply_type, assumption) apply (fast elim: domain_eq_imp_fun_type) done lemma f_n_pairs_in_R [rule_format]: "\h \ nat -> XX; domain(h`n) = succ(k); n \ nat\ \ \i \ k. \ R" -apply (unfold XX_def) + unfolding XX_def apply (drule apply_type, assumption) apply (elim UN_E CollectE) apply (drule domain_of_fun [symmetric, THEN trans], assumption, simp) done lemma restrict_cons_eq_restrict: "\restrict(h, domain(u))=u; h \ n->X; domain(u) \ n\ \ restrict(cons(\n, y\, h), domain(u)) = u" -apply (unfold restrict_def) + unfolding restrict_def apply (simp add: restrict_def Pi_iff) apply (erule sym [THEN trans, symmetric]) apply (blast elim: mem_irrefl) done lemma all_in_image_restrict_eq: "\\x \ f``n. restrict(f`n, domain(x))=x; f \ nat -> XX; n \ nat; domain(f`n) = succ(n); (\x \ f``n. domain(x)) \ n\ \ \x \ f``succ(n). restrict(cons(, f`n), domain(x)) = x" apply (rule ballI) apply (simp add: image_fun_succ) apply (drule f_n_type, assumption+) apply (erule disjE) apply (simp add: domain_of_fun restrict_cons_eq) apply (blast intro!: restrict_cons_eq_restrict) done lemma simplify_recursion: "\\b \ RR; f \ nat -> XX; range(R) \ domain(R); x \ domain(R)\ \ allRR" apply (unfold RR_def allRR_def) apply (rule oallI, drule ltD) apply (erule nat_induct) apply (drule_tac x=0 in ospec, blast intro: Limit_has_0) apply (force simp add: singleton_fun [THEN domain_of_fun] singleton_in_funs) (*induction step*) (** LEVEL 5 **) (*prevent simplification of \\ to \\ *) apply (simp only: separation split) apply (drule_tac x="succ(xa)" in ospec, blast intro: ltI) apply (elim conjE disjE) apply (force elim!: trans subst_context intro!: UN_image_succ_eq_succ) apply (erule notE) apply (simp add: XX_def UN_image_succ_eq_succ) apply (elim conjE bexE) apply (drule apply_domain_type, assumption+) apply (erule domainE)+ apply (frule f_n_type) apply (simp add: XX_def, assumption+) apply (rule rev_bexI, erule nat_succI) apply (rename_tac m i j y z) apply (rule_tac x = "cons(, f`m)" in bexI) prefer 2 apply (blast intro: cons_fun_type2) apply (rule conjI) prefer 2 apply (fast del: ballI subsetI elim: trans [OF _ subst_context, THEN domain_cons_eq_succ] subst_context all_in_image_restrict_eq [simplified XX_def] trans equalityD1) (*one remaining subgoal*) apply (rule ballI) apply (erule succE) (** LEVEL 25 **) apply (simp add: cons_val_n cons_val_k) (*assumption+ will not perform the required backtracking!*) apply (drule f_n_pairs_in_R [simplified XX_def, OF _ domain_of_fun], assumption, assumption, assumption) apply (simp add: nat_into_Ord [THEN succ_in_succ] succI2 cons_val_k) done lemma lemma2: "\allRR; f \ nat->XX; range(R) \ domain(R); x \ domain(R); n \ nat\ \ f`n \ succ(n) -> domain(R) \ (\i \ n. :R)" -apply (unfold allRR_def) + unfolding allRR_def apply (drule ospec) apply (erule ltI [OF _ Ord_nat]) apply (erule CollectE, simp) apply (rule conjI) prefer 2 apply (fast elim!: f_n_pairs_in_R trans subst_context) -apply (unfold XX_def) + unfolding XX_def apply (fast elim!: trans [THEN domain_eq_imp_fun_type] subst_context) done lemma lemma3: "\allRR; f \ nat->XX; n\nat; range(R) \ domain(R); x \ domain(R)\ \ f`n`n = f`succ(n)`n" apply (frule lemma2 [THEN conjunct1, THEN domain_of_fun], assumption+) -apply (unfold allRR_def) + unfolding allRR_def apply (drule ospec) apply (drule ltI [OF nat_succI Ord_nat], assumption, simp) apply (elim conjE ballE) apply (erule restrict_eq_imp_val_eq [symmetric], force) apply (simp add: image_fun OrdmemD) done end theorem DC_nat_imp_DC0: "DC(nat) \ DC0" apply (unfold DC_def DC0_def) apply (intro allI impI) apply (erule asm_rl conjE ex_in_domain [THEN exE] allE)+ apply (erule impE [OF _ imp_DC0.lemma4], assumption+) apply (erule bexE) apply (drule imp_DC0.simplify_recursion, assumption+) apply (rule_tac x = "\n \ nat. f`n`n" in bexI) apply (rule_tac [2] lam_type) apply (erule_tac [2] apply_type [OF imp_DC0.lemma2 [THEN conjunct1] succI1]) apply (rule ballI) apply (frule_tac n="succ(n)" in imp_DC0.lemma2, (assumption|erule nat_succI)+) apply (drule imp_DC0.lemma3, auto) done (* ********************************************************************** *) (* \K. Card(K) \ DC(K) \ WO3 *) (* ********************************************************************** *) lemma fun_Ord_inj: "\f \ a->X; Ord(a); \b c. \b a\ \ f`b\f`c\ \ f \ inj(a, X)" apply (unfold inj_def, simp) apply (intro ballI impI) apply (rule_tac j=x in Ord_in_Ord [THEN Ord_linear_lt], assumption+) apply (blast intro: Ord_in_Ord, auto) apply (atomize, blast dest: not_sym) done lemma value_in_image: "\f \ X->Y; A \ X; a \ A\ \ f`a \ f``A" by (fast elim!: image_fun [THEN ssubst]) lemma lesspoll_lemma: "\\ A \ B; C \ B\ \ A - C \ 0" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (fast dest!: Diff_eq_0_iff [THEN iffD1, THEN subset_imp_lepoll] intro!: eqpollI elim: notE elim!: eqpollE lepoll_trans) done theorem DC_WO3: "(\K. Card(K) \ DC(K)) \ WO3" apply (unfold DC_def WO3_def) apply (rule allI) apply (case_tac "A \ Hartog (A)") apply (fast dest!: lesspoll_imp_ex_lt_eqpoll intro!: Ord_Hartog leI [THEN le_imp_subset]) apply (erule allE impE)+ apply (rule Card_Hartog) apply (erule_tac x = A in allE) apply (erule_tac x = "{\z1,z2\ \ Pow (A) *A . z1 \ Hartog (A) \ z2 \ z1}" in allE) apply simp apply (erule impE, fast elim: lesspoll_lemma [THEN not_emptyE]) apply (erule bexE) apply (rule Hartog_lepoll_selfE) apply (rule lepoll_def [THEN def_imp_iff, THEN iffD2]) apply (rule exI, rule fun_Ord_inj, assumption, rule Ord_Hartog) apply (drule value_in_image) apply (drule OrdmemD, rule Ord_Hartog, assumption+, erule ltD) apply (drule ospec) apply (blast intro: ltI Ord_Hartog, force) done (* ********************************************************************** *) (* WO1 \ \K. Card(K) \ DC(K) *) (* ********************************************************************** *) lemma images_eq: "\\x \ A. f`x=g`x; f \ Df->Cf; g \ Dg->Cg; A \ Df; A \ Dg\ \ f``A = g``A" apply (simp (no_asm_simp) add: image_fun) done lemma lam_images_eq: "\Ord(a); b \ a\ \ (\x \ a. h(x))``b = (\x \ b. h(x))``b" apply (rule images_eq) apply (rule ballI) apply (drule OrdmemD [THEN subsetD], assumption+) apply simp apply (fast elim!: RepFunI OrdmemD intro!: lam_type)+ done lemma lam_type_RepFun: "(\b \ a. h(b)) \ a -> {h(b). b \ a}" by (fast intro!: lam_type RepFunI) lemma lemmaX: "\\Y \ Pow(X). Y \ K \ (\x \ X. \Y, x\ \ R); b \ K; Z \ Pow(X); Z \ K\ \ {x \ X. \Z,x\ \ R} \ 0" by blast lemma WO1_DC_lemma: "\Card(K); well_ord(X,Q); \Y \ Pow(X). Y \ K \ (\x \ X. \Y, x\ \ R); b \ K\ \ ff(b, X, Q, R) \ {x \ X. <(\c \ b. ff(c, X, Q, R))``b, x> \ R}" apply (rule_tac P = "b \ K" in impE, (erule_tac [2] asm_rl)+) apply (rule_tac i=b in Card_is_Ord [THEN Ord_in_Ord, THEN trans_induct], assumption+) apply (rule impI) apply (rule ff_def [THEN def_transrec, THEN ssubst]) apply (erule the_first_in, fast) apply (simp add: image_fun [OF lam_type_RepFun subset_refl]) apply (erule lemmaX, assumption) apply (blast intro: Card_is_Ord OrdmemD [THEN subsetD]) apply (blast intro: lesspoll_trans1 in_Card_imp_lesspoll RepFun_lepoll) done theorem WO1_DC_Card: "WO1 \ \K. Card(K) \ DC(K)" apply (unfold DC_def WO1_def) apply (rule allI impI)+ apply (erule allE exE conjE)+ apply (rule_tac x = "\b \ K. ff (b, X, Ra, R) " in bexI) apply (simp add: lam_images_eq [OF Card_is_Ord ltD]) apply (fast elim!: ltE WO1_DC_lemma [THEN CollectD2]) apply (rule_tac lam_type) apply (rule WO1_DC_lemma [THEN CollectD1], assumption+) done end diff --git a/src/ZF/AC/HH.thy b/src/ZF/AC/HH.thy --- a/src/ZF/AC/HH.thy +++ b/src/ZF/AC/HH.thy @@ -1,245 +1,245 @@ (* Title: ZF/AC/HH.thy Author: Krzysztof Grabczewski Some properties of the recursive definition of HH used in the proofs of AC17 \ AC1 AC1 \ WO2 AC15 \ WO6 *) theory HH imports AC_Equiv Hartog begin definition HH :: "[i, i, i] \ i" where "HH(f,x,a) \ transrec(a, \b r. let z = x - (\c \ b. r`c) in if f`z \ Pow(z)-{0} then f`z else {x})" subsection\Lemmas useful in each of the three proofs\ lemma HH_def_satisfies_eq: "HH(f,x,a) = (let z = x - (\b \ a. HH(f,x,b)) in if f`z \ Pow(z)-{0} then f`z else {x})" by (rule HH_def [THEN def_transrec, THEN trans], simp) lemma HH_values: "HH(f,x,a) \ Pow(x)-{0} | HH(f,x,a)={x}" apply (rule HH_def_satisfies_eq [THEN ssubst]) apply (simp add: Let_def Diff_subset [THEN PowI], fast) done lemma subset_imp_Diff_eq: "B \ A \ X-(\a \ A. P(a)) = X-(\a \ A-B. P(a))-(\b \ B. P(b))" by fast lemma Ord_DiffE: "\c \ a-b; b \ c=b | b cy. y\A \ P(y) = {x}) \ x - (\y \ A. P(y)) = x" by (simp, fast elim!: mem_irrefl) lemma HH_eq: "x - (\b \ a. HH(f,x,b)) = x - (\b \ a1. HH(f,x,b)) \ HH(f,x,a) = HH(f,x,a1)" apply (subst HH_def_satisfies_eq [of _ _ a1]) apply (rule HH_def_satisfies_eq [THEN trans], simp) done lemma HH_is_x_gt_too: "\HH(f,x,b)={x}; b \ HH(f,x,a)={x}" apply (rule_tac P = "bHH(f,x,a) \ Pow(x)-{0}; b \ HH(f,x,b) \ Pow(x)-{0}" apply (rule HH_values [THEN disjE], assumption) apply (drule HH_is_x_gt_too, assumption) apply (drule subst, assumption) apply (fast elim!: mem_irrefl) done lemma HH_subset_x_imp_subset_Diff_UN: "HH(f,x,a) \ Pow(x)-{0} \ HH(f,x,a) \ Pow(x - (\b \ a. HH(f,x,b)))-{0}" apply (drule HH_def_satisfies_eq [THEN subst]) apply (rule HH_def_satisfies_eq [THEN ssubst]) apply (simp add: Let_def Diff_subset [THEN PowI]) apply (drule split_if [THEN iffD1]) apply (fast elim!: mem_irrefl) done lemma HH_eq_arg_lt: "\HH(f,x,v)=HH(f,x,w); HH(f,x,v) \ Pow(x)-{0}; v \ w\ \ P" apply (frule_tac P = "\y. y \ Pow (x) -{0}" in subst, assumption) apply (drule_tac a = w in HH_subset_x_imp_subset_Diff_UN) apply (drule subst_elem, assumption) apply (fast intro!: singleton_iff [THEN iffD2] equals0I) done lemma HH_eq_imp_arg_eq: "\HH(f,x,v)=HH(f,x,w); HH(f,x,w) \ Pow(x)-{0}; Ord(v); Ord(w)\ \ v=w" apply (rule_tac j = w in Ord_linear_lt) apply (simp_all (no_asm_simp)) apply (drule subst_elem, assumption) apply (blast dest: ltD HH_eq_arg_lt) apply (blast dest: HH_eq_arg_lt [OF sym] ltD) done lemma HH_subset_x_imp_lepoll: "\HH(f, x, i) \ Pow(x)-{0}; Ord(i)\ \ i \ Pow(x)-{0}" apply (unfold lepoll_def inj_def) apply (rule_tac x = "\j \ i. HH (f, x, j) " in exI) apply (simp (no_asm_simp)) apply (fast del: DiffE elim!: HH_eq_imp_arg_eq Ord_in_Ord HH_subset_x_lt_too intro!: lam_type ballI ltI intro: bexI) done lemma HH_Hartog_is_x: "HH(f, x, Hartog(Pow(x)-{0})) = {x}" apply (rule HH_values [THEN disjE]) prefer 2 apply assumption apply (fast del: DiffE intro!: Ord_Hartog dest!: HH_subset_x_imp_lepoll elim!: Hartog_lepoll_selfE) done lemma HH_Least_eq_x: "HH(f, x, \ i. HH(f, x, i) = {x}) = {x}" by (fast intro!: Ord_Hartog HH_Hartog_is_x LeastI) lemma less_Least_subset_x: "a \ (\ i. HH(f,x,i)={x}) \ HH(f,x,a) \ Pow(x)-{0}" apply (rule HH_values [THEN disjE], assumption) apply (rule less_LeastE) apply (erule_tac [2] ltI [OF _ Ord_Least], assumption) done subsection\Lemmas used in the proofs of AC1 \ WO2 and AC17 \ AC1\ lemma lam_Least_HH_inj_Pow: "(\a \ (\ i. HH(f,x,i)={x}). HH(f,x,a)) \ inj(\ i. HH(f,x,i)={x}, Pow(x)-{0})" apply (unfold inj_def, simp) apply (fast intro!: lam_type dest: less_Least_subset_x elim!: HH_eq_imp_arg_eq Ord_Least [THEN Ord_in_Ord]) done lemma lam_Least_HH_inj: "\a \ (\ i. HH(f,x,i)={x}). \z \ x. HH(f,x,a) = {z} \ (\a \ (\ i. HH(f,x,i)={x}). HH(f,x,a)) \ inj(\ i. HH(f,x,i)={x}, {{y}. y \ x})" by (rule lam_Least_HH_inj_Pow [THEN inj_strengthen_type], simp) lemma lam_surj_sing: "\x - (\a \ A. F(a)) = 0; \a \ A. \z \ x. F(a) = {z}\ \ (\a \ A. F(a)) \ surj(A, {{y}. y \ x})" apply (simp add: surj_def lam_type Diff_eq_0_iff) apply (blast elim: equalityE) done lemma not_emptyI2: "y \ Pow(x)-{0} \ x \ 0" by auto lemma f_subset_imp_HH_subset: "f`(x - (\j \ i. HH(f,x,j))) \ Pow(x - (\j \ i. HH(f,x,j)))-{0} \ HH(f, x, i) \ Pow(x) - {0}" apply (rule HH_def_satisfies_eq [THEN ssubst]) apply (simp add: Let_def Diff_subset [THEN PowI] not_emptyI2 [THEN if_P], fast) done lemma f_subsets_imp_UN_HH_eq_x: "\z \ Pow(x)-{0}. f`z \ Pow(z)-{0} \ x - (\j \ (\ i. HH(f,x,i)={x}). HH(f,x,j)) = 0" apply (case_tac "P \ {0}" for P, fast) apply (drule Diff_subset [THEN PowI, THEN DiffI]) apply (drule bspec, assumption) apply (drule f_subset_imp_HH_subset) apply (blast dest!: subst_elem [OF _ HH_Least_eq_x [symmetric]] elim!: mem_irrefl) done lemma HH_values2: "HH(f,x,i) = f`(x - (\j \ i. HH(f,x,j))) | HH(f,x,i)={x}" apply (rule HH_def_satisfies_eq [THEN ssubst]) apply (simp add: Let_def Diff_subset [THEN PowI]) done lemma HH_subset_imp_eq: "HH(f,x,i): Pow(x)-{0} \ HH(f,x,i)=f`(x - (\j \ i. HH(f,x,j)))" apply (rule HH_values2 [THEN disjE], assumption) apply (fast elim!: equalityE mem_irrefl dest!: singleton_subsetD) done lemma f_sing_imp_HH_sing: "\f \ (Pow(x)-{0}) -> {{z}. z \ x}; a \ (\ i. HH(f,x,i)={x})\ \ \z \ x. HH(f,x,a) = {z}" apply (drule less_Least_subset_x) apply (frule HH_subset_imp_eq) apply (drule apply_type) apply (rule Diff_subset [THEN PowI, THEN DiffI]) apply (fast dest!: HH_subset_x_imp_subset_Diff_UN [THEN not_emptyI2], force) done lemma f_sing_lam_bij: "\x - (\j \ (\ i. HH(f,x,i)={x}). HH(f,x,j)) = 0; f \ (Pow(x)-{0}) -> {{z}. z \ x}\ \ (\a \ (\ i. HH(f,x,i)={x}). HH(f,x,a)) \ bij(\ i. HH(f,x,i)={x}, {{y}. y \ x})" -apply (unfold bij_def) + unfolding bij_def apply (fast intro!: lam_Least_HH_inj lam_surj_sing f_sing_imp_HH_sing) done lemma lam_singI: "f \ (\X \ Pow(x)-{0}. F(X)) \ (\X \ Pow(x)-{0}. {f`X}) \ (\X \ Pow(x)-{0}. {{z}. z \ F(X)})" by (fast del: DiffI DiffE intro!: lam_type singleton_eq_iff [THEN iffD2] dest: apply_type) (*FIXME: both uses have the form ...[THEN bij_converse_bij], so simplification is needed!*) lemmas bij_Least_HH_x = comp_bij [OF f_sing_lam_bij [OF _ lam_singI] lam_sing_bij [THEN bij_converse_bij]] subsection\The proof of AC1 \ WO2\ (*Establishing the existence of a bijection, namely converse (converse(\x\x. {x}) O Lambda (\ i. HH(\X\Pow(x) - {0}. {f ` X}, x, i) = {x}, HH(\X\Pow(x) - {0}. {f ` X}, x))) Perhaps it could be simplified. *) lemma bijection: "f \ (\X \ Pow(x) - {0}. X) \ \g. g \ bij(x, \ i. HH(\X \ Pow(x)-{0}. {f`X}, x, i) = {x})" apply (rule exI) apply (rule bij_Least_HH_x [THEN bij_converse_bij]) apply (rule f_subsets_imp_UN_HH_eq_x) apply (intro ballI apply_type) apply (fast intro: lam_type apply_type del: DiffE, assumption) apply (fast intro: Pi_weaken_type) done lemma AC1_WO2: "AC1 \ WO2" apply (unfold AC1_def WO2_def eqpoll_def) apply (intro allI) apply (drule_tac x = "Pow(A) - {0}" in spec) apply (blast dest: bijection) done end diff --git a/src/ZF/AC/Hartog.thy b/src/ZF/AC/Hartog.thy --- a/src/ZF/AC/Hartog.thy +++ b/src/ZF/AC/Hartog.thy @@ -1,83 +1,83 @@ (* Title: ZF/AC/Hartog.thy Author: Krzysztof Grabczewski Hartog's function. *) theory Hartog imports AC_Equiv begin definition Hartog :: "i \ i" where "Hartog(X) \ \ i. \ i \ X" lemma Ords_in_set: "\a. Ord(a) \ a \ X \ P" apply (rule_tac X = "{y \ X. Ord (y) }" in ON_class [elim_format]) apply fast done lemma Ord_lepoll_imp_ex_well_ord: "\Ord(a); a \ X\ \ \Y. Y \ X \ (\R. well_ord(Y,R) \ ordertype(Y,R)=a)" -apply (unfold lepoll_def) + unfolding lepoll_def apply (erule exE) apply (intro exI conjI) apply (erule inj_is_fun [THEN fun_is_rel, THEN image_subset]) apply (rule well_ord_rvimage [OF bij_is_inj well_ord_Memrel]) apply (erule restrict_bij [THEN bij_converse_bij]) apply (rule subset_refl, assumption) apply (rule trans) apply (rule bij_ordertype_vimage) apply (erule restrict_bij [THEN bij_converse_bij]) apply (rule subset_refl) apply (erule well_ord_Memrel) apply (erule ordertype_Memrel) done lemma Ord_lepoll_imp_eq_ordertype: "\Ord(a); a \ X\ \ \Y. Y \ X \ (\R. R \ X*X \ ordertype(Y,R)=a)" apply (drule Ord_lepoll_imp_ex_well_ord, assumption, clarify) apply (intro exI conjI) apply (erule_tac [3] ordertype_Int, auto) done lemma Ords_lepoll_set_lemma: "(\a. Ord(a) \ a \ X) \ \a. Ord(a) \ a \ {b. Z \ Pow(X)*Pow(X*X), \Y R. Z=\Y,R\ \ ordertype(Y,R)=b}" apply (intro allI impI) apply (elim allE impE, assumption) apply (blast dest!: Ord_lepoll_imp_eq_ordertype intro: sym) done lemma Ords_lepoll_set: "\a. Ord(a) \ a \ X \ P" by (erule Ords_lepoll_set_lemma [THEN Ords_in_set]) lemma ex_Ord_not_lepoll: "\a. Ord(a) \ \a \ X" apply (rule ccontr) apply (best intro: Ords_lepoll_set) done lemma not_Hartog_lepoll_self: "\ Hartog(A) \ A" -apply (unfold Hartog_def) + unfolding Hartog_def apply (rule ex_Ord_not_lepoll [THEN exE]) apply (rule LeastI, auto) done lemmas Hartog_lepoll_selfE = not_Hartog_lepoll_self [THEN notE] lemma Ord_Hartog: "Ord(Hartog(A))" by (unfold Hartog_def, rule Ord_Least) lemma less_HartogE1: "\i < Hartog(A); \ i \ A\ \ P" by (unfold Hartog_def, fast elim: less_LeastE) lemma less_HartogE: "\i < Hartog(A); i \ Hartog(A)\ \ P" by (blast intro: less_HartogE1 eqpoll_sym eqpoll_imp_lepoll lepoll_trans [THEN Hartog_lepoll_selfE]) lemma Card_Hartog: "Card(Hartog(A))" by (fast intro!: CardI Ord_Hartog elim: less_HartogE) end diff --git a/src/ZF/AC/WO1_AC.thy b/src/ZF/AC/WO1_AC.thy --- a/src/ZF/AC/WO1_AC.thy +++ b/src/ZF/AC/WO1_AC.thy @@ -1,106 +1,106 @@ (* Title: ZF/AC/WO1_AC.thy Author: Krzysztof Grabczewski The proofs of WO1 \ AC1 and WO1 \ AC10(n) for n >= 1 The latter proof is referred to as clear by the Rubins. However it seems to be quite complicated. The formal proof presented below is a mechanisation of the proof by Lawrence C. Paulson which is the following: Assume WO1. Let s be a set of infinite sets. Suppose x \ s. Then x is equipollent to |x| (by WO1), an infinite cardinal call it K. Since K = K \ K = |K+K| (by InfCard_cdouble_eq) there is an isomorphism h \ bij(K+K, x). (Here + means disjoint sum.) So there is a partition of x into 2-element sets, namely {{h(Inl(i)), h(Inr(i))} . i \ K} So for all x \ s the desired partition exists. By AC1 (which follows from WO1) there exists a function f that chooses a partition for each x \ s. Therefore we have AC10(2). *) theory WO1_AC imports AC_Equiv begin (* ********************************************************************** *) (* WO1 \ AC1 *) (* ********************************************************************** *) theorem WO1_AC1: "WO1 \ AC1" by (unfold AC1_def WO1_def, fast elim!: ex_choice_fun) (* ********************************************************************** *) (* WO1 \ AC10(n) (n >= 1) *) (* ********************************************************************** *) lemma lemma1: "\WO1; \B \ A. \C \ D(B). P(C,B)\ \ \f. \B \ A. P(f`B,B)" -apply (unfold WO1_def) + unfolding WO1_def apply (erule_tac x = "\({{C \ D (B) . P (C,B) }. B \ A}) " in allE) apply (erule exE, drule ex_choice_fun, fast) apply (erule exE) apply (rule_tac x = "\x \ A. f`{C \ D (x) . P (C,x) }" in exI) apply (simp, blast dest!: apply_type [OF _ RepFunI]) done lemma lemma2_1: "\\Finite(B); WO1\ \ |B| + |B| \ B" -apply (unfold WO1_def) + unfolding WO1_def apply (rule eqpoll_trans) prefer 2 apply (fast elim!: well_ord_cardinal_eqpoll) apply (rule eqpoll_sym [THEN eqpoll_trans]) apply (fast elim!: well_ord_cardinal_eqpoll) apply (drule spec [of _ B]) apply (clarify dest!: eqpoll_imp_Finite_iff [OF well_ord_cardinal_eqpoll]) apply (simp add: cadd_def [symmetric] eqpoll_refl InfCard_cdouble_eq Card_cardinal Inf_Card_is_InfCard) done lemma lemma2_2: "f \ bij(D+D, B) \ {{f`Inl(i), f`Inr(i)}. i \ D} \ Pow(Pow(B))" by (fast elim!: bij_is_fun [THEN apply_type]) lemma lemma2_3: "f \ bij(D+D, B) \ pairwise_disjoint({{f`Inl(i), f`Inr(i)}. i \ D})" -apply (unfold pairwise_disjoint_def) + unfolding pairwise_disjoint_def apply (blast dest: bij_is_inj [THEN inj_apply_equality]) done lemma lemma2_4: "\f \ bij(D+D, B); 1\n\ \ sets_of_size_between({{f`Inl(i), f`Inr(i)}. i \ D}, 2, succ(n))" apply (simp (no_asm_simp) add: sets_of_size_between_def succ_def) apply (blast intro!: cons_lepoll_cong intro: singleton_eqpoll_1 [THEN eqpoll_imp_lepoll] le_imp_subset [THEN subset_imp_lepoll] lepoll_trans dest: bij_is_inj [THEN inj_apply_equality] elim!: mem_irrefl) done lemma lemma2_5: "f \ bij(D+D, B) \ \({{f`Inl(i), f`Inr(i)}. i \ D})=B" apply (unfold bij_def surj_def) apply (fast elim!: inj_is_fun [THEN apply_type]) done lemma lemma2: "\WO1; \Finite(B); 1\n\ \ \C \ Pow(Pow(B)). pairwise_disjoint(C) \ sets_of_size_between(C, 2, succ(n)) \ \(C)=B" apply (drule lemma2_1 [THEN eqpoll_def [THEN def_imp_iff, THEN iffD1]], assumption) apply (blast intro!: lemma2_2 lemma2_3 lemma2_4 lemma2_5) done theorem WO1_AC10: "\WO1; 1\n\ \ AC10(n)" -apply (unfold AC10_def) + unfolding AC10_def apply (fast intro!: lemma1 elim!: lemma2) done end diff --git a/src/ZF/AC/WO1_WO7.thy b/src/ZF/AC/WO1_WO7.thy --- a/src/ZF/AC/WO1_WO7.thy +++ b/src/ZF/AC/WO1_WO7.thy @@ -1,114 +1,114 @@ (* Title: ZF/AC/WO1_WO7.thy Author: Lawrence C Paulson, CU Computer Laboratory Copyright 1998 University of Cambridge WO7 \ LEMMA \ WO1 (Rubin \ Rubin p. 5) LEMMA is the sentence denoted by (**) Also, WO1 \ WO8 *) theory WO1_WO7 imports AC_Equiv begin definition "LEMMA \ \X. \Finite(X) \ (\R. well_ord(X,R) \ \well_ord(X,converse(R)))" (* ********************************************************************** *) (* It is easy to see that WO7 is equivalent to (**) *) (* ********************************************************************** *) lemma WO7_iff_LEMMA: "WO7 \ LEMMA" apply (unfold WO7_def LEMMA_def) apply (blast intro: Finite_well_ord_converse) done (* ********************************************************************** *) (* It is also easy to show that LEMMA implies WO1. *) (* ********************************************************************** *) lemma LEMMA_imp_WO1: "LEMMA \ WO1" apply (unfold WO1_def LEMMA_def Finite_def eqpoll_def) apply (blast intro!: well_ord_rvimage [OF bij_is_inj nat_implies_well_ord]) done (* ********************************************************************** *) (* The Rubins' proof of the other implication is contained within the *) (* following sentence \ *) (* "... each infinite ordinal is well ordered by < but not by >." *) (* This statement can be proved by the following two theorems. *) (* But moreover we need to show similar property for any well ordered *) (* infinite set. It is not very difficult thanks to Isabelle order types *) (* We show that if a set is well ordered by some relation and by its *) (* converse, then apropriate order type is well ordered by the converse *) (* of it's membership relation, which in connection with the previous *) (* gives the conclusion. *) (* ********************************************************************** *) lemma converse_Memrel_not_wf_on: "\Ord(a); \Finite(a)\ \ \wf[a](converse(Memrel(a)))" apply (unfold wf_on_def wf_def) apply (drule nat_le_infinite_Ord [THEN le_imp_subset], assumption) apply (rule notI) apply (erule_tac x = nat in allE, blast) done lemma converse_Memrel_not_well_ord: "\Ord(a); \Finite(a)\ \ \well_ord(a,converse(Memrel(a)))" -apply (unfold well_ord_def) + unfolding well_ord_def apply (blast dest: converse_Memrel_not_wf_on) done lemma well_ord_rvimage_ordertype: "well_ord(A,r) \ rvimage (ordertype(A,r), converse(ordermap(A,r)),r) = Memrel(ordertype(A,r))" by (blast intro: ordertype_ord_iso [THEN ord_iso_sym] ord_iso_rvimage_eq Memrel_type [THEN subset_Int_iff [THEN iffD1]] trans) lemma well_ord_converse_Memrel: "\well_ord(A,r); well_ord(A,converse(r))\ \ well_ord(ordertype(A,r), converse(Memrel(ordertype(A,r))))" apply (subst well_ord_rvimage_ordertype [symmetric], assumption) apply (rule rvimage_converse [THEN subst]) apply (blast intro: ordertype_ord_iso ord_iso_sym ord_iso_is_bij bij_is_inj well_ord_rvimage) done lemma WO1_imp_LEMMA: "WO1 \ LEMMA" apply (unfold WO1_def LEMMA_def, clarify) apply (blast dest: well_ord_converse_Memrel Ord_ordertype [THEN converse_Memrel_not_well_ord] intro: ordertype_ord_iso ord_iso_is_bij bij_is_inj lepoll_Finite lepoll_def [THEN def_imp_iff, THEN iffD2] ) done lemma WO1_iff_WO7: "WO1 \ WO7" apply (simp add: WO7_iff_LEMMA) apply (blast intro: LEMMA_imp_WO1 WO1_imp_LEMMA) done (* ********************************************************************** *) (* The proof of WO8 \ WO1 (Rubin \ Rubin p. 6) *) (* ********************************************************************** *) lemma WO1_WO8: "WO1 \ WO8" by (unfold WO1_def WO8_def, fast) (* The implication "WO8 \ WO1": a faithful image of Rubin \ Rubin's proof*) lemma WO8_WO1: "WO8 \ WO1" apply (unfold WO1_def WO8_def) apply (rule allI) apply (erule_tac x = "{{x}. x \ A}" in allE) apply (erule impE) apply (rule_tac x = "\a \ {{x}. x \ A}. THE x. a={x}" in exI) apply (force intro!: lam_type simp add: singleton_eq_iff the_equality) apply (blast intro: lam_sing_bij bij_is_inj well_ord_rvimage) done end diff --git a/src/ZF/AC/WO2_AC16.thy b/src/ZF/AC/WO2_AC16.thy --- a/src/ZF/AC/WO2_AC16.thy +++ b/src/ZF/AC/WO2_AC16.thy @@ -1,579 +1,579 @@ (* Title: ZF/AC/WO2_AC16.thy Author: Krzysztof Grabczewski The proof of WO2 \ AC16(k #+ m, k) The main part of the proof is the inductive reasoning concerning properties of constructed family T_gamma. The proof deals with three cases for ordinals: 0, succ and limit ordinal. The first instance is trivial, the third not difficult, but the second is very complicated requiring many lemmas. We also need to prove that at any stage gamma the set (s - \(...) - k_gamma) (Rubin \ Rubin page 15) contains m distinct elements (in fact is equipollent to s) *) theory WO2_AC16 imports AC_Equiv AC16_lemmas Cardinal_aux begin (**** A recursive definition used in the proof of WO2 \ AC16 ****) definition recfunAC16 :: "[i,i,i,i] \ i" where "recfunAC16(f,h,i,a) \ transrec2(i, 0, \g r. if (\y \ r. h`g \ y) then r else r \ {f`(\ i. h`g \ f`i \ (\b f`i \ (\t \ r. \ h`b \ t))))})" (* ********************************************************************** *) (* Basic properties of recfunAC16 *) (* ********************************************************************** *) lemma recfunAC16_0: "recfunAC16(f,h,0,a) = 0" by (simp add: recfunAC16_def) lemma recfunAC16_succ: "recfunAC16(f,h,succ(i),a) = (if (\y \ recfunAC16(f,h,i,a). h ` i \ y) then recfunAC16(f,h,i,a) else recfunAC16(f,h,i,a) \ {f ` (\ j. h ` i \ f ` j \ (\b f`j \ (\t \ recfunAC16(f,h,i,a). \ h`b \ t))))})" apply (simp add: recfunAC16_def) done lemma recfunAC16_Limit: "Limit(i) \ recfunAC16(f,h,i,a) = (\j\g r. r \ B(g,r); Ord(i)\ \ j transrec2(j, 0, B) \ transrec2(i, 0, B)" apply (erule trans_induct) apply (rule Ord_cases, assumption+, fast) apply (simp (no_asm_simp)) apply (blast elim!: leE) apply (simp add: transrec2_Limit) apply (blast intro: OUN_I ltI Ord_in_Ord [THEN le_refl] elim!: Limit_has_succ [THEN ltE]) done lemma transrec2_mono: "\\g r. r \ B(g,r); j\i\ \ transrec2(j, 0, B) \ transrec2(i, 0, B)" apply (erule leE) apply (rule transrec2_mono_lemma) apply (auto intro: lt_Ord2 ) done (* ********************************************************************** *) (* Monotonicity of recfunAC16 *) (* ********************************************************************** *) lemma recfunAC16_mono: "i\j \ recfunAC16(f, g, i, a) \ recfunAC16(f, g, j, a)" -apply (unfold recfunAC16_def) + unfolding recfunAC16_def apply (rule transrec2_mono, auto) done (* ********************************************************************** *) (* case of limit ordinal *) (* ********************************************************************** *) lemma lemma3_1: "\\yzY \ F(y). f(z)<=Y) \ (\! Y. Y \ F(y) \ f(z)<=Y); \i j. i\j \ F(i) \ F(j); j\i; i F(i); f(z)<=V; W \ F(j); f(z)<=W\ \ V = W" apply (erule asm_rl allE impE)+ apply (drule subsetD, assumption, blast) done lemma lemma3: "\\yzY \ F(y). f(z)<=Y) \ (\! Y. Y \ F(y) \ f(z)<=Y); \i j. i\j \ F(i) \ F(j); i F(i); f(z)<=V; W \ F(j); f(z)<=W\ \ V = W" apply (rule_tac j=j in Ord_linear_le [OF lt_Ord lt_Ord], assumption+) apply (erule lemma3_1 [symmetric], assumption+) apply (erule lemma3_1, assumption+) done lemma lemma4: "\\y X \ (\xY \ F(y). h(x) \ Y) \ (\! Y. Y \ F(y) \ h(x) \ Y)); x < a\ \ \yzY \ F(y). h(z) \ Y) \ (\! Y. Y \ F(y) \ h(z) \ Y)" apply (intro oallI impI) apply (drule ospec, assumption, clarify) apply (blast elim!: oallE ) done lemma lemma5: "\\y X \ (\xY \ F(y). h(x) \ Y) \ (\! Y. Y \ F(y) \ h(x) \ Y)); x < a; Limit(x); \i j. i\j \ F(i) \ F(j)\ \ (\x X \ (\xax \ \x x) \ (\! Y. Y \ (\x h(xa) \ Y))" apply (rule conjI) apply (rule subsetI) apply (erule OUN_E) apply (drule ospec, assumption, fast) apply (drule lemma4, assumption) apply (rule oallI) apply (rule impI) apply (erule disjE) apply (frule ospec, erule Limit_has_succ, assumption) apply (drule_tac A = a and x = xa in ospec, assumption) apply (erule impE, rule le_refl [THEN disjI1], erule lt_Ord) apply (blast intro: lemma3 Limit_has_succ) apply (blast intro: lemma3) done (* ********************************************************************** *) (* case of successor ordinal *) (* ********************************************************************** *) (* First quite complicated proof of the fact used in the recursive construction of the family T_gamma (WO2 \ AC16(k #+ m, k)) - the fact that at any stage gamma the set (s - \(...) - k_gamma) is equipollent to s (Rubin \ Rubin page 15). *) (* ********************************************************************** *) (* dbl_Diff_eqpoll_Card *) (* ********************************************************************** *) lemma dbl_Diff_eqpoll_Card: "\A\a; Card(a); \Finite(a); B\a; C\a\ \ A - B - C\a" by (blast intro: Diff_lesspoll_eqpoll_Card) (* ********************************************************************** *) (* Case of finite ordinals *) (* ********************************************************************** *) lemma Finite_lesspoll_infinite_Ord: "\Finite(X); \Finite(a); Ord(a)\ \ X\a" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (rule conjI) apply (drule nat_le_infinite_Ord [THEN le_imp_lepoll], assumption) -apply (unfold Finite_def) + unfolding Finite_def apply (blast intro: leI [THEN le_imp_subset, THEN subset_imp_lepoll] ltI eqpoll_imp_lepoll lepoll_trans) apply (blast intro: eqpoll_sym [THEN eqpoll_trans]) done lemma Union_lesspoll: "\\x \ X. x \ n \ x \ T; well_ord(T, R); X \ b; bFinite(a); Card(a); n \ nat\ \ \(X)\a" apply (case_tac "Finite (X)") apply (blast intro: Card_is_Ord Finite_lesspoll_infinite_Ord lepoll_nat_imp_Finite Finite_Union) apply (drule lepoll_imp_ex_le_eqpoll) apply (erule lt_Ord) apply (elim exE conjE) apply (frule eqpoll_imp_lepoll [THEN lepoll_infinite], assumption) apply (erule eqpoll_sym [THEN eqpoll_def [THEN def_imp_iff, THEN iffD1], THEN exE]) apply (frule bij_is_surj [THEN surj_image_eq]) apply (drule image_fun [OF bij_is_fun subset_refl]) apply (drule sym [THEN trans], assumption) apply (blast intro: lt_Ord UN_lepoll lt_Card_imp_lesspoll lt_trans1 lesspoll_trans1) done (* ********************************************************************** *) (* recfunAC16_lepoll_index *) (* ********************************************************************** *) lemma Un_sing_eq_cons: "A \ {a} = cons(a, A)" by fast lemma Un_lepoll_succ: "A \ B \ A \ {a} \ succ(B)" apply (simp add: Un_sing_eq_cons succ_def) apply (blast elim!: mem_irrefl intro: cons_lepoll_cong) done lemma Diff_UN_succ_empty: "Ord(a) \ F(a) - (\b F(a) \ X - (\b X" by blast lemma recfunAC16_Diff_lepoll_1: "Ord(x) \ recfunAC16(f, g, x, a) - (\i 1" apply (erule Ord_cases) apply (simp add: recfunAC16_0 empty_subsetI [THEN subset_imp_lepoll]) (*Limit case*) prefer 2 apply (simp add: recfunAC16_Limit Diff_cancel empty_subsetI [THEN subset_imp_lepoll]) (*succ case*) apply (simp add: recfunAC16_succ Diff_UN_succ_empty [of _ "\j. recfunAC16(f,g,j,a)"] empty_subsetI [THEN subset_imp_lepoll]) apply (best intro: Diff_UN_succ_subset [THEN subset_imp_lepoll] singleton_eqpoll_1 [THEN eqpoll_imp_lepoll] lepoll_trans) done lemma in_Least_Diff: "\z \ F(x); Ord(x)\ \ z \ F(\ i. z \ F(i)) - (\j<(\ i. z \ F(i)). F(j))" by (fast elim: less_LeastE elim!: LeastI) lemma Least_eq_imp_ex: "\(\ i. w \ F(i)) = (\ i. z \ F(i)); w \ (\i (\i \ \b (F(b) - (\c z \ (F(b) - (\cA \ 1; a \ A; b \ A\ \ a=b" by (fast dest!: lepoll_1_is_sing) lemma UN_lepoll_index: "\\ij 1; Limit(a)\ \ (\x a" apply (rule lepoll_def [THEN def_imp_iff [THEN iffD2]]) apply (rule_tac x = "\z \ (\x i. z \ F (i) " in exI) -apply (unfold inj_def) + unfolding inj_def apply (rule CollectI) apply (rule lam_type) apply (erule OUN_E) apply (erule Least_in_Ord) apply (erule ltD) apply (erule lt_Ord2) apply (intro ballI) apply (simp (no_asm_simp)) apply (rule impI) apply (drule Least_eq_imp_ex, assumption+) apply (fast elim!: two_in_lepoll_1) done lemma recfunAC16_lepoll_index: "Ord(y) \ recfunAC16(f, h, y, a) \ y" apply (erule trans_induct3) (*0 case*) apply (simp (no_asm_simp) add: recfunAC16_0 lepoll_refl) (*succ case*) apply (simp (no_asm_simp) add: recfunAC16_succ) apply (blast dest!: succI1 [THEN rev_bspec] intro: subset_succI [THEN subset_imp_lepoll] Un_lepoll_succ lepoll_trans) apply (simp (no_asm_simp) add: recfunAC16_Limit) apply (blast intro: lt_Ord [THEN recfunAC16_Diff_lepoll_1] UN_lepoll_index) done lemma Union_recfunAC16_lesspoll: "\recfunAC16(f,g,y,a) \ {X \ Pow(A). X\n}; A\a; yFinite(a); Card(a); n \ nat\ \ \(recfunAC16(f,g,y,a))\a" apply (erule eqpoll_def [THEN def_imp_iff, THEN iffD1, THEN exE]) apply (rule_tac T=A in Union_lesspoll, simp_all) apply (blast intro!: eqpoll_imp_lepoll) apply (blast intro: bij_is_inj Card_is_Ord [THEN well_ord_Memrel] well_ord_rvimage) apply (erule lt_Ord [THEN recfunAC16_lepoll_index]) done lemma dbl_Diff_eqpoll: "\recfunAC16(f, h, y, a) \ {X \ Pow(A) . X\succ(k #+ m)}; Card(a); \ Finite(a); A\a; k \ nat; y bij(a, {Y \ Pow(A). Y\succ(k)})\ \ A - \(recfunAC16(f, h, y, a)) - h`y\a" apply (rule dbl_Diff_eqpoll_Card, simp_all) apply (simp add: Union_recfunAC16_lesspoll) apply (rule Finite_lesspoll_infinite_Ord) apply (rule Finite_def [THEN def_imp_iff, THEN iffD2]) apply (blast dest: ltD bij_is_fun [THEN apply_type], assumption) apply (blast intro: Card_is_Ord) done (* back to the proof *) lemmas disj_Un_eqpoll_nat_sum = eqpoll_trans [THEN eqpoll_trans, OF disj_Un_eqpoll_sum sum_eqpoll_cong nat_sum_eqpoll_sum] lemma Un_in_Collect: "\x \ Pow(A - B - h`i); x\m; h \ bij(a, {x \ Pow(A) . x\k}); i nat; m \ nat\ \ h ` i \ x \ {x \ Pow(A) . x\k #+ m}" by (blast intro: disj_Un_eqpoll_nat_sum dest: ltD bij_is_fun [THEN apply_type]) (* ********************************************************************** *) (* Lemmas simplifying assumptions *) (* ********************************************************************** *) lemma lemma6: "\\y (\x Q(x,y)); succ(j) \ F(j)<=X \ (\x Q(x,j))" by (blast intro!: lt_Ord succI1 [THEN ltI, THEN lt_Ord, THEN le_refl]) lemma lemma7: "\\x Q(x,j); succ(j) \ P(j,j) \ (\xj | P(x,j) \ Q(x,j))" by (fast elim!: leE) (* ********************************************************************** *) (* Lemmas needed to prove ex_next_set, which means that for any successor *) (* ordinal there is a set satisfying certain properties *) (* ********************************************************************** *) lemma ex_subset_eqpoll: "\A\a; \ Finite(a); Ord(a); m \ nat\ \ \X \ Pow(A). X\m" apply (rule lepoll_imp_eqpoll_subset [of m A, THEN exE]) apply (rule lepoll_trans, rule leI [THEN le_imp_lepoll]) apply (blast intro: lt_trans2 [OF ltI nat_le_infinite_Ord] Ord_nat) apply (erule eqpoll_sym [THEN eqpoll_imp_lepoll]) apply (fast elim!: eqpoll_sym) done lemma subset_Un_disjoint: "\A \ B \ C; A \ C = 0\ \ A \ B" by blast lemma Int_empty: "\X \ Pow(A - \(B) -C); T \ B; F \ T\ \ F \ X = 0" by blast (* ********************************************************************** *) (* equipollent subset (and finite) is the whole set *) (* ********************************************************************** *) lemma subset_imp_eq_lemma: "m \ nat \ \A B. A \ B \ m \ A \ B \ m \ A=B" apply (induct_tac "m") apply (fast dest!: lepoll_0_is_0) apply (intro allI impI) apply (elim conjE) apply (rule succ_lepoll_imp_not_empty [THEN not_emptyE], assumption) apply (frule subsetD [THEN Diff_sing_lepoll], assumption+) apply (frule lepoll_Diff_sing) apply (erule allE impE)+ apply (rule conjI) prefer 2 apply fast apply fast apply (blast elim: equalityE) done lemma subset_imp_eq: "\A \ B; m \ A; B \ m; m \ nat\ \ A=B" by (blast dest!: subset_imp_eq_lemma) lemma bij_imp_arg_eq: "\f \ bij(a, {Y \ X. Y\succ(k)}); k \ nat; f`b \ f`y; b \ b=y" apply (drule subset_imp_eq) apply (erule_tac [3] nat_succI) apply (unfold bij_def inj_def) apply (blast intro: eqpoll_sym eqpoll_imp_lepoll dest: ltD apply_type)+ done lemma ex_next_set: "\recfunAC16(f, h, y, a) \ {X \ Pow(A) . X\succ(k #+ m)}; Card(a); \ Finite(a); A\a; k \ nat; m \ nat; y bij(a, {Y \ Pow(A). Y\succ(k)}); \ (\Y \ recfunAC16(f, h, y, a). h`y \ Y)\ \ \X \ {Y \ Pow(A). Y\succ(k #+ m)}. h`y \ X \ (\b X \ (\T \ recfunAC16(f, h, y, a). \ h`b \ T))" apply (erule_tac m1=m in dbl_Diff_eqpoll [THEN ex_subset_eqpoll, THEN bexE], assumption+) apply (erule Card_is_Ord, assumption) apply (frule Un_in_Collect, (erule asm_rl nat_succI)+) apply (erule CollectE) apply (rule rev_bexI, simp) apply (rule conjI, blast) apply (intro ballI impI oallI notI) apply (drule subset_Un_disjoint, rule Int_empty, assumption+) apply (blast dest: bij_imp_arg_eq) done (* ********************************************************************** *) (* Lemma ex_next_Ord states that for any successor *) (* ordinal there is a number of the set satisfying certain properties *) (* ********************************************************************** *) lemma ex_next_Ord: "\recfunAC16(f, h, y, a) \ {X \ Pow(A) . X\succ(k #+ m)}; Card(a); \ Finite(a); A\a; k \ nat; m \ nat; y bij(a, {Y \ Pow(A). Y\succ(k)}); f \ bij(a, {Y \ Pow(A). Y\succ(k #+ m)}); \ (\Y \ recfunAC16(f, h, y, a). h`y \ Y)\ \ \c f`c \ (\b f`c \ (\T \ recfunAC16(f, h, y, a). \ h`b \ T))" apply (drule ex_next_set, assumption+) apply (erule bexE) apply (rule_tac x="converse(f)`X" in oexI) apply (simp add: right_inverse_bij) apply (blast intro: bij_converse_bij bij_is_fun [THEN apply_type] ltI Card_is_Ord) done (* ********************************************************************** *) (* Lemma simplifying assumptions *) (* ********************************************************************** *) lemma lemma8: "\\xxa \ F(j). P(x, xa)) \ (\! Y. Y \ F(j) \ P(x, Y)); F(j) \ X; L \ X; P(j, L) \ (\x (\xa \ F(j). \P(x, xa)))\ \ F(j) \ {L} \ X \ (\xj | (\xa \ (F(j) \ {L}). P(x, xa)) \ (\! Y. Y \ (F(j) \ {L}) \ P(x, Y)))" apply (rule conjI) apply (fast intro!: singleton_subsetI) apply (rule oallI) apply (blast elim!: leE oallE) done (* ********************************************************************** *) (* The main part of the proof: inductive proof of the property of T_gamma *) (* lemma main_induct *) (* ********************************************************************** *) lemma main_induct: "\b < a; f \ bij(a, {Y \ Pow(A) . Y\succ(k #+ m)}); h \ bij(a, {Y \ Pow(A) . Y\succ(k)}); \Finite(a); Card(a); A\a; k \ nat; m \ nat\ \ recfunAC16(f, h, b, a) \ {X \ Pow(A) . X\succ(k #+ m)} \ (\xY \ recfunAC16(f, h, b, a). h ` x \ Y) \ (\! Y. Y \ recfunAC16(f, h, b, a) \ h ` x \ Y))" apply (erule lt_induct) apply (frule lt_Ord) apply (erule Ord_cases) (* case 0 *) apply (simp add: recfunAC16_0) (* case Limit *) prefer 2 apply (simp add: recfunAC16_Limit) apply (rule lemma5, assumption+) apply (blast dest!: recfunAC16_mono) (* case succ *) apply clarify apply (erule lemma6 [THEN conjE], assumption) apply (simp (no_asm_simp) split del: split_if add: recfunAC16_succ) apply (rule conjI [THEN split_if [THEN iffD2]]) apply (simp, erule lemma7, assumption) apply (rule impI) apply (rule ex_next_Ord [THEN oexE], assumption+, rule le_refl [THEN lt_trans], assumption+) apply (erule lemma8, assumption) apply (rule bij_is_fun [THEN apply_type], assumption) apply (erule Least_le [THEN lt_trans2, THEN ltD]) apply (erule lt_Ord) apply (erule succ_leI) apply (erule LeastI) apply (erule lt_Ord) done (* ********************************************************************** *) (* Lemma to simplify the inductive proof *) (* - the desired property is a consequence of the inductive assumption *) (* ********************************************************************** *) lemma lemma_simp_induct: "\\b. b F(b) \ S \ (\xY \ F(b). f`x \ Y)) \ (\! Y. Y \ F(b) \ f`x \ Y)); f \ a->f``(a); Limit(a); \i j. i\j \ F(i) \ F(j)\ \ (\j S \ (\x \ f``a. \! Y. Y \ (\j x \ Y)" apply (rule conjI) apply (rule subsetI) apply (erule OUN_E, blast) apply (rule ballI) apply (erule imageE) apply (drule ltI, erule Limit_is_Ord) apply (drule Limit_has_succ, assumption) apply (frule_tac x1="succ(xa)" in spec [THEN mp], assumption) apply (erule conjE) apply (drule ospec) (** LEVEL 10 **) apply (erule leI [THEN succ_leE]) apply (erule impE) apply (fast elim!: leI [THEN succ_leE, THEN lt_Ord, THEN le_refl]) apply (drule apply_equality, assumption) apply (elim conjE ex1E) (** LEVEL 15 **) apply (rule ex1I, blast) apply (elim conjE OUN_E) apply (erule_tac i="succ(xa)" and j=aa in Ord_linear_le [OF lt_Ord lt_Ord], assumption) prefer 2 apply (drule spec [THEN spec, THEN mp, THEN subsetD], assumption+, blast) (** LEVEL 20 **) apply (drule_tac x1=aa in spec [THEN mp], assumption) apply (frule succ_leE) apply (drule spec [THEN spec, THEN mp, THEN subsetD], assumption+, blast) done (* ********************************************************************** *) (* The target theorem *) (* ********************************************************************** *) theorem WO2_AC16: "\WO2; 0 nat; m \ nat\ \ AC16(k #+ m,k)" -apply (unfold AC16_def) + unfolding AC16_def apply (rule allI) apply (rule impI) apply (frule WO2_infinite_subsets_eqpoll_X, assumption+) apply (frule_tac n="k #+ m" in WO2_infinite_subsets_eqpoll_X, simp, simp) apply (frule WO2_imp_ex_Card) apply (elim exE conjE) apply (drule eqpoll_trans [THEN eqpoll_sym, THEN eqpoll_def [THEN def_imp_iff, THEN iffD1]], assumption) apply (drule eqpoll_trans [THEN eqpoll_sym, THEN eqpoll_def [THEN def_imp_iff, THEN iffD1]], assumption+) apply (elim exE) apply (rename_tac h) apply (rule_tac x = "\j WO1. Every proof (except WO6 \ WO1 and WO1 \ WO2) are described as "clear" by Rubin \ Rubin (page 2). They refer reader to a book by Gödel to see the proof WO1 \ WO2. Fortunately order types made this proof also very easy. *) theory WO6_WO1 imports Cardinal_aux begin (* Auxiliary definitions used in proof *) definition NN :: "i \ i" where "NN(y) \ {m \ nat. \a. \f. Ord(a) \ domain(f)=a \ (\b (\b m)}" definition uu :: "[i, i, i, i] \ i" where "uu(f, beta, gamma, delta) \ (f`beta * f`gamma) \ f`delta" (** Definitions for case 1 **) definition vv1 :: "[i, i, i] \ i" where "vv1(f,m,b) \ let g = \ g. (\d. Ord(d) \ (domain(uu(f,b,g,d)) \ 0 \ domain(uu(f,b,g,d)) \ m)); d = \ d. domain(uu(f,b,g,d)) \ 0 \ domain(uu(f,b,g,d)) \ m in if f`b \ 0 then domain(uu(f,b,g,d)) else 0" definition ww1 :: "[i, i, i] \ i" where "ww1(f,m,b) \ f`b - vv1(f,m,b)" definition gg1 :: "[i, i, i] \ i" where "gg1(f,a,m) \ \b \ a++a. if b i" where "vv2(f,b,g,s) \ if f`g \ 0 then {uu(f, b, g, \ d. uu(f,b,g,d) \ 0)`s} else 0" definition ww2 :: "[i, i, i, i] \ i" where "ww2(f,b,g,s) \ f`g - vv2(f,b,g,s)" definition gg2 :: "[i, i, i, i] \ i" where "gg2(f,a,b,s) \ \g \ a++a. if g WO3" by (unfold WO2_def WO3_def, fast) (* ********************************************************************** *) lemma WO3_WO1: "WO3 \ WO1" apply (unfold eqpoll_def WO1_def WO3_def) apply (intro allI) apply (drule_tac x=A in spec) apply (blast intro: bij_is_inj well_ord_rvimage well_ord_Memrel [THEN well_ord_subset]) done (* ********************************************************************** *) lemma WO1_WO2: "WO1 \ WO2" apply (unfold eqpoll_def WO1_def WO2_def) apply (blast intro!: Ord_ordertype ordermap_bij) done (* ********************************************************************** *) lemma lam_sets: "f \ A->B \ (\x \ A. {f`x}): A -> {{b}. b \ B}" by (fast intro!: lam_type apply_type) lemma surj_imp_eq': "f \ surj(A,B) \ (\a \ A. {f`a}) = B" -apply (unfold surj_def) + unfolding surj_def apply (fast elim!: apply_type) done lemma surj_imp_eq: "\f \ surj(A,B); Ord(A)\ \ (\a WO4(1)" apply (unfold WO1_def WO4_def) apply (rule allI) apply (erule_tac x = A in allE) apply (erule exE) apply (intro exI conjI) apply (erule Ord_ordertype) apply (erule ordermap_bij [THEN bij_converse_bij, THEN bij_is_fun, THEN lam_sets, THEN domain_of_fun]) apply (simp_all add: singleton_eqpoll_1 eqpoll_imp_lepoll Ord_ordertype ordermap_bij [THEN bij_converse_bij, THEN bij_is_surj, THEN surj_imp_eq] ltD) done (* ********************************************************************** *) lemma WO4_mono: "\m\n; WO4(m)\ \ WO4(n)" -apply (unfold WO4_def) + unfolding WO4_def apply (blast dest!: spec intro: lepoll_trans [OF _ le_imp_lepoll]) done (* ********************************************************************** *) lemma WO4_WO5: "\m \ nat; 1\m; WO4(m)\ \ WO5" by (unfold WO4_def WO5_def, blast) (* ********************************************************************** *) lemma WO5_WO6: "WO5 \ WO6" by (unfold WO4_def WO5_def WO6_def, blast) (* ********************************************************************** The proof of "WO6 \ WO1". Simplified by L C Paulson. From the book "Equivalents of the Axiom of Choice" by Rubin \ Rubin, pages 2-5 ************************************************************************* *) lemma lt_oadd_odiff_disj: "\k < i++j; Ord(i); Ord(j)\ \ k < i | (\ k k = i ++ (k--i) \ (k--i) f`b" by (unfold uu_def, blast) lemma quant_domain_uu_lepoll_m: "\b m \ \bgd m" by (blast intro: domain_uu_subset [THEN subset_imp_lepoll] lepoll_trans) lemma uu_subset1: "uu(f,b,g,d) \ f`b * f`g" by (unfold uu_def, blast) lemma uu_subset2: "uu(f,b,g,d) \ f`d" by (unfold uu_def, blast) lemma uu_lepoll_m: "\\b m; d \ uu(f,b,g,d) \ m" by (blast intro: uu_subset2 [THEN subset_imp_lepoll] lepoll_trans) (* ********************************************************************** *) (* Two cases for lemma ii *) (* ********************************************************************** *) lemma cases: "\bgd m \ (\b 0 \ (\gd 0 \ u(f,b,g,d) \ m)) | (\b 0 \ (\gd 0 \ u(f,b,g,d) \ m))" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (blast del: equalityI) done (* ********************************************************************** *) (* Lemmas used in both cases *) (* ********************************************************************** *) lemma UN_oadd: "Ord(a) \ (\bb C(a++b))" by (blast intro: ltI lt_oadd1 oadd_lt_mono2 dest!: lt_oadd_disj) (* ********************************************************************** *) (* Case 1: lemmas *) (* ********************************************************************** *) lemma vv1_subset: "vv1(f,m,b) \ f`b" by (simp add: vv1_def Let_def domain_uu_subset) (* ********************************************************************** *) (* Case 1: Union of images is the whole "y" *) (* ********************************************************************** *) lemma UN_gg1_eq: "\Ord(a); m \ nat\ \ (\bbP(a, b); Ord(a); Ord(b); Least_a = (\ a. \x. Ord(x) \ P(a, x))\ \ P(Least_a, \ b. P(Least_a, b))" apply (erule ssubst) apply (rule_tac Q = "\z. P (z, \ b. P (z, b))" in LeastI2) apply (fast elim!: LeastI)+ done lemmas nested_Least_instance = nested_LeastI [of "\g d. domain(uu(f,b,g,d)) \ 0 \ domain(uu(f,b,g,d)) \ m"] for f b m lemma gg1_lepoll_m: "\Ord(a); m \ nat; \b0 \ (\gd 0 \ domain(uu(f,b,g,d)) \ m); \b succ(m); b \ gg1(f,a,m)`b \ m" apply (simp add: gg1_def empty_lepollI) apply (safe dest!: lt_oadd_odiff_disj) (*Case b show vv1(f,m,b) \ m *) apply (simp add: vv1_def Let_def empty_lepollI) apply (fast intro: nested_Least_instance [THEN conjunct2] elim!: lt_Ord) (*Case a\b \ show ww1(f,m,b--a) \ m *) apply (simp add: ww1_def empty_lepollI) apply (case_tac "f` (b--a) = 0", simp add: empty_lepollI) apply (rule Diff_lepoll, blast) apply (rule vv1_subset) apply (drule ospec [THEN mp], assumption+) apply (elim oexE conjE) apply (simp add: vv1_def Let_def lt_Ord nested_Least_instance [THEN conjunct1]) done (* ********************************************************************** *) (* Case 2: lemmas *) (* ********************************************************************** *) (* ********************************************************************** *) (* Case 2: vv2_subset *) (* ********************************************************************** *) lemma ex_d_uu_not_empty: "\b0; f`g\0; y*y \ y; (\b \ \d 0" by (unfold uu_def, blast) lemma uu_not_empty: "\b0; f`g\0; y*y \ y; (\b \ uu(f,b,g,\ d. (uu(f,b,g,d) \ 0)) \ 0" apply (drule ex_d_uu_not_empty, assumption+) apply (fast elim!: LeastI lt_Ord) done lemma not_empty_rel_imp_domain: "\r \ A*B; r\0\ \ domain(r)\0" by blast lemma Least_uu_not_empty_lt_a: "\b0; f`g\0; y*y \ y; (\b \ (\ d. uu(f,b,g,d) \ 0) < a" apply (erule ex_d_uu_not_empty [THEN oexE], assumption+) apply (blast intro: Least_le [THEN lt_trans1] lt_Ord) done lemma subset_Diff_sing: "\B \ A; a\B\ \ B \ A-{a}" by blast (*Could this be proved more directly?*) lemma supset_lepoll_imp_eq: "\A \ m; m \ B; B \ A; m \ nat\ \ A=B" apply (erule natE) apply (fast dest!: lepoll_0_is_0 intro!: equalityI) apply (safe intro!: equalityI) apply (rule ccontr) apply (rule succ_lepoll_natE) apply (erule lepoll_trans) apply (rule lepoll_trans) apply (erule subset_Diff_sing [THEN subset_imp_lepoll], assumption) apply (rule Diff_sing_lepoll, assumption+) done lemma uu_Least_is_fun: "\\gd0 \ domain(uu(f, b, g, d)) \ succ(m); \b succ(m); y*y \ y; (\b0; f`g\0; m \ nat; s \ f`b\ \ uu(f, b, g, \ d. uu(f,b,g,d)\0) \ f`b -> f`g" apply (drule_tac x2=g in ospec [THEN ospec, THEN mp]) apply (rule_tac [3] not_empty_rel_imp_domain [OF uu_subset1 uu_not_empty]) apply (rule_tac [2] Least_uu_not_empty_lt_a, assumption+) apply (rule rel_is_fun) apply (erule eqpoll_sym [THEN eqpoll_imp_lepoll]) apply (erule uu_lepoll_m) apply (rule Least_uu_not_empty_lt_a, assumption+) apply (rule uu_subset1) apply (rule supset_lepoll_imp_eq [OF _ eqpoll_sym [THEN eqpoll_imp_lepoll]]) apply (fast intro!: domain_uu_subset)+ done lemma vv2_subset: "\\gd0 \ domain(uu(f, b, g, d)) \ succ(m); \b succ(m); y*y \ y; (\b nat; s \ f`b\ \ vv2(f,b,g,s) \ f`g" apply (simp add: vv2_def) apply (blast intro: uu_Least_is_fun [THEN apply_type]) done (* ********************************************************************** *) (* Case 2: Union of images is the whole "y" *) (* ********************************************************************** *) lemma UN_gg2_eq: "\\gd 0 \ domain(uu(f,b,g,d)) \ succ(m); \b succ(m); y*y \ y; (\b nat; s \ f`b; b \ (\gm \ nat; m\0\ \ vv2(f,b,g,s) \ m" -apply (unfold vv2_def) + unfolding vv2_def apply (simp add: empty_lepollI) apply (fast dest!: le_imp_subset [THEN subset_imp_lepoll, THEN lepoll_0_is_0] intro!: singleton_eqpoll_1 [THEN eqpoll_imp_lepoll, THEN lepoll_trans] not_lt_imp_le [THEN le_imp_subset, THEN subset_imp_lepoll] nat_into_Ord nat_1I) done lemma ww2_lepoll: "\\b succ(m); g nat; vv2(f,b,g,d) \ f`g\ \ ww2(f,b,g,d) \ m" -apply (unfold ww2_def) + unfolding ww2_def apply (case_tac "f`g = 0") apply (simp add: empty_lepollI) apply (drule ospec, assumption) apply (rule Diff_lepoll, assumption+) apply (simp add: vv2_def not_emptyI) done lemma gg2_lepoll_m: "\\gd 0 \ domain(uu(f,b,g,d)) \ succ(m); \b succ(m); y*y \ y; (\b f`b; m \ nat; m\ 0; g \ gg2(f,a,b,s) ` g \ m" apply (simp add: gg2_def empty_lepollI) apply (safe elim!: lt_Ord2 dest!: lt_oadd_odiff_disj) apply (simp add: vv2_lepoll) apply (simp add: ww2_lepoll vv2_subset) done (* ********************************************************************** *) (* lemma ii *) (* ********************************************************************** *) lemma lemma_ii: "\succ(m) \ NN(y); y*y \ y; m \ nat; m\0\ \ m \ NN(y)" -apply (unfold NN_def) + unfolding NN_def apply (elim CollectE exE conjE) apply (rule quant_domain_uu_lepoll_m [THEN cases, THEN disjE], assumption) (* case 1 *) apply (simp add: lesspoll_succ_iff) apply (rule_tac x = "a++a" in exI) apply (fast intro!: Ord_oadd domain_gg1 UN_gg1_eq gg1_lepoll_m) (* case 2 *) apply (elim oexE conjE) apply (rule_tac A = "f`B" for B in not_emptyE, assumption) apply (rule CollectI) apply (erule succ_natD) apply (rule_tac x = "a++a" in exI) apply (rule_tac x = "gg2 (f,a,b,x) " in exI) apply (simp add: Ord_oadd domain_gg2 UN_gg2_eq gg2_lepoll_m) done (* ********************************************************************** *) (* lemma iv - p. 4: *) (* For every set x there is a set y such that x \ (y * y) \ y *) (* ********************************************************************** *) (* The leading \-quantifier looks odd but makes the proofs shorter (used only in the following two lemmas) *) lemma z_n_subset_z_succ_n: "\n \ nat. rec(n, x, \k r. r \ r*r) \ rec(succ(n), x, \k r. r \ r*r)" by (fast intro: rec_succ [THEN ssubst]) lemma le_subsets: "\\n \ nat. f(n)<=f(succ(n)); n\m; n \ nat; m \ nat\ \ f(n)<=f(m)" apply (erule_tac P = "n\m" in rev_mp) apply (rule_tac P = "\z. n\z \ f (n) \ f (z) " in nat_induct) apply (auto simp add: le_iff) done lemma le_imp_rec_subset: "\n\m; m \ nat\ \ rec(n, x, \k r. r \ r*r) \ rec(m, x, \k r. r \ r*r)" apply (rule z_n_subset_z_succ_n [THEN le_subsets]) apply (blast intro: lt_nat_in_nat)+ done lemma lemma_iv: "\y. x \ y*y \ y" apply (rule_tac x = "\n \ nat. rec (n, x, \k r. r \ r*r) " in exI) apply safe apply (rule nat_0I [THEN UN_I], simp) apply (rule_tac a = "succ (n \ na) " in UN_I) apply (erule Un_nat_type [THEN nat_succI], assumption) apply (auto intro: le_imp_rec_subset [THEN subsetD] intro!: Un_upper1_le Un_upper2_le Un_nat_type elim!: nat_into_Ord) done (* ********************************************************************** *) (* Rubin \ Rubin wrote, *) (* "It follows from (ii) and mathematical induction that if y*y \ y then *) (* y can be well-ordered" *) (* In fact we have to prove *) (* * WO6 \ NN(y) \ 0 *) (* * reverse induction which lets us infer that 1 \ NN(y) *) (* * 1 \ NN(y) \ y can be well-ordered *) (* ********************************************************************** *) (* ********************************************************************** *) (* WO6 \ NN(y) \ 0 *) (* ********************************************************************** *) lemma WO6_imp_NN_not_empty: "WO6 \ NN(y) \ 0" by (unfold WO6_def NN_def, clarify, blast) (* ********************************************************************** *) (* 1 \ NN(y) \ y can be well-ordered *) (* ********************************************************************** *) lemma lemma1: "\(\b y; \b 1; Ord(a)\ \ \c(\b y; \b 1; Ord(a)\ \ f` (\ i. f`i = {x}) = {x}" apply (drule lemma1, assumption+) apply (fast elim!: lt_Ord intro: LeastI) done lemma NN_imp_ex_inj: "1 \ NN(y) \ \a f. Ord(a) \ f \ inj(y, a)" -apply (unfold NN_def) + unfolding NN_def apply (elim CollectE exE conjE) apply (rule_tac x = a in exI) apply (rule_tac x = "\x \ y. \ i. f`i = {x}" in exI) apply (rule conjI, assumption) apply (rule_tac d = "\i. THE x. x \ f`i" in lam_injective) apply (drule lemma1, assumption+) apply (fast elim!: Least_le [THEN lt_trans1, THEN ltD] lt_Ord) apply (rule lemma2 [THEN ssubst], assumption+, blast) done lemma y_well_ord: "\y*y \ y; 1 \ NN(y)\ \ \r. well_ord(y, r)" apply (drule NN_imp_ex_inj) apply (fast elim!: well_ord_rvimage [OF _ well_ord_Memrel]) done (* ********************************************************************** *) (* reverse induction which lets us infer that 1 \ NN(y) *) (* ********************************************************************** *) lemma rev_induct_lemma [rule_format]: "\n \ nat; \m. \m \ nat; m\0; P(succ(m))\ \ P(m)\ \ n\0 \ P(n) \ P(1)" by (erule nat_induct, blast+) lemma rev_induct: "\n \ nat; P(n); n\0; \m. \m \ nat; m\0; P(succ(m))\ \ P(m)\ \ P(1)" by (rule rev_induct_lemma, blast+) lemma NN_into_nat: "n \ NN(y) \ n \ nat" by (simp add: NN_def) lemma lemma3: "\n \ NN(y); y*y \ y; n\0\ \ 1 \ NN(y)" apply (rule rev_induct [OF NN_into_nat], assumption+) apply (rule lemma_ii, assumption+) done (* ********************************************************************** *) (* Main theorem "WO6 \ WO1" *) (* ********************************************************************** *) (* another helpful lemma *) lemma NN_y_0: "0 \ NN(y) \ y=0" -apply (unfold NN_def) + unfolding NN_def apply (fast intro!: equalityI dest!: lepoll_0_is_0 elim: subst) done lemma WO6_imp_WO1: "WO6 \ WO1" -apply (unfold WO1_def) + unfolding WO1_def apply (rule allI) apply (case_tac "A=0") apply (fast intro!: well_ord_Memrel nat_0I [THEN nat_into_Ord]) apply (rule_tac x = A in lemma_iv [elim_format]) apply (erule exE) apply (drule WO6_imp_NN_not_empty) apply (erule Un_subset_iff [THEN iffD1, THEN conjE]) apply (erule_tac A = "NN (y) " in not_emptyE) apply (frule y_well_ord) apply (fast intro!: lemma3 dest!: NN_y_0 elim!: not_emptyE) apply (fast elim: well_ord_subset) done end diff --git a/src/ZF/Arith.thy b/src/ZF/Arith.thy --- a/src/ZF/Arith.thy +++ b/src/ZF/Arith.thy @@ -1,549 +1,549 @@ (* Title: ZF/Arith.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1992 University of Cambridge *) (*"Difference" is subtraction of natural numbers. There are no negative numbers; we have m #- n = 0 iff m<=n and m #- n = succ(k) iff m>n. Also, rec(m, 0, \z w.z) is pred(m). *) section\Arithmetic Operators and Their Definitions\ theory Arith imports Univ begin text\Proofs about elementary arithmetic: addition, multiplication, etc.\ definition pred :: "i\i" (*inverse of succ*) where "pred(y) \ nat_case(0, \x. x, y)" definition natify :: "i\i" (*coerces non-nats to nats*) where "natify \ Vrecursor(\f a. if a = succ(pred(a)) then succ(f`pred(a)) else 0)" consts raw_add :: "[i,i]\i" raw_diff :: "[i,i]\i" raw_mult :: "[i,i]\i" primrec "raw_add (0, n) = n" "raw_add (succ(m), n) = succ(raw_add(m, n))" primrec raw_diff_0: "raw_diff(m, 0) = m" raw_diff_succ: "raw_diff(m, succ(n)) = nat_case(0, \x. x, raw_diff(m, n))" primrec "raw_mult(0, n) = 0" "raw_mult(succ(m), n) = raw_add (n, raw_mult(m, n))" definition add :: "[i,i]\i" (infixl \#+\ 65) where "m #+ n \ raw_add (natify(m), natify(n))" definition diff :: "[i,i]\i" (infixl \#-\ 65) where "m #- n \ raw_diff (natify(m), natify(n))" definition mult :: "[i,i]\i" (infixl \#*\ 70) where "m #* n \ raw_mult (natify(m), natify(n))" definition raw_div :: "[i,i]\i" where "raw_div (m, n) \ transrec(m, \j f. if ji" where "raw_mod (m, n) \ transrec(m, \j f. if ji" (infixl \div\ 70) where "m div n \ raw_div (natify(m), natify(n))" definition mod :: "[i,i]\i" (infixl \mod\ 70) where "m mod n \ raw_mod (natify(m), natify(n))" declare rec_type [simp] nat_0_le [simp] lemma zero_lt_lemma: "\0 nat\ \ \j\nat. k = succ(j)" apply (erule rev_mp) apply (induct_tac "k", auto) done (* @{term"\0 < k; k \ nat; \j. \j \ nat; k = succ(j)\ \ Q\ \ Q"} *) lemmas zero_lt_natE = zero_lt_lemma [THEN bexE] subsection\\natify\, the Coercion to \<^term>\nat\\ lemma pred_succ_eq [simp]: "pred(succ(y)) = y" by (unfold pred_def, auto) lemma natify_succ: "natify(succ(x)) = succ(natify(x))" by (rule natify_def [THEN def_Vrecursor, THEN trans], auto) lemma natify_0 [simp]: "natify(0) = 0" by (rule natify_def [THEN def_Vrecursor, THEN trans], auto) lemma natify_non_succ: "\z. x \ succ(z) \ natify(x) = 0" by (rule natify_def [THEN def_Vrecursor, THEN trans], auto) lemma natify_in_nat [iff,TC]: "natify(x) \ nat" apply (rule_tac a=x in eps_induct) apply (case_tac "\z. x = succ(z)") apply (auto simp add: natify_succ natify_non_succ) done lemma natify_ident [simp]: "n \ nat \ natify(n) = n" apply (induct_tac "n") apply (auto simp add: natify_succ) done lemma natify_eqE: "\natify(x) = y; x \ nat\ \ x=y" by auto (*** Collapsing rules: to remove natify from arithmetic expressions ***) lemma natify_idem [simp]: "natify(natify(x)) = natify(x)" by simp (** Addition **) lemma add_natify1 [simp]: "natify(m) #+ n = m #+ n" by (simp add: add_def) lemma add_natify2 [simp]: "m #+ natify(n) = m #+ n" by (simp add: add_def) (** Multiplication **) lemma mult_natify1 [simp]: "natify(m) #* n = m #* n" by (simp add: mult_def) lemma mult_natify2 [simp]: "m #* natify(n) = m #* n" by (simp add: mult_def) (** Difference **) lemma diff_natify1 [simp]: "natify(m) #- n = m #- n" by (simp add: diff_def) lemma diff_natify2 [simp]: "m #- natify(n) = m #- n" by (simp add: diff_def) (** Remainder **) lemma mod_natify1 [simp]: "natify(m) mod n = m mod n" by (simp add: mod_def) lemma mod_natify2 [simp]: "m mod natify(n) = m mod n" by (simp add: mod_def) (** Quotient **) lemma div_natify1 [simp]: "natify(m) div n = m div n" by (simp add: div_def) lemma div_natify2 [simp]: "m div natify(n) = m div n" by (simp add: div_def) subsection\Typing rules\ (** Addition **) lemma raw_add_type: "\m\nat; n\nat\ \ raw_add (m, n) \ nat" by (induct_tac "m", auto) lemma add_type [iff,TC]: "m #+ n \ nat" by (simp add: add_def raw_add_type) (** Multiplication **) lemma raw_mult_type: "\m\nat; n\nat\ \ raw_mult (m, n) \ nat" apply (induct_tac "m") apply (simp_all add: raw_add_type) done lemma mult_type [iff,TC]: "m #* n \ nat" by (simp add: mult_def raw_mult_type) (** Difference **) lemma raw_diff_type: "\m\nat; n\nat\ \ raw_diff (m, n) \ nat" by (induct_tac "n", auto) lemma diff_type [iff,TC]: "m #- n \ nat" by (simp add: diff_def raw_diff_type) lemma diff_0_eq_0 [simp]: "0 #- n = 0" -apply (unfold diff_def) + unfolding diff_def apply (rule natify_in_nat [THEN nat_induct], auto) done (*Must simplify BEFORE the induction: else we get a critical pair*) lemma diff_succ_succ [simp]: "succ(m) #- succ(n) = m #- n" apply (simp add: natify_succ diff_def) apply (rule_tac x1 = n in natify_in_nat [THEN nat_induct], auto) done (*This defining property is no longer wanted*) declare raw_diff_succ [simp del] (*Natify has weakened this law, compared with the older approach*) lemma diff_0 [simp]: "m #- 0 = natify(m)" by (simp add: diff_def) lemma diff_le_self: "m\nat \ (m #- n) \ m" apply (subgoal_tac " (m #- natify (n)) \ m") apply (rule_tac [2] m = m and n = "natify (n) " in diff_induct) apply (erule_tac [6] leE) apply (simp_all add: le_iff) done subsection\Addition\ (*Natify has weakened this law, compared with the older approach*) lemma add_0_natify [simp]: "0 #+ m = natify(m)" by (simp add: add_def) lemma add_succ [simp]: "succ(m) #+ n = succ(m #+ n)" by (simp add: natify_succ add_def) lemma add_0: "m \ nat \ 0 #+ m = m" by simp (*Associative law for addition*) lemma add_assoc: "(m #+ n) #+ k = m #+ (n #+ k)" apply (subgoal_tac "(natify(m) #+ natify(n)) #+ natify(k) = natify(m) #+ (natify(n) #+ natify(k))") apply (rule_tac [2] n = "natify(m)" in nat_induct) apply auto done (*The following two lemmas are used for add_commute and sometimes elsewhere, since they are safe for rewriting.*) lemma add_0_right_natify [simp]: "m #+ 0 = natify(m)" apply (subgoal_tac "natify(m) #+ 0 = natify(m)") apply (rule_tac [2] n = "natify(m)" in nat_induct) apply auto done lemma add_succ_right [simp]: "m #+ succ(n) = succ(m #+ n)" -apply (unfold add_def) + unfolding add_def apply (rule_tac n = "natify(m) " in nat_induct) apply (auto simp add: natify_succ) done lemma add_0_right: "m \ nat \ m #+ 0 = m" by auto (*Commutative law for addition*) lemma add_commute: "m #+ n = n #+ m" apply (subgoal_tac "natify(m) #+ natify(n) = natify(n) #+ natify(m) ") apply (rule_tac [2] n = "natify(m) " in nat_induct) apply auto done (*for a/c rewriting*) lemma add_left_commute: "m#+(n#+k)=n#+(m#+k)" apply (rule add_commute [THEN trans]) apply (rule add_assoc [THEN trans]) apply (rule add_commute [THEN subst_context]) done (*Addition is an AC-operator*) lemmas add_ac = add_assoc add_commute add_left_commute (*Cancellation law on the left*) lemma raw_add_left_cancel: "\raw_add(k, m) = raw_add(k, n); k\nat\ \ m=n" apply (erule rev_mp) apply (induct_tac "k", auto) done lemma add_left_cancel_natify: "k #+ m = k #+ n \ natify(m) = natify(n)" -apply (unfold add_def) + unfolding add_def apply (drule raw_add_left_cancel, auto) done lemma add_left_cancel: "\i = j; i #+ m = j #+ n; m\nat; n\nat\ \ m = n" by (force dest!: add_left_cancel_natify) (*Thanks to Sten Agerholm*) lemma add_le_elim1_natify: "k#+m \ k#+n \ natify(m) \ natify(n)" apply (rule_tac P = "natify(k) #+m \ natify(k) #+n" in rev_mp) apply (rule_tac [2] n = "natify(k) " in nat_induct) apply auto done lemma add_le_elim1: "\k#+m \ k#+n; m \ nat; n \ nat\ \ m \ n" by (drule add_le_elim1_natify, auto) lemma add_lt_elim1_natify: "k#+m < k#+n \ natify(m) < natify(n)" apply (rule_tac P = "natify(k) #+m < natify(k) #+n" in rev_mp) apply (rule_tac [2] n = "natify(k) " in nat_induct) apply auto done lemma add_lt_elim1: "\k#+m < k#+n; m \ nat; n \ nat\ \ m < n" by (drule add_lt_elim1_natify, auto) lemma zero_less_add: "\n \ nat; m \ nat\ \ 0 < m #+ n \ (0Monotonicity of Addition\ (*strict, in 1st argument; proof is by rule induction on 'less than'. Still need j\nat, for consider j = omega. Then we can have inat, but natify(j)=0, so the conclusion fails.*) lemma add_lt_mono1: "\inat\ \ i#+k < j#+k" apply (frule lt_nat_in_nat, assumption) apply (erule succ_lt_induct) apply (simp_all add: leI) done text\strict, in second argument\ lemma add_lt_mono2: "\inat\ \ k#+i < k#+j" by (simp add: add_commute [of k] add_lt_mono1) text\A [clumsy] way of lifting < monotonicity to \\\ monotonicity\ lemma Ord_lt_mono_imp_le_mono: assumes lt_mono: "\i j. \i \ f(i) < f(j)" and ford: "\i. i:k \ Ord(f(i))" and leij: "i \ j" and jink: "j:k" shows "f(i) \ f(j)" apply (insert leij jink) apply (blast intro!: leCI lt_mono ford elim!: leE) done text\\\\ monotonicity, 1st argument\ lemma add_le_mono1: "\i \ j; j\nat\ \ i#+k \ j#+k" apply (rule_tac f = "\j. j#+k" in Ord_lt_mono_imp_le_mono, typecheck) apply (blast intro: add_lt_mono1 add_type [THEN nat_into_Ord])+ done text\\\\ monotonicity, both arguments\ lemma add_le_mono: "\i \ j; k \ l; j\nat; l\nat\ \ i#+k \ j#+l" apply (rule add_le_mono1 [THEN le_trans], assumption+) apply (subst add_commute, subst add_commute, rule add_le_mono1, assumption+) done text\Combinations of less-than and less-than-or-equals\ lemma add_lt_le_mono: "\il; j\nat; l\nat\ \ i#+k < j#+l" apply (rule add_lt_mono1 [THEN lt_trans2], assumption+) apply (subst add_commute, subst add_commute, rule add_le_mono1, assumption+) done lemma add_le_lt_mono: "\i\j; knat; l\nat\ \ i#+k < j#+l" by (subst add_commute, subst add_commute, erule add_lt_le_mono, assumption+) text\Less-than: in other words, strict in both arguments\ lemma add_lt_mono: "\inat; l\nat\ \ i#+k < j#+l" apply (rule add_lt_le_mono) apply (auto intro: leI) done (** Subtraction is the inverse of addition. **) lemma diff_add_inverse: "(n#+m) #- n = natify(m)" apply (subgoal_tac " (natify(n) #+ m) #- natify(n) = natify(m) ") apply (rule_tac [2] n = "natify(n) " in nat_induct) apply auto done lemma diff_add_inverse2: "(m#+n) #- n = natify(m)" by (simp add: add_commute [of m] diff_add_inverse) lemma diff_cancel: "(k#+m) #- (k#+n) = m #- n" apply (subgoal_tac "(natify(k) #+ natify(m)) #- (natify(k) #+ natify(n)) = natify(m) #- natify(n) ") apply (rule_tac [2] n = "natify(k) " in nat_induct) apply auto done lemma diff_cancel2: "(m#+k) #- (n#+k) = m #- n" by (simp add: add_commute [of _ k] diff_cancel) lemma diff_add_0: "n #- (n#+m) = 0" apply (subgoal_tac "natify(n) #- (natify(n) #+ natify(m)) = 0") apply (rule_tac [2] n = "natify(n) " in nat_induct) apply auto done lemma pred_0 [simp]: "pred(0) = 0" by (simp add: pred_def) lemma eq_succ_imp_eq_m1: "\i = succ(j); i\nat\ \ j = i #- 1 \ j \nat" by simp lemma pred_Un_distrib: "\i\nat; j\nat\ \ pred(i \ j) = pred(i) \ pred(j)" apply (erule_tac n=i in natE, simp) apply (erule_tac n=j in natE, simp) apply (simp add: succ_Un_distrib [symmetric]) done lemma pred_type [TC,simp]: "i \ nat \ pred(i) \ nat" by (simp add: pred_def split: split_nat_case) lemma nat_diff_pred: "\i\nat; j\nat\ \ i #- succ(j) = pred(i #- j)" apply (rule_tac m=i and n=j in diff_induct) apply (auto simp add: pred_def nat_imp_quasinat split: split_nat_case) done lemma diff_succ_eq_pred: "i #- succ(j) = pred(i #- j)" apply (insert nat_diff_pred [of "natify(i)" "natify(j)"]) apply (simp add: natify_succ [symmetric]) done lemma nat_diff_Un_distrib: "\i\nat; j\nat; k\nat\ \ (i \ j) #- k = (i#-k) \ (j#-k)" apply (rule_tac n=k in nat_induct) apply (simp_all add: diff_succ_eq_pred pred_Un_distrib) done lemma diff_Un_distrib: "\i\nat; j\nat\ \ (i \ j) #- k = (i#-k) \ (j#-k)" by (insert nat_diff_Un_distrib [of i j "natify(k)"], simp) text\We actually prove \<^term>\i #- j #- k = i #- (j #+ k)\\ lemma diff_diff_left [simplified]: "natify(i)#-natify(j)#-k = natify(i) #- (natify(j)#+k)" by (rule_tac m="natify(i)" and n="natify(j)" in diff_induct, auto) (** Lemmas for the CancelNumerals simproc **) lemma eq_add_iff: "(u #+ m = u #+ n) \ (0 #+ m = natify(n))" apply auto apply (blast dest: add_left_cancel_natify) apply (simp add: add_def) done lemma less_add_iff: "(u #+ m < u #+ n) \ (0 #+ m < natify(n))" apply (auto simp add: add_lt_elim1_natify) apply (drule add_lt_mono1) apply (auto simp add: add_commute [of u]) done lemma diff_add_eq: "((u #+ m) #- (u #+ n)) = ((0 #+ m) #- n)" by (simp add: diff_cancel) (*To tidy up the result of a simproc. Only the RHS will be simplified.*) lemma eq_cong2: "u = u' \ (t\u) \ (t\u')" by auto lemma iff_cong2: "u \ u' \ (t\u) \ (t\u')" by auto subsection\Multiplication\ lemma mult_0 [simp]: "0 #* m = 0" by (simp add: mult_def) lemma mult_succ [simp]: "succ(m) #* n = n #+ (m #* n)" by (simp add: add_def mult_def natify_succ raw_mult_type) (*right annihilation in product*) lemma mult_0_right [simp]: "m #* 0 = 0" -apply (unfold mult_def) + unfolding mult_def apply (rule_tac n = "natify(m) " in nat_induct) apply auto done (*right successor law for multiplication*) lemma mult_succ_right [simp]: "m #* succ(n) = m #+ (m #* n)" apply (subgoal_tac "natify(m) #* succ (natify(n)) = natify(m) #+ (natify(m) #* natify(n))") apply (simp (no_asm_use) add: natify_succ add_def mult_def) apply (rule_tac n = "natify(m) " in nat_induct) apply (simp_all add: add_ac) done lemma mult_1_natify [simp]: "1 #* n = natify(n)" by auto lemma mult_1_right_natify [simp]: "n #* 1 = natify(n)" by auto lemma mult_1: "n \ nat \ 1 #* n = n" by simp lemma mult_1_right: "n \ nat \ n #* 1 = n" by simp (*Commutative law for multiplication*) lemma mult_commute: "m #* n = n #* m" apply (subgoal_tac "natify(m) #* natify(n) = natify(n) #* natify(m) ") apply (rule_tac [2] n = "natify(m) " in nat_induct) apply auto done (*addition distributes over multiplication*) lemma add_mult_distrib: "(m #+ n) #* k = (m #* k) #+ (n #* k)" apply (subgoal_tac "(natify(m) #+ natify(n)) #* natify(k) = (natify(m) #* natify(k)) #+ (natify(n) #* natify(k))") apply (rule_tac [2] n = "natify(m) " in nat_induct) apply (simp_all add: add_assoc [symmetric]) done (*Distributive law on the left*) lemma add_mult_distrib_left: "k #* (m #+ n) = (k #* m) #+ (k #* n)" apply (subgoal_tac "natify(k) #* (natify(m) #+ natify(n)) = (natify(k) #* natify(m)) #+ (natify(k) #* natify(n))") apply (rule_tac [2] n = "natify(m) " in nat_induct) apply (simp_all add: add_ac) done (*Associative law for multiplication*) lemma mult_assoc: "(m #* n) #* k = m #* (n #* k)" apply (subgoal_tac "(natify(m) #* natify(n)) #* natify(k) = natify(m) #* (natify(n) #* natify(k))") apply (rule_tac [2] n = "natify(m) " in nat_induct) apply (simp_all add: add_mult_distrib) done (*for a/c rewriting*) lemma mult_left_commute: "m #* (n #* k) = n #* (m #* k)" apply (rule mult_commute [THEN trans]) apply (rule mult_assoc [THEN trans]) apply (rule mult_commute [THEN subst_context]) done lemmas mult_ac = mult_assoc mult_commute mult_left_commute lemma lt_succ_eq_0_disj: "\m\nat; n\nat\ \ (m < succ(n)) \ (m = 0 | (\j\nat. m = succ(j) \ j < n))" by (induct_tac "m", auto) lemma less_diff_conv [rule_format]: "\j\nat; k\nat\ \ \i\nat. (i < j #- k) \ (i #+ k < j)" by (erule_tac m = k in diff_induct, auto) lemmas nat_typechecks = rec_type nat_0I nat_1I nat_succI Ord_nat end diff --git a/src/ZF/ArithSimp.thy b/src/ZF/ArithSimp.thy --- a/src/ZF/ArithSimp.thy +++ b/src/ZF/ArithSimp.thy @@ -1,569 +1,569 @@ (* Title: ZF/ArithSimp.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 2000 University of Cambridge *) section\Arithmetic with simplification\ theory ArithSimp imports Arith begin ML_file \~~/src/Provers/Arith/cancel_numerals.ML\ ML_file \~~/src/Provers/Arith/combine_numerals.ML\ ML_file \arith_data.ML\ subsection\Difference\ lemma diff_self_eq_0 [simp]: "m #- m = 0" apply (subgoal_tac "natify (m) #- natify (m) = 0") apply (rule_tac [2] natify_in_nat [THEN nat_induct], auto) done (**Addition is the inverse of subtraction**) (*We need m:nat even if we replace the RHS by natify(m), for consider e.g. n=2, m=omega; then n + (m-n) = 2 + (0-2) = 2 \ 0 = natify(m).*) lemma add_diff_inverse: "\n \ m; m:nat\ \ n #+ (m#-n) = m" apply (frule lt_nat_in_nat, erule nat_succI) apply (erule rev_mp) apply (rule_tac m = m and n = n in diff_induct, auto) done lemma add_diff_inverse2: "\n \ m; m:nat\ \ (m#-n) #+ n = m" apply (frule lt_nat_in_nat, erule nat_succI) apply (simp (no_asm_simp) add: add_commute add_diff_inverse) done (*Proof is IDENTICAL to that of add_diff_inverse*) lemma diff_succ: "\n \ m; m:nat\ \ succ(m) #- n = succ(m#-n)" apply (frule lt_nat_in_nat, erule nat_succI) apply (erule rev_mp) apply (rule_tac m = m and n = n in diff_induct) apply (simp_all (no_asm_simp)) done lemma zero_less_diff [simp]: "\m: nat; n: nat\ \ 0 < (n #- m) \ mRemainder\ (*We need m:nat even with natify*) lemma div_termination: "\0 m; m:nat\ \ m #- n < m" apply (frule lt_nat_in_nat, erule nat_succI) apply (erule rev_mp) apply (erule rev_mp) apply (rule_tac m = m and n = n in diff_induct) apply (simp_all (no_asm_simp) add: diff_le_self) done (*for mod and div*) lemmas div_rls = nat_typechecks Ord_transrec_type apply_funtype div_termination [THEN ltD] nat_into_Ord not_lt_iff_le [THEN iffD1] lemma raw_mod_type: "\m:nat; n:nat\ \ raw_mod (m, n) \ nat" -apply (unfold raw_mod_def) + unfolding raw_mod_def apply (rule Ord_transrec_type) apply (auto simp add: nat_into_Ord [THEN Ord_0_lt_iff]) apply (blast intro: div_rls) done lemma mod_type [TC,iff]: "m mod n \ nat" -apply (unfold mod_def) + unfolding mod_def apply (simp (no_asm) add: mod_def raw_mod_type) done (** Aribtrary definitions for division by zero. Useful to simplify certain equations **) lemma DIVISION_BY_ZERO_DIV: "a div 0 = 0" -apply (unfold div_def) + unfolding div_def apply (rule raw_div_def [THEN def_transrec, THEN trans]) apply (simp (no_asm_simp)) done (*NOT for adding to default simpset*) lemma DIVISION_BY_ZERO_MOD: "a mod 0 = natify(a)" -apply (unfold mod_def) + unfolding mod_def apply (rule raw_mod_def [THEN def_transrec, THEN trans]) apply (simp (no_asm_simp)) done (*NOT for adding to default simpset*) lemma raw_mod_less: "m raw_mod (m,n) = m" apply (rule raw_mod_def [THEN def_transrec, THEN trans]) apply (simp (no_asm_simp) add: div_termination [THEN ltD]) done lemma mod_less [simp]: "\m nat\ \ m mod n = m" apply (frule lt_nat_in_nat, assumption) apply (simp (no_asm_simp) add: mod_def raw_mod_less) done lemma raw_mod_geq: "\0 m; m:nat\ \ raw_mod (m, n) = raw_mod (m#-n, n)" apply (frule lt_nat_in_nat, erule nat_succI) apply (rule raw_mod_def [THEN def_transrec, THEN trans]) apply (simp (no_asm_simp) add: div_termination [THEN ltD] not_lt_iff_le [THEN iffD2], blast) done lemma mod_geq: "\n \ m; m:nat\ \ m mod n = (m#-n) mod n" apply (frule lt_nat_in_nat, erule nat_succI) apply (case_tac "n=0") apply (simp add: DIVISION_BY_ZERO_MOD) apply (simp add: mod_def raw_mod_geq nat_into_Ord [THEN Ord_0_lt_iff]) done subsection\Division\ lemma raw_div_type: "\m:nat; n:nat\ \ raw_div (m, n) \ nat" -apply (unfold raw_div_def) + unfolding raw_div_def apply (rule Ord_transrec_type) apply (auto simp add: nat_into_Ord [THEN Ord_0_lt_iff]) apply (blast intro: div_rls) done lemma div_type [TC,iff]: "m div n \ nat" -apply (unfold div_def) + unfolding div_def apply (simp (no_asm) add: div_def raw_div_type) done lemma raw_div_less: "m raw_div (m,n) = 0" apply (rule raw_div_def [THEN def_transrec, THEN trans]) apply (simp (no_asm_simp) add: div_termination [THEN ltD]) done lemma div_less [simp]: "\m nat\ \ m div n = 0" apply (frule lt_nat_in_nat, assumption) apply (simp (no_asm_simp) add: div_def raw_div_less) done lemma raw_div_geq: "\0 m; m:nat\ \ raw_div(m,n) = succ(raw_div(m#-n, n))" apply (subgoal_tac "n \ 0") prefer 2 apply blast apply (frule lt_nat_in_nat, erule nat_succI) apply (rule raw_div_def [THEN def_transrec, THEN trans]) apply (simp (no_asm_simp) add: div_termination [THEN ltD] not_lt_iff_le [THEN iffD2] ) done lemma div_geq [simp]: "\0 m; m:nat\ \ m div n = succ ((m#-n) div n)" apply (frule lt_nat_in_nat, erule nat_succI) apply (simp (no_asm_simp) add: div_def raw_div_geq) done declare div_less [simp] div_geq [simp] (*A key result*) lemma mod_div_lemma: "\m: nat; n: nat\ \ (m div n)#*n #+ m mod n = m" apply (case_tac "n=0") apply (simp add: DIVISION_BY_ZERO_MOD) apply (simp add: nat_into_Ord [THEN Ord_0_lt_iff]) apply (erule complete_induct) apply (case_tac "xcase x apply (simp (no_asm_simp)) txt\case \<^term>\n \ x\\ apply (simp add: not_lt_iff_le add_assoc mod_geq div_termination [THEN ltD] add_diff_inverse) done lemma mod_div_equality_natify: "(m div n)#*n #+ m mod n = natify(m)" apply (subgoal_tac " (natify (m) div natify (n))#*natify (n) #+ natify (m) mod natify (n) = natify (m) ") apply force apply (subst mod_div_lemma, auto) done lemma mod_div_equality: "m: nat \ (m div n)#*n #+ m mod n = m" apply (simp (no_asm_simp) add: mod_div_equality_natify) done subsection\Further Facts about Remainder\ text\(mainly for mutilated chess board)\ lemma mod_succ_lemma: "\0 \ succ(m) mod n = (if succ(m mod n) = n then 0 else succ(m mod n))" apply (erule complete_induct) apply (case_tac "succ (x) case succ(x) < n\ apply (simp (no_asm_simp) add: nat_le_refl [THEN lt_trans] succ_neq_self) apply (simp add: ltD [THEN mem_imp_not_eq]) txt\case \<^term>\n \ succ(x)\\ apply (simp add: mod_geq not_lt_iff_le) apply (erule leE) apply (simp (no_asm_simp) add: mod_geq div_termination [THEN ltD] diff_succ) txt\equality case\ apply (simp add: diff_self_eq_0) done lemma mod_succ: "n:nat \ succ(m) mod n = (if succ(m mod n) = n then 0 else succ(m mod n))" apply (case_tac "n=0") apply (simp (no_asm_simp) add: natify_succ DIVISION_BY_ZERO_MOD) apply (subgoal_tac "natify (succ (m)) mod n = (if succ (natify (m) mod n) = n then 0 else succ (natify (m) mod n))") prefer 2 apply (subst natify_succ) apply (rule mod_succ_lemma) apply (auto simp del: natify_succ simp add: nat_into_Ord [THEN Ord_0_lt_iff]) done lemma mod_less_divisor: "\0 \ m mod n < n" apply (subgoal_tac "natify (m) mod n < n") apply (rule_tac [2] i = "natify (m) " in complete_induct) apply (case_tac [3] "xcase \<^term>\n \ x\\ apply (simp add: mod_geq not_lt_iff_le div_termination [THEN ltD]) done lemma mod_1_eq [simp]: "m mod 1 = 0" by (cut_tac n = 1 in mod_less_divisor, auto) lemma mod2_cases: "b<2 \ k mod 2 = b | k mod 2 = (if b=1 then 0 else 1)" apply (subgoal_tac "k mod 2: 2") prefer 2 apply (simp add: mod_less_divisor [THEN ltD]) apply (drule ltD, auto) done lemma mod2_succ_succ [simp]: "succ(succ(m)) mod 2 = m mod 2" apply (subgoal_tac "m mod 2: 2") prefer 2 apply (simp add: mod_less_divisor [THEN ltD]) apply (auto simp add: mod_succ) done lemma mod2_add_more [simp]: "(m#+m#+n) mod 2 = n mod 2" apply (subgoal_tac " (natify (m) #+natify (m) #+n) mod 2 = n mod 2") apply (rule_tac [2] n = "natify (m) " in nat_induct) apply auto done lemma mod2_add_self [simp]: "(m#+m) mod 2 = 0" by (cut_tac n = 0 in mod2_add_more, auto) subsection\Additional theorems about \\\\ lemma add_le_self: "m:nat \ m \ (m #+ n)" apply (simp (no_asm_simp)) done lemma add_le_self2: "m:nat \ m \ (n #+ m)" apply (simp (no_asm_simp)) done (*** Monotonicity of Multiplication ***) lemma mult_le_mono1: "\i \ j; j:nat\ \ (i#*k) \ (j#*k)" apply (subgoal_tac "natify (i) #*natify (k) \ j#*natify (k) ") apply (frule_tac [2] lt_nat_in_nat) apply (rule_tac [3] n = "natify (k) " in nat_induct) apply (simp_all add: add_le_mono) done (* @{text"\"} monotonicity, BOTH arguments*) lemma mult_le_mono: "\i \ j; k \ l; j:nat; l:nat\ \ i#*k \ j#*l" apply (rule mult_le_mono1 [THEN le_trans], assumption+) apply (subst mult_commute, subst mult_commute, rule mult_le_mono1, assumption+) done (*strict, in 1st argument; proof is by induction on k>0. I can't see how to relax the typing conditions.*) lemma mult_lt_mono2: "\i \ k#*i < k#*j" apply (erule zero_lt_natE) apply (frule_tac [2] lt_nat_in_nat) apply (simp_all (no_asm_simp)) apply (induct_tac "x") apply (simp_all (no_asm_simp) add: add_lt_mono) done lemma mult_lt_mono1: "\i \ i#*k < j#*k" apply (simp (no_asm_simp) add: mult_lt_mono2 mult_commute [of _ k]) done lemma add_eq_0_iff [iff]: "m#+n = 0 \ natify(m)=0 \ natify(n)=0" apply (subgoal_tac "natify (m) #+ natify (n) = 0 \ natify (m) =0 \ natify (n) =0") apply (rule_tac [2] n = "natify (m) " in natE) apply (rule_tac [4] n = "natify (n) " in natE) apply auto done lemma zero_lt_mult_iff [iff]: "0 < m#*n \ 0 < natify(m) \ 0 < natify(n)" apply (subgoal_tac "0 < natify (m) #*natify (n) \ 0 < natify (m) \ 0 < natify (n) ") apply (rule_tac [2] n = "natify (m) " in natE) apply (rule_tac [4] n = "natify (n) " in natE) apply (rule_tac [3] n = "natify (n) " in natE) apply auto done lemma mult_eq_1_iff [iff]: "m#*n = 1 \ natify(m)=1 \ natify(n)=1" apply (subgoal_tac "natify (m) #* natify (n) = 1 \ natify (m) =1 \ natify (n) =1") apply (rule_tac [2] n = "natify (m) " in natE) apply (rule_tac [4] n = "natify (n) " in natE) apply auto done lemma mult_is_zero: "\m: nat; n: nat\ \ (m #* n = 0) \ (m = 0 | n = 0)" apply auto apply (erule natE) apply (erule_tac [2] natE, auto) done lemma mult_is_zero_natify [iff]: "(m #* n = 0) \ (natify(m) = 0 | natify(n) = 0)" apply (cut_tac m = "natify (m) " and n = "natify (n) " in mult_is_zero) apply auto done subsection\Cancellation Laws for Common Factors in Comparisons\ lemma mult_less_cancel_lemma: "\k: nat; m: nat; n: nat\ \ (m#*k < n#*k) \ (0 m (0 < natify(k) \ natify(m) < natify(n))" apply (rule iff_trans) apply (rule_tac [2] mult_less_cancel_lemma, auto) done lemma mult_less_cancel1 [simp]: "(k#*m < k#*n) \ (0 < natify(k) \ natify(m) < natify(n))" apply (simp (no_asm) add: mult_less_cancel2 mult_commute [of k]) done lemma mult_le_cancel2 [simp]: "(m#*k \ n#*k) \ (0 < natify(k) \ natify(m) \ natify(n))" apply (simp (no_asm_simp) add: not_lt_iff_le [THEN iff_sym]) apply auto done lemma mult_le_cancel1 [simp]: "(k#*m \ k#*n) \ (0 < natify(k) \ natify(m) \ natify(n))" apply (simp (no_asm_simp) add: not_lt_iff_le [THEN iff_sym]) apply auto done lemma mult_le_cancel_le1: "k \ nat \ k #* m \ k \ (0 < k \ natify(m) \ 1)" by (cut_tac k = k and m = m and n = 1 in mult_le_cancel1, auto) lemma Ord_eq_iff_le: "\Ord(m); Ord(n)\ \ m=n \ (m \ n \ n \ m)" by (blast intro: le_anti_sym) lemma mult_cancel2_lemma: "\k: nat; m: nat; n: nat\ \ (m#*k = n#*k) \ (m=n | k=0)" apply (simp (no_asm_simp) add: Ord_eq_iff_le [of "m#*k"] Ord_eq_iff_le [of m]) apply (auto simp add: Ord_0_lt_iff) done lemma mult_cancel2 [simp]: "(m#*k = n#*k) \ (natify(m) = natify(n) | natify(k) = 0)" apply (rule iff_trans) apply (rule_tac [2] mult_cancel2_lemma, auto) done lemma mult_cancel1 [simp]: "(k#*m = k#*n) \ (natify(m) = natify(n) | natify(k) = 0)" apply (simp (no_asm) add: mult_cancel2 mult_commute [of k]) done (** Cancellation law for division **) lemma div_cancel_raw: "\0 \ (k#*m) div (k#*n) = m div n" apply (erule_tac i = m in complete_induct) apply (case_tac "x0 < natify(n); 0 < natify(k)\ \ (k#*m) div (k#*n) = m div n" apply (cut_tac k = "natify (k) " and m = "natify (m)" and n = "natify (n)" in div_cancel_raw) apply auto done subsection\More Lemmas about Remainder\ lemma mult_mod_distrib_raw: "\k:nat; m:nat; n:nat\ \ (k#*m) mod (k#*n) = k #* (m mod n)" apply (case_tac "k=0") apply (simp add: DIVISION_BY_ZERO_MOD) apply (case_tac "n=0") apply (simp add: DIVISION_BY_ZERO_MOD) apply (simp add: nat_into_Ord [THEN Ord_0_lt_iff]) apply (erule_tac i = m in complete_induct) apply (case_tac "x nat \ (m #+ n) mod n = m mod n" apply (subgoal_tac " (n #+ m) mod n = (n #+ m #- n) mod n") apply (simp add: add_commute) apply (subst mod_geq [symmetric], auto) done lemma mod_add_self2 [simp]: "(m #+ n) mod n = m mod n" apply (cut_tac n = "natify (n) " in mod_add_self2_raw) apply auto done lemma mod_add_self1 [simp]: "(n#+m) mod n = m mod n" apply (simp (no_asm_simp) add: add_commute mod_add_self2) done lemma mod_mult_self1_raw: "k \ nat \ (m #+ k#*n) mod n = m mod n" apply (erule nat_induct) apply (simp_all (no_asm_simp) add: add_left_commute [of _ n]) done lemma mod_mult_self1 [simp]: "(m #+ k#*n) mod n = m mod n" apply (cut_tac k = "natify (k) " in mod_mult_self1_raw) apply auto done lemma mod_mult_self2 [simp]: "(m #+ n#*k) mod n = m mod n" apply (simp (no_asm) add: mult_commute mod_mult_self1) done (*Lemma for gcd*) lemma mult_eq_self_implies_10: "m = m#*n \ natify(n)=1 | m=0" apply (subgoal_tac "m: nat") prefer 2 apply (erule ssubst) apply simp apply (rule disjCI) apply (drule sym) apply (rule Ord_linear_lt [of "natify(n)" 1]) apply simp_all apply (subgoal_tac "m #* n = 0", simp) apply (subst mult_natify2 [symmetric]) apply (simp del: mult_natify2) apply (drule nat_into_Ord [THEN Ord_0_lt, THEN [2] mult_lt_mono2], auto) done lemma less_imp_succ_add [rule_format]: "\m \ \k\nat. n = succ(m#+k)" apply (frule lt_nat_in_nat, assumption) apply (erule rev_mp) apply (induct_tac "n") apply (simp_all (no_asm) add: le_iff) apply (blast elim!: leE intro!: add_0_right [symmetric] add_succ_right [symmetric]) done lemma less_iff_succ_add: "\m: nat; n: nat\ \ (m (\k\nat. n = succ(m#+k))" by (auto intro: less_imp_succ_add) lemma add_lt_elim2: "\a #+ d = b #+ c; a < b; b \ nat; c \ nat; d \ nat\ \ c < d" by (drule less_imp_succ_add, auto) lemma add_le_elim2: "\a #+ d = b #+ c; a \ b; b \ nat; c \ nat; d \ nat\ \ c \ d" by (drule less_imp_succ_add, auto) subsubsection\More Lemmas About Difference\ lemma diff_is_0_lemma: "\m: nat; n: nat\ \ m #- n = 0 \ m \ n" apply (rule_tac m = m and n = n in diff_induct, simp_all) done lemma diff_is_0_iff: "m #- n = 0 \ natify(m) \ natify(n)" by (simp add: diff_is_0_lemma [symmetric]) lemma nat_lt_imp_diff_eq_0: "\a:nat; b:nat; a \ a #- b = 0" by (simp add: diff_is_0_iff le_iff) lemma raw_nat_diff_split: "\a:nat; b:nat\ \ (P(a #- b)) \ ((a < b \P(0)) \ (\d\nat. a = b #+ d \ P(d)))" apply (case_tac "a < b") apply (force simp add: nat_lt_imp_diff_eq_0) apply (rule iffI, force, simp) apply (drule_tac x="a#-b" in bspec) apply (simp_all add: Ordinal.not_lt_iff_le add_diff_inverse) done lemma nat_diff_split: "(P(a #- b)) \ (natify(a) < natify(b) \P(0)) \ (\d\nat. natify(a) = b #+ d \ P(d))" apply (cut_tac P=P and a="natify(a)" and b="natify(b)" in raw_nat_diff_split) apply simp_all done text\Difference and less-than\ lemma diff_lt_imp_lt: "\(k#-i) < (k#-j); i\nat; j\nat; k\nat\ \ jjk; k\nat\ \ (k#-i) < (k#-j)" apply (frule le_in_nat, assumption) apply (frule lt_nat_in_nat, assumption) apply (simp split: nat_diff_split, auto) apply (blast intro: lt_asym lt_trans2) apply (blast intro: lt_irrefl lt_trans2) apply (rule not_le_iff_lt [THEN iffD1], auto) apply (subgoal_tac "j #+ d < i #+ da", force) apply (blast intro: add_lt_le_mono) done lemma diff_lt_iff_lt: "\i\k; j\nat; k\nat\ \ (k#-i) < (k#-j) \ j5 div 2 = \3 and \5 mod 2 = 1; thus \5 = (\3)*2 + 1 *) section\Arithmetic on Binary Integers\ theory Bin imports Int Datatype begin consts bin :: i datatype "bin" = Pls | Min | Bit ("w \ bin", "b \ bool") (infixl \BIT\ 90) consts integ_of :: "i\i" NCons :: "[i,i]\i" bin_succ :: "i\i" bin_pred :: "i\i" bin_minus :: "i\i" bin_adder :: "i\i" bin_mult :: "[i,i]\i" primrec integ_of_Pls: "integ_of (Pls) = $# 0" integ_of_Min: "integ_of (Min) = $-($#1)" integ_of_BIT: "integ_of (w BIT b) = $#b $+ integ_of(w) $+ integ_of(w)" (** recall that cond(1,b,c)=b and cond(0,b,c)=0 **) primrec (*NCons adds a bit, suppressing leading 0s and 1s*) NCons_Pls: "NCons (Pls,b) = cond(b,Pls BIT b,Pls)" NCons_Min: "NCons (Min,b) = cond(b,Min,Min BIT b)" NCons_BIT: "NCons (w BIT c,b) = w BIT c BIT b" primrec (*successor. If a BIT, can change a 0 to a 1 without recursion.*) bin_succ_Pls: "bin_succ (Pls) = Pls BIT 1" bin_succ_Min: "bin_succ (Min) = Pls" bin_succ_BIT: "bin_succ (w BIT b) = cond(b, bin_succ(w) BIT 0, NCons(w,1))" primrec (*predecessor*) bin_pred_Pls: "bin_pred (Pls) = Min" bin_pred_Min: "bin_pred (Min) = Min BIT 0" bin_pred_BIT: "bin_pred (w BIT b) = cond(b, NCons(w,0), bin_pred(w) BIT 1)" primrec (*unary negation*) bin_minus_Pls: "bin_minus (Pls) = Pls" bin_minus_Min: "bin_minus (Min) = Pls BIT 1" bin_minus_BIT: "bin_minus (w BIT b) = cond(b, bin_pred(NCons(bin_minus(w),0)), bin_minus(w) BIT 0)" primrec (*sum*) bin_adder_Pls: "bin_adder (Pls) = (\w\bin. w)" bin_adder_Min: "bin_adder (Min) = (\w\bin. bin_pred(w))" bin_adder_BIT: "bin_adder (v BIT x) = (\w\bin. bin_case (v BIT x, bin_pred(v BIT x), \w y. NCons(bin_adder (v) ` cond(x and y, bin_succ(w), w), x xor y), w))" (*The bin_case above replaces the following mutually recursive function: primrec "adding (v,x,Pls) = v BIT x" "adding (v,x,Min) = bin_pred(v BIT x)" "adding (v,x,w BIT y) = NCons(bin_adder (v, cond(x and y, bin_succ(w), w)), x xor y)" *) definition bin_add :: "[i,i]\i" where "bin_add(v,w) \ bin_adder(v)`w" primrec bin_mult_Pls: "bin_mult (Pls,w) = Pls" bin_mult_Min: "bin_mult (Min,w) = bin_minus(w)" bin_mult_BIT: "bin_mult (v BIT b,w) = cond(b, bin_add(NCons(bin_mult(v,w),0),w), NCons(bin_mult(v,w),0))" syntax "_Int0" :: i (\#' 0\) "_Int1" :: i (\#' 1\) "_Int2" :: i (\#' 2\) "_Neg_Int1" :: i (\#-' 1\) "_Neg_Int2" :: i (\#-' 2\) translations "#0" \ "CONST integ_of(CONST Pls)" "#1" \ "CONST integ_of(CONST Pls BIT 1)" "#2" \ "CONST integ_of(CONST Pls BIT 1 BIT 0)" "#-1" \ "CONST integ_of(CONST Min)" "#-2" \ "CONST integ_of(CONST Min BIT 0)" syntax "_Int" :: "num_token \ i" (\#_\ 1000) "_Neg_Int" :: "num_token \ i" (\#-_\ 1000) ML_file \Tools/numeral_syntax.ML\ declare bin.intros [simp,TC] lemma NCons_Pls_0: "NCons(Pls,0) = Pls" by simp lemma NCons_Pls_1: "NCons(Pls,1) = Pls BIT 1" by simp lemma NCons_Min_0: "NCons(Min,0) = Min BIT 0" by simp lemma NCons_Min_1: "NCons(Min,1) = Min" by simp lemma NCons_BIT: "NCons(w BIT x,b) = w BIT x BIT b" by (simp add: bin.case_eqns) lemmas NCons_simps [simp] = NCons_Pls_0 NCons_Pls_1 NCons_Min_0 NCons_Min_1 NCons_BIT (** Type checking **) lemma integ_of_type [TC]: "w \ bin \ integ_of(w) \ int" apply (induct_tac "w") apply (simp_all add: bool_into_nat) done lemma NCons_type [TC]: "\w \ bin; b \ bool\ \ NCons(w,b) \ bin" by (induct_tac "w", auto) lemma bin_succ_type [TC]: "w \ bin \ bin_succ(w) \ bin" by (induct_tac "w", auto) lemma bin_pred_type [TC]: "w \ bin \ bin_pred(w) \ bin" by (induct_tac "w", auto) lemma bin_minus_type [TC]: "w \ bin \ bin_minus(w) \ bin" by (induct_tac "w", auto) (*This proof is complicated by the mutual recursion*) lemma bin_add_type [rule_format]: "v \ bin \ \w\bin. bin_add(v,w) \ bin" -apply (unfold bin_add_def) + unfolding bin_add_def apply (induct_tac "v") apply (rule_tac [3] ballI) apply (rename_tac [3] "w'") apply (induct_tac [3] "w'") apply (simp_all add: NCons_type) done declare bin_add_type [TC] lemma bin_mult_type [TC]: "\v \ bin; w \ bin\ \ bin_mult(v,w) \ bin" by (induct_tac "v", auto) subsubsection\The Carry and Borrow Functions, \<^term>\bin_succ\ and \<^term>\bin_pred\\ (*NCons preserves the integer value of its argument*) lemma integ_of_NCons [simp]: "\w \ bin; b \ bool\ \ integ_of(NCons(w,b)) = integ_of(w BIT b)" apply (erule bin.cases) apply (auto elim!: boolE) done lemma integ_of_succ [simp]: "w \ bin \ integ_of(bin_succ(w)) = $#1 $+ integ_of(w)" apply (erule bin.induct) apply (auto simp add: zadd_ac elim!: boolE) done lemma integ_of_pred [simp]: "w \ bin \ integ_of(bin_pred(w)) = $- ($#1) $+ integ_of(w)" apply (erule bin.induct) apply (auto simp add: zadd_ac elim!: boolE) done subsubsection\\<^term>\bin_minus\: Unary Negation of Binary Integers\ lemma integ_of_minus: "w \ bin \ integ_of(bin_minus(w)) = $- integ_of(w)" apply (erule bin.induct) apply (auto simp add: zadd_ac zminus_zadd_distrib elim!: boolE) done subsubsection\\<^term>\bin_add\: Binary Addition\ lemma bin_add_Pls [simp]: "w \ bin \ bin_add(Pls,w) = w" by (unfold bin_add_def, simp) lemma bin_add_Pls_right: "w \ bin \ bin_add(w,Pls) = w" -apply (unfold bin_add_def) + unfolding bin_add_def apply (erule bin.induct, auto) done lemma bin_add_Min [simp]: "w \ bin \ bin_add(Min,w) = bin_pred(w)" by (unfold bin_add_def, simp) lemma bin_add_Min_right: "w \ bin \ bin_add(w,Min) = bin_pred(w)" -apply (unfold bin_add_def) + unfolding bin_add_def apply (erule bin.induct, auto) done lemma bin_add_BIT_Pls [simp]: "bin_add(v BIT x,Pls) = v BIT x" by (unfold bin_add_def, simp) lemma bin_add_BIT_Min [simp]: "bin_add(v BIT x,Min) = bin_pred(v BIT x)" by (unfold bin_add_def, simp) lemma bin_add_BIT_BIT [simp]: "\w \ bin; y \ bool\ \ bin_add(v BIT x, w BIT y) = NCons(bin_add(v, cond(x and y, bin_succ(w), w)), x xor y)" by (unfold bin_add_def, simp) lemma integ_of_add [rule_format]: "v \ bin \ \w\bin. integ_of(bin_add(v,w)) = integ_of(v) $+ integ_of(w)" apply (erule bin.induct, simp, simp) apply (rule ballI) apply (induct_tac "wa") apply (auto simp add: zadd_ac elim!: boolE) done (*Subtraction*) lemma diff_integ_of_eq: "\v \ bin; w \ bin\ \ integ_of(v) $- integ_of(w) = integ_of(bin_add (v, bin_minus(w)))" -apply (unfold zdiff_def) + unfolding zdiff_def apply (simp add: integ_of_add integ_of_minus) done subsubsection\\<^term>\bin_mult\: Binary Multiplication\ lemma integ_of_mult: "\v \ bin; w \ bin\ \ integ_of(bin_mult(v,w)) = integ_of(v) $* integ_of(w)" apply (induct_tac "v", simp) apply (simp add: integ_of_minus) apply (auto simp add: zadd_ac integ_of_add zadd_zmult_distrib elim!: boolE) done subsection\Computations\ (** extra rules for bin_succ, bin_pred **) lemma bin_succ_1: "bin_succ(w BIT 1) = bin_succ(w) BIT 0" by simp lemma bin_succ_0: "bin_succ(w BIT 0) = NCons(w,1)" by simp lemma bin_pred_1: "bin_pred(w BIT 1) = NCons(w,0)" by simp lemma bin_pred_0: "bin_pred(w BIT 0) = bin_pred(w) BIT 1" by simp (** extra rules for bin_minus **) lemma bin_minus_1: "bin_minus(w BIT 1) = bin_pred(NCons(bin_minus(w), 0))" by simp lemma bin_minus_0: "bin_minus(w BIT 0) = bin_minus(w) BIT 0" by simp (** extra rules for bin_add **) lemma bin_add_BIT_11: "w \ bin \ bin_add(v BIT 1, w BIT 1) = NCons(bin_add(v, bin_succ(w)), 0)" by simp lemma bin_add_BIT_10: "w \ bin \ bin_add(v BIT 1, w BIT 0) = NCons(bin_add(v,w), 1)" by simp lemma bin_add_BIT_0: "\w \ bin; y \ bool\ \ bin_add(v BIT 0, w BIT y) = NCons(bin_add(v,w), y)" by simp (** extra rules for bin_mult **) lemma bin_mult_1: "bin_mult(v BIT 1, w) = bin_add(NCons(bin_mult(v,w),0), w)" by simp lemma bin_mult_0: "bin_mult(v BIT 0, w) = NCons(bin_mult(v,w),0)" by simp (** Simplification rules with integer constants **) lemma int_of_0: "$#0 = #0" by simp lemma int_of_succ: "$# succ(n) = #1 $+ $#n" by (simp add: int_of_add [symmetric] natify_succ) lemma zminus_0 [simp]: "$- #0 = #0" by simp lemma zadd_0_intify [simp]: "#0 $+ z = intify(z)" by simp lemma zadd_0_right_intify [simp]: "z $+ #0 = intify(z)" by simp lemma zmult_1_intify [simp]: "#1 $* z = intify(z)" by simp lemma zmult_1_right_intify [simp]: "z $* #1 = intify(z)" by (subst zmult_commute, simp) lemma zmult_0 [simp]: "#0 $* z = #0" by simp lemma zmult_0_right [simp]: "z $* #0 = #0" by (subst zmult_commute, simp) lemma zmult_minus1 [simp]: "#-1 $* z = $-z" by (simp add: zcompare_rls) lemma zmult_minus1_right [simp]: "z $* #-1 = $-z" apply (subst zmult_commute) apply (rule zmult_minus1) done subsection\Simplification Rules for Comparison of Binary Numbers\ text\Thanks to Norbert Voelker\ (** Equals (=) **) lemma eq_integ_of_eq: "\v \ bin; w \ bin\ \ ((integ_of(v)) = integ_of(w)) \ iszero (integ_of (bin_add (v, bin_minus(w))))" -apply (unfold iszero_def) + unfolding iszero_def apply (simp add: zcompare_rls integ_of_add integ_of_minus) done lemma iszero_integ_of_Pls: "iszero (integ_of(Pls))" by (unfold iszero_def, simp) lemma nonzero_integ_of_Min: "\ iszero (integ_of(Min))" -apply (unfold iszero_def) + unfolding iszero_def apply (simp add: zminus_equation) done lemma iszero_integ_of_BIT: "\w \ bin; x \ bool\ \ iszero (integ_of (w BIT x)) \ (x=0 \ iszero (integ_of(w)))" apply (unfold iszero_def, simp) apply (subgoal_tac "integ_of (w) \ int") apply typecheck apply (drule int_cases) apply (safe elim!: boolE) apply (simp_all (asm_lr) add: zcompare_rls zminus_zadd_distrib [symmetric] int_of_add [symmetric]) done lemma iszero_integ_of_0: "w \ bin \ iszero (integ_of (w BIT 0)) \ iszero (integ_of(w))" by (simp only: iszero_integ_of_BIT, blast) lemma iszero_integ_of_1: "w \ bin \ \ iszero (integ_of (w BIT 1))" by (simp only: iszero_integ_of_BIT, blast) (** Less-than (<) **) lemma less_integ_of_eq_neg: "\v \ bin; w \ bin\ \ integ_of(v) $< integ_of(w) \ znegative (integ_of (bin_add (v, bin_minus(w))))" apply (unfold zless_def zdiff_def) apply (simp add: integ_of_minus integ_of_add) done lemma not_neg_integ_of_Pls: "\ znegative (integ_of(Pls))" by simp lemma neg_integ_of_Min: "znegative (integ_of(Min))" by simp lemma neg_integ_of_BIT: "\w \ bin; x \ bool\ \ znegative (integ_of (w BIT x)) \ znegative (integ_of(w))" apply simp apply (subgoal_tac "integ_of (w) \ int") apply typecheck apply (drule int_cases) apply (auto elim!: boolE simp add: int_of_add [symmetric] zcompare_rls) apply (simp_all add: zminus_zadd_distrib [symmetric] zdiff_def int_of_add [symmetric]) apply (subgoal_tac "$#1 $- $# succ (succ (n #+ n)) = $- $# succ (n #+ n) ") apply (simp add: zdiff_def) apply (simp add: equation_zminus int_of_diff [symmetric]) done (** Less-than-or-equals (<=) **) lemma le_integ_of_eq_not_less: "(integ_of(x) $\ (integ_of(w))) \ \ (integ_of(w) $< (integ_of(x)))" by (simp add: not_zless_iff_zle [THEN iff_sym]) (*Delete the original rewrites, with their clumsy conditional expressions*) declare bin_succ_BIT [simp del] bin_pred_BIT [simp del] bin_minus_BIT [simp del] NCons_Pls [simp del] NCons_Min [simp del] bin_adder_BIT [simp del] bin_mult_BIT [simp del] (*Hide the binary representation of integer constants*) declare integ_of_Pls [simp del] integ_of_Min [simp del] integ_of_BIT [simp del] lemmas bin_arith_extra_simps = integ_of_add [symmetric] integ_of_minus [symmetric] integ_of_mult [symmetric] bin_succ_1 bin_succ_0 bin_pred_1 bin_pred_0 bin_minus_1 bin_minus_0 bin_add_Pls_right bin_add_Min_right bin_add_BIT_0 bin_add_BIT_10 bin_add_BIT_11 diff_integ_of_eq bin_mult_1 bin_mult_0 NCons_simps (*For making a minimal simpset, one must include these default simprules of thy. Also include simp_thms, or at least (\False)=True*) lemmas bin_arith_simps = bin_pred_Pls bin_pred_Min bin_succ_Pls bin_succ_Min bin_add_Pls bin_add_Min bin_minus_Pls bin_minus_Min bin_mult_Pls bin_mult_Min bin_arith_extra_simps (*Simplification of relational operations*) lemmas bin_rel_simps = eq_integ_of_eq iszero_integ_of_Pls nonzero_integ_of_Min iszero_integ_of_0 iszero_integ_of_1 less_integ_of_eq_neg not_neg_integ_of_Pls neg_integ_of_Min neg_integ_of_BIT le_integ_of_eq_not_less declare bin_arith_simps [simp] declare bin_rel_simps [simp] (** Simplification of arithmetic when nested to the right **) lemma add_integ_of_left [simp]: "\v \ bin; w \ bin\ \ integ_of(v) $+ (integ_of(w) $+ z) = (integ_of(bin_add(v,w)) $+ z)" by (simp add: zadd_assoc [symmetric]) lemma mult_integ_of_left [simp]: "\v \ bin; w \ bin\ \ integ_of(v) $* (integ_of(w) $* z) = (integ_of(bin_mult(v,w)) $* z)" by (simp add: zmult_assoc [symmetric]) lemma add_integ_of_diff1 [simp]: "\v \ bin; w \ bin\ \ integ_of(v) $+ (integ_of(w) $- c) = integ_of(bin_add(v,w)) $- (c)" -apply (unfold zdiff_def) + unfolding zdiff_def apply (rule add_integ_of_left, auto) done lemma add_integ_of_diff2 [simp]: "\v \ bin; w \ bin\ \ integ_of(v) $+ (c $- integ_of(w)) = integ_of (bin_add (v, bin_minus(w))) $+ (c)" apply (subst diff_integ_of_eq [symmetric]) apply (simp_all add: zdiff_def zadd_ac) done (** More for integer constants **) declare int_of_0 [simp] int_of_succ [simp] lemma zdiff0 [simp]: "#0 $- x = $-x" by (simp add: zdiff_def) lemma zdiff0_right [simp]: "x $- #0 = intify(x)" by (simp add: zdiff_def) lemma zdiff_self [simp]: "x $- x = #0" by (simp add: zdiff_def) lemma znegative_iff_zless_0: "k \ int \ znegative(k) \ k $< #0" by (simp add: zless_def) lemma zero_zless_imp_znegative_zminus: "\#0 $< k; k \ int\ \ znegative($-k)" by (simp add: zless_def) lemma zero_zle_int_of [simp]: "#0 $\ $# n" by (simp add: not_zless_iff_zle [THEN iff_sym] znegative_iff_zless_0 [THEN iff_sym]) lemma nat_of_0 [simp]: "nat_of(#0) = 0" by (simp only: natify_0 int_of_0 [symmetric] nat_of_int_of) lemma nat_le_int0_lemma: "\z $\ $#0; z \ int\ \ nat_of(z) = 0" by (auto simp add: znegative_iff_zless_0 [THEN iff_sym] zle_def zneg_nat_of) lemma nat_le_int0: "z $\ $#0 \ nat_of(z) = 0" apply (subgoal_tac "nat_of (intify (z)) = 0") apply (rule_tac [2] nat_le_int0_lemma, auto) done lemma int_of_eq_0_imp_natify_eq_0: "$# n = #0 \ natify(n) = 0" by (rule not_znegative_imp_zero, auto) lemma nat_of_zminus_int_of: "nat_of($- $# n) = 0" by (simp add: nat_of_def int_of_def raw_nat_of zminus image_intrel_int) lemma int_of_nat_of: "#0 $\ z \ $# nat_of(z) = intify(z)" apply (rule not_zneg_nat_of_intify) apply (simp add: znegative_iff_zless_0 not_zless_iff_zle) done declare int_of_nat_of [simp] nat_of_zminus_int_of [simp] lemma int_of_nat_of_if: "$# nat_of(z) = (if #0 $\ z then intify(z) else #0)" by (simp add: int_of_nat_of znegative_iff_zless_0 not_zle_iff_zless) lemma zless_nat_iff_int_zless: "\m \ nat; z \ int\ \ (m < nat_of(z)) \ ($#m $< z)" apply (case_tac "znegative (z) ") apply (erule_tac [2] not_zneg_nat_of [THEN subst]) apply (auto dest: zless_trans dest!: zero_zle_int_of [THEN zle_zless_trans] simp add: znegative_iff_zless_0) done (** nat_of and zless **) (*An alternative condition is @{term"$#0 \ w"} *) lemma zless_nat_conj_lemma: "$#0 $< z \ (nat_of(w) < nat_of(z)) \ (w $< z)" apply (rule iff_trans) apply (rule zless_int_of [THEN iff_sym]) apply (auto simp add: int_of_nat_of_if simp del: zless_int_of) apply (auto elim: zless_asym simp add: not_zle_iff_zless) apply (blast intro: zless_zle_trans) done lemma zless_nat_conj: "(nat_of(w) < nat_of(z)) \ ($#0 $< z \ w $< z)" apply (case_tac "$#0 $< z") apply (auto simp add: zless_nat_conj_lemma nat_le_int0 not_zless_iff_zle) done (*This simprule cannot be added unless we can find a way to make eq_integ_of_eq unconditional! [The condition "True" is a hack to prevent looping. Conditional rewrite rules are tried after unconditional ones, so a rule like eq_nat_number_of will be tried first to eliminate #mm=#nn.] lemma integ_of_reorient [simp]: "True \ (integ_of(w) = x) \ (x = integ_of(w))" by auto *) lemma integ_of_minus_reorient [simp]: "(integ_of(w) = $- x) \ ($- x = integ_of(w))" by auto lemma integ_of_add_reorient [simp]: "(integ_of(w) = x $+ y) \ (x $+ y = integ_of(w))" by auto lemma integ_of_diff_reorient [simp]: "(integ_of(w) = x $- y) \ (x $- y = integ_of(w))" by auto lemma integ_of_mult_reorient [simp]: "(integ_of(w) = x $* y) \ (x $* y = integ_of(w))" by auto (** To simplify inequalities involving integer negation and literals, such as -x = #3 **) lemmas [simp] = zminus_equation [where y = "integ_of(w)"] equation_zminus [where x = "integ_of(w)"] for w lemmas [iff] = zminus_zless [where y = "integ_of(w)"] zless_zminus [where x = "integ_of(w)"] for w lemmas [iff] = zminus_zle [where y = "integ_of(w)"] zle_zminus [where x = "integ_of(w)"] for w lemmas [simp] = Let_def [where s = "integ_of(w)"] for w (*** Simprocs for numeric literals ***) (** Combining of literal coefficients in sums of products **) lemma zless_iff_zdiff_zless_0: "(x $< y) \ (x$-y $< #0)" by (simp add: zcompare_rls) lemma eq_iff_zdiff_eq_0: "\x \ int; y \ int\ \ (x = y) \ (x$-y = #0)" by (simp add: zcompare_rls) lemma zle_iff_zdiff_zle_0: "(x $\ y) \ (x$-y $\ #0)" by (simp add: zcompare_rls) (** For combine_numerals **) lemma left_zadd_zmult_distrib: "i$*u $+ (j$*u $+ k) = (i$+j)$*u $+ k" by (simp add: zadd_zmult_distrib zadd_ac) (** For cancel_numerals **) lemma eq_add_iff1: "(i$*u $+ m = j$*u $+ n) \ ((i$-j)$*u $+ m = intify(n))" apply (simp add: zdiff_def zadd_zmult_distrib) apply (simp add: zcompare_rls) apply (simp add: zadd_ac) done lemma eq_add_iff2: "(i$*u $+ m = j$*u $+ n) \ (intify(m) = (j$-i)$*u $+ n)" apply (simp add: zdiff_def zadd_zmult_distrib) apply (simp add: zcompare_rls) apply (simp add: zadd_ac) done context fixes n :: i begin lemmas rel_iff_rel_0_rls = zless_iff_zdiff_zless_0 [where y = "u $+ v"] eq_iff_zdiff_eq_0 [where y = "u $+ v"] zle_iff_zdiff_zle_0 [where y = "u $+ v"] zless_iff_zdiff_zless_0 [where y = n] eq_iff_zdiff_eq_0 [where y = n] zle_iff_zdiff_zle_0 [where y = n] for u v lemma less_add_iff1: "(i$*u $+ m $< j$*u $+ n) \ ((i$-j)$*u $+ m $< n)" apply (simp add: zdiff_def zadd_zmult_distrib zadd_ac rel_iff_rel_0_rls) done lemma less_add_iff2: "(i$*u $+ m $< j$*u $+ n) \ (m $< (j$-i)$*u $+ n)" apply (simp add: zdiff_def zadd_zmult_distrib zadd_ac rel_iff_rel_0_rls) done end lemma le_add_iff1: "(i$*u $+ m $\ j$*u $+ n) \ ((i$-j)$*u $+ m $\ n)" apply (simp add: zdiff_def zadd_zmult_distrib) apply (simp add: zcompare_rls) apply (simp add: zadd_ac) done lemma le_add_iff2: "(i$*u $+ m $\ j$*u $+ n) \ (m $\ (j$-i)$*u $+ n)" apply (simp add: zdiff_def zadd_zmult_distrib) apply (simp add: zcompare_rls) apply (simp add: zadd_ac) done ML_file \int_arith.ML\ subsection \examples:\ text \\combine_numerals_prod\ (products of separate literals)\ lemma "#5 $* x $* #3 = y" apply simp oops schematic_goal "y2 $+ ?x42 = y $+ y2" apply simp oops lemma "oo : int \ l $+ (l $+ #2) $+ oo = oo" apply simp oops lemma "#9$*x $+ y = x$*#23 $+ z" apply simp oops lemma "y $+ x = x $+ z" apply simp oops lemma "x : int \ x $+ y $+ z = x $+ z" apply simp oops lemma "x : int \ y $+ (z $+ x) = z $+ x" apply simp oops lemma "z : int \ x $+ y $+ z = (z $+ y) $+ (x $+ w)" apply simp oops lemma "z : int \ x$*y $+ z = (z $+ y) $+ (y$*x $+ w)" apply simp oops lemma "#-3 $* x $+ y $\ x $* #2 $+ z" apply simp oops lemma "y $+ x $\ x $+ z" apply simp oops lemma "x $+ y $+ z $\ x $+ z" apply simp oops lemma "y $+ (z $+ x) $< z $+ x" apply simp oops lemma "x $+ y $+ z $< (z $+ y) $+ (x $+ w)" apply simp oops lemma "x$*y $+ z $< (z $+ y) $+ (y$*x $+ w)" apply simp oops lemma "l $+ #2 $+ #2 $+ #2 $+ (l $+ #2) $+ (oo $+ #2) = uu" apply simp oops lemma "u : int \ #2 $* u = u" apply simp oops lemma "(i $+ j $+ #12 $+ k) $- #15 = y" apply simp oops lemma "(i $+ j $+ #12 $+ k) $- #5 = y" apply simp oops lemma "y $- b $< b" apply simp oops lemma "y $- (#3 $* b $+ c) $< b $- #2 $* c" apply simp oops lemma "(#2 $* x $- (u $* v) $+ y) $- v $* #3 $* u = w" apply simp oops lemma "(#2 $* x $* u $* v $+ (u $* v) $* #4 $+ y) $- v $* u $* #4 = w" apply simp oops lemma "(#2 $* x $* u $* v $+ (u $* v) $* #4 $+ y) $- v $* u = w" apply simp oops lemma "u $* v $- (x $* u $* v $+ (u $* v) $* #4 $+ y) = w" apply simp oops lemma "(i $+ j $+ #12 $+ k) = u $+ #15 $+ y" apply simp oops lemma "(i $+ j $* #2 $+ #12 $+ k) = j $+ #5 $+ y" apply simp oops lemma "#2 $* y $+ #3 $* z $+ #6 $* w $+ #2 $* y $+ #3 $* z $+ #2 $* u = #2 $* y' $+ #3 $* z' $+ #6 $* w' $+ #2 $* y' $+ #3 $* z' $+ u $+ vv" apply simp oops lemma "a $+ $-(b$+c) $+ b = d" apply simp oops lemma "a $+ $-(b$+c) $- b = d" apply simp oops text \negative numerals\ lemma "(i $+ j $+ #-2 $+ k) $- (u $+ #5 $+ y) = zz" apply simp oops lemma "(i $+ j $+ #-3 $+ k) $< u $+ #5 $+ y" apply simp oops lemma "(i $+ j $+ #3 $+ k) $< u $+ #-6 $+ y" apply simp oops lemma "(i $+ j $+ #-12 $+ k) $- #15 = y" apply simp oops lemma "(i $+ j $+ #12 $+ k) $- #-15 = y" apply simp oops lemma "(i $+ j $+ #-12 $+ k) $- #-15 = y" apply simp oops text \Multiplying separated numerals\ lemma "#6 $* ($# x $* #2) = uu" apply simp oops lemma "#4 $* ($# x $* $# x) $* (#2 $* $# x) = uu" apply simp oops end diff --git a/src/ZF/Cardinal.thy b/src/ZF/Cardinal.thy --- a/src/ZF/Cardinal.thy +++ b/src/ZF/Cardinal.thy @@ -1,1180 +1,1180 @@ (* Title: ZF/Cardinal.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Cardinal Numbers Without the Axiom of Choice\ theory Cardinal imports OrderType Finite Nat Sum begin definition (*least ordinal operator*) Least :: "(i\o) \ i" (binder \\ \ 10) where "Least(P) \ THE i. Ord(i) \ P(i) \ (\j. j \P(j))" definition eqpoll :: "[i,i] \ o" (infixl \\\ 50) where "A \ B \ \f. f \ bij(A,B)" definition lepoll :: "[i,i] \ o" (infixl \\\ 50) where "A \ B \ \f. f \ inj(A,B)" definition lesspoll :: "[i,i] \ o" (infixl \\\ 50) where "A \ B \ A \ B \ \(A \ B)" definition cardinal :: "i\i" (\|_|\) where "|A| \ (\ i. i \ A)" definition Finite :: "i\o" where "Finite(A) \ \n\nat. A \ n" definition Card :: "i\o" where "Card(i) \ (i = |i|)" subsection\The Schroeder-Bernstein Theorem\ text\See Davey and Priestly, page 106\ (** Lemma: Banach's Decomposition Theorem **) lemma decomp_bnd_mono: "bnd_mono(X, \W. X - g``(Y - f``W))" by (rule bnd_monoI, blast+) lemma Banach_last_equation: "g \ Y->X \ g``(Y - f`` lfp(X, \W. X - g``(Y - f``W))) = X - lfp(X, \W. X - g``(Y - f``W))" apply (rule_tac P = "\u. v = X-u" for v in decomp_bnd_mono [THEN lfp_unfold, THEN ssubst]) apply (simp add: double_complement fun_is_rel [THEN image_subset]) done lemma decomposition: "\f \ X->Y; g \ Y->X\ \ \XA XB YA YB. (XA \ XB = 0) \ (XA \ XB = X) \ (YA \ YB = 0) \ (YA \ YB = Y) \ f``XA=YA \ g``YB=XB" apply (intro exI conjI) apply (rule_tac [6] Banach_last_equation) apply (rule_tac [5] refl) apply (assumption | rule Diff_disjoint Diff_partition fun_is_rel image_subset lfp_subset)+ done lemma schroeder_bernstein: "\f \ inj(X,Y); g \ inj(Y,X)\ \ \h. h \ bij(X,Y)" apply (insert decomposition [of f X Y g]) apply (simp add: inj_is_fun) apply (blast intro!: restrict_bij bij_disjoint_Un intro: bij_converse_bij) (* The instantiation of exI to @{term"restrict(f,XA) \ converse(restrict(g,YB))"} is forced by the context\*) done (** Equipollence is an equivalence relation **) lemma bij_imp_eqpoll: "f \ bij(A,B) \ A \ B" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (erule exI) done (*A \ A*) lemmas eqpoll_refl = id_bij [THEN bij_imp_eqpoll, simp] lemma eqpoll_sym: "X \ Y \ Y \ X" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (blast intro: bij_converse_bij) done lemma eqpoll_trans [trans]: "\X \ Y; Y \ Z\ \ X \ Z" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (blast intro: comp_bij) done (** Le-pollence is a partial ordering **) lemma subset_imp_lepoll: "X<=Y \ X \ Y" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule exI) apply (erule id_subset_inj) done lemmas lepoll_refl = subset_refl [THEN subset_imp_lepoll, simp] lemmas le_imp_lepoll = le_imp_subset [THEN subset_imp_lepoll] lemma eqpoll_imp_lepoll: "X \ Y \ X \ Y" by (unfold eqpoll_def bij_def lepoll_def, blast) lemma lepoll_trans [trans]: "\X \ Y; Y \ Z\ \ X \ Z" -apply (unfold lepoll_def) + unfolding lepoll_def apply (blast intro: comp_inj) done lemma eq_lepoll_trans [trans]: "\X \ Y; Y \ Z\ \ X \ Z" by (blast intro: eqpoll_imp_lepoll lepoll_trans) lemma lepoll_eq_trans [trans]: "\X \ Y; Y \ Z\ \ X \ Z" by (blast intro: eqpoll_imp_lepoll lepoll_trans) (*Asymmetry law*) lemma eqpollI: "\X \ Y; Y \ X\ \ X \ Y" apply (unfold lepoll_def eqpoll_def) apply (elim exE) apply (rule schroeder_bernstein, assumption+) done lemma eqpollE: "\X \ Y; \X \ Y; Y \ X\ \ P\ \ P" by (blast intro: eqpoll_imp_lepoll eqpoll_sym) lemma eqpoll_iff: "X \ Y \ X \ Y \ Y \ X" by (blast intro: eqpollI elim!: eqpollE) lemma lepoll_0_is_0: "A \ 0 \ A = 0" apply (unfold lepoll_def inj_def) apply (blast dest: apply_type) done (*@{term"0 \ Y"}*) lemmas empty_lepollI = empty_subsetI [THEN subset_imp_lepoll] lemma lepoll_0_iff: "A \ 0 \ A=0" by (blast intro: lepoll_0_is_0 lepoll_refl) lemma Un_lepoll_Un: "\A \ B; C \ D; B \ D = 0\ \ A \ C \ B \ D" -apply (unfold lepoll_def) + unfolding lepoll_def apply (blast intro: inj_disjoint_Un) done (*A \ 0 \ A=0*) lemmas eqpoll_0_is_0 = eqpoll_imp_lepoll [THEN lepoll_0_is_0] lemma eqpoll_0_iff: "A \ 0 \ A=0" by (blast intro: eqpoll_0_is_0 eqpoll_refl) lemma eqpoll_disjoint_Un: "\A \ B; C \ D; A \ C = 0; B \ D = 0\ \ A \ C \ B \ D" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (blast intro: bij_disjoint_Un) done subsection\lesspoll: contributions by Krzysztof Grabczewski\ lemma lesspoll_not_refl: "\ (i \ i)" by (simp add: lesspoll_def) lemma lesspoll_irrefl [elim!]: "i \ i \ P" by (simp add: lesspoll_def) lemma lesspoll_imp_lepoll: "A \ B \ A \ B" by (unfold lesspoll_def, blast) lemma lepoll_well_ord: "\A \ B; well_ord(B,r)\ \ \s. well_ord(A,s)" -apply (unfold lepoll_def) + unfolding lepoll_def apply (blast intro: well_ord_rvimage) done lemma lepoll_iff_leqpoll: "A \ B \ A \ B | A \ B" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (blast intro!: eqpollI elim!: eqpollE) done lemma inj_not_surj_succ: assumes fi: "f \ inj(A, succ(m))" and fns: "f \ surj(A, succ(m))" shows "\f. f \ inj(A,m)" proof - from fi [THEN inj_is_fun] fns obtain y where y: "y \ succ(m)" "\x. x\A \ f ` x \ y" by (auto simp add: surj_def) show ?thesis proof show "(\z\A. if f`z = m then y else f`z) \ inj(A, m)" using y fi by (simp add: inj_def) (auto intro!: if_type [THEN lam_type] intro: Pi_type dest: apply_funtype) qed qed (** Variations on transitivity **) lemma lesspoll_trans [trans]: "\X \ Y; Y \ Z\ \ X \ Z" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (blast elim!: eqpollE intro: eqpollI lepoll_trans) done lemma lesspoll_trans1 [trans]: "\X \ Y; Y \ Z\ \ X \ Z" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (blast elim!: eqpollE intro: eqpollI lepoll_trans) done lemma lesspoll_trans2 [trans]: "\X \ Y; Y \ Z\ \ X \ Z" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (blast elim!: eqpollE intro: eqpollI lepoll_trans) done lemma eq_lesspoll_trans [trans]: "\X \ Y; Y \ Z\ \ X \ Z" by (blast intro: eqpoll_imp_lepoll lesspoll_trans1) lemma lesspoll_eq_trans [trans]: "\X \ Y; Y \ Z\ \ X \ Z" by (blast intro: eqpoll_imp_lepoll lesspoll_trans2) (** \ -- the least number operator [from HOL/Univ.ML] **) lemma Least_equality: "\P(i); Ord(i); \x. x \P(x)\ \ (\ x. P(x)) = i" -apply (unfold Least_def) + unfolding Least_def apply (rule the_equality, blast) apply (elim conjE) apply (erule Ord_linear_lt, assumption, blast+) done lemma LeastI: assumes P: "P(i)" and i: "Ord(i)" shows "P(\ x. P(x))" proof - { from i have "P(i) \ P(\ x. P(x))" proof (induct i rule: trans_induct) case (step i) show ?case proof (cases "P(\ a. P(a))") case True thus ?thesis . next case False hence "\x. x \ i \ \P(x)" using step by blast hence "(\ a. P(a)) = i" using step by (blast intro: Least_equality ltD) thus ?thesis using step.prems by simp qed qed } thus ?thesis using P . qed text\The proof is almost identical to the one above!\ lemma Least_le: assumes P: "P(i)" and i: "Ord(i)" shows "(\ x. P(x)) \ i" proof - { from i have "P(i) \ (\ x. P(x)) \ i" proof (induct i rule: trans_induct) case (step i) show ?case proof (cases "(\ a. P(a)) \ i") case True thus ?thesis . next case False hence "\x. x \ i \ \ (\ a. P(a)) \ i" using step by blast hence "(\ a. P(a)) = i" using step by (blast elim: ltE intro: ltI Least_equality lt_trans1) thus ?thesis using step by simp qed qed } thus ?thesis using P . qed (*\ really is the smallest*) lemma less_LeastE: "\P(i); i < (\ x. P(x))\ \ Q" apply (rule Least_le [THEN [2] lt_trans2, THEN lt_irrefl], assumption+) apply (simp add: lt_Ord) done (*Easier to apply than LeastI: conclusion has only one occurrence of P*) lemma LeastI2: "\P(i); Ord(i); \j. P(j) \ Q(j)\ \ Q(\ j. P(j))" by (blast intro: LeastI ) (*If there is no such P then \ is vacuously 0*) lemma Least_0: "\\ (\i. Ord(i) \ P(i))\ \ (\ x. P(x)) = 0" -apply (unfold Least_def) + unfolding Least_def apply (rule the_0, blast) done lemma Ord_Least [intro,simp,TC]: "Ord(\ x. P(x))" proof (cases "\i. Ord(i) \ P(i)") case True then obtain i where "P(i)" "Ord(i)" by auto hence " (\ x. P(x)) \ i" by (rule Least_le) thus ?thesis by (elim ltE) next case False hence "(\ x. P(x)) = 0" by (rule Least_0) thus ?thesis by auto qed subsection\Basic Properties of Cardinals\ (*Not needed for simplification, but helpful below*) lemma Least_cong: "(\y. P(y) \ Q(y)) \ (\ x. P(x)) = (\ x. Q(x))" by simp (*Need AC to get @{term"X \ Y \ |X| \ |Y|"}; see well_ord_lepoll_imp_cardinal_le Converse also requires AC, but see well_ord_cardinal_eqE*) lemma cardinal_cong: "X \ Y \ |X| = |Y|" apply (unfold eqpoll_def cardinal_def) apply (rule Least_cong) apply (blast intro: comp_bij bij_converse_bij) done (*Under AC, the premise becomes trivial; one consequence is ||A|| = |A|*) lemma well_ord_cardinal_eqpoll: assumes r: "well_ord(A,r)" shows "|A| \ A" proof (unfold cardinal_def) show "(\ i. i \ A) \ A" by (best intro: LeastI Ord_ordertype ordermap_bij bij_converse_bij bij_imp_eqpoll r) qed (* @{term"Ord(A) \ |A| \ A"} *) lemmas Ord_cardinal_eqpoll = well_ord_Memrel [THEN well_ord_cardinal_eqpoll] lemma Ord_cardinal_idem: "Ord(A) \ ||A|| = |A|" by (rule Ord_cardinal_eqpoll [THEN cardinal_cong]) lemma well_ord_cardinal_eqE: assumes woX: "well_ord(X,r)" and woY: "well_ord(Y,s)" and eq: "|X| = |Y|" shows "X \ Y" proof - have "X \ |X|" by (blast intro: well_ord_cardinal_eqpoll [OF woX] eqpoll_sym) also have "... = |Y|" by (rule eq) also have "... \ Y" by (rule well_ord_cardinal_eqpoll [OF woY]) finally show ?thesis . qed lemma well_ord_cardinal_eqpoll_iff: "\well_ord(X,r); well_ord(Y,s)\ \ |X| = |Y| \ X \ Y" by (blast intro: cardinal_cong well_ord_cardinal_eqE) (** Observations from Kunen, page 28 **) lemma Ord_cardinal_le: "Ord(i) \ |i| \ i" -apply (unfold cardinal_def) + unfolding cardinal_def apply (erule eqpoll_refl [THEN Least_le]) done lemma Card_cardinal_eq: "Card(K) \ |K| = K" -apply (unfold Card_def) + unfolding Card_def apply (erule sym) done (* Could replace the @{term"\(j \ i)"} by @{term"\(i \ j)"}. *) lemma CardI: "\Ord(i); \j. j \(j \ i)\ \ Card(i)" apply (unfold Card_def cardinal_def) apply (subst Least_equality) apply (blast intro: eqpoll_refl)+ done lemma Card_is_Ord: "Card(i) \ Ord(i)" apply (unfold Card_def cardinal_def) apply (erule ssubst) apply (rule Ord_Least) done lemma Card_cardinal_le: "Card(K) \ K \ |K|" apply (simp (no_asm_simp) add: Card_is_Ord Card_cardinal_eq) done lemma Ord_cardinal [simp,intro!]: "Ord(|A|)" -apply (unfold cardinal_def) + unfolding cardinal_def apply (rule Ord_Least) done text\The cardinals are the initial ordinals.\ lemma Card_iff_initial: "Card(K) \ Ord(K) \ (\j. j \ j \ K)" proof - { fix j assume K: "Card(K)" "j \ K" assume "j < K" also have "... = (\ i. i \ K)" using K by (simp add: Card_def cardinal_def) finally have "j < (\ i. i \ K)" . hence "False" using K by (best dest: less_LeastE) } then show ?thesis by (blast intro: CardI Card_is_Ord) qed lemma lt_Card_imp_lesspoll: "\Card(a); i \ i \ a" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (drule Card_iff_initial [THEN iffD1]) apply (blast intro!: leI [THEN le_imp_lepoll]) done lemma Card_0: "Card(0)" apply (rule Ord_0 [THEN CardI]) apply (blast elim!: ltE) done lemma Card_Un: "\Card(K); Card(L)\ \ Card(K \ L)" apply (rule Ord_linear_le [of K L]) apply (simp_all add: subset_Un_iff [THEN iffD1] Card_is_Ord le_imp_subset subset_Un_iff2 [THEN iffD1]) done (*Infinite unions of cardinals? See Devlin, Lemma 6.7, page 98*) lemma Card_cardinal [iff]: "Card(|A|)" proof (unfold cardinal_def) show "Card(\ i. i \ A)" proof (cases "\i. Ord (i) \ i \ A") case False thus ?thesis \ \degenerate case\ by (simp add: Least_0 Card_0) next case True \ \real case: \<^term>\A\ is isomorphic to some ordinal\ then obtain i where i: "Ord(i)" "i \ A" by blast show ?thesis proof (rule CardI [OF Ord_Least], rule notI) fix j assume j: "j < (\ i. i \ A)" assume "j \ (\ i. i \ A)" also have "... \ A" using i by (auto intro: LeastI) finally have "j \ A" . thus False by (rule less_LeastE [OF _ j]) qed qed qed (*Kunen's Lemma 10.5*) lemma cardinal_eq_lemma: assumes i:"|i| \ j" and j: "j \ i" shows "|j| = |i|" proof (rule eqpollI [THEN cardinal_cong]) show "j \ i" by (rule le_imp_lepoll [OF j]) next have Oi: "Ord(i)" using j by (rule le_Ord2) hence "i \ |i|" by (blast intro: Ord_cardinal_eqpoll eqpoll_sym) also have "... \ j" by (blast intro: le_imp_lepoll i) finally show "i \ j" . qed lemma cardinal_mono: assumes ij: "i \ j" shows "|i| \ |j|" using Ord_cardinal [of i] Ord_cardinal [of j] proof (cases rule: Ord_linear_le) case le thus ?thesis . next case ge have i: "Ord(i)" using ij by (simp add: lt_Ord) have ci: "|i| \ j" by (blast intro: Ord_cardinal_le ij le_trans i) have "|i| = ||i||" by (auto simp add: Ord_cardinal_idem i) also have "... = |j|" by (rule cardinal_eq_lemma [OF ge ci]) finally have "|i| = |j|" . thus ?thesis by simp qed text\Since we have \<^term>\|succ(nat)| \ |nat|\, the converse of \cardinal_mono\ fails!\ lemma cardinal_lt_imp_lt: "\|i| < |j|; Ord(i); Ord(j)\ \ i < j" apply (rule Ord_linear2 [of i j], assumption+) apply (erule lt_trans2 [THEN lt_irrefl]) apply (erule cardinal_mono) done lemma Card_lt_imp_lt: "\|i| < K; Ord(i); Card(K)\ \ i < K" by (simp (no_asm_simp) add: cardinal_lt_imp_lt Card_is_Ord Card_cardinal_eq) lemma Card_lt_iff: "\Ord(i); Card(K)\ \ (|i| < K) \ (i < K)" by (blast intro: Card_lt_imp_lt Ord_cardinal_le [THEN lt_trans1]) lemma Card_le_iff: "\Ord(i); Card(K)\ \ (K \ |i|) \ (K \ i)" by (simp add: Card_lt_iff Card_is_Ord Ord_cardinal not_lt_iff_le [THEN iff_sym]) (*Can use AC or finiteness to discharge first premise*) lemma well_ord_lepoll_imp_cardinal_le: assumes wB: "well_ord(B,r)" and AB: "A \ B" shows "|A| \ |B|" using Ord_cardinal [of A] Ord_cardinal [of B] proof (cases rule: Ord_linear_le) case le thus ?thesis . next case ge from lepoll_well_ord [OF AB wB] obtain s where s: "well_ord(A, s)" by blast have "B \ |B|" by (blast intro: wB eqpoll_sym well_ord_cardinal_eqpoll) also have "... \ |A|" by (rule le_imp_lepoll [OF ge]) also have "... \ A" by (rule well_ord_cardinal_eqpoll [OF s]) finally have "B \ A" . hence "A \ B" by (blast intro: eqpollI AB) hence "|A| = |B|" by (rule cardinal_cong) thus ?thesis by simp qed lemma lepoll_cardinal_le: "\A \ i; Ord(i)\ \ |A| \ i" apply (rule le_trans) apply (erule well_ord_Memrel [THEN well_ord_lepoll_imp_cardinal_le], assumption) apply (erule Ord_cardinal_le) done lemma lepoll_Ord_imp_eqpoll: "\A \ i; Ord(i)\ \ |A| \ A" by (blast intro: lepoll_cardinal_le well_ord_Memrel well_ord_cardinal_eqpoll dest!: lepoll_well_ord) lemma lesspoll_imp_eqpoll: "\A \ i; Ord(i)\ \ |A| \ A" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (blast intro: lepoll_Ord_imp_eqpoll) done lemma cardinal_subset_Ord: "\A<=i; Ord(i)\ \ |A| \ i" apply (drule subset_imp_lepoll [THEN lepoll_cardinal_le]) apply (auto simp add: lt_def) apply (blast intro: Ord_trans) done subsection\The finite cardinals\ lemma cons_lepoll_consD: "\cons(u,A) \ cons(v,B); u\A; v\B\ \ A \ B" apply (unfold lepoll_def inj_def, safe) apply (rule_tac x = "\x\A. if f`x=v then f`u else f`x" in exI) apply (rule CollectI) (*Proving it's in the function space A->B*) apply (rule if_type [THEN lam_type]) apply (blast dest: apply_funtype) apply (blast elim!: mem_irrefl dest: apply_funtype) (*Proving it's injective*) apply (simp (no_asm_simp)) apply blast done lemma cons_eqpoll_consD: "\cons(u,A) \ cons(v,B); u\A; v\B\ \ A \ B" apply (simp add: eqpoll_iff) apply (blast intro: cons_lepoll_consD) done (*Lemma suggested by Mike Fourman*) lemma succ_lepoll_succD: "succ(m) \ succ(n) \ m \ n" -apply (unfold succ_def) + unfolding succ_def apply (erule cons_lepoll_consD) apply (rule mem_not_refl)+ done lemma nat_lepoll_imp_le: "m \ nat \ n \ nat \ m \ n \ m \ n" proof (induct m arbitrary: n rule: nat_induct) case 0 thus ?case by (blast intro!: nat_0_le) next case (succ m) show ?case using \n \ nat\ proof (cases rule: natE) case 0 thus ?thesis using succ by (simp add: lepoll_def inj_def) next case (succ n') thus ?thesis using succ.hyps \ succ(m) \ n\ by (blast intro!: succ_leI dest!: succ_lepoll_succD) qed qed lemma nat_eqpoll_iff: "\m \ nat; n \ nat\ \ m \ n \ m = n" apply (rule iffI) apply (blast intro: nat_lepoll_imp_le le_anti_sym elim!: eqpollE) apply (simp add: eqpoll_refl) done (*The object of all this work: every natural number is a (finite) cardinal*) lemma nat_into_Card: assumes n: "n \ nat" shows "Card(n)" proof (unfold Card_def cardinal_def, rule sym) have "Ord(n)" using n by auto moreover { fix i assume "i < n" "i \ n" hence False using n by (auto simp add: lt_nat_in_nat [THEN nat_eqpoll_iff]) } ultimately show "(\ i. i \ n) = n" by (auto intro!: Least_equality) qed lemmas cardinal_0 = nat_0I [THEN nat_into_Card, THEN Card_cardinal_eq, iff] lemmas cardinal_1 = nat_1I [THEN nat_into_Card, THEN Card_cardinal_eq, iff] (*Part of Kunen's Lemma 10.6*) lemma succ_lepoll_natE: "\succ(n) \ n; n \ nat\ \ P" by (rule nat_lepoll_imp_le [THEN lt_irrefl], auto) lemma nat_lepoll_imp_ex_eqpoll_n: "\n \ nat; nat \ X\ \ \Y. Y \ X \ n \ Y" apply (unfold lepoll_def eqpoll_def) apply (fast del: subsetI subsetCE intro!: subset_SIs dest!: Ord_nat [THEN [2] OrdmemD, THEN [2] restrict_inj] elim!: restrict_bij inj_is_fun [THEN fun_is_rel, THEN image_subset]) done (** \, \ and natural numbers **) lemma lepoll_succ: "i \ succ(i)" by (blast intro: subset_imp_lepoll) lemma lepoll_imp_lesspoll_succ: assumes A: "A \ m" and m: "m \ nat" shows "A \ succ(m)" proof - { assume "A \ succ(m)" hence "succ(m) \ A" by (rule eqpoll_sym) also have "... \ m" by (rule A) finally have "succ(m) \ m" . hence False by (rule succ_lepoll_natE) (rule m) } moreover have "A \ succ(m)" by (blast intro: lepoll_trans A lepoll_succ) ultimately show ?thesis by (auto simp add: lesspoll_def) qed lemma lesspoll_succ_imp_lepoll: "\A \ succ(m); m \ nat\ \ A \ m" apply (unfold lesspoll_def lepoll_def eqpoll_def bij_def) apply (auto dest: inj_not_surj_succ) done lemma lesspoll_succ_iff: "m \ nat \ A \ succ(m) \ A \ m" by (blast intro!: lepoll_imp_lesspoll_succ lesspoll_succ_imp_lepoll) lemma lepoll_succ_disj: "\A \ succ(m); m \ nat\ \ A \ m | A \ succ(m)" apply (rule disjCI) apply (rule lesspoll_succ_imp_lepoll) prefer 2 apply assumption apply (simp (no_asm_simp) add: lesspoll_def) done lemma lesspoll_cardinal_lt: "\A \ i; Ord(i)\ \ |A| < i" apply (unfold lesspoll_def, clarify) apply (frule lepoll_cardinal_le, assumption) apply (blast intro: well_ord_Memrel well_ord_cardinal_eqpoll [THEN eqpoll_sym] dest: lepoll_well_ord elim!: leE) done subsection\The first infinite cardinal: Omega, or nat\ (*This implies Kunen's Lemma 10.6*) lemma lt_not_lepoll: assumes n: "n nat" shows "\ i \ n" proof - { assume i: "i \ n" have "succ(n) \ i" using n by (elim ltE, blast intro: Ord_succ_subsetI [THEN subset_imp_lepoll]) also have "... \ n" by (rule i) finally have "succ(n) \ n" . hence False by (rule succ_lepoll_natE) (rule n) } thus ?thesis by auto qed text\A slightly weaker version of \nat_eqpoll_iff\\ lemma Ord_nat_eqpoll_iff: assumes i: "Ord(i)" and n: "n \ nat" shows "i \ n \ i=n" using i nat_into_Ord [OF n] proof (cases rule: Ord_linear_lt) case lt hence "i \ nat" by (rule lt_nat_in_nat) (rule n) thus ?thesis by (simp add: nat_eqpoll_iff n) next case eq thus ?thesis by (simp add: eqpoll_refl) next case gt hence "\ i \ n" using n by (rule lt_not_lepoll) hence "\ i \ n" using n by (blast intro: eqpoll_imp_lepoll) moreover have "i \ n" using \n by auto ultimately show ?thesis by blast qed lemma Card_nat: "Card(nat)" proof - { fix i assume i: "i < nat" "i \ nat" hence "\ nat \ i" by (simp add: lt_def lt_not_lepoll) hence False using i by (simp add: eqpoll_iff) } hence "(\ i. i \ nat) = nat" by (blast intro: Least_equality eqpoll_refl) thus ?thesis by (auto simp add: Card_def cardinal_def) qed (*Allows showing that |i| is a limit cardinal*) lemma nat_le_cardinal: "nat \ i \ nat \ |i|" apply (rule Card_nat [THEN Card_cardinal_eq, THEN subst]) apply (erule cardinal_mono) done lemma n_lesspoll_nat: "n \ nat \ n \ nat" by (blast intro: Ord_nat Card_nat ltI lt_Card_imp_lesspoll) subsection\Towards Cardinal Arithmetic\ (** Congruence laws for successor, cardinal addition and multiplication **) (*Congruence law for cons under equipollence*) lemma cons_lepoll_cong: "\A \ B; b \ B\ \ cons(a,A) \ cons(b,B)" apply (unfold lepoll_def, safe) apply (rule_tac x = "\y\cons (a,A) . if y=a then b else f`y" in exI) apply (rule_tac d = "\z. if z \ B then converse (f) `z else a" in lam_injective) apply (safe elim!: consE') apply simp_all apply (blast intro: inj_is_fun [THEN apply_type])+ done lemma cons_eqpoll_cong: "\A \ B; a \ A; b \ B\ \ cons(a,A) \ cons(b,B)" by (simp add: eqpoll_iff cons_lepoll_cong) lemma cons_lepoll_cons_iff: "\a \ A; b \ B\ \ cons(a,A) \ cons(b,B) \ A \ B" by (blast intro: cons_lepoll_cong cons_lepoll_consD) lemma cons_eqpoll_cons_iff: "\a \ A; b \ B\ \ cons(a,A) \ cons(b,B) \ A \ B" by (blast intro: cons_eqpoll_cong cons_eqpoll_consD) lemma singleton_eqpoll_1: "{a} \ 1" -apply (unfold succ_def) + unfolding succ_def apply (blast intro!: eqpoll_refl [THEN cons_eqpoll_cong]) done lemma cardinal_singleton: "|{a}| = 1" apply (rule singleton_eqpoll_1 [THEN cardinal_cong, THEN trans]) apply (simp (no_asm) add: nat_into_Card [THEN Card_cardinal_eq]) done lemma not_0_is_lepoll_1: "A \ 0 \ 1 \ A" apply (erule not_emptyE) apply (rule_tac a = "cons (x, A-{x}) " in subst) apply (rule_tac [2] a = "cons(0,0)" and P= "\y. y \ cons (x, A-{x})" in subst) prefer 3 apply (blast intro: cons_lepoll_cong subset_imp_lepoll, auto) done (*Congruence law for succ under equipollence*) lemma succ_eqpoll_cong: "A \ B \ succ(A) \ succ(B)" -apply (unfold succ_def) + unfolding succ_def apply (simp add: cons_eqpoll_cong mem_not_refl) done (*Congruence law for + under equipollence*) lemma sum_eqpoll_cong: "\A \ C; B \ D\ \ A+B \ C+D" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (blast intro!: sum_bij) done (*Congruence law for * under equipollence*) lemma prod_eqpoll_cong: "\A \ C; B \ D\ \ A*B \ C*D" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (blast intro!: prod_bij) done lemma inj_disjoint_eqpoll: "\f \ inj(A,B); A \ B = 0\ \ A \ (B - range(f)) \ B" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule_tac c = "\x. if x \ A then f`x else x" and d = "\y. if y \ range (f) then converse (f) `y else y" in lam_bijective) apply (blast intro!: if_type inj_is_fun [THEN apply_type]) apply (simp (no_asm_simp) add: inj_converse_fun [THEN apply_funtype]) apply (safe elim!: UnE') apply (simp_all add: inj_is_fun [THEN apply_rangeI]) apply (blast intro: inj_converse_fun [THEN apply_type])+ done subsection\Lemmas by Krzysztof Grabczewski\ (*New proofs using cons_lepoll_cons. Could generalise from succ to cons.*) text\If \<^term>\A\ has at most \<^term>\n+1\ elements and \<^term>\a \ A\ then \<^term>\A-{a}\ has at most \<^term>\n\.\ lemma Diff_sing_lepoll: "\a \ A; A \ succ(n)\ \ A - {a} \ n" -apply (unfold succ_def) + unfolding succ_def apply (rule cons_lepoll_consD) apply (rule_tac [3] mem_not_refl) apply (erule cons_Diff [THEN ssubst], safe) done text\If \<^term>\A\ has at least \<^term>\n+1\ elements then \<^term>\A-{a}\ has at least \<^term>\n\.\ lemma lepoll_Diff_sing: assumes A: "succ(n) \ A" shows "n \ A - {a}" proof - have "cons(n,n) \ A" using A by (unfold succ_def) also have "... \ cons(a, A-{a})" by (blast intro: subset_imp_lepoll) finally have "cons(n,n) \ cons(a, A-{a})" . thus ?thesis by (blast intro: cons_lepoll_consD mem_irrefl) qed lemma Diff_sing_eqpoll: "\a \ A; A \ succ(n)\ \ A - {a} \ n" by (blast intro!: eqpollI elim!: eqpollE intro: Diff_sing_lepoll lepoll_Diff_sing) lemma lepoll_1_is_sing: "\A \ 1; a \ A\ \ A = {a}" apply (frule Diff_sing_lepoll, assumption) apply (drule lepoll_0_is_0) apply (blast elim: equalityE) done lemma Un_lepoll_sum: "A \ B \ A+B" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule_tac x = "\x\A \ B. if x\A then Inl (x) else Inr (x)" in exI) apply (rule_tac d = "\z. snd (z)" in lam_injective) apply force apply (simp add: Inl_def Inr_def) done lemma well_ord_Un: "\well_ord(X,R); well_ord(Y,S)\ \ \T. well_ord(X \ Y, T)" by (erule well_ord_radd [THEN Un_lepoll_sum [THEN lepoll_well_ord]], assumption) (*Krzysztof Grabczewski*) lemma disj_Un_eqpoll_sum: "A \ B = 0 \ A \ B \ A + B" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule_tac x = "\a\A \ B. if a \ A then Inl (a) else Inr (a)" in exI) apply (rule_tac d = "\z. case (\x. x, \x. x, z)" in lam_bijective) apply auto done subsection \Finite and infinite sets\ lemma eqpoll_imp_Finite_iff: "A \ B \ Finite(A) \ Finite(B)" -apply (unfold Finite_def) + unfolding Finite_def apply (blast intro: eqpoll_trans eqpoll_sym) done lemma Finite_0 [simp]: "Finite(0)" -apply (unfold Finite_def) + unfolding Finite_def apply (blast intro!: eqpoll_refl nat_0I) done lemma Finite_cons: "Finite(x) \ Finite(cons(y,x))" -apply (unfold Finite_def) + unfolding Finite_def apply (case_tac "y \ x") apply (simp add: cons_absorb) apply (erule bexE) apply (rule bexI) apply (erule_tac [2] nat_succI) apply (simp (no_asm_simp) add: succ_def cons_eqpoll_cong mem_not_refl) done lemma Finite_succ: "Finite(x) \ Finite(succ(x))" -apply (unfold succ_def) + unfolding succ_def apply (erule Finite_cons) done lemma lepoll_nat_imp_Finite: assumes A: "A \ n" and n: "n \ nat" shows "Finite(A)" proof - have "A \ n \ Finite(A)" using n proof (induct n) case 0 hence "A = 0" by (rule lepoll_0_is_0) thus ?case by simp next case (succ n) hence "A \ n \ A \ succ(n)" by (blast dest: lepoll_succ_disj) thus ?case using succ by (auto simp add: Finite_def) qed thus ?thesis using A . qed lemma lesspoll_nat_is_Finite: "A \ nat \ Finite(A)" -apply (unfold Finite_def) + unfolding Finite_def apply (blast dest: ltD lesspoll_cardinal_lt lesspoll_imp_eqpoll [THEN eqpoll_sym]) done lemma lepoll_Finite: assumes Y: "Y \ X" and X: "Finite(X)" shows "Finite(Y)" proof - obtain n where n: "n \ nat" "X \ n" using X by (auto simp add: Finite_def) have "Y \ X" by (rule Y) also have "... \ n" by (rule n) finally have "Y \ n" . thus ?thesis using n by (simp add: lepoll_nat_imp_Finite) qed lemmas subset_Finite = subset_imp_lepoll [THEN lepoll_Finite] lemma Finite_cons_iff [iff]: "Finite(cons(y,x)) \ Finite(x)" by (blast intro: Finite_cons subset_Finite) lemma Finite_succ_iff [iff]: "Finite(succ(x)) \ Finite(x)" by (simp add: succ_def) lemma Finite_Int: "Finite(A) | Finite(B) \ Finite(A \ B)" by (blast intro: subset_Finite) lemmas Finite_Diff = Diff_subset [THEN subset_Finite] lemma nat_le_infinite_Ord: "\Ord(i); \ Finite(i)\ \ nat \ i" -apply (unfold Finite_def) + unfolding Finite_def apply (erule Ord_nat [THEN [2] Ord_linear2]) prefer 2 apply assumption apply (blast intro!: eqpoll_refl elim!: ltE) done lemma Finite_imp_well_ord: "Finite(A) \ \r. well_ord(A,r)" apply (unfold Finite_def eqpoll_def) apply (blast intro: well_ord_rvimage bij_is_inj well_ord_Memrel nat_into_Ord) done lemma succ_lepoll_imp_not_empty: "succ(x) \ y \ y \ 0" by (fast dest!: lepoll_0_is_0) lemma eqpoll_succ_imp_not_empty: "x \ succ(n) \ x \ 0" by (fast elim!: eqpoll_sym [THEN eqpoll_0_is_0, THEN succ_neq_0]) lemma Finite_Fin_lemma [rule_format]: "n \ nat \ \A. (A\n \ A \ X) \ A \ Fin(X)" apply (induct_tac n) apply (rule allI) apply (fast intro!: Fin.emptyI dest!: eqpoll_imp_lepoll [THEN lepoll_0_is_0]) apply (rule allI) apply (rule impI) apply (erule conjE) apply (rule eqpoll_succ_imp_not_empty [THEN not_emptyE], assumption) apply (frule Diff_sing_eqpoll, assumption) apply (erule allE) apply (erule impE, fast) apply (drule subsetD, assumption) apply (drule Fin.consI, assumption) apply (simp add: cons_Diff) done lemma Finite_Fin: "\Finite(A); A \ X\ \ A \ Fin(X)" by (unfold Finite_def, blast intro: Finite_Fin_lemma) lemma Fin_lemma [rule_format]: "n \ nat \ \A. A \ n \ A \ Fin(A)" apply (induct_tac n) apply (simp add: eqpoll_0_iff, clarify) apply (subgoal_tac "\u. u \ A") apply (erule exE) apply (rule Diff_sing_eqpoll [elim_format]) prefer 2 apply assumption apply assumption apply (rule_tac b = A in cons_Diff [THEN subst], assumption) apply (rule Fin.consI, blast) apply (blast intro: subset_consI [THEN Fin_mono, THEN subsetD]) (*Now for the lemma assumed above*) -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (blast intro: bij_converse_bij [THEN bij_is_fun, THEN apply_type]) done lemma Finite_into_Fin: "Finite(A) \ A \ Fin(A)" -apply (unfold Finite_def) + unfolding Finite_def apply (blast intro: Fin_lemma) done lemma Fin_into_Finite: "A \ Fin(U) \ Finite(A)" by (fast intro!: Finite_0 Finite_cons elim: Fin_induct) lemma Finite_Fin_iff: "Finite(A) \ A \ Fin(A)" by (blast intro: Finite_into_Fin Fin_into_Finite) lemma Finite_Un: "\Finite(A); Finite(B)\ \ Finite(A \ B)" by (blast intro!: Fin_into_Finite Fin_UnI dest!: Finite_into_Fin intro: Un_upper1 [THEN Fin_mono, THEN subsetD] Un_upper2 [THEN Fin_mono, THEN subsetD]) lemma Finite_Un_iff [simp]: "Finite(A \ B) \ (Finite(A) \ Finite(B))" by (blast intro: subset_Finite Finite_Un) text\The converse must hold too.\ lemma Finite_Union: "\\y\X. Finite(y); Finite(X)\ \ Finite(\(X))" apply (simp add: Finite_Fin_iff) apply (rule Fin_UnionI) apply (erule Fin_induct, simp) apply (blast intro: Fin.consI Fin_mono [THEN [2] rev_subsetD]) done (* Induction principle for Finite(A), by Sidi Ehmety *) lemma Finite_induct [case_names 0 cons, induct set: Finite]: "\Finite(A); P(0); \x B. \Finite(B); x \ B; P(B)\ \ P(cons(x, B))\ \ P(A)" apply (erule Finite_into_Fin [THEN Fin_induct]) apply (blast intro: Fin_into_Finite)+ done (*Sidi Ehmety. The contrapositive says \Finite(A) \ \Finite(A-{a}) *) lemma Diff_sing_Finite: "Finite(A - {a}) \ Finite(A)" -apply (unfold Finite_def) + unfolding Finite_def apply (case_tac "a \ A") apply (subgoal_tac [2] "A-{a}=A", auto) apply (rule_tac x = "succ (n) " in bexI) apply (subgoal_tac "cons (a, A - {a}) = A \ cons (n, n) = succ (n) ") apply (drule_tac a = a and b = n in cons_eqpoll_cong) apply (auto dest: mem_irrefl) done (*Sidi Ehmety. And the contrapositive of this says \\Finite(A); Finite(B)\ \ \Finite(A-B) *) lemma Diff_Finite [rule_format]: "Finite(B) \ Finite(A-B) \ Finite(A)" apply (erule Finite_induct, auto) apply (case_tac "x \ A") apply (subgoal_tac [2] "A-cons (x, B) = A - B") apply (subgoal_tac "A - cons (x, B) = (A - B) - {x}", simp) apply (drule Diff_sing_Finite, auto) done lemma Finite_RepFun: "Finite(A) \ Finite(RepFun(A,f))" by (erule Finite_induct, simp_all) lemma Finite_RepFun_iff_lemma [rule_format]: "\Finite(x); \x y. f(x)=f(y) \ x=y\ \ \A. x = RepFun(A,f) \ Finite(A)" apply (erule Finite_induct) apply clarify apply (case_tac "A=0", simp) apply (blast del: allE, clarify) apply (subgoal_tac "\z\A. x = f(z)") prefer 2 apply (blast del: allE elim: equalityE, clarify) apply (subgoal_tac "B = {f(u) . u \ A - {z}}") apply (blast intro: Diff_sing_Finite) apply (thin_tac "\A. P(A) \ Finite(A)" for P) apply (rule equalityI) apply (blast intro: elim: equalityE) apply (blast intro: elim: equalityCE) done text\I don't know why, but if the premise is expressed using meta-connectives then the simplifier cannot prove it automatically in conditional rewriting.\ lemma Finite_RepFun_iff: "(\x y. f(x)=f(y) \ x=y) \ Finite(RepFun(A,f)) \ Finite(A)" by (blast intro: Finite_RepFun Finite_RepFun_iff_lemma [of _ f]) lemma Finite_Pow: "Finite(A) \ Finite(Pow(A))" apply (erule Finite_induct) apply (simp_all add: Pow_insert Finite_Un Finite_RepFun) done lemma Finite_Pow_imp_Finite: "Finite(Pow(A)) \ Finite(A)" apply (subgoal_tac "Finite({{x} . x \ A})") apply (simp add: Finite_RepFun_iff ) apply (blast intro: subset_Finite) done lemma Finite_Pow_iff [iff]: "Finite(Pow(A)) \ Finite(A)" by (blast intro: Finite_Pow Finite_Pow_imp_Finite) lemma Finite_cardinal_iff: assumes i: "Ord(i)" shows "Finite(|i|) \ Finite(i)" by (auto simp add: Finite_def) (blast intro: eqpoll_trans eqpoll_sym Ord_cardinal_eqpoll [OF i])+ (*Krzysztof Grabczewski's proof that the converse of a finite, well-ordered set is well-ordered. Proofs simplified by lcp. *) lemma nat_wf_on_converse_Memrel: "n \ nat \ wf[n](converse(Memrel(n)))" proof (induct n rule: nat_induct) case 0 thus ?case by (blast intro: wf_onI) next case (succ x) hence wfx: "\Z. Z = 0 \ (\z\Z. \y. z \ y \ z \ x \ y \ x \ z \ x \ y \ Z)" by (simp add: wf_on_def wf_def) \ \not easy to erase the duplicate \<^term>\z \ x\!\ show ?case proof (rule wf_onI) fix Z u assume Z: "u \ Z" "\z\Z. \y\Z. \y, z\ \ converse(Memrel(succ(x)))" show False proof (cases "x \ Z") case True thus False using Z by (blast elim: mem_irrefl mem_asym) next case False thus False using wfx [of Z] Z by blast qed qed qed lemma nat_well_ord_converse_Memrel: "n \ nat \ well_ord(n,converse(Memrel(n)))" apply (frule Ord_nat [THEN Ord_in_Ord, THEN well_ord_Memrel]) apply (simp add: well_ord_def tot_ord_converse nat_wf_on_converse_Memrel) done lemma well_ord_converse: "\well_ord(A,r); well_ord(ordertype(A,r), converse(Memrel(ordertype(A, r))))\ \ well_ord(A,converse(r))" apply (rule well_ord_Int_iff [THEN iffD1]) apply (frule ordermap_bij [THEN bij_is_inj, THEN well_ord_rvimage], assumption) apply (simp add: rvimage_converse converse_Int converse_prod ordertype_ord_iso [THEN ord_iso_rvimage_eq]) done lemma ordertype_eq_n: assumes r: "well_ord(A,r)" and A: "A \ n" and n: "n \ nat" shows "ordertype(A,r) = n" proof - have "ordertype(A,r) \ A" by (blast intro: bij_imp_eqpoll bij_converse_bij ordermap_bij r) also have "... \ n" by (rule A) finally have "ordertype(A,r) \ n" . thus ?thesis by (simp add: Ord_nat_eqpoll_iff Ord_ordertype n r) qed lemma Finite_well_ord_converse: "\Finite(A); well_ord(A,r)\ \ well_ord(A,converse(r))" -apply (unfold Finite_def) + unfolding Finite_def apply (rule well_ord_converse, assumption) apply (blast dest: ordertype_eq_n intro!: nat_well_ord_converse_Memrel) done lemma nat_into_Finite: "n \ nat \ Finite(n)" by (auto simp add: Finite_def intro: eqpoll_refl) lemma nat_not_Finite: "\ Finite(nat)" proof - { fix n assume n: "n \ nat" "nat \ n" have "n \ nat" by (rule n) also have "... = n" using n by (simp add: Ord_nat_eqpoll_iff Ord_nat) finally have "n \ n" . hence False by (blast elim: mem_irrefl) } thus ?thesis by (auto simp add: Finite_def) qed end diff --git a/src/ZF/CardinalArith.thy b/src/ZF/CardinalArith.thy --- a/src/ZF/CardinalArith.thy +++ b/src/ZF/CardinalArith.thy @@ -1,940 +1,940 @@ (* Title: ZF/CardinalArith.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Cardinal Arithmetic Without the Axiom of Choice\ theory CardinalArith imports Cardinal OrderArith ArithSimp Finite begin definition InfCard :: "i\o" where "InfCard(i) \ Card(i) \ nat \ i" definition cmult :: "[i,i]\i" (infixl \\\ 70) where "i \ j \ |i*j|" definition cadd :: "[i,i]\i" (infixl \\\ 65) where "i \ j \ |i+j|" definition csquare_rel :: "i\i" where "csquare_rel(K) \ rvimage(K*K, lam \x,y\:K*K. y, x, y>, rmult(K,Memrel(K), K*K, rmult(K,Memrel(K), K,Memrel(K))))" definition jump_cardinal :: "i\i" where \ \This definition is more complex than Kunen's but it more easily proved to be a cardinal\ "jump_cardinal(K) \ \X\Pow(K). {z. r \ Pow(K*K), well_ord(X,r) \ z = ordertype(X,r)}" definition csucc :: "i\i" where \ \needed because \<^term>\jump_cardinal(K)\ might not be the successor of \<^term>\K\\ "csucc(K) \ \ L. Card(L) \ Kx. x\A \ Card(x)" shows "Card(\(A))" proof (rule CardI) show "Ord(\A)" using A by (simp add: Card_is_Ord) next fix j assume j: "j < \A" hence "\c\A. j < c \ Card(c)" using A by (auto simp add: lt_def intro: Card_is_Ord) then obtain c where c: "c\A" "j < c" "Card(c)" by blast hence jls: "j \ c" by (simp add: lt_Card_imp_lesspoll) { assume eqp: "j \ \A" have "c \ \A" using c by (blast intro: subset_imp_lepoll) also have "... \ j" by (rule eqpoll_sym [OF eqp]) also have "... \ c" by (rule jls) finally have "c \ c" . hence False by auto } thus "\ j \ \A" by blast qed lemma Card_UN: "(\x. x \ A \ Card(K(x))) \ Card(\x\A. K(x))" by blast lemma Card_OUN [simp,intro,TC]: "(\x. x \ A \ Card(K(x))) \ Card(\xCard(K); b \ K\ \ b \ K" -apply (unfold lesspoll_def) + unfolding lesspoll_def apply (simp add: Card_iff_initial) apply (fast intro!: le_imp_lepoll ltI leI) done subsection\Cardinal addition\ text\Note: Could omit proving the algebraic laws for cardinal addition and multiplication. On finite cardinals these operations coincide with addition and multiplication of natural numbers; on infinite cardinals they coincide with union (maximum). Either way we get most laws for free.\ subsubsection\Cardinal addition is commutative\ lemma sum_commute_eqpoll: "A+B \ B+A" proof (unfold eqpoll_def, rule exI) show "(\z\A+B. case(Inr,Inl,z)) \ bij(A+B, B+A)" by (auto intro: lam_bijective [where d = "case(Inr,Inl)"]) qed lemma cadd_commute: "i \ j = j \ i" -apply (unfold cadd_def) + unfolding cadd_def apply (rule sum_commute_eqpoll [THEN cardinal_cong]) done subsubsection\Cardinal addition is associative\ lemma sum_assoc_eqpoll: "(A+B)+C \ A+(B+C)" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule sum_assoc_bij) done text\Unconditional version requires AC\ lemma well_ord_cadd_assoc: assumes i: "well_ord(i,ri)" and j: "well_ord(j,rj)" and k: "well_ord(k,rk)" shows "(i \ j) \ k = i \ (j \ k)" proof (unfold cadd_def, rule cardinal_cong) have "|i + j| + k \ (i + j) + k" by (blast intro: sum_eqpoll_cong well_ord_cardinal_eqpoll eqpoll_refl well_ord_radd i j) also have "... \ i + (j + k)" by (rule sum_assoc_eqpoll) also have "... \ i + |j + k|" by (blast intro: sum_eqpoll_cong well_ord_cardinal_eqpoll eqpoll_refl well_ord_radd j k eqpoll_sym) finally show "|i + j| + k \ i + |j + k|" . qed subsubsection\0 is the identity for addition\ lemma sum_0_eqpoll: "0+A \ A" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule bij_0_sum) done lemma cadd_0 [simp]: "Card(K) \ 0 \ K = K" -apply (unfold cadd_def) + unfolding cadd_def apply (simp add: sum_0_eqpoll [THEN cardinal_cong] Card_cardinal_eq) done subsubsection\Addition by another cardinal\ lemma sum_lepoll_self: "A \ A+B" proof (unfold lepoll_def, rule exI) show "(\x\A. Inl (x)) \ inj(A, A + B)" by (simp add: inj_def) qed (*Could probably weaken the premises to well_ord(K,r), or removing using AC*) lemma cadd_le_self: assumes K: "Card(K)" and L: "Ord(L)" shows "K \ (K \ L)" proof (unfold cadd_def) have "K \ |K|" by (rule Card_cardinal_le [OF K]) moreover have "|K| \ |K + L|" using K L by (blast intro: well_ord_lepoll_imp_cardinal_le sum_lepoll_self well_ord_radd well_ord_Memrel Card_is_Ord) ultimately show "K \ |K + L|" by (blast intro: le_trans) qed subsubsection\Monotonicity of addition\ lemma sum_lepoll_mono: "\A \ C; B \ D\ \ A + B \ C + D" -apply (unfold lepoll_def) + unfolding lepoll_def apply (elim exE) apply (rule_tac x = "\z\A+B. case (\w. Inl(f`w), \y. Inr(fa`y), z)" in exI) apply (rule_tac d = "case (\w. Inl(converse(f) `w), \y. Inr(converse(fa) ` y))" in lam_injective) apply (typecheck add: inj_is_fun, auto) done lemma cadd_le_mono: "\K' \ K; L' \ L\ \ (K' \ L') \ (K \ L)" -apply (unfold cadd_def) + unfolding cadd_def apply (safe dest!: le_subset_iff [THEN iffD1]) apply (rule well_ord_lepoll_imp_cardinal_le) apply (blast intro: well_ord_radd well_ord_Memrel) apply (blast intro: sum_lepoll_mono subset_imp_lepoll) done subsubsection\Addition of finite cardinals is "ordinary" addition\ lemma sum_succ_eqpoll: "succ(A)+B \ succ(A+B)" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule_tac c = "\z. if z=Inl (A) then A+B else z" and d = "\z. if z=A+B then Inl (A) else z" in lam_bijective) apply simp_all apply (blast dest: sym [THEN eq_imp_not_mem] elim: mem_irrefl)+ done (*Pulling the succ(...) outside the |...| requires m, n \ nat *) (*Unconditional version requires AC*) lemma cadd_succ_lemma: assumes "Ord(m)" "Ord(n)" shows "succ(m) \ n = |succ(m \ n)|" proof (unfold cadd_def) have [intro]: "m + n \ |m + n|" using assms by (blast intro: eqpoll_sym well_ord_cardinal_eqpoll well_ord_radd well_ord_Memrel) have "|succ(m) + n| = |succ(m + n)|" by (rule sum_succ_eqpoll [THEN cardinal_cong]) also have "... = |succ(|m + n|)|" by (blast intro: succ_eqpoll_cong cardinal_cong) finally show "|succ(m) + n| = |succ(|m + n|)|" . qed lemma nat_cadd_eq_add: assumes m: "m \ nat" and [simp]: "n \ nat" shows"m \ n = m #+ n" using m proof (induct m) case 0 thus ?case by (simp add: nat_into_Card cadd_0) next case (succ m) thus ?case by (simp add: cadd_succ_lemma nat_into_Card Card_cardinal_eq) qed subsection\Cardinal multiplication\ subsubsection\Cardinal multiplication is commutative\ lemma prod_commute_eqpoll: "A*B \ B*A" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule_tac c = "\\x,y\.\y,x\" and d = "\\x,y\.\y,x\" in lam_bijective, auto) done lemma cmult_commute: "i \ j = j \ i" -apply (unfold cmult_def) + unfolding cmult_def apply (rule prod_commute_eqpoll [THEN cardinal_cong]) done subsubsection\Cardinal multiplication is associative\ lemma prod_assoc_eqpoll: "(A*B)*C \ A*(B*C)" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule prod_assoc_bij) done text\Unconditional version requires AC\ lemma well_ord_cmult_assoc: assumes i: "well_ord(i,ri)" and j: "well_ord(j,rj)" and k: "well_ord(k,rk)" shows "(i \ j) \ k = i \ (j \ k)" proof (unfold cmult_def, rule cardinal_cong) have "|i * j| * k \ (i * j) * k" by (blast intro: prod_eqpoll_cong well_ord_cardinal_eqpoll eqpoll_refl well_ord_rmult i j) also have "... \ i * (j * k)" by (rule prod_assoc_eqpoll) also have "... \ i * |j * k|" by (blast intro: prod_eqpoll_cong well_ord_cardinal_eqpoll eqpoll_refl well_ord_rmult j k eqpoll_sym) finally show "|i * j| * k \ i * |j * k|" . qed subsubsection\Cardinal multiplication distributes over addition\ lemma sum_prod_distrib_eqpoll: "(A+B)*C \ (A*C)+(B*C)" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule sum_prod_distrib_bij) done lemma well_ord_cadd_cmult_distrib: assumes i: "well_ord(i,ri)" and j: "well_ord(j,rj)" and k: "well_ord(k,rk)" shows "(i \ j) \ k = (i \ k) \ (j \ k)" proof (unfold cadd_def cmult_def, rule cardinal_cong) have "|i + j| * k \ (i + j) * k" by (blast intro: prod_eqpoll_cong well_ord_cardinal_eqpoll eqpoll_refl well_ord_radd i j) also have "... \ i * k + j * k" by (rule sum_prod_distrib_eqpoll) also have "... \ |i * k| + |j * k|" by (blast intro: sum_eqpoll_cong well_ord_cardinal_eqpoll well_ord_rmult i j k eqpoll_sym) finally show "|i + j| * k \ |i * k| + |j * k|" . qed subsubsection\Multiplication by 0 yields 0\ lemma prod_0_eqpoll: "0*A \ 0" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule lam_bijective, safe) done lemma cmult_0 [simp]: "0 \ i = 0" by (simp add: cmult_def prod_0_eqpoll [THEN cardinal_cong]) subsubsection\1 is the identity for multiplication\ lemma prod_singleton_eqpoll: "{x}*A \ A" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule singleton_prod_bij [THEN bij_converse_bij]) done lemma cmult_1 [simp]: "Card(K) \ 1 \ K = K" apply (unfold cmult_def succ_def) apply (simp add: prod_singleton_eqpoll [THEN cardinal_cong] Card_cardinal_eq) done subsection\Some inequalities for multiplication\ lemma prod_square_lepoll: "A \ A*A" apply (unfold lepoll_def inj_def) apply (rule_tac x = "\x\A. \x,x\" in exI, simp) done (*Could probably weaken the premise to well_ord(K,r), or remove using AC*) lemma cmult_square_le: "Card(K) \ K \ K \ K" -apply (unfold cmult_def) + unfolding cmult_def apply (rule le_trans) apply (rule_tac [2] well_ord_lepoll_imp_cardinal_le) apply (rule_tac [3] prod_square_lepoll) apply (simp add: le_refl Card_is_Ord Card_cardinal_eq) apply (blast intro: well_ord_rmult well_ord_Memrel Card_is_Ord) done subsubsection\Multiplication by a non-zero cardinal\ lemma prod_lepoll_self: "b \ B \ A \ A*B" apply (unfold lepoll_def inj_def) apply (rule_tac x = "\x\A. \x,b\" in exI, simp) done (*Could probably weaken the premises to well_ord(K,r), or removing using AC*) lemma cmult_le_self: "\Card(K); Ord(L); 0 \ K \ (K \ L)" -apply (unfold cmult_def) + unfolding cmult_def apply (rule le_trans [OF Card_cardinal_le well_ord_lepoll_imp_cardinal_le]) apply assumption apply (blast intro: well_ord_rmult well_ord_Memrel Card_is_Ord) apply (blast intro: prod_lepoll_self ltD) done subsubsection\Monotonicity of multiplication\ lemma prod_lepoll_mono: "\A \ C; B \ D\ \ A * B \ C * D" -apply (unfold lepoll_def) + unfolding lepoll_def apply (elim exE) apply (rule_tac x = "lam \w,y\:A*B. " in exI) apply (rule_tac d = "\\w,y\. " in lam_injective) apply (typecheck add: inj_is_fun, auto) done lemma cmult_le_mono: "\K' \ K; L' \ L\ \ (K' \ L') \ (K \ L)" -apply (unfold cmult_def) + unfolding cmult_def apply (safe dest!: le_subset_iff [THEN iffD1]) apply (rule well_ord_lepoll_imp_cardinal_le) apply (blast intro: well_ord_rmult well_ord_Memrel) apply (blast intro: prod_lepoll_mono subset_imp_lepoll) done subsection\Multiplication of finite cardinals is "ordinary" multiplication\ lemma prod_succ_eqpoll: "succ(A)*B \ B + A*B" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (rule_tac c = "\\x,y\. if x=A then Inl (y) else Inr (\x,y\)" and d = "case (\y. \A,y\, \z. z)" in lam_bijective) apply safe apply (simp_all add: succI2 if_type mem_imp_not_eq) done (*Unconditional version requires AC*) lemma cmult_succ_lemma: "\Ord(m); Ord(n)\ \ succ(m) \ n = n \ (m \ n)" apply (unfold cmult_def cadd_def) apply (rule prod_succ_eqpoll [THEN cardinal_cong, THEN trans]) apply (rule cardinal_cong [symmetric]) apply (rule sum_eqpoll_cong [OF eqpoll_refl well_ord_cardinal_eqpoll]) apply (blast intro: well_ord_rmult well_ord_Memrel) done lemma nat_cmult_eq_mult: "\m \ nat; n \ nat\ \ m \ n = m#*n" apply (induct_tac m) apply (simp_all add: cmult_succ_lemma nat_cadd_eq_add) done lemma cmult_2: "Card(n) \ 2 \ n = n \ n" by (simp add: cmult_succ_lemma Card_is_Ord cadd_commute [of _ 0]) lemma sum_lepoll_prod: assumes C: "2 \ C" shows "B+B \ C*B" proof - have "B+B \ 2*B" by (simp add: sum_eq_2_times) also have "... \ C*B" by (blast intro: prod_lepoll_mono lepoll_refl C) finally show "B+B \ C*B" . qed lemma lepoll_imp_sum_lepoll_prod: "\A \ B; 2 \ A\ \ A+B \ A*B" by (blast intro: sum_lepoll_mono sum_lepoll_prod lepoll_trans lepoll_refl) subsection\Infinite Cardinals are Limit Ordinals\ (*This proof is modelled upon one assuming nat<=A, with injection \z\cons(u,A). if z=u then 0 else if z \ nat then succ(z) else z and inverse \y. if y \ nat then nat_case(u, \z. z, y) else y. \ If f \ inj(nat,A) then range(f) behaves like the natural numbers.*) lemma nat_cons_lepoll: "nat \ A \ cons(u,A) \ A" -apply (unfold lepoll_def) + unfolding lepoll_def apply (erule exE) apply (rule_tac x = "\z\cons (u,A). if z=u then f`0 else if z \ range (f) then f`succ (converse (f) `z) else z" in exI) apply (rule_tac d = "\y. if y \ range(f) then nat_case (u, \z. f`z, converse(f) `y) else y" in lam_injective) apply (fast intro!: if_type apply_type intro: inj_is_fun inj_converse_fun) apply (simp add: inj_is_fun [THEN apply_rangeI] inj_converse_fun [THEN apply_rangeI] inj_converse_fun [THEN apply_funtype]) done lemma nat_cons_eqpoll: "nat \ A \ cons(u,A) \ A" apply (erule nat_cons_lepoll [THEN eqpollI]) apply (rule subset_consI [THEN subset_imp_lepoll]) done (*Specialized version required below*) lemma nat_succ_eqpoll: "nat \ A \ succ(A) \ A" -apply (unfold succ_def) + unfolding succ_def apply (erule subset_imp_lepoll [THEN nat_cons_eqpoll]) done lemma InfCard_nat: "InfCard(nat)" -apply (unfold InfCard_def) + unfolding InfCard_def apply (blast intro: Card_nat le_refl Card_is_Ord) done lemma InfCard_is_Card: "InfCard(K) \ Card(K)" -apply (unfold InfCard_def) + unfolding InfCard_def apply (erule conjunct1) done lemma InfCard_Un: "\InfCard(K); Card(L)\ \ InfCard(K \ L)" -apply (unfold InfCard_def) + unfolding InfCard_def apply (simp add: Card_Un Un_upper1_le [THEN [2] le_trans] Card_is_Ord) done (*Kunen's Lemma 10.11*) lemma InfCard_is_Limit: "InfCard(K) \ Limit(K)" -apply (unfold InfCard_def) + unfolding InfCard_def apply (erule conjE) apply (frule Card_is_Ord) apply (rule ltI [THEN non_succ_LimitI]) apply (erule le_imp_subset [THEN subsetD]) apply (safe dest!: Limit_nat [THEN Limit_le_succD]) -apply (unfold Card_def) + unfolding Card_def apply (drule trans) apply (erule le_imp_subset [THEN nat_succ_eqpoll, THEN cardinal_cong]) apply (erule Ord_cardinal_le [THEN lt_trans2, THEN lt_irrefl]) apply (rule le_eqI, assumption) apply (rule Ord_cardinal) done (*** An infinite cardinal equals its square (Kunen, Thm 10.12, page 29) ***) (*A general fact about ordermap*) lemma ordermap_eqpoll_pred: "\well_ord(A,r); x \ A\ \ ordermap(A,r)`x \ Order.pred(A,x,r)" -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (rule exI) apply (simp add: ordermap_eq_image well_ord_is_wf) apply (erule ordermap_bij [THEN bij_is_inj, THEN restrict_bij, THEN bij_converse_bij]) apply (rule pred_subset) done subsubsection\Establishing the well-ordering\ lemma well_ord_csquare: assumes K: "Ord(K)" shows "well_ord(K*K, csquare_rel(K))" proof (unfold csquare_rel_def, rule well_ord_rvimage) show "(\\x,y\\K \ K. \x \ y, x, y\) \ inj(K \ K, K \ K \ K)" using K by (force simp add: inj_def intro: lam_type Un_least_lt [THEN ltD] ltI) next show "well_ord(K \ K \ K, rmult(K, Memrel(K), K \ K, rmult(K, Memrel(K), K, Memrel(K))))" using K by (blast intro: well_ord_rmult well_ord_Memrel) qed subsubsection\Characterising initial segments of the well-ordering\ lemma csquareD: "\<\x,y\, \z,z\> \ csquare_rel(K); x \ x \ z \ y \ z" -apply (unfold csquare_rel_def) + unfolding csquare_rel_def apply (erule rev_mp) apply (elim ltE) apply (simp add: rvimage_iff Un_absorb Un_least_mem_iff ltD) apply (safe elim!: mem_irrefl intro!: Un_upper1_le Un_upper2_le) apply (simp_all add: lt_def succI2) done lemma pred_csquare_subset: "z Order.pred(K*K, \z,z\, csquare_rel(K)) \ succ(z)*succ(z)" apply (unfold Order.pred_def) apply (safe del: SigmaI dest!: csquareD) apply (unfold lt_def, auto) done lemma csquare_ltI: "\x \ <\x,y\, \z,z\> \ csquare_rel(K)" -apply (unfold csquare_rel_def) + unfolding csquare_rel_def apply (subgoal_tac "x y apply *) lemma csquare_or_eqI: "\x \ z; y \ z; z \ <\x,y\, \z,z\> \ csquare_rel(K) | x=z \ y=z" -apply (unfold csquare_rel_def) + unfolding csquare_rel_def apply (subgoal_tac "x yThe cardinality of initial segments\ lemma ordermap_z_lt: "\Limit(K); x y)\ \ ordermap(K*K, csquare_rel(K)) ` \x,y\ < ordermap(K*K, csquare_rel(K)) ` \z,z\" apply (subgoal_tac "z well_ord (K*K, csquare_rel (K))") prefer 2 apply (blast intro!: Un_least_lt Limit_has_succ Limit_is_Ord [THEN well_ord_csquare], clarify) apply (rule csquare_ltI [THEN ordermap_mono, THEN ltI]) apply (erule_tac [4] well_ord_is_wf) apply (blast intro!: Un_upper1_le Un_upper2_le Ord_ordermap elim!: ltE)+ done text\Kunen: "each \<^term>\\x,y\ \ K \ K\ has no more than \<^term>\z \ z\ predecessors..." (page 29)\ lemma ordermap_csquare_le: assumes K: "Limit(K)" and x: "x succ(x \ y)" shows "|ordermap(K \ K, csquare_rel(K)) ` \x,y\| \ |succ(z)| \ |succ(z)|" proof (unfold cmult_def, rule well_ord_lepoll_imp_cardinal_le) show "well_ord(|succ(z)| \ |succ(z)|, rmult(|succ(z)|, Memrel(|succ(z)|), |succ(z)|, Memrel(|succ(z)|)))" by (blast intro: Ord_cardinal well_ord_Memrel well_ord_rmult) next have zK: "z K, csquare_rel(K)) ` \x,y\ \ ordermap(K \ K, csquare_rel(K)) ` \z,z\" using z_def by (blast intro: ordermap_z_lt leI le_imp_lepoll K x y) also have "... \ Order.pred(K \ K, \z,z\, csquare_rel(K))" proof (rule ordermap_eqpoll_pred) show "well_ord(K \ K, csquare_rel(K))" using K by (rule Limit_is_Ord [THEN well_ord_csquare]) next show "\z, z\ \ K \ K" using zK by (blast intro: ltD) qed also have "... \ succ(z) \ succ(z)" using zK by (rule pred_csquare_subset [THEN subset_imp_lepoll]) also have "... \ |succ(z)| \ |succ(z)|" using oz by (blast intro: prod_eqpoll_cong Ord_succ Ord_cardinal_eqpoll eqpoll_sym) finally show "ordermap(K \ K, csquare_rel(K)) ` \x,y\ \ |succ(z)| \ |succ(z)|" . qed text\Kunen: "... so the order type is \\\ K"\ lemma ordertype_csquare_le: assumes IK: "InfCard(K)" and eq: "\y. y\K \ InfCard(y) \ y \ y = y" shows "ordertype(K*K, csquare_rel(K)) \ K" proof - have CK: "Card(K)" using IK by (rule InfCard_is_Card) hence OK: "Ord(K)" by (rule Card_is_Ord) moreover have "Ord(ordertype(K \ K, csquare_rel(K)))" using OK by (rule well_ord_csquare [THEN Ord_ordertype]) ultimately show ?thesis proof (rule all_lt_imp_le) fix i assume i: "i < ordertype(K \ K, csquare_rel(K))" hence Oi: "Ord(i)" by (elim ltE) obtain x y where x: "x \ K" and y: "y \ K" and ieq: "i = ordermap(K \ K, csquare_rel(K)) ` \x,y\" using i by (auto simp add: ordertype_unfold elim: ltE) hence xy: "Ord(x)" "Ord(y)" "x < K" "y < K" using OK by (blast intro: Ord_in_Ord ltI)+ hence ou: "Ord(x \ y)" by (simp add: Ord_Un) show "i < K" proof (rule Card_lt_imp_lt [OF _ Oi CK]) have "|i| \ |succ(succ(x \ y))| \ |succ(succ(x \ y))|" using IK xy by (auto simp add: ieq intro: InfCard_is_Limit [THEN ordermap_csquare_le]) moreover have "|succ(succ(x \ y))| \ |succ(succ(x \ y))| < K" proof (cases rule: Ord_linear2 [OF ou Ord_nat]) assume "x \ y < nat" hence "|succ(succ(x \ y))| \ |succ(succ(x \ y))| \ nat" by (simp add: lt_def nat_cmult_eq_mult nat_succI mult_type nat_into_Card [THEN Card_cardinal_eq] Ord_nat) also have "... \ K" using IK by (simp add: InfCard_def le_imp_subset) finally show "|succ(succ(x \ y))| \ |succ(succ(x \ y))| < K" by (simp add: ltI OK) next assume natxy: "nat \ x \ y" hence seq: "|succ(succ(x \ y))| = |x \ y|" using xy by (simp add: le_imp_subset nat_succ_eqpoll [THEN cardinal_cong] le_succ_iff) also have "... < K" using xy by (simp add: Un_least_lt Ord_cardinal_le [THEN lt_trans1]) finally have "|succ(succ(x \ y))| < K" . moreover have "InfCard(|succ(succ(x \ y))|)" using xy natxy by (simp add: seq InfCard_def Card_cardinal nat_le_cardinal) ultimately show ?thesis by (simp add: eq ltD) qed ultimately show "|i| < K" by (blast intro: lt_trans1) qed qed qed (*Main result: Kunen's Theorem 10.12*) lemma InfCard_csquare_eq: assumes IK: "InfCard(K)" shows "K \ K = K" proof - have OK: "Ord(K)" using IK by (simp add: Card_is_Ord InfCard_is_Card) show "K \ K = K" using OK IK proof (induct rule: trans_induct) case (step i) show "i \ i = i" proof (rule le_anti_sym) have "|i \ i| = |ordertype(i \ i, csquare_rel(i))|" by (rule cardinal_cong, simp add: step.hyps well_ord_csquare [THEN ordermap_bij, THEN bij_imp_eqpoll]) hence "i \ i \ ordertype(i \ i, csquare_rel(i))" by (simp add: step.hyps cmult_def Ord_cardinal_le well_ord_csquare [THEN Ord_ordertype]) moreover have "ordertype(i \ i, csquare_rel(i)) \ i" using step by (simp add: ordertype_csquare_le) ultimately show "i \ i \ i" by (rule le_trans) next show "i \ i \ i" using step by (blast intro: cmult_square_le InfCard_is_Card) qed qed qed (*Corollary for arbitrary well-ordered sets (all sets, assuming AC)*) lemma well_ord_InfCard_square_eq: assumes r: "well_ord(A,r)" and I: "InfCard(|A|)" shows "A \ A \ A" proof - have "A \ A \ |A| \ |A|" by (blast intro: prod_eqpoll_cong well_ord_cardinal_eqpoll eqpoll_sym r) also have "... \ A" proof (rule well_ord_cardinal_eqE [OF _ r]) show "well_ord(|A| \ |A|, rmult(|A|, Memrel(|A|), |A|, Memrel(|A|)))" by (blast intro: Ord_cardinal well_ord_rmult well_ord_Memrel r) next show "||A| \ |A|| = |A|" using InfCard_csquare_eq I by (simp add: cmult_def) qed finally show ?thesis . qed lemma InfCard_square_eqpoll: "InfCard(K) \ K \ K \ K" apply (rule well_ord_InfCard_square_eq) apply (erule InfCard_is_Card [THEN Card_is_Ord, THEN well_ord_Memrel]) apply (simp add: InfCard_is_Card [THEN Card_cardinal_eq]) done lemma Inf_Card_is_InfCard: "\Card(i); \ Finite(i)\ \ InfCard(i)" by (simp add: InfCard_def Card_is_Ord [THEN nat_le_infinite_Ord]) subsubsection\Toward's Kunen's Corollary 10.13 (1)\ lemma InfCard_le_cmult_eq: "\InfCard(K); L \ K; 0 \ K \ L = K" apply (rule le_anti_sym) prefer 2 apply (erule ltE, blast intro: cmult_le_self InfCard_is_Card) apply (frule InfCard_is_Card [THEN Card_is_Ord, THEN le_refl]) apply (rule cmult_le_mono [THEN le_trans], assumption+) apply (simp add: InfCard_csquare_eq) done (*Corollary 10.13 (1), for cardinal multiplication*) lemma InfCard_cmult_eq: "\InfCard(K); InfCard(L)\ \ K \ L = K \ L" apply (rule_tac i = K and j = L in Ord_linear_le) apply (typecheck add: InfCard_is_Card Card_is_Ord) apply (rule cmult_commute [THEN ssubst]) apply (rule Un_commute [THEN ssubst]) apply (simp_all add: InfCard_is_Limit [THEN Limit_has_0] InfCard_le_cmult_eq subset_Un_iff2 [THEN iffD1] le_imp_subset) done lemma InfCard_cdouble_eq: "InfCard(K) \ K \ K = K" apply (simp add: cmult_2 [symmetric] InfCard_is_Card cmult_commute) apply (simp add: InfCard_le_cmult_eq InfCard_is_Limit Limit_has_0 Limit_has_succ) done (*Corollary 10.13 (1), for cardinal addition*) lemma InfCard_le_cadd_eq: "\InfCard(K); L \ K\ \ K \ L = K" apply (rule le_anti_sym) prefer 2 apply (erule ltE, blast intro: cadd_le_self InfCard_is_Card) apply (frule InfCard_is_Card [THEN Card_is_Ord, THEN le_refl]) apply (rule cadd_le_mono [THEN le_trans], assumption+) apply (simp add: InfCard_cdouble_eq) done lemma InfCard_cadd_eq: "\InfCard(K); InfCard(L)\ \ K \ L = K \ L" apply (rule_tac i = K and j = L in Ord_linear_le) apply (typecheck add: InfCard_is_Card Card_is_Ord) apply (rule cadd_commute [THEN ssubst]) apply (rule Un_commute [THEN ssubst]) apply (simp_all add: InfCard_le_cadd_eq subset_Un_iff2 [THEN iffD1] le_imp_subset) done (*The other part, Corollary 10.13 (2), refers to the cardinality of the set of all n-tuples of elements of K. A better version for the Isabelle theory might be InfCard(K) \ |list(K)| = K. *) subsection\For Every Cardinal Number There Exists A Greater One\ text\This result is Kunen's Theorem 10.16, which would be trivial using AC\ lemma Ord_jump_cardinal: "Ord(jump_cardinal(K))" -apply (unfold jump_cardinal_def) + unfolding jump_cardinal_def apply (rule Ord_is_Transset [THEN [2] OrdI]) prefer 2 apply (blast intro!: Ord_ordertype) -apply (unfold Transset_def) + unfolding Transset_def apply (safe del: subsetI) apply (simp add: ordertype_pred_unfold, safe) apply (rule UN_I) apply (rule_tac [2] ReplaceI) prefer 4 apply (blast intro: well_ord_subset elim!: predE)+ done (*Allows selective unfolding. Less work than deriving intro/elim rules*) lemma jump_cardinal_iff: "i \ jump_cardinal(K) \ (\r X. r \ K*K \ X \ K \ well_ord(X,r) \ i = ordertype(X,r))" -apply (unfold jump_cardinal_def) + unfolding jump_cardinal_def apply (blast del: subsetI) done (*The easy part of Theorem 10.16: jump_cardinal(K) exceeds K*) lemma K_lt_jump_cardinal: "Ord(K) \ K < jump_cardinal(K)" apply (rule Ord_jump_cardinal [THEN [2] ltI]) apply (rule jump_cardinal_iff [THEN iffD2]) apply (rule_tac x="Memrel(K)" in exI) apply (rule_tac x=K in exI) apply (simp add: ordertype_Memrel well_ord_Memrel) apply (simp add: Memrel_def subset_iff) done (*The proof by contradiction: the bijection f yields a wellordering of X whose ordertype is jump_cardinal(K). *) lemma Card_jump_cardinal_lemma: "\well_ord(X,r); r \ K * K; X \ K; f \ bij(ordertype(X,r), jump_cardinal(K))\ \ jump_cardinal(K) \ jump_cardinal(K)" apply (subgoal_tac "f O ordermap (X,r) \ bij (X, jump_cardinal (K))") prefer 2 apply (blast intro: comp_bij ordermap_bij) apply (rule jump_cardinal_iff [THEN iffD2]) apply (intro exI conjI) apply (rule subset_trans [OF rvimage_type Sigma_mono], assumption+) apply (erule bij_is_inj [THEN well_ord_rvimage]) apply (rule Ord_jump_cardinal [THEN well_ord_Memrel]) apply (simp add: well_ord_Memrel [THEN [2] bij_ordertype_vimage] ordertype_Memrel Ord_jump_cardinal) done (*The hard part of Theorem 10.16: jump_cardinal(K) is itself a cardinal*) lemma Card_jump_cardinal: "Card(jump_cardinal(K))" apply (rule Ord_jump_cardinal [THEN CardI]) -apply (unfold eqpoll_def) + unfolding eqpoll_def apply (safe dest!: ltD jump_cardinal_iff [THEN iffD1]) apply (blast intro: Card_jump_cardinal_lemma [THEN mem_irrefl]) done subsection\Basic Properties of Successor Cardinals\ lemma csucc_basic: "Ord(K) \ Card(csucc(K)) \ K < csucc(K)" -apply (unfold csucc_def) + unfolding csucc_def apply (rule LeastI) apply (blast intro: Card_jump_cardinal K_lt_jump_cardinal Ord_jump_cardinal)+ done lemmas Card_csucc = csucc_basic [THEN conjunct1] lemmas lt_csucc = csucc_basic [THEN conjunct2] lemma Ord_0_lt_csucc: "Ord(K) \ 0 < csucc(K)" by (blast intro: Ord_0_le lt_csucc lt_trans1) lemma csucc_le: "\Card(L); K \ csucc(K) \ L" -apply (unfold csucc_def) + unfolding csucc_def apply (rule Least_le) apply (blast intro: Card_is_Ord)+ done lemma lt_csucc_iff: "\Ord(i); Card(K)\ \ i < csucc(K) \ |i| \ K" apply (rule iffI) apply (rule_tac [2] Card_lt_imp_lt) apply (erule_tac [2] lt_trans1) apply (simp_all add: lt_csucc Card_csucc Card_is_Ord) apply (rule notI [THEN not_lt_imp_le]) apply (rule Card_cardinal [THEN csucc_le, THEN lt_trans1, THEN lt_irrefl], assumption) apply (rule Ord_cardinal_le [THEN lt_trans1]) apply (simp_all add: Ord_cardinal Card_is_Ord) done lemma Card_lt_csucc_iff: "\Card(K'); Card(K)\ \ K' < csucc(K) \ K' \ K" by (simp add: lt_csucc_iff Card_cardinal_eq Card_is_Ord) lemma InfCard_csucc: "InfCard(K) \ InfCard(csucc(K))" by (simp add: InfCard_def Card_csucc Card_is_Ord lt_csucc [THEN leI, THEN [2] le_trans]) subsubsection\Removing elements from a finite set decreases its cardinality\ lemma Finite_imp_cardinal_cons [simp]: assumes FA: "Finite(A)" and a: "a\A" shows "|cons(a,A)| = succ(|A|)" proof - { fix X have "Finite(X) \ a \ X \ cons(a,X) \ X \ False" proof (induct X rule: Finite_induct) case 0 thus False by (simp add: lepoll_0_iff) next case (cons x Y) hence "cons(x, cons(a, Y)) \ cons(x, Y)" by (simp add: cons_commute) hence "cons(a, Y) \ Y" using cons by (blast dest: cons_lepoll_consD) thus False using cons by auto qed } hence [simp]: "\ cons(a,A) \ A" using a FA by auto have [simp]: "|A| \ A" using Finite_imp_well_ord [OF FA] by (blast intro: well_ord_cardinal_eqpoll) have "(\ i. i \ cons(a, A)) = succ(|A|)" proof (rule Least_equality [OF _ _ notI]) show "succ(|A|) \ cons(a, A)" by (simp add: succ_def cons_eqpoll_cong mem_not_refl a) next show "Ord(succ(|A|))" by simp next fix i assume i: "i \ |A|" "i \ cons(a, A)" have "cons(a, A) \ i" by (rule eqpoll_sym) (rule i) also have "... \ |A|" by (rule le_imp_lepoll) (rule i) also have "... \ A" by simp finally have "cons(a, A) \ A" . thus False by simp qed thus ?thesis by (simp add: cardinal_def) qed lemma Finite_imp_succ_cardinal_Diff: "\Finite(A); a \ A\ \ succ(|A-{a}|) = |A|" apply (rule_tac b = A in cons_Diff [THEN subst], assumption) apply (simp add: Finite_imp_cardinal_cons Diff_subset [THEN subset_Finite]) apply (simp add: cons_Diff) done lemma Finite_imp_cardinal_Diff: "\Finite(A); a \ A\ \ |A-{a}| < |A|" apply (rule succ_leE) apply (simp add: Finite_imp_succ_cardinal_Diff) done lemma Finite_cardinal_in_nat [simp]: "Finite(A) \ |A| \ nat" proof (induct rule: Finite_induct) case 0 thus ?case by (simp add: cardinal_0) next case (cons x A) thus ?case by (simp add: Finite_imp_cardinal_cons) qed lemma card_Un_Int: "\Finite(A); Finite(B)\ \ |A| #+ |B| = |A \ B| #+ |A \ B|" apply (erule Finite_induct, simp) apply (simp add: Finite_Int cons_absorb Un_cons Int_cons_left) done lemma card_Un_disjoint: "\Finite(A); Finite(B); A \ B = 0\ \ |A \ B| = |A| #+ |B|" by (simp add: Finite_Un card_Un_Int) lemma card_partition: assumes FC: "Finite(C)" shows "Finite (\ C) \ (\c\C. |c| = k) \ (\c1 \ C. \c2 \ C. c1 \ c2 \ c1 \ c2 = 0) \ k #* |C| = |\ C|" using FC proof (induct rule: Finite_induct) case 0 thus ?case by simp next case (cons x B) hence "x \ \B = 0" by auto thus ?case using cons by (auto simp add: card_Un_disjoint) qed subsubsection\Theorems by Krzysztof Grabczewski, proofs by lcp\ lemmas nat_implies_well_ord = nat_into_Ord [THEN well_ord_Memrel] lemma nat_sum_eqpoll_sum: assumes m: "m \ nat" and n: "n \ nat" shows "m + n \ m #+ n" proof - have "m + n \ |m+n|" using m n by (blast intro: nat_implies_well_ord well_ord_radd well_ord_cardinal_eqpoll eqpoll_sym) also have "... = m #+ n" using m n by (simp add: nat_cadd_eq_add [symmetric] cadd_def) finally show ?thesis . qed lemma Ord_subset_natD [rule_format]: "Ord(i) \ i \ nat \ i \ nat | i=nat" proof (induct i rule: trans_induct3) case 0 thus ?case by auto next case (succ i) thus ?case by auto next case (limit l) thus ?case by (blast dest: nat_le_Limit le_imp_subset) qed lemma Ord_nat_subset_into_Card: "\Ord(i); i \ nat\ \ Card(i)" by (blast dest: Ord_subset_natD intro: Card_nat nat_into_Card) end diff --git a/src/ZF/Coind/ECR.thy b/src/ZF/Coind/ECR.thy --- a/src/ZF/Coind/ECR.thy +++ b/src/ZF/Coind/ECR.thy @@ -1,167 +1,167 @@ (* Title: ZF/Coind/ECR.thy Author: Jacob Frost, Cambridge University Computer Laboratory Copyright 1995 University of Cambridge *) theory ECR imports Static Dynamic begin (* The extended correspondence relation *) consts HasTyRel :: i coinductive domains "HasTyRel" \ "Val * Ty" intros htr_constI [intro!]: "\c \ Const; t \ Ty; isof(c,t)\ \ \ HasTyRel" htr_closI [intro]: "\x \ ExVar; e \ Exp; t \ Ty; ve \ ValEnv; te \ TyEnv; \ ElabRel; ve_dom(ve) = te_dom(te); {.y \ ve_dom(ve)} \ Pow(HasTyRel)\ \ \ HasTyRel" monos Pow_mono type_intros Val_ValEnv.intros (* Pointwise extension to environments *) definition hastyenv :: "[i,i] \ o" where "hastyenv(ve,te) \ ve_dom(ve) = te_dom(te) \ (\x \ ve_dom(ve). \ HasTyRel)" (* Specialised co-induction rule *) lemma htr_closCI [intro]: "\x \ ExVar; e \ Exp; t \ Ty; ve \ ValEnv; te \ TyEnv; \ ElabRel; ve_dom(ve) = te_dom(te); {.y \ ve_dom(ve)} \ Pow({} \ HasTyRel)\ \ \ HasTyRel" apply (rule singletonI [THEN HasTyRel.coinduct], auto) done (* Specialised elimination rules *) inductive_cases htr_constE [elim!]: " \ HasTyRel" and htr_closE [elim]: " \ HasTyRel" (* Properties of the pointwise extension to environments *) lemmas HasTyRel_non_zero = HasTyRel.dom_subset [THEN subsetD, THEN SigmaD1, THEN ValNEE] lemma hastyenv_owr: "\ve \ ValEnv; te \ TyEnv; hastyenv(ve,te); \v,t\ \ HasTyRel\ \ hastyenv(ve_owr(ve,x,v),te_owr(te,x,t))" by (auto simp add: hastyenv_def ve_app_owr HasTyRel_non_zero) lemma basic_consistency_lem: "\ve \ ValEnv; te \ TyEnv; isofenv(ve,te)\ \ hastyenv(ve,te)" apply (unfold isofenv_def hastyenv_def) apply (force intro: te_appI ve_domI) done (* ############################################################ *) (* The Consistency theorem *) (* ############################################################ *) lemma consistency_const: "\c \ Const; hastyenv(ve,te); \ ElabRel\ \ \ HasTyRel" by blast lemma consistency_var: "\x \ ve_dom(ve); hastyenv(ve,te); \ ElabRel\ \ \ HasTyRel" by (unfold hastyenv_def, blast) lemma consistency_fn: "\ve \ ValEnv; x \ ExVar; e \ Exp; hastyenv(ve,te); \ ElabRel \ \ \ HasTyRel" by (unfold hastyenv_def, blast) declare ElabRel.dom_subset [THEN subsetD, dest] declare Ty.intros [simp, intro!] declare TyEnv.intros [simp, intro!] declare Val_ValEnv.intros [simp, intro!] lemma consistency_fix: "\ve \ ValEnv; x \ ExVar; e \ Exp; f \ ExVar; cl \ Val; v_clos(x,e,ve_owr(ve,f,cl)) = cl; hastyenv(ve,te); \ ElabRel\ \ \cl,t\ \ HasTyRel" -apply (unfold hastyenv_def) + unfolding hastyenv_def apply (erule elab_fixE, safe) apply hypsubst_thin apply (rule subst, assumption) apply (rule_tac te="te_owr(te, f, t_fun(t1, t2))" in htr_closCI) apply simp_all apply (blast intro: ve_owrI) apply (rule ElabRel.fnI) apply (simp_all add: ValNEE, force) done lemma consistency_app1: "\ve \ ValEnv; e1 \ Exp; e2 \ Exp; c1 \ Const; c2 \ Const; \ EvalRel; \t te. hastyenv(ve,te) \ \ ElabRel \ \ HasTyRel; \ EvalRel; \t te. hastyenv(ve,te) \ \ ElabRel \ \ HasTyRel; hastyenv(ve, te); \ ElabRel\ \ \ HasTyRel" by (blast intro!: c_appI intro: isof_app) lemma consistency_app2: "\ve \ ValEnv; vem \ ValEnv; e1 \ Exp; e2 \ Exp; em \ Exp; xm \ ExVar; v \ Val; \ EvalRel; \t te. hastyenv(ve,te) \ \ ElabRel \ \ HasTyRel; \ EvalRel; \t te. hastyenv(ve,te) \ \ ElabRel \ \v2,t\ \ HasTyRel; \ EvalRel; \t te. hastyenv(ve_owr(vem,xm,v2),te) \ \ ElabRel \ \v,t\ \ HasTyRel; hastyenv(ve,te); \ ElabRel\ \ \v,t\ \ HasTyRel" apply (erule elab_appE) apply (drule spec [THEN spec, THEN mp, THEN mp], assumption+) apply (drule spec [THEN spec, THEN mp, THEN mp], assumption+) apply (erule htr_closE) apply (erule elab_fnE, simp) apply clarify apply (drule spec [THEN spec, THEN mp, THEN mp]) prefer 2 apply assumption+ apply (rule hastyenv_owr, assumption) apply assumption apply (simp add: hastyenv_def, blast+) done lemma consistency [rule_format]: " \ EvalRel \ (\t te. hastyenv(ve,te) \ \ ElabRel \ \v,t\ \ HasTyRel)" apply (erule EvalRel.induct) apply (simp_all add: consistency_const consistency_var consistency_fn consistency_fix consistency_app1) apply (blast intro: consistency_app2) done lemma basic_consistency: "\ve \ ValEnv; te \ TyEnv; isofenv(ve,te); \ EvalRel; \ ElabRel\ \ isof(c,t)" by (blast dest: consistency intro!: basic_consistency_lem) end diff --git a/src/ZF/Coind/Map.thy b/src/ZF/Coind/Map.thy --- a/src/ZF/Coind/Map.thy +++ b/src/ZF/Coind/Map.thy @@ -1,184 +1,184 @@ (* Title: ZF/Coind/Map.thy Author: Jacob Frost, Cambridge University Computer Laboratory Copyright 1995 University of Cambridge Some sample proofs of inclusions for the final coalgebra "U" (by lcp). *) theory Map imports ZF begin definition TMap :: "[i,i] \ i" where "TMap(A,B) \ {m \ Pow(A*\(B)).\a \ A. m``{a} \ B}" definition PMap :: "[i,i] \ i" where "PMap(A,B) \ TMap(A,cons(0,B))" (* Note: 0 \ B \ TMap(A,B) = PMap(A,B) *) definition map_emp :: i where "map_emp \ 0" definition map_owr :: "[i,i,i]\i" where "map_owr(m,a,b) \ \x \ {a} \ domain(m). if x=a then b else m``{x}" definition map_app :: "[i,i]\i" where "map_app(m,a) \ m``{a}" lemma "{0,1} \ {1} \ TMap(I, {0,1})" by (unfold TMap_def, blast) lemma "{0} \ TMap(I,1) \ {1} \ TMap(I, {0} \ TMap(I,1))" by (unfold TMap_def, blast) lemma "{0,1} \ TMap(I,2) \ {1} \ TMap(I, {0,1} \ TMap(I,2))" by (unfold TMap_def, blast) (*A bit too slow. lemma "{0,1} \ TMap(I,TMap(I,2)) \ TMap(I,2) \ {1} \ TMap(I, {0,1} \ TMap(I,TMap(I,2)) \ TMap(I,2))" by (unfold TMap_def, blast) *) (* ############################################################ *) (* Lemmas *) (* ############################################################ *) lemma qbeta_if: "Sigma(A,B)``{a} = (if a \ A then B(a) else 0)" by auto lemma qbeta: "a \ A \ Sigma(A,B)``{a} = B(a)" by fast lemma qbeta_emp: "a\A \ Sigma(A,B)``{a} = 0" by fast lemma image_Sigma1: "a \ A \ Sigma(A,B)``{a}=0" by fast (* ############################################################ *) (* Inclusion in Quine Universes *) (* ############################################################ *) (* Lemmas *) lemma MapQU_lemma: "A \ univ(X) \ Pow(A * \(quniv(X))) \ quniv(X)" -apply (unfold quniv_def) + unfolding quniv_def apply (rule Pow_mono) apply (rule subset_trans [OF Sigma_mono product_univ]) apply (erule subset_trans) apply (rule arg_subset_eclose [THEN univ_mono]) apply (simp add: Union_Pow_eq) done (* Theorems *) lemma mapQU: "\m \ PMap(A,quniv(B)); \x. x \ A \ x \ univ(B)\ \ m \ quniv(B)" apply (unfold PMap_def TMap_def) apply (blast intro!: MapQU_lemma [THEN subsetD]) done (* ############################################################ *) (* Monotonicity *) (* ############################################################ *) lemma PMap_mono: "B \ C \ PMap(A,B)<=PMap(A,C)" by (unfold PMap_def TMap_def, blast) (* ############################################################ *) (* Introduction Rules *) (* ############################################################ *) (** map_emp **) lemma pmap_empI: "map_emp \ PMap(A,B)" by (unfold map_emp_def PMap_def TMap_def, auto) (** map_owr **) lemma pmap_owrI: "\m \ PMap(A,B); a \ A; b \ B\ \ map_owr(m,a,b):PMap(A,B)" apply (unfold map_owr_def PMap_def TMap_def, safe) apply (simp_all add: if_iff, auto) (*Remaining subgoal*) apply (rule excluded_middle [THEN disjE]) apply (erule image_Sigma1) apply (drule_tac psi = "uu \ B" for uu in asm_rl) apply (auto simp add: qbeta) done (** map_app **) lemma tmap_app_notempty: "\m \ TMap(A,B); a \ domain(m)\ \ map_app(m,a) \0" by (unfold TMap_def map_app_def, blast) lemma tmap_appI: "\m \ TMap(A,B); a \ domain(m)\ \ map_app(m,a):B" by (unfold TMap_def map_app_def domain_def, blast) lemma pmap_appI: "\m \ PMap(A,B); a \ domain(m)\ \ map_app(m,a):B" -apply (unfold PMap_def) + unfolding PMap_def apply (frule tmap_app_notempty, assumption) apply (drule tmap_appI, auto) done (** domain **) lemma tmap_domainD: "\m \ TMap(A,B); a \ domain(m)\ \ a \ A" by (unfold TMap_def, blast) lemma pmap_domainD: "\m \ PMap(A,B); a \ domain(m)\ \ a \ A" by (unfold PMap_def TMap_def, blast) (* ############################################################ *) (* Equalities *) (* ############################################################ *) (** Domain **) (* Lemmas *) lemma domain_UN: "domain(\x \ A. B(x)) = (\x \ A. domain(B(x)))" by fast lemma domain_Sigma: "domain(Sigma(A,B)) = {x \ A. \y. y \ B(x)}" by blast (* Theorems *) lemma map_domain_emp: "domain(map_emp) = 0" by (unfold map_emp_def, blast) lemma map_domain_owr: "b \ 0 \ domain(map_owr(f,a,b)) = {a} \ domain(f)" -apply (unfold map_owr_def) + unfolding map_owr_def apply (auto simp add: domain_Sigma) done (** Application **) lemma map_app_owr: "map_app(map_owr(f,a,b),c) = (if c=a then b else map_app(f,c))" by (simp add: qbeta_if map_app_def map_owr_def, blast) lemma map_app_owr1: "map_app(map_owr(f,a,b),a) = b" by (simp add: map_app_owr) lemma map_app_owr2: "c \ a \ map_app(map_owr(f,a,b),c)= map_app(f,c)" by (simp add: map_app_owr) end diff --git a/src/ZF/Coind/Values.thy b/src/ZF/Coind/Values.thy --- a/src/ZF/Coind/Values.thy +++ b/src/ZF/Coind/Values.thy @@ -1,115 +1,115 @@ (* Title: ZF/Coind/Values.thy Author: Jacob Frost, Cambridge University Computer Laboratory Copyright 1995 University of Cambridge *) theory Values imports Language Map begin (* Values, values environments and associated operators *) consts Val :: i ValEnv :: i Val_ValEnv :: i codatatype "Val" = v_const ("c \ Const") | v_clos ("x \ ExVar","e \ Exp","ve \ ValEnv") and "ValEnv" = ve_mk ("m \ PMap(ExVar,Val)") monos PMap_mono type_intros A_into_univ mapQU consts ve_owr :: "[i,i,i] \ i" ve_dom :: "i\i" ve_app :: "[i,i] \ i" primrec "ve_owr(ve_mk(m), x, v) = ve_mk(map_owr(m,x,v))" primrec "ve_dom(ve_mk(m)) = domain(m)" primrec "ve_app(ve_mk(m), a) = map_app(m,a)" definition ve_emp :: i where "ve_emp \ ve_mk(map_emp)" (* Elimination rules *) lemma ValEnvE: "\ve \ ValEnv; \m.\ve=ve_mk(m); m \ PMap(ExVar,Val)\ \ Q\ \ Q" apply (unfold Part_def Val_def ValEnv_def, clarify) apply (erule Val_ValEnv.cases) apply (auto simp add: Val_def Part_def Val_ValEnv.con_defs) done lemma ValE: "\v \ Val; \c. \v = v_const(c); c \ Const\ \ Q; \e ve x. \v = v_clos(x,e,ve); x \ ExVar; e \ Exp; ve \ ValEnv\ \ Q \ \ Q" apply (unfold Part_def Val_def ValEnv_def, clarify) apply (erule Val_ValEnv.cases) apply (auto simp add: ValEnv_def Part_def Val_ValEnv.con_defs) done (* Nonempty sets *) lemma v_closNE [simp]: "v_clos(x,e,ve) \ 0" by (unfold QPair_def QInl_def QInr_def Val_ValEnv.con_defs, blast) declare v_closNE [THEN notE, elim!] lemma v_constNE [simp]: "c \ Const \ v_const(c) \ 0" apply (unfold QPair_def QInl_def QInr_def Val_ValEnv.con_defs) apply (drule constNEE, auto) done (* Proving that the empty set is not a value *) lemma ValNEE: "v \ Val \ v \ 0" by (erule ValE, auto) (* Equalities for value environments *) lemma ve_dom_owr [simp]: "\ve \ ValEnv; v \0\ \ ve_dom(ve_owr(ve,x,v)) = ve_dom(ve) \ {x}" apply (erule ValEnvE) apply (auto simp add: map_domain_owr) done lemma ve_app_owr [simp]: "ve \ ValEnv \ ve_app(ve_owr(ve,y,v),x) = (if x=y then v else ve_app(ve,x))" by (erule ValEnvE, simp add: map_app_owr) (* Introduction rules for operators on value environments *) lemma ve_appI: "\ve \ ValEnv; x \ ve_dom(ve)\ \ ve_app(ve,x):Val" by (erule ValEnvE, simp add: pmap_appI) lemma ve_domI: "\ve \ ValEnv; x \ ve_dom(ve)\ \ x \ ExVar" apply (erule ValEnvE, simp) apply (blast dest: pmap_domainD) done lemma ve_empI: "ve_emp \ ValEnv" -apply (unfold ve_emp_def) + unfolding ve_emp_def apply (rule Val_ValEnv.intros) apply (rule pmap_empI) done lemma ve_owrI: "\ve \ ValEnv; x \ ExVar; v \ Val\ \ ve_owr(ve,x,v):ValEnv" apply (erule ValEnvE, simp) apply (blast intro: pmap_owrI Val_ValEnv.intros) done end diff --git a/src/ZF/Constructible/AC_in_L.thy b/src/ZF/Constructible/AC_in_L.thy --- a/src/ZF/Constructible/AC_in_L.thy +++ b/src/ZF/Constructible/AC_in_L.thy @@ -1,479 +1,479 @@ (* Title: ZF/Constructible/AC_in_L.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory *) section \The Axiom of Choice Holds in L!\ theory AC_in_L imports Formula Separation begin subsection\Extending a Wellordering over a List -- Lexicographic Power\ text\This could be moved into a library.\ consts rlist :: "[i,i]\i" inductive domains "rlist(A,r)" \ "list(A) * list(A)" intros shorterI: "\length(l') < length(l); l' \ list(A); l \ list(A)\ \ \ rlist(A,r)" sameI: "\ \ rlist(A,r); a \ A\ \ \ rlist(A,r)" diffI: "\length(l') = length(l); \ r; l' \ list(A); l \ list(A); a' \ A; a \ A\ \ \ rlist(A,r)" type_intros list.intros subsubsection\Type checking\ lemmas rlist_type = rlist.dom_subset lemmas field_rlist = rlist_type [THEN field_rel_subset] subsubsection\Linearity\ lemma rlist_Nil_Cons [intro]: "\a \ A; l \ list(A)\ \ <[], Cons(a,l)> \ rlist(A, r)" by (simp add: shorterI) lemma linear_rlist: assumes r: "linear(A,r)" shows "linear(list(A),rlist(A,r))" proof - { fix xs ys have "xs \ list(A) \ ys \ list(A) \ \xs,ys\ \ rlist(A,r) \ xs = ys \ \ys,xs\ \ rlist(A, r) " proof (induct xs arbitrary: ys rule: list.induct) case Nil thus ?case by (induct ys rule: list.induct) (auto simp add: shorterI) next case (Cons x xs) { fix y ys assume "y \ A" and "ys \ list(A)" with Cons have "\Cons(x,xs),Cons(y,ys)\ \ rlist(A,r) \ x=y \ xs = ys \ \Cons(y,ys), Cons(x,xs)\ \ rlist(A,r)" apply (rule_tac i = "length(xs)" and j = "length(ys)" in Ord_linear_lt) apply (simp_all add: shorterI) apply (rule linearE [OF r, of x y]) apply (auto simp add: diffI intro: sameI) done } note yConsCase = this show ?case using \ys \ list(A)\ by (cases rule: list.cases) (simp_all add: Cons rlist_Nil_Cons yConsCase) qed } thus ?thesis by (simp add: linear_def) qed subsubsection\Well-foundedness\ text\Nothing preceeds Nil in this ordering.\ inductive_cases rlist_NilE: " \ rlist(A,r)" inductive_cases rlist_ConsE: " \ rlist(A,r)" lemma not_rlist_Nil [simp]: " \ rlist(A,r)" by (blast intro: elim: rlist_NilE) lemma rlist_imp_length_le: " \ rlist(A,r) \ length(l') \ length(l)" apply (erule rlist.induct) apply (simp_all add: leI) done lemma wf_on_rlist_n: "\n \ nat; wf[A](r)\ \ wf[{l \ list(A). length(l) = n}](rlist(A,r))" apply (induct_tac n) apply (rule wf_onI2, simp) apply (rule wf_onI2, clarify) apply (erule_tac a=y in list.cases, clarify) apply (simp (no_asm_use)) apply clarify apply (simp (no_asm_use)) apply (subgoal_tac "\l2 \ list(A). length(l2) = x \ Cons(a,l2) \ B", blast) apply (erule_tac a=a in wf_on_induct, assumption) apply (rule ballI) apply (rule impI) apply (erule_tac a=l2 in wf_on_induct, blast, clarify) apply (rename_tac a' l2 l') apply (drule_tac x="Cons(a',l')" in bspec, typecheck) apply simp apply (erule mp, clarify) apply (erule rlist_ConsE, auto) done lemma list_eq_UN_length: "list(A) = (\n\nat. {l \ list(A). length(l) = n})" by (blast intro: length_type) lemma wf_on_rlist: "wf[A](r) \ wf[list(A)](rlist(A,r))" apply (subst list_eq_UN_length) apply (rule wf_on_Union) apply (rule wf_imp_wf_on [OF wf_Memrel [of nat]]) apply (simp add: wf_on_rlist_n) apply (frule rlist_type [THEN subsetD]) apply (simp add: length_type) apply (drule rlist_imp_length_le) apply (erule leE) apply (simp_all add: lt_def) done lemma wf_rlist: "wf(r) \ wf(rlist(field(r),r))" apply (simp add: wf_iff_wf_on_field) apply (rule wf_on_subset_A [OF _ field_rlist]) apply (blast intro: wf_on_rlist) done lemma well_ord_rlist: "well_ord(A,r) \ well_ord(list(A), rlist(A,r))" apply (rule well_ordI) apply (simp add: well_ord_def wf_on_rlist) apply (simp add: well_ord_def tot_ord_def linear_rlist) done subsection\An Injection from Formulas into the Natural Numbers\ text\There is a well-known bijection between \<^term>\nat*nat\ and \<^term>\nat\ given by the expression f(m,n) = triangle(m+n) + m, where triangle(k) enumerates the triangular numbers and can be defined by triangle(0)=0, triangle(succ(k)) = succ(k + triangle(k)). Some small amount of effort is needed to show that f is a bijection. We already know that such a bijection exists by the theorem \well_ord_InfCard_square_eq\: @{thm[display] well_ord_InfCard_square_eq[no_vars]} However, this result merely states that there is a bijection between the two sets. It provides no means of naming a specific bijection. Therefore, we conduct the proofs under the assumption that a bijection exists. The simplest way to organize this is to use a locale.\ text\Locale for any arbitrary injection between \<^term>\nat*nat\ and \<^term>\nat\\ locale Nat_Times_Nat = fixes fn assumes fn_inj: "fn \ inj(nat*nat, nat)" consts enum :: "[i,i]\i" primrec "enum(f, Member(x,y)) = f ` <0, f ` \x,y\>" "enum(f, Equal(x,y)) = f ` <1, f ` \x,y\>" "enum(f, Nand(p,q)) = f ` <2, f ` >" "enum(f, Forall(p)) = f ` " lemma (in Nat_Times_Nat) fn_type [TC,simp]: "\x \ nat; y \ nat\ \ fn`\x,y\ \ nat" by (blast intro: inj_is_fun [OF fn_inj] apply_funtype) lemma (in Nat_Times_Nat) fn_iff: "\x \ nat; y \ nat; u \ nat; v \ nat\ \ (fn`\x,y\ = fn`\u,v\) \ (x=u \ y=v)" by (blast dest: inj_apply_equality [OF fn_inj]) lemma (in Nat_Times_Nat) enum_type [TC,simp]: "p \ formula \ enum(fn,p) \ nat" by (induct_tac p, simp_all) lemma (in Nat_Times_Nat) enum_inject [rule_format]: "p \ formula \ \q\formula. enum(fn,p) = enum(fn,q) \ p=q" apply (induct_tac p, simp_all) apply (rule ballI) apply (erule formula.cases) apply (simp_all add: fn_iff) apply (rule ballI) apply (erule formula.cases) apply (simp_all add: fn_iff) apply (rule ballI) apply (erule_tac a=qa in formula.cases) apply (simp_all add: fn_iff) apply blast apply (rule ballI) apply (erule_tac a=q in formula.cases) apply (simp_all add: fn_iff, blast) done lemma (in Nat_Times_Nat) inj_formula_nat: "(\p \ formula. enum(fn,p)) \ inj(formula, nat)" apply (simp add: inj_def lam_type) apply (blast intro: enum_inject) done lemma (in Nat_Times_Nat) well_ord_formula: "well_ord(formula, measure(formula, enum(fn)))" apply (rule well_ord_measure, simp) apply (blast intro: enum_inject) done lemmas nat_times_nat_lepoll_nat = InfCard_nat [THEN InfCard_square_eqpoll, THEN eqpoll_imp_lepoll] text\Not needed--but interesting?\ theorem formula_lepoll_nat: "formula \ nat" apply (insert nat_times_nat_lepoll_nat) -apply (unfold lepoll_def) + unfolding lepoll_def apply (blast intro: Nat_Times_Nat.inj_formula_nat Nat_Times_Nat.intro) done subsection\Defining the Wellordering on \<^term>\DPow(A)\\ text\The objective is to build a wellordering on \<^term>\DPow(A)\ from a given one on \<^term>\A\. We first introduce wellorderings for environments, which are lists built over \<^term>\A\. We combine it with the enumeration of formulas. The order type of the resulting wellordering gives us a map from (environment, formula) pairs into the ordinals. For each member of \<^term>\DPow(A)\, we take the minimum such ordinal.\ definition env_form_r :: "[i,i,i]\i" where \ \wellordering on (environment, formula) pairs\ "env_form_r(f,r,A) \ rmult(list(A), rlist(A, r), formula, measure(formula, enum(f)))" definition env_form_map :: "[i,i,i,i]\i" where \ \map from (environment, formula) pairs to ordinals\ "env_form_map(f,r,A,z) \ ordermap(list(A) * formula, env_form_r(f,r,A)) ` z" definition DPow_ord :: "[i,i,i,i,i]\o" where \ \predicate that holds if \<^term>\k\ is a valid index for \<^term>\X\\ "DPow_ord(f,r,A,X,k) \ \env \ list(A). \p \ formula. arity(p) \ succ(length(env)) \ X = {x\A. sats(A, p, Cons(x,env))} \ env_form_map(f,r,A,\env,p\) = k" definition DPow_least :: "[i,i,i,i]\i" where \ \function yielding the smallest index for \<^term>\X\\ "DPow_least(f,r,A,X) \ \ k. DPow_ord(f,r,A,X,k)" definition DPow_r :: "[i,i,i]\i" where \ \a wellordering on \<^term>\DPow(A)\\ "DPow_r(f,r,A) \ measure(DPow(A), DPow_least(f,r,A))" lemma (in Nat_Times_Nat) well_ord_env_form_r: "well_ord(A,r) \ well_ord(list(A) * formula, env_form_r(fn,r,A))" by (simp add: env_form_r_def well_ord_rmult well_ord_rlist well_ord_formula) lemma (in Nat_Times_Nat) Ord_env_form_map: "\well_ord(A,r); z \ list(A) * formula\ \ Ord(env_form_map(fn,r,A,z))" by (simp add: env_form_map_def Ord_ordermap well_ord_env_form_r) lemma DPow_imp_ex_DPow_ord: "X \ DPow(A) \ \k. DPow_ord(fn,r,A,X,k)" apply (simp add: DPow_ord_def) apply (blast dest!: DPowD) done lemma (in Nat_Times_Nat) DPow_ord_imp_Ord: "\DPow_ord(fn,r,A,X,k); well_ord(A,r)\ \ Ord(k)" apply (simp add: DPow_ord_def, clarify) apply (simp add: Ord_env_form_map) done lemma (in Nat_Times_Nat) DPow_imp_DPow_least: "\X \ DPow(A); well_ord(A,r)\ \ DPow_ord(fn, r, A, X, DPow_least(fn,r,A,X))" apply (simp add: DPow_least_def) apply (blast dest: DPow_imp_ex_DPow_ord intro: DPow_ord_imp_Ord LeastI) done lemma (in Nat_Times_Nat) env_form_map_inject: "\env_form_map(fn,r,A,u) = env_form_map(fn,r,A,v); well_ord(A,r); u \ list(A) * formula; v \ list(A) * formula\ \ u=v" apply (simp add: env_form_map_def) apply (rule inj_apply_equality [OF bij_is_inj, OF ordermap_bij, OF well_ord_env_form_r], assumption+) done lemma (in Nat_Times_Nat) DPow_ord_unique: "\DPow_ord(fn,r,A,X,k); DPow_ord(fn,r,A,Y,k); well_ord(A,r)\ \ X=Y" apply (simp add: DPow_ord_def, clarify) apply (drule env_form_map_inject, auto) done lemma (in Nat_Times_Nat) well_ord_DPow_r: "well_ord(A,r) \ well_ord(DPow(A), DPow_r(fn,r,A))" apply (simp add: DPow_r_def) apply (rule well_ord_measure) apply (simp add: DPow_least_def) apply (drule DPow_imp_DPow_least, assumption)+ apply simp apply (blast intro: DPow_ord_unique) done lemma (in Nat_Times_Nat) DPow_r_type: "DPow_r(fn,r,A) \ DPow(A) * DPow(A)" by (simp add: DPow_r_def measure_def, blast) subsection\Limit Construction for Well-Orderings\ text\Now we work towards the transfinite definition of wellorderings for \<^term>\Lset(i)\. We assume as an inductive hypothesis that there is a family of wellorderings for smaller ordinals.\ definition rlimit :: "[i,i\i]\i" where \ \Expresses the wellordering at limit ordinals. The conditional lets us remove the premise \<^term>\Limit(i)\ from some theorems.\ "rlimit(i,r) \ if Limit(i) then {z: Lset(i) * Lset(i). \x' x. z = \ (lrank(x') < lrank(x) | (lrank(x') = lrank(x) \ \ r(succ(lrank(x)))))} else 0" definition Lset_new :: "i\i" where \ \This constant denotes the set of elements introduced at level \<^term>\succ(i)\\ "Lset_new(i) \ {x \ Lset(succ(i)). lrank(x) = i}" lemma Limit_Lset_eq2: "Limit(i) \ Lset(i) = (\j\i. Lset_new(j))" apply (simp add: Limit_Lset_eq) apply (rule equalityI) apply safe apply (subgoal_tac "Ord(y)") prefer 2 apply (blast intro: Ord_in_Ord Limit_is_Ord) apply (simp_all add: Limit_is_Ord Lset_iff_lrank_lt Lset_new_def Ord_mem_iff_lt) apply (blast intro: lt_trans) apply (rule_tac x = "succ(lrank(x))" in bexI) apply (simp) apply (blast intro: Limit_has_succ ltD) done lemma wf_on_Lset: "wf[Lset(succ(j))](r(succ(j))) \ wf[Lset_new(j)](rlimit(i,r))" apply (simp add: wf_on_def Lset_new_def) apply (erule wf_subset) apply (simp add: rlimit_def, force) done lemma wf_on_rlimit: "(\j wf[Lset(i)](rlimit(i,r))" apply (case_tac "Limit(i)") prefer 2 apply (simp add: rlimit_def wf_on_any_0) apply (simp add: Limit_Lset_eq2) apply (rule wf_on_Union) apply (rule wf_imp_wf_on [OF wf_Memrel [of i]]) apply (blast intro: wf_on_Lset Limit_has_succ Limit_is_Ord ltI) apply (force simp add: rlimit_def Limit_is_Ord Lset_iff_lrank_lt Lset_new_def Ord_mem_iff_lt) done lemma linear_rlimit: "\Limit(i); \j \ linear(Lset(i), rlimit(i,r))" apply (frule Limit_is_Ord) apply (simp add: Limit_Lset_eq2 Lset_new_def) apply (simp add: linear_def rlimit_def Ball_def lt_Ord Lset_iff_lrank_lt) apply (simp add: ltI, clarify) apply (rename_tac u v) apply (rule_tac i="lrank(u)" and j="lrank(v)" in Ord_linear_lt, simp_all) apply (drule_tac x="succ(lrank(u) \ lrank(v))" in ospec) apply (simp add: ltI) apply (drule_tac x=u in spec, simp) apply (drule_tac x=v in spec, simp) done lemma well_ord_rlimit: "\Limit(i); \j \ well_ord(Lset(i), rlimit(i,r))" by (blast intro: well_ordI wf_on_rlimit well_ord_is_wf linear_rlimit well_ord_is_linear) lemma rlimit_cong: "(\j. j r'(j) = r(j)) \ rlimit(i,r) = rlimit(i,r')" apply (simp add: rlimit_def, clarify) apply (rule refl iff_refl Collect_cong ex_cong conj_cong)+ apply (simp add: Limit_is_Ord Lset_lrank_lt) done subsection\Transfinite Definition of the Wellordering on \<^term>\L\\ definition L_r :: "[i, i] \ i" where "L_r(f) \ \i. transrec3(i, 0, \x r. DPow_r(f, r, Lset(x)), \x r. rlimit(x, \y. r`y))" subsubsection\The Corresponding Recursion Equations\ lemma [simp]: "L_r(f,0) = 0" by (simp add: L_r_def) lemma [simp]: "L_r(f, succ(i)) = DPow_r(f, L_r(f,i), Lset(i))" by (simp add: L_r_def) text\The limit case is non-trivial because of the distinction between object-level and meta-level abstraction.\ lemma [simp]: "Limit(i) \ L_r(f,i) = rlimit(i, L_r(f))" by (simp cong: rlimit_cong add: transrec3_Limit L_r_def ltD) lemma (in Nat_Times_Nat) L_r_type: "Ord(i) \ L_r(fn,i) \ Lset(i) * Lset(i)" apply (induct i rule: trans_induct3) apply (simp_all add: Lset_succ DPow_r_type well_ord_DPow_r rlimit_def Transset_subset_DPow [OF Transset_Lset], blast) done lemma (in Nat_Times_Nat) well_ord_L_r: "Ord(i) \ well_ord(Lset(i), L_r(fn,i))" apply (induct i rule: trans_induct3) apply (simp_all add: well_ord0 Lset_succ L_r_type well_ord_DPow_r well_ord_rlimit ltD) done lemma well_ord_L_r: "Ord(i) \ \r. well_ord(Lset(i), r)" apply (insert nat_times_nat_lepoll_nat) -apply (unfold lepoll_def) + unfolding lepoll_def apply (blast intro: Nat_Times_Nat.well_ord_L_r Nat_Times_Nat.intro) done text\Every constructible set is well-ordered! Therefore the Wellordering Theorem and the Axiom of Choice hold in \<^term>\L\\\ theorem L_implies_AC: assumes x: "L(x)" shows "\r. well_ord(x,r)" using Transset_Lset x apply (simp add: Transset_def L_def) apply (blast dest!: well_ord_L_r intro: well_ord_subset) done interpretation L: M_basic L by (rule M_basic_L) theorem "\x[L]. \r. wellordered(L,x,r)" proof fix x assume "L(x)" then obtain r where "well_ord(x,r)" by (blast dest: L_implies_AC) thus "\r. wellordered(L,x,r)" by (blast intro: L.well_ord_imp_relativized) qed text\In order to prove \<^term>\ \r[L]. wellordered(L,x,r)\, it's necessary to know that \<^term>\r\ is actually constructible. It follows from the assumption ``\<^term>\V\ equals \<^term>\L''\, but this reasoning doesn't appear to work in Isabelle.\ end diff --git a/src/ZF/Constructible/DPow_absolute.thy b/src/ZF/Constructible/DPow_absolute.thy --- a/src/ZF/Constructible/DPow_absolute.thy +++ b/src/ZF/Constructible/DPow_absolute.thy @@ -1,627 +1,627 @@ (* Title: ZF/Constructible/DPow_absolute.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory *) section \Absoluteness for the Definable Powerset Function\ theory DPow_absolute imports Satisfies_absolute begin subsection\Preliminary Internalizations\ subsubsection\The Operator \<^term>\is_formula_rec\\ text\The three arguments of \<^term>\p\ are always 2, 1, 0. It is buried within 11 quantifiers\\ (* is_formula_rec :: "[i\o, [i,i,i]\o, i, i] \ o" "is_formula_rec(M,MH,p,z) \ \dp[M]. \i[M]. \f[M]. finite_ordinal(M,dp) \ is_depth(M,p,dp) \ 2 1 0 successor(M,dp,i) \ fun_apply(M,f,p,z) \ is_transrec(M,MH,i,f)" *) definition formula_rec_fm :: "[i, i, i]\i" where "formula_rec_fm(mh,p,z) \ Exists(Exists(Exists( And(finite_ordinal_fm(2), And(depth_fm(p#+3,2), And(succ_fm(2,1), And(fun_apply_fm(0,p#+3,z#+3), is_transrec_fm(mh,1,0))))))))" lemma is_formula_rec_type [TC]: "\p \ formula; x \ nat; z \ nat\ \ formula_rec_fm(p,x,z) \ formula" by (simp add: formula_rec_fm_def) lemma sats_formula_rec_fm: assumes MH_iff_sats: "\a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10. \a0\A; a1\A; a2\A; a3\A; a4\A; a5\A; a6\A; a7\A; a8\A; a9\A; a10\A\ \ MH(a2, a1, a0) \ sats(A, p, Cons(a0,Cons(a1,Cons(a2,Cons(a3, Cons(a4,Cons(a5,Cons(a6,Cons(a7, Cons(a8,Cons(a9,Cons(a10,env))))))))))))" shows "\x \ nat; z \ nat; env \ list(A)\ \ sats(A, formula_rec_fm(p,x,z), env) \ is_formula_rec(##A, MH, nth(x,env), nth(z,env))" by (simp add: formula_rec_fm_def sats_is_transrec_fm is_formula_rec_def MH_iff_sats [THEN iff_sym]) lemma formula_rec_iff_sats: assumes MH_iff_sats: "\a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10. \a0\A; a1\A; a2\A; a3\A; a4\A; a5\A; a6\A; a7\A; a8\A; a9\A; a10\A\ \ MH(a2, a1, a0) \ sats(A, p, Cons(a0,Cons(a1,Cons(a2,Cons(a3, Cons(a4,Cons(a5,Cons(a6,Cons(a7, Cons(a8,Cons(a9,Cons(a10,env))))))))))))" shows "\nth(i,env) = x; nth(k,env) = z; i \ nat; k \ nat; env \ list(A)\ \ is_formula_rec(##A, MH, x, z) \ sats(A, formula_rec_fm(p,i,k), env)" by (simp add: sats_formula_rec_fm [OF MH_iff_sats]) theorem formula_rec_reflection: assumes MH_reflection: "\f' f g h. REFLECTS[\x. MH(L, f'(x), f(x), g(x), h(x)), \i x. MH(##Lset(i), f'(x), f(x), g(x), h(x))]" shows "REFLECTS[\x. is_formula_rec(L, MH(L,x), f(x), h(x)), \i x. is_formula_rec(##Lset(i), MH(##Lset(i),x), f(x), h(x))]" apply (simp (no_asm_use) only: is_formula_rec_def) apply (intro FOL_reflections function_reflections fun_plus_reflections depth_reflection is_transrec_reflection MH_reflection) done subsubsection\The Operator \<^term>\is_satisfies\\ (* is_satisfies(M,A,p,z) \ is_formula_rec (M, satisfies_MH(M,A), p, z) *) definition satisfies_fm :: "[i,i,i]\i" where "satisfies_fm(x) \ formula_rec_fm (satisfies_MH_fm(x#+5#+6, 2, 1, 0))" lemma is_satisfies_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ satisfies_fm(x,y,z) \ formula" by (simp add: satisfies_fm_def) lemma sats_satisfies_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, satisfies_fm(x,y,z), env) \ is_satisfies(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: satisfies_fm_def is_satisfies_def sats_formula_rec_fm) lemma satisfies_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ is_satisfies(##A, x, y, z) \ sats(A, satisfies_fm(i,j,k), env)" by (simp) theorem satisfies_reflection: "REFLECTS[\x. is_satisfies(L,f(x),g(x),h(x)), \i x. is_satisfies(##Lset(i),f(x),g(x),h(x))]" apply (simp only: is_satisfies_def) apply (intro formula_rec_reflection satisfies_MH_reflection) done subsection \Relativization of the Operator \<^term>\DPow'\\ lemma DPow'_eq: "DPow'(A) = {z . ep \ list(A) * formula, \env \ list(A). \p \ formula. ep = \env,p\ \ z = {x\A. sats(A, p, Cons(x,env))}}" by (simp add: DPow'_def, blast) text\Relativize the use of \<^term>\sats\ within \<^term>\DPow'\ (the comprehension).\ definition is_DPow_sats :: "[i\o,i,i,i,i] \ o" where "is_DPow_sats(M,A,env,p,x) \ \n1[M]. \e[M]. \sp[M]. is_satisfies(M,A,p,sp) \ is_Cons(M,x,env,e) \ fun_apply(M, sp, e, n1) \ number1(M, n1)" lemma (in M_satisfies) DPow_sats_abs: "\M(A); env \ list(A); p \ formula; M(x)\ \ is_DPow_sats(M,A,env,p,x) \ sats(A, p, Cons(x,env))" apply (subgoal_tac "M(env)") apply (simp add: is_DPow_sats_def satisfies_closed satisfies_abs) apply (blast dest: transM) done lemma (in M_satisfies) Collect_DPow_sats_abs: "\M(A); env \ list(A); p \ formula\ \ Collect(A, is_DPow_sats(M,A,env,p)) = {x \ A. sats(A, p, Cons(x,env))}" by (simp add: DPow_sats_abs transM [of _ A]) subsubsection\The Operator \<^term>\is_DPow_sats\, Internalized\ (* is_DPow_sats(M,A,env,p,x) \ \n1[M]. \e[M]. \sp[M]. is_satisfies(M,A,p,sp) \ is_Cons(M,x,env,e) \ fun_apply(M, sp, e, n1) \ number1(M, n1) *) definition DPow_sats_fm :: "[i,i,i,i]\i" where "DPow_sats_fm(A,env,p,x) \ Forall(Forall(Forall( Implies(satisfies_fm(A#+3,p#+3,0), Implies(Cons_fm(x#+3,env#+3,1), Implies(fun_apply_fm(0,1,2), number1_fm(2)))))))" lemma is_DPow_sats_type [TC]: "\A \ nat; x \ nat; y \ nat; z \ nat\ \ DPow_sats_fm(A,x,y,z) \ formula" by (simp add: DPow_sats_fm_def) lemma sats_DPow_sats_fm [simp]: "\u \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, DPow_sats_fm(u,x,y,z), env) \ is_DPow_sats(##A, nth(u,env), nth(x,env), nth(y,env), nth(z,env))" by (simp add: DPow_sats_fm_def is_DPow_sats_def) lemma DPow_sats_iff_sats: "\nth(u,env) = nu; nth(x,env) = nx; nth(y,env) = ny; nth(z,env) = nz; u \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ is_DPow_sats(##A,nu,nx,ny,nz) \ sats(A, DPow_sats_fm(u,x,y,z), env)" by simp theorem DPow_sats_reflection: "REFLECTS[\x. is_DPow_sats(L,f(x),g(x),h(x),g'(x)), \i x. is_DPow_sats(##Lset(i),f(x),g(x),h(x),g'(x))]" -apply (unfold is_DPow_sats_def) + unfolding is_DPow_sats_def apply (intro FOL_reflections function_reflections extra_reflections satisfies_reflection) done subsection\A Locale for Relativizing the Operator \<^term>\DPow'\\ locale M_DPow = M_satisfies + assumes sep: "\M(A); env \ list(A); p \ formula\ \ separation(M, \x. is_DPow_sats(M,A,env,p,x))" and rep: "M(A) \ strong_replacement (M, \ep z. \env[M]. \p[M]. mem_formula(M,p) \ mem_list(M,A,env) \ pair(M,env,p,ep) \ is_Collect(M, A, \x. is_DPow_sats(M,A,env,p,x), z))" lemma (in M_DPow) sep': "\M(A); env \ list(A); p \ formula\ \ separation(M, \x. sats(A, p, Cons(x,env)))" by (insert sep [of A env p], simp add: DPow_sats_abs) lemma (in M_DPow) rep': "M(A) \ strong_replacement (M, \ep z. \env\list(A). \p\formula. ep = \env,p\ \ z = {x \ A . sats(A, p, Cons(x, env))})" by (insert rep [of A], simp add: Collect_DPow_sats_abs) lemma univalent_pair_eq: "univalent (M, A, \xy z. \x\B. \y\C. xy = \x,y\ \ z = f(x,y))" by (simp add: univalent_def, blast) lemma (in M_DPow) DPow'_closed: "M(A) \ M(DPow'(A))" apply (simp add: DPow'_eq) apply (fast intro: rep' sep' univalent_pair_eq) done text\Relativization of the Operator \<^term>\DPow'\\ definition is_DPow' :: "[i\o,i,i] \ o" where "is_DPow'(M,A,Z) \ \X[M]. X \ Z \ subset(M,X,A) \ (\env[M]. \p[M]. mem_formula(M,p) \ mem_list(M,A,env) \ is_Collect(M, A, is_DPow_sats(M,A,env,p), X))" lemma (in M_DPow) DPow'_abs: "\M(A); M(Z)\ \ is_DPow'(M,A,Z) \ Z = DPow'(A)" apply (rule iffI) prefer 2 apply (simp add: is_DPow'_def DPow'_def Collect_DPow_sats_abs) apply (rule M_equalityI) apply (simp add: is_DPow'_def DPow'_def Collect_DPow_sats_abs, assumption) apply (erule DPow'_closed) done subsection\Instantiating the Locale \M_DPow\\ subsubsection\The Instance of Separation\ lemma DPow_separation: "\L(A); env \ list(A); p \ formula\ \ separation(L, \x. is_DPow_sats(L,A,env,p,x))" apply (rule gen_separation_multi [OF DPow_sats_reflection, of "{A,env,p}"], auto intro: transL) apply (rule_tac env="[A,env,p]" in DPow_LsetI) apply (rule DPow_sats_iff_sats sep_rules | simp)+ done subsubsection\The Instance of Replacement\ lemma DPow_replacement_Reflects: "REFLECTS [\x. \u[L]. u \ B \ (\env[L]. \p[L]. mem_formula(L,p) \ mem_list(L,A,env) \ pair(L,env,p,u) \ is_Collect (L, A, is_DPow_sats(L,A,env,p), x)), \i x. \u \ Lset(i). u \ B \ (\env \ Lset(i). \p \ Lset(i). mem_formula(##Lset(i),p) \ mem_list(##Lset(i),A,env) \ pair(##Lset(i),env,p,u) \ is_Collect (##Lset(i), A, is_DPow_sats(##Lset(i),A,env,p), x))]" -apply (unfold is_Collect_def) + unfolding is_Collect_def apply (intro FOL_reflections function_reflections mem_formula_reflection mem_list_reflection DPow_sats_reflection) done lemma DPow_replacement: "L(A) \ strong_replacement (L, \ep z. \env[L]. \p[L]. mem_formula(L,p) \ mem_list(L,A,env) \ pair(L,env,p,ep) \ is_Collect(L, A, \x. is_DPow_sats(L,A,env,p,x), z))" apply (rule strong_replacementI) apply (rule_tac u="{A,B}" in gen_separation_multi [OF DPow_replacement_Reflects], auto) -apply (unfold is_Collect_def) + unfolding is_Collect_def apply (rule_tac env="[A,B]" in DPow_LsetI) apply (rule sep_rules mem_formula_iff_sats mem_list_iff_sats DPow_sats_iff_sats | simp)+ done subsubsection\Actually Instantiating the Locale\ lemma M_DPow_axioms_L: "M_DPow_axioms(L)" apply (rule M_DPow_axioms.intro) apply (assumption | rule DPow_separation DPow_replacement)+ done theorem M_DPow_L: "M_DPow(L)" apply (rule M_DPow.intro) apply (rule M_satisfies_L) apply (rule M_DPow_axioms_L) done lemmas DPow'_closed [intro, simp] = M_DPow.DPow'_closed [OF M_DPow_L] and DPow'_abs [intro, simp] = M_DPow.DPow'_abs [OF M_DPow_L] subsubsection\The Operator \<^term>\is_Collect\\ text\The formula \<^term>\is_P\ has one free variable, 0, and it is enclosed within a single quantifier.\ (* is_Collect :: "[i\o,i,i\o,i] \ o" "is_Collect(M,A,P,z) \ \x[M]. x \ z \ x \ A \ P(x)" *) definition Collect_fm :: "[i, i, i]\i" where "Collect_fm(A,is_P,z) \ Forall(Iff(Member(0,succ(z)), And(Member(0,succ(A)), is_P)))" lemma is_Collect_type [TC]: "\is_P \ formula; x \ nat; y \ nat\ \ Collect_fm(x,is_P,y) \ formula" by (simp add: Collect_fm_def) lemma sats_Collect_fm: assumes is_P_iff_sats: "\a. a \ A \ is_P(a) \ sats(A, p, Cons(a, env))" shows "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, Collect_fm(x,p,y), env) \ is_Collect(##A, nth(x,env), is_P, nth(y,env))" by (simp add: Collect_fm_def is_Collect_def is_P_iff_sats [THEN iff_sym]) lemma Collect_iff_sats: assumes is_P_iff_sats: "\a. a \ A \ is_P(a) \ sats(A, p, Cons(a, env))" shows "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ is_Collect(##A, x, is_P, y) \ sats(A, Collect_fm(i,p,j), env)" by (simp add: sats_Collect_fm [OF is_P_iff_sats]) text\The second argument of \<^term>\is_P\ gives it direct access to \<^term>\x\, which is essential for handling free variable references.\ theorem Collect_reflection: assumes is_P_reflection: "\h f g. REFLECTS[\x. is_P(L, f(x), g(x)), \i x. is_P(##Lset(i), f(x), g(x))]" shows "REFLECTS[\x. is_Collect(L, f(x), is_P(L,x), g(x)), \i x. is_Collect(##Lset(i), f(x), is_P(##Lset(i), x), g(x))]" apply (simp (no_asm_use) only: is_Collect_def) apply (intro FOL_reflections is_P_reflection) done subsubsection\The Operator \<^term>\is_Replace\\ text\BEWARE! The formula \<^term>\is_P\ has free variables 0, 1 and not the usual 1, 0! It is enclosed within two quantifiers.\ (* is_Replace :: "[i\o,i,[i,i]\o,i] \ o" "is_Replace(M,A,P,z) \ \u[M]. u \ z \ (\x[M]. x\A \ P(x,u))" *) definition Replace_fm :: "[i, i, i]\i" where "Replace_fm(A,is_P,z) \ Forall(Iff(Member(0,succ(z)), Exists(And(Member(0,A#+2), is_P))))" lemma is_Replace_type [TC]: "\is_P \ formula; x \ nat; y \ nat\ \ Replace_fm(x,is_P,y) \ formula" by (simp add: Replace_fm_def) lemma sats_Replace_fm: assumes is_P_iff_sats: "\a b. \a \ A; b \ A\ \ is_P(a,b) \ sats(A, p, Cons(a,Cons(b,env)))" shows "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, Replace_fm(x,p,y), env) \ is_Replace(##A, nth(x,env), is_P, nth(y,env))" by (simp add: Replace_fm_def is_Replace_def is_P_iff_sats [THEN iff_sym]) lemma Replace_iff_sats: assumes is_P_iff_sats: "\a b. \a \ A; b \ A\ \ is_P(a,b) \ sats(A, p, Cons(a,Cons(b,env)))" shows "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ is_Replace(##A, x, is_P, y) \ sats(A, Replace_fm(i,p,j), env)" by (simp add: sats_Replace_fm [OF is_P_iff_sats]) text\The second argument of \<^term>\is_P\ gives it direct access to \<^term>\x\, which is essential for handling free variable references.\ theorem Replace_reflection: assumes is_P_reflection: "\h f g. REFLECTS[\x. is_P(L, f(x), g(x), h(x)), \i x. is_P(##Lset(i), f(x), g(x), h(x))]" shows "REFLECTS[\x. is_Replace(L, f(x), is_P(L,x), g(x)), \i x. is_Replace(##Lset(i), f(x), is_P(##Lset(i), x), g(x))]" apply (simp (no_asm_use) only: is_Replace_def) apply (intro FOL_reflections is_P_reflection) done subsubsection\The Operator \<^term>\is_DPow'\, Internalized\ (* "is_DPow'(M,A,Z) \ \X[M]. X \ Z \ subset(M,X,A) \ (\env[M]. \p[M]. mem_formula(M,p) \ mem_list(M,A,env) \ is_Collect(M, A, is_DPow_sats(M,A,env,p), X))" *) definition DPow'_fm :: "[i,i]\i" where "DPow'_fm(A,Z) \ Forall( Iff(Member(0,succ(Z)), And(subset_fm(0,succ(A)), Exists(Exists( And(mem_formula_fm(0), And(mem_list_fm(A#+3,1), Collect_fm(A#+3, DPow_sats_fm(A#+4, 2, 1, 0), 2))))))))" lemma is_DPow'_type [TC]: "\x \ nat; y \ nat\ \ DPow'_fm(x,y) \ formula" by (simp add: DPow'_fm_def) lemma sats_DPow'_fm [simp]: "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, DPow'_fm(x,y), env) \ is_DPow'(##A, nth(x,env), nth(y,env))" by (simp add: DPow'_fm_def is_DPow'_def sats_subset_fm' sats_Collect_fm) lemma DPow'_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ is_DPow'(##A, x, y) \ sats(A, DPow'_fm(i,j), env)" by (simp) theorem DPow'_reflection: "REFLECTS[\x. is_DPow'(L,f(x),g(x)), \i x. is_DPow'(##Lset(i),f(x),g(x))]" apply (simp only: is_DPow'_def) apply (intro FOL_reflections function_reflections mem_formula_reflection mem_list_reflection Collect_reflection DPow_sats_reflection) done subsection\A Locale for Relativizing the Operator \<^term>\Lset\\ definition transrec_body :: "[i\o,i,i,i,i] \ o" where "transrec_body(M,g,x) \ \y z. \gy[M]. y \ x \ fun_apply(M,g,y,gy) \ is_DPow'(M,gy,z)" lemma (in M_DPow) transrec_body_abs: "\M(x); M(g); M(z)\ \ transrec_body(M,g,x,y,z) \ y \ x \ z = DPow'(g`y)" by (simp add: transrec_body_def DPow'_abs transM [of _ x]) locale M_Lset = M_DPow + assumes strong_rep: "\M(x); M(g)\ \ strong_replacement(M, \y z. transrec_body(M,g,x,y,z))" and transrec_rep: "M(i) \ transrec_replacement(M, \x f u. \r[M]. is_Replace(M, x, transrec_body(M,f,x), r) \ big_union(M, r, u), i)" lemma (in M_Lset) strong_rep': "\M(x); M(g)\ \ strong_replacement(M, \y z. y \ x \ z = DPow'(g`y))" by (insert strong_rep [of x g], simp add: transrec_body_abs) lemma (in M_Lset) DPow_apply_closed: "\M(f); M(x); y\x\ \ M(DPow'(f`y))" by (blast intro: DPow'_closed dest: transM) lemma (in M_Lset) RepFun_DPow_apply_closed: "\M(f); M(x)\ \ M({DPow'(f`y). y\x})" by (blast intro: DPow_apply_closed RepFun_closed2 strong_rep') lemma (in M_Lset) RepFun_DPow_abs: "\M(x); M(f); M(r)\ \ is_Replace(M, x, \y z. transrec_body(M,f,x,y,z), r) \ r = {DPow'(f`y). y\x}" apply (simp add: transrec_body_abs RepFun_def) apply (rule iff_trans) apply (rule Replace_abs) apply (simp_all add: DPow_apply_closed strong_rep') done lemma (in M_Lset) transrec_rep': "M(i) \ transrec_replacement(M, \x f u. u = (\y\x. DPow'(f ` y)), i)" apply (insert transrec_rep [of i]) apply (simp add: RepFun_DPow_apply_closed RepFun_DPow_abs transrec_replacement_def) done text\Relativization of the Operator \<^term>\Lset\\ definition is_Lset :: "[i\o, i, i] \ o" where \ \We can use the term language below because \<^term>\is_Lset\ will not have to be internalized: it isn't used in any instance of separation.\ "is_Lset(M,a,z) \ is_transrec(M, \x f u. u = (\y\x. DPow'(f`y)), a, z)" lemma (in M_Lset) Lset_abs: "\Ord(i); M(i); M(z)\ \ is_Lset(M,i,z) \ z = Lset(i)" apply (simp add: is_Lset_def Lset_eq_transrec_DPow') apply (rule transrec_abs) apply (simp_all add: transrec_rep' relation2_def RepFun_DPow_apply_closed) done lemma (in M_Lset) Lset_closed: "\Ord(i); M(i)\ \ M(Lset(i))" apply (simp add: Lset_eq_transrec_DPow') apply (rule transrec_closed [OF transrec_rep']) apply (simp_all add: relation2_def RepFun_DPow_apply_closed) done subsection\Instantiating the Locale \M_Lset\\ subsubsection\The First Instance of Replacement\ lemma strong_rep_Reflects: "REFLECTS [\u. \v[L]. v \ B \ (\gy[L]. v \ x \ fun_apply(L,g,v,gy) \ is_DPow'(L,gy,u)), \i u. \v \ Lset(i). v \ B \ (\gy \ Lset(i). v \ x \ fun_apply(##Lset(i),g,v,gy) \ is_DPow'(##Lset(i),gy,u))]" by (intro FOL_reflections function_reflections DPow'_reflection) lemma strong_rep: "\L(x); L(g)\ \ strong_replacement(L, \y z. transrec_body(L,g,x,y,z))" -apply (unfold transrec_body_def) + unfolding transrec_body_def apply (rule strong_replacementI) apply (rule_tac u="{x,g,B}" in gen_separation_multi [OF strong_rep_Reflects], auto) apply (rule_tac env="[x,g,B]" in DPow_LsetI) apply (rule sep_rules DPow'_iff_sats | simp)+ done subsubsection\The Second Instance of Replacement\ lemma transrec_rep_Reflects: "REFLECTS [\x. \v[L]. v \ B \ (\y[L]. pair(L,v,y,x) \ is_wfrec (L, \x f u. \r[L]. is_Replace (L, x, \y z. \gy[L]. y \ x \ fun_apply(L,f,y,gy) \ is_DPow'(L,gy,z), r) \ big_union(L,r,u), mr, v, y)), \i x. \v \ Lset(i). v \ B \ (\y \ Lset(i). pair(##Lset(i),v,y,x) \ is_wfrec (##Lset(i), \x f u. \r \ Lset(i). is_Replace (##Lset(i), x, \y z. \gy \ Lset(i). y \ x \ fun_apply(##Lset(i),f,y,gy) \ is_DPow'(##Lset(i),gy,z), r) \ big_union(##Lset(i),r,u), mr, v, y))]" apply (simp only: rex_setclass_is_bex [symmetric]) \ \Convert \\y\Lset(i)\ to \\y[##Lset(i)]\ within the body of the \<^term>\is_wfrec\ application.\ apply (intro FOL_reflections function_reflections is_wfrec_reflection Replace_reflection DPow'_reflection) done lemma transrec_rep: "\L(j)\ \ transrec_replacement(L, \x f u. \r[L]. is_Replace(L, x, transrec_body(L,f,x), r) \ big_union(L, r, u), j)" apply (rule L.transrec_replacementI, assumption) -apply (unfold transrec_body_def) + unfolding transrec_body_def apply (rule strong_replacementI) apply (rule_tac u="{j,B,Memrel(eclose({j}))}" in gen_separation_multi [OF transrec_rep_Reflects], auto) apply (rule_tac env="[j,B,Memrel(eclose({j}))]" in DPow_LsetI) apply (rule sep_rules is_wfrec_iff_sats Replace_iff_sats DPow'_iff_sats | simp)+ done subsubsection\Actually Instantiating \M_Lset\\ lemma M_Lset_axioms_L: "M_Lset_axioms(L)" apply (rule M_Lset_axioms.intro) apply (assumption | rule strong_rep transrec_rep)+ done theorem M_Lset_L: "M_Lset(L)" apply (rule M_Lset.intro) apply (rule M_DPow_L) apply (rule M_Lset_axioms_L) done text\Finally: the point of the whole theory!\ lemmas Lset_closed = M_Lset.Lset_closed [OF M_Lset_L] and Lset_abs = M_Lset.Lset_abs [OF M_Lset_L] subsection\The Notion of Constructible Set\ definition constructible :: "[i\o,i] \ o" where "constructible(M,x) \ \i[M]. \Li[M]. ordinal(M,i) \ is_Lset(M,i,Li) \ x \ Li" theorem V_equals_L_in_L: "L(x) \ constructible(L,x)" apply (simp add: constructible_def Lset_abs Lset_closed) apply (simp add: L_def) apply (blast intro: Ord_in_L) done end diff --git a/src/ZF/Constructible/Formula.thy b/src/ZF/Constructible/Formula.thy --- a/src/ZF/Constructible/Formula.thy +++ b/src/ZF/Constructible/Formula.thy @@ -1,1040 +1,1040 @@ (* Title: ZF/Constructible/Formula.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory *) section \First-Order Formulas and the Definition of the Class L\ theory Formula imports ZF begin subsection\Internalized formulas of FOL\ text\De Bruijn representation. Unbound variables get their denotations from an environment.\ consts formula :: i datatype "formula" = Member ("x \ nat", "y \ nat") | Equal ("x \ nat", "y \ nat") | Nand ("p \ formula", "q \ formula") | Forall ("p \ formula") declare formula.intros [TC] definition Neg :: "i\i" where "Neg(p) \ Nand(p,p)" definition And :: "[i,i]\i" where "And(p,q) \ Neg(Nand(p,q))" definition Or :: "[i,i]\i" where "Or(p,q) \ Nand(Neg(p),Neg(q))" definition Implies :: "[i,i]\i" where "Implies(p,q) \ Nand(p,Neg(q))" definition Iff :: "[i,i]\i" where "Iff(p,q) \ And(Implies(p,q), Implies(q,p))" definition Exists :: "i\i" where "Exists(p) \ Neg(Forall(Neg(p)))" lemma Neg_type [TC]: "p \ formula \ Neg(p) \ formula" by (simp add: Neg_def) lemma And_type [TC]: "\p \ formula; q \ formula\ \ And(p,q) \ formula" by (simp add: And_def) lemma Or_type [TC]: "\p \ formula; q \ formula\ \ Or(p,q) \ formula" by (simp add: Or_def) lemma Implies_type [TC]: "\p \ formula; q \ formula\ \ Implies(p,q) \ formula" by (simp add: Implies_def) lemma Iff_type [TC]: "\p \ formula; q \ formula\ \ Iff(p,q) \ formula" by (simp add: Iff_def) lemma Exists_type [TC]: "p \ formula \ Exists(p) \ formula" by (simp add: Exists_def) consts satisfies :: "[i,i]\i" primrec (*explicit lambda is required because the environment varies*) "satisfies(A,Member(x,y)) = (\env \ list(A). bool_of_o (nth(x,env) \ nth(y,env)))" "satisfies(A,Equal(x,y)) = (\env \ list(A). bool_of_o (nth(x,env) = nth(y,env)))" "satisfies(A,Nand(p,q)) = (\env \ list(A). not ((satisfies(A,p)`env) and (satisfies(A,q)`env)))" "satisfies(A,Forall(p)) = (\env \ list(A). bool_of_o (\x\A. satisfies(A,p) ` (Cons(x,env)) = 1))" lemma satisfies_type: "p \ formula \ satisfies(A,p) \ list(A) -> bool" by (induct set: formula) simp_all abbreviation sats :: "[i,i,i] \ o" where "sats(A,p,env) \ satisfies(A,p)`env = 1" lemma sats_Member_iff [simp]: "env \ list(A) \ sats(A, Member(x,y), env) \ nth(x,env) \ nth(y,env)" by simp lemma sats_Equal_iff [simp]: "env \ list(A) \ sats(A, Equal(x,y), env) \ nth(x,env) = nth(y,env)" by simp lemma sats_Nand_iff [simp]: "env \ list(A) \ (sats(A, Nand(p,q), env)) \ \ (sats(A,p,env) \ sats(A,q,env))" by (simp add: Bool.and_def Bool.not_def cond_def) lemma sats_Forall_iff [simp]: "env \ list(A) \ sats(A, Forall(p), env) \ (\x\A. sats(A, p, Cons(x,env)))" by simp declare satisfies.simps [simp del] subsection\Dividing line between primitive and derived connectives\ lemma sats_Neg_iff [simp]: "env \ list(A) \ sats(A, Neg(p), env) \ \ sats(A,p,env)" by (simp add: Neg_def) lemma sats_And_iff [simp]: "env \ list(A) \ (sats(A, And(p,q), env)) \ sats(A,p,env) \ sats(A,q,env)" by (simp add: And_def) lemma sats_Or_iff [simp]: "env \ list(A) \ (sats(A, Or(p,q), env)) \ sats(A,p,env) | sats(A,q,env)" by (simp add: Or_def) lemma sats_Implies_iff [simp]: "env \ list(A) \ (sats(A, Implies(p,q), env)) \ (sats(A,p,env) \ sats(A,q,env))" by (simp add: Implies_def, blast) lemma sats_Iff_iff [simp]: "env \ list(A) \ (sats(A, Iff(p,q), env)) \ (sats(A,p,env) \ sats(A,q,env))" by (simp add: Iff_def, blast) lemma sats_Exists_iff [simp]: "env \ list(A) \ sats(A, Exists(p), env) \ (\x\A. sats(A, p, Cons(x,env)))" by (simp add: Exists_def) subsubsection\Derived rules to help build up formulas\ lemma mem_iff_sats: "\nth(i,env) = x; nth(j,env) = y; env \ list(A)\ \ (x\y) \ sats(A, Member(i,j), env)" by (simp add: satisfies.simps) lemma equal_iff_sats: "\nth(i,env) = x; nth(j,env) = y; env \ list(A)\ \ (x=y) \ sats(A, Equal(i,j), env)" by (simp add: satisfies.simps) lemma not_iff_sats: "\P \ sats(A,p,env); env \ list(A)\ \ (\P) \ sats(A, Neg(p), env)" by simp lemma conj_iff_sats: "\P \ sats(A,p,env); Q \ sats(A,q,env); env \ list(A)\ \ (P \ Q) \ sats(A, And(p,q), env)" by (simp) lemma disj_iff_sats: "\P \ sats(A,p,env); Q \ sats(A,q,env); env \ list(A)\ \ (P | Q) \ sats(A, Or(p,q), env)" by (simp) lemma iff_iff_sats: "\P \ sats(A,p,env); Q \ sats(A,q,env); env \ list(A)\ \ (P \ Q) \ sats(A, Iff(p,q), env)" by (simp) lemma imp_iff_sats: "\P \ sats(A,p,env); Q \ sats(A,q,env); env \ list(A)\ \ (P \ Q) \ sats(A, Implies(p,q), env)" by (simp) lemma ball_iff_sats: "\\x. x\A \ P(x) \ sats(A, p, Cons(x, env)); env \ list(A)\ \ (\x\A. P(x)) \ sats(A, Forall(p), env)" by (simp) lemma bex_iff_sats: "\\x. x\A \ P(x) \ sats(A, p, Cons(x, env)); env \ list(A)\ \ (\x\A. P(x)) \ sats(A, Exists(p), env)" by (simp) lemmas FOL_iff_sats = mem_iff_sats equal_iff_sats not_iff_sats conj_iff_sats disj_iff_sats imp_iff_sats iff_iff_sats imp_iff_sats ball_iff_sats bex_iff_sats subsection\Arity of a Formula: Maximum Free de Bruijn Index\ consts arity :: "i\i" primrec "arity(Member(x,y)) = succ(x) \ succ(y)" "arity(Equal(x,y)) = succ(x) \ succ(y)" "arity(Nand(p,q)) = arity(p) \ arity(q)" "arity(Forall(p)) = Arith.pred(arity(p))" lemma arity_type [TC]: "p \ formula \ arity(p) \ nat" by (induct_tac p, simp_all) lemma arity_Neg [simp]: "arity(Neg(p)) = arity(p)" by (simp add: Neg_def) lemma arity_And [simp]: "arity(And(p,q)) = arity(p) \ arity(q)" by (simp add: And_def) lemma arity_Or [simp]: "arity(Or(p,q)) = arity(p) \ arity(q)" by (simp add: Or_def) lemma arity_Implies [simp]: "arity(Implies(p,q)) = arity(p) \ arity(q)" by (simp add: Implies_def) lemma arity_Iff [simp]: "arity(Iff(p,q)) = arity(p) \ arity(q)" by (simp add: Iff_def, blast) lemma arity_Exists [simp]: "arity(Exists(p)) = Arith.pred(arity(p))" by (simp add: Exists_def) lemma arity_sats_iff [rule_format]: "\p \ formula; extra \ list(A)\ \ \env \ list(A). arity(p) \ length(env) \ sats(A, p, env @ extra) \ sats(A, p, env)" apply (induct_tac p) apply (simp_all add: Arith.pred_def nth_append Un_least_lt_iff nat_imp_quasinat split: split_nat_case, auto) done lemma arity_sats1_iff: "\arity(p) \ succ(length(env)); p \ formula; x \ A; env \ list(A); extra \ list(A)\ \ sats(A, p, Cons(x, env @ extra)) \ sats(A, p, Cons(x, env))" apply (insert arity_sats_iff [of p extra A "Cons(x,env)"]) apply simp done subsection\Renaming Some de Bruijn Variables\ definition incr_var :: "[i,i]\i" where "incr_var(x,nq) \ if x incr_var(x,nq) = x" by (simp add: incr_var_def) lemma incr_var_le: "nq\x \ incr_var(x,nq) = succ(x)" apply (simp add: incr_var_def) apply (blast dest: lt_trans1) done consts incr_bv :: "i\i" primrec "incr_bv(Member(x,y)) = (\nq \ nat. Member (incr_var(x,nq), incr_var(y,nq)))" "incr_bv(Equal(x,y)) = (\nq \ nat. Equal (incr_var(x,nq), incr_var(y,nq)))" "incr_bv(Nand(p,q)) = (\nq \ nat. Nand (incr_bv(p)`nq, incr_bv(q)`nq))" "incr_bv(Forall(p)) = (\nq \ nat. Forall (incr_bv(p) ` succ(nq)))" lemma [TC]: "x \ nat \ incr_var(x,nq) \ nat" by (simp add: incr_var_def) lemma incr_bv_type [TC]: "p \ formula \ incr_bv(p) \ nat -> formula" by (induct_tac p, simp_all) text\Obviously, \<^term>\DPow\ is closed under complements and finite intersections and unions. Needs an inductive lemma to allow two lists of parameters to be combined.\ lemma sats_incr_bv_iff [rule_format]: "\p \ formula; env \ list(A); x \ A\ \ \bvs \ list(A). sats(A, incr_bv(p) ` length(bvs), bvs @ Cons(x,env)) \ sats(A, p, bvs@env)" apply (induct_tac p) apply (simp_all add: incr_var_def nth_append succ_lt_iff length_type) apply (auto simp add: diff_succ not_lt_iff_le) done (*the following two lemmas prevent huge case splits in arity_incr_bv_lemma*) lemma incr_var_lemma: "\x \ nat; y \ nat; nq \ x\ \ succ(x) \ incr_var(y,nq) = succ(x \ y)" apply (simp add: incr_var_def Ord_Un_if, auto) apply (blast intro: leI) apply (simp add: not_lt_iff_le) apply (blast intro: le_anti_sym) apply (blast dest: lt_trans2) done lemma incr_And_lemma: "y < x \ y \ succ(x) = succ(x \ y)" apply (simp add: Ord_Un_if lt_Ord lt_Ord2 succ_lt_iff) apply (blast dest: lt_asym) done lemma arity_incr_bv_lemma [rule_format]: "p \ formula \ \n \ nat. arity (incr_bv(p) ` n) = (if n < arity(p) then succ(arity(p)) else arity(p))" apply (induct_tac p) apply (simp_all add: imp_disj not_lt_iff_le Un_least_lt_iff lt_Un_iff le_Un_iff succ_Un_distrib [symmetric] incr_var_lt incr_var_le Un_commute incr_var_lemma Arith.pred_def nat_imp_quasinat split: split_nat_case) txt\the Forall case reduces to linear arithmetic\ prefer 2 apply clarify apply (blast dest: lt_trans1) txt\left with the And case\ apply safe apply (blast intro: incr_And_lemma lt_trans1) apply (subst incr_And_lemma) apply (blast intro: lt_trans1) apply (simp add: Un_commute) done subsection\Renaming all but the First de Bruijn Variable\ definition incr_bv1 :: "i \ i" where "incr_bv1(p) \ incr_bv(p)`1" lemma incr_bv1_type [TC]: "p \ formula \ incr_bv1(p) \ formula" by (simp add: incr_bv1_def) (*For renaming all but the bound variable at level 0*) lemma sats_incr_bv1_iff: "\p \ formula; env \ list(A); x \ A; y \ A\ \ sats(A, incr_bv1(p), Cons(x, Cons(y, env))) \ sats(A, p, Cons(x,env))" apply (insert sats_incr_bv_iff [of p env A y "Cons(x,Nil)"]) apply (simp add: incr_bv1_def) done lemma formula_add_params1 [rule_format]: "\p \ formula; n \ nat; x \ A\ \ \bvs \ list(A). \env \ list(A). length(bvs) = n \ sats(A, iterates(incr_bv1, n, p), Cons(x, bvs@env)) \ sats(A, p, Cons(x,env))" apply (induct_tac n, simp, clarify) apply (erule list.cases) apply (simp_all add: sats_incr_bv1_iff) done lemma arity_incr_bv1_eq: "p \ formula \ arity(incr_bv1(p)) = (if 1 < arity(p) then succ(arity(p)) else arity(p))" apply (insert arity_incr_bv_lemma [of p 1]) apply (simp add: incr_bv1_def) done lemma arity_iterates_incr_bv1_eq: "\p \ formula; n \ nat\ \ arity(incr_bv1^n(p)) = (if 1 < arity(p) then n #+ arity(p) else arity(p))" apply (induct_tac n) apply (simp_all add: arity_incr_bv1_eq) apply (simp add: not_lt_iff_le) apply (blast intro: le_trans add_le_self2 arity_type) done subsection\Definable Powerset\ text\The definable powerset operation: Kunen's definition VI 1.1, page 165.\ definition DPow :: "i \ i" where "DPow(A) \ {X \ Pow(A). \env \ list(A). \p \ formula. arity(p) \ succ(length(env)) \ X = {x\A. sats(A, p, Cons(x,env))}}" lemma DPowI: "\env \ list(A); p \ formula; arity(p) \ succ(length(env))\ \ {x\A. sats(A, p, Cons(x,env))} \ DPow(A)" by (simp add: DPow_def, blast) text\With this rule we can specify \<^term>\p\ later.\ lemma DPowI2 [rule_format]: "\\x\A. P(x) \ sats(A, p, Cons(x,env)); env \ list(A); p \ formula; arity(p) \ succ(length(env))\ \ {x\A. P(x)} \ DPow(A)" by (simp add: DPow_def, blast) lemma DPowD: "X \ DPow(A) \ X \ A \ (\env \ list(A). \p \ formula. arity(p) \ succ(length(env)) \ X = {x\A. sats(A, p, Cons(x,env))})" by (simp add: DPow_def) lemmas DPow_imp_subset = DPowD [THEN conjunct1] (*Kunen's Lemma VI 1.2*) lemma "\p \ formula; env \ list(A); arity(p) \ succ(length(env))\ \ {x\A. sats(A, p, Cons(x,env))} \ DPow(A)" by (blast intro: DPowI) lemma DPow_subset_Pow: "DPow(A) \ Pow(A)" by (simp add: DPow_def, blast) lemma empty_in_DPow: "0 \ DPow(A)" apply (simp add: DPow_def) apply (rule_tac x=Nil in bexI) apply (rule_tac x="Neg(Equal(0,0))" in bexI) apply (auto simp add: Un_least_lt_iff) done lemma Compl_in_DPow: "X \ DPow(A) \ (A-X) \ DPow(A)" apply (simp add: DPow_def, clarify, auto) apply (rule bexI) apply (rule_tac x="Neg(p)" in bexI) apply auto done lemma Int_in_DPow: "\X \ DPow(A); Y \ DPow(A)\ \ X \ Y \ DPow(A)" apply (simp add: DPow_def, auto) apply (rename_tac envp p envq q) apply (rule_tac x="envp@envq" in bexI) apply (rule_tac x="And(p, iterates(incr_bv1,length(envp),q))" in bexI) apply typecheck apply (rule conjI) (*finally check the arity!*) apply (simp add: arity_iterates_incr_bv1_eq Un_least_lt_iff) apply (force intro: add_le_self le_trans) apply (simp add: arity_sats1_iff formula_add_params1, blast) done lemma Un_in_DPow: "\X \ DPow(A); Y \ DPow(A)\ \ X \ Y \ DPow(A)" apply (subgoal_tac "X \ Y = A - ((A-X) \ (A-Y))") apply (simp add: Int_in_DPow Compl_in_DPow) apply (simp add: DPow_def, blast) done lemma singleton_in_DPow: "a \ A \ {a} \ DPow(A)" apply (simp add: DPow_def) apply (rule_tac x="Cons(a,Nil)" in bexI) apply (rule_tac x="Equal(0,1)" in bexI) apply typecheck apply (force simp add: succ_Un_distrib [symmetric]) done lemma cons_in_DPow: "\a \ A; X \ DPow(A)\ \ cons(a,X) \ DPow(A)" apply (rule cons_eq [THEN subst]) apply (blast intro: singleton_in_DPow Un_in_DPow) done (*Part of Lemma 1.3*) lemma Fin_into_DPow: "X \ Fin(A) \ X \ DPow(A)" apply (erule Fin.induct) apply (rule empty_in_DPow) apply (blast intro: cons_in_DPow) done text\\<^term>\DPow\ is not monotonic. For example, let \<^term>\A\ be some non-constructible set of natural numbers, and let \<^term>\B\ be \<^term>\nat\. Then \<^term>\A<=B\ and obviously \<^term>\A \ DPow(A)\ but \<^term>\A \ DPow(B)\.\ (*This may be true but the proof looks difficult, requiring relativization lemma DPow_insert: "DPow (cons(a,A)) = DPow(A) \ {cons(a,X) . X \ DPow(A)}" apply (rule equalityI, safe) oops *) lemma Finite_Pow_subset_Pow: "Finite(A) \ Pow(A) \ DPow(A)" by (blast intro: Fin_into_DPow Finite_into_Fin Fin_subset) lemma Finite_DPow_eq_Pow: "Finite(A) \ DPow(A) = Pow(A)" apply (rule equalityI) apply (rule DPow_subset_Pow) apply (erule Finite_Pow_subset_Pow) done subsection\Internalized Formulas for the Ordinals\ text\The \sats\ theorems below differ from the usual form in that they include an element of absoluteness. That is, they relate internalized formulas to real concepts such as the subset relation, rather than to the relativized concepts defined in theory \Relative\. This lets us prove the theorem as \Ords_in_DPow\ without first having to instantiate the locale \M_trivial\. Note that the present theory does not even take \Relative\ as a parent.\ subsubsection\The subset relation\ definition subset_fm :: "[i,i]\i" where "subset_fm(x,y) \ Forall(Implies(Member(0,succ(x)), Member(0,succ(y))))" lemma subset_type [TC]: "\x \ nat; y \ nat\ \ subset_fm(x,y) \ formula" by (simp add: subset_fm_def) lemma arity_subset_fm [simp]: "\x \ nat; y \ nat\ \ arity(subset_fm(x,y)) = succ(x) \ succ(y)" by (simp add: subset_fm_def succ_Un_distrib [symmetric]) lemma sats_subset_fm [simp]: "\x < length(env); y \ nat; env \ list(A); Transset(A)\ \ sats(A, subset_fm(x,y), env) \ nth(x,env) \ nth(y,env)" apply (frule lt_length_in_nat, assumption) apply (simp add: subset_fm_def Transset_def) apply (blast intro: nth_type) done subsubsection\Transitive sets\ definition transset_fm :: "i\i" where "transset_fm(x) \ Forall(Implies(Member(0,succ(x)), subset_fm(0,succ(x))))" lemma transset_type [TC]: "x \ nat \ transset_fm(x) \ formula" by (simp add: transset_fm_def) lemma arity_transset_fm [simp]: "x \ nat \ arity(transset_fm(x)) = succ(x)" by (simp add: transset_fm_def succ_Un_distrib [symmetric]) lemma sats_transset_fm [simp]: "\x < length(env); env \ list(A); Transset(A)\ \ sats(A, transset_fm(x), env) \ Transset(nth(x,env))" apply (frule lt_nat_in_nat, erule length_type) apply (simp add: transset_fm_def Transset_def) apply (blast intro: nth_type) done subsubsection\Ordinals\ definition ordinal_fm :: "i\i" where "ordinal_fm(x) \ And(transset_fm(x), Forall(Implies(Member(0,succ(x)), transset_fm(0))))" lemma ordinal_type [TC]: "x \ nat \ ordinal_fm(x) \ formula" by (simp add: ordinal_fm_def) lemma arity_ordinal_fm [simp]: "x \ nat \ arity(ordinal_fm(x)) = succ(x)" by (simp add: ordinal_fm_def succ_Un_distrib [symmetric]) lemma sats_ordinal_fm: "\x < length(env); env \ list(A); Transset(A)\ \ sats(A, ordinal_fm(x), env) \ Ord(nth(x,env))" apply (frule lt_nat_in_nat, erule length_type) apply (simp add: ordinal_fm_def Ord_def Transset_def) apply (blast intro: nth_type) done text\The subset consisting of the ordinals is definable. Essential lemma for \Ord_in_Lset\. This result is the objective of the present subsection.\ theorem Ords_in_DPow: "Transset(A) \ {x \ A. Ord(x)} \ DPow(A)" apply (simp add: DPow_def Collect_subset) apply (rule_tac x=Nil in bexI) apply (rule_tac x="ordinal_fm(0)" in bexI) apply (simp_all add: sats_ordinal_fm) done subsection\Constant Lset: Levels of the Constructible Universe\ definition Lset :: "i\i" where "Lset(i) \ transrec(i, \x f. \y\x. DPow(f`y))" definition L :: "i\o" where \ \Kunen's definition VI 1.5, page 167\ "L(x) \ \i. Ord(i) \ x \ Lset(i)" text\NOT SUITABLE FOR REWRITING -- RECURSIVE!\ lemma Lset: "Lset(i) = (\j\i. DPow(Lset(j)))" by (subst Lset_def [THEN def_transrec], simp) lemma LsetI: "\y\x; A \ DPow(Lset(y))\ \ A \ Lset(x)" by (subst Lset, blast) lemma LsetD: "A \ Lset(x) \ \y\x. A \ DPow(Lset(y))" apply (insert Lset [of x]) apply (blast intro: elim: equalityE) done subsubsection\Transitivity\ lemma elem_subset_in_DPow: "\X \ A; X \ A\ \ X \ DPow(A)" apply (simp add: Transset_def DPow_def) apply (rule_tac x="[X]" in bexI) apply (rule_tac x="Member(0,1)" in bexI) apply (auto simp add: Un_least_lt_iff) done lemma Transset_subset_DPow: "Transset(A) \ A \ DPow(A)" apply clarify apply (simp add: Transset_def) apply (blast intro: elem_subset_in_DPow) done lemma Transset_DPow: "Transset(A) \ Transset(DPow(A))" apply (simp add: Transset_def) apply (blast intro: elem_subset_in_DPow dest: DPowD) done text\Kunen's VI 1.6 (a)\ lemma Transset_Lset: "Transset(Lset(i))" apply (rule_tac a=i in eps_induct) apply (subst Lset) apply (blast intro!: Transset_Union_family Transset_Un Transset_DPow) done lemma mem_Lset_imp_subset_Lset: "a \ Lset(i) \ a \ Lset(i)" apply (insert Transset_Lset) apply (simp add: Transset_def) done subsubsection\Monotonicity\ text\Kunen's VI 1.6 (b)\ lemma Lset_mono [rule_format]: "\j. i<=j \ Lset(i) \ Lset(j)" proof (induct i rule: eps_induct, intro allI impI) fix x j assume "\y\x. \j. y \ j \ Lset(y) \ Lset(j)" and "x \ j" thus "Lset(x) \ Lset(j)" by (force simp add: Lset [of x] Lset [of j]) qed text\This version lets us remove the premise \<^term>\Ord(i)\ sometimes.\ lemma Lset_mono_mem [rule_format]: "\j. i \ j \ Lset(i) \ Lset(j)" proof (induct i rule: eps_induct, intro allI impI) fix x j assume "\y\x. \j. y \ j \ Lset(y) \ Lset(j)" and "x \ j" thus "Lset(x) \ Lset(j)" by (force simp add: Lset [of j] intro!: bexI intro: elem_subset_in_DPow dest: LsetD DPowD) qed text\Useful with Reflection to bump up the ordinal\ lemma subset_Lset_ltD: "\A \ Lset(i); i < j\ \ A \ Lset(j)" by (blast dest: ltD [THEN Lset_mono_mem]) subsubsection\0, successor and limit equations for Lset\ lemma Lset_0 [simp]: "Lset(0) = 0" by (subst Lset, blast) lemma Lset_succ_subset1: "DPow(Lset(i)) \ Lset(succ(i))" by (subst Lset, rule succI1 [THEN RepFunI, THEN Union_upper]) lemma Lset_succ_subset2: "Lset(succ(i)) \ DPow(Lset(i))" apply (subst Lset, rule UN_least) apply (erule succE) apply blast apply clarify apply (rule elem_subset_in_DPow) apply (subst Lset) apply blast apply (blast intro: dest: DPowD Lset_mono_mem) done lemma Lset_succ: "Lset(succ(i)) = DPow(Lset(i))" by (intro equalityI Lset_succ_subset1 Lset_succ_subset2) lemma Lset_Union [simp]: "Lset(\(X)) = (\y\X. Lset(y))" apply (subst Lset) apply (rule equalityI) txt\first inclusion\ apply (rule UN_least) apply (erule UnionE) apply (rule subset_trans) apply (erule_tac [2] UN_upper, subst Lset, erule UN_upper) txt\opposite inclusion\ apply (rule UN_least) apply (subst Lset, blast) done subsubsection\Lset applied to Limit ordinals\ lemma Limit_Lset_eq: "Limit(i) \ Lset(i) = (\y\i. Lset(y))" by (simp add: Lset_Union [symmetric] Limit_Union_eq) lemma lt_LsetI: "\a \ Lset(j); j \ a \ Lset(i)" by (blast dest: Lset_mono [OF le_imp_subset [OF leI]]) lemma Limit_LsetE: "\a \ Lset(i); \R \ Limit(i); \x. \x Lset(x)\ \ R \ \ R" apply (rule classical) apply (rule Limit_Lset_eq [THEN equalityD1, THEN subsetD, THEN UN_E]) prefer 2 apply assumption apply blast apply (blast intro: ltI Limit_is_Ord) done subsubsection\Basic closure properties\ lemma zero_in_Lset: "y \ x \ 0 \ Lset(x)" by (subst Lset, blast intro: empty_in_DPow) lemma notin_Lset: "x \ Lset(x)" apply (rule_tac a=x in eps_induct) apply (subst Lset) apply (blast dest: DPowD) done subsection\Constructible Ordinals: Kunen's VI 1.9 (b)\ lemma Ords_of_Lset_eq: "Ord(i) \ {x\Lset(i). Ord(x)} = i" apply (erule trans_induct3) apply (simp_all add: Lset_succ Limit_Lset_eq Limit_Union_eq) txt\The successor case remains.\ apply (rule equalityI) txt\First inclusion\ apply clarify apply (erule Ord_linear_lt, assumption) apply (blast dest: DPow_imp_subset ltD notE [OF notin_Lset]) apply blast apply (blast dest: ltD) txt\Opposite inclusion, \<^term>\succ(x) \ DPow(Lset(x)) \ ON\\ apply auto txt\Key case:\ apply (erule subst, rule Ords_in_DPow [OF Transset_Lset]) apply (blast intro: elem_subset_in_DPow dest: OrdmemD elim: equalityE) apply (blast intro: Ord_in_Ord) done lemma Ord_subset_Lset: "Ord(i) \ i \ Lset(i)" by (subst Ords_of_Lset_eq [symmetric], assumption, fast) lemma Ord_in_Lset: "Ord(i) \ i \ Lset(succ(i))" apply (simp add: Lset_succ) apply (subst Ords_of_Lset_eq [symmetric], assumption, rule Ords_in_DPow [OF Transset_Lset]) done lemma Ord_in_L: "Ord(i) \ L(i)" by (simp add: L_def, blast intro: Ord_in_Lset) subsubsection\Unions\ lemma Union_in_Lset: "X \ Lset(i) \ \(X) \ Lset(succ(i))" apply (insert Transset_Lset) apply (rule LsetI [OF succI1]) apply (simp add: Transset_def DPow_def) apply (intro conjI, blast) txt\Now to create the formula \<^term>\\y. y \ X \ x \ y\\ apply (rule_tac x="Cons(X,Nil)" in bexI) apply (rule_tac x="Exists(And(Member(0,2), Member(1,0)))" in bexI) apply typecheck apply (simp add: succ_Un_distrib [symmetric], blast) done theorem Union_in_L: "L(X) \ L(\(X))" by (simp add: L_def, blast dest: Union_in_Lset) subsubsection\Finite sets and ordered pairs\ lemma singleton_in_Lset: "a \ Lset(i) \ {a} \ Lset(succ(i))" by (simp add: Lset_succ singleton_in_DPow) lemma doubleton_in_Lset: "\a \ Lset(i); b \ Lset(i)\ \ {a,b} \ Lset(succ(i))" by (simp add: Lset_succ empty_in_DPow cons_in_DPow) lemma Pair_in_Lset: "\a \ Lset(i); b \ Lset(i); Ord(i)\ \ \a,b\ \ Lset(succ(succ(i)))" -apply (unfold Pair_def) + unfolding Pair_def apply (blast intro: doubleton_in_Lset) done lemmas Lset_UnI1 = Un_upper1 [THEN Lset_mono [THEN subsetD]] lemmas Lset_UnI2 = Un_upper2 [THEN Lset_mono [THEN subsetD]] text\Hard work is finding a single \<^term>\j \ i\ such that \<^term>\{a,b} \ Lset(j)\\ lemma doubleton_in_LLimit: "\a \ Lset(i); b \ Lset(i); Limit(i)\ \ {a,b} \ Lset(i)" apply (erule Limit_LsetE, assumption) apply (erule Limit_LsetE, assumption) apply (blast intro: lt_LsetI [OF doubleton_in_Lset] Lset_UnI1 Lset_UnI2 Limit_has_succ Un_least_lt) done theorem doubleton_in_L: "\L(a); L(b)\ \ L({a, b})" apply (simp add: L_def, clarify) apply (drule Ord2_imp_greater_Limit, assumption) apply (blast intro: lt_LsetI doubleton_in_LLimit Limit_is_Ord) done lemma Pair_in_LLimit: "\a \ Lset(i); b \ Lset(i); Limit(i)\ \ \a,b\ \ Lset(i)" txt\Infer that a, b occur at ordinals x,xa < i.\ apply (erule Limit_LsetE, assumption) apply (erule Limit_LsetE, assumption) txt\Infer that \<^term>\succ(succ(x \ xa)) < i\\ apply (blast intro: lt_Ord lt_LsetI [OF Pair_in_Lset] Lset_UnI1 Lset_UnI2 Limit_has_succ Un_least_lt) done text\The rank function for the constructible universe\ definition lrank :: "i\i" where \ \Kunen's definition VI 1.7\ "lrank(x) \ \ i. x \ Lset(succ(i))" lemma L_I: "\x \ Lset(i); Ord(i)\ \ L(x)" by (simp add: L_def, blast) lemma L_D: "L(x) \ \i. Ord(i) \ x \ Lset(i)" by (simp add: L_def) lemma Ord_lrank [simp]: "Ord(lrank(a))" by (simp add: lrank_def) lemma Lset_lrank_lt [rule_format]: "Ord(i) \ x \ Lset(i) \ lrank(x) < i" apply (erule trans_induct3) apply simp apply (simp only: lrank_def) apply (blast intro: Least_le) apply (simp_all add: Limit_Lset_eq) apply (blast intro: ltI Limit_is_Ord lt_trans) done text\Kunen's VI 1.8. The proof is much harder than the text would suggest. For a start, it needs the previous lemma, which is proved by induction.\ lemma Lset_iff_lrank_lt: "Ord(i) \ x \ Lset(i) \ L(x) \ lrank(x) < i" apply (simp add: L_def, auto) apply (blast intro: Lset_lrank_lt) - apply (unfold lrank_def) + unfolding lrank_def apply (drule succI1 [THEN Lset_mono_mem, THEN subsetD]) apply (drule_tac P="\i. x \ Lset(succ(i))" in LeastI, assumption) apply (blast intro!: le_imp_subset Lset_mono [THEN subsetD]) done lemma Lset_succ_lrank_iff [simp]: "x \ Lset(succ(lrank(x))) \ L(x)" by (simp add: Lset_iff_lrank_lt) text\Kunen's VI 1.9 (a)\ lemma lrank_of_Ord: "Ord(i) \ lrank(i) = i" -apply (unfold lrank_def) + unfolding lrank_def apply (rule Least_equality) apply (erule Ord_in_Lset) apply assumption apply (insert notin_Lset [of i]) apply (blast intro!: le_imp_subset Lset_mono [THEN subsetD]) done text\This is lrank(lrank(a)) = lrank(a)\ declare Ord_lrank [THEN lrank_of_Ord, simp] text\Kunen's VI 1.10\ lemma Lset_in_Lset_succ: "Lset(i) \ Lset(succ(i))" apply (simp add: Lset_succ DPow_def) apply (rule_tac x=Nil in bexI) apply (rule_tac x="Equal(0,0)" in bexI) apply auto done lemma lrank_Lset: "Ord(i) \ lrank(Lset(i)) = i" -apply (unfold lrank_def) + unfolding lrank_def apply (rule Least_equality) apply (rule Lset_in_Lset_succ) apply assumption apply clarify apply (subgoal_tac "Lset(succ(ia)) \ Lset(i)") apply (blast dest: mem_irrefl) apply (blast intro!: le_imp_subset Lset_mono) done text\Kunen's VI 1.11\ lemma Lset_subset_Vset: "Ord(i) \ Lset(i) \ Vset(i)" apply (erule trans_induct) apply (subst Lset) apply (subst Vset) apply (rule UN_mono [OF subset_refl]) apply (rule subset_trans [OF DPow_subset_Pow]) apply (rule Pow_mono, blast) done text\Kunen's VI 1.12\ lemma Lset_subset_Vset': "i \ nat \ Lset(i) = Vset(i)" apply (erule nat_induct) apply (simp add: Vfrom_0) apply (simp add: Lset_succ Vset_succ Finite_Vset Finite_DPow_eq_Pow) done text\Every set of constructible sets is included in some \<^term>\Lset\\ lemma subset_Lset: "(\x\A. L(x)) \ \i. Ord(i) \ A \ Lset(i)" by (rule_tac x = "\x\A. succ(lrank(x))" in exI, force) lemma subset_LsetE: "\\x\A. L(x); \i. \Ord(i); A \ Lset(i)\ \ P\ \ P" by (blast dest: subset_Lset) subsubsection\For L to satisfy the Powerset axiom\ lemma LPow_env_typing: "\y \ Lset(i); Ord(i); y \ X\ \ \z \ Pow(X). y \ Lset(succ(lrank(z)))" by (auto intro: L_I iff: Lset_succ_lrank_iff) lemma LPow_in_Lset: "\X \ Lset(i); Ord(i)\ \ \j. Ord(j) \ {y \ Pow(X). L(y)} \ Lset(j)" apply (rule_tac x="succ(\y \ Pow(X). succ(lrank(y)))" in exI) apply simp apply (rule LsetI [OF succI1]) apply (simp add: DPow_def) apply (intro conjI, clarify) apply (rule_tac a=x in UN_I, simp+) txt\Now to create the formula \<^term>\y \ X\\ apply (rule_tac x="Cons(X,Nil)" in bexI) apply (rule_tac x="subset_fm(0,1)" in bexI) apply typecheck apply (rule conjI) apply (simp add: succ_Un_distrib [symmetric]) apply (rule equality_iffI) apply (simp add: Transset_UN [OF Transset_Lset] LPow_env_typing) apply (auto intro: L_I iff: Lset_succ_lrank_iff) done theorem LPow_in_L: "L(X) \ L({y \ Pow(X). L(y)})" by (blast intro: L_I dest: L_D LPow_in_Lset) subsection\Eliminating \<^term>\arity\ from the Definition of \<^term>\Lset\\ lemma nth_zero_eq_0: "n \ nat \ nth(n,[0]) = 0" by (induct_tac n, auto) lemma sats_app_0_iff [rule_format]: "\p \ formula; 0 \ A\ \ \env \ list(A). sats(A,p, env@[0]) \ sats(A,p,env)" apply (induct_tac p) apply (simp_all del: app_Cons add: app_Cons [symmetric] add: nth_zero_eq_0 nth_append not_lt_iff_le nth_eq_0) done lemma sats_app_zeroes_iff: "\p \ formula; 0 \ A; env \ list(A); n \ nat\ \ sats(A,p,env @ repeat(0,n)) \ sats(A,p,env)" apply (induct_tac n, simp) apply (simp del: repeat.simps add: repeat_succ_app sats_app_0_iff app_assoc [symmetric]) done lemma exists_bigger_env: "\p \ formula; 0 \ A; env \ list(A)\ \ \env' \ list(A). arity(p) \ succ(length(env')) \ (\a\A. sats(A,p,Cons(a,env')) \ sats(A,p,Cons(a,env)))" apply (rule_tac x="env @ repeat(0,arity(p))" in bexI) apply (simp del: app_Cons add: app_Cons [symmetric] add: length_repeat sats_app_zeroes_iff, typecheck) done text\A simpler version of \<^term>\DPow\: no arity check!\ definition DPow' :: "i \ i" where "DPow'(A) \ {X \ Pow(A). \env \ list(A). \p \ formula. X = {x\A. sats(A, p, Cons(x,env))}}" lemma DPow_subset_DPow': "DPow(A) \ DPow'(A)" by (simp add: DPow_def DPow'_def, blast) lemma DPow'_0: "DPow'(0) = {0}" by (auto simp add: DPow'_def) lemma DPow'_subset_DPow: "0 \ A \ DPow'(A) \ DPow(A)" apply (auto simp add: DPow'_def DPow_def) apply (frule exists_bigger_env, assumption+, force) done lemma DPow_eq_DPow': "Transset(A) \ DPow(A) = DPow'(A)" apply (drule Transset_0_disj) apply (erule disjE) apply (simp add: DPow'_0 Finite_DPow_eq_Pow) apply (rule equalityI) apply (rule DPow_subset_DPow') apply (erule DPow'_subset_DPow) done text\And thus we can relativize \<^term>\Lset\ without bothering with \<^term>\arity\ and \<^term>\length\\ lemma Lset_eq_transrec_DPow': "Lset(i) = transrec(i, \x f. \y\x. DPow'(f`y))" apply (rule_tac a=i in eps_induct) apply (subst Lset) apply (subst transrec) apply (simp only: DPow_eq_DPow' [OF Transset_Lset], simp) done text\With this rule we can specify \<^term>\p\ later and don't worry about arities at all!\ lemma DPow_LsetI [rule_format]: "\\x\Lset(i). P(x) \ sats(Lset(i), p, Cons(x,env)); env \ list(Lset(i)); p \ formula\ \ {x\Lset(i). P(x)} \ DPow(Lset(i))" by (simp add: DPow_eq_DPow' [OF Transset_Lset] DPow'_def, blast) end diff --git a/src/ZF/Constructible/L_axioms.thy b/src/ZF/Constructible/L_axioms.thy --- a/src/ZF/Constructible/L_axioms.thy +++ b/src/ZF/Constructible/L_axioms.thy @@ -1,1403 +1,1403 @@ (* Title: ZF/Constructible/L_axioms.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory *) section \The ZF Axioms (Except Separation) in L\ theory L_axioms imports Formula Relative Reflection MetaExists begin text \The class L satisfies the premises of locale \M_trivial\\ lemma transL: "\y\x; L(x)\ \ L(y)" apply (insert Transset_Lset) apply (simp add: Transset_def L_def, blast) done lemma nonempty: "L(0)" apply (simp add: L_def) apply (blast intro: zero_in_Lset) done theorem upair_ax: "upair_ax(L)" apply (simp add: upair_ax_def upair_def, clarify) apply (rule_tac x="{x,y}" in rexI) apply (simp_all add: doubleton_in_L) done theorem Union_ax: "Union_ax(L)" apply (simp add: Union_ax_def big_union_def, clarify) apply (rule_tac x="\(x)" in rexI) apply (simp_all add: Union_in_L, auto) apply (blast intro: transL) done theorem power_ax: "power_ax(L)" apply (simp add: power_ax_def powerset_def Relative.subset_def, clarify) apply (rule_tac x="{y \ Pow(x). L(y)}" in rexI) apply (simp_all add: LPow_in_L, auto) apply (blast intro: transL) done text\We don't actually need \<^term>\L\ to satisfy the foundation axiom.\ theorem foundation_ax: "foundation_ax(L)" apply (simp add: foundation_ax_def) apply (rule rallI) apply (cut_tac A=x in foundation) apply (blast intro: transL) done subsection\For L to satisfy Replacement\ (*Can't move these to Formula unless the definition of univalent is moved there too!*) lemma LReplace_in_Lset: "\X \ Lset(i); univalent(L,X,Q); Ord(i)\ \ \j. Ord(j) \ Replace(X, \x y. Q(x,y) \ L(y)) \ Lset(j)" apply (rule_tac x="\y \ Replace(X, \x y. Q(x,y) \ L(y)). succ(lrank(y))" in exI) apply simp apply clarify apply (rule_tac a=x in UN_I) apply (simp_all add: Replace_iff univalent_def) apply (blast dest: transL L_I) done lemma LReplace_in_L: "\L(X); univalent(L,X,Q)\ \ \Y. L(Y) \ Replace(X, \x y. Q(x,y) \ L(y)) \ Y" apply (drule L_D, clarify) apply (drule LReplace_in_Lset, assumption+) apply (blast intro: L_I Lset_in_Lset_succ) done theorem replacement: "replacement(L,P)" apply (simp add: replacement_def, clarify) apply (frule LReplace_in_L, assumption+, clarify) apply (rule_tac x=Y in rexI) apply (simp_all add: Replace_iff univalent_def, blast) done lemma strong_replacementI [rule_format]: "\\B[L]. separation(L, \u. \x[L]. x\B \ P(x,u))\ \ strong_replacement(L,P)" apply (simp add: strong_replacement_def, clarify) apply (frule replacementD [OF replacement], assumption, clarify) apply (drule_tac x=A in rspec, clarify) apply (drule_tac z=Y in separationD, assumption, clarify) apply (rule_tac x=y in rexI, force, assumption) done subsection\Instantiating the locale \M_trivial\\ text\No instances of Separation yet.\ lemma Lset_mono_le: "mono_le_subset(Lset)" by (simp add: mono_le_subset_def le_imp_subset Lset_mono) lemma Lset_cont: "cont_Ord(Lset)" by (simp add: cont_Ord_def Limit_Lset_eq OUnion_def Limit_is_Ord) lemmas L_nat = Ord_in_L [OF Ord_nat] theorem M_trivial_L: "M_trivial(L)" apply (rule M_trivial.intro) apply (rule M_trans.intro) apply (erule (1) transL) apply(rule exI,rule nonempty) apply (rule M_trivial_axioms.intro) apply (rule upair_ax) apply (rule Union_ax) done interpretation L: M_trivial L by (rule M_trivial_L) (* Replaces the following declarations... lemmas rall_abs = M_trivial.rall_abs [OF M_trivial_L] and rex_abs = M_trivial.rex_abs [OF M_trivial_L] ... declare rall_abs [simp] declare rex_abs [simp] ...and dozens of similar ones. *) subsection\Instantiation of the locale \reflection\\ text\instances of locale constants\ definition L_F0 :: "[i\o,i] \ i" where "L_F0(P,y) \ \ b. (\z. L(z) \ P(\y,z\)) \ (\z\Lset(b). P(\y,z\))" definition L_FF :: "[i\o,i] \ i" where "L_FF(P) \ \a. \y\Lset(a). L_F0(P,y)" definition L_ClEx :: "[i\o,i] \ o" where "L_ClEx(P) \ \a. Limit(a) \ normalize(L_FF(P),a) = a" text\We must use the meta-existential quantifier; otherwise the reflection terms become enormous!\ definition L_Reflects :: "[i\o,[i,i]\o] \ prop" (\(3REFLECTS/ [_,/ _])\) where "REFLECTS[P,Q] \ (\Cl. Closed_Unbounded(Cl) \ (\a. Cl(a) \ (\x \ Lset(a). P(x) \ Q(a,x))))" theorem Triv_reflection: "REFLECTS[P, \a x. P(x)]" apply (simp add: L_Reflects_def) apply (rule meta_exI) apply (rule Closed_Unbounded_Ord) done theorem Not_reflection: "REFLECTS[P,Q] \ REFLECTS[\x. \P(x), \a x. \Q(a,x)]" -apply (unfold L_Reflects_def) + unfolding L_Reflects_def apply (erule meta_exE) apply (rule_tac x=Cl in meta_exI, simp) done theorem And_reflection: "\REFLECTS[P,Q]; REFLECTS[P',Q']\ \ REFLECTS[\x. P(x) \ P'(x), \a x. Q(a,x) \ Q'(a,x)]" -apply (unfold L_Reflects_def) + unfolding L_Reflects_def apply (elim meta_exE) apply (rule_tac x="\a. Cl(a) \ Cla(a)" in meta_exI) apply (simp add: Closed_Unbounded_Int, blast) done theorem Or_reflection: "\REFLECTS[P,Q]; REFLECTS[P',Q']\ \ REFLECTS[\x. P(x) \ P'(x), \a x. Q(a,x) \ Q'(a,x)]" -apply (unfold L_Reflects_def) + unfolding L_Reflects_def apply (elim meta_exE) apply (rule_tac x="\a. Cl(a) \ Cla(a)" in meta_exI) apply (simp add: Closed_Unbounded_Int, blast) done theorem Imp_reflection: "\REFLECTS[P,Q]; REFLECTS[P',Q']\ \ REFLECTS[\x. P(x) \ P'(x), \a x. Q(a,x) \ Q'(a,x)]" -apply (unfold L_Reflects_def) + unfolding L_Reflects_def apply (elim meta_exE) apply (rule_tac x="\a. Cl(a) \ Cla(a)" in meta_exI) apply (simp add: Closed_Unbounded_Int, blast) done theorem Iff_reflection: "\REFLECTS[P,Q]; REFLECTS[P',Q']\ \ REFLECTS[\x. P(x) \ P'(x), \a x. Q(a,x) \ Q'(a,x)]" -apply (unfold L_Reflects_def) + unfolding L_Reflects_def apply (elim meta_exE) apply (rule_tac x="\a. Cl(a) \ Cla(a)" in meta_exI) apply (simp add: Closed_Unbounded_Int, blast) done lemma reflection_Lset: "reflection(Lset)" by (blast intro: reflection.intro Lset_mono_le Lset_cont Formula.Pair_in_LLimit)+ theorem Ex_reflection: "REFLECTS[\x. P(fst(x),snd(x)), \a x. Q(a,fst(x),snd(x))] \ REFLECTS[\x. \z. L(z) \ P(x,z), \a x. \z\Lset(a). Q(a,x,z)]" apply (unfold L_Reflects_def L_ClEx_def L_FF_def L_F0_def L_def) apply (elim meta_exE) apply (rule meta_exI) apply (erule reflection.Ex_reflection [OF reflection_Lset]) done theorem All_reflection: "REFLECTS[\x. P(fst(x),snd(x)), \a x. Q(a,fst(x),snd(x))] \ REFLECTS[\x. \z. L(z) \ P(x,z), \a x. \z\Lset(a). Q(a,x,z)]" apply (unfold L_Reflects_def L_ClEx_def L_FF_def L_F0_def L_def) apply (elim meta_exE) apply (rule meta_exI) apply (erule reflection.All_reflection [OF reflection_Lset]) done theorem Rex_reflection: "REFLECTS[ \x. P(fst(x),snd(x)), \a x. Q(a,fst(x),snd(x))] \ REFLECTS[\x. \z[L]. P(x,z), \a x. \z\Lset(a). Q(a,x,z)]" -apply (unfold rex_def) + unfolding rex_def apply (intro And_reflection Ex_reflection, assumption) done theorem Rall_reflection: "REFLECTS[\x. P(fst(x),snd(x)), \a x. Q(a,fst(x),snd(x))] \ REFLECTS[\x. \z[L]. P(x,z), \a x. \z\Lset(a). Q(a,x,z)]" -apply (unfold rall_def) + unfolding rall_def apply (intro Imp_reflection All_reflection, assumption) done text\This version handles an alternative form of the bounded quantifier in the second argument of \REFLECTS\.\ theorem Rex_reflection': "REFLECTS[\x. P(fst(x),snd(x)), \a x. Q(a,fst(x),snd(x))] \ REFLECTS[\x. \z[L]. P(x,z), \a x. \z[##Lset(a)]. Q(a,x,z)]" apply (unfold setclass_def rex_def) apply (erule Rex_reflection [unfolded rex_def Bex_def]) done text\As above.\ theorem Rall_reflection': "REFLECTS[\x. P(fst(x),snd(x)), \a x. Q(a,fst(x),snd(x))] \ REFLECTS[\x. \z[L]. P(x,z), \a x. \z[##Lset(a)]. Q(a,x,z)]" apply (unfold setclass_def rall_def) apply (erule Rall_reflection [unfolded rall_def Ball_def]) done lemmas FOL_reflections = Triv_reflection Not_reflection And_reflection Or_reflection Imp_reflection Iff_reflection Ex_reflection All_reflection Rex_reflection Rall_reflection Rex_reflection' Rall_reflection' lemma ReflectsD: "\REFLECTS[P,Q]; Ord(i)\ \ \j. i (\x \ Lset(j). P(x) \ Q(j,x))" apply (unfold L_Reflects_def Closed_Unbounded_def) apply (elim meta_exE, clarify) apply (blast dest!: UnboundedD) done lemma ReflectsE: "\REFLECTS[P,Q]; Ord(i); \j. \ix \ Lset(j). P(x) \ Q(j,x)\ \ R\ \ R" by (drule ReflectsD, assumption, blast) lemma Collect_mem_eq: "{x\A. x\B} = A \ B" by blast subsection\Internalized Formulas for some Set-Theoretic Concepts\ subsubsection\Some numbers to help write de Bruijn indices\ abbreviation digit3 :: i (\3\) where "3 \ succ(2)" abbreviation digit4 :: i (\4\) where "4 \ succ(3)" abbreviation digit5 :: i (\5\) where "5 \ succ(4)" abbreviation digit6 :: i (\6\) where "6 \ succ(5)" abbreviation digit7 :: i (\7\) where "7 \ succ(6)" abbreviation digit8 :: i (\8\) where "8 \ succ(7)" abbreviation digit9 :: i (\9\) where "9 \ succ(8)" subsubsection\The Empty Set, Internalized\ definition empty_fm :: "i\i" where "empty_fm(x) \ Forall(Neg(Member(0,succ(x))))" lemma empty_type [TC]: "x \ nat \ empty_fm(x) \ formula" by (simp add: empty_fm_def) lemma sats_empty_fm [simp]: "\x \ nat; env \ list(A)\ \ sats(A, empty_fm(x), env) \ empty(##A, nth(x,env))" by (simp add: empty_fm_def empty_def) lemma empty_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; env \ list(A)\ \ empty(##A, x) \ sats(A, empty_fm(i), env)" by simp theorem empty_reflection: "REFLECTS[\x. empty(L,f(x)), \i x. empty(##Lset(i),f(x))]" apply (simp only: empty_def) apply (intro FOL_reflections) done text\Not used. But maybe useful?\ lemma Transset_sats_empty_fm_eq_0: "\n \ nat; env \ list(A); Transset(A)\ \ sats(A, empty_fm(n), env) \ nth(n,env) = 0" apply (simp add: empty_fm_def empty_def Transset_def, auto) apply (case_tac "n < length(env)") apply (frule nth_type, assumption+, blast) apply (simp_all add: not_lt_iff_le nth_eq_0) done subsubsection\Unordered Pairs, Internalized\ definition upair_fm :: "[i,i,i]\i" where "upair_fm(x,y,z) \ And(Member(x,z), And(Member(y,z), Forall(Implies(Member(0,succ(z)), Or(Equal(0,succ(x)), Equal(0,succ(y)))))))" lemma upair_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ upair_fm(x,y,z) \ formula" by (simp add: upair_fm_def) lemma sats_upair_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, upair_fm(x,y,z), env) \ upair(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: upair_fm_def upair_def) lemma upair_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ upair(##A, x, y, z) \ sats(A, upair_fm(i,j,k), env)" by (simp) text\Useful? At least it refers to "real" unordered pairs\ lemma sats_upair_fm2 [simp]: "\x \ nat; y \ nat; z < length(env); env \ list(A); Transset(A)\ \ sats(A, upair_fm(x,y,z), env) \ nth(z,env) = {nth(x,env), nth(y,env)}" apply (frule lt_length_in_nat, assumption) apply (simp add: upair_fm_def Transset_def, auto) apply (blast intro: nth_type) done theorem upair_reflection: "REFLECTS[\x. upair(L,f(x),g(x),h(x)), \i x. upair(##Lset(i),f(x),g(x),h(x))]" apply (simp add: upair_def) apply (intro FOL_reflections) done subsubsection\Ordered pairs, Internalized\ definition pair_fm :: "[i,i,i]\i" where "pair_fm(x,y,z) \ Exists(And(upair_fm(succ(x),succ(x),0), Exists(And(upair_fm(succ(succ(x)),succ(succ(y)),0), upair_fm(1,0,succ(succ(z)))))))" lemma pair_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ pair_fm(x,y,z) \ formula" by (simp add: pair_fm_def) lemma sats_pair_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, pair_fm(x,y,z), env) \ pair(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: pair_fm_def pair_def) lemma pair_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ pair(##A, x, y, z) \ sats(A, pair_fm(i,j,k), env)" by (simp) theorem pair_reflection: "REFLECTS[\x. pair(L,f(x),g(x),h(x)), \i x. pair(##Lset(i),f(x),g(x),h(x))]" apply (simp only: pair_def) apply (intro FOL_reflections upair_reflection) done subsubsection\Binary Unions, Internalized\ definition union_fm :: "[i,i,i]\i" where "union_fm(x,y,z) \ Forall(Iff(Member(0,succ(z)), Or(Member(0,succ(x)),Member(0,succ(y)))))" lemma union_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ union_fm(x,y,z) \ formula" by (simp add: union_fm_def) lemma sats_union_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, union_fm(x,y,z), env) \ union(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: union_fm_def union_def) lemma union_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ union(##A, x, y, z) \ sats(A, union_fm(i,j,k), env)" by (simp) theorem union_reflection: "REFLECTS[\x. union(L,f(x),g(x),h(x)), \i x. union(##Lset(i),f(x),g(x),h(x))]" apply (simp only: union_def) apply (intro FOL_reflections) done subsubsection\Set ``Cons,'' Internalized\ definition cons_fm :: "[i,i,i]\i" where "cons_fm(x,y,z) \ Exists(And(upair_fm(succ(x),succ(x),0), union_fm(0,succ(y),succ(z))))" lemma cons_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ cons_fm(x,y,z) \ formula" by (simp add: cons_fm_def) lemma sats_cons_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, cons_fm(x,y,z), env) \ is_cons(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: cons_fm_def is_cons_def) lemma cons_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ is_cons(##A, x, y, z) \ sats(A, cons_fm(i,j,k), env)" by simp theorem cons_reflection: "REFLECTS[\x. is_cons(L,f(x),g(x),h(x)), \i x. is_cons(##Lset(i),f(x),g(x),h(x))]" apply (simp only: is_cons_def) apply (intro FOL_reflections upair_reflection union_reflection) done subsubsection\Successor Function, Internalized\ definition succ_fm :: "[i,i]\i" where "succ_fm(x,y) \ cons_fm(x,x,y)" lemma succ_type [TC]: "\x \ nat; y \ nat\ \ succ_fm(x,y) \ formula" by (simp add: succ_fm_def) lemma sats_succ_fm [simp]: "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, succ_fm(x,y), env) \ successor(##A, nth(x,env), nth(y,env))" by (simp add: succ_fm_def successor_def) lemma successor_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ successor(##A, x, y) \ sats(A, succ_fm(i,j), env)" by simp theorem successor_reflection: "REFLECTS[\x. successor(L,f(x),g(x)), \i x. successor(##Lset(i),f(x),g(x))]" apply (simp only: successor_def) apply (intro cons_reflection) done subsubsection\The Number 1, Internalized\ (* "number1(M,a) \ (\x[M]. empty(M,x) \ successor(M,x,a))" *) definition number1_fm :: "i\i" where "number1_fm(a) \ Exists(And(empty_fm(0), succ_fm(0,succ(a))))" lemma number1_type [TC]: "x \ nat \ number1_fm(x) \ formula" by (simp add: number1_fm_def) lemma sats_number1_fm [simp]: "\x \ nat; env \ list(A)\ \ sats(A, number1_fm(x), env) \ number1(##A, nth(x,env))" by (simp add: number1_fm_def number1_def) lemma number1_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; env \ list(A)\ \ number1(##A, x) \ sats(A, number1_fm(i), env)" by simp theorem number1_reflection: "REFLECTS[\x. number1(L,f(x)), \i x. number1(##Lset(i),f(x))]" apply (simp only: number1_def) apply (intro FOL_reflections empty_reflection successor_reflection) done subsubsection\Big Union, Internalized\ (* "big_union(M,A,z) \ \x[M]. x \ z \ (\y[M]. y\A \ x \ y)" *) definition big_union_fm :: "[i,i]\i" where "big_union_fm(A,z) \ Forall(Iff(Member(0,succ(z)), Exists(And(Member(0,succ(succ(A))), Member(1,0)))))" lemma big_union_type [TC]: "\x \ nat; y \ nat\ \ big_union_fm(x,y) \ formula" by (simp add: big_union_fm_def) lemma sats_big_union_fm [simp]: "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, big_union_fm(x,y), env) \ big_union(##A, nth(x,env), nth(y,env))" by (simp add: big_union_fm_def big_union_def) lemma big_union_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ big_union(##A, x, y) \ sats(A, big_union_fm(i,j), env)" by simp theorem big_union_reflection: "REFLECTS[\x. big_union(L,f(x),g(x)), \i x. big_union(##Lset(i),f(x),g(x))]" apply (simp only: big_union_def) apply (intro FOL_reflections) done subsubsection\Variants of Satisfaction Definitions for Ordinals, etc.\ text\The \sats\ theorems below are standard versions of the ones proved in theory \Formula\. They relate elements of type \<^term>\formula\ to relativized concepts such as \<^term>\subset\ or \<^term>\ordinal\ rather than to real concepts such as \<^term>\Ord\. Now that we have instantiated the locale \M_trivial\, we no longer require the earlier versions.\ lemma sats_subset_fm': "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, subset_fm(x,y), env) \ subset(##A, nth(x,env), nth(y,env))" by (simp add: subset_fm_def Relative.subset_def) theorem subset_reflection: "REFLECTS[\x. subset(L,f(x),g(x)), \i x. subset(##Lset(i),f(x),g(x))]" apply (simp only: Relative.subset_def) apply (intro FOL_reflections) done lemma sats_transset_fm': "\x \ nat; env \ list(A)\ \ sats(A, transset_fm(x), env) \ transitive_set(##A, nth(x,env))" by (simp add: sats_subset_fm' transset_fm_def transitive_set_def) theorem transitive_set_reflection: "REFLECTS[\x. transitive_set(L,f(x)), \i x. transitive_set(##Lset(i),f(x))]" apply (simp only: transitive_set_def) apply (intro FOL_reflections subset_reflection) done lemma sats_ordinal_fm': "\x \ nat; env \ list(A)\ \ sats(A, ordinal_fm(x), env) \ ordinal(##A,nth(x,env))" by (simp add: sats_transset_fm' ordinal_fm_def ordinal_def) lemma ordinal_iff_sats: "\nth(i,env) = x; i \ nat; env \ list(A)\ \ ordinal(##A, x) \ sats(A, ordinal_fm(i), env)" by (simp add: sats_ordinal_fm') theorem ordinal_reflection: "REFLECTS[\x. ordinal(L,f(x)), \i x. ordinal(##Lset(i),f(x))]" apply (simp only: ordinal_def) apply (intro FOL_reflections transitive_set_reflection) done subsubsection\Membership Relation, Internalized\ definition Memrel_fm :: "[i,i]\i" where "Memrel_fm(A,r) \ Forall(Iff(Member(0,succ(r)), Exists(And(Member(0,succ(succ(A))), Exists(And(Member(0,succ(succ(succ(A)))), And(Member(1,0), pair_fm(1,0,2))))))))" lemma Memrel_type [TC]: "\x \ nat; y \ nat\ \ Memrel_fm(x,y) \ formula" by (simp add: Memrel_fm_def) lemma sats_Memrel_fm [simp]: "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, Memrel_fm(x,y), env) \ membership(##A, nth(x,env), nth(y,env))" by (simp add: Memrel_fm_def membership_def) lemma Memrel_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ membership(##A, x, y) \ sats(A, Memrel_fm(i,j), env)" by simp theorem membership_reflection: "REFLECTS[\x. membership(L,f(x),g(x)), \i x. membership(##Lset(i),f(x),g(x))]" apply (simp only: membership_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Predecessor Set, Internalized\ definition pred_set_fm :: "[i,i,i,i]\i" where "pred_set_fm(A,x,r,B) \ Forall(Iff(Member(0,succ(B)), Exists(And(Member(0,succ(succ(r))), And(Member(1,succ(succ(A))), pair_fm(1,succ(succ(x)),0))))))" lemma pred_set_type [TC]: "\A \ nat; x \ nat; r \ nat; B \ nat\ \ pred_set_fm(A,x,r,B) \ formula" by (simp add: pred_set_fm_def) lemma sats_pred_set_fm [simp]: "\U \ nat; x \ nat; r \ nat; B \ nat; env \ list(A)\ \ sats(A, pred_set_fm(U,x,r,B), env) \ pred_set(##A, nth(U,env), nth(x,env), nth(r,env), nth(B,env))" by (simp add: pred_set_fm_def pred_set_def) lemma pred_set_iff_sats: "\nth(i,env) = U; nth(j,env) = x; nth(k,env) = r; nth(l,env) = B; i \ nat; j \ nat; k \ nat; l \ nat; env \ list(A)\ \ pred_set(##A,U,x,r,B) \ sats(A, pred_set_fm(i,j,k,l), env)" by (simp) theorem pred_set_reflection: "REFLECTS[\x. pred_set(L,f(x),g(x),h(x),b(x)), \i x. pred_set(##Lset(i),f(x),g(x),h(x),b(x))]" apply (simp only: pred_set_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Domain of a Relation, Internalized\ (* "is_domain(M,r,z) \ \x[M]. (x \ z \ (\w[M]. w\r \ (\y[M]. pair(M,x,y,w))))" *) definition domain_fm :: "[i,i]\i" where "domain_fm(r,z) \ Forall(Iff(Member(0,succ(z)), Exists(And(Member(0,succ(succ(r))), Exists(pair_fm(2,0,1))))))" lemma domain_type [TC]: "\x \ nat; y \ nat\ \ domain_fm(x,y) \ formula" by (simp add: domain_fm_def) lemma sats_domain_fm [simp]: "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, domain_fm(x,y), env) \ is_domain(##A, nth(x,env), nth(y,env))" by (simp add: domain_fm_def is_domain_def) lemma domain_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ is_domain(##A, x, y) \ sats(A, domain_fm(i,j), env)" by simp theorem domain_reflection: "REFLECTS[\x. is_domain(L,f(x),g(x)), \i x. is_domain(##Lset(i),f(x),g(x))]" apply (simp only: is_domain_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Range of a Relation, Internalized\ (* "is_range(M,r,z) \ \y[M]. (y \ z \ (\w[M]. w\r \ (\x[M]. pair(M,x,y,w))))" *) definition range_fm :: "[i,i]\i" where "range_fm(r,z) \ Forall(Iff(Member(0,succ(z)), Exists(And(Member(0,succ(succ(r))), Exists(pair_fm(0,2,1))))))" lemma range_type [TC]: "\x \ nat; y \ nat\ \ range_fm(x,y) \ formula" by (simp add: range_fm_def) lemma sats_range_fm [simp]: "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, range_fm(x,y), env) \ is_range(##A, nth(x,env), nth(y,env))" by (simp add: range_fm_def is_range_def) lemma range_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ is_range(##A, x, y) \ sats(A, range_fm(i,j), env)" by simp theorem range_reflection: "REFLECTS[\x. is_range(L,f(x),g(x)), \i x. is_range(##Lset(i),f(x),g(x))]" apply (simp only: is_range_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Field of a Relation, Internalized\ (* "is_field(M,r,z) \ \dr[M]. is_domain(M,r,dr) \ (\rr[M]. is_range(M,r,rr) \ union(M,dr,rr,z))" *) definition field_fm :: "[i,i]\i" where "field_fm(r,z) \ Exists(And(domain_fm(succ(r),0), Exists(And(range_fm(succ(succ(r)),0), union_fm(1,0,succ(succ(z)))))))" lemma field_type [TC]: "\x \ nat; y \ nat\ \ field_fm(x,y) \ formula" by (simp add: field_fm_def) lemma sats_field_fm [simp]: "\x \ nat; y \ nat; env \ list(A)\ \ sats(A, field_fm(x,y), env) \ is_field(##A, nth(x,env), nth(y,env))" by (simp add: field_fm_def is_field_def) lemma field_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j \ nat; env \ list(A)\ \ is_field(##A, x, y) \ sats(A, field_fm(i,j), env)" by simp theorem field_reflection: "REFLECTS[\x. is_field(L,f(x),g(x)), \i x. is_field(##Lset(i),f(x),g(x))]" apply (simp only: is_field_def) apply (intro FOL_reflections domain_reflection range_reflection union_reflection) done subsubsection\Image under a Relation, Internalized\ (* "image(M,r,A,z) \ \y[M]. (y \ z \ (\w[M]. w\r \ (\x[M]. x\A \ pair(M,x,y,w))))" *) definition image_fm :: "[i,i,i]\i" where "image_fm(r,A,z) \ Forall(Iff(Member(0,succ(z)), Exists(And(Member(0,succ(succ(r))), Exists(And(Member(0,succ(succ(succ(A)))), pair_fm(0,2,1)))))))" lemma image_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ image_fm(x,y,z) \ formula" by (simp add: image_fm_def) lemma sats_image_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, image_fm(x,y,z), env) \ image(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: image_fm_def Relative.image_def) lemma image_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ image(##A, x, y, z) \ sats(A, image_fm(i,j,k), env)" by (simp) theorem image_reflection: "REFLECTS[\x. image(L,f(x),g(x),h(x)), \i x. image(##Lset(i),f(x),g(x),h(x))]" apply (simp only: Relative.image_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Pre-Image under a Relation, Internalized\ (* "pre_image(M,r,A,z) \ \x[M]. x \ z \ (\w[M]. w\r \ (\y[M]. y\A \ pair(M,x,y,w)))" *) definition pre_image_fm :: "[i,i,i]\i" where "pre_image_fm(r,A,z) \ Forall(Iff(Member(0,succ(z)), Exists(And(Member(0,succ(succ(r))), Exists(And(Member(0,succ(succ(succ(A)))), pair_fm(2,0,1)))))))" lemma pre_image_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ pre_image_fm(x,y,z) \ formula" by (simp add: pre_image_fm_def) lemma sats_pre_image_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, pre_image_fm(x,y,z), env) \ pre_image(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: pre_image_fm_def Relative.pre_image_def) lemma pre_image_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ pre_image(##A, x, y, z) \ sats(A, pre_image_fm(i,j,k), env)" by (simp) theorem pre_image_reflection: "REFLECTS[\x. pre_image(L,f(x),g(x),h(x)), \i x. pre_image(##Lset(i),f(x),g(x),h(x))]" apply (simp only: Relative.pre_image_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Function Application, Internalized\ (* "fun_apply(M,f,x,y) \ (\xs[M]. \fxs[M]. upair(M,x,x,xs) \ image(M,f,xs,fxs) \ big_union(M,fxs,y))" *) definition fun_apply_fm :: "[i,i,i]\i" where "fun_apply_fm(f,x,y) \ Exists(Exists(And(upair_fm(succ(succ(x)), succ(succ(x)), 1), And(image_fm(succ(succ(f)), 1, 0), big_union_fm(0,succ(succ(y)))))))" lemma fun_apply_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ fun_apply_fm(x,y,z) \ formula" by (simp add: fun_apply_fm_def) lemma sats_fun_apply_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, fun_apply_fm(x,y,z), env) \ fun_apply(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: fun_apply_fm_def fun_apply_def) lemma fun_apply_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ fun_apply(##A, x, y, z) \ sats(A, fun_apply_fm(i,j,k), env)" by simp theorem fun_apply_reflection: "REFLECTS[\x. fun_apply(L,f(x),g(x),h(x)), \i x. fun_apply(##Lset(i),f(x),g(x),h(x))]" apply (simp only: fun_apply_def) apply (intro FOL_reflections upair_reflection image_reflection big_union_reflection) done subsubsection\The Concept of Relation, Internalized\ (* "is_relation(M,r) \ (\z[M]. z\r \ (\x[M]. \y[M]. pair(M,x,y,z)))" *) definition relation_fm :: "i\i" where "relation_fm(r) \ Forall(Implies(Member(0,succ(r)), Exists(Exists(pair_fm(1,0,2)))))" lemma relation_type [TC]: "\x \ nat\ \ relation_fm(x) \ formula" by (simp add: relation_fm_def) lemma sats_relation_fm [simp]: "\x \ nat; env \ list(A)\ \ sats(A, relation_fm(x), env) \ is_relation(##A, nth(x,env))" by (simp add: relation_fm_def is_relation_def) lemma relation_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; env \ list(A)\ \ is_relation(##A, x) \ sats(A, relation_fm(i), env)" by simp theorem is_relation_reflection: "REFLECTS[\x. is_relation(L,f(x)), \i x. is_relation(##Lset(i),f(x))]" apply (simp only: is_relation_def) apply (intro FOL_reflections pair_reflection) done subsubsection\The Concept of Function, Internalized\ (* "is_function(M,r) \ \x[M]. \y[M]. \y'[M]. \p[M]. \p'[M]. pair(M,x,y,p) \ pair(M,x,y',p') \ p\r \ p'\r \ y=y'" *) definition function_fm :: "i\i" where "function_fm(r) \ Forall(Forall(Forall(Forall(Forall( Implies(pair_fm(4,3,1), Implies(pair_fm(4,2,0), Implies(Member(1,r#+5), Implies(Member(0,r#+5), Equal(3,2))))))))))" lemma function_type [TC]: "\x \ nat\ \ function_fm(x) \ formula" by (simp add: function_fm_def) lemma sats_function_fm [simp]: "\x \ nat; env \ list(A)\ \ sats(A, function_fm(x), env) \ is_function(##A, nth(x,env))" by (simp add: function_fm_def is_function_def) lemma is_function_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; env \ list(A)\ \ is_function(##A, x) \ sats(A, function_fm(i), env)" by simp theorem is_function_reflection: "REFLECTS[\x. is_function(L,f(x)), \i x. is_function(##Lset(i),f(x))]" apply (simp only: is_function_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Typed Functions, Internalized\ (* "typed_function(M,A,B,r) \ is_function(M,r) \ is_relation(M,r) \ is_domain(M,r,A) \ (\u[M]. u\r \ (\x[M]. \y[M]. pair(M,x,y,u) \ y\B))" *) definition typed_function_fm :: "[i,i,i]\i" where "typed_function_fm(A,B,r) \ And(function_fm(r), And(relation_fm(r), And(domain_fm(r,A), Forall(Implies(Member(0,succ(r)), Forall(Forall(Implies(pair_fm(1,0,2),Member(0,B#+3)))))))))" lemma typed_function_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ typed_function_fm(x,y,z) \ formula" by (simp add: typed_function_fm_def) lemma sats_typed_function_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, typed_function_fm(x,y,z), env) \ typed_function(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: typed_function_fm_def typed_function_def) lemma typed_function_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ typed_function(##A, x, y, z) \ sats(A, typed_function_fm(i,j,k), env)" by simp lemmas function_reflections = empty_reflection number1_reflection upair_reflection pair_reflection union_reflection big_union_reflection cons_reflection successor_reflection fun_apply_reflection subset_reflection transitive_set_reflection membership_reflection pred_set_reflection domain_reflection range_reflection field_reflection image_reflection pre_image_reflection is_relation_reflection is_function_reflection lemmas function_iff_sats = empty_iff_sats number1_iff_sats upair_iff_sats pair_iff_sats union_iff_sats big_union_iff_sats cons_iff_sats successor_iff_sats fun_apply_iff_sats Memrel_iff_sats pred_set_iff_sats domain_iff_sats range_iff_sats field_iff_sats image_iff_sats pre_image_iff_sats relation_iff_sats is_function_iff_sats theorem typed_function_reflection: "REFLECTS[\x. typed_function(L,f(x),g(x),h(x)), \i x. typed_function(##Lset(i),f(x),g(x),h(x))]" apply (simp only: typed_function_def) apply (intro FOL_reflections function_reflections) done subsubsection\Composition of Relations, Internalized\ (* "composition(M,r,s,t) \ \p[M]. p \ t \ (\x[M]. \y[M]. \z[M]. \xy[M]. \yz[M]. pair(M,x,z,p) \ pair(M,x,y,xy) \ pair(M,y,z,yz) \ xy \ s \ yz \ r)" *) definition composition_fm :: "[i,i,i]\i" where "composition_fm(r,s,t) \ Forall(Iff(Member(0,succ(t)), Exists(Exists(Exists(Exists(Exists( And(pair_fm(4,2,5), And(pair_fm(4,3,1), And(pair_fm(3,2,0), And(Member(1,s#+6), Member(0,r#+6))))))))))))" lemma composition_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ composition_fm(x,y,z) \ formula" by (simp add: composition_fm_def) lemma sats_composition_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, composition_fm(x,y,z), env) \ composition(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: composition_fm_def composition_def) lemma composition_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ composition(##A, x, y, z) \ sats(A, composition_fm(i,j,k), env)" by simp theorem composition_reflection: "REFLECTS[\x. composition(L,f(x),g(x),h(x)), \i x. composition(##Lset(i),f(x),g(x),h(x))]" apply (simp only: composition_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Injections, Internalized\ (* "injection(M,A,B,f) \ typed_function(M,A,B,f) \ (\x[M]. \x'[M]. \y[M]. \p[M]. \p'[M]. pair(M,x,y,p) \ pair(M,x',y,p') \ p\f \ p'\f \ x=x')" *) definition injection_fm :: "[i,i,i]\i" where "injection_fm(A,B,f) \ And(typed_function_fm(A,B,f), Forall(Forall(Forall(Forall(Forall( Implies(pair_fm(4,2,1), Implies(pair_fm(3,2,0), Implies(Member(1,f#+5), Implies(Member(0,f#+5), Equal(4,3)))))))))))" lemma injection_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ injection_fm(x,y,z) \ formula" by (simp add: injection_fm_def) lemma sats_injection_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, injection_fm(x,y,z), env) \ injection(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: injection_fm_def injection_def) lemma injection_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ injection(##A, x, y, z) \ sats(A, injection_fm(i,j,k), env)" by simp theorem injection_reflection: "REFLECTS[\x. injection(L,f(x),g(x),h(x)), \i x. injection(##Lset(i),f(x),g(x),h(x))]" apply (simp only: injection_def) apply (intro FOL_reflections function_reflections typed_function_reflection) done subsubsection\Surjections, Internalized\ (* surjection :: "[i\o,i,i,i] \ o" "surjection(M,A,B,f) \ typed_function(M,A,B,f) \ (\y[M]. y\B \ (\x[M]. x\A \ fun_apply(M,f,x,y)))" *) definition surjection_fm :: "[i,i,i]\i" where "surjection_fm(A,B,f) \ And(typed_function_fm(A,B,f), Forall(Implies(Member(0,succ(B)), Exists(And(Member(0,succ(succ(A))), fun_apply_fm(succ(succ(f)),0,1))))))" lemma surjection_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ surjection_fm(x,y,z) \ formula" by (simp add: surjection_fm_def) lemma sats_surjection_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, surjection_fm(x,y,z), env) \ surjection(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: surjection_fm_def surjection_def) lemma surjection_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ surjection(##A, x, y, z) \ sats(A, surjection_fm(i,j,k), env)" by simp theorem surjection_reflection: "REFLECTS[\x. surjection(L,f(x),g(x),h(x)), \i x. surjection(##Lset(i),f(x),g(x),h(x))]" apply (simp only: surjection_def) apply (intro FOL_reflections function_reflections typed_function_reflection) done subsubsection\Bijections, Internalized\ (* bijection :: "[i\o,i,i,i] \ o" "bijection(M,A,B,f) \ injection(M,A,B,f) \ surjection(M,A,B,f)" *) definition bijection_fm :: "[i,i,i]\i" where "bijection_fm(A,B,f) \ And(injection_fm(A,B,f), surjection_fm(A,B,f))" lemma bijection_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ bijection_fm(x,y,z) \ formula" by (simp add: bijection_fm_def) lemma sats_bijection_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, bijection_fm(x,y,z), env) \ bijection(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: bijection_fm_def bijection_def) lemma bijection_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ bijection(##A, x, y, z) \ sats(A, bijection_fm(i,j,k), env)" by simp theorem bijection_reflection: "REFLECTS[\x. bijection(L,f(x),g(x),h(x)), \i x. bijection(##Lset(i),f(x),g(x),h(x))]" apply (simp only: bijection_def) apply (intro And_reflection injection_reflection surjection_reflection) done subsubsection\Restriction of a Relation, Internalized\ (* "restriction(M,r,A,z) \ \x[M]. x \ z \ (x \ r \ (\u[M]. u\A \ (\v[M]. pair(M,u,v,x))))" *) definition restriction_fm :: "[i,i,i]\i" where "restriction_fm(r,A,z) \ Forall(Iff(Member(0,succ(z)), And(Member(0,succ(r)), Exists(And(Member(0,succ(succ(A))), Exists(pair_fm(1,0,2)))))))" lemma restriction_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ restriction_fm(x,y,z) \ formula" by (simp add: restriction_fm_def) lemma sats_restriction_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, restriction_fm(x,y,z), env) \ restriction(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: restriction_fm_def restriction_def) lemma restriction_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ restriction(##A, x, y, z) \ sats(A, restriction_fm(i,j,k), env)" by simp theorem restriction_reflection: "REFLECTS[\x. restriction(L,f(x),g(x),h(x)), \i x. restriction(##Lset(i),f(x),g(x),h(x))]" apply (simp only: restriction_def) apply (intro FOL_reflections pair_reflection) done subsubsection\Order-Isomorphisms, Internalized\ (* order_isomorphism :: "[i\o,i,i,i,i,i] \ o" "order_isomorphism(M,A,r,B,s,f) \ bijection(M,A,B,f) \ (\x[M]. x\A \ (\y[M]. y\A \ (\p[M]. \fx[M]. \fy[M]. \q[M]. pair(M,x,y,p) \ fun_apply(M,f,x,fx) \ fun_apply(M,f,y,fy) \ pair(M,fx,fy,q) \ (p\r \ q\s))))" *) definition order_isomorphism_fm :: "[i,i,i,i,i]\i" where "order_isomorphism_fm(A,r,B,s,f) \ And(bijection_fm(A,B,f), Forall(Implies(Member(0,succ(A)), Forall(Implies(Member(0,succ(succ(A))), Forall(Forall(Forall(Forall( Implies(pair_fm(5,4,3), Implies(fun_apply_fm(f#+6,5,2), Implies(fun_apply_fm(f#+6,4,1), Implies(pair_fm(2,1,0), Iff(Member(3,r#+6), Member(0,s#+6)))))))))))))))" lemma order_isomorphism_type [TC]: "\A \ nat; r \ nat; B \ nat; s \ nat; f \ nat\ \ order_isomorphism_fm(A,r,B,s,f) \ formula" by (simp add: order_isomorphism_fm_def) lemma sats_order_isomorphism_fm [simp]: "\U \ nat; r \ nat; B \ nat; s \ nat; f \ nat; env \ list(A)\ \ sats(A, order_isomorphism_fm(U,r,B,s,f), env) \ order_isomorphism(##A, nth(U,env), nth(r,env), nth(B,env), nth(s,env), nth(f,env))" by (simp add: order_isomorphism_fm_def order_isomorphism_def) lemma order_isomorphism_iff_sats: "\nth(i,env) = U; nth(j,env) = r; nth(k,env) = B; nth(j',env) = s; nth(k',env) = f; i \ nat; j \ nat; k \ nat; j' \ nat; k' \ nat; env \ list(A)\ \ order_isomorphism(##A,U,r,B,s,f) \ sats(A, order_isomorphism_fm(i,j,k,j',k'), env)" by simp theorem order_isomorphism_reflection: "REFLECTS[\x. order_isomorphism(L,f(x),g(x),h(x),g'(x),h'(x)), \i x. order_isomorphism(##Lset(i),f(x),g(x),h(x),g'(x),h'(x))]" apply (simp only: order_isomorphism_def) apply (intro FOL_reflections function_reflections bijection_reflection) done subsubsection\Limit Ordinals, Internalized\ text\A limit ordinal is a non-empty, successor-closed ordinal\ (* "limit_ordinal(M,a) \ ordinal(M,a) \ \ empty(M,a) \ (\x[M]. x\a \ (\y[M]. y\a \ successor(M,x,y)))" *) definition limit_ordinal_fm :: "i\i" where "limit_ordinal_fm(x) \ And(ordinal_fm(x), And(Neg(empty_fm(x)), Forall(Implies(Member(0,succ(x)), Exists(And(Member(0,succ(succ(x))), succ_fm(1,0)))))))" lemma limit_ordinal_type [TC]: "x \ nat \ limit_ordinal_fm(x) \ formula" by (simp add: limit_ordinal_fm_def) lemma sats_limit_ordinal_fm [simp]: "\x \ nat; env \ list(A)\ \ sats(A, limit_ordinal_fm(x), env) \ limit_ordinal(##A, nth(x,env))" by (simp add: limit_ordinal_fm_def limit_ordinal_def sats_ordinal_fm') lemma limit_ordinal_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; env \ list(A)\ \ limit_ordinal(##A, x) \ sats(A, limit_ordinal_fm(i), env)" by simp theorem limit_ordinal_reflection: "REFLECTS[\x. limit_ordinal(L,f(x)), \i x. limit_ordinal(##Lset(i),f(x))]" apply (simp only: limit_ordinal_def) apply (intro FOL_reflections ordinal_reflection empty_reflection successor_reflection) done subsubsection\Finite Ordinals: The Predicate ``Is A Natural Number''\ (* "finite_ordinal(M,a) \ ordinal(M,a) \ \ limit_ordinal(M,a) \ (\x[M]. x\a \ \ limit_ordinal(M,x))" *) definition finite_ordinal_fm :: "i\i" where "finite_ordinal_fm(x) \ And(ordinal_fm(x), And(Neg(limit_ordinal_fm(x)), Forall(Implies(Member(0,succ(x)), Neg(limit_ordinal_fm(0))))))" lemma finite_ordinal_type [TC]: "x \ nat \ finite_ordinal_fm(x) \ formula" by (simp add: finite_ordinal_fm_def) lemma sats_finite_ordinal_fm [simp]: "\x \ nat; env \ list(A)\ \ sats(A, finite_ordinal_fm(x), env) \ finite_ordinal(##A, nth(x,env))" by (simp add: finite_ordinal_fm_def sats_ordinal_fm' finite_ordinal_def) lemma finite_ordinal_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; env \ list(A)\ \ finite_ordinal(##A, x) \ sats(A, finite_ordinal_fm(i), env)" by simp theorem finite_ordinal_reflection: "REFLECTS[\x. finite_ordinal(L,f(x)), \i x. finite_ordinal(##Lset(i),f(x))]" apply (simp only: finite_ordinal_def) apply (intro FOL_reflections ordinal_reflection limit_ordinal_reflection) done subsubsection\Omega: The Set of Natural Numbers\ (* omega(M,a) \ limit_ordinal(M,a) \ (\x[M]. x\a \ \ limit_ordinal(M,x)) *) definition omega_fm :: "i\i" where "omega_fm(x) \ And(limit_ordinal_fm(x), Forall(Implies(Member(0,succ(x)), Neg(limit_ordinal_fm(0)))))" lemma omega_type [TC]: "x \ nat \ omega_fm(x) \ formula" by (simp add: omega_fm_def) lemma sats_omega_fm [simp]: "\x \ nat; env \ list(A)\ \ sats(A, omega_fm(x), env) \ omega(##A, nth(x,env))" by (simp add: omega_fm_def omega_def) lemma omega_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; env \ list(A)\ \ omega(##A, x) \ sats(A, omega_fm(i), env)" by simp theorem omega_reflection: "REFLECTS[\x. omega(L,f(x)), \i x. omega(##Lset(i),f(x))]" apply (simp only: omega_def) apply (intro FOL_reflections limit_ordinal_reflection) done lemmas fun_plus_reflections = typed_function_reflection composition_reflection injection_reflection surjection_reflection bijection_reflection restriction_reflection order_isomorphism_reflection finite_ordinal_reflection ordinal_reflection limit_ordinal_reflection omega_reflection lemmas fun_plus_iff_sats = typed_function_iff_sats composition_iff_sats injection_iff_sats surjection_iff_sats bijection_iff_sats restriction_iff_sats order_isomorphism_iff_sats finite_ordinal_iff_sats ordinal_iff_sats limit_ordinal_iff_sats omega_iff_sats end diff --git a/src/ZF/Constructible/Normal.thy b/src/ZF/Constructible/Normal.thy --- a/src/ZF/Constructible/Normal.thy +++ b/src/ZF/Constructible/Normal.thy @@ -1,503 +1,503 @@ (* Title: ZF/Constructible/Normal.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory *) section \Closed Unbounded Classes and Normal Functions\ theory Normal imports ZF begin text\ One source is the book Frank R. Drake. \emph{Set Theory: An Introduction to Large Cardinals}. North-Holland, 1974. \ subsection \Closed and Unbounded (c.u.) Classes of Ordinals\ definition Closed :: "(i\o) \ o" where "Closed(P) \ \I. I \ 0 \ (\i\I. Ord(i) \ P(i)) \ P(\(I))" definition Unbounded :: "(i\o) \ o" where "Unbounded(P) \ \i. Ord(i) \ (\j. i P(j))" definition Closed_Unbounded :: "(i\o) \ o" where "Closed_Unbounded(P) \ Closed(P) \ Unbounded(P)" subsubsection\Simple facts about c.u. classes\ lemma ClosedI: "\\I. \I \ 0; \i\I. Ord(i) \ P(i)\ \ P(\(I))\ \ Closed(P)" by (simp add: Closed_def) lemma ClosedD: "\Closed(P); I \ 0; \i. i\I \ Ord(i); \i. i\I \ P(i)\ \ P(\(I))" by (simp add: Closed_def) lemma UnboundedD: "\Unbounded(P); Ord(i)\ \ \j. i P(j)" by (simp add: Unbounded_def) lemma Closed_Unbounded_imp_Unbounded: "Closed_Unbounded(C) \ Unbounded(C)" by (simp add: Closed_Unbounded_def) text\The universal class, V, is closed and unbounded. A bit odd, since C. U. concerns only ordinals, but it's used below!\ theorem Closed_Unbounded_V [simp]: "Closed_Unbounded(\x. True)" by (unfold Closed_Unbounded_def Closed_def Unbounded_def, blast) text\The class of ordinals, \<^term>\Ord\, is closed and unbounded.\ theorem Closed_Unbounded_Ord [simp]: "Closed_Unbounded(Ord)" by (unfold Closed_Unbounded_def Closed_def Unbounded_def, blast) text\The class of limit ordinals, \<^term>\Limit\, is closed and unbounded.\ theorem Closed_Unbounded_Limit [simp]: "Closed_Unbounded(Limit)" apply (simp add: Closed_Unbounded_def Closed_def Unbounded_def Limit_Union, clarify) apply (rule_tac x="i++nat" in exI) apply (blast intro: oadd_lt_self oadd_LimitI Limit_has_0) done text\The class of cardinals, \<^term>\Card\, is closed and unbounded.\ theorem Closed_Unbounded_Card [simp]: "Closed_Unbounded(Card)" apply (simp add: Closed_Unbounded_def Closed_def Unbounded_def) apply (blast intro: lt_csucc Card_csucc) done subsubsection\The intersection of any set-indexed family of c.u. classes is c.u.\ text\The constructions below come from Kunen, \emph{Set Theory}, page 78.\ locale cub_family = fixes P and A fixes next_greater \ \the next ordinal satisfying class \<^term>\A\\ fixes sup_greater \ \sup of those ordinals over all \<^term>\A\\ assumes closed: "a\A \ Closed(P(a))" and unbounded: "a\A \ Unbounded(P(a))" and A_non0: "A\0" defines "next_greater(a,x) \ \ y. x P(a,y)" and "sup_greater(x) \ \a\A. next_greater(a,x)" begin text\Trivial that the intersection is closed.\ lemma Closed_INT: "Closed(\x. \i\A. P(i,x))" by (blast intro: ClosedI ClosedD [OF closed]) text\All remaining effort goes to show that the intersection is unbounded.\ lemma Ord_sup_greater: "Ord(sup_greater(x))" by (simp add: sup_greater_def next_greater_def) lemma Ord_next_greater: "Ord(next_greater(a,x))" by (simp add: next_greater_def) text\\<^term>\next_greater\ works as expected: it returns a larger value and one that belongs to class \<^term>\P(a)\.\ lemma next_greater_lemma: "\Ord(x); a\A\ \ P(a, next_greater(a,x)) \ x < next_greater(a,x)" apply (simp add: next_greater_def) apply (rule exE [OF UnboundedD [OF unbounded]]) apply assumption+ apply (blast intro: LeastI2 lt_Ord2) done lemma next_greater_in_P: "\Ord(x); a\A\ \ P(a, next_greater(a,x))" by (blast dest: next_greater_lemma) lemma next_greater_gt: "\Ord(x); a\A\ \ x < next_greater(a,x)" by (blast dest: next_greater_lemma) lemma sup_greater_gt: "Ord(x) \ x < sup_greater(x)" apply (simp add: sup_greater_def) apply (insert A_non0) apply (blast intro: UN_upper_lt next_greater_gt Ord_next_greater) done lemma next_greater_le_sup_greater: "a\A \ next_greater(a,x) \ sup_greater(x)" apply (simp add: sup_greater_def) apply (blast intro: UN_upper_le Ord_next_greater) done lemma omega_sup_greater_eq_UN: "\Ord(x); a\A\ \ sup_greater^\ (x) = (\n\nat. next_greater(a, sup_greater^n (x)))" apply (simp add: iterates_omega_def) apply (rule le_anti_sym) apply (rule le_implies_UN_le_UN) apply (blast intro: leI next_greater_gt Ord_iterates Ord_sup_greater) txt\Opposite bound: @{subgoals[display,indent=0,margin=65]} \ apply (rule UN_least_le) apply (blast intro: Ord_iterates Ord_sup_greater) apply (rule_tac a="succ(n)" in UN_upper_le) apply (simp_all add: next_greater_le_sup_greater) apply (blast intro: Ord_iterates Ord_sup_greater) done lemma P_omega_sup_greater: "\Ord(x); a\A\ \ P(a, sup_greater^\ (x))" apply (simp add: omega_sup_greater_eq_UN) apply (rule ClosedD [OF closed]) apply (blast intro: ltD, auto) apply (blast intro: Ord_iterates Ord_next_greater Ord_sup_greater) apply (blast intro: next_greater_in_P Ord_iterates Ord_sup_greater) done lemma omega_sup_greater_gt: "Ord(x) \ x < sup_greater^\ (x)" apply (simp add: iterates_omega_def) apply (rule UN_upper_lt [of 1], simp_all) apply (blast intro: sup_greater_gt) apply (blast intro: Ord_iterates Ord_sup_greater) done lemma Unbounded_INT: "Unbounded(\x. \a\A. P(a,x))" - apply (unfold Unbounded_def) + unfolding Unbounded_def apply (blast intro!: omega_sup_greater_gt P_omega_sup_greater) done lemma Closed_Unbounded_INT: "Closed_Unbounded(\x. \a\A. P(a,x))" by (simp add: Closed_Unbounded_def Closed_INT Unbounded_INT) end theorem Closed_Unbounded_INT: "(\a. a\A \ Closed_Unbounded(P(a))) \ Closed_Unbounded(\x. \a\A. P(a, x))" apply (case_tac "A=0", simp) apply (rule cub_family.Closed_Unbounded_INT [OF cub_family.intro]) apply (simp_all add: Closed_Unbounded_def) done lemma Int_iff_INT2: "P(x) \ Q(x) \ (\i\2. (i=0 \ P(x)) \ (i=1 \ Q(x)))" by auto theorem Closed_Unbounded_Int: "\Closed_Unbounded(P); Closed_Unbounded(Q)\ \ Closed_Unbounded(\x. P(x) \ Q(x))" apply (simp only: Int_iff_INT2) apply (rule Closed_Unbounded_INT, auto) done subsection \Normal Functions\ definition mono_le_subset :: "(i\i) \ o" where "mono_le_subset(M) \ \i j. i\j \ M(i) \ M(j)" definition mono_Ord :: "(i\i) \ o" where "mono_Ord(F) \ \i j. i F(i) < F(j)" definition cont_Ord :: "(i\i) \ o" where "cont_Ord(F) \ \l. Limit(l) \ F(l) = (\ii) \ o" where "Normal(F) \ mono_Ord(F) \ cont_Ord(F)" subsubsection\Immediate properties of the definitions\ lemma NormalI: "\\i j. i F(i) < F(j); \l. Limit(l) \ F(l) = (\i \ Normal(F)" by (simp add: Normal_def mono_Ord_def cont_Ord_def) lemma mono_Ord_imp_Ord: "\Ord(i); mono_Ord(F)\ \ Ord(F(i))" apply (auto simp add: mono_Ord_def) apply (blast intro: lt_Ord) done lemma mono_Ord_imp_mono: "\i \ F(i) < F(j)" by (simp add: mono_Ord_def) lemma Normal_imp_Ord [simp]: "\Normal(F); Ord(i)\ \ Ord(F(i))" by (simp add: Normal_def mono_Ord_imp_Ord) lemma Normal_imp_cont: "\Normal(F); Limit(l)\ \ F(l) = (\ii \ F(i) < F(j)" by (simp add: Normal_def mono_Ord_def) lemma Normal_increasing: assumes i: "Ord(i)" and F: "Normal(F)" shows"i \ F(i)" using i proof (induct i rule: trans_induct3) case 0 thus ?case by (simp add: subset_imp_le F) next case (succ i) hence "F(i) < F(succ(i))" using F by (simp add: Normal_def mono_Ord_def) thus ?case using succ.hyps by (blast intro: lt_trans1) next case (limit l) hence "l = (\y (\y (\yy F(l)" using limit F by (simp add: Normal_imp_cont lt_Ord) ultimately show ?case by (blast intro: le_trans) qed subsubsection\The class of fixedpoints is closed and unbounded\ text\The proof is from Drake, pages 113--114.\ lemma mono_Ord_imp_le_subset: "mono_Ord(F) \ mono_le_subset(F)" apply (simp add: mono_le_subset_def, clarify) apply (subgoal_tac "F(i)\F(j)", blast dest: le_imp_subset) apply (simp add: le_iff) apply (blast intro: lt_Ord2 mono_Ord_imp_Ord mono_Ord_imp_mono) done text\The following equation is taken for granted in any set theory text.\ lemma cont_Ord_Union: "\cont_Ord(F); mono_le_subset(F); X=0 \ F(0)=0; \x\X. Ord(x)\ \ F(\(X)) = (\y\X. F(y))" apply (frule Ord_set_cases) apply (erule disjE, force) apply (thin_tac "X=0 \ Q" for Q, auto) txt\The trival case of \<^term>\\X \ X\\ apply (rule equalityI, blast intro: Ord_Union_eq_succD) apply (simp add: mono_le_subset_def UN_subset_iff le_subset_iff) apply (blast elim: equalityE) txt\The limit case, \<^term>\Limit(\X)\: @{subgoals[display,indent=0,margin=65]} \ apply (simp add: OUN_Union_eq cont_Ord_def) apply (rule equalityI) txt\First inclusion:\ apply (rule UN_least [OF OUN_least]) apply (simp add: mono_le_subset_def, blast intro: leI) txt\Second inclusion:\ apply (rule UN_least) apply (frule Union_upper_le, blast, blast) apply (erule leE, drule ltD, elim UnionE) apply (simp add: OUnion_def) apply blast+ done lemma Normal_Union: "\X\0; \x\X. Ord(x); Normal(F)\ \ F(\(X)) = (\y\X. F(y))" apply (simp add: Normal_def) apply (blast intro: mono_Ord_imp_le_subset cont_Ord_Union) done lemma Normal_imp_fp_Closed: "Normal(F) \ Closed(\i. F(i) = i)" apply (simp add: Closed_def ball_conj_distrib, clarify) apply (frule Ord_set_cases) apply (auto simp add: Normal_Union) done lemma iterates_Normal_increasing: "\n\nat; x < F(x); Normal(F)\ \ F^n (x) < F^(succ(n)) (x)" apply (induct n rule: nat_induct) apply (simp_all add: Normal_imp_mono) done lemma Ord_iterates_Normal: "\n\nat; Normal(F); Ord(x)\ \ Ord(F^n (x))" by (simp) text\THIS RESULT IS UNUSED\ lemma iterates_omega_Limit: "\Normal(F); x < F(x)\ \ Limit(F^\ (x))" apply (frule lt_Ord) apply (simp add: iterates_omega_def) apply (rule increasing_LimitI) \ \this lemma is @{thm increasing_LimitI [no_vars]}\ apply (blast intro: UN_upper_lt [of "1"] Normal_imp_Ord Ord_iterates lt_imp_0_lt iterates_Normal_increasing, clarify) apply (rule bexI) apply (blast intro: Ord_in_Ord [OF Ord_iterates_Normal]) apply (rule UN_I, erule nat_succI) apply (blast intro: iterates_Normal_increasing Ord_iterates_Normal ltD [OF lt_trans1, OF succ_leI, OF ltI]) done lemma iterates_omega_fixedpoint: "\Normal(F); Ord(a)\ \ F(F^\ (a)) = F^\ (a)" apply (frule Normal_increasing, assumption) apply (erule leE) apply (simp_all add: iterates_omega_triv [OF sym]) (*for subgoal 2*) apply (simp add: iterates_omega_def Normal_Union) apply (rule equalityI, force simp add: nat_succI) txt\Opposite inclusion: @{subgoals[display,indent=0,margin=65]} \ apply clarify apply (rule UN_I, assumption) apply (frule iterates_Normal_increasing, assumption, assumption, simp) apply (blast intro: Ord_trans ltD Ord_iterates_Normal Normal_imp_Ord [of F]) done lemma iterates_omega_increasing: "\Normal(F); Ord(a)\ \ a \ F^\ (a)" -apply (unfold iterates_omega_def) + unfolding iterates_omega_def apply (rule UN_upper_le [of 0], simp_all) done lemma Normal_imp_fp_Unbounded: "Normal(F) \ Unbounded(\i. F(i) = i)" apply (unfold Unbounded_def, clarify) apply (rule_tac x="F^\ (succ(i))" in exI) apply (simp add: iterates_omega_fixedpoint) apply (blast intro: lt_trans2 [OF _ iterates_omega_increasing]) done theorem Normal_imp_fp_Closed_Unbounded: "Normal(F) \ Closed_Unbounded(\i. F(i) = i)" by (simp add: Closed_Unbounded_def Normal_imp_fp_Closed Normal_imp_fp_Unbounded) subsubsection\Function \normalize\\ text\Function \normalize\ maps a function \F\ to a normal function that bounds it above. The result is normal if and only if \F\ is continuous: succ is not bounded above by any normal function, by @{thm [source] Normal_imp_fp_Unbounded}. \ definition normalize :: "[i\i, i] \ i" where "normalize(F,a) \ transrec2(a, F(0), \x r. F(succ(x)) \ succ(r))" lemma Ord_normalize [simp, intro]: "\Ord(a); \x. Ord(x) \ Ord(F(x))\ \ Ord(normalize(F, a))" apply (induct a rule: trans_induct3) apply (simp_all add: ltD def_transrec2 [OF normalize_def]) done lemma normalize_increasing: assumes ab: "a < b" and F: "\x. Ord(x) \ Ord(F(x))" shows "normalize(F,a) < normalize(F,b)" proof - { fix x have "Ord(b)" using ab by (blast intro: lt_Ord2) hence "x < b \ normalize(F,x) < normalize(F,b)" proof (induct b arbitrary: x rule: trans_induct3) case 0 thus ?case by simp next case (succ b) thus ?case by (auto simp add: le_iff def_transrec2 [OF normalize_def] intro: Un_upper2_lt F) next case (limit l) hence sc: "succ(x) < l" by (blast intro: Limit_has_succ) hence "normalize(F,x) < normalize(F,succ(x))" by (blast intro: limit elim: ltE) hence "normalize(F,x) < (\jx. Ord(x) \ Ord(F(x))) \ Normal(normalize(F))" apply (rule NormalI) apply (blast intro!: normalize_increasing) apply (simp add: def_transrec2 [OF normalize_def]) done theorem le_normalize: assumes a: "Ord(a)" and coF: "cont_Ord(F)" and F: "\x. Ord(x) \ Ord(F(x))" shows "F(a) \ normalize(F,a)" using a proof (induct a rule: trans_induct3) case 0 thus ?case by (simp add: F def_transrec2 [OF normalize_def]) next case (succ a) thus ?case by (simp add: def_transrec2 [OF normalize_def] Un_upper1_le F ) next case (limit l) thus ?case using F coF [unfolded cont_Ord_def] by (simp add: def_transrec2 [OF normalize_def] le_implies_OUN_le_OUN ltD) qed subsection \The Alephs\ text \This is the well-known transfinite enumeration of the cardinal numbers.\ definition Aleph :: "i \ i" (\\_\ [90] 90) where "Aleph(a) \ transrec2(a, nat, \x r. csucc(r))" lemma Card_Aleph [simp, intro]: "Ord(a) \ Card(Aleph(a))" apply (erule trans_induct3) apply (simp_all add: Card_csucc Card_nat Card_is_Ord def_transrec2 [OF Aleph_def]) done lemma Aleph_increasing: assumes ab: "a < b" shows "Aleph(a) < Aleph(b)" proof - { fix x have "Ord(b)" using ab by (blast intro: lt_Ord2) hence "x < b \ Aleph(x) < Aleph(b)" proof (induct b arbitrary: x rule: trans_induct3) case 0 thus ?case by simp next case (succ b) thus ?case by (force simp add: le_iff def_transrec2 [OF Aleph_def] intro: lt_trans lt_csucc Card_is_Ord) next case (limit l) hence sc: "succ(x) < l" by (blast intro: Limit_has_succ) hence "\ x < (\jj)" using limit by (blast intro: OUN_upper_lt Card_is_Ord ltD lt_Ord) thus ?case using limit by (simp add: def_transrec2 [OF Aleph_def]) qed } thus ?thesis using ab . qed theorem Normal_Aleph: "Normal(Aleph)" apply (rule NormalI) apply (blast intro!: Aleph_increasing) apply (simp add: def_transrec2 [OF Aleph_def]) done end diff --git a/src/ZF/Constructible/Satisfies_absolute.thy b/src/ZF/Constructible/Satisfies_absolute.thy --- a/src/ZF/Constructible/Satisfies_absolute.thy +++ b/src/ZF/Constructible/Satisfies_absolute.thy @@ -1,1039 +1,1039 @@ (* Title: ZF/Constructible/Satisfies_absolute.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory *) section \Absoluteness for the Satisfies Relation on Formulas\ theory Satisfies_absolute imports Datatype_absolute Rec_Separation begin subsection \More Internalization\ subsubsection\The Formula \<^term>\is_depth\, Internalized\ (* "is_depth(M,p,n) \ \sn[M]. \formula_n[M]. \formula_sn[M]. 2 1 0 is_formula_N(M,n,formula_n) \ p \ formula_n \ successor(M,n,sn) \ is_formula_N(M,sn,formula_sn) \ p \ formula_sn" *) definition depth_fm :: "[i,i]\i" where "depth_fm(p,n) \ Exists(Exists(Exists( And(formula_N_fm(n#+3,1), And(Neg(Member(p#+3,1)), And(succ_fm(n#+3,2), And(formula_N_fm(2,0), Member(p#+3,0))))))))" lemma depth_fm_type [TC]: "\x \ nat; y \ nat\ \ depth_fm(x,y) \ formula" by (simp add: depth_fm_def) lemma sats_depth_fm [simp]: "\x \ nat; y < length(env); env \ list(A)\ \ sats(A, depth_fm(x,y), env) \ is_depth(##A, nth(x,env), nth(y,env))" apply (frule_tac x=y in lt_length_in_nat, assumption) apply (simp add: depth_fm_def is_depth_def) done lemma depth_iff_sats: "\nth(i,env) = x; nth(j,env) = y; i \ nat; j < length(env); env \ list(A)\ \ is_depth(##A, x, y) \ sats(A, depth_fm(i,j), env)" by (simp) theorem depth_reflection: "REFLECTS[\x. is_depth(L, f(x), g(x)), \i x. is_depth(##Lset(i), f(x), g(x))]" apply (simp only: is_depth_def) apply (intro FOL_reflections function_reflections formula_N_reflection) done subsubsection\The Operator \<^term>\is_formula_case\\ text\The arguments of \<^term>\is_a\ are always 2, 1, 0, and the formula will be enclosed by three quantifiers.\ (* is_formula_case :: "[i\o, [i,i,i]\o, [i,i,i]\o, [i,i,i]\o, [i,i]\o, i, i] \ o" "is_formula_case(M, is_a, is_b, is_c, is_d, v, z) \ (\x[M]. \y[M]. x\nat \ y\nat \ is_Member(M,x,y,v) \ is_a(x,y,z)) \ (\x[M]. \y[M]. x\nat \ y\nat \ is_Equal(M,x,y,v) \ is_b(x,y,z)) \ (\x[M]. \y[M]. x\formula \ y\formula \ is_Nand(M,x,y,v) \ is_c(x,y,z)) \ (\x[M]. x\formula \ is_Forall(M,x,v) \ is_d(x,z))" *) definition formula_case_fm :: "[i, i, i, i, i, i]\i" where "formula_case_fm(is_a, is_b, is_c, is_d, v, z) \ And(Forall(Forall(Implies(finite_ordinal_fm(1), Implies(finite_ordinal_fm(0), Implies(Member_fm(1,0,v#+2), Forall(Implies(Equal(0,z#+3), is_a))))))), And(Forall(Forall(Implies(finite_ordinal_fm(1), Implies(finite_ordinal_fm(0), Implies(Equal_fm(1,0,v#+2), Forall(Implies(Equal(0,z#+3), is_b))))))), And(Forall(Forall(Implies(mem_formula_fm(1), Implies(mem_formula_fm(0), Implies(Nand_fm(1,0,v#+2), Forall(Implies(Equal(0,z#+3), is_c))))))), Forall(Implies(mem_formula_fm(0), Implies(Forall_fm(0,succ(v)), Forall(Implies(Equal(0,z#+2), is_d))))))))" lemma is_formula_case_type [TC]: "\is_a \ formula; is_b \ formula; is_c \ formula; is_d \ formula; x \ nat; y \ nat\ \ formula_case_fm(is_a, is_b, is_c, is_d, x, y) \ formula" by (simp add: formula_case_fm_def) lemma sats_formula_case_fm: assumes is_a_iff_sats: "\a0 a1 a2. \a0\A; a1\A; a2\A\ \ ISA(a2, a1, a0) \ sats(A, is_a, Cons(a0,Cons(a1,Cons(a2,env))))" and is_b_iff_sats: "\a0 a1 a2. \a0\A; a1\A; a2\A\ \ ISB(a2, a1, a0) \ sats(A, is_b, Cons(a0,Cons(a1,Cons(a2,env))))" and is_c_iff_sats: "\a0 a1 a2. \a0\A; a1\A; a2\A\ \ ISC(a2, a1, a0) \ sats(A, is_c, Cons(a0,Cons(a1,Cons(a2,env))))" and is_d_iff_sats: "\a0 a1. \a0\A; a1\A\ \ ISD(a1, a0) \ sats(A, is_d, Cons(a0,Cons(a1,env)))" shows "\x \ nat; y < length(env); env \ list(A)\ \ sats(A, formula_case_fm(is_a,is_b,is_c,is_d,x,y), env) \ is_formula_case(##A, ISA, ISB, ISC, ISD, nth(x,env), nth(y,env))" apply (frule_tac x=y in lt_length_in_nat, assumption) apply (simp add: formula_case_fm_def is_formula_case_def is_a_iff_sats [THEN iff_sym] is_b_iff_sats [THEN iff_sym] is_c_iff_sats [THEN iff_sym] is_d_iff_sats [THEN iff_sym]) done lemma formula_case_iff_sats: assumes is_a_iff_sats: "\a0 a1 a2. \a0\A; a1\A; a2\A\ \ ISA(a2, a1, a0) \ sats(A, is_a, Cons(a0,Cons(a1,Cons(a2,env))))" and is_b_iff_sats: "\a0 a1 a2. \a0\A; a1\A; a2\A\ \ ISB(a2, a1, a0) \ sats(A, is_b, Cons(a0,Cons(a1,Cons(a2,env))))" and is_c_iff_sats: "\a0 a1 a2. \a0\A; a1\A; a2\A\ \ ISC(a2, a1, a0) \ sats(A, is_c, Cons(a0,Cons(a1,Cons(a2,env))))" and is_d_iff_sats: "\a0 a1. \a0\A; a1\A\ \ ISD(a1, a0) \ sats(A, is_d, Cons(a0,Cons(a1,env)))" shows "\nth(i,env) = x; nth(j,env) = y; i \ nat; j < length(env); env \ list(A)\ \ is_formula_case(##A, ISA, ISB, ISC, ISD, x, y) \ sats(A, formula_case_fm(is_a,is_b,is_c,is_d,i,j), env)" by (simp add: sats_formula_case_fm [OF is_a_iff_sats is_b_iff_sats is_c_iff_sats is_d_iff_sats]) text\The second argument of \<^term>\is_a\ gives it direct access to \<^term>\x\, which is essential for handling free variable references. Treatment is based on that of \is_nat_case_reflection\.\ theorem is_formula_case_reflection: assumes is_a_reflection: "\h f g g'. REFLECTS[\x. is_a(L, h(x), f(x), g(x), g'(x)), \i x. is_a(##Lset(i), h(x), f(x), g(x), g'(x))]" and is_b_reflection: "\h f g g'. REFLECTS[\x. is_b(L, h(x), f(x), g(x), g'(x)), \i x. is_b(##Lset(i), h(x), f(x), g(x), g'(x))]" and is_c_reflection: "\h f g g'. REFLECTS[\x. is_c(L, h(x), f(x), g(x), g'(x)), \i x. is_c(##Lset(i), h(x), f(x), g(x), g'(x))]" and is_d_reflection: "\h f g g'. REFLECTS[\x. is_d(L, h(x), f(x), g(x)), \i x. is_d(##Lset(i), h(x), f(x), g(x))]" shows "REFLECTS[\x. is_formula_case(L, is_a(L,x), is_b(L,x), is_c(L,x), is_d(L,x), g(x), h(x)), \i x. is_formula_case(##Lset(i), is_a(##Lset(i), x), is_b(##Lset(i), x), is_c(##Lset(i), x), is_d(##Lset(i), x), g(x), h(x))]" apply (simp (no_asm_use) only: is_formula_case_def) apply (intro FOL_reflections function_reflections finite_ordinal_reflection mem_formula_reflection Member_reflection Equal_reflection Nand_reflection Forall_reflection is_a_reflection is_b_reflection is_c_reflection is_d_reflection) done subsection \Absoluteness for the Function \<^term>\satisfies\\ definition is_depth_apply :: "[i\o,i,i,i] \ o" where \ \Merely a useful abbreviation for the sequel.\ "is_depth_apply(M,h,p,z) \ \dp[M]. \sdp[M]. \hsdp[M]. finite_ordinal(M,dp) \ is_depth(M,p,dp) \ successor(M,dp,sdp) \ fun_apply(M,h,sdp,hsdp) \ fun_apply(M,hsdp,p,z)" lemma (in M_datatypes) is_depth_apply_abs [simp]: "\M(h); p \ formula; M(z)\ \ is_depth_apply(M,h,p,z) \ z = h ` succ(depth(p)) ` p" by (simp add: is_depth_apply_def formula_into_M depth_type eq_commute) text\There is at present some redundancy between the relativizations in e.g. \satisfies_is_a\ and those in e.g. \Member_replacement\.\ text\These constants let us instantiate the parameters \<^term>\a\, \<^term>\b\, \<^term>\c\, \<^term>\d\, etc., of the locale \Formula_Rec\.\ definition satisfies_a :: "[i,i,i]\i" where "satisfies_a(A) \ \x y. \env \ list(A). bool_of_o (nth(x,env) \ nth(y,env))" definition satisfies_is_a :: "[i\o,i,i,i,i]\o" where "satisfies_is_a(M,A) \ \x y zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. is_bool_of_o(M, \nx[M]. \ny[M]. is_nth(M,x,env,nx) \ is_nth(M,y,env,ny) \ nx \ ny, z), zz)" definition satisfies_b :: "[i,i,i]\i" where "satisfies_b(A) \ \x y. \env \ list(A). bool_of_o (nth(x,env) = nth(y,env))" definition satisfies_is_b :: "[i\o,i,i,i,i]\o" where \ \We simplify the formula to have just \<^term>\nx\ rather than introducing \<^term>\ny\ with \<^term>\nx=ny\\ "satisfies_is_b(M,A) \ \x y zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. is_bool_of_o(M, \nx[M]. is_nth(M,x,env,nx) \ is_nth(M,y,env,nx), z), zz)" definition satisfies_c :: "[i,i,i,i,i]\i" where "satisfies_c(A) \ \p q rp rq. \env \ list(A). not(rp ` env and rq ` env)" definition satisfies_is_c :: "[i\o,i,i,i,i,i]\o" where "satisfies_is_c(M,A,h) \ \p q zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. \hp[M]. \hq[M]. (\rp[M]. is_depth_apply(M,h,p,rp) \ fun_apply(M,rp,env,hp)) \ (\rq[M]. is_depth_apply(M,h,q,rq) \ fun_apply(M,rq,env,hq)) \ (\pq[M]. is_and(M,hp,hq,pq) \ is_not(M,pq,z)), zz)" definition satisfies_d :: "[i,i,i]\i" where "satisfies_d(A) \ \p rp. \env \ list(A). bool_of_o (\x\A. rp ` (Cons(x,env)) = 1)" definition satisfies_is_d :: "[i\o,i,i,i,i]\o" where "satisfies_is_d(M,A,h) \ \p zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. \rp[M]. is_depth_apply(M,h,p,rp) \ is_bool_of_o(M, \x[M]. \xenv[M]. \hp[M]. x\A \ is_Cons(M,x,env,xenv) \ fun_apply(M,rp,xenv,hp) \ number1(M,hp), z), zz)" definition satisfies_MH :: "[i\o,i,i,i,i]\o" where \ \The variable \<^term>\u\ is unused, but gives \<^term>\satisfies_MH\ the correct arity.\ "satisfies_MH \ \M A u f z. \fml[M]. is_formula(M,fml) \ is_lambda (M, fml, is_formula_case (M, satisfies_is_a(M,A), satisfies_is_b(M,A), satisfies_is_c(M,A,f), satisfies_is_d(M,A,f)), z)" definition is_satisfies :: "[i\o,i,i,i]\o" where "is_satisfies(M,A) \ is_formula_rec (M, satisfies_MH(M,A))" text\This lemma relates the fragments defined above to the original primitive recursion in \<^term>\satisfies\. Induction is not required: the definitions are directly equal!\ lemma satisfies_eq: "satisfies(A,p) = formula_rec (satisfies_a(A), satisfies_b(A), satisfies_c(A), satisfies_d(A), p)" by (simp add: satisfies_formula_def satisfies_a_def satisfies_b_def satisfies_c_def satisfies_d_def) text\Further constraints on the class \<^term>\M\ in order to prove absoluteness for the constants defined above. The ultimate goal is the absoluteness of the function \<^term>\satisfies\.\ locale M_satisfies = M_eclose + assumes Member_replacement: "\M(A); x \ nat; y \ nat\ \ strong_replacement (M, \env z. \bo[M]. \nx[M]. \ny[M]. env \ list(A) \ is_nth(M,x,env,nx) \ is_nth(M,y,env,ny) \ is_bool_of_o(M, nx \ ny, bo) \ pair(M, env, bo, z))" and Equal_replacement: "\M(A); x \ nat; y \ nat\ \ strong_replacement (M, \env z. \bo[M]. \nx[M]. \ny[M]. env \ list(A) \ is_nth(M,x,env,nx) \ is_nth(M,y,env,ny) \ is_bool_of_o(M, nx = ny, bo) \ pair(M, env, bo, z))" and Nand_replacement: "\M(A); M(rp); M(rq)\ \ strong_replacement (M, \env z. \rpe[M]. \rqe[M]. \andpq[M]. \notpq[M]. fun_apply(M,rp,env,rpe) \ fun_apply(M,rq,env,rqe) \ is_and(M,rpe,rqe,andpq) \ is_not(M,andpq,notpq) \ env \ list(A) \ pair(M, env, notpq, z))" and Forall_replacement: "\M(A); M(rp)\ \ strong_replacement (M, \env z. \bo[M]. env \ list(A) \ is_bool_of_o (M, \a[M]. \co[M]. \rpco[M]. a\A \ is_Cons(M,a,env,co) \ fun_apply(M,rp,co,rpco) \ number1(M, rpco), bo) \ pair(M,env,bo,z))" and formula_rec_replacement: \ \For the \<^term>\transrec\\ "\n \ nat; M(A)\ \ transrec_replacement(M, satisfies_MH(M,A), n)" and formula_rec_lambda_replacement: \ \For the \\-abstraction\ in the \<^term>\transrec\ body\ "\M(g); M(A)\ \ strong_replacement (M, \x y. mem_formula(M,x) \ (\c[M]. is_formula_case(M, satisfies_is_a(M,A), satisfies_is_b(M,A), satisfies_is_c(M,A,g), satisfies_is_d(M,A,g), x, c) \ pair(M, x, c, y)))" lemma (in M_satisfies) Member_replacement': "\M(A); x \ nat; y \ nat\ \ strong_replacement (M, \env z. env \ list(A) \ z = \env, bool_of_o(nth(x, env) \ nth(y, env))\)" by (insert Member_replacement, simp) lemma (in M_satisfies) Equal_replacement': "\M(A); x \ nat; y \ nat\ \ strong_replacement (M, \env z. env \ list(A) \ z = \env, bool_of_o(nth(x, env) = nth(y, env))\)" by (insert Equal_replacement, simp) lemma (in M_satisfies) Nand_replacement': "\M(A); M(rp); M(rq)\ \ strong_replacement (M, \env z. env \ list(A) \ z = \env, not(rp`env and rq`env)\)" by (insert Nand_replacement, simp) lemma (in M_satisfies) Forall_replacement': "\M(A); M(rp)\ \ strong_replacement (M, \env z. env \ list(A) \ z = \env, bool_of_o (\a\A. rp ` Cons(a,env) = 1)\)" by (insert Forall_replacement, simp) lemma (in M_satisfies) a_closed: "\M(A); x\nat; y\nat\ \ M(satisfies_a(A,x,y))" apply (simp add: satisfies_a_def) apply (blast intro: lam_closed2 Member_replacement') done lemma (in M_satisfies) a_rel: "M(A) \ Relation2(M, nat, nat, satisfies_is_a(M,A), satisfies_a(A))" apply (simp add: Relation2_def satisfies_is_a_def satisfies_a_def) apply (auto del: iffI intro!: lambda_abs2 simp add: Relation1_def) done lemma (in M_satisfies) b_closed: "\M(A); x\nat; y\nat\ \ M(satisfies_b(A,x,y))" apply (simp add: satisfies_b_def) apply (blast intro: lam_closed2 Equal_replacement') done lemma (in M_satisfies) b_rel: "M(A) \ Relation2(M, nat, nat, satisfies_is_b(M,A), satisfies_b(A))" apply (simp add: Relation2_def satisfies_is_b_def satisfies_b_def) apply (auto del: iffI intro!: lambda_abs2 simp add: Relation1_def) done lemma (in M_satisfies) c_closed: "\M(A); x \ formula; y \ formula; M(rx); M(ry)\ \ M(satisfies_c(A,x,y,rx,ry))" apply (simp add: satisfies_c_def) apply (rule lam_closed2) apply (rule Nand_replacement') apply (simp_all add: formula_into_M list_into_M [of _ A]) done lemma (in M_satisfies) c_rel: "\M(A); M(f)\ \ Relation2 (M, formula, formula, satisfies_is_c(M,A,f), \u v. satisfies_c(A, u, v, f ` succ(depth(u)) ` u, f ` succ(depth(v)) ` v))" apply (simp add: Relation2_def satisfies_is_c_def satisfies_c_def) apply (auto del: iffI intro!: lambda_abs2 simp add: Relation1_def formula_into_M) done lemma (in M_satisfies) d_closed: "\M(A); x \ formula; M(rx)\ \ M(satisfies_d(A,x,rx))" apply (simp add: satisfies_d_def) apply (rule lam_closed2) apply (rule Forall_replacement') apply (simp_all add: formula_into_M list_into_M [of _ A]) done lemma (in M_satisfies) d_rel: "\M(A); M(f)\ \ Relation1(M, formula, satisfies_is_d(M,A,f), \u. satisfies_d(A, u, f ` succ(depth(u)) ` u))" apply (simp del: rall_abs add: Relation1_def satisfies_is_d_def satisfies_d_def) apply (auto del: iffI intro!: lambda_abs2 simp add: Relation1_def) done lemma (in M_satisfies) fr_replace: "\n \ nat; M(A)\ \ transrec_replacement(M,satisfies_MH(M,A),n)" by (blast intro: formula_rec_replacement) lemma (in M_satisfies) formula_case_satisfies_closed: "\M(g); M(A); x \ formula\ \ M(formula_case (satisfies_a(A), satisfies_b(A), \u v. satisfies_c(A, u, v, g ` succ(depth(u)) ` u, g ` succ(depth(v)) ` v), \u. satisfies_d (A, u, g ` succ(depth(u)) ` u), x))" by (blast intro: a_closed b_closed c_closed d_closed) lemma (in M_satisfies) fr_lam_replace: "\M(g); M(A)\ \ strong_replacement (M, \x y. x \ formula \ y = \x, formula_rec_case(satisfies_a(A), satisfies_b(A), satisfies_c(A), satisfies_d(A), g, x)\)" apply (insert formula_rec_lambda_replacement) apply (simp add: formula_rec_case_def formula_case_satisfies_closed formula_case_abs [OF a_rel b_rel c_rel d_rel]) done text\Instantiate locale \Formula_Rec\ for the Function \<^term>\satisfies\\ lemma (in M_satisfies) Formula_Rec_axioms_M: "M(A) \ Formula_Rec_axioms(M, satisfies_a(A), satisfies_is_a(M,A), satisfies_b(A), satisfies_is_b(M,A), satisfies_c(A), satisfies_is_c(M,A), satisfies_d(A), satisfies_is_d(M,A))" apply (rule Formula_Rec_axioms.intro) apply (assumption | rule a_closed a_rel b_closed b_rel c_closed c_rel d_closed d_rel fr_replace [unfolded satisfies_MH_def] fr_lam_replace) + done theorem (in M_satisfies) Formula_Rec_M: "M(A) \ Formula_Rec(M, satisfies_a(A), satisfies_is_a(M,A), satisfies_b(A), satisfies_is_b(M,A), satisfies_c(A), satisfies_is_c(M,A), satisfies_d(A), satisfies_is_d(M,A))" apply (rule Formula_Rec.intro) apply (rule M_satisfies.axioms, rule M_satisfies_axioms) apply (erule Formula_Rec_axioms_M) done lemmas (in M_satisfies) satisfies_closed' = Formula_Rec.formula_rec_closed [OF Formula_Rec_M] and satisfies_abs' = Formula_Rec.formula_rec_abs [OF Formula_Rec_M] lemma (in M_satisfies) satisfies_closed: "\M(A); p \ formula\ \ M(satisfies(A,p))" by (simp add: Formula_Rec.formula_rec_closed [OF Formula_Rec_M] satisfies_eq) lemma (in M_satisfies) satisfies_abs: "\M(A); M(z); p \ formula\ \ is_satisfies(M,A,p,z) \ z = satisfies(A,p)" by (simp only: Formula_Rec.formula_rec_abs [OF Formula_Rec_M] satisfies_eq is_satisfies_def satisfies_MH_def) subsection\Internalizations Needed to Instantiate \M_satisfies\\ subsubsection\The Operator \<^term>\is_depth_apply\, Internalized\ (* is_depth_apply(M,h,p,z) \ \dp[M]. \sdp[M]. \hsdp[M]. 2 1 0 finite_ordinal(M,dp) \ is_depth(M,p,dp) \ successor(M,dp,sdp) \ fun_apply(M,h,sdp,hsdp) \ fun_apply(M,hsdp,p,z) *) definition depth_apply_fm :: "[i,i,i]\i" where "depth_apply_fm(h,p,z) \ Exists(Exists(Exists( And(finite_ordinal_fm(2), And(depth_fm(p#+3,2), And(succ_fm(2,1), And(fun_apply_fm(h#+3,1,0), fun_apply_fm(0,p#+3,z#+3))))))))" lemma depth_apply_type [TC]: "\x \ nat; y \ nat; z \ nat\ \ depth_apply_fm(x,y,z) \ formula" by (simp add: depth_apply_fm_def) lemma sats_depth_apply_fm [simp]: "\x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, depth_apply_fm(x,y,z), env) \ is_depth_apply(##A, nth(x,env), nth(y,env), nth(z,env))" by (simp add: depth_apply_fm_def is_depth_apply_def) lemma depth_apply_iff_sats: "\nth(i,env) = x; nth(j,env) = y; nth(k,env) = z; i \ nat; j \ nat; k \ nat; env \ list(A)\ \ is_depth_apply(##A, x, y, z) \ sats(A, depth_apply_fm(i,j,k), env)" by simp lemma depth_apply_reflection: "REFLECTS[\x. is_depth_apply(L,f(x),g(x),h(x)), \i x. is_depth_apply(##Lset(i),f(x),g(x),h(x))]" apply (simp only: is_depth_apply_def) apply (intro FOL_reflections function_reflections depth_reflection finite_ordinal_reflection) done subsubsection\The Operator \<^term>\satisfies_is_a\, Internalized\ (* satisfies_is_a(M,A) \ \x y zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. is_bool_of_o(M, \nx[M]. \ny[M]. is_nth(M,x,env,nx) \ is_nth(M,y,env,ny) \ nx \ ny, z), zz) *) definition satisfies_is_a_fm :: "[i,i,i,i]\i" where "satisfies_is_a_fm(A,x,y,z) \ Forall( Implies(is_list_fm(succ(A),0), lambda_fm( bool_of_o_fm(Exists( Exists(And(nth_fm(x#+6,3,1), And(nth_fm(y#+6,3,0), Member(1,0))))), 0), 0, succ(z))))" lemma satisfies_is_a_type [TC]: "\A \ nat; x \ nat; y \ nat; z \ nat\ \ satisfies_is_a_fm(A,x,y,z) \ formula" by (simp add: satisfies_is_a_fm_def) lemma sats_satisfies_is_a_fm [simp]: "\u \ nat; x < length(env); y < length(env); z \ nat; env \ list(A)\ \ sats(A, satisfies_is_a_fm(u,x,y,z), env) \ satisfies_is_a(##A, nth(u,env), nth(x,env), nth(y,env), nth(z,env))" apply (frule_tac x=x in lt_length_in_nat, assumption) apply (frule_tac x=y in lt_length_in_nat, assumption) apply (simp add: satisfies_is_a_fm_def satisfies_is_a_def sats_lambda_fm sats_bool_of_o_fm) done lemma satisfies_is_a_iff_sats: "\nth(u,env) = nu; nth(x,env) = nx; nth(y,env) = ny; nth(z,env) = nz; u \ nat; x < length(env); y < length(env); z \ nat; env \ list(A)\ \ satisfies_is_a(##A,nu,nx,ny,nz) \ sats(A, satisfies_is_a_fm(u,x,y,z), env)" by simp theorem satisfies_is_a_reflection: "REFLECTS[\x. satisfies_is_a(L,f(x),g(x),h(x),g'(x)), \i x. satisfies_is_a(##Lset(i),f(x),g(x),h(x),g'(x))]" -apply (unfold satisfies_is_a_def) + unfolding satisfies_is_a_def apply (intro FOL_reflections is_lambda_reflection bool_of_o_reflection nth_reflection is_list_reflection) done subsubsection\The Operator \<^term>\satisfies_is_b\, Internalized\ (* satisfies_is_b(M,A) \ \x y zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. is_bool_of_o(M, \nx[M]. is_nth(M,x,env,nx) \ is_nth(M,y,env,nx), z), zz) *) definition satisfies_is_b_fm :: "[i,i,i,i]\i" where "satisfies_is_b_fm(A,x,y,z) \ Forall( Implies(is_list_fm(succ(A),0), lambda_fm( bool_of_o_fm(Exists(And(nth_fm(x#+5,2,0), nth_fm(y#+5,2,0))), 0), 0, succ(z))))" lemma satisfies_is_b_type [TC]: "\A \ nat; x \ nat; y \ nat; z \ nat\ \ satisfies_is_b_fm(A,x,y,z) \ formula" by (simp add: satisfies_is_b_fm_def) lemma sats_satisfies_is_b_fm [simp]: "\u \ nat; x < length(env); y < length(env); z \ nat; env \ list(A)\ \ sats(A, satisfies_is_b_fm(u,x,y,z), env) \ satisfies_is_b(##A, nth(u,env), nth(x,env), nth(y,env), nth(z,env))" apply (frule_tac x=x in lt_length_in_nat, assumption) apply (frule_tac x=y in lt_length_in_nat, assumption) apply (simp add: satisfies_is_b_fm_def satisfies_is_b_def sats_lambda_fm sats_bool_of_o_fm) done lemma satisfies_is_b_iff_sats: "\nth(u,env) = nu; nth(x,env) = nx; nth(y,env) = ny; nth(z,env) = nz; u \ nat; x < length(env); y < length(env); z \ nat; env \ list(A)\ \ satisfies_is_b(##A,nu,nx,ny,nz) \ sats(A, satisfies_is_b_fm(u,x,y,z), env)" by simp theorem satisfies_is_b_reflection: "REFLECTS[\x. satisfies_is_b(L,f(x),g(x),h(x),g'(x)), \i x. satisfies_is_b(##Lset(i),f(x),g(x),h(x),g'(x))]" -apply (unfold satisfies_is_b_def) + unfolding satisfies_is_b_def apply (intro FOL_reflections is_lambda_reflection bool_of_o_reflection nth_reflection is_list_reflection) done subsubsection\The Operator \<^term>\satisfies_is_c\, Internalized\ (* satisfies_is_c(M,A,h) \ \p q zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. \hp[M]. \hq[M]. (\rp[M]. is_depth_apply(M,h,p,rp) \ fun_apply(M,rp,env,hp)) \ (\rq[M]. is_depth_apply(M,h,q,rq) \ fun_apply(M,rq,env,hq)) \ (\pq[M]. is_and(M,hp,hq,pq) \ is_not(M,pq,z)), zz) *) definition satisfies_is_c_fm :: "[i,i,i,i,i]\i" where "satisfies_is_c_fm(A,h,p,q,zz) \ Forall( Implies(is_list_fm(succ(A),0), lambda_fm( Exists(Exists( And(Exists(And(depth_apply_fm(h#+7,p#+7,0), fun_apply_fm(0,4,2))), And(Exists(And(depth_apply_fm(h#+7,q#+7,0), fun_apply_fm(0,4,1))), Exists(And(and_fm(2,1,0), not_fm(0,3))))))), 0, succ(zz))))" lemma satisfies_is_c_type [TC]: "\A \ nat; h \ nat; x \ nat; y \ nat; z \ nat\ \ satisfies_is_c_fm(A,h,x,y,z) \ formula" by (simp add: satisfies_is_c_fm_def) lemma sats_satisfies_is_c_fm [simp]: "\u \ nat; v \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, satisfies_is_c_fm(u,v,x,y,z), env) \ satisfies_is_c(##A, nth(u,env), nth(v,env), nth(x,env), nth(y,env), nth(z,env))" by (simp add: satisfies_is_c_fm_def satisfies_is_c_def sats_lambda_fm) lemma satisfies_is_c_iff_sats: "\nth(u,env) = nu; nth(v,env) = nv; nth(x,env) = nx; nth(y,env) = ny; nth(z,env) = nz; u \ nat; v \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ satisfies_is_c(##A,nu,nv,nx,ny,nz) \ sats(A, satisfies_is_c_fm(u,v,x,y,z), env)" by simp theorem satisfies_is_c_reflection: "REFLECTS[\x. satisfies_is_c(L,f(x),g(x),h(x),g'(x),h'(x)), \i x. satisfies_is_c(##Lset(i),f(x),g(x),h(x),g'(x),h'(x))]" -apply (unfold satisfies_is_c_def) + unfolding satisfies_is_c_def apply (intro FOL_reflections function_reflections is_lambda_reflection extra_reflections nth_reflection depth_apply_reflection is_list_reflection) done subsubsection\The Operator \<^term>\satisfies_is_d\, Internalized\ (* satisfies_is_d(M,A,h) \ \p zz. \lA[M]. is_list(M,A,lA) \ is_lambda(M, lA, \env z. \rp[M]. is_depth_apply(M,h,p,rp) \ is_bool_of_o(M, \x[M]. \xenv[M]. \hp[M]. x\A \ is_Cons(M,x,env,xenv) \ fun_apply(M,rp,xenv,hp) \ number1(M,hp), z), zz) *) definition satisfies_is_d_fm :: "[i,i,i,i]\i" where "satisfies_is_d_fm(A,h,p,zz) \ Forall( Implies(is_list_fm(succ(A),0), lambda_fm( Exists( And(depth_apply_fm(h#+5,p#+5,0), bool_of_o_fm( Forall(Forall(Forall( Implies(Member(2,A#+8), Implies(Cons_fm(2,5,1), Implies(fun_apply_fm(3,1,0), number1_fm(0))))))), 1))), 0, succ(zz))))" lemma satisfies_is_d_type [TC]: "\A \ nat; h \ nat; x \ nat; z \ nat\ \ satisfies_is_d_fm(A,h,x,z) \ formula" by (simp add: satisfies_is_d_fm_def) lemma sats_satisfies_is_d_fm [simp]: "\u \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, satisfies_is_d_fm(u,x,y,z), env) \ satisfies_is_d(##A, nth(u,env), nth(x,env), nth(y,env), nth(z,env))" by (simp add: satisfies_is_d_fm_def satisfies_is_d_def sats_lambda_fm sats_bool_of_o_fm) lemma satisfies_is_d_iff_sats: "\nth(u,env) = nu; nth(x,env) = nx; nth(y,env) = ny; nth(z,env) = nz; u \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ satisfies_is_d(##A,nu,nx,ny,nz) \ sats(A, satisfies_is_d_fm(u,x,y,z), env)" by simp theorem satisfies_is_d_reflection: "REFLECTS[\x. satisfies_is_d(L,f(x),g(x),h(x),g'(x)), \i x. satisfies_is_d(##Lset(i),f(x),g(x),h(x),g'(x))]" -apply (unfold satisfies_is_d_def) + unfolding satisfies_is_d_def apply (intro FOL_reflections function_reflections is_lambda_reflection extra_reflections nth_reflection depth_apply_reflection is_list_reflection) done subsubsection\The Operator \<^term>\satisfies_MH\, Internalized\ (* satisfies_MH \ \M A u f zz. \fml[M]. is_formula(M,fml) \ is_lambda (M, fml, is_formula_case (M, satisfies_is_a(M,A), satisfies_is_b(M,A), satisfies_is_c(M,A,f), satisfies_is_d(M,A,f)), zz) *) definition satisfies_MH_fm :: "[i,i,i,i]\i" where "satisfies_MH_fm(A,u,f,zz) \ Forall( Implies(is_formula_fm(0), lambda_fm( formula_case_fm(satisfies_is_a_fm(A#+7,2,1,0), satisfies_is_b_fm(A#+7,2,1,0), satisfies_is_c_fm(A#+7,f#+7,2,1,0), satisfies_is_d_fm(A#+6,f#+6,1,0), 1, 0), 0, succ(zz))))" lemma satisfies_MH_type [TC]: "\A \ nat; u \ nat; x \ nat; z \ nat\ \ satisfies_MH_fm(A,u,x,z) \ formula" by (simp add: satisfies_MH_fm_def) lemma sats_satisfies_MH_fm [simp]: "\u \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ sats(A, satisfies_MH_fm(u,x,y,z), env) \ satisfies_MH(##A, nth(u,env), nth(x,env), nth(y,env), nth(z,env))" by (simp add: satisfies_MH_fm_def satisfies_MH_def sats_lambda_fm sats_formula_case_fm) lemma satisfies_MH_iff_sats: "\nth(u,env) = nu; nth(x,env) = nx; nth(y,env) = ny; nth(z,env) = nz; u \ nat; x \ nat; y \ nat; z \ nat; env \ list(A)\ \ satisfies_MH(##A,nu,nx,ny,nz) \ sats(A, satisfies_MH_fm(u,x,y,z), env)" by simp lemmas satisfies_reflections = is_lambda_reflection is_formula_reflection is_formula_case_reflection satisfies_is_a_reflection satisfies_is_b_reflection satisfies_is_c_reflection satisfies_is_d_reflection theorem satisfies_MH_reflection: "REFLECTS[\x. satisfies_MH(L,f(x),g(x),h(x),g'(x)), \i x. satisfies_MH(##Lset(i),f(x),g(x),h(x),g'(x))]" -apply (unfold satisfies_MH_def) + unfolding satisfies_MH_def apply (intro FOL_reflections satisfies_reflections) done subsection\Lemmas for Instantiating the Locale \M_satisfies\\ subsubsection\The \<^term>\Member\ Case\ lemma Member_Reflects: "REFLECTS[\u. \v[L]. v \ B \ (\bo[L]. \nx[L]. \ny[L]. v \ lstA \ is_nth(L,x,v,nx) \ is_nth(L,y,v,ny) \ is_bool_of_o(L, nx \ ny, bo) \ pair(L,v,bo,u)), \i u. \v \ Lset(i). v \ B \ (\bo \ Lset(i). \nx \ Lset(i). \ny \ Lset(i). v \ lstA \ is_nth(##Lset(i), x, v, nx) \ is_nth(##Lset(i), y, v, ny) \ is_bool_of_o(##Lset(i), nx \ ny, bo) \ pair(##Lset(i), v, bo, u))]" by (intro FOL_reflections function_reflections nth_reflection bool_of_o_reflection) lemma Member_replacement: "\L(A); x \ nat; y \ nat\ \ strong_replacement (L, \env z. \bo[L]. \nx[L]. \ny[L]. env \ list(A) \ is_nth(L,x,env,nx) \ is_nth(L,y,env,ny) \ is_bool_of_o(L, nx \ ny, bo) \ pair(L, env, bo, z))" apply (rule strong_replacementI) apply (rule_tac u="{list(A),B,x,y}" in gen_separation_multi [OF Member_Reflects], auto) apply (rule_tac env="[list(A),B,x,y]" in DPow_LsetI) apply (rule sep_rules nth_iff_sats is_bool_of_o_iff_sats | simp)+ done subsubsection\The \<^term>\Equal\ Case\ lemma Equal_Reflects: "REFLECTS[\u. \v[L]. v \ B \ (\bo[L]. \nx[L]. \ny[L]. v \ lstA \ is_nth(L, x, v, nx) \ is_nth(L, y, v, ny) \ is_bool_of_o(L, nx = ny, bo) \ pair(L, v, bo, u)), \i u. \v \ Lset(i). v \ B \ (\bo \ Lset(i). \nx \ Lset(i). \ny \ Lset(i). v \ lstA \ is_nth(##Lset(i), x, v, nx) \ is_nth(##Lset(i), y, v, ny) \ is_bool_of_o(##Lset(i), nx = ny, bo) \ pair(##Lset(i), v, bo, u))]" by (intro FOL_reflections function_reflections nth_reflection bool_of_o_reflection) lemma Equal_replacement: "\L(A); x \ nat; y \ nat\ \ strong_replacement (L, \env z. \bo[L]. \nx[L]. \ny[L]. env \ list(A) \ is_nth(L,x,env,nx) \ is_nth(L,y,env,ny) \ is_bool_of_o(L, nx = ny, bo) \ pair(L, env, bo, z))" apply (rule strong_replacementI) apply (rule_tac u="{list(A),B,x,y}" in gen_separation_multi [OF Equal_Reflects], auto) apply (rule_tac env="[list(A),B,x,y]" in DPow_LsetI) apply (rule sep_rules nth_iff_sats is_bool_of_o_iff_sats | simp)+ done subsubsection\The \<^term>\Nand\ Case\ lemma Nand_Reflects: "REFLECTS [\x. \u[L]. u \ B \ (\rpe[L]. \rqe[L]. \andpq[L]. \notpq[L]. fun_apply(L, rp, u, rpe) \ fun_apply(L, rq, u, rqe) \ is_and(L, rpe, rqe, andpq) \ is_not(L, andpq, notpq) \ u \ list(A) \ pair(L, u, notpq, x)), \i x. \u \ Lset(i). u \ B \ (\rpe \ Lset(i). \rqe \ Lset(i). \andpq \ Lset(i). \notpq \ Lset(i). fun_apply(##Lset(i), rp, u, rpe) \ fun_apply(##Lset(i), rq, u, rqe) \ is_and(##Lset(i), rpe, rqe, andpq) \ is_not(##Lset(i), andpq, notpq) \ u \ list(A) \ pair(##Lset(i), u, notpq, x))]" apply (unfold is_and_def is_not_def) apply (intro FOL_reflections function_reflections) done lemma Nand_replacement: "\L(A); L(rp); L(rq)\ \ strong_replacement (L, \env z. \rpe[L]. \rqe[L]. \andpq[L]. \notpq[L]. fun_apply(L,rp,env,rpe) \ fun_apply(L,rq,env,rqe) \ is_and(L,rpe,rqe,andpq) \ is_not(L,andpq,notpq) \ env \ list(A) \ pair(L, env, notpq, z))" apply (rule strong_replacementI) apply (rule_tac u="{list(A),B,rp,rq}" in gen_separation_multi [OF Nand_Reflects], auto) apply (rule_tac env="[list(A),B,rp,rq]" in DPow_LsetI) apply (rule sep_rules is_and_iff_sats is_not_iff_sats | simp)+ done subsubsection\The \<^term>\Forall\ Case\ lemma Forall_Reflects: "REFLECTS [\x. \u[L]. u \ B \ (\bo[L]. u \ list(A) \ is_bool_of_o (L, \a[L]. \co[L]. \rpco[L]. a \ A \ is_Cons(L,a,u,co) \ fun_apply(L,rp,co,rpco) \ number1(L,rpco), bo) \ pair(L,u,bo,x)), \i x. \u \ Lset(i). u \ B \ (\bo \ Lset(i). u \ list(A) \ is_bool_of_o (##Lset(i), \a \ Lset(i). \co \ Lset(i). \rpco \ Lset(i). a \ A \ is_Cons(##Lset(i),a,u,co) \ fun_apply(##Lset(i),rp,co,rpco) \ number1(##Lset(i),rpco), bo) \ pair(##Lset(i),u,bo,x))]" -apply (unfold is_bool_of_o_def) + unfolding is_bool_of_o_def apply (intro FOL_reflections function_reflections Cons_reflection) done lemma Forall_replacement: "\L(A); L(rp)\ \ strong_replacement (L, \env z. \bo[L]. env \ list(A) \ is_bool_of_o (L, \a[L]. \co[L]. \rpco[L]. a\A \ is_Cons(L,a,env,co) \ fun_apply(L,rp,co,rpco) \ number1(L, rpco), bo) \ pair(L,env,bo,z))" apply (rule strong_replacementI) apply (rule_tac u="{A,list(A),B,rp}" in gen_separation_multi [OF Forall_Reflects], auto) apply (rule_tac env="[A,list(A),B,rp]" in DPow_LsetI) apply (rule sep_rules is_bool_of_o_iff_sats Cons_iff_sats | simp)+ done subsubsection\The \<^term>\transrec_replacement\ Case\ lemma formula_rec_replacement_Reflects: "REFLECTS [\x. \u[L]. u \ B \ (\y[L]. pair(L, u, y, x) \ is_wfrec (L, satisfies_MH(L,A), mesa, u, y)), \i x. \u \ Lset(i). u \ B \ (\y \ Lset(i). pair(##Lset(i), u, y, x) \ is_wfrec (##Lset(i), satisfies_MH(##Lset(i),A), mesa, u, y))]" by (intro FOL_reflections function_reflections satisfies_MH_reflection is_wfrec_reflection) lemma formula_rec_replacement: \ \For the \<^term>\transrec\\ "\n \ nat; L(A)\ \ transrec_replacement(L, satisfies_MH(L,A), n)" apply (rule L.transrec_replacementI, simp add: L.nat_into_M) apply (rule strong_replacementI) apply (rule_tac u="{B,A,n,Memrel(eclose({n}))}" in gen_separation_multi [OF formula_rec_replacement_Reflects], auto simp add: L.nat_into_M) apply (rule_tac env="[B,A,n,Memrel(eclose({n}))]" in DPow_LsetI) apply (rule sep_rules satisfies_MH_iff_sats is_wfrec_iff_sats | simp)+ done subsubsection\The Lambda Replacement Case\ lemma formula_rec_lambda_replacement_Reflects: "REFLECTS [\x. \u[L]. u \ B \ mem_formula(L,u) \ (\c[L]. is_formula_case (L, satisfies_is_a(L,A), satisfies_is_b(L,A), satisfies_is_c(L,A,g), satisfies_is_d(L,A,g), u, c) \ pair(L,u,c,x)), \i x. \u \ Lset(i). u \ B \ mem_formula(##Lset(i),u) \ (\c \ Lset(i). is_formula_case (##Lset(i), satisfies_is_a(##Lset(i),A), satisfies_is_b(##Lset(i),A), satisfies_is_c(##Lset(i),A,g), satisfies_is_d(##Lset(i),A,g), u, c) \ pair(##Lset(i),u,c,x))]" by (intro FOL_reflections function_reflections mem_formula_reflection is_formula_case_reflection satisfies_is_a_reflection satisfies_is_b_reflection satisfies_is_c_reflection satisfies_is_d_reflection) lemma formula_rec_lambda_replacement: \ \For the \<^term>\transrec\\ "\L(g); L(A)\ \ strong_replacement (L, \x y. mem_formula(L,x) \ (\c[L]. is_formula_case(L, satisfies_is_a(L,A), satisfies_is_b(L,A), satisfies_is_c(L,A,g), satisfies_is_d(L,A,g), x, c) \ pair(L, x, c, y)))" apply (rule strong_replacementI) apply (rule_tac u="{B,A,g}" in gen_separation_multi [OF formula_rec_lambda_replacement_Reflects], auto) apply (rule_tac env="[A,g,B]" in DPow_LsetI) apply (rule sep_rules mem_formula_iff_sats formula_case_iff_sats satisfies_is_a_iff_sats satisfies_is_b_iff_sats satisfies_is_c_iff_sats satisfies_is_d_iff_sats | simp)+ done subsection\Instantiating \M_satisfies\\ lemma M_satisfies_axioms_L: "M_satisfies_axioms(L)" apply (rule M_satisfies_axioms.intro) apply (assumption | rule Member_replacement Equal_replacement Nand_replacement Forall_replacement formula_rec_replacement formula_rec_lambda_replacement)+ done theorem M_satisfies_L: "M_satisfies(L)" apply (rule M_satisfies.intro) apply (rule M_eclose_L) apply (rule M_satisfies_axioms_L) done text\Finally: the point of the whole theory!\ lemmas satisfies_closed = M_satisfies.satisfies_closed [OF M_satisfies_L] and satisfies_abs = M_satisfies.satisfies_abs [OF M_satisfies_L] end diff --git a/src/ZF/Constructible/Wellorderings.thy b/src/ZF/Constructible/Wellorderings.thy --- a/src/ZF/Constructible/Wellorderings.thy +++ b/src/ZF/Constructible/Wellorderings.thy @@ -1,233 +1,233 @@ (* Title: ZF/Constructible/Wellorderings.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory *) section \Relativized Wellorderings\ theory Wellorderings imports Relative begin text\We define functions analogous to \<^term>\ordermap\ \<^term>\ordertype\ but without using recursion. Instead, there is a direct appeal to Replacement. This will be the basis for a version relativized to some class \M\. The main result is Theorem I 7.6 in Kunen, page 17.\ subsection\Wellorderings\ definition irreflexive :: "[i\o,i,i]\o" where "irreflexive(M,A,r) \ \x[M]. x\A \ \x,x\ \ r" definition transitive_rel :: "[i\o,i,i]\o" where "transitive_rel(M,A,r) \ \x[M]. x\A \ (\y[M]. y\A \ (\z[M]. z\A \ \x,y\\r \ \y,z\\r \ \x,z\\r))" definition linear_rel :: "[i\o,i,i]\o" where "linear_rel(M,A,r) \ \x[M]. x\A \ (\y[M]. y\A \ \x,y\\r | x=y | \y,x\\r)" definition wellfounded :: "[i\o,i]\o" where \ \EVERY non-empty set has an \r\-minimal element\ "wellfounded(M,r) \ \x[M]. x\0 \ (\y[M]. y\x \ \(\z[M]. z\x \ \z,y\ \ r))" definition wellfounded_on :: "[i\o,i,i]\o" where \ \every non-empty SUBSET OF \A\ has an \r\-minimal element\ "wellfounded_on(M,A,r) \ \x[M]. x\0 \ x\A \ (\y[M]. y\x \ \(\z[M]. z\x \ \z,y\ \ r))" definition wellordered :: "[i\o,i,i]\o" where \ \linear and wellfounded on \A\\ "wellordered(M,A,r) \ transitive_rel(M,A,r) \ linear_rel(M,A,r) \ wellfounded_on(M,A,r)" subsubsection \Trivial absoluteness proofs\ lemma (in M_basic) irreflexive_abs [simp]: "M(A) \ irreflexive(M,A,r) \ irrefl(A,r)" by (simp add: irreflexive_def irrefl_def) lemma (in M_basic) transitive_rel_abs [simp]: "M(A) \ transitive_rel(M,A,r) \ trans[A](r)" by (simp add: transitive_rel_def trans_on_def) lemma (in M_basic) linear_rel_abs [simp]: "M(A) \ linear_rel(M,A,r) \ linear(A,r)" by (simp add: linear_rel_def linear_def) lemma (in M_basic) wellordered_is_trans_on: "\wellordered(M,A,r); M(A)\ \ trans[A](r)" by (auto simp add: wellordered_def) lemma (in M_basic) wellordered_is_linear: "\wellordered(M,A,r); M(A)\ \ linear(A,r)" by (auto simp add: wellordered_def) lemma (in M_basic) wellordered_is_wellfounded_on: "\wellordered(M,A,r); M(A)\ \ wellfounded_on(M,A,r)" by (auto simp add: wellordered_def) lemma (in M_basic) wellfounded_imp_wellfounded_on: "\wellfounded(M,r); M(A)\ \ wellfounded_on(M,A,r)" by (auto simp add: wellfounded_def wellfounded_on_def) lemma (in M_basic) wellfounded_on_subset_A: "\wellfounded_on(M,A,r); B<=A\ \ wellfounded_on(M,B,r)" by (simp add: wellfounded_on_def, blast) subsubsection \Well-founded relations\ lemma (in M_basic) wellfounded_on_iff_wellfounded: "wellfounded_on(M,A,r) \ wellfounded(M, r \ A*A)" apply (simp add: wellfounded_on_def wellfounded_def, safe) apply force apply (drule_tac x=x in rspec, assumption, blast) done lemma (in M_basic) wellfounded_on_imp_wellfounded: "\wellfounded_on(M,A,r); r \ A*A\ \ wellfounded(M,r)" by (simp add: wellfounded_on_iff_wellfounded subset_Int_iff) lemma (in M_basic) wellfounded_on_field_imp_wellfounded: "wellfounded_on(M, field(r), r) \ wellfounded(M,r)" by (simp add: wellfounded_def wellfounded_on_iff_wellfounded, fast) lemma (in M_basic) wellfounded_iff_wellfounded_on_field: "M(r) \ wellfounded(M,r) \ wellfounded_on(M, field(r), r)" by (blast intro: wellfounded_imp_wellfounded_on wellfounded_on_field_imp_wellfounded) (*Consider the least z in domain(r) such that P(z) does not hold...*) lemma (in M_basic) wellfounded_induct: "\wellfounded(M,r); M(a); M(r); separation(M, \x. \P(x)); \x. M(x) \ (\y. \y,x\ \ r \ P(y)) \ P(x)\ \ P(a)" apply (simp (no_asm_use) add: wellfounded_def) apply (drule_tac x="{z \ domain(r). \P(z)}" in rspec) apply (blast dest: transM)+ done lemma (in M_basic) wellfounded_on_induct: "\a\A; wellfounded_on(M,A,r); M(A); separation(M, \x. x\A \ \P(x)); \x\A. M(x) \ (\y\A. \y,x\ \ r \ P(y)) \ P(x)\ \ P(a)" apply (simp (no_asm_use) add: wellfounded_on_def) apply (drule_tac x="{z\A. z\A \ \P(z)}" in rspec) apply (blast intro: transM)+ done subsubsection \Kunen's lemma IV 3.14, page 123\ lemma (in M_basic) linear_imp_relativized: "linear(A,r) \ linear_rel(M,A,r)" by (simp add: linear_def linear_rel_def) lemma (in M_basic) trans_on_imp_relativized: "trans[A](r) \ transitive_rel(M,A,r)" by (unfold transitive_rel_def trans_on_def, blast) lemma (in M_basic) wf_on_imp_relativized: "wf[A](r) \ wellfounded_on(M,A,r)" apply (clarsimp simp: wellfounded_on_def wf_def wf_on_def) apply (drule_tac x=x in spec, blast) done lemma (in M_basic) wf_imp_relativized: "wf(r) \ wellfounded(M,r)" apply (simp add: wellfounded_def wf_def, clarify) apply (drule_tac x=x in spec, blast) done lemma (in M_basic) well_ord_imp_relativized: "well_ord(A,r) \ wellordered(M,A,r)" by (simp add: wellordered_def well_ord_def tot_ord_def part_ord_def linear_imp_relativized trans_on_imp_relativized wf_on_imp_relativized) text\The property being well founded (and hence of being well ordered) is not absolute: the set that doesn't contain a minimal element may not exist in the class M. However, every set that is well founded in a transitive model M is well founded (page 124).\ subsection\Relativized versions of order-isomorphisms and order types\ lemma (in M_basic) order_isomorphism_abs [simp]: "\M(A); M(B); M(f)\ \ order_isomorphism(M,A,r,B,s,f) \ f \ ord_iso(A,r,B,s)" by (simp add: order_isomorphism_def ord_iso_def) lemma (in M_trans) pred_set_abs [simp]: "\M(r); M(B)\ \ pred_set(M,A,x,r,B) \ B = Order.pred(A,x,r)" apply (simp add: pred_set_def Order.pred_def) apply (blast dest: transM) done lemma (in M_basic) pred_closed [intro,simp]: "\M(A); M(r); M(x)\ \ M(Order.pred(A, x, r))" using pred_separation [of r x] by (simp add: Order.pred_def) lemma (in M_basic) membership_abs [simp]: "\M(r); M(A)\ \ membership(M,A,r) \ r = Memrel(A)" apply (simp add: membership_def Memrel_def, safe) apply (rule equalityI) apply clarify apply (frule transM, assumption) apply blast apply clarify apply (subgoal_tac "M(\xb,ya\)", blast) apply (blast dest: transM) apply auto done lemma (in M_basic) M_Memrel_iff: "M(A) \ Memrel(A) = {z \ A*A. \x[M]. \y[M]. z = \x,y\ \ x \ y}" unfolding Memrel_def by (blast dest: transM) lemma (in M_basic) Memrel_closed [intro,simp]: "M(A) \ M(Memrel(A))" using Memrel_separation by (simp add: M_Memrel_iff) subsection \Main results of Kunen, Chapter 1 section 6\ text\Subset properties-- proved outside the locale\ lemma linear_rel_subset: "\linear_rel(M, A, r); B \ A\ \ linear_rel(M, B, r)" by (unfold linear_rel_def, blast) lemma transitive_rel_subset: "\transitive_rel(M, A, r); B \ A\ \ transitive_rel(M, B, r)" by (unfold transitive_rel_def, blast) lemma wellfounded_on_subset: "\wellfounded_on(M, A, r); B \ A\ \ wellfounded_on(M, B, r)" by (unfold wellfounded_on_def subset_def, blast) lemma wellordered_subset: "\wellordered(M, A, r); B \ A\ \ wellordered(M, B, r)" -apply (unfold wellordered_def) + unfolding wellordered_def apply (blast intro: linear_rel_subset transitive_rel_subset wellfounded_on_subset) done lemma (in M_basic) wellfounded_on_asym: "\wellfounded_on(M,A,r); \a,x\\r; a\A; x\A; M(A)\ \ \x,a\\r" apply (simp add: wellfounded_on_def) apply (drule_tac x="{x,a}" in rspec) apply (blast dest: transM)+ done lemma (in M_basic) wellordered_asym: "\wellordered(M,A,r); \a,x\\r; a\A; x\A; M(A)\ \ \x,a\\r" by (simp add: wellordered_def, blast dest: wellfounded_on_asym) end diff --git a/src/ZF/Epsilon.thy b/src/ZF/Epsilon.thy --- a/src/ZF/Epsilon.thy +++ b/src/ZF/Epsilon.thy @@ -1,399 +1,399 @@ (* Title: ZF/Epsilon.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1993 University of Cambridge *) section\Epsilon Induction and Recursion\ theory Epsilon imports Nat begin definition eclose :: "i\i" where "eclose(A) \ \n\nat. nat_rec(n, A, \m r. \(r))" definition transrec :: "[i, [i,i]\i] \i" where "transrec(a,H) \ wfrec(Memrel(eclose({a})), a, H)" definition rank :: "i\i" where "rank(a) \ transrec(a, \x f. \y\x. succ(f`y))" definition transrec2 :: "[i, i, [i,i]\i] \i" where "transrec2(k, a, b) \ transrec(k, \i r. if(i=0, a, if(\j. i=succ(j), b(THE j. i=succ(j), r`(THE j. i=succ(j))), \ji, i]\i" where "recursor(a,b,k) \ transrec(k, \n f. nat_case(a, \m. b(m, f`m), n))" definition rec :: "[i, i, [i,i]\i]\i" where "rec(k,a,b) \ recursor(a,b,k)" subsection\Basic Closure Properties\ lemma arg_subset_eclose: "A \ eclose(A)" -apply (unfold eclose_def) + unfolding eclose_def apply (rule nat_rec_0 [THEN equalityD2, THEN subset_trans]) apply (rule nat_0I [THEN UN_upper]) done lemmas arg_into_eclose = arg_subset_eclose [THEN subsetD] lemma Transset_eclose: "Transset(eclose(A))" apply (unfold eclose_def Transset_def) apply (rule subsetI [THEN ballI]) apply (erule UN_E) apply (rule nat_succI [THEN UN_I], assumption) apply (erule nat_rec_succ [THEN ssubst]) apply (erule UnionI, assumption) done (* @{term"x \ eclose(A) \ x \ eclose(A)"} *) lemmas eclose_subset = Transset_eclose [unfolded Transset_def, THEN bspec] (* @{term"\A \ eclose(B); c \ A\ \ c \ eclose(B)"} *) lemmas ecloseD = eclose_subset [THEN subsetD] lemmas arg_in_eclose_sing = arg_subset_eclose [THEN singleton_subsetD] lemmas arg_into_eclose_sing = arg_in_eclose_sing [THEN ecloseD] (* This is epsilon-induction for eclose(A); see also eclose_induct_down... \a \ eclose(A); \x. \x \ eclose(A); \y\x. P(y)\ \ P(x) \ \ P(a) *) lemmas eclose_induct = Transset_induct [OF _ Transset_eclose, induct set: eclose] (*Epsilon induction*) lemma eps_induct: "\\x. \y\x. P(y) \ P(x)\ \ P(a)" by (rule arg_in_eclose_sing [THEN eclose_induct], blast) subsection\Leastness of \<^term>\eclose\\ (** eclose(A) is the least transitive set including A as a subset. **) lemma eclose_least_lemma: "\Transset(X); A<=X; n \ nat\ \ nat_rec(n, A, \m r. \(r)) \ X" -apply (unfold Transset_def) + unfolding Transset_def apply (erule nat_induct) apply (simp add: nat_rec_0) apply (simp add: nat_rec_succ, blast) done lemma eclose_least: "\Transset(X); A<=X\ \ eclose(A) \ X" -apply (unfold eclose_def) + unfolding eclose_def apply (rule eclose_least_lemma [THEN UN_least], assumption+) done (*COMPLETELY DIFFERENT induction principle from eclose_induct\*) lemma eclose_induct_down [consumes 1]: "\a \ eclose(b); \y. \y \ b\ \ P(y); \y z. \y \ eclose(b); P(y); z \ y\ \ P(z) \ \ P(a)" apply (rule eclose_least [THEN subsetD, THEN CollectD2, of "eclose(b)"]) prefer 3 apply assumption - apply (unfold Transset_def) + unfolding Transset_def apply (blast intro: ecloseD) apply (blast intro: arg_subset_eclose [THEN subsetD]) done lemma Transset_eclose_eq_arg: "Transset(X) \ eclose(X) = X" apply (erule equalityI [OF eclose_least arg_subset_eclose]) apply (rule subset_refl) done text\A transitive set either is empty or contains the empty set.\ lemma Transset_0_lemma [rule_format]: "Transset(A) \ x\A \ 0\A" apply (simp add: Transset_def) apply (rule_tac a=x in eps_induct, clarify) apply (drule bspec, assumption) apply (case_tac "x=0", auto) done lemma Transset_0_disj: "Transset(A) \ A=0 | 0\A" by (blast dest: Transset_0_lemma) subsection\Epsilon Recursion\ (*Unused...*) lemma mem_eclose_trans: "\A \ eclose(B); B \ eclose(C)\ \ A \ eclose(C)" by (rule eclose_least [OF Transset_eclose eclose_subset, THEN subsetD], assumption+) (*Variant of the previous lemma in a useable form for the sequel*) lemma mem_eclose_sing_trans: "\A \ eclose({B}); B \ eclose({C})\ \ A \ eclose({C})" by (rule eclose_least [OF Transset_eclose singleton_subsetI, THEN subsetD], assumption+) lemma under_Memrel: "\Transset(i); j \ i\ \ Memrel(i)-``{j} = j" by (unfold Transset_def, blast) lemma lt_Memrel: "j < i \ Memrel(i) -`` {j} = j" by (simp add: lt_def Ord_def under_Memrel) (* @{term"j \ eclose(A) \ Memrel(eclose(A)) -`` j = j"} *) lemmas under_Memrel_eclose = Transset_eclose [THEN under_Memrel] lemmas wfrec_ssubst = wf_Memrel [THEN wfrec, THEN ssubst] lemma wfrec_eclose_eq: "\k \ eclose({j}); j \ eclose({i})\ \ wfrec(Memrel(eclose({i})), k, H) = wfrec(Memrel(eclose({j})), k, H)" apply (erule eclose_induct) apply (rule wfrec_ssubst) apply (rule wfrec_ssubst) apply (simp add: under_Memrel_eclose mem_eclose_sing_trans [of _ j i]) done lemma wfrec_eclose_eq2: "k \ i \ wfrec(Memrel(eclose({i})),k,H) = wfrec(Memrel(eclose({k})),k,H)" apply (rule arg_in_eclose_sing [THEN wfrec_eclose_eq]) apply (erule arg_into_eclose_sing) done lemma transrec: "transrec(a,H) = H(a, \x\a. transrec(x,H))" -apply (unfold transrec_def) + unfolding transrec_def apply (rule wfrec_ssubst) apply (simp add: wfrec_eclose_eq2 arg_in_eclose_sing under_Memrel_eclose) done (*Avoids explosions in proofs; resolve it with a meta-level definition.*) lemma def_transrec: "\\x. f(x)\transrec(x,H)\ \ f(a) = H(a, \x\a. f(x))" apply simp apply (rule transrec) done lemma transrec_type: "\\x u. \x \ eclose({a}); u \ Pi(x,B)\ \ H(x,u) \ B(x)\ \ transrec(a,H) \ B(a)" apply (rule_tac i = a in arg_in_eclose_sing [THEN eclose_induct]) apply (subst transrec) apply (simp add: lam_type) done lemma eclose_sing_Ord: "Ord(i) \ eclose({i}) \ succ(i)" apply (erule Ord_is_Transset [THEN Transset_succ, THEN eclose_least]) apply (rule succI1 [THEN singleton_subsetI]) done lemma succ_subset_eclose_sing: "succ(i) \ eclose({i})" apply (insert arg_subset_eclose [of "{i}"], simp) apply (frule eclose_subset, blast) done lemma eclose_sing_Ord_eq: "Ord(i) \ eclose({i}) = succ(i)" apply (rule equalityI) apply (erule eclose_sing_Ord) apply (rule succ_subset_eclose_sing) done lemma Ord_transrec_type: assumes jini: "j \ i" and ordi: "Ord(i)" and minor: " \x u. \x \ i; u \ Pi(x,B)\ \ H(x,u) \ B(x)" shows "transrec(j,H) \ B(j)" apply (rule transrec_type) apply (insert jini ordi) apply (blast intro!: minor intro: Ord_trans dest: Ord_in_Ord [THEN eclose_sing_Ord, THEN subsetD]) done subsection\Rank\ (*NOT SUITABLE FOR REWRITING -- RECURSIVE!*) lemma rank: "rank(a) = (\y\a. succ(rank(y)))" by (subst rank_def [THEN def_transrec], simp) lemma Ord_rank [simp]: "Ord(rank(a))" apply (rule_tac a=a in eps_induct) apply (subst rank) apply (rule Ord_succ [THEN Ord_UN]) apply (erule bspec, assumption) done lemma rank_of_Ord: "Ord(i) \ rank(i) = i" apply (erule trans_induct) apply (subst rank) apply (simp add: Ord_equality) done lemma rank_lt: "a \ b \ rank(a) < rank(b)" apply (rule_tac a1 = b in rank [THEN ssubst]) apply (erule UN_I [THEN ltI]) apply (rule_tac [2] Ord_UN, auto) done lemma eclose_rank_lt: "a \ eclose(b) \ rank(a) < rank(b)" apply (erule eclose_induct_down) apply (erule rank_lt) apply (erule rank_lt [THEN lt_trans], assumption) done lemma rank_mono: "a<=b \ rank(a) \ rank(b)" apply (rule subset_imp_le) apply (auto simp add: rank [of a] rank [of b]) done lemma rank_Pow: "rank(Pow(a)) = succ(rank(a))" apply (rule rank [THEN trans]) apply (rule le_anti_sym) apply (rule_tac [2] UN_upper_le) apply (rule UN_least_le) apply (auto intro: rank_mono simp add: Ord_UN) done lemma rank_0 [simp]: "rank(0) = 0" by (rule rank [THEN trans], blast) lemma rank_succ [simp]: "rank(succ(x)) = succ(rank(x))" apply (rule rank [THEN trans]) apply (rule equalityI [OF UN_least succI1 [THEN UN_upper]]) apply (erule succE, blast) apply (erule rank_lt [THEN leI, THEN succ_leI, THEN le_imp_subset]) done lemma rank_Union: "rank(\(A)) = (\x\A. rank(x))" apply (rule equalityI) apply (rule_tac [2] rank_mono [THEN le_imp_subset, THEN UN_least]) apply (erule_tac [2] Union_upper) apply (subst rank) apply (rule UN_least) apply (erule UnionE) apply (rule subset_trans) apply (erule_tac [2] RepFunI [THEN Union_upper]) apply (erule rank_lt [THEN succ_leI, THEN le_imp_subset]) done lemma rank_eclose: "rank(eclose(a)) = rank(a)" apply (rule le_anti_sym) apply (rule_tac [2] arg_subset_eclose [THEN rank_mono]) apply (rule_tac a1 = "eclose (a) " in rank [THEN ssubst]) apply (rule Ord_rank [THEN UN_least_le]) apply (erule eclose_rank_lt [THEN succ_leI]) done lemma rank_pair1: "rank(a) < rank(\a,b\)" -apply (unfold Pair_def) + unfolding Pair_def apply (rule consI1 [THEN rank_lt, THEN lt_trans]) apply (rule consI1 [THEN consI2, THEN rank_lt]) done lemma rank_pair2: "rank(b) < rank(\a,b\)" -apply (unfold Pair_def) + unfolding Pair_def apply (rule consI1 [THEN consI2, THEN rank_lt, THEN lt_trans]) apply (rule consI1 [THEN consI2, THEN rank_lt]) done (*Not clear how to remove the P(a) condition, since the "then" part must refer to "a"*) lemma the_equality_if: "P(a) \ (THE x. P(x)) = (if (\!x. P(x)) then a else 0)" by (simp add: the_0 the_equality2) (*The first premise not only fixs i but ensures @{term"f\0"}. The second premise is now essential. Consider otherwise the relation r = {\0,0\,\0,1\,\0,2\,...}. Then f`0 = \(f``{0}) = \(nat) = nat, whose rank equals that of r.*) lemma rank_apply: "\i \ domain(f); function(f)\ \ rank(f`i) < rank(f)" apply clarify apply (simp add: function_apply_equality) apply (blast intro: lt_trans rank_lt rank_pair2) done subsection\Corollaries of Leastness\ lemma mem_eclose_subset: "A \ B \ eclose(A)<=eclose(B)" apply (rule Transset_eclose [THEN eclose_least]) apply (erule arg_into_eclose [THEN eclose_subset]) done lemma eclose_mono: "A<=B \ eclose(A) \ eclose(B)" apply (rule Transset_eclose [THEN eclose_least]) apply (erule subset_trans) apply (rule arg_subset_eclose) done (** Idempotence of eclose **) lemma eclose_idem: "eclose(eclose(A)) = eclose(A)" apply (rule equalityI) apply (rule eclose_least [OF Transset_eclose subset_refl]) apply (rule arg_subset_eclose) done (** Transfinite recursion for definitions based on the three cases of ordinals **) lemma transrec2_0 [simp]: "transrec2(0,a,b) = a" by (rule transrec2_def [THEN def_transrec, THEN trans], simp) lemma transrec2_succ [simp]: "transrec2(succ(i),a,b) = b(i, transrec2(i,a,b))" apply (rule transrec2_def [THEN def_transrec, THEN trans]) apply (simp add: the_equality if_P) done lemma transrec2_Limit: "Limit(i) \ transrec2(i,a,b) = (\jx. f(x)\transrec2(x,a,b)) \ f(0) = a \ f(succ(i)) = b(i, f(i)) \ (Limit(K) \ f(K) = (\jn \ nat; a \ C(0); \m z. \m \ nat; z \ C(m)\ \ b(m,z): C(succ(m))\ \ rec(n,a,b) \ C(n)" by (erule nat_induct, auto) end diff --git a/src/ZF/EquivClass.thy b/src/ZF/EquivClass.thy --- a/src/ZF/EquivClass.thy +++ b/src/ZF/EquivClass.thy @@ -1,233 +1,233 @@ (* Title: ZF/EquivClass.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Equivalence Relations\ theory EquivClass imports Trancl Perm begin definition quotient :: "[i,i]\i" (infixl \'/'/\ 90) (*set of equiv classes*) where "A//r \ {r``{x} . x \ A}" definition congruent :: "[i,i\i]\o" where "congruent(r,b) \ \y z. \y,z\:r \ b(y)=b(z)" definition congruent2 :: "[i,i,[i,i]\i]\o" where "congruent2(r1,r2,b) \ \y1 z1 y2 z2. \y1,z1\:r1 \ \y2,z2\:r2 \ b(y1,y2) = b(z1,z2)" abbreviation RESPECTS ::"[i\i, i] \ o" (infixr \respects\ 80) where "f respects r \ congruent(r,f)" abbreviation RESPECTS2 ::"[i\i\i, i] \ o" (infixr \respects2 \ 80) where "f respects2 r \ congruent2(r,r,f)" \ \Abbreviation for the common case where the relations are identical\ subsection\Suppes, Theorem 70: \<^term>\r\ is an equiv relation iff \<^term>\converse(r) O r = r\\ (** first half: equiv(A,r) \ converse(r) O r = r **) lemma sym_trans_comp_subset: "\sym(r); trans(r)\ \ converse(r) O r \ r" by (unfold trans_def sym_def, blast) lemma refl_comp_subset: "\refl(A,r); r \ A*A\ \ r \ converse(r) O r" by (unfold refl_def, blast) lemma equiv_comp_eq: "equiv(A,r) \ converse(r) O r = r" -apply (unfold equiv_def) + unfolding equiv_def apply (blast del: subsetI intro!: sym_trans_comp_subset refl_comp_subset) done (*second half*) lemma comp_equivI: "\converse(r) O r = r; domain(r) = A\ \ equiv(A,r)" apply (unfold equiv_def refl_def sym_def trans_def) apply (erule equalityE) apply (subgoal_tac "\x y. \x,y\ \ r \ \y,x\ \ r", blast+) done (** Equivalence classes **) (*Lemma for the next result*) lemma equiv_class_subset: "\sym(r); trans(r); \a,b\: r\ \ r``{a} \ r``{b}" by (unfold trans_def sym_def, blast) lemma equiv_class_eq: "\equiv(A,r); \a,b\: r\ \ r``{a} = r``{b}" -apply (unfold equiv_def) + unfolding equiv_def apply (safe del: subsetI intro!: equalityI equiv_class_subset) apply (unfold sym_def, blast) done lemma equiv_class_self: "\equiv(A,r); a \ A\ \ a \ r``{a}" by (unfold equiv_def refl_def, blast) (*Lemma for the next result*) lemma subset_equiv_class: "\equiv(A,r); r``{b} \ r``{a}; b \ A\ \ \a,b\: r" by (unfold equiv_def refl_def, blast) lemma eq_equiv_class: "\r``{a} = r``{b}; equiv(A,r); b \ A\ \ \a,b\: r" by (assumption | rule equalityD2 subset_equiv_class)+ (*thus r``{a} = r``{b} as well*) lemma equiv_class_nondisjoint: "\equiv(A,r); x: (r``{a} \ r``{b})\ \ \a,b\: r" by (unfold equiv_def trans_def sym_def, blast) lemma equiv_type: "equiv(A,r) \ r \ A*A" by (unfold equiv_def, blast) lemma equiv_class_eq_iff: "equiv(A,r) \ \x,y\: r \ r``{x} = r``{y} \ x \ A \ y \ A" by (blast intro: eq_equiv_class equiv_class_eq dest: equiv_type) lemma eq_equiv_class_iff: "\equiv(A,r); x \ A; y \ A\ \ r``{x} = r``{y} \ \x,y\: r" by (blast intro: eq_equiv_class equiv_class_eq dest: equiv_type) (*** Quotients ***) (** Introduction/elimination rules -- needed? **) lemma quotientI [TC]: "x \ A \ r``{x}: A//r" -apply (unfold quotient_def) + unfolding quotient_def apply (erule RepFunI) done lemma quotientE: "\X \ A//r; \x. \X = r``{x}; x \ A\ \ P\ \ P" by (unfold quotient_def, blast) lemma Union_quotient: "equiv(A,r) \ \(A//r) = A" by (unfold equiv_def refl_def quotient_def, blast) lemma quotient_disj: "\equiv(A,r); X \ A//r; Y \ A//r\ \ X=Y | (X \ Y \ 0)" -apply (unfold quotient_def) + unfolding quotient_def apply (safe intro!: equiv_class_eq, assumption) apply (unfold equiv_def trans_def sym_def, blast) done subsection\Defining Unary Operations upon Equivalence Classes\ (** Could have a locale with the premises equiv(A,r) and congruent(r,b) **) (*Conversion rule*) lemma UN_equiv_class: "\equiv(A,r); b respects r; a \ A\ \ (\x\r``{a}. b(x)) = b(a)" apply (subgoal_tac "\x \ r``{a}. b(x) = b(a)") apply simp apply (blast intro: equiv_class_self) apply (unfold equiv_def sym_def congruent_def, blast) done (*type checking of @{term"\x\r``{a}. b(x)"} *) lemma UN_equiv_class_type: "\equiv(A,r); b respects r; X \ A//r; \x. x \ A \ b(x) \ B\ \ (\x\X. b(x)) \ B" apply (unfold quotient_def, safe) apply (simp (no_asm_simp) add: UN_equiv_class) done (*Sufficient conditions for injectiveness. Could weaken premises! major premise could be an inclusion; bcong could be \y. y \ A \ b(y):B *) lemma UN_equiv_class_inject: "\equiv(A,r); b respects r; (\x\X. b(x))=(\y\Y. b(y)); X \ A//r; Y \ A//r; \x y. \x \ A; y \ A; b(x)=b(y)\ \ \x,y\:r\ \ X=Y" apply (unfold quotient_def, safe) apply (rule equiv_class_eq, assumption) apply (simp add: UN_equiv_class [of A r b]) done subsection\Defining Binary Operations upon Equivalence Classes\ lemma congruent2_implies_congruent: "\equiv(A,r1); congruent2(r1,r2,b); a \ A\ \ congruent(r2,b(a))" by (unfold congruent_def congruent2_def equiv_def refl_def, blast) lemma congruent2_implies_congruent_UN: "\equiv(A1,r1); equiv(A2,r2); congruent2(r1,r2,b); a \ A2\ \ congruent(r1, \x1. \x2 \ r2``{a}. b(x1,x2))" apply (unfold congruent_def, safe) apply (frule equiv_type [THEN subsetD], assumption) apply clarify apply (simp add: UN_equiv_class congruent2_implies_congruent) apply (unfold congruent2_def equiv_def refl_def, blast) done lemma UN_equiv_class2: "\equiv(A1,r1); equiv(A2,r2); congruent2(r1,r2,b); a1: A1; a2: A2\ \ (\x1 \ r1``{a1}. \x2 \ r2``{a2}. b(x1,x2)) = b(a1,a2)" by (simp add: UN_equiv_class congruent2_implies_congruent congruent2_implies_congruent_UN) (*type checking*) lemma UN_equiv_class_type2: "\equiv(A,r); b respects2 r; X1: A//r; X2: A//r; \x1 x2. \x1: A; x2: A\ \ b(x1,x2) \ B \ \ (\x1\X1. \x2\X2. b(x1,x2)) \ B" apply (unfold quotient_def, safe) apply (blast intro: UN_equiv_class_type congruent2_implies_congruent_UN congruent2_implies_congruent quotientI) done (*Suggested by John Harrison -- the two subproofs may be MUCH simpler than the direct proof*) lemma congruent2I: "\equiv(A1,r1); equiv(A2,r2); \y z w. \w \ A2; \y,z\ \ r1\ \ b(y,w) = b(z,w); \y z w. \w \ A1; \y,z\ \ r2\ \ b(w,y) = b(w,z) \ \ congruent2(r1,r2,b)" apply (unfold congruent2_def equiv_def refl_def, safe) apply (blast intro: trans) done lemma congruent2_commuteI: assumes equivA: "equiv(A,r)" and commute: "\y z. \y \ A; z \ A\ \ b(y,z) = b(z,y)" and congt: "\y z w. \w \ A; \y,z\: r\ \ b(w,y) = b(w,z)" shows "b respects2 r" apply (insert equivA [THEN equiv_type, THEN subsetD]) apply (rule congruent2I [OF equivA equivA]) apply (rule commute [THEN trans]) apply (rule_tac [3] commute [THEN trans, symmetric]) apply (rule_tac [5] sym) apply (blast intro: congt)+ done (*Obsolete?*) lemma congruent_commuteI: "\equiv(A,r); Z \ A//r; \w. \w \ A\ \ congruent(r, \z. b(w,z)); \x y. \x \ A; y \ A\ \ b(y,x) = b(x,y) \ \ congruent(r, \w. \z\Z. b(w,z))" apply (simp (no_asm) add: congruent_def) apply (safe elim!: quotientE) apply (frule equiv_type [THEN subsetD], assumption) apply (simp add: UN_equiv_class [of A r]) apply (simp add: congruent_def) done end diff --git a/src/ZF/Fixedpt.thy b/src/ZF/Fixedpt.thy --- a/src/ZF/Fixedpt.thy +++ b/src/ZF/Fixedpt.thy @@ -1,304 +1,304 @@ (* Title: ZF/Fixedpt.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1992 University of Cambridge *) section\Least and Greatest Fixed Points; the Knaster-Tarski Theorem\ theory Fixedpt imports equalities begin definition (*monotone operator from Pow(D) to itself*) bnd_mono :: "[i,i\i]\o" where "bnd_mono(D,h) \ h(D)<=D \ (\W X. W<=X \ X<=D \ h(W) \ h(X))" definition lfp :: "[i,i\i]\i" where "lfp(D,h) \ \({X: Pow(D). h(X) \ X})" definition gfp :: "[i,i\i]\i" where "gfp(D,h) \ \({X: Pow(D). X \ h(X)})" text\The theorem is proved in the lattice of subsets of \<^term>\D\, namely \<^term>\Pow(D)\, with Inter as the greatest lower bound.\ subsection\Monotone Operators\ lemma bnd_monoI: "\h(D)<=D; \W X. \W<=D; X<=D; W<=X\ \ h(W) \ h(X) \ \ bnd_mono(D,h)" by (unfold bnd_mono_def, clarify, blast) lemma bnd_monoD1: "bnd_mono(D,h) \ h(D) \ D" -apply (unfold bnd_mono_def) + unfolding bnd_mono_def apply (erule conjunct1) done lemma bnd_monoD2: "\bnd_mono(D,h); W<=X; X<=D\ \ h(W) \ h(X)" by (unfold bnd_mono_def, blast) lemma bnd_mono_subset: "\bnd_mono(D,h); X<=D\ \ h(X) \ D" by (unfold bnd_mono_def, clarify, blast) lemma bnd_mono_Un: "\bnd_mono(D,h); A \ D; B \ D\ \ h(A) \ h(B) \ h(A \ B)" -apply (unfold bnd_mono_def) + unfolding bnd_mono_def apply (rule Un_least, blast+) done (*unused*) lemma bnd_mono_UN: "\bnd_mono(D,h); \i\I. A(i) \ D\ \ (\i\I. h(A(i))) \ h((\i\I. A(i)))" -apply (unfold bnd_mono_def) + unfolding bnd_mono_def apply (rule UN_least) apply (elim conjE) apply (drule_tac x="A(i)" in spec) apply (drule_tac x="(\i\I. A(i))" in spec) apply blast done (*Useful??*) lemma bnd_mono_Int: "\bnd_mono(D,h); A \ D; B \ D\ \ h(A \ B) \ h(A) \ h(B)" apply (rule Int_greatest) apply (erule bnd_monoD2, rule Int_lower1, assumption) apply (erule bnd_monoD2, rule Int_lower2, assumption) done subsection\Proof of Knaster-Tarski Theorem using \<^term>\lfp\\ (*lfp is contained in each pre-fixedpoint*) lemma lfp_lowerbound: "\h(A) \ A; A<=D\ \ lfp(D,h) \ A" by (unfold lfp_def, blast) (*Unfolding the defn of Inter dispenses with the premise bnd_mono(D,h)!*) lemma lfp_subset: "lfp(D,h) \ D" by (unfold lfp_def Inter_def, blast) (*Used in datatype package*) lemma def_lfp_subset: "A \ lfp(D,h) \ A \ D" apply simp apply (rule lfp_subset) done lemma lfp_greatest: "\h(D) \ D; \X. \h(X) \ X; X<=D\ \ A<=X\ \ A \ lfp(D,h)" by (unfold lfp_def, blast) lemma lfp_lemma1: "\bnd_mono(D,h); h(A)<=A; A<=D\ \ h(lfp(D,h)) \ A" apply (erule bnd_monoD2 [THEN subset_trans]) apply (rule lfp_lowerbound, assumption+) done lemma lfp_lemma2: "bnd_mono(D,h) \ h(lfp(D,h)) \ lfp(D,h)" apply (rule bnd_monoD1 [THEN lfp_greatest]) apply (rule_tac [2] lfp_lemma1) apply (assumption+) done lemma lfp_lemma3: "bnd_mono(D,h) \ lfp(D,h) \ h(lfp(D,h))" apply (rule lfp_lowerbound) apply (rule bnd_monoD2, assumption) apply (rule lfp_lemma2, assumption) apply (erule_tac [2] bnd_mono_subset) apply (rule lfp_subset)+ done lemma lfp_unfold: "bnd_mono(D,h) \ lfp(D,h) = h(lfp(D,h))" apply (rule equalityI) apply (erule lfp_lemma3) apply (erule lfp_lemma2) done (*Definition form, to control unfolding*) lemma def_lfp_unfold: "\A\lfp(D,h); bnd_mono(D,h)\ \ A = h(A)" apply simp apply (erule lfp_unfold) done subsection\General Induction Rule for Least Fixedpoints\ lemma Collect_is_pre_fixedpt: "\bnd_mono(D,h); \x. x \ h(Collect(lfp(D,h),P)) \ P(x)\ \ h(Collect(lfp(D,h),P)) \ Collect(lfp(D,h),P)" by (blast intro: lfp_lemma2 [THEN subsetD] bnd_monoD2 [THEN subsetD] lfp_subset [THEN subsetD]) (*This rule yields an induction hypothesis in which the components of a data structure may be assumed to be elements of lfp(D,h)*) lemma induct: "\bnd_mono(D,h); a \ lfp(D,h); \x. x \ h(Collect(lfp(D,h),P)) \ P(x) \ \ P(a)" apply (rule Collect_is_pre_fixedpt [THEN lfp_lowerbound, THEN subsetD, THEN CollectD2]) apply (rule_tac [3] lfp_subset [THEN Collect_subset [THEN subset_trans]], blast+) done (*Definition form, to control unfolding*) lemma def_induct: "\A \ lfp(D,h); bnd_mono(D,h); a:A; \x. x \ h(Collect(A,P)) \ P(x) \ \ P(a)" by (rule induct, blast+) (*This version is useful when "A" is not a subset of D second premise could simply be h(D \ A) \ D or \X. X<=D \ h(X)<=D *) lemma lfp_Int_lowerbound: "\h(D \ A) \ A; bnd_mono(D,h)\ \ lfp(D,h) \ A" apply (rule lfp_lowerbound [THEN subset_trans]) apply (erule bnd_mono_subset [THEN Int_greatest], blast+) done (*Monotonicity of lfp, where h precedes i under a domain-like partial order monotonicity of h is not strictly necessary; h must be bounded by D*) lemma lfp_mono: assumes hmono: "bnd_mono(D,h)" and imono: "bnd_mono(E,i)" and subhi: "\X. X<=D \ h(X) \ i(X)" shows "lfp(D,h) \ lfp(E,i)" apply (rule bnd_monoD1 [THEN lfp_greatest]) apply (rule imono) apply (rule hmono [THEN [2] lfp_Int_lowerbound]) apply (rule Int_lower1 [THEN subhi, THEN subset_trans]) apply (rule imono [THEN bnd_monoD2, THEN subset_trans], auto) done (*This (unused) version illustrates that monotonicity is not really needed, but both lfp's must be over the SAME set D; Inter is anti-monotonic!*) lemma lfp_mono2: "\i(D) \ D; \X. X<=D \ h(X) \ i(X)\ \ lfp(D,h) \ lfp(D,i)" apply (rule lfp_greatest, assumption) apply (rule lfp_lowerbound, blast, assumption) done lemma lfp_cong: "\D=D'; \X. X \ D' \ h(X) = h'(X)\ \ lfp(D,h) = lfp(D',h')" apply (simp add: lfp_def) apply (rule_tac t=Inter in subst_context) apply (rule Collect_cong, simp_all) done subsection\Proof of Knaster-Tarski Theorem using \<^term>\gfp\\ (*gfp contains each post-fixedpoint that is contained in D*) lemma gfp_upperbound: "\A \ h(A); A<=D\ \ A \ gfp(D,h)" -apply (unfold gfp_def) + unfolding gfp_def apply (rule PowI [THEN CollectI, THEN Union_upper]) apply (assumption+) done lemma gfp_subset: "gfp(D,h) \ D" by (unfold gfp_def, blast) (*Used in datatype package*) lemma def_gfp_subset: "A\gfp(D,h) \ A \ D" apply simp apply (rule gfp_subset) done lemma gfp_least: "\bnd_mono(D,h); \X. \X \ h(X); X<=D\ \ X<=A\ \ gfp(D,h) \ A" -apply (unfold gfp_def) + unfolding gfp_def apply (blast dest: bnd_monoD1) done lemma gfp_lemma1: "\bnd_mono(D,h); A<=h(A); A<=D\ \ A \ h(gfp(D,h))" apply (rule subset_trans, assumption) apply (erule bnd_monoD2) apply (rule_tac [2] gfp_subset) apply (simp add: gfp_upperbound) done lemma gfp_lemma2: "bnd_mono(D,h) \ gfp(D,h) \ h(gfp(D,h))" apply (rule gfp_least) apply (rule_tac [2] gfp_lemma1) apply (assumption+) done lemma gfp_lemma3: "bnd_mono(D,h) \ h(gfp(D,h)) \ gfp(D,h)" apply (rule gfp_upperbound) apply (rule bnd_monoD2, assumption) apply (rule gfp_lemma2, assumption) apply (erule bnd_mono_subset, rule gfp_subset)+ done lemma gfp_unfold: "bnd_mono(D,h) \ gfp(D,h) = h(gfp(D,h))" apply (rule equalityI) apply (erule gfp_lemma2) apply (erule gfp_lemma3) done (*Definition form, to control unfolding*) lemma def_gfp_unfold: "\A\gfp(D,h); bnd_mono(D,h)\ \ A = h(A)" apply simp apply (erule gfp_unfold) done subsection\Coinduction Rules for Greatest Fixed Points\ (*weak version*) lemma weak_coinduct: "\a: X; X \ h(X); X \ D\ \ a \ gfp(D,h)" by (blast intro: gfp_upperbound [THEN subsetD]) lemma coinduct_lemma: "\X \ h(X \ gfp(D,h)); X \ D; bnd_mono(D,h)\ \ X \ gfp(D,h) \ h(X \ gfp(D,h))" apply (erule Un_least) apply (rule gfp_lemma2 [THEN subset_trans], assumption) apply (rule Un_upper2 [THEN subset_trans]) apply (rule bnd_mono_Un, assumption+) apply (rule gfp_subset) done (*strong version*) lemma coinduct: "\bnd_mono(D,h); a: X; X \ h(X \ gfp(D,h)); X \ D\ \ a \ gfp(D,h)" apply (rule weak_coinduct) apply (erule_tac [2] coinduct_lemma) apply (simp_all add: gfp_subset Un_subset_iff) done (*Definition form, to control unfolding*) lemma def_coinduct: "\A \ gfp(D,h); bnd_mono(D,h); a: X; X \ h(X \ A); X \ D\ \ a \ A" apply simp apply (rule coinduct, assumption+) done (*The version used in the induction/coinduction package*) lemma def_Collect_coinduct: "\A \ gfp(D, \w. Collect(D,P(w))); bnd_mono(D, \w. Collect(D,P(w))); a: X; X \ D; \z. z: X \ P(X \ A, z)\ \ a \ A" apply (rule def_coinduct, assumption+, blast+) done (*Monotonicity of gfp!*) lemma gfp_mono: "\bnd_mono(D,h); D \ E; \X. X<=D \ h(X) \ i(X)\ \ gfp(D,h) \ gfp(E,i)" apply (rule gfp_upperbound) apply (rule gfp_lemma2 [THEN subset_trans], assumption) apply (blast del: subsetI intro: gfp_subset) apply (blast del: subsetI intro: subset_trans gfp_subset) done end diff --git a/src/ZF/IMP/Equiv.thy b/src/ZF/IMP/Equiv.thy --- a/src/ZF/IMP/Equiv.thy +++ b/src/ZF/IMP/Equiv.thy @@ -1,83 +1,83 @@ (* Title: ZF/IMP/Equiv.thy Author: Heiko Loetzbeyer and Robert Sandner, TU München *) section \Equivalence\ theory Equiv imports Denotation Com begin lemma aexp_iff [rule_format]: "\a \ aexp; sigma: loc -> nat\ \ \n. \a,sigma\ -a-> n \ A(a,sigma) = n" apply (erule aexp.induct) apply (force intro!: evala.intros)+ done declare aexp_iff [THEN iffD1, simp] aexp_iff [THEN iffD2, intro!] inductive_cases [elim!]: "\true,sigma\ -b-> x" "\false,sigma\ -b-> x" " -b-> x" " -b-> x" " -b-> x" " -b-> x" lemma bexp_iff [rule_format]: "\b \ bexp; sigma: loc -> nat\ \ \w. \b,sigma\ -b-> w \ B(b,sigma) = w" apply (erule bexp.induct) apply (auto intro!: evalb.intros) done declare bexp_iff [THEN iffD1, simp] bexp_iff [THEN iffD2, intro!] lemma com1: "\c,sigma\ -c-> sigma' \ \ C(c)" apply (erule evalc.induct) apply (simp_all (no_asm_simp)) txt \\assign\\ apply (simp add: update_type) txt \\comp\\ apply fast txt \\while\\ apply (erule Gamma_bnd_mono [THEN lfp_unfold, THEN ssubst, OF C_subset]) apply (simp add: Gamma_def) txt \recursive case of \while\\ apply (erule Gamma_bnd_mono [THEN lfp_unfold, THEN ssubst, OF C_subset]) apply (auto simp add: Gamma_def) done declare B_type [intro!] A_type [intro!] declare evalc.intros [intro] lemma com2 [rule_format]: "c \ com \ \x \ C(c). -c-> snd(x)" apply (erule com.induct) txt \\skip\\ apply force txt \\assign\\ apply force txt \\comp\\ apply force txt \\while\\ apply safe apply simp_all apply (frule Gamma_bnd_mono [OF C_subset], erule Fixedpt.induct, assumption) - apply (unfold Gamma_def) + unfolding Gamma_def apply force txt \\if\\ apply auto done subsection \Main theorem\ theorem com_equivalence: "c \ com \ C(c) = {io \ (loc->nat) \ (loc->nat). -c-> snd(io)}" by (force intro: C_subset [THEN subsetD] elim: com2 dest: com1) end diff --git a/src/ZF/Induct/Comb.thy b/src/ZF/Induct/Comb.thy --- a/src/ZF/Induct/Comb.thy +++ b/src/ZF/Induct/Comb.thy @@ -1,273 +1,273 @@ (* Title: ZF/Induct/Comb.thy Author: Lawrence C Paulson Copyright 1994 University of Cambridge *) section \Combinatory Logic example: the Church-Rosser Theorem\ theory Comb imports ZF begin text \ Curiously, combinators do not include free variables. Example taken from @{cite camilleri92}. \ subsection \Definitions\ text \Datatype definition of combinators \S\ and \K\.\ consts comb :: i datatype comb = K | S | app ("p \ comb", "q \ comb") (infixl \\\ 90) text \ Inductive definition of contractions, \\\<^sup>1\ and (multi-step) reductions, \\\. \ consts contract :: i abbreviation contract_syntax :: "[i,i] \ o" (infixl \\\<^sup>1\ 50) where "p \\<^sup>1 q \ \p,q\ \ contract" abbreviation contract_multi :: "[i,i] \ o" (infixl \\\ 50) where "p \ q \ \p,q\ \ contract^*" inductive domains "contract" \ "comb \ comb" intros K: "\p \ comb; q \ comb\ \ K\p\q \\<^sup>1 p" S: "\p \ comb; q \ comb; r \ comb\ \ S\p\q\r \\<^sup>1 (p\r)\(q\r)" Ap1: "\p\\<^sup>1q; r \ comb\ \ p\r \\<^sup>1 q\r" Ap2: "\p\\<^sup>1q; r \ comb\ \ r\p \\<^sup>1 r\q" type_intros comb.intros text \ Inductive definition of parallel contractions, \\\<^sup>1\ and (multi-step) parallel reductions, \\\. \ consts parcontract :: i abbreviation parcontract_syntax :: "[i,i] \ o" (infixl \\\<^sup>1\ 50) where "p \\<^sup>1 q \ \p,q\ \ parcontract" abbreviation parcontract_multi :: "[i,i] \ o" (infixl \\\ 50) where "p \ q \ \p,q\ \ parcontract^+" inductive domains "parcontract" \ "comb \ comb" intros refl: "\p \ comb\ \ p \\<^sup>1 p" K: "\p \ comb; q \ comb\ \ K\p\q \\<^sup>1 p" S: "\p \ comb; q \ comb; r \ comb\ \ S\p\q\r \\<^sup>1 (p\r)\(q\r)" Ap: "\p\\<^sup>1q; r\\<^sup>1s\ \ p\r \\<^sup>1 q\s" type_intros comb.intros text \ Misc definitions. \ definition I :: i where "I \ S\K\K" definition diamond :: "i \ o" where "diamond(r) \ \x y. \x,y\\r \ (\y'. \r \ (\z. \y,z\\r \ \ r))" subsection \Transitive closure preserves the Church-Rosser property\ lemma diamond_strip_lemmaD [rule_format]: "\diamond(r); \x,y\:r^+\ \ \y'. :r \ (\z. : r^+ \ \y,z\: r)" - apply (unfold diamond_def) + unfolding diamond_def apply (erule trancl_induct) apply (blast intro: r_into_trancl) apply clarify apply (drule spec [THEN mp], assumption) apply (blast intro: r_into_trancl trans_trancl [THEN transD]) done lemma diamond_trancl: "diamond(r) \ diamond(r^+)" apply (simp (no_asm_simp) add: diamond_def) apply (rule impI [THEN allI, THEN allI]) apply (erule trancl_induct) apply auto apply (best intro: r_into_trancl trans_trancl [THEN transD] dest: diamond_strip_lemmaD)+ done inductive_cases Ap_E [elim!]: "p\q \ comb" subsection \Results about Contraction\ text \ For type checking: replaces \<^term>\a \\<^sup>1 b\ by \a, b \ comb\. \ lemmas contract_combE2 = contract.dom_subset [THEN subsetD, THEN SigmaE2] and contract_combD1 = contract.dom_subset [THEN subsetD, THEN SigmaD1] and contract_combD2 = contract.dom_subset [THEN subsetD, THEN SigmaD2] lemma field_contract_eq: "field(contract) = comb" by (blast intro: contract.K elim!: contract_combE2) lemmas reduction_refl = field_contract_eq [THEN equalityD2, THEN subsetD, THEN rtrancl_refl] lemmas rtrancl_into_rtrancl2 = r_into_rtrancl [THEN trans_rtrancl [THEN transD]] declare reduction_refl [intro!] contract.K [intro!] contract.S [intro!] lemmas reduction_rls = contract.K [THEN rtrancl_into_rtrancl2] contract.S [THEN rtrancl_into_rtrancl2] contract.Ap1 [THEN rtrancl_into_rtrancl2] contract.Ap2 [THEN rtrancl_into_rtrancl2] lemma "p \ comb \ I\p \ p" \ \Example only: not used\ unfolding I_def by (blast intro: reduction_rls) lemma comb_I: "I \ comb" unfolding I_def by blast subsection \Non-contraction results\ text \Derive a case for each combinator constructor.\ inductive_cases K_contractE [elim!]: "K \\<^sup>1 r" and S_contractE [elim!]: "S \\<^sup>1 r" and Ap_contractE [elim!]: "p\q \\<^sup>1 r" lemma I_contract_E: "I \\<^sup>1 r \ P" by (auto simp add: I_def) lemma K1_contractD: "K\p \\<^sup>1 r \ (\q. r = K\q \ p \\<^sup>1 q)" by auto lemma Ap_reduce1: "\p \ q; r \ comb\ \ p\r \ q\r" apply (frule rtrancl_type [THEN subsetD, THEN SigmaD1]) apply (drule field_contract_eq [THEN equalityD1, THEN subsetD]) apply (erule rtrancl_induct) apply (blast intro: reduction_rls) apply (erule trans_rtrancl [THEN transD]) apply (blast intro: contract_combD2 reduction_rls) done lemma Ap_reduce2: "\p \ q; r \ comb\ \ r\p \ r\q" apply (frule rtrancl_type [THEN subsetD, THEN SigmaD1]) apply (drule field_contract_eq [THEN equalityD1, THEN subsetD]) apply (erule rtrancl_induct) apply (blast intro: reduction_rls) apply (blast intro: trans_rtrancl [THEN transD] contract_combD2 reduction_rls) done text \Counterexample to the diamond property for \\\<^sup>1\.\ lemma KIII_contract1: "K\I\(I\I) \\<^sup>1 I" by (blast intro: comb_I) lemma KIII_contract2: "K\I\(I\I) \\<^sup>1 K\I\((K\I)\(K\I))" by (unfold I_def) (blast intro: contract.intros) lemma KIII_contract3: "K\I\((K\I)\(K\I)) \\<^sup>1 I" by (blast intro: comb_I) lemma not_diamond_contract: "\ diamond(contract)" - apply (unfold diamond_def) + unfolding diamond_def apply (blast intro: KIII_contract1 KIII_contract2 KIII_contract3 elim!: I_contract_E) done subsection \Results about Parallel Contraction\ text \For type checking: replaces \a \\<^sup>1 b\ by \a, b \ comb\\ lemmas parcontract_combE2 = parcontract.dom_subset [THEN subsetD, THEN SigmaE2] and parcontract_combD1 = parcontract.dom_subset [THEN subsetD, THEN SigmaD1] and parcontract_combD2 = parcontract.dom_subset [THEN subsetD, THEN SigmaD2] lemma field_parcontract_eq: "field(parcontract) = comb" by (blast intro: parcontract.K elim!: parcontract_combE2) text \Derive a case for each combinator constructor.\ inductive_cases K_parcontractE [elim!]: "K \\<^sup>1 r" and S_parcontractE [elim!]: "S \\<^sup>1 r" and Ap_parcontractE [elim!]: "p\q \\<^sup>1 r" declare parcontract.intros [intro] subsection \Basic properties of parallel contraction\ lemma K1_parcontractD [dest!]: "K\p \\<^sup>1 r \ (\p'. r = K\p' \ p \\<^sup>1 p')" by auto lemma S1_parcontractD [dest!]: "S\p \\<^sup>1 r \ (\p'. r = S\p' \ p \\<^sup>1 p')" by auto lemma S2_parcontractD [dest!]: "S\p\q \\<^sup>1 r \ (\p' q'. r = S\p'\q' \ p \\<^sup>1 p' \ q \\<^sup>1 q')" by auto lemma diamond_parcontract: "diamond(parcontract)" \ \Church-Rosser property for parallel contraction\ - apply (unfold diamond_def) + unfolding diamond_def apply (rule impI [THEN allI, THEN allI]) apply (erule parcontract.induct) apply (blast elim!: comb.free_elims intro: parcontract_combD2)+ done text \ \medskip Equivalence of \<^prop>\p \ q\ and \<^prop>\p \ q\. \ lemma contract_imp_parcontract: "p\\<^sup>1q \ p\\<^sup>1q" by (induct set: contract) auto lemma reduce_imp_parreduce: "p\q \ p\q" apply (frule rtrancl_type [THEN subsetD, THEN SigmaD1]) apply (drule field_contract_eq [THEN equalityD1, THEN subsetD]) apply (erule rtrancl_induct) apply (blast intro: r_into_trancl) apply (blast intro: contract_imp_parcontract r_into_trancl trans_trancl [THEN transD]) done lemma parcontract_imp_reduce: "p\\<^sup>1q \ p\q" apply (induct set: parcontract) apply (blast intro: reduction_rls) apply (blast intro: reduction_rls) apply (blast intro: reduction_rls) apply (blast intro: trans_rtrancl [THEN transD] Ap_reduce1 Ap_reduce2 parcontract_combD1 parcontract_combD2) done lemma parreduce_imp_reduce: "p\q \ p\q" apply (frule trancl_type [THEN subsetD, THEN SigmaD1]) apply (drule field_parcontract_eq [THEN equalityD1, THEN subsetD]) apply (erule trancl_induct, erule parcontract_imp_reduce) apply (erule trans_rtrancl [THEN transD]) apply (erule parcontract_imp_reduce) done lemma parreduce_iff_reduce: "p\q \ p\q" by (blast intro: parreduce_imp_reduce reduce_imp_parreduce) end diff --git a/src/ZF/Induct/FoldSet.thy b/src/ZF/Induct/FoldSet.thy --- a/src/ZF/Induct/FoldSet.thy +++ b/src/ZF/Induct/FoldSet.thy @@ -1,396 +1,396 @@ (* Title: ZF/Induct/FoldSet.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory A "fold" functional for finite sets. For n non-negative we have fold f e {x1,...,xn} = f x1 (... (f xn e)) where f is at least left-commutative. *) theory FoldSet imports ZF begin consts fold_set :: "[i, i, [i,i]\i, i] \ i" inductive domains "fold_set(A, B, f,e)" \ "Fin(A)*B" intros emptyI: "e\B \ \0, e\\fold_set(A, B, f,e)" consI: "\x\A; x \C; \C,y\ \ fold_set(A, B,f,e); f(x,y):B\ \ \fold_set(A, B, f, e)" type_intros Fin.intros definition fold :: "[i, [i,i]\i, i, i] \ i" (\fold[_]'(_,_,_')\) where "fold[B](f,e, A) \ THE x. \A, x\\fold_set(A, B, f,e)" definition setsum :: "[i\i, i] \ i" where "setsum(g, C) \ if Finite(C) then fold[int](\x y. g(x) $+ y, #0, C) else #0" (** foldSet **) inductive_cases empty_fold_setE: "\0, x\ \ fold_set(A, B, f,e)" inductive_cases cons_fold_setE: " \ fold_set(A, B, f,e)" (* add-hoc lemmas *) lemma cons_lemma1: "\x\C; x\B\ \ cons(x,B)=cons(x,C) \ B = C" by (auto elim: equalityE) lemma cons_lemma2: "\cons(x, B)=cons(y, C); x\y; x\B; y\C\ \ B - {y} = C-{x} \ x\C \ y\B" apply (auto elim: equalityE) done (* fold_set monotonicity *) lemma fold_set_mono_lemma: "\C, x\ \ fold_set(A, B, f, e) \ \D. A<=D \ \C, x\ \ fold_set(D, B, f, e)" apply (erule fold_set.induct) apply (auto intro: fold_set.intros) done lemma fold_set_mono: " C<=A \ fold_set(C, B, f, e) \ fold_set(A, B, f, e)" apply clarify apply (frule fold_set.dom_subset [THEN subsetD], clarify) apply (auto dest: fold_set_mono_lemma) done lemma fold_set_lemma: "\C, x\\fold_set(A, B, f, e) \ \C, x\\fold_set(C, B, f, e) \ C<=A" apply (erule fold_set.induct) apply (auto intro!: fold_set.intros intro: fold_set_mono [THEN subsetD]) done (* Proving that fold_set is deterministic *) lemma Diff1_fold_set: "\ \ fold_set(A, B, f,e); x\C; x\A; f(x, y):B\ \ \ fold_set(A, B, f, e)" apply (frule fold_set.dom_subset [THEN subsetD]) apply (erule cons_Diff [THEN subst], rule fold_set.intros, auto) done locale fold_typing = fixes A and B and e and f assumes ftype [intro,simp]: "\x \ A; y \ B\ \ f(x,y) \ B" and etype [intro,simp]: "e \ B" and fcomm: "\x \ A; y \ A; z \ B\ \ f(x, f(y, z))=f(y, f(x, z))" lemma (in fold_typing) Fin_imp_fold_set: "C\Fin(A) \ (\x. \C, x\ \ fold_set(A, B, f,e))" apply (erule Fin_induct) apply (auto dest: fold_set.dom_subset [THEN subsetD] intro: fold_set.intros etype ftype) done lemma Diff_sing_imp: "\C - {b} = D - {a}; a \ b; b \ C\ \ C = cons(b,D) - {a}" by (blast elim: equalityE) lemma (in fold_typing) fold_set_determ_lemma [rule_format]: "n\nat \ \C. |C| (\x. \C, x\ \ fold_set(A, B, f,e)\ (\y. \C, y\ \ fold_set(A, B, f,e) \ y=x))" apply (erule nat_induct) apply (auto simp add: le_iff) apply (erule fold_set.cases) apply (force elim!: empty_fold_setE) apply (erule fold_set.cases) apply (force elim!: empty_fold_setE, clarify) (*force simplification of "|C| < |cons(...)|"*) apply (frule_tac a = Ca in fold_set.dom_subset [THEN subsetD, THEN SigmaD1]) apply (frule_tac a = Cb in fold_set.dom_subset [THEN subsetD, THEN SigmaD1]) apply (simp add: Fin_into_Finite [THEN Finite_imp_cardinal_cons]) apply (case_tac "x=xb", auto) apply (simp add: cons_lemma1, blast) txt\case \<^term>\x\xb\\ apply (drule cons_lemma2, safe) apply (frule Diff_sing_imp, assumption+) txt\* LEVEL 17\ apply (subgoal_tac "|Ca| \ |Cb|") prefer 2 apply (rule succ_le_imp_le) apply (simp add: Fin_into_Finite Finite_imp_succ_cardinal_Diff Fin_into_Finite [THEN Finite_imp_cardinal_cons]) apply (rule_tac C1 = "Ca-{xb}" in Fin_imp_fold_set [THEN exE]) apply (blast intro: Diff_subset [THEN Fin_subset]) txt\* LEVEL 24 *\ apply (frule Diff1_fold_set, blast, blast) apply (blast dest!: ftype fold_set.dom_subset [THEN subsetD]) apply (subgoal_tac "ya = f(xb,xa) ") prefer 2 apply (blast del: equalityCE) apply (subgoal_tac " \ fold_set(A,B,f,e)") prefer 2 apply simp apply (subgoal_tac "yb = f (x, xa) ") apply (drule_tac [2] C = Cb in Diff1_fold_set, simp_all) apply (blast intro: fcomm dest!: fold_set.dom_subset [THEN subsetD]) apply (blast intro: ftype dest!: fold_set.dom_subset [THEN subsetD], blast) done lemma (in fold_typing) fold_set_determ: "\\C, x\\fold_set(A, B, f, e); \C, y\\fold_set(A, B, f, e)\ \ y=x" apply (frule fold_set.dom_subset [THEN subsetD], clarify) apply (drule Fin_into_Finite) apply (unfold Finite_def, clarify) apply (rule_tac n = "succ (n)" in fold_set_determ_lemma) apply (auto intro: eqpoll_imp_lepoll [THEN lepoll_cardinal_le]) done (** The fold function **) lemma (in fold_typing) fold_equality: "\C,y\ \ fold_set(A,B,f,e) \ fold[B](f,e,C) = y" -apply (unfold fold_def) + unfolding fold_def apply (frule fold_set.dom_subset [THEN subsetD], clarify) apply (rule the_equality) apply (rule_tac [2] A=C in fold_typing.fold_set_determ) apply (force dest: fold_set_lemma) apply (auto dest: fold_set_lemma) apply (simp add: fold_typing_def, auto) apply (auto dest: fold_set_lemma intro: ftype etype fcomm) done lemma fold_0 [simp]: "e \ B \ fold[B](f,e,0) = e" -apply (unfold fold_def) + unfolding fold_def apply (blast elim!: empty_fold_setE intro: fold_set.intros) done text\This result is the right-to-left direction of the subsequent result\ lemma (in fold_typing) fold_set_imp_cons: "\\C, y\ \ fold_set(C, B, f, e); C \ Fin(A); c \ A; c\C\ \ \ fold_set(cons(c, C), B, f, e)" apply (frule FinD [THEN fold_set_mono, THEN subsetD]) apply assumption apply (frule fold_set.dom_subset [of A, THEN subsetD]) apply (blast intro!: fold_set.consI intro: fold_set_mono [THEN subsetD]) done lemma (in fold_typing) fold_cons_lemma [rule_format]: "\C \ Fin(A); c \ A; c\C\ \ \ fold_set(cons(c, C), B, f, e) \ (\y. \C, y\ \ fold_set(C, B, f, e) \ v = f(c, y))" apply auto prefer 2 apply (blast intro: fold_set_imp_cons) apply (frule_tac Fin.consI [of c, THEN FinD, THEN fold_set_mono, THEN subsetD], assumption+) apply (frule_tac fold_set.dom_subset [of A, THEN subsetD]) apply (drule FinD) apply (rule_tac A1 = "cons(c,C)" and f1=f and B1=B and C1=C and e1=e in fold_typing.Fin_imp_fold_set [THEN exE]) apply (blast intro: fold_typing.intro ftype etype fcomm) apply (blast intro: Fin_subset [of _ "cons(c,C)"] Finite_into_Fin dest: Fin_into_Finite) apply (rule_tac x = x in exI) apply (auto intro: fold_set.intros) apply (drule_tac fold_set_lemma [of C], blast) apply (blast intro!: fold_set.consI intro: fold_set_determ fold_set_mono [THEN subsetD] dest: fold_set.dom_subset [THEN subsetD]) done lemma (in fold_typing) fold_cons: "\C\Fin(A); c\A; c\C\ \ fold[B](f, e, cons(c, C)) = f(c, fold[B](f, e, C))" -apply (unfold fold_def) + unfolding fold_def apply (simp add: fold_cons_lemma) apply (rule the_equality, auto) apply (subgoal_tac [2] "\C, y\ \ fold_set(A, B, f, e)") apply (drule Fin_imp_fold_set) apply (auto dest: fold_set_lemma simp add: fold_def [symmetric] fold_equality) apply (blast intro: fold_set_mono [THEN subsetD] dest!: FinD) done lemma (in fold_typing) fold_type [simp,TC]: "C\Fin(A) \ fold[B](f,e,C):B" apply (erule Fin_induct) apply (simp_all add: fold_cons ftype etype) done lemma (in fold_typing) fold_commute [rule_format]: "\C\Fin(A); c\A\ \ (\y\B. f(c, fold[B](f, y, C)) = fold[B](f, f(c, y), C))" apply (erule Fin_induct) apply (simp_all add: fold_typing.fold_cons [of A B _ f] fold_typing.fold_type [of A B _ f] fold_typing_def fcomm) done lemma (in fold_typing) fold_nest_Un_Int: "\C\Fin(A); D\Fin(A)\ \ fold[B](f, fold[B](f, e, D), C) = fold[B](f, fold[B](f, e, (C \ D)), C \ D)" apply (erule Fin_induct, auto) apply (simp add: Un_cons Int_cons_left fold_type fold_commute fold_typing.fold_cons [of A _ _ f] fold_typing_def fcomm cons_absorb) done lemma (in fold_typing) fold_nest_Un_disjoint: "\C\Fin(A); D\Fin(A); C \ D = 0\ \ fold[B](f,e,C \ D) = fold[B](f, fold[B](f,e,D), C)" by (simp add: fold_nest_Un_Int) lemma Finite_cons_lemma: "Finite(C) \ C\Fin(cons(c, C))" apply (drule Finite_into_Fin) apply (blast intro: Fin_mono [THEN subsetD]) done subsection\The Operator \<^term>\setsum\\ lemma setsum_0 [simp]: "setsum(g, 0) = #0" by (simp add: setsum_def) lemma setsum_cons [simp]: "Finite(C) \ setsum(g, cons(c,C)) = (if c \ C then setsum(g,C) else g(c) $+ setsum(g,C))" apply (auto simp add: setsum_def Finite_cons cons_absorb) apply (rule_tac A = "cons (c, C)" in fold_typing.fold_cons) apply (auto intro: fold_typing.intro Finite_cons_lemma) done lemma setsum_K0: "setsum((\i. #0), C) = #0" apply (case_tac "Finite (C) ") prefer 2 apply (simp add: setsum_def) apply (erule Finite_induct, auto) done (*The reversed orientation looks more natural, but LOOPS as a simprule!*) lemma setsum_Un_Int: "\Finite(C); Finite(D)\ \ setsum(g, C \ D) $+ setsum(g, C \ D) = setsum(g, C) $+ setsum(g, D)" apply (erule Finite_induct) apply (simp_all add: Int_cons_right cons_absorb Un_cons Int_commute Finite_Un Int_lower1 [THEN subset_Finite]) done lemma setsum_type [simp,TC]: "setsum(g, C):int" apply (case_tac "Finite (C) ") prefer 2 apply (simp add: setsum_def) apply (erule Finite_induct, auto) done lemma setsum_Un_disjoint: "\Finite(C); Finite(D); C \ D = 0\ \ setsum(g, C \ D) = setsum(g, C) $+ setsum(g,D)" apply (subst setsum_Un_Int [symmetric]) apply (subgoal_tac [3] "Finite (C \ D) ") apply (auto intro: Finite_Un) done lemma Finite_RepFun [rule_format (no_asm)]: "Finite(I) \ (\i\I. Finite(C(i))) \ Finite(RepFun(I, C))" apply (erule Finite_induct, auto) done lemma setsum_UN_disjoint [rule_format (no_asm)]: "Finite(I) \ (\i\I. Finite(C(i))) \ (\i\I. \j\I. i\j \ C(i) \ C(j) = 0) \ setsum(f, \i\I. C(i)) = setsum (\i. setsum(f, C(i)), I)" apply (erule Finite_induct, auto) apply (subgoal_tac "\i\B. x \ i") prefer 2 apply blast apply (subgoal_tac "C (x) \ (\i\B. C (i)) = 0") prefer 2 apply blast apply (subgoal_tac "Finite (\i\B. C (i)) \ Finite (C (x)) \ Finite (B) ") apply (simp (no_asm_simp) add: setsum_Un_disjoint) apply (auto intro: Finite_Union Finite_RepFun) done lemma setsum_addf: "setsum(\x. f(x) $+ g(x),C) = setsum(f, C) $+ setsum(g, C)" apply (case_tac "Finite (C) ") prefer 2 apply (simp add: setsum_def) apply (erule Finite_induct, auto) done lemma fold_set_cong: "\A=A'; B=B'; e=e'; (\x\A'. \y\B'. f(x,y) = f'(x,y))\ \ fold_set(A,B,f,e) = fold_set(A',B',f',e')" apply (simp add: fold_set_def) apply (intro refl iff_refl lfp_cong Collect_cong disj_cong ex_cong, auto) done lemma fold_cong: "\B=B'; A=A'; e=e'; \x y. \x\A'; y\B'\ \ f(x,y) = f'(x,y)\ \ fold[B](f,e,A) = fold[B'](f', e', A')" apply (simp add: fold_def) apply (subst fold_set_cong) apply (rule_tac [5] refl, simp_all) done lemma setsum_cong: "\A=B; \x. x\B \ f(x) = g(x)\ \ setsum(f, A) = setsum(g, B)" by (simp add: setsum_def cong add: fold_cong) lemma setsum_Un: "\Finite(A); Finite(B)\ \ setsum(f, A \ B) = setsum(f, A) $+ setsum(f, B) $- setsum(f, A \ B)" apply (subst setsum_Un_Int [symmetric], auto) done lemma setsum_zneg_or_0 [rule_format (no_asm)]: "Finite(A) \ (\x\A. g(x) $\ #0) \ setsum(g, A) $\ #0" apply (erule Finite_induct) apply (auto intro: zneg_or_0_add_zneg_or_0_imp_zneg_or_0) done lemma setsum_succD_lemma [rule_format]: "Finite(A) \ \n\nat. setsum(f,A) = $# succ(n) \ (\a\A. #0 $< f(a))" apply (erule Finite_induct) apply (auto simp del: int_of_0 int_of_succ simp add: not_zless_iff_zle int_of_0 [symmetric]) apply (subgoal_tac "setsum (f, B) $\ #0") apply simp_all prefer 2 apply (blast intro: setsum_zneg_or_0) apply (subgoal_tac "$# 1 $\ f (x) $+ setsum (f, B) ") apply (drule zdiff_zle_iff [THEN iffD2]) apply (subgoal_tac "$# 1 $\ $# 1 $- setsum (f,B) ") apply (drule_tac x = "$# 1" in zle_trans) apply (rule_tac [2] j = "#1" in zless_zle_trans, auto) done lemma setsum_succD: "\setsum(f, A) = $# succ(n); n\nat\\ \a\A. #0 $< f(a)" apply (case_tac "Finite (A) ") apply (blast intro: setsum_succD_lemma) -apply (unfold setsum_def) + unfolding setsum_def apply (auto simp del: int_of_0 int_of_succ simp add: int_succ_int_1 [symmetric] int_of_0 [symmetric]) done lemma g_zpos_imp_setsum_zpos [rule_format]: "Finite(A) \ (\x\A. #0 $\ g(x)) \ #0 $\ setsum(g, A)" apply (erule Finite_induct) apply (simp (no_asm)) apply (auto intro: zpos_add_zpos_imp_zpos) done lemma g_zpos_imp_setsum_zpos2 [rule_format]: "\Finite(A); \x. #0 $\ g(x)\ \ #0 $\ setsum(g, A)" apply (erule Finite_induct) apply (auto intro: zpos_add_zpos_imp_zpos) done lemma g_zspos_imp_setsum_zspos [rule_format]: "Finite(A) \ (\x\A. #0 $< g(x)) \ A \ 0 \ (#0 $< setsum(g, A))" apply (erule Finite_induct) apply (auto intro: zspos_add_zspos_imp_zspos) done lemma setsum_Diff [rule_format]: "Finite(A) \ \a. M(a) = #0 \ setsum(M, A) = setsum(M, A-{a})" apply (erule Finite_induct) apply (simp_all add: Diff_cons_eq Finite_Diff) done end diff --git a/src/ZF/Induct/Multiset.thy b/src/ZF/Induct/Multiset.thy --- a/src/ZF/Induct/Multiset.thy +++ b/src/ZF/Induct/Multiset.thy @@ -1,1294 +1,1294 @@ (* Title: ZF/Induct/Multiset.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory A definitional theory of multisets, including a wellfoundedness proof for the multiset order. The theory features ordinal multisets and the usual ordering. *) theory Multiset imports FoldSet Acc begin abbreviation (input) \ \Short cut for multiset space\ Mult :: "i\i" where "Mult(A) \ A -||> nat-{0}" definition (* This is the original "restrict" from ZF.thy. Restricts the function f to the domain A FIXME: adapt Multiset to the new "restrict". *) funrestrict :: "[i,i] \ i" where "funrestrict(f,A) \ \x \ A. f`x" definition (* M is a multiset *) multiset :: "i \ o" where "multiset(M) \ \A. M \ A -> nat-{0} \ Finite(A)" definition mset_of :: "i\i" where "mset_of(M) \ domain(M)" definition munion :: "[i, i] \ i" (infixl \+#\ 65) where "M +# N \ \x \ mset_of(M) \ mset_of(N). if x \ mset_of(M) \ mset_of(N) then (M`x) #+ (N`x) else (if x \ mset_of(M) then M`x else N`x)" definition (*convert a function to a multiset by eliminating 0*) normalize :: "i \ i" where "normalize(f) \ if (\A. f \ A -> nat \ Finite(A)) then funrestrict(f, {x \ mset_of(f). 0 < f`x}) else 0" definition mdiff :: "[i, i] \ i" (infixl \-#\ 65) where "M -# N \ normalize(\x \ mset_of(M). if x \ mset_of(N) then M`x #- N`x else M`x)" definition (* set of elements of a multiset *) msingle :: "i \ i" (\{#_#}\) where "{#a#} \ {\a, 1\}" definition MCollect :: "[i, i\o] \ i" (*comprehension*) where "MCollect(M, P) \ funrestrict(M, {x \ mset_of(M). P(x)})" definition (* Counts the number of occurrences of an element in a multiset *) mcount :: "[i, i] \ i" where "mcount(M, a) \ if a \ mset_of(M) then M`a else 0" definition msize :: "i \ i" where "msize(M) \ setsum(\a. $# mcount(M,a), mset_of(M))" abbreviation melem :: "[i,i] \ o" (\(_/ :# _)\ [50, 51] 50) where "a :# M \ a \ mset_of(M)" syntax "_MColl" :: "[pttrn, i, o] \ i" (\(1{# _ \ _./ _#})\) translations "{#x \ M. P#}" == "CONST MCollect(M, \x. P)" (* multiset orderings *) definition (* multirel1 has to be a set (not a predicate) so that we can form its transitive closure and reason about wf(.) and acc(.) *) multirel1 :: "[i,i]\i" where "multirel1(A, r) \ {\M, N\ \ Mult(A)*Mult(A). \a \ A. \M0 \ Mult(A). \K \ Mult(A). N=M0 +# {#a#} \ M=M0 +# K \ (\b \ mset_of(K). \b,a\ \ r)}" definition multirel :: "[i, i] \ i" where "multirel(A, r) \ multirel1(A, r)^+" (* ordinal multiset orderings *) definition omultiset :: "i \ o" where "omultiset(M) \ \i. Ord(i) \ M \ Mult(field(Memrel(i)))" definition mless :: "[i, i] \ o" (infixl \<#\ 50) where "M <# N \ \i. Ord(i) \ \M, N\ \ multirel(field(Memrel(i)), Memrel(i))" definition mle :: "[i, i] \ o" (infixl \<#=\ 50) where "M <#= N \ (omultiset(M) \ M = N) | M <# N" subsection\Properties of the original "restrict" from ZF.thy\ lemma funrestrict_subset: "\f \ Pi(C,B); A\C\ \ funrestrict(f,A) \ f" by (auto simp add: funrestrict_def lam_def intro: apply_Pair) lemma funrestrict_type: "\\x. x \ A \ f`x \ B(x)\ \ funrestrict(f,A) \ Pi(A,B)" by (simp add: funrestrict_def lam_type) lemma funrestrict_type2: "\f \ Pi(C,B); A\C\ \ funrestrict(f,A) \ Pi(A,B)" by (blast intro: apply_type funrestrict_type) lemma funrestrict [simp]: "a \ A \ funrestrict(f,A) ` a = f`a" by (simp add: funrestrict_def) lemma funrestrict_empty [simp]: "funrestrict(f,0) = 0" by (simp add: funrestrict_def) lemma domain_funrestrict [simp]: "domain(funrestrict(f,C)) = C" by (auto simp add: funrestrict_def lam_def) lemma fun_cons_funrestrict_eq: "f \ cons(a, b) -> B \ f = cons(, funrestrict(f, b))" apply (rule equalityI) prefer 2 apply (blast intro: apply_Pair funrestrict_subset [THEN subsetD]) apply (auto dest!: Pi_memberD simp add: funrestrict_def lam_def) done declare domain_of_fun [simp] declare domainE [rule del] text\A useful simplification rule\ lemma multiset_fun_iff: "(f \ A -> nat-{0}) \ f \ A->nat\(\a \ A. f`a \ nat \ 0 < f`a)" apply safe apply (rule_tac [4] B1 = "range (f) " in Pi_mono [THEN subsetD]) apply (auto intro!: Ord_0_lt dest: apply_type Diff_subset [THEN Pi_mono, THEN subsetD] simp add: range_of_fun apply_iff) done (** The multiset space **) lemma multiset_into_Mult: "\multiset(M); mset_of(M)\A\ \ M \ Mult(A)" apply (simp add: multiset_def) apply (auto simp add: multiset_fun_iff mset_of_def) apply (rule_tac B1 = "nat-{0}" in FiniteFun_mono [THEN subsetD], simp_all) apply (rule Finite_into_Fin [THEN [2] Fin_mono [THEN subsetD], THEN fun_FiniteFunI]) apply (simp_all (no_asm_simp) add: multiset_fun_iff) done lemma Mult_into_multiset: "M \ Mult(A) \ multiset(M) \ mset_of(M)\A" apply (simp add: multiset_def mset_of_def) apply (frule FiniteFun_is_fun) apply (drule FiniteFun_domain_Fin) apply (frule FinD, clarify) apply (rule_tac x = "domain (M) " in exI) apply (blast intro: Fin_into_Finite) done lemma Mult_iff_multiset: "M \ Mult(A) \ multiset(M) \ mset_of(M)\A" by (blast dest: Mult_into_multiset intro: multiset_into_Mult) lemma multiset_iff_Mult_mset_of: "multiset(M) \ M \ Mult(mset_of(M))" by (auto simp add: Mult_iff_multiset) text\The \<^term>\multiset\ operator\ (* the empty multiset is 0 *) lemma multiset_0 [simp]: "multiset(0)" by (auto intro: FiniteFun.intros simp add: multiset_iff_Mult_mset_of) text\The \<^term>\mset_of\ operator\ lemma multiset_set_of_Finite [simp]: "multiset(M) \ Finite(mset_of(M))" by (simp add: multiset_def mset_of_def, auto) lemma mset_of_0 [iff]: "mset_of(0) = 0" by (simp add: mset_of_def) lemma mset_is_0_iff: "multiset(M) \ mset_of(M)=0 \ M=0" by (auto simp add: multiset_def mset_of_def) lemma mset_of_single [iff]: "mset_of({#a#}) = {a}" by (simp add: msingle_def mset_of_def) lemma mset_of_union [iff]: "mset_of(M +# N) = mset_of(M) \ mset_of(N)" by (simp add: mset_of_def munion_def) lemma mset_of_diff [simp]: "mset_of(M)\A \ mset_of(M -# N) \ A" by (auto simp add: mdiff_def multiset_def normalize_def mset_of_def) (* msingle *) lemma msingle_not_0 [iff]: "{#a#} \ 0 \ 0 \ {#a#}" by (simp add: msingle_def) lemma msingle_eq_iff [iff]: "({#a#} = {#b#}) \ (a = b)" by (simp add: msingle_def) lemma msingle_multiset [iff,TC]: "multiset({#a#})" apply (simp add: multiset_def msingle_def) apply (rule_tac x = "{a}" in exI) apply (auto intro: Finite_cons Finite_0 fun_extend3) done (** normalize **) lemmas Collect_Finite = Collect_subset [THEN subset_Finite] lemma normalize_idem [simp]: "normalize(normalize(f)) = normalize(f)" apply (simp add: normalize_def funrestrict_def mset_of_def) apply (case_tac "\A. f \ A -> nat \ Finite (A) ") apply clarify apply (drule_tac x = "{x \ domain (f) . 0 < f ` x}" in spec) apply auto apply (auto intro!: lam_type simp add: Collect_Finite) done lemma normalize_multiset [simp]: "multiset(M) \ normalize(M) = M" by (auto simp add: multiset_def normalize_def mset_of_def funrestrict_def multiset_fun_iff) lemma multiset_normalize [simp]: "multiset(normalize(f))" apply (simp add: normalize_def) apply (simp add: normalize_def mset_of_def multiset_def, auto) apply (rule_tac x = "{x \ A . 0multiset(M); multiset(N)\ \ multiset(M +# N)" apply (unfold multiset_def munion_def mset_of_def, auto) apply (rule_tac x = "A \ Aa" in exI) apply (auto intro!: lam_type intro: Finite_Un simp add: multiset_fun_iff zero_less_add) done (* difference *) lemma mdiff_multiset [simp]: "multiset(M -# N)" by (simp add: mdiff_def) (** Algebraic properties of multisets **) (* Union *) lemma munion_0 [simp]: "multiset(M) \ M +# 0 = M \ 0 +# M = M" apply (simp add: multiset_def) apply (auto simp add: munion_def mset_of_def) done lemma munion_commute: "M +# N = N +# M" by (auto intro!: lam_cong simp add: munion_def) lemma munion_assoc: "(M +# N) +# K = M +# (N +# K)" apply (unfold munion_def mset_of_def) apply (rule lam_cong, auto) done lemma munion_lcommute: "M +# (N +# K) = N +# (M +# K)" apply (unfold munion_def mset_of_def) apply (rule lam_cong, auto) done lemmas munion_ac = munion_commute munion_assoc munion_lcommute (* Difference *) lemma mdiff_self_eq_0 [simp]: "M -# M = 0" by (simp add: mdiff_def normalize_def mset_of_def) lemma mdiff_0 [simp]: "0 -# M = 0" by (simp add: mdiff_def normalize_def) lemma mdiff_0_right [simp]: "multiset(M) \ M -# 0 = M" by (auto simp add: multiset_def mdiff_def normalize_def multiset_fun_iff mset_of_def funrestrict_def) lemma mdiff_union_inverse2 [simp]: "multiset(M) \ M +# {#a#} -# {#a#} = M" apply (unfold multiset_def munion_def mdiff_def msingle_def normalize_def mset_of_def) apply (auto cong add: if_cong simp add: ltD multiset_fun_iff funrestrict_def subset_Un_iff2 [THEN iffD1]) prefer 2 apply (force intro!: lam_type) apply (subgoal_tac [2] "{x \ A \ {a} . x \ a \ x \ A} = A") apply (rule fun_extension, auto) apply (drule_tac x = "A \ {a}" in spec) apply (simp add: Finite_Un) apply (force intro!: lam_type) done (** Count of elements **) lemma mcount_type [simp,TC]: "multiset(M) \ mcount(M, a) \ nat" by (auto simp add: multiset_def mcount_def mset_of_def multiset_fun_iff) lemma mcount_0 [simp]: "mcount(0, a) = 0" by (simp add: mcount_def) lemma mcount_single [simp]: "mcount({#b#}, a) = (if a=b then 1 else 0)" by (simp add: mcount_def mset_of_def msingle_def) lemma mcount_union [simp]: "\multiset(M); multiset(N)\ \ mcount(M +# N, a) = mcount(M, a) #+ mcount (N, a)" apply (auto simp add: multiset_def multiset_fun_iff mcount_def munion_def mset_of_def) done lemma mcount_diff [simp]: "multiset(M) \ mcount(M -# N, a) = mcount(M, a) #- mcount(N, a)" apply (simp add: multiset_def) apply (auto dest!: not_lt_imp_le simp add: mdiff_def multiset_fun_iff mcount_def normalize_def mset_of_def) apply (force intro!: lam_type) apply (force intro!: lam_type) done lemma mcount_elem: "\multiset(M); a \ mset_of(M)\ \ 0 < mcount(M, a)" apply (simp add: multiset_def, clarify) apply (simp add: mcount_def mset_of_def) apply (simp add: multiset_fun_iff) done (** msize **) lemma msize_0 [simp]: "msize(0) = #0" by (simp add: msize_def) lemma msize_single [simp]: "msize({#a#}) = #1" by (simp add: msize_def) lemma msize_type [simp,TC]: "msize(M) \ int" by (simp add: msize_def) lemma msize_zpositive: "multiset(M)\ #0 $\ msize(M)" by (auto simp add: msize_def intro: g_zpos_imp_setsum_zpos) lemma msize_int_of_nat: "multiset(M) \ \n \ nat. msize(M)= $# n" apply (rule not_zneg_int_of) apply (simp_all (no_asm_simp) add: msize_type [THEN znegative_iff_zless_0] not_zless_iff_zle msize_zpositive) done lemma not_empty_multiset_imp_exist: "\M\0; multiset(M)\ \ \a \ mset_of(M). 0 < mcount(M, a)" apply (simp add: multiset_def) apply (erule not_emptyE) apply (auto simp add: mset_of_def mcount_def multiset_fun_iff) apply (blast dest!: fun_is_rel) done lemma msize_eq_0_iff: "multiset(M) \ msize(M)=#0 \ M=0" apply (simp add: msize_def, auto) apply (rule_tac P = "setsum (u,v) \ #0" for u v in swap) apply blast apply (drule not_empty_multiset_imp_exist, assumption, clarify) apply (subgoal_tac "Finite (mset_of (M) - {a}) ") prefer 2 apply (simp add: Finite_Diff) apply (subgoal_tac "setsum (\x. $# mcount (M, x), cons (a, mset_of (M) -{a}))=#0") prefer 2 apply (simp add: cons_Diff, simp) apply (subgoal_tac "#0 $\ setsum (\x. $# mcount (M, x), mset_of (M) - {a}) ") apply (rule_tac [2] g_zpos_imp_setsum_zpos) apply (auto simp add: Finite_Diff not_zless_iff_zle [THEN iff_sym] znegative_iff_zless_0 [THEN iff_sym]) apply (rule not_zneg_int_of [THEN bexE]) apply (auto simp del: int_of_0 simp add: int_of_add [symmetric] int_of_0 [symmetric]) done lemma setsum_mcount_Int: "Finite(A) \ setsum(\a. $# mcount(N, a), A \ mset_of(N)) = setsum(\a. $# mcount(N, a), A)" apply (induct rule: Finite_induct) apply auto apply (subgoal_tac "Finite (B \ mset_of (N))") prefer 2 apply (blast intro: subset_Finite) apply (auto simp add: mcount_def Int_cons_left) done lemma msize_union [simp]: "\multiset(M); multiset(N)\ \ msize(M +# N) = msize(M) $+ msize(N)" apply (simp add: msize_def setsum_Un setsum_addf int_of_add setsum_mcount_Int) apply (subst Int_commute) apply (simp add: setsum_mcount_Int) done lemma msize_eq_succ_imp_elem: "\msize(M)= $# succ(n); n \ nat\ \ \a. a \ mset_of(M)" -apply (unfold msize_def) + unfolding msize_def apply (blast dest: setsum_succD) done (** Equality of multisets **) lemma equality_lemma: "\multiset(M); multiset(N); \a. mcount(M, a)=mcount(N, a)\ \ mset_of(M)=mset_of(N)" apply (simp add: multiset_def) apply (rule sym, rule equalityI) apply (auto simp add: multiset_fun_iff mcount_def mset_of_def) apply (drule_tac [!] x=x in spec) apply (case_tac [2] "x \ Aa", case_tac "x \ A", auto) done lemma multiset_equality: "\multiset(M); multiset(N)\\ M=N\(\a. mcount(M, a)=mcount(N, a))" apply auto apply (subgoal_tac "mset_of (M) = mset_of (N) ") prefer 2 apply (blast intro: equality_lemma) apply (simp add: multiset_def mset_of_def) apply (auto simp add: multiset_fun_iff) apply (rule fun_extension) apply (blast, blast) apply (drule_tac x = x in spec) apply (auto simp add: mcount_def mset_of_def) done (** More algebraic properties of multisets **) lemma munion_eq_0_iff [simp]: "\multiset(M); multiset(N)\\(M +# N =0) \ (M=0 \ N=0)" by (auto simp add: multiset_equality) lemma empty_eq_munion_iff [simp]: "\multiset(M); multiset(N)\\(0=M +# N) \ (M=0 \ N=0)" apply (rule iffI, drule sym) apply (simp_all add: multiset_equality) done lemma munion_right_cancel [simp]: "\multiset(M); multiset(N); multiset(K)\\(M +# K = N +# K)\(M=N)" by (auto simp add: multiset_equality) lemma munion_left_cancel [simp]: "\multiset(K); multiset(M); multiset(N)\ \(K +# M = K +# N) \ (M = N)" by (auto simp add: multiset_equality) lemma nat_add_eq_1_cases: "\m \ nat; n \ nat\ \ (m #+ n = 1) \ (m=1 \ n=0) | (m=0 \ n=1)" by (induct_tac n) auto lemma munion_is_single: "\multiset(M); multiset(N)\ \ (M +# N = {#a#}) \ (M={#a#} \ N=0) | (M = 0 \ N = {#a#})" apply (simp (no_asm_simp) add: multiset_equality) apply safe apply simp_all apply (case_tac "aa=a") apply (drule_tac [2] x = aa in spec) apply (drule_tac x = a in spec) apply (simp add: nat_add_eq_1_cases, simp) apply (case_tac "aaa=aa", simp) apply (drule_tac x = aa in spec) apply (simp add: nat_add_eq_1_cases) apply (case_tac "aaa=a") apply (drule_tac [4] x = aa in spec) apply (drule_tac [3] x = a in spec) apply (drule_tac [2] x = aaa in spec) apply (drule_tac x = aa in spec) apply (simp_all add: nat_add_eq_1_cases) done lemma msingle_is_union: "\multiset(M); multiset(N)\ \ ({#a#} = M +# N) \ ({#a#} = M \ N=0 | M = 0 \ {#a#} = N)" apply (subgoal_tac " ({#a#} = M +# N) \ (M +# N = {#a#}) ") apply (simp (no_asm_simp) add: munion_is_single) apply blast apply (blast dest: sym) done (** Towards induction over multisets **) lemma setsum_decr: "Finite(A) \ (\M. multiset(M) \ (\a \ mset_of(M). setsum(\z. $# mcount(M(a:=M`a #- 1), z), A) = (if a \ A then setsum(\z. $# mcount(M, z), A) $- #1 else setsum(\z. $# mcount(M, z), A))))" -apply (unfold multiset_def) + unfolding multiset_def apply (erule Finite_induct) apply (auto simp add: multiset_fun_iff) apply (unfold mset_of_def mcount_def) apply (case_tac "x \ A", auto) apply (subgoal_tac "$# M ` x $+ #-1 = $# M ` x $- $# 1") apply (erule ssubst) apply (rule int_of_diff, auto) done lemma setsum_decr2: "Finite(A) \ \M. multiset(M) \ (\a \ mset_of(M). setsum(\x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A) = (if a \ A then setsum(\x. $# mcount(M, x), A) $- $# M`a else setsum(\x. $# mcount(M, x), A)))" apply (simp add: multiset_def) apply (erule Finite_induct) apply (auto simp add: multiset_fun_iff mcount_def mset_of_def) done lemma setsum_decr3: "\Finite(A); multiset(M); a \ mset_of(M)\ \ setsum(\x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A - {a}) = (if a \ A then setsum(\x. $# mcount(M, x), A) $- $# M`a else setsum(\x. $# mcount(M, x), A))" apply (subgoal_tac "setsum (\x. $# mcount (funrestrict (M, mset_of (M) -{a}),x),A-{a}) = setsum (\x. $# mcount (funrestrict (M, mset_of (M) -{a}),x),A) ") apply (rule_tac [2] setsum_Diff [symmetric]) apply (rule sym, rule ssubst, blast) apply (rule sym, drule setsum_decr2, auto) apply (simp add: mcount_def mset_of_def) done lemma nat_le_1_cases: "n \ nat \ n \ 1 \ (n=0 | n=1)" by (auto elim: natE) lemma succ_pred_eq_self: "\0 nat\ \ succ(n #- 1) = n" apply (subgoal_tac "1 \ n") apply (drule add_diff_inverse2, auto) done text\Specialized for use in the proof below.\ lemma multiset_funrestict: "\\a\A. M ` a \ nat \ 0 < M ` a; Finite(A)\ \ multiset(funrestrict(M, A - {a}))" apply (simp add: multiset_def multiset_fun_iff) apply (rule_tac x="A-{a}" in exI) apply (auto intro: Finite_Diff funrestrict_type) done lemma multiset_induct_aux: assumes prem1: "\M a. \multiset(M); a\mset_of(M); P(M)\ \ P(cons(\a, 1\, M))" and prem2: "\M b. \multiset(M); b \ mset_of(M); P(M)\ \ P(M(b:= M`b #+ 1))" shows "\n \ nat; P(0)\ \ (\M. multiset(M)\ (setsum(\x. $# mcount(M, x), {x \ mset_of(M). 0 < M`x}) = $# n) \ P(M))" apply (erule nat_induct, clarify) apply (frule msize_eq_0_iff) apply (auto simp add: mset_of_def multiset_def multiset_fun_iff msize_def) apply (subgoal_tac "setsum (\x. $# mcount (M, x), A) =$# succ (x) ") apply (drule setsum_succD, auto) apply (case_tac "1 cons (a, A) . x\a\0, funrestrict (M, A-{a}))") prefer 2 apply (rule fun_cons_funrestrict_eq) apply (subgoal_tac "cons (a, A-{a}) = A") apply force apply force apply (rule_tac a = "cons (\a, 1\, funrestrict (M, A - {a}))" in ssubst) apply simp apply (frule multiset_funrestict, assumption) apply (rule prem1, assumption) apply (simp add: mset_of_def) apply (drule_tac x = "funrestrict (M, A-{a}) " in spec) apply (drule mp) apply (rule_tac x = "A-{a}" in exI) apply (auto intro: Finite_Diff funrestrict_type simp add: funrestrict) apply (frule_tac A = A and M = M and a = a in setsum_decr3) apply (simp (no_asm_simp) add: multiset_def multiset_fun_iff) apply blast apply (simp (no_asm_simp) add: mset_of_def) apply (drule_tac b = "if u then v else w" for u v w in sym, simp_all) apply (subgoal_tac "{x \ A - {a} . 0 < funrestrict (M, A - {x}) ` x} = A - {a}") apply (auto intro!: setsum_cong simp add: zdiff_eq_iff zadd_commute multiset_def multiset_fun_iff mset_of_def) done lemma multiset_induct2: "\multiset(M); P(0); (\M a. \multiset(M); a\mset_of(M); P(M)\ \ P(cons(\a, 1\, M))); (\M b. \multiset(M); b \ mset_of(M); P(M)\ \ P(M(b:= M`b #+ 1)))\ \ P(M)" apply (subgoal_tac "\n \ nat. setsum (\x. $# mcount (M, x), {x \ mset_of (M) . 0 < M ` x}) = $# n") apply (rule_tac [2] not_zneg_int_of) apply (simp_all (no_asm_simp) add: znegative_iff_zless_0 not_zless_iff_zle) apply (rule_tac [2] g_zpos_imp_setsum_zpos) prefer 2 apply (blast intro: multiset_set_of_Finite Collect_subset [THEN subset_Finite]) prefer 2 apply (simp add: multiset_def multiset_fun_iff, clarify) apply (rule multiset_induct_aux [rule_format], auto) done lemma munion_single_case1: "\multiset(M); a \mset_of(M)\ \ M +# {#a#} = cons(\a, 1\, M)" apply (simp add: multiset_def msingle_def) apply (auto simp add: munion_def) apply (unfold mset_of_def, simp) apply (rule fun_extension, rule lam_type, simp_all) apply (auto simp add: multiset_fun_iff fun_extend_apply) apply (drule_tac c = a and b = 1 in fun_extend3) apply (auto simp add: cons_eq Un_commute [of _ "{a}"]) done lemma munion_single_case2: "\multiset(M); a \ mset_of(M)\ \ M +# {#a#} = M(a:=M`a #+ 1)" apply (simp add: multiset_def) apply (auto simp add: munion_def multiset_fun_iff msingle_def) apply (unfold mset_of_def, simp) apply (subgoal_tac "A \ {a} = A") apply (rule fun_extension) apply (auto dest: domain_type intro: lam_type update_type) done (* Induction principle for multisets *) lemma multiset_induct: assumes M: "multiset(M)" and P0: "P(0)" and step: "\M a. \multiset(M); P(M)\ \ P(M +# {#a#})" shows "P(M)" apply (rule multiset_induct2 [OF M]) apply (simp_all add: P0) apply (frule_tac [2] a = b in munion_single_case2 [symmetric]) apply (frule_tac a = a in munion_single_case1 [symmetric]) apply (auto intro: step) done (** MCollect **) lemma MCollect_multiset [simp]: "multiset(M) \ multiset({# x \ M. P(x)#})" apply (simp add: MCollect_def multiset_def mset_of_def, clarify) apply (rule_tac x = "{x \ A. P (x) }" in exI) apply (auto dest: CollectD1 [THEN [2] apply_type] intro: Collect_subset [THEN subset_Finite] funrestrict_type) done lemma mset_of_MCollect [simp]: "multiset(M) \ mset_of({# x \ M. P(x) #}) \ mset_of(M)" by (auto simp add: mset_of_def MCollect_def multiset_def funrestrict_def) lemma MCollect_mem_iff [iff]: "x \ mset_of({#x \ M. P(x)#}) \ x \ mset_of(M) \ P(x)" by (simp add: MCollect_def mset_of_def) lemma mcount_MCollect [simp]: "mcount({# x \ M. P(x) #}, a) = (if P(a) then mcount(M,a) else 0)" by (simp add: mcount_def MCollect_def mset_of_def) lemma multiset_partition: "multiset(M) \ M = {# x \ M. P(x) #} +# {# x \ M. \ P(x) #}" by (simp add: multiset_equality) lemma natify_elem_is_self [simp]: "\multiset(M); a \ mset_of(M)\ \ natify(M`a) = M`a" by (auto simp add: multiset_def mset_of_def multiset_fun_iff) (* and more algebraic laws on multisets *) lemma munion_eq_conv_diff: "\multiset(M); multiset(N)\ \ (M +# {#a#} = N +# {#b#}) \ (M = N \ a = b | M = N -# {#a#} +# {#b#} \ N = M -# {#b#} +# {#a#})" apply (simp del: mcount_single add: multiset_equality) apply (rule iffI, erule_tac [2] disjE, erule_tac [3] conjE) apply (case_tac "a=b", auto) apply (drule_tac x = a in spec) apply (drule_tac [2] x = b in spec) apply (drule_tac [3] x = aa in spec) apply (drule_tac [4] x = a in spec, auto) apply (subgoal_tac [!] "mcount (N,a) :nat") apply (erule_tac [3] natE, erule natE, auto) done lemma melem_diff_single: "multiset(M) \ k \ mset_of(M -# {#a#}) \ (k=a \ 1 < mcount(M,a)) | (k\ a \ k \ mset_of(M))" apply (simp add: multiset_def) apply (simp add: normalize_def mset_of_def msingle_def mdiff_def mcount_def) apply (auto dest: domain_type intro: zero_less_diff [THEN iffD1] simp add: multiset_fun_iff apply_iff) apply (force intro!: lam_type) apply (force intro!: lam_type) apply (force intro!: lam_type) done lemma munion_eq_conv_exist: "\M \ Mult(A); N \ Mult(A)\ \ (M +# {#a#} = N +# {#b#}) \ (M=N \ a=b | (\K \ Mult(A). M= K +# {#b#} \ N=K +# {#a#}))" by (auto simp add: Mult_iff_multiset melem_diff_single munion_eq_conv_diff) subsection\Multiset Orderings\ (* multiset on a domain A are finite functions from A to nat-{0} *) (* multirel1 type *) lemma multirel1_type: "multirel1(A, r) \ Mult(A)*Mult(A)" by (auto simp add: multirel1_def) lemma multirel1_0 [simp]: "multirel1(0, r) =0" by (auto simp add: multirel1_def) lemma multirel1_iff: " \N, M\ \ multirel1(A, r) \ (\a. a \ A \ (\M0. M0 \ Mult(A) \ (\K. K \ Mult(A) \ M=M0 +# {#a#} \ N=M0 +# K \ (\b \ mset_of(K). \b,a\ \ r))))" by (auto simp add: multirel1_def Mult_iff_multiset Bex_def) text\Monotonicity of \<^term>\multirel1\\ lemma multirel1_mono1: "A\B \ multirel1(A, r)\multirel1(B, r)" apply (auto simp add: multirel1_def) apply (auto simp add: Un_subset_iff Mult_iff_multiset) apply (rule_tac x = a in bexI) apply (rule_tac x = M0 in bexI, simp) apply (rule_tac x = K in bexI) apply (auto simp add: Mult_iff_multiset) done lemma multirel1_mono2: "r\s \ multirel1(A,r)\multirel1(A, s)" apply (simp add: multirel1_def, auto) apply (rule_tac x = a in bexI) apply (rule_tac x = M0 in bexI) apply (simp_all add: Mult_iff_multiset) apply (rule_tac x = K in bexI) apply (simp_all add: Mult_iff_multiset, auto) done lemma multirel1_mono: "\A\B; r\s\ \ multirel1(A, r) \ multirel1(B, s)" apply (rule subset_trans) apply (rule multirel1_mono1) apply (rule_tac [2] multirel1_mono2, auto) done subsection\Toward the proof of well-foundedness of multirel1\ lemma not_less_0 [iff]: "\M,0\ \ multirel1(A, r)" by (auto simp add: multirel1_def Mult_iff_multiset) lemma less_munion: "\ \ multirel1(A, r); M0 \ Mult(A)\ \ (\M. \M, M0\ \ multirel1(A, r) \ N = M +# {#a#}) | (\K. K \ Mult(A) \ (\b \ mset_of(K). \b, a\ \ r) \ N = M0 +# K)" apply (frule multirel1_type [THEN subsetD]) apply (simp add: multirel1_iff) apply (auto simp add: munion_eq_conv_exist) apply (rule_tac x="Ka +# K" in exI, auto, simp add: Mult_iff_multiset) apply (simp (no_asm_simp) add: munion_left_cancel munion_assoc) apply (auto simp add: munion_commute) done lemma multirel1_base: "\M \ Mult(A); a \ A\ \ \ multirel1(A, r)" apply (auto simp add: multirel1_iff) apply (simp add: Mult_iff_multiset) apply (rule_tac x = a in exI, clarify) apply (rule_tac x = M in exI, simp) apply (rule_tac x = 0 in exI, auto) done lemma acc_0: "acc(0)=0" by (auto intro!: equalityI dest: acc.dom_subset [THEN subsetD]) lemma lemma1: "\\b \ A. \b,a\ \ r \ (\M \ acc(multirel1(A, r)). M +# {#b#}:acc(multirel1(A, r))); M0 \ acc(multirel1(A, r)); a \ A; \M. \M,M0\ \ multirel1(A, r) \ M +# {#a#} \ acc(multirel1(A, r))\ \ M0 +# {#a#} \ acc(multirel1(A, r))" apply (subgoal_tac "M0 \ Mult(A) ") prefer 2 apply (erule acc.cases) apply (erule fieldE) apply (auto dest: multirel1_type [THEN subsetD]) apply (rule accI) apply (rename_tac "N") apply (drule less_munion, blast) apply (auto simp add: Mult_iff_multiset) apply (erule_tac P = "\x \ mset_of (K) . \x, a\ \ r" in rev_mp) apply (erule_tac P = "mset_of (K) \A" in rev_mp) apply (erule_tac M = K in multiset_induct) (* three subgoals *) (* subgoal 1 \ the induction base case *) apply (simp (no_asm_simp)) (* subgoal 2 \ the induction general case *) apply (simp add: Ball_def Un_subset_iff, clarify) apply (drule_tac x = aa in spec, simp) apply (subgoal_tac "aa \ A") prefer 2 apply blast apply (drule_tac x = "M0 +# M" and P = "\x. x \ acc(multirel1(A, r)) \ Q(x)" for Q in spec) apply (simp add: munion_assoc [symmetric]) (* subgoal 3 \ additional conditions *) apply (auto intro!: multirel1_base [THEN fieldI2] simp add: Mult_iff_multiset) done lemma lemma2: "\\b \ A. \b,a\ \ r \ (\M \ acc(multirel1(A, r)). M +# {#b#} :acc(multirel1(A, r))); M \ acc(multirel1(A, r)); a \ A\ \ M +# {#a#} \ acc(multirel1(A, r))" apply (erule acc_induct) apply (blast intro: lemma1) done lemma lemma3: "\wf[A](r); a \ A\ \ \M \ acc(multirel1(A, r)). M +# {#a#} \ acc(multirel1(A, r))" apply (erule_tac a = a in wf_on_induct, blast) apply (blast intro: lemma2) done lemma lemma4: "multiset(M) \ mset_of(M)\A \ wf[A](r) \ M \ field(multirel1(A, r)) \ M \ acc(multirel1(A, r))" apply (erule multiset_induct) (* proving the base case *) apply clarify apply (rule accI, force) apply (simp add: multirel1_def) (* Proving the general case *) apply clarify apply simp apply (subgoal_tac "mset_of (M) \A") prefer 2 apply blast apply clarify apply (drule_tac a = a in lemma3, blast) apply (subgoal_tac "M \ field (multirel1 (A,r))") apply blast apply (rule multirel1_base [THEN fieldI1]) apply (auto simp add: Mult_iff_multiset) done lemma all_accessible: "\wf[A](r); M \ Mult(A); A \ 0\ \ M \ acc(multirel1(A, r))" apply (erule not_emptyE) apply (rule lemma4 [THEN mp, THEN mp, THEN mp]) apply (rule_tac [4] multirel1_base [THEN fieldI1]) apply (auto simp add: Mult_iff_multiset) done lemma wf_on_multirel1: "wf[A](r) \ wf[A-||>nat-{0}](multirel1(A, r))" apply (case_tac "A=0") apply (simp (no_asm_simp)) apply (rule wf_imp_wf_on) apply (rule wf_on_field_imp_wf) apply (simp (no_asm_simp) add: wf_on_0) apply (rule_tac A = "acc (multirel1 (A,r))" in wf_on_subset_A) apply (rule wf_on_acc) apply (blast intro: all_accessible) done lemma wf_multirel1: "wf(r) \wf(multirel1(field(r), r))" apply (simp (no_asm_use) add: wf_iff_wf_on_field) apply (drule wf_on_multirel1) apply (rule_tac A = "field (r) -||> nat - {0}" in wf_on_subset_A) apply (simp (no_asm_simp)) apply (rule field_rel_subset) apply (rule multirel1_type) done (** multirel **) lemma multirel_type: "multirel(A, r) \ Mult(A)*Mult(A)" apply (simp add: multirel_def) apply (rule trancl_type [THEN subset_trans]) apply (auto dest: multirel1_type [THEN subsetD]) done (* Monotonicity of multirel *) lemma multirel_mono: "\A\B; r\s\ \ multirel(A, r)\multirel(B,s)" apply (simp add: multirel_def) apply (rule trancl_mono) apply (rule multirel1_mono, auto) done (* Equivalence of multirel with the usual (closure-free) definition *) lemma add_diff_eq: "k \ nat \ 0 < k \ n #+ k #- 1 = n #+ (k #- 1)" by (erule nat_induct, auto) lemma mdiff_union_single_conv: "\a \ mset_of(J); multiset(I); multiset(J)\ \ I +# J -# {#a#} = I +# (J-# {#a#})" apply (simp (no_asm_simp) add: multiset_equality) apply (case_tac "a \ mset_of (I) ") apply (auto simp add: mcount_def mset_of_def multiset_def multiset_fun_iff) apply (auto dest: domain_type simp add: add_diff_eq) done lemma diff_add_commute: "\n \ m; m \ nat; n \ nat; k \ nat\ \ m #- n #+ k = m #+ k #- n" by (auto simp add: le_iff less_iff_succ_add) (* One direction *) lemma multirel_implies_one_step: "\M,N\ \ multirel(A, r) \ trans[A](r) \ (\I J K. I \ Mult(A) \ J \ Mult(A) \ K \ Mult(A) \ N = I +# J \ M = I +# K \ J \ 0 \ (\k \ mset_of(K). \j \ mset_of(J). \k,j\ \ r))" apply (simp add: multirel_def Ball_def Bex_def) apply (erule converse_trancl_induct) apply (simp_all add: multirel1_iff Mult_iff_multiset) (* Two subgoals remain *) (* Subgoal 1 *) apply clarify apply (rule_tac x = M0 in exI, force) (* Subgoal 2 *) apply clarify apply hypsubst_thin apply (case_tac "a \ mset_of (Ka) ") apply (rule_tac x = I in exI, simp (no_asm_simp)) apply (rule_tac x = J in exI, simp (no_asm_simp)) apply (rule_tac x = " (Ka -# {#a#}) +# K" in exI, simp (no_asm_simp)) apply (simp_all add: Un_subset_iff) apply (simp (no_asm_simp) add: munion_assoc [symmetric]) apply (drule_tac t = "\M. M-#{#a#}" in subst_context) apply (simp add: mdiff_union_single_conv melem_diff_single, clarify) apply (erule disjE, simp) apply (erule disjE, simp) apply (drule_tac x = a and P = "\x. x :# Ka \ Q(x)" for Q in spec) apply clarify apply (rule_tac x = xa in exI) apply (simp (no_asm_simp)) apply (blast dest: trans_onD) (* new we know that a\mset_of(Ka) *) apply (subgoal_tac "a :# I") apply (rule_tac x = "I-#{#a#}" in exI, simp (no_asm_simp)) apply (rule_tac x = "J+#{#a#}" in exI) apply (simp (no_asm_simp) add: Un_subset_iff) apply (rule_tac x = "Ka +# K" in exI) apply (simp (no_asm_simp) add: Un_subset_iff) apply (rule conjI) apply (simp (no_asm_simp) add: multiset_equality mcount_elem [THEN succ_pred_eq_self]) apply (rule conjI) apply (drule_tac t = "\M. M-#{#a#}" in subst_context) apply (simp add: mdiff_union_inverse2) apply (simp_all (no_asm_simp) add: multiset_equality) apply (rule diff_add_commute [symmetric]) apply (auto intro: mcount_elem) apply (subgoal_tac "a \ mset_of (I +# Ka) ") apply (drule_tac [2] sym, auto) done lemma melem_imp_eq_diff_union [simp]: "\a \ mset_of(M); multiset(M)\ \ M -# {#a#} +# {#a#} = M" by (simp add: multiset_equality mcount_elem [THEN succ_pred_eq_self]) lemma msize_eq_succ_imp_eq_union: "\msize(M)=$# succ(n); M \ Mult(A); n \ nat\ \ \a N. M = N +# {#a#} \ N \ Mult(A) \ a \ A" apply (drule msize_eq_succ_imp_elem, auto) apply (rule_tac x = a in exI) apply (rule_tac x = "M -# {#a#}" in exI) apply (frule Mult_into_multiset) apply (simp (no_asm_simp)) apply (auto simp add: Mult_iff_multiset) done (* The second direction *) lemma one_step_implies_multirel_lemma [rule_format (no_asm)]: "n \ nat \ (\I J K. I \ Mult(A) \ J \ Mult(A) \ K \ Mult(A) \ (msize(J) = $# n \ J \0 \ (\k \ mset_of(K). \j \ mset_of(J). \k, j\ \ r)) \ \ multirel(A, r))" apply (simp add: Mult_iff_multiset) apply (erule nat_induct, clarify) apply (drule_tac M = J in msize_eq_0_iff, auto) (* one subgoal remains *) apply (subgoal_tac "msize (J) =$# succ (x) ") prefer 2 apply simp apply (frule_tac A = A in msize_eq_succ_imp_eq_union) apply (simp_all add: Mult_iff_multiset, clarify) apply (rename_tac "J'", simp) apply (case_tac "J' = 0") apply (simp add: multirel_def) apply (rule r_into_trancl, clarify) apply (simp add: multirel1_iff Mult_iff_multiset, force) (*Now we know J' \ 0*) apply (drule sym, rotate_tac -1, simp) apply (erule_tac V = "$# x = msize (J') " in thin_rl) apply (frule_tac M = K and P = "\x. \x,a\ \ r" in multiset_partition) apply (erule_tac P = "\k \ mset_of (K) . P(k)" for P in rev_mp) apply (erule ssubst) apply (simp add: Ball_def, auto) apply (subgoal_tac "< (I +# {# x \ K. \x, a\ \ r#}) +# {# x \ K. \x, a\ \ r#}, (I +# {# x \ K. \x, a\ \ r#}) +# J'> \ multirel(A, r) ") prefer 2 apply (drule_tac x = "I +# {# x \ K. \x, a\ \ r#}" in spec) apply (rotate_tac -1) apply (drule_tac x = "J'" in spec) apply (rotate_tac -1) apply (drule_tac x = "{# x \ K. \x, a\ \ r#}" in spec, simp) apply blast apply (simp add: munion_assoc [symmetric] multirel_def) apply (rule_tac b = "I +# {# x \ K. \x, a\ \ r#} +# J'" in trancl_trans, blast) apply (rule r_into_trancl) apply (simp add: multirel1_iff Mult_iff_multiset) apply (rule_tac x = a in exI) apply (simp (no_asm_simp)) apply (rule_tac x = "I +# J'" in exI) apply (auto simp add: munion_ac Un_subset_iff) done lemma one_step_implies_multirel: "\J \ 0; \k \ mset_of(K). \j \ mset_of(J). \k,j\ \ r; I \ Mult(A); J \ Mult(A); K \ Mult(A)\ \ \ multirel(A, r)" apply (subgoal_tac "multiset (J) ") prefer 2 apply (simp add: Mult_iff_multiset) apply (frule_tac M = J in msize_int_of_nat) apply (auto intro: one_step_implies_multirel_lemma) done (** Proving that multisets are partially ordered **) (*irreflexivity*) lemma multirel_irrefl_lemma: "Finite(A) \ part_ord(A, r) \ (\x \ A. \y \ A. \x,y\ \ r) \A=0" apply (erule Finite_induct) apply (auto dest: subset_consI [THEN [2] part_ord_subset]) apply (auto simp add: part_ord_def irrefl_def) apply (drule_tac x = xa in bspec) apply (drule_tac [2] a = xa and b = x in trans_onD, auto) done lemma irrefl_on_multirel: "part_ord(A, r) \ irrefl(Mult(A), multirel(A, r))" apply (simp add: irrefl_def) apply (subgoal_tac "trans[A](r) ") prefer 2 apply (simp add: part_ord_def, clarify) apply (drule multirel_implies_one_step, clarify) apply (simp add: Mult_iff_multiset, clarify) apply (subgoal_tac "Finite (mset_of (K))") apply (frule_tac r = r in multirel_irrefl_lemma) apply (frule_tac B = "mset_of (K) " in part_ord_subset) apply simp_all apply (auto simp add: multiset_def mset_of_def) done lemma trans_on_multirel: "trans[Mult(A)](multirel(A, r))" apply (simp add: multirel_def trans_on_def) apply (blast intro: trancl_trans) done lemma multirel_trans: "\\M, N\ \ multirel(A, r); \N, K\ \ multirel(A, r)\ \ \M, K\ \ multirel(A,r)" apply (simp add: multirel_def) apply (blast intro: trancl_trans) done lemma trans_multirel: "trans(multirel(A,r))" apply (simp add: multirel_def) apply (rule trans_trancl) done lemma part_ord_multirel: "part_ord(A,r) \ part_ord(Mult(A), multirel(A, r))" apply (simp (no_asm) add: part_ord_def) apply (blast intro: irrefl_on_multirel trans_on_multirel) done (** Monotonicity of multiset union **) lemma munion_multirel1_mono: "\\M,N\ \ multirel1(A, r); K \ Mult(A)\ \ \ multirel1(A, r)" apply (frule multirel1_type [THEN subsetD]) apply (auto simp add: multirel1_iff Mult_iff_multiset) apply (rule_tac x = a in exI) apply (simp (no_asm_simp)) apply (rule_tac x = "K+#M0" in exI) apply (simp (no_asm_simp) add: Un_subset_iff) apply (rule_tac x = Ka in exI) apply (simp (no_asm_simp) add: munion_assoc) done lemma munion_multirel_mono2: "\\M, N\ \ multirel(A, r); K \ Mult(A)\\ \ multirel(A, r)" apply (frule multirel_type [THEN subsetD]) apply (simp (no_asm_use) add: multirel_def) apply clarify apply (drule_tac psi = "\M,N\ \ multirel1 (A, r) ^+" in asm_rl) apply (erule rev_mp) apply (erule rev_mp) apply (erule rev_mp) apply (erule trancl_induct, clarify) apply (blast intro: munion_multirel1_mono r_into_trancl, clarify) apply (subgoal_tac "y \ Mult(A) ") prefer 2 apply (blast dest: multirel_type [unfolded multirel_def, THEN subsetD]) apply (subgoal_tac " \ multirel1 (A, r) ") prefer 2 apply (blast intro: munion_multirel1_mono) apply (blast intro: r_into_trancl trancl_trans) done lemma munion_multirel_mono1: "\\M, N\ \ multirel(A, r); K \ Mult(A)\ \ \ multirel(A, r)" apply (frule multirel_type [THEN subsetD]) apply (rule_tac P = "\x. \x,u\ \ multirel(A, r)" for u in munion_commute [THEN subst]) apply (subst munion_commute [of N]) apply (rule munion_multirel_mono2) apply (auto simp add: Mult_iff_multiset) done lemma munion_multirel_mono: "\\M,K\ \ multirel(A, r); \N,L\ \ multirel(A, r)\ \ \ multirel(A, r)" apply (subgoal_tac "M \ Mult(A) \ N \ Mult(A) \ K \ Mult(A) \ L \ Mult(A) ") prefer 2 apply (blast dest: multirel_type [THEN subsetD]) apply (blast intro: munion_multirel_mono1 multirel_trans munion_multirel_mono2) done subsection\Ordinal Multisets\ (* A \ B \ field(Memrel(A)) \ field(Memrel(B)) *) lemmas field_Memrel_mono = Memrel_mono [THEN field_mono] (* \Aa \ Ba; A \ B\ \ multirel(field(Memrel(Aa)), Memrel(A))\ multirel(field(Memrel(Ba)), Memrel(B)) *) lemmas multirel_Memrel_mono = multirel_mono [OF field_Memrel_mono Memrel_mono] lemma omultiset_is_multiset [simp]: "omultiset(M) \ multiset(M)" apply (simp add: omultiset_def) apply (auto simp add: Mult_iff_multiset) done lemma munion_omultiset [simp]: "\omultiset(M); omultiset(N)\ \ omultiset(M +# N)" apply (simp add: omultiset_def, clarify) apply (rule_tac x = "i \ ia" in exI) apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff) apply (blast intro: field_Memrel_mono) done lemma mdiff_omultiset [simp]: "omultiset(M) \ omultiset(M -# N)" apply (simp add: omultiset_def, clarify) apply (simp add: Mult_iff_multiset) apply (rule_tac x = i in exI) apply (simp (no_asm_simp)) done (** Proving that Memrel is a partial order **) lemma irrefl_Memrel: "Ord(i) \ irrefl(field(Memrel(i)), Memrel(i))" apply (rule irreflI, clarify) apply (subgoal_tac "Ord (x) ") prefer 2 apply (blast intro: Ord_in_Ord) apply (drule_tac i = x in ltI [THEN lt_irrefl], auto) done lemma trans_iff_trans_on: "trans(r) \ trans[field(r)](r)" by (simp add: trans_on_def trans_def, auto) lemma part_ord_Memrel: "Ord(i) \part_ord(field(Memrel(i)), Memrel(i))" apply (simp add: part_ord_def) apply (simp (no_asm) add: trans_iff_trans_on [THEN iff_sym]) apply (blast intro: trans_Memrel irrefl_Memrel) done (* Ord(i) \ part_ord(field(Memrel(i))-||>nat-{0}, multirel(field(Memrel(i)), Memrel(i))) *) lemmas part_ord_mless = part_ord_Memrel [THEN part_ord_multirel] (*irreflexivity*) lemma mless_not_refl: "\(M <# M)" apply (simp add: mless_def, clarify) apply (frule multirel_type [THEN subsetD]) apply (drule part_ord_mless) apply (simp add: part_ord_def irrefl_def) done (* N R *) lemmas mless_irrefl = mless_not_refl [THEN notE, elim!] (*transitivity*) lemma mless_trans: "\K <# M; M <# N\ \ K <# N" apply (simp add: mless_def, clarify) apply (rule_tac x = "i \ ia" in exI) apply (blast dest: multirel_Memrel_mono [OF Un_upper1 Un_upper1, THEN subsetD] multirel_Memrel_mono [OF Un_upper2 Un_upper2, THEN subsetD] intro: multirel_trans Ord_Un) done (*asymmetry*) lemma mless_not_sym: "M <# N \ \ N <# M" apply clarify apply (rule mless_not_refl [THEN notE]) apply (erule mless_trans, assumption) done lemma mless_asym: "\M <# N; \P \ N <# M\ \ P" by (blast dest: mless_not_sym) lemma mle_refl [simp]: "omultiset(M) \ M <#= M" by (simp add: mle_def) (*anti-symmetry*) lemma mle_antisym: "\M <#= N; N <#= M\ \ M = N" apply (simp add: mle_def) apply (blast dest: mless_not_sym) done (*transitivity*) lemma mle_trans: "\K <#= M; M <#= N\ \ K <#= N" apply (simp add: mle_def) apply (blast intro: mless_trans) done lemma mless_le_iff: "M <# N \ (M <#= N \ M \ N)" by (simp add: mle_def, auto) (** Monotonicity of mless **) lemma munion_less_mono2: "\M <# N; omultiset(K)\ \ K +# M <# K +# N" apply (simp add: mless_def omultiset_def, clarify) apply (rule_tac x = "i \ ia" in exI) apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff) apply (rule munion_multirel_mono2) apply (blast intro: multirel_Memrel_mono [THEN subsetD]) apply (simp add: Mult_iff_multiset) apply (blast intro: field_Memrel_mono [THEN subsetD]) done lemma munion_less_mono1: "\M <# N; omultiset(K)\ \ M +# K <# N +# K" by (force dest: munion_less_mono2 simp add: munion_commute) lemma mless_imp_omultiset: "M <# N \ omultiset(M) \ omultiset(N)" by (auto simp add: mless_def omultiset_def dest: multirel_type [THEN subsetD]) lemma munion_less_mono: "\M <# K; N <# L\ \ M +# N <# K +# L" apply (frule_tac M = M in mless_imp_omultiset) apply (frule_tac M = N in mless_imp_omultiset) apply (blast intro: munion_less_mono1 munion_less_mono2 mless_trans) done (* <#= *) lemma mle_imp_omultiset: "M <#= N \ omultiset(M) \ omultiset(N)" by (auto simp add: mle_def mless_imp_omultiset) lemma mle_mono: "\M <#= K; N <#= L\ \ M +# N <#= K +# L" apply (frule_tac M = M in mle_imp_omultiset) apply (frule_tac M = N in mle_imp_omultiset) apply (auto simp add: mle_def intro: munion_less_mono1 munion_less_mono2 munion_less_mono) done lemma omultiset_0 [iff]: "omultiset(0)" by (auto simp add: omultiset_def Mult_iff_multiset) lemma empty_leI [simp]: "omultiset(M) \ 0 <#= M" apply (simp add: mle_def mless_def) apply (subgoal_tac "\i. Ord (i) \ M \ Mult(field(Memrel(i))) ") prefer 2 apply (simp add: omultiset_def) apply (case_tac "M=0", simp_all, clarify) apply (subgoal_tac "<0 +# 0, 0 +# M> \ multirel(field (Memrel(i)), Memrel(i))") apply (rule_tac [2] one_step_implies_multirel) apply (auto simp add: Mult_iff_multiset) done lemma munion_upper1: "\omultiset(M); omultiset(N)\ \ M <#= M +# N" apply (subgoal_tac "M +# 0 <#= M +# N") apply (rule_tac [2] mle_mono, auto) done end diff --git a/src/ZF/Induct/Primrec.thy b/src/ZF/Induct/Primrec.thy --- a/src/ZF/Induct/Primrec.thy +++ b/src/ZF/Induct/Primrec.thy @@ -1,374 +1,374 @@ (* Title: ZF/Induct/Primrec.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section \Primitive Recursive Functions: the inductive definition\ theory Primrec imports ZF begin text \ Proof adopted from @{cite szasz93}. See also @{cite \page 250, exercise 11\ mendelson}. \ subsection \Basic definitions\ definition SC :: "i" where "SC \ \l \ list(nat). list_case(0, \x xs. succ(x), l)" definition CONSTANT :: "i\i" where "CONSTANT(k) \ \l \ list(nat). k" definition PROJ :: "i\i" where "PROJ(i) \ \l \ list(nat). list_case(0, \x xs. x, drop(i,l))" definition COMP :: "[i,i]\i" where "COMP(g,fs) \ \l \ list(nat). g ` map(\f. f`l, fs)" definition PREC :: "[i,i]\i" where "PREC(f,g) \ \l \ list(nat). list_case(0, \x xs. rec(x, f`xs, \y r. g ` Cons(r, Cons(y, xs))), l)" \ \Note that \g\ is applied first to \<^term>\PREC(f,g)`y\ and then to \y\!\ consts ACK :: "i\i" primrec "ACK(0) = SC" "ACK(succ(i)) = PREC (CONSTANT (ACK(i) ` [1]), COMP(ACK(i), [PROJ(0)]))" abbreviation ack :: "[i,i]\i" where "ack(x,y) \ ACK(x) ` [y]" text \ \medskip Useful special cases of evaluation. \ lemma SC: "\x \ nat; l \ list(nat)\ \ SC ` (Cons(x,l)) = succ(x)" by (simp add: SC_def) lemma CONSTANT: "l \ list(nat) \ CONSTANT(k) ` l = k" by (simp add: CONSTANT_def) lemma PROJ_0: "\x \ nat; l \ list(nat)\ \ PROJ(0) ` (Cons(x,l)) = x" by (simp add: PROJ_def) lemma COMP_1: "l \ list(nat) \ COMP(g,[f]) ` l = g` [f`l]" by (simp add: COMP_def) lemma PREC_0: "l \ list(nat) \ PREC(f,g) ` (Cons(0,l)) = f`l" by (simp add: PREC_def) lemma PREC_succ: "\x \ nat; l \ list(nat)\ \ PREC(f,g) ` (Cons(succ(x),l)) = g ` Cons(PREC(f,g)`(Cons(x,l)), Cons(x,l))" by (simp add: PREC_def) subsection \Inductive definition of the PR functions\ consts prim_rec :: i inductive domains prim_rec \ "list(nat)->nat" intros "SC \ prim_rec" "k \ nat \ CONSTANT(k) \ prim_rec" "i \ nat \ PROJ(i) \ prim_rec" "\g \ prim_rec; fs\list(prim_rec)\ \ COMP(g,fs) \ prim_rec" "\f \ prim_rec; g \ prim_rec\ \ PREC(f,g) \ prim_rec" monos list_mono con_defs SC_def CONSTANT_def PROJ_def COMP_def PREC_def type_intros nat_typechecks list.intros lam_type list_case_type drop_type map_type apply_type rec_type lemma prim_rec_into_fun [TC]: "c \ prim_rec \ c \ list(nat) -> nat" by (erule subsetD [OF prim_rec.dom_subset]) lemmas [TC] = apply_type [OF prim_rec_into_fun] declare prim_rec.intros [TC] declare nat_into_Ord [TC] declare rec_type [TC] lemma ACK_in_prim_rec [TC]: "i \ nat \ ACK(i) \ prim_rec" by (induct set: nat) simp_all lemma ack_type [TC]: "\i \ nat; j \ nat\ \ ack(i,j) \ nat" by auto subsection \Ackermann's function cases\ lemma ack_0: "j \ nat \ ack(0,j) = succ(j)" \ \PROPERTY A 1\ by (simp add: SC) lemma ack_succ_0: "ack(succ(i), 0) = ack(i,1)" \ \PROPERTY A 2\ by (simp add: CONSTANT PREC_0) lemma ack_succ_succ: "\i\nat; j\nat\ \ ack(succ(i), succ(j)) = ack(i, ack(succ(i), j))" \ \PROPERTY A 3\ by (simp add: CONSTANT PREC_succ COMP_1 PROJ_0) lemmas [simp] = ack_0 ack_succ_0 ack_succ_succ ack_type and [simp del] = ACK.simps lemma lt_ack2: "i \ nat \ j \ nat \ j < ack(i,j)" \ \PROPERTY A 4\ apply (induct i arbitrary: j set: nat) apply simp apply (induct_tac j) apply (erule_tac [2] succ_leI [THEN lt_trans1]) apply (rule nat_0I [THEN nat_0_le, THEN lt_trans]) apply auto done lemma ack_lt_ack_succ2: "\i\nat; j\nat\ \ ack(i,j) < ack(i, succ(j))" \ \PROPERTY A 5-, the single-step lemma\ by (induct set: nat) (simp_all add: lt_ack2) lemma ack_lt_mono2: "\j nat; k \ nat\ \ ack(i,j) < ack(i,k)" \ \PROPERTY A 5, monotonicity for \<\\ apply (frule lt_nat_in_nat, assumption) apply (erule succ_lt_induct) apply assumption apply (rule_tac [2] lt_trans) apply (auto intro: ack_lt_ack_succ2) done lemma ack_le_mono2: "\j\k; i\nat; k\nat\ \ ack(i,j) \ ack(i,k)" \ \PROPERTY A 5', monotonicity for \\\\ apply (rule_tac f = "\j. ack (i,j) " in Ord_lt_mono_imp_le_mono) apply (assumption | rule ack_lt_mono2 ack_type [THEN nat_into_Ord])+ done lemma ack2_le_ack1: "\i\nat; j\nat\ \ ack(i, succ(j)) \ ack(succ(i), j)" \ \PROPERTY A 6\ apply (induct_tac j) apply simp_all apply (rule ack_le_mono2) apply (rule lt_ack2 [THEN succ_leI, THEN le_trans]) apply auto done lemma ack_lt_ack_succ1: "\i \ nat; j \ nat\ \ ack(i,j) < ack(succ(i),j)" \ \PROPERTY A 7-, the single-step lemma\ apply (rule ack_lt_mono2 [THEN lt_trans2]) apply (rule_tac [4] ack2_le_ack1) apply auto done lemma ack_lt_mono1: "\i nat; k \ nat\ \ ack(i,k) < ack(j,k)" \ \PROPERTY A 7, monotonicity for \<\\ apply (frule lt_nat_in_nat, assumption) apply (erule succ_lt_induct) apply assumption apply (rule_tac [2] lt_trans) apply (auto intro: ack_lt_ack_succ1) done lemma ack_le_mono1: "\i\j; j \ nat; k \ nat\ \ ack(i,k) \ ack(j,k)" \ \PROPERTY A 7', monotonicity for \\\\ apply (rule_tac f = "\j. ack (j,k) " in Ord_lt_mono_imp_le_mono) apply (assumption | rule ack_lt_mono1 ack_type [THEN nat_into_Ord])+ done lemma ack_1: "j \ nat \ ack(1,j) = succ(succ(j))" \ \PROPERTY A 8\ by (induct set: nat) simp_all lemma ack_2: "j \ nat \ ack(succ(1),j) = succ(succ(succ(j#+j)))" \ \PROPERTY A 9\ by (induct set: nat) (simp_all add: ack_1) lemma ack_nest_bound: "\i1 \ nat; i2 \ nat; j \ nat\ \ ack(i1, ack(i2,j)) < ack(succ(succ(i1#+i2)), j)" \ \PROPERTY A 10\ apply (rule lt_trans2 [OF _ ack2_le_ack1]) apply simp apply (rule add_le_self [THEN ack_le_mono1, THEN lt_trans1]) apply auto apply (force intro: add_le_self2 [THEN ack_lt_mono1, THEN ack_lt_mono2]) done lemma ack_add_bound: "\i1 \ nat; i2 \ nat; j \ nat\ \ ack(i1,j) #+ ack(i2,j) < ack(succ(succ(succ(succ(i1#+i2)))), j)" \ \PROPERTY A 11\ apply (rule_tac j = "ack (succ (1), ack (i1 #+ i2, j))" in lt_trans) apply (simp add: ack_2) apply (rule_tac [2] ack_nest_bound [THEN lt_trans2]) apply (rule add_le_mono [THEN leI, THEN leI]) apply (auto intro: add_le_self add_le_self2 ack_le_mono1) done lemma ack_add_bound2: "\i < ack(k,j); j \ nat; k \ nat\ \ i#+j < ack(succ(succ(succ(succ(k)))), j)" \ \PROPERTY A 12.\ \ \Article uses existential quantifier but the ALF proof used \<^term>\k#+#4\.\ \ \Quantified version must be nested \\k'. \i,j \\.\ apply (rule_tac j = "ack (k,j) #+ ack (0,j) " in lt_trans) apply (rule_tac [2] ack_add_bound [THEN lt_trans2]) apply (rule add_lt_mono) apply auto done subsection \Main result\ declare list_add_type [simp] lemma SC_case: "l \ list(nat) \ SC ` l < ack(1, list_add(l))" - apply (unfold SC_def) + unfolding SC_def apply (erule list.cases) apply (simp add: succ_iff) apply (simp add: ack_1 add_le_self) done lemma lt_ack1: "\i \ nat; j \ nat\ \ i < ack(i,j)" \ \PROPERTY A 4'? Extra lemma needed for \CONSTANT\ case, constant functions.\ apply (induct_tac i) apply (simp add: nat_0_le) apply (erule lt_trans1 [OF succ_leI ack_lt_ack_succ1]) apply auto done lemma CONSTANT_case: "\l \ list(nat); k \ nat\ \ CONSTANT(k) ` l < ack(k, list_add(l))" by (simp add: CONSTANT_def lt_ack1) lemma PROJ_case [rule_format]: "l \ list(nat) \ \i \ nat. PROJ(i) ` l < ack(0, list_add(l))" - apply (unfold PROJ_def) + unfolding PROJ_def apply simp apply (erule list.induct) apply (simp add: nat_0_le) apply simp apply (rule ballI) apply (erule_tac n = i in natE) apply (simp add: add_le_self) apply simp apply (erule bspec [THEN lt_trans2]) apply (rule_tac [2] add_le_self2 [THEN succ_leI]) apply auto done text \ \medskip \COMP\ case. \ lemma COMP_map_lemma: "fs \ list({f \ prim_rec. \kf \ nat. \l \ list(nat). f`l < ack(kf, list_add(l))}) \ \k \ nat. \l \ list(nat). list_add(map(\f. f ` l, fs)) < ack(k, list_add(l))" apply (induct set: list) apply (rule_tac x = 0 in bexI) apply (simp_all add: lt_ack1 nat_0_le) apply clarify apply (rule ballI [THEN bexI]) apply (rule add_lt_mono [THEN lt_trans]) apply (rule_tac [5] ack_add_bound) apply blast apply auto done lemma COMP_case: "\kg\nat; \l \ list(nat). g`l < ack(kg, list_add(l)); fs \ list({f \ prim_rec . \kf \ nat. \l \ list(nat). f`l < ack(kf, list_add(l))})\ \ \k \ nat. \l \ list(nat). COMP(g,fs)`l < ack(k, list_add(l))" apply (simp add: COMP_def) apply (frule list_CollectD) apply (erule COMP_map_lemma [THEN bexE]) apply (rule ballI [THEN bexI]) apply (erule bspec [THEN lt_trans]) apply (rule_tac [2] lt_trans) apply (rule_tac [3] ack_nest_bound) apply (erule_tac [2] bspec [THEN ack_lt_mono2]) apply auto done text \ \medskip \PREC\ case. \ lemma PREC_case_lemma: "\\l \ list(nat). f`l #+ list_add(l) < ack(kf, list_add(l)); \l \ list(nat). g`l #+ list_add(l) < ack(kg, list_add(l)); f \ prim_rec; kf\nat; g \ prim_rec; kg\nat; l \ list(nat)\ \ PREC(f,g)`l #+ list_add(l) < ack(succ(kf#+kg), list_add(l))" - apply (unfold PREC_def) + unfolding PREC_def apply (erule list.cases) apply (simp add: lt_trans [OF nat_le_refl lt_ack2]) apply simp apply (erule ssubst) \ \get rid of the needless assumption\ apply (induct_tac a) apply simp_all txt \base case\ apply (rule lt_trans, erule bspec, assumption) apply (simp add: add_le_self [THEN ack_lt_mono1]) txt \ind step\ apply (rule succ_leI [THEN lt_trans1]) apply (rule_tac j = "g ` ll #+ mm" for ll mm in lt_trans1) apply (erule_tac [2] bspec) apply (rule nat_le_refl [THEN add_le_mono]) apply typecheck apply (simp add: add_le_self2) txt \final part of the simplification\ apply simp apply (rule add_le_self2 [THEN ack_le_mono1, THEN lt_trans1]) apply (erule_tac [4] ack_lt_mono2) apply auto done lemma PREC_case: "\f \ prim_rec; kf\nat; g \ prim_rec; kg\nat; \l \ list(nat). f`l < ack(kf, list_add(l)); \l \ list(nat). g`l < ack(kg, list_add(l))\ \ \k \ nat. \l \ list(nat). PREC(f,g)`l< ack(k, list_add(l))" apply (rule ballI [THEN bexI]) apply (rule lt_trans1 [OF add_le_self PREC_case_lemma]) apply typecheck apply (blast intro: ack_add_bound2 list_add_type)+ done lemma ack_bounds_prim_rec: "f \ prim_rec \ \k \ nat. \l \ list(nat). f`l < ack(k, list_add(l))" apply (induct set: prim_rec) apply (auto intro: SC_case CONSTANT_case PROJ_case COMP_case PREC_case) done theorem ack_not_prim_rec: "(\l \ list(nat). list_case(0, \x xs. ack(x,x), l)) \ prim_rec" apply (rule notI) apply (drule ack_bounds_prim_rec) apply force done end diff --git a/src/ZF/Induct/PropLog.thy b/src/ZF/Induct/PropLog.thy --- a/src/ZF/Induct/PropLog.thy +++ b/src/ZF/Induct/PropLog.thy @@ -1,340 +1,340 @@ (* Title: ZF/Induct/PropLog.thy Author: Tobias Nipkow \ Lawrence C Paulson Copyright 1993 University of Cambridge *) section \Meta-theory of propositional logic\ theory PropLog imports ZF begin text \ Datatype definition of propositional logic formulae and inductive definition of the propositional tautologies. Inductive definition of propositional logic. Soundness and completeness w.r.t.\ truth-tables. Prove: If \H |= p\ then \G |= p\ where \G \ Fin(H)\ \ subsection \The datatype of propositions\ consts propn :: i datatype propn = Fls | Var ("n \ nat") (\#_\ [100] 100) | Imp ("p \ propn", "q \ propn") (infixr \\\ 90) subsection \The proof system\ consts thms :: "i \ i" abbreviation thms_syntax :: "[i,i] \ o" (infixl \|-\ 50) where "H |- p \ p \ thms(H)" inductive domains "thms(H)" \ "propn" intros H: "\p \ H; p \ propn\ \ H |- p" K: "\p \ propn; q \ propn\ \ H |- p\q\p" S: "\p \ propn; q \ propn; r \ propn\ \ H |- (p\q\r) \ (p\q) \ p\r" DN: "p \ propn \ H |- ((p\Fls) \ Fls) \ p" MP: "\H |- p\q; H |- p; p \ propn; q \ propn\ \ H |- q" type_intros "propn.intros" declare propn.intros [simp] subsection \The semantics\ subsubsection \Semantics of propositional logic.\ consts is_true_fun :: "[i,i] \ i" primrec "is_true_fun(Fls, t) = 0" "is_true_fun(Var(v), t) = (if v \ t then 1 else 0)" "is_true_fun(p\q, t) = (if is_true_fun(p,t) = 1 then is_true_fun(q,t) else 1)" definition is_true :: "[i,i] \ o" where "is_true(p,t) \ is_true_fun(p,t) = 1" \ \this definition is required since predicates can't be recursive\ lemma is_true_Fls [simp]: "is_true(Fls,t) \ False" by (simp add: is_true_def) lemma is_true_Var [simp]: "is_true(#v,t) \ v \ t" by (simp add: is_true_def) lemma is_true_Imp [simp]: "is_true(p\q,t) \ (is_true(p,t)\is_true(q,t))" by (simp add: is_true_def) subsubsection \Logical consequence\ text \ For every valuation, if all elements of \H\ are true then so is \p\. \ definition logcon :: "[i,i] \ o" (infixl \|=\ 50) where "H |= p \ \t. (\q \ H. is_true(q,t)) \ is_true(p,t)" text \ A finite set of hypotheses from \t\ and the \Var\s in \p\. \ consts hyps :: "[i,i] \ i" primrec "hyps(Fls, t) = 0" "hyps(Var(v), t) = (if v \ t then {#v} else {#v\Fls})" "hyps(p\q, t) = hyps(p,t) \ hyps(q,t)" subsection \Proof theory of propositional logic\ lemma thms_mono: "G \ H \ thms(G) \ thms(H)" apply (unfold thms.defs) apply (rule lfp_mono) apply (rule thms.bnd_mono)+ apply (assumption | rule univ_mono basic_monos)+ done lemmas thms_in_pl = thms.dom_subset [THEN subsetD] inductive_cases ImpE: "p\q \ propn" lemma thms_MP: "\H |- p\q; H |- p\ \ H |- q" \ \Stronger Modus Ponens rule: no typechecking!\ apply (rule thms.MP) apply (erule asm_rl thms_in_pl thms_in_pl [THEN ImpE])+ done lemma thms_I: "p \ propn \ H |- p\p" \ \Rule is called \I\ for Identity Combinator, not for Introduction.\ apply (rule thms.S [THEN thms_MP, THEN thms_MP]) apply (rule_tac [5] thms.K) apply (rule_tac [4] thms.K) apply simp_all done subsubsection \Weakening, left and right\ lemma weaken_left: "\G \ H; G|-p\ \ H|-p" \ \Order of premises is convenient with \THEN\\ by (erule thms_mono [THEN subsetD]) lemma weaken_left_cons: "H |- p \ cons(a,H) |- p" by (erule subset_consI [THEN weaken_left]) lemmas weaken_left_Un1 = Un_upper1 [THEN weaken_left] lemmas weaken_left_Un2 = Un_upper2 [THEN weaken_left] lemma weaken_right: "\H |- q; p \ propn\ \ H |- p\q" by (simp_all add: thms.K [THEN thms_MP] thms_in_pl) subsubsection \The deduction theorem\ theorem deduction: "\cons(p,H) |- q; p \ propn\ \ H |- p\q" apply (erule thms.induct) apply (blast intro: thms_I thms.H [THEN weaken_right]) apply (blast intro: thms.K [THEN weaken_right]) apply (blast intro: thms.S [THEN weaken_right]) apply (blast intro: thms.DN [THEN weaken_right]) apply (blast intro: thms.S [THEN thms_MP [THEN thms_MP]]) done subsubsection \The cut rule\ lemma cut: "\H|-p; cons(p,H) |- q\ \ H |- q" apply (rule deduction [THEN thms_MP]) apply (simp_all add: thms_in_pl) done lemma thms_FlsE: "\H |- Fls; p \ propn\ \ H |- p" apply (rule thms.DN [THEN thms_MP]) apply (rule_tac [2] weaken_right) apply (simp_all add: propn.intros) done lemma thms_notE: "\H |- p\Fls; H |- p; q \ propn\ \ H |- q" by (erule thms_MP [THEN thms_FlsE]) subsubsection \Soundness of the rules wrt truth-table semantics\ theorem soundness: "H |- p \ H |= p" - apply (unfold logcon_def) + unfolding logcon_def apply (induct set: thms) apply auto done subsection \Completeness\ subsubsection \Towards the completeness proof\ lemma Fls_Imp: "\H |- p\Fls; q \ propn\ \ H |- p\q" apply (frule thms_in_pl) apply (rule deduction) apply (rule weaken_left_cons [THEN thms_notE]) apply (blast intro: thms.H elim: ImpE)+ done lemma Imp_Fls: "\H |- p; H |- q\Fls\ \ H |- (p\q)\Fls" apply (frule thms_in_pl) apply (frule thms_in_pl [of concl: "q\Fls"]) apply (rule deduction) apply (erule weaken_left_cons [THEN thms_MP]) apply (rule consI1 [THEN thms.H, THEN thms_MP]) apply (blast intro: weaken_left_cons elim: ImpE)+ done lemma hyps_thms_if: "p \ propn \ hyps(p,t) |- (if is_true(p,t) then p else p\Fls)" \ \Typical example of strengthening the induction statement.\ apply simp apply (induct_tac p) apply (simp_all add: thms_I thms.H) apply (safe elim!: Fls_Imp [THEN weaken_left_Un1] Fls_Imp [THEN weaken_left_Un2]) apply (blast intro: weaken_left_Un1 weaken_left_Un2 weaken_right Imp_Fls)+ done lemma logcon_thms_p: "\p \ propn; 0 |= p\ \ hyps(p,t) |- p" \ \Key lemma for completeness; yields a set of assumptions satisfying \p\\ apply (drule hyps_thms_if) apply (simp add: logcon_def) done text \ For proving certain theorems in our new propositional logic. \ lemmas propn_SIs = propn.intros deduction and propn_Is = thms_in_pl thms.H thms.H [THEN thms_MP] text \ The excluded middle in the form of an elimination rule. \ lemma thms_excluded_middle: "\p \ propn; q \ propn\ \ H |- (p\q) \ ((p\Fls)\q) \ q" apply (rule deduction [THEN deduction]) apply (rule thms.DN [THEN thms_MP]) apply (best intro!: propn_SIs intro: propn_Is)+ done lemma thms_excluded_middle_rule: "\cons(p,H) |- q; cons(p\Fls,H) |- q; p \ propn\ \ H |- q" \ \Hard to prove directly because it requires cuts\ apply (rule thms_excluded_middle [THEN thms_MP, THEN thms_MP]) apply (blast intro!: propn_SIs intro: propn_Is)+ done subsubsection \Completeness -- lemmas for reducing the set of assumptions\ text \ For the case \<^prop>\hyps(p,t)-cons(#v,Y) |- p\ we also have \<^prop>\hyps(p,t)-{#v} \ hyps(p, t-{v})\. \ lemma hyps_Diff: "p \ propn \ hyps(p, t-{v}) \ cons(#v\Fls, hyps(p,t)-{#v})" by (induct set: propn) auto text \ For the case \<^prop>\hyps(p,t)-cons(#v \ Fls,Y) |- p\ we also have \<^prop>\hyps(p,t)-{#v\Fls} \ hyps(p, cons(v,t))\. \ lemma hyps_cons: "p \ propn \ hyps(p, cons(v,t)) \ cons(#v, hyps(p,t)-{#v\Fls})" by (induct set: propn) auto text \Two lemmas for use with \weaken_left\\ lemma cons_Diff_same: "B-C \ cons(a, B-cons(a,C))" by blast lemma cons_Diff_subset2: "cons(a, B-{c}) - D \ cons(a, B-cons(c,D))" by blast text \ The set \<^term>\hyps(p,t)\ is finite, and elements have the form \<^term>\#v\ or \<^term>\#v\Fls\; could probably prove the stronger \<^prop>\hyps(p,t) \ Fin(hyps(p,0) \ hyps(p,nat))\. \ lemma hyps_finite: "p \ propn \ hyps(p,t) \ Fin(\v \ nat. {#v, #v\Fls})" by (induct set: propn) auto lemmas Diff_weaken_left = Diff_mono [OF _ subset_refl, THEN weaken_left] text \ Induction on the finite set of assumptions \<^term>\hyps(p,t0)\. We may repeatedly subtract assumptions until none are left! \ lemma completeness_0_lemma [rule_format]: "\p \ propn; 0 |= p\ \ \t. hyps(p,t) - hyps(p,t0) |- p" apply (frule hyps_finite) apply (erule Fin_induct) apply (simp add: logcon_thms_p Diff_0) txt \inductive step\ apply safe txt \Case \<^prop>\hyps(p,t)-cons(#v,Y) |- p\\ apply (rule thms_excluded_middle_rule) apply (erule_tac [3] propn.intros) apply (blast intro: cons_Diff_same [THEN weaken_left]) apply (blast intro: cons_Diff_subset2 [THEN weaken_left] hyps_Diff [THEN Diff_weaken_left]) txt \Case \<^prop>\hyps(p,t)-cons(#v \ Fls,Y) |- p\\ apply (rule thms_excluded_middle_rule) apply (erule_tac [3] propn.intros) apply (blast intro: cons_Diff_subset2 [THEN weaken_left] hyps_cons [THEN Diff_weaken_left]) apply (blast intro: cons_Diff_same [THEN weaken_left]) done subsubsection \Completeness theorem\ lemma completeness_0: "\p \ propn; 0 |= p\ \ 0 |- p" \ \The base case for completeness\ apply (rule Diff_cancel [THEN subst]) apply (blast intro: completeness_0_lemma) done lemma logcon_Imp: "\cons(p,H) |= q\ \ H |= p\q" \ \A semantic analogue of the Deduction Theorem\ by (simp add: logcon_def) lemma completeness: "H \ Fin(propn) \ p \ propn \ H |= p \ H |- p" apply (induct arbitrary: p set: Fin) apply (safe intro!: completeness_0) apply (rule weaken_left_cons [THEN thms_MP]) apply (blast intro!: logcon_Imp propn.intros) apply (blast intro: propn_Is) done theorem thms_iff: "H \ Fin(propn) \ H |- p \ H |= p \ p \ propn" by (blast intro: soundness completeness thms_in_pl) end diff --git a/src/ZF/Induct/Rmap.thy b/src/ZF/Induct/Rmap.thy --- a/src/ZF/Induct/Rmap.thy +++ b/src/ZF/Induct/Rmap.thy @@ -1,70 +1,70 @@ (* Title: ZF/Induct/Rmap.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section \An operator to ``map'' a relation over a list\ theory Rmap imports ZF begin consts rmap :: "i\i" inductive domains "rmap(r)" \ "list(domain(r)) \ list(range(r))" intros NilI: "\Nil,Nil\ \ rmap(r)" ConsI: "\\x,y\: r; \xs,ys\ \ rmap(r)\ \ \ rmap(r)" type_intros domainI rangeI list.intros lemma rmap_mono: "r \ s \ rmap(r) \ rmap(s)" apply (unfold rmap.defs) apply (rule lfp_mono) apply (rule rmap.bnd_mono)+ apply (assumption | rule Sigma_mono list_mono domain_mono range_mono basic_monos)+ done inductive_cases Nil_rmap_case [elim!]: "\Nil,zs\ \ rmap(r)" and Cons_rmap_case [elim!]: " \ rmap(r)" declare rmap.intros [intro] lemma rmap_rel_type: "r \ A \ B \ rmap(r) \ list(A) \ list(B)" apply (rule rmap.dom_subset [THEN subset_trans]) apply (assumption | rule domain_rel_subset range_rel_subset Sigma_mono list_mono)+ done lemma rmap_total: "A \ domain(r) \ list(A) \ domain(rmap(r))" apply (rule subsetI) apply (erule list.induct) apply blast+ done lemma rmap_functional: "function(r) \ function(rmap(r))" - apply (unfold function_def) + unfolding function_def apply (rule impI [THEN allI, THEN allI]) apply (erule rmap.induct) apply blast+ done text \ \medskip If \f\ is a function then \rmap(f)\ behaves as expected. \ lemma rmap_fun_type: "f \ A->B \ rmap(f): list(A)->list(B)" by (simp add: Pi_iff rmap_rel_type rmap_functional rmap_total) lemma rmap_Nil: "rmap(f)`Nil = Nil" by (unfold apply_def) blast lemma rmap_Cons: "\f \ A->B; x \ A; xs: list(A)\ \ rmap(f) ` Cons(x,xs) = Cons(f`x, rmap(f)`xs)" by (blast intro: apply_equality apply_Pair rmap_fun_type rmap.intros) end diff --git a/src/ZF/Induct/Term.thy b/src/ZF/Induct/Term.thy --- a/src/ZF/Induct/Term.thy +++ b/src/ZF/Induct/Term.thy @@ -1,284 +1,284 @@ (* Title: ZF/Induct/Term.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section \Terms over an alphabet\ theory Term imports ZF begin text \ Illustrates the list functor (essentially the same type as in \Trees_Forest\). \ consts "term" :: "i \ i" datatype "term(A)" = Apply ("a \ A", "l \ list(term(A))") monos list_mono type_elims list_univ [THEN subsetD, elim_format] declare Apply [TC] definition term_rec :: "[i, [i, i, i] \ i] \ i" where "term_rec(t,d) \ Vrec(t, \t g. term_case(\x zs. d(x, zs, map(\z. g`z, zs)), t))" definition term_map :: "[i \ i, i] \ i" where "term_map(f,t) \ term_rec(t, \x zs rs. Apply(f(x), rs))" definition term_size :: "i \ i" where "term_size(t) \ term_rec(t, \x zs rs. succ(list_add(rs)))" definition reflect :: "i \ i" where "reflect(t) \ term_rec(t, \x zs rs. Apply(x, rev(rs)))" definition preorder :: "i \ i" where "preorder(t) \ term_rec(t, \x zs rs. Cons(x, flat(rs)))" definition postorder :: "i \ i" where "postorder(t) \ term_rec(t, \x zs rs. flat(rs) @ [x])" lemma term_unfold: "term(A) = A * list(term(A))" by (fast intro!: term.intros [unfolded term.con_defs] elim: term.cases [unfolded term.con_defs]) lemma term_induct2: "\t \ term(A); \x. \x \ A\ \ P(Apply(x,Nil)); \x z zs. \x \ A; z \ term(A); zs: list(term(A)); P(Apply(x,zs)) \ \ P(Apply(x, Cons(z,zs))) \ \ P(t)" \ \Induction on \<^term>\term(A)\ followed by induction on \<^term>\list\.\ apply (induct_tac t) apply (erule list.induct) apply (auto dest: list_CollectD) done lemma term_induct_eqn [consumes 1, case_names Apply]: "\t \ term(A); \x zs. \x \ A; zs: list(term(A)); map(f,zs) = map(g,zs)\ \ f(Apply(x,zs)) = g(Apply(x,zs)) \ \ f(t) = g(t)" \ \Induction on \<^term>\term(A)\ to prove an equation.\ apply (induct_tac t) apply (auto dest: map_list_Collect list_CollectD) done text \ \medskip Lemmas to justify using \<^term>\term\ in other recursive type definitions. \ lemma term_mono: "A \ B \ term(A) \ term(B)" apply (unfold term.defs) apply (rule lfp_mono) apply (rule term.bnd_mono)+ apply (rule univ_mono basic_monos| assumption)+ done lemma term_univ: "term(univ(A)) \ univ(A)" \ \Easily provable by induction also\ apply (unfold term.defs term.con_defs) apply (rule lfp_lowerbound) apply (rule_tac [2] A_subset_univ [THEN univ_mono]) apply safe apply (assumption | rule Pair_in_univ list_univ [THEN subsetD])+ done lemma term_subset_univ: "A \ univ(B) \ term(A) \ univ(B)" apply (rule subset_trans) apply (erule term_mono) apply (rule term_univ) done lemma term_into_univ: "\t \ term(A); A \ univ(B)\ \ t \ univ(B)" by (rule term_subset_univ [THEN subsetD]) text \ \medskip \term_rec\ -- by \Vset\ recursion. \ lemma map_lemma: "\l \ list(A); Ord(i); rank(l) \ map(\z. (\x \ Vset(i).h(x)) ` z, l) = map(h,l)" \ \\<^term>\map\ works correctly on the underlying list of terms.\ apply (induct set: list) apply simp apply (subgoal_tac "rank (a) rank (l) < i") apply (simp add: rank_of_Ord) apply (simp add: list.con_defs) apply (blast dest: rank_rls [THEN lt_trans]) done lemma term_rec [simp]: "ts \ list(A) \ term_rec(Apply(a,ts), d) = d(a, ts, map (\z. term_rec(z,d), ts))" \ \Typing premise is necessary to invoke \map_lemma\.\ apply (rule term_rec_def [THEN def_Vrec, THEN trans]) apply (unfold term.con_defs) apply (simp add: rank_pair2 map_lemma) done lemma term_rec_type: assumes t: "t \ term(A)" and a: "\x zs r. \x \ A; zs: list(term(A)); r \ list(\t \ term(A). C(t))\ \ d(x, zs, r): C(Apply(x,zs))" shows "term_rec(t,d) \ C(t)" \ \Slightly odd typing condition on \r\ in the second premise!\ using t apply induct apply (frule list_CollectD) apply (subst term_rec) apply (assumption | rule a)+ apply (erule list.induct) apply auto done lemma def_term_rec: "\\t. j(t)\term_rec(t,d); ts: list(A)\ \ j(Apply(a,ts)) = d(a, ts, map(\Z. j(Z), ts))" apply (simp only:) apply (erule term_rec) done lemma term_rec_simple_type [TC]: "\t \ term(A); \x zs r. \x \ A; zs: list(term(A)); r \ list(C)\ \ d(x, zs, r): C \ \ term_rec(t,d) \ C" apply (erule term_rec_type) apply (drule subset_refl [THEN UN_least, THEN list_mono, THEN subsetD]) apply simp done text \ \medskip \<^term>\term_map\. \ lemma term_map [simp]: "ts \ list(A) \ term_map(f, Apply(a, ts)) = Apply(f(a), map(term_map(f), ts))" by (rule term_map_def [THEN def_term_rec]) lemma term_map_type [TC]: "\t \ term(A); \x. x \ A \ f(x): B\ \ term_map(f,t) \ term(B)" - apply (unfold term_map_def) + unfolding term_map_def apply (erule term_rec_simple_type) apply fast done lemma term_map_type2 [TC]: "t \ term(A) \ term_map(f,t) \ term({f(u). u \ A})" apply (erule term_map_type) apply (erule RepFunI) done text \ \medskip \<^term>\term_size\. \ lemma term_size [simp]: "ts \ list(A) \ term_size(Apply(a, ts)) = succ(list_add(map(term_size, ts)))" by (rule term_size_def [THEN def_term_rec]) lemma term_size_type [TC]: "t \ term(A) \ term_size(t) \ nat" by (auto simp add: term_size_def) text \ \medskip \reflect\. \ lemma reflect [simp]: "ts \ list(A) \ reflect(Apply(a, ts)) = Apply(a, rev(map(reflect, ts)))" by (rule reflect_def [THEN def_term_rec]) lemma reflect_type [TC]: "t \ term(A) \ reflect(t) \ term(A)" by (auto simp add: reflect_def) text \ \medskip \preorder\. \ lemma preorder [simp]: "ts \ list(A) \ preorder(Apply(a, ts)) = Cons(a, flat(map(preorder, ts)))" by (rule preorder_def [THEN def_term_rec]) lemma preorder_type [TC]: "t \ term(A) \ preorder(t) \ list(A)" by (simp add: preorder_def) text \ \medskip \postorder\. \ lemma postorder [simp]: "ts \ list(A) \ postorder(Apply(a, ts)) = flat(map(postorder, ts)) @ [a]" by (rule postorder_def [THEN def_term_rec]) lemma postorder_type [TC]: "t \ term(A) \ postorder(t) \ list(A)" by (simp add: postorder_def) text \ \medskip Theorems about \term_map\. \ declare map_compose [simp] lemma term_map_ident: "t \ term(A) \ term_map(\u. u, t) = t" by (induct rule: term_induct_eqn) simp lemma term_map_compose: "t \ term(A) \ term_map(f, term_map(g,t)) = term_map(\u. f(g(u)), t)" by (induct rule: term_induct_eqn) simp lemma term_map_reflect: "t \ term(A) \ term_map(f, reflect(t)) = reflect(term_map(f,t))" by (induct rule: term_induct_eqn) (simp add: rev_map_distrib [symmetric]) text \ \medskip Theorems about \term_size\. \ lemma term_size_term_map: "t \ term(A) \ term_size(term_map(f,t)) = term_size(t)" by (induct rule: term_induct_eqn) simp lemma term_size_reflect: "t \ term(A) \ term_size(reflect(t)) = term_size(t)" by (induct rule: term_induct_eqn) (simp add: rev_map_distrib [symmetric] list_add_rev) lemma term_size_length: "t \ term(A) \ term_size(t) = length(preorder(t))" by (induct rule: term_induct_eqn) (simp add: length_flat) text \ \medskip Theorems about \reflect\. \ lemma reflect_reflect_ident: "t \ term(A) \ reflect(reflect(t)) = t" by (induct rule: term_induct_eqn) (simp add: rev_map_distrib) text \ \medskip Theorems about preorder. \ lemma preorder_term_map: "t \ term(A) \ preorder(term_map(f,t)) = map(f, preorder(t))" by (induct rule: term_induct_eqn) (simp add: map_flat) lemma preorder_reflect_eq_rev_postorder: "t \ term(A) \ preorder(reflect(t)) = rev(postorder(t))" by (induct rule: term_induct_eqn) (simp add: rev_app_distrib rev_flat rev_map_distrib [symmetric]) end diff --git a/src/ZF/Induct/Tree_Forest.thy b/src/ZF/Induct/Tree_Forest.thy --- a/src/ZF/Induct/Tree_Forest.thy +++ b/src/ZF/Induct/Tree_Forest.thy @@ -1,251 +1,251 @@ (* Title: ZF/Induct/Tree_Forest.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section \Trees and forests, a mutually recursive type definition\ theory Tree_Forest imports ZF begin subsection \Datatype definition\ consts tree :: "i \ i" forest :: "i \ i" tree_forest :: "i \ i" datatype "tree(A)" = Tcons ("a \ A", "f \ forest(A)") and "forest(A)" = Fnil | Fcons ("t \ tree(A)", "f \ forest(A)") (* FIXME *) lemmas tree'induct = tree_forest.mutual_induct [THEN conjunct1, THEN spec, THEN [2] rev_mp, of concl: _ t, consumes 1] and forest'induct = tree_forest.mutual_induct [THEN conjunct2, THEN spec, THEN [2] rev_mp, of concl: _ f, consumes 1] for t f declare tree_forest.intros [simp, TC] lemma tree_def: "tree(A) \ Part(tree_forest(A), Inl)" by (simp only: tree_forest.defs) lemma forest_def: "forest(A) \ Part(tree_forest(A), Inr)" by (simp only: tree_forest.defs) text \ \medskip \<^term>\tree_forest(A)\ as the union of \<^term>\tree(A)\ and \<^term>\forest(A)\. \ lemma tree_subset_TF: "tree(A) \ tree_forest(A)" apply (unfold tree_forest.defs) apply (rule Part_subset) done lemma treeI [TC]: "x \ tree(A) \ x \ tree_forest(A)" by (rule tree_subset_TF [THEN subsetD]) lemma forest_subset_TF: "forest(A) \ tree_forest(A)" apply (unfold tree_forest.defs) apply (rule Part_subset) done lemma treeI' [TC]: "x \ forest(A) \ x \ tree_forest(A)" by (rule forest_subset_TF [THEN subsetD]) lemma TF_equals_Un: "tree(A) \ forest(A) = tree_forest(A)" apply (insert tree_subset_TF forest_subset_TF) apply (auto intro!: equalityI tree_forest.intros elim: tree_forest.cases) done lemma tree_forest_unfold: "tree_forest(A) = (A \ forest(A)) + ({0} + tree(A) \ forest(A))" \ \NOT useful, but interesting \dots\ supply rews = tree_forest.con_defs tree_def forest_def apply (unfold tree_def forest_def) apply (fast intro!: tree_forest.intros [unfolded rews, THEN PartD1] elim: tree_forest.cases [unfolded rews]) done lemma tree_forest_unfold': "tree_forest(A) = A \ Part(tree_forest(A), \w. Inr(w)) + {0} + Part(tree_forest(A), \w. Inl(w)) * Part(tree_forest(A), \w. Inr(w))" by (rule tree_forest_unfold [unfolded tree_def forest_def]) lemma tree_unfold: "tree(A) = {Inl(x). x \ A \ forest(A)}" apply (unfold tree_def forest_def) apply (rule Part_Inl [THEN subst]) apply (rule tree_forest_unfold' [THEN subst_context]) done lemma forest_unfold: "forest(A) = {Inr(x). x \ {0} + tree(A)*forest(A)}" apply (unfold tree_def forest_def) apply (rule Part_Inr [THEN subst]) apply (rule tree_forest_unfold' [THEN subst_context]) done text \ \medskip Type checking for recursor: Not needed; possibly interesting? \ lemma TF_rec_type: "\z \ tree_forest(A); \x f r. \x \ A; f \ forest(A); r \ C(f) \ \ b(x,f,r) \ C(Tcons(x,f)); c \ C(Fnil); \t f r1 r2. \t \ tree(A); f \ forest(A); r1 \ C(t); r2 \ C(f) \ \ d(t,f,r1,r2) \ C(Fcons(t,f)) \ \ tree_forest_rec(b,c,d,z) \ C(z)" by (induct_tac z) simp_all lemma tree_forest_rec_type: "\\x f r. \x \ A; f \ forest(A); r \ D(f) \ \ b(x,f,r) \ C(Tcons(x,f)); c \ D(Fnil); \t f r1 r2. \t \ tree(A); f \ forest(A); r1 \ C(t); r2 \ D(f) \ \ d(t,f,r1,r2) \ D(Fcons(t,f)) \ \ (\t \ tree(A). tree_forest_rec(b,c,d,t) \ C(t)) \ (\f \ forest(A). tree_forest_rec(b,c,d,f) \ D(f))" \ \Mutually recursive version.\ - apply (unfold Ball_def) + unfolding Ball_def apply (rule tree_forest.mutual_induct) apply simp_all done subsection \Operations\ consts map :: "[i \ i, i] \ i" size :: "i \ i" preorder :: "i \ i" list_of_TF :: "i \ i" of_list :: "i \ i" reflect :: "i \ i" primrec "list_of_TF (Tcons(x,f)) = [Tcons(x,f)]" "list_of_TF (Fnil) = []" "list_of_TF (Fcons(t,tf)) = Cons (t, list_of_TF(tf))" primrec "of_list([]) = Fnil" "of_list(Cons(t,l)) = Fcons(t, of_list(l))" primrec "map (h, Tcons(x,f)) = Tcons(h(x), map(h,f))" "map (h, Fnil) = Fnil" "map (h, Fcons(t,tf)) = Fcons (map(h, t), map(h, tf))" primrec "size (Tcons(x,f)) = succ(size(f))" "size (Fnil) = 0" "size (Fcons(t,tf)) = size(t) #+ size(tf)" primrec "preorder (Tcons(x,f)) = Cons(x, preorder(f))" "preorder (Fnil) = Nil" "preorder (Fcons(t,tf)) = preorder(t) @ preorder(tf)" primrec "reflect (Tcons(x,f)) = Tcons(x, reflect(f))" "reflect (Fnil) = Fnil" "reflect (Fcons(t,tf)) = of_list (list_of_TF (reflect(tf)) @ Cons(reflect(t), Nil))" text \ \medskip \list_of_TF\ and \of_list\. \ lemma list_of_TF_type [TC]: "z \ tree_forest(A) \ list_of_TF(z) \ list(tree(A))" by (induct set: tree_forest) simp_all lemma of_list_type [TC]: "l \ list(tree(A)) \ of_list(l) \ forest(A)" by (induct set: list) simp_all text \ \medskip \map\. \ lemma assumes "\x. x \ A \ h(x): B" shows map_tree_type: "t \ tree(A) \ map(h,t) \ tree(B)" and map_forest_type: "f \ forest(A) \ map(h,f) \ forest(B)" using assms by (induct rule: tree'induct forest'induct) simp_all text \ \medskip \size\. \ lemma size_type [TC]: "z \ tree_forest(A) \ size(z) \ nat" by (induct set: tree_forest) simp_all text \ \medskip \preorder\. \ lemma preorder_type [TC]: "z \ tree_forest(A) \ preorder(z) \ list(A)" by (induct set: tree_forest) simp_all text \ \medskip Theorems about \list_of_TF\ and \of_list\. \ lemma forest_induct [consumes 1, case_names Fnil Fcons]: "\f \ forest(A); R(Fnil); \t f. \t \ tree(A); f \ forest(A); R(f)\ \ R(Fcons(t,f)) \ \ R(f)" \ \Essentially the same as list induction.\ apply (erule tree_forest.mutual_induct [THEN conjunct2, THEN spec, THEN [2] rev_mp]) apply (rule TrueI) apply simp apply simp done lemma forest_iso: "f \ forest(A) \ of_list(list_of_TF(f)) = f" by (induct rule: forest_induct) simp_all lemma tree_list_iso: "ts: list(tree(A)) \ list_of_TF(of_list(ts)) = ts" by (induct set: list) simp_all text \ \medskip Theorems about \map\. \ lemma map_ident: "z \ tree_forest(A) \ map(\u. u, z) = z" by (induct set: tree_forest) simp_all lemma map_compose: "z \ tree_forest(A) \ map(h, map(j,z)) = map(\u. h(j(u)), z)" by (induct set: tree_forest) simp_all text \ \medskip Theorems about \size\. \ lemma size_map: "z \ tree_forest(A) \ size(map(h,z)) = size(z)" by (induct set: tree_forest) simp_all lemma size_length: "z \ tree_forest(A) \ size(z) = length(preorder(z))" by (induct set: tree_forest) (simp_all add: length_app) text \ \medskip Theorems about \preorder\. \ lemma preorder_map: "z \ tree_forest(A) \ preorder(map(h,z)) = List.map(h, preorder(z))" by (induct set: tree_forest) (simp_all add: map_app_distrib) end diff --git a/src/ZF/IntDiv.thy b/src/ZF/IntDiv.thy --- a/src/ZF/IntDiv.thy +++ b/src/ZF/IntDiv.thy @@ -1,1771 +1,1771 @@ (* Title: ZF/IntDiv.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1999 University of Cambridge Here is the division algorithm in ML: fun posDivAlg (a,b) = if a1,a+b) else let val (q,r) = negDivAlg(a, 2*b) in if 0<=r-b then (2*q+1, r-b) else (2*q, r) end; fun negateSnd (q,r:int) = (q,\r); fun divAlg (a,b) = if 0<=a then if b>0 then posDivAlg (a,b) else if a=0 then (0,0) else negateSnd (negDivAlg (\a,\b)) else if 0a,\b)); *) section\The Division Operators Div and Mod\ theory IntDiv imports Bin OrderArith begin definition quorem :: "[i,i] \ o" where "quorem \ \\a,b\ \q,r\. a = b$*q $+ r \ (#0$ #0$\r \ r$(#0$ b$ r $\ #0)" definition adjust :: "[i,i] \ i" where "adjust(b) \ \\q,r\. if #0 $\ r$-b then <#2$*q $+ #1,r$-b> else <#2$*q,r>" (** the division algorithm **) definition posDivAlg :: "i \ i" where (*for the case a>=0, b>0*) (*recdef posDivAlg "inv_image less_than (\\a,b\. nat_of(a $- b $+ #1))"*) "posDivAlg(ab) \ wfrec(measure(int*int, \\a,b\. nat_of (a $- b $+ #1)), ab, \\a,b\ f. if (a$#0) then <#0,a> else adjust(b, f ` ))" (*for the case a\0, b\0*) definition negDivAlg :: "i \ i" where (*recdef negDivAlg "inv_image less_than (\\a,b\. nat_of(- a $- b))"*) "negDivAlg(ab) \ wfrec(measure(int*int, \\a,b\. nat_of ($- a $- b)), ab, \\a,b\ f. if (#0 $\ a$+b | b$\#0) then <#-1,a$+b> else adjust(b, f ` ))" (*for the general case @{term"b\0"}*) definition negateSnd :: "i \ i" where "negateSnd \ \\q,r\. " (*The full division algorithm considers all possible signs for a, b including the special case a=0, b<0, because negDivAlg requires a<0*) definition divAlg :: "i \ i" where "divAlg \ \\a,b\. if #0 $\ a then if #0 $\ b then posDivAlg (\a,b\) else if a=#0 then <#0,#0> else negateSnd (negDivAlg (<$-a,$-b>)) else if #0$a,b\) else negateSnd (posDivAlg (<$-a,$-b>))" definition zdiv :: "[i,i]\i" (infixl \zdiv\ 70) where "a zdiv b \ fst (divAlg ())" definition zmod :: "[i,i]\i" (infixl \zmod\ 70) where "a zmod b \ snd (divAlg ())" (** Some basic laws by Sidi Ehmety (need linear arithmetic!) **) lemma zspos_add_zspos_imp_zspos: "\#0 $< x; #0 $< y\ \ #0 $< x $+ y" apply (rule_tac y = "y" in zless_trans) apply (rule_tac [2] zdiff_zless_iff [THEN iffD1]) apply auto done lemma zpos_add_zpos_imp_zpos: "\#0 $\ x; #0 $\ y\ \ #0 $\ x $+ y" apply (rule_tac y = "y" in zle_trans) apply (rule_tac [2] zdiff_zle_iff [THEN iffD1]) apply auto done lemma zneg_add_zneg_imp_zneg: "\x $< #0; y $< #0\ \ x $+ y $< #0" apply (rule_tac y = "y" in zless_trans) apply (rule zless_zdiff_iff [THEN iffD1]) apply auto done (* this theorem is used below *) lemma zneg_or_0_add_zneg_or_0_imp_zneg_or_0: "\x $\ #0; y $\ #0\ \ x $+ y $\ #0" apply (rule_tac y = "y" in zle_trans) apply (rule zle_zdiff_iff [THEN iffD1]) apply auto done lemma zero_lt_zmagnitude: "\#0 $< k; k \ int\ \ 0 < zmagnitude(k)" apply (drule zero_zless_imp_znegative_zminus) apply (drule_tac [2] zneg_int_of) apply (auto simp add: zminus_equation [of k]) apply (subgoal_tac "0 < zmagnitude ($# succ (n))") apply simp apply (simp only: zmagnitude_int_of) apply simp done (*** Inequality lemmas involving $#succ(m) ***) lemma zless_add_succ_iff: "(w $< z $+ $# succ(m)) \ (w $< z $+ $#m | intify(w) = z $+ $#m)" apply (auto simp add: zless_iff_succ_zadd zadd_assoc int_of_add [symmetric]) apply (rule_tac [3] x = "0" in bexI) apply (cut_tac m = "m" in int_succ_int_1) apply (cut_tac m = "n" in int_succ_int_1) apply simp apply (erule natE) apply auto apply (rule_tac x = "succ (n) " in bexI) apply auto done lemma zadd_succ_lemma: "z \ int \ (w $+ $# succ(m) $\ z) \ (w $+ $#m $< z)" apply (simp only: not_zless_iff_zle [THEN iff_sym] zless_add_succ_iff) apply (auto intro: zle_anti_sym elim: zless_asym simp add: zless_imp_zle not_zless_iff_zle) done lemma zadd_succ_zle_iff: "(w $+ $# succ(m) $\ z) \ (w $+ $#m $< z)" apply (cut_tac z = "intify (z)" in zadd_succ_lemma) apply auto done (** Inequality reasoning **) lemma zless_add1_iff_zle: "(w $< z $+ #1) \ (w$\z)" apply (subgoal_tac "#1 = $# 1") apply (simp only: zless_add_succ_iff zle_def) apply auto done lemma add1_zle_iff: "(w $+ #1 $\ z) \ (w $< z)" apply (subgoal_tac "#1 = $# 1") apply (simp only: zadd_succ_zle_iff) apply auto done lemma add1_left_zle_iff: "(#1 $+ w $\ z) \ (w $< z)" apply (subst zadd_commute) apply (rule add1_zle_iff) done (*** Monotonicity of Multiplication ***) lemma zmult_mono_lemma: "k \ nat \ i $\ j \ i $* $#k $\ j $* $#k" apply (induct_tac "k") prefer 2 apply (subst int_succ_int_1) apply (simp_all (no_asm_simp) add: zadd_zmult_distrib2 zadd_zle_mono) done lemma zmult_zle_mono1: "\i $\ j; #0 $\ k\ \ i$*k $\ j$*k" apply (subgoal_tac "i $* intify (k) $\ j $* intify (k) ") apply (simp (no_asm_use)) apply (rule_tac b = "intify (k)" in not_zneg_mag [THEN subst]) apply (rule_tac [3] zmult_mono_lemma) apply auto apply (simp add: znegative_iff_zless_0 not_zless_iff_zle [THEN iff_sym]) done lemma zmult_zle_mono1_neg: "\i $\ j; k $\ #0\ \ j$*k $\ i$*k" apply (rule zminus_zle_zminus [THEN iffD1]) apply (simp del: zmult_zminus_right add: zmult_zminus_right [symmetric] zmult_zle_mono1 zle_zminus) done lemma zmult_zle_mono2: "\i $\ j; #0 $\ k\ \ k$*i $\ k$*j" apply (drule zmult_zle_mono1) apply (simp_all add: zmult_commute) done lemma zmult_zle_mono2_neg: "\i $\ j; k $\ #0\ \ k$*j $\ k$*i" apply (drule zmult_zle_mono1_neg) apply (simp_all add: zmult_commute) done (* $\ monotonicity, BOTH arguments*) lemma zmult_zle_mono: "\i $\ j; k $\ l; #0 $\ j; #0 $\ k\ \ i$*k $\ j$*l" apply (erule zmult_zle_mono1 [THEN zle_trans]) apply assumption apply (erule zmult_zle_mono2) apply assumption done (** strict, in 1st argument; proof is by induction on k>0 **) lemma zmult_zless_mono2_lemma [rule_format]: "\i$ nat\ \ 0 $#k $* i $< $#k $* j" apply (induct_tac "k") prefer 2 apply (subst int_succ_int_1) apply (erule natE) apply (simp_all add: zadd_zmult_distrib zadd_zless_mono zle_def) apply (frule nat_0_le) apply (subgoal_tac "i $+ (i $+ $# xa $* i) $< j $+ (j $+ $# xa $* j) ") apply (simp (no_asm_use)) apply (rule zadd_zless_mono) apply (simp_all (no_asm_simp) add: zle_def) done lemma zmult_zless_mono2: "\i$ \ k$*i $< k$*j" apply (subgoal_tac "intify (k) $* i $< intify (k) $* j") apply (simp (no_asm_use)) apply (rule_tac b = "intify (k)" in not_zneg_mag [THEN subst]) apply (rule_tac [3] zmult_zless_mono2_lemma) apply auto apply (simp add: znegative_iff_zless_0) apply (drule zless_trans, assumption) apply (auto simp add: zero_lt_zmagnitude) done lemma zmult_zless_mono1: "\i$ \ i$*k $< j$*k" apply (drule zmult_zless_mono2) apply (simp_all add: zmult_commute) done (* < monotonicity, BOTH arguments*) lemma zmult_zless_mono: "\i $< j; k $< l; #0 $< j; #0 $< k\ \ i$*k $< j$*l" apply (erule zmult_zless_mono1 [THEN zless_trans]) apply assumption apply (erule zmult_zless_mono2) apply assumption done lemma zmult_zless_mono1_neg: "\i $< j; k $< #0\ \ j$*k $< i$*k" apply (rule zminus_zless_zminus [THEN iffD1]) apply (simp del: zmult_zminus_right add: zmult_zminus_right [symmetric] zmult_zless_mono1 zless_zminus) done lemma zmult_zless_mono2_neg: "\i $< j; k $< #0\ \ k$*j $< k$*i" apply (rule zminus_zless_zminus [THEN iffD1]) apply (simp del: zmult_zminus add: zmult_zminus [symmetric] zmult_zless_mono2 zless_zminus) done (** Products of zeroes **) lemma zmult_eq_lemma: "\m \ int; n \ int\ \ (m = #0 | n = #0) \ (m$*n = #0)" apply (case_tac "m $< #0") apply (auto simp add: not_zless_iff_zle zle_def neq_iff_zless) apply (force dest: zmult_zless_mono1_neg zmult_zless_mono1)+ done lemma zmult_eq_0_iff [iff]: "(m$*n = #0) \ (intify(m) = #0 | intify(n) = #0)" apply (simp add: zmult_eq_lemma) done (** Cancellation laws for k*m < k*n and m*k < n*k, also for @{text"\"} and =, but not (yet?) for k*m < n*k. **) lemma zmult_zless_lemma: "\k \ int; m \ int; n \ int\ \ (m$*k $< n$*k) \ ((#0 $< k \ m$ n$ ((#0 $< k \ m$ n$ ((#0 $< k \ m$ n$ n$*k) \ ((#0 $< k \ m$\n) \ (k $< #0 \ n$\m))" by (auto simp add: not_zless_iff_zle [THEN iff_sym] zmult_zless_cancel2) lemma zmult_zle_cancel1: "(k$*m $\ k$*n) \ ((#0 $< k \ m$\n) \ (k $< #0 \ n$\m))" by (auto simp add: not_zless_iff_zle [THEN iff_sym] zmult_zless_cancel1) lemma int_eq_iff_zle: "\m \ int; n \ int\ \ m=n \ (m $\ n \ n $\ m)" apply (blast intro: zle_refl zle_anti_sym) done lemma zmult_cancel2_lemma: "\k \ int; m \ int; n \ int\ \ (m$*k = n$*k) \ (k=#0 | m=n)" apply (simp add: int_eq_iff_zle [of "m$*k"] int_eq_iff_zle [of m]) apply (auto simp add: zmult_zle_cancel2 neq_iff_zless) done lemma zmult_cancel2 [simp]: "(m$*k = n$*k) \ (intify(k) = #0 | intify(m) = intify(n))" apply (rule iff_trans) apply (rule_tac [2] zmult_cancel2_lemma) apply auto done lemma zmult_cancel1 [simp]: "(k$*m = k$*n) \ (intify(k) = #0 | intify(m) = intify(n))" by (simp add: zmult_commute [of k] zmult_cancel2) subsection\Uniqueness and monotonicity of quotients and remainders\ lemma unique_quotient_lemma: "\b$*q' $+ r' $\ b$*q $+ r; #0 $\ r'; #0 $< b; r $< b\ \ q' $\ q" apply (subgoal_tac "r' $+ b $* (q'$-q) $\ r") prefer 2 apply (simp add: zdiff_zmult_distrib2 zadd_ac zcompare_rls) apply (subgoal_tac "#0 $< b $* (#1 $+ q $- q') ") prefer 2 apply (erule zle_zless_trans) apply (simp add: zdiff_zmult_distrib2 zadd_zmult_distrib2 zadd_ac zcompare_rls) apply (erule zle_zless_trans) apply simp apply (subgoal_tac "b $* q' $< b $* (#1 $+ q)") prefer 2 apply (simp add: zdiff_zmult_distrib2 zadd_zmult_distrib2 zadd_ac zcompare_rls) apply (auto elim: zless_asym simp add: zmult_zless_cancel1 zless_add1_iff_zle zadd_ac zcompare_rls) done lemma unique_quotient_lemma_neg: "\b$*q' $+ r' $\ b$*q $+ r; r $\ #0; b $< #0; b $< r'\ \ q $\ q'" apply (rule_tac b = "$-b" and r = "$-r'" and r' = "$-r" in unique_quotient_lemma) apply (auto simp del: zminus_zadd_distrib simp add: zminus_zadd_distrib [symmetric] zle_zminus zless_zminus) done lemma unique_quotient: "\quorem (\a,b\, \q,r\); quorem (\a,b\, ); b \ int; b \ #0; q \ int; q' \ int\ \ q = q'" apply (simp add: split_ifs quorem_def neq_iff_zless) apply safe apply simp_all apply (blast intro: zle_anti_sym dest: zle_eq_refl [THEN unique_quotient_lemma] zle_eq_refl [THEN unique_quotient_lemma_neg] sym)+ done lemma unique_remainder: "\quorem (\a,b\, \q,r\); quorem (\a,b\, ); b \ int; b \ #0; q \ int; q' \ int; r \ int; r' \ int\ \ r = r'" apply (subgoal_tac "q = q'") prefer 2 apply (blast intro: unique_quotient) apply (simp add: quorem_def) done subsection\Correctness of posDivAlg, the Division Algorithm for \a\0\ and \b>0\\ lemma adjust_eq [simp]: "adjust(b, \q,r\) = (let diff = r$-b in if #0 $\ diff then <#2$*q $+ #1,diff> else <#2$*q,r>)" by (simp add: Let_def adjust_def) lemma posDivAlg_termination: "\#0 $< b; \ a $< b\ \ nat_of(a $- #2 $* b $+ #1) < nat_of(a $- b $+ #1)" apply (simp (no_asm) add: zless_nat_conj) apply (simp add: not_zless_iff_zle zless_add1_iff_zle zcompare_rls) done lemmas posDivAlg_unfold = def_wfrec [OF posDivAlg_def wf_measure] lemma posDivAlg_eqn: "\#0 $< b; a \ int; b \ int\ \ posDivAlg(\a,b\) = (if a$ else adjust(b, posDivAlg ()))" apply (rule posDivAlg_unfold [THEN trans]) apply (simp add: vimage_iff not_zless_iff_zle [THEN iff_sym]) apply (blast intro: posDivAlg_termination) done lemma posDivAlg_induct_lemma [rule_format]: assumes prem: "\a b. \a \ int; b \ int; \ (a $< b | b $\ #0) \ P()\ \ P(\a,b\)" shows "\u,v\ \ int*int \ P(\u,v\)" using wf_measure [where A = "int*int" and f = "\\a,b\.nat_of (a $- b $+ #1)"] proof (induct "\u,v\" arbitrary: u v rule: wf_induct) case (step x) hence uv: "u \ int" "v \ int" by auto thus ?case apply (rule prem) apply (rule impI) apply (rule step) apply (auto simp add: step uv not_zle_iff_zless posDivAlg_termination) done qed lemma posDivAlg_induct [consumes 2]: assumes u_int: "u \ int" and v_int: "v \ int" and ih: "\a b. \a \ int; b \ int; \ (a $< b | b $\ #0) \ P(a, #2 $* b)\ \ P(a,b)" shows "P(u,v)" apply (subgoal_tac "(\\x,y\. P (x,y)) (\u,v\)") apply simp apply (rule posDivAlg_induct_lemma) apply (simp (no_asm_use)) apply (rule ih) apply (auto simp add: u_int v_int) done (*FIXME: use intify in integ_of so that we always have @{term"integ_of w \ int"}. then this rewrite can work for all constants\*) lemma intify_eq_0_iff_zle: "intify(m) = #0 \ (m $\ #0 \ #0 $\ m)" by (simp add: int_eq_iff_zle) subsection\Some convenient biconditionals for products of signs\ lemma zmult_pos: "\#0 $< i; #0 $< j\ \ #0 $< i $* j" by (drule zmult_zless_mono1, auto) lemma zmult_neg: "\i $< #0; j $< #0\ \ #0 $< i $* j" by (drule zmult_zless_mono1_neg, auto) lemma zmult_pos_neg: "\#0 $< i; j $< #0\ \ i $* j $< #0" by (drule zmult_zless_mono1_neg, auto) (** Inequality reasoning **) lemma int_0_less_lemma: "\x \ int; y \ int\ \ (#0 $< x $* y) \ (#0 $< x \ #0 $< y | x $< #0 \ y $< #0)" apply (auto simp add: zle_def not_zless_iff_zle zmult_pos zmult_neg) apply (rule ccontr) apply (rule_tac [2] ccontr) apply (auto simp add: zle_def not_zless_iff_zle) apply (erule_tac P = "#0$< x$* y" in rev_mp) apply (erule_tac [2] P = "#0$< x$* y" in rev_mp) apply (drule zmult_pos_neg, assumption) prefer 2 apply (drule zmult_pos_neg, assumption) apply (auto dest: zless_not_sym simp add: zmult_commute) done lemma int_0_less_mult_iff: "(#0 $< x $* y) \ (#0 $< x \ #0 $< y | x $< #0 \ y $< #0)" apply (cut_tac x = "intify (x)" and y = "intify (y)" in int_0_less_lemma) apply auto done lemma int_0_le_lemma: "\x \ int; y \ int\ \ (#0 $\ x $* y) \ (#0 $\ x \ #0 $\ y | x $\ #0 \ y $\ #0)" by (auto simp add: zle_def not_zless_iff_zle int_0_less_mult_iff) lemma int_0_le_mult_iff: "(#0 $\ x $* y) \ ((#0 $\ x \ #0 $\ y) | (x $\ #0 \ y $\ #0))" apply (cut_tac x = "intify (x)" and y = "intify (y)" in int_0_le_lemma) apply auto done lemma zmult_less_0_iff: "(x $* y $< #0) \ (#0 $< x \ y $< #0 | x $< #0 \ #0 $< y)" apply (auto simp add: int_0_le_mult_iff not_zle_iff_zless [THEN iff_sym]) apply (auto dest: zless_not_sym simp add: not_zle_iff_zless) done lemma zmult_le_0_iff: "(x $* y $\ #0) \ (#0 $\ x \ y $\ #0 | x $\ #0 \ #0 $\ y)" by (auto dest: zless_not_sym simp add: int_0_less_mult_iff not_zless_iff_zle [THEN iff_sym]) (*Typechecking for posDivAlg*) lemma posDivAlg_type [rule_format]: "\a \ int; b \ int\ \ posDivAlg(\a,b\) \ int * int" apply (rule_tac u = "a" and v = "b" in posDivAlg_induct) apply assumption+ apply (case_tac "#0 $< ba") apply (simp add: posDivAlg_eqn adjust_def integ_of_type split: split_if_asm) apply clarify apply (simp add: int_0_less_mult_iff not_zle_iff_zless) apply (simp add: not_zless_iff_zle) apply (subst posDivAlg_unfold) apply simp done (*Correctness of posDivAlg: it computes quotients correctly*) lemma posDivAlg_correct [rule_format]: "\a \ int; b \ int\ \ #0 $\ a \ #0 $< b \ quorem (\a,b\, posDivAlg(\a,b\))" apply (rule_tac u = "a" and v = "b" in posDivAlg_induct) apply auto apply (simp_all add: quorem_def) txt\base case: a apply (simp add: posDivAlg_eqn) apply (simp add: not_zless_iff_zle [THEN iff_sym]) apply (simp add: int_0_less_mult_iff) txt\main argument\ apply (subst posDivAlg_eqn) apply (simp_all (no_asm_simp)) apply (erule splitE) apply (rule posDivAlg_type) apply (simp_all add: int_0_less_mult_iff) apply (auto simp add: zadd_zmult_distrib2 Let_def) txt\now just linear arithmetic\ apply (simp add: not_zle_iff_zless zdiff_zless_iff) done subsection\Correctness of negDivAlg, the division algorithm for a<0 and b>0\ lemma negDivAlg_termination: "\#0 $< b; a $+ b $< #0\ \ nat_of($- a $- #2 $* b) < nat_of($- a $- b)" apply (simp (no_asm) add: zless_nat_conj) apply (simp add: zcompare_rls not_zle_iff_zless zless_zdiff_iff [THEN iff_sym] zless_zminus) done lemmas negDivAlg_unfold = def_wfrec [OF negDivAlg_def wf_measure] lemma negDivAlg_eqn: "\#0 $< b; a \ int; b \ int\ \ negDivAlg(\a,b\) = (if #0 $\ a$+b then <#-1,a$+b> else adjust(b, negDivAlg ()))" apply (rule negDivAlg_unfold [THEN trans]) apply (simp (no_asm_simp) add: vimage_iff not_zless_iff_zle [THEN iff_sym]) apply (blast intro: negDivAlg_termination) done lemma negDivAlg_induct_lemma [rule_format]: assumes prem: "\a b. \a \ int; b \ int; \ (#0 $\ a $+ b | b $\ #0) \ P()\ \ P(\a,b\)" shows "\u,v\ \ int*int \ P(\u,v\)" using wf_measure [where A = "int*int" and f = "\\a,b\.nat_of ($- a $- b)"] proof (induct "\u,v\" arbitrary: u v rule: wf_induct) case (step x) hence uv: "u \ int" "v \ int" by auto thus ?case apply (rule prem) apply (rule impI) apply (rule step) apply (auto simp add: step uv not_zle_iff_zless negDivAlg_termination) done qed lemma negDivAlg_induct [consumes 2]: assumes u_int: "u \ int" and v_int: "v \ int" and ih: "\a b. \a \ int; b \ int; \ (#0 $\ a $+ b | b $\ #0) \ P(a, #2 $* b)\ \ P(a,b)" shows "P(u,v)" apply (subgoal_tac " (\\x,y\. P (x,y)) (\u,v\)") apply simp apply (rule negDivAlg_induct_lemma) apply (simp (no_asm_use)) apply (rule ih) apply (auto simp add: u_int v_int) done (*Typechecking for negDivAlg*) lemma negDivAlg_type: "\a \ int; b \ int\ \ negDivAlg(\a,b\) \ int * int" apply (rule_tac u = "a" and v = "b" in negDivAlg_induct) apply assumption+ apply (case_tac "#0 $< ba") apply (simp add: negDivAlg_eqn adjust_def integ_of_type split: split_if_asm) apply clarify apply (simp add: int_0_less_mult_iff not_zle_iff_zless) apply (simp add: not_zless_iff_zle) apply (subst negDivAlg_unfold) apply simp done (*Correctness of negDivAlg: it computes quotients correctly It doesn't work if a=0 because the 0/b=0 rather than -1*) lemma negDivAlg_correct [rule_format]: "\a \ int; b \ int\ \ a $< #0 \ #0 $< b \ quorem (\a,b\, negDivAlg(\a,b\))" apply (rule_tac u = "a" and v = "b" in negDivAlg_induct) apply auto apply (simp_all add: quorem_def) txt\base case: \<^term>\0$\a$+b\\ apply (simp add: negDivAlg_eqn) apply (simp add: not_zless_iff_zle [THEN iff_sym]) apply (simp add: int_0_less_mult_iff) txt\main argument\ apply (subst negDivAlg_eqn) apply (simp_all (no_asm_simp)) apply (erule splitE) apply (rule negDivAlg_type) apply (simp_all add: int_0_less_mult_iff) apply (auto simp add: zadd_zmult_distrib2 Let_def) txt\now just linear arithmetic\ apply (simp add: not_zle_iff_zless zdiff_zless_iff) done subsection\Existence shown by proving the division algorithm to be correct\ (*the case a=0*) lemma quorem_0: "\b \ #0; b \ int\ \ quorem (<#0,b>, <#0,#0>)" by (force simp add: quorem_def neq_iff_zless) lemma posDivAlg_zero_divisor: "posDivAlg() = <#0,a>" apply (subst posDivAlg_unfold) apply simp done lemma posDivAlg_0 [simp]: "posDivAlg (<#0,b>) = <#0,#0>" apply (subst posDivAlg_unfold) apply (simp add: not_zle_iff_zless) done (*Needed below. Actually it's an equivalence.*) lemma linear_arith_lemma: "\ (#0 $\ #-1 $+ b) \ (b $\ #0)" apply (simp add: not_zle_iff_zless) apply (drule zminus_zless_zminus [THEN iffD2]) apply (simp add: zadd_commute zless_add1_iff_zle zle_zminus) done lemma negDivAlg_minus1 [simp]: "negDivAlg (<#-1,b>) = <#-1, b$-#1>" apply (subst negDivAlg_unfold) apply (simp add: linear_arith_lemma integ_of_type vimage_iff) done lemma negateSnd_eq [simp]: "negateSnd (\q,r\) = " -apply (unfold negateSnd_def) + unfolding negateSnd_def apply auto done lemma negateSnd_type: "qr \ int * int \ negateSnd (qr) \ int * int" -apply (unfold negateSnd_def) + unfolding negateSnd_def apply auto done lemma quorem_neg: "\quorem (<$-a,$-b>, qr); a \ int; b \ int; qr \ int * int\ \ quorem (\a,b\, negateSnd(qr))" apply clarify apply (auto elim: zless_asym simp add: quorem_def zless_zminus) txt\linear arithmetic from here on\ apply (simp_all add: zminus_equation [of a] zminus_zless) apply (cut_tac [2] z = "b" and w = "#0" in zless_linear) apply (cut_tac [1] z = "b" and w = "#0" in zless_linear) apply auto apply (blast dest: zle_zless_trans)+ done lemma divAlg_correct: "\b \ #0; a \ int; b \ int\ \ quorem (\a,b\, divAlg(\a,b\))" apply (auto simp add: quorem_0 divAlg_def) apply (safe intro!: quorem_neg posDivAlg_correct negDivAlg_correct posDivAlg_type negDivAlg_type) apply (auto simp add: quorem_def neq_iff_zless) txt\linear arithmetic from here on\ apply (auto simp add: zle_def) done lemma divAlg_type: "\a \ int; b \ int\ \ divAlg(\a,b\) \ int * int" apply (auto simp add: divAlg_def) apply (auto simp add: posDivAlg_type negDivAlg_type negateSnd_type) done (** intify cancellation **) lemma zdiv_intify1 [simp]: "intify(x) zdiv y = x zdiv y" by (simp add: zdiv_def) lemma zdiv_intify2 [simp]: "x zdiv intify(y) = x zdiv y" by (simp add: zdiv_def) lemma zdiv_type [iff,TC]: "z zdiv w \ int" -apply (unfold zdiv_def) + unfolding zdiv_def apply (blast intro: fst_type divAlg_type) done lemma zmod_intify1 [simp]: "intify(x) zmod y = x zmod y" by (simp add: zmod_def) lemma zmod_intify2 [simp]: "x zmod intify(y) = x zmod y" by (simp add: zmod_def) lemma zmod_type [iff,TC]: "z zmod w \ int" -apply (unfold zmod_def) + unfolding zmod_def apply (rule snd_type) apply (blast intro: divAlg_type) done (** Arbitrary definitions for division by zero. Useful to simplify certain equations **) lemma DIVISION_BY_ZERO_ZDIV: "a zdiv #0 = #0" by (simp add: zdiv_def divAlg_def posDivAlg_zero_divisor) lemma DIVISION_BY_ZERO_ZMOD: "a zmod #0 = intify(a)" by (simp add: zmod_def divAlg_def posDivAlg_zero_divisor) (** Basic laws about division and remainder **) lemma raw_zmod_zdiv_equality: "\a \ int; b \ int\ \ a = b $* (a zdiv b) $+ (a zmod b)" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (cut_tac a = "a" and b = "b" in divAlg_correct) apply (auto simp add: quorem_def zdiv_def zmod_def split_def) done lemma zmod_zdiv_equality: "intify(a) = b $* (a zdiv b) $+ (a zmod b)" apply (rule trans) apply (rule_tac b = "intify (b)" in raw_zmod_zdiv_equality) apply auto done lemma pos_mod: "#0 $< b \ #0 $\ a zmod b \ a zmod b $< b" apply (cut_tac a = "intify (a)" and b = "intify (b)" in divAlg_correct) apply (auto simp add: intify_eq_0_iff_zle quorem_def zmod_def split_def) apply (blast dest: zle_zless_trans)+ done lemmas pos_mod_sign = pos_mod [THEN conjunct1] and pos_mod_bound = pos_mod [THEN conjunct2] lemma neg_mod: "b $< #0 \ a zmod b $\ #0 \ b $< a zmod b" apply (cut_tac a = "intify (a)" and b = "intify (b)" in divAlg_correct) apply (auto simp add: intify_eq_0_iff_zle quorem_def zmod_def split_def) apply (blast dest: zle_zless_trans) apply (blast dest: zless_trans)+ done lemmas neg_mod_sign = neg_mod [THEN conjunct1] and neg_mod_bound = neg_mod [THEN conjunct2] (** proving general properties of zdiv and zmod **) lemma quorem_div_mod: "\b \ #0; a \ int; b \ int\ \ quorem (\a,b\, )" apply (cut_tac a = "a" and b = "b" in zmod_zdiv_equality) apply (auto simp add: quorem_def neq_iff_zless pos_mod_sign pos_mod_bound neg_mod_sign neg_mod_bound) done (*Surely quorem(\a,b\,\q,r\) implies @{term"a \ int"}, but it doesn't matter*) lemma quorem_div: "\quorem(\a,b\,\q,r\); b \ #0; a \ int; b \ int; q \ int\ \ a zdiv b = q" by (blast intro: quorem_div_mod [THEN unique_quotient]) lemma quorem_mod: "\quorem(\a,b\,\q,r\); b \ #0; a \ int; b \ int; q \ int; r \ int\ \ a zmod b = r" by (blast intro: quorem_div_mod [THEN unique_remainder]) lemma zdiv_pos_pos_trivial_raw: "\a \ int; b \ int; #0 $\ a; a $< b\ \ a zdiv b = #0" apply (rule quorem_div) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans)+ done lemma zdiv_pos_pos_trivial: "\#0 $\ a; a $< b\ \ a zdiv b = #0" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zdiv_pos_pos_trivial_raw) apply auto done lemma zdiv_neg_neg_trivial_raw: "\a \ int; b \ int; a $\ #0; b $< a\ \ a zdiv b = #0" apply (rule_tac r = "a" in quorem_div) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans zless_trans)+ done lemma zdiv_neg_neg_trivial: "\a $\ #0; b $< a\ \ a zdiv b = #0" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zdiv_neg_neg_trivial_raw) apply auto done lemma zadd_le_0_lemma: "\a$+b $\ #0; #0 $< a; #0 $< b\ \ False" apply (drule_tac z' = "#0" and z = "b" in zadd_zless_mono) apply (auto simp add: zle_def) apply (blast dest: zless_trans) done lemma zdiv_pos_neg_trivial_raw: "\a \ int; b \ int; #0 $< a; a$+b $\ #0\ \ a zdiv b = #-1" apply (rule_tac r = "a $+ b" in quorem_div) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zadd_le_0_lemma zle_zless_trans)+ done lemma zdiv_pos_neg_trivial: "\#0 $< a; a$+b $\ #0\ \ a zdiv b = #-1" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zdiv_pos_neg_trivial_raw) apply auto done (*There is no zdiv_neg_pos_trivial because #0 zdiv b = #0 would supersede it*) lemma zmod_pos_pos_trivial_raw: "\a \ int; b \ int; #0 $\ a; a $< b\ \ a zmod b = a" apply (rule_tac q = "#0" in quorem_mod) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans)+ done lemma zmod_pos_pos_trivial: "\#0 $\ a; a $< b\ \ a zmod b = intify(a)" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_pos_pos_trivial_raw) apply auto done lemma zmod_neg_neg_trivial_raw: "\a \ int; b \ int; a $\ #0; b $< a\ \ a zmod b = a" apply (rule_tac q = "#0" in quorem_mod) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans zless_trans)+ done lemma zmod_neg_neg_trivial: "\a $\ #0; b $< a\ \ a zmod b = intify(a)" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_neg_neg_trivial_raw) apply auto done lemma zmod_pos_neg_trivial_raw: "\a \ int; b \ int; #0 $< a; a$+b $\ #0\ \ a zmod b = a$+b" apply (rule_tac q = "#-1" in quorem_mod) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zadd_le_0_lemma zle_zless_trans)+ done lemma zmod_pos_neg_trivial: "\#0 $< a; a$+b $\ #0\ \ a zmod b = a$+b" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_pos_neg_trivial_raw) apply auto done (*There is no zmod_neg_pos_trivial...*) (*Simpler laws such as -a zdiv b = -(a zdiv b) FAIL*) lemma zdiv_zminus_zminus_raw: "\a \ int; b \ int\ \ ($-a) zdiv ($-b) = a zdiv b" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (subst quorem_div_mod [THEN quorem_neg, simplified, THEN quorem_div]) apply auto done lemma zdiv_zminus_zminus [simp]: "($-a) zdiv ($-b) = a zdiv b" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zdiv_zminus_zminus_raw) apply auto done (*Simpler laws such as -a zmod b = -(a zmod b) FAIL*) lemma zmod_zminus_zminus_raw: "\a \ int; b \ int\ \ ($-a) zmod ($-b) = $- (a zmod b)" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (subst quorem_div_mod [THEN quorem_neg, simplified, THEN quorem_mod]) apply auto done lemma zmod_zminus_zminus [simp]: "($-a) zmod ($-b) = $- (a zmod b)" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_zminus_zminus_raw) apply auto done subsection\division of a number by itself\ lemma self_quotient_aux1: "\#0 $< a; a = r $+ a$*q; r $< a\ \ #1 $\ q" apply (subgoal_tac "#0 $< a$*q") apply (cut_tac w = "#0" and z = "q" in add1_zle_iff) apply (simp add: int_0_less_mult_iff) apply (blast dest: zless_trans) (*linear arithmetic...*) apply (drule_tac t = "\x. x $- r" in subst_context) apply (drule sym) apply (simp add: zcompare_rls) done lemma self_quotient_aux2: "\#0 $< a; a = r $+ a$*q; #0 $\ r\ \ q $\ #1" apply (subgoal_tac "#0 $\ a$* (#1$-q)") apply (simp add: int_0_le_mult_iff zcompare_rls) apply (blast dest: zle_zless_trans) apply (simp add: zdiff_zmult_distrib2) apply (drule_tac t = "\x. x $- a $* q" in subst_context) apply (simp add: zcompare_rls) done lemma self_quotient: "\quorem(\a,a\,\q,r\); a \ int; q \ int; a \ #0\ \ q = #1" apply (simp add: split_ifs quorem_def neq_iff_zless) apply (rule zle_anti_sym) apply safe apply auto prefer 4 apply (blast dest: zless_trans) apply (blast dest: zless_trans) apply (rule_tac [3] a = "$-a" and r = "$-r" in self_quotient_aux1) apply (rule_tac a = "$-a" and r = "$-r" in self_quotient_aux2) apply (rule_tac [6] zminus_equation [THEN iffD1]) apply (rule_tac [2] zminus_equation [THEN iffD1]) apply (force intro: self_quotient_aux1 self_quotient_aux2 simp add: zadd_commute zmult_zminus)+ done lemma self_remainder: "\quorem(\a,a\,\q,r\); a \ int; q \ int; r \ int; a \ #0\ \ r = #0" apply (frule self_quotient) apply (auto simp add: quorem_def) done lemma zdiv_self_raw: "\a \ #0; a \ int\ \ a zdiv a = #1" apply (blast intro: quorem_div_mod [THEN self_quotient]) done lemma zdiv_self [simp]: "intify(a) \ #0 \ a zdiv a = #1" apply (drule zdiv_self_raw) apply auto done (*Here we have 0 zmod 0 = 0, also assumed by Knuth (who puts m zmod 0 = 0) *) lemma zmod_self_raw: "a \ int \ a zmod a = #0" apply (case_tac "a = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (blast intro: quorem_div_mod [THEN self_remainder]) done lemma zmod_self [simp]: "a zmod a = #0" apply (cut_tac a = "intify (a)" in zmod_self_raw) apply auto done subsection\Computation of division and remainder\ lemma zdiv_zero [simp]: "#0 zdiv b = #0" by (simp add: zdiv_def divAlg_def) lemma zdiv_eq_minus1: "#0 $< b \ #-1 zdiv b = #-1" by (simp (no_asm_simp) add: zdiv_def divAlg_def) lemma zmod_zero [simp]: "#0 zmod b = #0" by (simp add: zmod_def divAlg_def) lemma zdiv_minus1: "#0 $< b \ #-1 zdiv b = #-1" by (simp add: zdiv_def divAlg_def) lemma zmod_minus1: "#0 $< b \ #-1 zmod b = b $- #1" by (simp add: zmod_def divAlg_def) (** a positive, b positive **) lemma zdiv_pos_pos: "\#0 $< a; #0 $\ b\ \ a zdiv b = fst (posDivAlg())" apply (simp (no_asm_simp) add: zdiv_def divAlg_def) apply (auto simp add: zle_def) done lemma zmod_pos_pos: "\#0 $< a; #0 $\ b\ \ a zmod b = snd (posDivAlg())" apply (simp (no_asm_simp) add: zmod_def divAlg_def) apply (auto simp add: zle_def) done (** a negative, b positive **) lemma zdiv_neg_pos: "\a $< #0; #0 $< b\ \ a zdiv b = fst (negDivAlg())" apply (simp (no_asm_simp) add: zdiv_def divAlg_def) apply (blast dest: zle_zless_trans) done lemma zmod_neg_pos: "\a $< #0; #0 $< b\ \ a zmod b = snd (negDivAlg())" apply (simp (no_asm_simp) add: zmod_def divAlg_def) apply (blast dest: zle_zless_trans) done (** a positive, b negative **) lemma zdiv_pos_neg: "\#0 $< a; b $< #0\ \ a zdiv b = fst (negateSnd(negDivAlg (<$-a, $-b>)))" apply (simp (no_asm_simp) add: zdiv_def divAlg_def intify_eq_0_iff_zle) apply auto apply (blast dest: zle_zless_trans)+ apply (blast dest: zless_trans) apply (blast intro: zless_imp_zle) done lemma zmod_pos_neg: "\#0 $< a; b $< #0\ \ a zmod b = snd (negateSnd(negDivAlg (<$-a, $-b>)))" apply (simp (no_asm_simp) add: zmod_def divAlg_def intify_eq_0_iff_zle) apply auto apply (blast dest: zle_zless_trans)+ apply (blast dest: zless_trans) apply (blast intro: zless_imp_zle) done (** a negative, b negative **) lemma zdiv_neg_neg: "\a $< #0; b $\ #0\ \ a zdiv b = fst (negateSnd(posDivAlg(<$-a, $-b>)))" apply (simp (no_asm_simp) add: zdiv_def divAlg_def) apply auto apply (blast dest!: zle_zless_trans)+ done lemma zmod_neg_neg: "\a $< #0; b $\ #0\ \ a zmod b = snd (negateSnd(posDivAlg(<$-a, $-b>)))" apply (simp (no_asm_simp) add: zmod_def divAlg_def) apply auto apply (blast dest!: zle_zless_trans)+ done declare zdiv_pos_pos [of "integ_of (v)" "integ_of (w)", simp] for v w declare zdiv_neg_pos [of "integ_of (v)" "integ_of (w)", simp] for v w declare zdiv_pos_neg [of "integ_of (v)" "integ_of (w)", simp] for v w declare zdiv_neg_neg [of "integ_of (v)" "integ_of (w)", simp] for v w declare zmod_pos_pos [of "integ_of (v)" "integ_of (w)", simp] for v w declare zmod_neg_pos [of "integ_of (v)" "integ_of (w)", simp] for v w declare zmod_pos_neg [of "integ_of (v)" "integ_of (w)", simp] for v w declare zmod_neg_neg [of "integ_of (v)" "integ_of (w)", simp] for v w declare posDivAlg_eqn [of concl: "integ_of (v)" "integ_of (w)", simp] for v w declare negDivAlg_eqn [of concl: "integ_of (v)" "integ_of (w)", simp] for v w (** Special-case simplification **) lemma zmod_1 [simp]: "a zmod #1 = #0" apply (cut_tac a = "a" and b = "#1" in pos_mod_sign) apply (cut_tac [2] a = "a" and b = "#1" in pos_mod_bound) apply auto (*arithmetic*) apply (drule add1_zle_iff [THEN iffD2]) apply (rule zle_anti_sym) apply auto done lemma zdiv_1 [simp]: "a zdiv #1 = intify(a)" apply (cut_tac a = "a" and b = "#1" in zmod_zdiv_equality) apply auto done lemma zmod_minus1_right [simp]: "a zmod #-1 = #0" apply (cut_tac a = "a" and b = "#-1" in neg_mod_sign) apply (cut_tac [2] a = "a" and b = "#-1" in neg_mod_bound) apply auto (*arithmetic*) apply (drule add1_zle_iff [THEN iffD2]) apply (rule zle_anti_sym) apply auto done lemma zdiv_minus1_right_raw: "a \ int \ a zdiv #-1 = $-a" apply (cut_tac a = "a" and b = "#-1" in zmod_zdiv_equality) apply auto apply (rule equation_zminus [THEN iffD2]) apply auto done lemma zdiv_minus1_right: "a zdiv #-1 = $-a" apply (cut_tac a = "intify (a)" in zdiv_minus1_right_raw) apply auto done declare zdiv_minus1_right [simp] subsection\Monotonicity in the first argument (divisor)\ lemma zdiv_mono1: "\a $\ a'; #0 $< b\ \ a zdiv b $\ a' zdiv b" apply (cut_tac a = "a" and b = "b" in zmod_zdiv_equality) apply (cut_tac a = "a'" and b = "b" in zmod_zdiv_equality) apply (rule unique_quotient_lemma) apply (erule subst) apply (erule subst) apply (simp_all (no_asm_simp) add: pos_mod_sign pos_mod_bound) done lemma zdiv_mono1_neg: "\a $\ a'; b $< #0\ \ a' zdiv b $\ a zdiv b" apply (cut_tac a = "a" and b = "b" in zmod_zdiv_equality) apply (cut_tac a = "a'" and b = "b" in zmod_zdiv_equality) apply (rule unique_quotient_lemma_neg) apply (erule subst) apply (erule subst) apply (simp_all (no_asm_simp) add: neg_mod_sign neg_mod_bound) done subsection\Monotonicity in the second argument (dividend)\ lemma q_pos_lemma: "\#0 $\ b'$*q' $+ r'; r' $< b'; #0 $< b'\ \ #0 $\ q'" apply (subgoal_tac "#0 $< b'$* (q' $+ #1)") apply (simp add: int_0_less_mult_iff) apply (blast dest: zless_trans intro: zless_add1_iff_zle [THEN iffD1]) apply (simp add: zadd_zmult_distrib2) apply (erule zle_zless_trans) apply (erule zadd_zless_mono2) done lemma zdiv_mono2_lemma: "\b$*q $+ r = b'$*q' $+ r'; #0 $\ b'$*q' $+ r'; r' $< b'; #0 $\ r; #0 $< b'; b' $\ b\ \ q $\ q'" apply (frule q_pos_lemma, assumption+) apply (subgoal_tac "b$*q $< b$* (q' $+ #1)") apply (simp add: zmult_zless_cancel1) apply (force dest: zless_add1_iff_zle [THEN iffD1] zless_trans zless_zle_trans) apply (subgoal_tac "b$*q = r' $- r $+ b'$*q'") prefer 2 apply (simp add: zcompare_rls) apply (simp (no_asm_simp) add: zadd_zmult_distrib2) apply (subst zadd_commute [of "b $* q'"], rule zadd_zless_mono) prefer 2 apply (blast intro: zmult_zle_mono1) apply (subgoal_tac "r' $+ #0 $< b $+ r") apply (simp add: zcompare_rls) apply (rule zadd_zless_mono) apply auto apply (blast dest: zless_zle_trans) done lemma zdiv_mono2_raw: "\#0 $\ a; #0 $< b'; b' $\ b; a \ int\ \ a zdiv b $\ a zdiv b'" apply (subgoal_tac "#0 $< b") prefer 2 apply (blast dest: zless_zle_trans) apply (cut_tac a = "a" and b = "b" in zmod_zdiv_equality) apply (cut_tac a = "a" and b = "b'" in zmod_zdiv_equality) apply (rule zdiv_mono2_lemma) apply (erule subst) apply (erule subst) apply (simp_all add: pos_mod_sign pos_mod_bound) done lemma zdiv_mono2: "\#0 $\ a; #0 $< b'; b' $\ b\ \ a zdiv b $\ a zdiv b'" apply (cut_tac a = "intify (a)" in zdiv_mono2_raw) apply auto done lemma q_neg_lemma: "\b'$*q' $+ r' $< #0; #0 $\ r'; #0 $< b'\ \ q' $< #0" apply (subgoal_tac "b'$*q' $< #0") prefer 2 apply (force intro: zle_zless_trans) apply (simp add: zmult_less_0_iff) apply (blast dest: zless_trans) done lemma zdiv_mono2_neg_lemma: "\b$*q $+ r = b'$*q' $+ r'; b'$*q' $+ r' $< #0; r $< b; #0 $\ r'; #0 $< b'; b' $\ b\ \ q' $\ q" apply (subgoal_tac "#0 $< b") prefer 2 apply (blast dest: zless_zle_trans) apply (frule q_neg_lemma, assumption+) apply (subgoal_tac "b$*q' $< b$* (q $+ #1)") apply (simp add: zmult_zless_cancel1) apply (blast dest: zless_trans zless_add1_iff_zle [THEN iffD1]) apply (simp (no_asm_simp) add: zadd_zmult_distrib2) apply (subgoal_tac "b$*q' $\ b'$*q'") prefer 2 apply (simp add: zmult_zle_cancel2) apply (blast dest: zless_trans) apply (subgoal_tac "b'$*q' $+ r $< b $+ (b$*q $+ r)") prefer 2 apply (erule ssubst) apply simp apply (drule_tac w' = "r" and z' = "#0" in zadd_zless_mono) apply (assumption) apply simp apply (simp (no_asm_use) add: zadd_commute) apply (rule zle_zless_trans) prefer 2 apply (assumption) apply (simp (no_asm_simp) add: zmult_zle_cancel2) apply (blast dest: zless_trans) done lemma zdiv_mono2_neg_raw: "\a $< #0; #0 $< b'; b' $\ b; a \ int\ \ a zdiv b' $\ a zdiv b" apply (subgoal_tac "#0 $< b") prefer 2 apply (blast dest: zless_zle_trans) apply (cut_tac a = "a" and b = "b" in zmod_zdiv_equality) apply (cut_tac a = "a" and b = "b'" in zmod_zdiv_equality) apply (rule zdiv_mono2_neg_lemma) apply (erule subst) apply (erule subst) apply (simp_all add: pos_mod_sign pos_mod_bound) done lemma zdiv_mono2_neg: "\a $< #0; #0 $< b'; b' $\ b\ \ a zdiv b' $\ a zdiv b" apply (cut_tac a = "intify (a)" in zdiv_mono2_neg_raw) apply auto done subsection\More algebraic laws for zdiv and zmod\ (** proving (a*b) zdiv c = a $* (b zdiv c) $+ a * (b zmod c) **) lemma zmult1_lemma: "\quorem(\b,c\, \q,r\); c \ int; c \ #0\ \ quorem (, )" apply (auto simp add: split_ifs quorem_def neq_iff_zless zadd_zmult_distrib2 pos_mod_sign pos_mod_bound neg_mod_sign neg_mod_bound) apply (auto intro: raw_zmod_zdiv_equality) done lemma zdiv_zmult1_eq_raw: "\b \ int; c \ int\ \ (a$*b) zdiv c = a$*(b zdiv c) $+ a$*(b zmod c) zdiv c" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zmult1_lemma, THEN quorem_div]) apply auto done lemma zdiv_zmult1_eq: "(a$*b) zdiv c = a$*(b zdiv c) $+ a$*(b zmod c) zdiv c" apply (cut_tac b = "intify (b)" and c = "intify (c)" in zdiv_zmult1_eq_raw) apply auto done lemma zmod_zmult1_eq_raw: "\b \ int; c \ int\ \ (a$*b) zmod c = a$*(b zmod c) zmod c" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zmult1_lemma, THEN quorem_mod]) apply auto done lemma zmod_zmult1_eq: "(a$*b) zmod c = a$*(b zmod c) zmod c" apply (cut_tac b = "intify (b)" and c = "intify (c)" in zmod_zmult1_eq_raw) apply auto done lemma zmod_zmult1_eq': "(a$*b) zmod c = ((a zmod c) $* b) zmod c" apply (rule trans) apply (rule_tac b = " (b $* a) zmod c" in trans) apply (rule_tac [2] zmod_zmult1_eq) apply (simp_all (no_asm) add: zmult_commute) done lemma zmod_zmult_distrib: "(a$*b) zmod c = ((a zmod c) $* (b zmod c)) zmod c" apply (rule zmod_zmult1_eq' [THEN trans]) apply (rule zmod_zmult1_eq) done lemma zdiv_zmult_self1 [simp]: "intify(b) \ #0 \ (a$*b) zdiv b = intify(a)" by (simp add: zdiv_zmult1_eq) lemma zdiv_zmult_self2 [simp]: "intify(b) \ #0 \ (b$*a) zdiv b = intify(a)" by (simp add: zmult_commute) lemma zmod_zmult_self1 [simp]: "(a$*b) zmod b = #0" by (simp add: zmod_zmult1_eq) lemma zmod_zmult_self2 [simp]: "(b$*a) zmod b = #0" by (simp add: zmult_commute zmod_zmult1_eq) (** proving (a$+b) zdiv c = a zdiv c $+ b zdiv c $+ ((a zmod c $+ b zmod c) zdiv c) **) lemma zadd1_lemma: "\quorem(\a,c\, \aq,ar\); quorem(\b,c\, \bq,br\); c \ int; c \ #0\ \ quorem (, )" apply (auto simp add: split_ifs quorem_def neq_iff_zless zadd_zmult_distrib2 pos_mod_sign pos_mod_bound neg_mod_sign neg_mod_bound) apply (auto intro: raw_zmod_zdiv_equality) done (*NOT suitable for rewriting: the RHS has an instance of the LHS*) lemma zdiv_zadd1_eq_raw: "\a \ int; b \ int; c \ int\ \ (a$+b) zdiv c = a zdiv c $+ b zdiv c $+ ((a zmod c $+ b zmod c) zdiv c)" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod, THEN quorem_div]) done lemma zdiv_zadd1_eq: "(a$+b) zdiv c = a zdiv c $+ b zdiv c $+ ((a zmod c $+ b zmod c) zdiv c)" apply (cut_tac a = "intify (a)" and b = "intify (b)" and c = "intify (c)" in zdiv_zadd1_eq_raw) apply auto done lemma zmod_zadd1_eq_raw: "\a \ int; b \ int; c \ int\ \ (a$+b) zmod c = (a zmod c $+ b zmod c) zmod c" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod, THEN quorem_mod]) done lemma zmod_zadd1_eq: "(a$+b) zmod c = (a zmod c $+ b zmod c) zmod c" apply (cut_tac a = "intify (a)" and b = "intify (b)" and c = "intify (c)" in zmod_zadd1_eq_raw) apply auto done lemma zmod_div_trivial_raw: "\a \ int; b \ int\ \ (a zmod b) zdiv b = #0" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (auto simp add: neq_iff_zless pos_mod_sign pos_mod_bound zdiv_pos_pos_trivial neg_mod_sign neg_mod_bound zdiv_neg_neg_trivial) done lemma zmod_div_trivial [simp]: "(a zmod b) zdiv b = #0" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_div_trivial_raw) apply auto done lemma zmod_mod_trivial_raw: "\a \ int; b \ int\ \ (a zmod b) zmod b = a zmod b" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (auto simp add: neq_iff_zless pos_mod_sign pos_mod_bound zmod_pos_pos_trivial neg_mod_sign neg_mod_bound zmod_neg_neg_trivial) done lemma zmod_mod_trivial [simp]: "(a zmod b) zmod b = a zmod b" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_mod_trivial_raw) apply auto done lemma zmod_zadd_left_eq: "(a$+b) zmod c = ((a zmod c) $+ b) zmod c" apply (rule trans [symmetric]) apply (rule zmod_zadd1_eq) apply (simp (no_asm)) apply (rule zmod_zadd1_eq [symmetric]) done lemma zmod_zadd_right_eq: "(a$+b) zmod c = (a $+ (b zmod c)) zmod c" apply (rule trans [symmetric]) apply (rule zmod_zadd1_eq) apply (simp (no_asm)) apply (rule zmod_zadd1_eq [symmetric]) done lemma zdiv_zadd_self1 [simp]: "intify(a) \ #0 \ (a$+b) zdiv a = b zdiv a $+ #1" by (simp (no_asm_simp) add: zdiv_zadd1_eq) lemma zdiv_zadd_self2 [simp]: "intify(a) \ #0 \ (b$+a) zdiv a = b zdiv a $+ #1" by (simp (no_asm_simp) add: zdiv_zadd1_eq) lemma zmod_zadd_self1 [simp]: "(a$+b) zmod a = b zmod a" apply (case_tac "a = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (simp (no_asm_simp) add: zmod_zadd1_eq) done lemma zmod_zadd_self2 [simp]: "(b$+a) zmod a = b zmod a" apply (case_tac "a = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (simp (no_asm_simp) add: zmod_zadd1_eq) done subsection\proving a zdiv (b*c) = (a zdiv b) zdiv c\ (*The condition c>0 seems necessary. Consider that 7 zdiv \6 = \2 but 7 zdiv 2 zdiv \3 = 3 zdiv \3 = \1. The subcase (a zdiv b) zmod c = 0 seems to cause particular problems.*) (** first, four lemmas to bound the remainder for the cases b<0 and b>0 **) lemma zdiv_zmult2_aux1: "\#0 $< c; b $< r; r $\ #0\ \ b$*c $< b$*(q zmod c) $+ r" apply (subgoal_tac "b $* (c $- q zmod c) $< r $* #1") apply (simp add: zdiff_zmult_distrib2 zadd_commute zcompare_rls) apply (rule zle_zless_trans) apply (erule_tac [2] zmult_zless_mono1) apply (rule zmult_zle_mono2_neg) apply (auto simp add: zcompare_rls zadd_commute add1_zle_iff pos_mod_bound) apply (blast intro: zless_imp_zle dest: zless_zle_trans) done lemma zdiv_zmult2_aux2: "\#0 $< c; b $< r; r $\ #0\ \ b $* (q zmod c) $+ r $\ #0" apply (subgoal_tac "b $* (q zmod c) $\ #0") prefer 2 apply (simp add: zmult_le_0_iff pos_mod_sign) apply (blast intro: zless_imp_zle dest: zless_zle_trans) (*arithmetic*) apply (drule zadd_zle_mono) apply assumption apply (simp add: zadd_commute) done lemma zdiv_zmult2_aux3: "\#0 $< c; #0 $\ r; r $< b\ \ #0 $\ b $* (q zmod c) $+ r" apply (subgoal_tac "#0 $\ b $* (q zmod c)") prefer 2 apply (simp add: int_0_le_mult_iff pos_mod_sign) apply (blast intro: zless_imp_zle dest: zle_zless_trans) (*arithmetic*) apply (drule zadd_zle_mono) apply assumption apply (simp add: zadd_commute) done lemma zdiv_zmult2_aux4: "\#0 $< c; #0 $\ r; r $< b\ \ b $* (q zmod c) $+ r $< b $* c" apply (subgoal_tac "r $* #1 $< b $* (c $- q zmod c)") apply (simp add: zdiff_zmult_distrib2 zadd_commute zcompare_rls) apply (rule zless_zle_trans) apply (erule zmult_zless_mono1) apply (rule_tac [2] zmult_zle_mono2) apply (auto simp add: zcompare_rls zadd_commute add1_zle_iff pos_mod_bound) apply (blast intro: zless_imp_zle dest: zle_zless_trans) done lemma zdiv_zmult2_lemma: "\quorem (\a,b\, \q,r\); a \ int; b \ int; b \ #0; #0 $< c\ \ quorem (, )" apply (auto simp add: zmult_ac zmod_zdiv_equality [symmetric] quorem_def neq_iff_zless int_0_less_mult_iff zadd_zmult_distrib2 [symmetric] zdiv_zmult2_aux1 zdiv_zmult2_aux2 zdiv_zmult2_aux3 zdiv_zmult2_aux4) apply (blast dest: zless_trans)+ done lemma zdiv_zmult2_eq_raw: "\#0 $< c; a \ int; b \ int\ \ a zdiv (b$*c) = (a zdiv b) zdiv c" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zdiv_zmult2_lemma, THEN quorem_div]) apply (auto simp add: intify_eq_0_iff_zle) apply (blast dest: zle_zless_trans) done lemma zdiv_zmult2_eq: "#0 $< c \ a zdiv (b$*c) = (a zdiv b) zdiv c" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zdiv_zmult2_eq_raw) apply auto done lemma zmod_zmult2_eq_raw: "\#0 $< c; a \ int; b \ int\ \ a zmod (b$*c) = b$*(a zdiv b zmod c) $+ a zmod b" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zdiv_zmult2_lemma, THEN quorem_mod]) apply (auto simp add: intify_eq_0_iff_zle) apply (blast dest: zle_zless_trans) done lemma zmod_zmult2_eq: "#0 $< c \ a zmod (b$*c) = b$*(a zdiv b zmod c) $+ a zmod b" apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_zmult2_eq_raw) apply auto done subsection\Cancellation of common factors in "zdiv"\ lemma zdiv_zmult_zmult1_aux1: "\#0 $< b; intify(c) \ #0\ \ (c$*a) zdiv (c$*b) = a zdiv b" apply (subst zdiv_zmult2_eq) apply auto done lemma zdiv_zmult_zmult1_aux2: "\b $< #0; intify(c) \ #0\ \ (c$*a) zdiv (c$*b) = a zdiv b" apply (subgoal_tac " (c $* ($-a)) zdiv (c $* ($-b)) = ($-a) zdiv ($-b)") apply (rule_tac [2] zdiv_zmult_zmult1_aux1) apply auto done lemma zdiv_zmult_zmult1_raw: "\intify(c) \ #0; b \ int\ \ (c$*a) zdiv (c$*b) = a zdiv b" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (auto simp add: neq_iff_zless [of b] zdiv_zmult_zmult1_aux1 zdiv_zmult_zmult1_aux2) done lemma zdiv_zmult_zmult1: "intify(c) \ #0 \ (c$*a) zdiv (c$*b) = a zdiv b" apply (cut_tac b = "intify (b)" in zdiv_zmult_zmult1_raw) apply auto done lemma zdiv_zmult_zmult2: "intify(c) \ #0 \ (a$*c) zdiv (b$*c) = a zdiv b" apply (drule zdiv_zmult_zmult1) apply (auto simp add: zmult_commute) done subsection\Distribution of factors over "zmod"\ lemma zmod_zmult_zmult1_aux1: "\#0 $< b; intify(c) \ #0\ \ (c$*a) zmod (c$*b) = c $* (a zmod b)" apply (subst zmod_zmult2_eq) apply auto done lemma zmod_zmult_zmult1_aux2: "\b $< #0; intify(c) \ #0\ \ (c$*a) zmod (c$*b) = c $* (a zmod b)" apply (subgoal_tac " (c $* ($-a)) zmod (c $* ($-b)) = c $* (($-a) zmod ($-b))") apply (rule_tac [2] zmod_zmult_zmult1_aux1) apply auto done lemma zmod_zmult_zmult1_raw: "\b \ int; c \ int\ \ (c$*a) zmod (c$*b) = c $* (a zmod b)" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (auto simp add: neq_iff_zless [of b] zmod_zmult_zmult1_aux1 zmod_zmult_zmult1_aux2) done lemma zmod_zmult_zmult1: "(c$*a) zmod (c$*b) = c $* (a zmod b)" apply (cut_tac b = "intify (b)" and c = "intify (c)" in zmod_zmult_zmult1_raw) apply auto done lemma zmod_zmult_zmult2: "(a$*c) zmod (b$*c) = (a zmod b) $* c" apply (cut_tac c = "c" in zmod_zmult_zmult1) apply (auto simp add: zmult_commute) done (** Quotients of signs **) lemma zdiv_neg_pos_less0: "\a $< #0; #0 $< b\ \ a zdiv b $< #0" apply (subgoal_tac "a zdiv b $\ #-1") apply (erule zle_zless_trans) apply (simp (no_asm)) apply (rule zle_trans) apply (rule_tac a' = "#-1" in zdiv_mono1) apply (rule zless_add1_iff_zle [THEN iffD1]) apply (simp (no_asm)) apply (auto simp add: zdiv_minus1) done lemma zdiv_nonneg_neg_le0: "\#0 $\ a; b $< #0\ \ a zdiv b $\ #0" apply (drule zdiv_mono1_neg) apply auto done lemma pos_imp_zdiv_nonneg_iff: "#0 $< b \ (#0 $\ a zdiv b) \ (#0 $\ a)" apply auto apply (drule_tac [2] zdiv_mono1) apply (auto simp add: neq_iff_zless) apply (simp (no_asm_use) add: not_zless_iff_zle [THEN iff_sym]) apply (blast intro: zdiv_neg_pos_less0) done lemma neg_imp_zdiv_nonneg_iff: "b $< #0 \ (#0 $\ a zdiv b) \ (a $\ #0)" apply (subst zdiv_zminus_zminus [symmetric]) apply (rule iff_trans) apply (rule pos_imp_zdiv_nonneg_iff) apply auto done (*But not (a zdiv b $\ 0 iff a$\0); consider a=1, b=2 when a zdiv b = 0.*) lemma pos_imp_zdiv_neg_iff: "#0 $< b \ (a zdiv b $< #0) \ (a $< #0)" apply (simp (no_asm_simp) add: not_zle_iff_zless [THEN iff_sym]) apply (erule pos_imp_zdiv_nonneg_iff) done (*Again the law fails for $\: consider a = -1, b = -2 when a zdiv b = 0*) lemma neg_imp_zdiv_neg_iff: "b $< #0 \ (a zdiv b $< #0) \ (#0 $< a)" apply (simp (no_asm_simp) add: not_zle_iff_zless [THEN iff_sym]) apply (erule neg_imp_zdiv_nonneg_iff) done (* THESE REMAIN TO BE CONVERTED -- but aren't that useful! subsection{* Speeding up the division algorithm with shifting *} (** computing "zdiv" by shifting **) lemma pos_zdiv_mult_2: "#0 $\ a \ (#1 $+ #2$*b) zdiv (#2$*a) = b zdiv a" apply (case_tac "a = #0") apply (subgoal_tac "#1 $\ a") apply (arith_tac 2) apply (subgoal_tac "#1 $< a $* #2") apply (arith_tac 2) apply (subgoal_tac "#2$* (#1 $+ b zmod a) $\ #2$*a") apply (rule_tac [2] zmult_zle_mono2) apply (auto simp add: zadd_commute zmult_commute add1_zle_iff pos_mod_bound) apply (subst zdiv_zadd1_eq) apply (simp (no_asm_simp) add: zdiv_zmult_zmult2 zmod_zmult_zmult2 zdiv_pos_pos_trivial) apply (subst zdiv_pos_pos_trivial) apply (simp (no_asm_simp) add: [zmod_pos_pos_trivial pos_mod_sign [THEN zadd_zle_mono1] RSN (2,zle_trans) ]) apply (auto simp add: zmod_pos_pos_trivial) apply (subgoal_tac "#0 $\ b zmod a") apply (asm_simp_tac (simpset () add: pos_mod_sign) 2) apply arith done lemma neg_zdiv_mult_2: "a $\ #0 \ (#1 $+ #2$*b) zdiv (#2$*a) \ (b$+#1) zdiv a" apply (subgoal_tac " (#1 $+ #2$* ($-b-#1)) zdiv (#2 $* ($-a)) \ ($-b-#1) zdiv ($-a)") apply (rule_tac [2] pos_zdiv_mult_2) apply (auto simp add: zmult_zminus_right) apply (subgoal_tac " (#-1 - (#2 $* b)) = - (#1 $+ (#2 $* b))") apply (Simp_tac 2) apply (asm_full_simp_tac (HOL_ss add: zdiv_zminus_zminus zdiff_def zminus_zadd_distrib [symmetric]) done (*Not clear why this must be proved separately; probably integ_of causes simplification problems*) lemma lemma: "\ #0 $\ x \ x $\ #0" apply auto done lemma zdiv_integ_of_BIT: "integ_of (v BIT b) zdiv integ_of (w BIT False) = (if \b | #0 $\ integ_of w then integ_of v zdiv (integ_of w) else (integ_of v $+ #1) zdiv (integ_of w))" apply (simp_tac (simpset_of @{theory_context Int} add: zadd_assoc integ_of_BIT) apply (simp (no_asm_simp) del: bin_arith_extra_simps@bin_rel_simps add: zdiv_zmult_zmult1 pos_zdiv_mult_2 lemma neg_zdiv_mult_2) done declare zdiv_integ_of_BIT [simp] (** computing "zmod" by shifting (proofs resemble those for "zdiv") **) lemma pos_zmod_mult_2: "#0 $\ a \ (#1 $+ #2$*b) zmod (#2$*a) = #1 $+ #2 $* (b zmod a)" apply (case_tac "a = #0") apply (subgoal_tac "#1 $\ a") apply (arith_tac 2) apply (subgoal_tac "#1 $< a $* #2") apply (arith_tac 2) apply (subgoal_tac "#2$* (#1 $+ b zmod a) $\ #2$*a") apply (rule_tac [2] zmult_zle_mono2) apply (auto simp add: zadd_commute zmult_commute add1_zle_iff pos_mod_bound) apply (subst zmod_zadd1_eq) apply (simp (no_asm_simp) add: zmod_zmult_zmult2 zmod_pos_pos_trivial) apply (rule zmod_pos_pos_trivial) apply (simp (no_asm_simp) # add: [zmod_pos_pos_trivial pos_mod_sign [THEN zadd_zle_mono1] RSN (2,zle_trans) ]) apply (auto simp add: zmod_pos_pos_trivial) apply (subgoal_tac "#0 $\ b zmod a") apply (asm_simp_tac (simpset () add: pos_mod_sign) 2) apply arith done lemma neg_zmod_mult_2: "a $\ #0 \ (#1 $+ #2$*b) zmod (#2$*a) = #2 $* ((b$+#1) zmod a) - #1" apply (subgoal_tac " (#1 $+ #2$* ($-b-#1)) zmod (#2$* ($-a)) = #1 $+ #2$* (($-b-#1) zmod ($-a))") apply (rule_tac [2] pos_zmod_mult_2) apply (auto simp add: zmult_zminus_right) apply (subgoal_tac " (#-1 - (#2 $* b)) = - (#1 $+ (#2 $* b))") apply (Simp_tac 2) apply (asm_full_simp_tac (HOL_ss add: zmod_zminus_zminus zdiff_def zminus_zadd_distrib [symmetric]) apply (dtac (zminus_equation [THEN iffD1, symmetric]) apply auto done lemma zmod_integ_of_BIT: "integ_of (v BIT b) zmod integ_of (w BIT False) = (if b then if #0 $\ integ_of w then #2 $* (integ_of v zmod integ_of w) $+ #1 else #2 $* ((integ_of v $+ #1) zmod integ_of w) - #1 else #2 $* (integ_of v zmod integ_of w))" apply (simp_tac (simpset_of @{theory_context Int} add: zadd_assoc integ_of_BIT) apply (simp (no_asm_simp) del: bin_arith_extra_simps@bin_rel_simps add: zmod_zmult_zmult1 pos_zmod_mult_2 lemma neg_zmod_mult_2) done declare zmod_integ_of_BIT [simp] *) end diff --git a/src/ZF/List.thy b/src/ZF/List.thy --- a/src/ZF/List.thy +++ b/src/ZF/List.thy @@ -1,1270 +1,1270 @@ (* Title: ZF/List.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Lists in Zermelo-Fraenkel Set Theory\ theory List imports Datatype ArithSimp begin consts list :: "i\i" datatype "list(A)" = Nil | Cons ("a \ A", "l \ list(A)") syntax "_Nil" :: i (\[]\) "_List" :: "is \ i" (\[(_)]\) translations "[x, xs]" == "CONST Cons(x, [xs])" "[x]" == "CONST Cons(x, [])" "[]" == "CONST Nil" consts length :: "i\i" hd :: "i\i" tl :: "i\i" primrec "length([]) = 0" "length(Cons(a,l)) = succ(length(l))" primrec "hd([]) = 0" "hd(Cons(a,l)) = a" primrec "tl([]) = []" "tl(Cons(a,l)) = l" consts map :: "[i\i, i] \ i" set_of_list :: "i\i" app :: "[i,i]\i" (infixr \@\ 60) (*map is a binding operator -- it applies to meta-level functions, not object-level functions. This simplifies the final form of term_rec_conv, although complicating its derivation.*) primrec "map(f,[]) = []" "map(f,Cons(a,l)) = Cons(f(a), map(f,l))" primrec "set_of_list([]) = 0" "set_of_list(Cons(a,l)) = cons(a, set_of_list(l))" primrec app_Nil: "[] @ ys = ys" app_Cons: "(Cons(a,l)) @ ys = Cons(a, l @ ys)" consts rev :: "i\i" flat :: "i\i" list_add :: "i\i" primrec "rev([]) = []" "rev(Cons(a,l)) = rev(l) @ [a]" primrec "flat([]) = []" "flat(Cons(l,ls)) = l @ flat(ls)" primrec "list_add([]) = 0" "list_add(Cons(a,l)) = a #+ list_add(l)" consts drop :: "[i,i]\i" primrec drop_0: "drop(0,l) = l" drop_succ: "drop(succ(i), l) = tl (drop(i,l))" (*** Thanks to Sidi Ehmety for the following ***) definition (* Function `take' returns the first n elements of a list *) take :: "[i,i]\i" where "take(n, as) \ list_rec(\n\nat. [], \a l r. \n\nat. nat_case([], \m. Cons(a, r`m), n), as)`n" definition nth :: "[i, i]\i" where \ \returns the (n+1)th element of a list, or 0 if the list is too short.\ "nth(n, as) \ list_rec(\n\nat. 0, \a l r. \n\nat. nat_case(a, \m. r`m, n), as) ` n" definition list_update :: "[i, i, i]\i" where "list_update(xs, i, v) \ list_rec(\n\nat. Nil, \u us vs. \n\nat. nat_case(Cons(v, us), \m. Cons(u, vs`m), n), xs)`i" consts filter :: "[i\o, i] \ i" upt :: "[i, i] \i" primrec "filter(P, Nil) = Nil" "filter(P, Cons(x, xs)) = (if P(x) then Cons(x, filter(P, xs)) else filter(P, xs))" primrec "upt(i, 0) = Nil" "upt(i, succ(j)) = (if i \ j then upt(i, j)@[j] else Nil)" definition min :: "[i,i] \i" where "min(x, y) \ (if x \ y then x else y)" definition max :: "[i, i] \i" where "max(x, y) \ (if x \ y then y else x)" (*** Aspects of the datatype definition ***) declare list.intros [simp,TC] (*An elimination rule, for type-checking*) inductive_cases ConsE: "Cons(a,l) \ list(A)" lemma Cons_type_iff [simp]: "Cons(a,l) \ list(A) \ a \ A \ l \ list(A)" by (blast elim: ConsE) (*Proving freeness results*) lemma Cons_iff: "Cons(a,l)=Cons(a',l') \ a=a' \ l=l'" by auto lemma Nil_Cons_iff: "\ Nil=Cons(a,l)" by auto lemma list_unfold: "list(A) = {0} + (A * list(A))" by (blast intro!: list.intros [unfolded list.con_defs] elim: list.cases [unfolded list.con_defs]) (** Lemmas to justify using "list" in other recursive type definitions **) lemma list_mono: "A<=B \ list(A) \ list(B)" apply (unfold list.defs ) apply (rule lfp_mono) apply (simp_all add: list.bnd_mono) apply (assumption | rule univ_mono basic_monos)+ done (*There is a similar proof by list induction.*) lemma list_univ: "list(univ(A)) \ univ(A)" apply (unfold list.defs list.con_defs) apply (rule lfp_lowerbound) apply (rule_tac [2] A_subset_univ [THEN univ_mono]) apply (blast intro!: zero_in_univ Inl_in_univ Inr_in_univ Pair_in_univ) done (*These two theorems justify datatypes involving list(nat), list(A), ...*) lemmas list_subset_univ = subset_trans [OF list_mono list_univ] lemma list_into_univ: "\l \ list(A); A \ univ(B)\ \ l \ univ(B)" by (blast intro: list_subset_univ [THEN subsetD]) lemma list_case_type: "\l \ list(A); c \ C(Nil); \x y. \x \ A; y \ list(A)\ \ h(x,y): C(Cons(x,y)) \ \ list_case(c,h,l) \ C(l)" by (erule list.induct, auto) lemma list_0_triv: "list(0) = {Nil}" apply (rule equalityI, auto) apply (induct_tac x, auto) done (*** List functions ***) lemma tl_type: "l \ list(A) \ tl(l) \ list(A)" apply (induct_tac "l") apply (simp_all (no_asm_simp) add: list.intros) done (** drop **) lemma drop_Nil [simp]: "i \ nat \ drop(i, Nil) = Nil" apply (induct_tac "i") apply (simp_all (no_asm_simp)) done lemma drop_succ_Cons [simp]: "i \ nat \ drop(succ(i), Cons(a,l)) = drop(i,l)" apply (rule sym) apply (induct_tac "i") apply (simp (no_asm)) apply (simp (no_asm_simp)) done lemma drop_type [simp,TC]: "\i \ nat; l \ list(A)\ \ drop(i,l) \ list(A)" apply (induct_tac "i") apply (simp_all (no_asm_simp) add: tl_type) done declare drop_succ [simp del] (** Type checking -- proved by induction, as usual **) lemma list_rec_type [TC]: "\l \ list(A); c \ C(Nil); \x y r. \x \ A; y \ list(A); r \ C(y)\ \ h(x,y,r): C(Cons(x,y)) \ \ list_rec(c,h,l) \ C(l)" by (induct_tac "l", auto) (** map **) lemma map_type [TC]: "\l \ list(A); \x. x \ A \ h(x): B\ \ map(h,l) \ list(B)" apply (simp add: map_list_def) apply (typecheck add: list.intros list_rec_type, blast) done lemma map_type2 [TC]: "l \ list(A) \ map(h,l) \ list({h(u). u \ A})" apply (erule map_type) apply (erule RepFunI) done (** length **) lemma length_type [TC]: "l \ list(A) \ length(l) \ nat" by (simp add: length_list_def) lemma lt_length_in_nat: "\x < length(xs); xs \ list(A)\ \ x \ nat" by (frule lt_nat_in_nat, typecheck) (** app **) lemma app_type [TC]: "\xs: list(A); ys: list(A)\ \ xs@ys \ list(A)" by (simp add: app_list_def) (** rev **) lemma rev_type [TC]: "xs: list(A) \ rev(xs) \ list(A)" by (simp add: rev_list_def) (** flat **) lemma flat_type [TC]: "ls: list(list(A)) \ flat(ls) \ list(A)" by (simp add: flat_list_def) (** set_of_list **) lemma set_of_list_type [TC]: "l \ list(A) \ set_of_list(l) \ Pow(A)" -apply (unfold set_of_list_list_def) + unfolding set_of_list_list_def apply (erule list_rec_type, auto) done lemma set_of_list_append: "xs: list(A) \ set_of_list (xs@ys) = set_of_list(xs) \ set_of_list(ys)" apply (erule list.induct) apply (simp_all (no_asm_simp) add: Un_cons) done (** list_add **) lemma list_add_type [TC]: "xs: list(nat) \ list_add(xs) \ nat" by (simp add: list_add_list_def) (*** theorems about map ***) lemma map_ident [simp]: "l \ list(A) \ map(\u. u, l) = l" apply (induct_tac "l") apply (simp_all (no_asm_simp)) done lemma map_compose: "l \ list(A) \ map(h, map(j,l)) = map(\u. h(j(u)), l)" apply (induct_tac "l") apply (simp_all (no_asm_simp)) done lemma map_app_distrib: "xs: list(A) \ map(h, xs@ys) = map(h,xs) @ map(h,ys)" apply (induct_tac "xs") apply (simp_all (no_asm_simp)) done lemma map_flat: "ls: list(list(A)) \ map(h, flat(ls)) = flat(map(map(h),ls))" apply (induct_tac "ls") apply (simp_all (no_asm_simp) add: map_app_distrib) done lemma list_rec_map: "l \ list(A) \ list_rec(c, d, map(h,l)) = list_rec(c, \x xs r. d(h(x), map(h,xs), r), l)" apply (induct_tac "l") apply (simp_all (no_asm_simp)) done (** theorems about list(Collect(A,P)) -- used in Induct/Term.thy **) (* @{term"c \ list(Collect(B,P)) \ c \ list"} *) lemmas list_CollectD = Collect_subset [THEN list_mono, THEN subsetD] lemma map_list_Collect: "l \ list({x \ A. h(x)=j(x)}) \ map(h,l) = map(j,l)" apply (induct_tac "l") apply (simp_all (no_asm_simp)) done (*** theorems about length ***) lemma length_map [simp]: "xs: list(A) \ length(map(h,xs)) = length(xs)" by (induct_tac "xs", simp_all) lemma length_app [simp]: "\xs: list(A); ys: list(A)\ \ length(xs@ys) = length(xs) #+ length(ys)" by (induct_tac "xs", simp_all) lemma length_rev [simp]: "xs: list(A) \ length(rev(xs)) = length(xs)" apply (induct_tac "xs") apply (simp_all (no_asm_simp) add: length_app) done lemma length_flat: "ls: list(list(A)) \ length(flat(ls)) = list_add(map(length,ls))" apply (induct_tac "ls") apply (simp_all (no_asm_simp) add: length_app) done (** Length and drop **) (*Lemma for the inductive step of drop_length*) lemma drop_length_Cons [rule_format]: "xs: list(A) \ \x. \z zs. drop(length(xs), Cons(x,xs)) = Cons(z,zs)" by (erule list.induct, simp_all) lemma drop_length [rule_format]: "l \ list(A) \ \i \ length(l). (\z zs. drop(i,l) = Cons(z,zs))" apply (erule list.induct, simp_all, safe) apply (erule drop_length_Cons) apply (rule natE) apply (erule Ord_trans [OF asm_rl length_type Ord_nat], assumption, simp_all) apply (blast intro: succ_in_naturalD length_type) done (*** theorems about app ***) lemma app_right_Nil [simp]: "xs: list(A) \ xs@Nil=xs" by (erule list.induct, simp_all) lemma app_assoc: "xs: list(A) \ (xs@ys)@zs = xs@(ys@zs)" by (induct_tac "xs", simp_all) lemma flat_app_distrib: "ls: list(list(A)) \ flat(ls@ms) = flat(ls)@flat(ms)" apply (induct_tac "ls") apply (simp_all (no_asm_simp) add: app_assoc) done (*** theorems about rev ***) lemma rev_map_distrib: "l \ list(A) \ rev(map(h,l)) = map(h,rev(l))" apply (induct_tac "l") apply (simp_all (no_asm_simp) add: map_app_distrib) done (*Simplifier needs the premises as assumptions because rewriting will not instantiate the variable ?A in the rules' typing conditions; note that rev_type does not instantiate ?A. Only the premises do. *) lemma rev_app_distrib: "\xs: list(A); ys: list(A)\ \ rev(xs@ys) = rev(ys)@rev(xs)" apply (erule list.induct) apply (simp_all add: app_assoc) done lemma rev_rev_ident [simp]: "l \ list(A) \ rev(rev(l))=l" apply (induct_tac "l") apply (simp_all (no_asm_simp) add: rev_app_distrib) done lemma rev_flat: "ls: list(list(A)) \ rev(flat(ls)) = flat(map(rev,rev(ls)))" apply (induct_tac "ls") apply (simp_all add: map_app_distrib flat_app_distrib rev_app_distrib) done (*** theorems about list_add ***) lemma list_add_app: "\xs: list(nat); ys: list(nat)\ \ list_add(xs@ys) = list_add(ys) #+ list_add(xs)" apply (induct_tac "xs", simp_all) done lemma list_add_rev: "l \ list(nat) \ list_add(rev(l)) = list_add(l)" apply (induct_tac "l") apply (simp_all (no_asm_simp) add: list_add_app) done lemma list_add_flat: "ls: list(list(nat)) \ list_add(flat(ls)) = list_add(map(list_add,ls))" apply (induct_tac "ls") apply (simp_all (no_asm_simp) add: list_add_app) done (** New induction rules **) lemma list_append_induct [case_names Nil snoc, consumes 1]: "\l \ list(A); P(Nil); \x y. \x \ A; y \ list(A); P(y)\ \ P(y @ [x]) \ \ P(l)" apply (subgoal_tac "P(rev(rev(l)))", simp) apply (erule rev_type [THEN list.induct], simp_all) done lemma list_complete_induct_lemma [rule_format]: assumes ih: "\l. \l \ list(A); \l' \ list(A). length(l') < length(l) \ P(l')\ \ P(l)" shows "n \ nat \ \l \ list(A). length(l) < n \ P(l)" apply (induct_tac n, simp) apply (blast intro: ih elim!: leE) done theorem list_complete_induct: "\l \ list(A); \l. \l \ list(A); \l' \ list(A). length(l') < length(l) \ P(l')\ \ P(l) \ \ P(l)" apply (rule list_complete_induct_lemma [of A]) prefer 4 apply (rule le_refl, simp) apply blast apply simp apply assumption done (*** Thanks to Sidi Ehmety for these results about min, take, etc. ***) (** min FIXME: replace by Int! **) (* Min theorems are also true for i, j ordinals *) lemma min_sym: "\i \ nat; j \ nat\ \ min(i,j)=min(j,i)" -apply (unfold min_def) + unfolding min_def apply (auto dest!: not_lt_imp_le dest: lt_not_sym intro: le_anti_sym) done lemma min_type [simp,TC]: "\i \ nat; j \ nat\ \ min(i,j):nat" by (unfold min_def, auto) lemma min_0 [simp]: "i \ nat \ min(0,i) = 0" -apply (unfold min_def) + unfolding min_def apply (auto dest: not_lt_imp_le) done lemma min_02 [simp]: "i \ nat \ min(i, 0) = 0" -apply (unfold min_def) + unfolding min_def apply (auto dest: not_lt_imp_le) done lemma lt_min_iff: "\i \ nat; j \ nat; k \ nat\ \ i i ii \ nat; j \ nat\ \ min(succ(i), succ(j))= succ(min(i, j))" apply (unfold min_def, auto) done (*** more theorems about lists ***) (** filter **) lemma filter_append [simp]: "xs:list(A) \ filter(P, xs@ys) = filter(P, xs) @ filter(P, ys)" by (induct_tac "xs", auto) lemma filter_type [simp,TC]: "xs:list(A) \ filter(P, xs):list(A)" by (induct_tac "xs", auto) lemma length_filter: "xs:list(A) \ length(filter(P, xs)) \ length(xs)" apply (induct_tac "xs", auto) apply (rule_tac j = "length (l) " in le_trans) apply (auto simp add: le_iff) done lemma filter_is_subset: "xs:list(A) \ set_of_list(filter(P,xs)) \ set_of_list(xs)" by (induct_tac "xs", auto) lemma filter_False [simp]: "xs:list(A) \ filter(\p. False, xs) = Nil" by (induct_tac "xs", auto) lemma filter_True [simp]: "xs:list(A) \ filter(\p. True, xs) = xs" by (induct_tac "xs", auto) (** length **) lemma length_is_0_iff [simp]: "xs:list(A) \ length(xs)=0 \ xs=Nil" by (erule list.induct, auto) lemma length_is_0_iff2 [simp]: "xs:list(A) \ 0 = length(xs) \ xs=Nil" by (erule list.induct, auto) lemma length_tl [simp]: "xs:list(A) \ length(tl(xs)) = length(xs) #- 1" by (erule list.induct, auto) lemma length_greater_0_iff: "xs:list(A) \ 0 xs \ Nil" by (erule list.induct, auto) lemma length_succ_iff: "xs:list(A) \ length(xs)=succ(n) \ (\y ys. xs=Cons(y, ys) \ length(ys)=n)" by (erule list.induct, auto) (** more theorems about append **) lemma append_is_Nil_iff [simp]: "xs:list(A) \ (xs@ys = Nil) \ (xs=Nil \ ys = Nil)" by (erule list.induct, auto) lemma append_is_Nil_iff2 [simp]: "xs:list(A) \ (Nil = xs@ys) \ (xs=Nil \ ys = Nil)" by (erule list.induct, auto) lemma append_left_is_self_iff [simp]: "xs:list(A) \ (xs@ys = xs) \ (ys = Nil)" by (erule list.induct, auto) lemma append_left_is_self_iff2 [simp]: "xs:list(A) \ (xs = xs@ys) \ (ys = Nil)" by (erule list.induct, auto) (*TOO SLOW as a default simprule!*) lemma append_left_is_Nil_iff [rule_format]: "\xs:list(A); ys:list(A); zs:list(A)\ \ length(ys)=length(zs) \ (xs@ys=zs \ (xs=Nil \ ys=zs))" apply (erule list.induct) apply (auto simp add: length_app) done (*TOO SLOW as a default simprule!*) lemma append_left_is_Nil_iff2 [rule_format]: "\xs:list(A); ys:list(A); zs:list(A)\ \ length(ys)=length(zs) \ (zs=ys@xs \ (xs=Nil \ ys=zs))" apply (erule list.induct) apply (auto simp add: length_app) done lemma append_eq_append_iff [rule_format]: "xs:list(A) \ \ys \ list(A). length(xs)=length(ys) \ (xs@us = ys@vs) \ (xs=ys \ us=vs)" apply (erule list.induct) apply (simp (no_asm_simp)) apply clarify apply (erule_tac a = ys in list.cases, auto) done declare append_eq_append_iff [simp] lemma append_eq_append [rule_format]: "xs:list(A) \ \ys \ list(A). \us \ list(A). \vs \ list(A). length(us) = length(vs) \ (xs@us = ys@vs) \ (xs=ys \ us=vs)" apply (induct_tac "xs") apply (force simp add: length_app, clarify) apply (erule_tac a = ys in list.cases, simp) apply (subgoal_tac "Cons (a, l) @ us =vs") apply (drule rev_iffD1 [OF _ append_left_is_Nil_iff], simp_all, blast) done lemma append_eq_append_iff2 [simp]: "\xs:list(A); ys:list(A); us:list(A); vs:list(A); length(us)=length(vs)\ \ xs@us = ys@vs \ (xs=ys \ us=vs)" apply (rule iffI) apply (rule append_eq_append, auto) done lemma append_self_iff [simp]: "\xs:list(A); ys:list(A); zs:list(A)\ \ xs@ys=xs@zs \ ys=zs" by simp lemma append_self_iff2 [simp]: "\xs:list(A); ys:list(A); zs:list(A)\ \ ys@xs=zs@xs \ ys=zs" by simp (* Can also be proved from append_eq_append_iff2, but the proof requires two more hypotheses: x \ A and y \ A *) lemma append1_eq_iff [rule_format]: "xs:list(A) \ \ys \ list(A). xs@[x] = ys@[y] \ (xs = ys \ x=y)" apply (erule list.induct) apply clarify apply (erule list.cases) apply simp_all txt\Inductive step\ apply clarify apply (erule_tac a=ys in list.cases, simp_all) done declare append1_eq_iff [simp] lemma append_right_is_self_iff [simp]: "\xs:list(A); ys:list(A)\ \ (xs@ys = ys) \ (xs=Nil)" by (simp (no_asm_simp) add: append_left_is_Nil_iff) lemma append_right_is_self_iff2 [simp]: "\xs:list(A); ys:list(A)\ \ (ys = xs@ys) \ (xs=Nil)" apply (rule iffI) apply (drule sym, auto) done lemma hd_append [rule_format]: "xs:list(A) \ xs \ Nil \ hd(xs @ ys) = hd(xs)" by (induct_tac "xs", auto) declare hd_append [simp] lemma tl_append [rule_format]: "xs:list(A) \ xs\Nil \ tl(xs @ ys) = tl(xs)@ys" by (induct_tac "xs", auto) declare tl_append [simp] (** rev **) lemma rev_is_Nil_iff [simp]: "xs:list(A) \ (rev(xs) = Nil \ xs = Nil)" by (erule list.induct, auto) lemma Nil_is_rev_iff [simp]: "xs:list(A) \ (Nil = rev(xs) \ xs = Nil)" by (erule list.induct, auto) lemma rev_is_rev_iff [rule_format]: "xs:list(A) \ \ys \ list(A). rev(xs)=rev(ys) \ xs=ys" apply (erule list.induct, force, clarify) apply (erule_tac a = ys in list.cases, auto) done declare rev_is_rev_iff [simp] lemma rev_list_elim [rule_format]: "xs:list(A) \ (xs=Nil \ P) \ (\ys \ list(A). \y \ A. xs =ys@[y] \P)\P" by (erule list_append_induct, auto) (** more theorems about drop **) lemma length_drop [rule_format]: "n \ nat \ \xs \ list(A). length(drop(n, xs)) = length(xs) #- n" apply (erule nat_induct) apply (auto elim: list.cases) done declare length_drop [simp] lemma drop_all [rule_format]: "n \ nat \ \xs \ list(A). length(xs) \ n \ drop(n, xs)=Nil" apply (erule nat_induct) apply (auto elim: list.cases) done declare drop_all [simp] lemma drop_append [rule_format]: "n \ nat \ \xs \ list(A). drop(n, xs@ys) = drop(n,xs) @ drop(n #- length(xs), ys)" apply (induct_tac "n") apply (auto elim: list.cases) done lemma drop_drop: "m \ nat \ \xs \ list(A). \n \ nat. drop(n, drop(m, xs))=drop(n #+ m, xs)" apply (induct_tac "m") apply (auto elim: list.cases) done (** take **) lemma take_0 [simp]: "xs:list(A) \ take(0, xs) = Nil" -apply (unfold take_def) + unfolding take_def apply (erule list.induct, auto) done lemma take_succ_Cons [simp]: "n \ nat \ take(succ(n), Cons(a, xs)) = Cons(a, take(n, xs))" by (simp add: take_def) (* Needed for proving take_all *) lemma take_Nil [simp]: "n \ nat \ take(n, Nil) = Nil" by (unfold take_def, auto) lemma take_all [rule_format]: "n \ nat \ \xs \ list(A). length(xs) \ n \ take(n, xs) = xs" apply (erule nat_induct) apply (auto elim: list.cases) done declare take_all [simp] lemma take_type [rule_format]: "xs:list(A) \ \n \ nat. take(n, xs):list(A)" apply (erule list.induct, simp, clarify) apply (erule natE, auto) done declare take_type [simp,TC] lemma take_append [rule_format]: "xs:list(A) \ \ys \ list(A). \n \ nat. take(n, xs @ ys) = take(n, xs) @ take(n #- length(xs), ys)" apply (erule list.induct, simp, clarify) apply (erule natE, auto) done declare take_append [simp] lemma take_take [rule_format]: "m \ nat \ \xs \ list(A). \n \ nat. take(n, take(m,xs))= take(min(n, m), xs)" apply (induct_tac "m", auto) apply (erule_tac a = xs in list.cases) apply (auto simp add: take_Nil) apply (erule_tac n=n in natE) apply (auto intro: take_0 take_type) done (** nth **) lemma nth_0 [simp]: "nth(0, Cons(a, l)) = a" by (simp add: nth_def) lemma nth_Cons [simp]: "n \ nat \ nth(succ(n), Cons(a,l)) = nth(n,l)" by (simp add: nth_def) lemma nth_empty [simp]: "nth(n, Nil) = 0" by (simp add: nth_def) lemma nth_type [rule_format]: "xs:list(A) \ \n. n < length(xs) \ nth(n,xs) \ A" apply (erule list.induct, simp, clarify) apply (subgoal_tac "n \ nat") apply (erule natE, auto dest!: le_in_nat) done declare nth_type [simp,TC] lemma nth_eq_0 [rule_format]: "xs:list(A) \ \n \ nat. length(xs) \ n \ nth(n,xs) = 0" apply (erule list.induct, simp, clarify) apply (erule natE, auto) done lemma nth_append [rule_format]: "xs:list(A) \ \n \ nat. nth(n, xs @ ys) = (if n < length(xs) then nth(n,xs) else nth(n #- length(xs), ys))" apply (induct_tac "xs", simp, clarify) apply (erule natE, auto) done lemma set_of_list_conv_nth: "xs:list(A) \ set_of_list(xs) = {x \ A. \i\nat. i x = nth(i,xs)}" apply (induct_tac "xs", simp_all) apply (rule equalityI, auto) apply (rule_tac x = 0 in bexI, auto) apply (erule natE, auto) done (* Other theorems about lists *) lemma nth_take_lemma [rule_format]: "k \ nat \ \xs \ list(A). (\ys \ list(A). k \ length(xs) \ k \ length(ys) \ (\i \ nat. i nth(i,xs) = nth(i,ys))\ take(k,xs) = take(k,ys))" apply (induct_tac "k") apply (simp_all (no_asm_simp) add: lt_succ_eq_0_disj all_conj_distrib) apply clarify (*Both lists are non-empty*) apply (erule_tac a=xs in list.cases, simp) apply (erule_tac a=ys in list.cases, clarify) apply (simp (no_asm_use) ) apply clarify apply (simp (no_asm_simp)) apply (rule conjI, force) apply (rename_tac y ys z zs) apply (drule_tac x = zs and x1 = ys in bspec [THEN bspec], auto) done lemma nth_equalityI [rule_format]: "\xs:list(A); ys:list(A); length(xs) = length(ys); \i \ nat. i < length(xs) \ nth(i,xs) = nth(i,ys)\ \ xs = ys" apply (subgoal_tac "length (xs) \ length (ys) ") apply (cut_tac k="length(xs)" and xs=xs and ys=ys in nth_take_lemma) apply (simp_all add: take_all) done (*The famous take-lemma*) lemma take_equalityI [rule_format]: "\xs:list(A); ys:list(A); (\i \ nat. take(i, xs) = take(i,ys))\ \ xs = ys" apply (case_tac "length (xs) \ length (ys) ") apply (drule_tac x = "length (ys) " in bspec) apply (drule_tac [3] not_lt_imp_le) apply (subgoal_tac [5] "length (ys) \ length (xs) ") apply (rule_tac [6] j = "succ (length (ys))" in le_trans) apply (rule_tac [6] leI) apply (drule_tac [5] x = "length (xs) " in bspec) apply (simp_all add: take_all) done lemma nth_drop [rule_format]: "n \ nat \ \i \ nat. \xs \ list(A). nth(i, drop(n, xs)) = nth(n #+ i, xs)" apply (induct_tac "n", simp_all, clarify) apply (erule list.cases, auto) done lemma take_succ [rule_format]: "xs\list(A) \ \i. i < length(xs) \ take(succ(i), xs) = take(i,xs) @ [nth(i, xs)]" apply (induct_tac "xs", auto) apply (subgoal_tac "i\nat") apply (erule natE) apply (auto simp add: le_in_nat) done lemma take_add [rule_format]: "\xs\list(A); j\nat\ \ \i\nat. take(i #+ j, xs) = take(i,xs) @ take(j, drop(i,xs))" apply (induct_tac "xs", simp_all, clarify) apply (erule_tac n = i in natE, simp_all) done lemma length_take: "l\list(A) \ \n\nat. length(take(n,l)) = min(n, length(l))" apply (induct_tac "l", safe, simp_all) apply (erule natE, simp_all) done subsection\The function zip\ text\Crafty definition to eliminate a type argument\ consts zip_aux :: "[i,i]\i" primrec (*explicit lambda is required because both arguments of "un" vary*) "zip_aux(B,[]) = (\ys \ list(B). list_case([], \y l. [], ys))" "zip_aux(B,Cons(x,l)) = (\ys \ list(B). list_case(Nil, \y zs. Cons(\x,y\, zip_aux(B,l)`zs), ys))" definition zip :: "[i, i]\i" where "zip(xs, ys) \ zip_aux(set_of_list(ys),xs)`ys" (* zip equations *) lemma list_on_set_of_list: "xs \ list(A) \ xs \ list(set_of_list(xs))" apply (induct_tac xs, simp_all) apply (blast intro: list_mono [THEN subsetD]) done lemma zip_Nil [simp]: "ys:list(A) \ zip(Nil, ys)=Nil" apply (simp add: zip_def list_on_set_of_list [of _ A]) apply (erule list.cases, simp_all) done lemma zip_Nil2 [simp]: "xs:list(A) \ zip(xs, Nil)=Nil" apply (simp add: zip_def list_on_set_of_list [of _ A]) apply (erule list.cases, simp_all) done lemma zip_aux_unique [rule_format]: "\B<=C; xs \ list(A)\ \ \ys \ list(B). zip_aux(C,xs) ` ys = zip_aux(B,xs) ` ys" apply (induct_tac xs) apply simp_all apply (blast intro: list_mono [THEN subsetD], clarify) apply (erule_tac a=ys in list.cases, auto) apply (blast intro: list_mono [THEN subsetD]) done lemma zip_Cons_Cons [simp]: "\xs:list(A); ys:list(B); x \ A; y \ B\ \ zip(Cons(x,xs), Cons(y, ys)) = Cons(\x,y\, zip(xs, ys))" apply (simp add: zip_def, auto) apply (rule zip_aux_unique, auto) apply (simp add: list_on_set_of_list [of _ B]) apply (blast intro: list_on_set_of_list list_mono [THEN subsetD]) done lemma zip_type [rule_format]: "xs:list(A) \ \ys \ list(B). zip(xs, ys):list(A*B)" apply (induct_tac "xs") apply (simp (no_asm)) apply clarify apply (erule_tac a = ys in list.cases, auto) done declare zip_type [simp,TC] (* zip length *) lemma length_zip [rule_format]: "xs:list(A) \ \ys \ list(B). length(zip(xs,ys)) = min(length(xs), length(ys))" -apply (unfold min_def) + unfolding min_def apply (induct_tac "xs", simp_all, clarify) apply (erule_tac a = ys in list.cases, auto) done declare length_zip [simp] lemma zip_append1 [rule_format]: "\ys:list(A); zs:list(B)\ \ \xs \ list(A). zip(xs @ ys, zs) = zip(xs, take(length(xs), zs)) @ zip(ys, drop(length(xs),zs))" apply (induct_tac "zs", force, clarify) apply (erule_tac a = xs in list.cases, simp_all) done lemma zip_append2 [rule_format]: "\xs:list(A); zs:list(B)\ \ \ys \ list(B). zip(xs, ys@zs) = zip(take(length(ys), xs), ys) @ zip(drop(length(ys), xs), zs)" apply (induct_tac "xs", force, clarify) apply (erule_tac a = ys in list.cases, auto) done lemma zip_append [simp]: "\length(xs) = length(us); length(ys) = length(vs); xs:list(A); us:list(B); ys:list(A); vs:list(B)\ \ zip(xs@ys,us@vs) = zip(xs, us) @ zip(ys, vs)" by (simp (no_asm_simp) add: zip_append1 drop_append diff_self_eq_0) lemma zip_rev [rule_format]: "ys:list(B) \ \xs \ list(A). length(xs) = length(ys) \ zip(rev(xs), rev(ys)) = rev(zip(xs, ys))" apply (induct_tac "ys", force, clarify) apply (erule_tac a = xs in list.cases) apply (auto simp add: length_rev) done declare zip_rev [simp] lemma nth_zip [rule_format]: "ys:list(B) \ \i \ nat. \xs \ list(A). i < length(xs) \ i < length(ys) \ nth(i,zip(xs, ys)) = " apply (induct_tac "ys", force, clarify) apply (erule_tac a = xs in list.cases, simp) apply (auto elim: natE) done declare nth_zip [simp] lemma set_of_list_zip [rule_format]: "\xs:list(A); ys:list(B); i \ nat\ \ set_of_list(zip(xs, ys)) = {\x, y\:A*B. \i\nat. i < min(length(xs), length(ys)) \ x = nth(i, xs) \ y = nth(i, ys)}" by (force intro!: Collect_cong simp add: lt_min_iff set_of_list_conv_nth) (** list_update **) lemma list_update_Nil [simp]: "i \ nat \list_update(Nil, i, v) = Nil" by (unfold list_update_def, auto) lemma list_update_Cons_0 [simp]: "list_update(Cons(x, xs), 0, v)= Cons(v, xs)" by (unfold list_update_def, auto) lemma list_update_Cons_succ [simp]: "n \ nat \ list_update(Cons(x, xs), succ(n), v)= Cons(x, list_update(xs, n, v))" apply (unfold list_update_def, auto) done lemma list_update_type [rule_format]: "\xs:list(A); v \ A\ \ \n \ nat. list_update(xs, n, v):list(A)" apply (induct_tac "xs") apply (simp (no_asm)) apply clarify apply (erule natE, auto) done declare list_update_type [simp,TC] lemma length_list_update [rule_format]: "xs:list(A) \ \i \ nat. length(list_update(xs, i, v))=length(xs)" apply (induct_tac "xs") apply (simp (no_asm)) apply clarify apply (erule natE, auto) done declare length_list_update [simp] lemma nth_list_update [rule_format]: "\xs:list(A)\ \ \i \ nat. \j \ nat. i < length(xs) \ nth(j, list_update(xs, i, x)) = (if i=j then x else nth(j, xs))" apply (induct_tac "xs") apply simp_all apply clarify apply (rename_tac i j) apply (erule_tac n=i in natE) apply (erule_tac [2] n=j in natE) apply (erule_tac n=j in natE, simp_all, force) done lemma nth_list_update_eq [simp]: "\i < length(xs); xs:list(A)\ \ nth(i, list_update(xs, i,x)) = x" by (simp (no_asm_simp) add: lt_length_in_nat nth_list_update) lemma nth_list_update_neq [rule_format]: "xs:list(A) \ \i \ nat. \j \ nat. i \ j \ nth(j, list_update(xs,i,x)) = nth(j,xs)" apply (induct_tac "xs") apply (simp (no_asm)) apply clarify apply (erule natE) apply (erule_tac [2] natE, simp_all) apply (erule natE, simp_all) done declare nth_list_update_neq [simp] lemma list_update_overwrite [rule_format]: "xs:list(A) \ \i \ nat. i < length(xs) \ list_update(list_update(xs, i, x), i, y) = list_update(xs, i,y)" apply (induct_tac "xs") apply (simp (no_asm)) apply clarify apply (erule natE, auto) done declare list_update_overwrite [simp] lemma list_update_same_conv [rule_format]: "xs:list(A) \ \i \ nat. i < length(xs) \ (list_update(xs, i, x) = xs) \ (nth(i, xs) = x)" apply (induct_tac "xs") apply (simp (no_asm)) apply clarify apply (erule natE, auto) done lemma update_zip [rule_format]: "ys:list(B) \ \i \ nat. \xy \ A*B. \xs \ list(A). length(xs) = length(ys) \ list_update(zip(xs, ys), i, xy) = zip(list_update(xs, i, fst(xy)), list_update(ys, i, snd(xy)))" apply (induct_tac "ys") apply auto apply (erule_tac a = xs in list.cases) apply (auto elim: natE) done lemma set_update_subset_cons [rule_format]: "xs:list(A) \ \i \ nat. set_of_list(list_update(xs, i, x)) \ cons(x, set_of_list(xs))" apply (induct_tac "xs") apply simp apply (rule ballI) apply (erule natE, simp_all, auto) done lemma set_of_list_update_subsetI: "\set_of_list(xs) \ A; xs:list(A); x \ A; i \ nat\ \ set_of_list(list_update(xs, i,x)) \ A" apply (rule subset_trans) apply (rule set_update_subset_cons, auto) done (** upt **) lemma upt_rec: "j \ nat \ upt(i,j) = (if ij \ i; j \ nat\ \ upt(i,j) = Nil" apply (subst upt_rec, auto) apply (auto simp add: le_iff) apply (drule lt_asym [THEN notE], auto) done (*Only needed if upt_Suc is deleted from the simpset*) lemma upt_succ_append: "\i \ j; j \ nat\ \ upt(i,succ(j)) = upt(i, j)@[j]" by simp lemma upt_conv_Cons: "\i nat\ \ upt(i,j) = Cons(i,upt(succ(i),j))" apply (rule trans) apply (rule upt_rec, auto) done lemma upt_type [simp,TC]: "j \ nat \ upt(i,j):list(nat)" by (induct_tac "j", auto) (*LOOPS as a simprule, since j<=j*) lemma upt_add_eq_append: "\i \ j; j \ nat; k \ nat\ \ upt(i, j #+k) = upt(i,j)@upt(j,j#+k)" apply (induct_tac "k") apply (auto simp add: app_assoc app_type) apply (rule_tac j = j in le_trans, auto) done lemma length_upt [simp]: "\i \ nat; j \ nat\ \length(upt(i,j)) = j #- i" apply (induct_tac "j") apply (rule_tac [2] sym) apply (auto dest!: not_lt_imp_le simp add: diff_succ diff_is_0_iff) done lemma nth_upt [simp]: "\i \ nat; j \ nat; k \ nat; i #+ k < j\ \ nth(k, upt(i,j)) = i #+ k" apply (rotate_tac -1, erule rev_mp) apply (induct_tac "j", simp) apply (auto dest!: not_lt_imp_le simp add: nth_append le_iff less_diff_conv add_commute) done lemma take_upt [rule_format]: "\m \ nat; n \ nat\ \ \i \ nat. i #+ m \ n \ take(m, upt(i,n)) = upt(i,i#+m)" apply (induct_tac "m") apply (simp (no_asm_simp) add: take_0) apply clarify apply (subst upt_rec, simp) apply (rule sym) apply (subst upt_rec, simp) apply (simp_all del: upt.simps) apply (rule_tac j = "succ (i #+ x) " in lt_trans2) apply auto done declare take_upt [simp] lemma map_succ_upt: "\m \ nat; n \ nat\ \ map(succ, upt(m,n))= upt(succ(m), succ(n))" apply (induct_tac "n") apply (auto simp add: map_app_distrib) done lemma nth_map [rule_format]: "xs:list(A) \ \n \ nat. n < length(xs) \ nth(n, map(f, xs)) = f(nth(n, xs))" apply (induct_tac "xs", simp) apply (rule ballI) apply (induct_tac "n", auto) done declare nth_map [simp] lemma nth_map_upt [rule_format]: "\m \ nat; n \ nat\ \ \i \ nat. i < n #- m \ nth(i, map(f, upt(m,n))) = f(m #+ i)" apply (rule_tac n = m and m = n in diff_induct, typecheck, simp, simp) apply (subst map_succ_upt [symmetric], simp_all, clarify) apply (subgoal_tac "i < length (upt (0, x))") prefer 2 apply (simp add: less_diff_conv) apply (rule_tac j = "succ (i #+ y) " in lt_trans2) apply simp apply simp apply (subgoal_tac "i < length (upt (y, x))") apply (simp_all add: add_commute less_diff_conv) done (** sublist (a generalization of nth to sets) **) definition sublist :: "[i, i] \ i" where "sublist(xs, A)\ map(fst, (filter(\p. snd(p): A, zip(xs, upt(0,length(xs))))))" lemma sublist_0 [simp]: "xs:list(A) \sublist(xs, 0) =Nil" by (unfold sublist_def, auto) lemma sublist_Nil [simp]: "sublist(Nil, A) = Nil" by (unfold sublist_def, auto) lemma sublist_shift_lemma: "\xs:list(B); i \ nat\ \ map(fst, filter(\p. snd(p):A, zip(xs, upt(i,i #+ length(xs))))) = map(fst, filter(\p. snd(p):nat \ snd(p) #+ i \ A, zip(xs,upt(0,length(xs)))))" apply (erule list_append_induct) apply (simp (no_asm_simp)) apply (auto simp add: add_commute length_app filter_append map_app_distrib) done lemma sublist_type [simp,TC]: "xs:list(B) \ sublist(xs, A):list(B)" -apply (unfold sublist_def) + unfolding sublist_def apply (induct_tac "xs") apply (auto simp add: filter_append map_app_distrib) done lemma upt_add_eq_append2: "\i \ nat; j \ nat\ \ upt(0, i #+ j) = upt(0, i) @ upt(i, i #+ j)" by (simp add: upt_add_eq_append [of 0] nat_0_le) lemma sublist_append: "\xs:list(B); ys:list(B)\ \ sublist(xs@ys, A) = sublist(xs, A) @ sublist(ys, {j \ nat. j #+ length(xs): A})" -apply (unfold sublist_def) + unfolding sublist_def apply (erule_tac l = ys in list_append_induct, simp) apply (simp (no_asm_simp) add: upt_add_eq_append2 app_assoc [symmetric]) apply (auto simp add: sublist_shift_lemma length_type map_app_distrib app_assoc) apply (simp_all add: add_commute) done lemma sublist_Cons: "\xs:list(B); x \ B\ \ sublist(Cons(x, xs), A) = (if 0 \ A then [x] else []) @ sublist(xs, {j \ nat. succ(j) \ A})" apply (erule_tac l = xs in list_append_induct) apply (simp (no_asm_simp) add: sublist_def) apply (simp del: app_Cons add: app_Cons [symmetric] sublist_append, simp) done lemma sublist_singleton [simp]: "sublist([x], A) = (if 0 \ A then [x] else [])" by (simp add: sublist_Cons) lemma sublist_upt_eq_take [rule_format]: "xs:list(A) \ \n\nat. sublist(xs,n) = take(n,xs)" apply (erule list.induct, simp) apply (clarify ) apply (erule natE) apply (simp_all add: nat_eq_Collect_lt Ord_mem_iff_lt sublist_Cons) done declare sublist_upt_eq_take [simp] lemma sublist_Int_eq: "xs \ list(B) \ sublist(xs, A \ nat) = sublist(xs, A)" apply (erule list.induct) apply (simp_all add: sublist_Cons) done text\Repetition of a List Element\ consts repeat :: "[i,i]\i" primrec "repeat(a,0) = []" "repeat(a,succ(n)) = Cons(a,repeat(a,n))" lemma length_repeat: "n \ nat \ length(repeat(a,n)) = n" by (induct_tac n, auto) lemma repeat_succ_app: "n \ nat \ repeat(a,succ(n)) = repeat(a,n) @ [a]" apply (induct_tac n) apply (simp_all del: app_Cons add: app_Cons [symmetric]) done lemma repeat_type [TC]: "\a \ A; n \ nat\ \ repeat(a,n) \ list(A)" by (induct_tac n, auto) end diff --git a/src/ZF/Nat.thy b/src/ZF/Nat.thy --- a/src/ZF/Nat.thy +++ b/src/ZF/Nat.thy @@ -1,297 +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 \ {\x,y\:nat*nat. x \ y}" definition Lt :: i where "Lt \ {\x, y\:nat*nat. x < y}" definition Ge :: i where "Ge \ {\x,y\:nat*nat. y \ x}" definition Gt :: i where "Gt \ {\x,y\: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] 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: 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. jx,y\ \ Le \ x \ y \ x \ nat \ y \ nat" by (force simp add: Le_def) end diff --git a/src/ZF/Order.thy b/src/ZF/Order.thy --- a/src/ZF/Order.thy +++ b/src/ZF/Order.thy @@ -1,714 +1,714 @@ (* Title: ZF/Order.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge Results from the book "Set Theory: an Introduction to Independence Proofs" by Kenneth Kunen. Chapter 1, section 6. Additional definitions and lemmas for reflexive orders. *) section\Partial and Total Orderings: Basic Definitions and Properties\ theory Order imports WF Perm begin text \We adopt the following convention: \ord\ is used for strict orders and \order\ is used for their reflexive counterparts.\ definition part_ord :: "[i,i]\o" (*Strict partial ordering*) where "part_ord(A,r) \ irrefl(A,r) \ trans[A](r)" definition linear :: "[i,i]\o" (*Strict total ordering*) where "linear(A,r) \ (\x\A. \y\A. \x,y\:r | x=y | \y,x\:r)" definition tot_ord :: "[i,i]\o" (*Strict total ordering*) where "tot_ord(A,r) \ part_ord(A,r) \ linear(A,r)" definition "preorder_on(A, r) \ refl(A, r) \ trans[A](r)" definition (*Partial ordering*) "partial_order_on(A, r) \ preorder_on(A, r) \ antisym(r)" abbreviation "Preorder(r) \ preorder_on(field(r), r)" abbreviation "Partial_order(r) \ partial_order_on(field(r), r)" definition well_ord :: "[i,i]\o" (*Well-ordering*) where "well_ord(A,r) \ tot_ord(A,r) \ wf[A](r)" definition mono_map :: "[i,i,i,i]\i" (*Order-preserving maps*) where "mono_map(A,r,B,s) \ {f \ A->B. \x\A. \y\A. \x,y\:r \ :s}" definition ord_iso :: "[i,i,i,i]\i" (\(\_, _\ \/ \_, _\)\ 51) (*Order isomorphisms*) where "\A,r\ \ \B,s\ \ {f \ bij(A,B). \x\A. \y\A. \x,y\:r \ :s}" definition pred :: "[i,i,i]\i" (*Set of predecessors*) where "pred(A,x,r) \ {y \ A. \y,x\:r}" definition ord_iso_map :: "[i,i,i,i]\i" (*Construction for linearity theorem*) where "ord_iso_map(A,r,B,s) \ \x\A. \y\B. \f \ ord_iso(pred(A,x,r), r, pred(B,y,s), s). {\x,y\}" definition first :: "[i, i, i] \ o" where "first(u, X, R) \ u \ X \ (\v\X. v\u \ \u,v\ \ R)" subsection\Immediate Consequences of the Definitions\ lemma part_ord_Imp_asym: "part_ord(A,r) \ asym(r \ A*A)" by (unfold part_ord_def irrefl_def trans_on_def asym_def, blast) lemma linearE: "\linear(A,r); x \ A; y \ A; \x,y\:r \ P; x=y \ P; \y,x\:r \ P\ \ P" by (simp add: linear_def, blast) (** General properties of well_ord **) lemma well_ordI: "\wf[A](r); linear(A,r)\ \ well_ord(A,r)" apply (simp add: irrefl_def part_ord_def tot_ord_def trans_on_def well_ord_def wf_on_not_refl) apply (fast elim: linearE wf_on_asym wf_on_chain3) done lemma well_ord_is_wf: "well_ord(A,r) \ wf[A](r)" by (unfold well_ord_def, safe) lemma well_ord_is_trans_on: "well_ord(A,r) \ trans[A](r)" by (unfold well_ord_def tot_ord_def part_ord_def, safe) lemma well_ord_is_linear: "well_ord(A,r) \ linear(A,r)" by (unfold well_ord_def tot_ord_def, blast) (** Derived rules for pred(A,x,r) **) lemma pred_iff: "y \ pred(A,x,r) \ \y,x\:r \ y \ A" by (unfold pred_def, blast) lemmas predI = conjI [THEN pred_iff [THEN iffD2]] lemma predE: "\y \ pred(A,x,r); \y \ A; \y,x\:r\ \ P\ \ P" by (simp add: pred_def) lemma pred_subset_under: "pred(A,x,r) \ r -`` {x}" by (simp add: pred_def, blast) lemma pred_subset: "pred(A,x,r) \ A" by (simp add: pred_def, blast) lemma pred_pred_eq: "pred(pred(A,x,r), y, r) = pred(A,x,r) \ pred(A,y,r)" by (simp add: pred_def, blast) lemma trans_pred_pred_eq: "\trans[A](r); \y,x\:r; x \ A; y \ A\ \ pred(pred(A,x,r), y, r) = pred(A,y,r)" by (unfold trans_on_def pred_def, blast) subsection\Restricting an Ordering's Domain\ (** The ordering's properties hold over all subsets of its domain [including initial segments of the form pred(A,x,r) **) (*Note: a relation s such that s<=r need not be a partial ordering*) lemma part_ord_subset: "\part_ord(A,r); B<=A\ \ part_ord(B,r)" by (unfold part_ord_def irrefl_def trans_on_def, blast) lemma linear_subset: "\linear(A,r); B<=A\ \ linear(B,r)" by (unfold linear_def, blast) lemma tot_ord_subset: "\tot_ord(A,r); B<=A\ \ tot_ord(B,r)" -apply (unfold tot_ord_def) + unfolding tot_ord_def apply (fast elim!: part_ord_subset linear_subset) done lemma well_ord_subset: "\well_ord(A,r); B<=A\ \ well_ord(B,r)" -apply (unfold well_ord_def) + unfolding well_ord_def apply (fast elim!: tot_ord_subset wf_on_subset_A) done (** Relations restricted to a smaller domain, by Krzysztof Grabczewski **) lemma irrefl_Int_iff: "irrefl(A,r \ A*A) \ irrefl(A,r)" by (unfold irrefl_def, blast) lemma trans_on_Int_iff: "trans[A](r \ A*A) \ trans[A](r)" by (unfold trans_on_def, blast) lemma part_ord_Int_iff: "part_ord(A,r \ A*A) \ part_ord(A,r)" -apply (unfold part_ord_def) + unfolding part_ord_def apply (simp add: irrefl_Int_iff trans_on_Int_iff) done lemma linear_Int_iff: "linear(A,r \ A*A) \ linear(A,r)" by (unfold linear_def, blast) lemma tot_ord_Int_iff: "tot_ord(A,r \ A*A) \ tot_ord(A,r)" -apply (unfold tot_ord_def) + unfolding tot_ord_def apply (simp add: part_ord_Int_iff linear_Int_iff) done lemma wf_on_Int_iff: "wf[A](r \ A*A) \ wf[A](r)" apply (unfold wf_on_def wf_def, fast) (*10 times faster than blast!*) done lemma well_ord_Int_iff: "well_ord(A,r \ A*A) \ well_ord(A,r)" -apply (unfold well_ord_def) + unfolding well_ord_def apply (simp add: tot_ord_Int_iff wf_on_Int_iff) done subsection\Empty and Unit Domains\ (*The empty relation is well-founded*) lemma wf_on_any_0: "wf[A](0)" by (simp add: wf_on_def wf_def, fast) subsubsection\Relations over the Empty Set\ lemma irrefl_0: "irrefl(0,r)" by (unfold irrefl_def, blast) lemma trans_on_0: "trans[0](r)" by (unfold trans_on_def, blast) lemma part_ord_0: "part_ord(0,r)" -apply (unfold part_ord_def) + unfolding part_ord_def apply (simp add: irrefl_0 trans_on_0) done lemma linear_0: "linear(0,r)" by (unfold linear_def, blast) lemma tot_ord_0: "tot_ord(0,r)" -apply (unfold tot_ord_def) + unfolding tot_ord_def apply (simp add: part_ord_0 linear_0) done lemma wf_on_0: "wf[0](r)" by (unfold wf_on_def wf_def, blast) lemma well_ord_0: "well_ord(0,r)" -apply (unfold well_ord_def) + unfolding well_ord_def apply (simp add: tot_ord_0 wf_on_0) done subsubsection\The Empty Relation Well-Orders the Unit Set\ text\by Grabczewski\ lemma tot_ord_unit: "tot_ord({a},0)" by (simp add: irrefl_def trans_on_def part_ord_def linear_def tot_ord_def) lemma well_ord_unit: "well_ord({a},0)" -apply (unfold well_ord_def) + unfolding well_ord_def apply (simp add: tot_ord_unit wf_on_any_0) done subsection\Order-Isomorphisms\ text\Suppes calls them "similarities"\ (** Order-preserving (monotone) maps **) lemma mono_map_is_fun: "f \ mono_map(A,r,B,s) \ f \ A->B" by (simp add: mono_map_def) lemma mono_map_is_inj: "\linear(A,r); wf[B](s); f \ mono_map(A,r,B,s)\ \ f \ inj(A,B)" apply (unfold mono_map_def inj_def, clarify) apply (erule_tac x=w and y=x in linearE, assumption+) apply (force intro: apply_type dest: wf_on_not_refl)+ done lemma ord_isoI: "\f \ bij(A, B); \x y. \x \ A; y \ A\ \ \x, y\ \ r \ \ s\ \ f \ ord_iso(A,r,B,s)" by (simp add: ord_iso_def) lemma ord_iso_is_mono_map: "f \ ord_iso(A,r,B,s) \ f \ mono_map(A,r,B,s)" apply (simp add: ord_iso_def mono_map_def) apply (blast dest!: bij_is_fun) done lemma ord_iso_is_bij: "f \ ord_iso(A,r,B,s) \ f \ bij(A,B)" by (simp add: ord_iso_def) (*Needed? But ord_iso_converse is!*) lemma ord_iso_apply: "\f \ ord_iso(A,r,B,s); \x,y\: r; x \ A; y \ A\ \ \ s" by (simp add: ord_iso_def) lemma ord_iso_converse: "\f \ ord_iso(A,r,B,s); \x,y\: s; x \ B; y \ B\ \ \ r" apply (simp add: ord_iso_def, clarify) apply (erule bspec [THEN bspec, THEN iffD2]) apply (erule asm_rl bij_converse_bij [THEN bij_is_fun, THEN apply_type])+ apply (auto simp add: right_inverse_bij) done (** Symmetry and Transitivity Rules **) (*Reflexivity of similarity*) lemma ord_iso_refl: "id(A): ord_iso(A,r,A,r)" by (rule id_bij [THEN ord_isoI], simp) (*Symmetry of similarity*) lemma ord_iso_sym: "f \ ord_iso(A,r,B,s) \ converse(f): ord_iso(B,s,A,r)" apply (simp add: ord_iso_def) apply (auto simp add: right_inverse_bij bij_converse_bij bij_is_fun [THEN apply_funtype]) done (*Transitivity of similarity*) lemma mono_map_trans: "\g \ mono_map(A,r,B,s); f \ mono_map(B,s,C,t)\ \ (f O g): mono_map(A,r,C,t)" -apply (unfold mono_map_def) + unfolding mono_map_def apply (auto simp add: comp_fun) done (*Transitivity of similarity: the order-isomorphism relation*) lemma ord_iso_trans: "\g \ ord_iso(A,r,B,s); f \ ord_iso(B,s,C,t)\ \ (f O g): ord_iso(A,r,C,t)" apply (unfold ord_iso_def, clarify) apply (frule bij_is_fun [of f]) apply (frule bij_is_fun [of g]) apply (auto simp add: comp_bij) done (** Two monotone maps can make an order-isomorphism **) lemma mono_ord_isoI: "\f \ mono_map(A,r,B,s); g \ mono_map(B,s,A,r); f O g = id(B); g O f = id(A)\ \ f \ ord_iso(A,r,B,s)" apply (simp add: ord_iso_def mono_map_def, safe) apply (intro fg_imp_bijective, auto) apply (subgoal_tac " \ r") apply (simp add: comp_eq_id_iff [THEN iffD1]) apply (blast intro: apply_funtype) done lemma well_ord_mono_ord_isoI: "\well_ord(A,r); well_ord(B,s); f \ mono_map(A,r,B,s); converse(f): mono_map(B,s,A,r)\ \ f \ ord_iso(A,r,B,s)" apply (intro mono_ord_isoI, auto) apply (frule mono_map_is_fun [THEN fun_is_rel]) apply (erule converse_converse [THEN subst], rule left_comp_inverse) apply (blast intro: left_comp_inverse mono_map_is_inj well_ord_is_linear well_ord_is_wf)+ done (** Order-isomorphisms preserve the ordering's properties **) lemma part_ord_ord_iso: "\part_ord(B,s); f \ ord_iso(A,r,B,s)\ \ part_ord(A,r)" apply (simp add: part_ord_def irrefl_def trans_on_def ord_iso_def) apply (fast intro: bij_is_fun [THEN apply_type]) done lemma linear_ord_iso: "\linear(B,s); f \ ord_iso(A,r,B,s)\ \ linear(A,r)" apply (simp add: linear_def ord_iso_def, safe) apply (drule_tac x1 = "f`x" and x = "f`y" in bspec [THEN bspec]) apply (safe elim!: bij_is_fun [THEN apply_type]) apply (drule_tac t = "(`) (converse (f))" in subst_context) apply (simp add: left_inverse_bij) done lemma wf_on_ord_iso: "\wf[B](s); f \ ord_iso(A,r,B,s)\ \ wf[A](r)" apply (simp add: wf_on_def wf_def ord_iso_def, safe) apply (drule_tac x = "{f`z. z \ Z \ A}" in spec) apply (safe intro!: equalityI) apply (blast dest!: equalityD1 intro: bij_is_fun [THEN apply_type])+ done lemma well_ord_ord_iso: "\well_ord(B,s); f \ ord_iso(A,r,B,s)\ \ well_ord(A,r)" apply (unfold well_ord_def tot_ord_def) apply (fast elim!: part_ord_ord_iso linear_ord_iso wf_on_ord_iso) done subsection\Main results of Kunen, Chapter 1 section 6\ (*Inductive argument for Kunen's Lemma 6.1, etc. Simple proof from Halmos, page 72*) lemma well_ord_iso_subset_lemma: "\well_ord(A,r); f \ ord_iso(A,r, A',r); A'<= A; y \ A\ \ \ : r" apply (simp add: well_ord_def ord_iso_def) apply (elim conjE CollectE) apply (rule_tac a=y in wf_on_induct, assumption+) apply (blast dest: bij_is_fun [THEN apply_type]) done (*Kunen's Lemma 6.1 \ there's no order-isomorphism to an initial segment of a well-ordering*) lemma well_ord_iso_predE: "\well_ord(A,r); f \ ord_iso(A, r, pred(A,x,r), r); x \ A\ \ P" apply (insert well_ord_iso_subset_lemma [of A r f "pred(A,x,r)" x]) apply (simp add: pred_subset) (*Now we know f`x < x *) apply (drule ord_iso_is_bij [THEN bij_is_fun, THEN apply_type], assumption) (*Now we also know @{term"f`x \ pred(A,x,r)"}: contradiction! *) apply (simp add: well_ord_def pred_def) done (*Simple consequence of Lemma 6.1*) lemma well_ord_iso_pred_eq: "\well_ord(A,r); f \ ord_iso(pred(A,a,r), r, pred(A,c,r), r); a \ A; c \ A\ \ a=c" apply (frule well_ord_is_trans_on) apply (frule well_ord_is_linear) apply (erule_tac x=a and y=c in linearE, assumption+) apply (drule ord_iso_sym) (*two symmetric cases*) apply (auto elim!: well_ord_subset [OF _ pred_subset, THEN well_ord_iso_predE] intro!: predI simp add: trans_pred_pred_eq) done (*Does not assume r is a wellordering!*) lemma ord_iso_image_pred: "\f \ ord_iso(A,r,B,s); a \ A\ \ f `` pred(A,a,r) = pred(B, f`a, s)" apply (unfold ord_iso_def pred_def) apply (erule CollectE) apply (simp (no_asm_simp) add: image_fun [OF bij_is_fun Collect_subset]) apply (rule equalityI) apply (safe elim!: bij_is_fun [THEN apply_type]) apply (rule RepFun_eqI) apply (blast intro!: right_inverse_bij [symmetric]) apply (auto simp add: right_inverse_bij bij_is_fun [THEN apply_funtype]) done lemma ord_iso_restrict_image: "\f \ ord_iso(A,r,B,s); C<=A\ \ restrict(f,C) \ ord_iso(C, r, f``C, s)" apply (simp add: ord_iso_def) apply (blast intro: bij_is_inj restrict_bij) done (*But in use, A and B may themselves be initial segments. Then use trans_pred_pred_eq to simplify the pred(pred...) terms. See just below.*) lemma ord_iso_restrict_pred: "\f \ ord_iso(A,r,B,s); a \ A\ \ restrict(f, pred(A,a,r)) \ ord_iso(pred(A,a,r), r, pred(B, f`a, s), s)" apply (simp add: ord_iso_image_pred [symmetric]) apply (blast intro: ord_iso_restrict_image elim: predE) done (*Tricky; a lot of forward proof!*) lemma well_ord_iso_preserving: "\well_ord(A,r); well_ord(B,s); \a,c\: r; f \ ord_iso(pred(A,a,r), r, pred(B,b,s), s); g \ ord_iso(pred(A,c,r), r, pred(B,d,s), s); a \ A; c \ A; b \ B; d \ B\ \ \b,d\: s" apply (frule ord_iso_is_bij [THEN bij_is_fun, THEN apply_type], (erule asm_rl predI predE)+) apply (subgoal_tac "b = g`a") apply (simp (no_asm_simp)) apply (rule well_ord_iso_pred_eq, auto) apply (frule ord_iso_restrict_pred, (erule asm_rl predI)+) apply (simp add: well_ord_is_trans_on trans_pred_pred_eq) apply (erule ord_iso_sym [THEN ord_iso_trans], assumption) done (*See Halmos, page 72*) lemma well_ord_iso_unique_lemma: "\well_ord(A,r); f \ ord_iso(A,r, B,s); g \ ord_iso(A,r, B,s); y \ A\ \ \ \ s" apply (frule well_ord_iso_subset_lemma) apply (rule_tac f = "converse (f) " and g = g in ord_iso_trans) apply auto apply (blast intro: ord_iso_sym) apply (frule ord_iso_is_bij [of f]) apply (frule ord_iso_is_bij [of g]) apply (frule ord_iso_converse) apply (blast intro!: bij_converse_bij intro: bij_is_fun apply_funtype)+ apply (erule notE) apply (simp add: left_inverse_bij bij_is_fun comp_fun_apply [of _ A B]) done (*Kunen's Lemma 6.2: Order-isomorphisms between well-orderings are unique*) lemma well_ord_iso_unique: "\well_ord(A,r); f \ ord_iso(A,r, B,s); g \ ord_iso(A,r, B,s)\ \ f = g" apply (rule fun_extension) apply (erule ord_iso_is_bij [THEN bij_is_fun])+ apply (subgoal_tac "f`x \ B \ g`x \ B \ linear(B,s)") apply (simp add: linear_def) apply (blast dest: well_ord_iso_unique_lemma) apply (blast intro: ord_iso_is_bij bij_is_fun apply_funtype well_ord_is_linear well_ord_ord_iso ord_iso_sym) done subsection\Towards Kunen's Theorem 6.3: Linearity of the Similarity Relation\ lemma ord_iso_map_subset: "ord_iso_map(A,r,B,s) \ A*B" by (unfold ord_iso_map_def, blast) lemma domain_ord_iso_map: "domain(ord_iso_map(A,r,B,s)) \ A" by (unfold ord_iso_map_def, blast) lemma range_ord_iso_map: "range(ord_iso_map(A,r,B,s)) \ B" by (unfold ord_iso_map_def, blast) lemma converse_ord_iso_map: "converse(ord_iso_map(A,r,B,s)) = ord_iso_map(B,s,A,r)" -apply (unfold ord_iso_map_def) + unfolding ord_iso_map_def apply (blast intro: ord_iso_sym) done lemma function_ord_iso_map: "well_ord(B,s) \ function(ord_iso_map(A,r,B,s))" apply (unfold ord_iso_map_def function_def) apply (blast intro: well_ord_iso_pred_eq ord_iso_sym ord_iso_trans) done lemma ord_iso_map_fun: "well_ord(B,s) \ ord_iso_map(A,r,B,s) \ domain(ord_iso_map(A,r,B,s)) -> range(ord_iso_map(A,r,B,s))" by (simp add: Pi_iff function_ord_iso_map ord_iso_map_subset [THEN domain_times_range]) lemma ord_iso_map_mono_map: "\well_ord(A,r); well_ord(B,s)\ \ ord_iso_map(A,r,B,s) \ mono_map(domain(ord_iso_map(A,r,B,s)), r, range(ord_iso_map(A,r,B,s)), s)" -apply (unfold mono_map_def) + unfolding mono_map_def apply (simp (no_asm_simp) add: ord_iso_map_fun) apply safe apply (subgoal_tac "x \ A \ ya:A \ y \ B \ yb:B") apply (simp add: apply_equality [OF _ ord_iso_map_fun]) - apply (unfold ord_iso_map_def) + unfolding ord_iso_map_def apply (blast intro: well_ord_iso_preserving, blast) done lemma ord_iso_map_ord_iso: "\well_ord(A,r); well_ord(B,s)\ \ ord_iso_map(A,r,B,s) \ ord_iso(domain(ord_iso_map(A,r,B,s)), r, range(ord_iso_map(A,r,B,s)), s)" apply (rule well_ord_mono_ord_isoI) prefer 4 apply (rule converse_ord_iso_map [THEN subst]) apply (simp add: ord_iso_map_mono_map ord_iso_map_subset [THEN converse_converse]) apply (blast intro!: domain_ord_iso_map range_ord_iso_map intro: well_ord_subset ord_iso_map_mono_map)+ done (*One way of saying that domain(ord_iso_map(A,r,B,s)) is downwards-closed*) lemma domain_ord_iso_map_subset: "\well_ord(A,r); well_ord(B,s); a \ A; a \ domain(ord_iso_map(A,r,B,s))\ \ domain(ord_iso_map(A,r,B,s)) \ pred(A, a, r)" -apply (unfold ord_iso_map_def) + unfolding ord_iso_map_def apply (safe intro!: predI) (*Case analysis on xa vs a in r *) apply (simp (no_asm_simp)) apply (frule_tac A = A in well_ord_is_linear) apply (rename_tac b y f) apply (erule_tac x=b and y=a in linearE, assumption+) (*Trivial case: b=a*) apply clarify apply blast (*Harder case: \a, xa\: r*) apply (frule ord_iso_is_bij [THEN bij_is_fun, THEN apply_type], (erule asm_rl predI predE)+) apply (frule ord_iso_restrict_pred) apply (simp add: pred_iff) apply (simp split: split_if_asm add: well_ord_is_trans_on trans_pred_pred_eq domain_UN domain_Union, blast) done (*For the 4-way case analysis in the main result*) lemma domain_ord_iso_map_cases: "\well_ord(A,r); well_ord(B,s)\ \ domain(ord_iso_map(A,r,B,s)) = A | (\x\A. domain(ord_iso_map(A,r,B,s)) = pred(A,x,r))" apply (frule well_ord_is_wf) apply (unfold wf_on_def wf_def) apply (drule_tac x = "A-domain (ord_iso_map (A,r,B,s))" in spec) apply safe (*The first case: the domain equals A*) apply (rule domain_ord_iso_map [THEN equalityI]) apply (erule Diff_eq_0_iff [THEN iffD1]) (*The other case: the domain equals an initial segment*) apply (blast del: domainI subsetI elim!: predE intro!: domain_ord_iso_map_subset intro: subsetI)+ done (*As above, by duality*) lemma range_ord_iso_map_cases: "\well_ord(A,r); well_ord(B,s)\ \ range(ord_iso_map(A,r,B,s)) = B | (\y\B. range(ord_iso_map(A,r,B,s)) = pred(B,y,s))" apply (rule converse_ord_iso_map [THEN subst]) apply (simp add: domain_ord_iso_map_cases) done text\Kunen's Theorem 6.3: Fundamental Theorem for Well-Ordered Sets\ theorem well_ord_trichotomy: "\well_ord(A,r); well_ord(B,s)\ \ ord_iso_map(A,r,B,s) \ ord_iso(A, r, B, s) | (\x\A. ord_iso_map(A,r,B,s) \ ord_iso(pred(A,x,r), r, B, s)) | (\y\B. ord_iso_map(A,r,B,s) \ ord_iso(A, r, pred(B,y,s), s))" apply (frule_tac B = B in domain_ord_iso_map_cases, assumption) apply (frule_tac B = B in range_ord_iso_map_cases, assumption) apply (drule ord_iso_map_ord_iso, assumption) apply (elim disjE bexE) apply (simp_all add: bexI) apply (rule wf_on_not_refl [THEN notE]) apply (erule well_ord_is_wf) apply assumption apply (subgoal_tac "\x,y\: ord_iso_map (A,r,B,s) ") apply (drule rangeI) apply (simp add: pred_def) apply (unfold ord_iso_map_def, blast) done subsection\Miscellaneous Results by Krzysztof Grabczewski\ (** Properties of converse(r) **) lemma irrefl_converse: "irrefl(A,r) \ irrefl(A,converse(r))" by (unfold irrefl_def, blast) lemma trans_on_converse: "trans[A](r) \ trans[A](converse(r))" by (unfold trans_on_def, blast) lemma part_ord_converse: "part_ord(A,r) \ part_ord(A,converse(r))" -apply (unfold part_ord_def) + unfolding part_ord_def apply (blast intro!: irrefl_converse trans_on_converse) done lemma linear_converse: "linear(A,r) \ linear(A,converse(r))" by (unfold linear_def, blast) lemma tot_ord_converse: "tot_ord(A,r) \ tot_ord(A,converse(r))" -apply (unfold tot_ord_def) + unfolding tot_ord_def apply (blast intro!: part_ord_converse linear_converse) done (** By Krzysztof Grabczewski. Lemmas involving the first element of a well ordered set **) lemma first_is_elem: "first(b,B,r) \ b \ B" by (unfold first_def, blast) lemma well_ord_imp_ex1_first: "\well_ord(A,r); B<=A; B\0\ \ (\!b. first(b,B,r))" apply (unfold well_ord_def wf_on_def wf_def first_def) apply (elim conjE allE disjE, blast) apply (erule bexE) apply (rule_tac a = x in ex1I, auto) apply (unfold tot_ord_def linear_def, blast) done lemma the_first_in: "\well_ord(A,r); B<=A; B\0\ \ (THE b. first(b,B,r)) \ B" apply (drule well_ord_imp_ex1_first, assumption+) apply (rule first_is_elem) apply (erule theI) done subsection \Lemmas for the Reflexive Orders\ lemma subset_vimage_vimage_iff: "\Preorder(r); A \ field(r); B \ field(r)\ \ r -`` A \ r -`` B \ (\a\A. \b\B. \a, b\ \ r)" apply (auto simp: subset_def preorder_on_def refl_def vimage_def image_def) apply blast unfolding trans_on_def apply (erule_tac P = "(\x. \y\field(r). \z\field(r). \x, y\ \ r \ \y, z\ \ r \ \x, z\ \ r)" for r in rev_ballE) (* instance obtained from proof term generated by best *) apply best apply blast done lemma subset_vimage1_vimage1_iff: "\Preorder(r); a \ field(r); b \ field(r)\ \ r -`` {a} \ r -`` {b} \ \a, b\ \ r" by (simp add: subset_vimage_vimage_iff) lemma Refl_antisym_eq_Image1_Image1_iff: "\refl(field(r), r); antisym(r); a \ field(r); b \ field(r)\ \ r `` {a} = r `` {b} \ a = b" apply rule apply (frule equality_iffD) apply (drule equality_iffD) apply (simp add: antisym_def refl_def) apply best apply (simp add: antisym_def refl_def) done lemma Partial_order_eq_Image1_Image1_iff: "\Partial_order(r); a \ field(r); b \ field(r)\ \ r `` {a} = r `` {b} \ a = b" by (simp add: partial_order_on_def preorder_on_def Refl_antisym_eq_Image1_Image1_iff) lemma Refl_antisym_eq_vimage1_vimage1_iff: "\refl(field(r), r); antisym(r); a \ field(r); b \ field(r)\ \ r -`` {a} = r -`` {b} \ a = b" apply rule apply (frule equality_iffD) apply (drule equality_iffD) apply (simp add: antisym_def refl_def) apply best apply (simp add: antisym_def refl_def) done lemma Partial_order_eq_vimage1_vimage1_iff: "\Partial_order(r); a \ field(r); b \ field(r)\ \ r -`` {a} = r -`` {b} \ a = b" by (simp add: partial_order_on_def preorder_on_def Refl_antisym_eq_vimage1_vimage1_iff) end diff --git a/src/ZF/OrderArith.thy b/src/ZF/OrderArith.thy --- a/src/ZF/OrderArith.thy +++ b/src/ZF/OrderArith.thy @@ -1,568 +1,568 @@ (* Title: ZF/OrderArith.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Combining Orderings: Foundations of Ordinal Arithmetic\ theory OrderArith imports Order Sum Ordinal begin definition (*disjoint sum of two relations; underlies ordinal addition*) radd :: "[i,i,i,i]\i" where "radd(A,r,B,s) \ {z: (A+B) * (A+B). (\x y. z = \Inl(x), Inr(y)\) | (\x' x. z = \Inl(x'), Inl(x)\ \ \x',x\:r) | (\y' y. z = \Inr(y'), Inr(y)\ \ \y',y\:s)}" definition (*lexicographic product of two relations; underlies ordinal multiplication*) rmult :: "[i,i,i,i]\i" where "rmult(A,r,B,s) \ {z: (A*B) * (A*B). \x' y' x y. z = \\x',y'\, \x,y\\ \ (\x',x\: r | (x'=x \ \y',y\: s))}" definition (*inverse image of a relation*) rvimage :: "[i,i,i]\i" where "rvimage(A,f,r) \ {z \ A*A. \x y. z = \x,y\ \ \f`x,f`y\: r}" definition measure :: "[i, i\i] \ i" where "measure(A,f) \ {\x,y\: A*A. f(x) < f(y)}" subsection\Addition of Relations -- Disjoint Sum\ subsubsection\Rewrite rules. Can be used to obtain introduction rules\ lemma radd_Inl_Inr_iff [iff]: "\Inl(a), Inr(b)\ \ radd(A,r,B,s) \ a \ A \ b \ B" by (unfold radd_def, blast) lemma radd_Inl_iff [iff]: "\Inl(a'), Inl(a)\ \ radd(A,r,B,s) \ a':A \ a \ A \ \a',a\:r" by (unfold radd_def, blast) lemma radd_Inr_iff [iff]: "\Inr(b'), Inr(b)\ \ radd(A,r,B,s) \ b':B \ b \ B \ \b',b\:s" by (unfold radd_def, blast) lemma radd_Inr_Inl_iff [simp]: "\Inr(b), Inl(a)\ \ radd(A,r,B,s) \ False" by (unfold radd_def, blast) declare radd_Inr_Inl_iff [THEN iffD1, dest!] subsubsection\Elimination Rule\ lemma raddE: "\\p',p\ \ radd(A,r,B,s); \x y. \p'=Inl(x); x \ A; p=Inr(y); y \ B\ \ Q; \x' x. \p'=Inl(x'); p=Inl(x); \x',x\: r; x':A; x \ A\ \ Q; \y' y. \p'=Inr(y'); p=Inr(y); \y',y\: s; y':B; y \ B\ \ Q \ \ Q" by (unfold radd_def, blast) subsubsection\Type checking\ lemma radd_type: "radd(A,r,B,s) \ (A+B) * (A+B)" -apply (unfold radd_def) + unfolding radd_def apply (rule Collect_subset) done lemmas field_radd = radd_type [THEN field_rel_subset] subsubsection\Linearity\ lemma linear_radd: "\linear(A,r); linear(B,s)\ \ linear(A+B,radd(A,r,B,s))" by (unfold linear_def, blast) subsubsection\Well-foundedness\ lemma wf_on_radd: "\wf[A](r); wf[B](s)\ \ wf[A+B](radd(A,r,B,s))" apply (rule wf_onI2) apply (subgoal_tac "\x\A. Inl (x) \ Ba") \ \Proving the lemma, which is needed twice!\ prefer 2 apply (erule_tac V = "y \ A + B" in thin_rl) apply (rule_tac ballI) apply (erule_tac r = r and a = x in wf_on_induct, assumption) apply blast txt\Returning to main part of proof\ apply safe apply blast apply (erule_tac r = s and a = ya in wf_on_induct, assumption, blast) done lemma wf_radd: "\wf(r); wf(s)\ \ wf(radd(field(r),r,field(s),s))" apply (simp add: wf_iff_wf_on_field) apply (rule wf_on_subset_A [OF _ field_radd]) apply (blast intro: wf_on_radd) done lemma well_ord_radd: "\well_ord(A,r); well_ord(B,s)\ \ well_ord(A+B, radd(A,r,B,s))" apply (rule well_ordI) apply (simp add: well_ord_def wf_on_radd) apply (simp add: well_ord_def tot_ord_def linear_radd) done subsubsection\An \<^term>\ord_iso\ congruence law\ lemma sum_bij: "\f \ bij(A,C); g \ bij(B,D)\ \ (\z\A+B. case(\x. Inl(f`x), \y. Inr(g`y), z)) \ bij(A+B, C+D)" apply (rule_tac d = "case (\x. Inl (converse(f)`x), \y. Inr(converse(g)`y))" in lam_bijective) apply (typecheck add: bij_is_inj inj_is_fun) apply (auto simp add: left_inverse_bij right_inverse_bij) done lemma sum_ord_iso_cong: "\f \ ord_iso(A,r,A',r'); g \ ord_iso(B,s,B',s')\ \ (\z\A+B. case(\x. Inl(f`x), \y. Inr(g`y), z)) \ ord_iso(A+B, radd(A,r,B,s), A'+B', radd(A',r',B',s'))" -apply (unfold ord_iso_def) + unfolding ord_iso_def apply (safe intro!: sum_bij) (*Do the beta-reductions now*) apply (auto cong add: conj_cong simp add: bij_is_fun [THEN apply_type]) done (*Could we prove an ord_iso result? Perhaps ord_iso(A+B, radd(A,r,B,s), A \ B, r \ s) *) lemma sum_disjoint_bij: "A \ B = 0 \ (\z\A+B. case(\x. x, \y. y, z)) \ bij(A+B, A \ B)" apply (rule_tac d = "\z. if z \ A then Inl (z) else Inr (z) " in lam_bijective) apply auto done subsubsection\Associativity\ lemma sum_assoc_bij: "(\z\(A+B)+C. case(case(Inl, \y. Inr(Inl(y))), \y. Inr(Inr(y)), z)) \ bij((A+B)+C, A+(B+C))" apply (rule_tac d = "case (\x. Inl (Inl (x)), case (\x. Inl (Inr (x)), Inr))" in lam_bijective) apply auto done lemma sum_assoc_ord_iso: "(\z\(A+B)+C. case(case(Inl, \y. Inr(Inl(y))), \y. Inr(Inr(y)), z)) \ ord_iso((A+B)+C, radd(A+B, radd(A,r,B,s), C, t), A+(B+C), radd(A, r, B+C, radd(B,s,C,t)))" by (rule sum_assoc_bij [THEN ord_isoI], auto) subsection\Multiplication of Relations -- Lexicographic Product\ subsubsection\Rewrite rule. Can be used to obtain introduction rules\ lemma rmult_iff [iff]: "\\a',b'\, \a,b\\ \ rmult(A,r,B,s) \ (\a',a\: r \ a':A \ a \ A \ b': B \ b \ B) | (\b',b\: s \ a'=a \ a \ A \ b': B \ b \ B)" by (unfold rmult_def, blast) lemma rmultE: "\\\a',b'\, \a,b\\ \ rmult(A,r,B,s); \\a',a\: r; a':A; a \ A; b':B; b \ B\ \ Q; \\b',b\: s; a \ A; a'=a; b':B; b \ B\ \ Q \ \ Q" by blast subsubsection\Type checking\ lemma rmult_type: "rmult(A,r,B,s) \ (A*B) * (A*B)" by (unfold rmult_def, rule Collect_subset) lemmas field_rmult = rmult_type [THEN field_rel_subset] subsubsection\Linearity\ lemma linear_rmult: "\linear(A,r); linear(B,s)\ \ linear(A*B,rmult(A,r,B,s))" by (simp add: linear_def, blast) subsubsection\Well-foundedness\ lemma wf_on_rmult: "\wf[A](r); wf[B](s)\ \ wf[A*B](rmult(A,r,B,s))" apply (rule wf_onI2) apply (erule SigmaE) apply (erule ssubst) apply (subgoal_tac "\b\B. \x,b\: Ba", blast) apply (erule_tac a = x in wf_on_induct, assumption) apply (rule ballI) apply (erule_tac a = b in wf_on_induct, assumption) apply (best elim!: rmultE bspec [THEN mp]) done lemma wf_rmult: "\wf(r); wf(s)\ \ wf(rmult(field(r),r,field(s),s))" apply (simp add: wf_iff_wf_on_field) apply (rule wf_on_subset_A [OF _ field_rmult]) apply (blast intro: wf_on_rmult) done lemma well_ord_rmult: "\well_ord(A,r); well_ord(B,s)\ \ well_ord(A*B, rmult(A,r,B,s))" apply (rule well_ordI) apply (simp add: well_ord_def wf_on_rmult) apply (simp add: well_ord_def tot_ord_def linear_rmult) done subsubsection\An \<^term>\ord_iso\ congruence law\ lemma prod_bij: "\f \ bij(A,C); g \ bij(B,D)\ \ (lam \x,y\:A*B. \f`x, g`y\) \ bij(A*B, C*D)" apply (rule_tac d = "\\x,y\. \converse (f) `x, converse (g) `y\" in lam_bijective) apply (typecheck add: bij_is_inj inj_is_fun) apply (auto simp add: left_inverse_bij right_inverse_bij) done lemma prod_ord_iso_cong: "\f \ ord_iso(A,r,A',r'); g \ ord_iso(B,s,B',s')\ \ (lam \x,y\:A*B. \f`x, g`y\) \ ord_iso(A*B, rmult(A,r,B,s), A'*B', rmult(A',r',B',s'))" -apply (unfold ord_iso_def) + unfolding ord_iso_def apply (safe intro!: prod_bij) apply (simp_all add: bij_is_fun [THEN apply_type]) apply (blast intro: bij_is_inj [THEN inj_apply_equality]) done lemma singleton_prod_bij: "(\z\A. \x,z\) \ bij(A, {x}*A)" by (rule_tac d = snd in lam_bijective, auto) (*Used??*) lemma singleton_prod_ord_iso: "well_ord({x},xr) \ (\z\A. \x,z\) \ ord_iso(A, r, {x}*A, rmult({x}, xr, A, r))" apply (rule singleton_prod_bij [THEN ord_isoI]) apply (simp (no_asm_simp)) apply (blast dest: well_ord_is_wf [THEN wf_on_not_refl]) done (*Here we build a complicated function term, then simplify it using case_cong, id_conv, comp_lam, case_case.*) lemma prod_sum_singleton_bij: "a\C \ (\x\C*B + D. case(\x. x, \y.\a,y\, x)) \ bij(C*B + D, C*B \ {a}*D)" apply (rule subst_elem) apply (rule id_bij [THEN sum_bij, THEN comp_bij]) apply (rule singleton_prod_bij) apply (rule sum_disjoint_bij, blast) apply (simp (no_asm_simp) cong add: case_cong) apply (rule comp_lam [THEN trans, symmetric]) apply (fast elim!: case_type) apply (simp (no_asm_simp) add: case_case) done lemma prod_sum_singleton_ord_iso: "\a \ A; well_ord(A,r)\ \ (\x\pred(A,a,r)*B + pred(B,b,s). case(\x. x, \y.\a,y\, x)) \ ord_iso(pred(A,a,r)*B + pred(B,b,s), radd(A*B, rmult(A,r,B,s), B, s), pred(A,a,r)*B \ {a}*pred(B,b,s), rmult(A,r,B,s))" apply (rule prod_sum_singleton_bij [THEN ord_isoI]) apply (simp (no_asm_simp) add: pred_iff well_ord_is_wf [THEN wf_on_not_refl]) apply (auto elim!: well_ord_is_wf [THEN wf_on_asym] predE) done subsubsection\Distributive law\ lemma sum_prod_distrib_bij: "(lam \x,z\:(A+B)*C. case(\y. Inl(\y,z\), \y. Inr(\y,z\), x)) \ bij((A+B)*C, (A*C)+(B*C))" by (rule_tac d = "case (\\x,y\.\Inl (x),y\, \\x,y\.\Inr (x),y\) " in lam_bijective, auto) lemma sum_prod_distrib_ord_iso: "(lam \x,z\:(A+B)*C. case(\y. Inl(\y,z\), \y. Inr(\y,z\), x)) \ ord_iso((A+B)*C, rmult(A+B, radd(A,r,B,s), C, t), (A*C)+(B*C), radd(A*C, rmult(A,r,C,t), B*C, rmult(B,s,C,t)))" by (rule sum_prod_distrib_bij [THEN ord_isoI], auto) subsubsection\Associativity\ lemma prod_assoc_bij: "(lam \\x,y\, z\:(A*B)*C. \x,\y,z\\) \ bij((A*B)*C, A*(B*C))" by (rule_tac d = "\\x, \y,z\\. \\x,y\, z\" in lam_bijective, auto) lemma prod_assoc_ord_iso: "(lam \\x,y\, z\:(A*B)*C. \x,\y,z\\) \ ord_iso((A*B)*C, rmult(A*B, rmult(A,r,B,s), C, t), A*(B*C), rmult(A, r, B*C, rmult(B,s,C,t)))" by (rule prod_assoc_bij [THEN ord_isoI], auto) subsection\Inverse Image of a Relation\ subsubsection\Rewrite rule\ lemma rvimage_iff: "\a,b\ \ rvimage(A,f,r) \ \f`a,f`b\: r \ a \ A \ b \ A" by (unfold rvimage_def, blast) subsubsection\Type checking\ lemma rvimage_type: "rvimage(A,f,r) \ A*A" by (unfold rvimage_def, rule Collect_subset) lemmas field_rvimage = rvimage_type [THEN field_rel_subset] lemma rvimage_converse: "rvimage(A,f, converse(r)) = converse(rvimage(A,f,r))" by (unfold rvimage_def, blast) subsubsection\Partial Ordering Properties\ lemma irrefl_rvimage: "\f \ inj(A,B); irrefl(B,r)\ \ irrefl(A, rvimage(A,f,r))" apply (unfold irrefl_def rvimage_def) apply (blast intro: inj_is_fun [THEN apply_type]) done lemma trans_on_rvimage: "\f \ inj(A,B); trans[B](r)\ \ trans[A](rvimage(A,f,r))" apply (unfold trans_on_def rvimage_def) apply (blast intro: inj_is_fun [THEN apply_type]) done lemma part_ord_rvimage: "\f \ inj(A,B); part_ord(B,r)\ \ part_ord(A, rvimage(A,f,r))" -apply (unfold part_ord_def) + unfolding part_ord_def apply (blast intro!: irrefl_rvimage trans_on_rvimage) done subsubsection\Linearity\ lemma linear_rvimage: "\f \ inj(A,B); linear(B,r)\ \ linear(A,rvimage(A,f,r))" apply (simp add: inj_def linear_def rvimage_iff) apply (blast intro: apply_funtype) done lemma tot_ord_rvimage: "\f \ inj(A,B); tot_ord(B,r)\ \ tot_ord(A, rvimage(A,f,r))" -apply (unfold tot_ord_def) + unfolding tot_ord_def apply (blast intro!: part_ord_rvimage linear_rvimage) done subsubsection\Well-foundedness\ lemma wf_rvimage [intro!]: "wf(r) \ wf(rvimage(A,f,r))" apply (simp (no_asm_use) add: rvimage_def wf_eq_minimal) apply clarify apply (subgoal_tac "\w. w \ {w: {f`x. x \ Q}. \x. x \ Q \ (f`x = w) }") apply (erule allE) apply (erule impE) apply assumption apply blast apply blast done text\But note that the combination of \wf_imp_wf_on\ and \wf_rvimage\ gives \<^prop>\wf(r) \ wf[C](rvimage(A,f,r))\\ lemma wf_on_rvimage: "\f \ A\B; wf[B](r)\ \ wf[A](rvimage(A,f,r))" apply (rule wf_onI2) apply (subgoal_tac "\z\A. f`z=f`y \ z \ Ba") apply blast apply (erule_tac a = "f`y" in wf_on_induct) apply (blast intro!: apply_funtype) apply (blast intro!: apply_funtype dest!: rvimage_iff [THEN iffD1]) done (*Note that we need only wf[A](...) and linear(A,...) to get the result!*) lemma well_ord_rvimage: "\f \ inj(A,B); well_ord(B,r)\ \ well_ord(A, rvimage(A,f,r))" apply (rule well_ordI) apply (unfold well_ord_def tot_ord_def) apply (blast intro!: wf_on_rvimage inj_is_fun) apply (blast intro!: linear_rvimage) done lemma ord_iso_rvimage: "f \ bij(A,B) \ f \ ord_iso(A, rvimage(A,f,s), B, s)" -apply (unfold ord_iso_def) + unfolding ord_iso_def apply (simp add: rvimage_iff) done lemma ord_iso_rvimage_eq: "f \ ord_iso(A,r, B,s) \ rvimage(A,f,s) = r \ A*A" by (unfold ord_iso_def rvimage_def, blast) subsection\Every well-founded relation is a subset of some inverse image of an ordinal\ lemma wf_rvimage_Ord: "Ord(i) \ wf(rvimage(A, f, Memrel(i)))" by (blast intro: wf_rvimage wf_Memrel) definition wfrank :: "[i,i]\i" where "wfrank(r,a) \ wfrec(r, a, \x f. \y \ r-``{x}. succ(f`y))" definition wftype :: "i\i" where "wftype(r) \ \y \ range(r). succ(wfrank(r,y))" lemma wfrank: "wf(r) \ wfrank(r,a) = (\y \ r-``{a}. succ(wfrank(r,y)))" by (subst wfrank_def [THEN def_wfrec], simp_all) lemma Ord_wfrank: "wf(r) \ Ord(wfrank(r,a))" apply (rule_tac a=a in wf_induct, assumption) apply (subst wfrank, assumption) apply (rule Ord_succ [THEN Ord_UN], blast) done lemma wfrank_lt: "\wf(r); \a,b\ \ r\ \ wfrank(r,a) < wfrank(r,b)" apply (rule_tac a1 = b in wfrank [THEN ssubst], assumption) apply (rule UN_I [THEN ltI]) apply (simp add: Ord_wfrank vimage_iff)+ done lemma Ord_wftype: "wf(r) \ Ord(wftype(r))" by (simp add: wftype_def Ord_wfrank) lemma wftypeI: "\wf(r); x \ field(r)\ \ wfrank(r,x) \ wftype(r)" apply (simp add: wftype_def) apply (blast intro: wfrank_lt [THEN ltD]) done lemma wf_imp_subset_rvimage: "\wf(r); r \ A*A\ \ \i f. Ord(i) \ r \ rvimage(A, f, Memrel(i))" apply (rule_tac x="wftype(r)" in exI) apply (rule_tac x="\x\A. wfrank(r,x)" in exI) apply (simp add: Ord_wftype, clarify) apply (frule subsetD, assumption, clarify) apply (simp add: rvimage_iff wfrank_lt [THEN ltD]) apply (blast intro: wftypeI) done theorem wf_iff_subset_rvimage: "relation(r) \ wf(r) \ (\i f A. Ord(i) \ r \ rvimage(A, f, Memrel(i)))" by (blast dest!: relation_field_times_field wf_imp_subset_rvimage intro: wf_rvimage_Ord [THEN wf_subset]) subsection\Other Results\ lemma wf_times: "A \ B = 0 \ wf(A*B)" by (simp add: wf_def, blast) text\Could also be used to prove \wf_radd\\ lemma wf_Un: "\range(r) \ domain(s) = 0; wf(r); wf(s)\ \ wf(r \ s)" apply (simp add: wf_def, clarify) apply (rule equalityI) prefer 2 apply blast apply clarify apply (drule_tac x=Z in spec) apply (drule_tac x="Z \ domain(s)" in spec) apply simp apply (blast intro: elim: equalityE) done subsubsection\The Empty Relation\ lemma wf0: "wf(0)" by (simp add: wf_def, blast) lemma linear0: "linear(0,0)" by (simp add: linear_def) lemma well_ord0: "well_ord(0,0)" by (blast intro: wf_imp_wf_on well_ordI wf0 linear0) subsubsection\The "measure" relation is useful with wfrec\ lemma measure_eq_rvimage_Memrel: "measure(A,f) = rvimage(A,Lambda(A,f),Memrel(Collect(RepFun(A,f),Ord)))" apply (simp (no_asm) add: measure_def rvimage_def Memrel_iff) apply (rule equalityI, auto) apply (auto intro: Ord_in_Ord simp add: lt_def) done lemma wf_measure [iff]: "wf(measure(A,f))" by (simp (no_asm) add: measure_eq_rvimage_Memrel wf_Memrel wf_rvimage) lemma measure_iff [iff]: "\x,y\ \ measure(A,f) \ x \ A \ y \ A \ f(x)x. x \ A \ Ord(f(x))" and inj: "\x y. \x \ A; y \ A; f(x) = f(y)\ \ x=y" shows "linear(A, measure(A,f))" apply (auto simp add: linear_def) apply (rule_tac i="f(x)" and j="f(y)" in Ord_linear_lt) apply (simp_all add: Ordf) apply (blast intro: inj) done lemma wf_on_measure: "wf[B](measure(A,f))" by (rule wf_imp_wf_on [OF wf_measure]) lemma well_ord_measure: assumes Ordf: "\x. x \ A \ Ord(f(x))" and inj: "\x y. \x \ A; y \ A; f(x) = f(y)\ \ x=y" shows "well_ord(A, measure(A,f))" apply (rule well_ordI) apply (rule wf_on_measure) apply (blast intro: linear_measure Ordf inj) done lemma measure_type: "measure(A,f) \ A*A" by (auto simp add: measure_def) subsubsection\Well-foundedness of Unions\ lemma wf_on_Union: assumes wfA: "wf[A](r)" and wfB: "\a. a\A \ wf[B(a)](s)" and ok: "\a u v. \\u,v\ \ s; v \ B(a); a \ A\ \ (\a'\A. \a',a\ \ r \ u \ B(a')) | u \ B(a)" shows "wf[\a\A. B(a)](s)" apply (rule wf_onI2) apply (erule UN_E) apply (subgoal_tac "\z \ B(a). z \ Ba", blast) apply (rule_tac a = a in wf_on_induct [OF wfA], assumption) apply (rule ballI) apply (rule_tac a = z in wf_on_induct [OF wfB], assumption, assumption) apply (rename_tac u) apply (drule_tac x=u in bspec, blast) apply (erule mp, clarify) apply (frule ok, assumption+, blast) done subsubsection\Bijections involving Powersets\ lemma Pow_sum_bij: "(\Z \ Pow(A+B). \{x \ A. Inl(x) \ Z}, {y \ B. Inr(y) \ Z}\) \ bij(Pow(A+B), Pow(A)*Pow(B))" apply (rule_tac d = "\\X,Y\. {Inl (x). x \ X} \ {Inr (y). y \ Y}" in lam_bijective) apply force+ done text\As a special case, we have \<^term>\bij(Pow(A*B), A \ Pow(B))\\ lemma Pow_Sigma_bij: "(\r \ Pow(Sigma(A,B)). \x \ A. r``{x}) \ bij(Pow(Sigma(A,B)), \x \ A. Pow(B(x)))" apply (rule_tac d = "\f. \x \ A. \y \ f`x. {\x,y\}" in lam_bijective) apply (blast intro: lam_type) apply (blast dest: apply_type, simp_all) apply fast (*strange, but blast can't do it*) apply (rule fun_extension, auto) by blast end diff --git a/src/ZF/OrderType.thy b/src/ZF/OrderType.thy --- a/src/ZF/OrderType.thy +++ b/src/ZF/OrderType.thy @@ -1,1028 +1,1028 @@ (* Title: ZF/OrderType.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Order Types and Ordinal Arithmetic\ theory OrderType imports OrderArith OrdQuant Nat begin text\The order type of a well-ordering is the least ordinal isomorphic to it. Ordinal arithmetic is traditionally defined in terms of order types, as it is here. But a definition by transfinite recursion would be much simpler!\ definition ordermap :: "[i,i]\i" where "ordermap(A,r) \ \x\A. wfrec[A](r, x, \x f. f `` pred(A,x,r))" definition ordertype :: "[i,i]\i" where "ordertype(A,r) \ ordermap(A,r)``A" definition (*alternative definition of ordinal numbers*) Ord_alt :: "i \ o" where "Ord_alt(X) \ well_ord(X, Memrel(X)) \ (\u\X. u=pred(X, u, Memrel(X)))" definition (*coercion to ordinal: if not, just 0*) ordify :: "i\i" where "ordify(x) \ if Ord(x) then x else 0" definition (*ordinal multiplication*) omult :: "[i,i]\i" (infixl \**\ 70) where "i ** j \ ordertype(j*i, rmult(j,Memrel(j),i,Memrel(i)))" definition (*ordinal addition*) raw_oadd :: "[i,i]\i" where "raw_oadd(i,j) \ ordertype(i+j, radd(i,Memrel(i),j,Memrel(j)))" definition oadd :: "[i,i]\i" (infixl \++\ 65) where "i ++ j \ raw_oadd(ordify(i),ordify(j))" definition (*ordinal subtraction*) odiff :: "[i,i]\i" (infixl \--\ 65) where "i -- j \ ordertype(i-j, Memrel(i))" subsection\Proofs needing the combination of Ordinal.thy and Order.thy\ lemma le_well_ord_Memrel: "j \ i \ well_ord(j, Memrel(i))" apply (rule well_ordI) apply (rule wf_Memrel [THEN wf_imp_wf_on]) apply (simp add: ltD lt_Ord linear_def ltI [THEN lt_trans2 [of _ j i]]) apply (intro ballI Ord_linear) apply (blast intro: Ord_in_Ord lt_Ord)+ done (*"Ord(i) \ well_ord(i, Memrel(i))"*) lemmas well_ord_Memrel = le_refl [THEN le_well_ord_Memrel] (*Kunen's Theorem 7.3 (i), page 16; see also Ordinal/Ord_in_Ord The smaller ordinal is an initial segment of the larger *) lemma lt_pred_Memrel: "j pred(i, j, Memrel(i)) = j" apply (simp add: pred_def lt_def) apply (blast intro: Ord_trans) done lemma pred_Memrel: "x \ A \ pred(A, x, Memrel(A)) = A \ x" by (unfold pred_def Memrel_def, blast) lemma Ord_iso_implies_eq_lemma: "\j ord_iso(i,Memrel(i),j,Memrel(j))\ \ R" apply (frule lt_pred_Memrel) apply (erule ltE) apply (rule well_ord_Memrel [THEN well_ord_iso_predE, of i f j], auto) -apply (unfold ord_iso_def) + unfolding ord_iso_def (*Combining the two simplifications causes looping*) apply (simp (no_asm_simp)) apply (blast intro: bij_is_fun [THEN apply_type] Ord_trans) done (*Kunen's Theorem 7.3 (ii), page 16. Isomorphic ordinals are equal*) lemma Ord_iso_implies_eq: "\Ord(i); Ord(j); f \ ord_iso(i,Memrel(i),j,Memrel(j))\ \ i=j" apply (rule_tac i = i and j = j in Ord_linear_lt) apply (blast intro: ord_iso_sym Ord_iso_implies_eq_lemma)+ done subsection\Ordermap and ordertype\ lemma ordermap_type: "ordermap(A,r) \ A -> ordertype(A,r)" apply (unfold ordermap_def ordertype_def) apply (rule lam_type) apply (rule lamI [THEN imageI], assumption+) done subsubsection\Unfolding of ordermap\ (*Useful for cardinality reasoning; see CardinalArith.ML*) lemma ordermap_eq_image: "\wf[A](r); x \ A\ \ ordermap(A,r) ` x = ordermap(A,r) `` pred(A,x,r)" apply (unfold ordermap_def pred_def) apply (simp (no_asm_simp)) apply (erule wfrec_on [THEN trans], assumption) apply (simp (no_asm_simp) add: subset_iff image_lam vimage_singleton_iff) done (*Useful for rewriting PROVIDED pred is not unfolded until later!*) lemma ordermap_pred_unfold: "\wf[A](r); x \ A\ \ ordermap(A,r) ` x = {ordermap(A,r)`y . y \ pred(A,x,r)}" by (simp add: ordermap_eq_image pred_subset ordermap_type [THEN image_fun]) (*pred-unfolded version. NOT suitable for rewriting -- loops!*) lemmas ordermap_unfold = ordermap_pred_unfold [simplified pred_def] (*The theorem above is \wf[A](r); x \ A\ \ ordermap(A,r) ` x = {ordermap(A,r) ` y . y: {y \ A . \y,x\ \ r}} NOTE: the definition of ordermap used here delivers ordinals only if r is transitive. If r is the predecessor relation on the naturals then ordermap(nat,predr) ` n equals {n-1} and not n. A more complicated definition, like ordermap(A,r) ` x = Union{succ(ordermap(A,r) ` y) . y: {y \ A . \y,x\ \ r}}, might eliminate the need for r to be transitive. *) subsubsection\Showing that ordermap, ordertype yield ordinals\ lemma Ord_ordermap: "\well_ord(A,r); x \ A\ \ Ord(ordermap(A,r) ` x)" apply (unfold well_ord_def tot_ord_def part_ord_def, safe) apply (rule_tac a=x in wf_on_induct, assumption+) apply (simp (no_asm_simp) add: ordermap_pred_unfold) apply (rule OrdI [OF _ Ord_is_Transset]) apply (unfold pred_def Transset_def) apply (blast intro: trans_onD dest!: ordermap_unfold [THEN equalityD1])+ done lemma Ord_ordertype: "well_ord(A,r) \ Ord(ordertype(A,r))" -apply (unfold ordertype_def) + unfolding ordertype_def apply (subst image_fun [OF ordermap_type subset_refl]) apply (rule OrdI [OF _ Ord_is_Transset]) prefer 2 apply (blast intro: Ord_ordermap) apply (unfold Transset_def well_ord_def) apply (blast intro: trans_onD dest!: ordermap_unfold [THEN equalityD1]) done subsubsection\ordermap preserves the orderings in both directions\ lemma ordermap_mono: "\\w,x\: r; wf[A](r); w \ A; x \ A\ \ ordermap(A,r)`w \ ordermap(A,r)`x" apply (erule_tac x1 = x in ordermap_unfold [THEN ssubst], assumption, blast) done (*linearity of r is crucial here*) lemma converse_ordermap_mono: "\ordermap(A,r)`w \ ordermap(A,r)`x; well_ord(A,r); w \ A; x \ A\ \ \w,x\: r" apply (unfold well_ord_def tot_ord_def, safe) apply (erule_tac x=w and y=x in linearE, assumption+) apply (blast elim!: mem_not_refl [THEN notE]) apply (blast dest: ordermap_mono intro: mem_asym) done lemma ordermap_surj: "ordermap(A, r) \ surj(A, ordertype(A, r))" unfolding ordertype_def by (rule surj_image) (rule ordermap_type) lemma ordermap_bij: "well_ord(A,r) \ ordermap(A,r) \ bij(A, ordertype(A,r))" apply (unfold well_ord_def tot_ord_def bij_def inj_def) apply (force intro!: ordermap_type ordermap_surj elim: linearE dest: ordermap_mono simp add: mem_not_refl) done subsubsection\Isomorphisms involving ordertype\ lemma ordertype_ord_iso: "well_ord(A,r) \ ordermap(A,r) \ ord_iso(A,r, ordertype(A,r), Memrel(ordertype(A,r)))" -apply (unfold ord_iso_def) + unfolding ord_iso_def apply (safe elim!: well_ord_is_wf intro!: ordermap_type [THEN apply_type] ordermap_mono ordermap_bij) apply (blast dest!: converse_ordermap_mono) done lemma ordertype_eq: "\f \ ord_iso(A,r,B,s); well_ord(B,s)\ \ ordertype(A,r) = ordertype(B,s)" apply (frule well_ord_ord_iso, assumption) apply (rule Ord_iso_implies_eq, (erule Ord_ordertype)+) apply (blast intro: ord_iso_trans ord_iso_sym ordertype_ord_iso) done lemma ordertype_eq_imp_ord_iso: "\ordertype(A,r) = ordertype(B,s); well_ord(A,r); well_ord(B,s)\ \ \f. f \ ord_iso(A,r,B,s)" apply (rule exI) apply (rule ordertype_ord_iso [THEN ord_iso_trans], assumption) apply (erule ssubst) apply (erule ordertype_ord_iso [THEN ord_iso_sym]) done subsubsection\Basic equalities for ordertype\ (*Ordertype of Memrel*) lemma le_ordertype_Memrel: "j \ i \ ordertype(j,Memrel(i)) = j" apply (rule Ord_iso_implies_eq [symmetric]) apply (erule ltE, assumption) apply (blast intro: le_well_ord_Memrel Ord_ordertype) apply (rule ord_iso_trans) apply (erule_tac [2] le_well_ord_Memrel [THEN ordertype_ord_iso]) apply (rule id_bij [THEN ord_isoI]) apply (simp (no_asm_simp)) apply (fast elim: ltE Ord_in_Ord Ord_trans) done (*"Ord(i) \ ordertype(i, Memrel(i)) = i"*) lemmas ordertype_Memrel = le_refl [THEN le_ordertype_Memrel] lemma ordertype_0 [simp]: "ordertype(0,r) = 0" apply (rule id_bij [THEN ord_isoI, THEN ordertype_eq, THEN trans]) apply (erule emptyE) apply (rule well_ord_0) apply (rule Ord_0 [THEN ordertype_Memrel]) done (*Ordertype of rvimage: \f \ bij(A,B); well_ord(B,s)\ \ ordertype(A, rvimage(A,f,s)) = ordertype(B,s) *) lemmas bij_ordertype_vimage = ord_iso_rvimage [THEN ordertype_eq] subsubsection\A fundamental unfolding law for ordertype.\ (*Ordermap returns the same result if applied to an initial segment*) lemma ordermap_pred_eq_ordermap: "\well_ord(A,r); y \ A; z \ pred(A,y,r)\ \ ordermap(pred(A,y,r), r) ` z = ordermap(A, r) ` z" apply (frule wf_on_subset_A [OF well_ord_is_wf pred_subset]) apply (rule_tac a=z in wf_on_induct, assumption+) apply (safe elim!: predE) apply (simp (no_asm_simp) add: ordermap_pred_unfold well_ord_is_wf pred_iff) (*combining these two simplifications LOOPS! *) apply (simp (no_asm_simp) add: pred_pred_eq) apply (simp add: pred_def) apply (rule RepFun_cong [OF _ refl]) apply (drule well_ord_is_trans_on) apply (fast elim!: trans_onD) done lemma ordertype_unfold: "ordertype(A,r) = {ordermap(A,r)`y . y \ A}" -apply (unfold ordertype_def) + unfolding ordertype_def apply (rule image_fun [OF ordermap_type subset_refl]) done text\Theorems by Krzysztof Grabczewski; proofs simplified by lcp\ lemma ordertype_pred_subset: "\well_ord(A,r); x \ A\ \ ordertype(pred(A,x,r),r) \ ordertype(A,r)" apply (simp add: ordertype_unfold well_ord_subset [OF _ pred_subset]) apply (fast intro: ordermap_pred_eq_ordermap elim: predE) done lemma ordertype_pred_lt: "\well_ord(A,r); x \ A\ \ ordertype(pred(A,x,r),r) < ordertype(A,r)" apply (rule ordertype_pred_subset [THEN subset_imp_le, THEN leE]) apply (simp_all add: Ord_ordertype well_ord_subset [OF _ pred_subset]) apply (erule sym [THEN ordertype_eq_imp_ord_iso, THEN exE]) apply (erule_tac [3] well_ord_iso_predE) apply (simp_all add: well_ord_subset [OF _ pred_subset]) done (*May rewrite with this -- provided no rules are supplied for proving that well_ord(pred(A,x,r), r) *) lemma ordertype_pred_unfold: "well_ord(A,r) \ ordertype(A,r) = {ordertype(pred(A,x,r),r). x \ A}" apply (rule equalityI) apply (safe intro!: ordertype_pred_lt [THEN ltD]) apply (auto simp add: ordertype_def well_ord_is_wf [THEN ordermap_eq_image] ordermap_type [THEN image_fun] ordermap_pred_eq_ordermap pred_subset) done subsection\Alternative definition of ordinal\ (*proof by Krzysztof Grabczewski*) lemma Ord_is_Ord_alt: "Ord(i) \ Ord_alt(i)" -apply (unfold Ord_alt_def) + unfolding Ord_alt_def apply (rule conjI) apply (erule well_ord_Memrel) apply (unfold Ord_def Transset_def pred_def Memrel_def, blast) done (*proof by lcp*) lemma Ord_alt_is_Ord: "Ord_alt(i) \ Ord(i)" apply (unfold Ord_alt_def Ord_def Transset_def well_ord_def tot_ord_def part_ord_def trans_on_def) apply (simp add: pred_Memrel) apply (blast elim!: equalityE) done subsection\Ordinal Addition\ subsubsection\Order Type calculations for radd\ text\Addition with 0\ lemma bij_sum_0: "(\z\A+0. case(\x. x, \y. y, z)) \ bij(A+0, A)" apply (rule_tac d = Inl in lam_bijective, safe) apply (simp_all (no_asm_simp)) done lemma ordertype_sum_0_eq: "well_ord(A,r) \ ordertype(A+0, radd(A,r,0,s)) = ordertype(A,r)" apply (rule bij_sum_0 [THEN ord_isoI, THEN ordertype_eq]) prefer 2 apply assumption apply force done lemma bij_0_sum: "(\z\0+A. case(\x. x, \y. y, z)) \ bij(0+A, A)" apply (rule_tac d = Inr in lam_bijective, safe) apply (simp_all (no_asm_simp)) done lemma ordertype_0_sum_eq: "well_ord(A,r) \ ordertype(0+A, radd(0,s,A,r)) = ordertype(A,r)" apply (rule bij_0_sum [THEN ord_isoI, THEN ordertype_eq]) prefer 2 apply assumption apply force done text\Initial segments of radd. Statements by Grabczewski\ (*In fact, pred(A+B, Inl(a), radd(A,r,B,s)) = pred(A,a,r)+0 *) lemma pred_Inl_bij: "a \ A \ (\x\pred(A,a,r). Inl(x)) \ bij(pred(A,a,r), pred(A+B, Inl(a), radd(A,r,B,s)))" -apply (unfold pred_def) + unfolding pred_def apply (rule_tac d = "case (\x. x, \y. y) " in lam_bijective) apply auto done lemma ordertype_pred_Inl_eq: "\a \ A; well_ord(A,r)\ \ ordertype(pred(A+B, Inl(a), radd(A,r,B,s)), radd(A,r,B,s)) = ordertype(pred(A,a,r), r)" apply (rule pred_Inl_bij [THEN ord_isoI, THEN ord_iso_sym, THEN ordertype_eq]) apply (simp_all add: well_ord_subset [OF _ pred_subset]) apply (simp add: pred_def) done lemma pred_Inr_bij: "b \ B \ id(A+pred(B,b,s)) \ bij(A+pred(B,b,s), pred(A+B, Inr(b), radd(A,r,B,s)))" apply (unfold pred_def id_def) apply (rule_tac d = "\z. z" in lam_bijective, auto) done lemma ordertype_pred_Inr_eq: "\b \ B; well_ord(A,r); well_ord(B,s)\ \ ordertype(pred(A+B, Inr(b), radd(A,r,B,s)), radd(A,r,B,s)) = ordertype(A+pred(B,b,s), radd(A,r,pred(B,b,s),s))" apply (rule pred_Inr_bij [THEN ord_isoI, THEN ord_iso_sym, THEN ordertype_eq]) prefer 2 apply (force simp add: pred_def id_def, assumption) apply (blast intro: well_ord_radd well_ord_subset [OF _ pred_subset]) done subsubsection\ordify: trivial coercion to an ordinal\ lemma Ord_ordify [iff, TC]: "Ord(ordify(x))" by (simp add: ordify_def) (*Collapsing*) lemma ordify_idem [simp]: "ordify(ordify(x)) = ordify(x)" by (simp add: ordify_def) subsubsection\Basic laws for ordinal addition\ lemma Ord_raw_oadd: "\Ord(i); Ord(j)\ \ Ord(raw_oadd(i,j))" by (simp add: raw_oadd_def ordify_def Ord_ordertype well_ord_radd well_ord_Memrel) lemma Ord_oadd [iff,TC]: "Ord(i++j)" by (simp add: oadd_def Ord_raw_oadd) text\Ordinal addition with zero\ lemma raw_oadd_0: "Ord(i) \ raw_oadd(i,0) = i" by (simp add: raw_oadd_def ordify_def ordertype_sum_0_eq ordertype_Memrel well_ord_Memrel) lemma oadd_0 [simp]: "Ord(i) \ i++0 = i" apply (simp (no_asm_simp) add: oadd_def raw_oadd_0 ordify_def) done lemma raw_oadd_0_left: "Ord(i) \ raw_oadd(0,i) = i" by (simp add: raw_oadd_def ordify_def ordertype_0_sum_eq ordertype_Memrel well_ord_Memrel) lemma oadd_0_left [simp]: "Ord(i) \ 0++i = i" by (simp add: oadd_def raw_oadd_0_left ordify_def) lemma oadd_eq_if_raw_oadd: "i++j = (if Ord(i) then (if Ord(j) then raw_oadd(i,j) else i) else (if Ord(j) then j else 0))" by (simp add: oadd_def ordify_def raw_oadd_0_left raw_oadd_0) lemma raw_oadd_eq_oadd: "\Ord(i); Ord(j)\ \ raw_oadd(i,j) = i++j" by (simp add: oadd_def ordify_def) (*** Further properties of ordinal addition. Statements by Grabczewski, proofs by lcp. ***) (*Surely also provable by transfinite induction on j?*) lemma lt_oadd1: "k k < i++j" apply (simp add: oadd_def ordify_def lt_Ord2 raw_oadd_0, clarify) apply (simp add: raw_oadd_def) apply (rule ltE, assumption) apply (rule ltI) apply (force simp add: ordertype_pred_unfold well_ord_radd well_ord_Memrel ordertype_pred_Inl_eq lt_pred_Memrel leI [THEN le_ordertype_Memrel]) apply (blast intro: Ord_ordertype well_ord_radd well_ord_Memrel) done (*Thus also we obtain the rule @{term"i++j = k \ i \ k"} *) lemma oadd_le_self: "Ord(i) \ i \ i++j" apply (rule all_lt_imp_le) apply (auto simp add: Ord_oadd lt_oadd1) done text\Various other results\ lemma id_ord_iso_Memrel: "A<=B \ id(A) \ ord_iso(A, Memrel(A), A, Memrel(B))" apply (rule id_bij [THEN ord_isoI]) apply (simp (no_asm_simp)) apply blast done lemma subset_ord_iso_Memrel: "\f \ ord_iso(A,Memrel(B),C,r); A<=B\ \ f \ ord_iso(A,Memrel(A),C,r)" apply (frule ord_iso_is_bij [THEN bij_is_fun, THEN fun_is_rel]) apply (frule ord_iso_trans [OF id_ord_iso_Memrel], assumption) apply (simp add: right_comp_id) done lemma restrict_ord_iso: "\f \ ord_iso(i, Memrel(i), Order.pred(A,a,r), r); a \ A; j < i; trans[A](r)\ \ restrict(f,j) \ ord_iso(j, Memrel(j), Order.pred(A,f`j,r), r)" apply (frule ltD) apply (frule ord_iso_is_bij [THEN bij_is_fun, THEN apply_type], assumption) apply (frule ord_iso_restrict_pred, assumption) apply (simp add: pred_iff trans_pred_pred_eq lt_pred_Memrel) apply (blast intro!: subset_ord_iso_Memrel le_imp_subset [OF leI]) done lemma restrict_ord_iso2: "\f \ ord_iso(Order.pred(A,a,r), r, i, Memrel(i)); a \ A; j < i; trans[A](r)\ \ converse(restrict(converse(f), j)) \ ord_iso(Order.pred(A, converse(f)`j, r), r, j, Memrel(j))" by (blast intro: restrict_ord_iso ord_iso_sym ltI) lemma ordertype_sum_Memrel: "\well_ord(A,r); k \ ordertype(A+k, radd(A, r, k, Memrel(j))) = ordertype(A+k, radd(A, r, k, Memrel(k)))" apply (erule ltE) apply (rule ord_iso_refl [THEN sum_ord_iso_cong, THEN ordertype_eq]) apply (erule OrdmemD [THEN id_ord_iso_Memrel, THEN ord_iso_sym]) apply (simp_all add: well_ord_radd well_ord_Memrel) done lemma oadd_lt_mono2: "k i++k < i++j" apply (simp add: oadd_def ordify_def raw_oadd_0_left lt_Ord lt_Ord2, clarify) apply (simp add: raw_oadd_def) apply (rule ltE, assumption) apply (rule ordertype_pred_unfold [THEN equalityD2, THEN subsetD, THEN ltI]) apply (simp_all add: Ord_ordertype well_ord_radd well_ord_Memrel) apply (rule bexI) apply (erule_tac [2] InrI) apply (simp add: ordertype_pred_Inr_eq well_ord_Memrel lt_pred_Memrel leI [THEN le_ordertype_Memrel] ordertype_sum_Memrel) done lemma oadd_lt_cancel2: "\i++j < i++k; Ord(j)\ \ j i++j < i++k \ ji++j = i++k; Ord(j); Ord(k)\ \ j=k" apply (simp add: oadd_eq_if_raw_oadd split: split_if_asm) apply (simp add: raw_oadd_eq_oadd) apply (rule Ord_linear_lt, auto) apply (force dest: oadd_lt_mono2 [of concl: i] simp add: lt_not_refl)+ done lemma lt_oadd_disj: "k < i++j \ kl\j. k = i++l )" apply (simp add: Ord_in_Ord' [of _ j] oadd_eq_if_raw_oadd split: split_if_asm) prefer 2 apply (simp add: Ord_in_Ord' [of _ j] lt_def) apply (simp add: ordertype_pred_unfold well_ord_radd well_ord_Memrel raw_oadd_def) apply (erule ltD [THEN RepFunE]) apply (force simp add: ordertype_pred_Inl_eq well_ord_Memrel ltI lt_pred_Memrel le_ordertype_Memrel leI ordertype_pred_Inr_eq ordertype_sum_Memrel) done subsubsection\Ordinal addition with successor -- via associativity!\ lemma oadd_assoc: "(i++j)++k = i++(j++k)" apply (simp add: oadd_eq_if_raw_oadd Ord_raw_oadd raw_oadd_0 raw_oadd_0_left, clarify) apply (simp add: raw_oadd_def) apply (rule ordertype_eq [THEN trans]) apply (rule sum_ord_iso_cong [OF ordertype_ord_iso [THEN ord_iso_sym] ord_iso_refl]) apply (simp_all add: Ord_ordertype well_ord_radd well_ord_Memrel) apply (rule sum_assoc_ord_iso [THEN ordertype_eq, THEN trans]) apply (rule_tac [2] ordertype_eq) apply (rule_tac [2] sum_ord_iso_cong [OF ord_iso_refl ordertype_ord_iso]) apply (blast intro: Ord_ordertype well_ord_radd well_ord_Memrel)+ done lemma oadd_unfold: "\Ord(i); Ord(j)\ \ i++j = i \ (\k\j. {i++k})" apply (rule subsetI [THEN equalityI]) apply (erule ltI [THEN lt_oadd_disj, THEN disjE]) apply (blast intro: Ord_oadd) apply (blast elim!: ltE, blast) apply (force intro: lt_oadd1 oadd_lt_mono2 simp add: Ord_mem_iff_lt) done lemma oadd_1: "Ord(i) \ i++1 = succ(i)" apply (simp (no_asm_simp) add: oadd_unfold Ord_1 oadd_0) apply blast done lemma oadd_succ [simp]: "Ord(j) \ i++succ(j) = succ(i++j)" apply (simp add: oadd_eq_if_raw_oadd, clarify) apply (simp add: raw_oadd_eq_oadd) apply (simp add: oadd_1 [of j, symmetric] oadd_1 [of "i++j", symmetric] oadd_assoc) done text\Ordinal addition with limit ordinals\ lemma oadd_UN: "\\x. x \ A \ Ord(j(x)); a \ A\ \ i ++ (\x\A. j(x)) = (\x\A. i++j(x))" by (blast intro: ltI Ord_UN Ord_oadd lt_oadd1 [THEN ltD] oadd_lt_mono2 [THEN ltD] elim!: ltE dest!: ltI [THEN lt_oadd_disj]) lemma oadd_Limit: "Limit(j) \ i++j = (\k\j. i++k)" apply (frule Limit_has_0 [THEN ltD]) apply (simp add: Limit_is_Ord [THEN Ord_in_Ord] oadd_UN [symmetric] Union_eq_UN [symmetric] Limit_Union_eq) done lemma oadd_eq_0_iff: "\Ord(i); Ord(j)\ \ (i ++ j) = 0 \ i=0 \ j=0" apply (erule trans_induct3 [of j]) apply (simp_all add: oadd_Limit) apply (simp add: Union_empty_iff Limit_def lt_def, blast) done lemma oadd_eq_lt_iff: "\Ord(i); Ord(j)\ \ 0 < (i ++ j) \ 0Ord(i); Limit(j)\ \ Limit(i ++ j)" apply (simp add: oadd_Limit) apply (frule Limit_has_1 [THEN ltD]) apply (rule increasing_LimitI) apply (rule Ord_0_lt) apply (blast intro: Ord_in_Ord [OF Limit_is_Ord]) apply (force simp add: Union_empty_iff oadd_eq_0_iff Limit_is_Ord [of j, THEN Ord_in_Ord], auto) apply (rule_tac x="succ(y)" in bexI) apply (simp add: ltI Limit_is_Ord [of j, THEN Ord_in_Ord]) apply (simp add: Limit_def lt_def) done text\Order/monotonicity properties of ordinal addition\ lemma oadd_le_self2: "Ord(i) \ i \ j++i" proof (induct i rule: trans_induct3) case 0 thus ?case by (simp add: Ord_0_le) next case (succ i) thus ?case by (simp add: oadd_succ succ_leI) next case (limit l) hence "l = (\x\l. x)" by (simp add: Union_eq_UN [symmetric] Limit_Union_eq) also have "... \ (\x\l. j++x)" by (rule le_implies_UN_le_UN) (rule limit.hyps) finally have "l \ (\x\l. j++x)" . thus ?case using limit.hyps by (simp add: oadd_Limit) qed lemma oadd_le_mono1: "k \ j \ k++i \ j++i" apply (frule lt_Ord) apply (frule le_Ord2) apply (simp add: oadd_eq_if_raw_oadd, clarify) apply (simp add: raw_oadd_eq_oadd) apply (erule_tac i = i in trans_induct3) apply (simp (no_asm_simp)) apply (simp (no_asm_simp) add: oadd_succ succ_le_iff) apply (simp (no_asm_simp) add: oadd_Limit) apply (rule le_implies_UN_le_UN, blast) done lemma oadd_lt_mono: "\i' \ i; j' \ i'++j' < i++j" by (blast intro: lt_trans1 oadd_le_mono1 oadd_lt_mono2 Ord_succD elim: ltE) lemma oadd_le_mono: "\i' \ i; j' \ j\ \ i'++j' \ i++j" by (simp del: oadd_succ add: oadd_succ [symmetric] le_Ord2 oadd_lt_mono) lemma oadd_le_iff2: "\Ord(j); Ord(k)\ \ i++j \ i++k \ j \ k" by (simp del: oadd_succ add: oadd_lt_iff2 oadd_succ [symmetric] Ord_succ) lemma oadd_lt_self: "\Ord(i); 0 \ i < i++j" apply (rule lt_trans2) apply (erule le_refl) apply (simp only: lt_Ord2 oadd_1 [of i, symmetric]) apply (blast intro: succ_leI oadd_le_mono) done text\Every ordinal is exceeded by some limit ordinal.\ lemma Ord_imp_greater_Limit: "Ord(i) \ \k. i Limit(k)" apply (rule_tac x="i ++ nat" in exI) apply (blast intro: oadd_LimitI oadd_lt_self Limit_nat [THEN Limit_has_0]) done lemma Ord2_imp_greater_Limit: "\Ord(i); Ord(j)\ \ \k. i j Limit(k)" apply (insert Ord_Un [of i j, THEN Ord_imp_greater_Limit]) apply (simp add: Un_least_lt_iff) done subsection\Ordinal Subtraction\ text\The difference is \<^term>\ordertype(j-i, Memrel(j))\. It's probably simpler to define the difference recursively!\ lemma bij_sum_Diff: "A<=B \ (\y\B. if(y \ A, Inl(y), Inr(y))) \ bij(B, A+(B-A))" apply (rule_tac d = "case (\x. x, \y. y) " in lam_bijective) apply (blast intro!: if_type) apply (fast intro!: case_type) apply (erule_tac [2] sumE) apply (simp_all (no_asm_simp)) done lemma ordertype_sum_Diff: "i \ j \ ordertype(i+(j-i), radd(i,Memrel(j),j-i,Memrel(j))) = ordertype(j, Memrel(j))" apply (safe dest!: le_subset_iff [THEN iffD1]) apply (rule bij_sum_Diff [THEN ord_isoI, THEN ord_iso_sym, THEN ordertype_eq]) apply (erule_tac [3] well_ord_Memrel, assumption) apply (simp (no_asm_simp)) apply (frule_tac j = y in Ord_in_Ord, assumption) apply (frule_tac j = x in Ord_in_Ord, assumption) apply (simp (no_asm_simp) add: Ord_mem_iff_lt lt_Ord not_lt_iff_le) apply (blast intro: lt_trans2 lt_trans) done lemma Ord_odiff [simp,TC]: "\Ord(i); Ord(j)\ \ Ord(i--j)" -apply (unfold odiff_def) + unfolding odiff_def apply (blast intro: Ord_ordertype Diff_subset well_ord_subset well_ord_Memrel) done lemma raw_oadd_ordertype_Diff: "i \ j \ raw_oadd(i,j--i) = ordertype(i+(j-i), radd(i,Memrel(j),j-i,Memrel(j)))" apply (simp add: raw_oadd_def odiff_def) apply (safe dest!: le_subset_iff [THEN iffD1]) apply (rule sum_ord_iso_cong [THEN ordertype_eq]) apply (erule id_ord_iso_Memrel) apply (rule ordertype_ord_iso [THEN ord_iso_sym]) apply (blast intro: well_ord_radd Diff_subset well_ord_subset well_ord_Memrel)+ done lemma oadd_odiff_inverse: "i \ j \ i ++ (j--i) = j" by (simp add: lt_Ord le_Ord2 oadd_def ordify_def raw_oadd_ordertype_Diff ordertype_sum_Diff ordertype_Memrel lt_Ord2 [THEN Ord_succD]) (*By oadd_inject, the difference between i and j is unique. Note that we get i++j = k \ j = k--i. *) lemma odiff_oadd_inverse: "\Ord(i); Ord(j)\ \ (i++j) -- i = j" apply (rule oadd_inject) apply (blast intro: oadd_odiff_inverse oadd_le_self) apply (blast intro: Ord_ordertype Ord_oadd Ord_odiff)+ done lemma odiff_lt_mono2: "\i i\ \ i--k < j--k" apply (rule_tac i = k in oadd_lt_cancel2) apply (simp add: oadd_odiff_inverse) apply (subst oadd_odiff_inverse) apply (blast intro: le_trans leI, assumption) apply (simp (no_asm_simp) add: lt_Ord le_Ord2) done subsection\Ordinal Multiplication\ lemma Ord_omult [simp,TC]: "\Ord(i); Ord(j)\ \ Ord(i**j)" -apply (unfold omult_def) + unfolding omult_def apply (blast intro: Ord_ordertype well_ord_rmult well_ord_Memrel) done subsubsection\A useful unfolding law\ lemma pred_Pair_eq: "\a \ A; b \ B\ \ pred(A*B, \a,b\, rmult(A,r,B,s)) = pred(A,a,r)*B \ ({a} * pred(B,b,s))" apply (unfold pred_def, blast) done lemma ordertype_pred_Pair_eq: "\a \ A; b \ B; well_ord(A,r); well_ord(B,s)\ \ ordertype(pred(A*B, \a,b\, rmult(A,r,B,s)), rmult(A,r,B,s)) = ordertype(pred(A,a,r)*B + pred(B,b,s), radd(A*B, rmult(A,r,B,s), B, s))" apply (simp (no_asm_simp) add: pred_Pair_eq) apply (rule ordertype_eq [symmetric]) apply (rule prod_sum_singleton_ord_iso) apply (simp_all add: pred_subset well_ord_rmult [THEN well_ord_subset]) apply (blast intro: pred_subset well_ord_rmult [THEN well_ord_subset] elim!: predE) done lemma ordertype_pred_Pair_lemma: "\i' \ ordertype(pred(i*j, , rmult(i,Memrel(i),j,Memrel(j))), rmult(i,Memrel(i),j,Memrel(j))) = raw_oadd (j**i', j')" apply (unfold raw_oadd_def omult_def) apply (simp add: ordertype_pred_Pair_eq lt_pred_Memrel ltD lt_Ord2 well_ord_Memrel) apply (rule trans) apply (rule_tac [2] ordertype_ord_iso [THEN sum_ord_iso_cong, THEN ordertype_eq]) apply (rule_tac [3] ord_iso_refl) apply (rule id_bij [THEN ord_isoI, THEN ordertype_eq]) apply (elim SigmaE sumE ltE ssubst) apply (simp_all add: well_ord_rmult well_ord_radd well_ord_Memrel Ord_ordertype lt_Ord lt_Ord2) apply (blast intro: Ord_trans)+ done lemma lt_omult: "\Ord(i); Ord(j); k \ \j' i'. k = j**i' ++ j' \ j' i'j' \ j**i' ++ j' < j**i" -apply (unfold omult_def) + unfolding omult_def apply (rule ltI) prefer 2 apply (simp add: Ord_ordertype well_ord_rmult well_ord_Memrel lt_Ord2) apply (simp add: ordertype_pred_unfold well_ord_rmult well_ord_Memrel lt_Ord2) apply (rule bexI [of _ i']) apply (rule bexI [of _ j']) apply (simp add: ordertype_pred_Pair_lemma ltI omult_def [symmetric]) apply (simp add: lt_Ord lt_Ord2 raw_oadd_eq_oadd) apply (simp_all add: lt_def) done lemma omult_unfold: "\Ord(i); Ord(j)\ \ j**i = (\j'\j. \i'\i. {j**i' ++ j'})" apply (rule subsetI [THEN equalityI]) apply (rule lt_omult [THEN exE]) apply (erule_tac [3] ltI) apply (simp_all add: Ord_omult) apply (blast elim!: ltE) apply (blast intro: omult_oadd_lt [THEN ltD] ltI) done subsubsection\Basic laws for ordinal multiplication\ text\Ordinal multiplication by zero\ lemma omult_0 [simp]: "i**0 = 0" -apply (unfold omult_def) + unfolding omult_def apply (simp (no_asm_simp)) done lemma omult_0_left [simp]: "0**i = 0" -apply (unfold omult_def) + unfolding omult_def apply (simp (no_asm_simp)) done text\Ordinal multiplication by 1\ lemma omult_1 [simp]: "Ord(i) \ i**1 = i" -apply (unfold omult_def) + unfolding omult_def apply (rule_tac s1="Memrel(i)" in ord_isoI [THEN ordertype_eq, THEN trans]) apply (rule_tac c = snd and d = "\z.\0,z\" in lam_bijective) apply (auto elim!: snd_type well_ord_Memrel ordertype_Memrel) done lemma omult_1_left [simp]: "Ord(i) \ 1**i = i" -apply (unfold omult_def) + unfolding omult_def apply (rule_tac s1="Memrel(i)" in ord_isoI [THEN ordertype_eq, THEN trans]) apply (rule_tac c = fst and d = "\z.\z,0\" in lam_bijective) apply (auto elim!: fst_type well_ord_Memrel ordertype_Memrel) done text\Distributive law for ordinal multiplication and addition\ lemma oadd_omult_distrib: "\Ord(i); Ord(j); Ord(k)\ \ i**(j++k) = (i**j)++(i**k)" apply (simp add: oadd_eq_if_raw_oadd) apply (simp add: omult_def raw_oadd_def) apply (rule ordertype_eq [THEN trans]) apply (rule prod_ord_iso_cong [OF ordertype_ord_iso [THEN ord_iso_sym] ord_iso_refl]) apply (simp_all add: well_ord_rmult well_ord_radd well_ord_Memrel Ord_ordertype) apply (rule sum_prod_distrib_ord_iso [THEN ordertype_eq, THEN trans]) apply (rule_tac [2] ordertype_eq) apply (rule_tac [2] sum_ord_iso_cong [OF ordertype_ord_iso ordertype_ord_iso]) apply (simp_all add: well_ord_rmult well_ord_radd well_ord_Memrel Ord_ordertype) done lemma omult_succ: "\Ord(i); Ord(j)\ \ i**succ(j) = (i**j)++i" by (simp del: oadd_succ add: oadd_1 [of j, symmetric] oadd_omult_distrib) text\Associative law\ lemma omult_assoc: "\Ord(i); Ord(j); Ord(k)\ \ (i**j)**k = i**(j**k)" -apply (unfold omult_def) + unfolding omult_def apply (rule ordertype_eq [THEN trans]) apply (rule prod_ord_iso_cong [OF ord_iso_refl ordertype_ord_iso [THEN ord_iso_sym]]) apply (blast intro: well_ord_rmult well_ord_Memrel)+ apply (rule prod_assoc_ord_iso [THEN ord_iso_sym, THEN ordertype_eq, THEN trans]) apply (rule_tac [2] ordertype_eq) apply (rule_tac [2] prod_ord_iso_cong [OF ordertype_ord_iso ord_iso_refl]) apply (blast intro: well_ord_rmult well_ord_Memrel Ord_ordertype)+ done text\Ordinal multiplication with limit ordinals\ lemma omult_UN: "\Ord(i); \x. x \ A \ Ord(j(x))\ \ i ** (\x\A. j(x)) = (\x\A. i**j(x))" by (simp (no_asm_simp) add: Ord_UN omult_unfold, blast) lemma omult_Limit: "\Ord(i); Limit(j)\ \ i**j = (\k\j. i**k)" by (simp add: Limit_is_Ord [THEN Ord_in_Ord] omult_UN [symmetric] Union_eq_UN [symmetric] Limit_Union_eq) subsubsection\Ordering/monotonicity properties of ordinal multiplication\ (*As a special case we have "\0 \ 0 < i**j" *) lemma lt_omult1: "\k \ k < i**j" apply (safe elim!: ltE intro!: ltI Ord_omult) apply (force simp add: omult_unfold) done lemma omult_le_self: "\Ord(i); 0 \ i \ i**j" by (blast intro: all_lt_imp_le Ord_omult lt_omult1 lt_Ord2) lemma omult_le_mono1: assumes kj: "k \ j" and i: "Ord(i)" shows "k**i \ j**i" proof - have o: "Ord(k)" "Ord(j)" by (rule lt_Ord [OF kj] le_Ord2 [OF kj])+ show ?thesis using i proof (induct i rule: trans_induct3) case 0 thus ?case by simp next case (succ i) thus ?case by (simp add: o kj omult_succ oadd_le_mono) next case (limit l) thus ?case by (auto simp add: o kj omult_Limit le_implies_UN_le_UN) qed qed lemma omult_lt_mono2: "\k \ i**k < i**j" apply (rule ltI) apply (simp (no_asm_simp) add: omult_unfold lt_Ord2) apply (safe elim!: ltE intro!: Ord_omult) apply (force simp add: Ord_omult) done lemma omult_le_mono2: "\k \ j; Ord(i)\ \ i**k \ i**j" apply (rule subset_imp_le) apply (safe elim!: ltE dest!: Ord_succD intro!: Ord_omult) apply (simp add: omult_unfold) apply (blast intro: Ord_trans) done lemma omult_le_mono: "\i' \ i; j' \ j\ \ i'**j' \ i**j" by (blast intro: le_trans omult_le_mono1 omult_le_mono2 Ord_succD elim: ltE) lemma omult_lt_mono: "\i' \ i; j' \ i'**j' < i**j" by (blast intro: lt_trans1 omult_le_mono1 omult_lt_mono2 Ord_succD elim: ltE) lemma omult_le_self2: assumes i: "Ord(i)" and j: "0 j**i" proof - have oj: "Ord(j)" by (rule lt_Ord2 [OF j]) show ?thesis using i proof (induct i rule: trans_induct3) case 0 thus ?case by simp next case (succ i) have "j ** i ++ 0 < j ** i ++ j" by (rule oadd_lt_mono2 [OF j]) with succ.hyps show ?case by (simp add: oj j omult_succ ) (rule lt_trans1) next case (limit l) hence "l = (\x\l. x)" by (simp add: Union_eq_UN [symmetric] Limit_Union_eq) also have "... \ (\x\l. j**x)" by (rule le_implies_UN_le_UN) (rule limit.hyps) finally have "l \ (\x\l. j**x)" . thus ?case using limit.hyps by (simp add: oj omult_Limit) qed qed text\Further properties of ordinal multiplication\ lemma omult_inject: "\i**j = i**k; 0 \ j=k" apply (rule Ord_linear_lt) prefer 4 apply assumption apply auto apply (force dest: omult_lt_mono2 simp add: lt_not_refl)+ done subsection\The Relation \<^term>\Lt\\ lemma wf_Lt: "wf(Lt)" apply (rule wf_subset) apply (rule wf_Memrel) apply (auto simp add: Lt_def Memrel_def lt_def) done lemma irrefl_Lt: "irrefl(A,Lt)" by (auto simp add: Lt_def irrefl_def) lemma trans_Lt: "trans[A](Lt)" apply (simp add: Lt_def trans_on_def) apply (blast intro: lt_trans) done lemma part_ord_Lt: "part_ord(A,Lt)" by (simp add: part_ord_def irrefl_Lt trans_Lt) lemma linear_Lt: "linear(nat,Lt)" apply (auto dest!: not_lt_imp_le simp add: Lt_def linear_def le_iff) apply (drule lt_asym, auto) done lemma tot_ord_Lt: "tot_ord(nat,Lt)" by (simp add: tot_ord_def linear_Lt part_ord_Lt) lemma well_ord_Lt: "well_ord(nat,Lt)" by (simp add: well_ord_def wf_Lt wf_imp_wf_on tot_ord_Lt) end diff --git a/src/ZF/Ordinal.thy b/src/ZF/Ordinal.thy --- a/src/ZF/Ordinal.thy +++ b/src/ZF/Ordinal.thy @@ -1,765 +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\ \ 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 "i i\j \ Ord(j)" definition Limit :: "i\o" where "Limit(i) \ Ord(i) \ 0 (\y. 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) + unfolding 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); \a,b\\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) + unfolding Ord_def apply (blast intro!: Transset_Un) done lemma Ord_Int [TC]: "\Ord(i); Ord(j)\ \ Ord(i \ j)" -apply (unfold Ord_def) + unfolding 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)\ \ iii\j; Ord(i); Ord(j)\ \ P\ \ P" -apply (unfold lt_def) + unfolding 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 \ (jiP \ 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 Ord(j))" by (unfold lt_def, blast) (*Equivalently, 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]: "\a,b\ \ Memrel(A) <-> a\b \ a\A \ b\A" by (unfold Memrel_def, blast) lemma MemrelI [intro!]: "\a \ b; a \ A; b \ A\ \ \a,b\ \ Memrel(A)" by auto lemma MemrelE [elim!]: "\\a,b\ \ 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) + unfolding 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) \ \a,b\ \ 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*) 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 [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\ 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 <-> iOrd(i); Ord(j)\ \ \ 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 \ ii k\ \ ii \ 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 succ(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 jOrd(i); Ord(j); Ord(k)\ \ 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 jOrd(i); Ord(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: "\jx. x\A \ 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. jj \ 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) + unfolding Limit_def apply (fast intro!: ltI elim!: ltE elim: Ord_trans) done lemma Limit_is_Ord: "Limit(i) \ Ord(i)" -apply (unfold Limit_def) + unfolding Limit_def apply (erule conjunct1) done lemma Limit_has_0: "Limit(i) \ 0 < i" -apply (unfold Limit_def) + unfolding 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 Limit(0)" by (simp add: Limit_def) lemma Limit_has_1: "Limit(i) \ 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 i \ 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 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\I \ Limit(i))\ \ Limit(\I)" apply (simp add: Limit_def lt_def) apply (blast intro!: equalityI) done end diff --git a/src/ZF/Perm.thy b/src/ZF/Perm.thy --- a/src/ZF/Perm.thy +++ b/src/ZF/Perm.thy @@ -1,554 +1,554 @@ (* Title: ZF/Perm.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1991 University of Cambridge The theory underlying permutation groups -- Composition of relations, the identity relation -- Injections, surjections, bijections -- Lemmas for the Schroeder-Bernstein Theorem *) section\Injections, Surjections, Bijections, Composition\ theory Perm imports func begin definition (*composition of relations and functions; NOT Suppes's relative product*) comp :: "[i,i]\i" (infixr \O\ 60) where "r O s \ {xz \ domain(s)*range(r) . \x y z. xz=\x,z\ \ \x,y\:s \ \y,z\:r}" definition (*the identity function for A*) id :: "i\i" where "id(A) \ (\x\A. x)" definition (*one-to-one functions from A to B*) inj :: "[i,i]\i" where "inj(A,B) \ { f \ A->B. \w\A. \x\A. f`w=f`x \ w=x}" definition (*onto functions from A to B*) surj :: "[i,i]\i" where "surj(A,B) \ { f \ A->B . \y\B. \x\A. f`x=y}" definition (*one-to-one and onto functions*) bij :: "[i,i]\i" where "bij(A,B) \ inj(A,B) \ surj(A,B)" subsection\Surjective Function Space\ lemma surj_is_fun: "f \ surj(A,B) \ f \ A->B" -apply (unfold surj_def) + unfolding surj_def apply (erule CollectD1) done lemma fun_is_surj: "f \ Pi(A,B) \ f \ surj(A,range(f))" -apply (unfold surj_def) + unfolding surj_def apply (blast intro: apply_equality range_of_fun domain_type) done lemma surj_range: "f \ surj(A,B) \ range(f)=B" -apply (unfold surj_def) + unfolding surj_def apply (best intro: apply_Pair elim: range_type) done text\A function with a right inverse is a surjection\ lemma f_imp_surjective: "\f \ A->B; \y. y \ B \ d(y): A; \y. y \ B \ f`d(y) = y\ \ f \ surj(A,B)" by (simp add: surj_def, blast) lemma lam_surjective: "\\x. x \ A \ c(x): B; \y. y \ B \ d(y): A; \y. y \ B \ c(d(y)) = y \ \ (\x\A. c(x)) \ surj(A,B)" apply (rule_tac d = d in f_imp_surjective) apply (simp_all add: lam_type) done text\Cantor's theorem revisited\ lemma cantor_surj: "f \ surj(A,Pow(A))" apply (unfold surj_def, safe) apply (cut_tac cantor) apply (best del: subsetI) done subsection\Injective Function Space\ lemma inj_is_fun: "f \ inj(A,B) \ f \ A->B" -apply (unfold inj_def) + unfolding inj_def apply (erule CollectD1) done text\Good for dealing with sets of pairs, but a bit ugly in use [used in AC]\ lemma inj_equality: "\\a,b\:f; \c,b\:f; f \ inj(A,B)\ \ a=c" -apply (unfold inj_def) + unfolding inj_def apply (blast dest: Pair_mem_PiD) done lemma inj_apply_equality: "\f \ inj(A,B); f`a=f`b; a \ A; b \ A\ \ a=b" by (unfold inj_def, blast) text\A function with a left inverse is an injection\ lemma f_imp_injective: "\f \ A->B; \x\A. d(f`x)=x\ \ f \ inj(A,B)" apply (simp (no_asm_simp) add: inj_def) apply (blast intro: subst_context [THEN box_equals]) done lemma lam_injective: "\\x. x \ A \ c(x): B; \x. x \ A \ d(c(x)) = x\ \ (\x\A. c(x)) \ inj(A,B)" apply (rule_tac d = d in f_imp_injective) apply (simp_all add: lam_type) done subsection\Bijections\ lemma bij_is_inj: "f \ bij(A,B) \ f \ inj(A,B)" -apply (unfold bij_def) + unfolding bij_def apply (erule IntD1) done lemma bij_is_surj: "f \ bij(A,B) \ f \ surj(A,B)" -apply (unfold bij_def) + unfolding bij_def apply (erule IntD2) done lemma bij_is_fun: "f \ bij(A,B) \ f \ A->B" by (rule bij_is_inj [THEN inj_is_fun]) lemma lam_bijective: "\\x. x \ A \ c(x): B; \y. y \ B \ d(y): A; \x. x \ A \ d(c(x)) = x; \y. y \ B \ c(d(y)) = y \ \ (\x\A. c(x)) \ bij(A,B)" -apply (unfold bij_def) + unfolding bij_def apply (blast intro!: lam_injective lam_surjective) done lemma RepFun_bijective: "(\y\x. \!y'. f(y') = f(y)) \ (\z\{f(y). y \ x}. THE y. f(y) = z) \ bij({f(y). y \ x}, x)" apply (rule_tac d = f in lam_bijective) apply (auto simp add: the_equality2) done subsection\Identity Function\ lemma idI [intro!]: "a \ A \ \a,a\ \ id(A)" -apply (unfold id_def) + unfolding id_def apply (erule lamI) done lemma idE [elim!]: "\p \ id(A); \x.\x \ A; p=\x,x\\ \ P\ \ P" by (simp add: id_def lam_def, blast) lemma id_type: "id(A) \ A->A" -apply (unfold id_def) + unfolding id_def apply (rule lam_type, assumption) done lemma id_conv [simp]: "x \ A \ id(A)`x = x" -apply (unfold id_def) + unfolding id_def apply (simp (no_asm_simp)) done lemma id_mono: "A<=B \ id(A) \ id(B)" -apply (unfold id_def) + unfolding id_def apply (erule lam_mono) done lemma id_subset_inj: "A<=B \ id(A): inj(A,B)" apply (simp add: inj_def id_def) apply (blast intro: lam_type) done lemmas id_inj = subset_refl [THEN id_subset_inj] lemma id_surj: "id(A): surj(A,A)" apply (unfold id_def surj_def) apply (simp (no_asm_simp)) done lemma id_bij: "id(A): bij(A,A)" -apply (unfold bij_def) + unfolding bij_def apply (blast intro: id_inj id_surj) done lemma subset_iff_id: "A \ B \ id(A) \ A->B" -apply (unfold id_def) + unfolding id_def apply (force intro!: lam_type dest: apply_type) done text\\<^term>\id\ as the identity relation\ lemma id_iff [simp]: "\x,y\ \ id(A) \ x=y \ y \ A" by auto subsection\Converse of a Function\ lemma inj_converse_fun: "f \ inj(A,B) \ converse(f) \ range(f)->A" -apply (unfold inj_def) + unfolding inj_def apply (simp (no_asm_simp) add: Pi_iff function_def) apply (erule CollectE) apply (simp (no_asm_simp) add: apply_iff) apply (blast dest: fun_is_rel) done text\Equations for converse(f)\ text\The premises are equivalent to saying that f is injective...\ lemma left_inverse_lemma: "\f \ A->B; converse(f): C->A; a \ A\ \ converse(f)`(f`a) = a" by (blast intro: apply_Pair apply_equality converseI) lemma left_inverse [simp]: "\f \ inj(A,B); a \ A\ \ converse(f)`(f`a) = a" by (blast intro: left_inverse_lemma inj_converse_fun inj_is_fun) lemma left_inverse_eq: "\f \ inj(A,B); f ` x = y; x \ A\ \ converse(f) ` y = x" by auto lemmas left_inverse_bij = bij_is_inj [THEN left_inverse] lemma right_inverse_lemma: "\f \ A->B; converse(f): C->A; b \ C\ \ f`(converse(f)`b) = b" by (rule apply_Pair [THEN converseD [THEN apply_equality]], auto) (*Should the premises be f \ surj(A,B), b \ B for symmetry with left_inverse? No: they would not imply that converse(f) was a function! *) lemma right_inverse [simp]: "\f \ inj(A,B); b \ range(f)\ \ f`(converse(f)`b) = b" by (blast intro: right_inverse_lemma inj_converse_fun inj_is_fun) lemma right_inverse_bij: "\f \ bij(A,B); b \ B\ \ f`(converse(f)`b) = b" by (force simp add: bij_def surj_range) subsection\Converses of Injections, Surjections, Bijections\ lemma inj_converse_inj: "f \ inj(A,B) \ converse(f): inj(range(f), A)" apply (rule f_imp_injective) apply (erule inj_converse_fun, clarify) apply (rule right_inverse) apply assumption apply blast done lemma inj_converse_surj: "f \ inj(A,B) \ converse(f): surj(range(f), A)" by (blast intro: f_imp_surjective inj_converse_fun left_inverse inj_is_fun range_of_fun [THEN apply_type]) text\Adding this as an intro! rule seems to cause looping\ lemma bij_converse_bij [TC]: "f \ bij(A,B) \ converse(f): bij(B,A)" -apply (unfold bij_def) + unfolding bij_def apply (fast elim: surj_range [THEN subst] inj_converse_inj inj_converse_surj) done subsection\Composition of Two Relations\ text\The inductive definition package could derive these theorems for \<^term>\r O s\\ lemma compI [intro]: "\\a,b\:s; \b,c\:r\ \ \a,c\ \ r O s" by (unfold comp_def, blast) lemma compE [elim!]: "\xz \ r O s; \x y z. \xz=\x,z\; \x,y\:s; \y,z\:r\ \ P\ \ P" by (unfold comp_def, blast) lemma compEpair: "\\a,c\ \ r O s; \y. \\a,y\:s; \y,c\:r\ \ P\ \ P" by (erule compE, simp) lemma converse_comp: "converse(R O S) = converse(S) O converse(R)" by blast subsection\Domain and Range -- see Suppes, Section 3.1\ text\Boyer et al., Set Theory in First-Order Logic, JAR 2 (1986), 287-327\ lemma range_comp: "range(r O s) \ range(r)" by blast lemma range_comp_eq: "domain(r) \ range(s) \ range(r O s) = range(r)" by (rule range_comp [THEN equalityI], blast) lemma domain_comp: "domain(r O s) \ domain(s)" by blast lemma domain_comp_eq: "range(s) \ domain(r) \ domain(r O s) = domain(s)" by (rule domain_comp [THEN equalityI], blast) lemma image_comp: "(r O s)``A = r``(s``A)" by blast lemma inj_inj_range: "f \ inj(A,B) \ f \ inj(A,range(f))" by (auto simp add: inj_def Pi_iff function_def) lemma inj_bij_range: "f \ inj(A,B) \ f \ bij(A,range(f))" by (auto simp add: bij_def intro: inj_inj_range inj_is_fun fun_is_surj) subsection\Other Results\ lemma comp_mono: "\r'<=r; s'<=s\ \ (r' O s') \ (r O s)" by blast text\composition preserves relations\ lemma comp_rel: "\s<=A*B; r<=B*C\ \ (r O s) \ A*C" by blast text\associative law for composition\ lemma comp_assoc: "(r O s) O t = r O (s O t)" by blast (*left identity of composition; provable inclusions are id(A) O r \ r and \r<=A*B; B<=C\ \ r \ id(C) O r *) lemma left_comp_id: "r<=A*B \ id(B) O r = r" by blast (*right identity of composition; provable inclusions are r O id(A) \ r and \r<=A*B; A<=C\ \ r \ r O id(C) *) lemma right_comp_id: "r<=A*B \ r O id(A) = r" by blast subsection\Composition Preserves Functions, Injections, and Surjections\ lemma comp_function: "\function(g); function(f)\ \ function(f O g)" by (unfold function_def, blast) text\Don't think the premises can be weakened much\ lemma comp_fun: "\g \ A->B; f \ B->C\ \ (f O g) \ A->C" apply (auto simp add: Pi_def comp_function Pow_iff comp_rel) apply (subst range_rel_subset [THEN domain_comp_eq], auto) done (*Thanks to the new definition of "apply", the premise f \ B->C is gone!*) lemma comp_fun_apply [simp]: "\g \ A->B; a \ A\ \ (f O g)`a = f`(g`a)" apply (frule apply_Pair, assumption) apply (simp add: apply_def image_comp) apply (blast dest: apply_equality) done text\Simplifies compositions of lambda-abstractions\ lemma comp_lam: "\\x. x \ A \ b(x): B\ \ (\y\B. c(y)) O (\x\A. b(x)) = (\x\A. c(b(x)))" apply (subgoal_tac "(\x\A. b(x)) \ A -> B") apply (rule fun_extension) apply (blast intro: comp_fun lam_funtype) apply (rule lam_funtype) apply simp apply (simp add: lam_type) done lemma comp_inj: "\g \ inj(A,B); f \ inj(B,C)\ \ (f O g) \ inj(A,C)" apply (frule inj_is_fun [of g]) apply (frule inj_is_fun [of f]) apply (rule_tac d = "\y. converse (g) ` (converse (f) ` y)" in f_imp_injective) apply (blast intro: comp_fun, simp) done lemma comp_surj: "\g \ surj(A,B); f \ surj(B,C)\ \ (f O g) \ surj(A,C)" -apply (unfold surj_def) + unfolding surj_def apply (blast intro!: comp_fun comp_fun_apply) done lemma comp_bij: "\g \ bij(A,B); f \ bij(B,C)\ \ (f O g) \ bij(A,C)" -apply (unfold bij_def) + unfolding bij_def apply (blast intro: comp_inj comp_surj) done subsection\Dual Properties of \<^term>\inj\ and \<^term>\surj\\ text\Useful for proofs from D Pastre. Automatic theorem proving in set theory. Artificial Intelligence, 10:1--27, 1978.\ lemma comp_mem_injD1: "\(f O g): inj(A,C); g \ A->B; f \ B->C\ \ g \ inj(A,B)" by (unfold inj_def, force) lemma comp_mem_injD2: "\(f O g): inj(A,C); g \ surj(A,B); f \ B->C\ \ f \ inj(B,C)" apply (unfold inj_def surj_def, safe) apply (rule_tac x1 = x in bspec [THEN bexE]) apply (erule_tac [3] x1 = w in bspec [THEN bexE], assumption+, safe) apply (rule_tac t = "(`) (g) " in subst_context) apply (erule asm_rl bspec [THEN bspec, THEN mp])+ apply (simp (no_asm_simp)) done lemma comp_mem_surjD1: "\(f O g): surj(A,C); g \ A->B; f \ B->C\ \ f \ surj(B,C)" -apply (unfold surj_def) + unfolding surj_def apply (blast intro!: comp_fun_apply [symmetric] apply_funtype) done lemma comp_mem_surjD2: "\(f O g): surj(A,C); g \ A->B; f \ inj(B,C)\ \ g \ surj(A,B)" apply (unfold inj_def surj_def, safe) apply (drule_tac x = "f`y" in bspec, auto) apply (blast intro: apply_funtype) done subsubsection\Inverses of Composition\ text\left inverse of composition; one inclusion is \<^term>\f \ A->B \ id(A) \ converse(f) O f\\ lemma left_comp_inverse: "f \ inj(A,B) \ converse(f) O f = id(A)" apply (unfold inj_def, clarify) apply (rule equalityI) apply (auto simp add: apply_iff, blast) done text\right inverse of composition; one inclusion is \<^term>\f \ A->B \ f O converse(f) \ id(B)\\ lemma right_comp_inverse: "f \ surj(A,B) \ f O converse(f) = id(B)" apply (simp add: surj_def, clarify) apply (rule equalityI) apply (best elim: domain_type range_type dest: apply_equality2) apply (blast intro: apply_Pair) done subsubsection\Proving that a Function is a Bijection\ lemma comp_eq_id_iff: "\f \ A->B; g \ B->A\ \ f O g = id(B) \ (\y\B. f`(g`y)=y)" apply (unfold id_def, safe) apply (drule_tac t = "\h. h`y " in subst_context) apply simp apply (rule fun_extension) apply (blast intro: comp_fun lam_type) apply auto done lemma fg_imp_bijective: "\f \ A->B; g \ B->A; f O g = id(B); g O f = id(A)\ \ f \ bij(A,B)" -apply (unfold bij_def) + unfolding bij_def apply (simp add: comp_eq_id_iff) apply (blast intro: f_imp_injective f_imp_surjective apply_funtype) done lemma nilpotent_imp_bijective: "\f \ A->A; f O f = id(A)\ \ f \ bij(A,A)" by (blast intro: fg_imp_bijective) lemma invertible_imp_bijective: "\converse(f): B->A; f \ A->B\ \ f \ bij(A,B)" by (simp add: fg_imp_bijective comp_eq_id_iff left_inverse_lemma right_inverse_lemma) subsubsection\Unions of Functions\ text\See similar theorems in func.thy\ text\Theorem by KG, proof by LCP\ lemma inj_disjoint_Un: "\f \ inj(A,B); g \ inj(C,D); B \ D = 0\ \ (\a\A \ C. if a \ A then f`a else g`a) \ inj(A \ C, B \ D)" apply (rule_tac d = "\z. if z \ B then converse (f) `z else converse (g) `z" in lam_injective) apply (auto simp add: inj_is_fun [THEN apply_type]) done lemma surj_disjoint_Un: "\f \ surj(A,B); g \ surj(C,D); A \ C = 0\ \ (f \ g) \ surj(A \ C, B \ D)" apply (simp add: surj_def fun_disjoint_Un) apply (blast dest!: domain_of_fun intro!: fun_disjoint_apply1 fun_disjoint_apply2) done text\A simple, high-level proof; the version for injections follows from it, using \<^term>\f \ inj(A,B) \ f \ bij(A,range(f))\\ lemma bij_disjoint_Un: "\f \ bij(A,B); g \ bij(C,D); A \ C = 0; B \ D = 0\ \ (f \ g) \ bij(A \ C, B \ D)" apply (rule invertible_imp_bijective) apply (subst converse_Un) apply (auto intro: fun_disjoint_Un bij_is_fun bij_converse_bij) done subsubsection\Restrictions as Surjections and Bijections\ lemma surj_image: "f \ Pi(A,B) \ f \ surj(A, f``A)" apply (simp add: surj_def) apply (blast intro: apply_equality apply_Pair Pi_type) done lemma surj_image_eq: "f \ surj(A, B) \ f``A = B" by (auto simp add: surj_def image_fun) (blast dest: apply_type) lemma restrict_image [simp]: "restrict(f,A) `` B = f `` (A \ B)" by (auto simp add: restrict_def) lemma restrict_inj: "\f \ inj(A,B); C<=A\ \ restrict(f,C): inj(C,B)" -apply (unfold inj_def) + unfolding inj_def apply (safe elim!: restrict_type2, auto) done lemma restrict_surj: "\f \ Pi(A,B); C<=A\ \ restrict(f,C): surj(C, f``C)" apply (insert restrict_type2 [THEN surj_image]) apply (simp add: restrict_image) done lemma restrict_bij: "\f \ inj(A,B); C<=A\ \ restrict(f,C): bij(C, f``C)" apply (simp add: inj_def bij_def) apply (blast intro: restrict_surj surj_is_fun) done subsubsection\Lemmas for Ramsey's Theorem\ lemma inj_weaken_type: "\f \ inj(A,B); B<=D\ \ f \ inj(A,D)" -apply (unfold inj_def) + unfolding inj_def apply (blast intro: fun_weaken_type) done lemma inj_succ_restrict: "\f \ inj(succ(m), A)\ \ restrict(f,m) \ inj(m, A-{f`m})" apply (rule restrict_bij [THEN bij_is_inj, THEN inj_weaken_type], assumption, blast) -apply (unfold inj_def) + unfolding inj_def apply (fast elim: range_type mem_irrefl dest: apply_equality) done lemma inj_extend: "\f \ inj(A,B); a\A; b\B\ \ cons(\a,b\,f) \ inj(cons(a,A), cons(b,B))" -apply (unfold inj_def) + unfolding inj_def apply (force intro: apply_type simp add: fun_extend) done end diff --git a/src/ZF/QUniv.thy b/src/ZF/QUniv.thy --- a/src/ZF/QUniv.thy +++ b/src/ZF/QUniv.thy @@ -1,203 +1,203 @@ (* Title: ZF/QUniv.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1993 University of Cambridge *) section\A Small Universe for Lazy Recursive Types\ theory QUniv imports Univ QPair begin (*Disjoint sums as a datatype*) rep_datatype elimination sumE induction TrueI case_eqns case_Inl case_Inr (*Variant disjoint sums as a datatype*) rep_datatype elimination qsumE induction TrueI case_eqns qcase_QInl qcase_QInr definition quniv :: "i \ i" where "quniv(A) \ Pow(univ(eclose(A)))" subsection\Properties involving Transset and Sum\ lemma Transset_includes_summands: "\Transset(C); A+B \ C\ \ A \ C \ B \ C" apply (simp add: sum_def Un_subset_iff) apply (blast dest: Transset_includes_range) done lemma Transset_sum_Int_subset: "Transset(C) \ (A+B) \ C \ (A \ C) + (B \ C)" apply (simp add: sum_def Int_Un_distrib2) apply (blast dest: Transset_Pair_D) done subsection\Introduction and Elimination Rules\ lemma qunivI: "X \ univ(eclose(A)) \ X \ quniv(A)" by (simp add: quniv_def) lemma qunivD: "X \ quniv(A) \ X \ univ(eclose(A))" by (simp add: quniv_def) lemma quniv_mono: "A<=B \ quniv(A) \ quniv(B)" -apply (unfold quniv_def) + unfolding quniv_def apply (erule eclose_mono [THEN univ_mono, THEN Pow_mono]) done subsection\Closure Properties\ lemma univ_eclose_subset_quniv: "univ(eclose(A)) \ quniv(A)" apply (simp add: quniv_def Transset_iff_Pow [symmetric]) apply (rule Transset_eclose [THEN Transset_univ]) done (*Key property for proving A_subset_quniv; requires eclose in definition of quniv*) lemma univ_subset_quniv: "univ(A) \ quniv(A)" apply (rule arg_subset_eclose [THEN univ_mono, THEN subset_trans]) apply (rule univ_eclose_subset_quniv) done lemmas univ_into_quniv = univ_subset_quniv [THEN subsetD] lemma Pow_univ_subset_quniv: "Pow(univ(A)) \ quniv(A)" -apply (unfold quniv_def) + unfolding quniv_def apply (rule arg_subset_eclose [THEN univ_mono, THEN Pow_mono]) done lemmas univ_subset_into_quniv = PowI [THEN Pow_univ_subset_quniv [THEN subsetD]] lemmas zero_in_quniv = zero_in_univ [THEN univ_into_quniv] lemmas one_in_quniv = one_in_univ [THEN univ_into_quniv] lemmas two_in_quniv = two_in_univ [THEN univ_into_quniv] lemmas A_subset_quniv = subset_trans [OF A_subset_univ univ_subset_quniv] lemmas A_into_quniv = A_subset_quniv [THEN subsetD] (*** univ(A) closure for Quine-inspired pairs and injections ***) (*Quine ordered pairs*) lemma QPair_subset_univ: "\a \ univ(A); b \ univ(A)\ \ \ univ(A)" by (simp add: QPair_def sum_subset_univ) subsection\Quine Disjoint Sum\ lemma QInl_subset_univ: "a \ univ(A) \ QInl(a) \ univ(A)" -apply (unfold QInl_def) + unfolding QInl_def apply (erule empty_subsetI [THEN QPair_subset_univ]) done lemmas naturals_subset_nat = Ord_nat [THEN Ord_is_Transset, unfolded Transset_def, THEN bspec] lemmas naturals_subset_univ = subset_trans [OF naturals_subset_nat nat_subset_univ] lemma QInr_subset_univ: "a \ univ(A) \ QInr(a) \ univ(A)" -apply (unfold QInr_def) + unfolding QInr_def apply (erule nat_1I [THEN naturals_subset_univ, THEN QPair_subset_univ]) done subsection\Closure for Quine-Inspired Products and Sums\ (*Quine ordered pairs*) lemma QPair_in_quniv: "\a: quniv(A); b: quniv(A)\ \ \ quniv(A)" by (simp add: quniv_def QPair_def sum_subset_univ) lemma QSigma_quniv: "quniv(A) <*> quniv(A) \ quniv(A)" by (blast intro: QPair_in_quniv) lemmas QSigma_subset_quniv = subset_trans [OF QSigma_mono QSigma_quniv] (*The opposite inclusion*) lemma quniv_QPair_D: " \ quniv(A) \ a: quniv(A) \ b: quniv(A)" apply (unfold quniv_def QPair_def) apply (rule Transset_includes_summands [THEN conjE]) apply (rule Transset_eclose [THEN Transset_univ]) apply (erule PowD, blast) done lemmas quniv_QPair_E = quniv_QPair_D [THEN conjE] lemma quniv_QPair_iff: " \ quniv(A) \ a: quniv(A) \ b: quniv(A)" by (blast intro: QPair_in_quniv dest: quniv_QPair_D) subsection\Quine Disjoint Sum\ lemma QInl_in_quniv: "a: quniv(A) \ QInl(a) \ quniv(A)" by (simp add: QInl_def zero_in_quniv QPair_in_quniv) lemma QInr_in_quniv: "b: quniv(A) \ QInr(b) \ quniv(A)" by (simp add: QInr_def one_in_quniv QPair_in_quniv) lemma qsum_quniv: "quniv(C) <+> quniv(C) \ quniv(C)" by (blast intro: QInl_in_quniv QInr_in_quniv) lemmas qsum_subset_quniv = subset_trans [OF qsum_mono qsum_quniv] subsection\The Natural Numbers\ lemmas nat_subset_quniv = subset_trans [OF nat_subset_univ univ_subset_quniv] (* n:nat \ n:quniv(A) *) lemmas nat_into_quniv = nat_subset_quniv [THEN subsetD] lemmas bool_subset_quniv = subset_trans [OF bool_subset_univ univ_subset_quniv] lemmas bool_into_quniv = bool_subset_quniv [THEN subsetD] (*Intersecting with Vfrom...*) lemma QPair_Int_Vfrom_succ_subset: "Transset(X) \ \ Vfrom(X, succ(i)) \ Vfrom(X,i); b \ Vfrom(X,i)>" by (simp add: QPair_def sum_def Int_Un_distrib2 Un_mono product_Int_Vfrom_subset [THEN subset_trans] Sigma_mono [OF Int_lower1 subset_refl]) subsection\"Take-Lemma" Rules\ (*for proving a=b by coinduction and c: quniv(A)*) (*Rule for level i -- preserving the level, not decreasing it*) lemma QPair_Int_Vfrom_subset: "Transset(X) \ \ Vfrom(X,i) \ Vfrom(X,i); b \ Vfrom(X,i)>" -apply (unfold QPair_def) + unfolding QPair_def apply (erule Transset_Vfrom [THEN Transset_sum_Int_subset]) done (*@{term"\a \ Vset(i) \ c; b \ Vset(i) \ d\ \ \ Vset(i) \ "}*) lemmas QPair_Int_Vset_subset_trans = subset_trans [OF Transset_0 [THEN QPair_Int_Vfrom_subset] QPair_mono] lemma QPair_Int_Vset_subset_UN: "Ord(i) \ \ Vset(i) \ (\j\i. Vset(j); b \ Vset(j)>)" apply (erule Ord_cases) (*0 case*) apply (simp add: Vfrom_0) (*succ(j) case*) apply (erule ssubst) apply (rule Transset_0 [THEN QPair_Int_Vfrom_succ_subset, THEN subset_trans]) apply (rule succI1 [THEN UN_upper]) (*Limit(i) case*) apply (simp del: UN_simps add: Limit_Vfrom_eq Int_UN_distrib UN_mono QPair_Int_Vset_subset_trans) done end diff --git a/src/ZF/Resid/Confluence.thy b/src/ZF/Resid/Confluence.thy --- a/src/ZF/Resid/Confluence.thy +++ b/src/ZF/Resid/Confluence.thy @@ -1,118 +1,118 @@ (* Title: ZF/Resid/Confluence.thy Author: Ole Rasmussen Copyright 1995 University of Cambridge *) theory Confluence imports Reduction begin definition confluence :: "i\o" where "confluence(R) \ \x y. \x,y\ \ R \ (\z.\x,z\ \ R \ (\u.\y,u\ \ R \ \z,u\ \ R))" definition strip :: "o" where "strip \ \x y. (x =\ y) \ (\z.(x =1\ z) \ (\u.(y =1\ u) \ (z=\u)))" (* ------------------------------------------------------------------------- *) (* strip lemmas *) (* ------------------------------------------------------------------------- *) lemma strip_lemma_r: "\confluence(Spar_red1)\\ strip" apply (unfold confluence_def strip_def) apply (rule impI [THEN allI, THEN allI]) apply (erule Spar_red.induct, fast) apply (fast intro: Spar_red.trans) done lemma strip_lemma_l: "strip\ confluence(Spar_red)" apply (unfold confluence_def strip_def) apply (rule impI [THEN allI, THEN allI]) apply (erule Spar_red.induct, blast) apply clarify apply (blast intro: Spar_red.trans) done (* ------------------------------------------------------------------------- *) (* Confluence *) (* ------------------------------------------------------------------------- *) lemma parallel_moves: "confluence(Spar_red1)" apply (unfold confluence_def, clarify) apply (frule simulation) apply (frule_tac n = z in simulation, clarify) apply (frule_tac v = va in paving) apply (force intro: completeness)+ done lemmas confluence_parallel_reduction = parallel_moves [THEN strip_lemma_r, THEN strip_lemma_l] lemma lemma1: "\confluence(Spar_red)\\ confluence(Sred)" by (unfold confluence_def, blast intro: par_red_red red_par_red) lemmas confluence_beta_reduction = confluence_parallel_reduction [THEN lemma1] (**** Conversion ****) consts Sconv1 :: "i" Sconv :: "i" abbreviation Sconv1_rel (infixl \<-1->\ 50) where "a<-1->b \ \a,b\ \ Sconv1" abbreviation Sconv_rel (infixl \<-\\ 50) where "a<-\b \ \a,b\ \ Sconv" inductive domains "Sconv1" \ "lambda*lambda" intros red1: "m -1-> n \ m<-1->n" expl: "n -1-> m \ m<-1->n" type_intros red1D1 red1D2 lambda.intros bool_typechecks declare Sconv1.intros [intro] inductive domains "Sconv" \ "lambda*lambda" intros one_step: "m<-1->n \ m<-\n" refl: "m \ lambda \ m<-\m" trans: "\m<-\n; n<-\p\ \ m<-\p" type_intros Sconv1.dom_subset [THEN subsetD] lambda.intros bool_typechecks declare Sconv.intros [intro] lemma conv_sym: "m<-\n \ n<-\m" apply (erule Sconv.induct) apply (erule Sconv1.induct, blast+) done (* ------------------------------------------------------------------------- *) (* Church_Rosser Theorem *) (* ------------------------------------------------------------------------- *) lemma Church_Rosser: "m<-\n \ \p.(m -\p) \ (n -\ p)" apply (erule Sconv.induct) apply (erule Sconv1.induct) apply (blast intro: red1D1 redD2) apply (blast intro: red1D1 redD2) apply (blast intro: red1D1 redD2) apply (cut_tac confluence_beta_reduction) -apply (unfold confluence_def) + unfolding confluence_def apply (blast intro: Sred.trans) done end diff --git a/src/ZF/Resid/Residuals.thy b/src/ZF/Resid/Residuals.thy --- a/src/ZF/Resid/Residuals.thy +++ b/src/ZF/Resid/Residuals.thy @@ -1,213 +1,213 @@ (* Title: ZF/Resid/Residuals.thy Author: Ole Rasmussen Copyright 1995 University of Cambridge *) theory Residuals imports Substitution begin consts Sres :: "i" abbreviation "residuals(u,v,w) \ \ Sres" inductive domains "Sres" \ "redexes*redexes*redexes" intros Res_Var: "n \ nat \ residuals(Var(n),Var(n),Var(n))" Res_Fun: "\residuals(u,v,w)\\ residuals(Fun(u),Fun(v),Fun(w))" Res_App: "\residuals(u1,v1,w1); residuals(u2,v2,w2); b \ bool\\ residuals(App(b,u1,u2),App(0,v1,v2),App(b,w1,w2))" Res_redex: "\residuals(u1,v1,w1); residuals(u2,v2,w2); b \ bool\\ residuals(App(b,Fun(u1),u2),App(1,Fun(v1),v2),w2/w1)" type_intros subst_type nat_typechecks redexes.intros bool_typechecks definition res_func :: "[i,i]\i" (infixl \|>\ 70) where "u |> v \ THE w. residuals(u,v,w)" subsection\Setting up rule lists\ declare Sres.intros [intro] declare Sreg.intros [intro] declare subst_type [intro] inductive_cases [elim!]: "residuals(Var(n),Var(n),v)" "residuals(Fun(t),Fun(u),v)" "residuals(App(b, u1, u2), App(0, v1, v2),v)" "residuals(App(b, u1, u2), App(1, Fun(v1), v2),v)" "residuals(Var(n),u,v)" "residuals(Fun(t),u,v)" "residuals(App(b, u1, u2), w,v)" "residuals(u,Var(n),v)" "residuals(u,Fun(t),v)" "residuals(w,App(b, u1, u2),v)" inductive_cases [elim!]: "Var(n) \ u" "Fun(n) \ u" "u \ Fun(n)" "App(1,Fun(t),a) \ u" "App(0,t,a) \ u" inductive_cases [elim!]: "Fun(t) \ redexes" declare Sres.intros [simp] subsection\residuals is a partial function\ lemma residuals_function [rule_format]: "residuals(u,v,w) \ \w1. residuals(u,v,w1) \ w1 = w" by (erule Sres.induct, force+) lemma residuals_intro [rule_format]: "u \ v \ regular(v) \ (\w. residuals(u,v,w))" by (erule Scomp.induct, force+) lemma comp_resfuncD: "\u \ v; regular(v)\ \ residuals(u, v, THE w. residuals(u, v, w))" apply (frule residuals_intro, assumption, clarify) apply (subst the_equality) apply (blast intro: residuals_function)+ done subsection\Residual function\ lemma res_Var [simp]: "n \ nat \ Var(n) |> Var(n) = Var(n)" by (unfold res_func_def, blast) lemma res_Fun [simp]: "\s \ t; regular(t)\\ Fun(s) |> Fun(t) = Fun(s |> t)" -apply (unfold res_func_def) + unfolding res_func_def apply (blast intro: comp_resfuncD residuals_function) done lemma res_App [simp]: "\s \ u; regular(u); t \ v; regular(v); b \ bool\ \ App(b,s,t) |> App(0,u,v) = App(b, s |> u, t |> v)" -apply (unfold res_func_def) + unfolding res_func_def apply (blast dest!: comp_resfuncD intro: residuals_function) done lemma res_redex [simp]: "\s \ u; regular(u); t \ v; regular(v); b \ bool\ \ App(b,Fun(s),t) |> App(1,Fun(u),v) = (t |> v)/ (s |> u)" -apply (unfold res_func_def) + unfolding res_func_def apply (blast elim!: redexes.free_elims dest!: comp_resfuncD intro: residuals_function) done lemma resfunc_type [simp]: "\s \ t; regular(t)\\ regular(t) \ s |> t \ redexes" by (erule Scomp.induct, auto) subsection\Commutation theorem\ lemma sub_comp [simp]: "u \ v \ u \ v" by (erule Ssub.induct, simp_all) lemma sub_preserve_reg [rule_format, simp]: "u \ v \ regular(v) \ regular(u)" by (erule Ssub.induct, auto) lemma residuals_lift_rec: "\u \ v; k \ nat\\ regular(v)\ (\n \ nat. lift_rec(u,n) |> lift_rec(v,n) = lift_rec(u |> v,n))" apply (erule Scomp.induct, safe) apply (simp_all add: lift_rec_Var subst_Var lift_subst) done lemma residuals_subst_rec: "u1 \ u2 \ \v1 v2. v1 \ v2 \ regular(v2) \ regular(u2) \ (\n \ nat. subst_rec(v1,u1,n) |> subst_rec(v2,u2,n) = subst_rec(v1 |> v2, u1 |> u2,n))" apply (erule Scomp.induct, safe) apply (simp_all add: lift_rec_Var subst_Var residuals_lift_rec) apply (drule_tac psi = "\x. P(x)" for P in asm_rl) apply (simp add: substitution) done lemma commutation [simp]: "\u1 \ u2; v1 \ v2; regular(u2); regular(v2)\ \ (v1/u1) |> (v2/u2) = (v1 |> v2)/(u1 |> u2)" by (simp add: residuals_subst_rec) subsection\Residuals are comp and regular\ lemma residuals_preserve_comp [rule_format, simp]: "u \ v \ \w. u \ w \ v \ w \ regular(w) \ (u|>w) \ (v|>w)" by (erule Scomp.induct, force+) lemma residuals_preserve_reg [rule_format, simp]: "u \ v \ regular(u) \ regular(v) \ regular(u|>v)" apply (erule Scomp.induct, auto) done subsection\Preservation lemma\ lemma union_preserve_comp: "u \ v \ v \ (u \ v)" by (erule Scomp.induct, simp_all) lemma preservation [rule_format]: "u \ v \ regular(v) \ u|>v = (u \ v)|>v" apply (erule Scomp.induct, safe) apply (drule_tac [3] psi = "Fun (u) |> v = w" for u v w in asm_rl) apply (auto simp add: union_preserve_comp comp_sym_iff) done declare sub_comp [THEN comp_sym, simp] subsection\Prism theorem\ (* Having more assumptions than needed -- removed below *) lemma prism_l [rule_format]: "v \ u \ regular(u) \ (\w. w \ v \ w \ u \ w |> u = (w|>v) |> (u|>v))" by (erule Ssub.induct, force+) lemma prism: "\v \ u; regular(u); w \ v\ \ w |> u = (w|>v) |> (u|>v)" apply (rule prism_l) apply (rule_tac [4] comp_trans, auto) done subsection\Levy's Cube Lemma\ lemma cube: "\u \ v; regular(v); regular(u); w \ u\\ (w|>u) |> (v|>u) = (w|>v) |> (u|>v)" apply (subst preservation [of u], assumption, assumption) apply (subst preservation [of v], erule comp_sym, assumption) apply (subst prism [symmetric, of v]) apply (simp add: union_r comp_sym_iff) apply (simp add: union_preserve_regular comp_sym_iff) apply (erule comp_trans, assumption) apply (simp add: prism [symmetric] union_l union_preserve_regular comp_sym_iff union_sym) done subsection\paving theorem\ lemma paving: "\w \ u; w \ v; regular(u); regular(v)\\ \uv vu. (w|>u) |> vu = (w|>v) |> uv \ (w|>u) \ vu \ regular(vu) \ (w|>v) \ uv \ regular(uv)" apply (subgoal_tac "u \ v") apply (safe intro!: exI) apply (rule cube) apply (simp_all add: comp_sym_iff) apply (blast intro: residuals_preserve_comp comp_trans comp_sym)+ done end diff --git a/src/ZF/Sum.thy b/src/ZF/Sum.thy --- a/src/ZF/Sum.thy +++ b/src/ZF/Sum.thy @@ -1,191 +1,191 @@ (* Title: ZF/Sum.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1993 University of Cambridge *) section\Disjoint Sums\ theory Sum imports Bool equalities begin text\And the "Part" primitive for simultaneous recursive type definitions\ definition sum :: "[i,i]\i" (infixr \+\ 65) where "A+B \ {0}*A \ {1}*B" definition Inl :: "i\i" where "Inl(a) \ \0,a\" definition Inr :: "i\i" where "Inr(b) \ \1,b\" definition "case" :: "[i\i, i\i, i]\i" where "case(c,d) \ (\\y,z\. cond(y, d(z), c(z)))" (*operator for selecting out the various summands*) definition Part :: "[i,i\i] \ i" where "Part(A,h) \ {x \ A. \z. x = h(z)}" subsection\Rules for the \<^term>\Part\ Primitive\ lemma Part_iff: "a \ Part(A,h) \ a \ A \ (\y. a=h(y))" -apply (unfold Part_def) + unfolding Part_def apply (rule separation) done lemma Part_eqI [intro]: "\a \ A; a=h(b)\ \ a \ Part(A,h)" by (unfold Part_def, blast) lemmas PartI = refl [THEN [2] Part_eqI] lemma PartE [elim!]: "\a \ Part(A,h); \z. \a \ A; a=h(z)\ \ P \ \ P" apply (unfold Part_def, blast) done lemma Part_subset: "Part(A,h) \ A" -apply (unfold Part_def) + unfolding Part_def apply (rule Collect_subset) done subsection\Rules for Disjoint Sums\ lemmas sum_defs = sum_def Inl_def Inr_def case_def lemma Sigma_bool: "Sigma(bool,C) = C(0) + C(1)" by (unfold bool_def sum_def, blast) (** Introduction rules for the injections **) lemma InlI [intro!,simp,TC]: "a \ A \ Inl(a) \ A+B" by (unfold sum_defs, blast) lemma InrI [intro!,simp,TC]: "b \ B \ Inr(b) \ A+B" by (unfold sum_defs, blast) (** Elimination rules **) lemma sumE [elim!]: "\u \ A+B; \x. \x \ A; u=Inl(x)\ \ P; \y. \y \ B; u=Inr(y)\ \ P \ \ P" by (unfold sum_defs, blast) (** Injection and freeness equivalences, for rewriting **) lemma Inl_iff [iff]: "Inl(a)=Inl(b) \ a=b" by (simp add: sum_defs) lemma Inr_iff [iff]: "Inr(a)=Inr(b) \ a=b" by (simp add: sum_defs) lemma Inl_Inr_iff [simp]: "Inl(a)=Inr(b) \ False" by (simp add: sum_defs) lemma Inr_Inl_iff [simp]: "Inr(b)=Inl(a) \ False" by (simp add: sum_defs) lemma sum_empty [simp]: "0+0 = 0" by (simp add: sum_defs) (*Injection and freeness rules*) lemmas Inl_inject = Inl_iff [THEN iffD1] lemmas Inr_inject = Inr_iff [THEN iffD1] lemmas Inl_neq_Inr = Inl_Inr_iff [THEN iffD1, THEN FalseE, elim!] lemmas Inr_neq_Inl = Inr_Inl_iff [THEN iffD1, THEN FalseE, elim!] lemma InlD: "Inl(a): A+B \ a \ A" by blast lemma InrD: "Inr(b): A+B \ b \ B" by blast lemma sum_iff: "u \ A+B \ (\x. x \ A \ u=Inl(x)) | (\y. y \ B \ u=Inr(y))" by blast lemma Inl_in_sum_iff [simp]: "(Inl(x) \ A+B) \ (x \ A)" by auto lemma Inr_in_sum_iff [simp]: "(Inr(y) \ A+B) \ (y \ B)" by auto lemma sum_subset_iff: "A+B \ C+D \ A<=C \ B<=D" by blast lemma sum_equal_iff: "A+B = C+D \ A=C \ B=D" by (simp add: extension sum_subset_iff, blast) lemma sum_eq_2_times: "A+A = 2*A" by (simp add: sum_def, blast) subsection\The Eliminator: \<^term>\case\\ lemma case_Inl [simp]: "case(c, d, Inl(a)) = c(a)" by (simp add: sum_defs) lemma case_Inr [simp]: "case(c, d, Inr(b)) = d(b)" by (simp add: sum_defs) lemma case_type [TC]: "\u \ A+B; \x. x \ A \ c(x): C(Inl(x)); \y. y \ B \ d(y): C(Inr(y)) \ \ case(c,d,u) \ C(u)" by auto lemma expand_case: "u \ A+B \ R(case(c,d,u)) \ ((\x\A. u = Inl(x) \ R(c(x))) \ (\y\B. u = Inr(y) \ R(d(y))))" by auto lemma case_cong: "\z \ A+B; \x. x \ A \ c(x)=c'(x); \y. y \ B \ d(y)=d'(y) \ \ case(c,d,z) = case(c',d',z)" by auto lemma case_case: "z \ A+B \ case(c, d, case(\x. Inl(c'(x)), \y. Inr(d'(y)), z)) = case(\x. c(c'(x)), \y. d(d'(y)), z)" by auto subsection\More Rules for \<^term>\Part(A,h)\\ lemma Part_mono: "A<=B \ Part(A,h)<=Part(B,h)" by blast lemma Part_Collect: "Part(Collect(A,P), h) = Collect(Part(A,h), P)" by blast lemmas Part_CollectE = Part_Collect [THEN equalityD1, THEN subsetD, THEN CollectE] lemma Part_Inl: "Part(A+B,Inl) = {Inl(x). x \ A}" by blast lemma Part_Inr: "Part(A+B,Inr) = {Inr(y). y \ B}" by blast lemma PartD1: "a \ Part(A,h) \ a \ A" by (simp add: Part_def) lemma Part_id: "Part(A,\x. x) = A" by blast lemma Part_Inr2: "Part(A+B, \x. Inr(h(x))) = {Inr(y). y \ Part(B,h)}" by blast lemma Part_sum_equality: "C \ A+B \ Part(C,Inl) \ Part(C,Inr) = C" by blast end diff --git a/src/ZF/Trancl.thy b/src/ZF/Trancl.thy --- a/src/ZF/Trancl.thy +++ b/src/ZF/Trancl.thy @@ -1,374 +1,374 @@ (* Title: ZF/Trancl.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1992 University of Cambridge *) section\Relations: Their General Properties and Transitive Closure\ theory Trancl imports Fixedpt Perm begin definition refl :: "[i,i]\o" where "refl(A,r) \ (\x\A. \x,x\ \ r)" definition irrefl :: "[i,i]\o" where "irrefl(A,r) \ \x\A. \x,x\ \ r" definition sym :: "i\o" where "sym(r) \ \x y. \x,y\: r \ \y,x\: r" definition asym :: "i\o" where "asym(r) \ \x y. \x,y\:r \ \ \y,x\:r" definition antisym :: "i\o" where "antisym(r) \ \x y.\x,y\:r \ \y,x\:r \ x=y" definition trans :: "i\o" where "trans(r) \ \x y z. \x,y\: r \ \y,z\: r \ \x,z\: r" definition trans_on :: "[i,i]\o" (\trans[_]'(_')\) where "trans[A](r) \ \x\A. \y\A. \z\A. \x,y\: r \ \y,z\: r \ \x,z\: r" definition rtrancl :: "i\i" (\(_^*)\ [100] 100) (*refl/transitive closure*) where "r^* \ lfp(field(r)*field(r), \s. id(field(r)) \ (r O s))" definition trancl :: "i\i" (\(_^+)\ [100] 100) (*transitive closure*) where "r^+ \ r O r^*" definition equiv :: "[i,i]\o" where "equiv(A,r) \ r \ A*A \ refl(A,r) \ sym(r) \ trans(r)" subsection\General properties of relations\ subsubsection\irreflexivity\ lemma irreflI: "\\x. x \ A \ \x,x\ \ r\ \ irrefl(A,r)" by (simp add: irrefl_def) lemma irreflE: "\irrefl(A,r); x \ A\ \ \x,x\ \ r" by (simp add: irrefl_def) subsubsection\symmetry\ lemma symI: "\\x y.\x,y\: r \ \y,x\: r\ \ sym(r)" by (unfold sym_def, blast) lemma symE: "\sym(r); \x,y\: r\ \ \y,x\: r" by (unfold sym_def, blast) subsubsection\antisymmetry\ lemma antisymI: "\\x y.\\x,y\: r; \y,x\: r\ \ x=y\ \ antisym(r)" by (simp add: antisym_def, blast) lemma antisymE: "\antisym(r); \x,y\: r; \y,x\: r\ \ x=y" by (simp add: antisym_def, blast) subsubsection\transitivity\ lemma transD: "\trans(r); \a,b\:r; \b,c\:r\ \ \a,c\:r" by (unfold trans_def, blast) lemma trans_onD: "\trans[A](r); \a,b\:r; \b,c\:r; a \ A; b \ A; c \ A\ \ \a,c\:r" by (unfold trans_on_def, blast) lemma trans_imp_trans_on: "trans(r) \ trans[A](r)" by (unfold trans_def trans_on_def, blast) lemma trans_on_imp_trans: "\trans[A](r); r \ A*A\ \ trans(r)" by (simp add: trans_on_def trans_def, blast) subsection\Transitive closure of a relation\ lemma rtrancl_bnd_mono: "bnd_mono(field(r)*field(r), \s. id(field(r)) \ (r O s))" by (rule bnd_monoI, blast+) lemma rtrancl_mono: "r<=s \ r^* \ s^*" -apply (unfold rtrancl_def) + unfolding rtrancl_def apply (rule lfp_mono) apply (rule rtrancl_bnd_mono)+ apply blast done (* @{term"r^* = id(field(r)) \ ( r O r^* )"} *) lemmas rtrancl_unfold = rtrancl_bnd_mono [THEN rtrancl_def [THEN def_lfp_unfold]] (** The relation rtrancl **) (* @{term"r^* \ field(r) * field(r)"} *) lemmas rtrancl_type = rtrancl_def [THEN def_lfp_subset] lemma relation_rtrancl: "relation(r^*)" apply (simp add: relation_def) apply (blast dest: rtrancl_type [THEN subsetD]) done (*Reflexivity of rtrancl*) lemma rtrancl_refl: "\a \ field(r)\ \ \a,a\ \ r^*" apply (rule rtrancl_unfold [THEN ssubst]) apply (erule idI [THEN UnI1]) done (*Closure under composition with r *) lemma rtrancl_into_rtrancl: "\\a,b\ \ r^*; \b,c\ \ r\ \ \a,c\ \ r^*" apply (rule rtrancl_unfold [THEN ssubst]) apply (rule compI [THEN UnI2], assumption, assumption) done (*rtrancl of r contains all pairs in r *) lemma r_into_rtrancl: "\a,b\ \ r \ \a,b\ \ r^*" by (rule rtrancl_refl [THEN rtrancl_into_rtrancl], blast+) (*The premise ensures that r consists entirely of pairs*) lemma r_subset_rtrancl: "relation(r) \ r \ r^*" by (simp add: relation_def, blast intro: r_into_rtrancl) lemma rtrancl_field: "field(r^*) = field(r)" by (blast intro: r_into_rtrancl dest!: rtrancl_type [THEN subsetD]) (** standard induction rule **) lemma rtrancl_full_induct [case_names initial step, consumes 1]: "\\a,b\ \ r^*; \x. x \ field(r) \ P(\x,x\); \x y z.\P(\x,y\); \x,y\: r^*; \y,z\: r\ \ P(\x,z\)\ \ P(\a,b\)" by (erule def_induct [OF rtrancl_def rtrancl_bnd_mono], blast) (*nice induction rule. Tried adding the typing hypotheses y,z \ field(r), but these caused expensive case splits!*) lemma rtrancl_induct [case_names initial step, induct set: rtrancl]: "\\a,b\ \ r^*; P(a); \y z.\\a,y\ \ r^*; \y,z\ \ r; P(y)\ \ P(z) \ \ P(b)" (*by induction on this formula*) apply (subgoal_tac "\y. \a,b\ = \a,y\ \ P (y) ") (*now solve first subgoal: this formula is sufficient*) apply (erule spec [THEN mp], rule refl) (*now do the induction*) apply (erule rtrancl_full_induct, blast+) done (*transitivity of transitive closure\-- by induction.*) lemma trans_rtrancl: "trans(r^*)" -apply (unfold trans_def) + unfolding trans_def apply (intro allI impI) apply (erule_tac b = z in rtrancl_induct, assumption) apply (blast intro: rtrancl_into_rtrancl) done lemmas rtrancl_trans = trans_rtrancl [THEN transD] (*elimination of rtrancl -- by induction on a special formula*) lemma rtranclE: "\\a,b\ \ r^*; (a=b) \ P; \y.\\a,y\ \ r^*; \y,b\ \ r\ \ P\ \ P" apply (subgoal_tac "a = b | (\y. \a,y\ \ r^* \ \y,b\ \ r) ") (*see HOL/trancl*) apply blast apply (erule rtrancl_induct, blast+) done (**** The relation trancl ****) (*Transitivity of r^+ is proved by transitivity of r^* *) lemma trans_trancl: "trans(r^+)" apply (unfold trans_def trancl_def) apply (blast intro: rtrancl_into_rtrancl trans_rtrancl [THEN transD, THEN compI]) done lemmas trans_on_trancl = trans_trancl [THEN trans_imp_trans_on] lemmas trancl_trans = trans_trancl [THEN transD] (** Conversions between trancl and rtrancl **) lemma trancl_into_rtrancl: "\a,b\ \ r^+ \ \a,b\ \ r^*" -apply (unfold trancl_def) + unfolding trancl_def apply (blast intro: rtrancl_into_rtrancl) done (*r^+ contains all pairs in r *) lemma r_into_trancl: "\a,b\ \ r \ \a,b\ \ r^+" -apply (unfold trancl_def) + unfolding trancl_def apply (blast intro!: rtrancl_refl) done (*The premise ensures that r consists entirely of pairs*) lemma r_subset_trancl: "relation(r) \ r \ r^+" by (simp add: relation_def, blast intro: r_into_trancl) (*intro rule by definition: from r^* and r *) lemma rtrancl_into_trancl1: "\\a,b\ \ r^*; \b,c\ \ r\ \ \a,c\ \ r^+" by (unfold trancl_def, blast) (*intro rule from r and r^* *) lemma rtrancl_into_trancl2: "\\a,b\ \ r; \b,c\ \ r^*\ \ \a,c\ \ r^+" apply (erule rtrancl_induct) apply (erule r_into_trancl) apply (blast intro: r_into_trancl trancl_trans) done (*Nice induction rule for trancl*) lemma trancl_induct [case_names initial step, induct set: trancl]: "\\a,b\ \ r^+; \y. \\a,y\ \ r\ \ P(y); \y z.\\a,y\ \ r^+; \y,z\ \ r; P(y)\ \ P(z) \ \ P(b)" apply (rule compEpair) apply (unfold trancl_def, assumption) (*by induction on this formula*) apply (subgoal_tac "\z. \y,z\ \ r \ P (z) ") (*now solve first subgoal: this formula is sufficient*) apply blast apply (erule rtrancl_induct) apply (blast intro: rtrancl_into_trancl1)+ done (*elimination of r^+ -- NOT an induction rule*) lemma tranclE: "\\a,b\ \ r^+; \a,b\ \ r \ P; \y.\\a,y\ \ r^+; \y,b\ \ r\ \ P \ \ P" apply (subgoal_tac "\a,b\ \ r | (\y. \a,y\ \ r^+ \ \y,b\ \ r) ") apply blast apply (rule compEpair) apply (unfold trancl_def, assumption) apply (erule rtranclE) apply (blast intro: rtrancl_into_trancl1)+ done lemma trancl_type: "r^+ \ field(r)*field(r)" -apply (unfold trancl_def) + unfolding trancl_def apply (blast elim: rtrancl_type [THEN subsetD, THEN SigmaE2]) done lemma relation_trancl: "relation(r^+)" apply (simp add: relation_def) apply (blast dest: trancl_type [THEN subsetD]) done lemma trancl_subset_times: "r \ A * A \ r^+ \ A * A" by (insert trancl_type [of r], blast) lemma trancl_mono: "r<=s \ r^+ \ s^+" by (unfold trancl_def, intro comp_mono rtrancl_mono) lemma trancl_eq_r: "\relation(r); trans(r)\ \ r^+ = r" apply (rule equalityI) prefer 2 apply (erule r_subset_trancl, clarify) apply (frule trancl_type [THEN subsetD], clarify) apply (erule trancl_induct, assumption) apply (blast dest: transD) done (** Suggested by Sidi Ould Ehmety **) lemma rtrancl_idemp [simp]: "(r^*)^* = r^*" apply (rule equalityI, auto) prefer 2 apply (frule rtrancl_type [THEN subsetD]) apply (blast intro: r_into_rtrancl ) txt\converse direction\ apply (frule rtrancl_type [THEN subsetD], clarify) apply (erule rtrancl_induct) apply (simp add: rtrancl_refl rtrancl_field) apply (blast intro: rtrancl_trans) done lemma rtrancl_subset: "\R \ S; S \ R^*\ \ S^* = R^*" apply (drule rtrancl_mono) apply (drule rtrancl_mono, simp_all, blast) done lemma rtrancl_Un_rtrancl: "\relation(r); relation(s)\ \ (r^* \ s^*)^* = (r \ s)^*" apply (rule rtrancl_subset) apply (blast dest: r_subset_rtrancl) apply (blast intro: rtrancl_mono [THEN subsetD]) done (*** "converse" laws by Sidi Ould Ehmety ***) (** rtrancl **) lemma rtrancl_converseD: "\x,y\:converse(r)^* \ \x,y\:converse(r^*)" apply (rule converseI) apply (frule rtrancl_type [THEN subsetD]) apply (erule rtrancl_induct) apply (blast intro: rtrancl_refl) apply (blast intro: r_into_rtrancl rtrancl_trans) done lemma rtrancl_converseI: "\x,y\:converse(r^*) \ \x,y\:converse(r)^*" apply (drule converseD) apply (frule rtrancl_type [THEN subsetD]) apply (erule rtrancl_induct) apply (blast intro: rtrancl_refl) apply (blast intro: r_into_rtrancl rtrancl_trans) done lemma rtrancl_converse: "converse(r)^* = converse(r^*)" apply (safe intro!: equalityI) apply (frule rtrancl_type [THEN subsetD]) apply (safe dest!: rtrancl_converseD intro!: rtrancl_converseI) done (** trancl **) lemma trancl_converseD: "\a, b\:converse(r)^+ \ \a, b\:converse(r^+)" apply (erule trancl_induct) apply (auto intro: r_into_trancl trancl_trans) done lemma trancl_converseI: "\x,y\:converse(r^+) \ \x,y\:converse(r)^+" apply (drule converseD) apply (erule trancl_induct) apply (auto intro: r_into_trancl trancl_trans) done lemma trancl_converse: "converse(r)^+ = converse(r^+)" apply (safe intro!: equalityI) apply (frule trancl_type [THEN subsetD]) apply (safe dest!: trancl_converseD intro!: trancl_converseI) done lemma converse_trancl_induct [case_names initial step, consumes 1]: "\\a, b\:r^+; \y. \y, b\ :r \ P(y); \y z. \\y, z\ \ r; \z, b\ \ r^+; P(z)\ \ P(y)\ \ P(a)" apply (drule converseI) apply (simp (no_asm_use) add: trancl_converse [symmetric]) apply (erule trancl_induct) apply (auto simp add: trancl_converse) done end diff --git a/src/ZF/UNITY/AllocBase.thy b/src/ZF/UNITY/AllocBase.thy --- a/src/ZF/UNITY/AllocBase.thy +++ b/src/ZF/UNITY/AllocBase.thy @@ -1,398 +1,398 @@ (* Title: ZF/UNITY/AllocBase.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2001 University of Cambridge *) section\Common declarations for Chandy and Charpentier's Allocator\ theory AllocBase imports Follows MultisetSum Guar begin abbreviation (input) tokbag :: i (* tokbags could be multisets...or any ordered type?*) where "tokbag \ nat" axiomatization NbT :: i and (* Number of tokens in system *) Nclients :: i (* Number of clients *) where NbT_pos: "NbT \ nat-{0}" and Nclients_pos: "Nclients \ nat-{0}" text\This function merely sums the elements of a list\ consts tokens :: "i \i" item :: i (* Items to be merged/distributed *) primrec "tokens(Nil) = 0" "tokens (Cons(x,xs)) = x #+ tokens(xs)" consts bag_of :: "i \ i" primrec "bag_of(Nil) = 0" "bag_of(Cons(x,xs)) = {#x#} +# bag_of(xs)" text\Definitions needed in Client.thy. We define a recursive predicate using 0 and 1 to code the truth values.\ consts all_distinct0 :: "i\i" primrec "all_distinct0(Nil) = 1" "all_distinct0(Cons(a, l)) = (if a \ set_of_list(l) then 0 else all_distinct0(l))" definition all_distinct :: "i\o" where "all_distinct(l) \ all_distinct0(l)=1" definition state_of :: "i \i" \ \coersion from anyting to state\ where "state_of(s) \ if s \ state then s else st0" definition lift :: "i \(i\i)" \ \simplifies the expression of programs\ where "lift(x) \ \s. s`x" text\function to show that the set of variables is infinite\ consts nat_list_inj :: "i\i" var_inj :: "i\i" primrec "nat_list_inj(0) = Nil" "nat_list_inj(succ(n)) = Cons(n, nat_list_inj(n))" primrec "var_inj(Var(l)) = length(l)" definition nat_var_inj :: "i\i" where "nat_var_inj(n) \ Var(nat_list_inj(n))" subsection\Various simple lemmas\ lemma Nclients_NbT_gt_0 [simp]: "0 < Nclients \ 0 < NbT" apply (cut_tac Nclients_pos NbT_pos) apply (auto intro: Ord_0_lt) done lemma Nclients_NbT_not_0 [simp]: "Nclients \ 0 \ NbT \ 0" by (cut_tac Nclients_pos NbT_pos, auto) lemma Nclients_type [simp,TC]: "Nclients\nat" by (cut_tac Nclients_pos NbT_pos, auto) lemma NbT_type [simp,TC]: "NbT\nat" by (cut_tac Nclients_pos NbT_pos, auto) lemma INT_Nclient_iff [iff]: "b\\(RepFun(Nclients, B)) \ (\x\Nclients. b\B(x))" by (force simp add: INT_iff) lemma setsum_fun_mono [rule_format]: "n\nat \ (\i\nat. i f(i) $\ g(i)) \ setsum(f, n) $\ setsum(g,n)" apply (induct_tac "n", simp_all) apply (subgoal_tac "Finite(x) \ x\x") prefer 2 apply (simp add: nat_into_Finite mem_not_refl, clarify) apply (simp (no_asm_simp) add: succ_def) apply (subgoal_tac "\i\nat. i f(i) $\ g(i) ") prefer 2 apply (force dest: leI) apply (rule zadd_zle_mono, simp_all) done lemma tokens_type [simp,TC]: "l\list(A) \ tokens(l)\nat" by (erule list.induct, auto) lemma tokens_mono_aux [rule_format]: "xs\list(A) \ \ys\list(A). \xs, ys\\prefix(A) \ tokens(xs) \ tokens(ys)" apply (induct_tac "xs") apply (auto dest: gen_prefix.dom_subset [THEN subsetD] simp add: prefix_def) done lemma tokens_mono: "\xs, ys\\prefix(A) \ tokens(xs) \ tokens(ys)" apply (cut_tac prefix_type) apply (blast intro: tokens_mono_aux) done lemma mono_tokens [iff]: "mono1(list(A), prefix(A), nat, Le,tokens)" -apply (unfold mono1_def) + unfolding mono1_def apply (auto intro: tokens_mono simp add: Le_def) done lemma tokens_append [simp]: "\xs\list(A); ys\list(A)\ \ tokens(xs@ys) = tokens(xs) #+ tokens(ys)" apply (induct_tac "xs", auto) done subsection\The function \<^term>\bag_of\\ lemma bag_of_type [simp,TC]: "l\list(A) \bag_of(l)\Mult(A)" apply (induct_tac "l") apply (auto simp add: Mult_iff_multiset) done lemma bag_of_multiset: "l\list(A) \ multiset(bag_of(l)) \ mset_of(bag_of(l))<=A" apply (drule bag_of_type) apply (auto simp add: Mult_iff_multiset) done lemma bag_of_append [simp]: "\xs\list(A); ys\list(A)\ \ bag_of(xs@ys) = bag_of(xs) +# bag_of(ys)" apply (induct_tac "xs") apply (auto simp add: bag_of_multiset munion_assoc) done lemma bag_of_mono_aux [rule_format]: "xs\list(A) \ \ys\list(A). \xs, ys\\prefix(A) \ \MultLe(A, r)" apply (induct_tac "xs", simp_all, clarify) apply (frule_tac l = ys in bag_of_multiset) apply (auto intro: empty_le_MultLe simp add: prefix_def) apply (rule munion_mono) apply (force simp add: MultLe_def Mult_iff_multiset) apply (blast dest: gen_prefix.dom_subset [THEN subsetD]) done lemma bag_of_mono [intro]: "\\xs, ys\\prefix(A); xs\list(A); ys\list(A)\ \ \MultLe(A, r)" apply (blast intro: bag_of_mono_aux) done lemma mono_bag_of [simp]: "mono1(list(A), prefix(A), Mult(A), MultLe(A,r), bag_of)" by (auto simp add: mono1_def bag_of_type) subsection\The function \<^term>\msetsum\\ lemmas nat_into_Fin = eqpoll_refl [THEN [2] Fin_lemma] lemma list_Int_length_Fin: "l \ list(A) \ C \ length(l) \ Fin(length(l))" apply (drule length_type) apply (rule Fin_subset) apply (rule Int_lower2) apply (erule nat_into_Fin) done lemma mem_Int_imp_lt_length: "\xs \ list(A); k \ C \ length(xs)\ \ k < length(xs)" by (simp add: ltI) lemma Int_succ_right: "A \ succ(k) = (if k \ A then cons(k, A \ k) else A \ k)" by auto lemma bag_of_sublist_lemma: "\C \ nat; x \ A; xs \ list(A)\ \ msetsum(\i. {#nth(i, xs @ [x])#}, C \ succ(length(xs)), A) = (if length(xs) \ C then {#x#} +# msetsum(\x. {#nth(x, xs)#}, C \ length(xs), A) else msetsum(\x. {#nth(x, xs)#}, C \ length(xs), A))" apply (simp add: subsetD nth_append lt_not_refl mem_Int_imp_lt_length cong add: msetsum_cong) apply (simp add: Int_succ_right) apply (simp add: lt_not_refl mem_Int_imp_lt_length cong add: msetsum_cong, clarify) apply (subst msetsum_cons) apply (rule_tac [3] succI1) apply (blast intro: list_Int_length_Fin subset_succI [THEN Fin_mono, THEN subsetD]) apply (simp add: mem_not_refl) apply (simp add: nth_type lt_not_refl) apply (blast intro: nat_into_Ord ltI length_type) apply (simp add: lt_not_refl mem_Int_imp_lt_length cong add: msetsum_cong) done lemma bag_of_sublist_lemma2: "l\list(A) \ C \ nat \ bag_of(sublist(l, C)) = msetsum(\i. {#nth(i, l)#}, C \ length(l), A)" apply (erule list_append_induct) apply (simp (no_asm)) apply (simp (no_asm_simp) add: sublist_append nth_append bag_of_sublist_lemma munion_commute bag_of_sublist_lemma msetsum_multiset munion_0) done lemma nat_Int_length_eq: "l \ list(A) \ nat \ length(l) = length(l)" apply (rule Int_absorb1) apply (rule OrdmemD, auto) done (*eliminating the assumption C<=nat*) lemma bag_of_sublist: "l\list(A) \ bag_of(sublist(l, C)) = msetsum(\i. {#nth(i, l)#}, C \ length(l), A)" apply (subgoal_tac " bag_of (sublist (l, C \ nat)) = msetsum (\i. {#nth (i, l) #}, C \ length (l), A) ") apply (simp add: sublist_Int_eq) apply (simp add: bag_of_sublist_lemma2 Int_lower2 Int_assoc nat_Int_length_eq) done lemma bag_of_sublist_Un_Int: "l\list(A) \ bag_of(sublist(l, B \ C)) +# bag_of(sublist(l, B \ C)) = bag_of(sublist(l, B)) +# bag_of(sublist(l, C))" apply (subgoal_tac "B \ C \ length (l) = (B \ length (l)) \ (C \ length (l))") prefer 2 apply blast apply (simp (no_asm_simp) add: bag_of_sublist Int_Un_distrib2 msetsum_Un_Int) apply (rule msetsum_Un_Int) apply (erule list_Int_length_Fin)+ apply (simp add: ltI nth_type) done lemma bag_of_sublist_Un_disjoint: "\l\list(A); B \ C = 0\ \ bag_of(sublist(l, B \ C)) = bag_of(sublist(l, B)) +# bag_of(sublist(l, C))" by (simp add: bag_of_sublist_Un_Int [symmetric] bag_of_multiset) lemma bag_of_sublist_UN_disjoint [rule_format]: "\Finite(I); \i\I. \j\I. i\j \ A(i) \ A(j) = 0; l\list(B)\ \ bag_of(sublist(l, \i\I. A(i))) = (msetsum(\i. bag_of(sublist(l, A(i))), I, B)) " apply (simp (no_asm_simp) del: UN_simps add: UN_simps [symmetric] bag_of_sublist) apply (subst msetsum_UN_disjoint [of _ _ _ "length (l)"]) apply (drule Finite_into_Fin, assumption) prefer 3 apply force apply (auto intro!: Fin_IntI2 Finite_into_Fin simp add: ltI nth_type length_type nat_into_Finite) done lemma part_ord_Lt [simp]: "part_ord(nat, Lt)" apply (unfold part_ord_def Lt_def irrefl_def trans_on_def) apply (auto intro: lt_trans) done subsubsection\The function \<^term>\all_distinct\\ lemma all_distinct_Nil [simp]: "all_distinct(Nil)" by (unfold all_distinct_def, auto) lemma all_distinct_Cons [simp]: "all_distinct(Cons(a,l)) \ (a\set_of_list(l) \ False) \ (a \ set_of_list(l) \ all_distinct(l))" -apply (unfold all_distinct_def) + unfolding all_distinct_def apply (auto elim: list.cases) done subsubsection\The function \<^term>\state_of\\ lemma state_of_state: "s\state \ state_of(s)=s" by (unfold state_of_def, auto) declare state_of_state [simp] lemma state_of_idem: "state_of(state_of(s))=state_of(s)" apply (unfold state_of_def, auto) done declare state_of_idem [simp] lemma state_of_type [simp,TC]: "state_of(s)\state" by (unfold state_of_def, auto) lemma lift_apply [simp]: "lift(x, s)=s`x" by (simp add: lift_def) (** Used in ClientImp **) lemma gen_Increains_state_of_eq: "Increasing(A, r, \s. f(state_of(s))) = Increasing(A, r, f)" apply (unfold Increasing_def, auto) done lemmas Increasing_state_ofD1 = gen_Increains_state_of_eq [THEN equalityD1, THEN subsetD] lemmas Increasing_state_ofD2 = gen_Increains_state_of_eq [THEN equalityD2, THEN subsetD] lemma Follows_state_of_eq: "Follows(A, r, \s. f(state_of(s)), \s. g(state_of(s))) = Follows(A, r, f, g)" apply (unfold Follows_def Increasing_def, auto) done lemmas Follows_state_ofD1 = Follows_state_of_eq [THEN equalityD1, THEN subsetD] lemmas Follows_state_ofD2 = Follows_state_of_eq [THEN equalityD2, THEN subsetD] lemma nat_list_inj_type: "n\nat \ nat_list_inj(n)\list(nat)" by (induct_tac "n", auto) lemma length_nat_list_inj: "n\nat \ length(nat_list_inj(n)) = n" by (induct_tac "n", auto) lemma var_infinite_lemma: "(\x\nat. nat_var_inj(x))\inj(nat, var)" -apply (unfold nat_var_inj_def) + unfolding nat_var_inj_def apply (rule_tac d = var_inj in lam_injective) apply (auto simp add: var.intros nat_list_inj_type) apply (simp add: length_nat_list_inj) done lemma nat_lepoll_var: "nat \ var" -apply (unfold lepoll_def) + unfolding lepoll_def apply (rule_tac x = " (\x\nat. nat_var_inj (x))" in exI) apply (rule var_infinite_lemma) done lemma var_not_Finite: "\Finite(var)" apply (insert nat_not_Finite) apply (blast intro: lepoll_Finite [OF nat_lepoll_var]) done lemma not_Finite_imp_exist: "\Finite(A) \ \x. x\A" apply (subgoal_tac "A\0") apply (auto simp add: Finite_0) done lemma Inter_Diff_var_iff: "Finite(A) \ b\(\(RepFun(var-A, B))) \ (\x\var-A. b\B(x))" apply (subgoal_tac "\x. x\var-A", auto) apply (subgoal_tac "\Finite (var-A) ") apply (drule not_Finite_imp_exist, auto) apply (cut_tac var_not_Finite) apply (erule swap) apply (rule_tac B = A in Diff_Finite, auto) done lemma Inter_var_DiffD: "\b\\(RepFun(var-A, B)); Finite(A); x\var-A\ \ b\B(x)" by (simp add: Inter_Diff_var_iff) (* \Finite(A); (\x\var-A. b\B(x))\ \ b\\(RepFun(var-A, B)) *) lemmas Inter_var_DiffI = Inter_Diff_var_iff [THEN iffD2] declare Inter_var_DiffI [intro!] lemma Acts_subset_Int_Pow_simp [simp]: "Acts(F)<= A \ Pow(state*state) \ Acts(F)<=A" by (insert Acts_type [of F], auto) lemma setsum_nsetsum_eq: "\Finite(A); \x\A. g(x)\nat\ \ setsum(\x. $#(g(x)), A) = $# nsetsum(\x. g(x), A)" apply (erule Finite_induct) apply (auto simp add: int_of_add) done lemma nsetsum_cong: "\A=B; \x\A. f(x)=g(x); \x\A. g(x)\nat; Finite(A)\ \ nsetsum(f, A) = nsetsum(g, B)" apply (subgoal_tac "$# nsetsum (f, A) = $# nsetsum (g, B)", simp) apply (simp add: setsum_nsetsum_eq [symmetric] cong: setsum_cong) done end diff --git a/src/ZF/UNITY/AllocImpl.thy b/src/ZF/UNITY/AllocImpl.thy --- a/src/ZF/UNITY/AllocImpl.thy +++ b/src/ZF/UNITY/AllocImpl.thy @@ -1,661 +1,661 @@ (* Title: ZF/UNITY/AllocImpl.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2002 University of Cambridge Single-client allocator implementation. Charpentier and Chandy, section 7 (page 17). *) theory AllocImpl imports ClientImpl begin abbreviation NbR :: i (*number of consumed messages*) where "NbR \ Var([succ(2)])" abbreviation available_tok :: i (*number of free tokens (T in paper)*) where "available_tok \ Var([succ(succ(2))])" axiomatization where alloc_type_assumes [simp]: "type_of(NbR) = nat \ type_of(available_tok)=nat" and alloc_default_val_assumes [simp]: "default_val(NbR) = 0 \ default_val(available_tok)=0" definition "alloc_giv_act \ {\s, t\ \ state*state. \k. k = length(s`giv) \ t = s(giv := s`giv @ [nth(k, s`ask)], available_tok := s`available_tok #- nth(k, s`ask)) \ k < length(s`ask) \ nth(k, s`ask) \ s`available_tok}" definition "alloc_rel_act \ {\s, t\ \ state*state. t = s(available_tok := s`available_tok #+ nth(s`NbR, s`rel), NbR := succ(s`NbR)) \ s`NbR < length(s`rel)}" definition (*The initial condition s`giv=[] is missing from the original definition: S. O. Ehmety *) "alloc_prog \ mk_program({s:state. s`available_tok=NbT \ s`NbR=0 \ s`giv=Nil}, {alloc_giv_act, alloc_rel_act}, \G \ preserves(lift(available_tok)) \ preserves(lift(NbR)) \ preserves(lift(giv)). Acts(G))" lemma available_tok_value_type [simp,TC]: "s\state \ s`available_tok \ nat" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = available_tok in apply_type, auto) done lemma NbR_value_type [simp,TC]: "s\state \ s`NbR \ nat" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = NbR in apply_type, auto) done (** The Alloc Program **) lemma alloc_prog_type [simp,TC]: "alloc_prog \ program" by (simp add: alloc_prog_def) declare alloc_prog_def [THEN def_prg_Init, simp] declare alloc_prog_def [THEN def_prg_AllowedActs, simp] declare alloc_prog_def [program] declare alloc_giv_act_def [THEN def_act_simp, simp] declare alloc_rel_act_def [THEN def_act_simp, simp] lemma alloc_prog_ok_iff: "\G \ program. (alloc_prog ok G) \ (G \ preserves(lift(giv)) \ G \ preserves(lift(available_tok)) \ G \ preserves(lift(NbR)) \ alloc_prog \ Allowed(G))" by (auto simp add: ok_iff_Allowed alloc_prog_def [THEN def_prg_Allowed]) lemma alloc_prog_preserves: "alloc_prog \ (\x \ var-{giv, available_tok, NbR}. preserves(lift(x)))" apply (rule Inter_var_DiffI, force) apply (rule ballI) apply (rule preservesI, safety) done (* As a special case of the rule above *) lemma alloc_prog_preserves_rel_ask_tok: "alloc_prog \ preserves(lift(rel)) \ preserves(lift(ask)) \ preserves(lift(tok))" apply auto apply (insert alloc_prog_preserves) apply (drule_tac [3] x = tok in Inter_var_DiffD) apply (drule_tac [2] x = ask in Inter_var_DiffD) apply (drule_tac x = rel in Inter_var_DiffD, auto) done lemma alloc_prog_Allowed: "Allowed(alloc_prog) = preserves(lift(giv)) \ preserves(lift(available_tok)) \ preserves(lift(NbR))" apply (cut_tac v="lift(giv)" in preserves_type) apply (auto simp add: Allowed_def client_prog_def [THEN def_prg_Allowed] cons_Int_distrib safety_prop_Acts_iff) done (* In particular we have *) lemma alloc_prog_ok_client_prog: "alloc_prog ok client_prog" apply (auto simp add: ok_iff_Allowed) apply (cut_tac alloc_prog_preserves) apply (cut_tac [2] client_prog_preserves) apply (auto simp add: alloc_prog_Allowed client_prog_Allowed) apply (drule_tac [6] B = "preserves (lift (NbR))" in InterD) apply (drule_tac [5] B = "preserves (lift (available_tok))" in InterD) apply (drule_tac [4] B = "preserves (lift (giv))" in InterD) apply (drule_tac [3] B = "preserves (lift (tok))" in InterD) apply (drule_tac [2] B = "preserves (lift (ask))" in InterD) apply (drule_tac B = "preserves (lift (rel))" in InterD) apply auto done (** Safety property: (28) **) lemma alloc_prog_Increasing_giv: "alloc_prog \ program guarantees Incr(lift(giv))" apply (auto intro!: increasing_imp_Increasing simp add: guar_def Increasing.increasing_def alloc_prog_ok_iff alloc_prog_Allowed, safety+) apply (auto dest: ActsD) apply (drule_tac f = "lift (giv) " in preserves_imp_eq) apply auto done lemma giv_Bounded_lamma1: "alloc_prog \ stable({s\state. s`NbR \ length(s`rel)} \ {s\state. s`available_tok #+ tokens(s`giv) = NbT #+ tokens(take(s`NbR, s`rel))})" apply safety apply auto apply (simp add: diff_add_0 add_commute diff_add_inverse add_assoc add_diff_inverse) apply (simp (no_asm_simp) add: take_succ) done lemma giv_Bounded_lemma2: "\G \ program; alloc_prog ok G; alloc_prog \ G \ Incr(lift(rel))\ \ alloc_prog \ G \ Stable({s\state. s`NbR \ length(s`rel)} \ {s\state. s`available_tok #+ tokens(s`giv) = NbT #+ tokens(take(s`NbR, s`rel))})" apply (cut_tac giv_Bounded_lamma1) apply (cut_tac alloc_prog_preserves_rel_ask_tok) apply (auto simp add: Collect_conj_eq [symmetric] alloc_prog_ok_iff) apply (subgoal_tac "G \ preserves (fun_pair (lift (available_tok), fun_pair (lift (NbR), lift (giv))))") apply (rotate_tac -1) apply (cut_tac A = "nat * nat * list(nat)" and P = "% y. n \ length(y) \ m #+ tokens(l) = NbT #+ tokens(take(n,y))" and g = "lift(rel)" and F = alloc_prog in stable_Join_Stable) prefer 3 apply assumption apply (auto simp add: Collect_conj_eq) apply (frule_tac g = length in imp_Increasing_comp) apply (blast intro: mono_length) apply (auto simp add: refl_prefix) apply (drule_tac a=xa and f = "length comp lift(rel)" in Increasing_imp_Stable) apply assumption apply (auto simp add: Le_def length_type) apply (auto dest: ActsD simp add: Stable_def Constrains_def constrains_def) apply (drule_tac f = "lift (rel) " in preserves_imp_eq) apply assumption+ apply (force dest: ActsD) apply (erule_tac V = "\x \ Acts (alloc_prog) \ Acts (G). P(x)" for P in thin_rl) apply (erule_tac V = "alloc_prog \ stable (u)" for u in thin_rl) apply (drule_tac a = "xc`rel" and f = "lift (rel)" in Increasing_imp_Stable) apply (auto simp add: Stable_def Constrains_def constrains_def) apply (drule bspec, force) apply (drule subsetD) apply (rule imageI, assumption) apply (auto simp add: prefix_take_iff) apply (rotate_tac -1) apply (erule ssubst) apply (auto simp add: take_take min_def) done (*Property (29), page 18: the number of tokens in circulation never exceeds NbT*) lemma alloc_prog_giv_Bounded: "alloc_prog \ Incr(lift(rel)) guarantees Always({s\state. tokens(s`giv) \ NbT #+ tokens(s`rel)})" apply (cut_tac NbT_pos) apply (auto simp add: guar_def) apply (rule Always_weaken) apply (rule AlwaysI) apply (rule_tac [2] giv_Bounded_lemma2, auto) apply (rule_tac j = "NbT #+ tokens(take (x` NbR, x`rel))" in le_trans) apply (erule subst) apply (auto intro!: tokens_mono simp add: prefix_take_iff min_def length_take) done (*Property (30), page 18: the number of tokens given never exceeds the number asked for*) lemma alloc_prog_ask_prefix_giv: "alloc_prog \ Incr(lift(ask)) guarantees Always({s\state. \ prefix(tokbag)})" apply (auto intro!: AlwaysI simp add: guar_def) apply (subgoal_tac "G \ preserves (lift (giv))") prefer 2 apply (simp add: alloc_prog_ok_iff) apply (rule_tac P = "\x y. \x,y\ \ prefix(tokbag)" and A = "list(nat)" in stable_Join_Stable) apply safety prefer 2 apply (simp add: lift_def, clarify) apply (drule_tac a = k in Increasing_imp_Stable, auto) done subsection\Towards proving the liveness property, (31)\ subsubsection\First, we lead up to a proof of Lemma 49, page 28.\ lemma alloc_prog_transient_lemma: "\G \ program; k\nat\ \ alloc_prog \ G \ transient({s\state. k \ length(s`rel)} \ {s\state. succ(s`NbR) = k})" apply auto apply (erule_tac V = "G\u" for u in thin_rl) apply (rule_tac act = alloc_rel_act in transientI) apply (simp (no_asm) add: alloc_prog_def [THEN def_prg_Acts]) apply (simp (no_asm) add: alloc_rel_act_def [THEN def_act_eq, THEN act_subset]) apply (auto simp add: alloc_prog_def [THEN def_prg_Acts] domain_def) apply (rule ReplaceI) apply (rule_tac x = "x (available_tok:= x`available_tok #+ nth (x`NbR, x`rel), NbR:=succ (x`NbR))" in exI) apply (auto intro!: state_update_type) done lemma alloc_prog_rel_Stable_NbR_lemma: "\G \ program; alloc_prog ok G; k\nat\ \ alloc_prog \ G \ Stable({s\state . k \ succ(s ` NbR)})" apply (auto intro!: stable_imp_Stable simp add: alloc_prog_ok_iff, safety, auto) apply (blast intro: le_trans leI) apply (drule_tac f = "lift (NbR)" and A = nat in preserves_imp_increasing) apply (drule_tac [2] g = succ in imp_increasing_comp) apply (rule_tac [2] mono_succ) apply (drule_tac [4] x = k in increasing_imp_stable) prefer 5 apply (simp add: Le_def comp_def, auto) done lemma alloc_prog_NbR_LeadsTo_lemma: "\G \ program; alloc_prog ok G; alloc_prog \ G \ Incr(lift(rel)); k\nat\ \ alloc_prog \ G \ {s\state. k \ length(s`rel)} \ {s\state. succ(s`NbR) = k} \w {s\state. k \ s`NbR}" apply (subgoal_tac "alloc_prog \ G \ Stable ({s\state. k \ length (s`rel)})") apply (drule_tac [2] a = k and g1 = length in imp_Increasing_comp [THEN Increasing_imp_Stable]) apply (rule_tac [2] mono_length) prefer 3 apply simp apply (simp_all add: refl_prefix Le_def comp_def length_type) apply (rule LeadsTo_weaken) apply (rule PSP_Stable) prefer 2 apply assumption apply (rule PSP_Stable) apply (rule_tac [2] alloc_prog_rel_Stable_NbR_lemma) apply (rule alloc_prog_transient_lemma [THEN transient_imp_leadsTo, THEN leadsTo_imp_LeadsTo], assumption+) apply (auto dest: not_lt_imp_le elim: lt_asym simp add: le_iff) done lemma alloc_prog_NbR_LeadsTo_lemma2 [rule_format]: "\G \ program; alloc_prog ok G; alloc_prog \ G \ Incr(lift(rel)); k\nat; n \ nat; n < k\ \ alloc_prog \ G \ {s\state . k \ length(s ` rel)} \ {s\state . s ` NbR = n} \w {x \ state. k \ length(x`rel)} \ (\m \ greater_than(n). {x \ state. x ` NbR=m})" -apply (unfold greater_than_def) + unfolding greater_than_def apply (rule_tac A' = "{x \ state. k \ length(x`rel)} \ {x \ state. n < x`NbR}" in LeadsTo_weaken_R) apply safe apply (subgoal_tac "alloc_prog \ G \ Stable ({s\state. k \ length (s`rel) }) ") apply (drule_tac [2] a = k and g1 = length in imp_Increasing_comp [THEN Increasing_imp_Stable]) apply (rule_tac [2] mono_length) prefer 3 apply simp apply (simp_all add: refl_prefix Le_def comp_def length_type) apply (subst Int_commute [of _ "{x \ state . n < x ` NbR}"]) apply (rule_tac A = "({s \ state . k \ length (s ` rel) } \ {s\state . s ` NbR = n}) \ {s\state. k \ length(s`rel)}" in LeadsTo_weaken_L) apply (rule PSP_Stable, safe) apply (rule_tac B = "{x \ state . n < length (x ` rel) } \ {s\state . s ` NbR = n}" in LeadsTo_Trans) apply (rule_tac [2] LeadsTo_weaken) apply (rule_tac [2] k = "succ (n)" in alloc_prog_NbR_LeadsTo_lemma) apply simp_all apply (rule subset_imp_LeadsTo, auto) apply (blast intro: lt_trans2) done lemma Collect_vimage_eq: "u\nat \ {. s \ A} -`` u = {s\A. f(s) < u}" by (force simp add: lt_def) (* Lemma 49, page 28 *) lemma alloc_prog_NbR_LeadsTo_lemma3: "\G \ program; alloc_prog ok G; alloc_prog \ G \ Incr(lift(rel)); k\nat\ \ alloc_prog \ G \ {s\state. k \ length(s`rel)} \w {s\state. k \ s`NbR}" (* Proof by induction over the difference between k and n *) apply (rule_tac f = "\s\state. k #- s`NbR" in LessThan_induct) apply (simp_all add: lam_def, auto) apply (rule single_LeadsTo_I, auto) apply (simp (no_asm_simp) add: Collect_vimage_eq) apply (rename_tac "s0") apply (case_tac "s0`NbR < k") apply (rule_tac [2] subset_imp_LeadsTo, safe) apply (auto dest!: not_lt_imp_le) apply (rule LeadsTo_weaken) apply (rule_tac n = "s0`NbR" in alloc_prog_NbR_LeadsTo_lemma2, safe) prefer 3 apply assumption apply (auto split: nat_diff_split simp add: greater_than_def not_lt_imp_le not_le_iff_lt) apply (blast dest: lt_asym) apply (force dest: add_lt_elim2) done subsubsection\Towards proving lemma 50, page 29\ lemma alloc_prog_giv_Ensures_lemma: "\G \ program; k\nat; alloc_prog ok G; alloc_prog \ G \ Incr(lift(ask))\ \ alloc_prog \ G \ {s\state. nth(length(s`giv), s`ask) \ s`available_tok} \ {s\state. k < length(s`ask)} \ {s\state. length(s`giv)=k} Ensures {s\state. \ k {s\state. length(s`giv) \ k}" apply (rule EnsuresI, auto) apply (erule_tac [2] V = "G\u" for u in thin_rl) apply (rule_tac [2] act = alloc_giv_act in transientI) prefer 2 apply (simp add: alloc_prog_def [THEN def_prg_Acts]) apply (simp add: alloc_giv_act_def [THEN def_act_eq, THEN act_subset]) apply (auto simp add: alloc_prog_def [THEN def_prg_Acts] domain_def) apply (erule_tac [2] swap) apply (rule_tac [2] ReplaceI) apply (rule_tac [2] x = "x (giv := x ` giv @ [nth (length(x`giv), x ` ask) ], available_tok := x ` available_tok #- nth (length(x`giv), x ` ask))" in exI) apply (auto intro!: state_update_type simp add: app_type) apply (rule_tac A = "{s\state . nth (length(s ` giv), s ` ask) \ s ` available_tok} \ {s\state . k < length(s ` ask) } \ {s\state. length(s`giv) =k}" and A' = "{s\state . nth (length(s ` giv), s ` ask) \ s ` available_tok} \ {s\state. \ k < length(s`ask) } \ {s\state . length(s ` giv) \ k}" in Constrains_weaken) apply (auto dest: ActsD simp add: Constrains_def constrains_def alloc_prog_def [THEN def_prg_Acts] alloc_prog_ok_iff) apply (subgoal_tac "length(xa ` giv @ [nth (length(xa ` giv), xa ` ask) ]) = length(xa ` giv) #+ 1") apply (rule_tac [2] trans) apply (rule_tac [2] length_app, auto) apply (rule_tac j = "xa ` available_tok" in le_trans, auto) apply (drule_tac f = "lift (available_tok)" in preserves_imp_eq) apply assumption+ apply auto apply (drule_tac a = "xa ` ask" and r = "prefix(tokbag)" and A = "list(tokbag)" in Increasing_imp_Stable) apply (auto simp add: prefix_iff) apply (drule StableD) apply (auto simp add: Constrains_def constrains_def, force) done lemma alloc_prog_giv_Stable_lemma: "\G \ program; alloc_prog ok G; k\nat\ \ alloc_prog \ G \ Stable({s\state . k \ length(s`giv)})" apply (auto intro!: stable_imp_Stable simp add: alloc_prog_ok_iff, safety) apply (auto intro: leI) apply (drule_tac f = "lift (giv)" and g = length in imp_preserves_comp) apply (drule_tac f = "length comp lift (giv)" and A = nat and r = Le in preserves_imp_increasing) apply (drule_tac [2] x = k in increasing_imp_stable) prefer 3 apply (simp add: Le_def comp_def) apply (auto simp add: length_type) done (* Lemma 50, page 29 *) lemma alloc_prog_giv_LeadsTo_lemma: "\G \ program; alloc_prog ok G; alloc_prog \ G \ Incr(lift(ask)); k\nat\ \ alloc_prog \ G \ {s\state. nth(length(s`giv), s`ask) \ s`available_tok} \ {s\state. k < length(s`ask)} \ {s\state. length(s`giv) = k} \w {s\state. k < length(s`giv)}" apply (subgoal_tac "alloc_prog \ G \ {s\state. nth (length(s`giv), s`ask) \ s`available_tok} \ {s\state. k < length(s`ask) } \ {s\state. length(s`giv) = k} \w {s\state. \ k {s\state. length(s`giv) \ k}") prefer 2 apply (blast intro: alloc_prog_giv_Ensures_lemma [THEN LeadsTo_Basis]) apply (subgoal_tac "alloc_prog \ G \ Stable ({s\state. k < length(s`ask) }) ") apply (drule PSP_Stable, assumption) apply (rule LeadsTo_weaken) apply (rule PSP_Stable) apply (rule_tac [2] k = k in alloc_prog_giv_Stable_lemma) apply (auto simp add: le_iff) apply (drule_tac a = "succ (k)" and g1 = length in imp_Increasing_comp [THEN Increasing_imp_Stable]) apply (rule mono_length) prefer 2 apply simp apply (simp_all add: refl_prefix Le_def comp_def length_type) done text\Lemma 51, page 29. This theorem states as invariant that if the number of tokens given does not exceed the number returned, then the upper limit (\<^term>\NbT\) does not exceed the number currently available.\ lemma alloc_prog_Always_lemma: "\G \ program; alloc_prog ok G; alloc_prog \ G \ Incr(lift(ask)); alloc_prog \ G \ Incr(lift(rel))\ \ alloc_prog \ G \ Always({s\state. tokens(s`giv) \ tokens(take(s`NbR, s`rel)) \ NbT \ s`available_tok})" apply (subgoal_tac "alloc_prog \ G \ Always ({s\state. s`NbR \ length(s`rel) } \ {s\state. s`available_tok #+ tokens(s`giv) = NbT #+ tokens(take (s`NbR, s`rel))})") apply (rule_tac [2] AlwaysI) apply (rule_tac [3] giv_Bounded_lemma2, auto) apply (rule Always_weaken, assumption, auto) apply (subgoal_tac "0 \ tokens(take (x ` NbR, x ` rel)) #- tokens(x`giv) ") prefer 2 apply (force) apply (subgoal_tac "x`available_tok = NbT #+ (tokens(take(x`NbR,x`rel)) #- tokens(x`giv))") apply (simp add: ) apply (auto split: nat_diff_split dest: lt_trans2) done subsubsection\Main lemmas towards proving property (31)\ lemma LeadsTo_strength_R: "\F \ C \w B'; F \ A-C \w B; B'<=B\ \ F \ A \w B" by (blast intro: LeadsTo_weaken LeadsTo_Un_Un) lemma PSP_StableI: "\F \ Stable(C); F \ A - C \w B; F \ A \ C \w B \ (state - C)\ \ F \ A \w B" apply (rule_tac A = " (A-C) \ (A \ C)" in LeadsTo_weaken_L) prefer 2 apply blast apply (rule LeadsTo_Un, assumption) apply (blast intro: LeadsTo_weaken dest: PSP_Stable) done lemma state_compl_eq [simp]: "state - {s\state. P(s)} = {s\state. \P(s)}" by auto (*needed?*) lemma single_state_Diff_eq [simp]: "{s}-{x \ state. P(x)} = (if s\state \ P(s) then 0 else {s})" by auto locale alloc_progress = fixes G assumes Gprog [intro,simp]: "G \ program" and okG [iff]: "alloc_prog ok G" and Incr_rel [intro]: "alloc_prog \ G \ Incr(lift(rel))" and Incr_ask [intro]: "alloc_prog \ G \ Incr(lift(ask))" and safety: "alloc_prog \ G \ Always(\k \ nat. {s\state. nth(k, s`ask) \ NbT})" and progress: "alloc_prog \ G \ (\k\nat. {s\state. k \ tokens(s`giv)} \w {s\state. k \ tokens(s`rel)})" (*First step in proof of (31) -- the corrected version from Charpentier. This lemma implies that if a client releases some tokens then the Allocator will eventually recognize that they've been released.*) lemma (in alloc_progress) tokens_take_NbR_lemma: "k \ tokbag \ alloc_prog \ G \ {s\state. k \ tokens(s`rel)} \w {s\state. k \ tokens(take(s`NbR, s`rel))}" apply (rule single_LeadsTo_I, safe) apply (rule_tac a1 = "s`rel" in Increasing_imp_Stable [THEN PSP_StableI]) apply (rule_tac [4] k1 = "length(s`rel)" in alloc_prog_NbR_LeadsTo_lemma3 [THEN LeadsTo_strength_R]) apply (rule_tac [8] subset_imp_LeadsTo) apply (auto intro!: Incr_rel) apply (rule_tac j = "tokens(take (length(s`rel), x`rel))" in le_trans) apply (rule_tac j = "tokens(take (length(s`rel), s`rel))" in le_trans) apply (auto intro!: tokens_mono take_mono simp add: prefix_iff) done (*** Rest of proofs done by lcp ***) (*Second step in proof of (31): by LHS of the guarantee and transivity of \w *) lemma (in alloc_progress) tokens_take_NbR_lemma2: "k \ tokbag \ alloc_prog \ G \ {s\state. tokens(s`giv) = k} \w {s\state. k \ tokens(take(s`NbR, s`rel))}" apply (rule LeadsTo_Trans) apply (rule_tac [2] tokens_take_NbR_lemma) prefer 2 apply assumption apply (insert progress) apply (blast intro: LeadsTo_weaken_L progress nat_into_Ord) done (*Third step in proof of (31): by PSP with the fact that giv increases *) lemma (in alloc_progress) length_giv_disj: "\k \ tokbag; n \ nat\ \ alloc_prog \ G \ {s\state. length(s`giv) = n \ tokens(s`giv) = k} \w {s\state. (length(s`giv) = n \ tokens(s`giv) = k \ k \ tokens(take(s`NbR, s`rel))) | n < length(s`giv)}" apply (rule single_LeadsTo_I, safe) apply (rule_tac a1 = "s`giv" in Increasing_imp_Stable [THEN PSP_StableI]) apply (rule alloc_prog_Increasing_giv [THEN guaranteesD]) apply (simp_all add: Int_cons_left) apply (rule LeadsTo_weaken) apply (rule_tac k = "tokens(s`giv)" in tokens_take_NbR_lemma2) apply auto apply (force dest: prefix_length_le [THEN le_iff [THEN iffD1]]) apply (simp add: not_lt_iff_le) apply (force dest: prefix_length_le_equal) done (*Fourth step in proof of (31): we apply lemma (51) *) lemma (in alloc_progress) length_giv_disj2: "\k \ tokbag; n \ nat\ \ alloc_prog \ G \ {s\state. length(s`giv) = n \ tokens(s`giv) = k} \w {s\state. (length(s`giv) = n \ NbT \ s`available_tok) | n < length(s`giv)}" apply (rule LeadsTo_weaken_R) apply (rule Always_LeadsToD [OF alloc_prog_Always_lemma length_giv_disj], auto) done (*Fifth step in proof of (31): from the fourth step, taking the union over all k\nat *) lemma (in alloc_progress) length_giv_disj3: "n \ nat \ alloc_prog \ G \ {s\state. length(s`giv) = n} \w {s\state. (length(s`giv) = n \ NbT \ s`available_tok) | n < length(s`giv)}" apply (rule LeadsTo_weaken_L) apply (rule_tac I = nat in LeadsTo_UN) apply (rule_tac k = i in length_giv_disj2) apply (simp_all add: UN_conj_eq) done (*Sixth step in proof of (31): from the fifth step, by PSP with the assumption that ask increases *) lemma (in alloc_progress) length_ask_giv: "\k \ nat; n < k\ \ alloc_prog \ G \ {s\state. length(s`ask) = k \ length(s`giv) = n} \w {s\state. (NbT \ s`available_tok \ length(s`giv) < length(s`ask) \ length(s`giv) = n) | n < length(s`giv)}" apply (rule single_LeadsTo_I, safe) apply (rule_tac a1 = "s`ask" and f1 = "lift(ask)" in Increasing_imp_Stable [THEN PSP_StableI]) apply (rule Incr_ask, simp_all) apply (rule LeadsTo_weaken) apply (rule_tac n = "length(s ` giv)" in length_giv_disj3) apply simp_all apply blast apply clarify apply simp apply (blast dest!: prefix_length_le intro: lt_trans2) done (*Seventh step in proof of (31): no request (ask[k]) exceeds NbT *) lemma (in alloc_progress) length_ask_giv2: "\k \ nat; n < k\ \ alloc_prog \ G \ {s\state. length(s`ask) = k \ length(s`giv) = n} \w {s\state. (nth(length(s`giv), s`ask) \ s`available_tok \ length(s`giv) < length(s`ask) \ length(s`giv) = n) | n < length(s`giv)}" apply (rule LeadsTo_weaken_R) apply (rule Always_LeadsToD [OF safety length_ask_giv], assumption+, clarify) apply (simp add: INT_iff) apply (drule_tac x = "length(x ` giv)" and P = "\x. f (x) \ NbT" for f in bspec) apply simp apply (blast intro: le_trans) done (*Eighth step in proof of (31): by 50, we get |giv| > n. *) lemma (in alloc_progress) extend_giv: "\k \ nat; n < k\ \ alloc_prog \ G \ {s\state. length(s`ask) = k \ length(s`giv) = n} \w {s\state. n < length(s`giv)}" apply (rule LeadsTo_Un_duplicate) apply (rule LeadsTo_cancel1) apply (rule_tac [2] alloc_prog_giv_LeadsTo_lemma) apply (simp_all add: Incr_ask lt_nat_in_nat) apply (rule LeadsTo_weaken_R) apply (rule length_ask_giv2, auto) done (*Ninth and tenth steps in proof of (31): by 50, we get |giv| > n. The report has an error: putting |ask|=k for the precondition fails because we can't expect |ask| to remain fixed until |giv| increases.*) lemma (in alloc_progress) alloc_prog_ask_LeadsTo_giv: "k \ nat \ alloc_prog \ G \ {s\state. k \ length(s`ask)} \w {s\state. k \ length(s`giv)}" (* Proof by induction over the difference between k and n *) apply (rule_tac f = "\s\state. k #- length(s`giv)" in LessThan_induct) apply (auto simp add: lam_def Collect_vimage_eq) apply (rule single_LeadsTo_I, auto) apply (rename_tac "s0") apply (case_tac "length(s0 ` giv) < length(s0 ` ask) ") apply (rule_tac [2] subset_imp_LeadsTo) apply (auto simp add: not_lt_iff_le) prefer 2 apply (blast dest: le_imp_not_lt intro: lt_trans2) apply (rule_tac a1 = "s0`ask" and f1 = "lift (ask)" in Increasing_imp_Stable [THEN PSP_StableI]) apply (rule Incr_ask, simp) apply (force) apply (rule LeadsTo_weaken) apply (rule_tac n = "length(s0 ` giv)" and k = "length(s0 ` ask)" in extend_giv) apply (auto dest: not_lt_imp_le simp add: leI diff_lt_iff_lt) apply (blast dest!: prefix_length_le intro: lt_trans2) done (*Final lemma: combine previous result with lemma (30)*) lemma (in alloc_progress) final: "h \ list(tokbag) \ alloc_prog \ G \ {s\state. \ prefix(tokbag)} \w {s\state. \ prefix(tokbag)}" apply (rule single_LeadsTo_I) prefer 2 apply simp apply (rename_tac s0) apply (rule_tac a1 = "s0`ask" and f1 = "lift (ask)" in Increasing_imp_Stable [THEN PSP_StableI]) apply (rule Incr_ask) apply (simp_all add: Int_cons_left) apply (rule LeadsTo_weaken) apply (rule_tac k1 = "length(s0 ` ask)" in Always_LeadsToD [OF alloc_prog_ask_prefix_giv [THEN guaranteesD] alloc_prog_ask_LeadsTo_giv]) apply (auto simp add: Incr_ask) apply (blast intro: length_le_prefix_imp_prefix prefix_trans prefix_length_le lt_trans2) done (** alloc_prog liveness property (31), page 18 **) theorem alloc_prog_progress: "alloc_prog \ Incr(lift(ask)) \ Incr(lift(rel)) \ Always(\k \ nat. {s\state. nth(k, s`ask) \ NbT}) \ (\k\nat. {s\state. k \ tokens(s`giv)} \w {s\state. k \ tokens(s`rel)}) guarantees (\h \ list(tokbag). {s\state. \ prefix(tokbag)} \w {s\state. \ prefix(tokbag)})" apply (rule guaranteesI) apply (rule INT_I) apply (rule alloc_progress.final) apply (auto simp add: alloc_progress_def) done end diff --git a/src/ZF/UNITY/ClientImpl.thy b/src/ZF/UNITY/ClientImpl.thy --- a/src/ZF/UNITY/ClientImpl.thy +++ b/src/ZF/UNITY/ClientImpl.thy @@ -1,307 +1,307 @@ (* Title: ZF/UNITY/ClientImpl.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2002 University of Cambridge Distributed Resource Management System: Client Implementation. *) theory ClientImpl imports AllocBase Guar begin abbreviation "ask \ Var(Nil)" (* input history: tokens requested *) abbreviation "giv \ Var([0])" (* output history: tokens granted *) abbreviation "rel \ Var([1])" (* input history: tokens released *) abbreviation "tok \ Var([2])" (* the number of available tokens *) axiomatization where type_assumes: "type_of(ask) = list(tokbag) \ type_of(giv) = list(tokbag) \ type_of(rel) = list(tokbag) \ type_of(tok) = nat" and default_val_assumes: "default_val(ask) = Nil \ default_val(giv) = Nil \ default_val(rel) = Nil \ default_val(tok) = 0" (*Array indexing is translated to list indexing as A[n] \ nth(n-1,A). *) definition (** Release some client_tokens **) "client_rel_act \ {\s,t\ \ state*state. \nrel \ nat. nrel = length(s`rel) \ t = s(rel:=(s`rel)@[nth(nrel, s`giv)]) \ nrel < length(s`giv) \ nth(nrel, s`ask) \ nth(nrel, s`giv)}" (** Choose a new token requirement **) (** Including t=s suppresses fairness, allowing the non-trivial part of the action to be ignored **) definition "client_tok_act \ {\s,t\ \ state*state. t=s | t = s(tok:=succ(s`tok mod NbT))}" definition "client_ask_act \ {\s,t\ \ state*state. t=s | (t=s(ask:=s`ask@[s`tok]))}" definition "client_prog \ mk_program({s \ state. s`tok \ NbT \ s`giv = Nil \ s`ask = Nil \ s`rel = Nil}, {client_rel_act, client_tok_act, client_ask_act}, \G \ preserves(lift(rel)) Int preserves(lift(ask)) Int preserves(lift(tok)). Acts(G))" declare type_assumes [simp] default_val_assumes [simp] (* This part should be automated *) lemma ask_value_type [simp,TC]: "s \ state \ s`ask \ list(nat)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = ask in apply_type, auto) done lemma giv_value_type [simp,TC]: "s \ state \ s`giv \ list(nat)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = giv in apply_type, auto) done lemma rel_value_type [simp,TC]: "s \ state \ s`rel \ list(nat)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = rel in apply_type, auto) done lemma tok_value_type [simp,TC]: "s \ state \ s`tok \ nat" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = tok in apply_type, auto) done (** The Client Program **) lemma client_type [simp,TC]: "client_prog \ program" -apply (unfold client_prog_def) + unfolding client_prog_def apply (simp (no_asm)) done declare client_prog_def [THEN def_prg_Init, simp] declare client_prog_def [THEN def_prg_AllowedActs, simp] declare client_prog_def [program] declare client_rel_act_def [THEN def_act_simp, simp] declare client_tok_act_def [THEN def_act_simp, simp] declare client_ask_act_def [THEN def_act_simp, simp] lemma client_prog_ok_iff: "\G \ program. (client_prog ok G) \ (G \ preserves(lift(rel)) \ G \ preserves(lift(ask)) \ G \ preserves(lift(tok)) \ client_prog \ Allowed(G))" by (auto simp add: ok_iff_Allowed client_prog_def [THEN def_prg_Allowed]) lemma client_prog_preserves: "client_prog:(\x \ var-{ask, rel, tok}. preserves(lift(x)))" apply (rule Inter_var_DiffI, force) apply (rule ballI) apply (rule preservesI, safety, auto) done lemma preserves_lift_imp_stable: "G \ preserves(lift(ff)) \ G \ stable({s \ state. P(s`ff)})" apply (drule preserves_imp_stable) apply (simp add: lift_def) done lemma preserves_imp_prefix: "G \ preserves(lift(ff)) \ G \ stable({s \ state. \k, s`ff\ \ prefix(nat)})" by (erule preserves_lift_imp_stable) (*Safety property 1 \ ask, rel are increasing: (24) *) lemma client_prog_Increasing_ask_rel: "client_prog: program guarantees Incr(lift(ask)) \ Incr(lift(rel))" -apply (unfold guar_def) + unfolding guar_def apply (auto intro!: increasing_imp_Increasing simp add: client_prog_ok_iff Increasing.increasing_def preserves_imp_prefix) apply (safety, force, force)+ done declare nth_append [simp] append_one_prefix [simp] lemma NbT_pos2: "0 the client never requests too many tokens. With no Substitution Axiom, we must prove the two invariants simultaneously. *) lemma ask_Bounded_lemma: "\client_prog ok G; G \ program\ \ client_prog \ G \ Always({s \ state. s`tok \ NbT} \ {s \ state. \elt \ set_of_list(s`ask). elt \ NbT})" apply (rotate_tac -1) apply (auto simp add: client_prog_ok_iff) apply (rule invariantI [THEN stable_Join_Always2], force) prefer 2 apply (fast intro: stable_Int preserves_lift_imp_stable, safety) apply (auto dest: ActsD) apply (cut_tac NbT_pos) apply (rule NbT_pos2 [THEN mod_less_divisor]) apply (auto dest: ActsD preserves_imp_eq simp add: set_of_list_append) done (* Export version, with no mention of tok in the postcondition, but unfortunately tok must be declared local.*) lemma client_prog_ask_Bounded: "client_prog \ program guarantees Always({s \ state. \elt \ set_of_list(s`ask). elt \ NbT})" apply (rule guaranteesI) apply (erule ask_Bounded_lemma [THEN Always_weaken], auto) done (*** Towards proving the liveness property ***) lemma client_prog_stable_rel_le_giv: "client_prog \ stable({s \ state. \ prefix(nat)})" by (safety, auto) lemma client_prog_Join_Stable_rel_le_giv: "\client_prog \ G \ Incr(lift(giv)); G \ preserves(lift(rel))\ \ client_prog \ G \ Stable({s \ state. \ prefix(nat)})" apply (rule client_prog_stable_rel_le_giv [THEN Increasing_preserves_Stable]) apply (auto simp add: lift_def) done lemma client_prog_Join_Always_rel_le_giv: "\client_prog \ G \ Incr(lift(giv)); G \ preserves(lift(rel))\ \ client_prog \ G \ Always({s \ state. \ prefix(nat)})" by (force intro!: AlwaysI client_prog_Join_Stable_rel_le_giv) lemma def_act_eq: "A \ {\s, t\ \ state*state. P(s, t)} \ A={\s, t\ \ state*state. P(s, t)}" by auto lemma act_subset: "A={\s,t\ \ state*state. P(s, t)} \ A<=state*state" by auto lemma transient_lemma: "client_prog \ transient({s \ state. s`rel = k \ \k, h\ \ strict_prefix(nat) \ \ prefix(nat) \ h pfixGe s`ask})" apply (rule_tac act = client_rel_act in transientI) apply (simp (no_asm) add: client_prog_def [THEN def_prg_Acts]) apply (simp (no_asm) add: client_rel_act_def [THEN def_act_eq, THEN act_subset]) apply (auto simp add: client_prog_def [THEN def_prg_Acts] domain_def) apply (rule ReplaceI) apply (rule_tac x = "x (rel:= x`rel @ [nth (length (x`rel), x`giv) ]) " in exI) apply (auto intro!: state_update_type app_type length_type nth_type, auto) apply (blast intro: lt_trans2 prefix_length_le strict_prefix_length_lt) apply (blast intro: lt_trans2 prefix_length_le strict_prefix_length_lt) apply (simp (no_asm_use) add: gen_prefix_iff_nth) apply (subgoal_tac "h \ list(nat)") apply (simp_all (no_asm_simp) add: prefix_type [THEN subsetD, THEN SigmaD1]) apply (auto simp add: prefix_def Ge_def) apply (drule strict_prefix_length_lt) apply (drule_tac x = "length (x`rel) " in spec) apply auto apply (simp (no_asm_use) add: gen_prefix_iff_nth) apply (auto simp add: id_def lam_def) done lemma strict_prefix_is_prefix: "\xs, ys\ \ strict_prefix(A) \ \xs, ys\ \ prefix(A) \ xs\ys" apply (unfold strict_prefix_def id_def lam_def) apply (auto dest: prefix_type [THEN subsetD]) done lemma induct_lemma: "\client_prog \ G \ Incr(lift(giv)); client_prog ok G; G \ program\ \ client_prog \ G \ {s \ state. s`rel = k \ \k,h\ \ strict_prefix(nat) \ \ prefix(nat) \ h pfixGe s`ask} \w {s \ state. \ strict_prefix(nat) \ \ prefix(nat) \ \ prefix(nat) \ h pfixGe s`ask}" apply (rule single_LeadsTo_I) prefer 2 apply simp apply (frule client_prog_Increasing_ask_rel [THEN guaranteesD]) apply (rotate_tac [3] 2) apply (auto simp add: client_prog_ok_iff) apply (rule transient_lemma [THEN Join_transient_I1, THEN transient_imp_leadsTo, THEN leadsTo_imp_LeadsTo, THEN PSP_Stable, THEN LeadsTo_weaken]) apply (rule Stable_Int [THEN Stable_Int, THEN Stable_Int]) apply (erule_tac f = "lift (giv) " and a = "s`giv" in Increasing_imp_Stable) apply (simp (no_asm_simp)) apply (erule_tac f = "lift (ask) " and a = "s`ask" in Increasing_imp_Stable) apply (simp (no_asm_simp)) apply (erule_tac f = "lift (rel) " and a = "s`rel" in Increasing_imp_Stable) apply (simp (no_asm_simp)) apply (erule client_prog_Join_Stable_rel_le_giv, blast, simp_all) prefer 2 apply (blast intro: sym strict_prefix_is_prefix [THEN iffD2] prefix_trans prefix_imp_pfixGe pfixGe_trans) apply (auto intro: strict_prefix_is_prefix [THEN iffD1, THEN conjunct1] prefix_trans) done lemma rel_progress_lemma: "\client_prog \ G \ Incr(lift(giv)); client_prog ok G; G \ program\ \ client_prog \ G \ {s \ state. \ strict_prefix(nat) \ \ prefix(nat) \ h pfixGe s`ask} \w {s \ state. \ prefix(nat)}" apply (rule_tac f = "\x \ state. length(h) #- length(x`rel)" in LessThan_induct) apply (auto simp add: vimage_def) prefer 2 apply (force simp add: lam_def) apply (rule single_LeadsTo_I) prefer 2 apply simp apply (subgoal_tac "h \ list(nat)") prefer 2 apply (blast dest: prefix_type [THEN subsetD]) apply (rule induct_lemma [THEN LeadsTo_weaken]) apply (simp add: length_type lam_def) apply (auto intro: strict_prefix_is_prefix [THEN iffD2] dest: common_prefix_linear prefix_type [THEN subsetD]) apply (erule swap) apply (rule imageI) apply (force dest!: simp add: lam_def) apply (simp add: length_type lam_def, clarify) apply (drule strict_prefix_length_lt)+ apply (drule less_imp_succ_add, simp)+ apply clarify apply simp apply (erule diff_le_self [THEN ltD]) done lemma progress_lemma: "\client_prog \ G \ Incr(lift(giv)); client_prog ok G; G \ program\ \ client_prog \ G \ {s \ state. \ prefix(nat) \ h pfixGe s`ask} \w {s \ state. \ prefix(nat)}" apply (rule client_prog_Join_Always_rel_le_giv [THEN Always_LeadsToI], assumption) apply (force simp add: client_prog_ok_iff) apply (rule LeadsTo_weaken_L) apply (rule LeadsTo_Un [OF rel_progress_lemma subset_refl [THEN subset_imp_LeadsTo]]) apply (auto intro: strict_prefix_is_prefix [THEN iffD2] dest: common_prefix_linear prefix_type [THEN subsetD]) done (*Progress property: all tokens that are given will be released*) lemma client_prog_progress: "client_prog \ Incr(lift(giv)) guarantees (\h \ list(nat). {s \ state. \ prefix(nat) \ h pfixGe s`ask} \w {s \ state. \ prefix(nat)})" apply (rule guaranteesI) apply (blast intro: progress_lemma, auto) done lemma client_prog_Allowed: "Allowed(client_prog) = preserves(lift(rel)) \ preserves(lift(ask)) \ preserves(lift(tok))" apply (cut_tac v = "lift (ask)" in preserves_type) apply (auto simp add: Allowed_def client_prog_def [THEN def_prg_Allowed] cons_Int_distrib safety_prop_Acts_iff) done end diff --git a/src/ZF/UNITY/Comp.thy b/src/ZF/UNITY/Comp.thy --- a/src/ZF/UNITY/Comp.thy +++ b/src/ZF/UNITY/Comp.thy @@ -1,342 +1,342 @@ (* Title: ZF/UNITY/Comp.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 1998 University of Cambridge From Chandy and Sanders, "Reasoning About Program Composition", Technical Report 2000-003, University of Florida, 2000. Revised by Sidi Ehmety on January 2001 Added: a strong form of the order relation over component and localize Theory ported from HOL. *) section\Composition\ theory Comp imports Union Increasing begin definition component :: "[i,i]\o" (infixl \component\ 65) where "F component H \ (\G. F \ G = H)" definition strict_component :: "[i,i]\o" (infixl \strict'_component\ 65) where "F strict_component H \ F component H \ F\H" definition (* A stronger form of the component relation *) component_of :: "[i,i]\o" (infixl \component'_of\ 65) where "F component_of H \ (\G. F ok G \ F \ G = H)" definition strict_component_of :: "[i,i]\o" (infixl \strict'_component'_of\ 65) where "F strict_component_of H \ F component_of H \ F\H" definition (* Preserves a state function f, in particular a variable *) preserves :: "(i\i)\i" where "preserves(f) \ {F:program. \z. F: stable({s:state. f(s) = z})}" definition fun_pair :: "[i\i, i \i] \(i\i)" where "fun_pair(f, g) \ \x. " definition localize :: "[i\i, i] \ i" where "localize(f,F) \ mk_program(Init(F), Acts(F), AllowedActs(F) \ (\G\preserves(f). Acts(G)))" (*** component and strict_component relations ***) lemma componentI: "H component F | H component G \ H component (F \ G)" apply (unfold component_def, auto) apply (rule_tac x = "Ga \ G" in exI) apply (rule_tac [2] x = "G \ F" in exI) apply (auto simp add: Join_ac) done lemma component_eq_subset: "G \ program \ (F component G) \ (Init(G) \ Init(F) \ Acts(F) \ Acts(G) \ AllowedActs(G) \ AllowedActs(F))" apply (unfold component_def, auto) apply (rule exI) apply (rule program_equalityI, auto) done lemma component_SKIP [simp]: "F \ program \ SKIP component F" -apply (unfold component_def) + unfolding component_def apply (rule_tac x = F in exI) apply (force intro: Join_SKIP_left) done lemma component_refl [simp]: "F \ program \ F component F" -apply (unfold component_def) + unfolding component_def apply (rule_tac x = F in exI) apply (force intro: Join_SKIP_right) done lemma SKIP_minimal: "F component SKIP \ programify(F) = SKIP" apply (rule program_equalityI) apply (simp_all add: component_eq_subset, blast) done lemma component_Join1: "F component (F \ G)" by (unfold component_def, blast) lemma component_Join2: "G component (F \ G)" -apply (unfold component_def) + unfolding component_def apply (simp (no_asm) add: Join_commute) apply blast done lemma Join_absorb1: "F component G \ F \ G = G" by (auto simp add: component_def Join_left_absorb) lemma Join_absorb2: "G component F \ F \ G = F" by (auto simp add: Join_ac component_def) lemma JOIN_component_iff: "H \ program\(JOIN(I,F) component H) \ (\i \ I. F(i) component H)" apply (case_tac "I=0", force) apply (simp (no_asm_simp) add: component_eq_subset) apply auto apply blast apply (rename_tac "y") apply (drule_tac c = y and A = "AllowedActs (H)" in subsetD) apply (blast elim!: not_emptyE)+ done lemma component_JOIN: "i \ I \ F(i) component (\i \ I. (F(i)))" -apply (unfold component_def) + unfolding component_def apply (blast intro: JOIN_absorb) done lemma component_trans: "\F component G; G component H\ \ F component H" -apply (unfold component_def) + unfolding component_def apply (blast intro: Join_assoc [symmetric]) done lemma component_antisym: "\F \ program; G \ program\ \(F component G \ G component F) \ F = G" apply (simp (no_asm_simp) add: component_eq_subset) apply clarify apply (rule program_equalityI, auto) done lemma Join_component_iff: "H \ program \ ((F \ G) component H) \ (F component H \ G component H)" apply (simp (no_asm_simp) add: component_eq_subset) apply blast done lemma component_constrains: "\F component G; G \ A co B; F \ program\ \ F \ A co B" apply (frule constrainsD2) apply (auto simp add: constrains_def component_eq_subset) done (*** preserves ***) lemma preserves_is_safety_prop [simp]: "safety_prop(preserves(f))" apply (unfold preserves_def safety_prop_def) apply (auto dest: ActsD simp add: stable_def constrains_def) apply (drule_tac c = act in subsetD, auto) done lemma preservesI [rule_format]: "\z. F \ stable({s \ state. f(s) = z}) \ F \ preserves(f)" apply (auto simp add: preserves_def) apply (blast dest: stableD2) done lemma preserves_imp_eq: "\F \ preserves(f); act \ Acts(F); \s,t\ \ act\ \ f(s) = f(t)" apply (unfold preserves_def stable_def constrains_def) apply (subgoal_tac "s \ state \ t \ state") prefer 2 apply (blast dest!: Acts_type [THEN subsetD], force) done lemma Join_preserves [iff]: "(F \ G \ preserves(v)) \ (programify(F) \ preserves(v) \ programify(G) \ preserves(v))" by (auto simp add: preserves_def INT_iff) lemma JOIN_preserves [iff]: "(JOIN(I,F): preserves(v)) \ (\i \ I. programify(F(i)):preserves(v))" by (auto simp add: JOIN_stable preserves_def INT_iff) lemma SKIP_preserves [iff]: "SKIP \ preserves(v)" by (auto simp add: preserves_def INT_iff) lemma fun_pair_apply [simp]: "fun_pair(f,g,x) = " -apply (unfold fun_pair_def) + unfolding fun_pair_def apply (simp (no_asm)) done lemma preserves_fun_pair: "preserves(fun_pair(v,w)) = preserves(v) \ preserves(w)" apply (rule equalityI) apply (auto simp add: preserves_def stable_def constrains_def, blast+) done lemma preserves_fun_pair_iff [iff]: "F \ preserves(fun_pair(v, w)) \ F \ preserves(v) \ preserves(w)" by (simp add: preserves_fun_pair) lemma fun_pair_comp_distrib: "(fun_pair(f, g) comp h)(x) = fun_pair(f comp h, g comp h, x)" by (simp add: fun_pair_def metacomp_def) lemma comp_apply [simp]: "(f comp g)(x) = f(g(x))" by (simp add: metacomp_def) lemma preserves_type: "preserves(v)<=program" by (unfold preserves_def, auto) lemma preserves_into_program [TC]: "F \ preserves(f) \ F \ program" by (blast intro: preserves_type [THEN subsetD]) lemma subset_preserves_comp: "preserves(f) \ preserves(g comp f)" apply (auto simp add: preserves_def stable_def constrains_def) apply (drule_tac x = "f (xb)" in spec) apply (drule_tac x = act in bspec, auto) done lemma imp_preserves_comp: "F \ preserves(f) \ F \ preserves(g comp f)" by (blast intro: subset_preserves_comp [THEN subsetD]) lemma preserves_subset_stable: "preserves(f) \ stable({s \ state. P(f(s))})" apply (auto simp add: preserves_def stable_def constrains_def) apply (rename_tac s' s) apply (subgoal_tac "f (s) = f (s') ") apply (force+) done lemma preserves_imp_stable: "F \ preserves(f) \ F \ stable({s \ state. P(f(s))})" by (blast intro: preserves_subset_stable [THEN subsetD]) lemma preserves_imp_increasing: "\F \ preserves(f); \x \ state. f(x):A\ \ F \ Increasing.increasing(A, r, f)" apply (unfold Increasing.increasing_def) apply (auto intro: preserves_into_program) apply (rule_tac P = "\x. \k, x\:r" in preserves_imp_stable, auto) done lemma preserves_id_subset_stable: "st_set(A) \ preserves(\x. x) \ stable(A)" apply (unfold preserves_def stable_def constrains_def, auto) apply (drule_tac x = xb in spec) apply (drule_tac x = act in bspec) apply (auto dest: ActsD) done lemma preserves_id_imp_stable: "\F \ preserves(\x. x); st_set(A)\ \ F \ stable(A)" by (blast intro: preserves_id_subset_stable [THEN subsetD]) (** Added by Sidi **) (** component_of **) (* component_of is stronger than component *) lemma component_of_imp_component: "F component_of H \ F component H" apply (unfold component_def component_of_def, blast) done (* component_of satisfies many of component's properties *) lemma component_of_refl [simp]: "F \ program \ F component_of F" -apply (unfold component_of_def) + unfolding component_of_def apply (rule_tac x = SKIP in exI, auto) done lemma component_of_SKIP [simp]: "F \ program \SKIP component_of F" apply (unfold component_of_def, auto) apply (rule_tac x = F in exI, auto) done lemma component_of_trans: "\F component_of G; G component_of H\ \ F component_of H" -apply (unfold component_of_def) + unfolding component_of_def apply (blast intro: Join_assoc [symmetric]) done (** localize **) lemma localize_Init_eq [simp]: "Init(localize(v,F)) = Init(F)" by (unfold localize_def, simp) lemma localize_Acts_eq [simp]: "Acts(localize(v,F)) = Acts(F)" by (unfold localize_def, simp) lemma localize_AllowedActs_eq [simp]: "AllowedActs(localize(v,F)) = AllowedActs(F) \ (\G \ preserves(v). Acts(G))" -apply (unfold localize_def) + unfolding localize_def apply (rule equalityI) apply (auto dest: Acts_type [THEN subsetD]) done (** Theorems used in ClientImpl **) lemma stable_localTo_stable2: "\F \ stable({s \ state. P(f(s), g(s))}); G \ preserves(f); G \ preserves(g)\ \ F \ G \ stable({s \ state. P(f(s), g(s))})" apply (auto dest: ActsD preserves_into_program simp add: stable_def constrains_def) apply (case_tac "act \ Acts (F) ") apply auto apply (drule preserves_imp_eq) apply (drule_tac [3] preserves_imp_eq, auto) done lemma Increasing_preserves_Stable: "\F \ stable({s \ state. :r}); G \ preserves(f); F \ G \ Increasing(A, r, g); \x \ state. f(x):A \ g(x):A\ \ F \ G \ Stable({s \ state. :r})" apply (auto simp add: stable_def Stable_def Increasing_def Constrains_def all_conj_distrib) apply (simp_all add: constrains_type [THEN subsetD] preserves_type [THEN subsetD]) apply (blast intro: constrains_weaken) (*The G case remains*) apply (auto dest: ActsD simp add: preserves_def stable_def constrains_def ball_conj_distrib all_conj_distrib) (*We have a G-action, so delete assumptions about F-actions*) apply (erule_tac V = "\act \ Acts (F). P (act)" for P in thin_rl) apply (erule_tac V = "\k\A. \act \ Acts (F) . P (k,act)" for P in thin_rl) apply (subgoal_tac "f (x) = f (xa) ") apply (auto dest!: bspec) done (** Lemma used in AllocImpl **) lemma Constrains_UN_left: "\\x \ I. F \ A(x) Co B; F \ program\ \ F:(\x \ I. A(x)) Co B" by (unfold Constrains_def constrains_def, auto) lemma stable_Join_Stable: "\F \ stable({s \ state. P(f(s), g(s))}); \k \ A. F \ G \ Stable({s \ state. P(k, g(s))}); G \ preserves(f); \s \ state. f(s):A\ \ F \ G \ Stable({s \ state. P(f(s), g(s))})" apply (unfold stable_def Stable_def preserves_def) apply (rule_tac A = "(\k \ A. {s \ state. f(s)=k} \ {s \ state. P (f (s), g (s))})" in Constrains_weaken_L) prefer 2 apply blast apply (rule Constrains_UN_left, auto) apply (rule_tac A = "{s \ state. f(s)=k} \ {s \ state. P (f (s), g (s))} \ {s \ state. P (k, g (s))}" and A' = "({s \ state. f(s)=k} \ {s \ state. P (f (s), g (s))}) \ {s \ state. P (k, g (s))}" in Constrains_weaken) prefer 2 apply blast prefer 2 apply blast apply (rule Constrains_Int) apply (rule constrains_imp_Constrains) apply (auto simp add: constrains_type [THEN subsetD]) apply (blast intro: constrains_weaken) apply (drule_tac x = k in spec) apply (blast intro: constrains_weaken) done end diff --git a/src/ZF/UNITY/Constrains.thy b/src/ZF/UNITY/Constrains.thy --- a/src/ZF/UNITY/Constrains.thy +++ b/src/ZF/UNITY/Constrains.thy @@ -1,507 +1,507 @@ (* Title: ZF/UNITY/Constrains.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge *) section\Weak Safety Properties\ theory Constrains imports UNITY begin consts traces :: "[i, i] \ i" (* Initial states and program \ (final state, reversed trace to it)... the domain may also be state*list(state) *) inductive domains "traces(init, acts)" <= "(init \ (\act\acts. field(act)))*list(\act\acts. field(act))" intros (*Initial trace is empty*) Init: "s: init \ \ traces(init,acts)" Acts: "\act:acts; \s,evs\ \ traces(init,acts); : act\ \ \ traces(init, acts)" type_intros list.intros UnI1 UnI2 UN_I fieldI2 fieldI1 consts reachable :: "i\i" inductive domains "reachable(F)" \ "Init(F) \ (\act\Acts(F). field(act))" intros Init: "s:Init(F) \ s:reachable(F)" Acts: "\act: Acts(F); s:reachable(F); : act\ \ s':reachable(F)" type_intros UnI1 UnI2 fieldI2 UN_I definition Constrains :: "[i,i] \ i" (infixl \Co\ 60) where "A Co B \ {F:program. F:(reachable(F) \ A) co B}" definition op_Unless :: "[i, i] \ i" (infixl \Unless\ 60) where "A Unless B \ (A-B) Co (A \ B)" definition Stable :: "i \ i" where "Stable(A) \ A Co A" definition (*Always is the weak form of "invariant"*) Always :: "i \ i" where "Always(A) \ initially(A) \ Stable(A)" (*** traces and reachable ***) lemma reachable_type: "reachable(F) \ state" apply (cut_tac F = F in Init_type) apply (cut_tac F = F in Acts_type) apply (cut_tac F = F in reachable.dom_subset, blast) done lemma st_set_reachable: "st_set(reachable(F))" -apply (unfold st_set_def) + unfolding st_set_def apply (rule reachable_type) done declare st_set_reachable [iff] lemma reachable_Int_state: "reachable(F) \ state = reachable(F)" by (cut_tac reachable_type, auto) declare reachable_Int_state [iff] lemma state_Int_reachable: "state \ reachable(F) = reachable(F)" by (cut_tac reachable_type, auto) declare state_Int_reachable [iff] lemma reachable_equiv_traces: "F \ program \ reachable(F)={s \ state. \evs. \s,evs\:traces(Init(F), Acts(F))}" apply (rule equalityI, safe) apply (blast dest: reachable_type [THEN subsetD]) apply (erule_tac [2] traces.induct) apply (erule reachable.induct) apply (blast intro: reachable.intros traces.intros)+ done lemma Init_into_reachable: "Init(F) \ reachable(F)" by (blast intro: reachable.intros) lemma stable_reachable: "\F \ program; G \ program; Acts(G) \ Acts(F)\ \ G \ stable(reachable(F))" apply (blast intro: stableI constrainsI st_setI reachable_type [THEN subsetD] reachable.intros) done declare stable_reachable [intro!] declare stable_reachable [simp] (*The set of all reachable states is an invariant...*) lemma invariant_reachable: "F \ program \ F \ invariant(reachable(F))" apply (unfold invariant_def initially_def) apply (blast intro: reachable_type [THEN subsetD] reachable.intros) done (*...in fact the strongest invariant!*) lemma invariant_includes_reachable: "F \ invariant(A) \ reachable(F) \ A" apply (cut_tac F = F in Acts_type) apply (cut_tac F = F in Init_type) apply (cut_tac F = F in reachable_type) apply (simp (no_asm_use) add: stable_def constrains_def invariant_def initially_def) apply (rule subsetI) apply (erule reachable.induct) apply (blast intro: reachable.intros)+ done (*** Co ***) lemma constrains_reachable_Int: "F \ B co B'\F:(reachable(F) \ B) co (reachable(F) \ B')" apply (frule constrains_type [THEN subsetD]) apply (frule stable_reachable [OF _ _ subset_refl]) apply (simp_all add: stable_def constrains_Int) done (*Resembles the previous definition of Constrains*) lemma Constrains_eq_constrains: "A Co B = {F \ program. F:(reachable(F) \ A) co (reachable(F) \ B)}" -apply (unfold Constrains_def) + unfolding Constrains_def apply (blast dest: constrains_reachable_Int constrains_type [THEN subsetD] intro: constrains_weaken) done lemmas Constrains_def2 = Constrains_eq_constrains [THEN eq_reflection] lemma constrains_imp_Constrains: "F \ A co A' \ F \ A Co A'" -apply (unfold Constrains_def) + unfolding Constrains_def apply (blast intro: constrains_weaken_L dest: constrainsD2) done lemma ConstrainsI: "\\act s s'. \act \ Acts(F); :act; s \ A\ \ s':A'; F \ program\ \ F \ A Co A'" apply (auto simp add: Constrains_def constrains_def st_set_def) apply (blast dest: reachable_type [THEN subsetD]) done lemma Constrains_type: "A Co B \ program" apply (unfold Constrains_def, blast) done lemma Constrains_empty: "F \ 0 Co B \ F \ program" by (auto dest: Constrains_type [THEN subsetD] intro: constrains_imp_Constrains) declare Constrains_empty [iff] lemma Constrains_state: "F \ A Co state \ F \ program" -apply (unfold Constrains_def) + unfolding Constrains_def apply (auto dest: Constrains_type [THEN subsetD] intro: constrains_imp_Constrains) done declare Constrains_state [iff] lemma Constrains_weaken_R: "\F \ A Co A'; A'<=B'\ \ F \ A Co B'" -apply (unfold Constrains_def2) + unfolding Constrains_def2 apply (blast intro: constrains_weaken_R) done lemma Constrains_weaken_L: "\F \ A Co A'; B<=A\ \ F \ B Co A'" -apply (unfold Constrains_def2) + unfolding Constrains_def2 apply (blast intro: constrains_weaken_L st_set_subset) done lemma Constrains_weaken: "\F \ A Co A'; B<=A; A'<=B'\ \ F \ B Co B'" -apply (unfold Constrains_def2) + unfolding Constrains_def2 apply (blast intro: constrains_weaken st_set_subset) done (** Union **) lemma Constrains_Un: "\F \ A Co A'; F \ B Co B'\ \ F \ (A \ B) Co (A' \ B')" apply (unfold Constrains_def2, auto) apply (simp add: Int_Un_distrib) apply (blast intro: constrains_Un) done lemma Constrains_UN: "\(\i. i \ I\F \ A(i) Co A'(i)); F \ program\ \ F:(\i \ I. A(i)) Co (\i \ I. A'(i))" by (auto intro: constrains_UN simp del: UN_simps simp add: Constrains_def2 Int_UN_distrib) (** Intersection **) lemma Constrains_Int: "\F \ A Co A'; F \ B Co B'\\ F:(A \ B) Co (A' \ B')" -apply (unfold Constrains_def) + unfolding Constrains_def apply (subgoal_tac "reachable (F) \ (A \ B) = (reachable (F) \ A) \ (reachable (F) \ B) ") apply (auto intro: constrains_Int) done lemma Constrains_INT: "\(\i. i \ I \F \ A(i) Co A'(i)); F \ program\ \ F:(\i \ I. A(i)) Co (\i \ I. A'(i))" apply (simp (no_asm_simp) del: INT_simps add: Constrains_def INT_extend_simps) apply (rule constrains_INT) apply (auto simp add: Constrains_def) done lemma Constrains_imp_subset: "F \ A Co A' \ reachable(F) \ A \ A'" -apply (unfold Constrains_def) + unfolding Constrains_def apply (blast dest: constrains_imp_subset) done lemma Constrains_trans: "\F \ A Co B; F \ B Co C\ \ F \ A Co C" -apply (unfold Constrains_def2) + unfolding Constrains_def2 apply (blast intro: constrains_trans constrains_weaken) done lemma Constrains_cancel: "\F \ A Co (A' \ B); F \ B Co B'\ \ F \ A Co (A' \ B')" -apply (unfold Constrains_def2) + unfolding Constrains_def2 apply (simp (no_asm_use) add: Int_Un_distrib) apply (blast intro: constrains_cancel) done (*** Stable ***) (* Useful because there's no Stable_weaken. [Tanja Vos] *) lemma stable_imp_Stable: "F \ stable(A) \ F \ Stable(A)" apply (unfold stable_def Stable_def) apply (erule constrains_imp_Constrains) done lemma Stable_eq: "\F \ Stable(A); A = B\ \ F \ Stable(B)" by blast lemma Stable_eq_stable: "F \ Stable(A) \ (F \ stable(reachable(F) \ A))" apply (auto dest: constrainsD2 simp add: Stable_def stable_def Constrains_def2) done lemma StableI: "F \ A Co A \ F \ Stable(A)" by (unfold Stable_def, assumption) lemma StableD: "F \ Stable(A) \ F \ A Co A" by (unfold Stable_def, assumption) lemma Stable_Un: "\F \ Stable(A); F \ Stable(A')\ \ F \ Stable(A \ A')" -apply (unfold Stable_def) + unfolding Stable_def apply (blast intro: Constrains_Un) done lemma Stable_Int: "\F \ Stable(A); F \ Stable(A')\ \ F \ Stable (A \ A')" -apply (unfold Stable_def) + unfolding Stable_def apply (blast intro: Constrains_Int) done lemma Stable_Constrains_Un: "\F \ Stable(C); F \ A Co (C \ A')\ \ F \ (C \ A) Co (C \ A')" -apply (unfold Stable_def) + unfolding Stable_def apply (blast intro: Constrains_Un [THEN Constrains_weaken_R]) done lemma Stable_Constrains_Int: "\F \ Stable(C); F \ (C \ A) Co A'\ \ F \ (C \ A) Co (C \ A')" -apply (unfold Stable_def) + unfolding Stable_def apply (blast intro: Constrains_Int [THEN Constrains_weaken]) done lemma Stable_UN: "\(\i. i \ I \ F \ Stable(A(i))); F \ program\ \ F \ Stable (\i \ I. A(i))" apply (simp add: Stable_def) apply (blast intro: Constrains_UN) done lemma Stable_INT: "\(\i. i \ I \ F \ Stable(A(i))); F \ program\ \ F \ Stable (\i \ I. A(i))" apply (simp add: Stable_def) apply (blast intro: Constrains_INT) done lemma Stable_reachable: "F \ program \F \ Stable (reachable(F))" apply (simp (no_asm_simp) add: Stable_eq_stable Int_absorb) done lemma Stable_type: "Stable(A) \ program" -apply (unfold Stable_def) + unfolding Stable_def apply (rule Constrains_type) done (*** The Elimination Theorem. The "free" m has become universally quantified! Should the premise be \m instead of \m ? Would make it harder to use in forward proof. ***) lemma Elimination: "\\m \ M. F \ ({s \ A. x(s) = m}) Co (B(m)); F \ program\ \ F \ ({s \ A. x(s):M}) Co (\m \ M. B(m))" apply (unfold Constrains_def, auto) apply (rule_tac A1 = "reachable (F) \ A" in UNITY.elimination [THEN constrains_weaken_L]) apply (auto intro: constrains_weaken_L) done (* As above, but for the special case of A=state *) lemma Elimination2: "\\m \ M. F \ {s \ state. x(s) = m} Co B(m); F \ program\ \ F \ {s \ state. x(s):M} Co (\m \ M. B(m))" apply (blast intro: Elimination) done (** Unless **) lemma Unless_type: "A Unless B <=program" -apply (unfold op_Unless_def) + unfolding op_Unless_def apply (rule Constrains_type) done (*** Specialized laws for handling Always ***) (** Natural deduction rules for "Always A" **) lemma AlwaysI: "\Init(F)<=A; F \ Stable(A)\ \ F \ Always(A)" apply (unfold Always_def initially_def) apply (frule Stable_type [THEN subsetD], auto) done lemma AlwaysD: "F \ Always(A) \ Init(F)<=A \ F \ Stable(A)" by (simp add: Always_def initially_def) lemmas AlwaysE = AlwaysD [THEN conjE] lemmas Always_imp_Stable = AlwaysD [THEN conjunct2] (*The set of all reachable states is Always*) lemma Always_includes_reachable: "F \ Always(A) \ reachable(F) \ A" apply (simp (no_asm_use) add: Stable_def Constrains_def constrains_def Always_def initially_def) apply (rule subsetI) apply (erule reachable.induct) apply (blast intro: reachable.intros)+ done lemma invariant_imp_Always: "F \ invariant(A) \ F \ Always(A)" apply (unfold Always_def invariant_def Stable_def stable_def) apply (blast intro: constrains_imp_Constrains) done lemmas Always_reachable = invariant_reachable [THEN invariant_imp_Always] lemma Always_eq_invariant_reachable: "Always(A) = {F \ program. F \ invariant(reachable(F) \ A)}" apply (simp (no_asm) add: Always_def invariant_def Stable_def Constrains_def2 stable_def initially_def) apply (rule equalityI, auto) apply (blast intro: reachable.intros reachable_type) done (*the RHS is the traditional definition of the "always" operator*) lemma Always_eq_includes_reachable: "Always(A) = {F \ program. reachable(F) \ A}" apply (rule equalityI, safe) apply (auto dest: invariant_includes_reachable simp add: subset_Int_iff invariant_reachable Always_eq_invariant_reachable) done lemma Always_type: "Always(A) \ program" by (unfold Always_def initially_def, auto) lemma Always_state_eq: "Always(state) = program" apply (rule equalityI) apply (auto dest: Always_type [THEN subsetD] reachable_type [THEN subsetD] simp add: Always_eq_includes_reachable) done declare Always_state_eq [simp] lemma state_AlwaysI: "F \ program \ F \ Always(state)" by (auto dest: reachable_type [THEN subsetD] simp add: Always_eq_includes_reachable) lemma Always_eq_UN_invariant: "st_set(A) \ Always(A) = (\I \ Pow(A). invariant(I))" apply (simp (no_asm) add: Always_eq_includes_reachable) apply (rule equalityI, auto) apply (blast intro: invariantI rev_subsetD [OF _ Init_into_reachable] rev_subsetD [OF _ invariant_includes_reachable] dest: invariant_type [THEN subsetD])+ done lemma Always_weaken: "\F \ Always(A); A \ B\ \ F \ Always(B)" by (auto simp add: Always_eq_includes_reachable) (*** "Co" rules involving Always ***) lemmas Int_absorb2 = subset_Int_iff [unfolded iff_def, THEN conjunct1, THEN mp] lemma Always_Constrains_pre: "F \ Always(I) \ (F:(I \ A) Co A') \ (F \ A Co A')" apply (simp (no_asm_simp) add: Always_includes_reachable [THEN Int_absorb2] Constrains_def Int_assoc [symmetric]) done lemma Always_Constrains_post: "F \ Always(I) \ (F \ A Co (I \ A')) \(F \ A Co A')" apply (simp (no_asm_simp) add: Always_includes_reachable [THEN Int_absorb2] Constrains_eq_constrains Int_assoc [symmetric]) done lemma Always_ConstrainsI: "\F \ Always(I); F \ (I \ A) Co A'\ \ F \ A Co A'" by (blast intro: Always_Constrains_pre [THEN iffD1]) (* \F \ Always(I); F \ A Co A'\ \ F \ A Co (I \ A') *) lemmas Always_ConstrainsD = Always_Constrains_post [THEN iffD2] (*The analogous proof of Always_LeadsTo_weaken doesn't terminate*) lemma Always_Constrains_weaken: "\F \ Always(C); F \ A Co A'; C \ B<=A; C \ A'<=B'\\F \ B Co B'" apply (rule Always_ConstrainsI) apply (drule_tac [2] Always_ConstrainsD, simp_all) apply (blast intro: Constrains_weaken) done (** Conjoining Always properties **) lemma Always_Int_distrib: "Always(A \ B) = Always(A) \ Always(B)" by (auto simp add: Always_eq_includes_reachable) (* the premise i \ I is need since \is formally not defined for I=0 *) lemma Always_INT_distrib: "i \ I\Always(\i \ I. A(i)) = (\i \ I. Always(A(i)))" apply (rule equalityI) apply (auto simp add: Inter_iff Always_eq_includes_reachable) done lemma Always_Int_I: "\F \ Always(A); F \ Always(B)\ \ F \ Always(A \ B)" apply (simp (no_asm_simp) add: Always_Int_distrib) done (*Allows a kind of "implication introduction"*) lemma Always_Diff_Un_eq: "\F \ Always(A)\ \ (F \ Always(C-A \ B)) \ (F \ Always(B))" by (auto simp add: Always_eq_includes_reachable) (*Delete the nearest invariance assumption (which will be the second one used by Always_Int_I) *) lemmas Always_thin = thin_rl [of "F \ Always(A)"] for F A (*To allow expansion of the program's definition when appropriate*) named_theorems program "program definitions" ML \ (*Combines two invariance ASSUMPTIONS into one. USEFUL??*) fun Always_Int_tac ctxt = dresolve_tac ctxt @{thms Always_Int_I} THEN' assume_tac ctxt THEN' eresolve_tac ctxt @{thms Always_thin}; (*Combines a list of invariance THEOREMS into one.*) val Always_Int_rule = foldr1 (fn (th1,th2) => [th1,th2] MRS @{thm Always_Int_I}); (*proves "co" properties when the program is specified*) fun constrains_tac ctxt = SELECT_GOAL (EVERY [REPEAT (Always_Int_tac ctxt 1), REPEAT (eresolve_tac ctxt @{thms Always_ConstrainsI} 1 ORELSE resolve_tac ctxt [@{thm StableI}, @{thm stableI}, @{thm constrains_imp_Constrains}] 1), resolve_tac ctxt @{thms constrainsI} 1, (* Three subgoals *) rewrite_goal_tac ctxt [@{thm st_set_def}] 3, REPEAT (force_tac ctxt 2), full_simp_tac (ctxt addsimps (Named_Theorems.get ctxt \<^named_theorems>\program\)) 1, ALLGOALS (clarify_tac ctxt), REPEAT (FIRSTGOAL (eresolve_tac ctxt @{thms disjE})), ALLGOALS (clarify_tac ctxt), REPEAT (FIRSTGOAL (eresolve_tac ctxt @{thms disjE})), ALLGOALS (clarify_tac ctxt), ALLGOALS (asm_full_simp_tac ctxt), ALLGOALS (clarify_tac ctxt)]); (*For proving invariants*) fun always_tac ctxt i = resolve_tac ctxt @{thms AlwaysI} i THEN force_tac ctxt i THEN constrains_tac ctxt i; \ method_setup safety = \ Scan.succeed (SIMPLE_METHOD' o constrains_tac)\ "for proving safety properties" method_setup always = \ Scan.succeed (SIMPLE_METHOD' o always_tac)\ "for proving invariants" end diff --git a/src/ZF/UNITY/Distributor.thy b/src/ZF/UNITY/Distributor.thy --- a/src/ZF/UNITY/Distributor.thy +++ b/src/ZF/UNITY/Distributor.thy @@ -1,166 +1,166 @@ (* Title: ZF/UNITY/Distributor.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2002 University of Cambridge A multiple-client allocator from a single-client allocator: Distributor specification. *) theory Distributor imports AllocBase Follows Guar GenPrefix begin text\Distributor specification (the number of outputs is Nclients)\ text\spec (14)\ definition distr_follows :: "[i, i, i, i \i] \i" where "distr_follows(A, In, iIn, Out) \ (lift(In) IncreasingWrt prefix(A)/list(A)) \ (lift(iIn) IncreasingWrt prefix(nat)/list(nat)) \ Always({s \ state. \elt \ set_of_list(s`iIn). elt < Nclients}) guarantees (\n \ Nclients. lift(Out(n)) Fols (\s. sublist(s`In, {k \ nat. k nth(k, s`iIn) = n})) Wrt prefix(A)/list(A))" definition distr_allowed_acts :: "[i\i]\i" where "distr_allowed_acts(Out) \ {D \ program. AllowedActs(D) = cons(id(state), \G \ (\n\nat. preserves(lift(Out(n)))). Acts(G))}" definition distr_spec :: "[i, i, i, i \i]\i" where "distr_spec(A, In, iIn, Out) \ distr_follows(A, In, iIn, Out) \ distr_allowed_acts(Out)" locale distr = fixes In \ \items to distribute\ and iIn \ \destinations of items to distribute\ and Out \ \distributed items\ and A \ \the type of items being distributed\ and D assumes var_assumes [simp]: "In \ var \ iIn \ var \ (\n. Out(n):var)" and all_distinct_vars: "\n. all_distinct([In, iIn, Out(n)])" and type_assumes [simp]: "type_of(In)=list(A) \ type_of(iIn)=list(nat) \ (\n. type_of(Out(n))=list(A))" and default_val_assumes [simp]: "default_val(In)=Nil \ default_val(iIn)=Nil \ (\n. default_val(Out(n))=Nil)" and distr_spec: "D \ distr_spec(A, In, iIn, Out)" lemma (in distr) In_value_type [simp,TC]: "s \ state \ s`In \ list(A)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = In in apply_type, auto) done lemma (in distr) iIn_value_type [simp,TC]: "s \ state \ s`iIn \ list(nat)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = iIn in apply_type, auto) done lemma (in distr) Out_value_type [simp,TC]: "s \ state \ s`Out(n):list(A)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = "Out (n)" in apply_type) apply auto done lemma (in distr) D_in_program [simp,TC]: "D \ program" apply (cut_tac distr_spec) apply (auto simp add: distr_spec_def distr_allowed_acts_def) done lemma (in distr) D_ok_iff: "G \ program \ D ok G \ ((\n \ nat. G \ preserves(lift(Out(n)))) \ D \ Allowed(G))" apply (cut_tac distr_spec) apply (auto simp add: INT_iff distr_spec_def distr_allowed_acts_def Allowed_def ok_iff_Allowed) apply (drule safety_prop_Acts_iff [THEN [2] rev_iffD1]) apply (auto intro: safety_prop_Inter) done lemma (in distr) distr_Increasing_Out: "D \ ((lift(In) IncreasingWrt prefix(A)/list(A)) \ (lift(iIn) IncreasingWrt prefix(nat)/list(nat)) \ Always({s \ state. \elt \ set_of_list(s`iIn). eltn \ Nclients. lift(Out(n)) IncreasingWrt prefix(A)/list(A))" apply (cut_tac D_in_program distr_spec) apply (simp (no_asm_use) add: distr_spec_def distr_follows_def) apply (auto intro!: guaranteesI intro: Follows_imp_Increasing_left dest!: guaranteesD) done lemma (in distr) distr_bag_Follows_lemma: "\\n \ nat. G \ preserves(lift(Out(n))); D \ G \ Always({s \ state. \elt \ set_of_list(s`iIn). elt < Nclients})\ \ D \ G \ Always ({s \ state. msetsum(\n. bag_of (sublist(s`In, {k \ nat. k < length(s`iIn) \ nth(k, s`iIn)= n})), Nclients, A) = bag_of(sublist(s`In, length(s`iIn)))})" apply (cut_tac D_in_program) apply (subgoal_tac "G \ program") prefer 2 apply (blast dest: preserves_type [THEN subsetD]) apply (erule Always_Diff_Un_eq [THEN iffD1]) apply (rule state_AlwaysI [THEN Always_weaken], auto) apply (rename_tac s) apply (subst bag_of_sublist_UN_disjoint [symmetric]) apply (simp (no_asm_simp) add: nat_into_Finite) apply blast apply (simp (no_asm_simp)) apply (simp add: set_of_list_conv_nth [of _ nat]) apply (subgoal_tac "(\i \ Nclients. {k\nat. k < length(s`iIn) \ nth(k, s`iIn) = i}) = length(s`iIn) ") apply (simp (no_asm_simp)) apply (rule equalityI) apply (force simp add: ltD, safe) apply (rename_tac m) apply (subgoal_tac "length (s ` iIn) \ nat") apply typecheck apply (subgoal_tac "m \ nat") apply (drule_tac x = "nth(m, s`iIn) " and P = "\elt. X (elt) \ elt ((lift(In) IncreasingWrt prefix(A)/list(A)) \ (lift(iIn) IncreasingWrt prefix(nat)/list(nat)) \ Always({s \ state. \elt \ set_of_list(s`iIn). elt < Nclients})) guarantees (\n \ Nclients. (\s. msetsum(\i. bag_of(s`Out(i)), Nclients, A)) Fols (\s. bag_of(sublist(s`In, length(s`iIn)))) Wrt MultLe(A, r)/Mult(A))" apply (cut_tac distr_spec) apply (rule guaranteesI, clarify) apply (rule distr_bag_Follows_lemma [THEN Always_Follows2]) apply (simp add: D_ok_iff, auto) apply (rule Follows_state_ofD1) apply (rule Follows_msetsum_UN) apply (simp_all add: nat_into_Finite bag_of_multiset [of _ A]) apply (auto simp add: distr_spec_def distr_follows_def) apply (drule guaranteesD, assumption) apply (simp_all cong add: Follows_cong add: refl_prefix mono_bag_of [THEN subset_Follows_comp, THEN subsetD, unfolded metacomp_def]) done end diff --git a/src/ZF/UNITY/FP.thy b/src/ZF/UNITY/FP.thy --- a/src/ZF/UNITY/FP.thy +++ b/src/ZF/UNITY/FP.thy @@ -1,83 +1,83 @@ (* Title: ZF/UNITY/FP.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge From Misra, "A Logic for Concurrent Programming", 1994 Theory ported from HOL. *) section\Fixed Point of a Program\ theory FP imports UNITY begin definition FP_Orig :: "i\i" where "FP_Orig(F) \ \({A \ Pow(state). \B. F \ stable(A \ B)})" definition FP :: "i\i" where "FP(F) \ {s\state. F \ stable({s})}" lemma FP_Orig_type: "FP_Orig(F) \ state" by (unfold FP_Orig_def, blast) lemma st_set_FP_Orig [iff]: "st_set(FP_Orig(F))" -apply (unfold st_set_def) + unfolding st_set_def apply (rule FP_Orig_type) done lemma FP_type: "FP(F) \ state" by (unfold FP_def, blast) lemma st_set_FP [iff]: "st_set(FP(F))" -apply (unfold st_set_def) + unfolding st_set_def apply (rule FP_type) done lemma stable_FP_Orig_Int: "F \ program \ F \ stable(FP_Orig(F) \ B)" apply (simp only: FP_Orig_def stable_def Int_Union2) apply (blast intro: constrains_UN) done lemma FP_Orig_weakest2: "\\B. F \ stable (A \ B); st_set(A)\ \ A \ FP_Orig(F)" by (unfold FP_Orig_def stable_def st_set_def, blast) lemmas FP_Orig_weakest = allI [THEN FP_Orig_weakest2] lemma stable_FP_Int: "F \ program \ F \ stable (FP(F) \ B)" apply (subgoal_tac "FP (F) \ B = (\x\B. FP (F) \ {x}) ") prefer 2 apply blast apply (simp (no_asm_simp) add: Int_cons_right) apply (unfold FP_def stable_def) apply (rule constrains_UN) apply (auto simp add: cons_absorb) done lemma FP_subset_FP_Orig: "F \ program \ FP(F) \ FP_Orig(F)" by (rule stable_FP_Int [THEN FP_Orig_weakest], auto) lemma FP_Orig_subset_FP: "F \ program \ FP_Orig(F) \ FP(F)" apply (unfold FP_Orig_def FP_def, clarify) apply (drule_tac x = "{x}" in spec) apply (simp add: Int_cons_right) apply (frule stableD2) apply (auto simp add: cons_absorb st_set_def) done lemma FP_equivalence: "F \ program \ FP(F) = FP_Orig(F)" by (blast intro!: FP_Orig_subset_FP FP_subset_FP_Orig) lemma FP_weakest [rule_format]: "\\B. F \ stable(A \ B); F \ program; st_set(A)\ \ A \ FP(F)" by (simp add: FP_equivalence FP_Orig_weakest) lemma Diff_FP: "\F \ program; st_set(A)\ \ A-FP(F) = (\act \ Acts(F). A - {s \ state. act``{s} \ {s}})" by (unfold FP_def stable_def constrains_def st_set_def, blast) end diff --git a/src/ZF/UNITY/Follows.thy b/src/ZF/UNITY/Follows.thy --- a/src/ZF/UNITY/Follows.thy +++ b/src/ZF/UNITY/Follows.thy @@ -1,475 +1,475 @@ (* Title: ZF/UNITY/Follows.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2002 University of Cambridge Theory ported from HOL. *) section\The "Follows" relation of Charpentier and Sivilotte\ theory Follows imports SubstAx Increasing begin definition Follows :: "[i, i, i\i, i\i] \ i" where "Follows(A, r, f, g) \ Increasing(A, r, g) Int Increasing(A, r,f) Int Always({s \ state. :r}) Int (\k \ A. {s \ state. :r} \w {s \ state. :r})" abbreviation Incr :: "[i\i]\i" where "Incr(f) \ Increasing(list(nat), prefix(nat), f)" abbreviation n_Incr :: "[i\i]\i" where "n_Incr(f) \ Increasing(nat, Le, f)" abbreviation s_Incr :: "[i\i]\i" where "s_Incr(f) \ Increasing(Pow(nat), SetLe(nat), f)" abbreviation m_Incr :: "[i\i]\i" where "m_Incr(f) \ Increasing(Mult(nat), MultLe(nat, Le), f)" abbreviation n_Fols :: "[i\i, i\i]\i" (infixl \n'_Fols\ 65) where "f n_Fols g \ Follows(nat, Le, f, g)" abbreviation Follows' :: "[i\i, i\i, i, i] \ i" (\(_ /Fols _ /Wrt (_ /'/ _))\ [60, 0, 0, 60] 60) where "f Fols g Wrt r/A \ Follows(A,r,f,g)" (*Does this hold for "invariant"?*) lemma Follows_cong: "\A=A'; r=r'; \x. x \ state \ f(x)=f'(x); \x. x \ state \ g(x)=g'(x)\ \ Follows(A, r, f, g) = Follows(A', r', f', g')" by (simp add: Increasing_def Follows_def) lemma subset_Always_comp: "\mono1(A, r, B, s, h); \x \ state. f(x):A \ g(x):A\ \ Always({x \ state. \ r})<=Always({x \ state. <(h comp f)(x), (h comp g)(x)> \ s})" apply (unfold mono1_def metacomp_def) apply (auto simp add: Always_eq_includes_reachable) done lemma imp_Always_comp: "\F \ Always({x \ state. \ r}); mono1(A, r, B, s, h); \x \ state. f(x):A \ g(x):A\ \ F \ Always({x \ state. <(h comp f)(x), (h comp g)(x)> \ s})" by (blast intro: subset_Always_comp [THEN subsetD]) lemma imp_Always_comp2: "\F \ Always({x \ state. \ r}); F \ Always({x \ state. \ s}); mono2(A, r, B, s, C, t, h); \x \ state. f1(x):A \ f(x):A \ g1(x):B \ g(x):B\ \ F \ Always({x \ state. \ t})" apply (auto simp add: Always_eq_includes_reachable mono2_def) apply (auto dest!: subsetD) done (* comp LeadsTo *) lemma subset_LeadsTo_comp: "\mono1(A, r, B, s, h); refl(A,r); trans[B](s); \x \ state. f(x):A \ g(x):A\ \ (\j \ A. {s \ state. \ r} \w {s \ state. \ r}) <= (\k \ B. {x \ state. \ s} \w {x \ state. \ s})" apply (unfold mono1_def metacomp_def, clarify) apply (simp_all (no_asm_use) add: INT_iff) apply auto apply (rule single_LeadsTo_I) prefer 2 apply (blast dest: LeadsTo_type [THEN subsetD], auto) apply (rotate_tac 5) apply (drule_tac x = "g (sa) " in bspec) apply (erule_tac [2] LeadsTo_weaken) apply (auto simp add: part_order_def refl_def) apply (rule_tac b = "h (g (sa))" in trans_onD) apply blast apply auto done lemma imp_LeadsTo_comp: "\F:(\j \ A. {s \ state. \ r} \w {s \ state. \ r}); mono1(A, r, B, s, h); refl(A,r); trans[B](s); \x \ state. f(x):A \ g(x):A\ \ F:(\k \ B. {x \ state. \ s} \w {x \ state. \ s})" apply (rule subset_LeadsTo_comp [THEN subsetD], auto) done lemma imp_LeadsTo_comp_right: "\F \ Increasing(B, s, g); \j \ A. F: {s \ state. \ r} \w {s \ state. \ r}; mono2(A, r, B, s, C, t, h); refl(A, r); refl(B, s); trans[C](t); \x \ state. f1(x):A \ f(x):A \ g(x):B; k \ C\ \ F:{x \ state. \ t} \w {x \ state. \ t}" apply (unfold mono2_def Increasing_def) apply (rule single_LeadsTo_I, auto) apply (drule_tac x = "g (sa) " and A = B in bspec) apply auto apply (drule_tac x = "f (sa) " and P = "\j. F \ X(j) \w Y(j)" for X Y in bspec) apply auto apply (rule PSP_Stable [THEN LeadsTo_weaken], blast, blast) apply auto apply (force simp add: part_order_def refl_def) apply (force simp add: part_order_def refl_def) apply (drule_tac x = "f1 (x)" and x1 = "f (sa) " and P2 = "\x y. \u\B. P (x,y,u)" for P in bspec [THEN bspec]) apply (drule_tac [3] x = "g (x) " and x1 = "g (sa) " and P2 = "\x y. P (x,y) \ d (x,y) \ t" for P d in bspec [THEN bspec]) apply auto apply (rule_tac b = "h (f (sa), g (sa))" and A = C in trans_onD) apply (auto simp add: part_order_def) done lemma imp_LeadsTo_comp_left: "\F \ Increasing(A, r, f); \j \ B. F: {x \ state. \ s} \w {x \ state. \ s}; mono2(A, r, B, s, C, t, h); refl(A,r); refl(B, s); trans[C](t); \x \ state. f(x):A \ g1(x):B \ g(x):B; k \ C\ \ F:{x \ state. \ t} \w {x \ state. \ t}" apply (unfold mono2_def Increasing_def) apply (rule single_LeadsTo_I, auto) apply (drule_tac x = "f (sa) " and P = "\k. F \ Stable (X (k))" for X in bspec) apply auto apply (drule_tac x = "g (sa) " in bspec) apply auto apply (rule PSP_Stable [THEN LeadsTo_weaken], blast, blast) apply auto apply (force simp add: part_order_def refl_def) apply (force simp add: part_order_def refl_def) apply (drule_tac x = "f (x) " and x1 = "f (sa) " in bspec [THEN bspec]) apply (drule_tac [3] x = "g1 (x) " and x1 = "g (sa) " and P2 = "\x y. P (x,y) \ d (x,y) \ t" for P d in bspec [THEN bspec]) apply auto apply (rule_tac b = "h (f (sa), g (sa))" and A = C in trans_onD) apply (auto simp add: part_order_def) done (** This general result is used to prove Follows Un, munion, etc. **) lemma imp_LeadsTo_comp2: "\F \ Increasing(A, r, f1) \ Increasing(B, s, g); \j \ A. F: {s \ state. \ r} \w {s \ state. \ r}; \j \ B. F: {x \ state. \ s} \w {x \ state. \ s}; mono2(A, r, B, s, C, t, h); refl(A,r); refl(B, s); trans[C](t); \x \ state. f(x):A \ g1(x):B \ f1(x):A \g(x):B; k \ C\ \ F:{x \ state. \ t} \w {x \ state. \ t}" apply (rule_tac B = "{x \ state. \ t}" in LeadsTo_Trans) apply (blast intro: imp_LeadsTo_comp_right) apply (blast intro: imp_LeadsTo_comp_left) done (* Follows type *) lemma Follows_type: "Follows(A, r, f, g)<=program" -apply (unfold Follows_def) + unfolding Follows_def apply (blast dest: Increasing_type [THEN subsetD]) done lemma Follows_into_program [TC]: "F \ Follows(A, r, f, g) \ F \ program" by (blast dest: Follows_type [THEN subsetD]) lemma FollowsD: "F \ Follows(A, r, f, g)\ F \ program \ (\a. a \ A) \ (\x \ state. f(x):A \ g(x):A)" -apply (unfold Follows_def) + unfolding Follows_def apply (blast dest: IncreasingD) done lemma Follows_constantI: "\F \ program; c \ A; refl(A, r)\ \ F \ Follows(A, r, \x. c, \x. c)" apply (unfold Follows_def, auto) apply (auto simp add: refl_def) done lemma subset_Follows_comp: "\mono1(A, r, B, s, h); refl(A, r); trans[B](s)\ \ Follows(A, r, f, g) \ Follows(B, s, h comp f, h comp g)" apply (unfold Follows_def, clarify) apply (frule_tac f = g in IncreasingD) apply (frule_tac f = f in IncreasingD) apply (rule IntI) apply (rule_tac [2] h = h in imp_LeadsTo_comp) prefer 5 apply assumption apply (auto intro: imp_Increasing_comp imp_Always_comp simp del: INT_simps) done lemma imp_Follows_comp: "\F \ Follows(A, r, f, g); mono1(A, r, B, s, h); refl(A, r); trans[B](s)\ \ F \ Follows(B, s, h comp f, h comp g)" apply (blast intro: subset_Follows_comp [THEN subsetD]) done (* 2-place monotone operation \ this general result is used to prove Follows_Un, Follows_munion *) (* 2-place monotone operation \ this general result is used to prove Follows_Un, Follows_munion *) lemma imp_Follows_comp2: "\F \ Follows(A, r, f1, f); F \ Follows(B, s, g1, g); mono2(A, r, B, s, C, t, h); refl(A,r); refl(B, s); trans[C](t)\ \ F \ Follows(C, t, \x. h(f1(x), g1(x)), \x. h(f(x), g(x)))" apply (unfold Follows_def, clarify) apply (frule_tac f = g in IncreasingD) apply (frule_tac f = f in IncreasingD) apply (rule IntI, safe) apply (rule_tac [3] h = h in imp_Always_comp2) prefer 5 apply assumption apply (rule_tac [2] h = h in imp_Increasing_comp2) prefer 4 apply assumption apply (rule_tac h = h in imp_Increasing_comp2) prefer 3 apply assumption apply simp_all apply (blast dest!: IncreasingD) apply (rule_tac h = h in imp_LeadsTo_comp2) prefer 4 apply assumption apply auto prefer 3 apply (simp add: mono2_def) apply (blast dest: IncreasingD)+ done lemma Follows_trans: "\F \ Follows(A, r, f, g); F \ Follows(A,r, g, h); trans[A](r)\ \ F \ Follows(A, r, f, h)" apply (frule_tac f = f in FollowsD) apply (frule_tac f = g in FollowsD) apply (simp add: Follows_def) apply (simp add: Always_eq_includes_reachable INT_iff, auto) apply (rule_tac [2] B = "{s \ state. \ r}" in LeadsTo_Trans) apply (rule_tac b = "g (x) " in trans_onD) apply blast+ done (** Destruction rules for Follows **) lemma Follows_imp_Increasing_left: "F \ Follows(A, r, f,g) \ F \ Increasing(A, r, f)" by (unfold Follows_def, blast) lemma Follows_imp_Increasing_right: "F \ Follows(A, r, f,g) \ F \ Increasing(A, r, g)" by (unfold Follows_def, blast) lemma Follows_imp_Always: "F :Follows(A, r, f, g) \ F \ Always({s \ state. \ r})" by (unfold Follows_def, blast) lemma Follows_imp_LeadsTo: "\F \ Follows(A, r, f, g); k \ A\ \ F: {s \ state. \ r } \w {s \ state. \ r}" by (unfold Follows_def, blast) lemma Follows_LeadsTo_pfixLe: "\F \ Follows(list(nat), gen_prefix(nat, Le), f, g); k \ list(nat)\ \ F \ {s \ state. k pfixLe g(s)} \w {s \ state. k pfixLe f(s)}" by (blast intro: Follows_imp_LeadsTo) lemma Follows_LeadsTo_pfixGe: "\F \ Follows(list(nat), gen_prefix(nat, Ge), f, g); k \ list(nat)\ \ F \ {s \ state. k pfixGe g(s)} \w {s \ state. k pfixGe f(s)}" by (blast intro: Follows_imp_LeadsTo) lemma Always_Follows1: "\F \ Always({s \ state. f(s) = g(s)}); F \ Follows(A, r, f, h); \x \ state. g(x):A\ \ F \ Follows(A, r, g, h)" apply (unfold Follows_def Increasing_def Stable_def) apply (simp add: INT_iff, auto) apply (rule_tac [3] C = "{s \ state. f(s)=g(s)}" and A = "{s \ state. \ r}" and A' = "{s \ state. \ r}" in Always_LeadsTo_weaken) apply (erule_tac A = "{s \ state. \ r}" and A' = "{s \ state. \ r}" in Always_Constrains_weaken) apply auto apply (drule Always_Int_I, assumption) apply (erule_tac A = "{s \ state. f(s)=g(s)} \ {s \ state. \ r}" in Always_weaken) apply auto done lemma Always_Follows2: "\F \ Always({s \ state. g(s) = h(s)}); F \ Follows(A, r, f, g); \x \ state. h(x):A\ \ F \ Follows(A, r, f, h)" apply (unfold Follows_def Increasing_def Stable_def) apply (simp add: INT_iff, auto) apply (rule_tac [3] C = "{s \ state. g (s) =h (s) }" and A = "{s \ state. \ r}" and A' = "{s \ state. \ r}" in Always_LeadsTo_weaken) apply (erule_tac A = "{s \ state. \ r}" and A' = "{s \ state. \ r}" in Always_Constrains_weaken) apply auto apply (drule Always_Int_I, assumption) apply (erule_tac A = "{s \ state. g(s)=h(s)} \ {s \ state. \ r}" in Always_weaken) apply auto done (** Union properties (with the subset ordering) **) lemma refl_SetLe [simp]: "refl(Pow(A), SetLe(A))" by (unfold refl_def SetLe_def, auto) lemma trans_on_SetLe [simp]: "trans[Pow(A)](SetLe(A))" by (unfold trans_on_def SetLe_def, auto) lemma antisym_SetLe [simp]: "antisym(SetLe(A))" by (unfold antisym_def SetLe_def, auto) lemma part_order_SetLe [simp]: "part_order(Pow(A), SetLe(A))" by (unfold part_order_def, auto) lemma increasing_Un: "\F \ Increasing.increasing(Pow(A), SetLe(A), f); F \ Increasing.increasing(Pow(A), SetLe(A), g)\ \ F \ Increasing.increasing(Pow(A), SetLe(A), \x. f(x) \ g(x))" by (rule_tac h = "(Un)" in imp_increasing_comp2, auto) lemma Increasing_Un: "\F \ Increasing(Pow(A), SetLe(A), f); F \ Increasing(Pow(A), SetLe(A), g)\ \ F \ Increasing(Pow(A), SetLe(A), \x. f(x) \ g(x))" by (rule_tac h = "(Un)" in imp_Increasing_comp2, auto) lemma Always_Un: "\F \ Always({s \ state. f1(s) \ f(s)}); F \ Always({s \ state. g1(s) \ g(s)})\ \ F \ Always({s \ state. f1(s) \ g1(s) \ f(s) \ g(s)})" by (simp add: Always_eq_includes_reachable, blast) lemma Follows_Un: "\F \ Follows(Pow(A), SetLe(A), f1, f); F \ Follows(Pow(A), SetLe(A), g1, g)\ \ F \ Follows(Pow(A), SetLe(A), \s. f1(s) \ g1(s), \s. f(s) \ g(s))" by (rule_tac h = "(Un)" in imp_Follows_comp2, auto) (** Multiset union properties (with the MultLe ordering) **) lemma refl_MultLe [simp]: "refl(Mult(A), MultLe(A,r))" by (unfold MultLe_def refl_def, auto) lemma MultLe_refl1 [simp]: "\multiset(M); mset_of(M)<=A\ \ \M, M\ \ MultLe(A, r)" apply (unfold MultLe_def id_def lam_def) apply (auto simp add: Mult_iff_multiset) done lemma MultLe_refl2 [simp]: "M \ Mult(A) \ \M, M\ \ MultLe(A, r)" by (unfold MultLe_def id_def lam_def, auto) lemma trans_on_MultLe [simp]: "trans[Mult(A)](MultLe(A,r))" apply (unfold MultLe_def trans_on_def) apply (auto intro: trancl_trans simp add: multirel_def) done lemma MultLe_type: "MultLe(A, r)<= (Mult(A) * Mult(A))" apply (unfold MultLe_def, auto) apply (drule multirel_type [THEN subsetD], auto) done lemma MultLe_trans: "\\M,K\ \ MultLe(A,r); \K,N\ \ MultLe(A,r)\ \ \M,N\ \ MultLe(A,r)" apply (cut_tac A=A in trans_on_MultLe) apply (drule trans_onD, assumption) apply (auto dest: MultLe_type [THEN subsetD]) done lemma part_order_imp_part_ord: "part_order(A, r) \ part_ord(A, r-id(A))" apply (unfold part_order_def part_ord_def) apply (simp add: refl_def id_def lam_def irrefl_def, auto) apply (simp (no_asm) add: trans_on_def) apply auto apply (blast dest: trans_onD) apply (simp (no_asm_use) add: antisym_def) apply auto done lemma antisym_MultLe [simp]: "part_order(A, r) \ antisym(MultLe(A,r))" apply (unfold MultLe_def antisym_def) apply (drule part_order_imp_part_ord, auto) apply (drule irrefl_on_multirel) apply (frule multirel_type [THEN subsetD]) apply (drule multirel_trans) apply (auto simp add: irrefl_def) done lemma part_order_MultLe [simp]: "part_order(A, r) \ part_order(Mult(A), MultLe(A, r))" apply (frule antisym_MultLe) apply (auto simp add: part_order_def) done lemma empty_le_MultLe [simp]: "\multiset(M); mset_of(M)<= A\ \ \0, M\ \ MultLe(A, r)" -apply (unfold MultLe_def) + unfolding MultLe_def apply (case_tac "M=0") apply (auto simp add: FiniteFun.intros) apply (subgoal_tac "<0 +# 0, 0 +# M> \ multirel (A, r - id (A))") apply (rule_tac [2] one_step_implies_multirel) apply (auto simp add: Mult_iff_multiset) done lemma empty_le_MultLe2 [simp]: "M \ Mult(A) \ \0, M\ \ MultLe(A, r)" by (simp add: Mult_iff_multiset) lemma munion_mono: "\\M, N\ \ MultLe(A, r); \K, L\ \ MultLe(A, r)\ \ \ MultLe(A, r)" -apply (unfold MultLe_def) + unfolding MultLe_def apply (auto intro: munion_multirel_mono1 munion_multirel_mono2 munion_multirel_mono multiset_into_Mult simp add: Mult_iff_multiset) done lemma increasing_munion: "\F \ Increasing.increasing(Mult(A), MultLe(A,r), f); F \ Increasing.increasing(Mult(A), MultLe(A,r), g)\ \ F \ Increasing.increasing(Mult(A),MultLe(A,r), \x. f(x) +# g(x))" by (rule_tac h = munion in imp_increasing_comp2, auto) lemma Increasing_munion: "\F \ Increasing(Mult(A), MultLe(A,r), f); F \ Increasing(Mult(A), MultLe(A,r), g)\ \ F \ Increasing(Mult(A),MultLe(A,r), \x. f(x) +# g(x))" by (rule_tac h = munion in imp_Increasing_comp2, auto) lemma Always_munion: "\F \ Always({s \ state. \ MultLe(A,r)}); F \ Always({s \ state. \ MultLe(A,r)}); \x \ state. f1(x):Mult(A)\f(x):Mult(A) \ g1(x):Mult(A) \ g(x):Mult(A)\ \ F \ Always({s \ state. \ MultLe(A,r)})" apply (rule_tac h = munion in imp_Always_comp2, simp_all) apply (blast intro: munion_mono, simp_all) done lemma Follows_munion: "\F \ Follows(Mult(A), MultLe(A, r), f1, f); F \ Follows(Mult(A), MultLe(A, r), g1, g)\ \ F \ Follows(Mult(A), MultLe(A, r), \s. f1(s) +# g1(s), \s. f(s) +# g(s))" by (rule_tac h = munion in imp_Follows_comp2, auto) (** Used in ClientImp **) lemma Follows_msetsum_UN: "\f. \\i \ I. F \ Follows(Mult(A), MultLe(A, r), f'(i), f(i)); \s. \i \ I. multiset(f'(i, s)) \ mset_of(f'(i, s))<=A \ multiset(f(i, s)) \ mset_of(f(i, s))<=A ; Finite(I); F \ program\ \ F \ Follows(Mult(A), MultLe(A, r), \x. msetsum(\i. f'(i, x), I, A), \x. msetsum(\i. f(i, x), I, A))" apply (erule rev_mp) apply (drule Finite_into_Fin) apply (erule Fin_induct) apply (simp (no_asm_simp)) apply (rule Follows_constantI) apply (simp_all (no_asm_simp) add: FiniteFun.intros) apply auto apply (rule Follows_munion, auto) done end diff --git a/src/ZF/UNITY/GenPrefix.thy b/src/ZF/UNITY/GenPrefix.thy --- a/src/ZF/UNITY/GenPrefix.thy +++ b/src/ZF/UNITY/GenPrefix.thy @@ -1,680 +1,680 @@ (* Title: ZF/UNITY/GenPrefix.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2001 University of Cambridge \xs,ys\:gen_prefix(r) if ys = xs' @ zs where length(xs) = length(xs') and corresponding elements of xs, xs' are pairwise related by r Based on Lex/Prefix *) section\Charpentier's Generalized Prefix Relation\ theory GenPrefix imports ZF begin definition (*really belongs in ZF/Trancl*) part_order :: "[i, i] \ o" where "part_order(A, r) \ refl(A,r) \ trans[A](r) \ antisym(r)" consts gen_prefix :: "[i, i] \ i" inductive (* Parameter A is the domain of zs's elements *) domains "gen_prefix(A, r)" \ "list(A)*list(A)" intros Nil: "<[],[]>:gen_prefix(A, r)" prepend: "\\xs,ys\:gen_prefix(A, r); \x,y\:r; x \ A; y \ A\ \ : gen_prefix(A, r)" append: "\\xs,ys\:gen_prefix(A, r); zs:list(A)\ \ :gen_prefix(A, r)" type_intros app_type list.Nil list.Cons definition prefix :: "i\i" where "prefix(A) \ gen_prefix(A, id(A))" definition strict_prefix :: "i\i" where "strict_prefix(A) \ prefix(A) - id(list(A))" (* less or equal and greater or equal over prefixes *) abbreviation pfixLe :: "[i, i] \ o" (infixl \pfixLe\ 50) where "xs pfixLe ys \ \xs, ys\:gen_prefix(nat, Le)" abbreviation pfixGe :: "[i, i] \ o" (infixl \pfixGe\ 50) where "xs pfixGe ys \ \xs, ys\:gen_prefix(nat, Ge)" lemma reflD: "\refl(A, r); x \ A\ \ \x,x\:r" apply (unfold refl_def, auto) done (*** preliminary lemmas ***) lemma Nil_gen_prefix: "xs \ list(A) \ <[], xs> \ gen_prefix(A, r)" by (drule gen_prefix.append [OF gen_prefix.Nil], simp) declare Nil_gen_prefix [simp] lemma gen_prefix_length_le: "\xs,ys\ \ gen_prefix(A, r) \ length(xs) \ length(ys)" apply (erule gen_prefix.induct) apply (subgoal_tac [3] "ys \ list (A) ") apply (auto dest: gen_prefix.dom_subset [THEN subsetD] intro: le_trans simp add: length_app) done lemma Cons_gen_prefix_aux: "\ \ gen_prefix(A, r)\ \ (\x xs. x \ A \ xs'= Cons(x,xs) \ (\y ys. y \ A \ ys' = Cons(y,ys) \ \x,y\:r \ \xs, ys\ \ gen_prefix(A, r)))" apply (erule gen_prefix.induct) prefer 3 apply (force intro: gen_prefix.append, auto) done lemma Cons_gen_prefixE: "\ \ gen_prefix(A, r); \y ys. \zs = Cons(y, ys); y \ A; x \ A; \x,y\:r; \xs,ys\ \ gen_prefix(A, r)\ \ P\ \ P" apply (frule gen_prefix.dom_subset [THEN subsetD], auto) apply (blast dest: Cons_gen_prefix_aux) done declare Cons_gen_prefixE [elim!] lemma Cons_gen_prefix_Cons: "( \ gen_prefix(A, r)) \ (x \ A \ y \ A \ \x,y\:r \ \xs,ys\ \ gen_prefix(A, r))" apply (auto intro: gen_prefix.prepend) done declare Cons_gen_prefix_Cons [iff] (** Monotonicity of gen_prefix **) lemma gen_prefix_mono2: "r<=s \ gen_prefix(A, r) \ gen_prefix(A, s)" apply clarify apply (frule gen_prefix.dom_subset [THEN subsetD], clarify) apply (erule rev_mp) apply (erule gen_prefix.induct) apply (auto intro: gen_prefix.append) done lemma gen_prefix_mono1: "A<=B \gen_prefix(A, r) \ gen_prefix(B, r)" apply clarify apply (frule gen_prefix.dom_subset [THEN subsetD], clarify) apply (erule rev_mp) apply (erule_tac P = "y \ list (A) " in rev_mp) apply (erule_tac P = "xa \ list (A) " in rev_mp) apply (erule gen_prefix.induct) apply (simp (no_asm_simp)) apply clarify apply (erule ConsE)+ apply (auto dest: gen_prefix.dom_subset [THEN subsetD] intro: gen_prefix.append list_mono [THEN subsetD]) done lemma gen_prefix_mono: "\A \ B; r \ s\ \ gen_prefix(A, r) \ gen_prefix(B, s)" apply (rule subset_trans) apply (rule gen_prefix_mono1) apply (rule_tac [2] gen_prefix_mono2, auto) done (*** gen_prefix order ***) (* reflexivity *) lemma refl_gen_prefix: "refl(A, r) \ refl(list(A), gen_prefix(A, r))" apply (unfold refl_def, auto) apply (induct_tac "x", auto) done declare refl_gen_prefix [THEN reflD, simp] (* Transitivity *) (* A lemma for proving gen_prefix_trans_comp *) lemma append_gen_prefix [rule_format (no_asm)]: "xs \ list(A) \ \zs. \ gen_prefix(A, r) \ \xs, zs\: gen_prefix(A, r)" apply (erule list.induct) apply (auto dest: gen_prefix.dom_subset [THEN subsetD]) done (* Lemma proving transitivity and more*) lemma gen_prefix_trans_comp [rule_format (no_asm)]: "\x, y\: gen_prefix(A, r) \ (\z \ list(A). \y,z\ \ gen_prefix(A, s)\\x, z\ \ gen_prefix(A, s O r))" apply (erule gen_prefix.induct) apply (auto elim: ConsE simp add: Nil_gen_prefix) apply (subgoal_tac "ys \ list (A) ") prefer 2 apply (blast dest: gen_prefix.dom_subset [THEN subsetD]) apply (drule_tac xs = ys and r = s in append_gen_prefix, auto) done lemma trans_comp_subset: "trans(r) \ r O r \ r" by (auto dest: transD) lemma trans_gen_prefix: "trans(r) \ trans(gen_prefix(A,r))" apply (simp (no_asm) add: trans_def) apply clarify apply (rule trans_comp_subset [THEN gen_prefix_mono2, THEN subsetD], assumption) apply (rule gen_prefix_trans_comp) apply (auto dest: gen_prefix.dom_subset [THEN subsetD]) done lemma trans_on_gen_prefix: "trans(r) \ trans[list(A)](gen_prefix(A, r))" apply (drule_tac A = A in trans_gen_prefix) apply (unfold trans_def trans_on_def, blast) done lemma prefix_gen_prefix_trans: "\\x,y\ \ prefix(A); \y, z\ \ gen_prefix(A, r); r<=A*A\ \ \x, z\ \ gen_prefix(A, r)" -apply (unfold prefix_def) + unfolding prefix_def apply (rule_tac P = "\r. \x,z\ \ gen_prefix (A, r) " in right_comp_id [THEN subst]) apply (blast dest: gen_prefix_trans_comp gen_prefix.dom_subset [THEN subsetD])+ done lemma gen_prefix_prefix_trans: "\\x,y\ \ gen_prefix(A,r); \y, z\ \ prefix(A); r<=A*A\ \ \x, z\ \ gen_prefix(A, r)" -apply (unfold prefix_def) + unfolding prefix_def apply (rule_tac P = "\r. \x,z\ \ gen_prefix (A, r) " in left_comp_id [THEN subst]) apply (blast dest: gen_prefix_trans_comp gen_prefix.dom_subset [THEN subsetD])+ done (** Antisymmetry **) lemma nat_le_lemma [rule_format]: "n \ nat \ \b \ nat. n #+ b \ n \ b = 0" by (induct_tac "n", auto) lemma antisym_gen_prefix: "antisym(r) \ antisym(gen_prefix(A, r))" apply (simp (no_asm) add: antisym_def) apply (rule impI [THEN allI, THEN allI]) apply (erule gen_prefix.induct, blast) apply (simp add: antisym_def, blast) txt\append case is hardest\ apply clarify apply (subgoal_tac "length (zs) = 0") apply (subgoal_tac "ys \ list (A) ") prefer 2 apply (blast dest: gen_prefix.dom_subset [THEN subsetD]) apply (drule_tac psi = " \ gen_prefix (A,r) " in asm_rl) apply simp apply (subgoal_tac "length (ys @ zs) = length (ys) #+ length (zs) \ys \ list (A) \xs \ list (A) ") prefer 2 apply (blast intro: length_app dest: gen_prefix.dom_subset [THEN subsetD]) apply (drule gen_prefix_length_le)+ apply clarify apply simp apply (drule_tac j = "length (xs) " in le_trans) apply blast apply (auto intro: nat_le_lemma) done (*** recursion equations ***) lemma gen_prefix_Nil: "xs \ list(A) \ \ gen_prefix(A,r) \ (xs = [])" by (induct_tac "xs", auto) declare gen_prefix_Nil [simp] lemma same_gen_prefix_gen_prefix: "\refl(A, r); xs \ list(A)\ \ : gen_prefix(A, r) \ \ys,zs\ \ gen_prefix(A, r)" -apply (unfold refl_def) + unfolding refl_def apply (induct_tac "xs") apply (simp_all (no_asm_simp)) done declare same_gen_prefix_gen_prefix [simp] lemma gen_prefix_Cons: "\xs \ list(A); ys \ list(A); y \ A\ \ \ gen_prefix(A,r) \ (xs=[] | (\z zs. xs=Cons(z,zs) \ z \ A \ \z,y\:r \ \zs,ys\ \ gen_prefix(A,r)))" apply (induct_tac "xs", auto) done lemma gen_prefix_take_append: "\refl(A,r); \xs,ys\ \ gen_prefix(A, r); zs \ list(A)\ \ \ gen_prefix(A, r)" apply (erule gen_prefix.induct) apply (simp (no_asm_simp)) apply (frule_tac [!] gen_prefix.dom_subset [THEN subsetD], auto) apply (frule gen_prefix_length_le) apply (subgoal_tac "take (length (xs), ys) \ list (A) ") apply (simp_all (no_asm_simp) add: diff_is_0_iff [THEN iffD2] take_type) done lemma gen_prefix_append_both: "\refl(A, r); \xs,ys\ \ gen_prefix(A,r); length(xs) = length(ys); zs \ list(A)\ \ \ gen_prefix(A, r)" apply (drule_tac zs = zs in gen_prefix_take_append, assumption+) apply (subgoal_tac "take (length (xs), ys) =ys") apply (auto intro!: take_all dest: gen_prefix.dom_subset [THEN subsetD]) done (*NOT suitable for rewriting since [y] has the form y#ys*) lemma append_cons_conv: "xs \ list(A) \ xs @ Cons(y, ys) = (xs @ [y]) @ ys" by (auto simp add: app_assoc) lemma append_one_gen_prefix_lemma [rule_format]: "\\xs,ys\ \ gen_prefix(A, r); refl(A, r)\ \ length(xs) < length(ys) \ \ gen_prefix(A, r)" apply (erule gen_prefix.induct, blast) apply (frule gen_prefix.dom_subset [THEN subsetD], clarify) apply (simp_all add: length_type) (* Append case is hardest *) apply (frule gen_prefix_length_le [THEN le_iff [THEN iffD1]]) apply (frule gen_prefix.dom_subset [THEN subsetD], clarify) apply (subgoal_tac "length (xs) :nat\length (ys) :nat \length (zs) :nat") prefer 2 apply (blast intro: length_type, clarify) apply (simp_all add: nth_append length_type length_app) apply (rule conjI) apply (blast intro: gen_prefix.append) apply (erule_tac V = "length (xs) < length (ys) \u" for u in thin_rl) apply (erule_tac a = zs in list.cases, auto) apply (rule_tac P1 = "\x. :w" for u v w in nat_diff_split [THEN iffD2]) apply auto apply (simplesubst append_cons_conv) apply (rule_tac [2] gen_prefix.append) apply (auto elim: ConsE simp add: gen_prefix_append_both) done lemma append_one_gen_prefix: "\\xs,ys\: gen_prefix(A, r); length(xs) < length(ys); refl(A, r)\ \ \ gen_prefix(A, r)" apply (blast intro: append_one_gen_prefix_lemma) done (** Proving the equivalence with Charpentier's definition **) lemma gen_prefix_imp_nth_lemma [rule_format]: "xs \ list(A) \ \ys \ list(A). \i \ nat. i < length(xs) \ \xs, ys\: gen_prefix(A, r) \ :r" apply (induct_tac "xs", simp, clarify) apply simp apply (erule natE, auto) done lemma gen_prefix_imp_nth: "\\xs,ys\ \ gen_prefix(A,r); i < length(xs)\ \ :r" apply (cut_tac A = A in gen_prefix.dom_subset) apply (rule gen_prefix_imp_nth_lemma) apply (auto simp add: lt_nat_in_nat) done lemma nth_imp_gen_prefix [rule_format]: "xs \ list(A) \ \ys \ list(A). length(xs) \ length(ys) \ (\i. i < length(xs) \ :r) \ \xs, ys\ \ gen_prefix(A, r)" apply (induct_tac "xs") apply (simp_all (no_asm_simp)) apply clarify apply (erule_tac a = ys in list.cases, simp) apply (force intro!: nat_0_le simp add: lt_nat_in_nat) done lemma gen_prefix_iff_nth: "(\xs,ys\ \ gen_prefix(A,r)) \ (xs \ list(A) \ ys \ list(A) \ length(xs) \ length(ys) \ (\i. i < length(xs) \ : r))" apply (rule iffI) apply (frule gen_prefix.dom_subset [THEN subsetD]) apply (frule gen_prefix_length_le, auto) apply (rule_tac [2] nth_imp_gen_prefix) apply (drule gen_prefix_imp_nth) apply (auto simp add: lt_nat_in_nat) done (** prefix is a partial order: **) lemma refl_prefix: "refl(list(A), prefix(A))" -apply (unfold prefix_def) + unfolding prefix_def apply (rule refl_gen_prefix) apply (auto simp add: refl_def) done declare refl_prefix [THEN reflD, simp] lemma trans_prefix: "trans(prefix(A))" -apply (unfold prefix_def) + unfolding prefix_def apply (rule trans_gen_prefix) apply (auto simp add: trans_def) done lemmas prefix_trans = trans_prefix [THEN transD] lemma trans_on_prefix: "trans[list(A)](prefix(A))" -apply (unfold prefix_def) + unfolding prefix_def apply (rule trans_on_gen_prefix) apply (auto simp add: trans_def) done lemmas prefix_trans_on = trans_on_prefix [THEN trans_onD] (* Monotonicity of "set" operator WRT prefix *) lemma set_of_list_prefix_mono: "\xs,ys\ \ prefix(A) \ set_of_list(xs) \ set_of_list(ys)" -apply (unfold prefix_def) + unfolding prefix_def apply (erule gen_prefix.induct) apply (subgoal_tac [3] "xs \ list (A) \ys \ list (A) ") prefer 4 apply (blast dest: gen_prefix.dom_subset [THEN subsetD]) apply (auto simp add: set_of_list_append) done (** recursion equations **) lemma Nil_prefix: "xs \ list(A) \ <[],xs> \ prefix(A)" -apply (unfold prefix_def) + unfolding prefix_def apply (simp (no_asm_simp) add: Nil_gen_prefix) done declare Nil_prefix [simp] lemma prefix_Nil: " \ prefix(A) \ (xs = [])" apply (unfold prefix_def, auto) apply (frule gen_prefix.dom_subset [THEN subsetD]) apply (drule_tac psi = " \ gen_prefix (A, id (A))" in asm_rl) apply (simp add: gen_prefix_Nil) done declare prefix_Nil [iff] lemma Cons_prefix_Cons: " \ prefix(A) \ (x=y \ \xs,ys\ \ prefix(A) \ y \ A)" apply (unfold prefix_def, auto) done declare Cons_prefix_Cons [iff] lemma same_prefix_prefix: "xs \ list(A)\ \ prefix(A) \ (\ys,zs\ \ prefix(A))" -apply (unfold prefix_def) + unfolding prefix_def apply (subgoal_tac "refl (A,id (A))") apply (simp (no_asm_simp)) apply (auto simp add: refl_def) done declare same_prefix_prefix [simp] lemma same_prefix_prefix_Nil: "xs \ list(A) \ \ prefix(A) \ ( \ prefix(A))" apply (rule_tac P = "\x. \u, x\:v \ w(x)" for u v w in app_right_Nil [THEN subst]) apply (rule_tac [2] same_prefix_prefix, auto) done declare same_prefix_prefix_Nil [simp] lemma prefix_appendI: "\\xs,ys\ \ prefix(A); zs \ list(A)\ \ \ prefix(A)" -apply (unfold prefix_def) + unfolding prefix_def apply (erule gen_prefix.append, assumption) done declare prefix_appendI [simp] lemma prefix_Cons: "\xs \ list(A); ys \ list(A); y \ A\ \ \ prefix(A) \ (xs=[] | (\zs. xs=Cons(y,zs) \ \zs,ys\ \ prefix(A)))" -apply (unfold prefix_def) + unfolding prefix_def apply (auto simp add: gen_prefix_Cons) done lemma append_one_prefix: "\\xs,ys\ \ prefix(A); length(xs) < length(ys)\ \ \ prefix(A)" -apply (unfold prefix_def) + unfolding prefix_def apply (subgoal_tac "refl (A, id (A))") apply (simp (no_asm_simp) add: append_one_gen_prefix) apply (auto simp add: refl_def) done lemma prefix_length_le: "\xs,ys\ \ prefix(A) \ length(xs) \ length(ys)" -apply (unfold prefix_def) + unfolding prefix_def apply (blast dest: gen_prefix_length_le) done lemma prefix_type: "prefix(A)<=list(A)*list(A)" -apply (unfold prefix_def) + unfolding prefix_def apply (blast intro!: gen_prefix.dom_subset) done lemma strict_prefix_type: "strict_prefix(A) \ list(A)*list(A)" -apply (unfold strict_prefix_def) + unfolding strict_prefix_def apply (blast intro!: prefix_type [THEN subsetD]) done lemma strict_prefix_length_lt_aux: "\xs,ys\ \ prefix(A) \ xs\ys \ length(xs) < length(ys)" -apply (unfold prefix_def) + unfolding prefix_def apply (erule gen_prefix.induct, clarify) apply (subgoal_tac [!] "ys \ list(A) \ xs \ list(A)") apply (auto dest: gen_prefix.dom_subset [THEN subsetD] simp add: length_type) apply (subgoal_tac "length (zs) =0") apply (drule_tac [2] not_lt_imp_le) apply (rule_tac [5] j = "length (ys) " in lt_trans2) apply auto done lemma strict_prefix_length_lt: "\xs,ys\:strict_prefix(A) \ length(xs) < length(ys)" -apply (unfold strict_prefix_def) + unfolding strict_prefix_def apply (rule strict_prefix_length_lt_aux [THEN mp]) apply (auto dest: prefix_type [THEN subsetD]) done (*Equivalence to the definition used in Lex/Prefix.thy*) lemma prefix_iff: "\xs,zs\ \ prefix(A) \ (\ys \ list(A). zs = xs@ys) \ xs \ list(A)" -apply (unfold prefix_def) + unfolding prefix_def apply (auto simp add: gen_prefix_iff_nth lt_nat_in_nat nth_append nth_type app_type length_app) apply (subgoal_tac "drop (length (xs), zs) \ list (A) ") apply (rule_tac x = "drop (length (xs), zs) " in bexI) apply safe prefer 2 apply (simp add: length_type drop_type) apply (rule nth_equalityI) apply (simp_all (no_asm_simp) add: nth_append app_type drop_type length_app length_drop) apply (rule nat_diff_split [THEN iffD2], simp_all, clarify) apply (drule_tac i = "length (zs) " in leI) apply (force simp add: le_subset_iff, safe) apply (subgoal_tac "length (xs) #+ (i #- length (xs)) = i") apply (subst nth_drop) apply (simp_all (no_asm_simp) add: leI split: nat_diff_split) done lemma prefix_snoc: "\xs \ list(A); ys \ list(A); y \ A\ \ \ prefix(A) \ (xs = ys@[y] | \xs,ys\ \ prefix(A))" apply (simp (no_asm) add: prefix_iff) apply (rule iffI, clarify) apply (erule_tac xs = ysa in rev_list_elim, simp) apply (simp add: app_type app_assoc [symmetric]) apply (auto simp add: app_assoc app_type) done declare prefix_snoc [simp] lemma prefix_append_iff [rule_format]: "zs \ list(A) \ \xs \ list(A). \ys \ list(A). ( \ prefix(A)) \ (\xs,ys\ \ prefix(A) | (\us. xs = ys@us \ \us,zs\ \ prefix(A)))" apply (erule list_append_induct, force, clarify) apply (rule iffI) apply (simp add: add: app_assoc [symmetric]) apply (erule disjE) apply (rule disjI2) apply (rule_tac x = "y @ [x]" in exI) apply (simp add: add: app_assoc [symmetric], force+) done (*Although the prefix ordering is not linear, the prefixes of a list are linearly ordered.*) lemma common_prefix_linear_lemma [rule_format]: "\zs \ list(A); xs \ list(A); ys \ list(A)\ \ \xs, zs\ \ prefix(A) \ \ys,zs\ \ prefix(A) \\xs,ys\ \ prefix(A) | \ys,xs\ \ prefix(A)" apply (erule list_append_induct, auto) done lemma common_prefix_linear: "\\xs, zs\ \ prefix(A); \ys,zs\ \ prefix(A)\ \ \xs,ys\ \ prefix(A) | \ys,xs\ \ prefix(A)" apply (cut_tac prefix_type) apply (blast del: disjCI intro: common_prefix_linear_lemma) done (*** pfixLe, pfixGe \ properties inherited from the translations ***) (** pfixLe **) lemma refl_Le: "refl(nat,Le)" apply (unfold refl_def, auto) done declare refl_Le [simp] lemma antisym_Le: "antisym(Le)" -apply (unfold antisym_def) + unfolding antisym_def apply (auto intro: le_anti_sym) done declare antisym_Le [simp] lemma trans_on_Le: "trans[nat](Le)" apply (unfold trans_on_def, auto) apply (blast intro: le_trans) done declare trans_on_Le [simp] lemma trans_Le: "trans(Le)" apply (unfold trans_def, auto) apply (blast intro: le_trans) done declare trans_Le [simp] lemma part_order_Le: "part_order(nat,Le)" by (unfold part_order_def, auto) declare part_order_Le [simp] lemma pfixLe_refl: "x \ list(nat) \ x pfixLe x" by (blast intro: refl_gen_prefix [THEN reflD] refl_Le) declare pfixLe_refl [simp] lemma pfixLe_trans: "\x pfixLe y; y pfixLe z\ \ x pfixLe z" by (blast intro: trans_gen_prefix [THEN transD] trans_Le) lemma pfixLe_antisym: "\x pfixLe y; y pfixLe x\ \ x = y" by (blast intro: antisym_gen_prefix [THEN antisymE] antisym_Le) lemma prefix_imp_pfixLe: "\xs,ys\:prefix(nat)\ xs pfixLe ys" -apply (unfold prefix_def) + unfolding prefix_def apply (rule gen_prefix_mono [THEN subsetD], auto) done lemma refl_Ge: "refl(nat, Ge)" by (unfold refl_def Ge_def, auto) declare refl_Ge [iff] lemma antisym_Ge: "antisym(Ge)" apply (unfold antisym_def Ge_def) apply (auto intro: le_anti_sym) done declare antisym_Ge [iff] lemma trans_Ge: "trans(Ge)" apply (unfold trans_def Ge_def) apply (auto intro: le_trans) done declare trans_Ge [iff] lemma pfixGe_refl: "x \ list(nat) \ x pfixGe x" by (blast intro: refl_gen_prefix [THEN reflD]) declare pfixGe_refl [simp] lemma pfixGe_trans: "\x pfixGe y; y pfixGe z\ \ x pfixGe z" by (blast intro: trans_gen_prefix [THEN transD]) lemma pfixGe_antisym: "\x pfixGe y; y pfixGe x\ \ x = y" by (blast intro: antisym_gen_prefix [THEN antisymE]) lemma prefix_imp_pfixGe: "\xs,ys\:prefix(nat) \ xs pfixGe ys" apply (unfold prefix_def Ge_def) apply (rule gen_prefix_mono [THEN subsetD], auto) done (* Added by Sidi \ prefix and take *) lemma prefix_imp_take: "\xs, ys\ \ prefix(A) \ xs = take(length(xs), ys)" -apply (unfold prefix_def) + unfolding prefix_def apply (erule gen_prefix.induct) apply (subgoal_tac [3] "length (xs) :nat") apply (auto dest: gen_prefix.dom_subset [THEN subsetD] simp add: length_type) apply (frule gen_prefix.dom_subset [THEN subsetD]) apply (frule gen_prefix_length_le) apply (auto simp add: take_append) apply (subgoal_tac "length (xs) #- length (ys) =0") apply (simp_all (no_asm_simp) add: diff_is_0_iff) done lemma prefix_length_equal: "\\xs,ys\ \ prefix(A); length(xs)=length(ys)\ \ xs = ys" apply (cut_tac A = A in prefix_type) apply (drule subsetD, auto) apply (drule prefix_imp_take) apply (erule trans, simp) done lemma prefix_length_le_equal: "\\xs,ys\ \ prefix(A); length(ys) \ length(xs)\ \ xs = ys" by (blast intro: prefix_length_equal le_anti_sym prefix_length_le) lemma take_prefix [rule_format]: "xs \ list(A) \ \n \ nat. \ prefix(A)" -apply (unfold prefix_def) + unfolding prefix_def apply (erule list.induct, simp, clarify) apply (erule natE, auto) done lemma prefix_take_iff: "\xs,ys\ \ prefix(A) \ (xs=take(length(xs), ys) \ xs \ list(A) \ ys \ list(A))" apply (rule iffI) apply (frule prefix_type [THEN subsetD]) apply (blast intro: prefix_imp_take, clarify) apply (erule ssubst) apply (blast intro: take_prefix length_type) done lemma prefix_imp_nth: "\\xs,ys\ \ prefix(A); i < length(xs)\ \ nth(i,xs) = nth(i,ys)" by (auto dest!: gen_prefix_imp_nth simp add: prefix_def) lemma nth_imp_prefix: "\xs \ list(A); ys \ list(A); length(xs) \ length(ys); \i. i < length(xs) \ nth(i, xs) = nth(i,ys)\ \ \xs,ys\ \ prefix(A)" apply (auto simp add: prefix_def nth_imp_gen_prefix) apply (auto intro!: nth_imp_gen_prefix simp add: prefix_def) apply (blast intro: nth_type lt_trans2) done lemma length_le_prefix_imp_prefix: "\length(xs) \ length(ys); \xs,zs\ \ prefix(A); \ys,zs\ \ prefix(A)\ \ \xs,ys\ \ prefix(A)" apply (cut_tac A = A in prefix_type) apply (rule nth_imp_prefix, blast, blast) apply assumption apply (rule_tac b = "nth (i,zs)" in trans) apply (blast intro: prefix_imp_nth) apply (blast intro: sym prefix_imp_nth prefix_length_le lt_trans2) done end diff --git a/src/ZF/UNITY/Guar.thy b/src/ZF/UNITY/Guar.thy --- a/src/ZF/UNITY/Guar.thy +++ b/src/ZF/UNITY/Guar.thy @@ -1,532 +1,532 @@ (* Title: ZF/UNITY/Guar.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge Guarantees, etc. From Chandy and Sanders, "Reasoning About Program Composition", Technical Report 2000-003, University of Florida, 2000. Revised by Sidi Ehmety on January 2001 Added \ Compatibility, weakest guarantees, etc. and Weakest existential property, from Charpentier and Chandy "Theorems about Composition", Fifth International Conference on Mathematics of Program, 2000. Theory ported from HOL. *) section\The Chandy-Sanders Guarantees Operator\ theory Guar imports Comp begin (* To be moved to theory WFair???? *) lemma leadsTo_Basis': "\F \ A co A \ B; F \ transient(A); st_set(B)\ \ F \ A \ B" apply (frule constrainsD2) apply (drule_tac B = "A-B" in constrains_weaken_L, blast) apply (drule_tac B = "A-B" in transient_strengthen, blast) apply (blast intro: ensuresI [THEN leadsTo_Basis]) done (*Existential and Universal properties. We formalize the two-program case, proving equivalence with Chandy and Sanders's n-ary definitions*) definition ex_prop :: "i \ o" where "ex_prop(X) \ X<=program \ (\F \ program. \G \ program. F ok G \ F \ X | G \ X \ (F \ G) \ X)" definition strict_ex_prop :: "i \ o" where "strict_ex_prop(X) \ X<=program \ (\F \ program. \G \ program. F ok G \ (F \ X | G \ X) \ (F \ G \ X))" definition uv_prop :: "i \ o" where "uv_prop(X) \ X<=program \ (SKIP \ X \ (\F \ program. \G \ program. F ok G \ F \ X \ G \ X \ (F \ G) \ X))" definition strict_uv_prop :: "i \ o" where "strict_uv_prop(X) \ X<=program \ (SKIP \ X \ (\F \ program. \G \ program. F ok G \(F \ X \ G \ X) \ (F \ G \ X)))" definition guar :: "[i, i] \ i" (infixl \guarantees\ 55) where (*higher than membership, lower than Co*) "X guarantees Y \ {F \ program. \G \ program. F ok G \ F \ G \ X \ F \ G \ Y}" definition (* Weakest guarantees *) wg :: "[i,i] \ i" where "wg(F,Y) \ \({X \ Pow(program). F:(X guarantees Y)})" definition (* Weakest existential property stronger than X *) wx :: "i \i" where "wx(X) \ \({Y \ Pow(program). Y<=X \ ex_prop(Y)})" definition (*Ill-defined programs can arise through "\"*) welldef :: i where "welldef \ {F \ program. Init(F) \ 0}" definition refines :: "[i, i, i] \ o" (\(3_ refines _ wrt _)\ [10,10,10] 10) where "G refines F wrt X \ \H \ program. (F ok H \ G ok H \ F \ H \ welldef \ X) \ (G \ H \ welldef \ X)" definition iso_refines :: "[i,i, i] \ o" (\(3_ iso'_refines _ wrt _)\ [10,10,10] 10) where "G iso_refines F wrt X \ F \ welldef \ X \ G \ welldef \ X" (*** existential properties ***) lemma ex_imp_subset_program: "ex_prop(X) \ X\program" by (simp add: ex_prop_def) lemma ex1 [rule_format]: "GG \ Fin(program) \ ex_prop(X) \ GG \ X\0 \ OK(GG, (\G. G)) \(\G \ GG. G) \ X" -apply (unfold ex_prop_def) + unfolding ex_prop_def apply (erule Fin_induct) apply (simp_all add: OK_cons_iff) apply (safe elim!: not_emptyE, auto) done lemma ex2 [rule_format]: "X \ program \ (\GG \ Fin(program). GG \ X \ 0 \ OK(GG,(\G. G))\(\G \ GG. G) \ X) \ ex_prop(X)" apply (unfold ex_prop_def, clarify) apply (drule_tac x = "{F,G}" in bspec) apply (simp_all add: OK_iff_ok) apply (auto intro: ok_sym) done (*Chandy \ Sanders take this as a definition*) lemma ex_prop_finite: "ex_prop(X) \ (X\program \ (\GG \ Fin(program). GG \ X \ 0 \ OK(GG,(\G. G))\(\G \ GG. G) \ X))" apply auto apply (blast intro: ex1 ex2 dest: ex_imp_subset_program)+ done (* Equivalent definition of ex_prop given at the end of section 3*) lemma ex_prop_equiv: "ex_prop(X) \ X\program \ (\G \ program. (G \ X \ (\H \ program. (G component_of H) \ H \ X)))" apply (unfold ex_prop_def component_of_def, safe, force, force, blast) apply (subst Join_commute) apply (blast intro: ok_sym) done (*** universal properties ***) lemma uv_imp_subset_program: "uv_prop(X)\ X\program" -apply (unfold uv_prop_def) + unfolding uv_prop_def apply (simp (no_asm_simp)) done lemma uv1 [rule_format]: "GG \ Fin(program) \ (uv_prop(X)\ GG \ X \ OK(GG, (\G. G)) \ (\G \ GG. G) \ X)" -apply (unfold uv_prop_def) + unfolding uv_prop_def apply (erule Fin_induct) apply (auto simp add: OK_cons_iff) done lemma uv2 [rule_format]: "X\program \ (\GG \ Fin(program). GG \ X \ OK(GG,(\G. G)) \ (\G \ GG. G) \ X) \ uv_prop(X)" apply (unfold uv_prop_def, auto) apply (drule_tac x = 0 in bspec, simp+) apply (drule_tac x = "{F,G}" in bspec, simp) apply (force dest: ok_sym simp add: OK_iff_ok) done (*Chandy \ Sanders take this as a definition*) lemma uv_prop_finite: "uv_prop(X) \ X\program \ (\GG \ Fin(program). GG \ X \ OK(GG, \G. G) \ (\G \ GG. G) \ X)" apply auto apply (blast dest: uv_imp_subset_program) apply (blast intro: uv1) apply (blast intro!: uv2 dest:) done (*** guarantees ***) lemma guaranteesI: "\(\G. \F ok G; F \ G \ X; G \ program\ \ F \ G \ Y); F \ program\ \ F \ X guarantees Y" by (simp add: guar_def component_def) lemma guaranteesD: "\F \ X guarantees Y; F ok G; F \ G \ X; G \ program\ \ F \ G \ Y" by (simp add: guar_def component_def) (*This version of guaranteesD matches more easily in the conclusion The major premise can no longer be F\H since we need to reason about G*) lemma component_guaranteesD: "\F \ X guarantees Y; F \ G = H; H \ X; F ok G; G \ program\ \ H \ Y" by (simp add: guar_def, blast) lemma guarantees_weaken: "\F \ X guarantees X'; Y \ X; X' \ Y'\ \ F \ Y guarantees Y'" by (simp add: guar_def, auto) lemma subset_imp_guarantees_program: "X \ Y \ X guarantees Y = program" by (unfold guar_def, blast) (*Equivalent to subset_imp_guarantees_UNIV but more intuitive*) lemma subset_imp_guarantees: "\X \ Y; F \ program\ \ F \ X guarantees Y" by (unfold guar_def, blast) lemma component_of_Join1: "F ok G \ F component_of (F \ G)" by (unfold component_of_def, blast) lemma component_of_Join2: "F ok G \ G component_of (F \ G)" apply (subst Join_commute) apply (blast intro: ok_sym component_of_Join1) done (*Remark at end of section 4.1 *) lemma ex_prop_imp: "ex_prop(Y) \ (Y = (program guarantees Y))" apply (simp (no_asm_use) add: ex_prop_equiv guar_def component_of_def) apply clarify apply (rule equalityI, blast, safe) apply (drule_tac x = x in bspec, assumption, force) done lemma guarantees_imp: "(Y = program guarantees Y) \ ex_prop(Y)" -apply (unfold guar_def) + unfolding guar_def apply (simp (no_asm_simp) add: ex_prop_equiv) apply safe apply (blast intro: elim: equalityE) apply (simp_all (no_asm_use) add: component_of_def) apply (force elim: equalityE)+ done lemma ex_prop_equiv2: "(ex_prop(Y)) \ (Y = program guarantees Y)" by (blast intro: ex_prop_imp guarantees_imp) (** Distributive laws. Re-orient to perform miniscoping **) lemma guarantees_UN_left: "i \ I \(\i \ I. X(i)) guarantees Y = (\i \ I. X(i) guarantees Y)" -apply (unfold guar_def) + unfolding guar_def apply (rule equalityI, safe) prefer 2 apply force apply blast+ done lemma guarantees_Un_left: "(X \ Y) guarantees Z = (X guarantees Z) \ (Y guarantees Z)" -apply (unfold guar_def) + unfolding guar_def apply (rule equalityI, safe, blast+) done lemma guarantees_INT_right: "i \ I \ X guarantees (\i \ I. Y(i)) = (\i \ I. X guarantees Y(i))" -apply (unfold guar_def) + unfolding guar_def apply (rule equalityI, safe, blast+) done lemma guarantees_Int_right: "Z guarantees (X \ Y) = (Z guarantees X) \ (Z guarantees Y)" by (unfold guar_def, blast) lemma guarantees_Int_right_I: "\F \ Z guarantees X; F \ Z guarantees Y\ \ F \ Z guarantees (X \ Y)" by (simp (no_asm_simp) add: guarantees_Int_right) lemma guarantees_INT_right_iff: "i \ I\ (F \ X guarantees (\i \ I. Y(i))) \ (\i \ I. F \ X guarantees Y(i))" by (simp add: guarantees_INT_right INT_iff, blast) lemma shunting: "(X guarantees Y) = (program guarantees ((program-X) \ Y))" by (unfold guar_def, auto) lemma contrapositive: "(X guarantees Y) = (program - Y) guarantees (program -X)" by (unfold guar_def, blast) (** The following two can be expressed using intersection and subset, which is more faithful to the text but looks cryptic. **) lemma combining1: "\F \ V guarantees X; F \ (X \ Y) guarantees Z\ \ F \ (V \ Y) guarantees Z" by (unfold guar_def, blast) lemma combining2: "\F \ V guarantees (X \ Y); F \ Y guarantees Z\ \ F \ V guarantees (X \ Z)" by (unfold guar_def, blast) (** The following two follow Chandy-Sanders, but the use of object-quantifiers does not suit Isabelle... **) (*Premise should be (\i. i \ I \ F \ X guarantees Y i) *) lemma all_guarantees: "\\i \ I. F \ X guarantees Y(i); i \ I\ \ F \ X guarantees (\i \ I. Y(i))" by (unfold guar_def, blast) (*Premises should be \F \ X guarantees Y i; i \ I\ *) lemma ex_guarantees: "\i \ I. F \ X guarantees Y(i) \ F \ X guarantees (\i \ I. Y(i))" by (unfold guar_def, blast) (*** Additional guarantees laws, by lcp ***) lemma guarantees_Join_Int: "\F \ U guarantees V; G \ X guarantees Y; F ok G\ \ F \ G: (U \ X) guarantees (V \ Y)" -apply (unfold guar_def) + unfolding guar_def apply (simp (no_asm)) apply safe apply (simp add: Join_assoc) apply (subgoal_tac "F \ G \ Ga = G \ (F \ Ga) ") apply (simp add: ok_commute) apply (simp (no_asm_simp) add: Join_ac) done lemma guarantees_Join_Un: "\F \ U guarantees V; G \ X guarantees Y; F ok G\ \ F \ G: (U \ X) guarantees (V \ Y)" -apply (unfold guar_def) + unfolding guar_def apply (simp (no_asm)) apply safe apply (simp add: Join_assoc) apply (subgoal_tac "F \ G \ Ga = G \ (F \ Ga) ") apply (rotate_tac 4) apply (drule_tac x = "F \ Ga" in bspec) apply (simp (no_asm)) apply (force simp add: ok_commute) apply (simp (no_asm_simp) add: Join_ac) done lemma guarantees_JOIN_INT: "\\i \ I. F(i) \ X(i) guarantees Y(i); OK(I,F); i \ I\ \ (\i \ I. F(i)) \ (\i \ I. X(i)) guarantees (\i \ I. Y(i))" apply (unfold guar_def, safe) prefer 2 apply blast apply (drule_tac x = xa in bspec) apply (simp_all add: INT_iff, safe) apply (drule_tac x = "(\x \ (I-{xa}) . F (x)) \ G" and A=program in bspec) apply (auto intro: OK_imp_ok simp add: Join_assoc [symmetric] JOIN_Join_diff JOIN_absorb) done lemma guarantees_JOIN_UN: "\\i \ I. F(i) \ X(i) guarantees Y(i); OK(I,F)\ \ JOIN(I,F) \ (\i \ I. X(i)) guarantees (\i \ I. Y(i))" apply (unfold guar_def, auto) apply (drule_tac x = y in bspec, simp_all, safe) apply (rename_tac G y) apply (drule_tac x = "JOIN (I-{y}, F) \ G" and A=program in bspec) apply (auto intro: OK_imp_ok simp add: Join_assoc [symmetric] JOIN_Join_diff JOIN_absorb) done (*** guarantees laws for breaking down the program, by lcp ***) lemma guarantees_Join_I1: "\F \ X guarantees Y; F ok G\ \ F \ G \ X guarantees Y" apply (simp add: guar_def, safe) apply (simp add: Join_assoc) done lemma guarantees_Join_I2: "\G \ X guarantees Y; F ok G\ \ F \ G \ X guarantees Y" apply (simp add: Join_commute [of _ G] ok_commute [of _ G]) apply (blast intro: guarantees_Join_I1) done lemma guarantees_JOIN_I: "\i \ I; F(i) \ X guarantees Y; OK(I,F)\ \ (\i \ I. F(i)) \ X guarantees Y" apply (unfold guar_def, safe) apply (drule_tac x = "JOIN (I-{i},F) \ G" in bspec) apply (simp (no_asm)) apply (auto intro: OK_imp_ok simp add: JOIN_Join_diff Join_assoc [symmetric]) done (*** well-definedness ***) lemma Join_welldef_D1: "F \ G \ welldef \ programify(F) \ welldef" by (unfold welldef_def, auto) lemma Join_welldef_D2: "F \ G \ welldef \ programify(G) \ welldef" by (unfold welldef_def, auto) (*** refinement ***) lemma refines_refl: "F refines F wrt X" by (unfold refines_def, blast) (* More results on guarantees, added by Sidi Ehmety from Chandy \ Sander, section 6 *) lemma wg_type: "wg(F, X) \ program" by (unfold wg_def, auto) lemma guarantees_type: "X guarantees Y \ program" by (unfold guar_def, auto) lemma wgD2: "G \ wg(F, X) \ G \ program \ F \ program" apply (unfold wg_def, auto) apply (blast dest: guarantees_type [THEN subsetD]) done lemma guarantees_equiv: "(F \ X guarantees Y) \ F \ program \ (\H \ program. H \ X \ (F component_of H \ H \ Y))" by (unfold guar_def component_of_def, force) lemma wg_weakest: "\X. \F \ (X guarantees Y); X \ program\ \ X \ wg(F,Y)" by (unfold wg_def, auto) lemma wg_guarantees: "F \ program \ F \ wg(F,Y) guarantees Y" by (unfold wg_def guar_def, blast) lemma wg_equiv: "H \ wg(F,X) \ ((F component_of H \ H \ X) \ F \ program \ H \ program)" apply (simp add: wg_def guarantees_equiv) apply (rule iffI, safe) apply (rule_tac [4] x = "{H}" in bexI) apply (rule_tac [3] x = "{H}" in bexI, blast+) done lemma component_of_wg: "F component_of H \ H \ wg(F,X) \ (H \ X \ F \ program \ H \ program)" by (simp (no_asm_simp) add: wg_equiv) lemma wg_finite [rule_format]: "\FF \ Fin(program). FF \ X \ 0 \ OK(FF, \F. F) \ (\F \ FF. ((\F \ FF. F) \ wg(F,X)) \ ((\F \ FF. F) \ X))" apply clarify apply (subgoal_tac "F component_of (\F \ FF. F) ") apply (drule_tac X = X in component_of_wg) apply (force dest!: Fin.dom_subset [THEN subsetD, THEN PowD]) apply (simp_all add: component_of_def) apply (rule_tac x = "\F \ (FF-{F}) . F" in exI) apply (auto intro: JOIN_Join_diff dest: ok_sym simp add: OK_iff_ok) done lemma wg_ex_prop: "ex_prop(X) \ (F \ X) \ (\H \ program. H \ wg(F,X) \ F \ program)" apply (simp (no_asm_use) add: ex_prop_equiv wg_equiv) apply blast done (** From Charpentier and Chandy "Theorems About Composition" **) (* Proposition 2 *) lemma wx_subset: "wx(X)\X" by (unfold wx_def, auto) lemma wx_ex_prop: "ex_prop(wx(X))" apply (simp (no_asm_use) add: ex_prop_def wx_def) apply safe apply blast apply (rule_tac x=x in bexI, force, simp)+ done lemma wx_weakest: "\Z. Z\program \ Z\ X \ ex_prop(Z) \ Z \ wx(X)" by (unfold wx_def, auto) (* Proposition 6 *) lemma wx'_ex_prop: "ex_prop({F \ program. \G \ program. F ok G \ F \ G \ X})" apply (unfold ex_prop_def, safe) apply (drule_tac x = "G \ Ga" in bspec) apply (simp (no_asm)) apply (force simp add: Join_assoc) apply (drule_tac x = "F \ Ga" in bspec) apply (simp (no_asm)) apply (simp (no_asm_use)) apply safe apply (simp (no_asm_simp) add: ok_commute) apply (subgoal_tac "F \ G = G \ F") apply (simp (no_asm_simp) add: Join_assoc) apply (simp (no_asm) add: Join_commute) done (* Equivalence with the other definition of wx *) lemma wx_equiv: "wx(X) = {F \ program. \G \ program. F ok G \ (F \ G) \ X}" -apply (unfold wx_def) + unfolding wx_def apply (rule equalityI, safe, blast) apply (simp (no_asm_use) add: ex_prop_def) apply blast apply (rule_tac B = "{F \ program. \G \ program. F ok G \ F \ G \ X}" in UnionI, safe) apply (rule_tac [2] wx'_ex_prop) apply (drule_tac x=SKIP in bspec, simp)+ apply auto done (* Propositions 7 to 11 are all about this second definition of wx. And by equivalence between the two definition, they are the same as the ones proved *) (* Proposition 12 *) (* Main result of the paper *) lemma guarantees_wx_eq: "(X guarantees Y) = wx((program-X) \ Y)" by (auto simp add: guar_def wx_equiv) (* {* Corollary, but this result has already been proved elsewhere *} "ex_prop(X guarantees Y)" *) (* Rules given in section 7 of Chandy and Sander's Reasoning About Program composition paper *) lemma stable_guarantees_Always: "\Init(F) \ A; F \ program\ \ F \ stable(A) guarantees Always(A)" apply (rule guaranteesI) prefer 2 apply assumption apply (simp (no_asm) add: Join_commute) apply (rule stable_Join_Always1) apply (simp_all add: invariant_def) apply (auto simp add: programify_def initially_def) done lemma constrains_guarantees_leadsTo: "\F \ transient(A); st_set(B)\ \ F: (A co A \ B) guarantees (A \ (B-A))" apply (rule guaranteesI) prefer 2 apply (blast dest: transient_type [THEN subsetD]) apply (rule leadsTo_Basis') apply (blast intro: constrains_weaken_R) apply (blast intro!: Join_transient_I1, blast) done end diff --git a/src/ZF/UNITY/Increasing.thy b/src/ZF/UNITY/Increasing.thy --- a/src/ZF/UNITY/Increasing.thy +++ b/src/ZF/UNITY/Increasing.thy @@ -1,227 +1,227 @@ (* Title: ZF/UNITY/Increasing.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2001 University of Cambridge Increasing's parameters are a state function f, a domain A and an order relation r over the domain A. *) section\Charpentier's "Increasing" Relation\ theory Increasing imports Constrains Monotonicity begin definition increasing :: "[i, i, i\i] \ i" (\increasing[_]'(_, _')\) where "increasing[A](r, f) \ {F \ program. (\k \ A. F \ stable({s \ state. \ r})) \ (\x \ state. f(x):A)}" definition Increasing :: "[i, i, i\i] \ i" (\Increasing[_]'(_, _')\) where "Increasing[A](r, f) \ {F \ program. (\k \ A. F \ Stable({s \ state. \ r})) \ (\x \ state. f(x):A)}" abbreviation (input) IncWrt :: "[i\i, i, i] \ i" (\(_ IncreasingWrt _ '/ _)\ [60, 0, 60] 60) where "f IncreasingWrt r/A \ Increasing[A](r,f)" (** increasing **) lemma increasing_type: "increasing[A](r, f) \ program" by (unfold increasing_def, blast) lemma increasing_into_program: "F \ increasing[A](r, f) \ F \ program" by (unfold increasing_def, blast) lemma increasing_imp_stable: "\F \ increasing[A](r, f); x \ A\ \F \ stable({s \ state. :r})" by (unfold increasing_def, blast) lemma increasingD: "F \ increasing[A](r,f) \ F \ program \ (\a. a \ A) \ (\s \ state. f(s):A)" -apply (unfold increasing_def) + unfolding increasing_def apply (subgoal_tac "\x. x \ state") apply (auto dest: stable_type [THEN subsetD] intro: st0_in_state) done lemma increasing_constant [simp]: "F \ increasing[A](r, \s. c) \ F \ program \ c \ A" apply (unfold increasing_def stable_def) apply (subgoal_tac "\x. x \ state") apply (auto dest: stable_type [THEN subsetD] intro: st0_in_state) done lemma subset_increasing_comp: "\mono1(A, r, B, s, g); refl(A, r); trans[B](s)\ \ increasing[A](r, f) \ increasing[B](s, g comp f)" apply (unfold increasing_def stable_def part_order_def constrains_def mono1_def metacomp_def, clarify, simp) apply clarify apply (subgoal_tac "xa \ state") prefer 2 apply (blast dest!: ActsD) apply (subgoal_tac ":r") prefer 2 apply (force simp add: refl_def) apply (rotate_tac 5) apply (drule_tac x = "f (xb) " in bspec) apply (rotate_tac [2] -1) apply (drule_tac [2] x = act in bspec, simp_all) apply (drule_tac A = "act``u" and c = xa for u in subsetD, blast) apply (drule_tac x = "f(xa) " and x1 = "f(xb)" in bspec [THEN bspec]) apply (rule_tac [3] b = "g (f (xb))" and A = B in trans_onD) apply simp_all done lemma imp_increasing_comp: "\F \ increasing[A](r, f); mono1(A, r, B, s, g); refl(A, r); trans[B](s)\ \ F \ increasing[B](s, g comp f)" by (rule subset_increasing_comp [THEN subsetD], auto) lemma strict_increasing: "increasing[nat](Le, f) \ increasing[nat](Lt, f)" by (unfold increasing_def Lt_def, auto) lemma strict_gt_increasing: "increasing[nat](Ge, f) \ increasing[nat](Gt, f)" apply (unfold increasing_def Gt_def Ge_def, auto) apply (erule natE) apply (auto simp add: stable_def) done (** Increasing **) lemma increasing_imp_Increasing: "F \ increasing[A](r, f) \ F \ Increasing[A](r, f)" apply (unfold increasing_def Increasing_def) apply (auto intro: stable_imp_Stable) done lemma Increasing_type: "Increasing[A](r, f) \ program" by (unfold Increasing_def, auto) lemma Increasing_into_program: "F \ Increasing[A](r, f) \ F \ program" by (unfold Increasing_def, auto) lemma Increasing_imp_Stable: "\F \ Increasing[A](r, f); a \ A\ \ F \ Stable({s \ state. :r})" by (unfold Increasing_def, blast) lemma IncreasingD: "F \ Increasing[A](r, f) \ F \ program \ (\a. a \ A) \ (\s \ state. f(s):A)" -apply (unfold Increasing_def) + unfolding Increasing_def apply (subgoal_tac "\x. x \ state") apply (auto intro: st0_in_state) done lemma Increasing_constant [simp]: "F \ Increasing[A](r, \s. c) \ F \ program \ (c \ A)" apply (subgoal_tac "\x. x \ state") apply (auto dest!: IncreasingD intro: st0_in_state increasing_imp_Increasing) done lemma subset_Increasing_comp: "\mono1(A, r, B, s, g); refl(A, r); trans[B](s)\ \ Increasing[A](r, f) \ Increasing[B](s, g comp f)" apply (unfold Increasing_def Stable_def Constrains_def part_order_def constrains_def mono1_def metacomp_def, safe) apply (simp_all add: ActsD) apply (subgoal_tac "xb \ state \ xa \ state") prefer 2 apply (simp add: ActsD) apply (subgoal_tac ":r") prefer 2 apply (force simp add: refl_def) apply (rotate_tac 5) apply (drule_tac x = "f (xb) " in bspec) apply simp_all apply clarify apply (rotate_tac -2) apply (drule_tac x = act in bspec) apply (drule_tac [2] A = "act``u" and c = xa for u in subsetD, simp_all, blast) apply (drule_tac x = "f(xa)" and x1 = "f(xb)" in bspec [THEN bspec]) apply (rule_tac [3] b = "g (f (xb))" and A = B in trans_onD) apply simp_all done lemma imp_Increasing_comp: "\F \ Increasing[A](r, f); mono1(A, r, B, s, g); refl(A, r); trans[B](s)\ \ F \ Increasing[B](s, g comp f)" apply (rule subset_Increasing_comp [THEN subsetD], auto) done lemma strict_Increasing: "Increasing[nat](Le, f) \ Increasing[nat](Lt, f)" by (unfold Increasing_def Lt_def, auto) lemma strict_gt_Increasing: "Increasing[nat](Ge, f)<= Increasing[nat](Gt, f)" apply (unfold Increasing_def Ge_def Gt_def, auto) apply (erule natE) apply (auto simp add: Stable_def) done (** Two-place monotone operations **) lemma imp_increasing_comp2: "\F \ increasing[A](r, f); F \ increasing[B](s, g); mono2(A, r, B, s, C, t, h); refl(A, r); refl(B, s); trans[C](t)\ \ F \ increasing[C](t, \x. h(f(x), g(x)))" apply (unfold increasing_def stable_def part_order_def constrains_def mono2_def, clarify, simp) apply clarify apply (rename_tac xa xb) apply (subgoal_tac "xb \ state \ xa \ state") prefer 2 apply (blast dest!: ActsD) apply (subgoal_tac ":r \ :s") prefer 2 apply (force simp add: refl_def) apply (rotate_tac 6) apply (drule_tac x = "f (xb) " in bspec) apply (rotate_tac [2] 1) apply (drule_tac [2] x = "g (xb) " in bspec) apply simp_all apply (rotate_tac -1) apply (drule_tac x = act in bspec) apply (rotate_tac [2] -3) apply (drule_tac [2] x = act in bspec, simp_all) apply (drule_tac A = "act``u" and c = xa for u in subsetD) apply (drule_tac [2] A = "act``u" and c = xa for u in subsetD, blast, blast) apply (rotate_tac -4) apply (drule_tac x = "f (xa) " and x1 = "f (xb) " in bspec [THEN bspec]) apply (rotate_tac [3] -1) apply (drule_tac [3] x = "g (xa) " and x1 = "g (xb) " in bspec [THEN bspec]) apply simp_all apply (rule_tac b = "h (f (xb), g (xb))" and A = C in trans_onD) apply simp_all done lemma imp_Increasing_comp2: "\F \ Increasing[A](r, f); F \ Increasing[B](s, g); mono2(A, r, B, s, C, t, h); refl(A, r); refl(B, s); trans[C](t)\ \ F \ Increasing[C](t, \x. h(f(x), g(x)))" apply (unfold Increasing_def stable_def part_order_def constrains_def mono2_def Stable_def Constrains_def, safe) apply (simp_all add: ActsD) apply (subgoal_tac "xa \ state \ x \ state") prefer 2 apply (blast dest!: ActsD) apply (subgoal_tac ":r \ :s") prefer 2 apply (force simp add: refl_def) apply (rotate_tac 6) apply (drule_tac x = "f (xa) " in bspec) apply (rotate_tac [2] 1) apply (drule_tac [2] x = "g (xa) " in bspec) apply simp_all apply clarify apply (rotate_tac -2) apply (drule_tac x = act in bspec) apply (rotate_tac [2] -3) apply (drule_tac [2] x = act in bspec, simp_all) apply (drule_tac A = "act``u" and c = x for u in subsetD) apply (drule_tac [2] A = "act``u" and c = x for u in subsetD, blast, blast) apply (rotate_tac -9) apply (drule_tac x = "f (x) " and x1 = "f (xa) " in bspec [THEN bspec]) apply (rotate_tac [3] -1) apply (drule_tac [3] x = "g (x) " and x1 = "g (xa) " in bspec [THEN bspec]) apply simp_all apply (rule_tac b = "h (f (xa), g (xa))" and A = C in trans_onD) apply simp_all done end diff --git a/src/ZF/UNITY/Merge.thy b/src/ZF/UNITY/Merge.thy --- a/src/ZF/UNITY/Merge.thy +++ b/src/ZF/UNITY/Merge.thy @@ -1,196 +1,196 @@ (* Title: ZF/UNITY/Merge.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2002 University of Cambridge A multiple-client allocator from a single-client allocator: Merge specification. *) theory Merge imports AllocBase Follows Guar GenPrefix begin (** Merge specification (the number of inputs is Nclients) ***) (** Parameter A represents the type of items to Merge **) definition (*spec (10)*) merge_increasing :: "[i, i, i] \i" where "merge_increasing(A, Out, iOut) \ program guarantees (lift(Out) IncreasingWrt prefix(A)/list(A)) Int (lift(iOut) IncreasingWrt prefix(nat)/list(nat))" definition (*spec (11)*) merge_eq_Out :: "[i, i] \i" where "merge_eq_Out(Out, iOut) \ program guarantees Always({s \ state. length(s`Out) = length(s`iOut)})" definition (*spec (12)*) merge_bounded :: "i\i" where "merge_bounded(iOut) \ program guarantees Always({s \ state. \elt \ set_of_list(s`iOut). elti, i, i] \i" where "merge_follows(A, In, Out, iOut) \ (\n \ Nclients. lift(In(n)) IncreasingWrt prefix(A)/list(A)) guarantees (\n \ Nclients. (\s. sublist(s`Out, {k \ nat. k < length(s`iOut) \ nth(k, s`iOut) = n})) Fols lift(In(n)) Wrt prefix(A)/list(A))" definition (*spec: preserves part*) merge_preserves :: "[i\i] \i" where "merge_preserves(In) \ \n \ nat. preserves(lift(In(n)))" definition (* environmental constraints*) merge_allowed_acts :: "[i, i] \i" where "merge_allowed_acts(Out, iOut) \ {F \ program. AllowedActs(F) = cons(id(state), (\G \ preserves(lift(Out)) \ preserves(lift(iOut)). Acts(G)))}" definition merge_spec :: "[i, i \i, i, i]\i" where "merge_spec(A, In, Out, iOut) \ merge_increasing(A, Out, iOut) \ merge_eq_Out(Out, iOut) \ merge_bounded(iOut) \ merge_follows(A, In, Out, iOut) \ merge_allowed_acts(Out, iOut) \ merge_preserves(In)" (** State definitions. OUTPUT variables are locals **) locale merge = fixes In \ \merge's INPUT histories: streams to merge\ and Out \ \merge's OUTPUT history: merged items\ and iOut \ \merge's OUTPUT history: origins of merged items\ and A \ \the type of items being merged\ and M assumes var_assumes [simp]: "(\n. In(n):var) \ Out \ var \ iOut \ var" and all_distinct_vars: "\n. all_distinct([In(n), Out, iOut])" and type_assumes [simp]: "(\n. type_of(In(n))=list(A)) \ type_of(Out)=list(A) \ type_of(iOut)=list(nat)" and default_val_assumes [simp]: "(\n. default_val(In(n))=Nil) \ default_val(Out)=Nil \ default_val(iOut)=Nil" and merge_spec: "M \ merge_spec(A, In, Out, iOut)" lemma (in merge) In_value_type [TC,simp]: "s \ state \ s`In(n) \ list(A)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = "In (n)" in apply_type) apply auto done lemma (in merge) Out_value_type [TC,simp]: "s \ state \ s`Out \ list(A)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = Out in apply_type, auto) done lemma (in merge) iOut_value_type [TC,simp]: "s \ state \ s`iOut \ list(nat)" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = iOut in apply_type, auto) done lemma (in merge) M_in_program [intro,simp]: "M \ program" apply (cut_tac merge_spec) apply (auto dest: guarantees_type [THEN subsetD] simp add: merge_spec_def merge_increasing_def) done lemma (in merge) merge_Allowed: "Allowed(M) = (preserves(lift(Out)) \ preserves(lift(iOut)))" apply (insert merge_spec preserves_type [of "lift (Out)"]) apply (auto simp add: merge_spec_def merge_allowed_acts_def Allowed_def safety_prop_Acts_iff) done lemma (in merge) M_ok_iff: "G \ program \ M ok G \ (G \ preserves(lift(Out)) \ G \ preserves(lift(iOut)) \ M \ Allowed(G))" apply (cut_tac merge_spec) apply (auto simp add: merge_Allowed ok_iff_Allowed) done lemma (in merge) merge_Always_Out_eq_iOut: "\G \ preserves(lift(Out)); G \ preserves(lift(iOut)); M \ Allowed(G)\ \ M \ G \ Always({s \ state. length(s`Out)=length(s`iOut)})" apply (frule preserves_type [THEN subsetD]) apply (subgoal_tac "G \ program") prefer 2 apply assumption apply (frule M_ok_iff) apply (cut_tac merge_spec) apply (force dest: guaranteesD simp add: merge_spec_def merge_eq_Out_def) done lemma (in merge) merge_Bounded: "\G \ preserves(lift(iOut)); G \ preserves(lift(Out)); M \ Allowed(G)\ \ M \ G: Always({s \ state. \elt \ set_of_list(s`iOut). eltG \ preserves(lift(iOut)); G: preserves(lift(Out)); M \ Allowed(G)\ \ M \ G \ Always ({s \ state. msetsum(\i. bag_of(sublist(s`Out, {k \ nat. k < length(s`iOut) \ nth(k, s`iOut)=i})), Nclients, A) = bag_of(s`Out)})" apply (rule Always_Diff_Un_eq [THEN iffD1]) apply (rule_tac [2] state_AlwaysI [THEN Always_weaken]) apply (rule Always_Int_I [OF merge_Always_Out_eq_iOut merge_Bounded], auto) apply (subst bag_of_sublist_UN_disjoint [symmetric]) apply (auto simp add: nat_into_Finite set_of_list_conv_nth [OF iOut_value_type]) apply (subgoal_tac " (\i \ Nclients. {k \ nat. k < length (x`iOut) \ nth (k, x`iOut) = i}) = length (x`iOut) ") apply (auto simp add: sublist_upt_eq_take [OF Out_value_type] length_type [OF iOut_value_type] take_all [OF _ Out_value_type] length_type [OF iOut_value_type]) apply (rule equalityI) apply (blast dest: ltD, clarify) apply (subgoal_tac "length (x ` iOut) \ nat") prefer 2 apply (simp add: length_type [OF iOut_value_type]) apply (subgoal_tac "xa \ nat") apply (simp_all add: Ord_mem_iff_lt) prefer 2 apply (blast intro: lt_trans) apply (drule_tac x = "nth (xa, x`iOut)" and P = "\elt. X (elt) \ elt (\n \ Nclients. lift(In(n)) IncreasingWrt prefix(A)/list(A)) guarantees (\s. bag_of(s`Out)) Fols (\s. msetsum(\i. bag_of(s`In(i)),Nclients, A)) Wrt MultLe(A, r)/Mult(A)" apply (cut_tac merge_spec) apply (rule merge_bag_Follows_lemma [THEN Always_Follows1, THEN guaranteesI]) apply (simp_all add: M_ok_iff, clarify) apply (rule Follows_state_ofD1 [OF Follows_msetsum_UN]) apply (simp_all add: nat_into_Finite bag_of_multiset [of _ A]) apply (simp add: INT_iff merge_spec_def merge_follows_def, clarify) apply (cut_tac merge_spec) apply (subgoal_tac "M ok G") prefer 2 apply (force intro: M_ok_iff [THEN iffD2]) apply (drule guaranteesD, assumption) apply (simp add: merge_spec_def merge_follows_def, blast) apply (simp cong add: Follows_cong add: refl_prefix mono_bag_of [THEN subset_Follows_comp, THEN subsetD, unfolded metacomp_def]) done end diff --git a/src/ZF/UNITY/Monotonicity.thy b/src/ZF/UNITY/Monotonicity.thy --- a/src/ZF/UNITY/Monotonicity.thy +++ b/src/ZF/UNITY/Monotonicity.thy @@ -1,120 +1,120 @@ (* Title: ZF/UNITY/Monotonicity.thy Author: Sidi O Ehmety, Cambridge University Computer Laboratory Copyright 2002 University of Cambridge Monotonicity of an operator (meta-function) with respect to arbitrary set relations. *) section\Monotonicity of an Operator WRT a Relation\ theory Monotonicity imports GenPrefix MultisetSum begin definition mono1 :: "[i, i, i, i, i\i] \ o" where "mono1(A, r, B, s, f) \ (\x \ A. \y \ A. \x,y\ \ r \ \ s) \ (\x \ A. f(x) \ B)" (* monotonicity of a 2-place meta-function f *) definition mono2 :: "[i, i, i, i, i, i, [i,i]\i] \ o" where "mono2(A, r, B, s, C, t, f) \ (\x \ A. \y \ A. \u \ B. \v \ B. \x,y\ \ r \ \u,v\ \ s \ \ t) \ (\x \ A. \y \ B. f(x,y) \ C)" (* Internalized relations on sets and multisets *) definition SetLe :: "i \i" where "SetLe(A) \ {\x,y\ \ Pow(A)*Pow(A). x \ y}" definition MultLe :: "[i,i] \i" where "MultLe(A, r) \ multirel(A, r - id(A)) \ id(Mult(A))" lemma mono1D: "\mono1(A, r, B, s, f); \x, y\ \ r; x \ A; y \ A\ \ \ s" by (unfold mono1_def, auto) lemma mono2D: "\mono2(A, r, B, s, C, t, f); \x, y\ \ r; \u,v\ \ s; x \ A; y \ A; u \ B; v \ B\ \ \ t" by (unfold mono2_def, auto) (** Monotonicity of take **) lemma take_mono_left_lemma: "\i \ j; xs \ list(A); i \ nat; j \ nat\ \ \ prefix(A)" apply (case_tac "length (xs) \ i") apply (subgoal_tac "length (xs) \ j") apply (simp) apply (blast intro: le_trans) apply (drule not_lt_imp_le, auto) apply (case_tac "length (xs) \ j") apply (auto simp add: take_prefix) apply (drule not_lt_imp_le, auto) apply (drule_tac m = i in less_imp_succ_add, auto) apply (subgoal_tac "i #+ k \ length (xs) ") apply (simp add: take_add prefix_iff take_type drop_type) apply (blast intro: leI) done lemma take_mono_left: "\i \ j; xs \ list(A); j \ nat\ \ \ prefix(A)" by (blast intro: le_in_nat take_mono_left_lemma) lemma take_mono_right: "\\xs,ys\ \ prefix(A); i \ nat\ \ \ prefix(A)" by (auto simp add: prefix_iff) lemma take_mono: "\i \ j; \xs, ys\ \ prefix(A); j \ nat\ \ \ prefix(A)" apply (rule_tac b = "take (j, xs) " in prefix_trans) apply (auto dest: prefix_type [THEN subsetD] intro: take_mono_left take_mono_right) done lemma mono_take [iff]: "mono2(nat, Le, list(A), prefix(A), list(A), prefix(A), take)" apply (unfold mono2_def Le_def, auto) apply (blast intro: take_mono) done (** Monotonicity of length **) lemmas length_mono = prefix_length_le lemma mono_length [iff]: "mono1(list(A), prefix(A), nat, Le, length)" -apply (unfold mono1_def) + unfolding mono1_def apply (auto dest: prefix_length_le simp add: Le_def) done (** Monotonicity of \ **) lemma mono_Un [iff]: "mono2(Pow(A), SetLe(A), Pow(A), SetLe(A), Pow(A), SetLe(A), (Un))" by (unfold mono2_def SetLe_def, auto) (* Monotonicity of multiset union *) lemma mono_munion [iff]: "mono2(Mult(A), MultLe(A,r), Mult(A), MultLe(A, r), Mult(A), MultLe(A, r), munion)" apply (unfold mono2_def MultLe_def) apply (auto simp add: Mult_iff_multiset) apply (blast intro: munion_multirel_mono munion_multirel_mono1 munion_multirel_mono2 multiset_into_Mult)+ done lemma mono_succ [iff]: "mono1(nat, Le, nat, Le, succ)" by (unfold mono1_def Le_def, auto) end diff --git a/src/ZF/UNITY/Mutex.thy b/src/ZF/UNITY/Mutex.thy --- a/src/ZF/UNITY/Mutex.thy +++ b/src/ZF/UNITY/Mutex.thy @@ -1,320 +1,320 @@ (* Title: ZF/UNITY/Mutex.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge Based on "A Family of 2-Process Mutual Exclusion Algorithms" by J Misra. Variables' types are introduced globally so that type verification reduces to the usual ZF typechecking \ an ill-tyed expression will reduce to the empty set. *) section\Mutual Exclusion\ theory Mutex imports SubstAx begin text\Based on "A Family of 2-Process Mutual Exclusion Algorithms" by J Misra Variables' types are introduced globally so that type verification reduces to the usual ZF typechecking: an ill-tyed expressions reduce to the empty set. \ abbreviation "p \ Var([0])" abbreviation "m \ Var([1])" abbreviation "n \ Var([0,0])" abbreviation "u \ Var([0,1])" abbreviation "v \ Var([1,0])" axiomatization where \ \Type declarations\ p_type: "type_of(p)=bool \ default_val(p)=0" and m_type: "type_of(m)=int \ default_val(m)=#0" and n_type: "type_of(n)=int \ default_val(n)=#0" and u_type: "type_of(u)=bool \ default_val(u)=0" and v_type: "type_of(v)=bool \ default_val(v)=0" definition (** The program for process U **) "U0 \ {\s,t\:state*state. t = s(u:=1, m:=#1) \ s`m = #0}" definition "U1 \ {\s,t\:state*state. t = s(p:= s`v, m:=#2) \ s`m = #1}" definition "U2 \ {\s,t\:state*state. t = s(m:=#3) \ s`p=0 \ s`m = #2}" definition "U3 \ {\s,t\:state*state. t=s(u:=0, m:=#4) \ s`m = #3}" definition "U4 \ {\s,t\:state*state. t = s(p:=1, m:=#0) \ s`m = #4}" (** The program for process V **) definition "V0 \ {\s,t\:state*state. t = s (v:=1, n:=#1) \ s`n = #0}" definition "V1 \ {\s,t\:state*state. t = s(p:=not(s`u), n:=#2) \ s`n = #1}" definition "V2 \ {\s,t\:state*state. t = s(n:=#3) \ s`p=1 \ s`n = #2}" definition "V3 \ {\s,t\:state*state. t = s (v:=0, n:=#4) \ s`n = #3}" definition "V4 \ {\s,t\:state*state. t = s (p:=0, n:=#0) \ s`n = #4}" definition "Mutex \ mk_program({s:state. s`u=0 \ s`v=0 \ s`m = #0 \ s`n = #0}, {U0, U1, U2, U3, U4, V0, V1, V2, V3, V4}, Pow(state*state))" (** The correct invariants **) definition "IU \ {s:state. (s`u = 1\(#1 $\ s`m \ s`m $\ #3)) \ (s`m = #3 \ s`p=0)}" definition "IV \ {s:state. (s`v = 1 \ (#1 $\ s`n \ s`n $\ #3)) \ (s`n = #3 \ s`p=1)}" (** The faulty invariant (for U alone) **) definition "bad_IU \ {s:state. (s`u = 1 \ (#1 $\ s`m \ s`m $\ #3))\ (#3 $\ s`m \ s`m $\ #4 \ s`p=0)}" (** Variables' types **) declare p_type [simp] u_type [simp] v_type [simp] m_type [simp] n_type [simp] lemma u_value_type: "s \ state \s`u \ bool" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = u in apply_type, auto) done lemma v_value_type: "s \ state \ s`v \ bool" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = v in apply_type, auto) done lemma p_value_type: "s \ state \ s`p \ bool" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = p in apply_type, auto) done lemma m_value_type: "s \ state \ s`m \ int" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = m in apply_type, auto) done lemma n_value_type: "s \ state \s`n \ int" -apply (unfold state_def) + unfolding state_def apply (drule_tac a = n in apply_type, auto) done declare p_value_type [simp] u_value_type [simp] v_value_type [simp] m_value_type [simp] n_value_type [simp] declare p_value_type [TC] u_value_type [TC] v_value_type [TC] m_value_type [TC] n_value_type [TC] text\Mutex is a program\ lemma Mutex_in_program [simp,TC]: "Mutex \ program" by (simp add: Mutex_def) declare Mutex_def [THEN def_prg_Init, simp] declare Mutex_def [program] declare U0_def [THEN def_act_simp, simp] declare U1_def [THEN def_act_simp, simp] declare U2_def [THEN def_act_simp, simp] declare U3_def [THEN def_act_simp, simp] declare U4_def [THEN def_act_simp, simp] declare V0_def [THEN def_act_simp, simp] declare V1_def [THEN def_act_simp, simp] declare V2_def [THEN def_act_simp, simp] declare V3_def [THEN def_act_simp, simp] declare V4_def [THEN def_act_simp, simp] declare U0_def [THEN def_set_simp, simp] declare U1_def [THEN def_set_simp, simp] declare U2_def [THEN def_set_simp, simp] declare U3_def [THEN def_set_simp, simp] declare U4_def [THEN def_set_simp, simp] declare V0_def [THEN def_set_simp, simp] declare V1_def [THEN def_set_simp, simp] declare V2_def [THEN def_set_simp, simp] declare V3_def [THEN def_set_simp, simp] declare V4_def [THEN def_set_simp, simp] declare IU_def [THEN def_set_simp, simp] declare IV_def [THEN def_set_simp, simp] declare bad_IU_def [THEN def_set_simp, simp] lemma IU: "Mutex \ Always(IU)" apply (rule AlwaysI, force) apply (unfold Mutex_def, safety, auto) done lemma IV: "Mutex \ Always(IV)" apply (rule AlwaysI, force) apply (unfold Mutex_def, safety) done (*The safety property: mutual exclusion*) lemma mutual_exclusion: "Mutex \ Always({s \ state. \(s`m = #3 \ s`n = #3)})" apply (rule Always_weaken) apply (rule Always_Int_I [OF IU IV], auto) done (*The bad invariant FAILS in V1*) lemma less_lemma: "\x$<#1; #3 $\ x\ \ P" apply (drule_tac j = "#1" and k = "#3" in zless_zle_trans) apply (drule_tac [2] j = x in zle_zless_trans, auto) done lemma "Mutex \ Always(bad_IU)" apply (rule AlwaysI, force) apply (unfold Mutex_def, safety, auto) apply (subgoal_tac "#1 $\ #3") apply (drule_tac x = "#1" and y = "#3" in zle_trans, auto) apply (simp (no_asm) add: not_zless_iff_zle [THEN iff_sym]) apply auto (*Resulting state: n=1, p=false, m=4, u=false. Execution of V1 (the command of process v guarded by n=1) sets p:=true, violating the invariant!*) oops (*** Progress for U ***) lemma U_F0: "Mutex \ {s \ state. s`m=#2} Unless {s \ state. s`m=#3}" by (unfold op_Unless_def Mutex_def, safety) lemma U_F1: "Mutex \ {s \ state. s`m=#1} \w {s \ state. s`p = s`v \ s`m = #2}" by (unfold Mutex_def, ensures U1) lemma U_F2: "Mutex \ {s \ state. s`p =0 \ s`m = #2} \w {s \ state. s`m = #3}" apply (cut_tac IU) apply (unfold Mutex_def, ensures U2) done lemma U_F3: "Mutex \ {s \ state. s`m = #3} \w {s \ state. s`p=1}" apply (rule_tac B = "{s \ state. s`m = #4}" in LeadsTo_Trans) - apply (unfold Mutex_def) + unfolding Mutex_def apply (ensures U3) apply (ensures U4) done lemma U_lemma2: "Mutex \ {s \ state. s`m = #2} \w {s \ state. s`p=1}" apply (rule LeadsTo_Diff [OF LeadsTo_weaken_L Int_lower2 [THEN subset_imp_LeadsTo]]) apply (rule LeadsTo_Trans [OF U_F2 U_F3], auto) apply (auto dest!: p_value_type simp add: bool_def) done lemma U_lemma1: "Mutex \ {s \ state. s`m = #1} \w {s \ state. s`p =1}" by (rule LeadsTo_Trans [OF U_F1 [THEN LeadsTo_weaken_R] U_lemma2], blast) lemma eq_123: "i \ int \ (#1 $\ i \ i $\ #3) \ (i=#1 | i=#2 | i=#3)" apply auto apply (auto simp add: neq_iff_zless) apply (drule_tac [4] j = "#3" and i = i in zle_zless_trans) apply (drule_tac [2] j = i and i = "#1" in zle_zless_trans) apply (drule_tac j = i and i = "#1" in zle_zless_trans, auto) apply (rule zle_anti_sym) apply (simp_all (no_asm_simp) add: zless_add1_iff_zle [THEN iff_sym]) done lemma U_lemma123: "Mutex \ {s \ state. #1 $\ s`m \ s`m $\ #3} \w {s \ state. s`p=1}" by (simp add: eq_123 Collect_disj_eq LeadsTo_Un_distrib U_lemma1 U_lemma2 U_F3) (*Misra's F4*) lemma u_Leadsto_p: "Mutex \ {s \ state. s`u = 1} \w {s \ state. s`p=1}" by (rule Always_LeadsTo_weaken [OF IU U_lemma123], auto) (*** Progress for V ***) lemma V_F0: "Mutex \ {s \ state. s`n=#2} Unless {s \ state. s`n=#3}" by (unfold op_Unless_def Mutex_def, safety) lemma V_F1: "Mutex \ {s \ state. s`n=#1} \w {s \ state. s`p = not(s`u) \ s`n = #2}" by (unfold Mutex_def, ensures "V1") lemma V_F2: "Mutex \ {s \ state. s`p=1 \ s`n = #2} \w {s \ state. s`n = #3}" apply (cut_tac IV) apply (unfold Mutex_def, ensures "V2") done lemma V_F3: "Mutex \ {s \ state. s`n = #3} \w {s \ state. s`p=0}" apply (rule_tac B = "{s \ state. s`n = #4}" in LeadsTo_Trans) - apply (unfold Mutex_def) + unfolding Mutex_def apply (ensures V3) apply (ensures V4) done lemma V_lemma2: "Mutex \ {s \ state. s`n = #2} \w {s \ state. s`p=0}" apply (rule LeadsTo_Diff [OF LeadsTo_weaken_L Int_lower2 [THEN subset_imp_LeadsTo]]) apply (rule LeadsTo_Trans [OF V_F2 V_F3], auto) apply (auto dest!: p_value_type simp add: bool_def) done lemma V_lemma1: "Mutex \ {s \ state. s`n = #1} \w {s \ state. s`p = 0}" by (rule LeadsTo_Trans [OF V_F1 [THEN LeadsTo_weaken_R] V_lemma2], blast) lemma V_lemma123: "Mutex \ {s \ state. #1 $\ s`n \ s`n $\ #3} \w {s \ state. s`p = 0}" by (simp add: eq_123 Collect_disj_eq LeadsTo_Un_distrib V_lemma1 V_lemma2 V_F3) (*Misra's F4*) lemma v_Leadsto_not_p: "Mutex \ {s \ state. s`v = 1} \w {s \ state. s`p = 0}" by (rule Always_LeadsTo_weaken [OF IV V_lemma123], auto) (** Absence of starvation **) (*Misra's F6*) lemma m1_Leadsto_3: "Mutex \ {s \ state. s`m = #1} \w {s \ state. s`m = #3}" apply (rule LeadsTo_cancel2 [THEN LeadsTo_Un_duplicate]) apply (rule_tac [2] U_F2) apply (simp add: Collect_conj_eq) apply (subst Un_commute) apply (rule LeadsTo_cancel2 [THEN LeadsTo_Un_duplicate]) apply (rule_tac [2] PSP_Unless [OF v_Leadsto_not_p U_F0]) apply (rule U_F1 [THEN LeadsTo_weaken_R], auto) apply (auto dest!: v_value_type simp add: bool_def) done (*The same for V*) lemma n1_Leadsto_3: "Mutex \ {s \ state. s`n = #1} \w {s \ state. s`n = #3}" apply (rule LeadsTo_cancel2 [THEN LeadsTo_Un_duplicate]) apply (rule_tac [2] V_F2) apply (simp add: Collect_conj_eq) apply (subst Un_commute) apply (rule LeadsTo_cancel2 [THEN LeadsTo_Un_duplicate]) apply (rule_tac [2] PSP_Unless [OF u_Leadsto_p V_F0]) apply (rule V_F1 [THEN LeadsTo_weaken_R], auto) apply (auto dest!: u_value_type simp add: bool_def) done end diff --git a/src/ZF/UNITY/SubstAx.thy b/src/ZF/UNITY/SubstAx.thy --- a/src/ZF/UNITY/SubstAx.thy +++ b/src/ZF/UNITY/SubstAx.thy @@ -1,380 +1,380 @@ (* Title: ZF/UNITY/SubstAx.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge Theory ported from HOL. *) section\Weak LeadsTo relation (restricted to the set of reachable states)\ theory SubstAx imports WFair Constrains begin definition (* The definitions below are not `conventional', but yield simpler rules *) Ensures :: "[i,i] \ i" (infixl \Ensures\ 60) where "A Ensures B \ {F \ program. F \ (reachable(F) \ A) ensures (reachable(F) \ B) }" definition LeadsTo :: "[i, i] \ i" (infixl \\w\ 60) where "A \w B \ {F \ program. F:(reachable(F) \ A) \ (reachable(F) \ B)}" (*Resembles the previous definition of LeadsTo*) (* Equivalence with the HOL-like definition *) lemma LeadsTo_eq: "st_set(B)\ A \w B = {F \ program. F:(reachable(F) \ A) \ B}" -apply (unfold LeadsTo_def) + unfolding LeadsTo_def apply (blast dest: psp_stable2 leadsToD2 constrainsD2 intro: leadsTo_weaken) done lemma LeadsTo_type: "A \w B <=program" by (unfold LeadsTo_def, auto) (*** Specialized laws for handling invariants ***) (** Conjoining an Always property **) lemma Always_LeadsTo_pre: "F \ Always(I) \ (F:(I \ A) \w A') \ (F \ A \w A')" by (simp add: LeadsTo_def Always_eq_includes_reachable Int_absorb2 Int_assoc [symmetric] leadsToD2) lemma Always_LeadsTo_post: "F \ Always(I) \ (F \ A \w (I \ A')) \ (F \ A \w A')" -apply (unfold LeadsTo_def) + unfolding LeadsTo_def apply (simp add: Always_eq_includes_reachable Int_absorb2 Int_assoc [symmetric] leadsToD2) done (* Like 'Always_LeadsTo_pre RS iffD1', but with premises in the good order *) lemma Always_LeadsToI: "\F \ Always(C); F \ (C \ A) \w A'\ \ F \ A \w A'" by (blast intro: Always_LeadsTo_pre [THEN iffD1]) (* Like 'Always_LeadsTo_post RS iffD2', but with premises in the good order *) lemma Always_LeadsToD: "\F \ Always(C); F \ A \w A'\ \ F \ A \w (C \ A')" by (blast intro: Always_LeadsTo_post [THEN iffD2]) (*** Introduction rules \ Basis, Trans, Union ***) lemma LeadsTo_Basis: "F \ A Ensures B \ F \ A \w B" by (auto simp add: Ensures_def LeadsTo_def) lemma LeadsTo_Trans: "\F \ A \w B; F \ B \w C\ \ F \ A \w C" apply (simp (no_asm_use) add: LeadsTo_def) apply (blast intro: leadsTo_Trans) done lemma LeadsTo_Union: "\(\A. A \ S \ F \ A \w B); F \ program\\F \ \(S) \w B" apply (simp add: LeadsTo_def) apply (subst Int_Union_Union2) apply (rule leadsTo_UN, auto) done (*** Derived rules ***) lemma leadsTo_imp_LeadsTo: "F \ A \ B \ F \ A \w B" apply (frule leadsToD2, clarify) apply (simp (no_asm_simp) add: LeadsTo_eq) apply (blast intro: leadsTo_weaken_L) done (*Useful with cancellation, disjunction*) lemma LeadsTo_Un_duplicate: "F \ A \w (A' \ A') \ F \ A \w A'" by (simp add: Un_ac) lemma LeadsTo_Un_duplicate2: "F \ A \w (A' \ C \ C) \ F \ A \w (A' \ C)" by (simp add: Un_ac) lemma LeadsTo_UN: "\(\i. i \ I \ F \ A(i) \w B); F \ program\ \F:(\i \ I. A(i)) \w B" apply (simp add: LeadsTo_def) apply (simp (no_asm_simp) del: UN_simps add: Int_UN_distrib) apply (rule leadsTo_UN, auto) done (*Binary union introduction rule*) lemma LeadsTo_Un: "\F \ A \w C; F \ B \w C\ \ F \ (A \ B) \w C" apply (subst Un_eq_Union) apply (rule LeadsTo_Union) apply (auto dest: LeadsTo_type [THEN subsetD]) done (*Lets us look at the starting state*) lemma single_LeadsTo_I: "\(\s. s \ A \ F:{s} \w B); F \ program\\F \ A \w B" apply (subst UN_singleton [symmetric], rule LeadsTo_UN, auto) done lemma subset_imp_LeadsTo: "\A \ B; F \ program\ \ F \ A \w B" apply (simp (no_asm_simp) add: LeadsTo_def) apply (blast intro: subset_imp_leadsTo) done lemma empty_LeadsTo: "F \ 0 \w A \ F \ program" by (auto dest: LeadsTo_type [THEN subsetD] intro: empty_subsetI [THEN subset_imp_LeadsTo]) declare empty_LeadsTo [iff] lemma LeadsTo_state: "F \ A \w state \ F \ program" by (auto dest: LeadsTo_type [THEN subsetD] simp add: LeadsTo_eq) declare LeadsTo_state [iff] lemma LeadsTo_weaken_R: "\F \ A \w A'; A'<=B'\ \ F \ A \w B'" -apply (unfold LeadsTo_def) + unfolding LeadsTo_def apply (auto intro: leadsTo_weaken_R) done lemma LeadsTo_weaken_L: "\F \ A \w A'; B \ A\ \ F \ B \w A'" -apply (unfold LeadsTo_def) + unfolding LeadsTo_def apply (auto intro: leadsTo_weaken_L) done lemma LeadsTo_weaken: "\F \ A \w A'; B<=A; A'<=B'\ \ F \ B \w B'" by (blast intro: LeadsTo_weaken_R LeadsTo_weaken_L LeadsTo_Trans) lemma Always_LeadsTo_weaken: "\F \ Always(C); F \ A \w A'; C \ B \ A; C \ A' \ B'\ \ F \ B \w B'" apply (blast dest: Always_LeadsToI intro: LeadsTo_weaken Always_LeadsToD) done (** Two theorems for "proof lattices" **) lemma LeadsTo_Un_post: "F \ A \w B \ F:(A \ B) \w B" by (blast dest: LeadsTo_type [THEN subsetD] intro: LeadsTo_Un subset_imp_LeadsTo) lemma LeadsTo_Trans_Un: "\F \ A \w B; F \ B \w C\ \ F \ (A \ B) \w C" apply (blast intro: LeadsTo_Un subset_imp_LeadsTo LeadsTo_weaken_L LeadsTo_Trans dest: LeadsTo_type [THEN subsetD]) done (** Distributive laws **) lemma LeadsTo_Un_distrib: "(F \ (A \ B) \w C) \ (F \ A \w C \ F \ B \w C)" by (blast intro: LeadsTo_Un LeadsTo_weaken_L) lemma LeadsTo_UN_distrib: "(F \ (\i \ I. A(i)) \w B) \ (\i \ I. F \ A(i) \w B) \ F \ program" by (blast dest: LeadsTo_type [THEN subsetD] intro: LeadsTo_UN LeadsTo_weaken_L) lemma LeadsTo_Union_distrib: "(F \ \(S) \w B) \ (\A \ S. F \ A \w B) \ F \ program" by (blast dest: LeadsTo_type [THEN subsetD] intro: LeadsTo_Union LeadsTo_weaken_L) (** More rules using the premise "Always(I)" **) lemma EnsuresI: "\F:(A-B) Co (A \ B); F \ transient (A-B)\ \ F \ A Ensures B" apply (simp add: Ensures_def Constrains_eq_constrains) apply (blast intro: ensuresI constrains_weaken transient_strengthen dest: constrainsD2) done lemma Always_LeadsTo_Basis: "\F \ Always(I); F \ (I \ (A-A')) Co (A \ A'); F \ transient (I \ (A-A'))\ \ F \ A \w A'" apply (rule Always_LeadsToI, assumption) apply (blast intro: EnsuresI LeadsTo_Basis Always_ConstrainsD [THEN Constrains_weaken] transient_strengthen) done (*Set difference: maybe combine with leadsTo_weaken_L?? This is the most useful form of the "disjunction" rule*) lemma LeadsTo_Diff: "\F \ (A-B) \w C; F \ (A \ B) \w C\ \ F \ A \w C" by (blast intro: LeadsTo_Un LeadsTo_weaken) lemma LeadsTo_UN_UN: "\(\i. i \ I \ F \ A(i) \w A'(i)); F \ program\ \ F \ (\i \ I. A(i)) \w (\i \ I. A'(i))" apply (rule LeadsTo_Union, auto) apply (blast intro: LeadsTo_weaken_R) done (*Binary union version*) lemma LeadsTo_Un_Un: "\F \ A \w A'; F \ B \w B'\ \ F:(A \ B) \w (A' \ B')" by (blast intro: LeadsTo_Un LeadsTo_weaken_R) (** The cancellation law **) lemma LeadsTo_cancel2: "\F \ A \w(A' \ B); F \ B \w B'\ \ F \ A \w (A' \ B')" by (blast intro: LeadsTo_Un_Un subset_imp_LeadsTo LeadsTo_Trans dest: LeadsTo_type [THEN subsetD]) lemma Un_Diff: "A \ (B - A) = A \ B" by auto lemma LeadsTo_cancel_Diff2: "\F \ A \w (A' \ B); F \ (B-A') \w B'\ \ F \ A \w (A' \ B')" apply (rule LeadsTo_cancel2) prefer 2 apply assumption apply (simp (no_asm_simp) add: Un_Diff) done lemma LeadsTo_cancel1: "\F \ A \w (B \ A'); F \ B \w B'\ \ F \ A \w (B' \ A')" apply (simp add: Un_commute) apply (blast intro!: LeadsTo_cancel2) done lemma Diff_Un2: "(B - A) \ A = B \ A" by auto lemma LeadsTo_cancel_Diff1: "\F \ A \w (B \ A'); F \ (B-A') \w B'\ \ F \ A \w (B' \ A')" apply (rule LeadsTo_cancel1) prefer 2 apply assumption apply (simp (no_asm_simp) add: Diff_Un2) done (** The impossibility law **) (*The set "A" may be non-empty, but it contains no reachable states*) lemma LeadsTo_empty: "F \ A \w 0 \ F \ Always (state -A)" apply (simp (no_asm_use) add: LeadsTo_def Always_eq_includes_reachable) apply (cut_tac reachable_type) apply (auto dest!: leadsTo_empty) done (** PSP \ Progress-Safety-Progress **) (*Special case of PSP \ Misra's "stable conjunction"*) lemma PSP_Stable: "\F \ A \w A'; F \ Stable(B)\\ F:(A \ B) \w (A' \ B)" apply (simp add: LeadsTo_def Stable_eq_stable, clarify) apply (drule psp_stable, assumption) apply (simp add: Int_ac) done lemma PSP_Stable2: "\F \ A \w A'; F \ Stable(B)\ \ F \ (B \ A) \w (B \ A')" apply (simp (no_asm_simp) add: PSP_Stable Int_ac) done lemma PSP: "\F \ A \w A'; F \ B Co B'\\ F \ (A \ B') \w ((A' \ B) \ (B' - B))" apply (simp (no_asm_use) add: LeadsTo_def Constrains_eq_constrains) apply (blast dest: psp intro: leadsTo_weaken) done lemma PSP2: "\F \ A \w A'; F \ B Co B'\\ F:(B' \ A) \w ((B \ A') \ (B' - B))" by (simp (no_asm_simp) add: PSP Int_ac) lemma PSP_Unless: "\F \ A \w A'; F \ B Unless B'\\ F:(A \ B) \w ((A' \ B) \ B')" -apply (unfold op_Unless_def) + unfolding op_Unless_def apply (drule PSP, assumption) apply (blast intro: LeadsTo_Diff LeadsTo_weaken subset_imp_LeadsTo) done (*** Induction rules ***) (** Meta or object quantifier ????? **) lemma LeadsTo_wf_induct: "\wf(r); \m \ I. F \ (A \ f-``{m}) \w ((A \ f-``(converse(r) `` {m})) \ B); field(r)<=I; A<=f-``I; F \ program\ \ F \ A \w B" apply (simp (no_asm_use) add: LeadsTo_def) apply auto apply (erule_tac I = I and f = f in leadsTo_wf_induct, safe) apply (drule_tac [2] x = m in bspec, safe) apply (rule_tac [2] A' = "reachable (F) \ (A \ f -`` (converse (r) ``{m}) \ B) " in leadsTo_weaken_R) apply (auto simp add: Int_assoc) done lemma LessThan_induct: "\\m \ nat. F:(A \ f-``{m}) \w ((A \ f-``m) \ B); A<=f-``nat; F \ program\ \ F \ A \w B" apply (rule_tac A1 = nat and f1 = "\x. x" in wf_measure [THEN LeadsTo_wf_induct]) apply (simp_all add: nat_measure_field) apply (simp add: ltI Image_inverse_lessThan vimage_def [symmetric]) done (****** To be ported ??? I am not sure. integ_0_le_induct LessThan_bounded_induct GreaterThan_bounded_induct *****) (*** Completion \ Binary and General Finite versions ***) lemma Completion: "\F \ A \w (A' \ C); F \ A' Co (A' \ C); F \ B \w (B' \ C); F \ B' Co (B' \ C)\ \ F \ (A \ B) \w ((A' \ B') \ C)" apply (simp (no_asm_use) add: LeadsTo_def Constrains_eq_constrains Int_Un_distrib) apply (blast intro: completion leadsTo_weaken) done lemma Finite_completion_aux: "\I \ Fin(X);F \ program\ \ (\i \ I. F \ (A(i)) \w (A'(i) \ C)) \ (\i \ I. F \ (A'(i)) Co (A'(i) \ C)) \ F \ (\i \ I. A(i)) \w ((\i \ I. A'(i)) \ C)" apply (erule Fin_induct) apply (auto simp del: INT_simps simp add: Inter_0) apply (rule Completion, auto) apply (simp del: INT_simps add: INT_extend_simps) apply (blast intro: Constrains_INT) done lemma Finite_completion: "\I \ Fin(X); \i. i \ I \ F \ A(i) \w (A'(i) \ C); \i. i \ I \ F \ A'(i) Co (A'(i) \ C); F \ program\ \ F \ (\i \ I. A(i)) \w ((\i \ I. A'(i)) \ C)" by (blast intro: Finite_completion_aux [THEN mp, THEN mp]) lemma Stable_completion: "\F \ A \w A'; F \ Stable(A'); F \ B \w B'; F \ Stable(B')\ \ F \ (A \ B) \w (A' \ B')" -apply (unfold Stable_def) + unfolding Stable_def apply (rule_tac C1 = 0 in Completion [THEN LeadsTo_weaken_R]) prefer 5 apply blast apply auto done lemma Finite_stable_completion: "\I \ Fin(X); (\i. i \ I \ F \ A(i) \w A'(i)); (\i. i \ I \F \ Stable(A'(i))); F \ program\ \ F \ (\i \ I. A(i)) \w (\i \ I. A'(i))" -apply (unfold Stable_def) + unfolding Stable_def apply (rule_tac C1 = 0 in Finite_completion [THEN LeadsTo_weaken_R], simp_all) apply (rule_tac [3] subset_refl, auto) done ML \ (*proves "ensures/leadsTo" properties when the program is specified*) fun ensures_tac ctxt sact = SELECT_GOAL (EVERY [REPEAT (Always_Int_tac ctxt 1), eresolve_tac ctxt @{thms Always_LeadsTo_Basis} 1 ORELSE (*subgoal may involve LeadsTo, leadsTo or ensures*) REPEAT (ares_tac ctxt [@{thm LeadsTo_Basis}, @{thm leadsTo_Basis}, @{thm EnsuresI}, @{thm ensuresI}] 1), (*now there are two subgoals: co \ transient*) simp_tac (ctxt addsimps (Named_Theorems.get ctxt \<^named_theorems>\program\)) 2, Rule_Insts.res_inst_tac ctxt [((("act", 0), Position.none), sact)] [] @{thm transientI} 2, (*simplify the command's domain*) simp_tac (ctxt addsimps [@{thm domain_def}]) 3, (* proving the domain part *) clarify_tac ctxt 3, dresolve_tac ctxt @{thms swap} 3, force_tac ctxt 4, resolve_tac ctxt @{thms ReplaceI} 3, force_tac ctxt 3, force_tac ctxt 4, asm_full_simp_tac ctxt 3, resolve_tac ctxt @{thms conjI} 3, simp_tac ctxt 4, REPEAT (resolve_tac ctxt @{thms state_update_type} 3), constrains_tac ctxt 1, ALLGOALS (clarify_tac ctxt), ALLGOALS (asm_full_simp_tac (ctxt addsimps [@{thm st_set_def}])), ALLGOALS (clarify_tac ctxt), ALLGOALS (asm_lr_simp_tac ctxt)]); \ method_setup ensures = \ Args.goal_spec -- Scan.lift Parse.embedded_inner_syntax >> (fn (quant, s) => fn ctxt => SIMPLE_METHOD'' quant (ensures_tac ctxt s)) \ "for proving progress properties" end diff --git a/src/ZF/UNITY/UNITY.thy b/src/ZF/UNITY/UNITY.thy --- a/src/ZF/UNITY/UNITY.thy +++ b/src/ZF/UNITY/UNITY.thy @@ -1,625 +1,625 @@ (* Title: ZF/UNITY/UNITY.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge *) section \The Basic UNITY Theory\ theory UNITY imports State begin text\The basic UNITY theory (revised version, based upon the "co" operator) From Misra, "A Logic for Concurrent Programming", 1994. This ZF theory was ported from its HOL equivalent.\ definition program :: i where "program \ {: Pow(state) * Pow(Pow(state*state)) * Pow(Pow(state*state)). id(state) \ acts \ id(state) \ allowed}" definition mk_program :: "[i,i,i]\i" where \ \The definition yields a program thanks to the coercions init \ state, acts \ Pow(state*state), etc.\ "mk_program(init, acts, allowed) \ state, cons(id(state), acts \ Pow(state*state)), cons(id(state), allowed \ Pow(state*state))>" definition SKIP :: i (\\\) where "SKIP \ mk_program(state, 0, Pow(state*state))" (* Coercion from anything to program *) definition programify :: "i\i" where "programify(F) \ if F \ program then F else SKIP" definition RawInit :: "i\i" where "RawInit(F) \ fst(F)" definition Init :: "i\i" where "Init(F) \ RawInit(programify(F))" definition RawActs :: "i\i" where "RawActs(F) \ cons(id(state), fst(snd(F)))" definition Acts :: "i\i" where "Acts(F) \ RawActs(programify(F))" definition RawAllowedActs :: "i\i" where "RawAllowedActs(F) \ cons(id(state), snd(snd(F)))" definition AllowedActs :: "i\i" where "AllowedActs(F) \ RawAllowedActs(programify(F))" definition Allowed :: "i \i" where "Allowed(F) \ {G \ program. Acts(G) \ AllowedActs(F)}" definition initially :: "i\i" where "initially(A) \ {F \ program. Init(F)\A}" definition "constrains" :: "[i, i] \ i" (infixl \co\ 60) where "A co B \ {F \ program. (\act \ Acts(F). act``A\B) \ st_set(A)}" \ \the condition \<^term>\st_set(A)\ makes the definition slightly stronger than the HOL one\ definition unless :: "[i, i] \ i" (infixl \unless\ 60) where "A unless B \ (A - B) co (A \ B)" definition stable :: "i\i" where "stable(A) \ A co A" definition strongest_rhs :: "[i, i] \ i" where "strongest_rhs(F, A) \ \({B \ Pow(state). F \ A co B})" definition invariant :: "i \ i" where "invariant(A) \ initially(A) \ stable(A)" (* meta-function composition *) definition metacomp :: "[i\i, i\i] \ (i\i)" (infixl \comp\ 65) where "f comp g \ \x. f(g(x))" definition pg_compl :: "i\i" where "pg_compl(X)\ program - X" text\SKIP\ lemma SKIP_in_program [iff,TC]: "SKIP \ program" by (force simp add: SKIP_def program_def mk_program_def) subsection\The function \<^term>\programify\, the coercion from anything to program\ lemma programify_program [simp]: "F \ program \ programify(F)=F" by (force simp add: programify_def) lemma programify_in_program [iff,TC]: "programify(F) \ program" by (force simp add: programify_def) text\Collapsing rules: to remove programify from expressions\ lemma programify_idem [simp]: "programify(programify(F))=programify(F)" by (force simp add: programify_def) lemma Init_programify [simp]: "Init(programify(F)) = Init(F)" by (simp add: Init_def) lemma Acts_programify [simp]: "Acts(programify(F)) = Acts(F)" by (simp add: Acts_def) lemma AllowedActs_programify [simp]: "AllowedActs(programify(F)) = AllowedActs(F)" by (simp add: AllowedActs_def) subsection\The Inspectors for Programs\ lemma id_in_RawActs: "F \ program \id(state) \ RawActs(F)" by (auto simp add: program_def RawActs_def) lemma id_in_Acts [iff,TC]: "id(state) \ Acts(F)" by (simp add: id_in_RawActs Acts_def) lemma id_in_RawAllowedActs: "F \ program \id(state) \ RawAllowedActs(F)" by (auto simp add: program_def RawAllowedActs_def) lemma id_in_AllowedActs [iff,TC]: "id(state) \ AllowedActs(F)" by (simp add: id_in_RawAllowedActs AllowedActs_def) lemma cons_id_Acts [simp]: "cons(id(state), Acts(F)) = Acts(F)" by (simp add: cons_absorb) lemma cons_id_AllowedActs [simp]: "cons(id(state), AllowedActs(F)) = AllowedActs(F)" by (simp add: cons_absorb) subsection\Types of the Inspectors\ lemma RawInit_type: "F \ program \ RawInit(F)\state" by (auto simp add: program_def RawInit_def) lemma RawActs_type: "F \ program \ RawActs(F)\Pow(state*state)" by (auto simp add: program_def RawActs_def) lemma RawAllowedActs_type: "F \ program \ RawAllowedActs(F)\Pow(state*state)" by (auto simp add: program_def RawAllowedActs_def) lemma Init_type: "Init(F)\state" by (simp add: RawInit_type Init_def) lemmas InitD = Init_type [THEN subsetD] lemma st_set_Init [iff]: "st_set(Init(F))" -apply (unfold st_set_def) + unfolding st_set_def apply (rule Init_type) done lemma Acts_type: "Acts(F)\Pow(state*state)" by (simp add: RawActs_type Acts_def) lemma AllowedActs_type: "AllowedActs(F) \ Pow(state*state)" by (simp add: RawAllowedActs_type AllowedActs_def) text\Needed in Behaviors\ lemma ActsD: "\act \ Acts(F); \ act\ \ s \ state \ s' \ state" by (blast dest: Acts_type [THEN subsetD]) lemma AllowedActsD: "\act \ AllowedActs(F); \ act\ \ s \ state \ s' \ state" by (blast dest: AllowedActs_type [THEN subsetD]) subsection\Simplification rules involving \<^term>\state\, \<^term>\Init\, \<^term>\Acts\, and \<^term>\AllowedActs\\ text\But are they really needed?\ lemma state_subset_is_Init_iff [iff]: "state \ Init(F) \ Init(F)=state" by (cut_tac F = F in Init_type, auto) lemma Pow_state_times_state_is_subset_Acts_iff [iff]: "Pow(state*state) \ Acts(F) \ Acts(F)=Pow(state*state)" by (cut_tac F = F in Acts_type, auto) lemma Pow_state_times_state_is_subset_AllowedActs_iff [iff]: "Pow(state*state) \ AllowedActs(F) \ AllowedActs(F)=Pow(state*state)" by (cut_tac F = F in AllowedActs_type, auto) subsubsection\Eliminating \\ state\ from expressions\ lemma Init_Int_state [simp]: "Init(F) \ state = Init(F)" by (cut_tac F = F in Init_type, blast) lemma state_Int_Init [simp]: "state \ Init(F) = Init(F)" by (cut_tac F = F in Init_type, blast) lemma Acts_Int_Pow_state_times_state [simp]: "Acts(F) \ Pow(state*state) = Acts(F)" by (cut_tac F = F in Acts_type, blast) lemma state_times_state_Int_Acts [simp]: "Pow(state*state) \ Acts(F) = Acts(F)" by (cut_tac F = F in Acts_type, blast) lemma AllowedActs_Int_Pow_state_times_state [simp]: "AllowedActs(F) \ Pow(state*state) = AllowedActs(F)" by (cut_tac F = F in AllowedActs_type, blast) lemma state_times_state_Int_AllowedActs [simp]: "Pow(state*state) \ AllowedActs(F) = AllowedActs(F)" by (cut_tac F = F in AllowedActs_type, blast) subsubsection\The Operator \<^term>\mk_program\\ lemma mk_program_in_program [iff,TC]: "mk_program(init, acts, allowed) \ program" by (auto simp add: mk_program_def program_def) lemma RawInit_eq [simp]: "RawInit(mk_program(init, acts, allowed)) = init \ state" by (auto simp add: mk_program_def RawInit_def) lemma RawActs_eq [simp]: "RawActs(mk_program(init, acts, allowed)) = cons(id(state), acts \ Pow(state*state))" by (auto simp add: mk_program_def RawActs_def) lemma RawAllowedActs_eq [simp]: "RawAllowedActs(mk_program(init, acts, allowed)) = cons(id(state), allowed \ Pow(state*state))" by (auto simp add: mk_program_def RawAllowedActs_def) lemma Init_eq [simp]: "Init(mk_program(init, acts, allowed)) = init \ state" by (simp add: Init_def) lemma Acts_eq [simp]: "Acts(mk_program(init, acts, allowed)) = cons(id(state), acts \ Pow(state*state))" by (simp add: Acts_def) lemma AllowedActs_eq [simp]: "AllowedActs(mk_program(init, acts, allowed))= cons(id(state), allowed \ Pow(state*state))" by (simp add: AllowedActs_def) text\Init, Acts, and AlowedActs of SKIP\ lemma RawInit_SKIP [simp]: "RawInit(SKIP) = state" by (simp add: SKIP_def) lemma RawAllowedActs_SKIP [simp]: "RawAllowedActs(SKIP) = Pow(state*state)" by (force simp add: SKIP_def) lemma RawActs_SKIP [simp]: "RawActs(SKIP) = {id(state)}" by (force simp add: SKIP_def) lemma Init_SKIP [simp]: "Init(SKIP) = state" by (force simp add: SKIP_def) lemma Acts_SKIP [simp]: "Acts(SKIP) = {id(state)}" by (force simp add: SKIP_def) lemma AllowedActs_SKIP [simp]: "AllowedActs(SKIP) = Pow(state*state)" by (force simp add: SKIP_def) text\Equality of UNITY programs\ lemma raw_surjective_mk_program: "F \ program \ mk_program(RawInit(F), RawActs(F), RawAllowedActs(F))=F" apply (auto simp add: program_def mk_program_def RawInit_def RawActs_def RawAllowedActs_def, blast+) done lemma surjective_mk_program [simp]: "mk_program(Init(F), Acts(F), AllowedActs(F)) = programify(F)" by (auto simp add: raw_surjective_mk_program Init_def Acts_def AllowedActs_def) lemma program_equalityI: "\Init(F) = Init(G); Acts(F) = Acts(G); AllowedActs(F) = AllowedActs(G); F \ program; G \ program\ \ F = G" apply (subgoal_tac "programify(F) = programify(G)") apply simp apply (simp only: surjective_mk_program [symmetric]) done lemma program_equalityE: "\F = G; \Init(F) = Init(G); Acts(F) = Acts(G); AllowedActs(F) = AllowedActs(G)\ \ P\ \ P" by force lemma program_equality_iff: "\F \ program; G \ program\ \(F=G) \ (Init(F) = Init(G) \ Acts(F) = Acts(G) \ AllowedActs(F) = AllowedActs(G))" by (blast intro: program_equalityI program_equalityE) subsection\These rules allow "lazy" definition expansion\ lemma def_prg_Init: "F \ mk_program (init,acts,allowed) \ Init(F) = init \ state" by auto lemma def_prg_Acts: "F \ mk_program (init,acts,allowed) \ Acts(F) = cons(id(state), acts \ Pow(state*state))" by auto lemma def_prg_AllowedActs: "F \ mk_program (init,acts,allowed) \ AllowedActs(F) = cons(id(state), allowed \ Pow(state*state))" by auto lemma def_prg_simps: "\F \ mk_program (init,acts,allowed)\ \ Init(F) = init \ state \ Acts(F) = cons(id(state), acts \ Pow(state*state)) \ AllowedActs(F) = cons(id(state), allowed \ Pow(state*state))" by auto text\An action is expanded only if a pair of states is being tested against it\ lemma def_act_simp: "\act \ { \ A*B. P(s, s')}\ \ ( \ act) \ ( \ A*B \ P(s, s'))" by auto text\A set is expanded only if an element is being tested against it\ lemma def_set_simp: "A \ B \ (x \ A) \ (x \ B)" by auto subsection\The Constrains Operator\ lemma constrains_type: "A co B \ program" by (force simp add: constrains_def) lemma constrainsI: "\(\act s s'. \act: Acts(F); \ act; s \ A\ \ s' \ A'); F \ program; st_set(A)\ \ F \ A co A'" by (force simp add: constrains_def) lemma constrainsD: "F \ A co B \ \act \ Acts(F). act``A\B" by (force simp add: constrains_def) lemma constrainsD2: "F \ A co B \ F \ program \ st_set(A)" by (force simp add: constrains_def) lemma constrains_empty [iff]: "F \ 0 co B \ F \ program" by (force simp add: constrains_def st_set_def) lemma constrains_empty2 [iff]: "(F \ A co 0) \ (A=0 \ F \ program)" by (force simp add: constrains_def st_set_def) lemma constrains_state [iff]: "(F \ state co B) \ (state\B \ F \ program)" apply (cut_tac F = F in Acts_type) apply (force simp add: constrains_def st_set_def) done lemma constrains_state2 [iff]: "F \ A co state \ (F \ program \ st_set(A))" apply (cut_tac F = F in Acts_type) apply (force simp add: constrains_def st_set_def) done text\monotonic in 2nd argument\ lemma constrains_weaken_R: "\F \ A co A'; A'\B'\ \ F \ A co B'" apply (unfold constrains_def, blast) done text\anti-monotonic in 1st argument\ lemma constrains_weaken_L: "\F \ A co A'; B\A\ \ F \ B co A'" apply (unfold constrains_def st_set_def, blast) done lemma constrains_weaken: "\F \ A co A'; B\A; A'\B'\ \ F \ B co B'" apply (drule constrains_weaken_R) apply (drule_tac [2] constrains_weaken_L, blast+) done subsection\Constrains and Union\ lemma constrains_Un: "\F \ A co A'; F \ B co B'\ \ F \ (A \ B) co (A' \ B')" by (auto simp add: constrains_def st_set_def, force) lemma constrains_UN: "\\i. i \ I \ F \ A(i) co A'(i); F \ program\ \ F \ (\i \ I. A(i)) co (\i \ I. A'(i))" by (force simp add: constrains_def st_set_def) lemma constrains_Un_distrib: "(A \ B) co C = (A co C) \ (B co C)" by (force simp add: constrains_def st_set_def) lemma constrains_UN_distrib: "i \ I \ (\i \ I. A(i)) co B = (\i \ I. A(i) co B)" by (force simp add: constrains_def st_set_def) subsection\Constrains and Intersection\ lemma constrains_Int_distrib: "C co (A \ B) = (C co A) \ (C co B)" by (force simp add: constrains_def st_set_def) lemma constrains_INT_distrib: "x \ I \ A co (\i \ I. B(i)) = (\i \ I. A co B(i))" by (force simp add: constrains_def st_set_def) lemma constrains_Int: "\F \ A co A'; F \ B co B'\ \ F \ (A \ B) co (A' \ B')" by (force simp add: constrains_def st_set_def) lemma constrains_INT [rule_format]: "\\i \ I. F \ A(i) co A'(i); F \ program\ \ F \ (\i \ I. A(i)) co (\i \ I. A'(i))" apply (case_tac "I=0") apply (simp add: Inter_def) apply (erule not_emptyE) apply (auto simp add: constrains_def st_set_def, blast) apply (drule bspec, assumption, force) done (* The rule below simulates the HOL's one for (\z. A i) co (\z. B i) *) lemma constrains_All: "\\z. F:{s \ state. P(s, z)} co {s \ state. Q(s, z)}; F \ program\\ F:{s \ state. \z. P(s, z)} co {s \ state. \z. Q(s, z)}" by (unfold constrains_def, blast) lemma constrains_imp_subset: "\F \ A co A'\ \ A \ A'" by (unfold constrains_def st_set_def, force) text\The reasoning is by subsets since "co" refers to single actions only. So this rule isn't that useful.\ lemma constrains_trans: "\F \ A co B; F \ B co C\ \ F \ A co C" by (unfold constrains_def st_set_def, auto, blast) lemma constrains_cancel: "\F \ A co (A' \ B); F \ B co B'\ \ F \ A co (A' \ B')" apply (drule_tac A = B in constrains_imp_subset) apply (blast intro: constrains_weaken_R) done subsection\The Unless Operator\ lemma unless_type: "A unless B \ program" by (force simp add: unless_def constrains_def) lemma unlessI: "\F \ (A-B) co (A \ B)\ \ F \ A unless B" -apply (unfold unless_def) + unfolding unless_def apply (blast dest: constrainsD2) done lemma unlessD: "F :A unless B \ F \ (A-B) co (A \ B)" by (unfold unless_def, auto) subsection\The Operator \<^term>\initially\\ lemma initially_type: "initially(A) \ program" by (unfold initially_def, blast) lemma initiallyI: "\F \ program; Init(F)\A\ \ F \ initially(A)" by (unfold initially_def, blast) lemma initiallyD: "F \ initially(A) \ Init(F)\A" by (unfold initially_def, blast) subsection\The Operator \<^term>\stable\\ lemma stable_type: "stable(A)\program" by (unfold stable_def constrains_def, blast) lemma stableI: "F \ A co A \ F \ stable(A)" by (unfold stable_def, assumption) lemma stableD: "F \ stable(A) \ F \ A co A" by (unfold stable_def, assumption) lemma stableD2: "F \ stable(A) \ F \ program \ st_set(A)" by (unfold stable_def constrains_def, auto) lemma stable_state [simp]: "stable(state) = program" by (auto simp add: stable_def constrains_def dest: Acts_type [THEN subsetD]) lemma stable_unless: "stable(A)= A unless 0" by (auto simp add: unless_def stable_def) subsection\Union and Intersection with \<^term>\stable\\ lemma stable_Un: "\F \ stable(A); F \ stable(A')\ \ F \ stable(A \ A')" -apply (unfold stable_def) + unfolding stable_def apply (blast intro: constrains_Un) done lemma stable_UN: "\\i. i\I \ F \ stable(A(i)); F \ program\ \ F \ stable (\i \ I. A(i))" -apply (unfold stable_def) + unfolding stable_def apply (blast intro: constrains_UN) done lemma stable_Int: "\F \ stable(A); F \ stable(A')\ \ F \ stable (A \ A')" -apply (unfold stable_def) + unfolding stable_def apply (blast intro: constrains_Int) done lemma stable_INT: "\\i. i \ I \ F \ stable(A(i)); F \ program\ \ F \ stable (\i \ I. A(i))" -apply (unfold stable_def) + unfolding stable_def apply (blast intro: constrains_INT) done lemma stable_All: "\\z. F \ stable({s \ state. P(s, z)}); F \ program\ \ F \ stable({s \ state. \z. P(s, z)})" -apply (unfold stable_def) + unfolding stable_def apply (rule constrains_All, auto) done lemma stable_constrains_Un: "\F \ stable(C); F \ A co (C \ A')\ \ F \ (C \ A) co (C \ A')" apply (unfold stable_def constrains_def st_set_def, auto) apply (blast dest!: bspec) done lemma stable_constrains_Int: "\F \ stable(C); F \ (C \ A) co A'\ \ F \ (C \ A) co (C \ A')" by (unfold stable_def constrains_def st_set_def, blast) (* \F \ stable(C); F \ (C \ A) co A\ \ F \ stable(C \ A) *) lemmas stable_constrains_stable = stable_constrains_Int [THEN stableI] subsection\The Operator \<^term>\invariant\\ lemma invariant_type: "invariant(A) \ program" -apply (unfold invariant_def) + unfolding invariant_def apply (blast dest: stable_type [THEN subsetD]) done lemma invariantI: "\Init(F)\A; F \ stable(A)\ \ F \ invariant(A)" apply (unfold invariant_def initially_def) apply (frule stable_type [THEN subsetD], auto) done lemma invariantD: "F \ invariant(A) \ Init(F)\A \ F \ stable(A)" by (unfold invariant_def initially_def, auto) lemma invariantD2: "F \ invariant(A) \ F \ program \ st_set(A)" -apply (unfold invariant_def) + unfolding invariant_def apply (blast dest: stableD2) done text\Could also say \<^term>\invariant(A) \ invariant(B) \ invariant (A \ B)\\ lemma invariant_Int: "\F \ invariant(A); F \ invariant(B)\ \ F \ invariant(A \ B)" apply (unfold invariant_def initially_def) apply (simp add: stable_Int, blast) done subsection\The Elimination Theorem\ (** The "free" m has become universally quantified! Should the premise be \m instead of \m ? Would make it harder to use in forward proof. **) text\The general case is easier to prove than the special case!\ lemma "elimination": "\\m \ M. F \ {s \ A. x(s) = m} co B(m); F \ program\ \ F \ {s \ A. x(s) \ M} co (\m \ M. B(m))" by (auto simp add: constrains_def st_set_def, blast) text\As above, but for the special case of A=state\ lemma elimination2: "\\m \ M. F \ {s \ state. x(s) = m} co B(m); F \ program\ \ F:{s \ state. x(s) \ M} co (\m \ M. B(m))" by (rule UNITY.elimination, auto) subsection\The Operator \<^term>\strongest_rhs\\ lemma constrains_strongest_rhs: "\F \ program; st_set(A)\ \ F \ A co (strongest_rhs(F,A))" by (auto simp add: constrains_def strongest_rhs_def st_set_def dest: Acts_type [THEN subsetD]) lemma strongest_rhs_is_strongest: "\F \ A co B; st_set(B)\ \ strongest_rhs(F,A) \ B" by (auto simp add: constrains_def strongest_rhs_def st_set_def) ML \ fun simp_of_act def = def RS @{thm def_act_simp}; fun simp_of_set def = def RS @{thm def_set_simp}; \ end diff --git a/src/ZF/UNITY/Union.thy b/src/ZF/UNITY/Union.thy --- a/src/ZF/UNITY/Union.thy +++ b/src/ZF/UNITY/Union.thy @@ -1,576 +1,576 @@ (* Title: ZF/UNITY/Union.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge Unions of programs Partly from Misra's Chapter 5 \ Asynchronous Compositions of Programs Theory ported form HOL.. *) theory Union imports SubstAx FP begin definition (*FIXME: conjoin Init(F) \ Init(G) \ 0 *) ok :: "[i, i] \ o" (infixl \ok\ 65) where "F ok G \ Acts(F) \ AllowedActs(G) \ Acts(G) \ AllowedActs(F)" definition (*FIXME: conjoin (\i \ I. Init(F(i))) \ 0 *) OK :: "[i, i\i] \ o" where "OK(I,F) \ (\i \ I. \j \ I-{i}. Acts(F(i)) \ AllowedActs(F(j)))" definition JOIN :: "[i, i\i] \ i" where "JOIN(I,F) \ if I = 0 then SKIP else mk_program(\i \ I. Init(F(i)), \i \ I. Acts(F(i)), \i \ I. AllowedActs(F(i)))" definition Join :: "[i, i] \ i" (infixl \\\ 65) where "F \ G \ mk_program (Init(F) \ Init(G), Acts(F) \ Acts(G), AllowedActs(F) \ AllowedActs(G))" definition (*Characterizes safety properties. Used with specifying AllowedActs*) safety_prop :: "i \ o" where "safety_prop(X) \ X\program \ SKIP \ X \ (\G \ program. Acts(G) \ (\F \ X. Acts(F)) \ G \ X)" syntax "_JOIN1" :: "[pttrns, i] \ i" (\(3\_./ _)\ 10) "_JOIN" :: "[pttrn, i, i] \ i" (\(3\_ \ _./ _)\ 10) translations "\x \ A. B" == "CONST JOIN(A, (\x. B))" "\x y. B" == "\x. \y. B" "\x. B" == "CONST JOIN(CONST state, (\x. B))" subsection\SKIP\ lemma reachable_SKIP [simp]: "reachable(SKIP) = state" by (force elim: reachable.induct intro: reachable.intros) text\Elimination programify from ok and \\ lemma ok_programify_left [iff]: "programify(F) ok G \ F ok G" by (simp add: ok_def) lemma ok_programify_right [iff]: "F ok programify(G) \ F ok G" by (simp add: ok_def) lemma Join_programify_left [simp]: "programify(F) \ G = F \ G" by (simp add: Join_def) lemma Join_programify_right [simp]: "F \ programify(G) = F \ G" by (simp add: Join_def) subsection\SKIP and safety properties\ lemma SKIP_in_constrains_iff [iff]: "(SKIP \ A co B) \ (A\B \ st_set(A))" by (unfold constrains_def st_set_def, auto) lemma SKIP_in_Constrains_iff [iff]: "(SKIP \ A Co B)\ (state \ A\B)" by (unfold Constrains_def, auto) lemma SKIP_in_stable [iff]: "SKIP \ stable(A) \ st_set(A)" by (auto simp add: stable_def) lemma SKIP_in_Stable [iff]: "SKIP \ Stable(A)" by (unfold Stable_def, auto) subsection\Join and JOIN types\ lemma Join_in_program [iff,TC]: "F \ G \ program" by (unfold Join_def, auto) lemma JOIN_in_program [iff,TC]: "JOIN(I,F) \ program" by (unfold JOIN_def, auto) subsection\Init, Acts, and AllowedActs of Join and JOIN\ lemma Init_Join [simp]: "Init(F \ G) = Init(F) \ Init(G)" by (simp add: Int_assoc Join_def) lemma Acts_Join [simp]: "Acts(F \ G) = Acts(F) \ Acts(G)" by (simp add: Int_Un_distrib2 cons_absorb Join_def) lemma AllowedActs_Join [simp]: "AllowedActs(F \ G) = AllowedActs(F) \ AllowedActs(G)" apply (simp add: Int_assoc cons_absorb Join_def) done subsection\Join's algebraic laws\ lemma Join_commute: "F \ G = G \ F" by (simp add: Join_def Un_commute Int_commute) lemma Join_left_commute: "A \ (B \ C) = B \ (A \ C)" apply (simp add: Join_def Int_Un_distrib2 cons_absorb) apply (simp add: Un_ac Int_ac Int_Un_distrib2 cons_absorb) done lemma Join_assoc: "(F \ G) \ H = F \ (G \ H)" by (simp add: Un_ac Join_def cons_absorb Int_assoc Int_Un_distrib2) subsection\Needed below\ lemma cons_id [simp]: "cons(id(state), Pow(state * state)) = Pow(state*state)" by auto lemma Join_SKIP_left [simp]: "SKIP \ F = programify(F)" apply (unfold Join_def SKIP_def) apply (auto simp add: Int_absorb cons_eq) done lemma Join_SKIP_right [simp]: "F \ SKIP = programify(F)" apply (subst Join_commute) apply (simp add: Join_SKIP_left) done lemma Join_absorb [simp]: "F \ F = programify(F)" by (rule program_equalityI, auto) lemma Join_left_absorb: "F \ (F \ G) = F \ G" by (simp add: Join_assoc [symmetric]) subsection\Join is an AC-operator\ lemmas Join_ac = Join_assoc Join_left_absorb Join_commute Join_left_commute subsection\Eliminating programify form JOIN and OK expressions\ lemma OK_programify [iff]: "OK(I, \x. programify(F(x))) \ OK(I, F)" by (simp add: OK_def) lemma JOIN_programify [iff]: "JOIN(I, \x. programify(F(x))) = JOIN(I, F)" by (simp add: JOIN_def) subsection\JOIN\ lemma JOIN_empty [simp]: "JOIN(0, F) = SKIP" by (unfold JOIN_def, auto) lemma Init_JOIN [simp]: "Init(\i \ I. F(i)) = (if I=0 then state else (\i \ I. Init(F(i))))" by (simp add: JOIN_def INT_extend_simps del: INT_simps) lemma Acts_JOIN [simp]: "Acts(JOIN(I,F)) = cons(id(state), \i \ I. Acts(F(i)))" -apply (unfold JOIN_def) + unfolding JOIN_def apply (auto simp del: INT_simps UN_simps) apply (rule equalityI) apply (auto dest: Acts_type [THEN subsetD]) done lemma AllowedActs_JOIN [simp]: "AllowedActs(\i \ I. F(i)) = (if I=0 then Pow(state*state) else (\i \ I. AllowedActs(F(i))))" apply (unfold JOIN_def, auto) apply (rule equalityI) apply (auto elim!: not_emptyE dest: AllowedActs_type [THEN subsetD]) done lemma JOIN_cons [simp]: "(\i \ cons(a,I). F(i)) = F(a) \ (\i \ I. F(i))" by (rule program_equalityI, auto) lemma JOIN_cong [cong]: "\I=J; \i. i \ J \ F(i) = G(i)\ \ (\i \ I. F(i)) = (\i \ J. G(i))" by (simp add: JOIN_def) subsection\JOIN laws\ lemma JOIN_absorb: "k \ I \F(k) \ (\i \ I. F(i)) = (\i \ I. F(i))" apply (subst JOIN_cons [symmetric]) apply (auto simp add: cons_absorb) done lemma JOIN_Un: "(\i \ I \ J. F(i)) = ((\i \ I. F(i)) \ (\i \ J. F(i)))" apply (rule program_equalityI) apply (simp_all add: UN_Un INT_Un) apply (simp_all del: INT_simps add: INT_extend_simps, blast) done lemma JOIN_constant: "(\i \ I. c) = (if I=0 then SKIP else programify(c))" by (rule program_equalityI, auto) lemma JOIN_Join_distrib: "(\i \ I. F(i) \ G(i)) = (\i \ I. F(i)) \ (\i \ I. G(i))" apply (rule program_equalityI) apply (simp_all add: INT_Int_distrib, blast) done lemma JOIN_Join_miniscope: "(\i \ I. F(i) \ G) = ((\i \ I. F(i) \ G))" by (simp add: JOIN_Join_distrib JOIN_constant) text\Used to prove guarantees_JOIN_I\ lemma JOIN_Join_diff: "i \ I\F(i) \ JOIN(I - {i}, F) = JOIN(I, F)" apply (rule program_equalityI) apply (auto elim!: not_emptyE) done subsection\Safety: co, stable, FP\ (*Fails if I=0 because it collapses to SKIP \ A co B, i.e. to A\B. So an alternative precondition is A\B, but most proofs using this rule require I to be nonempty for other reasons anyway.*) lemma JOIN_constrains: "i \ I\(\i \ I. F(i)) \ A co B \ (\i \ I. programify(F(i)) \ A co B)" apply (unfold constrains_def JOIN_def st_set_def, auto) prefer 2 apply blast apply (rename_tac j act y z) apply (cut_tac F = "F (j) " in Acts_type) apply (drule_tac x = act in bspec, auto) done lemma Join_constrains [iff]: "(F \ G \ A co B) \ (programify(F) \ A co B \ programify(G) \ A co B)" by (auto simp add: constrains_def) lemma Join_unless [iff]: "(F \ G \ A unless B) \ (programify(F) \ A unless B \ programify(G) \ A unless B)" by (simp add: Join_constrains unless_def) (*Analogous weak versions FAIL; see Misra [1994] 5.4.1, Substitution Axiom. reachable (F \ G) could be much bigger than reachable F, reachable G *) lemma Join_constrains_weaken: "\F \ A co A'; G \ B co B'\ \ F \ G \ (A \ B) co (A' \ B')" apply (subgoal_tac "st_set (A) \ st_set (B) \ F \ program \ G \ program") prefer 2 apply (blast dest: constrainsD2, simp) apply (blast intro: constrains_weaken) done (*If I=0, it degenerates to SKIP \ state co 0, which is false.*) lemma JOIN_constrains_weaken: assumes major: "(\i. i \ I \ F(i) \ A(i) co A'(i))" and minor: "i \ I" shows "(\i \ I. F(i)) \ (\i \ I. A(i)) co (\i \ I. A'(i))" apply (cut_tac minor) apply (simp (no_asm_simp) add: JOIN_constrains) apply clarify apply (rename_tac "j") apply (frule_tac i = j in major) apply (frule constrainsD2, simp) apply (blast intro: constrains_weaken) done lemma JOIN_stable: "(\i \ I. F(i)) \ stable(A) \ ((\i \ I. programify(F(i)) \ stable(A)) \ st_set(A))" apply (auto simp add: stable_def constrains_def JOIN_def) apply (cut_tac F = "F (i) " in Acts_type) apply (drule_tac x = act in bspec, auto) done lemma initially_JOIN_I: assumes major: "(\i. i \ I \F(i) \ initially(A))" and minor: "i \ I" shows "(\i \ I. F(i)) \ initially(A)" apply (cut_tac minor) apply (auto elim!: not_emptyE simp add: Inter_iff initially_def) apply (frule_tac i = x in major) apply (auto simp add: initially_def) done lemma invariant_JOIN_I: assumes major: "(\i. i \ I \ F(i) \ invariant(A))" and minor: "i \ I" shows "(\i \ I. F(i)) \ invariant(A)" apply (cut_tac minor) apply (auto intro!: initially_JOIN_I dest: major simp add: invariant_def JOIN_stable) apply (erule_tac V = "i \ I" in thin_rl) apply (frule major) apply (drule_tac [2] major) apply (auto simp add: invariant_def) apply (frule stableD2, force)+ done lemma Join_stable [iff]: " (F \ G \ stable(A)) \ (programify(F) \ stable(A) \ programify(G) \ stable(A))" by (simp add: stable_def) lemma initially_JoinI [intro!]: "\F \ initially(A); G \ initially(A)\ \ F \ G \ initially(A)" by (unfold initially_def, auto) lemma invariant_JoinI: "\F \ invariant(A); G \ invariant(A)\ \ F \ G \ invariant(A)" apply (subgoal_tac "F \ program\G \ program") prefer 2 apply (blast dest: invariantD2) apply (simp add: invariant_def) apply (auto intro: Join_in_program) done (* Fails if I=0 because \i \ 0. A(i) = 0 *) lemma FP_JOIN: "i \ I \ FP(\i \ I. F(i)) = (\i \ I. FP (programify(F(i))))" by (auto simp add: FP_def Inter_def st_set_def JOIN_stable) subsection\Progress: transient, ensures\ lemma JOIN_transient: "i \ I \ (\i \ I. F(i)) \ transient(A) \ (\i \ I. programify(F(i)) \ transient(A))" apply (auto simp add: transient_def JOIN_def) -apply (unfold st_set_def) + unfolding st_set_def apply (drule_tac [2] x = act in bspec) apply (auto dest: Acts_type [THEN subsetD]) done lemma Join_transient [iff]: "F \ G \ transient(A) \ (programify(F) \ transient(A) | programify(G) \ transient(A))" apply (auto simp add: transient_def Join_def Int_Un_distrib2) done lemma Join_transient_I1: "F \ transient(A) \ F \ G \ transient(A)" by (simp add: Join_transient transientD2) lemma Join_transient_I2: "G \ transient(A) \ F \ G \ transient(A)" by (simp add: Join_transient transientD2) (*If I=0 it degenerates to (SKIP \ A ensures B) = False, i.e. to \(A\B) *) lemma JOIN_ensures: "i \ I \ (\i \ I. F(i)) \ A ensures B \ ((\i \ I. programify(F(i)) \ (A-B) co (A \ B)) \ (\i \ I. programify(F(i)) \ A ensures B))" by (auto simp add: ensures_def JOIN_constrains JOIN_transient) lemma Join_ensures: "F \ G \ A ensures B \ (programify(F) \ (A-B) co (A \ B) \ programify(G) \ (A-B) co (A \ B) \ (programify(F) \ transient (A-B) | programify(G) \ transient (A-B)))" -apply (unfold ensures_def) + unfolding ensures_def apply (auto simp add: Join_transient) done lemma stable_Join_constrains: "\F \ stable(A); G \ A co A'\ \ F \ G \ A co A'" apply (unfold stable_def constrains_def Join_def st_set_def) apply (cut_tac F = F in Acts_type) apply (cut_tac F = G in Acts_type, force) done (*Premise for G cannot use Always because F \ Stable A is weaker than G \ stable A *) lemma stable_Join_Always1: "\F \ stable(A); G \ invariant(A)\ \ F \ G \ Always(A)" apply (subgoal_tac "F \ program \ G \ program \ st_set (A) ") prefer 2 apply (blast dest: invariantD2 stableD2) apply (simp add: Always_def invariant_def initially_def Stable_eq_stable) apply (force intro: stable_Int) done (*As above, but exchanging the roles of F and G*) lemma stable_Join_Always2: "\F \ invariant(A); G \ stable(A)\ \ F \ G \ Always(A)" apply (subst Join_commute) apply (blast intro: stable_Join_Always1) done lemma stable_Join_ensures1: "\F \ stable(A); G \ A ensures B\ \ F \ G \ A ensures B" apply (subgoal_tac "F \ program \ G \ program \ st_set (A) ") prefer 2 apply (blast dest: stableD2 ensures_type [THEN subsetD]) apply (simp (no_asm_simp) add: Join_ensures) apply (simp add: stable_def ensures_def) apply (erule constrains_weaken, auto) done (*As above, but exchanging the roles of F and G*) lemma stable_Join_ensures2: "\F \ A ensures B; G \ stable(A)\ \ F \ G \ A ensures B" apply (subst Join_commute) apply (blast intro: stable_Join_ensures1) done subsection\The ok and OK relations\ lemma ok_SKIP1 [iff]: "SKIP ok F" by (auto dest: Acts_type [THEN subsetD] simp add: ok_def) lemma ok_SKIP2 [iff]: "F ok SKIP" by (auto dest: Acts_type [THEN subsetD] simp add: ok_def) lemma ok_Join_commute: "(F ok G \ (F \ G) ok H) \ (G ok H \ F ok (G \ H))" by (auto simp add: ok_def) lemma ok_commute: "(F ok G) \(G ok F)" by (auto simp add: ok_def) lemmas ok_sym = ok_commute [THEN iffD1] lemma ok_iff_OK: "OK({\0,F\,\1,G\,\2,H\}, snd) \ (F ok G \ (F \ G) ok H)" by (simp add: ok_def Join_def OK_def Int_assoc cons_absorb Int_Un_distrib2 Ball_def, safe, force+) lemma ok_Join_iff1 [iff]: "F ok (G \ H) \ (F ok G \ F ok H)" by (auto simp add: ok_def) lemma ok_Join_iff2 [iff]: "(G \ H) ok F \ (G ok F \ H ok F)" by (auto simp add: ok_def) (*useful? Not with the previous two around*) lemma ok_Join_commute_I: "\F ok G; (F \ G) ok H\ \ F ok (G \ H)" by (auto simp add: ok_def) lemma ok_JOIN_iff1 [iff]: "F ok JOIN(I,G) \ (\i \ I. F ok G(i))" by (force dest: Acts_type [THEN subsetD] elim!: not_emptyE simp add: ok_def) lemma ok_JOIN_iff2 [iff]: "JOIN(I,G) ok F \ (\i \ I. G(i) ok F)" apply (auto elim!: not_emptyE simp add: ok_def) apply (blast dest: Acts_type [THEN subsetD]) done lemma OK_iff_ok: "OK(I,F) \ (\i \ I. \j \ I-{i}. F(i) ok (F(j)))" by (auto simp add: ok_def OK_def) lemma OK_imp_ok: "\OK(I,F); i \ I; j \ I; i\j\ \ F(i) ok F(j)" by (auto simp add: OK_iff_ok) lemma OK_0 [iff]: "OK(0,F)" by (simp add: OK_def) lemma OK_cons_iff: "OK(cons(i, I), F) \ (i \ I \ OK(I, F)) | (i\I \ OK(I, F) \ F(i) ok JOIN(I,F))" apply (simp add: OK_iff_ok) apply (blast intro: ok_sym) done subsection\Allowed\ lemma Allowed_SKIP [simp]: "Allowed(SKIP) = program" by (auto dest: Acts_type [THEN subsetD] simp add: Allowed_def) lemma Allowed_Join [simp]: "Allowed(F \ G) = Allowed(programify(F)) \ Allowed(programify(G))" apply (auto simp add: Allowed_def) done lemma Allowed_JOIN [simp]: "i \ I \ Allowed(JOIN(I,F)) = (\i \ I. Allowed(programify(F(i))))" apply (auto simp add: Allowed_def, blast) done lemma ok_iff_Allowed: "F ok G \ (programify(F) \ Allowed(programify(G)) \ programify(G) \ Allowed(programify(F)))" by (simp add: ok_def Allowed_def) lemma OK_iff_Allowed: "OK(I,F) \ (\i \ I. \j \ I-{i}. programify(F(i)) \ Allowed(programify(F(j))))" apply (auto simp add: OK_iff_ok ok_iff_Allowed) done subsection\safety_prop, for reasoning about given instances of "ok"\ lemma safety_prop_Acts_iff: "safety_prop(X) \ (Acts(G) \ cons(id(state), (\F \ X. Acts(F)))) \ (programify(G) \ X)" apply (simp (no_asm_use) add: safety_prop_def) apply clarify apply (case_tac "G \ program", simp_all, blast, safe) prefer 2 apply force apply (force simp add: programify_def) done lemma safety_prop_AllowedActs_iff_Allowed: "safety_prop(X) \ (\G \ X. Acts(G)) \ AllowedActs(F) \ (X \ Allowed(programify(F)))" apply (simp add: Allowed_def safety_prop_Acts_iff [THEN iff_sym] safety_prop_def, blast) done lemma Allowed_eq: "safety_prop(X) \ Allowed(mk_program(init, acts, \F \ X. Acts(F))) = X" apply (subgoal_tac "cons (id (state), \(RepFun (X, Acts)) \ Pow (state * state)) = \(RepFun (X, Acts))") apply (rule_tac [2] equalityI) apply (simp del: UN_simps add: Allowed_def safety_prop_Acts_iff safety_prop_def, auto) apply (force dest: Acts_type [THEN subsetD] simp add: safety_prop_def)+ done lemma def_prg_Allowed: "\F \ mk_program (init, acts, \F \ X. Acts(F)); safety_prop(X)\ \ Allowed(F) = X" by (simp add: Allowed_eq) (*For safety_prop to hold, the property must be satisfiable!*) lemma safety_prop_constrains [iff]: "safety_prop(A co B) \ (A \ B \ st_set(A))" by (simp add: safety_prop_def constrains_def st_set_def, blast) (* To be used with resolution *) lemma safety_prop_constrainsI [iff]: "\A\B; st_set(A)\ \safety_prop(A co B)" by auto lemma safety_prop_stable [iff]: "safety_prop(stable(A)) \ st_set(A)" by (simp add: stable_def) lemma safety_prop_stableI: "st_set(A) \ safety_prop(stable(A))" by auto lemma safety_prop_Int [simp]: "\safety_prop(X) ; safety_prop(Y)\ \ safety_prop(X \ Y)" apply (simp add: safety_prop_def, safe, blast) apply (drule_tac [2] B = "\(RepFun (X \ Y, Acts))" and C = "\(RepFun (Y, Acts))" in subset_trans) apply (drule_tac B = "\(RepFun (X \ Y, Acts))" and C = "\(RepFun (X, Acts))" in subset_trans) apply blast+ done (* If I=0 the conclusion becomes safety_prop(0) which is false *) lemma safety_prop_Inter: assumes major: "(\i. i \ I \safety_prop(X(i)))" and minor: "i \ I" shows "safety_prop(\i \ I. X(i))" apply (simp add: safety_prop_def) apply (cut_tac minor, safe) apply (simp (no_asm_use) add: Inter_iff) apply clarify apply (frule major) apply (drule_tac [2] i = xa in major) apply (frule_tac [4] i = xa in major) apply (auto simp add: safety_prop_def) apply (drule_tac B = "\(RepFun (\(RepFun (I, X)), Acts))" and C = "\(RepFun (X (xa), Acts))" in subset_trans) apply blast+ done lemma def_UNION_ok_iff: "\F \ mk_program(init,acts, \G \ X. Acts(G)); safety_prop(X)\ \ F ok G \ (programify(G) \ X \ acts \ Pow(state*state) \ AllowedActs(G))" -apply (unfold ok_def) + unfolding ok_def apply (drule_tac G = G in safety_prop_Acts_iff) apply (cut_tac F = G in AllowedActs_type) apply (cut_tac F = G in Acts_type, auto) done end diff --git a/src/ZF/UNITY/WFair.thy b/src/ZF/UNITY/WFair.thy --- a/src/ZF/UNITY/WFair.thy +++ b/src/ZF/UNITY/WFair.thy @@ -1,707 +1,707 @@ (* Title: ZF/UNITY/WFair.thy Author: Sidi Ehmety, Computer Laboratory Copyright 1998 University of Cambridge *) section\Progress under Weak Fairness\ theory WFair imports UNITY ZFC begin text\This theory defines the operators transient, ensures and leadsTo, assuming weak fairness. From Misra, "A Logic for Concurrent Programming", 1994.\ definition (* This definition specifies weak fairness. The rest of the theory is generic to all forms of fairness.*) transient :: "i\i" where "transient(A) \{F \ program. (\act\Acts(F). A<=domain(act) \ act``A \ state-A) \ st_set(A)}" definition ensures :: "[i,i] \ i" (infixl \ensures\ 60) where "A ensures B \ ((A-B) co (A \ B)) \ transient(A-B)" consts (*LEADS-TO constant for the inductive definition*) leads :: "[i, i]\i" inductive domains "leads(D, F)" \ "Pow(D)*Pow(D)" intros Basis: "\F \ A ensures B; A \ Pow(D); B \ Pow(D)\ \ \A,B\:leads(D, F)" Trans: "\\A,B\ \ leads(D, F); \B,C\ \ leads(D, F)\ \ \A,C\:leads(D, F)" Union: "\S \ Pow({A \ S. \A, B\:leads(D, F)}); B \ Pow(D); S \ Pow(Pow(D))\ \ <\(S),B>:leads(D, F)" monos Pow_mono type_intros Union_Pow_iff [THEN iffD2] UnionI PowI definition (* The Visible version of the LEADS-TO relation*) leadsTo :: "[i, i] \ i" (infixl \\\ 60) where "A \ B \ {F \ program. \A,B\:leads(state, F)}" definition (* wlt(F, B) is the largest set that leads to B*) wlt :: "[i, i] \ i" where "wlt(F, B) \ \({A \ Pow(state). F \ A \ B})" (** Ad-hoc set-theory rules **) lemma Int_Union_Union: "\(B) \ A = (\b \ B. b \ A)" by auto lemma Int_Union_Union2: "A \ \(B) = (\b \ B. A \ b)" by auto (*** transient ***) lemma transient_type: "transient(A)<=program" by (unfold transient_def, auto) lemma transientD2: "F \ transient(A) \ F \ program \ st_set(A)" apply (unfold transient_def, auto) done lemma stable_transient_empty: "\F \ stable(A); F \ transient(A)\ \ A = 0" by (simp add: stable_def constrains_def transient_def, fast) lemma transient_strengthen: "\F \ transient(A); B<=A\ \ F \ transient(B)" apply (simp add: transient_def st_set_def, clarify) apply (blast intro!: rev_bexI) done lemma transientI: "\act \ Acts(F); A \ domain(act); act``A \ state-A; F \ program; st_set(A)\ \ F \ transient(A)" by (simp add: transient_def, blast) lemma transientE: "\F \ transient(A); \act. \act \ Acts(F); A \ domain(act); act``A \ state-A\\P\ \P" by (simp add: transient_def, blast) lemma transient_state: "transient(state) = 0" apply (simp add: transient_def) apply (rule equalityI, auto) apply (cut_tac F = x in Acts_type) apply (simp add: Diff_cancel) apply (auto intro: st0_in_state) done lemma transient_state2: "state<=B \ transient(B) = 0" apply (simp add: transient_def st_set_def) apply (rule equalityI, auto) apply (cut_tac F = x in Acts_type) apply (subgoal_tac "B=state") apply (auto intro: st0_in_state) done lemma transient_empty: "transient(0) = program" by (auto simp add: transient_def) declare transient_empty [simp] transient_state [simp] transient_state2 [simp] (*** ensures ***) lemma ensures_type: "A ensures B <=program" by (simp add: ensures_def constrains_def, auto) lemma ensuresI: "\F:(A-B) co (A \ B); F \ transient(A-B)\\F \ A ensures B" -apply (unfold ensures_def) + unfolding ensures_def apply (auto simp add: transient_type [THEN subsetD]) done (* Added by Sidi, from Misra's notes, Progress chapter, exercise 4 *) lemma ensuresI2: "\F \ A co A \ B; F \ transient(A)\ \ F \ A ensures B" apply (drule_tac B = "A-B" in constrains_weaken_L) apply (drule_tac [2] B = "A-B" in transient_strengthen) apply (auto simp add: ensures_def transient_type [THEN subsetD]) done lemma ensuresD: "F \ A ensures B \ F:(A-B) co (A \ B) \ F \ transient (A-B)" by (unfold ensures_def, auto) lemma ensures_weaken_R: "\F \ A ensures A'; A'<=B'\ \ F \ A ensures B'" -apply (unfold ensures_def) + unfolding ensures_def apply (blast intro: transient_strengthen constrains_weaken) done (*The L-version (precondition strengthening) fails, but we have this*) lemma stable_ensures_Int: "\F \ stable(C); F \ A ensures B\ \ F:(C \ A) ensures (C \ B)" -apply (unfold ensures_def) + unfolding ensures_def apply (simp (no_asm) add: Int_Un_distrib [symmetric] Diff_Int_distrib [symmetric]) apply (blast intro: transient_strengthen stable_constrains_Int constrains_weaken) done lemma stable_transient_ensures: "\F \ stable(A); F \ transient(C); A<=B \ C\ \ F \ A ensures B" apply (frule stable_type [THEN subsetD]) apply (simp add: ensures_def stable_def) apply (blast intro: transient_strengthen constrains_weaken) done lemma ensures_eq: "(A ensures B) = (A unless B) \ transient (A-B)" by (auto simp add: ensures_def unless_def) lemma subset_imp_ensures: "\F \ program; A<=B\ \ F \ A ensures B" by (auto simp add: ensures_def constrains_def transient_def st_set_def) (*** leadsTo ***) lemmas leads_left = leads.dom_subset [THEN subsetD, THEN SigmaD1] lemmas leads_right = leads.dom_subset [THEN subsetD, THEN SigmaD2] lemma leadsTo_type: "A \ B \ program" by (unfold leadsTo_def, auto) lemma leadsToD2: "F \ A \ B \ F \ program \ st_set(A) \ st_set(B)" apply (unfold leadsTo_def st_set_def) apply (blast dest: leads_left leads_right) done lemma leadsTo_Basis: "\F \ A ensures B; st_set(A); st_set(B)\ \ F \ A \ B" apply (unfold leadsTo_def st_set_def) apply (cut_tac ensures_type) apply (auto intro: leads.Basis) done declare leadsTo_Basis [intro] (* Added by Sidi, from Misra's notes, Progress chapter, exercise number 4 *) (* \F \ program; A<=B; st_set(A); st_set(B)\ \ A \ B *) lemmas subset_imp_leadsTo = subset_imp_ensures [THEN leadsTo_Basis] lemma leadsTo_Trans: "\F \ A \ B; F \ B \ C\\F \ A \ C" -apply (unfold leadsTo_def) + unfolding leadsTo_def apply (auto intro: leads.Trans) done (* Better when used in association with leadsTo_weaken_R *) lemma transient_imp_leadsTo: "F \ transient(A) \ F \ A \ (state-A)" -apply (unfold transient_def) + unfolding transient_def apply (blast intro: ensuresI [THEN leadsTo_Basis] constrains_weaken transientI) done (*Useful with cancellation, disjunction*) lemma leadsTo_Un_duplicate: "F \ A \ (A' \ A') \ F \ A \ A'" by simp lemma leadsTo_Un_duplicate2: "F \ A \ (A' \ C \ C) \ F \ A \ (A' \ C)" by (simp add: Un_ac) (*The Union introduction rule as we should have liked to state it*) lemma leadsTo_Union: "\\A. A \ S \ F \ A \ B; F \ program; st_set(B)\ \ F \ \(S) \ B" apply (unfold leadsTo_def st_set_def) apply (blast intro: leads.Union dest: leads_left) done lemma leadsTo_Union_Int: "\\A. A \ S \F \ (A \ C) \ B; F \ program; st_set(B)\ \ F \ (\(S)Int C)\ B" apply (unfold leadsTo_def st_set_def) apply (simp only: Int_Union_Union) apply (blast dest: leads_left intro: leads.Union) done lemma leadsTo_UN: "\\i. i \ I \ F \ A(i) \ B; F \ program; st_set(B)\ \ F:(\i \ I. A(i)) \ B" apply (simp add: Int_Union_Union leadsTo_def st_set_def) apply (blast dest: leads_left intro: leads.Union) done (* Binary union introduction rule *) lemma leadsTo_Un: "\F \ A \ C; F \ B \ C\ \ F \ (A \ B) \ C" apply (subst Un_eq_Union) apply (blast intro: leadsTo_Union dest: leadsToD2) done lemma single_leadsTo_I: "\\x. x \ A\ F:{x} \ B; F \ program; st_set(B)\ \ F \ A \ B" apply (rule_tac b = A in UN_singleton [THEN subst]) apply (rule leadsTo_UN, auto) done lemma leadsTo_refl: "\F \ program; st_set(A)\ \ F \ A \ A" by (blast intro: subset_imp_leadsTo) lemma leadsTo_refl_iff: "F \ A \ A \ F \ program \ st_set(A)" by (auto intro: leadsTo_refl dest: leadsToD2) lemma empty_leadsTo: "F \ 0 \ B \ (F \ program \ st_set(B))" by (auto intro: subset_imp_leadsTo dest: leadsToD2) declare empty_leadsTo [iff] lemma leadsTo_state: "F \ A \ state \ (F \ program \ st_set(A))" by (auto intro: subset_imp_leadsTo dest: leadsToD2 st_setD) declare leadsTo_state [iff] lemma leadsTo_weaken_R: "\F \ A \ A'; A'<=B'; st_set(B')\ \ F \ A \ B'" by (blast dest: leadsToD2 intro: subset_imp_leadsTo leadsTo_Trans) lemma leadsTo_weaken_L: "\F \ A \ A'; B<=A\ \ F \ B \ A'" apply (frule leadsToD2) apply (blast intro: leadsTo_Trans subset_imp_leadsTo st_set_subset) done lemma leadsTo_weaken: "\F \ A \ A'; B<=A; A'<=B'; st_set(B')\\ F \ B \ B'" apply (frule leadsToD2) apply (blast intro: leadsTo_weaken_R leadsTo_weaken_L leadsTo_Trans leadsTo_refl) done (* This rule has a nicer conclusion *) lemma transient_imp_leadsTo2: "\F \ transient(A); state-A<=B; st_set(B)\ \ F \ A \ B" apply (frule transientD2) apply (rule leadsTo_weaken_R) apply (auto simp add: transient_imp_leadsTo) done (*Distributes over binary unions*) lemma leadsTo_Un_distrib: "F:(A \ B) \ C \ (F \ A \ C \ F \ B \ C)" by (blast intro: leadsTo_Un leadsTo_weaken_L) lemma leadsTo_UN_distrib: "(F:(\i \ I. A(i)) \ B)\ ((\i \ I. F \ A(i) \ B) \ F \ program \ st_set(B))" apply (blast dest: leadsToD2 intro: leadsTo_UN leadsTo_weaken_L) done lemma leadsTo_Union_distrib: "(F \ \(S) \ B) \ (\A \ S. F \ A \ B) \ F \ program \ st_set(B)" by (blast dest: leadsToD2 intro: leadsTo_Union leadsTo_weaken_L) text\Set difference: maybe combine with \leadsTo_weaken_L\??\ lemma leadsTo_Diff: "\F: (A-B) \ C; F \ B \ C; st_set(C)\ \ F \ A \ C" by (blast intro: leadsTo_Un leadsTo_weaken dest: leadsToD2) lemma leadsTo_UN_UN: "\\i. i \ I \ F \ A(i) \ A'(i); F \ program\ \ F: (\i \ I. A(i)) \ (\i \ I. A'(i))" apply (rule leadsTo_Union) apply (auto intro: leadsTo_weaken_R dest: leadsToD2) done (*Binary union version*) lemma leadsTo_Un_Un: "\F \ A \ A'; F \ B \ B'\ \ F \ (A \ B) \ (A' \ B')" apply (subgoal_tac "st_set (A) \ st_set (A') \ st_set (B) \ st_set (B') ") prefer 2 apply (blast dest: leadsToD2) apply (blast intro: leadsTo_Un leadsTo_weaken_R) done (** The cancellation law **) lemma leadsTo_cancel2: "\F \ A \ (A' \ B); F \ B \ B'\ \ F \ A \ (A' \ B')" apply (subgoal_tac "st_set (A) \ st_set (A') \ st_set (B) \ st_set (B') \F \ program") prefer 2 apply (blast dest: leadsToD2) apply (blast intro: leadsTo_Trans leadsTo_Un_Un leadsTo_refl) done lemma leadsTo_cancel_Diff2: "\F \ A \ (A' \ B); F \ (B-A') \ B'\\ F \ A \ (A' \ B')" apply (rule leadsTo_cancel2) prefer 2 apply assumption apply (blast dest: leadsToD2 intro: leadsTo_weaken_R) done lemma leadsTo_cancel1: "\F \ A \ (B \ A'); F \ B \ B'\ \ F \ A \ (B' \ A')" apply (simp add: Un_commute) apply (blast intro!: leadsTo_cancel2) done lemma leadsTo_cancel_Diff1: "\F \ A \ (B \ A'); F: (B-A') \ B'\\ F \ A \ (B' \ A')" apply (rule leadsTo_cancel1) prefer 2 apply assumption apply (blast intro: leadsTo_weaken_R dest: leadsToD2) done (*The INDUCTION rule as we should have liked to state it*) lemma leadsTo_induct: assumes major: "F \ za \ zb" and basis: "\A B. \F \ A ensures B; st_set(A); st_set(B)\ \ P(A,B)" and trans: "\A B C. \F \ A \ B; P(A, B); F \ B \ C; P(B, C)\ \ P(A,C)" and union: "\B S. \\A \ S. F \ A \ B; \A \ S. P(A,B); st_set(B); \A \ S. st_set(A)\ \ P(\(S), B)" shows "P(za, zb)" apply (cut_tac major) apply (unfold leadsTo_def, clarify) apply (erule leads.induct) apply (blast intro: basis [unfolded st_set_def]) apply (blast intro: trans [unfolded leadsTo_def]) apply (force intro: union [unfolded st_set_def leadsTo_def]) done (* Added by Sidi, an induction rule without ensures *) lemma leadsTo_induct2: assumes major: "F \ za \ zb" and basis1: "\A B. \A<=B; st_set(B)\ \ P(A, B)" and basis2: "\A B. \F \ A co A \ B; F \ transient(A); st_set(B)\ \ P(A, B)" and trans: "\A B C. \F \ A \ B; P(A, B); F \ B \ C; P(B, C)\ \ P(A,C)" and union: "\B S. \\A \ S. F \ A \ B; \A \ S. P(A,B); st_set(B); \A \ S. st_set(A)\ \ P(\(S), B)" shows "P(za, zb)" apply (cut_tac major) apply (erule leadsTo_induct) apply (auto intro: trans union) apply (simp add: ensures_def, clarify) apply (frule constrainsD2) apply (drule_tac B' = " (A-B) \ B" in constrains_weaken_R) apply blast apply (frule ensuresI2 [THEN leadsTo_Basis]) apply (drule_tac [4] basis2, simp_all) apply (frule_tac A1 = A and B = B in Int_lower2 [THEN basis1]) apply (subgoal_tac "A=\({A - B, A \ B}) ") prefer 2 apply blast apply (erule ssubst) apply (rule union) apply (auto intro: subset_imp_leadsTo) done (** Variant induction rule: on the preconditions for B **) (*Lemma is the weak version: can't see how to do it in one step*) lemma leadsTo_induct_pre_aux: "\F \ za \ zb; P(zb); \A B. \F \ A ensures B; P(B); st_set(A); st_set(B)\ \ P(A); \S. \\A \ S. P(A); \A \ S. st_set(A)\ \ P(\(S)) \ \ P(za)" txt\by induction on this formula\ apply (subgoal_tac "P (zb) \ P (za) ") txt\now solve first subgoal: this formula is sufficient\ apply (blast intro: leadsTo_refl) apply (erule leadsTo_induct) apply (blast+) done lemma leadsTo_induct_pre: "\F \ za \ zb; P(zb); \A B. \F \ A ensures B; F \ B \ zb; P(B); st_set(A)\ \ P(A); \S. \A \ S. F \ A \ zb \ P(A) \ st_set(A) \ P(\(S)) \ \ P(za)" apply (subgoal_tac " (F \ za \ zb) \ P (za) ") apply (erule conjunct2) apply (frule leadsToD2) apply (erule leadsTo_induct_pre_aux) prefer 3 apply (blast dest: leadsToD2 intro: leadsTo_Union) prefer 2 apply (blast intro: leadsTo_Trans leadsTo_Basis) apply (blast intro: leadsTo_refl) done (** The impossibility law **) lemma leadsTo_empty: "F \ A \ 0 \ A=0" apply (erule leadsTo_induct_pre) apply (auto simp add: ensures_def constrains_def transient_def st_set_def) apply (drule bspec, assumption)+ apply blast done declare leadsTo_empty [simp] subsection\PSP: Progress-Safety-Progress\ text\Special case of PSP: Misra's "stable conjunction"\ lemma psp_stable: "\F \ A \ A'; F \ stable(B)\ \ F:(A \ B) \ (A' \ B)" -apply (unfold stable_def) + unfolding stable_def apply (frule leadsToD2) apply (erule leadsTo_induct) prefer 3 apply (blast intro: leadsTo_Union_Int) prefer 2 apply (blast intro: leadsTo_Trans) apply (rule leadsTo_Basis) apply (simp add: ensures_def Diff_Int_distrib2 [symmetric] Int_Un_distrib2 [symmetric]) apply (auto intro: transient_strengthen constrains_Int) done lemma psp_stable2: "\F \ A \ A'; F \ stable(B)\\F: (B \ A) \ (B \ A')" apply (simp (no_asm_simp) add: psp_stable Int_ac) done lemma psp_ensures: "\F \ A ensures A'; F \ B co B'\\ F: (A \ B') ensures ((A' \ B) \ (B' - B))" apply (unfold ensures_def constrains_def st_set_def) (*speeds up the proof*) apply clarify apply (blast intro: transient_strengthen) done lemma psp: "\F \ A \ A'; F \ B co B'; st_set(B')\\ F:(A \ B') \ ((A' \ B) \ (B' - B))" apply (subgoal_tac "F \ program \ st_set (A) \ st_set (A') \ st_set (B) ") prefer 2 apply (blast dest!: constrainsD2 leadsToD2) apply (erule leadsTo_induct) prefer 3 apply (blast intro: leadsTo_Union_Int) txt\Basis case\ apply (blast intro: psp_ensures leadsTo_Basis) txt\Transitivity case has a delicate argument involving "cancellation"\ apply (rule leadsTo_Un_duplicate2) apply (erule leadsTo_cancel_Diff1) apply (simp add: Int_Diff Diff_triv) apply (blast intro: leadsTo_weaken_L dest: constrains_imp_subset) done lemma psp2: "\F \ A \ A'; F \ B co B'; st_set(B')\ \ F \ (B' \ A) \ ((B \ A') \ (B' - B))" by (simp (no_asm_simp) add: psp Int_ac) lemma psp_unless: "\F \ A \ A'; F \ B unless B'; st_set(B); st_set(B')\ \ F \ (A \ B) \ ((A' \ B) \ B')" -apply (unfold unless_def) + unfolding unless_def apply (subgoal_tac "st_set (A) \st_set (A') ") prefer 2 apply (blast dest: leadsToD2) apply (drule psp, assumption, blast) apply (blast intro: leadsTo_weaken) done subsection\Proving the induction rules\ (** The most general rule \ r is any wf relation; f is any variant function **) lemma leadsTo_wf_induct_aux: "\wf(r); m \ I; field(r)<=I; F \ program; st_set(B); \m \ I. F \ (A \ f-``{m}) \ ((A \ f-``(converse(r)``{m})) \ B)\ \ F \ (A \ f-``{m}) \ B" apply (erule_tac a = m in wf_induct2, simp_all) apply (subgoal_tac "F \ (A \ (f-`` (converse (r) ``{x}))) \ B") apply (blast intro: leadsTo_cancel1 leadsTo_Un_duplicate) apply (subst vimage_eq_UN) apply (simp del: UN_simps add: Int_UN_distrib) apply (auto intro: leadsTo_UN simp del: UN_simps simp add: Int_UN_distrib) done (** Meta or object quantifier ? **) lemma leadsTo_wf_induct: "\wf(r); field(r)<=I; A<=f-``I; F \ program; st_set(A); st_set(B); \m \ I. F \ (A \ f-``{m}) \ ((A \ f-``(converse(r)``{m})) \ B)\ \ F \ A \ B" apply (rule_tac b = A in subst) defer 1 apply (rule_tac I = I in leadsTo_UN) apply (erule_tac I = I in leadsTo_wf_induct_aux, assumption+, best) done lemma nat_measure_field: "field(measure(nat, \x. x)) = nat" -apply (unfold field_def) + unfolding field_def apply (simp add: measure_def) apply (rule equalityI, force, clarify) apply (erule_tac V = "x\range (y)" for y in thin_rl) apply (erule nat_induct) apply (rule_tac [2] b = "succ (succ (xa))" in domainI) apply (rule_tac b = "succ (0) " in domainI) apply simp_all done lemma Image_inverse_lessThan: "k measure(A, \x. x) -`` {k} = k" apply (rule equalityI) apply (auto simp add: measure_def) apply (blast intro: ltD) apply (rule vimageI) prefer 2 apply blast apply (simp add: lt_Ord lt_Ord2 Ord_mem_iff_lt) apply (blast intro: lt_trans) done (*Alternative proof is via the lemma F \ (A \ f-`(lessThan m)) \ B*) lemma lessThan_induct: "\A<=f-``nat; F \ program; st_set(A); st_set(B); \m \ nat. F:(A \ f-``{m}) \ ((A \ f -`` m) \ B)\ \ F \ A \ B" apply (rule_tac A1 = nat and f1 = "\x. x" in wf_measure [THEN leadsTo_wf_induct]) apply (simp_all add: nat_measure_field) apply (simp add: ltI Image_inverse_lessThan vimage_def [symmetric]) done (*** wlt ****) (*Misra's property W3*) lemma wlt_type: "wlt(F,B) <=state" by (unfold wlt_def, auto) lemma wlt_st_set: "st_set(wlt(F, B))" -apply (unfold st_set_def) + unfolding st_set_def apply (rule wlt_type) done declare wlt_st_set [iff] lemma wlt_leadsTo_iff: "F \ wlt(F, B) \ B \ (F \ program \ st_set(B))" -apply (unfold wlt_def) + unfolding wlt_def apply (blast dest: leadsToD2 intro!: leadsTo_Union) done (* \F \ program; st_set(B)\ \ F \ wlt(F, B) \ B *) lemmas wlt_leadsTo = conjI [THEN wlt_leadsTo_iff [THEN iffD2]] lemma leadsTo_subset: "F \ A \ B \ A \ wlt(F, B)" -apply (unfold wlt_def) + unfolding wlt_def apply (frule leadsToD2) apply (auto simp add: st_set_def) done (*Misra's property W2*) lemma leadsTo_eq_subset_wlt: "F \ A \ B \ (A \ wlt(F,B) \ F \ program \ st_set(B))" apply auto apply (blast dest: leadsToD2 leadsTo_subset intro: leadsTo_weaken_L wlt_leadsTo)+ done (*Misra's property W4*) lemma wlt_increasing: "\F \ program; st_set(B)\ \ B \ wlt(F,B)" apply (rule leadsTo_subset) apply (simp (no_asm_simp) add: leadsTo_eq_subset_wlt [THEN iff_sym] subset_imp_leadsTo) done (*Used in the Trans case below*) lemma leadsTo_123_aux: "\B \ A2; F \ (A1 - B) co (A1 \ B); F \ (A2 - C) co (A2 \ C)\ \ F \ (A1 \ A2 - C) co (A1 \ A2 \ C)" apply (unfold constrains_def st_set_def, blast) done (*Lemma (1,2,3) of Misra's draft book, Chapter 4, "Progress"*) (* slightly different from the HOL one \ B here is bounded *) lemma leadsTo_123: "F \ A \ A' \ \B \ Pow(state). A<=B \ F \ B \ A' \ F \ (B-A') co (B \ A')" apply (frule leadsToD2) apply (erule leadsTo_induct) txt\Basis\ apply (blast dest: ensuresD constrainsD2 st_setD) txt\Trans\ apply clarify apply (rule_tac x = "Ba \ Bb" in bexI) apply (blast intro: leadsTo_123_aux leadsTo_Un_Un leadsTo_cancel1 leadsTo_Un_duplicate, blast) txt\Union\ apply (clarify dest!: ball_conj_distrib [THEN iffD1]) apply (subgoal_tac "\y. y \ Pi (S, \A. {Ba \ Pow (state) . A<=Ba \ F \ Ba \ B \ F \ Ba - B co Ba \ B}) ") defer 1 apply (rule AC_ball_Pi, safe) apply (rotate_tac 1) apply (drule_tac x = x in bspec, blast, blast) apply (rule_tac x = "\A \ S. y`A" in bexI, safe) apply (rule_tac [3] I1 = S in constrains_UN [THEN constrains_weaken]) apply (rule_tac [2] leadsTo_Union) prefer 5 apply (blast dest!: apply_type, simp_all) apply (force dest!: apply_type)+ done (*Misra's property W5*) lemma wlt_constrains_wlt: "\F \ program; st_set(B)\ \F \ (wlt(F, B) - B) co (wlt(F,B))" apply (cut_tac F = F in wlt_leadsTo [THEN leadsTo_123], assumption, blast) apply clarify apply (subgoal_tac "Ba = wlt (F,B) ") prefer 2 apply (blast dest: leadsTo_eq_subset_wlt [THEN iffD1], clarify) apply (simp add: wlt_increasing [THEN subset_Un_iff2 [THEN iffD1]]) done subsection\Completion: Binary and General Finite versions\ lemma completion_aux: "\W = wlt(F, (B' \ C)); F \ A \ (A' \ C); F \ A' co (A' \ C); F \ B \ (B' \ C); F \ B' co (B' \ C)\ \ F \ (A \ B) \ ((A' \ B') \ C)" apply (subgoal_tac "st_set (C) \st_set (W) \st_set (W-C) \st_set (A') \st_set (A) \ st_set (B) \ st_set (B') \ F \ program") prefer 2 apply simp apply (blast dest!: leadsToD2) apply (subgoal_tac "F \ (W-C) co (W \ B' \ C) ") prefer 2 apply (blast intro!: constrains_weaken [OF constrains_Un [OF _ wlt_constrains_wlt]]) apply (subgoal_tac "F \ (W-C) co W") prefer 2 apply (simp add: wlt_increasing [THEN subset_Un_iff2 [THEN iffD1]] Un_assoc) apply (subgoal_tac "F \ (A \ W - C) \ (A' \ W \ C) ") prefer 2 apply (blast intro: wlt_leadsTo psp [THEN leadsTo_weaken]) (** step 13 **) apply (subgoal_tac "F \ (A' \ W \ C) \ (A' \ B' \ C) ") apply (drule leadsTo_Diff) apply (blast intro: subset_imp_leadsTo dest: leadsToD2 constrainsD2) apply (force simp add: st_set_def) apply (subgoal_tac "A \ B \ A \ W") prefer 2 apply (blast dest!: leadsTo_subset intro!: subset_refl [THEN Int_mono]) apply (blast intro: leadsTo_Trans subset_imp_leadsTo) txt\last subgoal\ apply (rule_tac leadsTo_Un_duplicate2) apply (rule_tac leadsTo_Un_Un) prefer 2 apply (blast intro: leadsTo_refl) apply (rule_tac A'1 = "B' \ C" in wlt_leadsTo[THEN psp2, THEN leadsTo_weaken]) apply blast+ done lemmas completion = refl [THEN completion_aux] lemma finite_completion_aux: "\I \ Fin(X); F \ program; st_set(C)\ \ (\i \ I. F \ (A(i)) \ (A'(i) \ C)) \ (\i \ I. F \ (A'(i)) co (A'(i) \ C)) \ F \ (\i \ I. A(i)) \ ((\i \ I. A'(i)) \ C)" apply (erule Fin_induct) apply (auto simp add: Inter_0) apply (rule completion) apply (auto simp del: INT_simps simp add: INT_extend_simps) apply (blast intro: constrains_INT) done lemma finite_completion: "\I \ Fin(X); \i. i \ I \ F \ A(i) \ (A'(i) \ C); \i. i \ I \ F \ A'(i) co (A'(i) \ C); F \ program; st_set(C)\ \ F \ (\i \ I. A(i)) \ ((\i \ I. A'(i)) \ C)" by (blast intro: finite_completion_aux [THEN mp, THEN mp]) lemma stable_completion: "\F \ A \ A'; F \ stable(A'); F \ B \ B'; F \ stable(B')\ \ F \ (A \ B) \ (A' \ B')" -apply (unfold stable_def) + unfolding stable_def apply (rule_tac C1 = 0 in completion [THEN leadsTo_weaken_R], simp+) apply (blast dest: leadsToD2) done lemma finite_stable_completion: "\I \ Fin(X); (\i. i \ I \ F \ A(i) \ A'(i)); (\i. i \ I \ F \ stable(A'(i))); F \ program\ \ F \ (\i \ I. A(i)) \ (\i \ I. A'(i))" -apply (unfold stable_def) + unfolding stable_def apply (subgoal_tac "st_set (\i \ I. A' (i))") prefer 2 apply (blast dest: leadsToD2) apply (rule_tac C1 = 0 in finite_completion [THEN leadsTo_weaken_R], auto) done end diff --git a/src/ZF/Univ.thy b/src/ZF/Univ.thy --- a/src/ZF/Univ.thy +++ b/src/ZF/Univ.thy @@ -1,797 +1,797 @@ (* Title: ZF/Univ.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1992 University of Cambridge Standard notation for Vset(i) is V(i), but users might want V for a variable. NOTE: univ(A) could be a translation; would simplify many proofs! But Ind_Syntax.univ refers to the constant "Univ.univ" *) section\The Cumulative Hierarchy and a Small Universe for Recursive Types\ theory Univ imports Epsilon Cardinal begin definition Vfrom :: "[i,i]\i" where "Vfrom(A,i) \ transrec(i, \x f. A \ (\y\x. Pow(f`y)))" abbreviation Vset :: "i\i" where "Vset(x) \ Vfrom(0,x)" definition Vrec :: "[i, [i,i]\i] \i" where "Vrec(a,H) \ transrec(rank(a), \x g. \z\Vset(succ(x)). H(z, \w\Vset(x). g`rank(w)`w)) ` a" definition Vrecursor :: "[[i,i]\i, i] \i" where "Vrecursor(H,a) \ transrec(rank(a), \x g. \z\Vset(succ(x)). H(\w\Vset(x). g`rank(w)`w, z)) ` a" definition univ :: "i\i" where "univ(A) \ Vfrom(A,nat)" subsection\Immediate Consequences of the Definition of \<^term>\Vfrom(A,i)\\ text\NOT SUITABLE FOR REWRITING -- RECURSIVE!\ lemma Vfrom: "Vfrom(A,i) = A \ (\j\i. Pow(Vfrom(A,j)))" by (subst Vfrom_def [THEN def_transrec], simp) subsubsection\Monotonicity\ lemma Vfrom_mono [rule_format]: "A<=B \ \j. i<=j \ Vfrom(A,i) \ Vfrom(B,j)" apply (rule_tac a=i in eps_induct) apply (rule impI [THEN allI]) apply (subst Vfrom [of A]) apply (subst Vfrom [of B]) apply (erule Un_mono) apply (erule UN_mono, blast) done lemma VfromI: "\a \ Vfrom(A,j); j \ a \ Vfrom(A,i)" by (blast dest: Vfrom_mono [OF subset_refl le_imp_subset [OF leI]]) subsubsection\A fundamental equality: Vfrom does not require ordinals!\ lemma Vfrom_rank_subset1: "Vfrom(A,x) \ Vfrom(A,rank(x))" proof (induct x rule: eps_induct) fix x assume "\y\x. Vfrom(A,y) \ Vfrom(A,rank(y))" thus "Vfrom(A, x) \ Vfrom(A, rank(x))" by (simp add: Vfrom [of _ x] Vfrom [of _ "rank(x)"], blast intro!: rank_lt [THEN ltD]) qed lemma Vfrom_rank_subset2: "Vfrom(A,rank(x)) \ Vfrom(A,x)" apply (rule_tac a=x in eps_induct) apply (subst Vfrom) apply (subst Vfrom, rule subset_refl [THEN Un_mono]) apply (rule UN_least) txt\expand \rank(x1) = (\y\x1. succ(rank(y)))\ in assumptions\ apply (erule rank [THEN equalityD1, THEN subsetD, THEN UN_E]) apply (rule subset_trans) apply (erule_tac [2] UN_upper) apply (rule subset_refl [THEN Vfrom_mono, THEN subset_trans, THEN Pow_mono]) apply (erule ltI [THEN le_imp_subset]) apply (rule Ord_rank [THEN Ord_succ]) apply (erule bspec, assumption) done lemma Vfrom_rank_eq: "Vfrom(A,rank(x)) = Vfrom(A,x)" apply (rule equalityI) apply (rule Vfrom_rank_subset2) apply (rule Vfrom_rank_subset1) done subsection\Basic Closure Properties\ lemma zero_in_Vfrom: "y:x \ 0 \ Vfrom(A,x)" by (subst Vfrom, blast) lemma i_subset_Vfrom: "i \ Vfrom(A,i)" apply (rule_tac a=i in eps_induct) apply (subst Vfrom, blast) done lemma A_subset_Vfrom: "A \ Vfrom(A,i)" apply (subst Vfrom) apply (rule Un_upper1) done lemmas A_into_Vfrom = A_subset_Vfrom [THEN subsetD] lemma subset_mem_Vfrom: "a \ Vfrom(A,i) \ a \ Vfrom(A,succ(i))" by (subst Vfrom, blast) subsubsection\Finite sets and ordered pairs\ lemma singleton_in_Vfrom: "a \ Vfrom(A,i) \ {a} \ Vfrom(A,succ(i))" by (rule subset_mem_Vfrom, safe) lemma doubleton_in_Vfrom: "\a \ Vfrom(A,i); b \ Vfrom(A,i)\ \ {a,b} \ Vfrom(A,succ(i))" by (rule subset_mem_Vfrom, safe) lemma Pair_in_Vfrom: "\a \ Vfrom(A,i); b \ Vfrom(A,i)\ \ \a,b\ \ Vfrom(A,succ(succ(i)))" -apply (unfold Pair_def) + unfolding Pair_def apply (blast intro: doubleton_in_Vfrom) done lemma succ_in_Vfrom: "a \ Vfrom(A,i) \ succ(a) \ Vfrom(A,succ(succ(i)))" apply (intro subset_mem_Vfrom succ_subsetI, assumption) apply (erule subset_trans) apply (rule Vfrom_mono [OF subset_refl subset_succI]) done subsection\0, Successor and Limit Equations for \<^term>\Vfrom\\ lemma Vfrom_0: "Vfrom(A,0) = A" by (subst Vfrom, blast) lemma Vfrom_succ_lemma: "Ord(i) \ Vfrom(A,succ(i)) = A \ Pow(Vfrom(A,i))" apply (rule Vfrom [THEN trans]) apply (rule equalityI [THEN subst_context, OF _ succI1 [THEN RepFunI, THEN Union_upper]]) apply (rule UN_least) apply (rule subset_refl [THEN Vfrom_mono, THEN Pow_mono]) apply (erule ltI [THEN le_imp_subset]) apply (erule Ord_succ) done lemma Vfrom_succ: "Vfrom(A,succ(i)) = A \ Pow(Vfrom(A,i))" apply (rule_tac x1 = "succ (i)" in Vfrom_rank_eq [THEN subst]) apply (rule_tac x1 = i in Vfrom_rank_eq [THEN subst]) apply (subst rank_succ) apply (rule Ord_rank [THEN Vfrom_succ_lemma]) done (*The premise distinguishes this from Vfrom(A,0); allowing X=0 forces the conclusion to be Vfrom(A,\(X)) = A \ (\y\X. Vfrom(A,y)) *) lemma Vfrom_Union: "y:X \ Vfrom(A,\(X)) = (\y\X. Vfrom(A,y))" apply (subst Vfrom) apply (rule equalityI) txt\first inclusion\ apply (rule Un_least) apply (rule A_subset_Vfrom [THEN subset_trans]) apply (rule UN_upper, assumption) apply (rule UN_least) apply (erule UnionE) apply (rule subset_trans) apply (erule_tac [2] UN_upper, subst Vfrom, erule subset_trans [OF UN_upper Un_upper2]) txt\opposite inclusion\ apply (rule UN_least) apply (subst Vfrom, blast) done subsection\\<^term>\Vfrom\ applied to Limit Ordinals\ (*NB. limit ordinals are non-empty: Vfrom(A,0) = A = A \ (\y\0. Vfrom(A,y)) *) lemma Limit_Vfrom_eq: "Limit(i) \ Vfrom(A,i) = (\y\i. Vfrom(A,y))" apply (rule Limit_has_0 [THEN ltD, THEN Vfrom_Union, THEN subst], assumption) apply (simp add: Limit_Union_eq) done lemma Limit_VfromE: "\a \ Vfrom(A,i); \R \ Limit(i); \x. \x Vfrom(A,x)\ \ R \ \ R" apply (rule classical) apply (rule Limit_Vfrom_eq [THEN equalityD1, THEN subsetD, THEN UN_E]) prefer 2 apply assumption apply blast apply (blast intro: ltI Limit_is_Ord) done lemma singleton_in_VLimit: "\a \ Vfrom(A,i); Limit(i)\ \ {a} \ Vfrom(A,i)" apply (erule Limit_VfromE, assumption) apply (erule singleton_in_Vfrom [THEN VfromI]) apply (blast intro: Limit_has_succ) done lemmas Vfrom_UnI1 = Un_upper1 [THEN subset_refl [THEN Vfrom_mono, THEN subsetD]] lemmas Vfrom_UnI2 = Un_upper2 [THEN subset_refl [THEN Vfrom_mono, THEN subsetD]] text\Hard work is finding a single j:i such that {a,b}<=Vfrom(A,j)\ lemma doubleton_in_VLimit: "\a \ Vfrom(A,i); b \ Vfrom(A,i); Limit(i)\ \ {a,b} \ Vfrom(A,i)" apply (erule Limit_VfromE, assumption) apply (erule Limit_VfromE, assumption) apply (blast intro: VfromI [OF doubleton_in_Vfrom] Vfrom_UnI1 Vfrom_UnI2 Limit_has_succ Un_least_lt) done lemma Pair_in_VLimit: "\a \ Vfrom(A,i); b \ Vfrom(A,i); Limit(i)\ \ \a,b\ \ Vfrom(A,i)" txt\Infer that a, b occur at ordinals x,xa < i.\ apply (erule Limit_VfromE, assumption) apply (erule Limit_VfromE, assumption) txt\Infer that \<^term>\succ(succ(x \ xa)) < i\\ apply (blast intro: VfromI [OF Pair_in_Vfrom] Vfrom_UnI1 Vfrom_UnI2 Limit_has_succ Un_least_lt) done lemma product_VLimit: "Limit(i) \ Vfrom(A,i) * Vfrom(A,i) \ Vfrom(A,i)" by (blast intro: Pair_in_VLimit) lemmas Sigma_subset_VLimit = subset_trans [OF Sigma_mono product_VLimit] lemmas nat_subset_VLimit = subset_trans [OF nat_le_Limit [THEN le_imp_subset] i_subset_Vfrom] lemma nat_into_VLimit: "\n: nat; Limit(i)\ \ n \ Vfrom(A,i)" by (blast intro: nat_subset_VLimit [THEN subsetD]) subsubsection\Closure under Disjoint Union\ lemmas zero_in_VLimit = Limit_has_0 [THEN ltD, THEN zero_in_Vfrom] lemma one_in_VLimit: "Limit(i) \ 1 \ Vfrom(A,i)" by (blast intro: nat_into_VLimit) lemma Inl_in_VLimit: "\a \ Vfrom(A,i); Limit(i)\ \ Inl(a) \ Vfrom(A,i)" -apply (unfold Inl_def) + unfolding Inl_def apply (blast intro: zero_in_VLimit Pair_in_VLimit) done lemma Inr_in_VLimit: "\b \ Vfrom(A,i); Limit(i)\ \ Inr(b) \ Vfrom(A,i)" -apply (unfold Inr_def) + unfolding Inr_def apply (blast intro: one_in_VLimit Pair_in_VLimit) done lemma sum_VLimit: "Limit(i) \ Vfrom(C,i)+Vfrom(C,i) \ Vfrom(C,i)" by (blast intro!: Inl_in_VLimit Inr_in_VLimit) lemmas sum_subset_VLimit = subset_trans [OF sum_mono sum_VLimit] subsection\Properties assuming \<^term>\Transset(A)\\ lemma Transset_Vfrom: "Transset(A) \ Transset(Vfrom(A,i))" apply (rule_tac a=i in eps_induct) apply (subst Vfrom) apply (blast intro!: Transset_Union_family Transset_Un Transset_Pow) done lemma Transset_Vfrom_succ: "Transset(A) \ Vfrom(A, succ(i)) = Pow(Vfrom(A,i))" apply (rule Vfrom_succ [THEN trans]) apply (rule equalityI [OF _ Un_upper2]) apply (rule Un_least [OF _ subset_refl]) apply (rule A_subset_Vfrom [THEN subset_trans]) apply (erule Transset_Vfrom [THEN Transset_iff_Pow [THEN iffD1]]) done lemma Transset_Pair_subset: "\\a,b\ \ C; Transset(C)\ \ a: C \ b: C" by (unfold Pair_def Transset_def, blast) lemma Transset_Pair_subset_VLimit: "\\a,b\ \ Vfrom(A,i); Transset(A); Limit(i)\ \ \a,b\ \ Vfrom(A,i)" apply (erule Transset_Pair_subset [THEN conjE]) apply (erule Transset_Vfrom) apply (blast intro: Pair_in_VLimit) done lemma Union_in_Vfrom: "\X \ Vfrom(A,j); Transset(A)\ \ \(X) \ Vfrom(A, succ(j))" apply (drule Transset_Vfrom) apply (rule subset_mem_Vfrom) apply (unfold Transset_def, blast) done lemma Union_in_VLimit: "\X \ Vfrom(A,i); Limit(i); Transset(A)\ \ \(X) \ Vfrom(A,i)" apply (rule Limit_VfromE, assumption+) apply (blast intro: Limit_has_succ VfromI Union_in_Vfrom) done (*** Closure under product/sum applied to elements -- thus Vfrom(A,i) is a model of simple type theory provided A is a transitive set and i is a limit ordinal ***) text\General theorem for membership in Vfrom(A,i) when i is a limit ordinal\ lemma in_VLimit: "\a \ Vfrom(A,i); b \ Vfrom(A,i); Limit(i); \x y j. \j Vfrom(A,j); y \ Vfrom(A,j)\ \ \k. h(x,y) \ Vfrom(A,k) \ k \ h(a,b) \ Vfrom(A,i)" txt\Infer that a, b occur at ordinals x,xa < i.\ apply (erule Limit_VfromE, assumption) apply (erule Limit_VfromE, assumption, atomize) apply (drule_tac x=a in spec) apply (drule_tac x=b in spec) apply (drule_tac x="x \ xa \ 2" in spec) apply (simp add: Un_least_lt_iff lt_Ord Vfrom_UnI1 Vfrom_UnI2) apply (blast intro: Limit_has_0 Limit_has_succ VfromI) done subsubsection\Products\ lemma prod_in_Vfrom: "\a \ Vfrom(A,j); b \ Vfrom(A,j); Transset(A)\ \ a*b \ Vfrom(A, succ(succ(succ(j))))" apply (drule Transset_Vfrom) apply (rule subset_mem_Vfrom) -apply (unfold Transset_def) + unfolding Transset_def apply (blast intro: Pair_in_Vfrom) done lemma prod_in_VLimit: "\a \ Vfrom(A,i); b \ Vfrom(A,i); Limit(i); Transset(A)\ \ a*b \ Vfrom(A,i)" apply (erule in_VLimit, assumption+) apply (blast intro: prod_in_Vfrom Limit_has_succ) done subsubsection\Disjoint Sums, or Quine Ordered Pairs\ lemma sum_in_Vfrom: "\a \ Vfrom(A,j); b \ Vfrom(A,j); Transset(A); 1:j\ \ a+b \ Vfrom(A, succ(succ(succ(j))))" -apply (unfold sum_def) + unfolding sum_def apply (drule Transset_Vfrom) apply (rule subset_mem_Vfrom) -apply (unfold Transset_def) + unfolding Transset_def apply (blast intro: zero_in_Vfrom Pair_in_Vfrom i_subset_Vfrom [THEN subsetD]) done lemma sum_in_VLimit: "\a \ Vfrom(A,i); b \ Vfrom(A,i); Limit(i); Transset(A)\ \ a+b \ Vfrom(A,i)" apply (erule in_VLimit, assumption+) apply (blast intro: sum_in_Vfrom Limit_has_succ) done subsubsection\Function Space!\ lemma fun_in_Vfrom: "\a \ Vfrom(A,j); b \ Vfrom(A,j); Transset(A)\ \ a->b \ Vfrom(A, succ(succ(succ(succ(j)))))" -apply (unfold Pi_def) + unfolding Pi_def apply (drule Transset_Vfrom) apply (rule subset_mem_Vfrom) apply (rule Collect_subset [THEN subset_trans]) apply (subst Vfrom) apply (rule subset_trans [THEN subset_trans]) apply (rule_tac [3] Un_upper2) apply (rule_tac [2] succI1 [THEN UN_upper]) apply (rule Pow_mono) -apply (unfold Transset_def) + unfolding Transset_def apply (blast intro: Pair_in_Vfrom) done lemma fun_in_VLimit: "\a \ Vfrom(A,i); b \ Vfrom(A,i); Limit(i); Transset(A)\ \ a->b \ Vfrom(A,i)" apply (erule in_VLimit, assumption+) apply (blast intro: fun_in_Vfrom Limit_has_succ) done lemma Pow_in_Vfrom: "\a \ Vfrom(A,j); Transset(A)\ \ Pow(a) \ Vfrom(A, succ(succ(j)))" apply (drule Transset_Vfrom) apply (rule subset_mem_Vfrom) -apply (unfold Transset_def) + unfolding Transset_def apply (subst Vfrom, blast) done lemma Pow_in_VLimit: "\a \ Vfrom(A,i); Limit(i); Transset(A)\ \ Pow(a) \ Vfrom(A,i)" by (blast elim: Limit_VfromE intro: Limit_has_succ Pow_in_Vfrom VfromI) subsection\The Set \<^term>\Vset(i)\\ lemma Vset: "Vset(i) = (\j\i. Pow(Vset(j)))" by (subst Vfrom, blast) lemmas Vset_succ = Transset_0 [THEN Transset_Vfrom_succ] lemmas Transset_Vset = Transset_0 [THEN Transset_Vfrom] subsubsection\Characterisation of the elements of \<^term>\Vset(i)\\ lemma VsetD [rule_format]: "Ord(i) \ \b. b \ Vset(i) \ rank(b) < i" apply (erule trans_induct) apply (subst Vset, safe) apply (subst rank) apply (blast intro: ltI UN_succ_least_lt) done lemma VsetI_lemma [rule_format]: "Ord(i) \ \b. rank(b) \ i \ b \ Vset(i)" apply (erule trans_induct) apply (rule allI) apply (subst Vset) apply (blast intro!: rank_lt [THEN ltD]) done lemma VsetI: "rank(x) x \ Vset(i)" by (blast intro: VsetI_lemma elim: ltE) text\Merely a lemma for the next result\ lemma Vset_Ord_rank_iff: "Ord(i) \ b \ Vset(i) \ rank(b) < i" by (blast intro: VsetD VsetI) lemma Vset_rank_iff [simp]: "b \ Vset(a) \ rank(b) < rank(a)" apply (rule Vfrom_rank_eq [THEN subst]) apply (rule Ord_rank [THEN Vset_Ord_rank_iff]) done text\This is rank(rank(a)) = rank(a)\ declare Ord_rank [THEN rank_of_Ord, simp] lemma rank_Vset: "Ord(i) \ rank(Vset(i)) = i" apply (subst rank) apply (rule equalityI, safe) apply (blast intro: VsetD [THEN ltD]) apply (blast intro: VsetD [THEN ltD] Ord_trans) apply (blast intro: i_subset_Vfrom [THEN subsetD] Ord_in_Ord [THEN rank_of_Ord, THEN ssubst]) done lemma Finite_Vset: "i \ nat \ Finite(Vset(i))" apply (erule nat_induct) apply (simp add: Vfrom_0) apply (simp add: Vset_succ) done subsubsection\Reasoning about Sets in Terms of Their Elements' Ranks\ lemma arg_subset_Vset_rank: "a \ Vset(rank(a))" apply (rule subsetI) apply (erule rank_lt [THEN VsetI]) done lemma Int_Vset_subset: "\\i. Ord(i) \ a \ Vset(i) \ b\ \ a \ b" apply (rule subset_trans) apply (rule Int_greatest [OF subset_refl arg_subset_Vset_rank]) apply (blast intro: Ord_rank) done subsubsection\Set Up an Environment for Simplification\ lemma rank_Inl: "rank(a) < rank(Inl(a))" -apply (unfold Inl_def) + unfolding Inl_def apply (rule rank_pair2) done lemma rank_Inr: "rank(a) < rank(Inr(a))" -apply (unfold Inr_def) + unfolding Inr_def apply (rule rank_pair2) done lemmas rank_rls = rank_Inl rank_Inr rank_pair1 rank_pair2 subsubsection\Recursion over Vset Levels!\ text\NOT SUITABLE FOR REWRITING: recursive!\ lemma Vrec: "Vrec(a,H) = H(a, \x\Vset(rank(a)). Vrec(x,H))" -apply (unfold Vrec_def) + unfolding Vrec_def apply (subst transrec, simp) apply (rule refl [THEN lam_cong, THEN subst_context], simp add: lt_def) done text\This form avoids giant explosions in proofs. NOTE the form of the premise!\ lemma def_Vrec: "\\x. h(x)\Vrec(x,H)\ \ h(a) = H(a, \x\Vset(rank(a)). h(x))" apply simp apply (rule Vrec) done text\NOT SUITABLE FOR REWRITING: recursive!\ lemma Vrecursor: "Vrecursor(H,a) = H(\x\Vset(rank(a)). Vrecursor(H,x), a)" -apply (unfold Vrecursor_def) + unfolding Vrecursor_def apply (subst transrec, simp) apply (rule refl [THEN lam_cong, THEN subst_context], simp add: lt_def) done text\This form avoids giant explosions in proofs. NOTE the form of the premise!\ lemma def_Vrecursor: "h \ Vrecursor(H) \ h(a) = H(\x\Vset(rank(a)). h(x), a)" apply simp apply (rule Vrecursor) done subsection\The Datatype Universe: \<^term>\univ(A)\\ lemma univ_mono: "A<=B \ univ(A) \ univ(B)" -apply (unfold univ_def) + unfolding univ_def apply (erule Vfrom_mono) apply (rule subset_refl) done lemma Transset_univ: "Transset(A) \ Transset(univ(A))" -apply (unfold univ_def) + unfolding univ_def apply (erule Transset_Vfrom) done subsubsection\The Set \<^term>\univ(A)\ as a Limit\ lemma univ_eq_UN: "univ(A) = (\i\nat. Vfrom(A,i))" -apply (unfold univ_def) + unfolding univ_def apply (rule Limit_nat [THEN Limit_Vfrom_eq]) done lemma subset_univ_eq_Int: "c \ univ(A) \ c = (\i\nat. c \ Vfrom(A,i))" apply (rule subset_UN_iff_eq [THEN iffD1]) apply (erule univ_eq_UN [THEN subst]) done lemma univ_Int_Vfrom_subset: "\a \ univ(X); \i. i:nat \ a \ Vfrom(X,i) \ b\ \ a \ b" apply (subst subset_univ_eq_Int, assumption) apply (rule UN_least, simp) done lemma univ_Int_Vfrom_eq: "\a \ univ(X); b \ univ(X); \i. i:nat \ a \ Vfrom(X,i) = b \ Vfrom(X,i) \ \ a = b" apply (rule equalityI) apply (rule univ_Int_Vfrom_subset, assumption) apply (blast elim: equalityCE) apply (rule univ_Int_Vfrom_subset, assumption) apply (blast elim: equalityCE) done subsection\Closure Properties for \<^term>\univ(A)\\ lemma zero_in_univ: "0 \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (rule nat_0I [THEN zero_in_Vfrom]) done lemma zero_subset_univ: "{0} \ univ(A)" by (blast intro: zero_in_univ) lemma A_subset_univ: "A \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (rule A_subset_Vfrom) done lemmas A_into_univ = A_subset_univ [THEN subsetD] subsubsection\Closure under Unordered and Ordered Pairs\ lemma singleton_in_univ: "a: univ(A) \ {a} \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (blast intro: singleton_in_VLimit Limit_nat) done lemma doubleton_in_univ: "\a: univ(A); b: univ(A)\ \ {a,b} \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (blast intro: doubleton_in_VLimit Limit_nat) done lemma Pair_in_univ: "\a: univ(A); b: univ(A)\ \ \a,b\ \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (blast intro: Pair_in_VLimit Limit_nat) done lemma Union_in_univ: "\X: univ(A); Transset(A)\ \ \(X) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (blast intro: Union_in_VLimit Limit_nat) done lemma product_univ: "univ(A)*univ(A) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (rule Limit_nat [THEN product_VLimit]) done subsubsection\The Natural Numbers\ lemma nat_subset_univ: "nat \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (rule i_subset_Vfrom) done lemma nat_into_univ: "n \ nat \ n \ univ(A)" by (rule nat_subset_univ [THEN subsetD]) subsubsection\Instances for 1 and 2\ lemma one_in_univ: "1 \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (rule Limit_nat [THEN one_in_VLimit]) done text\unused!\ lemma two_in_univ: "2 \ univ(A)" by (blast intro: nat_into_univ) lemma bool_subset_univ: "bool \ univ(A)" -apply (unfold bool_def) + unfolding bool_def apply (blast intro!: zero_in_univ one_in_univ) done lemmas bool_into_univ = bool_subset_univ [THEN subsetD] subsubsection\Closure under Disjoint Union\ lemma Inl_in_univ: "a: univ(A) \ Inl(a) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (erule Inl_in_VLimit [OF _ Limit_nat]) done lemma Inr_in_univ: "b: univ(A) \ Inr(b) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (erule Inr_in_VLimit [OF _ Limit_nat]) done lemma sum_univ: "univ(C)+univ(C) \ univ(C)" -apply (unfold univ_def) + unfolding univ_def apply (rule Limit_nat [THEN sum_VLimit]) done lemmas sum_subset_univ = subset_trans [OF sum_mono sum_univ] lemma Sigma_subset_univ: "\A \ univ(D); \x. x \ A \ B(x) \ univ(D)\ \ Sigma(A,B) \ univ(D)" apply (simp add: univ_def) apply (blast intro: Sigma_subset_VLimit del: subsetI) done (*Closure under binary union -- use Un_least Closure under Collect -- use Collect_subset [THEN subset_trans] Closure under RepFun -- use RepFun_subset *) subsection\Finite Branching Closure Properties\ subsubsection\Closure under Finite Powerset\ lemma Fin_Vfrom_lemma: "\b: Fin(Vfrom(A,i)); Limit(i)\ \ \j. b \ Vfrom(A,j) \ j Fin(Vfrom(A,i)) \ Vfrom(A,i)" apply (rule subsetI) apply (drule Fin_Vfrom_lemma, safe) apply (rule Vfrom [THEN ssubst]) apply (blast dest!: ltD) done lemmas Fin_subset_VLimit = subset_trans [OF Fin_mono Fin_VLimit] lemma Fin_univ: "Fin(univ(A)) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (rule Limit_nat [THEN Fin_VLimit]) done subsubsection\Closure under Finite Powers: Functions from a Natural Number\ lemma nat_fun_VLimit: "\n: nat; Limit(i)\ \ n -> Vfrom(A,i) \ Vfrom(A,i)" apply (erule nat_fun_subset_Fin [THEN subset_trans]) apply (blast del: subsetI intro: subset_refl Fin_subset_VLimit Sigma_subset_VLimit nat_subset_VLimit) done lemmas nat_fun_subset_VLimit = subset_trans [OF Pi_mono nat_fun_VLimit] lemma nat_fun_univ: "n: nat \ n -> univ(A) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (erule nat_fun_VLimit [OF _ Limit_nat]) done subsubsection\Closure under Finite Function Space\ text\General but seldom-used version; normally the domain is fixed\ lemma FiniteFun_VLimit1: "Limit(i) \ Vfrom(A,i) -||> Vfrom(A,i) \ Vfrom(A,i)" apply (rule FiniteFun.dom_subset [THEN subset_trans]) apply (blast del: subsetI intro: Fin_subset_VLimit Sigma_subset_VLimit subset_refl) done lemma FiniteFun_univ1: "univ(A) -||> univ(A) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (rule Limit_nat [THEN FiniteFun_VLimit1]) done text\Version for a fixed domain\ lemma FiniteFun_VLimit: "\W \ Vfrom(A,i); Limit(i)\ \ W -||> Vfrom(A,i) \ Vfrom(A,i)" apply (rule subset_trans) apply (erule FiniteFun_mono [OF _ subset_refl]) apply (erule FiniteFun_VLimit1) done lemma FiniteFun_univ: "W \ univ(A) \ W -||> univ(A) \ univ(A)" -apply (unfold univ_def) + unfolding univ_def apply (erule FiniteFun_VLimit [OF _ Limit_nat]) done lemma FiniteFun_in_univ: "\f: W -||> univ(A); W \ univ(A)\ \ f \ univ(A)" by (erule FiniteFun_univ [THEN subsetD], assumption) text\Remove \\\ from the rule above\ lemmas FiniteFun_in_univ' = FiniteFun_in_univ [OF _ subsetI] subsection\* For QUniv. Properties of Vfrom analogous to the "take-lemma" *\ text\Intersecting a*b with Vfrom...\ text\This version says a, b exist one level down, in the smaller set Vfrom(X,i)\ lemma doubleton_in_Vfrom_D: "\{a,b} \ Vfrom(X,succ(i)); Transset(X)\ \ a \ Vfrom(X,i) \ b \ Vfrom(X,i)" by (drule Transset_Vfrom_succ [THEN equalityD1, THEN subsetD, THEN PowD], assumption, fast) text\This weaker version says a, b exist at the same level\ lemmas Vfrom_doubleton_D = Transset_Vfrom [THEN Transset_doubleton_D] (** Using only the weaker theorem would prove \a,b\ \ Vfrom(X,i) implies a, b \ Vfrom(X,i), which is useless for induction. Using only the stronger theorem would prove \a,b\ \ Vfrom(X,succ(succ(i))) implies a, b \ Vfrom(X,i), leaving the succ(i) case untreated. The combination gives a reduction by precisely one level, which is most convenient for proofs. **) lemma Pair_in_Vfrom_D: "\\a,b\ \ Vfrom(X,succ(i)); Transset(X)\ \ a \ Vfrom(X,i) \ b \ Vfrom(X,i)" -apply (unfold Pair_def) + unfolding Pair_def apply (blast dest!: doubleton_in_Vfrom_D Vfrom_doubleton_D) done lemma product_Int_Vfrom_subset: "Transset(X) \ (a*b) \ Vfrom(X, succ(i)) \ (a \ Vfrom(X,i)) * (b \ Vfrom(X,i))" by (blast dest!: Pair_in_Vfrom_D) ML \ val rank_ss = simpset_of (\<^context> addsimps [@{thm VsetI}] addsimps @{thms rank_rls} @ (@{thms rank_rls} RLN (2, [@{thm lt_trans}]))); \ end diff --git a/src/ZF/WF.thy b/src/ZF/WF.thy --- a/src/ZF/WF.thy +++ b/src/ZF/WF.thy @@ -1,372 +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. \y,x\: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. \y,x\: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. \y,x\: r \ y \ B) \ x \ B \ A<=B\\ lemma wf_onI2: assumes prem: "\y B. \\x\A. (\y\A. \y,x\: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. \y,x\: r \ P(y)\ \ P(x)\ \ P(a)" -apply (unfold wf_def) + unfolding 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. \y,x\: 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. \y,x\: r \ P(y)\ \ P(x) \ \ P(a)" -apply (unfold wf_on_def) + unfolding wf_on_def apply (erule wf_induct2, assumption) apply (rule field_Int_square, blast) done 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. \y,x\: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) \ \a,a\ \ r" by (erule_tac a=a in wf_induct, blast) lemma wf_not_sym [rule_format]: "wf(r) \ \x. \a,x\:r \ \x,a\ \ r" by (erule_tac a=a in wf_induct, blast) (* @{term"\wf(r); \a,x\ \ r; \P \ \x,a\ \ r\ \ P"} *) lemmas wf_asym = wf_not_sym [THEN swap] lemma wf_on_not_refl: "\wf[A](r); a \ A\ \ \a,a\ \ r" by (erule_tac a=a in wf_on_induct, assumption, blast) lemma wf_on_not_sym: "\wf[A](r); a \ A\ \ (\b. b\A \ \a,b\:r \ \b,a\\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 \ \a,b\ \ r; \b,a\ \ 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); \a,b\:r; \b,c\:r; \c,a\:r; a \ A; b \ A; c \ A\ \ P" apply (subgoal_tac "\y\A. \z\A. \a,y\:r \ \y,z\:r \ \z,a\: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) + unfolding 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); \x,a\:r\ \ f`x = H(x, restrict(f,r-``{x}))" -apply (unfold is_recfun_def) + unfolding 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)\ \ \x,a\:r \ \x,b\: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. \y,z\:f \ \y,z\: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); \b,a\: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) + unfolding 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 "\xa,a1\ \ 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); \b,a\: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) + unfolding 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) + unfolding 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. \y,z\:r \ y\Q))" by (unfold wf_def, blast) end diff --git a/src/ZF/ZF_Base.thy b/src/ZF/ZF_Base.thy --- a/src/ZF/ZF_Base.thy +++ b/src/ZF/ZF_Base.thy @@ -1,650 +1,650 @@ (* Title: ZF/ZF_Base.thy Author: Lawrence C Paulson and Martin D Coen, CU Computer Laboratory Copyright 1993 University of Cambridge *) section \Base of Zermelo-Fraenkel Set Theory\ theory ZF_Base imports FOL begin subsection \Signature\ declare [[eta_contract = false]] typedecl i instance i :: "term" .. axiomatization mem :: "[i, i] \ o" (infixl \\\ 50) \ \membership relation\ and zero :: "i" (\0\) \ \the empty set\ and Pow :: "i \ i" \ \power sets\ and Inf :: "i" \ \infinite set\ and Union :: "i \ i" (\\_\ [90] 90) and PrimReplace :: "[i, [i, i] \ o] \ i" abbreviation not_mem :: "[i, i] \ o" (infixl \\\ 50) \ \negated membership relation\ where "x \ y \ \ (x \ y)" subsection \Bounded Quantifiers\ definition Ball :: "[i, i \ o] \ o" where "Ball(A, P) \ \x. x\A \ P(x)" definition Bex :: "[i, i \ o] \ o" where "Bex(A, P) \ \x. x\A \ P(x)" syntax "_Ball" :: "[pttrn, i, o] \ o" (\(3\_\_./ _)\ 10) "_Bex" :: "[pttrn, i, o] \ o" (\(3\_\_./ _)\ 10) translations "\x\A. P" \ "CONST Ball(A, \x. P)" "\x\A. P" \ "CONST Bex(A, \x. P)" subsection \Variations on Replacement\ (* Derived form of replacement, restricting P to its functional part. The resulting set (for functional P) is the same as with PrimReplace, but the rules are simpler. *) definition Replace :: "[i, [i, i] \ o] \ i" where "Replace(A,P) \ PrimReplace(A, \x y. (\!z. P(x,z)) \ P(x,y))" syntax "_Replace" :: "[pttrn, pttrn, i, o] \ i" (\(1{_ ./ _ \ _, _})\) translations "{y. x\A, Q}" \ "CONST Replace(A, \x y. Q)" (* Functional form of replacement -- analgous to ML's map functional *) definition RepFun :: "[i, i \ i] \ i" where "RepFun(A,f) \ {y . x\A, y=f(x)}" syntax "_RepFun" :: "[i, pttrn, i] \ i" (\(1{_ ./ _ \ _})\ [51,0,51]) translations "{b. x\A}" \ "CONST RepFun(A, \x. b)" (* Separation and Pairing can be derived from the Replacement and Powerset Axioms using the following definitions. *) definition Collect :: "[i, i \ o] \ i" where "Collect(A,P) \ {y . x\A, x=y \ P(x)}" syntax "_Collect" :: "[pttrn, i, o] \ i" (\(1{_ \ _ ./ _})\) translations "{x\A. P}" \ "CONST Collect(A, \x. P)" subsection \General union and intersection\ definition Inter :: "i \ i" (\\_\ [90] 90) where "\(A) \ { x\\(A) . \y\A. x\y}" syntax "_UNION" :: "[pttrn, i, i] \ i" (\(3\_\_./ _)\ 10) "_INTER" :: "[pttrn, i, i] \ i" (\(3\_\_./ _)\ 10) translations "\x\A. B" == "CONST Union({B. x\A})" "\x\A. B" == "CONST Inter({B. x\A})" subsection \Finite sets and binary operations\ (*Unordered pairs (Upair) express binary union/intersection and cons; set enumerations translate as {a,...,z} = cons(a,...,cons(z,0)...)*) definition Upair :: "[i, i] \ i" where "Upair(a,b) \ {y. x\Pow(Pow(0)), (x=0 \ y=a) | (x=Pow(0) \ y=b)}" definition Subset :: "[i, i] \ o" (infixl \\\ 50) \ \subset relation\ where subset_def: "A \ B \ \x\A. x\B" definition Diff :: "[i, i] \ i" (infixl \-\ 65) \ \set difference\ where "A - B \ { x\A . \(x\B) }" definition Un :: "[i, i] \ i" (infixl \\\ 65) \ \binary union\ where "A \ B \ \(Upair(A,B))" definition Int :: "[i, i] \ i" (infixl \\\ 70) \ \binary intersection\ where "A \ B \ \(Upair(A,B))" definition cons :: "[i, i] \ i" where "cons(a,A) \ Upair(a,a) \ A" definition succ :: "i \ i" where "succ(i) \ cons(i, i)" nonterminal "is" syntax "" :: "i \ is" (\_\) "_Enum" :: "[i, is] \ is" (\_,/ _\) "_Finset" :: "is \ i" (\{(_)}\) translations "{x, xs}" == "CONST cons(x, {xs})" "{x}" == "CONST cons(x, 0)" subsection \Axioms\ (* ZF axioms -- see Suppes p.238 Axioms for Union, Pow and Replace state existence only, uniqueness is derivable using extensionality. *) axiomatization where extension: "A = B \ A \ B \ B \ A" and Union_iff: "A \ \(C) \ (\B\C. A\B)" and Pow_iff: "A \ Pow(B) \ A \ B" and (*We may name this set, though it is not uniquely defined.*) infinity: "0 \ Inf \ (\y\Inf. succ(y) \ Inf)" and (*This formulation facilitates case analysis on A.*) foundation: "A = 0 \ (\x\A. \y\x. y\A)" and (*Schema axiom since predicate P is a higher-order variable*) replacement: "(\x\A. \y z. P(x,y) \ P(x,z) \ y = z) \ b \ PrimReplace(A,P) \ (\x\A. P(x,b))" subsection \Definite descriptions -- via Replace over the set "1"\ definition The :: "(i \ o) \ i" (binder \THE \ 10) where the_def: "The(P) \ \({y . x \ {0}, P(y)})" definition If :: "[o, i, i] \ i" (\(if (_)/ then (_)/ else (_))\ [10] 10) where if_def: "if P then a else b \ THE z. P \ z=a | \P \ z=b" abbreviation (input) old_if :: "[o, i, i] \ i" (\if '(_,_,_')\) where "if(P,a,b) \ If(P,a,b)" subsection \Ordered Pairing\ (* this "symmetric" definition works better than {{a}, {a,b}} *) definition Pair :: "[i, i] \ i" where "Pair(a,b) \ {{a,a}, {a,b}}" definition fst :: "i \ i" where "fst(p) \ THE a. \b. p = Pair(a, b)" definition snd :: "i \ i" where "snd(p) \ THE b. \a. p = Pair(a, b)" definition split :: "[[i, i] \ 'a, i] \ 'a::{}" \ \for pattern-matching\ where "split(c) \ \p. c(fst(p), snd(p))" (* Patterns -- extends pre-defined type "pttrn" used in abstractions *) nonterminal patterns syntax "_pattern" :: "patterns \ pttrn" (\\_\\) "" :: "pttrn \ patterns" (\_\) "_patterns" :: "[pttrn, patterns] \ patterns" (\_,/_\) "_Tuple" :: "[i, is] \ i" (\\(_,/ _)\\) translations "\x, y, z\" == "\x, \y, z\\" "\x, y\" == "CONST Pair(x, y)" "\\x,y,zs\.b" == "CONST split(\x \y,zs\.b)" "\\x,y\.b" == "CONST split(\x y. b)" definition Sigma :: "[i, i \ i] \ i" where "Sigma(A,B) \ \x\A. \y\B(x). {\x,y\}" abbreviation cart_prod :: "[i, i] \ i" (infixr \\\ 80) \ \Cartesian product\ where "A \ B \ Sigma(A, \_. B)" subsection \Relations and Functions\ (*converse of relation r, inverse of function*) definition converse :: "i \ i" where "converse(r) \ {z. w\r, \x y. w=\x,y\ \ z=\y,x\}" definition domain :: "i \ i" where "domain(r) \ {x. w\r, \y. w=\x,y\}" definition range :: "i \ i" where "range(r) \ domain(converse(r))" definition field :: "i \ i" where "field(r) \ domain(r) \ range(r)" definition relation :: "i \ o" \ \recognizes sets of pairs\ where "relation(r) \ \z\r. \x y. z = \x,y\" definition "function" :: "i \ o" \ \recognizes functions; can have non-pairs\ where "function(r) \ \x y. \x,y\ \ r \ (\y'. \x,y'\ \ r \ y = y')" definition Image :: "[i, i] \ i" (infixl \``\ 90) \ \image\ where image_def: "r `` A \ {y \ range(r). \x\A. \x,y\ \ r}" definition vimage :: "[i, i] \ i" (infixl \-``\ 90) \ \inverse image\ where vimage_def: "r -`` A \ converse(r)``A" (* Restrict the relation r to the domain A *) definition restrict :: "[i, i] \ i" where "restrict(r,A) \ {z \ r. \x\A. \y. z = \x,y\}" (* Abstraction, application and Cartesian product of a family of sets *) definition Lambda :: "[i, i \ i] \ i" where lam_def: "Lambda(A,b) \ {\x,b(x)\. x\A}" definition "apply" :: "[i, i] \ i" (infixl \`\ 90) \ \function application\ where "f`a \ \(f``{a})" definition Pi :: "[i, i \ i] \ i" where "Pi(A,B) \ {f\Pow(Sigma(A,B)). A\domain(f) \ function(f)}" abbreviation function_space :: "[i, i] \ i" (infixr \\\ 60) \ \function space\ where "A \ B \ Pi(A, \_. B)" (* binder syntax *) syntax "_PROD" :: "[pttrn, i, i] \ i" (\(3\_\_./ _)\ 10) "_SUM" :: "[pttrn, i, i] \ i" (\(3\_\_./ _)\ 10) "_lam" :: "[pttrn, i, i] \ i" (\(3\_\_./ _)\ 10) translations "\x\A. B" == "CONST Pi(A, \x. B)" "\x\A. B" == "CONST Sigma(A, \x. B)" "\x\A. f" == "CONST Lambda(A, \x. f)" subsection \ASCII syntax\ notation (ASCII) cart_prod (infixr \*\ 80) and Int (infixl \Int\ 70) and Un (infixl \Un\ 65) and function_space (infixr \->\ 60) and Subset (infixl \<=\ 50) and mem (infixl \:\ 50) and not_mem (infixl \\:\ 50) syntax (ASCII) "_Ball" :: "[pttrn, i, o] \ o" (\(3ALL _:_./ _)\ 10) "_Bex" :: "[pttrn, i, o] \ o" (\(3EX _:_./ _)\ 10) "_Collect" :: "[pttrn, i, o] \ i" (\(1{_: _ ./ _})\) "_Replace" :: "[pttrn, pttrn, i, o] \ i" (\(1{_ ./ _: _, _})\) "_RepFun" :: "[i, pttrn, i] \ i" (\(1{_ ./ _: _})\ [51,0,51]) "_UNION" :: "[pttrn, i, i] \ i" (\(3UN _:_./ _)\ 10) "_INTER" :: "[pttrn, i, i] \ i" (\(3INT _:_./ _)\ 10) "_PROD" :: "[pttrn, i, i] \ i" (\(3PROD _:_./ _)\ 10) "_SUM" :: "[pttrn, i, i] \ i" (\(3SUM _:_./ _)\ 10) "_lam" :: "[pttrn, i, i] \ i" (\(3lam _:_./ _)\ 10) "_Tuple" :: "[i, is] \ i" (\<(_,/ _)>\) "_pattern" :: "patterns \ pttrn" (\<_>\) subsection \Substitution\ (*Useful examples: singletonI RS subst_elem, subst_elem RSN (2,IntI) *) lemma subst_elem: "\b\A; a=b\ \ a\A" by (erule ssubst, assumption) subsection\Bounded universal quantifier\ lemma ballI [intro!]: "\\x. x\A \ P(x)\ \ \x\A. P(x)" by (simp add: Ball_def) lemmas strip = impI allI ballI lemma bspec [dest?]: "\\x\A. P(x); x: A\ \ P(x)" by (simp add: Ball_def) (*Instantiates x first: better for automatic theorem proving?*) lemma rev_ballE [elim]: "\\x\A. P(x); x\A \ Q; P(x) \ Q\ \ Q" by (simp add: Ball_def, blast) lemma ballE: "\\x\A. P(x); P(x) \ Q; x\A \ Q\ \ Q" by blast (*Used in the datatype package*) lemma rev_bspec: "\x: A; \x\A. P(x)\ \ P(x)" by (simp add: Ball_def) (*Trival rewrite rule; @{term"(\x\A.P)<->P"} holds only if A is nonempty!*) lemma ball_triv [simp]: "(\x\A. P) <-> ((\x. x\A) \ P)" by (simp add: Ball_def) (*Congruence rule for rewriting*) lemma ball_cong [cong]: "\A=A'; \x. x\A' \ P(x) <-> P'(x)\ \ (\x\A. P(x)) <-> (\x\A'. P'(x))" by (simp add: Ball_def) lemma atomize_ball: "(\x. x \ A \ P(x)) \ Trueprop (\x\A. P(x))" by (simp only: Ball_def atomize_all atomize_imp) lemmas [symmetric, rulify] = atomize_ball and [symmetric, defn] = atomize_ball subsection\Bounded existential quantifier\ lemma bexI [intro]: "\P(x); x: A\ \ \x\A. P(x)" by (simp add: Bex_def, blast) (*The best argument order when there is only one @{term"x\A"}*) lemma rev_bexI: "\x\A; P(x)\ \ \x\A. P(x)" by blast (*Not of the general form for such rules. The existential quanitifer becomes universal. *) lemma bexCI: "\\x\A. \P(x) \ P(a); a: A\ \ \x\A. P(x)" by blast lemma bexE [elim!]: "\\x\A. P(x); \x. \x\A; P(x)\ \ Q\ \ Q" by (simp add: Bex_def, blast) (*We do not even have @{term"(\x\A. True) <-> True"} unless @{term"A" is nonempty\*) lemma bex_triv [simp]: "(\x\A. P) <-> ((\x. x\A) \ P)" by (simp add: Bex_def) lemma bex_cong [cong]: "\A=A'; \x. x\A' \ P(x) <-> P'(x)\ \ (\x\A. P(x)) <-> (\x\A'. P'(x))" by (simp add: Bex_def cong: conj_cong) subsection\Rules for subsets\ lemma subsetI [intro!]: "(\x. x\A \ x\B) \ A \ B" by (simp add: subset_def) (*Rule in Modus Ponens style [was called subsetE] *) lemma subsetD [elim]: "\A \ B; c\A\ \ c\B" -apply (unfold subset_def) + unfolding subset_def apply (erule bspec, assumption) done (*Classical elimination rule*) lemma subsetCE [elim]: "\A \ B; c\A \ P; c\B \ P\ \ P" by (simp add: subset_def, blast) (*Sometimes useful with premises in this order*) lemma rev_subsetD: "\c\A; A<=B\ \ c\B" by blast lemma contra_subsetD: "\A \ B; c \ B\ \ c \ A" by blast lemma rev_contra_subsetD: "\c \ B; A \ B\ \ c \ A" by blast lemma subset_refl [simp]: "A \ A" by blast lemma subset_trans: "\A<=B; B<=C\ \ A<=C" by blast (*Useful for proving A<=B by rewriting in some cases*) lemma subset_iff: "A<=B <-> (\x. x\A \ x\B)" apply (unfold subset_def Ball_def) apply (rule iff_refl) done text\For calculations\ declare subsetD [trans] rev_subsetD [trans] subset_trans [trans] subsection\Rules for equality\ (*Anti-symmetry of the subset relation*) lemma equalityI [intro]: "\A \ B; B \ A\ \ A = B" by (rule extension [THEN iffD2], rule conjI) lemma equality_iffI: "(\x. x\A <-> x\B) \ A = B" by (rule equalityI, blast+) lemmas equalityD1 = extension [THEN iffD1, THEN conjunct1] lemmas equalityD2 = extension [THEN iffD1, THEN conjunct2] lemma equalityE: "\A = B; \A<=B; B<=A\ \ P\ \ P" by (blast dest: equalityD1 equalityD2) lemma equalityCE: "\A = B; \c\A; c\B\ \ P; \c\A; c\B\ \ P\ \ P" by (erule equalityE, blast) lemma equality_iffD: "A = B \ (\x. x \ A <-> x \ B)" by auto subsection\Rules for Replace -- the derived form of replacement\ lemma Replace_iff: "b \ {y. x\A, P(x,y)} <-> (\x\A. P(x,b) \ (\y. P(x,y) \ y=b))" -apply (unfold Replace_def) + unfolding Replace_def apply (rule replacement [THEN iff_trans], blast+) done (*Introduction; there must be a unique y such that P(x,y), namely y=b. *) lemma ReplaceI [intro]: "\P(x,b); x: A; \y. P(x,y) \ y=b\ \ b \ {y. x\A, P(x,y)}" by (rule Replace_iff [THEN iffD2], blast) (*Elimination; may asssume there is a unique y such that P(x,y), namely y=b. *) lemma ReplaceE: "\b \ {y. x\A, P(x,y)}; \x. \x: A; P(x,b); \y. P(x,y)\y=b\ \ R \ \ R" by (rule Replace_iff [THEN iffD1, THEN bexE], simp+) (*As above but without the (generally useless) 3rd assumption*) lemma ReplaceE2 [elim!]: "\b \ {y. x\A, P(x,y)}; \x. \x: A; P(x,b)\ \ R \ \ R" by (erule ReplaceE, blast) lemma Replace_cong [cong]: "\A=B; \x y. x\B \ P(x,y) <-> Q(x,y)\ \ Replace(A,P) = Replace(B,Q)" apply (rule equality_iffI) apply (simp add: Replace_iff) done subsection\Rules for RepFun\ lemma RepFunI: "a \ A \ f(a) \ {f(x). x\A}" by (simp add: RepFun_def Replace_iff, blast) (*Useful for coinduction proofs*) lemma RepFun_eqI [intro]: "\b=f(a); a \ A\ \ b \ {f(x). x\A}" apply (erule ssubst) apply (erule RepFunI) done lemma RepFunE [elim!]: "\b \ {f(x). x\A}; \x.\x\A; b=f(x)\ \ P\ \ P" by (simp add: RepFun_def Replace_iff, blast) lemma RepFun_cong [cong]: "\A=B; \x. x\B \ f(x)=g(x)\ \ RepFun(A,f) = RepFun(B,g)" by (simp add: RepFun_def) lemma RepFun_iff [simp]: "b \ {f(x). x\A} <-> (\x\A. b=f(x))" by (unfold Bex_def, blast) lemma triv_RepFun [simp]: "{x. x\A} = A" by blast subsection\Rules for Collect -- forming a subset by separation\ (*Separation is derivable from Replacement*) lemma separation [simp]: "a \ {x\A. P(x)} <-> a\A \ P(a)" by (unfold Collect_def, blast) lemma CollectI [intro!]: "\a\A; P(a)\ \ a \ {x\A. P(x)}" by simp lemma CollectE [elim!]: "\a \ {x\A. P(x)}; \a\A; P(a)\ \ R\ \ R" by simp lemma CollectD1: "a \ {x\A. P(x)} \ a\A" by (erule CollectE, assumption) lemma CollectD2: "a \ {x\A. P(x)} \ P(a)" by (erule CollectE, assumption) lemma Collect_cong [cong]: "\A=B; \x. x\B \ P(x) <-> Q(x)\ \ Collect(A, \x. P(x)) = Collect(B, \x. Q(x))" by (simp add: Collect_def) subsection\Rules for Unions\ declare Union_iff [simp] (*The order of the premises presupposes that C is rigid; A may be flexible*) lemma UnionI [intro]: "\B: C; A: B\ \ A: \(C)" by (simp, blast) lemma UnionE [elim!]: "\A \ \(C); \B.\A: B; B: C\ \ R\ \ R" by (simp, blast) subsection\Rules for Unions of families\ (* @{term"\x\A. B(x)"} abbreviates @{term"\({B(x). x\A})"} *) lemma UN_iff [simp]: "b \ (\x\A. B(x)) <-> (\x\A. b \ B(x))" by (simp add: Bex_def, blast) (*The order of the premises presupposes that A is rigid; b may be flexible*) lemma UN_I: "\a: A; b: B(a)\ \ b: (\x\A. B(x))" by (simp, blast) lemma UN_E [elim!]: "\b \ (\x\A. B(x)); \x.\x: A; b: B(x)\ \ R\ \ R" by blast lemma UN_cong: "\A=B; \x. x\B \ C(x)=D(x)\ \ (\x\A. C(x)) = (\x\B. D(x))" by simp (*No "Addcongs [UN_cong]" because @{term\} is a combination of constants*) (* UN_E appears before UnionE so that it is tried first, to avoid expensive calls to hyp_subst_tac. Cannot include UN_I as it is unsafe: would enlarge the search space.*) subsection\Rules for the empty set\ (*The set @{term"{x\0. False}"} is empty; by foundation it equals 0 See Suppes, page 21.*) lemma not_mem_empty [simp]: "a \ 0" apply (cut_tac foundation) apply (best dest: equalityD2) done lemmas emptyE [elim!] = not_mem_empty [THEN notE] lemma empty_subsetI [simp]: "0 \ A" by blast lemma equals0I: "\\y. y\A \ False\ \ A=0" by blast lemma equals0D [dest]: "A=0 \ a \ A" by blast declare sym [THEN equals0D, dest] lemma not_emptyI: "a\A \ A \ 0" by blast lemma not_emptyE: "\A \ 0; \x. x\A \ R\ \ R" by blast subsection\Rules for Inter\ (*Not obviously useful for proving InterI, InterD, InterE*) lemma Inter_iff: "A \ \(C) <-> (\x\C. A: x) \ C\0" by (simp add: Inter_def Ball_def, blast) (* Intersection is well-behaved only if the family is non-empty! *) lemma InterI [intro!]: "\\x. x: C \ A: x; C\0\ \ A \ \(C)" by (simp add: Inter_iff) (*A "destruct" rule -- every B in C contains A as an element, but A\B can hold when B\C does not! This rule is analogous to "spec". *) lemma InterD [elim, Pure.elim]: "\A \ \(C); B \ C\ \ A \ B" by (unfold Inter_def, blast) (*"Classical" elimination rule -- does not require exhibiting @{term"B\C"} *) lemma InterE [elim]: "\A \ \(C); B\C \ R; A\B \ R\ \ R" by (simp add: Inter_def, blast) subsection\Rules for Intersections of families\ (* @{term"\x\A. B(x)"} abbreviates @{term"\({B(x). x\A})"} *) lemma INT_iff: "b \ (\x\A. B(x)) <-> (\x\A. b \ B(x)) \ A\0" by (force simp add: Inter_def) lemma INT_I: "\\x. x: A \ b: B(x); A\0\ \ b: (\x\A. B(x))" by blast lemma INT_E: "\b \ (\x\A. B(x)); a: A\ \ b \ B(a)" by blast lemma INT_cong: "\A=B; \x. x\B \ C(x)=D(x)\ \ (\x\A. C(x)) = (\x\B. D(x))" by simp (*No "Addcongs [INT_cong]" because @{term\} is a combination of constants*) subsection\Rules for Powersets\ lemma PowI: "A \ B \ A \ Pow(B)" by (erule Pow_iff [THEN iffD2]) lemma PowD: "A \ Pow(B) \ A<=B" by (erule Pow_iff [THEN iffD1]) declare Pow_iff [iff] lemmas Pow_bottom = empty_subsetI [THEN PowI] \ \\<^term>\0 \ Pow(B)\\ lemmas Pow_top = subset_refl [THEN PowI] \ \\<^term>\A \ Pow(A)\\ subsection\Cantor's Theorem: There is no surjection from a set to its powerset.\ (*The search is undirected. Allowing redundant introduction rules may make it diverge. Variable b represents ANY map, such as (lam x\A.b(x)): A->Pow(A). *) lemma cantor: "\S \ Pow(A). \x\A. b(x) \ S" by (best elim!: equalityCE del: ReplaceI RepFun_eqI) end diff --git a/src/ZF/Zorn.thy b/src/ZF/Zorn.thy --- a/src/ZF/Zorn.thy +++ b/src/ZF/Zorn.thy @@ -1,517 +1,517 @@ (* Title: ZF/Zorn.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1994 University of Cambridge *) section\Zorn's Lemma\ theory Zorn imports OrderArith AC Inductive begin text\Based upon the unpublished article ``Towards the Mechanization of the Proofs of Some Classical Theorems of Set Theory,'' by Abrial and Laffitte.\ definition Subset_rel :: "i\i" where "Subset_rel(A) \ {z \ A*A . \x y. z=\x,y\ \ x<=y \ x\y}" definition chain :: "i\i" where "chain(A) \ {F \ Pow(A). \X\F. \Y\F. X<=Y | Y<=X}" definition super :: "[i,i]\i" where "super(A,c) \ {d \ chain(A). c<=d \ c\d}" definition maxchain :: "i\i" where "maxchain(A) \ {c \ chain(A). super(A,c)=0}" definition increasing :: "i\i" where "increasing(A) \ {f \ Pow(A)->Pow(A). \x. x<=A \ x<=f`x}" text\Lemma for the inductive definition below\ lemma Union_in_Pow: "Y \ Pow(Pow(A)) \ \(Y) \ Pow(A)" by blast text\We could make the inductive definition conditional on \<^term>\next \ increasing(S)\ but instead we make this a side-condition of an introduction rule. Thus the induction rule lets us assume that condition! Many inductive proofs are therefore unconditional.\ consts "TFin" :: "[i,i]\i" inductive domains "TFin(S,next)" \ "Pow(S)" intros nextI: "\x \ TFin(S,next); next \ increasing(S)\ \ next`x \ TFin(S,next)" Pow_UnionI: "Y \ Pow(TFin(S,next)) \ \(Y) \ TFin(S,next)" monos Pow_mono con_defs increasing_def type_intros CollectD1 [THEN apply_funtype] Union_in_Pow subsection\Mathematical Preamble\ lemma Union_lemma0: "(\x\C. x<=A | B<=x) \ \(C)<=A | B<=\(C)" by blast lemma Inter_lemma0: "\c \ C; \x\C. A<=x | x<=B\ \ A \ \(C) | \(C) \ B" by blast subsection\The Transfinite Construction\ lemma increasingD1: "f \ increasing(A) \ f \ Pow(A)->Pow(A)" -apply (unfold increasing_def) + unfolding increasing_def apply (erule CollectD1) done lemma increasingD2: "\f \ increasing(A); x<=A\ \ x \ f`x" by (unfold increasing_def, blast) lemmas TFin_UnionI = PowI [THEN TFin.Pow_UnionI] lemmas TFin_is_subset = TFin.dom_subset [THEN subsetD, THEN PowD] text\Structural induction on \<^term>\TFin(S,next)\\ lemma TFin_induct: "\n \ TFin(S,next); \x. \x \ TFin(S,next); P(x); next \ increasing(S)\ \ P(next`x); \Y. \Y \ TFin(S,next); \y\Y. P(y)\ \ P(\(Y)) \ \ P(n)" by (erule TFin.induct, blast+) subsection\Some Properties of the Transfinite Construction\ lemmas increasing_trans = subset_trans [OF _ increasingD2, OF _ _ TFin_is_subset] text\Lemma 1 of section 3.1\ lemma TFin_linear_lemma1: "\n \ TFin(S,next); m \ TFin(S,next); \x \ TFin(S,next) . x<=m \ x=m | next`x<=m\ \ n<=m | next`m<=n" apply (erule TFin_induct) apply (erule_tac [2] Union_lemma0) (*or just Blast_tac*) (*downgrade subsetI from intro! to intro*) apply (blast dest: increasing_trans) done text\Lemma 2 of section 3.2. Interesting in its own right! Requires \<^term>\next \ increasing(S)\ in the second induction step.\ lemma TFin_linear_lemma2: "\m \ TFin(S,next); next \ increasing(S)\ \ \n \ TFin(S,next). n<=m \ n=m | next`n \ m" apply (erule TFin_induct) apply (rule impI [THEN ballI]) txt\case split using \TFin_linear_lemma1\\ apply (rule_tac n1 = n and m1 = x in TFin_linear_lemma1 [THEN disjE], assumption+) apply (blast del: subsetI intro: increasing_trans subsetI, blast) txt\second induction step\ apply (rule impI [THEN ballI]) apply (rule Union_lemma0 [THEN disjE]) apply (erule_tac [3] disjI2) prefer 2 apply blast apply (rule ballI) apply (drule bspec, assumption) apply (drule subsetD, assumption) apply (rule_tac n1 = n and m1 = x in TFin_linear_lemma1 [THEN disjE], assumption+, blast) apply (erule increasingD2 [THEN subset_trans, THEN disjI1]) apply (blast dest: TFin_is_subset)+ done text\a more convenient form for Lemma 2\ lemma TFin_subsetD: "\n<=m; m \ TFin(S,next); n \ TFin(S,next); next \ increasing(S)\ \ n=m | next`n \ m" by (blast dest: TFin_linear_lemma2 [rule_format]) text\Consequences from section 3.3 -- Property 3.2, the ordering is total\ lemma TFin_subset_linear: "\m \ TFin(S,next); n \ TFin(S,next); next \ increasing(S)\ \ n \ m | m<=n" apply (rule disjE) apply (rule TFin_linear_lemma1 [OF _ _TFin_linear_lemma2]) apply (assumption+, erule disjI2) apply (blast del: subsetI intro: subsetI increasingD2 [THEN subset_trans] TFin_is_subset) done text\Lemma 3 of section 3.3\ lemma equal_next_upper: "\n \ TFin(S,next); m \ TFin(S,next); m = next`m\ \ n \ m" apply (erule TFin_induct) apply (drule TFin_subsetD) apply (assumption+, force, blast) done text\Property 3.3 of section 3.3\ lemma equal_next_Union: "\m \ TFin(S,next); next \ increasing(S)\ \ m = next`m <-> m = \(TFin(S,next))" apply (rule iffI) apply (rule Union_upper [THEN equalityI]) apply (rule_tac [2] equal_next_upper [THEN Union_least]) apply (assumption+) apply (erule ssubst) apply (rule increasingD2 [THEN equalityI], assumption) apply (blast del: subsetI intro: subsetI TFin_UnionI TFin.nextI TFin_is_subset)+ done subsection\Hausdorff's Theorem: Every Set Contains a Maximal Chain\ text\NOTE: We assume the partial ordering is \\\, the subset relation!\ text\* Defining the "next" operation for Hausdorff's Theorem *\ lemma chain_subset_Pow: "chain(A) \ Pow(A)" -apply (unfold chain_def) + unfolding chain_def apply (rule Collect_subset) done lemma super_subset_chain: "super(A,c) \ chain(A)" -apply (unfold super_def) + unfolding super_def apply (rule Collect_subset) done lemma maxchain_subset_chain: "maxchain(A) \ chain(A)" -apply (unfold maxchain_def) + unfolding maxchain_def apply (rule Collect_subset) done lemma choice_super: "\ch \ (\X \ Pow(chain(S)) - {0}. X); X \ chain(S); X \ maxchain(S)\ \ ch ` super(S,X) \ super(S,X)" apply (erule apply_type) apply (unfold super_def maxchain_def, blast) done lemma choice_not_equals: "\ch \ (\X \ Pow(chain(S)) - {0}. X); X \ chain(S); X \ maxchain(S)\ \ ch ` super(S,X) \ X" apply (rule notI) apply (drule choice_super, assumption, assumption) apply (simp add: super_def) done text\This justifies Definition 4.4\ lemma Hausdorff_next_exists: "ch \ (\X \ Pow(chain(S))-{0}. X) \ \next \ increasing(S). \X \ Pow(S). next`X = if(X \ chain(S)-maxchain(S), ch`super(S,X), X)" apply (rule_tac x="\X\Pow(S). if X \ chain(S) - maxchain(S) then ch ` super(S, X) else X" in bexI) apply force -apply (unfold increasing_def) + unfolding increasing_def apply (rule CollectI) apply (rule lam_type) apply (simp (no_asm_simp)) apply (blast dest: super_subset_chain [THEN subsetD] chain_subset_Pow [THEN subsetD] choice_super) txt\Now, verify that it increases\ apply (simp (no_asm_simp) add: Pow_iff subset_refl) apply safe apply (drule choice_super) apply (assumption+) apply (simp add: super_def, blast) done text\Lemma 4\ lemma TFin_chain_lemma4: "\c \ TFin(S,next); ch \ (\X \ Pow(chain(S))-{0}. X); next \ increasing(S); \X \ Pow(S). next`X = if(X \ chain(S)-maxchain(S), ch`super(S,X), X)\ \ c \ chain(S)" apply (erule TFin_induct) apply (simp (no_asm_simp) add: chain_subset_Pow [THEN subsetD, THEN PowD] choice_super [THEN super_subset_chain [THEN subsetD]]) -apply (unfold chain_def) + unfolding chain_def apply (rule CollectI, blast, safe) apply (rule_tac m1=B and n1=Ba in TFin_subset_linear [THEN disjE], fast+) txt\\Blast_tac's\ slow\ done theorem Hausdorff: "\c. c \ maxchain(S)" apply (rule AC_Pi_Pow [THEN exE]) apply (rule Hausdorff_next_exists [THEN bexE], assumption) apply (rename_tac ch "next") apply (subgoal_tac "\(TFin (S,next)) \ chain (S) ") prefer 2 apply (blast intro!: TFin_chain_lemma4 subset_refl [THEN TFin_UnionI]) apply (rule_tac x = "\(TFin (S,next))" in exI) apply (rule classical) apply (subgoal_tac "next ` Union(TFin (S,next)) = \(TFin (S,next))") apply (rule_tac [2] equal_next_Union [THEN iffD2, symmetric]) apply (rule_tac [2] subset_refl [THEN TFin_UnionI]) prefer 2 apply assumption apply (rule_tac [2] refl) apply (simp add: subset_refl [THEN TFin_UnionI, THEN TFin.dom_subset [THEN subsetD, THEN PowD]]) apply (erule choice_not_equals [THEN notE]) apply (assumption+) done subsection\Zorn's Lemma: If All Chains in S Have Upper Bounds In S, then S contains a Maximal Element\ text\Used in the proof of Zorn's Lemma\ lemma chain_extend: "\c \ chain(A); z \ A; \x \ c. x<=z\ \ cons(z,c) \ chain(A)" by (unfold chain_def, blast) lemma Zorn: "\c \ chain(S). \(c) \ S \ \y \ S. \z \ S. y<=z \ y=z" apply (rule Hausdorff [THEN exE]) apply (simp add: maxchain_def) apply (rename_tac c) apply (rule_tac x = "\(c)" in bexI) prefer 2 apply blast apply safe apply (rename_tac z) apply (rule classical) apply (subgoal_tac "cons (z,c) \ super (S,c) ") apply (blast elim: equalityE) apply (unfold super_def, safe) apply (fast elim: chain_extend) apply (fast elim: equalityE) done text \Alternative version of Zorn's Lemma\ theorem Zorn2: "\c \ chain(S). \y \ S. \x \ c. x \ y \ \y \ S. \z \ S. y<=z \ y=z" apply (cut_tac Hausdorff maxchain_subset_chain) apply (erule exE) apply (drule subsetD, assumption) apply (drule bspec, assumption, erule bexE) apply (rule_tac x = y in bexI) prefer 2 apply assumption apply clarify apply rule apply assumption apply rule apply (rule ccontr) apply (frule_tac z=z in chain_extend) apply (assumption, blast) apply (unfold maxchain_def super_def) apply (blast elim!: equalityCE) done subsection\Zermelo's Theorem: Every Set can be Well-Ordered\ text\Lemma 5\ lemma TFin_well_lemma5: "\n \ TFin(S,next); Z \ TFin(S,next); z:Z; \ \(Z) \ Z\ \ \m \ Z. n \ m" apply (erule TFin_induct) prefer 2 apply blast txt\second induction step is easy\ apply (rule ballI) apply (rule bspec [THEN TFin_subsetD, THEN disjE], auto) apply (subgoal_tac "m = \(Z) ") apply blast+ done text\Well-ordering of \<^term>\TFin(S,next)\\ lemma well_ord_TFin_lemma: "\Z \ TFin(S,next); z \ Z\ \ \(Z) \ Z" apply (rule classical) apply (subgoal_tac "Z = {\(TFin (S,next))}") apply (simp (no_asm_simp) add: Inter_singleton) apply (erule equal_singleton) apply (rule Union_upper [THEN equalityI]) apply (rule_tac [2] subset_refl [THEN TFin_UnionI, THEN TFin_well_lemma5, THEN bspec], blast+) done text\This theorem just packages the previous result\ lemma well_ord_TFin: "next \ increasing(S) \ well_ord(TFin(S,next), Subset_rel(TFin(S,next)))" apply (rule well_ordI) apply (unfold Subset_rel_def linear_def) txt\Prove the well-foundedness goal\ apply (rule wf_onI) apply (frule well_ord_TFin_lemma, assumption) apply (drule_tac x = "\(Z) " in bspec, assumption) apply blast txt\Now prove the linearity goal\ apply (intro ballI) apply (case_tac "x=y") apply blast txt\The \<^term>\x\y\ case remains\ apply (rule_tac n1=x and m1=y in TFin_subset_linear [THEN disjE], assumption+, blast+) done text\* Defining the "next" operation for Zermelo's Theorem *\ lemma choice_Diff: "\ch \ (\X \ Pow(S) - {0}. X); X \ S; X\S\ \ ch ` (S-X) \ S-X" apply (erule apply_type) apply (blast elim!: equalityE) done text\This justifies Definition 6.1\ lemma Zermelo_next_exists: "ch \ (\X \ Pow(S)-{0}. X) \ \next \ increasing(S). \X \ Pow(S). next`X = (if X=S then S else cons(ch`(S-X), X))" apply (rule_tac x="\X\Pow(S). if X=S then S else cons(ch`(S-X), X)" in bexI) apply force -apply (unfold increasing_def) + unfolding increasing_def apply (rule CollectI) apply (rule lam_type) txt\Type checking is surprisingly hard!\ apply (simp (no_asm_simp) add: Pow_iff cons_subset_iff subset_refl) apply (blast intro!: choice_Diff [THEN DiffD1]) txt\Verify that it increases\ apply (intro allI impI) apply (simp add: Pow_iff subset_consI subset_refl) done text\The construction of the injection\ lemma choice_imp_injection: "\ch \ (\X \ Pow(S)-{0}. X); next \ increasing(S); \X \ Pow(S). next`X = if(X=S, S, cons(ch`(S-X), X))\ \ (\ x \ S. \({y \ TFin(S,next). x \ y})) \ inj(S, TFin(S,next) - {S})" apply (rule_tac d = "\y. ch` (S-y) " in lam_injective) apply (rule DiffI) apply (rule Collect_subset [THEN TFin_UnionI]) apply (blast intro!: Collect_subset [THEN TFin_UnionI] elim: equalityE) apply (subgoal_tac "x \ \({y \ TFin (S,next) . x \ y}) ") prefer 2 apply (blast elim: equalityE) apply (subgoal_tac "\({y \ TFin (S,next) . x \ y}) \ S") prefer 2 apply (blast elim: equalityE) txt\For proving \x \ next`\(...)\. Abrial and Laffitte's justification appears to be faulty.\ apply (subgoal_tac "\ next ` Union({y \ TFin (S,next) . x \ y}) \ \({y \ TFin (S,next) . x \ y}) ") prefer 2 apply (simp del: Union_iff add: Collect_subset [THEN TFin_UnionI, THEN TFin_is_subset] Pow_iff cons_subset_iff subset_refl choice_Diff [THEN DiffD2]) apply (subgoal_tac "x \ next ` Union({y \ TFin (S,next) . x \ y}) ") prefer 2 apply (blast intro!: Collect_subset [THEN TFin_UnionI] TFin.nextI) txt\End of the lemmas!\ apply (simp add: Collect_subset [THEN TFin_UnionI, THEN TFin_is_subset]) done text\The wellordering theorem\ theorem AC_well_ord: "\r. well_ord(S,r)" apply (rule AC_Pi_Pow [THEN exE]) apply (rule Zermelo_next_exists [THEN bexE], assumption) apply (rule exI) apply (rule well_ord_rvimage) apply (erule_tac [2] well_ord_TFin) apply (rule choice_imp_injection [THEN inj_weaken_type], blast+) done subsection \Zorn's Lemma for Partial Orders\ text \Reimported from HOL by Clemens Ballarin.\ definition Chain :: "i \ i" where "Chain(r) = {A \ Pow(field(r)). \a\A. \b\A. \a, b\ \ r | \b, a\ \ r}" lemma mono_Chain: "r \ s \ Chain(r) \ Chain(s)" unfolding Chain_def by blast theorem Zorn_po: assumes po: "Partial_order(r)" and u: "\C\Chain(r). \u\field(r). \a\C. \a, u\ \ r" shows "\m\field(r). \a\field(r). \m, a\ \ r \ a = m" proof - have "Preorder(r)" using po by (simp add: partial_order_on_def) \ \Mirror r in the set of subsets below (wrt r) elements of A (?).\ let ?B = "\x\field(r). r -`` {x}" let ?S = "?B `` field(r)" have "\C\chain(?S). \U\?S. \A\C. A \ U" proof (clarsimp simp: chain_def Subset_rel_def bex_image_simp) fix C assume 1: "C \ ?S" and 2: "\A\C. \B\C. A \ B | B \ A" let ?A = "{x \ field(r). \M\C. M = ?B`x}" have "C = ?B `` ?A" using 1 apply (auto simp: image_def) apply rule apply rule apply (drule subsetD) apply assumption apply (erule CollectE) apply rule apply assumption apply (erule bexE) apply rule prefer 2 apply assumption apply rule apply (erule lamE) apply simp apply assumption apply (thin_tac "C \ X" for X) apply (fast elim: lamE) done have "?A \ Chain(r)" proof (simp add: Chain_def subsetI, intro conjI ballI impI) fix a b assume "a \ field(r)" "r -`` {a} \ C" "b \ field(r)" "r -`` {b} \ C" hence "r -`` {a} \ r -`` {b} | r -`` {b} \ r -`` {a}" using 2 by auto then show "\a, b\ \ r | \b, a\ \ r" using \Preorder(r)\ \a \ field(r)\ \b \ field(r)\ by (simp add: subset_vimage1_vimage1_iff) qed then obtain u where uA: "u \ field(r)" "\a\?A. \a, u\ \ r" using u apply auto apply (drule bspec) apply assumption apply auto done have "\A\C. A \ r -`` {u}" proof (auto intro!: vimageI) fix a B assume aB: "B \ C" "a \ B" with 1 obtain x where "x \ field(r)" "B = r -`` {x}" apply - apply (drule subsetD) apply assumption apply (erule imageE) apply (erule lamE) apply simp done then show "\a, u\ \ r" using uA aB \Preorder(r)\ by (auto simp: preorder_on_def refl_def) (blast dest: trans_onD)+ qed then show "\U\field(r). \A\C. A \ r -`` {U}" using \u \ field(r)\ .. qed from Zorn2 [OF this] obtain m B where "m \ field(r)" "B = r -`` {m}" "\x\field(r). B \ r -`` {x} \ B = r -`` {x}" by (auto elim!: lamE simp: ball_image_simp) then have "\a\field(r). \m, a\ \ r \ a = m" using po \Preorder(r)\ \m \ field(r)\ by (auto simp: subset_vimage1_vimage1_iff Partial_order_eq_vimage1_vimage1_iff) then show ?thesis using \m \ field(r)\ by blast qed 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]: "\a,b\\ converse(r) \ \b,a\\r" by (unfold converse_def, blast) lemma converseI [intro!]: "\a,b\\r \ \b,a\\converse(r)" by (unfold converse_def, blast) lemma converseD: "\a,b\ \ converse(r) \ \b,a\ \ r" by (unfold converse_def, blast) lemma converseE [elim!]: "\yx \ converse(r); \x y. \yx=\y,x\; \x,y\\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: "\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. \a,y\\ r)" by (unfold domain_def, blast) lemma domainI [intro]: "\a,b\\ r \ a: domain(r)" by (unfold domain_def, blast) lemma domainE [elim!]: "\a \ domain(r); \y. \a,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(\a,b\,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]: "\a,b\\ r \ b \ range(r)" -apply (unfold range_def) + unfolding range_def apply (erule converseI [THEN domainI]) done lemma rangeE [elim!]: "\b \ range(r); \x. \x,b\\ r \ P\ \ P" by (unfold range_def, blast) lemma range_subset: "range(A*B) \ B" -apply (unfold range_def) + unfolding 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(\a,b\,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: "\a,b\\ r \ a \ field(r)" by (unfold field_def, blast) lemma fieldI2: "\a,b\\ r \ b \ field(r)" by (unfold field_def, blast) lemma fieldCI [intro]: "(\ \c,a\\r \ \a,b\\ r) \ a \ field(r)" apply (unfold field_def, blast) done lemma fieldE [elim!]: "\a \ field(r); \x. \a,x\\ r \ P; \x. \x,a\\ 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) + unfolding field_def apply (rule Un_upper1) done lemma range_subset_field: "range(r) \ field(r)" -apply (unfold field_def) + unfolding 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(\a,b\,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: "\\a,c\ \ r; c\b\ \ domain(r-{\a,b\}) = domain(r)" by blast lemma range_Diff_eq: "\\c,b\ \ r; c\a\ \ range(r-{\a,b\}) = range(r)" by blast subsection\Image of a Set under a Function or Relation\ lemma image_iff: "b \ r``A \ (\x\A. \x,b\\r)" by (unfold image_def, blast) lemma image_singleton_iff: "b \ r``{a} \ \a,b\\r" by (rule image_iff [THEN iff_trans], blast) lemma imageI [intro]: "\\a,b\\ r; a\A\ \ b \ r``A" by (unfold image_def, blast) lemma imageE [elim!]: "\b: r``A; \x.\\x,b\\ 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(\x,y\)})" 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. \a,y\\r)" by (unfold vimage_def image_def converse_def, blast) lemma vimage_singleton_iff: "a \ r-``{b} \ \a,b\\r" by (rule vimage_iff [THEN iff_trans], blast) lemma vimageI [intro]: "\\a,b\\ r; b\B\ \ a \ r-``B" by (unfold vimage_def, blast) lemma vimageE [elim!]: "\a: r-``B; \x.\\a,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) + unfolding 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/ex/Commutation.thy b/src/ZF/ex/Commutation.thy --- a/src/ZF/ex/Commutation.thy +++ b/src/ZF/ex/Commutation.thy @@ -1,142 +1,142 @@ (* Title: ZF/ex/Commutation.thy Author: Tobias Nipkow \ Sidi Ould Ehmety Copyright 1995 TU Muenchen Commutation theory for proving the Church Rosser theorem. *) theory Commutation imports ZF begin definition square :: "[i, i, i, i] \ o" where "square(r,s,t,u) \ (\a b. \a,b\ \ r \ (\c. \a, c\ \ s \ (\x. \b,x\ \ t \ \c,x\ \ u)))" definition commute :: "[i, i] \ o" where "commute(r,s) \ square(r,s,s,r)" definition diamond :: "i\o" where "diamond(r) \ commute(r, r)" definition strip :: "i\o" where "strip(r) \ commute(r^*, r)" definition Church_Rosser :: "i \ o" where "Church_Rosser(r) \ (\x y. \x,y\ \ (r \ converse(r))^* \ (\z. \x,z\ \ r^* \ \y,z\ \ r^*))" definition confluent :: "i\o" where "confluent(r) \ diamond(r^*)" lemma square_sym: "square(r,s,t,u) \ square(s,r,u,t)" unfolding square_def by blast lemma square_subset: "\square(r,s,t,u); t \ t'\ \ square(r,s,t',u)" unfolding square_def by blast lemma square_rtrancl: "square(r,s,s,t) \ field(s)<=field(t) \ square(r^*,s,s,t^*)" apply (unfold square_def, clarify) apply (erule rtrancl_induct) apply (blast intro: rtrancl_refl) apply (blast intro: rtrancl_into_rtrancl) done (* A special case of square_rtrancl_on *) lemma diamond_strip: "diamond(r) \ strip(r)" apply (unfold diamond_def commute_def strip_def) apply (rule square_rtrancl, simp_all) done (*** commute ***) lemma commute_sym: "commute(r,s) \ commute(s,r)" unfolding commute_def by (blast intro: square_sym) lemma commute_rtrancl: "commute(r,s) \ field(r)=field(s) \ commute(r^*,s^*)" -apply (unfold commute_def) + unfolding commute_def apply (rule square_rtrancl) apply (rule square_sym [THEN square_rtrancl, THEN square_sym]) apply (simp_all add: rtrancl_field) done lemma confluentD: "confluent(r) \ diamond(r^*)" by (simp add: confluent_def) lemma strip_confluent: "strip(r) \ confluent(r)" apply (unfold strip_def confluent_def diamond_def) apply (drule commute_rtrancl) apply (simp_all add: rtrancl_field) done lemma commute_Un: "\commute(r,t); commute(s,t)\ \ commute(r \ s, t)" unfolding commute_def square_def by blast lemma diamond_Un: "\diamond(r); diamond(s); commute(r, s)\ \ diamond(r \ s)" unfolding diamond_def by (blast intro: commute_Un commute_sym) lemma diamond_confluent: "diamond(r) \ confluent(r)" apply (unfold diamond_def confluent_def) apply (erule commute_rtrancl, simp) done lemma confluent_Un: "\confluent(r); confluent(s); commute(r^*, s^*); relation(r); relation(s)\ \ confluent(r \ s)" -apply (unfold confluent_def) + unfolding confluent_def apply (rule rtrancl_Un_rtrancl [THEN subst], auto) apply (blast dest: diamond_Un intro: diamond_confluent [THEN confluentD]) done lemma diamond_to_confluence: "\diamond(r); s \ r; r<= s^*\ \ confluent(s)" apply (drule rtrancl_subset [symmetric], assumption) apply (simp_all add: confluent_def) apply (blast intro: diamond_confluent [THEN confluentD]) done (*** Church_Rosser ***) lemma Church_Rosser1: "Church_Rosser(r) \ confluent(r)" apply (unfold confluent_def Church_Rosser_def square_def commute_def diamond_def, auto) apply (drule converseI) apply (simp (no_asm_use) add: rtrancl_converse [symmetric]) apply (drule_tac x = b in spec) apply (drule_tac x1 = c in spec [THEN mp]) apply (rule_tac b = a in rtrancl_trans) apply (blast intro: rtrancl_mono [THEN subsetD])+ done lemma Church_Rosser2: "confluent(r) \ Church_Rosser(r)" apply (unfold confluent_def Church_Rosser_def square_def commute_def diamond_def, auto) apply (frule fieldI1) apply (simp add: rtrancl_field) apply (erule rtrancl_induct, auto) apply (blast intro: rtrancl_refl) apply (blast del: rtrancl_refl intro: r_into_rtrancl rtrancl_trans)+ done lemma Church_Rosser: "Church_Rosser(r) \ confluent(r)" by (blast intro: Church_Rosser1 Church_Rosser2) end diff --git a/src/ZF/ex/Limit.thy b/src/ZF/ex/Limit.thy --- a/src/ZF/ex/Limit.thy +++ b/src/ZF/ex/Limit.thy @@ -1,2306 +1,2306 @@ (* Title: ZF/ex/Limit.thy Author: Sten Agerholm Author: Lawrence C Paulson A formalization of the inverse limit construction of domain theory. The following paper comments on the formalization: "A Comparison of HOL-ST and Isabelle/ZF" by Sten Agerholm In Proceedings of the First Isabelle Users Workshop, Technical Report No. 379, University of Cambridge Computer Laboratory, 1995. This is a condensed version of: "A Comparison of HOL-ST and Isabelle/ZF" by Sten Agerholm Technical Report No. 369, University of Cambridge Computer Laboratory, 1995. *) theory Limit imports ZF begin definition rel :: "[i,i,i]\o" where "rel(D,x,y) \ \x,y\:snd(D)" definition set :: "i\i" where "set(D) \ fst(D)" definition po :: "i\o" where "po(D) \ (\x \ set(D). rel(D,x,x)) \ (\x \ set(D). \y \ set(D). \z \ set(D). rel(D,x,y) \ rel(D,y,z) \ rel(D,x,z)) \ (\x \ set(D). \y \ set(D). rel(D,x,y) \ rel(D,y,x) \ x = y)" definition chain :: "[i,i]\o" where (* Chains are object level functions nat->set(D) *) "chain(D,X) \ X \ nat->set(D) \ (\n \ nat. rel(D,X`n,X`(succ(n))))" definition isub :: "[i,i,i]\o" where "isub(D,X,x) \ x \ set(D) \ (\n \ nat. rel(D,X`n,x))" definition islub :: "[i,i,i]\o" where "islub(D,X,x) \ isub(D,X,x) \ (\y. isub(D,X,y) \ rel(D,x,y))" definition lub :: "[i,i]\i" where "lub(D,X) \ THE x. islub(D,X,x)" definition cpo :: "i\o" where "cpo(D) \ po(D) \ (\X. chain(D,X) \ (\x. islub(D,X,x)))" definition pcpo :: "i\o" where "pcpo(D) \ cpo(D) \ (\x \ set(D). \y \ set(D). rel(D,x,y))" definition bot :: "i\i" where "bot(D) \ THE x. x \ set(D) \ (\y \ set(D). rel(D,x,y))" definition mono :: "[i,i]\i" where "mono(D,E) \ {f \ set(D)->set(E). \x \ set(D). \y \ set(D). rel(D,x,y) \ rel(E,f`x,f`y)}" definition cont :: "[i,i]\i" where "cont(D,E) \ {f \ mono(D,E). \X. chain(D,X) \ f`(lub(D,X)) = lub(E,\n \ nat. f`(X`n))}" definition cf :: "[i,i]\i" where "cf(D,E) \ cont(D,E)*cont(D,E). \x \ set(D). rel(E,(fst(y))`x,(snd(y))`x)}>" definition suffix :: "[i,i]\i" where "suffix(X,n) \ \m \ nat. X`(n #+ m)" definition subchain :: "[i,i]\o" where "subchain(X,Y) \ \m \ nat. \n \ nat. X`m = Y`(m #+ n)" definition dominate :: "[i,i,i]\o" where "dominate(D,X,Y) \ \m \ nat. \n \ nat. rel(D,X`m,Y`n)" definition matrix :: "[i,i]\o" where "matrix(D,M) \ M \ nat -> (nat -> set(D)) \ (\n \ nat. \m \ nat. rel(D,M`n`m,M`succ(n)`m)) \ (\n \ nat. \m \ nat. rel(D,M`n`m,M`n`succ(m))) \ (\n \ nat. \m \ nat. rel(D,M`n`m,M`succ(n)`succ(m)))" definition projpair :: "[i,i,i,i]\o" where "projpair(D,E,e,p) \ e \ cont(D,E) \ p \ cont(E,D) \ p O e = id(set(D)) \ rel(cf(E,E),e O p,id(set(E)))" definition emb :: "[i,i,i]\o" where "emb(D,E,e) \ \p. projpair(D,E,e,p)" definition Rp :: "[i,i,i]\i" where "Rp(D,E,e) \ THE p. projpair(D,E,e,p)" definition (* Twice, constructions on cpos are more difficult. *) iprod :: "i\i" where "iprod(DD) \ <(\n \ nat. set(DD`n)), {x:(\n \ nat. set(DD`n))*(\n \ nat. set(DD`n)). \n \ nat. rel(DD`n,fst(x)`n,snd(x)`n)}>" definition mkcpo :: "[i,i\o]\i" where (* Cannot use rel(D), is meta fun, need two more args *) "mkcpo(D,P) \ <{x \ set(D). P(x)},{x \ set(D)*set(D). rel(D,fst(x),snd(x))}>" definition subcpo :: "[i,i]\o" where "subcpo(D,E) \ set(D) \ set(E) \ (\x \ set(D). \y \ set(D). rel(D,x,y) \ rel(E,x,y)) \ (\X. chain(D,X) \ lub(E,X):set(D))" definition subpcpo :: "[i,i]\o" where "subpcpo(D,E) \ subcpo(D,E) \ bot(E):set(D)" definition emb_chain :: "[i,i]\o" where "emb_chain(DD,ee) \ (\n \ nat. cpo(DD`n)) \ (\n \ nat. emb(DD`n,DD`succ(n),ee`n))" definition Dinf :: "[i,i]\i" where "Dinf(DD,ee) \ mkcpo(iprod(DD)) (\x. \n \ nat. Rp(DD`n,DD`succ(n),ee`n)`(x`succ(n)) = x`n)" definition e_less :: "[i,i,i,i]\i" where (* Valid for m \ n only. *) "e_less(DD,ee,m,n) \ rec(n#-m,id(set(DD`m)),\x y. ee`(m#+x) O y)" definition e_gr :: "[i,i,i,i]\i" where (* Valid for n \ m only. *) "e_gr(DD,ee,m,n) \ rec(m#-n,id(set(DD`n)), \x y. y O Rp(DD`(n#+x),DD`(succ(n#+x)),ee`(n#+x)))" definition eps :: "[i,i,i,i]\i" where "eps(DD,ee,m,n) \ if(m \ n,e_less(DD,ee,m,n),e_gr(DD,ee,m,n))" definition rho_emb :: "[i,i,i]\i" where "rho_emb(DD,ee,n) \ \x \ set(DD`n). \m \ nat. eps(DD,ee,n,m)`x" definition rho_proj :: "[i,i,i]\i" where "rho_proj(DD,ee,n) \ \x \ set(Dinf(DD,ee)). x`n" definition commute :: "[i,i,i,i\i]\o" where "commute(DD,ee,E,r) \ (\n \ nat. emb(DD`n,E,r(n))) \ (\m \ nat. \n \ nat. m \ n \ r(n) O eps(DD,ee,m,n) = r(m))" definition mediating :: "[i,i,i\i,i\i,i]\o" where "mediating(E,G,r,f,t) \ emb(E,G,t) \ (\n \ nat. f(n) = t O r(n))" lemmas nat_linear_le = Ord_linear_le [OF nat_into_Ord nat_into_Ord] (*----------------------------------------------------------------------*) (* Basic results. *) (*----------------------------------------------------------------------*) lemma set_I: "x \ fst(D) \ x \ set(D)" by (simp add: set_def) lemma rel_I: "\x,y\:snd(D) \ rel(D,x,y)" by (simp add: rel_def) lemma rel_E: "rel(D,x,y) \ \x,y\:snd(D)" by (simp add: rel_def) (*----------------------------------------------------------------------*) (* I/E/D rules for po and cpo. *) (*----------------------------------------------------------------------*) lemma po_refl: "\po(D); x \ set(D)\ \ rel(D,x,x)" by (unfold po_def, blast) lemma po_trans: "\po(D); rel(D,x,y); rel(D,y,z); x \ set(D); y \ set(D); z \ set(D)\ \ rel(D,x,z)" by (unfold po_def, blast) lemma po_antisym: "\po(D); rel(D,x,y); rel(D,y,x); x \ set(D); y \ set(D)\ \ x = y" by (unfold po_def, blast) lemma poI: "\\x. x \ set(D) \ rel(D,x,x); \x y z. \rel(D,x,y); rel(D,y,z); x \ set(D); y \ set(D); z \ set(D)\ \ rel(D,x,z); \x y. \rel(D,x,y); rel(D,y,x); x \ set(D); y \ set(D)\ \ x=y\ \ po(D)" by (unfold po_def, blast) lemma cpoI: "\po(D); \X. chain(D,X) \ islub(D,X,x(D,X))\ \ cpo(D)" by (simp add: cpo_def, blast) lemma cpo_po: "cpo(D) \ po(D)" by (simp add: cpo_def) lemma cpo_refl [simp,intro!,TC]: "\cpo(D); x \ set(D)\ \ rel(D,x,x)" by (blast intro: po_refl cpo_po) lemma cpo_trans: "\cpo(D); rel(D,x,y); rel(D,y,z); x \ set(D); y \ set(D); z \ set(D)\ \ rel(D,x,z)" by (blast intro: cpo_po po_trans) lemma cpo_antisym: "\cpo(D); rel(D,x,y); rel(D,y,x); x \ set(D); y \ set(D)\ \ x = y" by (blast intro: cpo_po po_antisym) lemma cpo_islub: "\cpo(D); chain(D,X); \x. islub(D,X,x) \ R\ \ R" by (simp add: cpo_def, blast) (*----------------------------------------------------------------------*) (* Theorems about isub and islub. *) (*----------------------------------------------------------------------*) lemma islub_isub: "islub(D,X,x) \ isub(D,X,x)" by (simp add: islub_def) lemma islub_in: "islub(D,X,x) \ x \ set(D)" by (simp add: islub_def isub_def) lemma islub_ub: "\islub(D,X,x); n \ nat\ \ rel(D,X`n,x)" by (simp add: islub_def isub_def) lemma islub_least: "\islub(D,X,x); isub(D,X,y)\ \ rel(D,x,y)" by (simp add: islub_def) lemma islubI: "\isub(D,X,x); \y. isub(D,X,y) \ rel(D,x,y)\ \ islub(D,X,x)" by (simp add: islub_def) lemma isubI: "\x \ set(D); \n. n \ nat \ rel(D,X`n,x)\ \ isub(D,X,x)" by (simp add: isub_def) lemma isubE: "\isub(D,X,x); \x \ set(D); \n. n \ nat\rel(D,X`n,x)\ \ P \ \ P" by (simp add: isub_def) lemma isubD1: "isub(D,X,x) \ x \ set(D)" by (simp add: isub_def) lemma isubD2: "\isub(D,X,x); n \ nat\\rel(D,X`n,x)" by (simp add: isub_def) lemma islub_unique: "\islub(D,X,x); islub(D,X,y); cpo(D)\ \ x = y" by (blast intro: cpo_antisym islub_least islub_isub islub_in) (*----------------------------------------------------------------------*) (* lub gives the least upper bound of chains. *) (*----------------------------------------------------------------------*) lemma cpo_lub: "\chain(D,X); cpo(D)\ \ islub(D,X,lub(D,X))" apply (simp add: lub_def) apply (best elim: cpo_islub intro: theI islub_unique) done (*----------------------------------------------------------------------*) (* Theorems about chains. *) (*----------------------------------------------------------------------*) lemma chainI: "\X \ nat->set(D); \n. n \ nat \ rel(D,X`n,X`succ(n))\ \ chain(D,X)" by (simp add: chain_def) lemma chain_fun: "chain(D,X) \ X \ nat -> set(D)" by (simp add: chain_def) lemma chain_in [simp,TC]: "\chain(D,X); n \ nat\ \ X`n \ set(D)" apply (simp add: chain_def) apply (blast dest: apply_type) done lemma chain_rel [simp,TC]: "\chain(D,X); n \ nat\ \ rel(D, X ` n, X ` succ(n))" by (simp add: chain_def) lemma chain_rel_gen_add: "\chain(D,X); cpo(D); n \ nat; m \ nat\ \ rel(D,X`n,(X`(m #+ n)))" apply (induct_tac m) apply (auto intro: cpo_trans) done lemma chain_rel_gen: "\n \ m; chain(D,X); cpo(D); m \ nat\ \ rel(D,X`n,X`m)" apply (frule lt_nat_in_nat, erule nat_succI) apply (erule rev_mp) (*prepare the induction*) apply (induct_tac m) apply (auto intro: cpo_trans simp add: le_iff) done (*----------------------------------------------------------------------*) (* Theorems about pcpos and bottom. *) (*----------------------------------------------------------------------*) lemma pcpoI: "\\y. y \ set(D)\rel(D,x,y); x \ set(D); cpo(D)\\pcpo(D)" by (simp add: pcpo_def, auto) lemma pcpo_cpo [TC]: "pcpo(D) \ cpo(D)" by (simp add: pcpo_def) lemma pcpo_bot_ex1: "pcpo(D) \ \! x. x \ set(D) \ (\y \ set(D). rel(D,x,y))" apply (simp add: pcpo_def) apply (blast intro: cpo_antisym) done lemma bot_least [TC]: "\pcpo(D); y \ set(D)\ \ rel(D,bot(D),y)" apply (simp add: bot_def) apply (best intro: pcpo_bot_ex1 [THEN theI2]) done lemma bot_in [TC]: "pcpo(D) \ bot(D):set(D)" apply (simp add: bot_def) apply (best intro: pcpo_bot_ex1 [THEN theI2]) done lemma bot_unique: "\pcpo(D); x \ set(D); \y. y \ set(D) \ rel(D,x,y)\ \ x = bot(D)" by (blast intro: cpo_antisym pcpo_cpo bot_in bot_least) (*----------------------------------------------------------------------*) (* Constant chains and lubs and cpos. *) (*----------------------------------------------------------------------*) lemma chain_const: "\x \ set(D); cpo(D)\ \ chain(D,(\n \ nat. x))" by (simp add: chain_def) lemma islub_const: "\x \ set(D); cpo(D)\ \ islub(D,(\n \ nat. x),x)" by (simp add: islub_def isub_def, blast) lemma lub_const: "\x \ set(D); cpo(D)\ \ lub(D,\n \ nat. x) = x" by (blast intro: islub_unique cpo_lub chain_const islub_const) (*----------------------------------------------------------------------*) (* Taking the suffix of chains has no effect on ub's. *) (*----------------------------------------------------------------------*) lemma isub_suffix: "\chain(D,X); cpo(D)\ \ isub(D,suffix(X,n),x) \ isub(D,X,x)" apply (simp add: isub_def suffix_def, safe) apply (drule_tac x = na in bspec) apply (auto intro: cpo_trans chain_rel_gen_add) done lemma islub_suffix: "\chain(D,X); cpo(D)\ \ islub(D,suffix(X,n),x) \ islub(D,X,x)" by (simp add: islub_def isub_suffix) lemma lub_suffix: "\chain(D,X); cpo(D)\ \ lub(D,suffix(X,n)) = lub(D,X)" by (simp add: lub_def islub_suffix) (*----------------------------------------------------------------------*) (* Dominate and subchain. *) (*----------------------------------------------------------------------*) lemma dominateI: "\\m. m \ nat \ n(m):nat; \m. m \ nat \ rel(D,X`m,Y`n(m))\ \ dominate(D,X,Y)" by (simp add: dominate_def, blast) lemma dominate_isub: "\dominate(D,X,Y); isub(D,Y,x); cpo(D); X \ nat->set(D); Y \ nat->set(D)\ \ isub(D,X,x)" apply (simp add: isub_def dominate_def) apply (blast intro: cpo_trans intro!: apply_funtype) done lemma dominate_islub: "\dominate(D,X,Y); islub(D,X,x); islub(D,Y,y); cpo(D); X \ nat->set(D); Y \ nat->set(D)\ \ rel(D,x,y)" apply (simp add: islub_def) apply (blast intro: dominate_isub) done lemma subchain_isub: "\subchain(Y,X); isub(D,X,x)\ \ isub(D,Y,x)" by (simp add: isub_def subchain_def, force) lemma dominate_islub_eq: "\dominate(D,X,Y); subchain(Y,X); islub(D,X,x); islub(D,Y,y); cpo(D); X \ nat->set(D); Y \ nat->set(D)\ \ x = y" by (blast intro: cpo_antisym dominate_islub islub_least subchain_isub islub_isub islub_in) (*----------------------------------------------------------------------*) (* Matrix. *) (*----------------------------------------------------------------------*) lemma matrix_fun: "matrix(D,M) \ M \ nat -> (nat -> set(D))" by (simp add: matrix_def) lemma matrix_in_fun: "\matrix(D,M); n \ nat\ \ M`n \ nat -> set(D)" by (blast intro: apply_funtype matrix_fun) lemma matrix_in: "\matrix(D,M); n \ nat; m \ nat\ \ M`n`m \ set(D)" by (blast intro: apply_funtype matrix_in_fun) lemma matrix_rel_1_0: "\matrix(D,M); n \ nat; m \ nat\ \ rel(D,M`n`m,M`succ(n)`m)" by (simp add: matrix_def) lemma matrix_rel_0_1: "\matrix(D,M); n \ nat; m \ nat\ \ rel(D,M`n`m,M`n`succ(m))" by (simp add: matrix_def) lemma matrix_rel_1_1: "\matrix(D,M); n \ nat; m \ nat\ \ rel(D,M`n`m,M`succ(n)`succ(m))" by (simp add: matrix_def) lemma fun_swap: "f \ X->Y->Z \ (\y \ Y. \x \ X. f`x`y):Y->X->Z" by (blast intro: lam_type apply_funtype) lemma matrix_sym_axis: "matrix(D,M) \ matrix(D,\m \ nat. \n \ nat. M`n`m)" by (simp add: matrix_def fun_swap) lemma matrix_chain_diag: "matrix(D,M) \ chain(D,\n \ nat. M`n`n)" apply (simp add: chain_def) apply (auto intro: lam_type matrix_in matrix_rel_1_1) done lemma matrix_chain_left: "\matrix(D,M); n \ nat\ \ chain(D,M`n)" -apply (unfold chain_def) + unfolding chain_def apply (auto intro: matrix_fun [THEN apply_type] matrix_in matrix_rel_0_1) done lemma matrix_chain_right: "\matrix(D,M); m \ nat\ \ chain(D,\n \ nat. M`n`m)" apply (simp add: chain_def) apply (auto intro: lam_type matrix_in matrix_rel_1_0) done lemma matrix_chainI: assumes xprem: "\x. x \ nat\chain(D,M`x)" and yprem: "\y. y \ nat\chain(D,\x \ nat. M`x`y)" and Mfun: "M \ nat->nat->set(D)" and cpoD: "cpo(D)" shows "matrix(D,M)" proof - { fix n m assume "n \ nat" "m \ nat" with chain_rel [OF yprem] have "rel(D, M ` n ` m, M ` succ(n) ` m)" by simp } note rel_succ = this show "matrix(D,M)" proof (simp add: matrix_def Mfun rel_succ, intro conjI ballI) fix n m assume n: "n \ nat" and m: "m \ nat" thus "rel(D, M ` n ` m, M ` n ` succ(m))" by (simp add: chain_rel xprem) next fix n m assume n: "n \ nat" and m: "m \ nat" thus "rel(D, M ` n ` m, M ` succ(n) ` succ(m))" by (rule cpo_trans [OF cpoD rel_succ], simp_all add: chain_fun [THEN apply_type] xprem) qed qed lemma lemma2: "\x \ nat; m \ nat; rel(D,(\n \ nat. M`n`m1)`x,(\n \ nat. M`n`m1)`m)\ \ rel(D,M`x`m1,M`m`m1)" by simp lemma isub_lemma: "\isub(D, \n \ nat. M`n`n, y); matrix(D,M); cpo(D)\ \ isub(D, \n \ nat. lub(D,\m \ nat. M`n`m), y)" proof (simp add: isub_def, safe) fix n assume DM: "matrix(D, M)" and D: "cpo(D)" and n: "n \ nat" and y: "y \ set(D)" and rel: "\n\nat. rel(D, M ` n ` n, y)" have "rel(D, lub(D, M ` n), y)" proof (rule matrix_chain_left [THEN cpo_lub, THEN islub_least], simp_all add: n D DM) show "isub(D, M ` n, y)" proof (unfold isub_def, intro conjI ballI y) fix k assume k: "k \ nat" show "rel(D, M ` n ` k, y)" proof (cases "n \ k") case True hence yy: "rel(D, M`n`k, M`k`k)" by (blast intro: lemma2 n k y DM D chain_rel_gen matrix_chain_right) show "?thesis" by (rule cpo_trans [OF D yy], simp_all add: k rel n y DM matrix_in) next case False hence le: "k \ n" by (blast intro: not_le_iff_lt [THEN iffD1, THEN leI] nat_into_Ord n k) show "?thesis" by (rule cpo_trans [OF D chain_rel_gen [OF le]], simp_all add: n y k rel DM D matrix_chain_left) qed qed qed moreover have "M ` n \ nat \ set(D)" by (blast intro: DM n matrix_fun [THEN apply_type]) ultimately show "rel(D, lub(D, Lambda(nat, (`)(M ` n))), y)" by simp qed lemma matrix_chain_lub: "\matrix(D,M); cpo(D)\ \ chain(D,\n \ nat. lub(D,\m \ nat. M`n`m))" proof (simp add: chain_def, intro conjI ballI) assume "matrix(D, M)" "cpo(D)" thus "(\x\nat. lub(D, Lambda(nat, (`)(M ` x)))) \ nat \ set(D)" by (force intro: islub_in cpo_lub chainI lam_type matrix_in matrix_rel_0_1) next fix n assume DD: "matrix(D, M)" "cpo(D)" "n \ nat" hence "dominate(D, M ` n, M ` succ(n))" by (force simp add: dominate_def intro: matrix_rel_1_0) with DD show "rel(D, lub(D, Lambda(nat, (`)(M ` n))), lub(D, Lambda(nat, (`)(M ` succ(n)))))" by (simp add: matrix_chain_left [THEN chain_fun, THEN eta] dominate_islub cpo_lub matrix_chain_left chain_fun) qed lemma isub_eq: assumes DM: "matrix(D, M)" and D: "cpo(D)" shows "isub(D,(\n \ nat. lub(D,\m \ nat. M`n`m)),y) \ isub(D,(\n \ nat. M`n`n),y)" proof assume isub: "isub(D, \n\nat. lub(D, Lambda(nat, (`)(M ` n))), y)" hence dom: "dominate(D, \n\nat. M ` n ` n, \n\nat. lub(D, Lambda(nat, (`)(M ` n))))" using DM D by (simp add: dominate_def, intro ballI bexI, simp_all add: matrix_chain_left [THEN chain_fun, THEN eta] islub_ub cpo_lub matrix_chain_left) thus "isub(D, \n\nat. M ` n ` n, y)" using DM D by - (rule dominate_isub [OF dom isub], simp_all add: matrix_chain_diag chain_fun matrix_chain_lub) next assume isub: "isub(D, \n\nat. M ` n ` n, y)" thus "isub(D, \n\nat. lub(D, Lambda(nat, (`)(M ` n))), y)" using DM D by (simp add: isub_lemma) qed lemma lub_matrix_diag_aux1: "lub(D,(\n \ nat. lub(D,\m \ nat. M`n`m))) = (THE x. islub(D, (\n \ nat. lub(D,\m \ nat. M`n`m)), x))" by (simp add: lub_def) lemma lub_matrix_diag_aux2: "lub(D,(\n \ nat. M`n`n)) = (THE x. islub(D, (\n \ nat. M`n`n), x))" by (simp add: lub_def) lemma lub_matrix_diag: "\matrix(D,M); cpo(D)\ \ lub(D,(\n \ nat. lub(D,\m \ nat. M`n`m))) = lub(D,(\n \ nat. M`n`n))" apply (simp (no_asm) add: lub_matrix_diag_aux1 lub_matrix_diag_aux2) apply (simp add: islub_def isub_eq) done lemma lub_matrix_diag_sym: "\matrix(D,M); cpo(D)\ \ lub(D,(\m \ nat. lub(D,\n \ nat. M`n`m))) = lub(D,(\n \ nat. M`n`n))" by (drule matrix_sym_axis [THEN lub_matrix_diag], auto) (*----------------------------------------------------------------------*) (* I/E/D rules for mono and cont. *) (*----------------------------------------------------------------------*) lemma monoI: "\f \ set(D)->set(E); \x y. \rel(D,x,y); x \ set(D); y \ set(D)\ \ rel(E,f`x,f`y)\ \ f \ mono(D,E)" by (simp add: mono_def) lemma mono_fun: "f \ mono(D,E) \ f \ set(D)->set(E)" by (simp add: mono_def) lemma mono_map: "\f \ mono(D,E); x \ set(D)\ \ f`x \ set(E)" by (blast intro!: mono_fun [THEN apply_type]) lemma mono_mono: "\f \ mono(D,E); rel(D,x,y); x \ set(D); y \ set(D)\ \ rel(E,f`x,f`y)" by (simp add: mono_def) lemma contI: "\f \ set(D)->set(E); \x y. \rel(D,x,y); x \ set(D); y \ set(D)\ \ rel(E,f`x,f`y); \X. chain(D,X) \ f`lub(D,X) = lub(E,\n \ nat. f`(X`n))\ \ f \ cont(D,E)" by (simp add: cont_def mono_def) lemma cont2mono: "f \ cont(D,E) \ f \ mono(D,E)" by (simp add: cont_def) lemma cont_fun [TC]: "f \ cont(D,E) \ f \ set(D)->set(E)" apply (simp add: cont_def) apply (rule mono_fun, blast) done lemma cont_map [TC]: "\f \ cont(D,E); x \ set(D)\ \ f`x \ set(E)" by (blast intro!: cont_fun [THEN apply_type]) declare comp_fun [TC] lemma cont_mono: "\f \ cont(D,E); rel(D,x,y); x \ set(D); y \ set(D)\ \ rel(E,f`x,f`y)" apply (simp add: cont_def) apply (blast intro!: mono_mono) done lemma cont_lub: "\f \ cont(D,E); chain(D,X)\ \ f`(lub(D,X)) = lub(E,\n \ nat. f`(X`n))" by (simp add: cont_def) (*----------------------------------------------------------------------*) (* Continuity and chains. *) (*----------------------------------------------------------------------*) lemma mono_chain: "\f \ mono(D,E); chain(D,X)\ \ chain(E,\n \ nat. f`(X`n))" apply (simp (no_asm) add: chain_def) apply (blast intro: lam_type mono_map chain_in mono_mono chain_rel) done lemma cont_chain: "\f \ cont(D,E); chain(D,X)\ \ chain(E,\n \ nat. f`(X`n))" by (blast intro: mono_chain cont2mono) (*----------------------------------------------------------------------*) (* I/E/D rules about (set+rel) cf, the continuous function space. *) (*----------------------------------------------------------------------*) (* The following development more difficult with cpo-as-relation approach. *) lemma cf_cont: "f \ set(cf(D,E)) \ f \ cont(D,E)" by (simp add: set_def cf_def) lemma cont_cf: (* Non-trivial with relation *) "f \ cont(D,E) \ f \ set(cf(D,E))" by (simp add: set_def cf_def) (* rel_cf originally an equality. Now stated as two rules. Seemed easiest. *) lemma rel_cfI: "\\x. x \ set(D) \ rel(E,f`x,g`x); f \ cont(D,E); g \ cont(D,E)\ \ rel(cf(D,E),f,g)" by (simp add: rel_I cf_def) lemma rel_cf: "\rel(cf(D,E),f,g); x \ set(D)\ \ rel(E,f`x,g`x)" by (simp add: rel_def cf_def) (*----------------------------------------------------------------------*) (* Theorems about the continuous function space. *) (*----------------------------------------------------------------------*) lemma chain_cf: "\chain(cf(D,E),X); x \ set(D)\ \ chain(E,\n \ nat. X`n`x)" apply (rule chainI) apply (blast intro: lam_type apply_funtype cont_fun cf_cont chain_in, simp) apply (blast intro: rel_cf chain_rel) done lemma matrix_lemma: "\chain(cf(D,E),X); chain(D,Xa); cpo(D); cpo(E)\ \ matrix(E,\x \ nat. \xa \ nat. X`x`(Xa`xa))" apply (rule matrix_chainI, auto) apply (force intro: chainI lam_type apply_funtype cont_fun cf_cont cont_mono) apply (force intro: chainI lam_type apply_funtype cont_fun cf_cont rel_cf) apply (blast intro: lam_type apply_funtype cont_fun cf_cont chain_in) done lemma chain_cf_lub_cont: assumes ch: "chain(cf(D,E),X)" and D: "cpo(D)" and E: "cpo(E)" shows "(\x \ set(D). lub(E, \n \ nat. X ` n ` x)) \ cont(D, E)" proof (rule contI) show "(\x\set(D). lub(E, \n\nat. X ` n ` x)) \ set(D) \ set(E)" by (blast intro: lam_type chain_cf [THEN cpo_lub, THEN islub_in] ch E) next fix x y assume xy: "rel(D, x, y)" "x \ set(D)" "y \ set(D)" hence dom: "dominate(E, \n\nat. X ` n ` x, \n\nat. X ` n ` y)" by (force intro: dominateI chain_in [OF ch, THEN cf_cont, THEN cont_mono]) note chE = chain_cf [OF ch] from xy show "rel(E, (\x\set(D). lub(E, \n\nat. X ` n ` x)) ` x, (\x\set(D). lub(E, \n\nat. X ` n ` x)) ` y)" by (simp add: dominate_islub [OF dom] cpo_lub [OF chE] E chain_fun [OF chE]) next fix Y assume chDY: "chain(D,Y)" have "lub(E, \x\nat. lub(E, \y\nat. X ` x ` (Y ` y))) = lub(E, \x\nat. X ` x ` (Y ` x))" using matrix_lemma [THEN lub_matrix_diag, OF ch chDY] by (simp add: D E) also have "... = lub(E, \x\nat. lub(E, \n\nat. X ` n ` (Y ` x)))" using matrix_lemma [THEN lub_matrix_diag_sym, OF ch chDY] by (simp add: D E) finally have "lub(E, \x\nat. lub(E, \n\nat. X ` x ` (Y ` n))) = lub(E, \x\nat. lub(E, \n\nat. X ` n ` (Y ` x)))" . thus "(\x\set(D). lub(E, \n\nat. X ` n ` x)) ` lub(D, Y) = lub(E, \n\nat. (\x\set(D). lub(E, \n\nat. X ` n ` x)) ` (Y ` n))" by (simp add: cpo_lub [THEN islub_in] D chDY chain_in [THEN cf_cont, THEN cont_lub, OF ch]) qed lemma islub_cf: "\chain(cf(D,E),X); cpo(D); cpo(E)\ \ islub(cf(D,E), X, \x \ set(D). lub(E,\n \ nat. X`n`x))" apply (rule islubI) apply (rule isubI) apply (rule chain_cf_lub_cont [THEN cont_cf], assumption+) apply (rule rel_cfI) apply (force dest!: chain_cf [THEN cpo_lub, THEN islub_ub]) apply (blast intro: cf_cont chain_in) apply (blast intro: cont_cf chain_cf_lub_cont) apply (rule rel_cfI, simp) apply (force intro: chain_cf [THEN cpo_lub, THEN islub_least] cf_cont [THEN cont_fun, THEN apply_type] isubI elim: isubD2 [THEN rel_cf] isubD1) apply (blast intro: chain_cf_lub_cont isubD1 cf_cont)+ done lemma cpo_cf [TC]: "\cpo(D); cpo(E)\ \ cpo(cf(D,E))" apply (rule poI [THEN cpoI]) apply (rule rel_cfI) apply (assumption | rule cpo_refl cf_cont [THEN cont_fun, THEN apply_type] cf_cont)+ apply (rule rel_cfI) apply (rule cpo_trans, assumption) apply (erule rel_cf, assumption) apply (rule rel_cf, assumption) apply (assumption | rule cf_cont [THEN cont_fun, THEN apply_type] cf_cont)+ apply (rule fun_extension) apply (assumption | rule cf_cont [THEN cont_fun])+ apply (blast intro: cpo_antisym rel_cf cf_cont [THEN cont_fun, THEN apply_type]) apply (fast intro: islub_cf) done lemma lub_cf: "\chain(cf(D,E),X); cpo(D); cpo(E)\ \ lub(cf(D,E), X) = (\x \ set(D). lub(E,\n \ nat. X`n`x))" by (blast intro: islub_unique cpo_lub islub_cf cpo_cf) lemma const_cont [TC]: "\y \ set(E); cpo(D); cpo(E)\ \ (\x \ set(D).y) \ cont(D,E)" apply (rule contI) prefer 2 apply simp apply (blast intro: lam_type) apply (simp add: chain_in cpo_lub [THEN islub_in] lub_const) done lemma cf_least: "\cpo(D); pcpo(E); y \ cont(D,E)\\rel(cf(D,E),(\x \ set(D).bot(E)),y)" apply (rule rel_cfI, simp, typecheck) done lemma pcpo_cf: "\cpo(D); pcpo(E)\ \ pcpo(cf(D,E))" apply (rule pcpoI) apply (assumption | rule cf_least bot_in const_cont [THEN cont_cf] cf_cont cpo_cf pcpo_cpo)+ done lemma bot_cf: "\cpo(D); pcpo(E)\ \ bot(cf(D,E)) = (\x \ set(D).bot(E))" by (blast intro: bot_unique [symmetric] pcpo_cf cf_least bot_in [THEN const_cont, THEN cont_cf] cf_cont pcpo_cpo) (*----------------------------------------------------------------------*) (* Identity and composition. *) (*----------------------------------------------------------------------*) lemma id_cont [TC,intro!]: "cpo(D) \ id(set(D)) \ cont(D,D)" by (simp add: id_type contI cpo_lub [THEN islub_in] chain_fun [THEN eta]) lemmas comp_cont_apply = cont_fun [THEN comp_fun_apply] lemma comp_pres_cont [TC]: "\f \ cont(D',E); g \ cont(D,D'); cpo(D)\ \ f O g \ cont(D,E)" apply (rule contI) apply (rule_tac [2] comp_cont_apply [THEN ssubst]) apply (rule_tac [4] comp_cont_apply [THEN ssubst]) apply (rule_tac [6] cont_mono) apply (rule_tac [7] cont_mono) (* 13 subgoals *) apply typecheck (* proves all but the lub case *) apply (subst comp_cont_apply) apply (rule_tac [3] cont_lub [THEN ssubst]) apply (rule_tac [5] cont_lub [THEN ssubst]) prefer 7 apply (simp add: comp_cont_apply chain_in) apply (auto intro: cpo_lub [THEN islub_in] cont_chain) done lemma comp_mono: "\f \ cont(D',E); g \ cont(D,D'); f':cont(D',E); g':cont(D,D'); rel(cf(D',E),f,f'); rel(cf(D,D'),g,g'); cpo(D); cpo(E)\ \ rel(cf(D,E),f O g,f' O g')" apply (rule rel_cfI) apply (subst comp_cont_apply) apply (rule_tac [3] comp_cont_apply [THEN ssubst]) apply (rule_tac [5] cpo_trans) apply (assumption | rule rel_cf cont_mono cont_map comp_pres_cont)+ done lemma chain_cf_comp: "\chain(cf(D',E),X); chain(cf(D,D'),Y); cpo(D); cpo(E)\ \ chain(cf(D,E),\n \ nat. X`n O Y`n)" apply (rule chainI) defer 1 apply simp apply (rule rel_cfI) apply (rule comp_cont_apply [THEN ssubst]) apply (rule_tac [3] comp_cont_apply [THEN ssubst]) apply (rule_tac [5] cpo_trans) apply (rule_tac [6] rel_cf) apply (rule_tac [8] cont_mono) apply (blast intro: lam_type comp_pres_cont cont_cf chain_in [THEN cf_cont] cont_map chain_rel rel_cf)+ done lemma comp_lubs: "\chain(cf(D',E),X); chain(cf(D,D'),Y); cpo(D); cpo(D'); cpo(E)\ \ lub(cf(D',E),X) O lub(cf(D,D'),Y) = lub(cf(D,E),\n \ nat. X`n O Y`n)" apply (rule fun_extension) apply (rule_tac [3] lub_cf [THEN ssubst]) apply (assumption | rule comp_fun cf_cont [THEN cont_fun] cpo_lub [THEN islub_in] cpo_cf chain_cf_comp)+ apply (simp add: chain_in [THEN cf_cont, THEN comp_cont_apply]) apply (subst comp_cont_apply) apply (assumption | rule cpo_lub [THEN islub_in, THEN cf_cont] cpo_cf)+ apply (simp add: lub_cf chain_cf chain_in [THEN cf_cont, THEN cont_lub] chain_cf [THEN cpo_lub, THEN islub_in]) apply (cut_tac M = "\xa \ nat. \xb \ nat. X`xa` (Y`xb`x)" in lub_matrix_diag) prefer 3 apply simp apply (rule matrix_chainI, simp_all) apply (drule chain_in [THEN cf_cont], assumption) apply (force dest: cont_chain [OF _ chain_cf]) apply (rule chain_cf) apply (assumption | rule cont_fun [THEN apply_type] chain_in [THEN cf_cont] lam_type)+ done (*----------------------------------------------------------------------*) (* Theorems about projpair. *) (*----------------------------------------------------------------------*) lemma projpairI: "\e \ cont(D,E); p \ cont(E,D); p O e = id(set(D)); rel(cf(E,E))(e O p)(id(set(E)))\ \ projpair(D,E,e,p)" by (simp add: projpair_def) lemma projpair_e_cont: "projpair(D,E,e,p) \ e \ cont(D,E)" by (simp add: projpair_def) lemma projpair_p_cont: "projpair(D,E,e,p) \ p \ cont(E,D)" by (simp add: projpair_def) lemma projpair_ep_cont: "projpair(D,E,e,p) \ e \ cont(D,E) \ p \ cont(E,D)" by (simp add: projpair_def) lemma projpair_eq: "projpair(D,E,e,p) \ p O e = id(set(D))" by (simp add: projpair_def) lemma projpair_rel: "projpair(D,E,e,p) \ rel(cf(E,E))(e O p)(id(set(E)))" by (simp add: projpair_def) (*----------------------------------------------------------------------*) (* NB! projpair_e_cont and projpair_p_cont cannot be used repeatedly *) (* at the same time since both match a goal of the form f \ cont(X,Y).*) (*----------------------------------------------------------------------*) (*----------------------------------------------------------------------*) (* Uniqueness of embedding projection pairs. *) (*----------------------------------------------------------------------*) lemmas id_comp = fun_is_rel [THEN left_comp_id] and comp_id = fun_is_rel [THEN right_comp_id] lemma projpair_unique_aux1: "\cpo(D); cpo(E); projpair(D,E,e,p); projpair(D,E,e',p'); rel(cf(D,E),e,e')\ \ rel(cf(E,D),p',p)" apply (rule_tac b=p' in projpair_p_cont [THEN cont_fun, THEN id_comp, THEN subst], assumption) apply (rule projpair_eq [THEN subst], assumption) apply (rule cpo_trans) apply (assumption | rule cpo_cf)+ (* The following corresponds to EXISTS_TAC, non-trivial instantiation. *) apply (rule_tac [4] f = "p O (e' O p')" in cont_cf) apply (subst comp_assoc) apply (blast intro: cpo_cf cont_cf comp_mono comp_pres_cont dest: projpair_ep_cont) apply (rule_tac P = "\x. rel (cf (E,D),p O e' O p',x)" in projpair_p_cont [THEN cont_fun, THEN comp_id, THEN subst], assumption) apply (rule comp_mono) apply (blast intro: cpo_cf cont_cf comp_pres_cont projpair_rel dest: projpair_ep_cont)+ done text\Proof's very like the previous one. Is there a pattern that could be exploited?\ lemma projpair_unique_aux2: "\cpo(D); cpo(E); projpair(D,E,e,p); projpair(D,E,e',p'); rel(cf(E,D),p',p)\ \ rel(cf(D,E),e,e')" apply (rule_tac b=e in projpair_e_cont [THEN cont_fun, THEN comp_id, THEN subst], assumption) apply (rule_tac e1=e' in projpair_eq [THEN subst], assumption) apply (rule cpo_trans) apply (assumption | rule cpo_cf)+ apply (rule_tac [4] f = "(e O p) O e'" in cont_cf) apply (subst comp_assoc) apply (blast intro: cpo_cf cont_cf comp_mono comp_pres_cont dest: projpair_ep_cont) apply (rule_tac P = "\x. rel (cf (D,E), (e O p) O e',x)" in projpair_e_cont [THEN cont_fun, THEN id_comp, THEN subst], assumption) apply (blast intro: cpo_cf cont_cf comp_pres_cont projpair_rel comp_mono dest: projpair_ep_cont)+ done lemma projpair_unique: "\cpo(D); cpo(E); projpair(D,E,e,p); projpair(D,E,e',p')\ \ (e=e')\(p=p')" by (blast intro: cpo_antisym projpair_unique_aux1 projpair_unique_aux2 cpo_cf cont_cf dest: projpair_ep_cont) (* Slightly different, more asms, since THE chooses the unique element. *) lemma embRp: "\emb(D,E,e); cpo(D); cpo(E)\ \ projpair(D,E,e,Rp(D,E,e))" apply (simp add: emb_def Rp_def) apply (blast intro: theI2 projpair_unique [THEN iffD1]) done lemma embI: "projpair(D,E,e,p) \ emb(D,E,e)" by (simp add: emb_def, auto) lemma Rp_unique: "\projpair(D,E,e,p); cpo(D); cpo(E)\ \ Rp(D,E,e) = p" by (blast intro: embRp embI projpair_unique [THEN iffD1]) lemma emb_cont [TC]: "emb(D,E,e) \ e \ cont(D,E)" apply (simp add: emb_def) apply (blast intro: projpair_e_cont) done (* The following three theorems have cpo asms due to THE (uniqueness). *) lemmas Rp_cont [TC] = embRp [THEN projpair_p_cont] lemmas embRp_eq = embRp [THEN projpair_eq] lemmas embRp_rel = embRp [THEN projpair_rel] lemma embRp_eq_thm: "\emb(D,E,e); x \ set(D); cpo(D); cpo(E)\ \ Rp(D,E,e)`(e`x) = x" apply (rule comp_fun_apply [THEN subst]) apply (assumption | rule Rp_cont emb_cont cont_fun)+ apply (subst embRp_eq) apply (auto intro: id_conv) done (*----------------------------------------------------------------------*) (* The identity embedding. *) (*----------------------------------------------------------------------*) lemma projpair_id: "cpo(D) \ projpair(D,D,id(set(D)),id(set(D)))" apply (simp add: projpair_def) apply (blast intro: cpo_cf cont_cf) done lemma emb_id: "cpo(D) \ emb(D,D,id(set(D)))" by (auto intro: embI projpair_id) lemma Rp_id: "cpo(D) \ Rp(D,D,id(set(D))) = id(set(D))" by (auto intro: Rp_unique projpair_id) (*----------------------------------------------------------------------*) (* Composition preserves embeddings. *) (*----------------------------------------------------------------------*) (* Considerably shorter, only partly due to a simpler comp_assoc. *) (* Proof in HOL-ST: 70 lines (minus 14 due to comp_assoc complication). *) (* Proof in Isa/ZF: 23 lines (compared to 56: 60% reduction). *) lemma comp_lemma: "\emb(D,D',e); emb(D',E,e'); cpo(D); cpo(D'); cpo(E)\ \ projpair(D,E,e' O e,(Rp(D,D',e)) O (Rp(D',E,e')))" apply (simp add: projpair_def, safe) apply (assumption | rule comp_pres_cont Rp_cont emb_cont)+ apply (rule comp_assoc [THEN subst]) apply (rule_tac t1 = e' in comp_assoc [THEN ssubst]) apply (subst embRp_eq) (* Matches everything due to subst/ssubst. *) apply assumption+ apply (subst comp_id) apply (assumption | rule cont_fun Rp_cont embRp_eq)+ apply (rule comp_assoc [THEN subst]) apply (rule_tac t1 = "Rp (D,D',e)" in comp_assoc [THEN ssubst]) apply (rule cpo_trans) apply (assumption | rule cpo_cf)+ apply (rule comp_mono) apply (rule_tac [6] cpo_refl) apply (erule_tac [7] asm_rl | rule_tac [7] cont_cf Rp_cont)+ prefer 6 apply (blast intro: cpo_cf) apply (rule_tac [5] comp_mono) apply (rule_tac [10] embRp_rel) apply (rule_tac [9] cpo_cf [THEN cpo_refl]) apply (simp_all add: comp_id embRp_rel comp_pres_cont Rp_cont id_cont emb_cont cont_fun cont_cf) done (* The use of THEN is great in places like the following, both ugly in HOL. *) lemmas emb_comp = comp_lemma [THEN embI] lemmas Rp_comp = comp_lemma [THEN Rp_unique] (*----------------------------------------------------------------------*) (* Infinite cartesian product. *) (*----------------------------------------------------------------------*) lemma iprodI: "x:(\n \ nat. set(DD`n)) \ x \ set(iprod(DD))" by (simp add: set_def iprod_def) lemma iprodE: "x \ set(iprod(DD)) \ x:(\n \ nat. set(DD`n))" by (simp add: set_def iprod_def) (* Contains typing conditions in contrast to HOL-ST *) lemma rel_iprodI: "\\n. n \ nat \ rel(DD`n,f`n,g`n); f:(\n \ nat. set(DD`n)); g:(\n \ nat. set(DD`n))\ \ rel(iprod(DD),f,g)" by (simp add: iprod_def rel_I) lemma rel_iprodE: "\rel(iprod(DD),f,g); n \ nat\ \ rel(DD`n,f`n,g`n)" by (simp add: iprod_def rel_def) lemma chain_iprod: "\chain(iprod(DD),X); \n. n \ nat \ cpo(DD`n); n \ nat\ \ chain(DD`n,\m \ nat. X`m`n)" apply (unfold chain_def, safe) apply (rule lam_type) apply (rule apply_type) apply (rule iprodE) apply (blast intro: apply_funtype, assumption) apply (simp add: rel_iprodE) done lemma islub_iprod: "\chain(iprod(DD),X); \n. n \ nat \ cpo(DD`n)\ \ islub(iprod(DD),X,\n \ nat. lub(DD`n,\m \ nat. X`m`n))" apply (simp add: islub_def isub_def, safe) apply (rule iprodI) apply (blast intro: lam_type chain_iprod [THEN cpo_lub, THEN islub_in]) apply (rule rel_iprodI, simp) (*looks like something should be inserted into the assumptions!*) apply (rule_tac P = "\t. rel (DD`na,t,lub (DD`na,\x \ nat. X`x`na))" and b1 = "\n. X`n`na" in beta [THEN subst]) apply (simp del: beta_if add: chain_iprod [THEN cpo_lub, THEN islub_ub] iprodE chain_in)+ apply (blast intro: iprodI lam_type chain_iprod [THEN cpo_lub, THEN islub_in]) apply (rule rel_iprodI) apply (simp | rule islub_least chain_iprod [THEN cpo_lub])+ apply (simp add: isub_def, safe) apply (erule iprodE [THEN apply_type]) apply (simp_all add: rel_iprodE lam_type iprodE chain_iprod [THEN cpo_lub, THEN islub_in]) done lemma cpo_iprod [TC]: "(\n. n \ nat \ cpo(DD`n)) \ cpo(iprod(DD))" apply (assumption | rule cpoI poI)+ apply (rule rel_iprodI) (*not repeated: want to solve 1, leave 2 unchanged *) apply (simp | rule cpo_refl iprodE [THEN apply_type] iprodE)+ apply (rule rel_iprodI) apply (drule rel_iprodE) apply (drule_tac [2] rel_iprodE) apply (simp | rule cpo_trans iprodE [THEN apply_type] iprodE)+ apply (rule fun_extension) apply (blast intro: iprodE) apply (blast intro: iprodE) apply (blast intro: cpo_antisym rel_iprodE iprodE [THEN apply_type])+ apply (auto intro: islub_iprod) done lemma lub_iprod: "\chain(iprod(DD),X); \n. n \ nat \ cpo(DD`n)\ \ lub(iprod(DD),X) = (\n \ nat. lub(DD`n,\m \ nat. X`m`n))" by (blast intro: cpo_lub [THEN islub_unique] islub_iprod cpo_iprod) (*----------------------------------------------------------------------*) (* The notion of subcpo. *) (*----------------------------------------------------------------------*) lemma subcpoI: "\set(D)<=set(E); \x y. \x \ set(D); y \ set(D)\ \ rel(D,x,y)\rel(E,x,y); \X. chain(D,X) \ lub(E,X) \ set(D)\ \ subcpo(D,E)" by (simp add: subcpo_def) lemma subcpo_subset: "subcpo(D,E) \ set(D)<=set(E)" by (simp add: subcpo_def) lemma subcpo_rel_eq: "\subcpo(D,E); x \ set(D); y \ set(D)\ \ rel(D,x,y)\rel(E,x,y)" by (simp add: subcpo_def) lemmas subcpo_relD1 = subcpo_rel_eq [THEN iffD1] lemmas subcpo_relD2 = subcpo_rel_eq [THEN iffD2] lemma subcpo_lub: "\subcpo(D,E); chain(D,X)\ \ lub(E,X) \ set(D)" by (simp add: subcpo_def) lemma chain_subcpo: "\subcpo(D,E); chain(D,X)\ \ chain(E,X)" by (blast intro: Pi_type [THEN chainI] chain_fun subcpo_relD1 subcpo_subset [THEN subsetD] chain_in chain_rel) lemma ub_subcpo: "\subcpo(D,E); chain(D,X); isub(D,X,x)\ \ isub(E,X,x)" by (blast intro: isubI subcpo_relD1 subcpo_relD1 chain_in isubD1 isubD2 subcpo_subset [THEN subsetD] chain_in chain_rel) lemma islub_subcpo: "\subcpo(D,E); cpo(E); chain(D,X)\ \ islub(D,X,lub(E,X))" by (blast intro: islubI isubI subcpo_lub subcpo_relD2 chain_in islub_ub islub_least cpo_lub chain_subcpo isubD1 ub_subcpo) lemma subcpo_cpo: "\subcpo(D,E); cpo(E)\ \ cpo(D)" apply (assumption | rule cpoI poI)+ apply (simp add: subcpo_rel_eq) apply (assumption | rule cpo_refl subcpo_subset [THEN subsetD])+ apply (simp add: subcpo_rel_eq) apply (blast intro: subcpo_subset [THEN subsetD] cpo_trans) apply (simp add: subcpo_rel_eq) apply (blast intro: cpo_antisym subcpo_subset [THEN subsetD]) apply (fast intro: islub_subcpo) done lemma lub_subcpo: "\subcpo(D,E); cpo(E); chain(D,X)\ \ lub(D,X) = lub(E,X)" by (blast intro: cpo_lub [THEN islub_unique] islub_subcpo subcpo_cpo) (*----------------------------------------------------------------------*) (* Making subcpos using mkcpo. *) (*----------------------------------------------------------------------*) lemma mkcpoI: "\x \ set(D); P(x)\ \ x \ set(mkcpo(D,P))" by (simp add: set_def mkcpo_def) lemma mkcpoD1: "x \ set(mkcpo(D,P))\ x \ set(D)" by (simp add: set_def mkcpo_def) lemma mkcpoD2: "x \ set(mkcpo(D,P))\ P(x)" by (simp add: set_def mkcpo_def) lemma rel_mkcpoE: "rel(mkcpo(D,P),x,y) \ rel(D,x,y)" by (simp add: rel_def mkcpo_def) lemma rel_mkcpo: "\x \ set(D); y \ set(D)\ \ rel(mkcpo(D,P),x,y) \ rel(D,x,y)" by (simp add: mkcpo_def rel_def set_def) lemma chain_mkcpo: "chain(mkcpo(D,P),X) \ chain(D,X)" apply (rule chainI) apply (blast intro: Pi_type chain_fun chain_in [THEN mkcpoD1]) apply (blast intro: rel_mkcpo [THEN iffD1] chain_rel mkcpoD1 chain_in) done lemma subcpo_mkcpo: "\\X. chain(mkcpo(D,P),X) \ P(lub(D,X)); cpo(D)\ \ subcpo(mkcpo(D,P),D)" apply (intro subcpoI subsetI rel_mkcpo) apply (erule mkcpoD1)+ apply (blast intro: mkcpoI cpo_lub [THEN islub_in] chain_mkcpo) done (*----------------------------------------------------------------------*) (* Embedding projection chains of cpos. *) (*----------------------------------------------------------------------*) lemma emb_chainI: "\\n. n \ nat \ cpo(DD`n); \n. n \ nat \ emb(DD`n,DD`succ(n),ee`n)\ \ emb_chain(DD,ee)" by (simp add: emb_chain_def) lemma emb_chain_cpo [TC]: "\emb_chain(DD,ee); n \ nat\ \ cpo(DD`n)" by (simp add: emb_chain_def) lemma emb_chain_emb: "\emb_chain(DD,ee); n \ nat\ \ emb(DD`n,DD`succ(n),ee`n)" by (simp add: emb_chain_def) (*----------------------------------------------------------------------*) (* Dinf, the inverse Limit. *) (*----------------------------------------------------------------------*) lemma DinfI: "\x:(\n \ nat. set(DD`n)); \n. n \ nat \ Rp(DD`n,DD`succ(n),ee`n)`(x`succ(n)) = x`n\ \ x \ set(Dinf(DD,ee))" apply (simp add: Dinf_def) apply (blast intro: mkcpoI iprodI) done lemma Dinf_prod: "x \ set(Dinf(DD,ee)) \ x:(\n \ nat. set(DD`n))" apply (simp add: Dinf_def) apply (erule mkcpoD1 [THEN iprodE]) done lemma Dinf_eq: "\x \ set(Dinf(DD,ee)); n \ nat\ \ Rp(DD`n,DD`succ(n),ee`n)`(x`succ(n)) = x`n" apply (simp add: Dinf_def) apply (blast dest: mkcpoD2) done lemma rel_DinfI: "\\n. n \ nat \ rel(DD`n,x`n,y`n); x:(\n \ nat. set(DD`n)); y:(\n \ nat. set(DD`n))\ \ rel(Dinf(DD,ee),x,y)" apply (simp add: Dinf_def) apply (blast intro: rel_mkcpo [THEN iffD2] rel_iprodI iprodI) done lemma rel_Dinf: "\rel(Dinf(DD,ee),x,y); n \ nat\ \ rel(DD`n,x`n,y`n)" apply (simp add: Dinf_def) apply (erule rel_mkcpoE [THEN rel_iprodE], assumption) done lemma chain_Dinf: "chain(Dinf(DD,ee),X) \ chain(iprod(DD),X)" apply (simp add: Dinf_def) apply (erule chain_mkcpo) done lemma subcpo_Dinf: "emb_chain(DD,ee) \ subcpo(Dinf(DD,ee),iprod(DD))" apply (simp add: Dinf_def) apply (rule subcpo_mkcpo) apply (simp add: Dinf_def [symmetric]) apply (rule ballI) apply (simplesubst lub_iprod) \ \Subst would rewrite the lhs. We want to change the rhs.\ apply (assumption | rule chain_Dinf emb_chain_cpo)+ apply simp apply (subst Rp_cont [THEN cont_lub]) apply (assumption | rule emb_chain_cpo emb_chain_emb nat_succI chain_iprod chain_Dinf)+ (* Useful simplification, ugly in HOL. *) apply (simp add: Dinf_eq chain_in) apply (auto intro: cpo_iprod emb_chain_cpo) done (* Simple example of existential reasoning in Isabelle versus HOL. *) lemma cpo_Dinf: "emb_chain(DD,ee) \ cpo(Dinf(DD,ee))" apply (rule subcpo_cpo) apply (erule subcpo_Dinf) apply (auto intro: cpo_iprod emb_chain_cpo) done (* Again and again the proofs are much easier to WRITE in Isabelle, but the proof steps are essentially the same (I think). *) lemma lub_Dinf: "\chain(Dinf(DD,ee),X); emb_chain(DD,ee)\ \ lub(Dinf(DD,ee),X) = (\n \ nat. lub(DD`n,\m \ nat. X`m`n))" apply (subst subcpo_Dinf [THEN lub_subcpo]) apply (auto intro: cpo_iprod emb_chain_cpo lub_iprod chain_Dinf) done (*----------------------------------------------------------------------*) (* Generalising embedddings D_m -> D_{m+1} to embeddings D_m -> D_n, *) (* defined as eps(DD,ee,m,n), via e_less and e_gr. *) (*----------------------------------------------------------------------*) lemma e_less_eq: "m \ nat \ e_less(DD,ee,m,m) = id(set(DD`m))" by (simp add: e_less_def) lemma lemma_succ_sub: "succ(m#+n)#-m = succ(natify(n))" by simp lemma e_less_add: "e_less(DD,ee,m,succ(m#+k)) = (ee`(m#+k))O(e_less(DD,ee,m,m#+k))" by (simp add: e_less_def) lemma le_exists: "\m \ n; \x. \n=m#+x; x \ nat\ \ Q; n \ nat\ \ Q" apply (drule less_imp_succ_add, auto) done lemma e_less_le: "\m \ n; n \ nat\ \ e_less(DD,ee,m,succ(n)) = ee`n O e_less(DD,ee,m,n)" apply (rule le_exists, assumption) apply (simp add: e_less_add, assumption) done (* All theorems assume variables m and n are natural numbers. *) lemma e_less_succ: "m \ nat \ e_less(DD,ee,m,succ(m)) = ee`m O id(set(DD`m))" by (simp add: e_less_le e_less_eq) lemma e_less_succ_emb: "\\n. n \ nat \ emb(DD`n,DD`succ(n),ee`n); m \ nat\ \ e_less(DD,ee,m,succ(m)) = ee`m" apply (simp add: e_less_succ) apply (blast intro: emb_cont cont_fun comp_id) done (* Compare this proof with the HOL one, here we do type checking. *) (* In any case the one below was very easy to write. *) lemma emb_e_less_add: "\emb_chain(DD,ee); m \ nat\ \ emb(DD`m, DD`(m#+k), e_less(DD,ee,m,m#+k))" apply (subgoal_tac "emb (DD`m, DD` (m#+natify (k)), e_less (DD,ee,m,m#+natify (k))) ") apply (rule_tac [2] n = "natify (k) " in nat_induct) apply (simp_all add: e_less_eq) apply (assumption | rule emb_id emb_chain_cpo)+ apply (simp add: e_less_add) apply (auto intro: emb_comp emb_chain_emb emb_chain_cpo) done lemma emb_e_less: "\m \ n; emb_chain(DD,ee); n \ nat\ \ emb(DD`m, DD`n, e_less(DD,ee,m,n))" apply (frule lt_nat_in_nat) apply (erule nat_succI) (* same proof as e_less_le *) apply (rule le_exists, assumption) apply (simp add: emb_e_less_add, assumption) done lemma comp_mono_eq: "\f=f'; g=g'\ \ f O g = f' O g'" by simp (* Note the object-level implication for induction on k. This must be removed later to allow the theorems to be used for simp. Therefore this theorem is only a lemma. *) lemma e_less_split_add_lemma [rule_format]: "\emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ n \ k \ e_less(DD,ee,m,m#+k) = e_less(DD,ee,m#+n,m#+k) O e_less(DD,ee,m,m#+n)" apply (induct_tac k) apply (simp add: e_less_eq id_type [THEN id_comp]) apply (simp add: le_succ_iff) apply (rule impI) apply (erule disjE) apply (erule impE, assumption) apply (simp add: e_less_add) apply (subst e_less_le) apply (assumption | rule add_le_mono nat_le_refl add_type nat_succI)+ apply (subst comp_assoc) apply (assumption | rule comp_mono_eq refl)+ apply (simp del: add_succ_right add: add_succ_right [symmetric] add: e_less_eq add_type nat_succI) apply (subst id_comp) (* simp cannot unify/inst right, use brr below (?) . *) apply (assumption | rule emb_e_less_add [THEN emb_cont, THEN cont_fun] refl nat_succI)+ done lemma e_less_split_add: "\n \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ e_less(DD,ee,m,m#+k) = e_less(DD,ee,m#+n,m#+k) O e_less(DD,ee,m,m#+n)" by (blast intro: e_less_split_add_lemma) lemma e_gr_eq: "m \ nat \ e_gr(DD,ee,m,m) = id(set(DD`m))" by (simp add: e_gr_def) lemma e_gr_add: "\n \ nat; k \ nat\ \ e_gr(DD,ee,succ(n#+k),n) = e_gr(DD,ee,n#+k,n) O Rp(DD`(n#+k),DD`succ(n#+k),ee`(n#+k))" by (simp add: e_gr_def) lemma e_gr_le: "\n \ m; m \ nat; n \ nat\ \ e_gr(DD,ee,succ(m),n) = e_gr(DD,ee,m,n) O Rp(DD`m,DD`succ(m),ee`m)" apply (erule le_exists) apply (simp add: e_gr_add, assumption+) done lemma e_gr_succ: "m \ nat \ e_gr(DD,ee,succ(m),m) = id(set(DD`m)) O Rp(DD`m,DD`succ(m),ee`m)" by (simp add: e_gr_le e_gr_eq) (* Cpo asm's due to THE uniqueness. *) lemma e_gr_succ_emb: "\emb_chain(DD,ee); m \ nat\ \ e_gr(DD,ee,succ(m),m) = Rp(DD`m,DD`succ(m),ee`m)" apply (simp add: e_gr_succ) apply (blast intro: id_comp Rp_cont cont_fun emb_chain_cpo emb_chain_emb) done lemma e_gr_fun_add: "\emb_chain(DD,ee); n \ nat; k \ nat\ \ e_gr(DD,ee,n#+k,n): set(DD`(n#+k))->set(DD`n)" apply (induct_tac k) apply (simp add: e_gr_eq id_type) apply (simp add: e_gr_add) apply (blast intro: comp_fun Rp_cont cont_fun emb_chain_emb emb_chain_cpo) done lemma e_gr_fun: "\n \ m; emb_chain(DD,ee); m \ nat; n \ nat\ \ e_gr(DD,ee,m,n): set(DD`m)->set(DD`n)" apply (rule le_exists, assumption) apply (simp add: e_gr_fun_add, assumption+) done lemma e_gr_split_add_lemma: "\emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ m \ k \ e_gr(DD,ee,n#+k,n) = e_gr(DD,ee,n#+m,n) O e_gr(DD,ee,n#+k,n#+m)" apply (induct_tac k) apply (rule impI) apply (simp add: le0_iff e_gr_eq id_type [THEN comp_id]) apply (simp add: le_succ_iff) apply (rule impI) apply (erule disjE) apply (erule impE, assumption) apply (simp add: e_gr_add) apply (subst e_gr_le) apply (assumption | rule add_le_mono nat_le_refl add_type nat_succI)+ apply (subst comp_assoc) apply (assumption | rule comp_mono_eq refl)+ (* New direct subgoal *) apply (simp del: add_succ_right add: add_succ_right [symmetric] add: e_gr_eq) apply (subst comp_id) (* simp cannot unify/inst right, use brr below (?) . *) apply (assumption | rule e_gr_fun add_type refl add_le_self nat_succI)+ done lemma e_gr_split_add: "\m \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ e_gr(DD,ee,n#+k,n) = e_gr(DD,ee,n#+m,n) O e_gr(DD,ee,n#+k,n#+m)" apply (blast intro: e_gr_split_add_lemma [THEN mp]) done lemma e_less_cont: "\m \ n; emb_chain(DD,ee); m \ nat; n \ nat\ \ e_less(DD,ee,m,n):cont(DD`m,DD`n)" apply (blast intro: emb_cont emb_e_less) done lemma e_gr_cont: "\n \ m; emb_chain(DD,ee); m \ nat; n \ nat\ \ e_gr(DD,ee,m,n):cont(DD`m,DD`n)" apply (erule rev_mp) apply (induct_tac m) apply (simp add: le0_iff e_gr_eq nat_0I) apply (assumption | rule impI id_cont emb_chain_cpo nat_0I)+ apply (simp add: le_succ_iff) apply (erule disjE) apply (erule impE, assumption) apply (simp add: e_gr_le) apply (blast intro: comp_pres_cont Rp_cont emb_chain_cpo emb_chain_emb) apply (simp add: e_gr_eq) done (* Considerably shorter.... 57 against 26 *) lemma e_less_e_gr_split_add: "\n \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ e_less(DD,ee,m,m#+n) = e_gr(DD,ee,m#+k,m#+n) O e_less(DD,ee,m,m#+k)" (* Use mp to prepare for induction. *) apply (erule rev_mp) apply (induct_tac k) apply (simp add: e_gr_eq e_less_eq id_type [THEN id_comp]) apply (simp add: le_succ_iff) apply (rule impI) apply (erule disjE) apply (erule impE, assumption) apply (simp add: e_gr_le e_less_le add_le_mono) apply (subst comp_assoc) apply (rule_tac s1 = "ee` (m#+x)" in comp_assoc [THEN subst]) apply (subst embRp_eq) apply (assumption | rule emb_chain_emb add_type emb_chain_cpo nat_succI)+ apply (subst id_comp) apply (blast intro: e_less_cont [THEN cont_fun] add_le_self) apply (rule refl) apply (simp del: add_succ_right add: add_succ_right [symmetric] add: e_gr_eq) apply (blast intro: id_comp [symmetric] e_less_cont [THEN cont_fun] add_le_self) done (* Again considerably shorter, and easy to obtain from the previous thm. *) lemma e_gr_e_less_split_add: "\m \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ e_gr(DD,ee,n#+m,n) = e_gr(DD,ee,n#+k,n) O e_less(DD,ee,n#+m,n#+k)" (* Use mp to prepare for induction. *) apply (erule rev_mp) apply (induct_tac k) apply (simp add: e_gr_eq e_less_eq id_type [THEN id_comp]) apply (simp add: le_succ_iff) apply (rule impI) apply (erule disjE) apply (erule impE, assumption) apply (simp add: e_gr_le e_less_le add_le_self nat_le_refl add_le_mono) apply (subst comp_assoc) apply (rule_tac s1 = "ee` (n#+x)" in comp_assoc [THEN subst]) apply (subst embRp_eq) apply (assumption | rule emb_chain_emb add_type emb_chain_cpo nat_succI)+ apply (subst id_comp) apply (blast intro!: e_less_cont [THEN cont_fun] add_le_mono nat_le_refl) apply (rule refl) apply (simp del: add_succ_right add: add_succ_right [symmetric] add: e_less_eq) apply (blast intro: comp_id [symmetric] e_gr_cont [THEN cont_fun] add_le_self) done lemma emb_eps: "\m \ n; emb_chain(DD,ee); m \ nat; n \ nat\ \ emb(DD`m,DD`n,eps(DD,ee,m,n))" apply (simp add: eps_def) apply (blast intro: emb_e_less) done lemma eps_fun: "\emb_chain(DD,ee); m \ nat; n \ nat\ \ eps(DD,ee,m,n): set(DD`m)->set(DD`n)" apply (simp add: eps_def) apply (auto intro: e_less_cont [THEN cont_fun] not_le_iff_lt [THEN iffD1, THEN leI] e_gr_fun nat_into_Ord) done lemma eps_id: "n \ nat \ eps(DD,ee,n,n) = id(set(DD`n))" by (simp add: eps_def e_less_eq) lemma eps_e_less_add: "\m \ nat; n \ nat\ \ eps(DD,ee,m,m#+n) = e_less(DD,ee,m,m#+n)" by (simp add: eps_def add_le_self) lemma eps_e_less: "\m \ n; m \ nat; n \ nat\ \ eps(DD,ee,m,n) = e_less(DD,ee,m,n)" by (simp add: eps_def) lemma eps_e_gr_add: "\n \ nat; k \ nat\ \ eps(DD,ee,n#+k,n) = e_gr(DD,ee,n#+k,n)" by (simp add: eps_def e_less_eq e_gr_eq) lemma eps_e_gr: "\n \ m; m \ nat; n \ nat\ \ eps(DD,ee,m,n) = e_gr(DD,ee,m,n)" apply (erule le_exists) apply (simp_all add: eps_e_gr_add) done lemma eps_succ_ee: "\\n. n \ nat \ emb(DD`n,DD`succ(n),ee`n); m \ nat\ \ eps(DD,ee,m,succ(m)) = ee`m" by (simp add: eps_e_less le_succ_iff e_less_succ_emb) lemma eps_succ_Rp: "\emb_chain(DD,ee); m \ nat\ \ eps(DD,ee,succ(m),m) = Rp(DD`m,DD`succ(m),ee`m)" by (simp add: eps_e_gr le_succ_iff e_gr_succ_emb) lemma eps_cont: "\emb_chain(DD,ee); m \ nat; n \ nat\ \ eps(DD,ee,m,n): cont(DD`m,DD`n)" apply (rule_tac i = m and j = n in nat_linear_le) apply (simp_all add: eps_e_less e_less_cont eps_e_gr e_gr_cont) done (* Theorems about splitting. *) lemma eps_split_add_left: "\n \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,m#+k) = eps(DD,ee,m#+n,m#+k) O eps(DD,ee,m,m#+n)" apply (simp add: eps_e_less add_le_self add_le_mono) apply (auto intro: e_less_split_add) done lemma eps_split_add_left_rev: "\n \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,m#+n) = eps(DD,ee,m#+k,m#+n) O eps(DD,ee,m,m#+k)" apply (simp add: eps_e_less_add eps_e_gr add_le_self add_le_mono) apply (auto intro: e_less_e_gr_split_add) done lemma eps_split_add_right: "\m \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,n#+k,n) = eps(DD,ee,n#+m,n) O eps(DD,ee,n#+k,n#+m)" apply (simp add: eps_e_gr add_le_self add_le_mono) apply (auto intro: e_gr_split_add) done lemma eps_split_add_right_rev: "\m \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,n#+m,n) = eps(DD,ee,n#+k,n) O eps(DD,ee,n#+m,n#+k)" apply (simp add: eps_e_gr_add eps_e_less add_le_self add_le_mono) apply (auto intro: e_gr_e_less_split_add) done (* Arithmetic *) lemma le_exists_lemma: "\n \ k; k \ m; \p q. \p \ q; k=n#+p; m=n#+q; p \ nat; q \ nat\ \ R; m \ nat\\R" apply (rule le_exists, assumption) prefer 2 apply (simp add: lt_nat_in_nat) apply (rule le_trans [THEN le_exists], assumption+, force+) done lemma eps_split_left_le: "\m \ k; k \ n; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,n) = eps(DD,ee,k,n) O eps(DD,ee,m,k)" apply (rule le_exists_lemma, assumption+) apply (auto intro: eps_split_add_left) done lemma eps_split_left_le_rev: "\m \ n; n \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,n) = eps(DD,ee,k,n) O eps(DD,ee,m,k)" apply (rule le_exists_lemma, assumption+) apply (auto intro: eps_split_add_left_rev) done lemma eps_split_right_le: "\n \ k; k \ m; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,n) = eps(DD,ee,k,n) O eps(DD,ee,m,k)" apply (rule le_exists_lemma, assumption+) apply (auto intro: eps_split_add_right) done lemma eps_split_right_le_rev: "\n \ m; m \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,n) = eps(DD,ee,k,n) O eps(DD,ee,m,k)" apply (rule le_exists_lemma, assumption+) apply (auto intro: eps_split_add_right_rev) done (* The desired two theorems about `splitting'. *) lemma eps_split_left: "\m \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,n) = eps(DD,ee,k,n) O eps(DD,ee,m,k)" apply (rule nat_linear_le) apply (rule_tac [4] eps_split_right_le_rev) prefer 4 apply assumption apply (rule_tac [3] nat_linear_le) apply (rule_tac [5] eps_split_left_le) prefer 6 apply assumption apply (simp_all add: eps_split_left_le_rev) done lemma eps_split_right: "\n \ k; emb_chain(DD,ee); m \ nat; n \ nat; k \ nat\ \ eps(DD,ee,m,n) = eps(DD,ee,k,n) O eps(DD,ee,m,k)" apply (rule nat_linear_le) apply (rule_tac [3] eps_split_left_le_rev) prefer 3 apply assumption apply (rule_tac [8] nat_linear_le) apply (rule_tac [10] eps_split_right_le) prefer 11 apply assumption apply (simp_all add: eps_split_right_le_rev) done (*----------------------------------------------------------------------*) (* That was eps: D_m -> D_n, NEXT rho_emb: D_n -> Dinf. *) (*----------------------------------------------------------------------*) (* Considerably shorter. *) lemma rho_emb_fun: "\emb_chain(DD,ee); n \ nat\ \ rho_emb(DD,ee,n): set(DD`n) -> set(Dinf(DD,ee))" apply (simp add: rho_emb_def) apply (assumption | rule lam_type DinfI eps_cont [THEN cont_fun, THEN apply_type])+ apply simp apply (rule_tac i = "succ (na) " and j = n in nat_linear_le) apply blast apply assumption apply (simplesubst eps_split_right_le) \ \Subst would rewrite the lhs. We want to change the rhs.\ prefer 2 apply assumption apply simp apply (assumption | rule add_le_self nat_0I nat_succI)+ apply (simp add: eps_succ_Rp) apply (subst comp_fun_apply) apply (assumption | rule eps_fun nat_succI Rp_cont [THEN cont_fun] emb_chain_emb emb_chain_cpo refl)+ (* Now the second part of the proof. Slightly different than HOL. *) apply (simp add: eps_e_less nat_succI) apply (erule le_iff [THEN iffD1, THEN disjE]) apply (simp add: e_less_le) apply (subst comp_fun_apply) apply (assumption | rule e_less_cont cont_fun emb_chain_emb emb_cont)+ apply (subst embRp_eq_thm) apply (assumption | rule emb_chain_emb e_less_cont [THEN cont_fun, THEN apply_type] emb_chain_cpo nat_succI)+ apply (simp add: eps_e_less) apply (simp add: eps_succ_Rp e_less_eq id_conv nat_succI) done lemma rho_emb_apply1: "x \ set(DD`n) \ rho_emb(DD,ee,n)`x = (\m \ nat. eps(DD,ee,n,m)`x)" by (simp add: rho_emb_def) lemma rho_emb_apply2: "\x \ set(DD`n); m \ nat\ \ rho_emb(DD,ee,n)`x`m = eps(DD,ee,n,m)`x" by (simp add: rho_emb_def) lemma rho_emb_id: "\x \ set(DD`n); n \ nat\ \ rho_emb(DD,ee,n)`x`n = x" by (simp add: rho_emb_apply2 eps_id) (* Shorter proof, 23 against 62. *) lemma rho_emb_cont: "\emb_chain(DD,ee); n \ nat\ \ rho_emb(DD,ee,n): cont(DD`n,Dinf(DD,ee))" apply (rule contI) apply (assumption | rule rho_emb_fun)+ apply (rule rel_DinfI) apply (simp add: rho_emb_def) apply (assumption | rule eps_cont [THEN cont_mono] Dinf_prod apply_type rho_emb_fun)+ (* Continuity, different order, slightly different proofs. *) apply (subst lub_Dinf) apply (rule chainI) apply (assumption | rule lam_type rho_emb_fun [THEN apply_type] chain_in)+ apply simp apply (rule rel_DinfI) apply (simp add: rho_emb_apply2 chain_in) apply (assumption | rule eps_cont [THEN cont_mono] chain_rel Dinf_prod rho_emb_fun [THEN apply_type] chain_in nat_succI)+ (* Now, back to the result of applying lub_Dinf *) apply (simp add: rho_emb_apply2 chain_in) apply (subst rho_emb_apply1) apply (assumption | rule cpo_lub [THEN islub_in] emb_chain_cpo)+ apply (rule fun_extension) apply (assumption | rule lam_type eps_cont [THEN cont_fun, THEN apply_type] cpo_lub [THEN islub_in] emb_chain_cpo)+ apply (assumption | rule cont_chain eps_cont emb_chain_cpo)+ apply simp apply (simp add: eps_cont [THEN cont_lub]) done (* 32 vs 61, using safe_tac with imp in asm would be unfortunate (5steps) *) lemma eps1_aux1: "\m \ n; emb_chain(DD,ee); x \ set(Dinf(DD,ee)); m \ nat; n \ nat\ \ rel(DD`n,e_less(DD,ee,m,n)`(x`m),x`n)" apply (erule rev_mp) (* For induction proof *) apply (induct_tac n) apply (rule impI) apply (simp add: e_less_eq) apply (subst id_conv) apply (assumption | rule apply_type Dinf_prod cpo_refl emb_chain_cpo nat_0I)+ apply (simp add: le_succ_iff) apply (rule impI) apply (erule disjE) apply (drule mp, assumption) apply (rule cpo_trans) apply (rule_tac [2] e_less_le [THEN ssubst]) apply (assumption | rule emb_chain_cpo nat_succI)+ apply (subst comp_fun_apply) apply (assumption | rule emb_chain_emb [THEN emb_cont] e_less_cont cont_fun apply_type Dinf_prod)+ apply (rule_tac y = "x`xa" in emb_chain_emb [THEN emb_cont, THEN cont_mono]) apply (assumption | rule e_less_cont [THEN cont_fun] apply_type Dinf_prod)+ apply (rule_tac x1 = x and n1 = xa in Dinf_eq [THEN subst]) apply (rule_tac [3] comp_fun_apply [THEN subst]) apply (rename_tac [5] y) apply (rule_tac [5] P = "\z. rel(DD`succ(y), (ee`y O Rp(DD'(y)`y,DD'(y)`succ(y),ee'(y)`y)) ` (x`succ(y)), z)" for DD' ee' in id_conv [THEN subst]) apply (rule_tac [6] rel_cf) (* Dinf and cont_fun doesn't go well together, both Pi(_,\x._). *) (* solves 10 of 11 subgoals *) apply (assumption | rule Dinf_prod [THEN apply_type] cont_fun Rp_cont e_less_cont emb_cont emb_chain_emb emb_chain_cpo apply_type embRp_rel disjI1 [THEN le_succ_iff [THEN iffD2]] nat_succI)+ apply (simp add: e_less_eq) apply (subst id_conv) apply (auto intro: apply_type Dinf_prod emb_chain_cpo) done (* 18 vs 40 *) lemma eps1_aux2: "\n \ m; emb_chain(DD,ee); x \ set(Dinf(DD,ee)); m \ nat; n \ nat\ \ rel(DD`n,e_gr(DD,ee,m,n)`(x`m),x`n)" apply (erule rev_mp) (* For induction proof *) apply (induct_tac m) apply (rule impI) apply (simp add: e_gr_eq) apply (subst id_conv) apply (assumption | rule apply_type Dinf_prod cpo_refl emb_chain_cpo nat_0I)+ apply (simp add: le_succ_iff) apply (rule impI) apply (erule disjE) apply (drule mp, assumption) apply (subst e_gr_le) apply (rule_tac [4] comp_fun_apply [THEN ssubst]) apply (rule_tac [6] Dinf_eq [THEN ssubst]) apply (assumption | rule emb_chain_emb emb_chain_cpo Rp_cont e_gr_cont cont_fun emb_cont apply_type Dinf_prod nat_succI)+ apply (simp add: e_gr_eq) apply (subst id_conv) apply (auto intro: apply_type Dinf_prod emb_chain_cpo) done lemma eps1: "\emb_chain(DD,ee); x \ set(Dinf(DD,ee)); m \ nat; n \ nat\ \ rel(DD`n,eps(DD,ee,m,n)`(x`m),x`n)" apply (simp add: eps_def) apply (blast intro: eps1_aux1 not_le_iff_lt [THEN iffD1, THEN leI, THEN eps1_aux2] nat_into_Ord) done (* The following theorem is needed/useful due to type check for rel_cfI, but also elsewhere. Look for occurrences of rel_cfI, rel_DinfI, etc to evaluate the problem. *) lemma lam_Dinf_cont: "\emb_chain(DD,ee); n \ nat\ \ (\x \ set(Dinf(DD,ee)). x`n) \ cont(Dinf(DD,ee),DD`n)" apply (rule contI) apply (assumption | rule lam_type apply_type Dinf_prod)+ apply simp apply (assumption | rule rel_Dinf)+ apply (subst beta) apply (auto intro: cpo_Dinf islub_in cpo_lub) apply (simp add: chain_in lub_Dinf) done lemma rho_projpair: "\emb_chain(DD,ee); n \ nat\ \ projpair(DD`n,Dinf(DD,ee),rho_emb(DD,ee,n),rho_proj(DD,ee,n))" apply (simp add: rho_proj_def) apply (rule projpairI) apply (assumption | rule rho_emb_cont)+ (* lemma used, introduced because same fact needed below due to rel_cfI. *) apply (assumption | rule lam_Dinf_cont)+ (*-----------------------------------------------*) (* This part is 7 lines, but 30 in HOL (75% reduction!) *) apply (rule fun_extension) apply (rule_tac [3] id_conv [THEN ssubst]) apply (rule_tac [4] comp_fun_apply [THEN ssubst]) apply (rule_tac [6] beta [THEN ssubst]) apply (rule_tac [7] rho_emb_id [THEN ssubst]) apply (assumption | rule comp_fun id_type lam_type rho_emb_fun Dinf_prod [THEN apply_type] apply_type refl)+ (*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*) apply (rule rel_cfI) (* ----------------\>>Yields type cond, not in HOL *) apply (subst id_conv) apply (rule_tac [2] comp_fun_apply [THEN ssubst]) apply (rule_tac [4] beta [THEN ssubst]) apply (rule_tac [5] rho_emb_apply1 [THEN ssubst]) apply (rule_tac [6] rel_DinfI) apply (rule_tac [6] beta [THEN ssubst]) (* Dinf_prod bad with lam_type *) apply (assumption | rule eps1 lam_type rho_emb_fun eps_fun Dinf_prod [THEN apply_type] refl)+ apply (assumption | rule apply_type eps_fun Dinf_prod comp_pres_cont rho_emb_cont lam_Dinf_cont id_cont cpo_Dinf emb_chain_cpo)+ done lemma emb_rho_emb: "\emb_chain(DD,ee); n \ nat\ \ emb(DD`n,Dinf(DD,ee),rho_emb(DD,ee,n))" by (auto simp add: emb_def intro: exI rho_projpair) lemma rho_proj_cont: "\emb_chain(DD,ee); n \ nat\ \ rho_proj(DD,ee,n) \ cont(Dinf(DD,ee),DD`n)" by (auto intro: rho_projpair projpair_p_cont) (*----------------------------------------------------------------------*) (* Commutivity and universality. *) (*----------------------------------------------------------------------*) lemma commuteI: "\\n. n \ nat \ emb(DD`n,E,r(n)); \m n. \m \ n; m \ nat; n \ nat\ \ r(n) O eps(DD,ee,m,n) = r(m)\ \ commute(DD,ee,E,r)" by (simp add: commute_def) lemma commute_emb [TC]: "\commute(DD,ee,E,r); n \ nat\ \ emb(DD`n,E,r(n))" by (simp add: commute_def) lemma commute_eq: "\commute(DD,ee,E,r); m \ n; m \ nat; n \ nat\ \ r(n) O eps(DD,ee,m,n) = r(m) " by (simp add: commute_def) (* Shorter proof: 11 vs 46 lines. *) lemma rho_emb_commute: "emb_chain(DD,ee) \ commute(DD,ee,Dinf(DD,ee),rho_emb(DD,ee))" apply (rule commuteI) apply (assumption | rule emb_rho_emb)+ apply (rule fun_extension) (* Manual instantiation in HOL. *) apply (rule_tac [3] comp_fun_apply [THEN ssubst]) apply (rule_tac [5] fun_extension) (*Next, clean up and instantiate unknowns *) apply (assumption | rule comp_fun rho_emb_fun eps_fun Dinf_prod apply_type)+ apply (simp add: rho_emb_apply2 eps_fun [THEN apply_type]) apply (rule comp_fun_apply [THEN subst]) apply (rule_tac [3] eps_split_left [THEN subst]) apply (auto intro: eps_fun) done lemma le_succ: "n \ nat \ n \ succ(n)" by (simp add: le_succ_iff) (* Shorter proof: 21 vs 83 (106 - 23, due to OAssoc complication) *) lemma commute_chain: "\commute(DD,ee,E,r); emb_chain(DD,ee); cpo(E)\ \ chain(cf(E,E),\n \ nat. r(n) O Rp(DD`n,E,r(n)))" apply (rule chainI) apply (blast intro: lam_type cont_cf comp_pres_cont commute_emb Rp_cont emb_cont emb_chain_cpo, simp) apply (rule_tac r1 = r and m1 = n in commute_eq [THEN subst]) apply (assumption | rule le_succ nat_succI)+ apply (subst Rp_comp) apply (assumption | rule emb_eps commute_emb emb_chain_cpo le_succ nat_succI)+ apply (rule comp_assoc [THEN subst]) (* comp_assoc is simpler in Isa *) apply (rule_tac r1 = "r (succ (n))" in comp_assoc [THEN ssubst]) apply (rule comp_mono) apply (blast intro: comp_pres_cont eps_cont emb_eps commute_emb Rp_cont emb_cont emb_chain_cpo le_succ)+ apply (rule_tac b="r(succ(n))" in comp_id [THEN subst]) (* 1 subst too much *) apply (rule_tac [2] comp_mono) apply (blast intro: comp_pres_cont eps_cont emb_eps emb_id commute_emb Rp_cont emb_cont cont_fun emb_chain_cpo le_succ)+ apply (subst comp_id) (* Undoes "1 subst too much", typing next anyway *) apply (blast intro: cont_fun Rp_cont emb_cont commute_emb cont_cf cpo_cf emb_chain_cpo embRp_rel emb_eps le_succ)+ done lemma rho_emb_chain: "emb_chain(DD,ee) \ chain(cf(Dinf(DD,ee),Dinf(DD,ee)), \n \ nat. rho_emb(DD,ee,n) O Rp(DD`n,Dinf(DD,ee),rho_emb(DD,ee,n)))" by (auto intro: commute_chain rho_emb_commute cpo_Dinf) lemma rho_emb_chain_apply1: "\emb_chain(DD,ee); x \ set(Dinf(DD,ee))\ \ chain(Dinf(DD,ee), \n \ nat. (rho_emb(DD,ee,n) O Rp(DD`n,Dinf(DD,ee),rho_emb(DD,ee,n)))`x)" by (drule rho_emb_chain [THEN chain_cf], assumption, simp) lemma chain_iprod_emb_chain: "\chain(iprod(DD),X); emb_chain(DD,ee); n \ nat\ \ chain(DD`n,\m \ nat. X `m `n)" by (auto intro: chain_iprod emb_chain_cpo) lemma rho_emb_chain_apply2: "\emb_chain(DD,ee); x \ set(Dinf(DD,ee)); n \ nat\ \ chain (DD`n, \xa \ nat. (rho_emb(DD, ee, xa) O Rp(DD ` xa, Dinf(DD, ee),rho_emb(DD, ee, xa))) ` x ` n)" by (frule rho_emb_chain_apply1 [THEN chain_Dinf, THEN chain_iprod_emb_chain], auto) (* Shorter proof: 32 vs 72 (roughly), Isabelle proof has lemmas. *) lemma rho_emb_lub: "emb_chain(DD,ee) \ lub(cf(Dinf(DD,ee),Dinf(DD,ee)), \n \ nat. rho_emb(DD,ee,n) O Rp(DD`n,Dinf(DD,ee),rho_emb(DD,ee,n))) = id(set(Dinf(DD,ee)))" apply (rule cpo_antisym) apply (rule cpo_cf) (*Instantiate variable, continued below (loops otherwise)*) apply (assumption | rule cpo_Dinf)+ apply (rule islub_least) apply (assumption | rule cpo_lub rho_emb_chain cpo_cf cpo_Dinf isubI cont_cf id_cont)+ apply simp apply (assumption | rule embRp_rel emb_rho_emb emb_chain_cpo cpo_Dinf)+ apply (rule rel_cfI) apply (simp add: lub_cf rho_emb_chain cpo_Dinf) apply (rule rel_DinfI) (* Additional assumptions *) apply (subst lub_Dinf) apply (assumption | rule rho_emb_chain_apply1)+ defer 1 apply (assumption | rule Dinf_prod cpo_lub [THEN islub_in] id_cont cpo_Dinf cpo_cf cf_cont rho_emb_chain rho_emb_chain_apply1 id_cont [THEN cont_cf])+ apply simp apply (rule dominate_islub) apply (rule_tac [3] cpo_lub) apply (rule_tac [6] x1 = "x`n" in chain_const [THEN chain_fun]) defer 1 apply (assumption | rule rho_emb_chain_apply2 emb_chain_cpo islub_const apply_type Dinf_prod emb_chain_cpo chain_fun rho_emb_chain_apply2)+ apply (rule dominateI, assumption, simp) apply (subst comp_fun_apply) apply (assumption | rule cont_fun Rp_cont emb_cont emb_rho_emb cpo_Dinf emb_chain_cpo)+ apply (subst rho_projpair [THEN Rp_unique]) prefer 5 apply (simp add: rho_proj_def) apply (rule rho_emb_id [THEN ssubst]) apply (auto intro: cpo_Dinf apply_type Dinf_prod emb_chain_cpo) done lemma theta_chain: (* almost same proof as commute_chain *) "\commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G)\ \ chain(cf(E,G),\n \ nat. f(n) O Rp(DD`n,E,r(n)))" apply (rule chainI) apply (blast intro: lam_type cont_cf comp_pres_cont commute_emb Rp_cont emb_cont emb_chain_cpo, simp) apply (rule_tac r1 = r and m1 = n in commute_eq [THEN subst]) apply (rule_tac [5] r1 = f and m1 = n in commute_eq [THEN subst]) apply (assumption | rule le_succ nat_succI)+ apply (subst Rp_comp) apply (assumption | rule emb_eps commute_emb emb_chain_cpo le_succ nat_succI)+ apply (rule comp_assoc [THEN subst]) apply (rule_tac r1 = "f (succ (n))" in comp_assoc [THEN ssubst]) apply (rule comp_mono) apply (blast intro: comp_pres_cont eps_cont emb_eps commute_emb Rp_cont emb_cont emb_chain_cpo le_succ)+ apply (rule_tac b="f(succ(n))" in comp_id [THEN subst]) (* 1 subst too much *) apply (rule_tac [2] comp_mono) apply (blast intro: comp_pres_cont eps_cont emb_eps emb_id commute_emb Rp_cont emb_cont cont_fun emb_chain_cpo le_succ)+ apply (subst comp_id) (* Undoes "1 subst too much", typing next anyway *) apply (blast intro: cont_fun Rp_cont emb_cont commute_emb cont_cf cpo_cf emb_chain_cpo embRp_rel emb_eps le_succ)+ done lemma theta_proj_chain: (* similar proof to theta_chain *) "\commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G)\ \ chain(cf(G,E),\n \ nat. r(n) O Rp(DD`n,G,f(n)))" apply (rule chainI) apply (blast intro: lam_type cont_cf comp_pres_cont commute_emb Rp_cont emb_cont emb_chain_cpo, simp) apply (rule_tac r1 = r and m1 = n in commute_eq [THEN subst]) apply (rule_tac [5] r1 = f and m1 = n in commute_eq [THEN subst]) apply (assumption | rule le_succ nat_succI)+ apply (subst Rp_comp) apply (assumption | rule emb_eps commute_emb emb_chain_cpo le_succ nat_succI)+ apply (rule comp_assoc [THEN subst]) (* comp_assoc is simpler in Isa *) apply (rule_tac r1 = "r (succ (n))" in comp_assoc [THEN ssubst]) apply (rule comp_mono) apply (blast intro: comp_pres_cont eps_cont emb_eps commute_emb Rp_cont emb_cont emb_chain_cpo le_succ)+ apply (rule_tac b="r(succ(n))" in comp_id [THEN subst]) (* 1 subst too much *) apply (rule_tac [2] comp_mono) apply (blast intro: comp_pres_cont eps_cont emb_eps emb_id commute_emb Rp_cont emb_cont cont_fun emb_chain_cpo le_succ)+ apply (subst comp_id) (* Undoes "1 subst too much", typing next anyway *) apply (blast intro: cont_fun Rp_cont emb_cont commute_emb cont_cf cpo_cf emb_chain_cpo embRp_rel emb_eps le_succ)+ done (* Simplification with comp_assoc is possible inside a \-abstraction, because it does not have assumptions. If it had, as the HOL-ST theorem too strongly has, we would be in deep trouble due to HOL's lack of proper conditional rewriting (a HOL contrib provides something that works). *) (* Controlled simplification inside lambda: introduce lemmas *) lemma commute_O_lemma: "\commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G); x \ nat\ \ r(x) O Rp(DD ` x, G, f(x)) O f(x) O Rp(DD ` x, E, r(x)) = r(x) O Rp(DD ` x, E, r(x))" apply (rule_tac s1 = "f (x) " in comp_assoc [THEN subst]) apply (subst embRp_eq) apply (rule_tac [4] id_comp [THEN ssubst]) apply (auto intro: cont_fun Rp_cont commute_emb emb_chain_cpo) done (* Shorter proof (but lemmas): 19 vs 79 (103 - 24, due to OAssoc) *) lemma theta_projpair: "\lub(cf(E,E), \n \ nat. r(n) O Rp(DD`n,E,r(n))) = id(set(E)); commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G)\ \ projpair (E,G, lub(cf(E,G), \n \ nat. f(n) O Rp(DD`n,E,r(n))), lub(cf(G,E), \n \ nat. r(n) O Rp(DD`n,G,f(n))))" apply (simp add: projpair_def rho_proj_def, safe) apply (rule_tac [3] comp_lubs [THEN ssubst]) (* The following one line is 15 lines in HOL, and includes existentials. *) apply (assumption | rule cf_cont islub_in cpo_lub cpo_cf theta_chain theta_proj_chain)+ apply (simp (no_asm) add: comp_assoc) apply (simp add: commute_O_lemma) apply (subst comp_lubs) apply (assumption | rule cf_cont islub_in cpo_lub cpo_cf theta_chain theta_proj_chain)+ apply (simp (no_asm) add: comp_assoc) apply (simp add: commute_O_lemma) apply (rule dominate_islub) defer 1 apply (rule cpo_lub) apply (assumption | rule commute_chain commute_emb islub_const cont_cf id_cont cpo_cf chain_fun chain_const)+ apply (rule dominateI, assumption, simp) apply (blast intro: embRp_rel commute_emb emb_chain_cpo) done lemma emb_theta: "\lub(cf(E,E), \n \ nat. r(n) O Rp(DD`n,E,r(n))) = id(set(E)); commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G)\ \ emb(E,G,lub(cf(E,G), \n \ nat. f(n) O Rp(DD`n,E,r(n))))" apply (simp add: emb_def) apply (blast intro: theta_projpair) done lemma mono_lemma: "\g \ cont(D,D'); cpo(D); cpo(D'); cpo(E)\ \ (\f \ cont(D',E). f O g) \ mono(cf(D',E),cf(D,E))" apply (rule monoI) apply (simp add: set_def cf_def) apply (drule cf_cont)+ apply simp apply (blast intro: comp_mono lam_type comp_pres_cont cpo_cf cont_cf) done lemma commute_lam_lemma: "\commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G); n \ nat\ \ (\na \ nat. (\f \ cont(E, G). f O r(n)) ` ((\n \ nat. f(n) O Rp(DD ` n, E, r(n))) ` na)) = (\na \ nat. (f(na) O Rp(DD ` na, E, r(na))) O r(n))" apply (rule fun_extension) (*something wrong here*) apply (auto simp del: beta_if simp add: beta intro: lam_type) done lemma chain_lemma: "\commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G); n \ nat\ \ chain(cf(DD`n,G),\x \ nat. (f(x) O Rp(DD ` x, E, r(x))) O r(n))" apply (rule commute_lam_lemma [THEN subst]) apply (blast intro: theta_chain emb_chain_cpo commute_emb [THEN emb_cont, THEN mono_lemma, THEN mono_chain])+ done lemma suffix_lemma: "\commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G); cpo(DD`x); x \ nat\ \ suffix(\n \ nat. (f(n) O Rp(DD`n,E,r(n))) O r(x),x) = (\n \ nat. f(x))" apply (simp add: suffix_def) apply (rule lam_type [THEN fun_extension]) apply (blast intro: lam_type comp_fun cont_fun Rp_cont emb_cont commute_emb emb_chain_cpo)+ apply simp apply (rename_tac y) apply (subgoal_tac "f(x#+y) O (Rp(DD`(x#+y), E, r(x#+y)) O r (x#+y)) O eps(DD, ee, x, x#+y) = f(x)") apply (simp add: comp_assoc commute_eq add_le_self) apply (simp add: embRp_eq eps_fun [THEN id_comp] commute_emb emb_chain_cpo) apply (blast intro: commute_eq add_le_self) done lemma mediatingI: "\emb(E,G,t); \n. n \ nat \ f(n) = t O r(n)\\mediating(E,G,r,f,t)" by (simp add: mediating_def) lemma mediating_emb: "mediating(E,G,r,f,t) \ emb(E,G,t)" by (simp add: mediating_def) lemma mediating_eq: "\mediating(E,G,r,f,t); n \ nat\ \ f(n) = t O r(n)" by (simp add: mediating_def) lemma lub_universal_mediating: "\lub(cf(E,E), \n \ nat. r(n) O Rp(DD`n,E,r(n))) = id(set(E)); commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G)\ \ mediating(E,G,r,f,lub(cf(E,G), \n \ nat. f(n) O Rp(DD`n,E,r(n))))" apply (assumption | rule mediatingI emb_theta)+ apply (rule_tac b = "r (n) " in lub_const [THEN subst]) apply (rule_tac [3] comp_lubs [THEN ssubst]) apply (blast intro: cont_cf emb_cont commute_emb cpo_cf theta_chain chain_const emb_chain_cpo)+ apply (simp (no_asm)) apply (rule_tac n1 = n in lub_suffix [THEN subst]) apply (assumption | rule chain_lemma cpo_cf emb_chain_cpo)+ apply (simp add: suffix_lemma lub_const cont_cf emb_cont commute_emb cpo_cf emb_chain_cpo) done lemma lub_universal_unique: "\mediating(E,G,r,f,t); lub(cf(E,E), \n \ nat. r(n) O Rp(DD`n,E,r(n))) = id(set(E)); commute(DD,ee,E,r); commute(DD,ee,G,f); emb_chain(DD,ee); cpo(E); cpo(G)\ \ t = lub(cf(E,G), \n \ nat. f(n) O Rp(DD`n,E,r(n)))" apply (rule_tac b = t in comp_id [THEN subst]) apply (erule_tac [2] subst) apply (rule_tac [2] b = t in lub_const [THEN subst]) apply (rule_tac [4] comp_lubs [THEN ssubst]) prefer 9 apply (simp add: comp_assoc mediating_eq) apply (assumption | rule cont_fun emb_cont mediating_emb cont_cf cpo_cf chain_const commute_chain emb_chain_cpo)+ done (*---------------------------------------------------------------------*) (* Dinf yields the inverse_limit, stated as rho_emb_commute and *) (* Dinf_universal. *) (*---------------------------------------------------------------------*) theorem Dinf_universal: "\commute(DD,ee,G,f); emb_chain(DD,ee); cpo(G)\ \ mediating (Dinf(DD,ee),G,rho_emb(DD,ee),f, lub(cf(Dinf(DD,ee),G), \n \ nat. f(n) O Rp(DD`n,Dinf(DD,ee),rho_emb(DD,ee,n)))) \ (\t. mediating(Dinf(DD,ee),G,rho_emb(DD,ee),f,t) \ t = lub(cf(Dinf(DD,ee),G), \n \ nat. f(n) O Rp(DD`n,Dinf(DD,ee),rho_emb(DD,ee,n))))" apply safe apply (assumption | rule lub_universal_mediating rho_emb_commute rho_emb_lub cpo_Dinf)+ apply (auto intro: lub_universal_unique rho_emb_commute rho_emb_lub cpo_Dinf) done end diff --git a/src/ZF/ex/Ramsey.thy b/src/ZF/ex/Ramsey.thy --- a/src/ZF/ex/Ramsey.thy +++ b/src/ZF/ex/Ramsey.thy @@ -1,197 +1,197 @@ (* Title: ZF/ex/Ramsey.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1992 University of Cambridge Ramsey's Theorem (finite exponent 2 version) Based upon the article D Basin and M Kaufmann, The Boyer-Moore Prover and Nuprl: An Experimental Comparison. In G Huet and G Plotkin, editors, Logical Frameworks. (CUP, 1991), pages 89-119 See also M Kaufmann, An example in NQTHM: Ramsey's Theorem Internal Note, Computational Logic, Inc., Austin, Texas 78703 Available from the author: kaufmann@cli.com This function compute Ramsey numbers according to the proof given below (which, does not constrain the base case values at all. fun ram 0 j = 1 | ram i 0 = 1 | ram i j = ram (i-1) j + ram i (j-1) *) theory Ramsey imports ZF begin definition Symmetric :: "i\o" where "Symmetric(E) \ (\x y. \x,y\:E \ \y,x\:E)" definition Atleast :: "[i,i]\o" where \ \not really necessary: ZF defines cardinality\ "Atleast(n,S) \ (\f. f \ inj(n,S))" definition Clique :: "[i,i,i]\o" where "Clique(C,V,E) \ (C \ V) \ (\x \ C. \y \ C. x\y \ \x,y\ \ E)" definition Indept :: "[i,i,i]\o" where "Indept(I,V,E) \ (I \ V) \ (\x \ I. \y \ I. x\y \ \x,y\ \ E)" definition Ramsey :: "[i,i,i]\o" where "Ramsey(n,i,j) \ \V E. Symmetric(E) \ Atleast(n,V) \ (\C. Clique(C,V,E) \ Atleast(i,C)) | (\I. Indept(I,V,E) \ Atleast(j,I))" (*** Cliques and Independent sets ***) lemma Clique0 [intro]: "Clique(0,V,E)" by (unfold Clique_def, blast) lemma Clique_superset: "\Clique(C,V',E); V'<=V\ \ Clique(C,V,E)" by (unfold Clique_def, blast) lemma Indept0 [intro]: "Indept(0,V,E)" by (unfold Indept_def, blast) lemma Indept_superset: "\Indept(I,V',E); V'<=V\ \ Indept(I,V,E)" by (unfold Indept_def, blast) (*** Atleast ***) lemma Atleast0 [intro]: "Atleast(0,A)" by (unfold Atleast_def inj_def Pi_def function_def, blast) lemma Atleast_succD: "Atleast(succ(m),A) \ \x \ A. Atleast(m, A-{x})" -apply (unfold Atleast_def) + unfolding Atleast_def apply (blast dest: inj_is_fun [THEN apply_type] inj_succ_restrict) done lemma Atleast_superset: "\Atleast(n,A); A \ B\ \ Atleast(n,B)" by (unfold Atleast_def, blast intro: inj_weaken_type) lemma Atleast_succI: "\Atleast(m,B); b\ B\ \ Atleast(succ(m), cons(b,B))" apply (unfold Atleast_def succ_def) apply (blast intro: inj_extend elim: mem_irrefl) done lemma Atleast_Diff_succI: "\Atleast(m, B-{x}); x \ B\ \ Atleast(succ(m), B)" by (blast intro: Atleast_succI [THEN Atleast_superset]) (*** Main Cardinality Lemma ***) (*The #-succ(0) strengthens the original theorem statement, but precisely the same proof could be used\*) lemma pigeon2 [rule_format]: "m \ nat \ \n \ nat. \A B. Atleast((m#+n) #- succ(0), A \ B) \ Atleast(m,A) | Atleast(n,B)" apply (induct_tac "m") apply (blast intro!: Atleast0, simp) apply (rule ballI) apply (rename_tac m' n) (*simplifier does NOT preserve bound names!*) apply (induct_tac "n", auto) apply (erule Atleast_succD [THEN bexE]) apply (rename_tac n' A B z) apply (erule UnE) (**case z \ B. Instantiate the '\A B' induction hypothesis. **) apply (drule_tac [2] x1 = A and x = "B-{z}" in spec [THEN spec]) apply (erule_tac [2] mp [THEN disjE]) (*cases Atleast(succ(m1),A) and Atleast(succ(k),B)*) apply (erule_tac [3] asm_rl notE Atleast_Diff_succI)+ (*proving the condition*) prefer 2 apply (blast intro: Atleast_superset) (**case z \ A. Instantiate the '\n \ nat. \A B' induction hypothesis. **) apply (drule_tac x2="succ(n')" and x1="A-{z}" and x=B in bspec [THEN spec, THEN spec]) apply (erule nat_succI) apply (erule mp [THEN disjE]) (*cases Atleast(succ(m1),A) and Atleast(succ(k),B)*) apply (erule_tac [2] asm_rl Atleast_Diff_succI notE)+ (*proving the condition*) apply simp apply (blast intro: Atleast_superset) done (**** Ramsey's Theorem ****) (** Base cases of induction; they now admit ANY Ramsey number **) lemma Ramsey0j: "Ramsey(n,0,j)" by (unfold Ramsey_def, blast) lemma Ramseyi0: "Ramsey(n,i,0)" by (unfold Ramsey_def, blast) (** Lemmas for induction step **) (*The use of succ(m) here, rather than #-succ(0), simplifies the proof of Ramsey_step_lemma.*) lemma Atleast_partition: "\Atleast(m #+ n, A); m \ nat; n \ nat\ \ Atleast(succ(m), {x \ A. \P(x)}) | Atleast(n, {x \ A. P(x)})" apply (rule nat_succI [THEN pigeon2], assumption+) apply (rule Atleast_superset, auto) done (*For the Atleast part, proves \(a \ I) from the second premise!*) lemma Indept_succ: "\Indept(I, {z \ V-{a}. \a,z\ \ E}, E); Symmetric(E); a \ V; Atleast(j,I)\ \ Indept(cons(a,I), V, E) \ Atleast(succ(j), cons(a,I))" apply (unfold Symmetric_def Indept_def) apply (blast intro!: Atleast_succI) done lemma Clique_succ: "\Clique(C, {z \ V-{a}. \a,z\:E}, E); Symmetric(E); a \ V; Atleast(j,C)\ \ Clique(cons(a,C), V, E) \ Atleast(succ(j), cons(a,C))" apply (unfold Symmetric_def Clique_def) apply (blast intro!: Atleast_succI) done (** Induction step **) (*Published proofs gloss over the need for Ramsey numbers to be POSITIVE.*) lemma Ramsey_step_lemma: "\Ramsey(succ(m), succ(i), j); Ramsey(n, i, succ(j)); m \ nat; n \ nat\ \ Ramsey(succ(m#+n), succ(i), succ(j))" apply (unfold Ramsey_def, clarify) apply (erule Atleast_succD [THEN bexE]) apply (erule_tac P1 = "\z.\x,z\:E" in Atleast_partition [THEN disjE], assumption+) (*case m*) apply (fast dest!: Indept_succ elim: Clique_superset) (*case n*) apply (fast dest!: Clique_succ elim: Indept_superset) done (** The actual proof **) (*Again, the induction requires Ramsey numbers to be positive.*) lemma ramsey_lemma: "i \ nat \ \j \ nat. \n \ nat. Ramsey(succ(n), i, j)" apply (induct_tac "i") apply (blast intro!: Ramsey0j) apply (rule ballI) apply (induct_tac "j") apply (blast intro!: Ramseyi0) apply (blast intro!: add_type Ramsey_step_lemma) done (*Final statement in a tidy form, without succ(...) *) lemma ramsey: "\i \ nat; j \ nat\ \ \n \ nat. Ramsey(n,i,j)" by (blast dest: ramsey_lemma) 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. \x,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'. \\x,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: "\\a,b\: f; \a,c\: f; f \ Pi(A,B)\ \ b=c" by (unfold Pi_def function_def, blast) lemma function_apply_equality: "\\a,b\: f; function(f)\ \ f`a = b" by (unfold apply_def function_def, blast) lemma apply_equality: "\\a,b\: f; f \ Pi(A,B)\ \ f`a = b" -apply (unfold Pi_def) + unfolding 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) \ \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: "\\a,b\ \ f; f \ Pi(A,B)\ \ a \ A" by (blast dest: fun_is_rel) lemma range_type: "\\a,b\ \ f; f \ Pi(A,B)\ \ b \ B(a)" by (blast dest: fun_is_rel) lemma Pair_mem_PiD: "\\a,b\: 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) + unfolding 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: "\\a,c\: (\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\} \ {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) + unfolding 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) + unfolding Pi_def apply (blast intro!: rel_Union function_Union) done 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(\c,b\,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(\c,b\,f) \ cons(c,A) -> B" by (blast intro: fun_extend [THEN fun_weaken_type]) lemma extend_apply: "c \ domain(f) \ cons(\c,b\,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(\c,b\,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(\c,b\, 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(\n,b\, 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) + unfolding 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) + unfolding 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) + unfolding 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. \x,y\:r \ \x,y\:s; A<=B\ \ r``A \ s``B" by blast lemma vimage_pair_mono: "\\x y. \x,y\:r \ \x,y\: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 diff --git a/src/ZF/pair.thy b/src/ZF/pair.thy --- a/src/ZF/pair.thy +++ b/src/ZF/pair.thy @@ -1,185 +1,185 @@ (* Title: ZF/pair.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1992 University of Cambridge *) section\Ordered Pairs\ theory pair imports upair begin ML_file \simpdata.ML\ setup \ map_theory_simpset (Simplifier.set_mksimps (fn ctxt => map mk_eq o ZF_atomize o Variable.gen_all ctxt) #> Simplifier.add_cong @{thm if_weak_cong}) \ ML \val ZF_ss = simpset_of \<^context>\ simproc_setup defined_Bex ("\x\A. P(x) \ Q(x)") = \ fn _ => Quantifier1.rearrange_Bex (fn ctxt => unfold_tac ctxt @{thms Bex_def}) \ simproc_setup defined_Ball ("\x\A. P(x) \ Q(x)") = \ fn _ => Quantifier1.rearrange_Ball (fn ctxt => unfold_tac ctxt @{thms Ball_def}) \ (** Lemmas for showing that \a,b\ uniquely determines a and b **) lemma singleton_eq_iff [iff]: "{a} = {b} \ a=b" by (rule extension [THEN iff_trans], blast) lemma doubleton_eq_iff: "{a,b} = {c,d} \ (a=c \ b=d) | (a=d \ b=c)" by (rule extension [THEN iff_trans], blast) lemma Pair_iff [simp]: "\a,b\ = \c,d\ \ a=c \ b=d" by (simp add: Pair_def doubleton_eq_iff, blast) lemmas Pair_inject = Pair_iff [THEN iffD1, THEN conjE, elim!] lemmas Pair_inject1 = Pair_iff [THEN iffD1, THEN conjunct1] lemmas Pair_inject2 = Pair_iff [THEN iffD1, THEN conjunct2] lemma Pair_not_0: "\a,b\ \ 0" -apply (unfold Pair_def) + unfolding Pair_def apply (blast elim: equalityE) done lemmas Pair_neq_0 = Pair_not_0 [THEN notE, elim!] declare sym [THEN Pair_neq_0, elim!] lemma Pair_neq_fst: "\a,b\=a \ P" proof (unfold Pair_def) assume eq: "{{a, a}, {a, b}} = a" have "{a, a} \ {{a, a}, {a, b}}" by (rule consI1) hence "{a, a} \ a" by (simp add: eq) moreover have "a \ {a, a}" by (rule consI1) ultimately show "P" by (rule mem_asym) qed lemma Pair_neq_snd: "\a,b\=b \ P" proof (unfold Pair_def) assume eq: "{{a, a}, {a, b}} = b" have "{a, b} \ {{a, a}, {a, b}}" by blast hence "{a, b} \ b" by (simp add: eq) moreover have "b \ {a, b}" by blast ultimately show "P" by (rule mem_asym) qed subsection\Sigma: Disjoint Union of a Family of Sets\ text\Generalizes Cartesian product\ lemma Sigma_iff [simp]: "\a,b\: Sigma(A,B) \ a \ A \ b \ B(a)" by (simp add: Sigma_def) lemma SigmaI [TC,intro!]: "\a \ A; b \ B(a)\ \ \a,b\ \ Sigma(A,B)" by simp lemmas SigmaD1 = Sigma_iff [THEN iffD1, THEN conjunct1] lemmas SigmaD2 = Sigma_iff [THEN iffD1, THEN conjunct2] (*The general elimination rule*) lemma SigmaE [elim!]: "\c \ Sigma(A,B); \x y.\x \ A; y \ B(x); c=\x,y\\ \ P \ \ P" by (unfold Sigma_def, blast) lemma SigmaE2 [elim!]: "\\a,b\ \ Sigma(A,B); \a \ A; b \ B(a)\ \ P \ \ P" by (unfold Sigma_def, blast) lemma Sigma_cong: "\A=A'; \x. x \ A' \ B(x)=B'(x)\ \ Sigma(A,B) = Sigma(A',B')" by (simp add: Sigma_def) (*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 -> *) lemma Sigma_empty1 [simp]: "Sigma(0,B) = 0" by blast lemma Sigma_empty2 [simp]: "A*0 = 0" by blast lemma Sigma_empty_iff: "A*B=0 \ A=0 | B=0" by blast subsection\Projections \<^term>\fst\ and \<^term>\snd\\ lemma fst_conv [simp]: "fst(\a,b\) = a" by (simp add: fst_def) lemma snd_conv [simp]: "snd(\a,b\) = b" by (simp add: snd_def) lemma fst_type [TC]: "p \ Sigma(A,B) \ fst(p) \ A" by auto lemma snd_type [TC]: "p \ Sigma(A,B) \ snd(p) \ B(fst(p))" by auto lemma Pair_fst_snd_eq: "a \ Sigma(A,B) \ = a" by auto subsection\The Eliminator, \<^term>\split\\ (*A META-equality, so that it applies to higher types as well...*) lemma split [simp]: "split(\x y. c(x,y), \a,b\) \ c(a,b)" by (simp add: split_def) lemma split_type [TC]: "\p \ Sigma(A,B); \x y.\x \ A; y \ B(x)\ \ c(x,y):C(\x,y\) \ \ split(\x y. c(x,y), p) \ C(p)" by (erule SigmaE, auto) lemma expand_split: "u \ A*B \ R(split(c,u)) \ (\x\A. \y\B. u = \x,y\ \ R(c(x,y)))" by (auto simp add: split_def) subsection\A version of \<^term>\split\ for Formulae: Result Type \<^typ>\o\\ lemma splitI: "R(a,b) \ split(R, \a,b\)" by (simp add: split_def) lemma splitE: "\split(R,z); z \ Sigma(A,B); \x y. \z = \x,y\; R(x,y)\ \ P \ \ P" by (auto simp add: split_def) lemma splitD: "split(R,\a,b\) \ R(a,b)" by (simp add: split_def) text \ \bigskip Complex rules for Sigma. \ lemma split_paired_Bex_Sigma [simp]: "(\z \ Sigma(A,B). P(z)) \ (\x \ A. \y \ B(x). P(\x,y\))" by blast lemma split_paired_Ball_Sigma [simp]: "(\z \ Sigma(A,B). P(z)) \ (\x \ A. \y \ B(x). P(\x,y\))" by blast end diff --git a/src/ZF/upair.thy b/src/ZF/upair.thy --- a/src/ZF/upair.thy +++ b/src/ZF/upair.thy @@ -1,528 +1,528 @@ (* Title: ZF/upair.thy Author: Lawrence C Paulson and Martin D Coen, CU Computer Laboratory Copyright 1993 University of Cambridge Observe the order of dependence: Upair is defined in terms of Replace \ is defined in terms of Upair and \(similarly for Int) cons is defined in terms of Upair and Un Ordered pairs and descriptions are defined using cons ("set notation") *) section\Unordered Pairs\ theory upair imports ZF_Base keywords "print_tcset" :: diag begin ML_file \Tools/typechk.ML\ lemma atomize_ball [symmetric, rulify]: "(\x. x \ A \ P(x)) \ Trueprop (\x\A. P(x))" by (simp add: Ball_def atomize_all atomize_imp) subsection\Unordered Pairs: constant \<^term>\Upair\\ lemma Upair_iff [simp]: "c \ Upair(a,b) \ (c=a | c=b)" by (unfold Upair_def, blast) lemma UpairI1: "a \ Upair(a,b)" by simp lemma UpairI2: "b \ Upair(a,b)" by simp lemma UpairE: "\a \ Upair(b,c); a=b \ P; a=c \ P\ \ P" by (simp, blast) subsection\Rules for Binary Union, Defined via \<^term>\Upair\\ lemma Un_iff [simp]: "c \ A \ B \ (c \ A | c \ B)" apply (simp add: Un_def) apply (blast intro: UpairI1 UpairI2 elim: UpairE) done lemma UnI1: "c \ A \ c \ A \ B" by simp lemma UnI2: "c \ B \ c \ A \ B" by simp declare UnI1 [elim?] UnI2 [elim?] lemma UnE [elim!]: "\c \ A \ B; c \ A \ P; c \ B \ P\ \ P" by (simp, blast) (*Stronger version of the rule above*) lemma UnE': "\c \ A \ B; c \ A \ P; \c \ B; c\A\ \ P\ \ P" by (simp, blast) (*Classical introduction rule: no commitment to A vs B*) lemma UnCI [intro!]: "(c \ B \ c \ A) \ c \ A \ B" by (simp, blast) subsection\Rules for Binary Intersection, Defined via \<^term>\Upair\\ lemma Int_iff [simp]: "c \ A \ B \ (c \ A \ c \ B)" -apply (unfold Int_def) + unfolding Int_def apply (blast intro: UpairI1 UpairI2 elim: UpairE) done lemma IntI [intro!]: "\c \ A; c \ B\ \ c \ A \ B" by simp lemma IntD1: "c \ A \ B \ c \ A" by simp lemma IntD2: "c \ A \ B \ c \ B" by simp lemma IntE [elim!]: "\c \ A \ B; \c \ A; c \ B\ \ P\ \ P" by simp subsection\Rules for Set Difference, Defined via \<^term>\Upair\\ lemma Diff_iff [simp]: "c \ A-B \ (c \ A \ c\B)" by (unfold Diff_def, blast) lemma DiffI [intro!]: "\c \ A; c \ B\ \ c \ A - B" by simp lemma DiffD1: "c \ A - B \ c \ A" by simp lemma DiffD2: "c \ A - B \ c \ B" by simp lemma DiffE [elim!]: "\c \ A - B; \c \ A; c\B\ \ P\ \ P" by simp subsection\Rules for \<^term>\cons\\ lemma cons_iff [simp]: "a \ cons(b,A) \ (a=b | a \ A)" -apply (unfold cons_def) + unfolding cons_def apply (blast intro: UpairI1 UpairI2 elim: UpairE) done (*risky as a typechecking rule, but solves otherwise unconstrained goals of the form x \ ?A*) lemma consI1 [simp,TC]: "a \ cons(a,B)" by simp lemma consI2: "a \ B \ a \ cons(b,B)" by simp lemma consE [elim!]: "\a \ cons(b,A); a=b \ P; a \ A \ P\ \ P" by (simp, blast) (*Stronger version of the rule above*) lemma consE': "\a \ cons(b,A); a=b \ P; \a \ A; a\b\ \ P\ \ P" by (simp, blast) (*Classical introduction rule*) lemma consCI [intro!]: "(a\B \ a=b) \ a \ cons(b,B)" by (simp, blast) lemma cons_not_0 [simp]: "cons(a,B) \ 0" by (blast elim: equalityE) lemmas cons_neq_0 = cons_not_0 [THEN notE] declare cons_not_0 [THEN not_sym, simp] subsection\Singletons\ lemma singleton_iff: "a \ {b} \ a=b" by simp lemma singletonI [intro!]: "a \ {a}" by (rule consI1) lemmas singletonE = singleton_iff [THEN iffD1, elim_format, elim!] subsection\Descriptions\ lemma the_equality [intro]: "\P(a); \x. P(x) \ x=a\ \ (THE x. P(x)) = a" -apply (unfold the_def) + unfolding the_def apply (fast dest: subst) done (* Only use this if you already know \!x. P(x) *) lemma the_equality2: "\\!x. P(x); P(a)\ \ (THE x. P(x)) = a" by blast lemma theI: "\!x. P(x) \ P(THE x. P(x))" apply (erule ex1E) apply (subst the_equality) apply (blast+) done (*No congruence rule is necessary: if @{term"\y.P(y)\Q(y)"} then @{term "THE x.P(x)"} rewrites to @{term "THE x.Q(x)"} *) (*If it's "undefined", it's zero!*) lemma the_0: "\ (\!x. P(x)) \ (THE x. P(x))=0" -apply (unfold the_def) + unfolding the_def apply (blast elim!: ReplaceE) done (*Easier to apply than theI: conclusion has only one occurrence of P*) lemma theI2: assumes p1: "\ Q(0) \ \!x. P(x)" and p2: "\x. P(x) \ Q(x)" shows "Q(THE x. P(x))" apply (rule classical) apply (rule p2) apply (rule theI) apply (rule classical) apply (rule p1) apply (erule the_0 [THEN subst], assumption) done lemma the_eq_trivial [simp]: "(THE x. x = a) = a" by blast lemma the_eq_trivial2 [simp]: "(THE x. a = x) = a" by blast subsection\Conditional Terms: \if-then-else\\ lemma if_true [simp]: "(if True then a else b) = a" by (unfold if_def, blast) lemma if_false [simp]: "(if False then a else b) = b" by (unfold if_def, blast) (*Never use with case splitting, or if P is known to be true or false*) lemma if_cong: "\P\Q; Q \ a=c; \Q \ b=d\ \ (if P then a else b) = (if Q then c else d)" by (simp add: if_def cong add: conj_cong) (*Prevents simplification of x and y \ faster and allows the execution of functional programs. NOW THE DEFAULT.*) lemma if_weak_cong: "P\Q \ (if P then x else y) = (if Q then x else y)" by simp (*Not needed for rewriting, since P would rewrite to True anyway*) lemma if_P: "P \ (if P then a else b) = a" by (unfold if_def, blast) (*Not needed for rewriting, since P would rewrite to False anyway*) lemma if_not_P: "\P \ (if P then a else b) = b" by (unfold if_def, blast) lemma split_if [split]: "P(if Q then x else y) \ ((Q \ P(x)) \ (\Q \ P(y)))" by (case_tac Q, simp_all) (** Rewrite rules for boolean case-splitting: faster than split_if [split] **) lemmas split_if_eq1 = split_if [of "\x. x = b"] for b lemmas split_if_eq2 = split_if [of "\x. a = x"] for a lemmas split_if_mem1 = split_if [of "\x. x \ b"] for b lemmas split_if_mem2 = split_if [of "\x. a \ x"] for a lemmas split_ifs = split_if_eq1 split_if_eq2 split_if_mem1 split_if_mem2 (*Logically equivalent to split_if_mem2*) lemma if_iff: "a: (if P then x else y) \ P \ a \ x | \P \ a \ y" by simp lemma if_type [TC]: "\P \ a \ A; \P \ b \ A\ \ (if P then a else b): A" by simp (** Splitting IFs in the assumptions **) lemma split_if_asm: "P(if Q then x else y) \ (\((Q \ \P(x)) | (\Q \ \P(y))))" by simp lemmas if_splits = split_if split_if_asm subsection\Consequences of Foundation\ (*was called mem_anti_sym*) lemma mem_asym: "\a \ b; \P \ b \ a\ \ P" apply (rule classical) apply (rule_tac A1 = "{a,b}" in foundation [THEN disjE]) apply (blast elim!: equalityE)+ done (*was called mem_anti_refl*) lemma mem_irrefl: "a \ a \ P" by (blast intro: mem_asym) (*mem_irrefl should NOT be added to default databases: it would be tried on most goals, making proofs slower!*) lemma mem_not_refl: "a \ a" apply (rule notI) apply (erule mem_irrefl) done (*Good for proving inequalities by rewriting*) lemma mem_imp_not_eq: "a \ A \ a \ A" by (blast elim!: mem_irrefl) lemma eq_imp_not_mem: "a=A \ a \ A" by (blast intro: elim: mem_irrefl) subsection\Rules for Successor\ lemma succ_iff: "i \ succ(j) \ i=j | i \ j" by (unfold succ_def, blast) lemma succI1 [simp]: "i \ succ(i)" by (simp add: succ_iff) lemma succI2: "i \ j \ i \ succ(j)" by (simp add: succ_iff) lemma succE [elim!]: "\i \ succ(j); i=j \ P; i \ j \ P\ \ P" apply (simp add: succ_iff, blast) done (*Classical introduction rule*) lemma succCI [intro!]: "(i\j \ i=j) \ i \ succ(j)" by (simp add: succ_iff, blast) lemma succ_not_0 [simp]: "succ(n) \ 0" by (blast elim!: equalityE) lemmas succ_neq_0 = succ_not_0 [THEN notE, elim!] declare succ_not_0 [THEN not_sym, simp] declare sym [THEN succ_neq_0, elim!] (* @{term"succ(c) \ B \ c \ B"} *) lemmas succ_subsetD = succI1 [THEN [2] subsetD] (* @{term"succ(b) \ b"} *) lemmas succ_neq_self = succI1 [THEN mem_imp_not_eq, THEN not_sym] lemma succ_inject_iff [simp]: "succ(m) = succ(n) \ m=n" by (blast elim: mem_asym elim!: equalityE) lemmas succ_inject = succ_inject_iff [THEN iffD1, dest!] subsection\Miniscoping of the Bounded Universal Quantifier\ lemma ball_simps1: "(\x\A. P(x) \ Q) \ (\x\A. P(x)) \ (A=0 | Q)" "(\x\A. P(x) | Q) \ ((\x\A. P(x)) | Q)" "(\x\A. P(x) \ Q) \ ((\x\A. P(x)) \ Q)" "(\(\x\A. P(x))) \ (\x\A. \P(x))" "(\x\0.P(x)) \ True" "(\x\succ(i).P(x)) \ P(i) \ (\x\i. P(x))" "(\x\cons(a,B).P(x)) \ P(a) \ (\x\B. P(x))" "(\x\RepFun(A,f). P(x)) \ (\y\A. P(f(y)))" "(\x\\(A).P(x)) \ (\y\A. \x\y. P(x))" by blast+ lemma ball_simps2: "(\x\A. P \ Q(x)) \ (A=0 | P) \ (\x\A. Q(x))" "(\x\A. P | Q(x)) \ (P | (\x\A. Q(x)))" "(\x\A. P \ Q(x)) \ (P \ (\x\A. Q(x)))" by blast+ lemma ball_simps3: "(\x\Collect(A,Q).P(x)) \ (\x\A. Q(x) \ P(x))" by blast+ lemmas ball_simps [simp] = ball_simps1 ball_simps2 ball_simps3 lemma ball_conj_distrib: "(\x\A. P(x) \ Q(x)) \ ((\x\A. P(x)) \ (\x\A. Q(x)))" by blast subsection\Miniscoping of the Bounded Existential Quantifier\ lemma bex_simps1: "(\x\A. P(x) \ Q) \ ((\x\A. P(x)) \ Q)" "(\x\A. P(x) | Q) \ (\x\A. P(x)) | (A\0 \ Q)" "(\x\A. P(x) \ Q) \ ((\x\A. P(x)) \ (A\0 \ Q))" "(\x\0.P(x)) \ False" "(\x\succ(i).P(x)) \ P(i) | (\x\i. P(x))" "(\x\cons(a,B).P(x)) \ P(a) | (\x\B. P(x))" "(\x\RepFun(A,f). P(x)) \ (\y\A. P(f(y)))" "(\x\\(A).P(x)) \ (\y\A. \x\y. P(x))" "(\(\x\A. P(x))) \ (\x\A. \P(x))" by blast+ lemma bex_simps2: "(\x\A. P \ Q(x)) \ (P \ (\x\A. Q(x)))" "(\x\A. P | Q(x)) \ (A\0 \ P) | (\x\A. Q(x))" "(\x\A. P \ Q(x)) \ ((A=0 | P) \ (\x\A. Q(x)))" by blast+ lemma bex_simps3: "(\x\Collect(A,Q).P(x)) \ (\x\A. Q(x) \ P(x))" by blast lemmas bex_simps [simp] = bex_simps1 bex_simps2 bex_simps3 lemma bex_disj_distrib: "(\x\A. P(x) | Q(x)) \ ((\x\A. P(x)) | (\x\A. Q(x)))" by blast (** One-point rule for bounded quantifiers: see HOL/Set.ML **) lemma bex_triv_one_point1 [simp]: "(\x\A. x=a) \ (a \ A)" by blast lemma bex_triv_one_point2 [simp]: "(\x\A. a=x) \ (a \ A)" by blast lemma bex_one_point1 [simp]: "(\x\A. x=a \ P(x)) \ (a \ A \ P(a))" by blast lemma bex_one_point2 [simp]: "(\x\A. a=x \ P(x)) \ (a \ A \ P(a))" by blast lemma ball_one_point1 [simp]: "(\x\A. x=a \ P(x)) \ (a \ A \ P(a))" by blast lemma ball_one_point2 [simp]: "(\x\A. a=x \ P(x)) \ (a \ A \ P(a))" by blast subsection\Miniscoping of the Replacement Operator\ text\These cover both \<^term>\Replace\ and \<^term>\Collect\\ lemma Rep_simps [simp]: "{x. y \ 0, R(x,y)} = 0" "{x \ 0. P(x)} = 0" "{x \ A. Q} = (if Q then A else 0)" "RepFun(0,f) = 0" "RepFun(succ(i),f) = cons(f(i), RepFun(i,f))" "RepFun(cons(a,B),f) = cons(f(a), RepFun(B,f))" by (simp_all, blast+) subsection\Miniscoping of Unions\ lemma UN_simps1: "(\x\C. cons(a, B(x))) = (if C=0 then 0 else cons(a, \x\C. B(x)))" "(\x\C. A(x) \ B') = (if C=0 then 0 else (\x\C. A(x)) \ B')" "(\x\C. A' \ B(x)) = (if C=0 then 0 else A' \ (\x\C. B(x)))" "(\x\C. A(x) \ B') = ((\x\C. A(x)) \ B')" "(\x\C. A' \ B(x)) = (A' \ (\x\C. B(x)))" "(\x\C. A(x) - B') = ((\x\C. A(x)) - B')" "(\x\C. A' - B(x)) = (if C=0 then 0 else A' - (\x\C. B(x)))" apply (simp_all add: Inter_def) apply (blast intro!: equalityI )+ done lemma UN_simps2: "(\x\\(A). B(x)) = (\y\A. \x\y. B(x))" "(\z\(\x\A. B(x)). C(z)) = (\x\A. \z\B(x). C(z))" "(\x\RepFun(A,f). B(x)) = (\a\A. B(f(a)))" by blast+ lemmas UN_simps [simp] = UN_simps1 UN_simps2 text\Opposite of miniscoping: pull the operator out\ lemma UN_extend_simps1: "(\x\C. A(x)) \ B = (if C=0 then B else (\x\C. A(x) \ B))" "((\x\C. A(x)) \ B) = (\x\C. A(x) \ B)" "((\x\C. A(x)) - B) = (\x\C. A(x) - B)" apply simp_all apply blast+ done lemma UN_extend_simps2: "cons(a, \x\C. B(x)) = (if C=0 then {a} else (\x\C. cons(a, B(x))))" "A \ (\x\C. B(x)) = (if C=0 then A else (\x\C. A \ B(x)))" "(A \ (\x\C. B(x))) = (\x\C. A \ B(x))" "A - (\x\C. B(x)) = (if C=0 then A else (\x\C. A - B(x)))" "(\y\A. \x\y. B(x)) = (\x\\(A). B(x))" "(\a\A. B(f(a))) = (\x\RepFun(A,f). B(x))" apply (simp_all add: Inter_def) apply (blast intro!: equalityI)+ done lemma UN_UN_extend: "(\x\A. \z\B(x). C(z)) = (\z\(\x\A. B(x)). C(z))" by blast lemmas UN_extend_simps = UN_extend_simps1 UN_extend_simps2 UN_UN_extend subsection\Miniscoping of Intersections\ lemma INT_simps1: "(\x\C. A(x) \ B) = (\x\C. A(x)) \ B" "(\x\C. A(x) - B) = (\x\C. A(x)) - B" "(\x\C. A(x) \ B) = (if C=0 then 0 else (\x\C. A(x)) \ B)" by (simp_all add: Inter_def, blast+) lemma INT_simps2: "(\x\C. A \ B(x)) = A \ (\x\C. B(x))" "(\x\C. A - B(x)) = (if C=0 then 0 else A - (\x\C. B(x)))" "(\x\C. cons(a, B(x))) = (if C=0 then 0 else cons(a, \x\C. B(x)))" "(\x\C. A \ B(x)) = (if C=0 then 0 else A \ (\x\C. B(x)))" apply (simp_all add: Inter_def) apply (blast intro!: equalityI)+ done lemmas INT_simps [simp] = INT_simps1 INT_simps2 text\Opposite of miniscoping: pull the operator out\ lemma INT_extend_simps1: "(\x\C. A(x)) \ B = (\x\C. A(x) \ B)" "(\x\C. A(x)) - B = (\x\C. A(x) - B)" "(\x\C. A(x)) \ B = (if C=0 then B else (\x\C. A(x) \ B))" apply (simp_all add: Inter_def, blast+) done lemma INT_extend_simps2: "A \ (\x\C. B(x)) = (\x\C. A \ B(x))" "A - (\x\C. B(x)) = (if C=0 then A else (\x\C. A - B(x)))" "cons(a, \x\C. B(x)) = (if C=0 then {a} else (\x\C. cons(a, B(x))))" "A \ (\x\C. B(x)) = (if C=0 then A else (\x\C. A \ B(x)))" apply (simp_all add: Inter_def) apply (blast intro!: equalityI)+ done lemmas INT_extend_simps = INT_extend_simps1 INT_extend_simps2 subsection\Other simprules\ (*** Miniscoping: pushing in big Unions, Intersections, quantifiers, etc. ***) lemma misc_simps [simp]: "0 \ A = A" "A \ 0 = A" "0 \ A = 0" "A \ 0 = 0" "0 - A = 0" "A - 0 = A" "\(0) = 0" "\(cons(b,A)) = b \ \(A)" "\({b}) = b" by blast+ end