# HG changeset patch # User wenzelm # Date 1470413668 -7200 # Node ID 7195acc2fe935ad710bf32c842754d93543c78fd # Parent fb63942e470eeceddb53b8fcd55dfade24b7e7ef misc tuning and modernization; diff -r fb63942e470e -r 7195acc2fe93 src/HOL/Complete_Partial_Order.thy --- a/src/HOL/Complete_Partial_Order.thy Fri Aug 05 16:36:03 2016 +0200 +++ b/src/HOL/Complete_Partial_Order.thy Fri Aug 05 18:14:28 2016 +0200 @@ -1,12 +1,12 @@ -(* Title: HOL/Complete_Partial_Order.thy - Author: Brian Huffman, Portland State University - Author: Alexander Krauss, TU Muenchen +(* Title: HOL/Complete_Partial_Order.thy + Author: Brian Huffman, Portland State University + Author: Alexander Krauss, TU Muenchen *) section \Chain-complete partial orders and their fixpoints\ theory Complete_Partial_Order -imports Product_Type + imports Product_Type begin subsection \Monotone functions\ @@ -14,131 +14,139 @@ text \Dictionary-passing version of @{const Orderings.mono}.\ definition monotone :: "('a \ 'a \ bool) \ ('b \ 'b \ bool) \ ('a \ 'b) \ bool" -where "monotone orda ordb f \ (\x y. orda x y \ ordb (f x) (f y))" + where "monotone orda ordb f \ (\x y. orda x y \ ordb (f x) (f y))" -lemma monotoneI[intro?]: "(\x y. orda x y \ ordb (f x) (f y)) - \ monotone orda ordb f" -unfolding monotone_def by iprover +lemma monotoneI[intro?]: "(\x y. orda x y \ ordb (f x) (f y)) \ monotone orda ordb f" + unfolding monotone_def by iprover lemma monotoneD[dest?]: "monotone orda ordb f \ orda x y \ ordb (f x) (f y)" -unfolding monotone_def by iprover + unfolding monotone_def by iprover subsection \Chains\ -text \A chain is a totally-ordered set. Chains are parameterized over +text \ + A chain is a totally-ordered set. Chains are parameterized over the order for maximal flexibility, since type classes are not enough. \ -definition - chain :: "('a \ 'a \ bool) \ 'a set \ bool" -where - "chain ord S \ (\x\S. \y\S. ord x y \ ord y x)" +definition chain :: "('a \ 'a \ bool) \ 'a set \ bool" + where "chain ord S \ (\x\S. \y\S. ord x y \ ord y x)" lemma chainI: assumes "\x y. x \ S \ y \ S \ ord x y \ ord y x" shows "chain ord S" -using assms unfolding chain_def by fast + using assms unfolding chain_def by fast lemma chainD: assumes "chain ord S" and "x \ S" and "y \ S" shows "ord x y \ ord y x" -using assms unfolding chain_def by fast + using assms unfolding chain_def by fast lemma chainE: assumes "chain ord S" and "x \ S" and "y \ S" obtains "ord x y" | "ord y x" -using assms unfolding chain_def by fast + using assms unfolding chain_def by fast lemma chain_empty: "chain ord {}" -by(simp add: chain_def) + by (simp add: chain_def) lemma chain_equality: "chain op = A \ (\x\A. \y\A. x = y)" -by(auto simp add: chain_def) + by (auto simp add: chain_def) + +lemma chain_subset: "chain ord A \ B \ A \ chain ord B" + by (rule chainI) (blast dest: chainD) -lemma chain_subset: - "\ chain ord A; B \ A \ - \ chain ord B" -by(rule chainI)(blast dest: chainD) +lemma chain_imageI: + assumes chain: "chain le_a Y" + and mono: "\x y. x \ Y \ y \ Y \ le_a x y \ le_b (f x) (f y)" + shows "chain le_b (f ` Y)" + by (blast intro: chainI dest: chainD[OF chain] mono) -lemma chain_imageI: - assumes chain: "chain le_a Y" - and mono: "\x y. \ x \ Y; y \ Y; le_a x y \ \ le_b (f x) (f y)" - shows "chain le_b (f ` Y)" -by(blast intro: chainI dest: chainD[OF chain] mono) subsection \Chain-complete partial orders\ text \ - A ccpo has a least upper bound for any chain. In particular, the - empty set is a chain, so every ccpo must have a bottom element. + A \ccpo\ has a least upper bound for any chain. In particular, the + empty set is a chain, so every \ccpo\ must have a bottom element. \ class ccpo = order + Sup + - assumes ccpo_Sup_upper: "\chain (op \) A; x \ A\ \ x \ Sup A" - assumes ccpo_Sup_least: "\chain (op \) A; \x. x \ A \ x \ z\ \ Sup A \ z" + assumes ccpo_Sup_upper: "chain (op \) A \ x \ A \ x \ Sup A" + assumes ccpo_Sup_least: "chain (op \) A \ (\x. x \ A \ x \ z) \ Sup A \ z" begin lemma chain_singleton: "Complete_Partial_Order.chain op \ {x}" -by(rule chainI) simp + by (rule chainI) simp lemma ccpo_Sup_singleton [simp]: "\{x} = x" -by(rule antisym)(auto intro: ccpo_Sup_least ccpo_Sup_upper simp add: chain_singleton) + by (rule antisym)(auto intro: ccpo_Sup_least ccpo_Sup_upper simp add: chain_singleton) + subsection \Transfinite iteration of a function\ -context notes [[inductive_internals]] begin +context notes [[inductive_internals]] +begin inductive_set iterates :: "('a \ 'a) \ 'a set" -for f :: "'a \ 'a" -where - step: "x \ iterates f \ f x \ iterates f" -| Sup: "chain (op \) M \ \x\M. x \ iterates f \ Sup M \ iterates f" + for f :: "'a \ 'a" + where + step: "x \ iterates f \ f x \ iterates f" + | Sup: "chain (op \) M \ \x\M. x \ iterates f \ Sup M \ iterates f" end -lemma iterates_le_f: - "x \ iterates f \ monotone (op \) (op \) f \ x \ f x" -by (induct x rule: iterates.induct) - (force dest: monotoneD intro!: ccpo_Sup_upper ccpo_Sup_least)+ +lemma iterates_le_f: "x \ iterates f \ monotone (op \) (op \) f \ x \ f x" + by (induct x rule: iterates.induct) + (force dest: monotoneD intro!: ccpo_Sup_upper ccpo_Sup_least)+ lemma chain_iterates: assumes f: "monotone (op \) (op \) f" shows "chain (op \) (iterates f)" (is "chain _ ?C") proof (rule chainI) - fix x y assume "x \ ?C" "y \ ?C" + fix x y + assume "x \ ?C" "y \ ?C" then show "x \ y \ y \ x" proof (induct x arbitrary: y rule: iterates.induct) - fix x y assume y: "y \ ?C" - and IH: "\z. z \ ?C \ x \ z \ z \ x" + fix x y + assume y: "y \ ?C" + and IH: "\z. z \ ?C \ x \ z \ z \ x" from y show "f x \ y \ y \ f x" proof (induct y rule: iterates.induct) - case (step y) with IH f show ?case by (auto dest: monotoneD) + case (step y) + with IH f show ?case by (auto dest: monotoneD) next case (Sup M) then have chM: "chain (op \) M" and IH': "\z. z \ M \ f x \ z \ z \ f x" by auto show "f x \ Sup M \ Sup M \ f x" proof (cases "\z\M. f x \ z") - case True then have "f x \ Sup M" + case True + then have "f x \ Sup M" apply rule apply (erule order_trans) - by (rule ccpo_Sup_upper[OF chM]) - thus ?thesis .. + apply (rule ccpo_Sup_upper[OF chM]) + apply assumption + done + then show ?thesis .. next - case False with IH' - show ?thesis by (auto intro: ccpo_Sup_least[OF chM]) + case False + with IH' show ?thesis + by (auto intro: ccpo_Sup_least[OF chM]) qed qed next case (Sup M y) show ?case proof (cases "\x\M. y \ x") - case True then have "y \ Sup M" + case True + then have "y \ Sup M" apply rule apply (erule order_trans) - by (rule ccpo_Sup_upper[OF Sup(1)]) - thus ?thesis .. + apply (rule ccpo_Sup_upper[OF Sup(1)]) + apply assumption + done + then show ?thesis .. next case False with Sup show ?thesis by (auto intro: ccpo_Sup_least) @@ -147,19 +155,19 @@ qed lemma bot_in_iterates: "Sup {} \ iterates f" -by(auto intro: iterates.Sup simp add: chain_empty) + by (auto intro: iterates.Sup simp add: chain_empty) + subsection \Fixpoint combinator\ -definition - fixp :: "('a \ 'a) \ 'a" -where - "fixp f = Sup (iterates f)" +definition fixp :: "('a \ 'a) \ 'a" + where "fixp f = Sup (iterates f)" lemma iterates_fixp: - assumes f: "monotone (op \) (op \) f" shows "fixp f \ iterates f" -unfolding fixp_def -by (simp add: iterates.Sup chain_iterates f) + assumes f: "monotone (op \) (op \) f" + shows "fixp f \ iterates f" + unfolding fixp_def + by (simp add: iterates.Sup chain_iterates f) lemma fixp_unfold: assumes f: "monotone (op \) (op \) f" @@ -169,35 +177,45 @@ by (intro iterates_le_f iterates_fixp f) have "f (fixp f) \ Sup (iterates f)" by (intro ccpo_Sup_upper chain_iterates f iterates.step iterates_fixp) - thus "f (fixp f) \ fixp f" - unfolding fixp_def . + then show "f (fixp f) \ fixp f" + by (simp only: fixp_def) qed lemma fixp_lowerbound: - assumes f: "monotone (op \) (op \) f" and z: "f z \ z" shows "fixp f \ z" -unfolding fixp_def + assumes f: "monotone (op \) (op \) f" + and z: "f z \ z" + shows "fixp f \ z" + unfolding fixp_def proof (rule ccpo_Sup_least[OF chain_iterates[OF f]]) - fix x assume "x \ iterates f" - thus "x \ z" + fix x + assume "x \ iterates f" + then show "x \ z" proof (induct x rule: iterates.induct) - fix x assume "x \ z" with f have "f x \ f z" by (rule monotoneD) - also note z finally show "f x \ z" . - qed (auto intro: ccpo_Sup_least) + case (step x) + from f \x \ z\ have "f x \ f z" by (rule monotoneD) + also note z + finally show "f x \ z" . + next + case (Sup M) + then show ?case + by (auto intro: ccpo_Sup_least) + qed qed end + subsection \Fixpoint induction\ setup \Sign.map_naming (Name_Space.mandatory_path "ccpo")\ definition admissible :: "('a set \ 'a) \ ('a \ 'a \ bool) \ ('a \ bool) \ bool" -where "admissible lub ord P = (\A. chain ord A \ (A \ {}) \ (\x\A. P x) \ P (lub A))" + where "admissible lub ord P \ (\A. chain ord A \ A \ {} \ (\x\A. P x) \ P (lub A))" lemma admissibleI: assumes "\A. chain ord A \ A \ {} \ \x\A. P x \ P (lub A)" shows "ccpo.admissible lub ord P" -using assms unfolding ccpo.admissible_def by fast + using assms unfolding ccpo.admissible_def by fast lemma admissibleD: assumes "ccpo.admissible lub ord P" @@ -205,7 +223,7 @@ assumes "A \ {}" assumes "\x. x \ A \ P x" shows "P (lub A)" -using assms by (auto simp: ccpo.admissible_def) + using assms by (auto simp: ccpo.admissible_def) setup \Sign.map_naming Name_Space.parent_path\ @@ -215,44 +233,54 @@ assumes bot: "P (Sup {})" assumes step: "\x. P x \ P (f x)" shows "P (fixp f)" -unfolding fixp_def using adm chain_iterates[OF mono] + unfolding fixp_def + using adm chain_iterates[OF mono] proof (rule ccpo.admissibleD) - show "iterates f \ {}" using bot_in_iterates by auto - fix x assume "x \ iterates f" - thus "P x" - by (induct rule: iterates.induct) - (case_tac "M = {}", auto intro: step bot ccpo.admissibleD adm) + show "iterates f \ {}" + using bot_in_iterates by auto +next + fix x + assume "x \ iterates f" + then show "P x" + proof (induct rule: iterates.induct) + case prems: (step x) + from this(2) show ?case by (rule step) + next + case (Sup M) + then show ?case by (cases "M = {}") (auto intro: step bot ccpo.admissibleD adm) + qed qed lemma admissible_True: "ccpo.admissible lub ord (\x. True)" -unfolding ccpo.admissible_def by simp + unfolding ccpo.admissible_def by simp (*lemma admissible_False: "\ ccpo.admissible lub ord (\x. False)" unfolding ccpo.admissible_def chain_def by simp *) lemma admissible_const: "ccpo.admissible lub ord (\x. t)" -by(auto intro: ccpo.admissibleI) + by (auto intro: ccpo.admissibleI) lemma admissible_conj: assumes "ccpo.admissible lub ord (\x. P x)" assumes "ccpo.admissible lub ord (\x. Q x)" shows "ccpo.admissible lub ord (\x. P x \ Q x)" -using assms unfolding ccpo.admissible_def by simp + using assms unfolding ccpo.admissible_def by simp lemma admissible_all: assumes "\y. ccpo.admissible lub ord (\x. P x y)" shows "ccpo.admissible lub ord (\x. \y. P x y)" -using assms unfolding ccpo.admissible_def by fast + using assms unfolding ccpo.admissible_def by fast lemma admissible_ball: assumes "\y. y \ A \ ccpo.admissible lub ord (\x. P x y)" shows "ccpo.admissible lub ord (\x. \y\A. P x y)" -using assms unfolding ccpo.admissible_def by fast + using assms unfolding ccpo.admissible_def by fast lemma chain_compr: "chain ord A \ chain ord {x \ A. P x}" -unfolding chain_def by fast + unfolding chain_def by fast -context ccpo begin +context ccpo +begin lemma admissible_disj_lemma: assumes A: "chain (op \)A" @@ -280,17 +308,24 @@ assumes Q: "ccpo.admissible Sup (op \) (\x. Q x)" shows "ccpo.admissible Sup (op \) (\x. P x \ Q x)" proof (rule ccpo.admissibleI) - fix A :: "'a set" assume A: "chain (op \) A" - assume "A \ {}" - and "\x\A. P x \ Q x" - hence "(\x\A. P x) \ (\x\A. \y\A. x \ y \ P y) \ (\x\A. Q x) \ (\x\A. \y\A. x \ y \ Q y)" - using chainD[OF A] by blast - hence "(\x. x \ A \ P x) \ Sup A = Sup {x \ A. P x} \ (\x. x \ A \ Q x) \ Sup A = Sup {x \ A. Q x}" + fix A :: "'a set" + assume A: "chain (op \) A" + assume "A \ {}" and "\x\A. P x \ Q x" + then have "(\x\A. P x) \ (\x\A. \y\A. x \ y \ P y) \ (\x\A. Q x) \ (\x\A. \y\A. x \ y \ Q y)" + using chainD[OF A] by blast (* slow *) + then have "(\x. x \ A \ P x) \ Sup A = Sup {x \ A. P x} \ (\x. x \ A \ Q x) \ Sup A = Sup {x \ A. Q x}" using admissible_disj_lemma [OF A] by blast - thus "P (Sup A) \ Q (Sup A)" - apply (rule disjE, simp_all) - apply (rule disjI1, rule ccpo.admissibleD [OF P chain_compr [OF A]], simp, simp) - apply (rule disjI2, rule ccpo.admissibleD [OF Q chain_compr [OF A]], simp, simp) + then show "P (Sup A) \ Q (Sup A)" + apply (rule disjE) + apply simp_all + apply (rule disjI1) + apply (rule ccpo.admissibleD [OF P chain_compr [OF A]]) + apply simp + apply simp + apply (rule disjI2) + apply (rule ccpo.admissibleD [OF Q chain_compr [OF A]]) + apply simp + apply simp done qed @@ -300,7 +335,8 @@ by standard (fast intro: Sup_upper Sup_least)+ lemma lfp_eq_fixp: - assumes f: "mono f" shows "lfp f = fixp f" + assumes f: "mono f" + shows "lfp f = fixp f" proof (rule antisym) from f have f': "monotone (op \) (op \) f" unfolding mono_def monotone_def . diff -r fb63942e470e -r 7195acc2fe93 src/HOL/Finite_Set.thy --- a/src/HOL/Finite_Set.thy Fri Aug 05 16:36:03 2016 +0200 +++ b/src/HOL/Finite_Set.thy Fri Aug 05 18:14:28 2016 +0200 @@ -1,24 +1,26 @@ (* Title: HOL/Finite_Set.thy - Author: Tobias Nipkow, Lawrence C Paulson and Markus Wenzel - with contributions by Jeremy Avigad and Andrei Popescu + Author: Tobias Nipkow + Author: Lawrence C Paulson + Author: Markus Wenzel + Author: Jeremy Avigad + Author: Andrei Popescu *) section \Finite sets\ theory Finite_Set -imports Product_Type Sum_Type Fields + imports Product_Type Sum_Type Fields begin subsection \Predicate for finite sets\ -context - notes [[inductive_internals]] +context notes [[inductive_internals]] begin inductive finite :: "'a set \ bool" -where - emptyI [simp, intro!]: "finite {}" -| insertI [simp, intro!]: "finite A \ finite (insert a A)" + where + emptyI [simp, intro!]: "finite {}" + | insertI [simp, intro!]: "finite A \ finite (insert a A)" end @@ -145,7 +147,7 @@ shows "\f n::nat. f ` A = {i. i < n} \ inj_on f A" proof - from finite_imp_nat_seg_image_inj_on [OF \finite A\] - obtain f and n::nat where bij: "bij_betw f {i. i ?f ` A = {i. i inj_on h A \ finite (h -` F \ A)" @@ -328,7 +330,8 @@ done lemma finite_finite_vimage_IntI: - assumes "finite F" and "\y. y \ F \ finite ((h -` {y}) \ A)" + assumes "finite F" + and "\y. y \ F \ finite ((h -` {y}) \ A)" shows "finite (h -` F \ A)" proof - have *: "h -` F \ A = (\ y\F. (h -` {y}) \ A)" @@ -464,7 +467,7 @@ proof assume "finite (Pow A)" then have "finite ((\x. {x}) ` A)" - by (blast intro: finite_subset) + by (blast intro: finite_subset) (* somewhat slow *) then show "finite A" by (rule finite_imageD [unfolded inj_on_def]) simp next @@ -492,7 +495,7 @@ from finite_subset[OF this] assms have 1: "finite (?F ` ?S)" by simp have 2: "inj_on ?F ?S" - by (fastforce simp add: inj_on_def set_eq_iff fun_eq_iff) + by (fastforce simp add: inj_on_def set_eq_iff fun_eq_iff) (* somewhat slow *) show ?thesis by (rule finite_imageD [OF 1 2]) qed @@ -524,7 +527,7 @@ lemma finite_subset_induct [consumes 2, case_names empty insert]: assumes "finite F" and "F \ A" - assumes empty: "P {}" + and empty: "P {}" and insert: "\a F. finite F \ a \ A \ a \ F \ P F \ P (insert a F)" shows "P F" using \finite F\ \F \ A\ @@ -545,7 +548,7 @@ lemma finite_empty_induct: assumes "finite A" - assumes "P A" + and "P A" and remove: "\a A. finite A \ a \ A \ P A \ P (A - {a})" shows "P {}" proof - @@ -604,8 +607,8 @@ lemma finite_subset_induct' [consumes 2, case_names empty insert]: assumes "finite F" and "F \ A" - and empty: "P {}" - and insert: "\a F. \finite F; a \ A; F \ A; a \ F; P F \ \ P (insert a F)" + and empty: "P {}" + and insert: "\a F. \finite F; a \ A; F \ A; a \ F; P F \ \ P (insert a F)" shows "P F" proof - from \finite F\ @@ -632,7 +635,8 @@ subsection \Class \finite\\ -class finite = assumes finite_UNIV: "finite (UNIV :: 'a set)" +class finite = + assumes finite_UNIV: "finite (UNIV :: 'a set)" begin lemma finite [simp]: "finite (A :: 'a set)" @@ -700,9 +704,9 @@ inductive fold_graph :: "('a \ 'b \ 'b) \ 'b \ 'a set \ 'b \ bool" for f :: "'a \ 'b \ 'b" and z :: 'b -where - emptyI [intro]: "fold_graph f z {} z" -| insertI [intro]: "x \ A \ fold_graph f z A y \ fold_graph f z (insert x A) (f x y)" + where + emptyI [intro]: "fold_graph f z {} z" + | insertI [intro]: "x \ A \ fold_graph f z A y \ fold_graph f z (insert x A) (f x y)" inductive_cases empty_fold_graphE [elim!]: "fold_graph f z {} x" @@ -1069,7 +1073,7 @@ interpret comp_fun_idem Set.remove by (fact comp_fun_idem_remove) from \finite A\ have "fold Set.remove B A = B - A" - by (induct A arbitrary: B) auto + by (induct A arbitrary: B) auto (* slow *) then show ?thesis .. qed @@ -1124,7 +1128,7 @@ qed lemma comp_fun_commute_Pow_fold: "comp_fun_commute (\x A. A \ Set.insert x ` A)" - by (clarsimp simp: fun_eq_iff comp_fun_commute_def) blast + by (clarsimp simp: fun_eq_iff comp_fun_commute_def) blast (* somewhat slow *) lemma Pow_fold: assumes "finite A" @@ -1222,13 +1226,12 @@ subsubsection \The natural case\ locale folding = - fixes f :: "'a \ 'b \ 'b" - fixes z :: "'b" + fixes f :: "'a \ 'b \ 'b" and z :: "'b" assumes comp_fun_commute: "f y \ f x = f x \ f y" begin interpretation fold?: comp_fun_commute f - by standard (insert comp_fun_commute, simp add: fun_eq_iff) + by standard (use comp_fun_commute in \simp add: fun_eq_iff\) definition F :: "'a set \ 'b" where eq_fold: "F A = fold f z A" @@ -1332,14 +1335,14 @@ lemma card_Suc_Diff1: "finite A \ x \ A \ Suc (card (A - {x})) = card A" apply (rule insert_Diff [THEN subst, where t = A]) - apply assumption + apply assumption apply (simp del: insert_Diff_single) done lemma card_insert_le_m1: "n > 0 \ card y \ n - 1 \ card (insert x y) \ n" apply (cases "finite y") - apply (cases "x \ y") - apply (auto simp: insert_absorb) + apply (cases "x \ y") + apply (auto simp: insert_absorb) done lemma card_Diff_singleton: "finite A \ x \ A \ card (A - {x}) = card A - 1" @@ -1397,7 +1400,7 @@ lemma card_seteq: "finite B \ (\A. A \ B \ card B \ card A \ A = B)" apply (induct rule: finite_induct) - apply simp + apply simp apply clarify apply (subgoal_tac "finite A \ A - {x} \ F") prefer 2 apply (blast intro: finite_subset, atomize) @@ -1430,7 +1433,7 @@ lemma card_Un_le: "card (A \ B) \ card A + card B" apply (cases "finite A") apply (cases "finite B") - using le_iff_add card_Un_Int apply blast + apply (use le_iff_add card_Un_Int in blast) apply simp apply simp done @@ -1539,7 +1542,7 @@ lemma insert_partition: "x \ F \ \c1 \ insert x F. \c2 \ insert x F. c1 \ c2 \ c1 \ c2 = {} \ x \ \F = {}" - by auto + by auto (* somewhat slow *) lemma finite_psubset_induct [consumes 1, case_names psubset]: assumes finite: "finite A" @@ -1597,13 +1600,13 @@ and remove: "\A. finite A \ A \ {} \ A \ B \ (\x. x \ A \ P (A - {x})) \ P A" shows "P B" proof (cases "finite B") - assume "\finite B" + case False then show ?thesis by (rule infinite) next + case True define A where "A = B" - assume "finite B" - then have "finite A" "A \ B" - by (simp_all add: A_def) + with True have "finite A" "A \ B" + by simp_all then show "P A" proof (induct "card A" arbitrary: A) case 0 @@ -1623,9 +1626,9 @@ lemma finite_remove_induct [consumes 1, case_names empty remove]: fixes P :: "'a set \ bool" - assumes finite: "finite B" - and empty: "P {}" - and rm: "\A. finite A \ A \ {} \ A \ B \ (\x. x \ A \ P (A - {x})) \ P A" + assumes "finite B" + and "P {}" + and "\A. finite A \ A \ {} \ A \ B \ (\x. x \ A \ P (A - {x})) \ P A" defines "B' \ B" shows "P B'" by (induct B' rule: remove_induct) (simp_all add: assms) @@ -1636,10 +1639,14 @@ "finite C \ finite (\C) \ (\c\C. card c = k) \ (\c1 \ C. \c2 \ C. c1 \ c2 \ c1 \ c2 = {}) \ k * card C = card (\C)" - apply (induct rule: finite_induct) - apply simp - apply (simp add: card_Un_disjoint insert_partition finite_subset [of _ "\(insert x F)"]) - done +proof (induct rule: finite_induct) + case empty + then show ?case by simp +next + case (insert x F) + then show ?case + by (simp add: card_Un_disjoint insert_partition finite_subset [of _ "\(insert _ _)"]) +qed lemma card_eq_UNIV_imp_eq_UNIV: assumes fin: "finite (UNIV :: 'a set)" @@ -1679,7 +1686,7 @@ show "b \ A - {b}" by blast show "card (A - {b}) = k" and "k = 0 \ A - {b} = {}" - using assms b fin by(fastforce dest:mk_disjoint_insert)+ + using assms b fin by (fastforce dest: mk_disjoint_insert)+ qed qed @@ -1688,7 +1695,7 @@ (\b B. A = insert b B \ b \ B \ card B = k \ (k = 0 \ B = {}))" apply (auto elim!: card_eq_SucD) apply (subst card.insert) - apply (auto simp add: intro:ccontr) + apply (auto simp add: intro:ccontr) done lemma card_1_singletonE: @@ -1761,7 +1768,7 @@ qed lemma bij_betw_same_card: "bij_betw f A B \ card A = card B" - by(auto simp: card_image bij_betw_def) + by (auto simp: card_image bij_betw_def) lemma endo_inj_surj: "finite A \ f ` A \ A \ inj_on f A \ f ` A = A" by (simp add: card_seteq card_image) @@ -1852,12 +1859,12 @@ from finite_Pow_iff[THEN iffD2, OF \finite B\] have "finite (?F ` A)" by (blast intro: rev_finite_subset) from pigeonhole_infinite [where f = ?F, OF assms(1) this] - obtain a0 where "a0 \ A" and 1: "\ finite {a\A. ?F a = ?F a0}" .. + obtain a0 where "a0 \ A" and infinite: "\ finite {a\A. ?F a = ?F a0}" .. obtain b0 where "b0 \ B" and "R a0 b0" using \a0 \ A\ assms(3) by blast - have "finite {a\A. ?F a = ?F a0}" if "finite{a:A. R a b0}" + have "finite {a\A. ?F a = ?F a0}" if "finite {a\A. R a b0}" using \b0 \ B\ \R a0 b0\ that by (blast intro: rev_finite_subset) - with 1 \b0 : B\ show ?thesis + with infinite \b0 \ B\ show ?thesis by blast qed @@ -1896,7 +1903,7 @@ then show ?case apply simp apply (subst card_Un_disjoint) - apply (auto simp add: disjoint_eq_subset_Compl) + apply (auto simp add: disjoint_eq_subset_Compl) done qed qed @@ -1914,10 +1921,12 @@ by (simp add: eq_card_imp_inj_on) qed -lemma finite_UNIV_surj_inj: "finite(UNIV:: 'a set) \ surj f \ inj f" for f :: "'a \ 'a" +lemma finite_UNIV_surj_inj: "finite(UNIV:: 'a set) \ surj f \ inj f" + for f :: "'a \ 'a" by (blast intro: finite_surj_inj subset_UNIV) -lemma finite_UNIV_inj_surj: "finite(UNIV:: 'a set) \ inj f \ surj f" for f :: "'a \ 'a" +lemma finite_UNIV_inj_surj: "finite(UNIV:: 'a set) \ inj f \ surj f" + for f :: "'a \ 'a" by (fastforce simp:surj_def dest!: endo_inj_surj) corollary infinite_UNIV_nat [iff]: "\ finite (UNIV :: nat set)" @@ -2013,7 +2022,7 @@ using psubset.hyps by blast show False apply (rule psubset.IH [where B = "A - {x}"]) - using \x \ A\ apply blast + apply (use \x \ A\ in blast) apply (simp add: \X (A - {x})\) done qed diff -r fb63942e470e -r 7195acc2fe93 src/HOL/Hilbert_Choice.thy --- a/src/HOL/Hilbert_Choice.thy Fri Aug 05 16:36:03 2016 +0200 +++ b/src/HOL/Hilbert_Choice.thy Fri Aug 05 18:14:28 2016 +0200 @@ -6,23 +6,23 @@ section \Hilbert's Epsilon-Operator and the Axiom of Choice\ theory Hilbert_Choice -imports Wellfounded -keywords "specification" :: thy_goal + imports Wellfounded + keywords "specification" :: thy_goal begin subsection \Hilbert's epsilon\ -axiomatization Eps :: "('a => bool) => 'a" where - someI: "P x ==> P (Eps P)" +axiomatization Eps :: "('a \ bool) \ 'a" + where someI: "P x \ P (Eps P)" syntax (epsilon) - "_Eps" :: "[pttrn, bool] => 'a" ("(3\_./ _)" [0, 10] 10) + "_Eps" :: "pttrn \ bool \ 'a" ("(3\_./ _)" [0, 10] 10) syntax (input) - "_Eps" :: "[pttrn, bool] => 'a" ("(3@ _./ _)" [0, 10] 10) + "_Eps" :: "pttrn \ bool \ 'a" ("(3@ _./ _)" [0, 10] 10) syntax - "_Eps" :: "[pttrn, bool] => 'a" ("(3SOME _./ _)" [0, 10] 10) + "_Eps" :: "pttrn \ bool \ 'a" ("(3SOME _./ _)" [0, 10] 10) translations - "SOME x. P" == "CONST Eps (%x. P)" + "SOME x. P" \ "CONST Eps (\x. P)" print_translation \ [(@{const_syntax Eps}, fn _ => fn [Abs abs] => @@ -30,90 +30,92 @@ in Syntax.const @{syntax_const "_Eps"} $ x $ t end)] \ \ \to avoid eta-contraction of body\ -definition inv_into :: "'a set => ('a => 'b) => ('b => 'a)" where -"inv_into A f == %x. SOME y. y : A & f y = x" +definition inv_into :: "'a set \ ('a \ 'b) \ ('b \ 'a)" + where "inv_into A f \ \x. SOME y. y \ A \ f y = x" -abbreviation inv :: "('a => 'b) => ('b => 'a)" where -"inv == inv_into UNIV" +abbreviation inv :: "('a \ 'b) \ ('b \ 'a)" + where "inv \ inv_into UNIV" subsection \Hilbert's Epsilon-operator\ -text\Easier to apply than \someI\ if the witness comes from an -existential formula\ -lemma someI_ex [elim?]: "\x. P x ==> P (SOME x. P x)" -apply (erule exE) -apply (erule someI) -done +text \ + Easier to apply than \someI\ if the witness comes from an + existential formula. +\ +lemma someI_ex [elim?]: "\x. P x \ P (SOME x. P x)" + apply (erule exE) + apply (erule someI) + done -text\Easier to apply than \someI\ because the conclusion has only one -occurrence of @{term P}.\ -lemma someI2: "[| P a; !!x. P x ==> Q x |] ==> Q (SOME x. P x)" +text \ + Easier to apply than \someI\ because the conclusion has only one + occurrence of @{term P}. +\ +lemma someI2: "P a \ (\x. P x \ Q x) \ Q (SOME x. P x)" by (blast intro: someI) -text\Easier to apply than \someI2\ if the witness comes from an -existential formula\ - -lemma someI2_ex: "[| \a. P a; !!x. P x ==> Q x |] ==> Q (SOME x. P x)" - by (blast intro: someI2) - -lemma someI2_bex: "[| \a\A. P a; !!x. x \ A \ P x ==> Q x |] ==> Q (SOME x. x \ A \ P x)" +text \ + Easier to apply than \someI2\ if the witness comes from an + existential formula. +\ +lemma someI2_ex: "\a. P a \ (\x. P x \ Q x) \ Q (SOME x. P x)" by (blast intro: someI2) -lemma some_equality [intro]: - "[| P a; !!x. P x ==> x=a |] ==> (SOME x. P x) = a" -by (blast intro: someI2) +lemma someI2_bex: "\a\A. P a \ (\x. x \ A \ P x \ Q x) \ Q (SOME x. x \ A \ P x)" + by (blast intro: someI2) + +lemma some_equality [intro]: "P a \ (\x. P x \ x = a) \ (SOME x. P x) = a" + by (blast intro: someI2) -lemma some1_equality: "[| EX!x. P x; P a |] ==> (SOME x. P x) = a" -by blast +lemma some1_equality: "EX!x. P x \ P a \ (SOME x. P x) = a" + by blast -lemma some_eq_ex: "P (SOME x. P x) = (\x. P x)" -by (blast intro: someI) +lemma some_eq_ex: "P (SOME x. P x) \ (\x. P x)" + by (blast intro: someI) lemma some_in_eq: "(SOME x. x \ A) \ A \ A \ {}" unfolding ex_in_conv[symmetric] by (rule some_eq_ex) -lemma some_eq_trivial [simp]: "(SOME y. y=x) = x" -apply (rule some_equality) -apply (rule refl, assumption) -done +lemma some_eq_trivial [simp]: "(SOME y. y = x) = x" + by (rule some_equality) (rule refl) -lemma some_sym_eq_trivial [simp]: "(SOME y. x=y) = x" -apply (rule some_equality) -apply (rule refl) -apply (erule sym) -done +lemma some_sym_eq_trivial [simp]: "(SOME y. x = y) = x" + apply (rule some_equality) + apply (rule refl) + apply (erule sym) + done -subsection\Axiom of Choice, Proved Using the Description Operator\ +subsection \Axiom of Choice, Proved Using the Description Operator\ -lemma choice: "\x. \y. Q x y ==> \f. \x. Q x (f x)" -by (fast elim: someI) +lemma choice: "\x. \y. Q x y \ \f. \x. Q x (f x)" + by (fast elim: someI) -lemma bchoice: "\x\S. \y. Q x y ==> \f. \x\S. Q x (f x)" -by (fast elim: someI) +lemma bchoice: "\x\S. \y. Q x y \ \f. \x\S. Q x (f x)" + by (fast elim: someI) lemma choice_iff: "(\x. \y. Q x y) \ (\f. \x. Q x (f x))" -by (fast elim: someI) + by (fast elim: someI) lemma choice_iff': "(\x. P x \ (\y. Q x y)) \ (\f. \x. P x \ Q x (f x))" -by (fast elim: someI) + by (fast elim: someI) lemma bchoice_iff: "(\x\S. \y. Q x y) \ (\f. \x\S. Q x (f x))" -by (fast elim: someI) + by (fast elim: someI) lemma bchoice_iff': "(\x\S. P x \ (\y. Q x y)) \ (\f. \x\S. P x \ Q x (f x))" -by (fast elim: someI) + by (fast elim: someI) lemma dependent_nat_choice: - assumes 1: "\x. P 0 x" and - 2: "\x n. P n x \ \y. P (Suc n) y \ Q n x y" + assumes 1: "\x. P 0 x" + and 2: "\x n. P n x \ \y. P (Suc n) y \ Q n x y" shows "\f. \n. P n (f n) \ Q n (f n) (f (Suc n))" proof (intro exI allI conjI) fix n define f where "f = rec_nat (SOME x. P 0 x) (\n x. SOME y. P (Suc n) y \ Q n x y)" - have "P 0 (f 0)" "\n. P n (f n) \ P (Suc n) (f (Suc n)) \ Q n (f n) (f (Suc n))" - using someI_ex[OF 1] someI_ex[OF 2] by (simp_all add: f_def) + then have "P 0 (f 0)" "\n. P n (f n) \ P (Suc n) (f (Suc n)) \ Q n (f n) (f (Suc n))" + using someI_ex[OF 1] someI_ex[OF 2] by simp_all then show "P n (f n)" "Q n (f n) (f (Suc n))" by (induct n) auto qed @@ -121,181 +123,172 @@ subsection \Function Inverse\ -lemma inv_def: "inv f = (%y. SOME x. f x = y)" -by(simp add: inv_into_def) +lemma inv_def: "inv f = (\y. SOME x. f x = y)" + by (simp add: inv_into_def) -lemma inv_into_into: "x : f ` A ==> inv_into A f x : A" -apply (simp add: inv_into_def) -apply (fast intro: someI2) -done +lemma inv_into_into: "x \ f ` A \ inv_into A f x \ A" + by (simp add: inv_into_def) (fast intro: someI2) -lemma inv_identity [simp]: - "inv (\a. a) = (\a. a)" +lemma inv_identity [simp]: "inv (\a. a) = (\a. a)" by (simp add: inv_def) -lemma inv_id [simp]: - "inv id = id" +lemma inv_id [simp]: "inv id = id" by (simp add: id_def) -lemma inv_into_f_f [simp]: - "[| inj_on f A; x : A |] ==> inv_into A f (f x) = x" -apply (simp add: inv_into_def inj_on_def) -apply (blast intro: someI2) -done +lemma inv_into_f_f [simp]: "inj_on f A \ x \ A \ inv_into A f (f x) = x" + by (simp add: inv_into_def inj_on_def) (blast intro: someI2) -lemma inv_f_f: "inj f ==> inv f (f x) = x" -by simp +lemma inv_f_f: "inj f \ inv f (f x) = x" + by simp -lemma f_inv_into_f: "y : f`A ==> f (inv_into A f y) = y" -apply (simp add: inv_into_def) -apply (fast intro: someI2) -done +lemma f_inv_into_f: "y : f`A \ f (inv_into A f y) = y" + by (simp add: inv_into_def) (fast intro: someI2) -lemma inv_into_f_eq: "[| inj_on f A; x : A; f x = y |] ==> inv_into A f y = x" -apply (erule subst) -apply (fast intro: inv_into_f_f) -done +lemma inv_into_f_eq: "inj_on f A \ x \ A \ f x = y \ inv_into A f y = x" + by (erule subst) (fast intro: inv_into_f_f) -lemma inv_f_eq: "[| inj f; f x = y |] ==> inv f y = x" -by (simp add:inv_into_f_eq) +lemma inv_f_eq: "inj f \ f x = y \ inv f y = x" + by (simp add:inv_into_f_eq) -lemma inj_imp_inv_eq: "[| inj f; ALL x. f(g x) = x |] ==> inv f = g" +lemma inj_imp_inv_eq: "inj f \ \x. f (g x) = x \ inv f = g" by (blast intro: inv_into_f_eq) -text\But is it useful?\ +text \But is it useful?\ lemma inj_transfer: - assumes injf: "inj f" and minor: "!!y. y \ range(f) ==> P(inv f y)" + assumes inj: "inj f" + and minor: "\y. y \ range f \ P (inv f y)" shows "P x" proof - have "f x \ range f" by auto - hence "P(inv f (f x))" by (rule minor) - thus "P x" by (simp add: inv_into_f_f [OF injf]) + then have "P(inv f (f x))" by (rule minor) + then show "P x" by (simp add: inv_into_f_f [OF inj]) qed -lemma inj_iff: "(inj f) = (inv f o f = id)" -apply (simp add: o_def fun_eq_iff) -apply (blast intro: inj_on_inverseI inv_into_f_f) -done +lemma inj_iff: "inj f \ inv f \ f = id" + by (simp add: o_def fun_eq_iff) (blast intro: inj_on_inverseI inv_into_f_f) -lemma inv_o_cancel[simp]: "inj f ==> inv f o f = id" -by (simp add: inj_iff) +lemma inv_o_cancel[simp]: "inj f \ inv f \ f = id" + by (simp add: inj_iff) + +lemma o_inv_o_cancel[simp]: "inj f \ g \ inv f \ f = g" + by (simp add: comp_assoc) -lemma o_inv_o_cancel[simp]: "inj f ==> g o inv f o f = g" -by (simp add: comp_assoc) +lemma inv_into_image_cancel[simp]: "inj_on f A \ S \ A \ inv_into A f ` f ` S = S" + by (fastforce simp: image_def) -lemma inv_into_image_cancel[simp]: - "inj_on f A ==> S <= A ==> inv_into A f ` f ` S = S" -by(fastforce simp: image_def) +lemma inj_imp_surj_inv: "inj f \ surj (inv f)" + by (blast intro!: surjI inv_into_f_f) -lemma inj_imp_surj_inv: "inj f ==> surj (inv f)" -by (blast intro!: surjI inv_into_f_f) - -lemma surj_f_inv_f: "surj f ==> f(inv f y) = y" -by (simp add: f_inv_into_f) +lemma surj_f_inv_f: "surj f \ f (inv f y) = y" + by (simp add: f_inv_into_f) lemma inv_into_injective: assumes eq: "inv_into A f x = inv_into A f y" - and x: "x: f`A" - and y: "y: f`A" - shows "x=y" + and x: "x \ f`A" + and y: "y \ f`A" + shows "x = y" proof - - have "f (inv_into A f x) = f (inv_into A f y)" using eq by simp - thus ?thesis by (simp add: f_inv_into_f x y) + from eq have "f (inv_into A f x) = f (inv_into A f y)" + by simp + with x y show ?thesis + by (simp add: f_inv_into_f) qed -lemma inj_on_inv_into: "B <= f`A ==> inj_on (inv_into A f) B" -by (blast intro: inj_onI dest: inv_into_injective injD) +lemma inj_on_inv_into: "B \ f`A \ inj_on (inv_into A f) B" + by (blast intro: inj_onI dest: inv_into_injective injD) -lemma bij_betw_inv_into: "bij_betw f A B ==> bij_betw (inv_into A f) B A" -by (auto simp add: bij_betw_def inj_on_inv_into) +lemma bij_betw_inv_into: "bij_betw f A B \ bij_betw (inv_into A f) B A" + by (auto simp add: bij_betw_def inj_on_inv_into) -lemma surj_imp_inj_inv: "surj f ==> inj (inv f)" -by (simp add: inj_on_inv_into) +lemma surj_imp_inj_inv: "surj f \ inj (inv f)" + by (simp add: inj_on_inv_into) -lemma surj_iff: "(surj f) = (f o inv f = id)" -by (auto intro!: surjI simp: surj_f_inv_f fun_eq_iff[where 'b='a]) +lemma surj_iff: "surj f \ f \ inv f = id" + by (auto intro!: surjI simp: surj_f_inv_f fun_eq_iff[where 'b='a]) lemma surj_iff_all: "surj f \ (\x. f (inv f x) = x)" - unfolding surj_iff by (simp add: o_def fun_eq_iff) + by (simp add: o_def surj_iff fun_eq_iff) -lemma surj_imp_inv_eq: "[| surj f; \x. g(f x) = x |] ==> inv f = g" -apply (rule ext) -apply (drule_tac x = "inv f x" in spec) -apply (simp add: surj_f_inv_f) -done +lemma surj_imp_inv_eq: "surj f \ \x. g (f x) = x \ inv f = g" + apply (rule ext) + apply (drule_tac x = "inv f x" in spec) + apply (simp add: surj_f_inv_f) + done -lemma bij_imp_bij_inv: "bij f ==> bij (inv f)" -by (simp add: bij_def inj_imp_surj_inv surj_imp_inj_inv) +lemma bij_imp_bij_inv: "bij f \ bij (inv f)" + by (simp add: bij_def inj_imp_surj_inv surj_imp_inj_inv) -lemma inv_equality: "[| !!x. g (f x) = x; !!y. f (g y) = y |] ==> inv f = g" -apply (rule ext) -apply (auto simp add: inv_into_def) -done +lemma inv_equality: "(\x. g (f x) = x) \ (\y. f (g y) = y) \ inv f = g" + by (rule ext) (auto simp add: inv_into_def) + +lemma inv_inv_eq: "bij f \ inv (inv f) = f" + by (rule inv_equality) (auto simp add: bij_def surj_f_inv_f) -lemma inv_inv_eq: "bij f ==> inv (inv f) = f" -apply (rule inv_equality) -apply (auto simp add: bij_def surj_f_inv_f) -done - -(** bij(inv f) implies little about f. Consider f::bool=>bool such that - f(True)=f(False)=True. Then it's consistent with axiom someI that - inv f could be any function at all, including the identity function. - If inv f=id then inv f is a bijection, but inj f, surj(f) and - inv(inv f)=f all fail. -**) +text \ + \bij (inv f)\ implies little about \f\. Consider \f :: bool \ bool\ such + that \f True = f False = True\. Then it ia consistent with axiom \someI\ + that \inv f\ could be any function at all, including the identity function. + If \inv f = id\ then \inv f\ is a bijection, but \inj f\, \surj f\ and \inv + (inv f) = f\ all fail. +\ lemma inv_into_comp: - "[| inj_on f (g ` A); inj_on g A; x : f ` g ` A |] ==> - inv_into A (f o g) x = (inv_into A g o inv_into (g ` A) f) x" -apply (rule inv_into_f_eq) - apply (fast intro: comp_inj_on) - apply (simp add: inv_into_into) -apply (simp add: f_inv_into_f inv_into_into) -done + "inj_on f (g ` A) \ inj_on g A \ x \ f ` g ` A \ + inv_into A (f \ g) x = (inv_into A g \ inv_into (g ` A) f) x" + apply (rule inv_into_f_eq) + apply (fast intro: comp_inj_on) + apply (simp add: inv_into_into) + apply (simp add: f_inv_into_f inv_into_into) + done -lemma o_inv_distrib: "[| bij f; bij g |] ==> inv (f o g) = inv g o inv f" -apply (rule inv_equality) -apply (auto simp add: bij_def surj_f_inv_f) -done +lemma o_inv_distrib: "bij f \ bij g \ inv (f \ g) = inv g \ inv f" + by (rule inv_equality) (auto simp add: bij_def surj_f_inv_f) -lemma image_surj_f_inv_f: "surj f ==> f ` (inv f ` A) = A" +lemma image_surj_f_inv_f: "surj f \ f ` (inv f ` A) = A" by (simp add: surj_f_inv_f image_comp comp_def) -lemma image_inv_f_f: "inj f ==> inv f ` (f ` A) = A" +lemma image_inv_f_f: "inj f \ inv f ` (f ` A) = A" by simp -lemma inv_image_comp: "inj f ==> inv f ` (f ` X) = X" +lemma inv_image_comp: "inj f \ inv f ` (f ` X) = X" by (fact image_inv_f_f) -lemma bij_image_Collect_eq: "bij f ==> f ` Collect P = {y. P (inv f y)}" -apply auto -apply (force simp add: bij_is_inj) -apply (blast intro: bij_is_surj [THEN surj_f_inv_f, symmetric]) -done +lemma bij_image_Collect_eq: "bij f \ f ` Collect P = {y. P (inv f y)}" + apply auto + apply (force simp add: bij_is_inj) + apply (blast intro: bij_is_surj [THEN surj_f_inv_f, symmetric]) + done -lemma bij_vimage_eq_inv_image: "bij f ==> f -` A = inv f ` A" -apply (auto simp add: bij_is_surj [THEN surj_f_inv_f]) -apply (blast intro: bij_is_inj [THEN inv_into_f_f, symmetric]) -done +lemma bij_vimage_eq_inv_image: "bij f \ f -` A = inv f ` A" + apply (auto simp add: bij_is_surj [THEN surj_f_inv_f]) + apply (blast intro: bij_is_inj [THEN inv_into_f_f, symmetric]) + done lemma finite_fun_UNIVD1: assumes fin: "finite (UNIV :: ('a \ 'b) set)" - and card: "card (UNIV :: 'b set) \ Suc 0" + and card: "card (UNIV :: 'b set) \ Suc 0" shows "finite (UNIV :: 'a set)" proof - - from fin have finb: "finite (UNIV :: 'b set)" by (rule finite_fun_UNIVD2) + from fin have finb: "finite (UNIV :: 'b set)" + by (rule finite_fun_UNIVD2) with card have "card (UNIV :: 'b set) \ Suc (Suc 0)" by (cases "card (UNIV :: 'b set)") (auto simp add: card_eq_0_iff) - then obtain n where "card (UNIV :: 'b set) = Suc (Suc n)" "n = card (UNIV :: 'b set) - Suc (Suc 0)" by auto - then obtain b1 b2 where b1b2: "(b1 :: 'b) \ (b2 :: 'b)" by (auto simp add: card_Suc_eq) - from fin have "finite (range (\f :: 'a \ 'b. inv f b1))" by (rule finite_imageI) + then obtain n where "card (UNIV :: 'b set) = Suc (Suc n)" "n = card (UNIV :: 'b set) - Suc (Suc 0)" + by auto + then obtain b1 b2 where b1b2: "(b1 :: 'b) \ (b2 :: 'b)" + by (auto simp add: card_Suc_eq) + from fin have "finite (range (\f :: 'a \ 'b. inv f b1))" + by (rule finite_imageI) moreover have "UNIV = range (\f :: 'a \ 'b. inv f b1)" proof (rule UNIV_eq_I) fix x :: 'a - from b1b2 have "x = inv (\y. if y = x then b1 else b2) b1" by (simp add: inv_into_def) - thus "x \ range (\f::'a \ 'b. inv f b1)" by blast + from b1b2 have "x = inv (\y. if y = x then b1 else b2) b1" + by (simp add: inv_into_def) + then show "x \ range (\f::'a \ 'b. inv f b1)" + by blast qed - ultimately show "finite (UNIV :: 'a set)" by simp + ultimately show "finite (UNIV :: 'a set)" + by simp qed text \ @@ -318,18 +311,18 @@ define Sseq where "Sseq = rec_nat S (\n T. T - {SOME e. e \ T})" define pick where "pick n = (SOME e. e \ Sseq n)" for n have *: "Sseq n \ S" "\ finite (Sseq n)" for n - by (induct n) (auto simp add: Sseq_def inf) + by (induct n) (auto simp: Sseq_def inf) then have **: "\n. pick n \ Sseq n" unfolding pick_def by (subst (asm) finite.simps) (auto simp add: ex_in_conv intro: someI_ex) with * have "range pick \ S" by auto - moreover - { - fix n m + moreover have "pick n \ pick (n + Suc m)" for m n + proof - have "pick n \ Sseq (n + Suc m)" by (induct m) (auto simp add: Sseq_def pick_def) - with ** have "pick n \ pick (n + Suc m)" by auto - } - then have "inj pick" by (intro linorder_injI) (auto simp add: less_iff_Suc_add) + with ** show ?thesis by auto + qed + then have "inj pick" + by (intro linorder_injI) (auto simp add: less_iff_Suc_add) ultimately show ?thesis by blast qed @@ -338,31 +331,35 @@ using finite_imageD finite_subset infinite_UNIV_char_0 infinite_countable_subset by auto lemma image_inv_into_cancel: - assumes SURJ: "f`A=A'" and SUB: "B' \ A'" + assumes surj: "f`A = A'" + and sub: "B' \ A'" shows "f `((inv_into A f)`B') = B'" using assms -proof (auto simp add: f_inv_into_f) - let ?f' = "(inv_into A f)" - fix a' assume *: "a' \ B'" - then have "a' \ A'" using SUB by auto - then have "a' = f (?f' a')" - using SURJ by (auto simp add: f_inv_into_f) - then show "a' \ f ` (?f' ` B')" using * by blast +proof (auto simp: f_inv_into_f) + let ?f' = "inv_into A f" + fix a' + assume *: "a' \ B'" + with sub have "a' \ A'" by auto + with surj have "a' = f (?f' a')" + by (auto simp: f_inv_into_f) + with * show "a' \ f ` (?f' ` B')" by blast qed lemma inv_into_inv_into_eq: - assumes "bij_betw f A A'" "a \ A" + assumes "bij_betw f A A'" + and a: "a \ A" shows "inv_into A' (inv_into A f) a = f a" proof - - let ?f' = "inv_into A f" let ?f'' = "inv_into A' ?f'" - have 1: "bij_betw ?f' A' A" using assms - by (auto simp add: bij_betw_inv_into) - obtain a' where 2: "a' \ A'" and 3: "?f' a' = a" - using 1 \a \ A\ unfolding bij_betw_def by force - hence "?f'' a = a'" - using \a \ A\ 1 3 by (auto simp add: f_inv_into_f bij_betw_def) - moreover have "f a = a'" using assms 2 3 - by (auto simp add: bij_betw_def) + let ?f' = "inv_into A f" + let ?f'' = "inv_into A' ?f'" + from assms have *: "bij_betw ?f' A' A" + by (auto simp: bij_betw_inv_into) + with a obtain a' where a': "a' \ A'" "?f' a' = a" + unfolding bij_betw_def by force + with a * have "?f'' a = a'" + by (auto simp: f_inv_into_f bij_betw_def) + moreover from assms a' have "f a = a'" + by (auto simp: bij_betw_def) ultimately show "?f'' a = f a" by simp qed @@ -370,72 +367,82 @@ assumes "A \ {}" shows "(\f. inj_on f A \ f ` A \ A') \ (\g. g ` A' = A)" proof safe - fix f assume INJ: "inj_on f A" and INCL: "f ` A \ A'" - let ?phi = "\a' a. a \ A \ f a = a'" let ?csi = "\a. a \ A" + fix f + assume inj: "inj_on f A" and incl: "f ` A \ A'" + let ?phi = "\a' a. a \ A \ f a = a'" + let ?csi = "\a. a \ A" let ?g = "\a'. if a' \ f ` A then (SOME a. ?phi a' a) else (SOME a. ?csi a)" have "?g ` A' = A" proof - show "?g ` A' \ A" + show "?g ` A' \ A" proof clarify - fix a' assume *: "a' \ A'" + fix a' + assume *: "a' \ A'" show "?g a' \ A" - proof cases - assume Case1: "a' \ f ` A" + proof (cases "a' \ f ` A") + case True then obtain a where "?phi a' a" by blast - hence "?phi a' (SOME a. ?phi a' a)" using someI[of "?phi a'" a] by blast - with Case1 show ?thesis by auto + then have "?phi a' (SOME a. ?phi a' a)" + using someI[of "?phi a'" a] by blast + with True show ?thesis by auto next - assume Case2: "a' \ f ` A" - hence "?csi (SOME a. ?csi a)" using assms someI_ex[of ?csi] by blast - with Case2 show ?thesis by auto + case False + with assms have "?csi (SOME a. ?csi a)" + using someI_ex[of ?csi] by blast + with False show ?thesis by auto qed qed next - show "A \ ?g ` A'" - proof- - {fix a assume *: "a \ A" - let ?b = "SOME aa. ?phi (f a) aa" - have "?phi (f a) a" using * by auto - hence 1: "?phi (f a) ?b" using someI[of "?phi(f a)" a] by blast - hence "?g(f a) = ?b" using * by auto - moreover have "a = ?b" using 1 INJ * by (auto simp add: inj_on_def) - ultimately have "?g(f a) = a" by simp - with INCL * have "?g(f a) = a \ f a \ A'" by auto - } - thus ?thesis by force + show "A \ ?g ` A'" + proof - + have "?g (f a) = a \ f a \ A'" if a: "a \ A" for a + proof - + let ?b = "SOME aa. ?phi (f a) aa" + from a have "?phi (f a) a" by auto + then have *: "?phi (f a) ?b" + using someI[of "?phi(f a)" a] by blast + then have "?g (f a) = ?b" using a by auto + moreover from inj * a have "a = ?b" + by (auto simp add: inj_on_def) + ultimately have "?g(f a) = a" by simp + with incl a show ?thesis by auto + qed + then show ?thesis by force qed qed - thus "\g. g ` A' = A" by blast + then show "\g. g ` A' = A" by blast next - fix g let ?f = "inv_into A' g" + fix g + let ?f = "inv_into A' g" have "inj_on ?f (g ` A')" - by (auto simp add: inj_on_inv_into) - moreover - {fix a' assume *: "a' \ A'" - let ?phi = "\ b'. b' \ A' \ g b' = g a'" - have "?phi a'" using * by auto - hence "?phi(SOME b'. ?phi b')" using someI[of ?phi] by blast - hence "?f(g a') \ A'" unfolding inv_into_def by auto - } - ultimately show "\f. inj_on f (g ` A') \ f ` g ` A' \ A'" by auto + by (auto simp: inj_on_inv_into) + moreover have "?f (g a') \ A'" if a': "a' \ A'" for a' + proof - + let ?phi = "\ b'. b' \ A' \ g b' = g a'" + from a' have "?phi a'" by auto + then have "?phi (SOME b'. ?phi b')" + using someI[of ?phi] by blast + then show ?thesis by (auto simp: inv_into_def) + qed + ultimately show "\f. inj_on f (g ` A') \ f ` g ` A' \ A'" + by auto qed lemma Ex_inj_on_UNION_Sigma: "\f. (inj_on f (\i \ I. A i) \ f ` (\i \ I. A i) \ (SIGMA i : I. A i))" proof - let ?phi = "\ a i. i \ I \ a \ A i" - let ?sm = "\ a. SOME i. ?phi a i" + let ?phi = "\a i. i \ I \ a \ A i" + let ?sm = "\a. SOME i. ?phi a i" let ?f = "\a. (?sm a, a)" - have "inj_on ?f (\i \ I. A i)" unfolding inj_on_def by auto + have "inj_on ?f (\i \ I. A i)" + by (auto simp: inj_on_def) moreover - { { fix i a assume "i \ I" and "a \ A i" - hence "?sm a \ I \ a \ A(?sm a)" using someI[of "?phi a" i] by auto - } - hence "?f ` (\i \ I. A i) \ (SIGMA i : I. A i)" by auto - } - ultimately - show "inj_on ?f (\i \ I. A i) \ ?f ` (\i \ I. A i) \ (SIGMA i : I. A i)" - by auto + have "?sm a \ I \ a \ A(?sm a)" if "i \ I" and "a \ A i" for i a + using that someI[of "?phi a" i] by auto + then have "?f ` (\i \ I. A i) \ (SIGMA i : I. A i)" + by auto + ultimately show "inj_on ?f (\i \ I. A i) \ ?f ` (\i \ I. A i) \ (SIGMA i : I. A i)" + by auto qed lemma inv_unique_comp: @@ -448,190 +455,199 @@ subsection \The Cantor-Bernstein Theorem\ lemma Cantor_Bernstein_aux: - shows "\A' h. A' \ A \ - (\a \ A'. a \ g`(B - f ` A')) \ - (\a \ A'. h a = f a) \ - (\a \ A - A'. h a \ B - (f ` A') \ a = g(h a))" -proof- - obtain H where H_def: "H = (\ A'. A - (g`(B - (f ` A'))))" by blast - have 0: "mono H" unfolding mono_def H_def by blast - then obtain A' where 1: "H A' = A'" using lfp_unfold by blast - hence 2: "A' = A - (g`(B - (f ` A')))" unfolding H_def by simp - hence 3: "A' \ A" by blast - have 4: "\a \ A'. a \ g`(B - f ` A')" - using 2 by blast - have 5: "\a \ A - A'. \b \ B - (f ` A'). a = g b" - using 2 by blast - (* *) - obtain h where h_def: - "h = (\ a. if a \ A' then f a else (SOME b. b \ B - (f ` A') \ a = g b))" by blast - hence "\a \ A'. h a = f a" by auto - moreover - have "\a \ A - A'. h a \ B - (f ` A') \ a = g(h a)" + "\A' h. A' \ A \ + (\a \ A'. a \ g ` (B - f ` A')) \ + (\a \ A'. h a = f a) \ + (\a \ A - A'. h a \ B - (f ` A') \ a = g (h a))" +proof - + define H where "H A' = A - (g ` (B - (f ` A')))" for A' + have "mono H" unfolding mono_def H_def by blast + from lfp_unfold [OF this] obtain A' where "H A' = A'" by blast + then have "A' = A - (g ` (B - (f ` A')))" by (simp add: H_def) + then have 1: "A' \ A" + and 2: "\a \ A'. a \ g ` (B - f ` A')" + and 3: "\a \ A - A'. \b \ B - (f ` A'). a = g b" + by blast+ + define h where "h a = (if a \ A' then f a else (SOME b. b \ B - (f ` A') \ a = g b))" for a + then have 4: "\a \ A'. h a = f a" by simp + have "\a \ A - A'. h a \ B - (f ` A') \ a = g (h a)" proof - fix a assume *: "a \ A - A'" - let ?phi = "\ b. b \ B - (f ` A') \ a = g b" - have "h a = (SOME b. ?phi b)" using h_def * by auto - moreover have "\b. ?phi b" using 5 * by auto - ultimately show "?phi (h a)" using someI_ex[of ?phi] by auto + fix a + let ?phi = "\b. b \ B - (f ` A') \ a = g b" + assume *: "a \ A - A'" + from * have "h a = (SOME b. ?phi b)" by (auto simp: h_def) + moreover from 3 * have "\b. ?phi b" by auto + ultimately show "?phi (h a)" + using someI_ex[of ?phi] by auto qed - ultimately show ?thesis using 3 4 by blast + with 1 2 4 show ?thesis by blast qed theorem Cantor_Bernstein: - assumes INJ1: "inj_on f A" and SUB1: "f ` A \ B" and - INJ2: "inj_on g B" and SUB2: "g ` B \ A" + assumes inj1: "inj_on f A" and sub1: "f ` A \ B" + and inj2: "inj_on g B" and sub2: "g ` B \ A" shows "\h. bij_betw h A B" proof- - obtain A' and h where 0: "A' \ A" and - 1: "\a \ A'. a \ g`(B - f ` A')" and - 2: "\a \ A'. h a = f a" and - 3: "\a \ A - A'. h a \ B - (f ` A') \ a = g(h a)" - using Cantor_Bernstein_aux[of A g B f] by blast + obtain A' and h where "A' \ A" + and 1: "\a \ A'. a \ g ` (B - f ` A')" + and 2: "\a \ A'. h a = f a" + and 3: "\a \ A - A'. h a \ B - (f ` A') \ a = g (h a)" + using Cantor_Bernstein_aux [of A g B f] by blast have "inj_on h A" proof (intro inj_onI) fix a1 a2 assume 4: "a1 \ A" and 5: "a2 \ A" and 6: "h a1 = h a2" show "a1 = a2" - proof(cases "a1 \ A'") - assume Case1: "a1 \ A'" + proof (cases "a1 \ A'") + case True show ?thesis - proof(cases "a2 \ A'") - assume Case11: "a2 \ A'" - hence "f a1 = f a2" using Case1 2 6 by auto - thus ?thesis using INJ1 Case1 Case11 0 - unfolding inj_on_def by blast + proof (cases "a2 \ A'") + case True': True + with True 2 6 have "f a1 = f a2" by auto + with inj1 \A' \ A\ True True' show ?thesis + unfolding inj_on_def by blast next - assume Case12: "a2 \ A'" - hence False using 3 5 2 6 Case1 by force - thus ?thesis by simp + case False + with 2 3 5 6 True have False by force + then show ?thesis .. qed next - assume Case2: "a1 \ A'" + case False show ?thesis - proof(cases "a2 \ A'") - assume Case21: "a2 \ A'" - hence False using 3 4 2 6 Case2 by auto - thus ?thesis by simp + proof (cases "a2 \ A'") + case True + with 2 3 4 6 False have False by auto + then show ?thesis .. next - assume Case22: "a2 \ A'" - hence "a1 = g(h a1) \ a2 = g(h a2)" using Case2 4 5 3 by auto - thus ?thesis using 6 by simp + case False': False + with False 3 4 5 have "a1 = g (h a1)" "a2 = g (h a2)" by auto + with 6 show ?thesis by simp qed qed qed - (* *) - moreover - have "h ` A = B" + moreover have "h ` A = B" proof safe - fix a assume "a \ A" - thus "h a \ B" using SUB1 2 3 by (cases "a \ A'") auto + fix a + assume "a \ A" + with sub1 2 3 show "h a \ B" by (cases "a \ A'") auto next - fix b assume *: "b \ B" + fix b + assume *: "b \ B" show "b \ h ` A" - proof(cases "b \ f ` A'") - assume Case1: "b \ f ` A'" - then obtain a where "a \ A' \ b = f a" by blast - thus ?thesis using 2 0 by force + proof (cases "b \ f ` A'") + case True + then obtain a where "a \ A'" "b = f a" by blast + with \A' \ A\ 2 show ?thesis by force next - assume Case2: "b \ f ` A'" - hence "g b \ A'" using 1 * by auto - hence 4: "g b \ A - A'" using * SUB2 by auto - hence "h(g b) \ B \ g(h(g b)) = g b" - using 3 by auto - hence "h(g b) = b" using * INJ2 unfolding inj_on_def by auto - thus ?thesis using 4 by force + case False + with 1 * have "g b \ A'" by auto + with sub2 * have 4: "g b \ A - A'" by auto + with 3 have "h (g b) \ B" "g (h (g b)) = g b" by auto + with inj2 * have "h (g b) = b" by (auto simp: inj_on_def) + with 4 show ?thesis by force qed qed - (* *) - ultimately show ?thesis unfolding bij_betw_def by auto + ultimately show ?thesis + by (auto simp: bij_betw_def) qed + subsection \Other Consequences of Hilbert's Epsilon\ text \Hilbert's Epsilon and the @{term split} Operator\ -text\Looping simprule\ -lemma split_paired_Eps: "(SOME x. P x) = (SOME (a,b). P(a,b))" +text \Looping simprule!\ +lemma split_paired_Eps: "(SOME x. P x) = (SOME (a, b). P (a, b))" by simp lemma Eps_case_prod: "Eps (case_prod P) = (SOME xy. P (fst xy) (snd xy))" by (simp add: split_def) -lemma Eps_case_prod_eq [simp]: "(@(x',y'). x = x' & y = y') = (x,y)" +lemma Eps_case_prod_eq [simp]: "(SOME (x', y'). x = x' \ y = y') = (x, y)" by blast -text\A relation is wellfounded iff it has no infinite descending chain\ -lemma wf_iff_no_infinite_down_chain: - "wf r = (~(\f. \i. (f(Suc i),f i) \ r))" -apply (simp only: wf_eq_minimal) -apply (rule iffI) - apply (rule notI) - apply (erule exE) - apply (erule_tac x = "{w. \i. w=f i}" in allE, blast) -apply (erule contrapos_np, simp, clarify) -apply (subgoal_tac "\n. rec_nat x (%i y. @z. z:Q & (z,y) :r) n \ Q") - apply (rule_tac x = "rec_nat x (%i y. @z. z:Q & (z,y) :r)" in exI) - apply (rule allI, simp) - apply (rule someI2_ex, blast, blast) -apply (rule allI) -apply (induct_tac "n", simp_all) -apply (rule someI2_ex, blast+) -done +text \A relation is wellfounded iff it has no infinite descending chain.\ +lemma wf_iff_no_infinite_down_chain: "wf r \ (\ (\f. \i. (f (Suc i), f i) \ r))" + apply (simp only: wf_eq_minimal) + apply (rule iffI) + apply (rule notI) + apply (erule exE) + apply (erule_tac x = "{w. \i. w = f i}" in allE) + apply blast + apply (erule contrapos_np) + apply simp + apply clarify + apply (subgoal_tac "\n. rec_nat x (\i y. SOME z. z \ Q \ (z, y) \ r) n \ Q") + apply (rule_tac x = "rec_nat x (\i y. SOME z. z \ Q \ (z, y) \ r)" in exI) + apply (rule allI) + apply simp + apply (rule someI2_ex) + apply blast + apply blast + apply (rule allI) + apply (induct_tac n) + apply simp_all + apply (rule someI2_ex) + apply blast + apply blast + done lemma wf_no_infinite_down_chainE: - assumes "wf r" obtains k where "(f (Suc k), f k) \ r" -using \wf r\ wf_iff_no_infinite_down_chain[of r] by blast + assumes "wf r" + obtains k where "(f (Suc k), f k) \ r" + using assms wf_iff_no_infinite_down_chain[of r] by blast -text\A dynamically-scoped fact for TFL\ -lemma tfl_some: "\P x. P x --> P (Eps P)" +text \A dynamically-scoped fact for TFL\ +lemma tfl_some: "\P x. P x \ P (Eps P)" by (blast intro: someI) subsection \Least value operator\ -definition - LeastM :: "['a => 'b::ord, 'a => bool] => 'a" where - "LeastM m P == SOME x. P x & (\y. P y --> m x <= m y)" +definition LeastM :: "('a \ 'b::ord) \ ('a \ bool) \ 'a" + where "LeastM m P \ (SOME x. P x \ (\y. P y \ m x \ m y))" syntax - "_LeastM" :: "[pttrn, 'a => 'b::ord, bool] => 'a" ("LEAST _ WRT _. _" [0, 4, 10] 10) + "_LeastM" :: "pttrn \ ('a \ 'b::ord) \ bool \ 'a" ("LEAST _ WRT _. _" [0, 4, 10] 10) translations - "LEAST x WRT m. P" == "CONST LeastM m (%x. P)" + "LEAST x WRT m. P" \ "CONST LeastM m (\x. P)" lemma LeastMI2: - "P x ==> (!!y. P y ==> m x <= m y) - ==> (!!x. P x ==> \y. P y --> m x \ m y ==> Q x) - ==> Q (LeastM m P)" + "P x \ + (\y. P y \ m x \ m y) \ + (\x. P x \ \y. P y \ m x \ m y \ Q x) \ + Q (LeastM m P)" apply (simp add: LeastM_def) - apply (rule someI2_ex, blast, blast) + apply (rule someI2_ex) + apply blast + apply blast done lemma LeastM_equality: - "P k ==> (!!x. P x ==> m k <= m x) - ==> m (LEAST x WRT m. P x) = (m k::'a::order)" - apply (rule LeastMI2, assumption, blast) + "P k \ (\x. P x \ m k \ m x) \ m (LEAST x WRT m. P x) = (m k :: 'a::order)" + apply (rule LeastMI2) + apply assumption + apply blast apply (blast intro!: order_antisym) done lemma wf_linord_ex_has_least: - "wf r ==> \x y. ((x,y):r^+) = ((y,x)~:r^*) ==> P k - ==> \x. P x & (!y. P y --> (m x,m y):r^*)" + "wf r \ \x y. (x, y) \ r\<^sup>+ \ (y, x) \ r\<^sup>* \ P k \ \x. P x \ (\y. P y \ (m x, m y) \ r\<^sup>*)" apply (drule wf_trancl [THEN wf_eq_minimal [THEN iffD1]]) - apply (drule_tac x = "m`Collect P" in spec, force) + apply (drule_tac x = "m ` Collect P" in spec) + apply force done -lemma ex_has_least_nat: - "P k ==> \x. P x & (\y. P y --> m x <= (m y::nat))" +lemma ex_has_least_nat: "P k \ \x. P x \ (\y. P y \ m x \ (m y :: nat))" apply (simp only: pred_nat_trancl_eq_le [symmetric]) apply (rule wf_pred_nat [THEN wf_linord_ex_has_least]) - apply (simp add: less_eq linorder_not_le pred_nat_trancl_eq_le, assumption) + apply (simp add: less_eq linorder_not_le pred_nat_trancl_eq_le) + apply assumption done -lemma LeastM_nat_lemma: - "P k ==> P (LeastM m P) & (\y. P y --> m (LeastM m P) <= (m y::nat))" +lemma LeastM_nat_lemma: "P k \ P (LeastM m P) \ (\y. P y \ m (LeastM m P) \ (m y :: nat))" apply (simp add: LeastM_def) apply (rule someI_ex) apply (erule ex_has_least_nat) @@ -639,91 +655,87 @@ lemmas LeastM_natI = LeastM_nat_lemma [THEN conjunct1] -lemma LeastM_nat_le: "P x ==> m (LeastM m P) <= (m x::nat)" -by (rule LeastM_nat_lemma [THEN conjunct2, THEN spec, THEN mp], assumption, assumption) +lemma LeastM_nat_le: "P x \ m (LeastM m P) \ (m x :: nat)" + by (rule LeastM_nat_lemma [THEN conjunct2, THEN spec, THEN mp]) subsection \Greatest value operator\ -definition - GreatestM :: "['a => 'b::ord, 'a => bool] => 'a" where - "GreatestM m P == SOME x. P x & (\y. P y --> m y <= m x)" +definition GreatestM :: "('a \ 'b::ord) \ ('a \ bool) \ 'a" + where "GreatestM m P \ SOME x. P x \ (\y. P y \ m y \ m x)" -definition - Greatest :: "('a::ord => bool) => 'a" (binder "GREATEST " 10) where - "Greatest == GreatestM (%x. x)" +definition Greatest :: "('a::ord \ bool) \ 'a" (binder "GREATEST " 10) + where "Greatest \ GreatestM (\x. x)" syntax - "_GreatestM" :: "[pttrn, 'a => 'b::ord, bool] => 'a" - ("GREATEST _ WRT _. _" [0, 4, 10] 10) + "_GreatestM" :: "pttrn \ ('a \ 'b::ord) \ bool \ 'a" ("GREATEST _ WRT _. _" [0, 4, 10] 10) translations - "GREATEST x WRT m. P" == "CONST GreatestM m (%x. P)" + "GREATEST x WRT m. P" \ "CONST GreatestM m (\x. P)" lemma GreatestMI2: - "P x ==> (!!y. P y ==> m y <= m x) - ==> (!!x. P x ==> \y. P y --> m y \ m x ==> Q x) - ==> Q (GreatestM m P)" + "P x \ + (\y. P y \ m y \ m x) \ + (\x. P x \ \y. P y \ m y \ m x \ Q x) \ + Q (GreatestM m P)" apply (simp add: GreatestM_def) - apply (rule someI2_ex, blast, blast) + apply (rule someI2_ex) + apply blast + apply blast done lemma GreatestM_equality: - "P k ==> (!!x. P x ==> m x <= m k) - ==> m (GREATEST x WRT m. P x) = (m k::'a::order)" - apply (rule_tac m = m in GreatestMI2, assumption, blast) + "P k \ + (\x. P x \ m x \ m k) \ + m (GREATEST x WRT m. P x) = (m k :: 'a::order)" + apply (rule GreatestMI2 [where m = m]) + apply assumption + apply blast apply (blast intro!: order_antisym) done -lemma Greatest_equality: - "P (k::'a::order) ==> (!!x. P x ==> x <= k) ==> (GREATEST x. P x) = k" +lemma Greatest_equality: "P k \ (\x. P x \ x \ k) \ (GREATEST x. P x) = k" + for k :: "'a::order" apply (simp add: Greatest_def) - apply (erule GreatestM_equality, blast) + apply (erule GreatestM_equality) + apply blast done lemma ex_has_greatest_nat_lemma: - "P k ==> \x. P x --> (\y. P y & ~ ((m y::nat) <= m x)) - ==> \y. P y & ~ (m y < m k + n)" - apply (induct n, force) - apply (force simp add: le_Suc_eq) - done + "P k \ \x. P x \ (\y. P y \ \ m y \ (m x :: nat)) \ \y. P y \ \ m y < m k + n" + by (induct n) (force simp: le_Suc_eq)+ lemma ex_has_greatest_nat: - "P k ==> \y. P y --> m y < b - ==> \x. P x & (\y. P y --> (m y::nat) <= m x)" + "P k \ \y. P y \ m y < b \ \x. P x \ (\y. P y \ m y \ (m x :: nat))" apply (rule ccontr) apply (cut_tac P = P and n = "b - m k" in ex_has_greatest_nat_lemma) - apply (subgoal_tac [3] "m k <= b", auto) + apply (subgoal_tac [3] "m k \ b") + apply auto done lemma GreatestM_nat_lemma: - "P k ==> \y. P y --> m y < b - ==> P (GreatestM m P) & (\y. P y --> (m y::nat) <= m (GreatestM m P))" + "P k \ \y. P y \ m y < b \ + P (GreatestM m P) \ (\y. P y \ (m y :: nat) \ m (GreatestM m P))" apply (simp add: GreatestM_def) apply (rule someI_ex) - apply (erule ex_has_greatest_nat, assumption) + apply (erule ex_has_greatest_nat) + apply assumption done lemmas GreatestM_natI = GreatestM_nat_lemma [THEN conjunct1] -lemma GreatestM_nat_le: - "P x ==> \y. P y --> m y < b - ==> (m x::nat) <= m (GreatestM m P)" - apply (blast dest: GreatestM_nat_lemma [THEN conjunct2, THEN spec, of P]) - done +lemma GreatestM_nat_le: "P x \ \y. P y \ m y < b \ (m x :: nat) \ m (GreatestM m P)" + by (blast dest: GreatestM_nat_lemma [THEN conjunct2, THEN spec, of P]) -text \\medskip Specialization to \GREATEST\.\ +text \\<^medskip> Specialization to \GREATEST\.\ -lemma GreatestI: "P (k::nat) ==> \y. P y --> y < b ==> P (GREATEST x. P x)" - apply (simp add: Greatest_def) - apply (rule GreatestM_natI, auto) - done +lemma GreatestI: "P k \ \y. P y \ y < b \ P (GREATEST x. P x)" + for k :: nat + unfolding Greatest_def by (rule GreatestM_natI) auto -lemma Greatest_le: - "P x ==> \y. P y --> y < b ==> (x::nat) <= (GREATEST x. P x)" - apply (simp add: Greatest_def) - apply (rule GreatestM_nat_le, auto) - done +lemma Greatest_le: "P x \ \y. P y \ y < b \ x \ (GREATEST x. P x)" + for x :: nat + unfolding Greatest_def by (rule GreatestM_nat_le) auto subsection \An aside: bounded accessible part\ @@ -732,7 +744,8 @@ lemma finite_mono_remains_stable_implies_strict_prefix: fixes f :: "nat \ 'a::order" - assumes S: "finite (range f)" "mono f" and eq: "\n. f n = f (Suc n) \ f (Suc n) = f (Suc (Suc n))" + assumes S: "finite (range f)" "mono f" + and eq: "\n. f n = f (Suc n) \ f (Suc n) = f (Suc (Suc n))" shows "\N. (\n\N. \m\N. m < n \ f m < f n) \ (\n\N. f N = f n)" using assms proof - @@ -740,15 +753,16 @@ proof (rule ccontr) assume "\ ?thesis" then have "\n. f n \ f (Suc n)" by auto - then have "\n. f n < f (Suc n)" - using \mono f\ by (auto simp: le_less mono_iff_le_Suc) - with lift_Suc_mono_less_iff[of f] - have *: "\n m. n < m \ f n < f m" by auto + with \mono f\ have "\n. f n < f (Suc n)" + by (auto simp: le_less mono_iff_le_Suc) + with lift_Suc_mono_less_iff[of f] have *: "\n m. n < m \ f n < f m" + by auto have "inj f" proof (intro injI) fix x y assume "f x = f y" - then show "x = y" by (cases x y rule: linorder_cases) (auto dest: *) + then show "x = y" + by (cases x y rule: linorder_cases) (auto dest: *) qed with \finite (range f)\ have "finite (UNIV::nat set)" by (rule finite_imageD) @@ -760,16 +774,22 @@ unfolding N_def using n by (rule LeastI) show ?thesis proof (intro exI[of _ N] conjI allI impI) - fix n assume "N \ n" + fix n + assume "N \ n" then have "\m. N \ m \ m \ n \ f m = f N" proof (induct rule: dec_induct) - case (step n) then show ?case - using eq[rule_format, of "n - 1"] N + case base + then show ?case by simp + next + case (step n) + then show ?case + using eq [rule_format, of "n - 1"] N by (cases n) (auto simp add: le_Suc_eq) - qed simp + qed from this[of n] \N \ n\ show "f N = f n" by auto next - fix n m :: nat assume "m < n" "n \ N" + fix n m :: nat + assume "m < n" "n \ N" then show "f m < f n" proof (induct rule: less_Suc_induct) case (1 i) @@ -777,37 +797,41 @@ then have "f i \ f (Suc i)" unfolding N_def by (rule not_less_Least) with \mono f\ show ?case by (simp add: mono_iff_le_Suc less_le) - qed auto + next + case 2 + then show ?case by simp + qed qed qed lemma finite_mono_strict_prefix_implies_finite_fixpoint: fixes f :: "nat \ 'a set" assumes S: "\i. f i \ S" "finite S" - and inj: "\N. (\n\N. \m\N. m < n \ f m \ f n) \ (\n\N. f N = f n)" + and ex: "\N. (\n\N. \m\N. m < n \ f m \ f n) \ (\n\N. f N = f n)" shows "f (card S) = (\n. f n)" proof - - from inj obtain N where inj: "(\n\N. \m\N. m < n \ f m \ f n)" and eq: "(\n\N. f N = f n)" by auto - - { fix i have "i \ N \ i \ card (f i)" - proof (induct i) - case 0 then show ?case by simp - next - case (Suc i) - with inj[rule_format, of "Suc i" i] - have "(f i) \ (f (Suc i))" by auto - moreover have "finite (f (Suc i))" using S by (rule finite_subset) - ultimately have "card (f i) < card (f (Suc i))" by (intro psubset_card_mono) - with Suc show ?case using inj by auto - qed - } + from ex obtain N where inj: "\n m. n \ N \ m \ N \ m < n \ f m \ f n" + and eq: "\n\N. f N = f n" + by atomize auto + have "i \ N \ i \ card (f i)" for i + proof (induct i) + case 0 + then show ?case by simp + next + case (Suc i) + with inj [of "Suc i" i] have "(f i) \ (f (Suc i))" by auto + moreover have "finite (f (Suc i))" using S by (rule finite_subset) + ultimately have "card (f i) < card (f (Suc i))" by (intro psubset_card_mono) + with Suc inj show ?case by auto + qed then have "N \ card (f N)" by simp also have "\ \ card S" using S by (intro card_mono) finally have "f (card S) = f N" using eq by auto - then show ?thesis using eq inj[rule_format, of N] + then show ?thesis + using eq inj [of N] apply auto apply (case_tac "n < N") - apply (auto simp: not_less) + apply (auto simp: not_less) done qed @@ -819,183 +843,174 @@ assumes bij: "bij f" begin -lemma bij_inv: - "bij (inv f)" +lemma bij_inv: "bij (inv f)" using bij by (rule bij_imp_bij_inv) -lemma surj [simp]: - "surj f" +lemma surj [simp]: "surj f" using bij by (rule bij_is_surj) -lemma inj: - "inj f" +lemma inj: "inj f" using bij by (rule bij_is_inj) -lemma surj_inv [simp]: - "surj (inv f)" +lemma surj_inv [simp]: "surj (inv f)" using inj by (rule inj_imp_surj_inv) -lemma inj_inv: - "inj (inv f)" +lemma inj_inv: "inj (inv f)" using surj by (rule surj_imp_inj_inv) -lemma eqI: - "f a = f b \ a = b" +lemma eqI: "f a = f b \ a = b" using inj by (rule injD) -lemma eq_iff [simp]: - "f a = f b \ a = b" +lemma eq_iff [simp]: "f a = f b \ a = b" by (auto intro: eqI) -lemma eq_invI: - "inv f a = inv f b \ a = b" +lemma eq_invI: "inv f a = inv f b \ a = b" using inj_inv by (rule injD) -lemma eq_inv_iff [simp]: - "inv f a = inv f b \ a = b" +lemma eq_inv_iff [simp]: "inv f a = inv f b \ a = b" by (auto intro: eq_invI) -lemma inv_left [simp]: - "inv f (f a) = a" +lemma inv_left [simp]: "inv f (f a) = a" using inj by (simp add: inv_f_eq) -lemma inv_comp_left [simp]: - "inv f \ f = id" +lemma inv_comp_left [simp]: "inv f \ f = id" by (simp add: fun_eq_iff) -lemma inv_right [simp]: - "f (inv f a) = a" +lemma inv_right [simp]: "f (inv f a) = a" using surj by (simp add: surj_f_inv_f) -lemma inv_comp_right [simp]: - "f \ inv f = id" +lemma inv_comp_right [simp]: "f \ inv f = id" by (simp add: fun_eq_iff) -lemma inv_left_eq_iff [simp]: - "inv f a = b \ f b = a" +lemma inv_left_eq_iff [simp]: "inv f a = b \ f b = a" by auto -lemma inv_right_eq_iff [simp]: - "b = inv f a \ f b = a" +lemma inv_right_eq_iff [simp]: "b = inv f a \ f b = a" by auto end lemma infinite_imp_bij_betw: -assumes INF: "\ finite A" -shows "\h. bij_betw h A (A - {a})" -proof(cases "a \ A") - assume Case1: "a \ A" hence "A - {a} = A" by blast - thus ?thesis using bij_betw_id[of A] by auto + assumes infinite: "\ finite A" + shows "\h. bij_betw h A (A - {a})" +proof (cases "a \ A") + case False + then have "A - {a} = A" by blast + then show ?thesis + using bij_betw_id[of A] by auto next - assume Case2: "a \ A" - have "\ finite (A - {a})" using INF by auto - with infinite_iff_countable_subset[of "A - {a}"] obtain f::"nat \ 'a" - where 1: "inj f" and 2: "f ` UNIV \ A - {a}" by blast - obtain g where g_def: "g = (\ n. if n = 0 then a else f (Suc n))" by blast - obtain A' where A'_def: "A' = g ` UNIV" by blast - have temp: "\y. f y \ a" using 2 by blast - have 3: "inj_on g UNIV \ g ` UNIV \ A \ a \ g ` UNIV" - proof(auto simp add: Case2 g_def, unfold inj_on_def, intro ballI impI, - case_tac "x = 0", auto simp add: 2) - fix y assume "a = (if y = 0 then a else f (Suc y))" - thus "y = 0" using temp by (case_tac "y = 0", auto) + case True + with infinite have "\ finite (A - {a})" by auto + with infinite_iff_countable_subset[of "A - {a}"] + obtain f :: "nat \ 'a" where 1: "inj f" and 2: "f ` UNIV \ A - {a}" by blast + define g where "g n = (if n = 0 then a else f (Suc n))" for n + define A' where "A' = g ` UNIV" + have *: "\y. f y \ a" using 2 by blast + have 3: "inj_on g UNIV \ g ` UNIV \ A \ a \ g ` UNIV" + apply (auto simp add: True g_def [abs_def]) + apply (unfold inj_on_def) + apply (intro ballI impI) + apply (case_tac "x = 0") + apply (auto simp add: 2) + proof - + fix y + assume "a = (if y = 0 then a else f (Suc y))" + then show "y = 0" by (cases "y = 0") (use * in auto) next fix x y assume "f (Suc x) = (if y = 0 then a else f (Suc y))" - thus "x = y" using 1 temp unfolding inj_on_def by (case_tac "y = 0", auto) + with 1 * show "x = y" by (cases "y = 0") (auto simp: inj_on_def) next - fix n show "f (Suc n) \ A" using 2 by blast + fix n + from 2 show "f (Suc n) \ A" by blast qed - hence 4: "bij_betw g UNIV A' \ a \ A' \ A' \ A" - using inj_on_imp_bij_betw[of g] unfolding A'_def by auto - hence 5: "bij_betw (inv g) A' UNIV" - by (auto simp add: bij_betw_inv_into) - (* *) - obtain n where "g n = a" using 3 by auto - hence 6: "bij_betw g (UNIV - {n}) (A' - {a})" - using 3 4 unfolding A'_def - by clarify (rule bij_betw_subset, auto simp: image_set_diff) - (* *) - obtain v where v_def: "v = (\ m. if m < n then m else Suc m)" by blast + then have 4: "bij_betw g UNIV A' \ a \ A' \ A' \ A" + using inj_on_imp_bij_betw[of g] by (auto simp: A'_def) + then have 5: "bij_betw (inv g) A' UNIV" + by (auto simp add: bij_betw_inv_into) + from 3 obtain n where n: "g n = a" by auto + have 6: "bij_betw g (UNIV - {n}) (A' - {a})" + by (rule bij_betw_subset) (use 3 4 n in \auto simp: image_set_diff A'_def\) + define v where "v m = (if m < n then m else Suc m)" for m have 7: "bij_betw v UNIV (UNIV - {n})" - proof(unfold bij_betw_def inj_on_def, intro conjI, clarify) - fix m1 m2 assume "v m1 = v m2" - thus "m1 = m2" - by(case_tac "m1 < n", case_tac "m2 < n", - auto simp add: inj_on_def v_def, case_tac "m2 < n", auto) + proof (unfold bij_betw_def inj_on_def, intro conjI, clarify) + fix m1 m2 + assume "v m1 = v m2" + then show "m1 = m2" + apply (cases "m1 < n") + apply (cases "m2 < n") + apply (auto simp: inj_on_def v_def [abs_def]) + apply (cases "m2 < n") + apply auto + done next show "v ` UNIV = UNIV - {n}" - proof(auto simp add: v_def) - fix m assume *: "m \ n" and **: "m \ Suc ` {m'. \ m' < n}" - {assume "n \ m" with * have 71: "Suc n \ m" by auto - then obtain m' where 72: "m = Suc m'" using Suc_le_D by auto - with 71 have "n \ m'" by auto - with 72 ** have False by auto - } - thus "m < n" by force + proof (auto simp: v_def [abs_def]) + fix m + assume "m \ n" + assume *: "m \ Suc ` {m'. \ m' < n}" + have False if "n \ m" + proof - + from \m \ n\ that have **: "Suc n \ m" by auto + from Suc_le_D [OF this] obtain m' where m': "m = Suc m'" .. + with ** have "n \ m'" by auto + with m' * show ?thesis by auto + qed + then show "m < n" by force qed qed - (* *) - obtain h' where h'_def: "h' = g o v o (inv g)" by blast - hence 8: "bij_betw h' A' (A' - {a})" using 5 7 6 - by (auto simp add: bij_betw_trans) - (* *) - obtain h where h_def: "h = (\ b. if b \ A' then h' b else b)" by blast - have "\b \ A'. h b = h' b" unfolding h_def by auto - hence "bij_betw h A' (A' - {a})" using 8 bij_betw_cong[of A' h] by auto + define h' where "h' = g \ v \ (inv g)" + with 5 6 7 have 8: "bij_betw h' A' (A' - {a})" + by (auto simp add: bij_betw_trans) + define h where "h b = (if b \ A' then h' b else b)" for b + then have "\b \ A'. h b = h' b" by simp + with 8 have "bij_betw h A' (A' - {a})" + using bij_betw_cong[of A' h] by auto moreover - {have "\b \ A - A'. h b = b" unfolding h_def by auto - hence "bij_betw h (A - A') (A - A')" - using bij_betw_cong[of "A - A'" h id] bij_betw_id[of "A - A'"] by auto - } + have "\b \ A - A'. h b = b" by (auto simp: h_def) + then have "bij_betw h (A - A') (A - A')" + using bij_betw_cong[of "A - A'" h id] bij_betw_id[of "A - A'"] by auto moreover - have "(A' Int (A - A') = {} \ A' \ (A - A') = A) \ - ((A' - {a}) Int (A - A') = {} \ (A' - {a}) \ (A - A') = A - {a})" - using 4 by blast + from 4 have "(A' \ (A - A') = {} \ A' \ (A - A') = A) \ + ((A' - {a}) \ (A - A') = {} \ (A' - {a}) \ (A - A') = A - {a})" + by blast ultimately have "bij_betw h A (A - {a})" - using bij_betw_combine[of h A' "A' - {a}" "A - A'" "A - A'"] by simp - thus ?thesis by blast + using bij_betw_combine[of h A' "A' - {a}" "A - A'" "A - A'"] by simp + then show ?thesis by blast qed lemma infinite_imp_bij_betw2: -assumes INF: "\ finite A" -shows "\h. bij_betw h A (A \ {a})" -proof(cases "a \ A") - assume Case1: "a \ A" hence "A \ {a} = A" by blast - thus ?thesis using bij_betw_id[of A] by auto + assumes "\ finite A" + shows "\h. bij_betw h A (A \ {a})" +proof (cases "a \ A") + case True + then have "A \ {a} = A" by blast + then show ?thesis using bij_betw_id[of A] by auto next + case False let ?A' = "A \ {a}" - assume Case2: "a \ A" hence "A = ?A' - {a}" by blast - moreover have "\ finite ?A'" using INF by auto + from False have "A = ?A' - {a}" by blast + moreover from assms have "\ finite ?A'" by auto ultimately obtain f where "bij_betw f ?A' A" - using infinite_imp_bij_betw[of ?A' a] by auto - hence "bij_betw(inv_into ?A' f) A ?A'" using bij_betw_inv_into by blast - thus ?thesis by auto + using infinite_imp_bij_betw[of ?A' a] by auto + then have "bij_betw (inv_into ?A' f) A ?A'" by (rule bij_betw_inv_into) + then show ?thesis by auto qed -lemma bij_betw_inv_into_left: -assumes BIJ: "bij_betw f A A'" and IN: "a \ A" -shows "(inv_into A f) (f a) = a" -using assms unfolding bij_betw_def -by clarify (rule inv_into_f_f) +lemma bij_betw_inv_into_left: "bij_betw f A A' \ a \ A \ inv_into A f (f a) = a" + unfolding bij_betw_def by clarify (rule inv_into_f_f) -lemma bij_betw_inv_into_right: -assumes "bij_betw f A A'" "a' \ A'" -shows "f(inv_into A f a') = a'" -using assms unfolding bij_betw_def using f_inv_into_f by force +lemma bij_betw_inv_into_right: "bij_betw f A A' \ a' \ A' \ f (inv_into A f a') = a'" + unfolding bij_betw_def using f_inv_into_f by force lemma bij_betw_inv_into_subset: -assumes BIJ: "bij_betw f A A'" and - SUB: "B \ A" and IM: "f ` B = B'" -shows "bij_betw (inv_into A f) B' B" -using assms unfolding bij_betw_def -by (auto intro: inj_on_inv_into) + "bij_betw f A A' \ B \ A \ f ` B = B' \ bij_betw (inv_into A f) B' B" + by (auto simp: bij_betw_def intro: inj_on_inv_into) subsection \Specification package -- Hilbertized version\ -lemma exE_some: "[| Ex P ; c == Eps P |] ==> P c" +lemma exE_some: "Ex P \ c \ Eps P \ P c" by (simp only: someI_ex) ML_file "Tools/choice_specification.ML" diff -r fb63942e470e -r 7195acc2fe93 src/HOL/Relation.thy --- a/src/HOL/Relation.thy Fri Aug 05 16:36:03 2016 +0200 +++ b/src/HOL/Relation.thy Fri Aug 05 18:14:28 2016 +0200 @@ -1,11 +1,12 @@ (* Title: HOL/Relation.thy - Author: Lawrence C Paulson, Cambridge University Computer Laboratory; Stefan Berghofer, TU Muenchen + Author: Lawrence C Paulson, Cambridge University Computer Laboratory + Author: Stefan Berghofer, TU Muenchen *) section \Relations -- as sets of pairs, and binary predicates\ theory Relation -imports Finite_Set + imports Finite_Set begin text \A preliminary: classical rules for reasoning on predicates\ @@ -400,16 +401,17 @@ by (auto intro: transpI) lemma trans_empty [simp]: "trans {}" -by (blast intro: transI) + by (blast intro: transI) lemma transp_empty [simp]: "transp (\x y. False)" -using trans_empty[to_pred] by(simp add: bot_fun_def) + using trans_empty[to_pred] by (simp add: bot_fun_def) lemma trans_singleton [simp]: "trans {(a, a)}" -by (blast intro: transI) + by (blast intro: transI) lemma transp_singleton [simp]: "transp (\x y. x = a \ y = a)" -by(simp add: transp_def) + by (simp add: transp_def) + subsubsection \Totality\ @@ -418,7 +420,7 @@ lemma total_onI [intro?]: "(\x y. \x \ A; y \ A; x \ y\ \ (x, y) \ r \ (y, x) \ r) \ total_on A r" -unfolding total_on_def by blast + unfolding total_on_def by blast abbreviation "total \ total_on UNIV" @@ -426,7 +428,8 @@ by (simp add: total_on_def) lemma total_on_singleton [simp]: "total_on {x} {(x, x)}" -unfolding total_on_def by blast + unfolding total_on_def by blast + subsubsection \Single valued relations\ @@ -496,7 +499,7 @@ subsubsection \Diagonal: identity over a set\ -definition Id_on :: "'a set \ 'a rel" +definition Id_on :: "'a set \ 'a rel" where "Id_on A = (\x\A. {(x, x)})" lemma Id_on_empty [simp]: "Id_on {} = {}" @@ -633,7 +636,7 @@ lemma relcompp_apply: "(R OO S) a c \ (\b. R a b \ S b c)" unfolding relcomp_unfold [to_pred] .. -lemma eq_OO: "op= OO R = R" +lemma eq_OO: "op = OO R = R" by blast lemma OO_eq: "R OO op = = R" @@ -728,10 +731,10 @@ lemma conversep_inject[simp]: "r\\ = s \\ \ r = s" by (fact converse_inject[to_pred]) -lemma converse_subset_swap: "r \ s \ = (r \ \ s)" +lemma converse_subset_swap: "r \ s \ \ r \ \ s" by auto -lemma conversep_le_swap: "r \ s \\ = (r \\ \ s)" +lemma conversep_le_swap: "r \ s \\ \ r \\ \ s" by (fact converse_subset_swap[to_pred]) lemma converse_Id [simp]: "Id\ = Id" @@ -800,7 +803,7 @@ where "Field r = Domain r \ Range r" lemma FieldI1: "(i, j) \ R \ i \ Field R" -unfolding Field_def by blast + unfolding Field_def by blast lemma FieldI2: "(i, j) \ R \ j \ Field R" unfolding Field_def by auto @@ -932,7 +935,7 @@ by blast lemma Field_square [simp]: "Field (x \ x) = x" -unfolding Field_def by blast + unfolding Field_def by blast subsubsection \Image of a set under a relation\ @@ -972,7 +975,7 @@ by blast lemma Image_Int_eq: "single_valued (converse R) \ R `` (A \ B) = R `` A \ R `` B" - by (simp add: single_valued_def, blast) + by (auto simp: single_valued_def) lemma Image_Un: "R `` (A \ B) = R `` A \ R `` B" by blast @@ -1079,7 +1082,7 @@ interpret comp_fun_idem Set.insert by (fact comp_fun_idem_insert) show ?thesis - by standard (auto simp add: fun_eq_iff comp_fun_commute split: prod.split) + by standard (auto simp: fun_eq_iff comp_fun_commute split: prod.split) qed lemma Image_fold: diff -r fb63942e470e -r 7195acc2fe93 src/HOL/Transitive_Closure.thy --- a/src/HOL/Transitive_Closure.thy Fri Aug 05 16:36:03 2016 +0200 +++ b/src/HOL/Transitive_Closure.thy Fri Aug 05 18:14:28 2016 +0200 @@ -6,7 +6,7 @@ section \Reflexive and Transitive closure of a relation\ theory Transitive_Closure -imports Relation + imports Relation begin ML_file "~~/src/Provers/trancl.ML" @@ -16,25 +16,24 @@ \trancl\ is transitive closure, \reflcl\ is reflexive closure. - These postfix operators have \emph{maximum priority}, forcing their + These postfix operators have \<^emph>\maximum priority\, forcing their operands to be atomic. \ -context - notes [[inductive_internals]] +context notes [[inductive_internals]] begin inductive_set rtrancl :: "('a \ 'a) set \ ('a \ 'a) set" ("(_\<^sup>*)" [1000] 999) for r :: "('a \ 'a) set" -where - rtrancl_refl [intro!, Pure.intro!, simp]: "(a, a) \ r\<^sup>*" -| rtrancl_into_rtrancl [Pure.intro]: "(a, b) \ r\<^sup>* \ (b, c) \ r \ (a, c) \ r\<^sup>*" + where + rtrancl_refl [intro!, Pure.intro!, simp]: "(a, a) \ r\<^sup>*" + | rtrancl_into_rtrancl [Pure.intro]: "(a, b) \ r\<^sup>* \ (b, c) \ r \ (a, c) \ r\<^sup>*" inductive_set trancl :: "('a \ 'a) set \ ('a \ 'a) set" ("(_\<^sup>+)" [1000] 999) for r :: "('a \ 'a) set" -where - r_into_trancl [intro, Pure.intro]: "(a, b) \ r \ (a, b) \ r\<^sup>+" -| trancl_into_trancl [Pure.intro]: "(a, b) \ r\<^sup>+ \ (b, c) \ r \ (a, c) \ r\<^sup>+" + where + r_into_trancl [intro, Pure.intro]: "(a, b) \ r \ (a, b) \ r\<^sup>+" + | trancl_into_trancl [Pure.intro]: "(a, b) \ r\<^sup>+ \ (b, c) \ r \ (a, c) \ r\<^sup>+" notation rtranclp ("(_\<^sup>*\<^sup>*)" [1000] 1000) and @@ -215,7 +214,9 @@ lemma rtrancl_r_diff_Id: "(r - Id)\<^sup>* = r\<^sup>*" apply (rule sym) - apply (rule rtrancl_subset, blast, clarify) + apply (rule rtrancl_subset) + apply blast + apply clarify apply (rename_tac a b) apply (case_tac "a = b") apply blast @@ -258,10 +259,10 @@ lemmas converse_rtrancl_induct = converse_rtranclp_induct [to_set] lemmas converse_rtranclp_induct2 = - converse_rtranclp_induct [of _ "(ax,ay)" "(bx,by)", split_rule, consumes 1, case_names refl step] + converse_rtranclp_induct [of _ "(ax, ay)" "(bx, by)", split_rule, consumes 1, case_names refl step] lemmas converse_rtrancl_induct2 = - converse_rtrancl_induct [of "(ax,ay)" "(bx,by)", split_format (complete), + converse_rtrancl_induct [of "(ax, ay)" "(bx, by)", split_format (complete), consumes 1, case_names refl step] lemma converse_rtranclpE [consumes 1, case_names base step]: @@ -283,24 +284,30 @@ lemma r_comp_rtrancl_eq: "r O r\<^sup>* = r\<^sup>* O r" by (blast elim: rtranclE converse_rtranclE - intro: rtrancl_into_rtrancl converse_rtrancl_into_rtrancl) + intro: rtrancl_into_rtrancl converse_rtrancl_into_rtrancl) lemma rtrancl_unfold: "r\<^sup>* = Id \ r\<^sup>* O r" by (auto intro: rtrancl_into_rtrancl elim: rtranclE) lemma rtrancl_Un_separatorE: "(a, b) \ (P \ Q)\<^sup>* \ \x y. (a, x) \ P\<^sup>* \ (x, y) \ Q \ x = y \ (a, b) \ P\<^sup>*" - apply (induct rule:rtrancl.induct) - apply blast - apply (blast intro:rtrancl_trans) - done +proof (induct rule: rtrancl.induct) + case rtrancl_refl + then show ?case by blast +next + case rtrancl_into_rtrancl + then show ?case by (blast intro: rtrancl_trans) +qed lemma rtrancl_Un_separator_converseE: "(a, b) \ (P \ Q)\<^sup>* \ \x y. (x, b) \ P\<^sup>* \ (y, x) \ Q \ y = x \ (a, b) \ P\<^sup>*" - apply (induct rule:converse_rtrancl_induct) - apply blast - apply (blast intro:rtrancl_trans) - done +proof (induct rule: converse_rtrancl_induct) + case base + then show ?case by blast +next + case step + then show ?case by (blast intro: rtrancl_trans) +qed lemma Image_closed_trancl: assumes "r `` X \ X" @@ -368,10 +375,10 @@ lemmas trancl_induct [induct set: trancl] = tranclp_induct [to_set] lemmas tranclp_induct2 = - tranclp_induct [of _ "(ax,ay)" "(bx,by)", split_rule, consumes 1, case_names base step] + tranclp_induct [of _ "(ax, ay)" "(bx, by)", split_rule, consumes 1, case_names base step] lemmas trancl_induct2 = - trancl_induct [of "(ax,ay)" "(bx,by)", split_format (complete), + trancl_induct [of "(ax, ay)" "(bx, by)", split_format (complete), consumes 1, case_names base step] lemma tranclp_trans_induct: @@ -394,7 +401,7 @@ apply (rule subsetI) apply auto apply (erule trancl_induct) - apply auto + apply auto done lemma trancl_unfold: "r\<^sup>+ = r \ r\<^sup>+ O r" @@ -449,7 +456,7 @@ lemma tranclp_converseI: "(r\<^sup>+\<^sup>+)\\ x y \ (r\\)\<^sup>+\<^sup>+ x y" apply (drule conversepD) apply (erule tranclp_induct) - apply (iprover intro: conversepI tranclp_trans)+ + apply (iprover intro: conversepI tranclp_trans)+ done lemmas trancl_converseI = tranclp_converseI [to_set] @@ -457,7 +464,7 @@ lemma tranclp_converseD: "(r\\)\<^sup>+\<^sup>+ x y \ (r\<^sup>+\<^sup>+)\\ x y" apply (rule conversepI) apply (erule tranclp_induct) - apply (iprover dest: conversepD intro: tranclp_trans)+ + apply (iprover dest: conversepD intro: tranclp_trans)+ done lemmas trancl_converseD = tranclp_converseD [to_set] @@ -493,7 +500,7 @@ lemma converse_tranclpE: assumes major: "tranclp r x z" and base: "r x z \ P" - and step: "\ y. r x y \ tranclp r y z \ P" + and step: "\y. r x y \ tranclp r y z \ P" shows P proof - from tranclpD [OF major] obtain y where "r x y" and "rtranclp r y z" @@ -582,7 +589,7 @@ apply (blast intro: rtrancl_into_trancl1 trancl_into_rtrancl trancl_trans) apply (rule subsetI) apply (blast intro: trancl_mono rtrancl_mono - [THEN [2] rev_subsetD] rtrancl_trancl_trancl rtrancl_into_trancl2) + [THEN [2] rev_subsetD] rtrancl_trancl_trancl rtrancl_into_trancl2) done lemma trancl_insert2: @@ -655,26 +662,23 @@ lemma single_valued_confluent: "single_valued r \ (x, y) \ r\<^sup>* \ (x, z) \ r\<^sup>* \ (y, z) \ r\<^sup>* \ (z, y) \ r\<^sup>*" apply (erule rtrancl_induct) - apply simp + apply simp apply (erule disjE) apply (blast elim:converse_rtranclE dest:single_valuedD) - apply(blast intro:rtrancl_trans) + apply (blast intro:rtrancl_trans) done lemma r_r_into_trancl: "(a, b) \ R \ (b, c) \ R \ (a, c) \ R\<^sup>+" by (fast intro: trancl_trans) lemma trancl_into_trancl: "(a, b) \ r\<^sup>+ \ (b, c) \ r \ (a, c) \ r\<^sup>+" - apply (induct rule: trancl_induct) - apply (fast intro: r_r_into_trancl) - apply (fast intro: r_r_into_trancl trancl_trans) - done + by (induct rule: trancl_induct) (fast intro: r_r_into_trancl trancl_trans)+ lemma tranclp_rtranclp_tranclp: "r\<^sup>+\<^sup>+ a b \ r\<^sup>*\<^sup>* b c \ r\<^sup>+\<^sup>+ a c" apply (drule tranclpD) apply (elim exE conjE) apply (drule rtranclp_trans, assumption) - apply (drule rtranclp_into_tranclp2, assumption, assumption) + apply (drule (2) rtranclp_into_tranclp2) done lemmas trancl_rtrancl_trancl = tranclp_rtranclp_tranclp [to_set] @@ -704,14 +708,14 @@ begin primrec relpow :: "nat \ ('a \ 'a) set \ ('a \ 'a) set" -where - "relpow 0 R = Id" -| "relpow (Suc n) R = (R ^^ n) O R" + where + "relpow 0 R = Id" + | "relpow (Suc n) R = (R ^^ n) O R" primrec relpowp :: "nat \ ('a \ 'a \ bool) \ ('a \ 'a \ bool)" -where - "relpowp 0 R = HOL.eq" -| "relpowp (Suc n) R = (R ^^ n) OO R" + where + "relpowp 0 R = HOL.eq" + | "relpowp (Suc n) R = (R ^^ n) OO R" end @@ -740,10 +744,12 @@ hide_const (open) relpow hide_const (open) relpowp -lemma relpow_1 [simp]: "R ^^ 1 = R" for R :: "('a \ 'a) set" +lemma relpow_1 [simp]: "R ^^ 1 = R" + for R :: "('a \ 'a) set" by simp -lemma relpowp_1 [simp]: "P ^^ 1 = P" for P :: "'a \ 'a \ bool" +lemma relpowp_1 [simp]: "P ^^ 1 = P" + for P :: "'a \ 'a \ bool" by (fact relpow_1 [to_pred]) lemma relpow_0_I: "(x, x) \ R ^^ 0" @@ -777,22 +783,20 @@ by (fact relpow_Suc_E [to_pred]) lemma relpow_E: - "(x, z) \ R ^^ n \ (n = 0 \ x = z \ P) - \ (\y m. n = Suc m \ (x, y) \ R ^^ m \ (y, z) \ R \ P) - \ P" + "(x, z) \ R ^^ n \ + (n = 0 \ x = z \ P) \ + (\y m. n = Suc m \ (x, y) \ R ^^ m \ (y, z) \ R \ P) \ P" by (cases n) auto lemma relpowp_E: - "(P ^^ n) x z \ (n = 0 \ x = z \ Q) - \ (\y m. n = Suc m \ (P ^^ m) x y \ P y z \ Q) - \ Q" + "(P ^^ n) x z \ + (n = 0 \ x = z \ Q) \ + (\y m. n = Suc m \ (P ^^ m) x y \ P y z \ Q) \ Q" by (fact relpow_E [to_pred]) lemma relpow_Suc_D2: "(x, z) \ R ^^ Suc n \ (\y. (x, y) \ R \ (y, z) \ R ^^ n)" - apply (induct n arbitrary: x z) - apply (blast intro: relpow_0_I elim: relpow_0_E relpow_Suc_E) - apply (blast intro: relpow_Suc_I elim: relpow_0_E relpow_Suc_E) - done + by (induct n arbitrary: x z) + (blast intro: relpow_0_I relpow_Suc_I elim: relpow_0_E relpow_Suc_E)+ lemma relpowp_Suc_D2: "(P ^^ Suc n) x z \ \y. P x y \ (P ^^ n) y z" by (fact relpow_Suc_D2 [to_pred]) @@ -810,18 +814,21 @@ by (fact relpow_Suc_D2' [to_pred]) lemma relpow_E2: - "(x, z) \ R ^^ n \ (n = 0 \ x = z \ P) - \ (\y m. n = Suc m \ (x, y) \ R \ (y, z) \ R ^^ m \ P) - \ P" - apply (cases n, simp) + "(x, z) \ R ^^ n \ + (n = 0 \ x = z \ P) \ + (\y m. n = Suc m \ (x, y) \ R \ (y, z) \ R ^^ m \ P) \ P" + apply (cases n) + apply simp apply (rename_tac nat) - apply (cut_tac n=nat and R=R in relpow_Suc_D2', simp, blast) + apply (cut_tac n=nat and R=R in relpow_Suc_D2') + apply simp + apply blast done lemma relpowp_E2: - "(P ^^ n) x z \ (n = 0 \ x = z \ Q) - \ (\y m. n = Suc m \ P x y \ (P ^^ m) y z \ Q) - \ Q" + "(P ^^ n) x z \ + (n = 0 \ x = z \ Q) \ + (\y m. n = Suc m \ P x y \ (P ^^ m) y z \ Q) \ Q" by (fact relpow_E2 [to_pred]) lemma relpow_add: "R ^^ (m + n) = R^^m O R^^n" @@ -848,7 +855,8 @@ proof (cases p) case (Pair x y) with assms have "(x, y) \ R\<^sup>*" by simp - then have "(x, y) \ (\n. R ^^ n)" proof induct + then have "(x, y) \ (\n. R ^^ n)" + proof induct case base show ?case by (blast intro: relpow_0_I) next @@ -869,7 +877,8 @@ proof (cases p) case (Pair x y) with assms have "(x, y) \ R ^^ n" by simp - then have "(x, y) \ R\<^sup>*" proof (induct n arbitrary: x y) + then have "(x, y) \ R\<^sup>*" + proof (induct n arbitrary: x y) case 0 then show ?case by simp next @@ -905,10 +914,12 @@ apply (clarsimp simp: relcomp_unfold) apply fastforce apply clarsimp - apply (case_tac n, simp) + apply (case_tac n) + apply simp apply clarsimp apply (drule relpow_imp_rtrancl) - apply (drule rtrancl_into_trancl1) apply auto + apply (drule rtrancl_into_trancl1) + apply auto done lemma tranclp_power: "(P\<^sup>+\<^sup>+) x y \ (\n > 0. (P ^^ n) x y)" @@ -954,7 +965,8 @@ lemma relpow_finite_bounded1: fixes R :: "('a \ 'a) set" assumes "finite R" and "k > 0" - shows "R^^k \ (\n\{n. 0 < n \ n \ card R}. R^^n)" (is "_ \ ?r") + shows "R^^k \ (\n\{n. 0 < n \ n \ card R}. R^^n)" + (is "_ \ ?r") proof - have "(a, b) \ R^^(Suc k) \ \n. 0 < n \ n \ card R \ (a, b) \ R^^n" for a b k proof (induct k arbitrary: b) @@ -1050,8 +1062,7 @@ shows "R^^k \ (UN n:{n. n \ card R}. R^^n)" apply (cases k) apply force - using relpow_finite_bounded1[OF assms, of k] - apply auto + apply (use relpow_finite_bounded1[OF assms, of k] in auto) done lemma rtrancl_finite_eq_relpow: "finite R \ R\<^sup>* = (\n\{n. n \ card R}. R^^n)" @@ -1076,20 +1087,26 @@ fixes R :: "('a \ 'a) set" assumes "finite R" shows "n > 0 \ finite (R^^n)" - apply (induct n) - apply simp - apply (case_tac n) - apply (simp_all add: assms) - done +proof (induct n) + case 0 + then show ?case by simp +next + case (Suc n) + then show ?case by (cases n) (use assms in simp_all) +qed lemma single_valued_relpow: fixes R :: "('a \ 'a) set" shows "single_valued R \ single_valued (R ^^ n)" - apply (induct n arbitrary: R) - apply simp_all - apply (rule single_valuedI) - apply (fast dest: single_valuedD elim: relpow_Suc_E) - done +proof (induct n arbitrary: R) + case 0 + then show ?case by simp +next + case (Suc n) + show ?case + by (rule single_valuedI) + (use Suc in \fast dest: single_valuedD elim: relpow_Suc_E\) +qed subsection \Bounded transitive closure\ @@ -1101,7 +1118,6 @@ proof show "R \ ntrancl 0 R" unfolding ntrancl_def by fastforce -next have "0 < i \ i \ Suc 0 \ i = 1" for i by auto then show "ntrancl 0 R \ R" @@ -1110,31 +1126,30 @@ lemma ntrancl_Suc [simp]: "ntrancl (Suc n) R = ntrancl n R O (Id \ R)" proof - { - fix a b - assume "(a, b) \ ntrancl (Suc n) R" - from this obtain i where "0 < i" "i \ Suc (Suc n)" "(a, b) \ R ^^ i" + have "(a, b) \ ntrancl n R O (Id \ R)" if "(a, b) \ ntrancl (Suc n) R" for a b + proof - + from that obtain i where "0 < i" "i \ Suc (Suc n)" "(a, b) \ R ^^ i" unfolding ntrancl_def by auto - have "(a, b) \ ntrancl n R O (Id \ R)" + show ?thesis proof (cases "i = 1") case True from this \(a, b) \ R ^^ i\ show ?thesis - unfolding ntrancl_def by auto + by (auto simp: ntrancl_def) next case False - from this \0 < i\ obtain j where j: "i = Suc j" "0 < j" + with \0 < i\ obtain j where j: "i = Suc j" "0 < j" by (cases i) auto - from this \(a, b) \ R ^^ i\ obtain c where c1: "(a, c) \ R ^^ j" and c2:"(c, b) \ R" + with \(a, b) \ R ^^ i\ obtain c where c1: "(a, c) \ R ^^ j" and c2: "(c, b) \ R" by auto from c1 j \i \ Suc (Suc n)\ have "(a, c) \ ntrancl n R" - unfolding ntrancl_def by fastforce - from this c2 show ?thesis by fastforce + by (fastforce simp: ntrancl_def) + with c2 show ?thesis by fastforce qed - } + qed then show "ntrancl (Suc n) R \ ntrancl n R O (Id \ R)" by auto show "ntrancl n R O (Id \ R) \ ntrancl (Suc n) R" - unfolding ntrancl_def by fastforce + by (fastforce simp: ntrancl_def) qed lemma [code]: "ntrancl (Suc n) r = (let r' = ntrancl n r in r' \ r' O r)" @@ -1169,9 +1184,7 @@ qed lemma acyclic_insert [iff]: "acyclic (insert (y, x) r) \ acyclic r \ (x, y) \ r\<^sup>*" - apply (simp add: acyclic_def trancl_insert) - apply (blast intro: rtrancl_trans) - done + by (simp add: acyclic_def trancl_insert) (blast intro: rtrancl_trans) lemma acyclic_converse [iff]: "acyclic (r\) \ acyclic r" by (simp add: acyclic_def trancl_converse) @@ -1179,9 +1192,8 @@ lemmas acyclicP_converse [iff] = acyclic_converse [to_pred] lemma acyclic_impl_antisym_rtrancl: "acyclic r \ antisym (r\<^sup>*)" - apply (simp add: acyclic_def antisym_def) - apply (blast elim: rtranclE intro: rtrancl_into_trancl1 rtrancl_trancl_trancl) - done + by (simp add: acyclic_def antisym_def) + (blast elim: rtranclE intro: rtrancl_into_trancl1 rtrancl_trancl_trancl) (* Other direction: acyclic = no loops @@ -1197,7 +1209,6 @@ subsection \Setup of transitivity reasoner\ ML \ - structure Trancl_Tac = Trancl_Tac ( val r_into_trancl = @{thm trancl.r_into_trancl}; diff -r fb63942e470e -r 7195acc2fe93 src/HOL/Wellfounded.thy --- a/src/HOL/Wellfounded.thy Fri Aug 05 16:36:03 2016 +0200 +++ b/src/HOL/Wellfounded.thy Fri Aug 05 18:14:28 2016 +0200 @@ -187,9 +187,7 @@ text \Well-foundedness of subsets\ lemma wf_subset: "wf r \ p \ r \ wf p" - apply (simp add: wf_eq_minimal) - apply fast - done + by (simp add: wf_eq_minimal) fast lemmas wfP_subset = wf_subset [to_pred] @@ -198,11 +196,12 @@ lemma wf_empty [iff]: "wf {}" by (simp add: wf_def) -lemma wfP_empty [iff]: - "wfP (\x y. False)" +lemma wfP_empty [iff]: "wfP (\x y. False)" proof - - have "wfP bot" by (fact wf_empty [to_pred bot_empty_eq2]) - then show ?thesis by (simp add: bot_fun_def) + have "wfP bot" + by (fact wf_empty [to_pred bot_empty_eq2]) + then show ?thesis + by (simp add: bot_fun_def) qed lemma wf_Int1: "wf r \ wf (r \ r')" @@ -217,9 +216,10 @@ shows "wf R" proof (rule wfI_pf) fix A assume "A \ R `` A" - then have "A \ (R ^^ n) `` A" by (induct n) force+ - with \wf (R ^^ n)\ - show "A = {}" by (rule wfE_pf) + then have "A \ (R ^^ n) `` A" + by (induct n) force+ + with \wf (R ^^ n)\ show "A = {}" + by (rule wfE_pf) qed text \Well-foundedness of \insert\.\ @@ -257,7 +257,7 @@ apply (case_tac "\p. f p \ Q") apply (erule_tac x = "{p. f p \ Q}" in allE) apply (fast dest: inj_onD) -apply blast + apply blast done @@ -379,7 +379,7 @@ qed qed -lemma wf_comp_self: "wf R = wf (R O R)" \ \special case\ +lemma wf_comp_self: "wf R \ wf (R O R)" \ \special case\ by (rule wf_union_merge [where S = "{}", simplified]) @@ -390,12 +390,13 @@ lemma qc_wf_relto_iff: assumes "R O S \ (R \ S)\<^sup>* O R" \ \R quasi-commutes over S\ shows "wf (S\<^sup>* O R O S\<^sup>*) \ wf R" - (is "wf ?S \ _") + (is "wf ?S \ _") proof show "wf R" if "wf ?S" proof - have "R \ ?S" by auto - with that show "wf R" using wf_subset by auto + with wf_subset [of ?S] that show "wf R" + by auto qed next show "wf ?S" if "wf R" @@ -607,10 +608,7 @@ qed lemma accp_downwards_aux: "r\<^sup>*\<^sup>* b a \ accp r a \ accp r b" - apply (erule rtranclp_induct) - apply blast - apply (blast dest: accp_downward) - done + by (erule rtranclp_induct) (blast dest: accp_downward)+ theorem accp_downwards: "accp r a \ r\<^sup>*\<^sup>* b a \ accp r b" by (blast dest: accp_downwards_aux) @@ -691,7 +689,7 @@ text \Inverse Image\ lemma wf_inv_image [simp,intro!]: "wf r \ wf (inv_image r f)" - for f :: "'a \ 'b" + for f :: "'a \ 'b" apply (simp add: inv_image_def wf_eq_minimal) apply clarify apply (subgoal_tac "\w::'b. w \ {w. \x::'a. x \ Q \ f x = w}") @@ -776,7 +774,7 @@ done lemma trans_finite_psubset: "trans finite_psubset" - by (auto simp add: finite_psubset_def less_le trans_def) + by (auto simp: finite_psubset_def less_le trans_def) lemma in_finite_psubset[simp]: "(A, B) \ finite_psubset \ A \ B \ finite B" unfolding finite_psubset_def by auto