1 (* Title: HOL/Hilbert_Choice.thy |
1 (* Title: HOL/Hilbert_Choice.thy |
2 Author: Lawrence C Paulson, Tobias Nipkow |
2 Author: Lawrence C Paulson, Tobias Nipkow |
3 Copyright 2001 University of Cambridge |
3 Copyright 2001 University of Cambridge |
4 *) |
4 *) |
5 |
5 |
6 section {* Hilbert's Epsilon-Operator and the Axiom of Choice *} |
6 section \<open>Hilbert's Epsilon-Operator and the Axiom of Choice\<close> |
7 |
7 |
8 theory Hilbert_Choice |
8 theory Hilbert_Choice |
9 imports Nat Wellfounded |
9 imports Nat Wellfounded |
10 keywords "specification" :: thy_goal |
10 keywords "specification" :: thy_goal |
11 begin |
11 begin |
12 |
12 |
13 subsection {* Hilbert's epsilon *} |
13 subsection \<open>Hilbert's epsilon\<close> |
14 |
14 |
15 axiomatization Eps :: "('a => bool) => 'a" where |
15 axiomatization Eps :: "('a => bool) => 'a" where |
16 someI: "P x ==> P (Eps P)" |
16 someI: "P x ==> P (Eps P)" |
17 |
17 |
18 syntax (epsilon) |
18 syntax (epsilon) |
22 syntax |
22 syntax |
23 "_Eps" :: "[pttrn, bool] => 'a" ("(3SOME _./ _)" [0, 10] 10) |
23 "_Eps" :: "[pttrn, bool] => 'a" ("(3SOME _./ _)" [0, 10] 10) |
24 translations |
24 translations |
25 "SOME x. P" == "CONST Eps (%x. P)" |
25 "SOME x. P" == "CONST Eps (%x. P)" |
26 |
26 |
27 print_translation {* |
27 print_translation \<open> |
28 [(@{const_syntax Eps}, fn _ => fn [Abs abs] => |
28 [(@{const_syntax Eps}, fn _ => fn [Abs abs] => |
29 let val (x, t) = Syntax_Trans.atomic_abs_tr' abs |
29 let val (x, t) = Syntax_Trans.atomic_abs_tr' abs |
30 in Syntax.const @{syntax_const "_Eps"} $ x $ t end)] |
30 in Syntax.const @{syntax_const "_Eps"} $ x $ t end)] |
31 *} -- {* to avoid eta-contraction of body *} |
31 \<close> -- \<open>to avoid eta-contraction of body\<close> |
32 |
32 |
33 definition inv_into :: "'a set => ('a => 'b) => ('b => 'a)" where |
33 definition inv_into :: "'a set => ('a => 'b) => ('b => 'a)" where |
34 "inv_into A f == %x. SOME y. y : A & f y = x" |
34 "inv_into A f == %x. SOME y. y : A & f y = x" |
35 |
35 |
36 abbreviation inv :: "('a => 'b) => ('b => 'a)" where |
36 abbreviation inv :: "('a => 'b) => ('b => 'a)" where |
37 "inv == inv_into UNIV" |
37 "inv == inv_into UNIV" |
38 |
38 |
39 |
39 |
40 subsection {*Hilbert's Epsilon-operator*} |
40 subsection \<open>Hilbert's Epsilon-operator\<close> |
41 |
41 |
42 text{*Easier to apply than @{text someI} if the witness comes from an |
42 text\<open>Easier to apply than @{text someI} if the witness comes from an |
43 existential formula*} |
43 existential formula\<close> |
44 lemma someI_ex [elim?]: "\<exists>x. P x ==> P (SOME x. P x)" |
44 lemma someI_ex [elim?]: "\<exists>x. P x ==> P (SOME x. P x)" |
45 apply (erule exE) |
45 apply (erule exE) |
46 apply (erule someI) |
46 apply (erule someI) |
47 done |
47 done |
48 |
48 |
49 text{*Easier to apply than @{text someI} because the conclusion has only one |
49 text\<open>Easier to apply than @{text someI} because the conclusion has only one |
50 occurrence of @{term P}.*} |
50 occurrence of @{term P}.\<close> |
51 lemma someI2: "[| P a; !!x. P x ==> Q x |] ==> Q (SOME x. P x)" |
51 lemma someI2: "[| P a; !!x. P x ==> Q x |] ==> Q (SOME x. P x)" |
52 by (blast intro: someI) |
52 by (blast intro: someI) |
53 |
53 |
54 text{*Easier to apply than @{text someI2} if the witness comes from an |
54 text\<open>Easier to apply than @{text someI2} if the witness comes from an |
55 existential formula*} |
55 existential formula\<close> |
56 lemma someI2_ex: "[| \<exists>a. P a; !!x. P x ==> Q x |] ==> Q (SOME x. P x)" |
56 lemma someI2_ex: "[| \<exists>a. P a; !!x. P x ==> Q x |] ==> Q (SOME x. P x)" |
57 by (blast intro: someI2) |
57 by (blast intro: someI2) |
58 |
58 |
59 lemma some_equality [intro]: |
59 lemma some_equality [intro]: |
60 "[| P a; !!x. P x ==> x=a |] ==> (SOME x. P x) = a" |
60 "[| P a; !!x. P x ==> x=a |] ==> (SOME x. P x) = a" |
150 by (simp add:inv_into_f_eq) |
150 by (simp add:inv_into_f_eq) |
151 |
151 |
152 lemma inj_imp_inv_eq: "[| inj f; ALL x. f(g x) = x |] ==> inv f = g" |
152 lemma inj_imp_inv_eq: "[| inj f; ALL x. f(g x) = x |] ==> inv f = g" |
153 by (blast intro: inv_into_f_eq) |
153 by (blast intro: inv_into_f_eq) |
154 |
154 |
155 text{*But is it useful?*} |
155 text\<open>But is it useful?\<close> |
156 lemma inj_transfer: |
156 lemma inj_transfer: |
157 assumes injf: "inj f" and minor: "!!y. y \<in> range(f) ==> P(inv f y)" |
157 assumes injf: "inj f" and minor: "!!y. y \<in> range(f) ==> P(inv f y)" |
158 shows "P x" |
158 shows "P x" |
159 proof - |
159 proof - |
160 have "f x \<in> range f" by auto |
160 have "f x \<in> range f" by auto |
286 thus "x \<in> range (\<lambda>f\<Colon>'a \<Rightarrow> 'b. inv f b1)" by blast |
286 thus "x \<in> range (\<lambda>f\<Colon>'a \<Rightarrow> 'b. inv f b1)" by blast |
287 qed |
287 qed |
288 ultimately show "finite (UNIV :: 'a set)" by simp |
288 ultimately show "finite (UNIV :: 'a set)" by simp |
289 qed |
289 qed |
290 |
290 |
291 text {* |
291 text \<open> |
292 Every infinite set contains a countable subset. More precisely we |
292 Every infinite set contains a countable subset. More precisely we |
293 show that a set @{text S} is infinite if and only if there exists an |
293 show that a set @{text S} is infinite if and only if there exists an |
294 injective function from the naturals into @{text S}. |
294 injective function from the naturals into @{text S}. |
295 |
295 |
296 The ``only if'' direction is harder because it requires the |
296 The ``only if'' direction is harder because it requires the |
297 construction of a sequence of pairwise different elements of an |
297 construction of a sequence of pairwise different elements of an |
298 infinite set @{text S}. The idea is to construct a sequence of |
298 infinite set @{text S}. The idea is to construct a sequence of |
299 non-empty and infinite subsets of @{text S} obtained by successively |
299 non-empty and infinite subsets of @{text S} obtained by successively |
300 removing elements of @{text S}. |
300 removing elements of @{text S}. |
301 *} |
301 \<close> |
302 |
302 |
303 lemma infinite_countable_subset: |
303 lemma infinite_countable_subset: |
304 assumes inf: "\<not> finite (S::'a set)" |
304 assumes inf: "\<not> finite (S::'a set)" |
305 shows "\<exists>f. inj (f::nat \<Rightarrow> 'a) \<and> range f \<subseteq> S" |
305 shows "\<exists>f. inj (f::nat \<Rightarrow> 'a) \<and> range f \<subseteq> S" |
306 -- {* Courtesy of Stephan Merz *} |
306 -- \<open>Courtesy of Stephan Merz\<close> |
307 proof - |
307 proof - |
308 def Sseq \<equiv> "rec_nat S (\<lambda>n T. T - {SOME e. e \<in> T})" |
308 def Sseq \<equiv> "rec_nat S (\<lambda>n T. T - {SOME e. e \<in> T})" |
309 def pick \<equiv> "\<lambda>n. (SOME e. e \<in> Sseq n)" |
309 def pick \<equiv> "\<lambda>n. (SOME e. e \<in> Sseq n)" |
310 { fix n have "Sseq n \<subseteq> S" "\<not> finite (Sseq n)" by (induct n) (auto simp add: Sseq_def inf) } |
310 { fix n have "Sseq n \<subseteq> S" "\<not> finite (Sseq n)" by (induct n) (auto simp add: Sseq_def inf) } |
311 moreover then have *: "\<And>n. pick n \<in> Sseq n" |
311 moreover then have *: "\<And>n. pick n \<in> Sseq n" |
319 then have "inj pick" by (intro linorder_injI) (auto simp add: less_iff_Suc_add) |
319 then have "inj pick" by (intro linorder_injI) (auto simp add: less_iff_Suc_add) |
320 ultimately show ?thesis by blast |
320 ultimately show ?thesis by blast |
321 qed |
321 qed |
322 |
322 |
323 lemma infinite_iff_countable_subset: "\<not> finite S \<longleftrightarrow> (\<exists>f. inj (f::nat \<Rightarrow> 'a) \<and> range f \<subseteq> S)" |
323 lemma infinite_iff_countable_subset: "\<not> finite S \<longleftrightarrow> (\<exists>f. inj (f::nat \<Rightarrow> 'a) \<and> range f \<subseteq> S)" |
324 -- {* Courtesy of Stephan Merz *} |
324 -- \<open>Courtesy of Stephan Merz\<close> |
325 using finite_imageD finite_subset infinite_UNIV_char_0 infinite_countable_subset by auto |
325 using finite_imageD finite_subset infinite_UNIV_char_0 infinite_countable_subset by auto |
326 |
326 |
327 lemma image_inv_into_cancel: |
327 lemma image_inv_into_cancel: |
328 assumes SURJ: "f`A=A'" and SUB: "B' \<le> A'" |
328 assumes SURJ: "f`A=A'" and SUB: "B' \<le> A'" |
329 shows "f `((inv_into A f)`B') = B'" |
329 shows "f `((inv_into A f)`B') = B'" |
343 proof - |
343 proof - |
344 let ?f' = "inv_into A f" let ?f'' = "inv_into A' ?f'" |
344 let ?f' = "inv_into A f" let ?f'' = "inv_into A' ?f'" |
345 have 1: "bij_betw ?f' A' A" using assms |
345 have 1: "bij_betw ?f' A' A" using assms |
346 by (auto simp add: bij_betw_inv_into) |
346 by (auto simp add: bij_betw_inv_into) |
347 obtain a' where 2: "a' \<in> A'" and 3: "?f' a' = a" |
347 obtain a' where 2: "a' \<in> A'" and 3: "?f' a' = a" |
348 using 1 `a \<in> A` unfolding bij_betw_def by force |
348 using 1 \<open>a \<in> A\<close> unfolding bij_betw_def by force |
349 hence "?f'' a = a'" |
349 hence "?f'' a = a'" |
350 using `a \<in> A` 1 3 by (auto simp add: f_inv_into_f bij_betw_def) |
350 using \<open>a \<in> A\<close> 1 3 by (auto simp add: f_inv_into_f bij_betw_def) |
351 moreover have "f a = a'" using assms 2 3 |
351 moreover have "f a = a'" using assms 2 3 |
352 by (auto simp add: bij_betw_def) |
352 by (auto simp add: bij_betw_def) |
353 ultimately show "?f'' a = f a" by simp |
353 ultimately show "?f'' a = f a" by simp |
354 qed |
354 qed |
355 |
355 |
430 and gf: "g \<circ> f = id" |
430 and gf: "g \<circ> f = id" |
431 shows "inv f = g" |
431 shows "inv f = g" |
432 using fg gf inv_equality[of g f] by (auto simp add: fun_eq_iff) |
432 using fg gf inv_equality[of g f] by (auto simp add: fun_eq_iff) |
433 |
433 |
434 |
434 |
435 subsection {* The Cantor-Bernstein Theorem *} |
435 subsection \<open>The Cantor-Bernstein Theorem\<close> |
436 |
436 |
437 lemma Cantor_Bernstein_aux: |
437 lemma Cantor_Bernstein_aux: |
438 shows "\<exists>A' h. A' \<le> A \<and> |
438 shows "\<exists>A' h. A' \<le> A \<and> |
439 (\<forall>a \<in> A'. a \<notin> g`(B - f ` A')) \<and> |
439 (\<forall>a \<in> A'. a \<notin> g`(B - f ` A')) \<and> |
440 (\<forall>a \<in> A'. h a = f a) \<and> |
440 (\<forall>a \<in> A'. h a = f a) \<and> |
532 qed |
532 qed |
533 (* *) |
533 (* *) |
534 ultimately show ?thesis unfolding bij_betw_def by auto |
534 ultimately show ?thesis unfolding bij_betw_def by auto |
535 qed |
535 qed |
536 |
536 |
537 subsection {*Other Consequences of Hilbert's Epsilon*} |
537 subsection \<open>Other Consequences of Hilbert's Epsilon\<close> |
538 |
538 |
539 text {*Hilbert's Epsilon and the @{term split} Operator*} |
539 text \<open>Hilbert's Epsilon and the @{term split} Operator\<close> |
540 |
540 |
541 text{*Looping simprule*} |
541 text\<open>Looping simprule\<close> |
542 lemma split_paired_Eps: "(SOME x. P x) = (SOME (a,b). P(a,b))" |
542 lemma split_paired_Eps: "(SOME x. P x) = (SOME (a,b). P(a,b))" |
543 by simp |
543 by simp |
544 |
544 |
545 lemma Eps_split: "Eps (split P) = (SOME xy. P (fst xy) (snd xy))" |
545 lemma Eps_split: "Eps (split P) = (SOME xy. P (fst xy) (snd xy))" |
546 by (simp add: split_def) |
546 by (simp add: split_def) |
547 |
547 |
548 lemma Eps_split_eq [simp]: "(@(x',y'). x = x' & y = y') = (x,y)" |
548 lemma Eps_split_eq [simp]: "(@(x',y'). x = x' & y = y') = (x,y)" |
549 by blast |
549 by blast |
550 |
550 |
551 |
551 |
552 text{*A relation is wellfounded iff it has no infinite descending chain*} |
552 text\<open>A relation is wellfounded iff it has no infinite descending chain\<close> |
553 lemma wf_iff_no_infinite_down_chain: |
553 lemma wf_iff_no_infinite_down_chain: |
554 "wf r = (~(\<exists>f. \<forall>i. (f(Suc i),f i) \<in> r))" |
554 "wf r = (~(\<exists>f. \<forall>i. (f(Suc i),f i) \<in> r))" |
555 apply (simp only: wf_eq_minimal) |
555 apply (simp only: wf_eq_minimal) |
556 apply (rule iffI) |
556 apply (rule iffI) |
557 apply (rule notI) |
557 apply (rule notI) |
567 apply (rule someI2_ex, blast+) |
567 apply (rule someI2_ex, blast+) |
568 done |
568 done |
569 |
569 |
570 lemma wf_no_infinite_down_chainE: |
570 lemma wf_no_infinite_down_chainE: |
571 assumes "wf r" obtains k where "(f (Suc k), f k) \<notin> r" |
571 assumes "wf r" obtains k where "(f (Suc k), f k) \<notin> r" |
572 using `wf r` wf_iff_no_infinite_down_chain[of r] by blast |
572 using \<open>wf r\<close> wf_iff_no_infinite_down_chain[of r] by blast |
573 |
573 |
574 |
574 |
575 text{*A dynamically-scoped fact for TFL *} |
575 text\<open>A dynamically-scoped fact for TFL\<close> |
576 lemma tfl_some: "\<forall>P x. P x --> P (Eps P)" |
576 lemma tfl_some: "\<forall>P x. P x --> P (Eps P)" |
577 by (blast intro: someI) |
577 by (blast intro: someI) |
578 |
578 |
579 |
579 |
580 subsection {* Least value operator *} |
580 subsection \<open>Least value operator\<close> |
581 |
581 |
582 definition |
582 definition |
583 LeastM :: "['a => 'b::ord, 'a => bool] => 'a" where |
583 LeastM :: "['a => 'b::ord, 'a => bool] => 'a" where |
584 "LeastM m P == SOME x. P x & (\<forall>y. P y --> m x <= m y)" |
584 "LeastM m P == SOME x. P x & (\<forall>y. P y --> m x <= m y)" |
585 |
585 |
628 |
628 |
629 lemma LeastM_nat_le: "P x ==> m (LeastM m P) <= (m x::nat)" |
629 lemma LeastM_nat_le: "P x ==> m (LeastM m P) <= (m x::nat)" |
630 by (rule LeastM_nat_lemma [THEN conjunct2, THEN spec, THEN mp], assumption, assumption) |
630 by (rule LeastM_nat_lemma [THEN conjunct2, THEN spec, THEN mp], assumption, assumption) |
631 |
631 |
632 |
632 |
633 subsection {* Greatest value operator *} |
633 subsection \<open>Greatest value operator\<close> |
634 |
634 |
635 definition |
635 definition |
636 GreatestM :: "['a => 'b::ord, 'a => bool] => 'a" where |
636 GreatestM :: "['a => 'b::ord, 'a => bool] => 'a" where |
637 "GreatestM m P == SOME x. P x & (\<forall>y. P y --> m y <= m x)" |
637 "GreatestM m P == SOME x. P x & (\<forall>y. P y --> m y <= m x)" |
638 |
638 |
697 ==> (m x::nat) <= m (GreatestM m P)" |
697 ==> (m x::nat) <= m (GreatestM m P)" |
698 apply (blast dest: GreatestM_nat_lemma [THEN conjunct2, THEN spec, of P]) |
698 apply (blast dest: GreatestM_nat_lemma [THEN conjunct2, THEN spec, of P]) |
699 done |
699 done |
700 |
700 |
701 |
701 |
702 text {* \medskip Specialization to @{text GREATEST}. *} |
702 text \<open>\medskip Specialization to @{text GREATEST}.\<close> |
703 |
703 |
704 lemma GreatestI: "P (k::nat) ==> \<forall>y. P y --> y < b ==> P (GREATEST x. P x)" |
704 lemma GreatestI: "P (k::nat) ==> \<forall>y. P y --> y < b ==> P (GREATEST x. P x)" |
705 apply (simp add: Greatest_def) |
705 apply (simp add: Greatest_def) |
706 apply (rule GreatestM_natI, auto) |
706 apply (rule GreatestM_natI, auto) |
707 done |
707 done |
711 apply (simp add: Greatest_def) |
711 apply (simp add: Greatest_def) |
712 apply (rule GreatestM_nat_le, auto) |
712 apply (rule GreatestM_nat_le, auto) |
713 done |
713 done |
714 |
714 |
715 |
715 |
716 subsection {* An aside: bounded accessible part *} |
716 subsection \<open>An aside: bounded accessible part\<close> |
717 |
717 |
718 text {* Finite monotone eventually stable sequences *} |
718 text \<open>Finite monotone eventually stable sequences\<close> |
719 |
719 |
720 lemma finite_mono_remains_stable_implies_strict_prefix: |
720 lemma finite_mono_remains_stable_implies_strict_prefix: |
721 fixes f :: "nat \<Rightarrow> 'a::order" |
721 fixes f :: "nat \<Rightarrow> 'a::order" |
722 assumes S: "finite (range f)" "mono f" and eq: "\<forall>n. f n = f (Suc n) \<longrightarrow> f (Suc n) = f (Suc (Suc n))" |
722 assumes S: "finite (range f)" "mono f" and eq: "\<forall>n. f n = f (Suc n) \<longrightarrow> f (Suc n) = f (Suc (Suc n))" |
723 shows "\<exists>N. (\<forall>n\<le>N. \<forall>m\<le>N. m < n \<longrightarrow> f m < f n) \<and> (\<forall>n\<ge>N. f N = f n)" |
723 shows "\<exists>N. (\<forall>n\<le>N. \<forall>m\<le>N. m < n \<longrightarrow> f m < f n) \<and> (\<forall>n\<ge>N. f N = f n)" |
726 have "\<exists>n. f n = f (Suc n)" |
726 have "\<exists>n. f n = f (Suc n)" |
727 proof (rule ccontr) |
727 proof (rule ccontr) |
728 assume "\<not> ?thesis" |
728 assume "\<not> ?thesis" |
729 then have "\<And>n. f n \<noteq> f (Suc n)" by auto |
729 then have "\<And>n. f n \<noteq> f (Suc n)" by auto |
730 then have "\<And>n. f n < f (Suc n)" |
730 then have "\<And>n. f n < f (Suc n)" |
731 using `mono f` by (auto simp: le_less mono_iff_le_Suc) |
731 using \<open>mono f\<close> by (auto simp: le_less mono_iff_le_Suc) |
732 with lift_Suc_mono_less_iff[of f] |
732 with lift_Suc_mono_less_iff[of f] |
733 have *: "\<And>n m. n < m \<Longrightarrow> f n < f m" by auto |
733 have *: "\<And>n m. n < m \<Longrightarrow> f n < f m" by auto |
734 have "inj f" |
734 have "inj f" |
735 proof (intro injI) |
735 proof (intro injI) |
736 fix x y |
736 fix x y |
737 assume "f x = f y" |
737 assume "f x = f y" |
738 then show "x = y" by (cases x y rule: linorder_cases) (auto dest: *) |
738 then show "x = y" by (cases x y rule: linorder_cases) (auto dest: *) |
739 qed |
739 qed |
740 with `finite (range f)` have "finite (UNIV::nat set)" |
740 with \<open>finite (range f)\<close> have "finite (UNIV::nat set)" |
741 by (rule finite_imageD) |
741 by (rule finite_imageD) |
742 then show False by simp |
742 then show False by simp |
743 qed |
743 qed |
744 then obtain n where n: "f n = f (Suc n)" .. |
744 then obtain n where n: "f n = f (Suc n)" .. |
745 def N \<equiv> "LEAST n. f n = f (Suc n)" |
745 def N \<equiv> "LEAST n. f n = f (Suc n)" |
752 proof (induct rule: dec_induct) |
752 proof (induct rule: dec_induct) |
753 case (step n) then show ?case |
753 case (step n) then show ?case |
754 using eq[rule_format, of "n - 1"] N |
754 using eq[rule_format, of "n - 1"] N |
755 by (cases n) (auto simp add: le_Suc_eq) |
755 by (cases n) (auto simp add: le_Suc_eq) |
756 qed simp |
756 qed simp |
757 from this[of n] `N \<le> n` show "f N = f n" by auto |
757 from this[of n] \<open>N \<le> n\<close> show "f N = f n" by auto |
758 next |
758 next |
759 fix n m :: nat assume "m < n" "n \<le> N" |
759 fix n m :: nat assume "m < n" "n \<le> N" |
760 then show "f m < f n" |
760 then show "f m < f n" |
761 proof (induct rule: less_Suc_induct[consumes 1]) |
761 proof (induct rule: less_Suc_induct[consumes 1]) |
762 case (1 i) |
762 case (1 i) |
763 then have "i < N" by simp |
763 then have "i < N" by simp |
764 then have "f i \<noteq> f (Suc i)" |
764 then have "f i \<noteq> f (Suc i)" |
765 unfolding N_def by (rule not_less_Least) |
765 unfolding N_def by (rule not_less_Least) |
766 with `mono f` show ?case by (simp add: mono_iff_le_Suc less_le) |
766 with \<open>mono f\<close> show ?case by (simp add: mono_iff_le_Suc less_le) |
767 qed auto |
767 qed auto |
768 qed |
768 qed |
769 qed |
769 qed |
770 |
770 |
771 lemma finite_mono_strict_prefix_implies_finite_fixpoint: |
771 lemma finite_mono_strict_prefix_implies_finite_fixpoint: |
797 apply (auto simp: not_less) |
797 apply (auto simp: not_less) |
798 done |
798 done |
799 qed |
799 qed |
800 |
800 |
801 |
801 |
802 subsection {* More on injections, bijections, and inverses *} |
802 subsection \<open>More on injections, bijections, and inverses\<close> |
803 |
803 |
804 lemma infinite_imp_bij_betw: |
804 lemma infinite_imp_bij_betw: |
805 assumes INF: "\<not> finite A" |
805 assumes INF: "\<not> finite A" |
806 shows "\<exists>h. bij_betw h A (A - {a})" |
806 shows "\<exists>h. bij_betw h A (A - {a})" |
807 proof(cases "a \<in> A") |
807 proof(cases "a \<in> A") |
911 shows "bij_betw (inv_into A f) B' B" |
911 shows "bij_betw (inv_into A f) B' B" |
912 using assms unfolding bij_betw_def |
912 using assms unfolding bij_betw_def |
913 by (auto intro: inj_on_inv_into) |
913 by (auto intro: inj_on_inv_into) |
914 |
914 |
915 |
915 |
916 subsection {* Specification package -- Hilbertized version *} |
916 subsection \<open>Specification package -- Hilbertized version\<close> |
917 |
917 |
918 lemma exE_some: "[| Ex P ; c == Eps P |] ==> P c" |
918 lemma exE_some: "[| Ex P ; c == Eps P |] ==> P c" |
919 by (simp only: someI_ex) |
919 by (simp only: someI_ex) |
920 |
920 |
921 ML_file "Tools/choice_specification.ML" |
921 ML_file "Tools/choice_specification.ML" |