src/HOL/Hilbert_Choice.thy
changeset 33057 764547b68538
parent 33014 85d7a096e63f
child 35115 446c5063e4fd
equal deleted inserted replaced
33056:791a4655cae3 33057:764547b68538
    29 [(@{const_syntax Eps}, fn [Abs abs] =>
    29 [(@{const_syntax Eps}, fn [Abs abs] =>
    30      let val (x,t) = atomic_abs_tr' abs
    30      let val (x,t) = atomic_abs_tr' abs
    31      in Syntax.const "_Eps" $ x $ t end)]
    31      in Syntax.const "_Eps" $ x $ t end)]
    32 *}
    32 *}
    33 
    33 
    34 definition inv_onto :: "'a set => ('a => 'b) => ('b => 'a)" where
    34 definition inv_into :: "'a set => ('a => 'b) => ('b => 'a)" where
    35 "inv_onto A f == %x. SOME y. y : A & f y = x"
    35 "inv_into A f == %x. SOME y. y : A & f y = x"
    36 
    36 
    37 abbreviation inv :: "('a => 'b) => ('b => 'a)" where
    37 abbreviation inv :: "('a => 'b) => ('b => 'a)" where
    38 "inv == inv_onto UNIV"
    38 "inv == inv_into UNIV"
    39 
    39 
    40 
    40 
    41 subsection {*Hilbert's Epsilon-operator*}
    41 subsection {*Hilbert's Epsilon-operator*}
    42 
    42 
    43 text{*Easier to apply than @{text someI} if the witness comes from an
    43 text{*Easier to apply than @{text someI} if the witness comes from an
    90 
    90 
    91 
    91 
    92 subsection {*Function Inverse*}
    92 subsection {*Function Inverse*}
    93 
    93 
    94 lemma inv_def: "inv f = (%y. SOME x. f x = y)"
    94 lemma inv_def: "inv f = (%y. SOME x. f x = y)"
    95 by(simp add: inv_onto_def)
    95 by(simp add: inv_into_def)
    96 
    96 
    97 lemma inv_onto_into: "x : f ` A ==> inv_onto A f x : A"
    97 lemma inv_into_into: "x : f ` A ==> inv_into A f x : A"
    98 apply (simp add: inv_onto_def)
    98 apply (simp add: inv_into_def)
    99 apply (fast intro: someI2)
    99 apply (fast intro: someI2)
   100 done
   100 done
   101 
   101 
   102 lemma inv_id [simp]: "inv id = id"
   102 lemma inv_id [simp]: "inv id = id"
   103 by (simp add: inv_onto_def id_def)
   103 by (simp add: inv_into_def id_def)
   104 
   104 
   105 lemma inv_onto_f_f [simp]:
   105 lemma inv_into_f_f [simp]:
   106   "[| inj_on f A;  x : A |] ==> inv_onto A f (f x) = x"
   106   "[| inj_on f A;  x : A |] ==> inv_into A f (f x) = x"
   107 apply (simp add: inv_onto_def inj_on_def)
   107 apply (simp add: inv_into_def inj_on_def)
   108 apply (blast intro: someI2)
   108 apply (blast intro: someI2)
   109 done
   109 done
   110 
   110 
   111 lemma inv_f_f: "inj f ==> inv f (f x) = x"
   111 lemma inv_f_f: "inj f ==> inv f (f x) = x"
   112 by (simp add: inv_onto_f_f)
   112 by (simp add: inv_into_f_f)
   113 
   113 
   114 lemma f_inv_onto_f: "y : f`A  ==> f (inv_onto A f y) = y"
   114 lemma f_inv_into_f: "y : f`A  ==> f (inv_into A f y) = y"
   115 apply (simp add: inv_onto_def)
   115 apply (simp add: inv_into_def)
   116 apply (fast intro: someI2)
   116 apply (fast intro: someI2)
   117 done
   117 done
   118 
   118 
   119 lemma inv_onto_f_eq: "[| inj_on f A; x : A; f x = y |] ==> inv_onto A f y = x"
   119 lemma inv_into_f_eq: "[| inj_on f A; x : A; f x = y |] ==> inv_into A f y = x"
   120 apply (erule subst)
   120 apply (erule subst)
   121 apply (fast intro: inv_onto_f_f)
   121 apply (fast intro: inv_into_f_f)
   122 done
   122 done
   123 
   123 
   124 lemma inv_f_eq: "[| inj f; f x = y |] ==> inv f y = x"
   124 lemma inv_f_eq: "[| inj f; f x = y |] ==> inv f y = x"
   125 by (simp add:inv_onto_f_eq)
   125 by (simp add:inv_into_f_eq)
   126 
   126 
   127 lemma inj_imp_inv_eq: "[| inj f; ALL x. f(g x) = x |] ==> inv f = g"
   127 lemma inj_imp_inv_eq: "[| inj f; ALL x. f(g x) = x |] ==> inv f = g"
   128 by (blast intro: ext inv_onto_f_eq)
   128 by (blast intro: ext inv_into_f_eq)
   129 
   129 
   130 text{*But is it useful?*}
   130 text{*But is it useful?*}
   131 lemma inj_transfer:
   131 lemma inj_transfer:
   132   assumes injf: "inj f" and minor: "!!y. y \<in> range(f) ==> P(inv f y)"
   132   assumes injf: "inj f" and minor: "!!y. y \<in> range(f) ==> P(inv f y)"
   133   shows "P x"
   133   shows "P x"
   134 proof -
   134 proof -
   135   have "f x \<in> range f" by auto
   135   have "f x \<in> range f" by auto
   136   hence "P(inv f (f x))" by (rule minor)
   136   hence "P(inv f (f x))" by (rule minor)
   137   thus "P x" by (simp add: inv_onto_f_f [OF injf])
   137   thus "P x" by (simp add: inv_into_f_f [OF injf])
   138 qed
   138 qed
   139 
   139 
   140 lemma inj_iff: "(inj f) = (inv f o f = id)"
   140 lemma inj_iff: "(inj f) = (inv f o f = id)"
   141 apply (simp add: o_def expand_fun_eq)
   141 apply (simp add: o_def expand_fun_eq)
   142 apply (blast intro: inj_on_inverseI inv_onto_f_f)
   142 apply (blast intro: inj_on_inverseI inv_into_f_f)
   143 done
   143 done
   144 
   144 
   145 lemma inv_o_cancel[simp]: "inj f ==> inv f o f = id"
   145 lemma inv_o_cancel[simp]: "inj f ==> inv f o f = id"
   146 by (simp add: inj_iff)
   146 by (simp add: inj_iff)
   147 
   147 
   148 lemma o_inv_o_cancel[simp]: "inj f ==> g o inv f o f = g"
   148 lemma o_inv_o_cancel[simp]: "inj f ==> g o inv f o f = g"
   149 by (simp add: o_assoc[symmetric])
   149 by (simp add: o_assoc[symmetric])
   150 
   150 
   151 lemma inv_onto_image_cancel[simp]:
   151 lemma inv_into_image_cancel[simp]:
   152   "inj_on f A ==> S <= A ==> inv_onto A f ` f ` S = S"
   152   "inj_on f A ==> S <= A ==> inv_into A f ` f ` S = S"
   153 by(fastsimp simp: image_def)
   153 by(fastsimp simp: image_def)
   154 
   154 
   155 lemma inj_imp_surj_inv: "inj f ==> surj (inv f)"
   155 lemma inj_imp_surj_inv: "inj f ==> surj (inv f)"
   156 by (blast intro: surjI inv_onto_f_f)
   156 by (blast intro: surjI inv_into_f_f)
   157 
   157 
   158 lemma surj_f_inv_f: "surj f ==> f(inv f y) = y"
   158 lemma surj_f_inv_f: "surj f ==> f(inv f y) = y"
   159 by (simp add: f_inv_onto_f surj_range)
   159 by (simp add: f_inv_into_f surj_range)
   160 
   160 
   161 lemma inv_onto_injective:
   161 lemma inv_into_injective:
   162   assumes eq: "inv_onto A f x = inv_onto A f y"
   162   assumes eq: "inv_into A f x = inv_into A f y"
   163       and x: "x: f`A"
   163       and x: "x: f`A"
   164       and y: "y: f`A"
   164       and y: "y: f`A"
   165   shows "x=y"
   165   shows "x=y"
   166 proof -
   166 proof -
   167   have "f (inv_onto A f x) = f (inv_onto A f y)" using eq by simp
   167   have "f (inv_into A f x) = f (inv_into A f y)" using eq by simp
   168   thus ?thesis by (simp add: f_inv_onto_f x y)
   168   thus ?thesis by (simp add: f_inv_into_f x y)
   169 qed
   169 qed
   170 
   170 
   171 lemma inj_on_inv_onto: "B <= f`A ==> inj_on (inv_onto A f) B"
   171 lemma inj_on_inv_into: "B <= f`A ==> inj_on (inv_into A f) B"
   172 by (blast intro: inj_onI dest: inv_onto_injective injD)
   172 by (blast intro: inj_onI dest: inv_into_injective injD)
   173 
   173 
   174 lemma bij_betw_inv_onto: "bij_betw f A B ==> bij_betw (inv_onto A f) B A"
   174 lemma bij_betw_inv_into: "bij_betw f A B ==> bij_betw (inv_into A f) B A"
   175 by (auto simp add: bij_betw_def inj_on_inv_onto)
   175 by (auto simp add: bij_betw_def inj_on_inv_into)
   176 
   176 
   177 lemma surj_imp_inj_inv: "surj f ==> inj (inv f)"
   177 lemma surj_imp_inj_inv: "surj f ==> inj (inv f)"
   178 by (simp add: inj_on_inv_onto surj_range)
   178 by (simp add: inj_on_inv_into surj_range)
   179 
   179 
   180 lemma surj_iff: "(surj f) = (f o inv f = id)"
   180 lemma surj_iff: "(surj f) = (f o inv f = id)"
   181 apply (simp add: o_def expand_fun_eq)
   181 apply (simp add: o_def expand_fun_eq)
   182 apply (blast intro: surjI surj_f_inv_f)
   182 apply (blast intro: surjI surj_f_inv_f)
   183 done
   183 done
   191 lemma bij_imp_bij_inv: "bij f ==> bij (inv f)"
   191 lemma bij_imp_bij_inv: "bij f ==> bij (inv f)"
   192 by (simp add: bij_def inj_imp_surj_inv surj_imp_inj_inv)
   192 by (simp add: bij_def inj_imp_surj_inv surj_imp_inj_inv)
   193 
   193 
   194 lemma inv_equality: "[| !!x. g (f x) = x;  !!y. f (g y) = y |] ==> inv f = g"
   194 lemma inv_equality: "[| !!x. g (f x) = x;  !!y. f (g y) = y |] ==> inv f = g"
   195 apply (rule ext)
   195 apply (rule ext)
   196 apply (auto simp add: inv_onto_def)
   196 apply (auto simp add: inv_into_def)
   197 done
   197 done
   198 
   198 
   199 lemma inv_inv_eq: "bij f ==> inv (inv f) = f"
   199 lemma inv_inv_eq: "bij f ==> inv (inv f) = f"
   200 apply (rule inv_equality)
   200 apply (rule inv_equality)
   201 apply (auto simp add: bij_def surj_f_inv_f)
   201 apply (auto simp add: bij_def surj_f_inv_f)
   206     inv f could be any function at all, including the identity function.
   206     inv f could be any function at all, including the identity function.
   207     If inv f=id then inv f is a bijection, but inj f, surj(f) and
   207     If inv f=id then inv f is a bijection, but inj f, surj(f) and
   208     inv(inv f)=f all fail.
   208     inv(inv f)=f all fail.
   209 **)
   209 **)
   210 
   210 
   211 lemma inv_onto_comp:
   211 lemma inv_into_comp:
   212   "[| inj_on f (g ` A); inj_on g A; x : f ` g ` A |] ==>
   212   "[| inj_on f (g ` A); inj_on g A; x : f ` g ` A |] ==>
   213   inv_onto A (f o g) x = (inv_onto A g o inv_onto (g ` A) f) x"
   213   inv_into A (f o g) x = (inv_into A g o inv_into (g ` A) f) x"
   214 apply (rule inv_onto_f_eq)
   214 apply (rule inv_into_f_eq)
   215   apply (fast intro: comp_inj_on)
   215   apply (fast intro: comp_inj_on)
   216  apply (simp add: inv_onto_into)
   216  apply (simp add: inv_into_into)
   217 apply (simp add: f_inv_onto_f inv_onto_into)
   217 apply (simp add: f_inv_into_f inv_into_into)
   218 done
   218 done
   219 
   219 
   220 lemma o_inv_distrib: "[| bij f; bij g |] ==> inv (f o g) = inv g o inv f"
   220 lemma o_inv_distrib: "[| bij f; bij g |] ==> inv (f o g) = inv g o inv f"
   221 apply (rule inv_equality)
   221 apply (rule inv_equality)
   222 apply (auto simp add: bij_def surj_f_inv_f)
   222 apply (auto simp add: bij_def surj_f_inv_f)
   237 apply (blast intro: bij_is_surj [THEN surj_f_inv_f, symmetric])
   237 apply (blast intro: bij_is_surj [THEN surj_f_inv_f, symmetric])
   238 done
   238 done
   239 
   239 
   240 lemma bij_vimage_eq_inv_image: "bij f ==> f -` A = inv f ` A" 
   240 lemma bij_vimage_eq_inv_image: "bij f ==> f -` A = inv f ` A" 
   241 apply (auto simp add: bij_is_surj [THEN surj_f_inv_f])
   241 apply (auto simp add: bij_is_surj [THEN surj_f_inv_f])
   242 apply (blast intro: bij_is_inj [THEN inv_onto_f_f, symmetric])
   242 apply (blast intro: bij_is_inj [THEN inv_into_f_f, symmetric])
   243 done
   243 done
   244 
   244 
   245 lemma finite_fun_UNIVD1:
   245 lemma finite_fun_UNIVD1:
   246   assumes fin: "finite (UNIV :: ('a \<Rightarrow> 'b) set)"
   246   assumes fin: "finite (UNIV :: ('a \<Rightarrow> 'b) set)"
   247   and card: "card (UNIV :: 'b set) \<noteq> Suc 0"
   247   and card: "card (UNIV :: 'b set) \<noteq> Suc 0"
   254   then obtain b1 b2 where b1b2: "(b1 :: 'b) \<noteq> (b2 :: 'b)" by (auto simp add: card_Suc_eq)
   254   then obtain b1 b2 where b1b2: "(b1 :: 'b) \<noteq> (b2 :: 'b)" by (auto simp add: card_Suc_eq)
   255   from fin have "finite (range (\<lambda>f :: 'a \<Rightarrow> 'b. inv f b1))" by (rule finite_imageI)
   255   from fin have "finite (range (\<lambda>f :: 'a \<Rightarrow> 'b. inv f b1))" by (rule finite_imageI)
   256   moreover have "UNIV = range (\<lambda>f :: 'a \<Rightarrow> 'b. inv f b1)"
   256   moreover have "UNIV = range (\<lambda>f :: 'a \<Rightarrow> 'b. inv f b1)"
   257   proof (rule UNIV_eq_I)
   257   proof (rule UNIV_eq_I)
   258     fix x :: 'a
   258     fix x :: 'a
   259     from b1b2 have "x = inv (\<lambda>y. if y = x then b1 else b2) b1" by (simp add: inv_onto_def)
   259     from b1b2 have "x = inv (\<lambda>y. if y = x then b1 else b2) b1" by (simp add: inv_into_def)
   260     thus "x \<in> range (\<lambda>f\<Colon>'a \<Rightarrow> 'b. inv f b1)" by blast
   260     thus "x \<in> range (\<lambda>f\<Colon>'a \<Rightarrow> 'b. inv f b1)" by blast
   261   qed
   261   qed
   262   ultimately show "finite (UNIV :: 'a set)" by simp
   262   ultimately show "finite (UNIV :: 'a set)" by simp
   263 qed
   263 qed
   264 
   264