diff --git a/src/HOL/Analysis/Complex_Transcendental.thy b/src/HOL/Analysis/Complex_Transcendental.thy --- a/src/HOL/Analysis/Complex_Transcendental.thy +++ b/src/HOL/Analysis/Complex_Transcendental.thy @@ -1,4121 +1,4108 @@ section \Complex Transcendental Functions\ text\By John Harrison et al. Ported from HOL Light by L C Paulson (2015)\ theory Complex_Transcendental imports Complex_Analysis_Basics Summation_Tests "HOL-Library.Periodic_Fun" begin subsection\Möbius transformations\ (* TODO: Figure out what to do with Möbius transformations *) definition\<^marker>\tag important\ "moebius a b c d \ (\z. (a*z+b) / (c*z+d :: 'a :: field))" theorem moebius_inverse: assumes "a * d \ b * c" "c * z + d \ 0" shows "moebius d (-b) (-c) a (moebius a b c d z) = z" proof - from assms have "(-c) * moebius a b c d z + a \ 0" unfolding moebius_def by (simp add: field_simps) with assms show ?thesis unfolding moebius_def by (simp add: moebius_def divide_simps) (simp add: algebra_simps)? qed lemma moebius_inverse': assumes "a * d \ b * c" "c * z - a \ 0" shows "moebius a b c d (moebius d (-b) (-c) a z) = z" using assms moebius_inverse[of d a "-b" "-c" z] by (auto simp: algebra_simps) lemma cmod_add_real_less: assumes "Im z \ 0" "r\0" shows "cmod (z + r) < cmod z + \r\" proof (cases z) case (Complex x y) then have "0 < y * y" using assms mult_neg_neg by force with assms have "r * x / \r\ < sqrt (x*x + y*y)" by (simp add: real_less_rsqrt power2_eq_square) then show ?thesis using assms Complex apply (simp add: cmod_def) apply (rule power2_less_imp_less, auto) apply (simp add: power2_eq_square field_simps) done qed lemma cmod_diff_real_less: "Im z \ 0 \ x\0 \ cmod (z - x) < cmod z + \x\" using cmod_add_real_less [of z "-x"] by simp lemma cmod_square_less_1_plus: assumes "Im z = 0 \ \Re z\ < 1" shows "(cmod z)\<^sup>2 < 1 + cmod (1 - z\<^sup>2)" proof (cases "Im z = 0 \ Re z = 0") case True with assms abs_square_less_1 show ?thesis by (force simp add: Re_power2 Im_power2 cmod_def) next case False with cmod_diff_real_less [of "1 - z\<^sup>2" "1"] show ?thesis by (simp add: norm_power Im_power2) qed subsection\<^marker>\tag unimportant\\The Exponential Function\ lemma norm_exp_i_times [simp]: "norm (exp(\ * of_real y)) = 1" by simp lemma norm_exp_imaginary: "norm(exp z) = 1 \ Re z = 0" by simp lemma field_differentiable_within_exp: "exp field_differentiable (at z within s)" using DERIV_exp field_differentiable_at_within field_differentiable_def by blast lemma continuous_within_exp: fixes z::"'a::{real_normed_field,banach}" shows "continuous (at z within s) exp" by (simp add: continuous_at_imp_continuous_within) lemma holomorphic_on_exp [holomorphic_intros]: "exp holomorphic_on s" by (simp add: field_differentiable_within_exp holomorphic_on_def) lemma holomorphic_on_exp' [holomorphic_intros]: "f holomorphic_on s \ (\x. exp (f x)) holomorphic_on s" using holomorphic_on_compose[OF _ holomorphic_on_exp] by (simp add: o_def) subsection\Euler and de Moivre formulas\ text\The sine series times \<^term>\i\\ lemma sin_i_eq: "(\n. (\ * sin_coeff n) * z^n) sums (\ * sin z)" proof - have "(\n. \ * sin_coeff n *\<^sub>R z^n) sums (\ * sin z)" using sin_converges sums_mult by blast then show ?thesis by (simp add: scaleR_conv_of_real field_simps) qed theorem exp_Euler: "exp(\ * z) = cos(z) + \ * sin(z)" proof - have "(\n. (cos_coeff n + \ * sin_coeff n) * z^n) = (\n. (\ * z) ^ n /\<^sub>R (fact n))" proof fix n show "(cos_coeff n + \ * sin_coeff n) * z^n = (\ * z) ^ n /\<^sub>R (fact n)" by (auto simp: cos_coeff_def sin_coeff_def scaleR_conv_of_real field_simps elim!: evenE oddE) qed - also have "... sums (exp (\ * z))" + also have "\ sums (exp (\ * z))" by (rule exp_converges) finally have "(\n. (cos_coeff n + \ * sin_coeff n) * z^n) sums (exp (\ * z))" . moreover have "(\n. (cos_coeff n + \ * sin_coeff n) * z^n) sums (cos z + \ * sin z)" using sums_add [OF cos_converges [of z] sin_i_eq [of z]] by (simp add: field_simps scaleR_conv_of_real) ultimately show ?thesis using sums_unique2 by blast qed corollary\<^marker>\tag unimportant\ exp_minus_Euler: "exp(-(\ * z)) = cos(z) - \ * sin(z)" using exp_Euler [of "-z"] by simp lemma sin_exp_eq: "sin z = (exp(\ * z) - exp(-(\ * z))) / (2*\)" by (simp add: exp_Euler exp_minus_Euler) lemma sin_exp_eq': "sin z = \ * (exp(-(\ * z)) - exp(\ * z)) / 2" by (simp add: exp_Euler exp_minus_Euler) lemma cos_exp_eq: "cos z = (exp(\ * z) + exp(-(\ * z))) / 2" by (simp add: exp_Euler exp_minus_Euler) theorem Euler: "exp(z) = of_real(exp(Re z)) * (of_real(cos(Im z)) + \ * of_real(sin(Im z)))" by (cases z) (simp add: exp_add exp_Euler cos_of_real exp_of_real sin_of_real Complex_eq) lemma Re_sin: "Re(sin z) = sin(Re z) * (exp(Im z) + exp(-(Im z))) / 2" by (simp add: sin_exp_eq field_simps Re_divide Im_exp) lemma Im_sin: "Im(sin z) = cos(Re z) * (exp(Im z) - exp(-(Im z))) / 2" by (simp add: sin_exp_eq field_simps Im_divide Re_exp) lemma Re_cos: "Re(cos z) = cos(Re z) * (exp(Im z) + exp(-(Im z))) / 2" by (simp add: cos_exp_eq field_simps Re_divide Re_exp) lemma Im_cos: "Im(cos z) = sin(Re z) * (exp(-(Im z)) - exp(Im z)) / 2" by (simp add: cos_exp_eq field_simps Im_divide Im_exp) lemma Re_sin_pos: "0 < Re z \ Re z < pi \ Re (sin z) > 0" by (auto simp: Re_sin Im_sin add_pos_pos sin_gt_zero) lemma Im_sin_nonneg: "Re z = 0 \ 0 \ Im z \ 0 \ Im (sin z)" by (simp add: Re_sin Im_sin algebra_simps) lemma Im_sin_nonneg2: "Re z = pi \ Im z \ 0 \ 0 \ Im (sin z)" by (simp add: Re_sin Im_sin algebra_simps) subsection\<^marker>\tag unimportant\\Relationships between real and complex trigonometric and hyperbolic functions\ lemma real_sin_eq [simp]: "Re(sin(of_real x)) = sin x" by (simp add: sin_of_real) lemma real_cos_eq [simp]: "Re(cos(of_real x)) = cos x" by (simp add: cos_of_real) lemma DeMoivre: "(cos z + \ * sin z) ^ n = cos(n * z) + \ * sin(n * z)" by (metis exp_Euler [symmetric] exp_of_nat_mult mult.left_commute) lemma exp_cnj: "cnj (exp z) = exp (cnj z)" proof - have "(\n. cnj (z ^ n /\<^sub>R (fact n))) = (\n. (cnj z)^n /\<^sub>R (fact n))" by auto - also have "... sums (exp (cnj z))" + also have "\ sums (exp (cnj z))" by (rule exp_converges) finally have "(\n. cnj (z ^ n /\<^sub>R (fact n))) sums (exp (cnj z))" . moreover have "(\n. cnj (z ^ n /\<^sub>R (fact n))) sums (cnj (exp z))" by (metis exp_converges sums_cnj) ultimately show ?thesis using sums_unique2 by blast qed lemma cnj_sin: "cnj(sin z) = sin(cnj z)" by (simp add: sin_exp_eq exp_cnj field_simps) lemma cnj_cos: "cnj(cos z) = cos(cnj z)" by (simp add: cos_exp_eq exp_cnj field_simps) lemma field_differentiable_at_sin: "sin field_differentiable at z" using DERIV_sin field_differentiable_def by blast lemma field_differentiable_within_sin: "sin field_differentiable (at z within S)" by (simp add: field_differentiable_at_sin field_differentiable_at_within) lemma field_differentiable_at_cos: "cos field_differentiable at z" using DERIV_cos field_differentiable_def by blast lemma field_differentiable_within_cos: "cos field_differentiable (at z within S)" by (simp add: field_differentiable_at_cos field_differentiable_at_within) lemma holomorphic_on_sin: "sin holomorphic_on S" by (simp add: field_differentiable_within_sin holomorphic_on_def) lemma holomorphic_on_cos: "cos holomorphic_on S" by (simp add: field_differentiable_within_cos holomorphic_on_def) lemma holomorphic_on_sin' [holomorphic_intros]: assumes "f holomorphic_on A" shows "(\x. sin (f x)) holomorphic_on A" using holomorphic_on_compose[OF assms holomorphic_on_sin] by (simp add: o_def) lemma holomorphic_on_cos' [holomorphic_intros]: assumes "f holomorphic_on A" shows "(\x. cos (f x)) holomorphic_on A" using holomorphic_on_compose[OF assms holomorphic_on_cos] by (simp add: o_def) subsection\<^marker>\tag unimportant\\More on the Polar Representation of Complex Numbers\ lemma exp_Complex: "exp(Complex r t) = of_real(exp r) * Complex (cos t) (sin t)" by (simp add: Complex_eq exp_add exp_Euler exp_of_real sin_of_real cos_of_real) lemma exp_eq_1: "exp z = 1 \ Re(z) = 0 \ (\n::int. Im(z) = of_int (2 * n) * pi)" (is "?lhs = ?rhs") proof assume "exp z = 1" then have "Re z = 0" by (metis exp_eq_one_iff norm_exp_eq_Re norm_one) with \?lhs\ show ?rhs by (metis Re_exp complex_Re_of_int cos_one_2pi_int exp_zero mult.commute mult_numeral_1 numeral_One of_int_mult of_int_numeral) next assume ?rhs then show ?lhs using Im_exp Re_exp complex_eq_iff by (simp add: cos_one_2pi_int cos_one_sin_zero mult.commute) qed lemma exp_eq: "exp w = exp z \ (\n::int. w = z + (of_int (2 * n) * pi) * \)" (is "?lhs = ?rhs") proof - have "exp w = exp z \ exp (w-z) = 1" by (simp add: exp_diff) - also have "... \ (Re w = Re z \ (\n::int. Im w - Im z = of_int (2 * n) * pi))" + also have "\ \ (Re w = Re z \ (\n::int. Im w - Im z = of_int (2 * n) * pi))" by (simp add: exp_eq_1) - also have "... \ ?rhs" + also have "\ \ ?rhs" by (auto simp: algebra_simps intro!: complex_eqI) finally show ?thesis . qed lemma exp_complex_eqI: "\Im w - Im z\ < 2*pi \ exp w = exp z \ w = z" by (auto simp: exp_eq abs_mult) lemma exp_integer_2pi: assumes "n \ \" shows "exp((2 * n * pi) * \) = 1" proof - have "exp((2 * n * pi) * \) = exp 0" using assms unfolding Ints_def exp_eq by auto - also have "... = 1" + also have "\ = 1" by simp finally show ?thesis . qed lemma exp_plus_2pin [simp]: "exp (z + \ * (of_int n * (of_real pi * 2))) = exp z" by (simp add: exp_eq) lemma exp_integer_2pi_plus1: assumes "n \ \" shows "exp(((2 * n + 1) * pi) * \) = - 1" proof - from assms obtain n' where [simp]: "n = of_int n'" by (auto simp: Ints_def) have "exp(((2 * n + 1) * pi) * \) = exp (pi * \)" using assms by (subst exp_eq) (auto intro!: exI[of _ n'] simp: algebra_simps) - also have "... = - 1" + also have "\ = - 1" by simp finally show ?thesis . qed lemma inj_on_exp_pi: fixes z::complex shows "inj_on exp (ball z pi)" proof (clarsimp simp: inj_on_def exp_eq) fix y n assume "dist z (y + 2 * of_int n * of_real pi * \) < pi" "dist z y < pi" then have "dist y (y + 2 * of_int n * of_real pi * \) < pi+pi" using dist_commute_lessI dist_triangle_less_add by blast then have "norm (2 * of_int n * of_real pi * \) < 2*pi" by (simp add: dist_norm) then show "n = 0" by (auto simp: norm_mult) qed lemma cmod_add_squared: fixes r1 r2::real assumes "r1 \ 0" "r2 \ 0" shows "(cmod (r1 * exp (\ * \1) + r2 * exp (\ * \2)))\<^sup>2 = r1\<^sup>2 + r2\<^sup>2 + 2 * r1 * r2 * cos (\1 - \2)" (is "(cmod (?z1 + ?z2))\<^sup>2 = ?rhs") proof - have "(cmod (?z1 + ?z2))\<^sup>2 = (?z1 + ?z2) * cnj (?z1 + ?z2)" by (rule complex_norm_square) also have "\ = (?z1 * cnj ?z1 + ?z2 * cnj ?z2) + (?z1 * cnj ?z2 + cnj ?z1 * ?z2)" by (simp add: algebra_simps) also have "\ = (norm ?z1)\<^sup>2 + (norm ?z2)\<^sup>2 + 2 * Re (?z1 * cnj ?z2)" unfolding complex_norm_square [symmetric] cnj_add_mult_eq_Re by simp also have "\ = ?rhs" by (simp add: norm_mult) (simp add: exp_Euler complex_is_Real_iff [THEN iffD1] cos_diff algebra_simps) finally show ?thesis using of_real_eq_iff by blast qed lemma cmod_diff_squared: fixes r1 r2::real assumes "r1 \ 0" "r2 \ 0" shows "(cmod (r1 * exp (\ * \1) - r2 * exp (\ * \2)))\<^sup>2 = r1\<^sup>2 + r2\<^sup>2 - 2*r1*r2*cos (\1 - \2)" (is "(cmod (?z1 - ?z2))\<^sup>2 = ?rhs") proof - have "exp (\ * (\2 + pi)) = - exp (\ * \2)" by (simp add: exp_Euler cos_plus_pi sin_plus_pi) then have "(cmod (?z1 - ?z2))\<^sup>2 = cmod (?z1 + r2 * exp (\ * (\2 + pi))) ^2" by simp also have "\ = r1\<^sup>2 + r2\<^sup>2 + 2*r1*r2*cos (\1 - (\2 + pi))" using assms cmod_add_squared by blast also have "\ = ?rhs" by (simp add: add.commute diff_add_eq_diff_diff_swap) finally show ?thesis . qed lemma polar_convergence: fixes R::real assumes "\j. r j > 0" "R > 0" shows "((\j. r j * exp (\ * \ j)) \ (R * exp (\ * \))) \ (r \ R) \ (\k. (\j. \ j - of_int (k j) * (2 * pi)) \ \)" (is "(?z \ ?Z) = ?rhs") proof assume L: "?z \ ?Z" have rR: "r \ R" using tendsto_norm [OF L] assms by (auto simp: norm_mult abs_of_pos) moreover obtain k where "(\j. \ j - of_int (k j) * (2 * pi)) \ \" proof - have "cos (\ j - \) = ((r j)\<^sup>2 + R\<^sup>2 - (norm(?z j - ?Z))\<^sup>2) / (2 * R * r j)" for j apply (subst cmod_diff_squared) using assms by (auto simp: field_split_simps less_le) moreover have "(\j. ((r j)\<^sup>2 + R\<^sup>2 - (norm(?z j - ?Z))\<^sup>2) / (2 * R * r j)) \ ((R\<^sup>2 + R\<^sup>2 - (norm(?Z - ?Z))\<^sup>2) / (2 * R * R))" by (intro L rR tendsto_intros) (use \R > 0\ in force) moreover have "((R\<^sup>2 + R\<^sup>2 - (norm(?Z - ?Z))\<^sup>2) / (2 * R * R)) = 1" using \R > 0\ by (simp add: power2_eq_square field_split_simps) ultimately have "(\j. cos (\ j - \)) \ 1" by auto then show ?thesis using that cos_diff_limit_1 by blast qed ultimately show ?rhs by metis next assume R: ?rhs show "?z \ ?Z" proof (rule tendsto_mult) show "(\x. complex_of_real (r x)) \ of_real R" using R by (auto simp: tendsto_of_real_iff) obtain k where "(\j. \ j - of_int (k j) * (2 * pi)) \ \" using R by metis then have "(\j. complex_of_real (\ j - of_int (k j) * (2 * pi))) \ of_real \" using tendsto_of_real_iff by force then have "(\j. exp (\ * of_real (\ j - of_int (k j) * (2 * pi)))) \ exp (\ * \)" using tendsto_mult [OF tendsto_const] isCont_exp isCont_tendsto_compose by blast moreover have "exp (\ * of_real (\ j - of_int (k j) * (2 * pi))) = exp (\ * \ j)" for j unfolding exp_eq by (rule_tac x="- k j" in exI) (auto simp: algebra_simps) ultimately show "(\j. exp (\ * \ j)) \ exp (\ * \)" by auto qed qed -lemma sin_cos_eq_iff: "sin y = sin x \ cos y = cos x \ (\n::int. y = x + 2 * pi * n)" -proof - - { assume "sin y = sin x" "cos y = cos x" - then have "cos (y-x) = 1" - using cos_add [of y "-x"] by simp - then have "\n::int. y-x = 2 * pi * n" - using cos_one_2pi_int by auto } - then show ?thesis - apply (auto simp: sin_add cos_add) - apply (metis add.commute diff_add_cancel) - done +lemma sin_cos_eq_iff: "sin y = sin x \ cos y = cos x \ (\n::int. y = x + 2 * pi * n)" (is "?L=?R") +proof + assume ?L + then have "cos (y-x) = 1" + using cos_add [of y "-x"] by simp + then show ?R + by (metis cos_one_2pi_int add.commute diff_add_cancel mult.assoc mult.commute) +next + assume ?R + then show ?L + by (auto simp: sin_add cos_add) qed lemma exp_i_ne_1: assumes "0 < x" "x < 2*pi" shows "exp(\ * of_real x) \ 1" proof assume "exp (\ * of_real x) = 1" then have "exp (\ * of_real x) = exp 0" by simp then obtain n where "\ * of_real x = (of_int (2 * n) * pi) * \" by (simp only: Ints_def exp_eq) auto then have "of_real x = (of_int (2 * n) * pi)" by (metis complex_i_not_zero mult.commute mult_cancel_left of_real_eq_iff real_scaleR_def scaleR_conv_of_real) then have "x = (of_int (2 * n) * pi)" by simp then show False using assms by (cases n) (auto simp: zero_less_mult_iff mult_less_0_iff) qed lemma sin_eq_0: fixes z::complex shows "sin z = 0 \ (\n::int. z = of_real(n * pi))" by (simp add: sin_exp_eq exp_eq) lemma cos_eq_0: fixes z::complex - shows "cos z = 0 \ (\n::int. z = of_real(n * pi) + of_real pi/2)" + shows "cos z = 0 \ (\n::int. z = complex_of_real(n * pi) + of_real pi/2)" using sin_eq_0 [of "z - of_real pi/2"] by (simp add: sin_diff algebra_simps) lemma cos_eq_1: fixes z::complex - shows "cos z = 1 \ (\n::int. z = of_real(2 * n * pi))" + shows "cos z = 1 \ (\n::int. z = complex_of_real(2 * n * pi))" proof - have "cos z = cos (2*(z/2))" by simp - also have "... = 1 - 2 * sin (z/2) ^ 2" + also have "\ = 1 - 2 * sin (z/2) ^ 2" by (simp only: cos_double_sin) finally have [simp]: "cos z = 1 \ sin (z/2) = 0" by simp show ?thesis by (auto simp: sin_eq_0) qed lemma csin_eq_1: fixes z::complex shows "sin z = 1 \ (\n::int. z = of_real(2 * n * pi) + of_real pi/2)" using cos_eq_1 [of "z - of_real pi/2"] by (simp add: cos_diff algebra_simps) lemma csin_eq_minus1: fixes z::complex - shows "sin z = -1 \ (\n::int. z = of_real(2 * n * pi) + 3/2*pi)" + shows "sin z = -1 \ (\n::int. z = complex_of_real(2 * n * pi) + 3/2*pi)" (is "_ = ?rhs") proof - have "sin z = -1 \ sin (-z) = 1" by (simp add: equation_minus_iff) - also have "... \ (\n::int. -z = of_real(2 * n * pi) + of_real pi/2)" + also have "\ \ (\n::int. -z = of_real(2 * n * pi) + of_real pi/2)" by (simp only: csin_eq_1) - also have "... \ (\n::int. z = - of_real(2 * n * pi) - of_real pi/2)" + also have "\ \ (\n::int. z = - of_real(2 * n * pi) - of_real pi/2)" by (rule iff_exI) (metis add.inverse_inverse add_uminus_conv_diff minus_add_distrib) - also have "... = ?rhs" + also have "\ = ?rhs" apply safe apply (rule_tac [2] x="-(x+1)" in exI) apply (rule_tac x="-(x+1)" in exI) apply (simp_all add: algebra_simps) done finally show ?thesis . qed lemma ccos_eq_minus1: fixes z::complex - shows "cos z = -1 \ (\n::int. z = of_real(2 * n * pi) + pi)" + shows "cos z = -1 \ (\n::int. z = complex_of_real(2 * n * pi) + pi)" using csin_eq_1 [of "z - of_real pi/2"] by (simp add: sin_diff algebra_simps equation_minus_iff) lemma sin_eq_1: "sin x = 1 \ (\n::int. x = (2 * n + 1 / 2) * pi)" (is "_ = ?rhs") proof - have "sin x = 1 \ sin (complex_of_real x) = 1" by (metis of_real_1 one_complex.simps(1) real_sin_eq sin_of_real) - also have "... \ (\n::int. complex_of_real x = of_real(2 * n * pi) + of_real pi/2)" + also have "\ \ (\n::int. complex_of_real x = of_real(2 * n * pi) + of_real pi/2)" by (simp only: csin_eq_1) - also have "... \ (\n::int. x = of_real(2 * n * pi) + of_real pi/2)" + also have "\ \ (\n::int. x = of_real(2 * n * pi) + of_real pi/2)" by (rule iff_exI) (auto simp: algebra_simps intro: injD [OF inj_of_real [where 'a = complex]]) - also have "... = ?rhs" + also have "\ = ?rhs" by (auto simp: algebra_simps) finally show ?thesis . qed lemma sin_eq_minus1: "sin x = -1 \ (\n::int. x = (2*n + 3/2) * pi)" (is "_ = ?rhs") proof - have "sin x = -1 \ sin (complex_of_real x) = -1" by (metis Re_complex_of_real of_real_def scaleR_minus1_left sin_of_real) - also have "... \ (\n::int. complex_of_real x = of_real(2 * n * pi) + 3/2*pi)" - by (simp only: csin_eq_minus1) - also have "... \ (\n::int. x = of_real(2 * n * pi) + 3/2*pi)" + also have "\ \ (\n::int. complex_of_real x = of_real(2 * n * pi) + 3/2*pi)" + by (simp add: csin_eq_minus1) + also have "\ \ (\n::int. x = of_real(2 * n * pi) + 3/2*pi)" by (rule iff_exI) (auto simp: algebra_simps intro: injD [OF inj_of_real [where 'a = complex]]) - also have "... = ?rhs" + also have "\ = ?rhs" by (auto simp: algebra_simps) finally show ?thesis . qed lemma cos_eq_minus1: "cos x = -1 \ (\n::int. x = (2*n + 1) * pi)" (is "_ = ?rhs") proof - have "cos x = -1 \ cos (complex_of_real x) = -1" by (metis Re_complex_of_real of_real_def scaleR_minus1_left cos_of_real) - also have "... \ (\n::int. complex_of_real x = of_real(2 * n * pi) + pi)" - by (simp only: ccos_eq_minus1) - also have "... \ (\n::int. x = of_real(2 * n * pi) + pi)" + also have "\ \ (\n::int. complex_of_real x = of_real(2 * n * pi) + pi)" + by (simp add: ccos_eq_minus1) + also have "\ \ (\n::int. x = of_real(2 * n * pi) + pi)" by (rule iff_exI) (auto simp: algebra_simps intro: injD [OF inj_of_real [where 'a = complex]]) - also have "... = ?rhs" + also have "\ = ?rhs" by (auto simp: algebra_simps) finally show ?thesis . qed lemma cos_gt_neg1: assumes "(t::real) \ {-pi<.. -1" proof - have "cos t \ -1" by simp moreover have "cos t \ -1" proof assume "cos t = -1" then obtain n where n: "t = (2 * of_int n + 1) * pi" by (subst (asm) cos_eq_minus1) auto from assms have "t / pi \ {-1<..<1}" by (auto simp: field_simps) also from n have "t / pi = of_int (2 * n + 1)" by auto finally show False by auto qed ultimately show ?thesis by linarith qed lemma dist_exp_i_1: "norm(exp(\ * of_real t) - 1) = 2 * \sin(t / 2)\" proof - have "sqrt (2 - cos t * 2) = 2 * \sin (t / 2)\" using cos_double_sin [of "t/2"] by (simp add: real_sqrt_mult) then show ?thesis by (simp add: exp_Euler cmod_def power2_diff sin_of_real cos_of_real algebra_simps) qed lemma sin_cx_2pi [simp]: "\z = of_int m; even m\ \ sin (z * complex_of_real pi) = 0" by (simp add: sin_eq_0) lemma cos_cx_2pi [simp]: "\z = of_int m; even m\ \ cos (z * complex_of_real pi) = 1" using cos_eq_1 by auto lemma complex_sin_eq: fixes w :: complex shows "sin w = sin z \ (\n \ \. w = z + of_real(2*n*pi) \ w = -z + of_real((2*n + 1)*pi))" (is "?lhs = ?rhs") proof assume ?lhs then have "sin w - sin z = 0" by (auto simp: algebra_simps) then have "sin ((w - z) / 2)*cos ((w + z) / 2) = 0" by (auto simp: sin_diff_sin) then consider "sin ((w - z) / 2) = 0" | "cos ((w + z) / 2) = 0" using mult_eq_0_iff by blast then show ?rhs proof cases case 1 then show ?thesis by (simp add: sin_eq_0 algebra_simps) (metis Ints_of_int of_real_of_int_eq) next case 2 then show ?thesis by (simp add: cos_eq_0 algebra_simps) (metis Ints_of_int of_real_of_int_eq) qed next assume ?rhs then consider n::int where "w = z + of_real (2 * of_int n * pi)" | n::int where " w = -z + of_real ((2 * of_int n + 1) * pi)" using Ints_cases by blast then show ?lhs proof cases case 1 then show ?thesis using Periodic_Fun.sin.plus_of_int [of z n] by (auto simp: algebra_simps) next case 2 then show ?thesis using Periodic_Fun.sin.plus_of_int [of "-z" "n"] apply (simp add: algebra_simps) by (metis add.commute add.inverse_inverse add_diff_cancel_left diff_add_cancel sin_plus_pi) qed qed lemma complex_cos_eq: fixes w :: complex shows "cos w = cos z \ (\n \ \. w = z + of_real(2*n*pi) \ w = -z + of_real(2*n*pi))" (is "?lhs = ?rhs") proof assume ?lhs then have "cos w - cos z = 0" by (auto simp: algebra_simps) then have "sin ((w + z) / 2) * sin ((z - w) / 2) = 0" by (auto simp: cos_diff_cos) then consider "sin ((w + z) / 2) = 0" | "sin ((z - w) / 2) = 0" using mult_eq_0_iff by blast then show ?rhs proof cases case 1 then obtain n where "w + z = of_int n * (complex_of_real pi * 2)" by (auto simp: sin_eq_0 algebra_simps) then have "w = -z + of_real(2 * of_int n * pi)" by (auto simp: algebra_simps) then show ?thesis using Ints_of_int by blast next case 2 then obtain n where "z = w + of_int n * (complex_of_real pi * 2)" by (auto simp: sin_eq_0 algebra_simps) then have "w = z + complex_of_real (2 * of_int(-n) * pi)" by (auto simp: algebra_simps) then show ?thesis using Ints_of_int by blast qed next assume ?rhs then obtain n::int where w: "w = z + of_real (2* of_int n*pi) \ w = -z + of_real(2*n*pi)" using Ints_cases by (metis of_int_mult of_int_numeral) then show ?lhs using Periodic_Fun.cos.plus_of_int [of z n] apply (simp add: algebra_simps) by (metis cos.plus_of_int cos_minus minus_add_cancel mult.commute) qed lemma sin_eq: "sin x = sin y \ (\n \ \. x = y + 2*n*pi \ x = -y + (2*n + 1)*pi)" using complex_sin_eq [of x y] by (simp only: sin_of_real Re_complex_of_real of_real_add [symmetric] of_real_minus [symmetric] of_real_mult [symmetric] of_real_eq_iff) lemma cos_eq: "cos x = cos y \ (\n \ \. x = y + 2*n*pi \ x = -y + 2*n*pi)" using complex_cos_eq [of x y] by (simp only: cos_of_real Re_complex_of_real of_real_add [symmetric] of_real_minus [symmetric] of_real_mult [symmetric] of_real_eq_iff) lemma sinh_complex: fixes z :: complex shows "(exp z - inverse (exp z)) / 2 = -\ * sin(\ * z)" by (simp add: sin_exp_eq field_split_simps exp_minus) lemma sin_i_times: fixes z :: complex shows "sin(\ * z) = \ * ((exp z - inverse (exp z)) / 2)" using sinh_complex by auto lemma sinh_real: fixes x :: real shows "of_real((exp x - inverse (exp x)) / 2) = -\ * sin(\ * of_real x)" by (simp add: exp_of_real sin_i_times) lemma cosh_complex: fixes z :: complex shows "(exp z + inverse (exp z)) / 2 = cos(\ * z)" by (simp add: cos_exp_eq field_split_simps exp_minus exp_of_real) lemma cosh_real: fixes x :: real shows "of_real((exp x + inverse (exp x)) / 2) = cos(\ * of_real x)" by (simp add: cos_exp_eq field_split_simps exp_minus exp_of_real) lemmas cos_i_times = cosh_complex [symmetric] lemma norm_cos_squared: "norm(cos z) ^ 2 = cos(Re z) ^ 2 + (exp(Im z) - inverse(exp(Im z))) ^ 2 / 4" proof (cases z) case (Complex x1 x2) then show ?thesis apply (simp only: cos_add cmod_power2 cos_of_real sin_of_real Complex_eq) apply (simp add: cos_exp_eq sin_exp_eq exp_minus exp_of_real Re_divide Im_divide power_divide) apply (simp only: left_diff_distrib [symmetric] power_mult_distrib sin_squared_eq) apply (simp add: power2_eq_square field_split_simps) done qed lemma norm_sin_squared: "norm(sin z) ^ 2 = (exp(2 * Im z) + inverse(exp(2 * Im z)) - 2 * cos(2 * Re z)) / 4" proof (cases z) case (Complex x1 x2) then show ?thesis apply (simp only: sin_add cmod_power2 cos_of_real sin_of_real cos_double_cos exp_double Complex_eq) apply (simp add: cos_exp_eq sin_exp_eq exp_minus exp_of_real Re_divide Im_divide power_divide) apply (simp only: left_diff_distrib [symmetric] power_mult_distrib cos_squared_eq) apply (simp add: power2_eq_square field_split_simps) done qed lemma exp_uminus_Im: "exp (- Im z) \ exp (cmod z)" using abs_Im_le_cmod linear order_trans by fastforce lemma norm_cos_le: fixes z::complex shows "norm(cos z) \ exp(norm z)" proof - have "Im z \ cmod z" using abs_Im_le_cmod abs_le_D1 by auto then have "exp (- Im z) + exp (Im z) \ exp (cmod z) * 2" by (metis exp_uminus_Im add_mono exp_le_cancel_iff mult_2_right) then show ?thesis by (force simp add: cos_exp_eq norm_divide intro: order_trans [OF norm_triangle_ineq]) qed lemma norm_cos_plus1_le: fixes z::complex shows "norm(1 + cos z) \ 2 * exp(norm z)" proof - have mono: "\u w z::real. (1 \ w | 1 \ z) \ (w \ u & z \ u) \ 2 + w + z \ 4 * u" by arith have *: "Im z \ cmod z" using abs_Im_le_cmod abs_le_D1 by auto have triangle3: "\x y z. norm(x + y + z) \ norm(x) + norm(y) + norm(z)" by (simp add: norm_add_rule_thm) have "norm(1 + cos z) = cmod (1 + (exp (\ * z) + exp (- (\ * z))) / 2)" by (simp add: cos_exp_eq) - also have "... = cmod ((2 + exp (\ * z) + exp (- (\ * z))) / 2)" + also have "\ = cmod ((2 + exp (\ * z) + exp (- (\ * z))) / 2)" by (simp add: field_simps) - also have "... = cmod (2 + exp (\ * z) + exp (- (\ * z))) / 2" + also have "\ = cmod (2 + exp (\ * z) + exp (- (\ * z))) / 2" by (simp add: norm_divide) finally show ?thesis by (metis exp_eq_one_iff exp_le_cancel_iff mult_2 norm_cos_le norm_ge_zero norm_one norm_triangle_mono) qed lemma sinh_conv_sin: "sinh z = -\ * sin (\*z)" by (simp add: sinh_field_def sin_i_times exp_minus) lemma cosh_conv_cos: "cosh z = cos (\*z)" by (simp add: cosh_field_def cos_i_times exp_minus) lemma tanh_conv_tan: "tanh z = -\ * tan (\*z)" by (simp add: tanh_def sinh_conv_sin cosh_conv_cos tan_def) lemma sin_conv_sinh: "sin z = -\ * sinh (\*z)" by (simp add: sinh_conv_sin) lemma cos_conv_cosh: "cos z = cosh (\*z)" by (simp add: cosh_conv_cos) lemma tan_conv_tanh: "tan z = -\ * tanh (\*z)" by (simp add: tan_def sin_conv_sinh cos_conv_cosh tanh_def) lemma sinh_complex_eq_iff: "sinh (z :: complex) = sinh w \ (\n\\. z = w - 2 * \ * of_real n * of_real pi \ z = -(2 * complex_of_real n + 1) * \ * complex_of_real pi - w)" (is "_ = ?rhs") proof - have "sinh z = sinh w \ sin (\ * z) = sin (\ * w)" by (simp add: sinh_conv_sin) also have "\ \ ?rhs" by (subst complex_sin_eq) (force simp: field_simps complex_eq_iff) finally show ?thesis . qed subsection\<^marker>\tag unimportant\\Taylor series for complex exponential, sine and cosine\ declare power_Suc [simp del] lemma Taylor_exp_field: fixes z::"'a::{banach,real_normed_field}" shows "norm (exp z - (\i\n. z ^ i / fact i)) \ exp (norm z) * (norm z ^ Suc n) / fact n" proof (rule field_Taylor[of _ n "\k. exp" "exp (norm z)" 0 z, simplified]) show "convex (closed_segment 0 z)" by (rule convex_closed_segment [of 0 z]) next fix k x assume "x \ closed_segment 0 z" "k \ n" show "(exp has_field_derivative exp x) (at x within closed_segment 0 z)" using DERIV_exp DERIV_subset by blast next fix x assume x: "x \ closed_segment 0 z" have "norm (exp x) \ exp (norm x)" by (rule norm_exp) also have "norm x \ norm z" using x by (auto simp: closed_segment_def intro!: mult_left_le_one_le) finally show "norm (exp x) \ exp (norm z)" by simp qed auto lemma Taylor_exp: "norm(exp z - (\k\n. z ^ k / (fact k))) \ exp\Re z\ * (norm z) ^ (Suc n) / (fact n)" proof (rule complex_Taylor [of _ n "\k. exp" "exp\Re z\" 0 z, simplified]) show "convex (closed_segment 0 z)" by (rule convex_closed_segment [of 0 z]) next fix k x assume "x \ closed_segment 0 z" "k \ n" show "(exp has_field_derivative exp x) (at x within closed_segment 0 z)" using DERIV_exp DERIV_subset by blast next fix x assume "x \ closed_segment 0 z" then obtain u where u: "x = complex_of_real u * z" "0 \ u" "u \ 1" by (auto simp: closed_segment_def scaleR_conv_of_real) then have "u * Re z \ \Re z\" by (metis abs_ge_self abs_ge_zero mult.commute mult.right_neutral mult_mono) then show "Re x \ \Re z\" by (simp add: u) qed auto lemma assumes "0 \ u" "u \ 1" shows cmod_sin_le_exp: "cmod (sin (u *\<^sub>R z)) \ exp \Im z\" and cmod_cos_le_exp: "cmod (cos (u *\<^sub>R z)) \ exp \Im z\" proof - have mono: "\u w z::real. w \ u \ z \ u \ (w + z)/2 \ u" by simp have *: "(cmod (exp (\ * (u * z))) + cmod (exp (- (\ * (u * z)))) ) / 2 \ exp \Im z\" proof (rule mono) show "cmod (exp (\ * (u * z))) \ exp \Im z\" using assms by (auto simp: abs_if mult_left_le_one_le not_less intro: order_trans [of _ 0]) show "cmod (exp (- (\ * (u * z)))) \ exp \Im z\" using assms by (auto simp: abs_if mult_left_le_one_le mult_nonneg_nonpos intro: order_trans [of _ 0]) qed have "cmod (sin (u *\<^sub>R z)) = cmod (exp (\ * (u * z)) - exp (- (\ * (u * z)))) / 2" by (auto simp: scaleR_conv_of_real norm_mult norm_power sin_exp_eq norm_divide) - also have "... \ (cmod (exp (\ * (u * z))) + cmod (exp (- (\ * (u * z)))) ) / 2" + also have "\ \ (cmod (exp (\ * (u * z))) + cmod (exp (- (\ * (u * z)))) ) / 2" by (intro divide_right_mono norm_triangle_ineq4) simp - also have "... \ exp \Im z\" + also have "\ \ exp \Im z\" by (rule *) finally show "cmod (sin (u *\<^sub>R z)) \ exp \Im z\" . have "cmod (cos (u *\<^sub>R z)) = cmod (exp (\ * (u * z)) + exp (- (\ * (u * z)))) / 2" by (auto simp: scaleR_conv_of_real norm_mult norm_power cos_exp_eq norm_divide) - also have "... \ (cmod (exp (\ * (u * z))) + cmod (exp (- (\ * (u * z)))) ) / 2" + also have "\ \ (cmod (exp (\ * (u * z))) + cmod (exp (- (\ * (u * z)))) ) / 2" by (intro divide_right_mono norm_triangle_ineq) simp - also have "... \ exp \Im z\" + also have "\ \ exp \Im z\" by (rule *) finally show "cmod (cos (u *\<^sub>R z)) \ exp \Im z\" . qed lemma Taylor_sin: "norm(sin z - (\k\n. complex_of_real (sin_coeff k) * z ^ k)) \ exp\Im z\ * (norm z) ^ (Suc n) / (fact n)" proof - have mono: "\u w z::real. w \ u \ z \ u \ w + z \ u*2" by arith have *: "cmod (sin z - (\i\n. (-1) ^ (i div 2) * (if even i then sin 0 else cos 0) * z ^ i / (fact i))) \ exp \Im z\ * cmod z ^ Suc n / (fact n)" proof (rule complex_Taylor [of "closed_segment 0 z" n "\k x. (-1)^(k div 2) * (if even k then sin x else cos x)" "exp\Im z\" 0 z, simplified]) fix k x show "((\x. (- 1) ^ (k div 2) * (if even k then sin x else cos x)) has_field_derivative (- 1) ^ (Suc k div 2) * (if odd k then sin x else cos x)) (at x within closed_segment 0 z)" apply (auto simp: power_Suc) apply (intro derivative_eq_intros | simp)+ done next fix x assume "x \ closed_segment 0 z" then show "cmod ((- 1) ^ (Suc n div 2) * (if odd n then sin x else cos x)) \ exp \Im z\" by (auto simp: closed_segment_def norm_mult norm_power cmod_sin_le_exp cmod_cos_le_exp) qed have **: "\k. complex_of_real (sin_coeff k) * z ^ k = (-1)^(k div 2) * (if even k then sin 0 else cos 0) * z^k / of_nat (fact k)" by (auto simp: sin_coeff_def elim!: oddE) show ?thesis by (simp add: ** order_trans [OF _ *]) qed lemma Taylor_cos: "norm(cos z - (\k\n. complex_of_real (cos_coeff k) * z ^ k)) \ exp\Im z\ * (norm z) ^ Suc n / (fact n)" proof - have mono: "\u w z::real. w \ u \ z \ u \ w + z \ u*2" by arith have *: "cmod (cos z - (\i\n. (-1) ^ (Suc i div 2) * (if even i then cos 0 else sin 0) * z ^ i / (fact i))) \ exp \Im z\ * cmod z ^ Suc n / (fact n)" proof (rule complex_Taylor [of "closed_segment 0 z" n "\k x. (-1)^(Suc k div 2) * (if even k then cos x else sin x)" "exp\Im z\" 0 z, simplified]) fix k x assume "x \ closed_segment 0 z" "k \ n" show "((\x. (- 1) ^ (Suc k div 2) * (if even k then cos x else sin x)) has_field_derivative (- 1) ^ Suc (k div 2) * (if odd k then cos x else sin x)) (at x within closed_segment 0 z)" apply (auto simp: power_Suc) apply (intro derivative_eq_intros | simp)+ done next fix x assume "x \ closed_segment 0 z" then show "cmod ((- 1) ^ Suc (n div 2) * (if odd n then cos x else sin x)) \ exp \Im z\" by (auto simp: closed_segment_def norm_mult norm_power cmod_sin_le_exp cmod_cos_le_exp) qed have **: "\k. complex_of_real (cos_coeff k) * z ^ k = (-1)^(Suc k div 2) * (if even k then cos 0 else sin 0) * z^k / of_nat (fact k)" by (auto simp: cos_coeff_def elim!: evenE) show ?thesis by (simp add: ** order_trans [OF _ *]) qed declare power_Suc [simp] text\32-bit Approximation to e\ lemma e_approx_32: "\exp(1) - 5837465777 / 2147483648\ \ (inverse(2 ^ 32)::real)" using Taylor_exp [of 1 14] exp_le apply (simp add: sum_distrib_right in_Reals_norm Re_exp atMost_nat_numeral fact_numeral) apply (simp only: pos_le_divide_eq [symmetric]) done lemma e_less_272: "exp 1 < (272/100::real)" using e_approx_32 by (simp add: abs_if split: if_split_asm) lemma ln_272_gt_1: "ln (272/100) > (1::real)" by (metis e_less_272 exp_less_cancel_iff exp_ln_iff less_trans ln_exp) text\Apparently redundant. But many arguments involve integers.\ lemma ln3_gt_1: "ln 3 > (1::real)" by (simp add: less_trans [OF ln_272_gt_1]) subsection\The argument of a complex number (HOL Light version)\ definition\<^marker>\tag important\ is_Arg :: "[complex,real] \ bool" where "is_Arg z r \ z = of_real(norm z) * exp(\ * of_real r)" definition\<^marker>\tag important\ Arg2pi :: "complex \ real" where "Arg2pi z \ if z = 0 then 0 else THE t. 0 \ t \ t < 2*pi \ is_Arg z t" lemma is_Arg_2pi_iff: "is_Arg z (r + of_int k * (2 * pi)) \ is_Arg z r" by (simp add: algebra_simps is_Arg_def) lemma is_Arg_eqI: assumes r: "is_Arg z r" and s: "is_Arg z s" and rs: "abs (r-s) < 2*pi" and "z \ 0" shows "r = s" proof - have zr: "z = (cmod z) * exp (\ * r)" and zs: "z = (cmod z) * exp (\ * s)" using r s by (auto simp: is_Arg_def) with \z \ 0\ have eq: "exp (\ * r) = exp (\ * s)" by (metis mult_eq_0_iff mult_left_cancel) have "\ * r = \ * s" by (rule exp_complex_eqI) (use rs in \auto simp: eq exp_complex_eqI\) then show ?thesis by simp qed text\This function returns the angle of a complex number from its representation in polar coordinates. Due to periodicity, its range is arbitrary. \<^term>\Arg2pi\ follows HOL Light in adopting the interval \[0,2\)\. But we have the same periodicity issue with logarithms, and it is usual to adopt the same interval for the complex logarithm and argument functions. Further on down, we shall define both functions for the interval \(-\,\]\. The present version is provided for compatibility.\ lemma Arg2pi_0 [simp]: "Arg2pi(0) = 0" by (simp add: Arg2pi_def) lemma Arg2pi_unique_lemma: assumes z: "is_Arg z t" and z': "is_Arg z t'" and t: "0 \ t" "t < 2*pi" and t': "0 \ t'" "t' < 2*pi" and nz: "z \ 0" shows "t' = t" proof - have [dest]: "\x y z::real. x\0 \ x+y < z \ y * of_real t') = of_real (cmod z) * exp (\ * of_real t)" by (metis z z' is_Arg_def) then have "exp (\ * of_real t') = exp (\ * of_real t)" by (metis nz mult_left_cancel mult_zero_left z is_Arg_def) then have "sin t' = sin t \ cos t' = cos t" by (metis cis.simps cis_conv_exp) then obtain n::int where n: "t' = t + 2 * n * pi" by (auto simp: sin_cos_eq_iff) then have "n=0" by (cases n) (use t t' in \auto simp: mult_less_0_iff algebra_simps\) then show "t' = t" by (simp add: n) qed lemma Arg2pi: "0 \ Arg2pi z \ Arg2pi z < 2*pi \ is_Arg z (Arg2pi z)" proof (cases "z=0") case True then show ?thesis by (simp add: Arg2pi_def is_Arg_def) next case False obtain t where t: "0 \ t" "t < 2*pi" and ReIm: "Re z / cmod z = cos t" "Im z / cmod z = sin t" using sincos_total_2pi [OF complex_unit_circle [OF False]] by blast have z: "is_Arg z t" unfolding is_Arg_def using t False ReIm by (intro complex_eqI) (auto simp: exp_Euler sin_of_real cos_of_real field_split_simps) show ?thesis apply (simp add: Arg2pi_def False) apply (rule theI [where a=t]) using t z False apply (auto intro: Arg2pi_unique_lemma) done qed corollary\<^marker>\tag unimportant\ shows Arg2pi_ge_0: "0 \ Arg2pi z" and Arg2pi_lt_2pi: "Arg2pi z < 2*pi" and Arg2pi_eq: "z = of_real(norm z) * exp(\ * of_real(Arg2pi z))" using Arg2pi is_Arg_def by auto lemma complex_norm_eq_1_exp: "norm z = 1 \ exp(\ * of_real (Arg2pi z)) = z" by (metis Arg2pi_eq cis_conv_exp mult.left_neutral norm_cis of_real_1) lemma Arg2pi_unique: "\of_real r * exp(\ * of_real a) = z; 0 < r; 0 \ a; a < 2*pi\ \ Arg2pi z = a" by (rule Arg2pi_unique_lemma [unfolded is_Arg_def, OF _ Arg2pi_eq]) (use Arg2pi [of z] in \auto simp: norm_mult\) lemma cos_Arg2pi: "cmod z * cos (Arg2pi z) = Re z" and sin_Arg2pi: "cmod z * sin (Arg2pi z) = Im z" using Arg2pi_eq [of z] cis_conv_exp Re_rcis Im_rcis unfolding rcis_def by metis+ lemma Arg2pi_minus: assumes "z \ 0" shows "Arg2pi (-z) = (if Arg2pi z < pi then Arg2pi z + pi else Arg2pi z - pi)" apply (rule Arg2pi_unique [of "norm z", OF complex_eqI]) using cos_Arg2pi sin_Arg2pi Arg2pi_ge_0 Arg2pi_lt_2pi [of z] assms by (auto simp: Re_exp Im_exp) lemma Arg2pi_times_of_real [simp]: assumes "0 < r" shows "Arg2pi (of_real r * z) = Arg2pi z" proof (cases "z=0") case False show ?thesis by (rule Arg2pi_unique [of "r * norm z"]) (use Arg2pi False assms is_Arg_def in auto) qed auto lemma Arg2pi_times_of_real2 [simp]: "0 < r \ Arg2pi (z * of_real r) = Arg2pi z" by (metis Arg2pi_times_of_real mult.commute) lemma Arg2pi_divide_of_real [simp]: "0 < r \ Arg2pi (z / of_real r) = Arg2pi z" by (metis Arg2pi_times_of_real2 less_numeral_extra(3) nonzero_eq_divide_eq of_real_eq_0_iff) lemma Arg2pi_le_pi: "Arg2pi z \ pi \ 0 \ Im z" proof (cases "z=0") case False have "0 \ Im z \ 0 \ Im (of_real (cmod z) * exp (\ * complex_of_real (Arg2pi z)))" by (metis Arg2pi_eq) - also have "... = (0 \ Im (exp (\ * complex_of_real (Arg2pi z))))" + also have "\ = (0 \ Im (exp (\ * complex_of_real (Arg2pi z))))" using False by (simp add: zero_le_mult_iff) - also have "... \ Arg2pi z \ pi" + also have "\ \ Arg2pi z \ pi" by (simp add: Im_exp) (metis Arg2pi_ge_0 Arg2pi_lt_2pi sin_lt_zero sin_ge_zero not_le) finally show ?thesis by blast qed auto lemma Arg2pi_lt_pi: "0 < Arg2pi z \ Arg2pi z < pi \ 0 < Im z" proof (cases "z=0") case False have "0 < Im z \ 0 < Im (of_real (cmod z) * exp (\ * complex_of_real (Arg2pi z)))" by (metis Arg2pi_eq) - also have "... = (0 < Im (exp (\ * complex_of_real (Arg2pi z))))" + also have "\ = (0 < Im (exp (\ * complex_of_real (Arg2pi z))))" using False by (simp add: zero_less_mult_iff) - also have "... \ 0 < Arg2pi z \ Arg2pi z < pi" (is "_ = ?rhs") + also have "\ \ 0 < Arg2pi z \ Arg2pi z < pi" (is "_ = ?rhs") proof - have "0 < sin (Arg2pi z) \ ?rhs" by (meson Arg2pi_ge_0 Arg2pi_lt_2pi less_le_trans not_le sin_le_zero sin_x_le_x) then show ?thesis by (auto simp: Im_exp sin_gt_zero) qed finally show ?thesis by blast qed auto lemma Arg2pi_eq_0: "Arg2pi z = 0 \ z \ \ \ 0 \ Re z" proof (cases "z=0") case False have "z \ \ \ 0 \ Re z \ z \ \ \ 0 \ Re (of_real (cmod z) * exp (\ * complex_of_real (Arg2pi z)))" by (metis Arg2pi_eq) - also have "... \ z \ \ \ 0 \ Re (exp (\ * complex_of_real (Arg2pi z)))" + also have "\ \ z \ \ \ 0 \ Re (exp (\ * complex_of_real (Arg2pi z)))" using False by (simp add: zero_le_mult_iff) - also have "... \ Arg2pi z = 0" + also have "\ \ Arg2pi z = 0" proof - have [simp]: "Arg2pi z = 0 \ z \ \" using Arg2pi_eq [of z] by (auto simp: Reals_def) moreover have "\z \ \; 0 \ cos (Arg2pi z)\ \ Arg2pi z = 0" by (metis Arg2pi_lt_pi Arg2pi_ge_0 Arg2pi_le_pi cos_pi complex_is_Real_iff leD less_linear less_minus_one_simps(2) minus_minus neg_less_eq_nonneg order_refl) ultimately show ?thesis by (auto simp: Re_exp) qed finally show ?thesis by blast qed auto corollary\<^marker>\tag unimportant\ Arg2pi_gt_0: assumes "z \ \\<^sub>\\<^sub>0" shows "Arg2pi z > 0" using Arg2pi_eq_0 Arg2pi_ge_0 assms dual_order.strict_iff_order unfolding nonneg_Reals_def by fastforce lemma Arg2pi_eq_pi: "Arg2pi z = pi \ z \ \ \ Re z < 0" using Arg2pi_le_pi [of z] Arg2pi_lt_pi [of z] Arg2pi_eq_0 [of z] Arg2pi_ge_0 [of z] by (fastforce simp: complex_is_Real_iff) lemma Arg2pi_eq_0_pi: "Arg2pi z = 0 \ Arg2pi z = pi \ z \ \" using Arg2pi_eq_0 Arg2pi_eq_pi not_le by auto lemma Arg2pi_of_real: "Arg2pi (of_real r) = (if r<0 then pi else 0)" using Arg2pi_eq_0_pi Arg2pi_eq_pi by fastforce lemma Arg2pi_real: "z \ \ \ Arg2pi z = (if 0 \ Re z then 0 else pi)" using Arg2pi_eq_0 Arg2pi_eq_0_pi by auto lemma Arg2pi_inverse: "Arg2pi(inverse z) = (if z \ \ then Arg2pi z else 2*pi - Arg2pi z)" proof (cases "z=0") case False show ?thesis apply (rule Arg2pi_unique [of "inverse (norm z)"]) using Arg2pi_eq False Arg2pi_ge_0 [of z] Arg2pi_lt_2pi [of z] Arg2pi_eq_0 [of z] by (auto simp: Arg2pi_real in_Reals_norm exp_diff field_simps) qed auto lemma Arg2pi_eq_iff: assumes "w \ 0" "z \ 0" shows "Arg2pi w = Arg2pi z \ (\x. 0 < x & w = of_real x * z)" using assms Arg2pi_eq [of z] Arg2pi_eq [of w] apply auto apply (rule_tac x="norm w / norm z" in exI) apply (simp add: field_split_simps) by (metis mult.commute mult.left_commute) lemma Arg2pi_inverse_eq_0: "Arg2pi(inverse z) = 0 \ Arg2pi z = 0" by (metis Arg2pi_eq_0 Arg2pi_inverse inverse_inverse_eq) lemma Arg2pi_divide: assumes "w \ 0" "z \ 0" "Arg2pi w \ Arg2pi z" shows "Arg2pi(z / w) = Arg2pi z - Arg2pi w" apply (rule Arg2pi_unique [of "norm(z / w)"]) using assms Arg2pi_eq Arg2pi_ge_0 [of w] Arg2pi_lt_2pi [of z] apply (auto simp: exp_diff norm_divide field_simps) done lemma Arg2pi_le_div_sum: assumes "w \ 0" "z \ 0" "Arg2pi w \ Arg2pi z" shows "Arg2pi z = Arg2pi w + Arg2pi(z / w)" by (simp add: Arg2pi_divide assms) lemma Arg2pi_le_div_sum_eq: assumes "w \ 0" "z \ 0" shows "Arg2pi w \ Arg2pi z \ Arg2pi z = Arg2pi w + Arg2pi(z / w)" using assms by (auto simp: Arg2pi_ge_0 intro: Arg2pi_le_div_sum) lemma Arg2pi_diff: assumes "w \ 0" "z \ 0" shows "Arg2pi w - Arg2pi z = (if Arg2pi z \ Arg2pi w then Arg2pi(w / z) else Arg2pi(w/z) - 2*pi)" using assms Arg2pi_divide Arg2pi_inverse [of "w/z"] Arg2pi_eq_0_pi by (force simp add: Arg2pi_ge_0 Arg2pi_divide not_le split: if_split_asm) lemma Arg2pi_add: assumes "w \ 0" "z \ 0" shows "Arg2pi w + Arg2pi z = (if Arg2pi w + Arg2pi z < 2*pi then Arg2pi(w * z) else Arg2pi(w * z) + 2*pi)" - using assms Arg2pi_diff [of "w*z" z] Arg2pi_le_div_sum_eq [of z "w*z"] - apply (auto simp: Arg2pi_ge_0 Arg2pi_divide not_le) - apply (metis Arg2pi_lt_2pi add.commute) - apply (metis (no_types) Arg2pi add.commute diff_0 diff_add_cancel diff_less_eq diff_minus_eq_add not_less) - done + using assms Arg2pi_diff [of "w*z" z] Arg2pi_le_div_sum_eq [of z "w*z"] Arg2pi [of "w * z"] + by auto lemma Arg2pi_times: assumes "w \ 0" "z \ 0" shows "Arg2pi (w * z) = (if Arg2pi w + Arg2pi z < 2*pi then Arg2pi w + Arg2pi z else (Arg2pi w + Arg2pi z) - 2*pi)" using Arg2pi_add [OF assms] by auto lemma Arg2pi_cnj_eq_inverse: "z\0 \ Arg2pi (cnj z) = Arg2pi (inverse z)" apply (simp add: Arg2pi_eq_iff field_split_simps complex_norm_square [symmetric]) by (metis of_real_power zero_less_norm_iff zero_less_power) lemma Arg2pi_cnj: "Arg2pi(cnj z) = (if z \ \ then Arg2pi z else 2*pi - Arg2pi z)" proof (cases "z=0") case False then show ?thesis by (simp add: Arg2pi_cnj_eq_inverse Arg2pi_inverse) qed auto lemma Arg2pi_exp: "0 \ Im z \ Im z < 2*pi \ Arg2pi(exp z) = Im z" by (rule Arg2pi_unique [of "exp(Re z)"]) (auto simp: exp_eq_polar) lemma complex_split_polar: obtains r a::real where "z = complex_of_real r * (cos a + \ * sin a)" "0 \ r" "0 \ a" "a < 2*pi" using Arg2pi cis.ctr cis_conv_exp unfolding Complex_eq is_Arg_def by fastforce lemma Re_Im_le_cmod: "Im w * sin \ + Re w * cos \ \ cmod w" proof (cases w rule: complex_split_polar) case (1 r a) with sin_cos_le1 [of a \] show ?thesis apply (simp add: norm_mult cmod_unit_one) by (metis (no_types, opaque_lifting) abs_le_D1 distrib_left mult.commute mult.left_commute mult_left_le) qed subsection\<^marker>\tag unimportant\\Analytic properties of tangent function\ lemma cnj_tan: "cnj(tan z) = tan(cnj z)" by (simp add: cnj_cos cnj_sin tan_def) lemma field_differentiable_at_tan: "cos z \ 0 \ tan field_differentiable at z" unfolding field_differentiable_def using DERIV_tan by blast lemma field_differentiable_within_tan: "cos z \ 0 \ tan field_differentiable (at z within s)" using field_differentiable_at_tan field_differentiable_at_within by blast lemma continuous_within_tan: "cos z \ 0 \ continuous (at z within s) tan" using continuous_at_imp_continuous_within isCont_tan by blast lemma continuous_on_tan [continuous_intros]: "(\z. z \ s \ cos z \ 0) \ continuous_on s tan" by (simp add: continuous_at_imp_continuous_on) lemma holomorphic_on_tan: "(\z. z \ s \ cos z \ 0) \ tan holomorphic_on s" by (simp add: field_differentiable_within_tan holomorphic_on_def) subsection\The principal branch of the Complex logarithm\ instantiation complex :: ln begin definition\<^marker>\tag important\ ln_complex :: "complex \ complex" where "ln_complex \ \z. THE w. exp w = z & -pi < Im(w) & Im(w) \ pi" text\NOTE: within this scope, the constant Ln is not yet available!\ lemma assumes "z \ 0" shows exp_Ln [simp]: "exp(ln z) = z" and mpi_less_Im_Ln: "-pi < Im(ln z)" and Im_Ln_le_pi: "Im(ln z) \ pi" proof - obtain \ where z: "z / (cmod z) = Complex (cos \) (sin \)" using complex_unimodular_polar [of "z / (norm z)"] assms by (auto simp: norm_divide field_split_simps) obtain \ where \: "- pi < \" "\ \ pi" "sin \ = sin \" "cos \ = cos \" using sincos_principal_value [of "\"] assms by (auto simp: norm_divide field_split_simps) have "exp(ln z) = z & -pi < Im(ln z) & Im(ln z) \ pi" unfolding ln_complex_def apply (rule theI [where a = "Complex (ln(norm z)) \"]) using z assms \ apply (auto simp: field_simps exp_complex_eqI exp_eq_polar cis.code) done then show "exp(ln z) = z" "-pi < Im(ln z)" "Im(ln z) \ pi" by auto qed lemma Ln_exp [simp]: assumes "-pi < Im(z)" "Im(z) \ pi" shows "ln(exp z) = z" proof (rule exp_complex_eqI) show "\Im (ln (exp z)) - Im z\ < 2 * pi" using assms mpi_less_Im_Ln [of "exp z"] Im_Ln_le_pi [of "exp z"] by auto qed auto subsection\<^marker>\tag unimportant\\Relation to Real Logarithm\ lemma Ln_of_real: assumes "0 < z" shows "ln(of_real z::complex) = of_real(ln z)" proof - have "ln(of_real (exp (ln z))::complex) = ln (exp (of_real (ln z)))" by (simp add: exp_of_real) - also have "... = of_real(ln z)" + also have "\ = of_real(ln z)" using assms by (subst Ln_exp) auto finally show ?thesis using assms by simp qed corollary\<^marker>\tag unimportant\ Ln_in_Reals [simp]: "z \ \ \ Re z > 0 \ ln z \ \" by (auto simp: Ln_of_real elim: Reals_cases) corollary\<^marker>\tag unimportant\ Im_Ln_of_real [simp]: "r > 0 \ Im (ln (of_real r)) = 0" by (simp add: Ln_of_real) lemma cmod_Ln_Reals [simp]: "z \ \ \ 0 < Re z \ cmod (ln z) = norm (ln (Re z))" using Ln_of_real by force lemma Ln_Reals_eq: "\x \ \; Re x > 0\ \ ln x = of_real (ln (Re x))" using Ln_of_real by force lemma Ln_1 [simp]: "ln 1 = (0::complex)" proof - have "ln (exp 0) = (0::complex)" by (simp add: del: exp_zero) then show ?thesis by simp qed lemma Ln_eq_zero_iff [simp]: "x \ \\<^sub>\\<^sub>0 \ ln x = 0 \ x = 1" for x::complex by auto (metis exp_Ln exp_zero nonpos_Reals_zero_I) instance by intro_classes (rule ln_complex_def Ln_1) end abbreviation Ln :: "complex \ complex" where "Ln \ ln" lemma Ln_eq_iff: "w \ 0 \ z \ 0 \ (Ln w = Ln z \ w = z)" by (metis exp_Ln) lemma Ln_unique: "exp(z) = w \ -pi < Im(z) \ Im(z) \ pi \ Ln w = z" using Ln_exp by blast lemma Re_Ln [simp]: "z \ 0 \ Re(Ln z) = ln(norm z)" by (metis exp_Ln ln_exp norm_exp_eq_Re) corollary\<^marker>\tag unimportant\ ln_cmod_le: assumes z: "z \ 0" shows "ln (cmod z) \ cmod (Ln z)" using norm_exp [of "Ln z", simplified exp_Ln [OF z]] by (metis Re_Ln complex_Re_le_cmod z) proposition\<^marker>\tag unimportant\ exists_complex_root: fixes z :: complex assumes "n \ 0" obtains w where "z = w ^ n" proof (cases "z=0") case False then show ?thesis by (rule_tac w = "exp(Ln z / n)" in that) (simp add: assms exp_of_nat_mult [symmetric]) qed (use assms in auto) corollary\<^marker>\tag unimportant\ exists_complex_root_nonzero: fixes z::complex assumes "z \ 0" "n \ 0" obtains w where "w \ 0" "z = w ^ n" by (metis exists_complex_root [of n z] assms power_0_left) subsection\<^marker>\tag unimportant\\Derivative of Ln away from the branch cut\ lemma assumes "z \ \\<^sub>\\<^sub>0" shows has_field_derivative_Ln: "(Ln has_field_derivative inverse(z)) (at z)" and Im_Ln_less_pi: "Im (Ln z) < pi" proof - have znz [simp]: "z \ 0" using assms by auto then have "Im (Ln z) \ pi" by (metis (no_types) Im_exp Ln_in_Reals assms complex_nonpos_Reals_iff complex_is_Real_iff exp_Ln mult_zero_right not_less pi_neq_zero sin_pi znz) then show *: "Im (Ln z) < pi" using assms Im_Ln_le_pi by (simp add: le_neq_trans) let ?U = "{w. -pi < Im(w) \ Im(w) < pi}" have 1: "open ?U" by (simp add: open_Collect_conj open_halfspace_Im_gt open_halfspace_Im_lt) have 2: "\x. x \ ?U \ (exp has_derivative blinfun_apply(Blinfun ((*) (exp x)))) (at x)" by (simp add: bounded_linear_Blinfun_apply bounded_linear_mult_right has_field_derivative_imp_has_derivative) have 3: "continuous_on ?U (\x. Blinfun ((*) (exp x)))" unfolding blinfun_mult_right.abs_eq [symmetric] by (intro continuous_intros) have 4: "Ln z \ ?U" by (auto simp: mpi_less_Im_Ln *) have 5: "Blinfun ((*) (inverse z)) o\<^sub>L Blinfun ((*) (exp (Ln z))) = id_blinfun" by (rule blinfun_eqI) (simp add: bounded_linear_mult_right bounded_linear_Blinfun_apply) obtain U' V g g' where "open U'" and sub: "U' \ ?U" and "Ln z \ U'" "open V" "z \ V" and hom: "homeomorphism U' V exp g" and g: "\y. y \ V \ (g has_derivative (g' y)) (at y)" and g': "\y. y \ V \ g' y = inv ((*) (exp (g y)))" and bij: "\y. y \ V \ bij ((*) (exp (g y)))" using inverse_function_theorem [OF 1 2 3 4 5] by (simp add: bounded_linear_Blinfun_apply bounded_linear_mult_right) blast show "(Ln has_field_derivative inverse(z)) (at z)" unfolding has_field_derivative_def proof (rule has_derivative_transform_within_open) show g_eq_Ln: "g y = Ln y" if "y \ V" for y proof - obtain x where "y = exp x" "x \ U'" using hom homeomorphism_image1 that \y \ V\ by blast then show ?thesis using sub hom homeomorphism_apply1 by fastforce qed have "0 \ V" by (meson exp_not_eq_zero hom homeomorphism_def) then have "\y. y \ V \ g' y = inv ((*) y)" by (metis exp_Ln g' g_eq_Ln) then have g': "g' z = (\x. x/z)" by (metis (no_types, opaque_lifting) bij \z \ V\ bij_inv_eq_iff exp_Ln g_eq_Ln nonzero_mult_div_cancel_left znz) show "(g has_derivative (*) (inverse z)) (at z)" using g [OF \z \ V\] g' by (simp add: \z \ V\ field_class.field_divide_inverse has_derivative_imp_has_field_derivative has_field_derivative_imp_has_derivative) qed (auto simp: \z \ V\ \open V\) qed declare has_field_derivative_Ln [derivative_intros] declare has_field_derivative_Ln [THEN DERIV_chain2, derivative_intros] lemma field_differentiable_at_Ln: "z \ \\<^sub>\\<^sub>0 \ Ln field_differentiable at z" using field_differentiable_def has_field_derivative_Ln by blast lemma field_differentiable_within_Ln: "z \ \\<^sub>\\<^sub>0 \ Ln field_differentiable (at z within S)" using field_differentiable_at_Ln field_differentiable_within_subset by blast lemma continuous_at_Ln: "z \ \\<^sub>\\<^sub>0 \ continuous (at z) Ln" by (simp add: field_differentiable_imp_continuous_at field_differentiable_within_Ln) lemma isCont_Ln' [simp,continuous_intros]: "\isCont f z; f z \ \\<^sub>\\<^sub>0\ \ isCont (\x. Ln (f x)) z" by (blast intro: isCont_o2 [OF _ continuous_at_Ln]) lemma continuous_within_Ln [continuous_intros]: "z \ \\<^sub>\\<^sub>0 \ continuous (at z within S) Ln" using continuous_at_Ln continuous_at_imp_continuous_within by blast lemma continuous_on_Ln [continuous_intros]: "(\z. z \ S \ z \ \\<^sub>\\<^sub>0) \ continuous_on S Ln" by (simp add: continuous_at_imp_continuous_on continuous_within_Ln) lemma continuous_on_Ln' [continuous_intros]: "continuous_on S f \ (\z. z \ S \ f z \ \\<^sub>\\<^sub>0) \ continuous_on S (\x. Ln (f x))" by (rule continuous_on_compose2[OF continuous_on_Ln, of "UNIV - nonpos_Reals" S f]) auto lemma holomorphic_on_Ln [holomorphic_intros]: "S \ \\<^sub>\\<^sub>0 = {} \ Ln holomorphic_on S" by (simp add: disjoint_iff field_differentiable_within_Ln holomorphic_on_def) lemma holomorphic_on_Ln' [holomorphic_intros]: "(\z. z \ A \ f z \ \\<^sub>\\<^sub>0) \ f holomorphic_on A \ (\z. Ln (f z)) holomorphic_on A" using holomorphic_on_compose_gen[OF _ holomorphic_on_Ln, of f A "- \\<^sub>\\<^sub>0"] by (auto simp: o_def) lemma tendsto_Ln [tendsto_intros]: fixes L F assumes "(f \ L) F" "L \ \\<^sub>\\<^sub>0" shows "((\x. Ln (f x)) \ Ln L) F" proof - have "nhds L \ filtermap f F" using assms(1) by (simp add: filterlim_def) moreover have "\\<^sub>F y in nhds L. y \ - \\<^sub>\\<^sub>0" using eventually_nhds_in_open[of "- \\<^sub>\\<^sub>0" L] assms by (auto simp: open_Compl) ultimately have "\\<^sub>F y in filtermap f F. y \ - \\<^sub>\\<^sub>0" by (rule filter_leD) moreover have "continuous_on (-\\<^sub>\\<^sub>0) Ln" by (rule continuous_on_Ln) auto ultimately show ?thesis using continuous_on_tendsto_compose[of "- \\<^sub>\\<^sub>0" Ln f L F] assms by (simp add: eventually_filtermap) qed lemma divide_ln_mono: fixes x y::real assumes "3 \ x" "x \ y" shows "x / ln x \ y / ln y" proof (rule exE [OF complex_mvt_line [of x y "\z. z / Ln z" "\z. 1/(Ln z) - 1/(Ln z)^2"]]; clarsimp simp add: closed_segment_Reals closed_segment_eq_real_ivl assms) show "\u. \x \ u; u \ y\ \ ((\z. z / Ln z) has_field_derivative 1 / Ln u - 1 / (Ln u)\<^sup>2) (at u)" using \3 \ x\ by (force intro!: derivative_eq_intros simp: field_simps power_eq_if) show "x / ln x \ y / ln y" if "Re (y / Ln y) - Re (x / Ln x) = (Re (1 / Ln u) - Re (1 / (Ln u)\<^sup>2)) * (y - x)" and x: "x \ u" "u \ y" for u proof - have eq: "y / ln y = (1 / ln u - 1 / (ln u)\<^sup>2) * (y - x) + x / ln x" using that \3 \ x\ by (auto simp: Ln_Reals_eq in_Reals_norm group_add_class.diff_eq_eq) show ?thesis using exp_le \3 \ x\ x by (simp add: eq) (simp add: power_eq_if divide_simps ln_ge_iff) qed qed theorem Ln_series: fixes z :: complex assumes "norm z < 1" shows "(\n. (-1)^Suc n / of_nat n * z^n) sums ln (1 + z)" (is "(\n. ?f n * z^n) sums _") proof - let ?F = "\z. \n. ?f n * z^n" and ?F' = "\z. \n. diffs ?f n * z^n" have r: "conv_radius ?f = 1" by (intro conv_radius_ratio_limit_nonzero[of _ 1]) (simp_all add: norm_divide LIMSEQ_Suc_n_over_n del: of_nat_Suc) have "\c. \z\ball 0 1. ln (1 + z) - ?F z = c" proof (rule has_field_derivative_zero_constant) fix z :: complex assume z': "z \ ball 0 1" hence z: "norm z < 1" by simp define t :: complex where "t = of_real (1 + norm z) / 2" from z have t: "norm z < norm t" "norm t < 1" unfolding t_def by (simp_all add: field_simps norm_divide del: of_real_add) have "Re (-z) \ norm (-z)" by (rule complex_Re_le_cmod) - also from z have "... < 1" by simp + also from z have "\ < 1" by simp finally have "((\z. ln (1 + z)) has_field_derivative inverse (1+z)) (at z)" by (auto intro!: derivative_eq_intros simp: complex_nonpos_Reals_iff) moreover have "(?F has_field_derivative ?F' z) (at z)" using t r by (intro termdiffs_strong[of _ t] summable_in_conv_radius) simp_all ultimately have "((\z. ln (1 + z) - ?F z) has_field_derivative (inverse (1 + z) - ?F' z)) (at z within ball 0 1)" by (intro derivative_intros) (simp_all add: at_within_open[OF z']) also have "(\n. of_nat n * ?f n * z ^ (n - Suc 0)) sums ?F' z" using t r by (intro diffs_equiv termdiff_converges[OF t(1)] summable_in_conv_radius) simp_all from sums_split_initial_segment[OF this, of 1] have "(\i. (-z) ^ i) sums ?F' z" by (simp add: power_minus[of z] del: of_nat_Suc) hence "?F' z = inverse (1 + z)" using z by (simp add: sums_iff suminf_geometric divide_inverse) also have "inverse (1 + z) - inverse (1 + z) = 0" by simp finally show "((\z. ln (1 + z) - ?F z) has_field_derivative 0) (at z within ball 0 1)" . qed simp_all then obtain c where c: "\z. z \ ball 0 1 \ ln (1 + z) - ?F z = c" by blast from c[of 0] have "c = 0" by (simp only: powser_zero) simp with c[of z] assms have "ln (1 + z) = ?F z" by simp moreover have "summable (\n. ?f n * z^n)" using assms r by (intro summable_in_conv_radius) simp_all ultimately show ?thesis by (simp add: sums_iff) qed lemma Ln_series': "cmod z < 1 \ (\n. - ((-z)^n) / of_nat n) sums ln (1 + z)" by (drule Ln_series) (simp add: power_minus') lemma ln_series': assumes "abs (x::real) < 1" shows "(\n. - ((-x)^n) / of_nat n) sums ln (1 + x)" proof - from assms have "(\n. - ((-of_real x)^n) / of_nat n) sums ln (1 + complex_of_real x)" by (intro Ln_series') simp_all also have "(\n. - ((-of_real x)^n) / of_nat n) = (\n. complex_of_real (- ((-x)^n) / of_nat n))" by (rule ext) simp also from assms have "ln (1 + complex_of_real x) = of_real (ln (1 + x))" by (subst Ln_of_real [symmetric]) simp_all finally show ?thesis by (subst (asm) sums_of_real_iff) qed lemma Ln_approx_linear: fixes z :: complex assumes "norm z < 1" shows "norm (ln (1 + z) - z) \ norm z^2 / (1 - norm z)" proof - let ?f = "\n. (-1)^Suc n / of_nat n" from assms have "(\n. ?f n * z^n) sums ln (1 + z)" using Ln_series by simp moreover have "(\n. (if n = 1 then 1 else 0) * z^n) sums z" using powser_sums_if[of 1] by simp ultimately have "(\n. (?f n - (if n = 1 then 1 else 0)) * z^n) sums (ln (1 + z) - z)" by (subst left_diff_distrib, intro sums_diff) simp_all from sums_split_initial_segment[OF this, of "Suc 1"] have "(\i. (-(z^2)) * inverse (2 + of_nat i) * (- z)^i) sums (Ln (1 + z) - z)" by (simp add: power2_eq_square mult_ac power_minus[of z] divide_inverse) hence "(Ln (1 + z) - z) = (\i. (-(z^2)) * inverse (of_nat (i+2)) * (-z)^i)" by (simp add: sums_iff) also have A: "summable (\n. norm z^2 * (inverse (real_of_nat (Suc (Suc n))) * cmod z ^ n))" by (rule summable_mult, rule summable_comparison_test_ev[OF _ summable_geometric[of "norm z"]]) (auto simp: assms field_simps intro!: always_eventually) hence "norm (\i. (-(z^2)) * inverse (of_nat (i+2)) * (-z)^i) \ (\i. norm (-(z^2) * inverse (of_nat (i+2)) * (-z)^i))" by (intro summable_norm) (auto simp: norm_power norm_inverse norm_mult mult_ac simp del: of_nat_add of_nat_Suc) also have "norm ((-z)^2 * (-z)^i) * inverse (of_nat (i+2)) \ norm ((-z)^2 * (-z)^i) * 1" for i by (intro mult_left_mono) (simp_all add: field_split_simps) hence "(\i. norm (-(z^2) * inverse (of_nat (i+2)) * (-z)^i)) \ (\i. norm (-(z^2) * (-z)^i))" using A assms unfolding norm_power norm_inverse norm_divide norm_mult apply (intro suminf_le summable_mult summable_geometric) apply (auto simp: norm_power field_simps simp del: of_nat_add of_nat_Suc) done - also have "... = norm z^2 * (\i. norm z^i)" using assms + also have "\ = norm z^2 * (\i. norm z^i)" using assms by (subst suminf_mult [symmetric]) (auto intro!: summable_geometric simp: norm_mult norm_power) also have "(\i. norm z^i) = inverse (1 - norm z)" using assms by (subst suminf_geometric) (simp_all add: divide_inverse) - also have "norm z^2 * ... = norm z^2 / (1 - norm z)" by (simp add: divide_inverse) + also have "norm z^2 * \ = norm z^2 / (1 - norm z)" by (simp add: divide_inverse) finally show ?thesis . qed subsection\<^marker>\tag unimportant\\Quadrant-type results for Ln\ lemma cos_lt_zero_pi: "pi/2 < x \ x < 3*pi/2 \ cos x < 0" using cos_minus_pi cos_gt_zero_pi [of "x-pi"] by simp lemma Re_Ln_pos_lt: assumes "z \ 0" shows "\Im(Ln z)\ < pi/2 \ 0 < Re(z)" proof - { fix w assume "w = Ln z" then have w: "Im w \ pi" "- pi < Im w" using Im_Ln_le_pi [of z] mpi_less_Im_Ln [of z] assms by auto have "\Im w\ < pi/2 \ 0 < Re(exp w)" proof assume "\Im w\ < pi/2" then show "0 < Re(exp w)" by (auto simp: Re_exp cos_gt_zero_pi split: if_split_asm) next assume R: "0 < Re(exp w)" then have "\Im w\ \ pi/2" by (metis cos_minus cos_pi_half mult_eq_0_iff Re_exp abs_if order_less_irrefl) then show "\Im w\ < pi/2" using cos_lt_zero_pi [of "-(Im w)"] cos_lt_zero_pi [of "(Im w)"] w R by (force simp: Re_exp zero_less_mult_iff abs_if not_less_iff_gr_or_eq) qed } then show ?thesis using assms by auto qed lemma Re_Ln_pos_le: assumes "z \ 0" shows "\Im(Ln z)\ \ pi/2 \ 0 \ Re(z)" proof - { fix w assume "w = Ln z" then have w: "Im w \ pi" "- pi < Im w" using Im_Ln_le_pi [of z] mpi_less_Im_Ln [of z] assms by auto then have "\Im w\ \ pi/2 \ 0 \ Re(exp w)" using cos_lt_zero_pi [of "- (Im w)"] cos_lt_zero_pi [of "(Im w)"] not_le by (auto simp: Re_exp zero_le_mult_iff abs_if intro: cos_ge_zero) } then show ?thesis using assms by auto qed lemma Im_Ln_pos_lt: assumes "z \ 0" shows "0 < Im(Ln z) \ Im(Ln z) < pi \ 0 < Im(z)" proof - { fix w assume "w = Ln z" then have w: "Im w \ pi" "- pi < Im w" using Im_Ln_le_pi [of z] mpi_less_Im_Ln [of z] assms by auto then have "0 < Im w \ Im w < pi \ 0 < Im(exp w)" using sin_gt_zero [of "- (Im w)"] sin_gt_zero [of "(Im w)"] less_linear by (fastforce simp add: Im_exp zero_less_mult_iff) } then show ?thesis using assms by auto qed lemma Im_Ln_pos_le: assumes "z \ 0" shows "0 \ Im(Ln z) \ Im(Ln z) \ pi \ 0 \ Im(z)" proof - { fix w assume "w = Ln z" then have w: "Im w \ pi" "- pi < Im w" using Im_Ln_le_pi [of z] mpi_less_Im_Ln [of z] assms by auto then have "0 \ Im w \ Im w \ pi \ 0 \ Im(exp w)" using sin_ge_zero [of "- (Im w)"] sin_ge_zero [of "abs(Im w)"] sin_zero_pi_iff [of "Im w"] by (force simp: Im_exp zero_le_mult_iff sin_ge_zero) } then show ?thesis using assms by auto qed lemma Re_Ln_pos_lt_imp: "0 < Re(z) \ \Im(Ln z)\ < pi/2" by (metis Re_Ln_pos_lt less_irrefl zero_complex.simps(1)) lemma Im_Ln_pos_lt_imp: "0 < Im(z) \ 0 < Im(Ln z) \ Im(Ln z) < pi" by (metis Im_Ln_pos_lt not_le order_refl zero_complex.simps(2)) text\A reference to the set of positive real numbers\ lemma Im_Ln_eq_0: "z \ 0 \ (Im(Ln z) = 0 \ 0 < Re(z) \ Im(z) = 0)" -by (metis Im_complex_of_real Im_exp Ln_in_Reals Re_Ln_pos_lt Re_Ln_pos_lt_imp - Re_complex_of_real complex_is_Real_iff exp_Ln exp_of_real pi_gt_zero) + using Im_Ln_pos_le Im_Ln_pos_lt Re_Ln_pos_lt by fastforce lemma Im_Ln_eq_pi: "z \ 0 \ (Im(Ln z) = pi \ Re(z) < 0 \ Im(z) = 0)" -by (metis Im_Ln_eq_0 Im_Ln_pos_le Im_Ln_pos_lt add.left_neutral complex_eq less_eq_real_def - mult_zero_right not_less_iff_gr_or_eq pi_ge_zero pi_neq_zero rcis_zero_arg rcis_zero_mod) + using Im_Ln_eq_0 Im_Ln_pos_le Im_Ln_pos_lt complex.expand by fastforce subsection\<^marker>\tag unimportant\\More Properties of Ln\ lemma cnj_Ln: assumes "z \ \\<^sub>\\<^sub>0" shows "cnj(Ln z) = Ln(cnj z)" proof (cases "z=0") case False show ?thesis proof (rule exp_complex_eqI) have "\Im (cnj (Ln z)) - Im (Ln (cnj z))\ \ \Im (cnj (Ln z))\ + \Im (Ln (cnj z))\" by (rule abs_triangle_ineq4) - also have "... < pi + pi" + also have "\ < pi + pi" proof - have "\Im (cnj (Ln z))\ < pi" by (simp add: False Im_Ln_less_pi abs_if assms minus_less_iff mpi_less_Im_Ln) moreover have "\Im (Ln (cnj z))\ \ pi" by (meson abs_le_iff complex_cnj_zero_iff less_eq_real_def minus_less_iff False Im_Ln_le_pi mpi_less_Im_Ln) ultimately show ?thesis by simp qed finally show "\Im (cnj (Ln z)) - Im (Ln (cnj z))\ < 2 * pi" by simp show "exp (cnj (Ln z)) = exp (Ln (cnj z))" by (metis False complex_cnj_zero_iff exp_Ln exp_cnj) qed qed (use assms in auto) lemma Ln_inverse: assumes "z \ \\<^sub>\\<^sub>0" shows "Ln(inverse z) = -(Ln z)" proof (cases "z=0") case False show ?thesis proof (rule exp_complex_eqI) have "\Im (Ln (inverse z)) - Im (- Ln z)\ \ \Im (Ln (inverse z))\ + \Im (- Ln z)\" by (rule abs_triangle_ineq4) - also have "... < pi + pi" + also have "\ < pi + pi" proof - have "\Im (Ln (inverse z))\ < pi" by (simp add: False Im_Ln_less_pi abs_if assms minus_less_iff mpi_less_Im_Ln) moreover have "\Im (- Ln z)\ \ pi" using False Im_Ln_le_pi mpi_less_Im_Ln by fastforce ultimately show ?thesis by simp qed finally show "\Im (Ln (inverse z)) - Im (- Ln z)\ < 2 * pi" by simp show "exp (Ln (inverse z)) = exp (- Ln z)" by (simp add: False exp_minus) qed qed (use assms in auto) lemma Ln_minus1 [simp]: "Ln(-1) = \ * pi" proof (rule exp_complex_eqI) show "\Im (Ln (- 1)) - Im (\ * pi)\ < 2 * pi" using Im_Ln_le_pi [of "-1"] mpi_less_Im_Ln [of "-1"] by auto qed auto lemma Ln_ii [simp]: "Ln \ = \ * of_real pi/2" using Ln_exp [of "\ * (of_real pi/2)"] unfolding exp_Euler by simp lemma Ln_minus_ii [simp]: "Ln(-\) = - (\ * pi/2)" proof - have "Ln(-\) = Ln(inverse \)" by simp - also have "... = - (Ln \)" using Ln_inverse by blast - also have "... = - (\ * pi/2)" by simp + also have "\ = - (Ln \)" using Ln_inverse by blast + also have "\ = - (\ * pi/2)" by simp finally show ?thesis . qed lemma Ln_times: assumes "w \ 0" "z \ 0" shows "Ln(w * z) = (if Im(Ln w + Ln z) \ -pi then (Ln(w) + Ln(z)) + \ * of_real(2*pi) else if Im(Ln w + Ln z) > pi then (Ln(w) + Ln(z)) - \ * of_real(2*pi) else Ln(w) + Ln(z))" using pi_ge_zero Im_Ln_le_pi [of w] Im_Ln_le_pi [of z] using assms mpi_less_Im_Ln [of w] mpi_less_Im_Ln [of z] by (auto simp: exp_add exp_diff sin_double cos_double exp_Euler intro!: Ln_unique) corollary\<^marker>\tag unimportant\ Ln_times_simple: "\w \ 0; z \ 0; -pi < Im(Ln w) + Im(Ln z); Im(Ln w) + Im(Ln z) \ pi\ \ Ln(w * z) = Ln(w) + Ln(z)" by (simp add: Ln_times) corollary\<^marker>\tag unimportant\ Ln_times_of_real: "\r > 0; z \ 0\ \ Ln(of_real r * z) = ln r + Ln(z)" using mpi_less_Im_Ln Im_Ln_le_pi by (force simp: Ln_times) corollary\<^marker>\tag unimportant\ Ln_times_of_nat: "\r > 0; z \ 0\ \ Ln(of_nat r * z :: complex) = ln (of_nat r) + Ln(z)" using Ln_times_of_real[of "of_nat r" z] by simp corollary\<^marker>\tag unimportant\ Ln_times_Reals: "\r \ Reals; Re r > 0; z \ 0\ \ Ln(r * z) = ln (Re r) + Ln(z)" using Ln_Reals_eq Ln_times_of_real by fastforce corollary\<^marker>\tag unimportant\ Ln_divide_of_real: "\r > 0; z \ 0\ \ Ln(z / of_real r) = Ln(z) - ln r" using Ln_times_of_real [of "inverse r" z] by (simp add: ln_inverse Ln_of_real mult.commute divide_inverse of_real_inverse [symmetric] del: of_real_inverse) corollary\<^marker>\tag unimportant\ Ln_prod: fixes f :: "'a \ complex" assumes "finite A" "\x. x \ A \ f x \ 0" shows "\n. Ln (prod f A) = (\x \ A. Ln (f x) + (of_int (n x) * (2 * pi)) * \)" using assms proof (induction A) case (insert x A) then obtain n where n: "Ln (prod f A) = (\x\A. Ln (f x) + of_real (of_int (n x) * (2 * pi)) * \)" by auto define D where "D \ Im (Ln (f x)) + Im (Ln (prod f A))" define q::int where "q \ (if D \ -pi then 1 else if D > pi then -1 else 0)" have "prod f A \ 0" "f x \ 0" by (auto simp: insert.hyps insert.prems) with insert.hyps pi_ge_zero show ?case by (rule_tac x="n(x:=q)" in exI) (force simp: Ln_times q_def D_def n intro!: sum.cong) qed auto lemma Ln_minus: assumes "z \ 0" shows "Ln(-z) = (if Im(z) \ 0 \ \(Re(z) < 0 \ Im(z) = 0) then Ln(z) + \ * pi else Ln(z) - \ * pi)" (is "_ = ?rhs") using Im_Ln_le_pi [of z] mpi_less_Im_Ln [of z] assms Im_Ln_eq_pi [of z] Im_Ln_pos_lt [of z] by (fastforce simp: exp_add exp_diff exp_Euler intro!: Ln_unique) lemma Ln_inverse_if: assumes "z \ 0" shows "Ln (inverse z) = (if z \ \\<^sub>\\<^sub>0 then -(Ln z) + \ * 2 * complex_of_real pi else -(Ln z))" proof (cases "z \ \\<^sub>\\<^sub>0") case False then show ?thesis by (simp add: Ln_inverse) next case True then have z: "Im z = 0" "Re z < 0" "- z \ \\<^sub>\\<^sub>0" using assms complex_eq_iff complex_nonpos_Reals_iff by auto have "Ln(inverse z) = Ln(- (inverse (-z)))" by simp - also have "... = Ln (inverse (-z)) + \ * complex_of_real pi" + also have "\ = Ln (inverse (-z)) + \ * complex_of_real pi" using assms z by (simp add: Ln_minus divide_less_0_iff) - also have "... = - Ln (- z) + \ * complex_of_real pi" + also have "\ = - Ln (- z) + \ * complex_of_real pi" using z Ln_inverse by presburger - also have "... = - (Ln z) + \ * 2 * complex_of_real pi" + also have "\ = - (Ln z) + \ * 2 * complex_of_real pi" using Ln_minus assms z by auto finally show ?thesis by (simp add: True) qed lemma Ln_times_ii: assumes "z \ 0" shows "Ln(\ * z) = (if 0 \ Re(z) | Im(z) < 0 then Ln(z) + \ * of_real pi/2 else Ln(z) - \ * of_real(3 * pi/2))" using Im_Ln_le_pi [of z] mpi_less_Im_Ln [of z] assms Im_Ln_eq_pi [of z] Im_Ln_pos_lt [of z] Re_Ln_pos_le [of z] by (simp add: Ln_times) auto lemma Ln_of_nat [simp]: "0 < n \ Ln (of_nat n) = of_real (ln (of_nat n))" by (subst of_real_of_nat_eq[symmetric], subst Ln_of_real[symmetric]) simp_all lemma Ln_of_nat_over_of_nat: assumes "m > 0" "n > 0" shows "Ln (of_nat m / of_nat n) = of_real (ln (of_nat m) - ln (of_nat n))" proof - have "of_nat m / of_nat n = (of_real (of_nat m / of_nat n) :: complex)" by simp - also from assms have "Ln ... = of_real (ln (of_nat m / of_nat n))" + also from assms have "Ln \ = of_real (ln (of_nat m / of_nat n))" by (simp add: Ln_of_real[symmetric]) - also from assms have "... = of_real (ln (of_nat m) - ln (of_nat n))" + also from assms have "\ = of_real (ln (of_nat m) - ln (of_nat n))" by (simp add: ln_div) finally show ?thesis . qed subsection\The Argument of a Complex Number\ text\Unlike in HOL Light, it's defined for the same interval as the complex logarithm: \(-\,\]\.\ lemma Arg_eq_Im_Ln: assumes "z \ 0" shows "Arg z = Im (Ln z)" proof (rule cis_Arg_unique) show "sgn z = cis (Im (Ln z))" by (metis assms exp_Ln exp_eq_polar nonzero_mult_div_cancel_left norm_eq_zero norm_exp_eq_Re of_real_eq_0_iff sgn_eq) show "- pi < Im (Ln z)" by (simp add: assms mpi_less_Im_Ln) show "Im (Ln z) \ pi" by (simp add: Im_Ln_le_pi assms) qed text \The 1990s definition of argument coincides with the more recent one\ lemma\<^marker>\tag important\ Arg_def: shows "Arg z = (if z = 0 then 0 else Im (Ln z))" by (simp add: Arg_eq_Im_Ln Arg_zero) lemma Arg_of_real [simp]: "Arg (of_real r) = (if r<0 then pi else 0)" by (simp add: Im_Ln_eq_pi Arg_def) lemma mpi_less_Arg: "-pi < Arg z" and Arg_le_pi: "Arg z \ pi" by (auto simp: Arg_def mpi_less_Im_Ln Im_Ln_le_pi) lemma assumes "z \ 0" shows Arg_eq: "z = of_real(norm z) * exp(\ * Arg z)" using assms exp_Ln exp_eq_polar by (auto simp: Arg_def) lemma is_Arg_Arg: "z \ 0 \ is_Arg z (Arg z)" by (simp add: Arg_eq is_Arg_def) lemma Argument_exists: assumes "z \ 0" and R: "R = {r-pi<..r+pi}" obtains s where "is_Arg z s" "s\R" proof - let ?rp = "r - Arg z + pi" define k where "k \ \?rp / (2 * pi)\" have "(Arg z + of_int k * (2 * pi)) \ R" using floor_divide_lower [of "2*pi" ?rp] floor_divide_upper [of "2*pi" ?rp] by (auto simp: k_def algebra_simps R) then show ?thesis using Arg_eq \z \ 0\ is_Arg_2pi_iff is_Arg_def that by blast qed lemma Argument_exists_unique: assumes "z \ 0" and R: "R = {r-pi<..r+pi}" obtains s where "is_Arg z s" "s\R" "\t. \is_Arg z t; t\R\ \ s=t" proof - obtain s where s: "is_Arg z s" "s\R" using Argument_exists [OF assms] . moreover have "\t. \is_Arg z t; t\R\ \ s=t" using assms s by (auto simp: is_Arg_eqI) ultimately show thesis using that by blast qed lemma Argument_Ex1: assumes "z \ 0" and R: "R = {r-pi<..r+pi}" shows "\!s. is_Arg z s \ s \ R" using Argument_exists_unique [OF assms] by metis lemma Arg_divide: assumes "w \ 0" "z \ 0" shows "is_Arg (z / w) (Arg z - Arg w)" using Arg_eq [of z] Arg_eq [of w] Arg_eq [of "norm(z / w)"] assms by (auto simp: is_Arg_def norm_divide field_simps exp_diff Arg_of_real) lemma Arg_unique_lemma: assumes z: "is_Arg z t" and z': "is_Arg z t'" and t: "- pi < t" "t \ pi" and t': "- pi < t'" "t' \ pi" and nz: "z \ 0" shows "t' = t" using Arg2pi_unique_lemma [of "- (inverse z)"] proof - have "pi - t' = pi - t" proof (rule Arg2pi_unique_lemma [of "- (inverse z)"]) have "- (inverse z) = - (inverse (of_real(norm z) * exp(\ * t)))" by (metis is_Arg_def z) - also have "... = (cmod (- inverse z)) * exp (\ * (pi - t))" + also have "\ = (cmod (- inverse z)) * exp (\ * (pi - t))" by (auto simp: field_simps exp_diff norm_divide) finally show "is_Arg (- inverse z) (pi - t)" unfolding is_Arg_def . have "- (inverse z) = - (inverse (of_real(norm z) * exp(\ * t')))" by (metis is_Arg_def z') - also have "... = (cmod (- inverse z)) * exp (\ * (pi - t'))" + also have "\ = (cmod (- inverse z)) * exp (\ * (pi - t'))" by (auto simp: field_simps exp_diff norm_divide) finally show "is_Arg (- inverse z) (pi - t')" unfolding is_Arg_def . qed (use assms in auto) then show ?thesis by simp qed lemma complex_norm_eq_1_exp_eq: "norm z = 1 \ exp(\ * (Arg z)) = z" by (metis Arg_eq exp_not_eq_zero exp_zero mult.left_neutral norm_zero of_real_1 norm_exp_i_times) lemma Arg_unique: "\of_real r * exp(\ * a) = z; 0 < r; -pi < a; a \ pi\ \ Arg z = a" by (rule Arg_unique_lemma [unfolded is_Arg_def, OF _ Arg_eq]) (use mpi_less_Arg Arg_le_pi in \auto simp: norm_mult\) lemma Arg_minus: assumes "z \ 0" shows "Arg (-z) = (if Arg z \ 0 then Arg z + pi else Arg z - pi)" proof - have [simp]: "cmod z * cos (Arg z) = Re z" using assms Arg_eq [of z] by (metis Re_exp exp_Ln norm_exp_eq_Re Arg_def) have [simp]: "cmod z * sin (Arg z) = Im z" using assms Arg_eq [of z] by (metis Im_exp exp_Ln norm_exp_eq_Re Arg_def) show ?thesis apply (rule Arg_unique [of "norm z", OF complex_eqI]) using mpi_less_Arg [of z] Arg_le_pi [of z] assms by (auto simp: Re_exp Im_exp) qed lemma Arg_times_of_real [simp]: assumes "0 < r" shows "Arg (of_real r * z) = Arg z" proof (cases "z=0") case True then show ?thesis by (simp add: Arg_def) next case False with Arg_eq assms show ?thesis by (auto simp: mpi_less_Arg Arg_le_pi intro!: Arg_unique [of "r * norm z"]) qed lemma Arg_times_of_real2 [simp]: "0 < r \ Arg (z * of_real r) = Arg z" by (metis Arg_times_of_real mult.commute) lemma Arg_divide_of_real [simp]: "0 < r \ Arg (z / of_real r) = Arg z" by (metis Arg_times_of_real2 less_numeral_extra(3) nonzero_eq_divide_eq of_real_eq_0_iff) lemma Arg_less_0: "0 \ Arg z \ 0 \ Im z" using Im_Ln_le_pi Im_Ln_pos_le by (simp add: Arg_def) lemma Arg_eq_pi: "Arg z = pi \ Re z < 0 \ Im z = 0" by (auto simp: Arg_def Im_Ln_eq_pi) lemma Arg_lt_pi: "0 < Arg z \ Arg z < pi \ 0 < Im z" using Arg_less_0 [of z] Im_Ln_pos_lt by (auto simp: order.order_iff_strict Arg_def) lemma Arg_eq_0: "Arg z = 0 \ z \ \ \ 0 \ Re z" using complex_is_Real_iff by (simp add: Arg_def Im_Ln_eq_0) (metis less_eq_real_def of_real_Re of_real_def scale_zero_left) corollary\<^marker>\tag unimportant\ Arg_ne_0: assumes "z \ \\<^sub>\\<^sub>0" shows "Arg z \ 0" using assms by (auto simp: nonneg_Reals_def Arg_eq_0) lemma Arg_eq_pi_iff: "Arg z = pi \ z \ \ \ Re z < 0" proof (cases "z=0") case False then show ?thesis using Arg_eq_0 [of "-z"] Arg_eq_pi complex_is_Real_iff by blast qed (simp add: Arg_def) lemma Arg_eq_0_pi: "Arg z = 0 \ Arg z = pi \ z \ \" using Arg_eq_pi_iff Arg_eq_0 by force lemma Arg_real: "z \ \ \ Arg z = (if 0 \ Re z then 0 else pi)" using Arg_eq_0 Arg_eq_0_pi by auto lemma Arg_inverse: "Arg(inverse z) = (if z \ \ then Arg z else - Arg z)" proof (cases "z \ \") case True then show ?thesis by simp (metis Arg2pi_inverse Arg2pi_real Arg_real Reals_inverse) next case False then have z: "Arg z < pi" "z \ 0" using Arg_eq_0_pi Arg_le_pi by (auto simp: less_eq_real_def) show ?thesis apply (rule Arg_unique [of "inverse (norm z)"]) using False z mpi_less_Arg [of z] Arg_eq [of z] by (auto simp: exp_minus field_simps) qed lemma Arg_eq_iff: assumes "w \ 0" "z \ 0" shows "Arg w = Arg z \ (\x. 0 < x \ w = of_real x * z)" (is "?lhs = ?rhs") proof assume ?lhs then have "w = complex_of_real (cmod w / cmod z) * z" by (metis Arg_eq assms divide_divide_eq_right eq_divide_eq exp_not_eq_zero of_real_divide) then show ?rhs using assms divide_pos_pos zero_less_norm_iff by blast qed auto lemma Arg_inverse_eq_0: "Arg(inverse z) = 0 \ Arg z = 0" by (metis Arg_eq_0 Arg_inverse inverse_inverse_eq) lemma Arg_cnj_eq_inverse: "z\0 \ Arg (cnj z) = Arg (inverse z)" using Arg2pi_cnj_eq_inverse Arg2pi_eq_iff Arg_eq_iff by auto lemma Arg_cnj: "Arg(cnj z) = (if z \ \ then Arg z else - Arg z)" by (metis Arg_cnj_eq_inverse Arg_inverse Reals_0 complex_cnj_zero) lemma Arg_exp: "-pi < Im z \ Im z \ pi \ Arg(exp z) = Im z" by (rule Arg_unique [of "exp(Re z)"]) (auto simp: exp_eq_polar) lemma Ln_Arg: "z\0 \ Ln(z) = ln(norm z) + \ * Arg(z)" by (metis Arg_def Re_Ln complex_eq) lemma continuous_at_Arg: assumes "z \ \\<^sub>\\<^sub>0" shows "continuous (at z) Arg" proof - have [simp]: "(\z. Im (Ln z)) \z\ Arg z" using Arg_def assms continuous_at by fastforce show ?thesis unfolding continuous_at proof (rule Lim_transform_within_open) show "\w. \w \ - \\<^sub>\\<^sub>0; w \ z\ \ Im (Ln w) = Arg w" by (metis Arg_def Compl_iff nonpos_Reals_zero_I) qed (use assms in auto) qed lemma continuous_within_Arg: "z \ \\<^sub>\\<^sub>0 \ continuous (at z within S) Arg" using continuous_at_Arg continuous_at_imp_continuous_within by blast subsection\The Unwinding Number and the Ln product Formula\ text\Note that in this special case the unwinding number is -1, 0 or 1. But it's always an integer.\ lemma is_Arg_exp_Im: "is_Arg (exp z) (Im z)" using exp_eq_polar is_Arg_def norm_exp_eq_Re by auto lemma is_Arg_exp_diff_2pi: assumes "is_Arg (exp z) \" shows "\k. Im z - of_int k * (2 * pi) = \" proof (intro exI is_Arg_eqI) let ?k = "\(Im z - \) / (2 * pi)\" show "is_Arg (exp z) (Im z - real_of_int ?k * (2 * pi))" by (metis diff_add_cancel is_Arg_2pi_iff is_Arg_exp_Im) show "\Im z - real_of_int ?k * (2 * pi) - \\ < 2 * pi" using floor_divide_upper [of "2*pi" "Im z - \"] floor_divide_lower [of "2*pi" "Im z - \"] by (auto simp: algebra_simps abs_if) qed (auto simp: is_Arg_exp_Im assms) lemma Arg_exp_diff_2pi: "\k. Im z - of_int k * (2 * pi) = Arg (exp z)" using is_Arg_exp_diff_2pi [OF is_Arg_Arg] by auto lemma unwinding_in_Ints: "(z - Ln(exp z)) / (of_real(2*pi) * \) \ \" using Arg_exp_diff_2pi [of z] by (force simp: Ints_def image_def field_simps Arg_def intro!: complex_eqI) definition\<^marker>\tag important\ unwinding :: "complex \ int" where "unwinding z \ THE k. of_int k = (z - Ln(exp z)) / (of_real(2*pi) * \)" lemma unwinding: "of_int (unwinding z) = (z - Ln(exp z)) / (of_real(2*pi) * \)" using unwinding_in_Ints [of z] unfolding unwinding_def Ints_def by force lemma unwinding_2pi: "(2*pi) * \ * unwinding(z) = z - Ln(exp z)" by (simp add: unwinding) lemma Ln_times_unwinding: "w \ 0 \ z \ 0 \ Ln(w * z) = Ln(w) + Ln(z) - (2*pi) * \ * unwinding(Ln w + Ln z)" using unwinding_2pi by (simp add: exp_add) lemma arg_conv_arctan: assumes "Re z > 0" shows "Arg z = arctan (Im z / Re z)" proof (rule cis_Arg_unique) show "sgn z = cis (arctan (Im z / Re z))" proof (rule complex_eqI) have "Re (cis (arctan (Im z / Re z))) = 1 / sqrt (1 + (Im z)\<^sup>2 / (Re z)\<^sup>2)" by (simp add: cos_arctan power_divide) also have "1 + Im z ^ 2 / Re z ^ 2 = norm z ^ 2 / Re z ^ 2" using assms by (simp add: cmod_def field_simps) also have "1 / sqrt \ = Re z / norm z" using assms by (simp add: real_sqrt_divide) finally show "Re (sgn z) = Re (cis (arctan (Im z / Re z)))" by simp next have "Im (cis (arctan (Im z / Re z))) = Im z / (Re z * sqrt (1 + (Im z)\<^sup>2 / (Re z)\<^sup>2))" by (simp add: sin_arctan field_simps) also have "1 + Im z ^ 2 / Re z ^ 2 = norm z ^ 2 / Re z ^ 2" using assms by (simp add: cmod_def field_simps) also have "Im z / (Re z * sqrt \) = Im z / norm z" using assms by (simp add: real_sqrt_divide) finally show "Im (sgn z) = Im (cis (arctan (Im z / Re z)))" by simp qed next show "arctan (Im z / Re z) > -pi" by (rule le_less_trans[OF _ arctan_lbound]) auto next have "arctan (Im z / Re z) < pi / 2" by (rule arctan_ubound) also have "\ \ pi" by simp finally show "arctan (Im z / Re z) \ pi" by simp qed subsection\<^marker>\tag unimportant\\Relation between Ln and Arg2pi, and hence continuity of Arg2pi\ lemma Arg2pi_Ln: assumes "0 < Arg2pi z" shows "Arg2pi z = Im(Ln(-z)) + pi" proof (cases "z = 0") case True with assms show ?thesis by simp next case False then have "z / of_real(norm z) = exp(\ * of_real(Arg2pi z))" using Arg2pi [of z] by (metis is_Arg_def abs_norm_cancel nonzero_mult_div_cancel_left norm_of_real zero_less_norm_iff) then have "- z / of_real(norm z) = exp (\ * (of_real (Arg2pi z) - pi))" using cis_conv_exp cis_pi by (auto simp: exp_diff algebra_simps) then have "ln (- z / of_real(norm z)) = ln (exp (\ * (of_real (Arg2pi z) - pi)))" by simp - also have "... = \ * (of_real(Arg2pi z) - pi)" + also have "\ = \ * (of_real(Arg2pi z) - pi)" using Arg2pi [of z] assms pi_not_less_zero by auto finally have "Arg2pi z = Im (Ln (- z / of_real (cmod z))) + pi" by simp - also have "... = Im (Ln (-z) - ln (cmod z)) + pi" + also have "\ = Im (Ln (-z) - ln (cmod z)) + pi" by (metis diff_0_right minus_diff_eq zero_less_norm_iff Ln_divide_of_real False) - also have "... = Im (Ln (-z)) + pi" + also have "\ = Im (Ln (-z)) + pi" by simp finally show ?thesis . qed lemma continuous_at_Arg2pi: assumes "z \ \\<^sub>\\<^sub>0" shows "continuous (at z) Arg2pi" proof - have *: "isCont (\z. Im (Ln (- z)) + pi) z" by (rule Complex.isCont_Im isCont_Ln' continuous_intros | simp add: assms complex_is_Real_iff)+ have [simp]: "Im x \ 0 \ Im (Ln (- x)) + pi = Arg2pi x" for x using Arg2pi_Ln by (simp add: Arg2pi_gt_0 complex_nonneg_Reals_iff) consider "Re z < 0" | "Im z \ 0" using assms using complex_nonneg_Reals_iff not_le by blast then have [simp]: "(\z. Im (Ln (- z)) + pi) \z\ Arg2pi z" using "*" by (simp add: Arg2pi_Ln Arg2pi_gt_0 assms continuous_within) show ?thesis unfolding continuous_at proof (rule Lim_transform_within_open) show "\x. \x \ - \\<^sub>\\<^sub>0; x \ z\ \ Im (Ln (- x)) + pi = Arg2pi x" by (auto simp add: Arg2pi_Ln [OF Arg2pi_gt_0] complex_nonneg_Reals_iff) qed (use assms in auto) qed text\Relation between Arg2pi and arctangent in upper halfplane\ lemma Arg2pi_arctan_upperhalf: assumes "0 < Im z" shows "Arg2pi z = pi/2 - arctan(Re z / Im z)" proof (cases "z = 0") case False show ?thesis proof (rule Arg2pi_unique [of "norm z"]) show "(cmod z) * exp (\ * (pi / 2 - arctan (Re z / Im z))) = z" apply (rule complex_eqI) using assms norm_complex_def [of z, symmetric] unfolding exp_Euler cos_diff sin_diff sin_of_real cos_of_real by (simp_all add: field_simps real_sqrt_divide sin_arctan cos_arctan) qed (use False arctan [of "Re z / Im z"] in auto) qed (use assms in auto) lemma Arg2pi_eq_Im_Ln: assumes "0 \ Im z" "0 < Re z" shows "Arg2pi z = Im (Ln z)" proof (cases "Im z = 0") case True then show ?thesis using Arg2pi_eq_0 Ln_in_Reals assms(2) complex_is_Real_iff by auto next case False then have *: "Arg2pi z > 0" using Arg2pi_gt_0 complex_is_Real_iff by blast then have "z \ 0" by auto with * assms False show ?thesis by (subst Arg2pi_Ln) (auto simp: Ln_minus) qed lemma continuous_within_upperhalf_Arg2pi: assumes "z \ 0" shows "continuous (at z within {z. 0 \ Im z}) Arg2pi" proof (cases "z \ \\<^sub>\\<^sub>0") case False then show ?thesis using continuous_at_Arg2pi continuous_at_imp_continuous_within by auto next case True then have z: "z \ \" "0 < Re z" using assms by (auto simp: complex_nonneg_Reals_iff complex_is_Real_iff complex_neq_0) then have [simp]: "Arg2pi z = 0" "Im (Ln z) = 0" by (auto simp: Arg2pi_eq_0 Im_Ln_eq_0 assms complex_is_Real_iff) show ?thesis proof (clarsimp simp add: continuous_within Lim_within dist_norm) fix e::real assume "0 < e" moreover have "continuous (at z) (\x. Im (Ln x))" using z by (simp add: continuous_at_Ln complex_nonpos_Reals_iff) ultimately obtain d where d: "d>0" "\x. x \ z \ cmod (x - z) < d \ \Im (Ln x)\ < e" by (auto simp: continuous_within Lim_within dist_norm) { fix x assume "cmod (x - z) < Re z / 2" then have "\Re x - Re z\ < Re z / 2" by (metis le_less_trans abs_Re_le_cmod minus_complex.simps(1)) then have "0 < Re x" using z by linarith } then show "\d>0. \x. 0 \ Im x \ x \ z \ cmod (x - z) < d \ \Arg2pi x\ < e" apply (rule_tac x="min d (Re z / 2)" in exI) using z d by (auto simp: Arg2pi_eq_Im_Ln) qed qed lemma continuous_on_upperhalf_Arg2pi: "continuous_on ({z. 0 \ Im z} - {0}) Arg2pi" unfolding continuous_on_eq_continuous_within by (metis DiffE Diff_subset continuous_within_subset continuous_within_upperhalf_Arg2pi insertCI) lemma open_Arg2pi2pi_less_Int: assumes "0 \ s" "t \ 2*pi" shows "open ({y. s < Arg2pi y} \ {y. Arg2pi y < t})" proof - have 1: "continuous_on (UNIV - \\<^sub>\\<^sub>0) Arg2pi" using continuous_at_Arg2pi continuous_at_imp_continuous_within by (auto simp: continuous_on_eq_continuous_within) have 2: "open (UNIV - \\<^sub>\\<^sub>0 :: complex set)" by (simp add: open_Diff) have "open ({z. s < z} \ {z. z < t})" using open_lessThan [of t] open_greaterThan [of s] by (metis greaterThan_def lessThan_def open_Int) moreover have "{y. s < Arg2pi y} \ {y. Arg2pi y < t} \ - \\<^sub>\\<^sub>0" using assms by (auto simp: Arg2pi_real complex_nonneg_Reals_iff complex_is_Real_iff) ultimately show ?thesis using continuous_imp_open_vimage [OF 1 2, of "{z. Re z > s} \ {z. Re z < t}"] by auto qed lemma open_Arg2pi2pi_gt: "open {z. t < Arg2pi z}" proof (cases "t < 0") case True then have "{z. t < Arg2pi z} = UNIV" using Arg2pi_ge_0 less_le_trans by auto then show ?thesis by simp next case False then show ?thesis using open_Arg2pi2pi_less_Int [of t "2*pi"] Arg2pi_lt_2pi by auto qed lemma closed_Arg2pi2pi_le: "closed {z. Arg2pi z \ t}" using open_Arg2pi2pi_gt [of t] by (simp add: closed_def Set.Collect_neg_eq [symmetric] not_le) subsection\<^marker>\tag unimportant\\Complex Powers\ lemma powr_to_1 [simp]: "z powr 1 = (z::complex)" by (simp add: powr_def) lemma powr_nat: fixes n::nat and z::complex shows "z powr n = (if z = 0 then 0 else z^n)" by (simp add: exp_of_nat_mult powr_def) lemma norm_powr_real: "w \ \ \ 0 < Re w \ norm(w powr z) = exp(Re z * ln(Re w))" using Ln_Reals_eq norm_exp_eq_Re by (auto simp: Im_Ln_eq_0 powr_def norm_complex_def) lemma powr_complexpow [simp]: fixes x::complex shows "x \ 0 \ x powr (of_nat n) = x^n" by (induct n) (auto simp: ac_simps powr_add) lemma powr_complexnumeral [simp]: fixes x::complex shows "x powr (numeral n) = x ^ (numeral n)" by (metis of_nat_numeral power_zero_numeral powr_nat) lemma cnj_powr: assumes "Im a = 0 \ Re a \ 0" shows "cnj (a powr b) = cnj a powr cnj b" proof (cases "a = 0") case False with assms have "a \ \\<^sub>\\<^sub>0" by (auto simp: complex_eq_iff complex_nonpos_Reals_iff) with False show ?thesis by (simp add: powr_def exp_cnj cnj_Ln) qed simp lemma powr_real_real: assumes "w \ \" "z \ \" "0 < Re w" shows "w powr z = exp(Re z * ln(Re w))" proof - have "w \ 0" using assms by auto with assms show ?thesis by (simp add: powr_def Ln_Reals_eq of_real_exp) qed lemma powr_of_real: fixes x::real and y::real shows "0 \ x \ of_real x powr (of_real y::complex) = of_real (x powr y)" by (simp_all add: powr_def exp_eq_polar) lemma powr_of_int: fixes z::complex and n::int assumes "z\(0::complex)" shows "z powr of_int n = (if n\0 then z^nat n else inverse (z^nat (-n)))" by (metis assms not_le of_int_of_nat powr_complexpow powr_minus) lemma powr_Reals_eq: "\x \ \; y \ \; Re x \ 0\ \ x powr y = of_real (Re x powr Re y)" by (metis of_real_Re powr_of_real) lemma norm_powr_real_mono: "\w \ \; 1 < Re w\ \ cmod(w powr z1) \ cmod(w powr z2) \ Re z1 \ Re z2" by (auto simp: powr_def algebra_simps Reals_def Ln_of_real) lemma powr_times_real: "\x \ \; y \ \; 0 \ Re x; 0 \ Re y\ \ (x * y) powr z = x powr z * y powr z" by (auto simp: Reals_def powr_def Ln_times exp_add algebra_simps less_eq_real_def Ln_of_real) lemma Re_powr_le: "r \ \\<^sub>\\<^sub>0 \ Re (r powr z) \ Re r powr Re z" by (auto simp: powr_def nonneg_Reals_def order_trans [OF complex_Re_le_cmod]) lemma fixes w::complex shows Reals_powr [simp]: "\w \ \\<^sub>\\<^sub>0; z \ \\ \ w powr z \ \" and nonneg_Reals_powr [simp]: "\w \ \\<^sub>\\<^sub>0; z \ \\ \ w powr z \ \\<^sub>\\<^sub>0" by (auto simp: nonneg_Reals_def Reals_def powr_of_real) lemma powr_neg_real_complex: "(- of_real x) powr a = (-1) powr (of_real (sgn x) * a) * of_real x powr (a :: complex)" proof (cases "x = 0") assume x: "x \ 0" hence "(-x) powr a = exp (a * ln (-of_real x))" by (simp add: powr_def) also from x have "ln (-of_real x) = Ln (of_real x) + of_real (sgn x) * pi * \" by (simp add: Ln_minus Ln_of_real) - also from x have "exp (a * ...) = cis pi powr (of_real (sgn x) * a) * of_real x powr a" + also from x have "exp (a * \) = cis pi powr (of_real (sgn x) * a) * of_real x powr a" by (simp add: powr_def exp_add algebra_simps Ln_of_real cis_conv_exp) also note cis_pi finally show ?thesis by simp qed simp_all lemma has_field_derivative_powr: fixes z :: complex assumes "z \ \\<^sub>\\<^sub>0" shows "((\z. z powr s) has_field_derivative (s * z powr (s - 1))) (at z)" proof (cases "z=0") case False then have \
: "exp (s * Ln z) * inverse z = exp ((s - 1) * Ln z)" by (simp add: divide_complex_def exp_diff left_diff_distrib') show ?thesis unfolding powr_def proof (rule has_field_derivative_transform_within) show "((\z. exp (s * Ln z)) has_field_derivative s * (if z = 0 then 0 else exp ((s - 1) * Ln z))) (at z)" by (intro derivative_eq_intros | simp add: assms False \
)+ qed (use False in auto) qed (use assms in auto) declare has_field_derivative_powr[THEN DERIV_chain2, derivative_intros] lemma has_field_derivative_powr_of_int: fixes z :: complex assumes gderiv:"(g has_field_derivative gd) (at z within S)" and "g z\0" shows "((\z. g z powr of_int n) has_field_derivative (n * g z powr (of_int n - 1) * gd)) (at z within S)" proof - define dd where "dd = of_int n * g z powr (of_int (n - 1)) * gd" obtain e where "e>0" and e_dist:"\y\S. dist z y < e \ g y \ 0" using DERIV_continuous[OF gderiv,THEN continuous_within_avoid] \g z\0\ by auto have ?thesis when "n\0" proof - define dd' where "dd' = of_int n * g z ^ (nat n - 1) * gd" have "dd=dd'" proof (cases "n=0") case False then have "n-1 \0" using \n\0\ by auto then have "g z powr (of_int (n - 1)) = g z ^ (nat n - 1)" using powr_of_int[OF \g z\0\,of "n-1"] by (simp add: nat_diff_distrib') then show ?thesis unfolding dd_def dd'_def by simp qed (simp add:dd_def dd'_def) then have "((\z. g z powr of_int n) has_field_derivative dd) (at z within S) \ ((\z. g z powr of_int n) has_field_derivative dd') (at z within S)" by simp - also have "... \ ((\z. g z ^ nat n) has_field_derivative dd') (at z within S)" + also have "\ \ ((\z. g z ^ nat n) has_field_derivative dd') (at z within S)" proof (rule has_field_derivative_cong_eventually) show "\\<^sub>F x in at z within S. g x powr of_int n = g x ^ nat n" unfolding eventually_at apply (rule exI[where x=e]) using powr_of_int that \e>0\ e_dist by (simp add: dist_commute) qed (use powr_of_int \g z\0\ that in simp) - also have "..." unfolding dd'_def using gderiv that + also have "\" unfolding dd'_def using gderiv that by (auto intro!: derivative_eq_intros) finally have "((\z. g z powr of_int n) has_field_derivative dd) (at z within S)" . then show ?thesis unfolding dd_def by simp qed moreover have ?thesis when "n<0" proof - define dd' where "dd' = of_int n / g z ^ (nat (1 - n)) * gd" have "dd=dd'" proof - have "g z powr of_int (n - 1) = inverse (g z ^ nat (1-n))" using powr_of_int[OF \g z\0\,of "n-1"] that by auto then show ?thesis unfolding dd_def dd'_def by (simp add: divide_inverse) qed then have "((\z. g z powr of_int n) has_field_derivative dd) (at z within S) \ ((\z. g z powr of_int n) has_field_derivative dd') (at z within S)" by simp - also have "... \ ((\z. inverse (g z ^ nat (-n))) has_field_derivative dd') (at z within S)" + also have "\ \ ((\z. inverse (g z ^ nat (-n))) has_field_derivative dd') (at z within S)" proof (rule has_field_derivative_cong_eventually) show "\\<^sub>F x in at z within S. g x powr of_int n = inverse (g x ^ nat (- n))" unfolding eventually_at apply (rule exI[where x=e]) using powr_of_int that \e>0\ e_dist by (simp add: dist_commute) qed (use powr_of_int \g z\0\ that in simp) - also have "..." + also have "\" proof - have "nat (- n) + nat (1 - n) - Suc 0 = nat (- n) + nat (- n)" by auto then show ?thesis unfolding dd'_def using gderiv that \g z\0\ by (auto intro!: derivative_eq_intros simp add:field_split_simps power_add[symmetric]) qed finally have "((\z. g z powr of_int n) has_field_derivative dd) (at z within S)" . then show ?thesis unfolding dd_def by simp qed ultimately show ?thesis by force qed lemma field_differentiable_powr_of_int: fixes z :: complex assumes gderiv: "g field_differentiable (at z within S)" and "g z \ 0" shows "(\z. g z powr of_int n) field_differentiable (at z within S)" using has_field_derivative_powr_of_int assms(2) field_differentiable_def gderiv by blast lemma holomorphic_on_powr_of_int [holomorphic_intros]: assumes holf: "f holomorphic_on S" and 0: "\z. z\S \ f z \ 0" shows "(\z. (f z) powr of_int n) holomorphic_on S" proof (cases "n\0") case True then have "?thesis \ (\z. (f z) ^ nat n) holomorphic_on S" by (metis (no_types, lifting) 0 holomorphic_cong powr_of_int) moreover have "(\z. (f z) ^ nat n) holomorphic_on S" using holf by (auto intro: holomorphic_intros) ultimately show ?thesis by auto next case False then have "?thesis \ (\z. inverse (f z) ^ nat (-n)) holomorphic_on S" by (metis (no_types, lifting) "0" holomorphic_cong power_inverse powr_of_int) moreover have "(\z. inverse (f z) ^ nat (-n)) holomorphic_on S" using assms by (auto intro!:holomorphic_intros) ultimately show ?thesis by auto qed lemma has_field_derivative_powr_right [derivative_intros]: "w \ 0 \ ((\z. w powr z) has_field_derivative Ln w * w powr z) (at z)" unfolding powr_def by (intro derivative_eq_intros | simp)+ lemma field_differentiable_powr_right [derivative_intros]: fixes w::complex shows "w \ 0 \ (\z. w powr z) field_differentiable (at z)" using field_differentiable_def has_field_derivative_powr_right by blast lemma holomorphic_on_powr_right [holomorphic_intros]: assumes "f holomorphic_on s" shows "(\z. w powr (f z)) holomorphic_on s" proof (cases "w = 0") case False with assms show ?thesis unfolding holomorphic_on_def field_differentiable_def by (metis (full_types) DERIV_chain' has_field_derivative_powr_right) qed simp lemma holomorphic_on_divide_gen [holomorphic_intros]: assumes f: "f holomorphic_on s" and g: "g holomorphic_on s" and 0: "\z z'. \z \ s; z' \ s\ \ g z = 0 \ g z' = 0" shows "(\z. f z / g z) holomorphic_on s" proof (cases "\z\s. g z = 0") case True with 0 have "g z = 0" if "z \ s" for z using that by blast then show ?thesis using g holomorphic_transform by auto next case False with 0 have "g z \ 0" if "z \ s" for z using that by blast with holomorphic_on_divide show ?thesis using f g by blast qed lemma norm_powr_real_powr: "w \ \ \ 0 \ Re w \ cmod (w powr z) = Re w powr Re z" by (metis dual_order.order_iff_strict norm_powr_real norm_zero of_real_0 of_real_Re powr_def) lemma tendsto_powr_complex: fixes f g :: "_ \ complex" assumes a: "a \ \\<^sub>\\<^sub>0" assumes f: "(f \ a) F" and g: "(g \ b) F" shows "((\z. f z powr g z) \ a powr b) F" proof - from a have [simp]: "a \ 0" by auto from f g a have "((\z. exp (g z * ln (f z))) \ a powr b) F" (is ?P) by (auto intro!: tendsto_intros simp: powr_def) also { have "eventually (\z. z \ 0) (nhds a)" by (intro t1_space_nhds) simp_all with f have "eventually (\z. f z \ 0) F" using filterlim_iff by blast } hence "?P \ ((\z. f z powr g z) \ a powr b) F" by (intro tendsto_cong refl) (simp_all add: powr_def mult_ac) finally show ?thesis . qed lemma tendsto_powr_complex_0: fixes f g :: "'a \ complex" assumes f: "(f \ 0) F" and g: "(g \ b) F" and b: "Re b > 0" shows "((\z. f z powr g z) \ 0) F" proof (rule tendsto_norm_zero_cancel) define h where "h = (\z. if f z = 0 then 0 else exp (Re (g z) * ln (cmod (f z)) + abs (Im (g z)) * pi))" { fix z :: 'a assume z: "f z \ 0" define c where "c = abs (Im (g z)) * pi" from mpi_less_Im_Ln[OF z] Im_Ln_le_pi[OF z] have "abs (Im (Ln (f z))) \ pi" by simp from mult_left_mono[OF this, of "abs (Im (g z))"] have "abs (Im (g z) * Im (ln (f z))) \ c" by (simp add: abs_mult c_def) hence "-Im (g z) * Im (ln (f z)) \ c" by simp hence "norm (f z powr g z) \ h z" by (simp add: powr_def field_simps h_def c_def) } hence le: "norm (f z powr g z) \ h z" for z by (cases "f x = 0") (simp_all add: h_def) have g': "(g \ b) (inf F (principal {z. f z \ 0}))" by (rule tendsto_mono[OF _ g]) simp_all have "((\x. norm (f x)) \ 0) (inf F (principal {z. f z \ 0}))" by (subst tendsto_norm_zero_iff, rule tendsto_mono[OF _ f]) simp_all moreover { have "filterlim (\x. norm (f x)) (principal {0<..}) (principal {z. f z \ 0})" by (auto simp: filterlim_def) hence "filterlim (\x. norm (f x)) (principal {0<..}) (inf F (principal {z. f z \ 0}))" by (rule filterlim_mono) simp_all } ultimately have norm: "filterlim (\x. norm (f x)) (at_right 0) (inf F (principal {z. f z \ 0}))" by (simp add: filterlim_inf at_within_def) have A: "LIM x inf F (principal {z. f z \ 0}). Re (g x) * -ln (cmod (f x)) :> at_top" by (rule filterlim_tendsto_pos_mult_at_top tendsto_intros g' b filterlim_compose[OF filterlim_uminus_at_top_at_bot] filterlim_compose[OF ln_at_0] norm)+ have B: "LIM x inf F (principal {z. f z \ 0}). -\Im (g x)\ * pi + -(Re (g x) * ln (cmod (f x))) :> at_top" by (rule filterlim_tendsto_add_at_top tendsto_intros g')+ (insert A, simp_all) have C: "(h \ 0) F" unfolding h_def by (intro filterlim_If tendsto_const filterlim_compose[OF exp_at_bot]) (insert B, auto simp: filterlim_uminus_at_bot algebra_simps) show "((\x. norm (f x powr g x)) \ 0) F" by (rule Lim_null_comparison[OF always_eventually C]) (insert le, auto) qed lemma tendsto_powr_complex' [tendsto_intros]: fixes f g :: "_ \ complex" assumes "a \ \\<^sub>\\<^sub>0 \ (a = 0 \ Re b > 0)" and "(f \ a) F" "(g \ b) F" shows "((\z. f z powr g z) \ a powr b) F" using assms tendsto_powr_complex tendsto_powr_complex_0 by fastforce lemma tendsto_neg_powr_complex_of_real: assumes "filterlim f at_top F" and "Re s < 0" shows "((\x. complex_of_real (f x) powr s) \ 0) F" proof - have "((\x. norm (complex_of_real (f x) powr s)) \ 0) F" proof (rule Lim_transform_eventually) from assms(1) have "eventually (\x. f x \ 0) F" by (auto simp: filterlim_at_top) thus "eventually (\x. f x powr Re s = norm (of_real (f x) powr s)) F" by eventually_elim (simp add: norm_powr_real_powr) from assms show "((\x. f x powr Re s) \ 0) F" by (intro tendsto_neg_powr) qed thus ?thesis by (simp add: tendsto_norm_zero_iff) qed lemma tendsto_neg_powr_complex_of_nat: assumes "filterlim f at_top F" and "Re s < 0" shows "((\x. of_nat (f x) powr s) \ 0) F" proof - have "((\x. of_real (real (f x)) powr s) \ 0) F" using assms(2) by (intro filterlim_compose[OF _ tendsto_neg_powr_complex_of_real] filterlim_compose[OF _ assms(1)] filterlim_real_sequentially filterlim_ident) auto thus ?thesis by simp qed lemma continuous_powr_complex: assumes "f (netlimit F) \ \\<^sub>\\<^sub>0" "continuous F f" "continuous F g" shows "continuous F (\z. f z powr g z :: complex)" using assms unfolding continuous_def by (intro tendsto_powr_complex) simp_all lemma isCont_powr_complex [continuous_intros]: assumes "f z \ \\<^sub>\\<^sub>0" "isCont f z" "isCont g z" shows "isCont (\z. f z powr g z :: complex) z" using assms unfolding isCont_def by (intro tendsto_powr_complex) simp_all lemma continuous_on_powr_complex [continuous_intros]: assumes "A \ {z. Re (f z) \ 0 \ Im (f z) \ 0}" assumes "\z. z \ A \ f z = 0 \ Re (g z) > 0" assumes "continuous_on A f" "continuous_on A g" shows "continuous_on A (\z. f z powr g z)" unfolding continuous_on_def proof fix z assume z: "z \ A" show "((\z. f z powr g z) \ f z powr g z) (at z within A)" proof (cases "f z = 0") case False from assms(1,2) z have "Re (f z) \ 0 \ Im (f z) \ 0" "f z = 0 \ Re (g z) > 0" by auto with assms(3,4) z show ?thesis by (intro tendsto_powr_complex') (auto elim!: nonpos_Reals_cases simp: complex_eq_iff continuous_on_def) next case True with assms z show ?thesis by (auto intro!: tendsto_powr_complex_0 simp: continuous_on_def) qed qed subsection\<^marker>\tag unimportant\\Some Limits involving Logarithms\ lemma lim_Ln_over_power: fixes s::complex assumes "0 < Re s" shows "(\n. Ln (of_nat n) / of_nat n powr s) \ 0" proof (simp add: lim_sequentially dist_norm, clarify) fix e::real assume e: "0 < e" have "\xo>0. \x\xo. 0 < e * 2 + (e * Re s * 2 - 2) * x + e * (Re s)\<^sup>2 * x\<^sup>2" proof (rule_tac x="2/(e * (Re s)\<^sup>2)" in exI, safe) show "0 < 2 / (e * (Re s)\<^sup>2)" using e assms by (simp add: field_simps) next fix x::real assume x: "2 / (e * (Re s)\<^sup>2) \ x" have "2 / (e * (Re s)\<^sup>2) > 0" using e assms by simp with x have "x > 0" by linarith then have "x * 2 \ e * (x\<^sup>2 * (Re s)\<^sup>2)" using e assms x by (auto simp: power2_eq_square field_simps) - also have "... < e * (2 + (x * (Re s * 2) + x\<^sup>2 * (Re s)\<^sup>2))" + also have "\ < e * (2 + (x * (Re s * 2) + x\<^sup>2 * (Re s)\<^sup>2))" using e assms \x > 0\ by (auto simp: power2_eq_square field_simps add_pos_pos) finally show "0 < e * 2 + (e * Re s * 2 - 2) * x + e * (Re s)\<^sup>2 * x\<^sup>2" by (auto simp: algebra_simps) qed then have "\xo>0. \x\xo. x / e < 1 + (Re s * x) + (1/2) * (Re s * x)^2" using e by (simp add: field_simps) then have "\xo>0. \x\xo. x / e < exp (Re s * x)" using assms by (force intro: less_le_trans [OF _ exp_lower_Taylor_quadratic]) then obtain xo where "xo > 0" and xo: "\x. x \ xo \ x < e * exp (Re s * x)" using e by (auto simp: field_simps) have "norm (Ln (of_nat n) / of_nat n powr s) < e" if "n \ nat \exp xo\" for n proof - have "ln (real n) \ xo" using that exp_gt_zero ln_ge_iff [of n] nat_ceiling_le_eq by fastforce then show ?thesis using e xo [of "ln n"] by (auto simp: norm_divide norm_powr_real field_split_simps) qed then show "\no. \n\no. norm (Ln (of_nat n) / of_nat n powr s) < e" by blast qed lemma lim_Ln_over_n: "((\n. Ln(of_nat n) / of_nat n) \ 0) sequentially" using lim_Ln_over_power [of 1] by simp lemma lim_ln_over_power: fixes s :: real assumes "0 < s" shows "((\n. ln n / (n powr s)) \ 0) sequentially" proof - have "(\n. ln (Suc n) / (Suc n) powr s) \ 0" using lim_Ln_over_power [of "of_real s", THEN filterlim_sequentially_Suc [THEN iffD2]] assms by (simp add: lim_sequentially dist_norm Ln_Reals_eq norm_powr_real_powr norm_divide) then show ?thesis using filterlim_sequentially_Suc[of "\n::nat. ln n / n powr s"] by auto qed lemma lim_ln_over_n [tendsto_intros]: "((\n. ln(real_of_nat n) / of_nat n) \ 0) sequentially" using lim_ln_over_power [of 1] by auto lemma lim_log_over_n [tendsto_intros]: "(\n. log k n/n) \ 0" proof - have *: "log k n/n = (1/ln k) * (ln n / n)" for n unfolding log_def by auto have "(\n. (1/ln k) * (ln n / n)) \ (1/ln k) * 0" by (intro tendsto_intros) then show ?thesis unfolding * by auto qed lemma lim_1_over_complex_power: assumes "0 < Re s" shows "(\n. 1 / of_nat n powr s) \ 0" proof (rule Lim_null_comparison) have "\n>0. 3 \ n \ 1 \ ln (real_of_nat n)" using ln_272_gt_1 by (force intro: order_trans [of _ "ln (272/100)"]) then show "\\<^sub>F x in sequentially. cmod (1 / of_nat x powr s) \ cmod (Ln (of_nat x) / of_nat x powr s)" by (auto simp: norm_divide field_split_simps eventually_sequentially) show "(\n. cmod (Ln (of_nat n) / of_nat n powr s)) \ 0" using lim_Ln_over_power [OF assms] by (metis tendsto_norm_zero_iff) qed lemma lim_1_over_real_power: fixes s :: real assumes "0 < s" shows "((\n. 1 / (of_nat n powr s)) \ 0) sequentially" using lim_1_over_complex_power [of "of_real s", THEN filterlim_sequentially_Suc [THEN iffD2]] assms apply (subst filterlim_sequentially_Suc [symmetric]) by (simp add: lim_sequentially dist_norm Ln_Reals_eq norm_powr_real_powr norm_divide) lemma lim_1_over_Ln: "((\n. 1 / Ln(of_nat n)) \ 0) sequentially" proof (clarsimp simp add: lim_sequentially dist_norm norm_divide field_split_simps) fix r::real assume "0 < r" have ir: "inverse (exp (inverse r)) > 0" by simp obtain n where n: "1 < of_nat n * inverse (exp (inverse r))" using ex_less_of_nat_mult [of _ 1, OF ir] by auto then have "exp (inverse r) < of_nat n" by (simp add: field_split_simps) then have "ln (exp (inverse r)) < ln (of_nat n)" by (metis exp_gt_zero less_trans ln_exp ln_less_cancel_iff) with \0 < r\ have "1 < r * ln (real_of_nat n)" by (simp add: field_simps) moreover have "n > 0" using n using neq0_conv by fastforce ultimately show "\no. \k. Ln (of_nat k) \ 0 \ no \ k \ 1 < r * cmod (Ln (of_nat k))" using n \0 < r\ by (rule_tac x=n in exI) (force simp: field_split_simps intro: less_le_trans) qed lemma lim_1_over_ln: "((\n. 1 / ln(real_of_nat n)) \ 0) sequentially" using lim_1_over_Ln [THEN filterlim_sequentially_Suc [THEN iffD2]] apply (subst filterlim_sequentially_Suc [symmetric]) by (simp add: lim_sequentially dist_norm Ln_Reals_eq norm_powr_real_powr norm_divide) lemma lim_ln1_over_ln: "(\n. ln(Suc n) / ln n) \ 1" proof (rule Lim_transform_eventually) have "(\n. ln(1 + 1/n) / ln n) \ 0" proof (rule Lim_transform_bound) show "(inverse o real) \ 0" by (metis comp_def lim_inverse_n lim_explicit) show "\\<^sub>F n in sequentially. norm (ln (1 + 1 / n) / ln n) \ norm ((inverse \ real) n)" proof fix n::nat assume n: "3 \ n" then have "ln 3 \ ln n" and ln0: "0 \ ln n" by auto with ln3_gt_1 have "1/ ln n \ 1" by (simp add: field_split_simps) moreover have "ln (1 + 1 / real n) \ 1/n" by (simp add: ln_add_one_self_le_self) ultimately have "ln (1 + 1 / real n) * (1 / ln n) \ (1/n) * 1" by (intro mult_mono) (use n in auto) then show "norm (ln (1 + 1 / n) / ln n) \ norm ((inverse \ real) n)" by (simp add: field_simps ln0) qed qed then show "(\n. 1 + ln(1 + 1/n) / ln n) \ 1" by (metis (full_types) add.right_neutral tendsto_add_const_iff) show "\\<^sub>F k in sequentially. 1 + ln (1 + 1 / k) / ln k = ln(Suc k) / ln k" by (simp add: field_split_simps ln_div eventually_sequentiallyI [of 2]) qed lemma lim_ln_over_ln1: "(\n. ln n / ln(Suc n)) \ 1" proof - have "(\n. inverse (ln(Suc n) / ln n)) \ inverse 1" by (rule tendsto_inverse [OF lim_ln1_over_ln]) auto then show ?thesis by simp qed subsection\<^marker>\tag unimportant\\Relation between Square Root and exp/ln, hence its derivative\ lemma csqrt_exp_Ln: assumes "z \ 0" shows "csqrt z = exp(Ln(z) / 2)" proof - have "(exp (Ln z / 2))\<^sup>2 = (exp (Ln z))" by (metis exp_double nonzero_mult_div_cancel_left times_divide_eq_right zero_neq_numeral) - also have "... = z" + also have "\ = z" using assms exp_Ln by blast finally have "csqrt z = csqrt ((exp (Ln z / 2))\<^sup>2)" by simp - also have "... = exp (Ln z / 2)" + also have "\ = exp (Ln z / 2)" apply (rule csqrt_square) using cos_gt_zero_pi [of "(Im (Ln z) / 2)"] Im_Ln_le_pi mpi_less_Im_Ln assms by (fastforce simp: Re_exp Im_exp ) finally show ?thesis using assms csqrt_square by simp qed lemma csqrt_inverse: assumes "z \ \\<^sub>\\<^sub>0" shows "csqrt (inverse z) = inverse (csqrt z)" proof (cases "z=0") case False then show ?thesis using assms csqrt_exp_Ln Ln_inverse exp_minus by (simp add: csqrt_exp_Ln Ln_inverse exp_minus) qed auto lemma cnj_csqrt: assumes "z \ \\<^sub>\\<^sub>0" shows "cnj(csqrt z) = csqrt(cnj z)" proof (cases "z=0") case False then show ?thesis by (simp add: assms cnj_Ln csqrt_exp_Ln exp_cnj) qed auto lemma has_field_derivative_csqrt: assumes "z \ \\<^sub>\\<^sub>0" shows "(csqrt has_field_derivative inverse(2 * csqrt z)) (at z)" proof - have z: "z \ 0" using assms by auto then have *: "inverse z = inverse (2*z) * 2" by (simp add: field_split_simps) have [simp]: "exp (Ln z / 2) * inverse z = inverse (csqrt z)" by (simp add: z field_simps csqrt_exp_Ln [symmetric]) (metis power2_csqrt power2_eq_square) have "Im z = 0 \ 0 < Re z" using assms complex_nonpos_Reals_iff not_less by blast with z have "((\z. exp (Ln z / 2)) has_field_derivative inverse (2 * csqrt z)) (at z)" by (force intro: derivative_eq_intros * simp add: assms) then show ?thesis proof (rule has_field_derivative_transform_within) show "\x. dist x z < cmod z \ exp (Ln x / 2) = csqrt x" by (metis csqrt_exp_Ln dist_0_norm less_irrefl) qed (use z in auto) qed lemma field_differentiable_at_csqrt: "z \ \\<^sub>\\<^sub>0 \ csqrt field_differentiable at z" using field_differentiable_def has_field_derivative_csqrt by blast lemma field_differentiable_within_csqrt: "z \ \\<^sub>\\<^sub>0 \ csqrt field_differentiable (at z within s)" using field_differentiable_at_csqrt field_differentiable_within_subset by blast lemma continuous_at_csqrt: "z \ \\<^sub>\\<^sub>0 \ continuous (at z) csqrt" by (simp add: field_differentiable_within_csqrt field_differentiable_imp_continuous_at) corollary\<^marker>\tag unimportant\ isCont_csqrt' [simp]: "\isCont f z; f z \ \\<^sub>\\<^sub>0\ \ isCont (\x. csqrt (f x)) z" by (blast intro: isCont_o2 [OF _ continuous_at_csqrt]) lemma continuous_within_csqrt: "z \ \\<^sub>\\<^sub>0 \ continuous (at z within s) csqrt" by (simp add: field_differentiable_imp_continuous_at field_differentiable_within_csqrt) lemma continuous_on_csqrt [continuous_intros]: "(\z. z \ s \ z \ \\<^sub>\\<^sub>0) \ continuous_on s csqrt" by (simp add: continuous_at_imp_continuous_on continuous_within_csqrt) lemma holomorphic_on_csqrt: "(\z. z \ s \ z \ \\<^sub>\\<^sub>0) \ csqrt holomorphic_on s" by (simp add: field_differentiable_within_csqrt holomorphic_on_def) lemma continuous_within_closed_nontrivial: "closed s \ a \ s ==> continuous (at a within s) f" using open_Compl by (force simp add: continuous_def eventually_at_topological filterlim_iff open_Collect_neg) lemma continuous_within_csqrt_posreal: "continuous (at z within (\ \ {w. 0 \ Re(w)})) csqrt" proof (cases "z \ \\<^sub>\\<^sub>0") case True have [simp]: "Im z = 0" and 0: "Re z < 0 \ z = 0" using True cnj.code complex_cnj_zero_iff by (auto simp: Complex_eq complex_nonpos_Reals_iff) fastforce show ?thesis using 0 proof assume "Re z < 0" then show ?thesis by (auto simp: continuous_within_closed_nontrivial [OF closed_Real_halfspace_Re_ge]) next assume "z = 0" moreover have "\e. 0 < e \ \x'\\ \ {w. 0 \ Re w}. cmod x' < e^2 \ cmod (csqrt x') < e" by (auto simp: Reals_def real_less_lsqrt) ultimately show ?thesis using zero_less_power by (fastforce simp: continuous_within_eps_delta) qed qed (blast intro: continuous_within_csqrt) subsection\Complex arctangent\ text\The branch cut gives standard bounds in the real case.\ definition\<^marker>\tag important\ Arctan :: "complex \ complex" where "Arctan \ \z. (\/2) * Ln((1 - \*z) / (1 + \*z))" lemma Arctan_def_moebius: "Arctan z = \/2 * Ln (moebius (-\) 1 \ 1 z)" by (simp add: Arctan_def moebius_def add_ac) lemma Ln_conv_Arctan: assumes "z \ -1" shows "Ln z = -2*\ * Arctan (moebius 1 (- 1) (- \) (- \) z)" proof - have "Arctan (moebius 1 (- 1) (- \) (- \) z) = \/2 * Ln (moebius (- \) 1 \ 1 (moebius 1 (- 1) (- \) (- \) z))" by (simp add: Arctan_def_moebius) also from assms have "\ * z \ \ * (-1)" by (subst mult_left_cancel) simp hence "\ * z - -\ \ 0" by (simp add: eq_neg_iff_add_eq_0) from moebius_inverse'[OF _ this, of 1 1] have "moebius (- \) 1 \ 1 (moebius 1 (- 1) (- \) (- \) z) = z" by simp finally show ?thesis by (simp add: field_simps) qed lemma Arctan_0 [simp]: "Arctan 0 = 0" by (simp add: Arctan_def) lemma Im_complex_div_lemma: "Im((1 - \*z) / (1 + \*z)) = 0 \ Re z = 0" by (auto simp: Im_complex_div_eq_0 algebra_simps) lemma Re_complex_div_lemma: "0 < Re((1 - \*z) / (1 + \*z)) \ norm z < 1" by (simp add: Re_complex_div_gt_0 algebra_simps cmod_def power2_eq_square) lemma tan_Arctan: assumes "z\<^sup>2 \ -1" shows [simp]:"tan(Arctan z) = z" proof - have "1 + \*z \ 0" by (metis assms complex_i_mult_minus i_squared minus_unique power2_eq_square power2_minus) moreover have "1 - \*z \ 0" by (metis assms complex_i_mult_minus i_squared power2_eq_square power2_minus right_minus_eq) ultimately show ?thesis by (simp add: Arctan_def tan_def sin_exp_eq cos_exp_eq exp_minus csqrt_exp_Ln [symmetric] divide_simps power2_eq_square [symmetric]) qed lemma Arctan_tan [simp]: assumes "\Re z\ < pi/2" shows "Arctan(tan z) = z" proof - have "Ln ((1 - \ * tan z) / (1 + \ * tan z)) = 2 * z / \" proof (rule Ln_unique) have ge_pi2: "\n::int. \of_int (2*n + 1) * pi/2\ \ pi/2" by (case_tac n rule: int_cases) (auto simp: abs_mult) have "exp (\*z)*exp (\*z) = -1 \ exp (2*\*z) = -1" by (metis distrib_right exp_add mult_2) - also have "... \ exp (2*\*z) = exp (\*pi)" + also have "\ \ exp (2*\*z) = exp (\*pi)" using cis_conv_exp cis_pi by auto - also have "... \ exp (2*\*z - \*pi) = 1" + also have "\ \ exp (2*\*z - \*pi) = 1" by (metis (no_types) diff_add_cancel diff_minus_eq_add exp_add exp_minus_inverse mult.commute) - also have "... \ Re(\*2*z - \*pi) = 0 \ (\n::int. Im(\*2*z - \*pi) = of_int (2 * n) * pi)" + also have "\ \ Re(\*2*z - \*pi) = 0 \ (\n::int. Im(\*2*z - \*pi) = of_int (2 * n) * pi)" by (simp add: exp_eq_1) - also have "... \ Im z = 0 \ (\n::int. 2 * Re z = of_int (2*n + 1) * pi)" + also have "\ \ Im z = 0 \ (\n::int. 2 * Re z = of_int (2*n + 1) * pi)" by (simp add: algebra_simps) - also have "... \ False" + also have "\ \ False" using assms ge_pi2 apply (auto simp: algebra_simps) by (metis abs_mult_pos not_less of_nat_less_0_iff of_nat_numeral) finally have "exp (\*z)*exp (\*z) + 1 \ 0" by (auto simp: add.commute minus_unique) then show "exp (2 * z / \) = (1 - \ * tan z) / (1 + \ * tan z)" apply (simp add: tan_def sin_exp_eq cos_exp_eq exp_minus divide_simps) by (simp add: algebra_simps flip: power2_eq_square exp_double) qed (use assms in auto) then show ?thesis by (auto simp: Arctan_def) qed lemma assumes "Re z = 0 \ \Im z\ < 1" shows Re_Arctan_bounds: "\Re(Arctan z)\ < pi/2" and has_field_derivative_Arctan: "(Arctan has_field_derivative inverse(1 + z\<^sup>2)) (at z)" proof - have nz0: "1 + \*z \ 0" using assms by (metis abs_one add_diff_cancel_left' complex_i_mult_minus diff_0 i_squared imaginary_unit.simps less_asym neg_equal_iff_equal) have "z \ -\" using assms by auto then have zz: "1 + z * z \ 0" by (metis abs_one assms i_squared imaginary_unit.simps less_irrefl minus_unique square_eq_iff) have nz1: "1 - \*z \ 0" using assms by (force simp add: i_times_eq_iff) have nz2: "inverse (1 + \*z) \ 0" using assms by (metis Im_complex_div_lemma Re_complex_div_lemma cmod_eq_Im divide_complex_def less_irrefl mult_zero_right zero_complex.simps(1) zero_complex.simps(2)) have nzi: "((1 - \*z) * inverse (1 + \*z)) \ 0" using nz1 nz2 by auto have "Im ((1 - \*z) / (1 + \*z)) = 0 \ 0 < Re ((1 - \*z) / (1 + \*z))" apply (simp add: divide_complex_def) apply (simp add: divide_simps split: if_split_asm) using assms apply (auto simp: algebra_simps abs_square_less_1 [unfolded power2_eq_square]) done then have *: "((1 - \*z) / (1 + \*z)) \ \\<^sub>\\<^sub>0" by (auto simp add: complex_nonpos_Reals_iff) show "\Re(Arctan z)\ < pi/2" unfolding Arctan_def divide_complex_def using mpi_less_Im_Ln [OF nzi] by (auto simp: abs_if intro!: Im_Ln_less_pi * [unfolded divide_complex_def]) show "(Arctan has_field_derivative inverse(1 + z\<^sup>2)) (at z)" unfolding Arctan_def scaleR_conv_of_real apply (intro derivative_eq_intros | simp add: nz0 *)+ using nz1 zz apply (simp add: field_split_simps power2_eq_square) apply algebra done qed lemma field_differentiable_at_Arctan: "(Re z = 0 \ \Im z\ < 1) \ Arctan field_differentiable at z" using has_field_derivative_Arctan by (auto simp: field_differentiable_def) lemma field_differentiable_within_Arctan: "(Re z = 0 \ \Im z\ < 1) \ Arctan field_differentiable (at z within s)" using field_differentiable_at_Arctan field_differentiable_at_within by blast declare has_field_derivative_Arctan [derivative_intros] declare has_field_derivative_Arctan [THEN DERIV_chain2, derivative_intros] lemma continuous_at_Arctan: "(Re z = 0 \ \Im z\ < 1) \ continuous (at z) Arctan" by (simp add: field_differentiable_imp_continuous_at field_differentiable_within_Arctan) lemma continuous_within_Arctan: "(Re z = 0 \ \Im z\ < 1) \ continuous (at z within s) Arctan" using continuous_at_Arctan continuous_at_imp_continuous_within by blast lemma continuous_on_Arctan [continuous_intros]: "(\z. z \ s \ Re z = 0 \ \Im z\ < 1) \ continuous_on s Arctan" by (auto simp: continuous_at_imp_continuous_on continuous_within_Arctan) lemma holomorphic_on_Arctan: "(\z. z \ s \ Re z = 0 \ \Im z\ < 1) \ Arctan holomorphic_on s" by (simp add: field_differentiable_within_Arctan holomorphic_on_def) theorem Arctan_series: assumes z: "norm (z :: complex) < 1" defines "g \ \n. if odd n then -\*\^n / n else 0" defines "h \ \z n. (-1)^n / of_nat (2*n+1) * (z::complex)^(2*n+1)" shows "(\n. g n * z^n) sums Arctan z" and "h z sums Arctan z" proof - define G where [abs_def]: "G z = (\n. g n * z^n)" for z have summable: "summable (\n. g n * u^n)" if "norm u < 1" for u proof (cases "u = 0") assume u: "u \ 0" have "(\n. ereal (norm (h u n) / norm (h u (Suc n)))) = (\n. ereal (inverse (norm u)^2) * ereal ((2 + inverse (real (Suc n))) / (2 - inverse (real (Suc n)))))" proof fix n have "ereal (norm (h u n) / norm (h u (Suc n))) = ereal (inverse (norm u)^2) * ereal (((2*Suc n+1) / (Suc n)) / ((2*Suc n-1) / (Suc n)))" by (simp add: h_def norm_mult norm_power norm_divide field_split_simps power2_eq_square eval_nat_numeral del: of_nat_add of_nat_Suc) also have "of_nat (2*Suc n+1) / of_nat (Suc n) = (2::real) + inverse (real (Suc n))" by (auto simp: field_split_simps simp del: of_nat_Suc) simp_all? also have "of_nat (2*Suc n-1) / of_nat (Suc n) = (2::real) - inverse (real (Suc n))" by (auto simp: field_split_simps simp del: of_nat_Suc) simp_all? finally show "ereal (norm (h u n) / norm (h u (Suc n))) = ereal (inverse (norm u)^2) * ereal ((2 + inverse (real (Suc n))) / (2 - inverse (real (Suc n))))" . qed also have "\ \ ereal (inverse (norm u)^2) * ereal ((2 + 0) / (2 - 0))" by (intro tendsto_intros LIMSEQ_inverse_real_of_nat) simp_all finally have "liminf (\n. ereal (cmod (h u n) / cmod (h u (Suc n)))) = inverse (norm u)^2" by (intro lim_imp_Liminf) simp_all moreover from power_strict_mono[OF that, of 2] u have "inverse (norm u)^2 > 1" by (simp add: field_split_simps) ultimately have A: "liminf (\n. ereal (cmod (h u n) / cmod (h u (Suc n)))) > 1" by simp from u have "summable (h u)" by (intro summable_norm_cancel[OF ratio_test_convergence[OF _ A]]) (auto simp: h_def norm_divide norm_mult norm_power simp del: of_nat_Suc intro!: mult_pos_pos divide_pos_pos always_eventually) thus "summable (\n. g n * u^n)" by (subst summable_mono_reindex[of "\n. 2*n+1", symmetric]) (auto simp: power_mult strict_mono_def g_def h_def elim!: oddE) qed (simp add: h_def) have "\c. \u\ball 0 1. Arctan u - G u = c" proof (rule has_field_derivative_zero_constant) fix u :: complex assume "u \ ball 0 1" hence u: "norm u < 1" by (simp) define K where "K = (norm u + 1) / 2" from u and abs_Im_le_cmod[of u] have Im_u: "\Im u\ < 1" by linarith from u have K: "0 \ K" "norm u < K" "K < 1" by (simp_all add: K_def) hence "(G has_field_derivative (\n. diffs g n * u ^ n)) (at u)" unfolding G_def by (intro termdiffs_strong[of _ "of_real K"] summable) simp_all also have "(\n. diffs g n * u^n) = (\n. if even n then (\*u)^n else 0)" by (intro ext) (simp_all del: of_nat_Suc add: g_def diffs_def power_mult_distrib) also have "suminf \ = (\n. (-(u^2))^n)" by (subst suminf_mono_reindex[of "\n. 2*n", symmetric]) (auto elim!: evenE simp: strict_mono_def power_mult power_mult_distrib) also from u have "norm u^2 < 1^2" by (intro power_strict_mono) simp_all hence "(\n. (-(u^2))^n) = inverse (1 + u^2)" by (subst suminf_geometric) (simp_all add: norm_power inverse_eq_divide) finally have "(G has_field_derivative inverse (1 + u\<^sup>2)) (at u)" . from DERIV_diff[OF has_field_derivative_Arctan this] Im_u u show "((\u. Arctan u - G u) has_field_derivative 0) (at u within ball 0 1)" by (simp_all add: at_within_open[OF _ open_ball]) qed simp_all then obtain c where c: "\u. norm u < 1 \ Arctan u - G u = c" by auto from this[of 0] have "c = 0" by (simp add: G_def g_def) with c z have "Arctan z = G z" by simp with summable[OF z] show "(\n. g n * z^n) sums Arctan z" unfolding G_def by (simp add: sums_iff) thus "h z sums Arctan z" by (subst (asm) sums_mono_reindex[of "\n. 2*n+1", symmetric]) (auto elim!: oddE simp: strict_mono_def power_mult g_def h_def) qed text \A quickly-converging series for the logarithm, based on the arctangent.\ theorem ln_series_quadratic: assumes x: "x > (0::real)" shows "(\n. (2*((x - 1) / (x + 1)) ^ (2*n+1) / of_nat (2*n+1))) sums ln x" proof - define y :: complex where "y = of_real ((x-1)/(x+1))" from x have x': "complex_of_real x \ of_real (-1)" by (subst of_real_eq_iff) auto from x have "\x - 1\ < \x + 1\" by linarith hence "norm (complex_of_real (x - 1) / complex_of_real (x + 1)) < 1" by (simp add: norm_divide del: of_real_add of_real_diff) hence "norm (\ * y) < 1" unfolding y_def by (subst norm_mult) simp hence "(\n. (-2*\) * ((-1)^n / of_nat (2*n+1) * (\*y)^(2*n+1))) sums ((-2*\) * Arctan (\*y))" by (intro Arctan_series sums_mult) simp_all also have "(\n. (-2*\) * ((-1)^n / of_nat (2*n+1) * (\*y)^(2*n+1))) = (\n. (-2*\) * ((-1)^n * (\*y*(-y\<^sup>2)^n)/of_nat (2*n+1)))" by (intro ext) (simp_all add: power_mult power_mult_distrib) also have "\ = (\n. 2*y* ((-1) * (-y\<^sup>2))^n/of_nat (2*n+1))" by (intro ext, subst power_mult_distrib) (simp add: algebra_simps power_mult) also have "\ = (\n. 2*y^(2*n+1) / of_nat (2*n+1))" by (subst power_add, subst power_mult) (simp add: mult_ac) also have "\ = (\n. of_real (2*((x-1)/(x+1))^(2*n+1) / of_nat (2*n+1)))" by (intro ext) (simp add: y_def) also have "\ * y = (of_real x - 1) / (-\ * (of_real x + 1))" by (subst divide_divide_eq_left [symmetric]) (simp add: y_def) also have "\ = moebius 1 (-1) (-\) (-\) (of_real x)" by (simp add: moebius_def algebra_simps) also from x' have "-2*\*Arctan \ = Ln (of_real x)" by (intro Ln_conv_Arctan [symmetric]) simp_all also from x have "\ = ln x" by (rule Ln_of_real) finally show ?thesis by (subst (asm) sums_of_real_iff) qed subsection\<^marker>\tag unimportant\ \Real arctangent\ lemma Im_Arctan_of_real [simp]: "Im (Arctan (of_real x)) = 0" proof - have ne: "1 + x\<^sup>2 \ 0" by (metis power_one sum_power2_eq_zero_iff zero_neq_one) have ne1: "1 + \ * complex_of_real x \ 0" using Complex_eq complex_eq_cancel_iff2 by fastforce have "Re (Ln ((1 - \ * x) * inverse (1 + \ * x))) = 0" apply (rule norm_exp_imaginary) using ne apply (simp add: ne1 cmod_def) apply (auto simp: field_split_simps) apply algebra done then show ?thesis unfolding Arctan_def divide_complex_def by (simp add: complex_eq_iff) qed lemma arctan_eq_Re_Arctan: "arctan x = Re (Arctan (of_real x))" proof (rule arctan_unique) have "(1 - \ * x) / (1 + \ * x) \ \\<^sub>\\<^sub>0" by (auto simp: Im_complex_div_lemma complex_nonpos_Reals_iff) then show "- (pi / 2) < Re (Arctan (complex_of_real x))" by (simp add: Arctan_def Im_Ln_less_pi) next have *: " (1 - \*x) / (1 + \*x) \ 0" by (simp add: field_split_simps) ( simp add: complex_eq_iff) show "Re (Arctan (complex_of_real x)) < pi / 2" using mpi_less_Im_Ln [OF *] by (simp add: Arctan_def) next have "tan (Re (Arctan (of_real x))) = Re (tan (Arctan (of_real x)))" by (auto simp: tan_def Complex.Re_divide Re_sin Re_cos Im_sin Im_cos field_simps power2_eq_square) - also have "... = x" + also have "\ = x" proof - have "(complex_of_real x)\<^sup>2 \ - 1" by (metis diff_0_right minus_diff_eq mult_zero_left not_le of_real_1 of_real_eq_iff of_real_minus of_real_power power2_eq_square real_minus_mult_self_le zero_less_one) then show ?thesis by simp qed finally show "tan (Re (Arctan (complex_of_real x))) = x" . qed lemma Arctan_of_real: "Arctan (of_real x) = of_real (arctan x)" unfolding arctan_eq_Re_Arctan divide_complex_def by (simp add: complex_eq_iff) lemma Arctan_in_Reals [simp]: "z \ \ \ Arctan z \ \" by (metis Reals_cases Reals_of_real Arctan_of_real) declare arctan_one [simp] lemma arctan_less_pi4_pos: "x < 1 \ arctan x < pi/4" by (metis arctan_less_iff arctan_one) lemma arctan_less_pi4_neg: "-1 < x \ -(pi/4) < arctan x" by (metis arctan_less_iff arctan_minus arctan_one) lemma arctan_less_pi4: "\x\ < 1 \ \arctan x\ < pi/4" by (metis abs_less_iff arctan_less_pi4_pos arctan_minus) lemma arctan_le_pi4: "\x\ \ 1 \ \arctan x\ \ pi/4" by (metis abs_le_iff arctan_le_iff arctan_minus arctan_one) lemma abs_arctan: "\arctan x\ = arctan \x\" by (simp add: abs_if arctan_minus) lemma arctan_add_raw: assumes "\arctan x + arctan y\ < pi/2" shows "arctan x + arctan y = arctan((x + y) / (1 - x * y))" proof (rule arctan_unique [symmetric]) show 12: "- (pi / 2) < arctan x + arctan y" "arctan x + arctan y < pi / 2" using assms by linarith+ show "tan (arctan x + arctan y) = (x + y) / (1 - x * y)" using cos_gt_zero_pi [OF 12] by (simp add: arctan tan_add) qed lemma arctan_inverse: assumes "0 < x" shows "arctan(inverse x) = pi/2 - arctan x" proof - have "arctan(inverse x) = arctan(inverse(tan(arctan x)))" by (simp add: arctan) - also have "... = arctan (tan (pi / 2 - arctan x))" + also have "\ = arctan (tan (pi / 2 - arctan x))" by (simp add: tan_cot) - also have "... = pi/2 - arctan x" + also have "\ = pi/2 - arctan x" proof - have "0 < pi - arctan x" using arctan_ubound [of x] pi_gt_zero by linarith with assms show ?thesis by (simp add: Transcendental.arctan_tan) qed finally show ?thesis . qed lemma arctan_add_small: assumes "\x * y\ < 1" shows "(arctan x + arctan y = arctan((x + y) / (1 - x * y)))" proof (cases "x = 0 \ y = 0") case False with assms have "\x\ < inverse \y\" by (simp add: field_split_simps abs_mult) with False have "\arctan x\ < pi / 2 - \arctan y\" using assms by (auto simp add: abs_arctan arctan_inverse [symmetric] arctan_less_iff) then show ?thesis by (intro arctan_add_raw) linarith qed auto lemma abs_arctan_le: fixes x::real shows "\arctan x\ \ \x\" proof - have 1: "\x. x \ \ \ cmod (inverse (1 + x\<^sup>2)) \ 1" by (simp add: norm_divide divide_simps in_Reals_norm complex_is_Real_iff power2_eq_square) have "cmod (Arctan w - Arctan z) \ 1 * cmod (w-z)" if "w \ \" "z \ \" for w z apply (rule field_differentiable_bound [OF convex_Reals, of Arctan _ 1]) apply (rule has_field_derivative_at_within [OF has_field_derivative_Arctan]) using 1 that by (auto simp: Reals_def) then have "cmod (Arctan (of_real x) - Arctan 0) \ 1 * cmod (of_real x - 0)" using Reals_0 Reals_of_real by blast then show ?thesis by (simp add: Arctan_of_real) qed lemma arctan_le_self: "0 \ x \ arctan x \ x" by (metis abs_arctan_le abs_of_nonneg zero_le_arctan_iff) lemma abs_tan_ge: "\x\ < pi/2 \ \x\ \ \tan x\" by (metis abs_arctan_le abs_less_iff arctan_tan minus_less_iff) lemma arctan_bounds: assumes "0 \ x" "x < 1" shows arctan_lower_bound: "(\k<2 * n. (- 1) ^ k * (1 / real (k * 2 + 1) * x ^ (k * 2 + 1))) \ arctan x" (is "(\k<_. (- 1)^ k * ?a k) \ _") and arctan_upper_bound: "arctan x \ (\k<2 * n + 1. (- 1) ^ k * (1 / real (k * 2 + 1) * x ^ (k * 2 + 1)))" proof - have tendsto_zero: "?a \ 0" proof (rule tendsto_eq_rhs) show "(\k. 1 / real (k * 2 + 1) * x ^ (k * 2 + 1)) \ 0 * 0" using assms by (intro tendsto_mult real_tendsto_divide_at_top) (auto simp: filterlim_real_sequentially filterlim_sequentially_iff_filterlim_real intro!: real_tendsto_divide_at_top tendsto_power_zero filterlim_real_sequentially tendsto_eq_intros filterlim_at_top_mult_tendsto_pos filterlim_tendsto_add_at_top) qed simp have nonneg: "0 \ ?a n" for n by (force intro!: divide_nonneg_nonneg mult_nonneg_nonneg zero_le_power assms) have le: "?a (Suc n) \ ?a n" for n by (rule mult_mono[OF _ power_decreasing]) (auto simp: field_split_simps assms less_imp_le) from summable_Leibniz'(4)[of ?a, OF tendsto_zero nonneg le, of n] summable_Leibniz'(2)[of ?a, OF tendsto_zero nonneg le, of n] assms show "(\k<2*n. (- 1)^ k * ?a k) \ arctan x" "arctan x \ (\k<2 * n + 1. (- 1)^ k * ?a k)" by (auto simp: arctan_series) qed subsection\<^marker>\tag unimportant\ \Bounds on pi using real arctangent\ lemma pi_machin: "pi = 16 * arctan (1 / 5) - 4 * arctan (1 / 239)" using machin by simp lemma pi_approx: "3.141592653588 \ pi" "pi \ 3.1415926535899" unfolding pi_machin using arctan_bounds[of "1/5" 4] arctan_bounds[of "1/239" 4] by (simp_all add: eval_nat_numeral) lemma pi_gt3: "pi > 3" using pi_approx by simp subsection\Inverse Sine\ definition\<^marker>\tag important\ Arcsin :: "complex \ complex" where "Arcsin \ \z. -\ * Ln(\ * z + csqrt(1 - z\<^sup>2))" lemma Arcsin_body_lemma: "\ * z + csqrt(1 - z\<^sup>2) \ 0" using power2_csqrt [of "1 - z\<^sup>2"] by (metis add.inverse_inverse complex_i_mult_minus diff_0 diff_add_cancel diff_minus_eq_add mult.assoc mult.commute numeral_One power2_eq_square zero_neq_numeral) lemma Arcsin_range_lemma: "\Re z\ < 1 \ 0 < Re(\ * z + csqrt(1 - z\<^sup>2))" using Complex.cmod_power2 [of z, symmetric] by (simp add: real_less_rsqrt algebra_simps Re_power2 cmod_square_less_1_plus) lemma Re_Arcsin: "Re(Arcsin z) = Im (Ln (\ * z + csqrt(1 - z\<^sup>2)))" by (simp add: Arcsin_def) lemma Im_Arcsin: "Im(Arcsin z) = - ln (cmod (\ * z + csqrt (1 - z\<^sup>2)))" by (simp add: Arcsin_def Arcsin_body_lemma) lemma one_minus_z2_notin_nonpos_Reals: assumes "Im z = 0 \ \Re z\ < 1" shows "1 - z\<^sup>2 \ \\<^sub>\\<^sub>0" proof (cases "Im z = 0") case True with assms show ?thesis by (simp add: complex_nonpos_Reals_iff flip: abs_square_less_1) next case False have "\ (Im z)\<^sup>2 \ - 1" using False power2_less_eq_zero_iff by fastforce with False show ?thesis by (auto simp add: complex_nonpos_Reals_iff Re_power2 Im_power2) qed lemma isCont_Arcsin_lemma: assumes le0: "Re (\ * z + csqrt (1 - z\<^sup>2)) \ 0" and "(Im z = 0 \ \Re z\ < 1)" shows False proof (cases "Im z = 0") case True then show ?thesis using assms by (fastforce simp: cmod_def abs_square_less_1 [symmetric]) next case False have leim: "(cmod (1 - z\<^sup>2) + (1 - Re (z\<^sup>2))) / 2 \ (Im z)\<^sup>2" using le0 sqrt_le_D by fastforce have neq: "(cmod z)\<^sup>2 \ 1 + cmod (1 - z\<^sup>2)" proof (clarsimp simp add: cmod_def) assume "(Re z)\<^sup>2 + (Im z)\<^sup>2 = 1 + sqrt ((1 - Re (z\<^sup>2))\<^sup>2 + (Im (z\<^sup>2))\<^sup>2)" then have "((Re z)\<^sup>2 + (Im z)\<^sup>2 - 1)\<^sup>2 = ((1 - Re (z\<^sup>2))\<^sup>2 + (Im (z\<^sup>2))\<^sup>2)" by simp then show False using False by (simp add: power2_eq_square algebra_simps) qed moreover have 2: "(Im z)\<^sup>2 = (1 + ((Im z)\<^sup>2 + cmod (1 - z\<^sup>2)) - (Re z)\<^sup>2) / 2" using leim cmod_power2 [of z] norm_triangle_ineq2 [of "z^2" 1] by (simp add: norm_power Re_power2 norm_minus_commute [of 1]) ultimately show False by (simp add: Re_power2 Im_power2 cmod_power2) qed lemma isCont_Arcsin: assumes "(Im z = 0 \ \Re z\ < 1)" shows "isCont Arcsin z" proof - have 1: "\ * z + csqrt (1 - z\<^sup>2) \ \\<^sub>\\<^sub>0" by (metis isCont_Arcsin_lemma assms complex_nonpos_Reals_iff) have 2: "1 - z\<^sup>2 \ \\<^sub>\\<^sub>0" by (simp add: one_minus_z2_notin_nonpos_Reals assms) show ?thesis using assms unfolding Arcsin_def by (intro isCont_Ln' isCont_csqrt' continuous_intros 1 2) qed lemma isCont_Arcsin' [simp]: shows "isCont f z \ (Im (f z) = 0 \ \Re (f z)\ < 1) \ isCont (\x. Arcsin (f x)) z" by (blast intro: isCont_o2 [OF _ isCont_Arcsin]) lemma sin_Arcsin [simp]: "sin(Arcsin z) = z" proof - have "\*z*2 + csqrt (1 - z\<^sup>2)*2 = 0 \ (\*z)*2 + csqrt (1 - z\<^sup>2)*2 = 0" by (simp add: algebra_simps) \ \Cancelling a factor of 2\ - moreover have "... \ (\*z) + csqrt (1 - z\<^sup>2) = 0" + moreover have "\ \ (\*z) + csqrt (1 - z\<^sup>2) = 0" by (metis Arcsin_body_lemma distrib_right no_zero_divisors zero_neq_numeral) ultimately show ?thesis apply (simp add: sin_exp_eq Arcsin_def Arcsin_body_lemma exp_minus divide_simps) apply (simp add: algebra_simps) apply (simp add: power2_eq_square [symmetric] algebra_simps) done qed lemma Re_eq_pihalf_lemma: "\Re z\ = pi/2 \ Im z = 0 \ Re ((exp (\*z) + inverse (exp (\*z))) / 2) = 0 \ 0 \ Im ((exp (\*z) + inverse (exp (\*z))) / 2)" apply (simp add: cos_i_times [symmetric] Re_cos Im_cos abs_if del: eq_divide_eq_numeral1) by (metis cos_minus cos_pi_half) lemma Re_less_pihalf_lemma: assumes "\Re z\ < pi / 2" shows "0 < Re ((exp (\*z) + inverse (exp (\*z))) / 2)" proof - have "0 < cos (Re z)" using assms using cos_gt_zero_pi by auto then show ?thesis by (simp add: cos_i_times [symmetric] Re_cos Im_cos add_pos_pos) qed lemma Arcsin_sin: assumes "\Re z\ < pi/2 \ (\Re z\ = pi/2 \ Im z = 0)" shows "Arcsin(sin z) = z" proof - have "Arcsin(sin z) = - (\ * Ln (csqrt (1 - (\ * (exp (\*z) - inverse (exp (\*z))))\<^sup>2 / 4) - (inverse (exp (\*z)) - exp (\*z)) / 2))" by (simp add: sin_exp_eq Arcsin_def exp_minus power_divide) - also have "... = - (\ * Ln (csqrt (((exp (\*z) + inverse (exp (\*z)))/2)\<^sup>2) - (inverse (exp (\*z)) - exp (\*z)) / 2))" + also have "\ = - (\ * Ln (csqrt (((exp (\*z) + inverse (exp (\*z)))/2)\<^sup>2) - (inverse (exp (\*z)) - exp (\*z)) / 2))" by (simp add: field_simps power2_eq_square) - also have "... = - (\ * Ln (((exp (\*z) + inverse (exp (\*z)))/2) - (inverse (exp (\*z)) - exp (\*z)) / 2))" + also have "\ = - (\ * Ln (((exp (\*z) + inverse (exp (\*z)))/2) - (inverse (exp (\*z)) - exp (\*z)) / 2))" apply (subst csqrt_square) using assms Re_eq_pihalf_lemma Re_less_pihalf_lemma by auto - also have "... = - (\ * Ln (exp (\*z)))" + also have "\ = - (\ * Ln (exp (\*z)))" by (simp add: field_simps power2_eq_square) - also have "... = z" + also have "\ = z" using assms by (auto simp: abs_if simp del: eq_divide_eq_numeral1 split: if_split_asm) finally show ?thesis . qed lemma Arcsin_unique: "\sin z = w; \Re z\ < pi/2 \ (\Re z\ = pi/2 \ Im z = 0)\ \ Arcsin w = z" by (metis Arcsin_sin) lemma Arcsin_0 [simp]: "Arcsin 0 = 0" by (metis Arcsin_sin norm_zero pi_half_gt_zero real_norm_def sin_zero zero_complex.simps(1)) lemma Arcsin_1 [simp]: "Arcsin 1 = pi/2" by (metis Arcsin_sin Im_complex_of_real Re_complex_of_real numeral_One of_real_numeral pi_half_ge_zero real_sqrt_abs real_sqrt_pow2 real_sqrt_power sin_of_real sin_pi_half) lemma Arcsin_minus_1 [simp]: "Arcsin(-1) = - (pi/2)" by (metis Arcsin_1 Arcsin_sin Im_complex_of_real Re_complex_of_real abs_of_nonneg of_real_minus pi_half_ge_zero power2_minus real_sqrt_abs sin_Arcsin sin_minus) lemma has_field_derivative_Arcsin: assumes "Im z = 0 \ \Re z\ < 1" shows "(Arcsin has_field_derivative inverse(cos(Arcsin z))) (at z)" proof - have "(sin (Arcsin z))\<^sup>2 \ 1" using assms one_minus_z2_notin_nonpos_Reals by force then have "cos (Arcsin z) \ 0" by (metis diff_0_right power_zero_numeral sin_squared_eq) then show ?thesis by (rule has_field_derivative_inverse_basic [OF DERIV_sin _ _ open_ball [of z 1]]) (auto intro: isCont_Arcsin assms) qed declare has_field_derivative_Arcsin [derivative_intros] declare has_field_derivative_Arcsin [THEN DERIV_chain2, derivative_intros] lemma field_differentiable_at_Arcsin: "(Im z = 0 \ \Re z\ < 1) \ Arcsin field_differentiable at z" using field_differentiable_def has_field_derivative_Arcsin by blast lemma field_differentiable_within_Arcsin: "(Im z = 0 \ \Re z\ < 1) \ Arcsin field_differentiable (at z within s)" using field_differentiable_at_Arcsin field_differentiable_within_subset by blast lemma continuous_within_Arcsin: "(Im z = 0 \ \Re z\ < 1) \ continuous (at z within s) Arcsin" using continuous_at_imp_continuous_within isCont_Arcsin by blast lemma continuous_on_Arcsin [continuous_intros]: "(\z. z \ s \ Im z = 0 \ \Re z\ < 1) \ continuous_on s Arcsin" by (simp add: continuous_at_imp_continuous_on) lemma holomorphic_on_Arcsin: "(\z. z \ s \ Im z = 0 \ \Re z\ < 1) \ Arcsin holomorphic_on s" by (simp add: field_differentiable_within_Arcsin holomorphic_on_def) subsection\Inverse Cosine\ definition\<^marker>\tag important\ Arccos :: "complex \ complex" where "Arccos \ \z. -\ * Ln(z + \ * csqrt(1 - z\<^sup>2))" lemma Arccos_range_lemma: "\Re z\ < 1 \ 0 < Im(z + \ * csqrt(1 - z\<^sup>2))" using Arcsin_range_lemma [of "-z"] by simp lemma Arccos_body_lemma: "z + \ * csqrt(1 - z\<^sup>2) \ 0" using Arcsin_body_lemma [of z] by (metis Arcsin_body_lemma complex_i_mult_minus diff_minus_eq_add power2_minus right_minus_eq) lemma Re_Arccos: "Re(Arccos z) = Im (Ln (z + \ * csqrt(1 - z\<^sup>2)))" by (simp add: Arccos_def) lemma Im_Arccos: "Im(Arccos z) = - ln (cmod (z + \ * csqrt (1 - z\<^sup>2)))" by (simp add: Arccos_def Arccos_body_lemma) text\A very tricky argument to find!\ lemma isCont_Arccos_lemma: assumes eq0: "Im (z + \ * csqrt (1 - z\<^sup>2)) = 0" and "(Im z = 0 \ \Re z\ < 1)" shows False proof (cases "Im z = 0") case True then show ?thesis using assms by (fastforce simp add: cmod_def abs_square_less_1 [symmetric]) next case False have Imz: "Im z = - sqrt ((1 + ((Im z)\<^sup>2 + cmod (1 - z\<^sup>2)) - (Re z)\<^sup>2) / 2)" using eq0 abs_Re_le_cmod [of "1-z\<^sup>2"] by (simp add: Re_power2 algebra_simps) have "(cmod z)\<^sup>2 - 1 \ cmod (1 - z\<^sup>2)" proof (clarsimp simp add: cmod_def) assume "(Re z)\<^sup>2 + (Im z)\<^sup>2 - 1 = sqrt ((1 - Re (z\<^sup>2))\<^sup>2 + (Im (z\<^sup>2))\<^sup>2)" then have "((Re z)\<^sup>2 + (Im z)\<^sup>2 - 1)\<^sup>2 = ((1 - Re (z\<^sup>2))\<^sup>2 + (Im (z\<^sup>2))\<^sup>2)" by simp then show False using False by (simp add: power2_eq_square algebra_simps) qed moreover have "(Im z)\<^sup>2 = (1 + ((Im z)\<^sup>2 + cmod (1 - z\<^sup>2)) - (Re z)\<^sup>2) / 2" using abs_Re_le_cmod [of "1-z\<^sup>2"] by (subst Imz) (simp add: Re_power2) ultimately show False by (simp add: cmod_power2) qed lemma isCont_Arccos: assumes "(Im z = 0 \ \Re z\ < 1)" shows "isCont Arccos z" proof - have "z + \ * csqrt (1 - z\<^sup>2) \ \\<^sub>\\<^sub>0" by (metis complex_nonpos_Reals_iff isCont_Arccos_lemma assms) with assms show ?thesis unfolding Arccos_def by (simp_all add: one_minus_z2_notin_nonpos_Reals assms) qed lemma isCont_Arccos' [simp]: "isCont f z \ (Im (f z) = 0 \ \Re (f z)\ < 1) \ isCont (\x. Arccos (f x)) z" by (blast intro: isCont_o2 [OF _ isCont_Arccos]) lemma cos_Arccos [simp]: "cos(Arccos z) = z" proof - have "z*2 + \ * (2 * csqrt (1 - z\<^sup>2)) = 0 \ z*2 + \ * csqrt (1 - z\<^sup>2)*2 = 0" by (simp add: algebra_simps) \ \Cancelling a factor of 2\ - moreover have "... \ z + \ * csqrt (1 - z\<^sup>2) = 0" + moreover have "\ \ z + \ * csqrt (1 - z\<^sup>2) = 0" by (metis distrib_right mult_eq_0_iff zero_neq_numeral) ultimately show ?thesis by (simp add: cos_exp_eq Arccos_def Arccos_body_lemma exp_minus field_simps flip: power2_eq_square) qed lemma Arccos_cos: assumes "0 < Re z \ Re z < pi \ Re z = 0 \ 0 \ Im z \ Re z = pi \ Im z \ 0" shows "Arccos(cos z) = z" proof - have *: "((\ - (exp (\ * z))\<^sup>2 * \) / (2 * exp (\ * z))) = sin z" by (simp add: sin_exp_eq exp_minus field_simps power2_eq_square) have "1 - (exp (\ * z) + inverse (exp (\ * z)))\<^sup>2 / 4 = ((\ - (exp (\ * z))\<^sup>2 * \) / (2 * exp (\ * z)))\<^sup>2" by (simp add: field_simps power2_eq_square) then have "Arccos(cos z) = - (\ * Ln ((exp (\ * z) + inverse (exp (\ * z))) / 2 + \ * csqrt (((\ - (exp (\ * z))\<^sup>2 * \) / (2 * exp (\ * z)))\<^sup>2)))" by (simp add: cos_exp_eq Arccos_def exp_minus power_divide) - also have "... = - (\ * Ln ((exp (\ * z) + inverse (exp (\ * z))) / 2 + + also have "\ = - (\ * Ln ((exp (\ * z) + inverse (exp (\ * z))) / 2 + \ * ((\ - (exp (\ * z))\<^sup>2 * \) / (2 * exp (\ * z)))))" apply (subst csqrt_square) using assms Re_sin_pos [of z] Im_sin_nonneg [of z] Im_sin_nonneg2 [of z] by (auto simp: * Re_sin Im_sin) - also have "... = - (\ * Ln (exp (\*z)))" + also have "\ = - (\ * Ln (exp (\*z)))" by (simp add: field_simps power2_eq_square) - also have "... = z" + also have "\ = z" using assms by (subst Complex_Transcendental.Ln_exp, auto) finally show ?thesis . qed lemma Arccos_unique: "\cos z = w; 0 < Re z \ Re z < pi \ Re z = 0 \ 0 \ Im z \ Re z = pi \ Im z \ 0\ \ Arccos w = z" using Arccos_cos by blast lemma Arccos_0 [simp]: "Arccos 0 = pi/2" by (rule Arccos_unique) auto lemma Arccos_1 [simp]: "Arccos 1 = 0" by (rule Arccos_unique) auto lemma Arccos_minus1: "Arccos(-1) = pi" by (rule Arccos_unique) auto lemma has_field_derivative_Arccos: assumes "(Im z = 0 \ \Re z\ < 1)" shows "(Arccos has_field_derivative - inverse(sin(Arccos z))) (at z)" proof - have "x\<^sup>2 \ -1" for x::real by (sos "((R<1 + (([~1] * A=0) + (R<1 * (R<1 * [x__]^2)))))") with assms have "(cos (Arccos z))\<^sup>2 \ 1" by (auto simp: complex_eq_iff Re_power2 Im_power2 abs_square_eq_1) then have "- sin (Arccos z) \ 0" by (metis cos_squared_eq diff_0_right mult_zero_left neg_0_equal_iff_equal power2_eq_square) then have "(Arccos has_field_derivative inverse(- sin(Arccos z))) (at z)" by (rule has_field_derivative_inverse_basic [OF DERIV_cos _ _ open_ball [of z 1]]) (auto intro: isCont_Arccos assms) then show ?thesis by simp qed declare has_field_derivative_Arcsin [derivative_intros] declare has_field_derivative_Arcsin [THEN DERIV_chain2, derivative_intros] lemma field_differentiable_at_Arccos: "(Im z = 0 \ \Re z\ < 1) \ Arccos field_differentiable at z" using field_differentiable_def has_field_derivative_Arccos by blast lemma field_differentiable_within_Arccos: "(Im z = 0 \ \Re z\ < 1) \ Arccos field_differentiable (at z within s)" using field_differentiable_at_Arccos field_differentiable_within_subset by blast lemma continuous_within_Arccos: "(Im z = 0 \ \Re z\ < 1) \ continuous (at z within s) Arccos" using continuous_at_imp_continuous_within isCont_Arccos by blast lemma continuous_on_Arccos [continuous_intros]: "(\z. z \ s \ Im z = 0 \ \Re z\ < 1) \ continuous_on s Arccos" by (simp add: continuous_at_imp_continuous_on) lemma holomorphic_on_Arccos: "(\z. z \ s \ Im z = 0 \ \Re z\ < 1) \ Arccos holomorphic_on s" by (simp add: field_differentiable_within_Arccos holomorphic_on_def) subsection\<^marker>\tag unimportant\\Upper and Lower Bounds for Inverse Sine and Cosine\ lemma Arcsin_bounds: "\Re z\ < 1 \ \Re(Arcsin z)\ < pi/2" unfolding Re_Arcsin by (blast intro: Re_Ln_pos_lt_imp Arcsin_range_lemma) lemma Arccos_bounds: "\Re z\ < 1 \ 0 < Re(Arccos z) \ Re(Arccos z) < pi" unfolding Re_Arccos by (blast intro!: Im_Ln_pos_lt_imp Arccos_range_lemma) lemma Re_Arccos_bounds: "-pi < Re(Arccos z) \ Re(Arccos z) \ pi" unfolding Re_Arccos by (blast intro!: mpi_less_Im_Ln Im_Ln_le_pi Arccos_body_lemma) lemma Re_Arccos_bound: "\Re(Arccos z)\ \ pi" by (meson Re_Arccos_bounds abs_le_iff less_eq_real_def minus_less_iff) lemma Im_Arccos_bound: "\Im (Arccos w)\ \ cmod w" proof - have "(Im (Arccos w))\<^sup>2 \ (cmod (cos (Arccos w)))\<^sup>2 - (cos (Re (Arccos w)))\<^sup>2" using norm_cos_squared [of "Arccos w"] real_le_abs_sinh [of "Im (Arccos w)"] by (simp only: abs_le_square_iff) (simp add: field_split_simps) - also have "... \ (cmod w)\<^sup>2" + also have "\ \ (cmod w)\<^sup>2" by (auto simp: cmod_power2) finally show ?thesis using abs_le_square_iff by force qed lemma Re_Arcsin_bounds: "-pi < Re(Arcsin z) & Re(Arcsin z) \ pi" unfolding Re_Arcsin by (blast intro!: mpi_less_Im_Ln Im_Ln_le_pi Arcsin_body_lemma) lemma Re_Arcsin_bound: "\Re(Arcsin z)\ \ pi" by (meson Re_Arcsin_bounds abs_le_iff less_eq_real_def minus_less_iff) lemma norm_Arccos_bounded: fixes w :: complex shows "norm (Arccos w) \ pi + norm w" proof - have Re: "(Re (Arccos w))\<^sup>2 \ pi\<^sup>2" "(Im (Arccos w))\<^sup>2 \ (cmod w)\<^sup>2" using Re_Arccos_bound [of w] Im_Arccos_bound [of w] abs_le_square_iff by force+ have "Arccos w \ Arccos w \ pi\<^sup>2 + (cmod w)\<^sup>2" using Re by (simp add: dot_square_norm cmod_power2 [of "Arccos w"]) then have "cmod (Arccos w) \ pi + cmod (cos (Arccos w))" apply (simp add: norm_le_square) by (metis dot_square_norm norm_ge_zero norm_le_square pi_ge_zero triangle_lemma) then show "cmod (Arccos w) \ pi + cmod w" by auto qed subsection\<^marker>\tag unimportant\\Interrelations between Arcsin and Arccos\ lemma cos_Arcsin_nonzero: assumes "z\<^sup>2 \ 1" shows "cos(Arcsin z) \ 0" proof - have eq: "(\ * z * (csqrt (1 - z\<^sup>2)))\<^sup>2 = z\<^sup>2 * (z\<^sup>2 - 1)" by (simp add: algebra_simps) have "\ * z * (csqrt (1 - z\<^sup>2)) \ z\<^sup>2 - 1" proof assume "\ * z * (csqrt (1 - z\<^sup>2)) = z\<^sup>2 - 1" then have "(\ * z * (csqrt (1 - z\<^sup>2)))\<^sup>2 = (z\<^sup>2 - 1)\<^sup>2" by simp then have "z\<^sup>2 * (z\<^sup>2 - 1) = (z\<^sup>2 - 1)*(z\<^sup>2 - 1)" using eq power2_eq_square by auto then show False using assms by simp qed then have "1 + \ * z * (csqrt (1 - z * z)) \ z\<^sup>2" by (metis add_minus_cancel power2_eq_square uminus_add_conv_diff) then have "2*(1 + \ * z * (csqrt (1 - z * z))) \ 2*z\<^sup>2" (*FIXME cancel_numeral_factor*) by (metis mult_cancel_left zero_neq_numeral) then have "(\ * z + csqrt (1 - z\<^sup>2))\<^sup>2 \ -1" using assms apply (simp add: power2_sum) apply (simp add: power2_eq_square algebra_simps) done then show ?thesis apply (simp add: cos_exp_eq Arcsin_def exp_minus) apply (simp add: divide_simps Arcsin_body_lemma) apply (metis add.commute minus_unique power2_eq_square) done qed lemma sin_Arccos_nonzero: assumes "z\<^sup>2 \ 1" shows "sin(Arccos z) \ 0" proof - have eq: "(\ * z * (csqrt (1 - z\<^sup>2)))\<^sup>2 = -(z\<^sup>2) * (1 - z\<^sup>2)" by (simp add: algebra_simps) have "\ * z * (csqrt (1 - z\<^sup>2)) \ 1 - z\<^sup>2" proof assume "\ * z * (csqrt (1 - z\<^sup>2)) = 1 - z\<^sup>2" then have "(\ * z * (csqrt (1 - z\<^sup>2)))\<^sup>2 = (1 - z\<^sup>2)\<^sup>2" by simp then have "-(z\<^sup>2) * (1 - z\<^sup>2) = (1 - z\<^sup>2)*(1 - z\<^sup>2)" using eq power2_eq_square by auto then have "-(z\<^sup>2) = (1 - z\<^sup>2)" using assms by (metis add.commute add.right_neutral diff_add_cancel mult_right_cancel) then show False using assms by simp qed then have "z\<^sup>2 + \ * z * (csqrt (1 - z\<^sup>2)) \ 1" by (simp add: algebra_simps) then have "2*(z\<^sup>2 + \ * z * (csqrt (1 - z\<^sup>2))) \ 2*1" by (metis mult_cancel_left2 zero_neq_numeral) (*FIXME cancel_numeral_factor*) then have "(z + \ * csqrt (1 - z\<^sup>2))\<^sup>2 \ 1" using assms by (metis Arccos_def add.commute add.left_neutral cancel_comm_monoid_add_class.diff_cancel cos_Arccos csqrt_0 mult_zero_right) then show ?thesis apply (simp add: sin_exp_eq Arccos_def exp_minus) apply (simp add: divide_simps Arccos_body_lemma) apply (simp add: power2_eq_square) done qed lemma cos_sin_csqrt: assumes "0 < cos(Re z) \ cos(Re z) = 0 \ Im z * sin(Re z) \ 0" shows "cos z = csqrt(1 - (sin z)\<^sup>2)" proof (rule csqrt_unique [THEN sym]) show "(cos z)\<^sup>2 = 1 - (sin z)\<^sup>2" by (simp add: cos_squared_eq) qed (use assms in \auto simp: Re_cos Im_cos add_pos_pos mult_le_0_iff zero_le_mult_iff\) lemma sin_cos_csqrt: assumes "0 < sin(Re z) \ sin(Re z) = 0 \ 0 \ Im z * cos(Re z)" shows "sin z = csqrt(1 - (cos z)\<^sup>2)" proof (rule csqrt_unique [THEN sym]) show "(sin z)\<^sup>2 = 1 - (cos z)\<^sup>2" by (simp add: sin_squared_eq) qed (use assms in \auto simp: Re_sin Im_sin add_pos_pos mult_le_0_iff zero_le_mult_iff\) lemma Arcsin_Arccos_csqrt_pos: "(0 < Re z | Re z = 0 & 0 \ Im z) \ Arcsin z = Arccos(csqrt(1 - z\<^sup>2))" by (simp add: Arcsin_def Arccos_def Complex.csqrt_square add.commute) lemma Arccos_Arcsin_csqrt_pos: "(0 < Re z | Re z = 0 & 0 \ Im z) \ Arccos z = Arcsin(csqrt(1 - z\<^sup>2))" by (simp add: Arcsin_def Arccos_def Complex.csqrt_square add.commute) lemma sin_Arccos: "0 < Re z | Re z = 0 & 0 \ Im z \ sin(Arccos z) = csqrt(1 - z\<^sup>2)" by (simp add: Arccos_Arcsin_csqrt_pos) lemma cos_Arcsin: "0 < Re z | Re z = 0 & 0 \ Im z \ cos(Arcsin z) = csqrt(1 - z\<^sup>2)" by (simp add: Arcsin_Arccos_csqrt_pos) subsection\<^marker>\tag unimportant\\Relationship with Arcsin on the Real Numbers\ lemma Im_Arcsin_of_real: assumes "\x\ \ 1" shows "Im (Arcsin (of_real x)) = 0" proof - have "csqrt (1 - (of_real x)\<^sup>2) = (if x^2 \ 1 then sqrt (1 - x^2) else \ * sqrt (x^2 - 1))" by (simp add: of_real_sqrt del: csqrt_of_real_nonneg) then have "cmod (\ * of_real x + csqrt (1 - (of_real x)\<^sup>2))^2 = 1" using assms abs_square_le_1 by (force simp add: Complex.cmod_power2) then have "cmod (\ * of_real x + csqrt (1 - (of_real x)\<^sup>2)) = 1" by (simp add: norm_complex_def) then show ?thesis by (simp add: Im_Arcsin exp_minus) qed corollary\<^marker>\tag unimportant\ Arcsin_in_Reals [simp]: "z \ \ \ \Re z\ \ 1 \ Arcsin z \ \" by (metis Im_Arcsin_of_real Re_complex_of_real Reals_cases complex_is_Real_iff) lemma arcsin_eq_Re_Arcsin: assumes "\x\ \ 1" shows "arcsin x = Re (Arcsin (of_real x))" unfolding arcsin_def proof (rule the_equality, safe) show "- (pi / 2) \ Re (Arcsin (complex_of_real x))" using Re_Ln_pos_le [OF Arcsin_body_lemma, of "of_real x"] by (auto simp: Complex.in_Reals_norm Re_Arcsin) next show "Re (Arcsin (complex_of_real x)) \ pi / 2" using Re_Ln_pos_le [OF Arcsin_body_lemma, of "of_real x"] by (auto simp: Complex.in_Reals_norm Re_Arcsin) next show "sin (Re (Arcsin (complex_of_real x))) = x" using Re_sin [of "Arcsin (of_real x)"] Arcsin_body_lemma [of "of_real x"] by (simp add: Im_Arcsin_of_real assms) next fix x' assume "- (pi / 2) \ x'" "x' \ pi / 2" "x = sin x'" then show "x' = Re (Arcsin (complex_of_real (sin x')))" unfolding sin_of_real [symmetric] by (subst Arcsin_sin) auto qed lemma of_real_arcsin: "\x\ \ 1 \ of_real(arcsin x) = Arcsin(of_real x)" by (metis Im_Arcsin_of_real add.right_neutral arcsin_eq_Re_Arcsin complex_eq mult_zero_right of_real_0) subsection\<^marker>\tag unimportant\\Relationship with Arccos on the Real Numbers\ lemma Im_Arccos_of_real: assumes "\x\ \ 1" shows "Im (Arccos (of_real x)) = 0" proof - have "csqrt (1 - (of_real x)\<^sup>2) = (if x^2 \ 1 then sqrt (1 - x^2) else \ * sqrt (x^2 - 1))" by (simp add: of_real_sqrt del: csqrt_of_real_nonneg) then have "cmod (of_real x + \ * csqrt (1 - (of_real x)\<^sup>2))^2 = 1" using assms abs_square_le_1 by (force simp add: Complex.cmod_power2) then have "cmod (of_real x + \ * csqrt (1 - (of_real x)\<^sup>2)) = 1" by (simp add: norm_complex_def) then show ?thesis by (simp add: Im_Arccos exp_minus) qed corollary\<^marker>\tag unimportant\ Arccos_in_Reals [simp]: "z \ \ \ \Re z\ \ 1 \ Arccos z \ \" by (metis Im_Arccos_of_real Re_complex_of_real Reals_cases complex_is_Real_iff) lemma arccos_eq_Re_Arccos: assumes "\x\ \ 1" shows "arccos x = Re (Arccos (of_real x))" unfolding arccos_def proof (rule the_equality, safe) show "0 \ Re (Arccos (complex_of_real x))" using Im_Ln_pos_le [OF Arccos_body_lemma, of "of_real x"] by (auto simp: Complex.in_Reals_norm Re_Arccos) next show "Re (Arccos (complex_of_real x)) \ pi" using Im_Ln_pos_le [OF Arccos_body_lemma, of "of_real x"] by (auto simp: Complex.in_Reals_norm Re_Arccos) next show "cos (Re (Arccos (complex_of_real x))) = x" using Re_cos [of "Arccos (of_real x)"] Arccos_body_lemma [of "of_real x"] by (simp add: Im_Arccos_of_real assms) next fix x' assume "0 \ x'" "x' \ pi" "x = cos x'" then show "x' = Re (Arccos (complex_of_real (cos x')))" unfolding cos_of_real [symmetric] by (subst Arccos_cos) auto qed lemma of_real_arccos: "\x\ \ 1 \ of_real(arccos x) = Arccos(of_real x)" by (metis Im_Arccos_of_real add.right_neutral arccos_eq_Re_Arccos complex_eq mult_zero_right of_real_0) subsection\<^marker>\tag unimportant\\Some interrelationships among the real inverse trig functions\ lemma arccos_arctan: assumes "-1 < x" "x < 1" shows "arccos x = pi/2 - arctan(x / sqrt(1 - x\<^sup>2))" proof - have "arctan(x / sqrt(1 - x\<^sup>2)) - (pi/2 - arccos x) = 0" proof (rule sin_eq_0_pi) show "- pi < arctan (x / sqrt (1 - x\<^sup>2)) - (pi / 2 - arccos x)" using arctan_lbound [of "x / sqrt(1 - x\<^sup>2)"] arccos_bounded [of x] assms by (simp add: algebra_simps) next show "arctan (x / sqrt (1 - x\<^sup>2)) - (pi / 2 - arccos x) < pi" using arctan_ubound [of "x / sqrt(1 - x\<^sup>2)"] arccos_bounded [of x] assms by (simp add: algebra_simps) next show "sin (arctan (x / sqrt (1 - x\<^sup>2)) - (pi / 2 - arccos x)) = 0" using assms by (simp add: algebra_simps sin_diff cos_add sin_arccos sin_arctan cos_arctan power2_eq_square square_eq_1_iff) qed then show ?thesis by simp qed lemma arcsin_plus_arccos: assumes "-1 \ x" "x \ 1" shows "arcsin x + arccos x = pi/2" proof - have "arcsin x = pi/2 - arccos x" apply (rule sin_inj_pi) using assms arcsin [OF assms] arccos [OF assms] by (auto simp: algebra_simps sin_diff) then show ?thesis by (simp add: algebra_simps) qed lemma arcsin_arccos_eq: "-1 \ x \ x \ 1 \ arcsin x = pi/2 - arccos x" using arcsin_plus_arccos by force lemma arccos_arcsin_eq: "-1 \ x \ x \ 1 \ arccos x = pi/2 - arcsin x" using arcsin_plus_arccos by force lemma arcsin_arctan: "-1 < x \ x < 1 \ arcsin x = arctan(x / sqrt(1 - x\<^sup>2))" by (simp add: arccos_arctan arcsin_arccos_eq) lemma csqrt_1_diff_eq: "csqrt (1 - (of_real x)\<^sup>2) = (if x^2 \ 1 then sqrt (1 - x^2) else \ * sqrt (x^2 - 1))" by ( simp add: of_real_sqrt del: csqrt_of_real_nonneg) lemma arcsin_arccos_sqrt_pos: "0 \ x \ x \ 1 \ arcsin x = arccos(sqrt(1 - x\<^sup>2))" apply (simp add: abs_square_le_1 arcsin_eq_Re_Arcsin arccos_eq_Re_Arccos) apply (subst Arcsin_Arccos_csqrt_pos) apply (auto simp: power_le_one csqrt_1_diff_eq) done lemma arcsin_arccos_sqrt_neg: "-1 \ x \ x \ 0 \ arcsin x = -arccos(sqrt(1 - x\<^sup>2))" using arcsin_arccos_sqrt_pos [of "-x"] by (simp add: arcsin_minus) lemma arccos_arcsin_sqrt_pos: "0 \ x \ x \ 1 \ arccos x = arcsin(sqrt(1 - x\<^sup>2))" apply (simp add: abs_square_le_1 arcsin_eq_Re_Arcsin arccos_eq_Re_Arccos) apply (subst Arccos_Arcsin_csqrt_pos) apply (auto simp: power_le_one csqrt_1_diff_eq) done lemma arccos_arcsin_sqrt_neg: "-1 \ x \ x \ 0 \ arccos x = pi - arcsin(sqrt(1 - x\<^sup>2))" using arccos_arcsin_sqrt_pos [of "-x"] by (simp add: arccos_minus) subsection\<^marker>\tag unimportant\\Continuity results for arcsin and arccos\ lemma continuous_on_Arcsin_real [continuous_intros]: "continuous_on {w \ \. \Re w\ \ 1} Arcsin" proof - have "continuous_on {w \ \. \Re w\ \ 1} (\x. complex_of_real (arcsin (Re x))) = continuous_on {w \ \. \Re w\ \ 1} (\x. complex_of_real (Re (Arcsin (of_real (Re x)))))" by (rule continuous_on_cong [OF refl]) (simp add: arcsin_eq_Re_Arcsin) - also have "... = ?thesis" + also have "\ = ?thesis" by (rule continuous_on_cong [OF refl]) simp finally show ?thesis using continuous_on_arcsin [OF continuous_on_Re [OF continuous_on_id], of "{w \ \. \Re w\ \ 1}"] continuous_on_of_real by fastforce qed lemma continuous_within_Arcsin_real: "continuous (at z within {w \ \. \Re w\ \ 1}) Arcsin" proof (cases "z \ {w \ \. \Re w\ \ 1}") case True then show ?thesis using continuous_on_Arcsin_real continuous_on_eq_continuous_within by blast next case False with closed_real_abs_le [of 1] show ?thesis by (rule continuous_within_closed_nontrivial) qed lemma continuous_on_Arccos_real: "continuous_on {w \ \. \Re w\ \ 1} Arccos" proof - have "continuous_on {w \ \. \Re w\ \ 1} (\x. complex_of_real (arccos (Re x))) = continuous_on {w \ \. \Re w\ \ 1} (\x. complex_of_real (Re (Arccos (of_real (Re x)))))" by (rule continuous_on_cong [OF refl]) (simp add: arccos_eq_Re_Arccos) - also have "... = ?thesis" + also have "\ = ?thesis" by (rule continuous_on_cong [OF refl]) simp finally show ?thesis using continuous_on_arccos [OF continuous_on_Re [OF continuous_on_id], of "{w \ \. \Re w\ \ 1}"] continuous_on_of_real by fastforce qed lemma continuous_within_Arccos_real: "continuous (at z within {w \ \. \Re w\ \ 1}) Arccos" proof (cases "z \ {w \ \. \Re w\ \ 1}") case True then show ?thesis using continuous_on_Arccos_real continuous_on_eq_continuous_within by blast next case False with closed_real_abs_le [of 1] show ?thesis by (rule continuous_within_closed_nontrivial) qed lemma sinh_ln_complex: "x \ 0 \ sinh (ln x :: complex) = (x - inverse x) / 2" by (simp add: sinh_def exp_minus scaleR_conv_of_real exp_of_real) lemma cosh_ln_complex: "x \ 0 \ cosh (ln x :: complex) = (x + inverse x) / 2" by (simp add: cosh_def exp_minus scaleR_conv_of_real) lemma tanh_ln_complex: "x \ 0 \ tanh (ln x :: complex) = (x ^ 2 - 1) / (x ^ 2 + 1)" by (simp add: tanh_def sinh_ln_complex cosh_ln_complex divide_simps power2_eq_square) subsection\Roots of unity\ theorem complex_root_unity: fixes j::nat assumes "n \ 0" shows "exp(2 * of_real pi * \ * of_nat j / of_nat n)^n = 1" -proof - - have *: "of_nat j * (complex_of_real pi * 2) = complex_of_real (2 * real j * pi)" - by (simp) - then show ?thesis - apply (simp add: exp_of_nat_mult [symmetric] mult_ac exp_Euler) - apply (simp only: * cos_of_real sin_of_real) - apply simp - done -qed + by (metis assms bot_nat_0.not_eq_extremum exp_divide_power_eq exp_of_nat2_mult exp_two_pi_i power_one) lemma complex_root_unity_eq: fixes j::nat and k::nat assumes "1 \ n" shows "(exp(2 * of_real pi * \ * of_nat j / of_nat n) = exp(2 * of_real pi * \ * of_nat k / of_nat n) \ j mod n = k mod n)" proof - have "(\z::int. \ * (of_nat j * (of_real pi * 2)) = \ * (of_nat k * (of_real pi * 2)) + \ * (of_int z * (of_nat n * (of_real pi * 2)))) \ (\z::int. of_nat j * (\ * (of_real pi * 2)) = (of_nat k + of_nat n * of_int z) * (\ * (of_real pi * 2)))" by (simp add: algebra_simps) - also have "... \ (\z::int. of_nat j = of_nat k + of_nat n * (of_int z :: complex))" + also have "\ \ (\z::int. of_nat j = of_nat k + of_nat n * (of_int z :: complex))" by simp - also have "... \ (\z::int. of_nat j = of_nat k + of_nat n * z)" + also have "\ \ (\z::int. of_nat j = of_nat k + of_nat n * z)" by (metis (mono_tags, opaque_lifting) of_int_add of_int_eq_iff of_int_mult of_int_of_nat_eq) - also have "... \ int j mod int n = int k mod int n" + also have "\ \ int j mod int n = int k mod int n" by (auto simp: mod_eq_dvd_iff dvd_def algebra_simps) - also have "... \ j mod n = k mod n" + also have "\ \ j mod n = k mod n" by (metis of_nat_eq_iff zmod_int) finally have "(\z. \ * (of_nat j * (of_real pi * 2)) = \ * (of_nat k * (of_real pi * 2)) + \ * (of_int z * (of_nat n * (of_real pi * 2)))) \ j mod n = k mod n" . note * = this show ?thesis using assms by (simp add: exp_eq field_split_simps *) qed corollary bij_betw_roots_unity: "bij_betw (\j. exp(2 * of_real pi * \ * of_nat j / of_nat n)) {.. * of_nat j / of_nat n) | j. j < n}" by (auto simp: bij_betw_def inj_on_def complex_root_unity_eq) lemma complex_root_unity_eq_1: fixes j::nat and k::nat assumes "1 \ n" shows "exp(2 * of_real pi * \ * of_nat j / of_nat n) = 1 \ n dvd j" proof - have "1 = exp(2 * of_real pi * \ * (of_nat n / of_nat n))" using assms by simp then have "exp(2 * of_real pi * \ * (of_nat j / of_nat n)) = 1 \ j mod n = n mod n" using complex_root_unity_eq [of n j n] assms by simp then show ?thesis by auto qed lemma finite_complex_roots_unity_explicit: "finite {exp(2 * of_real pi * \ * of_nat j / of_nat n) | j::nat. j < n}" by simp lemma card_complex_roots_unity_explicit: "card {exp(2 * of_real pi * \ * of_nat j / of_nat n) | j::nat. j < n} = n" by (simp add: Finite_Set.bij_betw_same_card [OF bij_betw_roots_unity, symmetric]) lemma complex_roots_unity: assumes "1 \ n" shows "{z::complex. z^n = 1} = {exp(2 * of_real pi * \ * of_nat j / of_nat n) | j. j < n}" apply (rule Finite_Set.card_seteq [symmetric]) using assms apply (auto simp: card_complex_roots_unity_explicit finite_roots_unity complex_root_unity card_roots_unity) done lemma card_complex_roots_unity: "1 \ n \ card {z::complex. z^n = 1} = n" by (simp add: card_complex_roots_unity_explicit complex_roots_unity) lemma complex_not_root_unity: "1 \ n \ \u::complex. norm u = 1 \ u^n \ 1" apply (rule_tac x="exp (of_real pi * \ * of_real (1 / n))" in exI) apply (auto simp: Re_complex_div_eq_0 exp_of_nat_mult [symmetric] mult_ac exp_Euler) done end diff --git a/src/HOL/Library/Extended_Nonnegative_Real.thy b/src/HOL/Library/Extended_Nonnegative_Real.thy --- a/src/HOL/Library/Extended_Nonnegative_Real.thy +++ b/src/HOL/Library/Extended_Nonnegative_Real.thy @@ -1,2085 +1,2047 @@ (* Title: HOL/Library/Extended_Nonnegative_Real.thy Author: Johannes Hölzl *) subsection \The type of non-negative extended real numbers\ theory Extended_Nonnegative_Real imports Extended_Real Indicator_Function begin lemma ereal_ineq_diff_add: assumes "b \ (-\::ereal)" "a \ b" shows "a = b + (a-b)" by (metis add.commute assms ereal_eq_minus_iff ereal_minus_le_iff ereal_plus_eq_PInfty) lemma Limsup_const_add: fixes c :: "'a::{complete_linorder, linorder_topology, topological_monoid_add, ordered_ab_semigroup_add}" shows "F \ bot \ Limsup F (\x. c + f x) = c + Limsup F f" by (rule Limsup_compose_continuous_mono) (auto intro!: monoI add_mono continuous_on_add continuous_on_id continuous_on_const) lemma Liminf_const_add: fixes c :: "'a::{complete_linorder, linorder_topology, topological_monoid_add, ordered_ab_semigroup_add}" shows "F \ bot \ Liminf F (\x. c + f x) = c + Liminf F f" by (rule Liminf_compose_continuous_mono) (auto intro!: monoI add_mono continuous_on_add continuous_on_id continuous_on_const) lemma Liminf_add_const: fixes c :: "'a::{complete_linorder, linorder_topology, topological_monoid_add, ordered_ab_semigroup_add}" shows "F \ bot \ Liminf F (\x. f x + c) = Liminf F f + c" by (rule Liminf_compose_continuous_mono) (auto intro!: monoI add_mono continuous_on_add continuous_on_id continuous_on_const) lemma sums_offset: fixes f g :: "nat \ 'a :: {t2_space, topological_comm_monoid_add}" assumes "(\n. f (n + i)) sums l" shows "f sums (l + (\jk. (\nj l + (\jjj=i..j=0..j=i..j\(\n. n + i)`{0..jnjk. (\n l + (\j 'a :: {t2_space, topological_comm_monoid_add}" shows "summable (\j. f (j + i)) \ suminf f = (\j. f (j + i)) + (\jz::real. 0 < z \ z < 1 \ P z) \ eventually P (at_left 1)" by (subst eventually_at_left[of 0]) (auto intro: exI[of _ 0]) lemma mult_eq_1: fixes a b :: "'a :: {ordered_semiring, comm_monoid_mult}" shows "0 \ a \ a \ 1 \ b \ 1 \ a * b = 1 \ (a = 1 \ b = 1)" by (metis mult.left_neutral eq_iff mult.commute mult_right_mono) lemma ereal_add_diff_cancel: fixes a b :: ereal shows "\b\ \ \ \ (a + b) - b = a" by (cases a b rule: ereal2_cases) auto lemma add_top: fixes x :: "'a::{order_top, ordered_comm_monoid_add}" shows "0 \ x \ x + top = top" by (intro top_le add_increasing order_refl) lemma top_add: fixes x :: "'a::{order_top, ordered_comm_monoid_add}" shows "0 \ x \ top + x = top" by (intro top_le add_increasing2 order_refl) lemma le_lfp: "mono f \ x \ lfp f \ f x \ lfp f" by (subst lfp_unfold) (auto dest: monoD) lemma lfp_transfer: assumes \: "sup_continuous \" and f: "sup_continuous f" and mg: "mono g" assumes bot: "\ bot \ lfp g" and eq: "\x. x \ lfp f \ \ (f x) = g (\ x)" shows "\ (lfp f) = lfp g" proof (rule antisym) note mf = sup_continuous_mono[OF f] have f_le_lfp: "(f ^^ i) bot \ lfp f" for i by (induction i) (auto intro: le_lfp mf) have "\ ((f ^^ i) bot) \ lfp g" for i by (induction i) (auto simp: bot eq f_le_lfp intro!: le_lfp mg) then show "\ (lfp f) \ lfp g" unfolding sup_continuous_lfp[OF f] by (subst \[THEN sup_continuousD]) (auto intro!: mono_funpow sup_continuous_mono[OF f] SUP_least) show "lfp g \ \ (lfp f)" by (rule lfp_lowerbound) (simp add: eq[symmetric] lfp_fixpoint[OF mf]) qed lemma sup_continuous_applyD: "sup_continuous f \ sup_continuous (\x. f x h)" using sup_continuous_apply[THEN sup_continuous_compose] . lemma sup_continuous_SUP[order_continuous_intros]: fixes M :: "_ \ _ \ 'a::complete_lattice" assumes M: "\i. i \ I \ sup_continuous (M i)" shows "sup_continuous (SUP i\I. M i)" unfolding sup_continuous_def by (auto simp add: sup_continuousD [OF M] image_comp intro: SUP_commute) lemma sup_continuous_apply_SUP[order_continuous_intros]: fixes M :: "_ \ _ \ 'a::complete_lattice" shows "(\i. i \ I \ sup_continuous (M i)) \ sup_continuous (\x. SUP i\I. M i x)" unfolding SUP_apply[symmetric] by (rule sup_continuous_SUP) lemma sup_continuous_lfp'[order_continuous_intros]: assumes 1: "sup_continuous f" assumes 2: "\g. sup_continuous g \ sup_continuous (f g)" shows "sup_continuous (lfp f)" proof - have "sup_continuous ((f ^^ i) bot)" for i proof (induction i) case (Suc i) then show ?case by (auto intro!: 2) qed (simp add: bot_fun_def sup_continuous_const) then show ?thesis unfolding sup_continuous_lfp[OF 1] by (intro order_continuous_intros) qed lemma sup_continuous_lfp''[order_continuous_intros]: assumes 1: "\s. sup_continuous (f s)" assumes 2: "\g. sup_continuous g \ sup_continuous (\s. f s (g s))" shows "sup_continuous (\x. lfp (f x))" proof - have "sup_continuous (\x. (f x ^^ i) bot)" for i proof (induction i) case (Suc i) then show ?case by (auto intro!: 2) qed (simp add: bot_fun_def sup_continuous_const) then show ?thesis unfolding sup_continuous_lfp[OF 1] by (intro order_continuous_intros) qed lemma mono_INF_fun: "(\x y. mono (F x y)) \ mono (\z x. INF y \ X x. F x y z :: 'a :: complete_lattice)" by (auto intro!: INF_mono[OF bexI] simp: le_fun_def mono_def) lemma continuous_on_cmult_ereal: "\c::ereal\ \ \ \ continuous_on A f \ continuous_on A (\x. c * f x)" using tendsto_cmult_ereal[of c f "f x" "at x within A" for x] by (auto simp: continuous_on_def simp del: tendsto_cmult_ereal) lemma real_of_nat_Sup: assumes "A \ {}" "bdd_above A" shows "of_nat (Sup A) = (SUP a\A. of_nat a :: real)" proof (intro antisym) show "(SUP a\A. of_nat a::real) \ of_nat (Sup A)" using assms by (intro cSUP_least of_nat_mono) (auto intro: cSup_upper) have "Sup A \ A" using assms by (auto simp: Sup_nat_def bdd_above_nat) then show "of_nat (Sup A) \ (SUP a\A. of_nat a::real)" by (intro cSUP_upper bdd_above_image_mono assms) (auto simp: mono_def) qed lemma (in complete_lattice) SUP_sup_const1: "I \ {} \ (SUP i\I. sup c (f i)) = sup c (SUP i\I. f i)" using SUP_sup_distrib[of "\_. c" I f] by simp lemma (in complete_lattice) SUP_sup_const2: "I \ {} \ (SUP i\I. sup (f i) c) = sup (SUP i\I. f i) c" using SUP_sup_distrib[of f I "\_. c"] by simp lemma one_less_of_natD: assumes "(1::'a::linordered_semidom) < of_nat n" shows "1 < n" by (cases n) (use assms in auto) subsection \Defining the extended non-negative reals\ text \Basic definitions and type class setup\ typedef ennreal = "{x :: ereal. 0 \ x}" morphisms enn2ereal e2ennreal' by auto definition "e2ennreal x = e2ennreal' (max 0 x)" lemma enn2ereal_range: "e2ennreal ` {0..} = UNIV" proof - have "\y\0. x = e2ennreal y" for x by (cases x) (auto simp: e2ennreal_def max_absorb2) then show ?thesis by (auto simp: image_iff Bex_def) qed lemma type_definition_ennreal': "type_definition enn2ereal e2ennreal {x. 0 \ x}" using type_definition_ennreal by (auto simp: type_definition_def e2ennreal_def max_absorb2) setup_lifting type_definition_ennreal' declare [[coercion e2ennreal]] instantiation ennreal :: complete_linorder begin lift_definition top_ennreal :: ennreal is top by (rule top_greatest) lift_definition bot_ennreal :: ennreal is 0 by (rule order_refl) lift_definition sup_ennreal :: "ennreal \ ennreal \ ennreal" is sup by (rule le_supI1) lift_definition inf_ennreal :: "ennreal \ ennreal \ ennreal" is inf by (rule le_infI) lift_definition Inf_ennreal :: "ennreal set \ ennreal" is "Inf" by (rule Inf_greatest) lift_definition Sup_ennreal :: "ennreal set \ ennreal" is "sup 0 \ Sup" by auto lift_definition less_eq_ennreal :: "ennreal \ ennreal \ bool" is "(\)" . lift_definition less_ennreal :: "ennreal \ ennreal \ bool" is "(<)" . instance by standard (transfer ; auto simp: Inf_lower Inf_greatest Sup_upper Sup_least le_max_iff_disj max.absorb1)+ end lemma pcr_ennreal_enn2ereal[simp]: "pcr_ennreal (enn2ereal x) x" by (simp add: ennreal.pcr_cr_eq cr_ennreal_def) lemma rel_fun_eq_pcr_ennreal: "rel_fun (=) pcr_ennreal f g \ f = enn2ereal \ g" by (auto simp: rel_fun_def ennreal.pcr_cr_eq cr_ennreal_def) instantiation ennreal :: infinity begin definition infinity_ennreal :: ennreal where [simp]: "\ = (top::ennreal)" instance .. end instantiation ennreal :: "{semiring_1_no_zero_divisors, comm_semiring_1}" begin lift_definition one_ennreal :: ennreal is 1 by simp lift_definition zero_ennreal :: ennreal is 0 by simp lift_definition plus_ennreal :: "ennreal \ ennreal \ ennreal" is "(+)" by simp lift_definition times_ennreal :: "ennreal \ ennreal \ ennreal" is "(*)" by simp instance by standard (transfer; auto simp: field_simps ereal_right_distrib)+ end instantiation ennreal :: minus begin lift_definition minus_ennreal :: "ennreal \ ennreal \ ennreal" is "\a b. max 0 (a - b)" by simp instance .. end instance ennreal :: numeral .. instantiation ennreal :: inverse begin lift_definition inverse_ennreal :: "ennreal \ ennreal" is inverse by (rule inverse_ereal_ge0I) definition divide_ennreal :: "ennreal \ ennreal \ ennreal" where "x div y = x * inverse (y :: ennreal)" instance .. end lemma ennreal_zero_less_one: "0 < (1::ennreal)" \ \TODO: remove\ by transfer auto instance ennreal :: dioid proof (standard; transfer) fix a b :: ereal assume "0 \ a" "0 \ b" then show "(a \ b) = (\c\Collect ((\) 0). b = a + c)" unfolding ereal_ex_split Bex_def by (cases a b rule: ereal2_cases) (auto intro!: exI[of _ "real_of_ereal (b - a)"]) qed instance ennreal :: ordered_comm_semiring by standard (transfer ; auto intro: add_mono mult_mono mult_ac ereal_left_distrib ereal_mult_left_mono)+ instance ennreal :: linordered_nonzero_semiring proof fix a b::ennreal show "a < b \ a + 1 < b + 1" by transfer (simp add: add_right_mono ereal_add_cancel_right less_le) qed (transfer; simp) instance ennreal :: strict_ordered_ab_semigroup_add proof fix a b c d :: ennreal show "a < b \ c < d \ a + c < b + d" by transfer (auto intro!: ereal_add_strict_mono) qed declare [[coercion "of_nat :: nat \ ennreal"]] lemma e2ennreal_neg: "x \ 0 \ e2ennreal x = 0" unfolding zero_ennreal_def e2ennreal_def by (simp add: max_absorb1) lemma e2ennreal_mono: "x \ y \ e2ennreal x \ e2ennreal y" by (cases "0 \ x" "0 \ y" rule: bool.exhaust[case_product bool.exhaust]) (auto simp: e2ennreal_neg less_eq_ennreal.abs_eq eq_onp_def) lemma enn2ereal_nonneg[simp]: "0 \ enn2ereal x" using ennreal.enn2ereal[of x] by simp lemma ereal_ennreal_cases: obtains b where "0 \ a" "a = enn2ereal b" | "a < 0" using e2ennreal'_inverse[of a, symmetric] by (cases "0 \ a") (auto intro: enn2ereal_nonneg) lemma rel_fun_liminf[transfer_rule]: "rel_fun (rel_fun (=) pcr_ennreal) pcr_ennreal liminf liminf" proof - have "rel_fun (rel_fun (=) pcr_ennreal) pcr_ennreal (\x. sup 0 (liminf x)) liminf" unfolding liminf_SUP_INF[abs_def] by (transfer_prover_start, transfer_step+; simp) then show ?thesis apply (subst (asm) (2) rel_fun_def) apply (subst (2) rel_fun_def) apply (auto simp: comp_def max.absorb2 Liminf_bounded rel_fun_eq_pcr_ennreal) done qed lemma rel_fun_limsup[transfer_rule]: "rel_fun (rel_fun (=) pcr_ennreal) pcr_ennreal limsup limsup" proof - have "rel_fun (rel_fun (=) pcr_ennreal) pcr_ennreal (\x. INF n. sup 0 (SUP i\{n..}. x i)) limsup" unfolding limsup_INF_SUP[abs_def] by (transfer_prover_start, transfer_step+; simp) then show ?thesis unfolding limsup_INF_SUP[abs_def] apply (subst (asm) (2) rel_fun_def) apply (subst (2) rel_fun_def) apply (auto simp: comp_def max.absorb2 Sup_upper2 rel_fun_eq_pcr_ennreal) apply (subst (asm) max.absorb2) apply (auto intro: SUP_upper2) done qed lemma sum_enn2ereal[simp]: "(\i. i \ I \ 0 \ f i) \ (\i\I. enn2ereal (f i)) = enn2ereal (sum f I)" by (induction I rule: infinite_finite_induct) (auto simp: sum_nonneg zero_ennreal.rep_eq plus_ennreal.rep_eq) lemma transfer_e2ennreal_sum [transfer_rule]: "rel_fun (rel_fun (=) pcr_ennreal) (rel_fun (=) pcr_ennreal) sum sum" by (auto intro!: rel_funI simp: rel_fun_eq_pcr_ennreal comp_def) lemma enn2ereal_of_nat[simp]: "enn2ereal (of_nat n) = ereal n" by (induction n) (auto simp: zero_ennreal.rep_eq one_ennreal.rep_eq plus_ennreal.rep_eq) lemma enn2ereal_numeral[simp]: "enn2ereal (numeral a) = numeral a" by (metis enn2ereal_of_nat numeral_eq_ereal of_nat_numeral) lemma transfer_numeral[transfer_rule]: "pcr_ennreal (numeral a) (numeral a)" unfolding cr_ennreal_def pcr_ennreal_def by auto subsection \Cancellation simprocs\ lemma ennreal_add_left_cancel: "a + b = a + c \ a = (\::ennreal) \ b = c" unfolding infinity_ennreal_def by transfer (simp add: top_ereal_def ereal_add_cancel_left) lemma ennreal_add_left_cancel_le: "a + b \ a + c \ a = (\::ennreal) \ b \ c" unfolding infinity_ennreal_def by transfer (simp add: ereal_add_le_add_iff top_ereal_def disj_commute) lemma ereal_add_left_cancel_less: fixes a b c :: ereal shows "0 \ a \ 0 \ b \ a + b < a + c \ a \ \ \ b < c" by (cases a b c rule: ereal3_cases) auto lemma ennreal_add_left_cancel_less: "a + b < a + c \ a \ (\::ennreal) \ b < c" unfolding infinity_ennreal_def by transfer (simp add: top_ereal_def ereal_add_left_cancel_less) ML \ structure Cancel_Ennreal_Common = struct (* copied from src/HOL/Tools/nat_numeral_simprocs.ML *) fun find_first_t _ _ [] = raise TERM("find_first_t", []) | find_first_t past u (t::terms) = if u aconv t then (rev past @ terms) else find_first_t (t::past) u terms fun dest_summing (Const (\<^const_name>\Groups.plus\, _) $ t $ u, ts) = dest_summing (t, dest_summing (u, ts)) | dest_summing (t, ts) = t :: ts val mk_sum = Arith_Data.long_mk_sum fun dest_sum t = dest_summing (t, []) val find_first = find_first_t [] val trans_tac = Numeral_Simprocs.trans_tac val norm_ss = simpset_of (put_simpset HOL_basic_ss \<^context> addsimps @{thms ac_simps add_0_left add_0_right}) fun norm_tac ctxt = ALLGOALS (simp_tac (put_simpset norm_ss ctxt)) fun simplify_meta_eq ctxt cancel_th th = Arith_Data.simplify_meta_eq [] ctxt ([th, cancel_th] MRS trans) fun mk_eq (a, b) = HOLogic.mk_Trueprop (HOLogic.mk_eq (a, b)) end structure Eq_Ennreal_Cancel = ExtractCommonTermFun (open Cancel_Ennreal_Common val mk_bal = HOLogic.mk_eq val dest_bal = HOLogic.dest_bin \<^const_name>\HOL.eq\ \<^typ>\ennreal\ fun simp_conv _ _ = SOME @{thm ennreal_add_left_cancel} ) structure Le_Ennreal_Cancel = ExtractCommonTermFun (open Cancel_Ennreal_Common val mk_bal = HOLogic.mk_binrel \<^const_name>\Orderings.less_eq\ val dest_bal = HOLogic.dest_bin \<^const_name>\Orderings.less_eq\ \<^typ>\ennreal\ fun simp_conv _ _ = SOME @{thm ennreal_add_left_cancel_le} ) structure Less_Ennreal_Cancel = ExtractCommonTermFun (open Cancel_Ennreal_Common val mk_bal = HOLogic.mk_binrel \<^const_name>\Orderings.less\ val dest_bal = HOLogic.dest_bin \<^const_name>\Orderings.less\ \<^typ>\ennreal\ fun simp_conv _ _ = SOME @{thm ennreal_add_left_cancel_less} ) \ simproc_setup ennreal_eq_cancel ("(l::ennreal) + m = n" | "(l::ennreal) = m + n") = \fn phi => fn ctxt => fn ct => Eq_Ennreal_Cancel.proc ctxt (Thm.term_of ct)\ simproc_setup ennreal_le_cancel ("(l::ennreal) + m \ n" | "(l::ennreal) \ m + n") = \fn phi => fn ctxt => fn ct => Le_Ennreal_Cancel.proc ctxt (Thm.term_of ct)\ simproc_setup ennreal_less_cancel ("(l::ennreal) + m < n" | "(l::ennreal) < m + n") = \fn phi => fn ctxt => fn ct => Less_Ennreal_Cancel.proc ctxt (Thm.term_of ct)\ subsection \Order with top\ lemma ennreal_zero_less_top[simp]: "0 < (top::ennreal)" by transfer (simp add: top_ereal_def) lemma ennreal_one_less_top[simp]: "1 < (top::ennreal)" by transfer (simp add: top_ereal_def) lemma ennreal_zero_neq_top[simp]: "0 \ (top::ennreal)" by transfer (simp add: top_ereal_def) lemma ennreal_top_neq_zero[simp]: "(top::ennreal) \ 0" by transfer (simp add: top_ereal_def) lemma ennreal_top_neq_one[simp]: "top \ (1::ennreal)" by transfer (simp add: top_ereal_def one_ereal_def flip: ereal_max) lemma ennreal_one_neq_top[simp]: "1 \ (top::ennreal)" by transfer (simp add: top_ereal_def one_ereal_def flip: ereal_max) lemma ennreal_add_less_top[simp]: fixes a b :: ennreal shows "a + b < top \ a < top \ b < top" by transfer (auto simp: top_ereal_def) lemma ennreal_add_eq_top[simp]: fixes a b :: ennreal shows "a + b = top \ a = top \ b = top" by transfer (auto simp: top_ereal_def) lemma ennreal_sum_less_top[simp]: fixes f :: "'a \ ennreal" shows "finite I \ (\i\I. f i) < top \ (\i\I. f i < top)" by (induction I rule: finite_induct) auto lemma ennreal_sum_eq_top[simp]: fixes f :: "'a \ ennreal" shows "finite I \ (\i\I. f i) = top \ (\i\I. f i = top)" by (induction I rule: finite_induct) auto lemma ennreal_mult_eq_top_iff: fixes a b :: ennreal shows "a * b = top \ (a = top \ b \ 0) \ (b = top \ a \ 0)" by transfer (auto simp: top_ereal_def) lemma ennreal_top_eq_mult_iff: fixes a b :: ennreal shows "top = a * b \ (a = top \ b \ 0) \ (b = top \ a \ 0)" using ennreal_mult_eq_top_iff[of a b] by auto lemma ennreal_mult_less_top: fixes a b :: ennreal shows "a * b < top \ (a = 0 \ b = 0 \ (a < top \ b < top))" by transfer (auto simp add: top_ereal_def) lemma top_power_ennreal: "top ^ n = (if n = 0 then 1 else top :: ennreal)" by (induction n) (simp_all add: ennreal_mult_eq_top_iff) lemma ennreal_prod_eq_0[simp]: fixes f :: "'a \ ennreal" shows "(prod f A = 0) = (finite A \ (\i\A. f i = 0))" by (induction A rule: infinite_finite_induct) auto lemma ennreal_prod_eq_top: fixes f :: "'a \ ennreal" shows "(\i\I. f i) = top \ (finite I \ ((\i\I. f i \ 0) \ (\i\I. f i = top)))" by (induction I rule: infinite_finite_induct) (auto simp: ennreal_mult_eq_top_iff) lemma ennreal_top_mult: "top * a = (if a = 0 then 0 else top :: ennreal)" by (simp add: ennreal_mult_eq_top_iff) lemma ennreal_mult_top: "a * top = (if a = 0 then 0 else top :: ennreal)" by (simp add: ennreal_mult_eq_top_iff) lemma enn2ereal_eq_top_iff[simp]: "enn2ereal x = \ \ x = top" by transfer (simp add: top_ereal_def) lemma enn2ereal_top[simp]: "enn2ereal top = \" by transfer (simp add: top_ereal_def) lemma e2ennreal_infty[simp]: "e2ennreal \ = top" by (simp add: top_ennreal.abs_eq top_ereal_def) lemma ennreal_top_minus[simp]: "top - x = (top::ennreal)" by transfer (auto simp: top_ereal_def max_def) lemma minus_top_ennreal: "x - top = (if x = top then top else 0:: ennreal)" by transfer (use ereal_eq_minus_iff top_ereal_def in force) lemma bot_ennreal: "bot = (0::ennreal)" by transfer rule lemma ennreal_of_nat_neq_top[simp]: "of_nat i \ (top::ennreal)" by (induction i) auto lemma numeral_eq_of_nat: "(numeral a::ennreal) = of_nat (numeral a)" by simp lemma of_nat_less_top: "of_nat i < (top::ennreal)" using less_le_trans[of "of_nat i" "of_nat (Suc i)" "top::ennreal"] by simp lemma top_neq_numeral[simp]: "top \ (numeral i::ennreal)" using of_nat_less_top[of "numeral i"] by simp lemma ennreal_numeral_less_top[simp]: "numeral i < (top::ennreal)" using of_nat_less_top[of "numeral i"] by simp lemma ennreal_add_bot[simp]: "bot + x = (x::ennreal)" by transfer simp lemma add_top_right_ennreal [simp]: "x + top = (top :: ennreal)" by (cases x) auto lemma add_top_left_ennreal [simp]: "top + x = (top :: ennreal)" by (cases x) auto lemma ennreal_top_mult_left [simp]: "x \ 0 \ x * top = (top :: ennreal)" by (subst ennreal_mult_eq_top_iff) auto lemma ennreal_top_mult_right [simp]: "x \ 0 \ top * x = (top :: ennreal)" by (subst ennreal_mult_eq_top_iff) auto lemma power_top_ennreal [simp]: "n > 0 \ top ^ n = (top :: ennreal)" by (induction n) auto lemma power_eq_top_ennreal_iff: "x ^ n = top \ x = (top :: ennreal) \ n > 0" by (induction n) (auto simp: ennreal_mult_eq_top_iff) lemma ennreal_mult_le_mult_iff: "c \ 0 \ c \ top \ c * a \ c * b \ a \ (b :: ennreal)" including ennreal.lifting by (transfer, subst ereal_mult_le_mult_iff) (auto simp: top_ereal_def) lemma power_mono_ennreal: "x \ y \ x ^ n \ (y ^ n :: ennreal)" by (induction n) (auto intro!: mult_mono) instance ennreal :: semiring_char_0 proof (standard, safe intro!: linorder_injI) have *: "1 + of_nat k \ (0::ennreal)" for k using add_pos_nonneg[OF zero_less_one, of "of_nat k :: ennreal"] by auto fix x y :: nat assume "x < y" "of_nat x = (of_nat y::ennreal)" then show False by (auto simp add: less_iff_Suc_add *) qed subsection \Arithmetic\ lemma ennreal_minus_zero[simp]: "a - (0::ennreal) = a" by transfer (auto simp: max_def) lemma ennreal_add_diff_cancel_right[simp]: fixes x y z :: ennreal shows "y \ top \ (x + y) - y = x" by transfer (metis ereal_eq_minus_iff max_absorb2 not_MInfty_nonneg top_ereal_def) lemma ennreal_add_diff_cancel_left[simp]: fixes x y z :: ennreal shows "y \ top \ (y + x) - y = x" by (simp add: add.commute) lemma fixes a b :: ennreal shows "a - b = 0 \ a \ b" by transfer (metis ereal_diff_gr0 le_cases max.absorb2 not_less) lemma ennreal_minus_cancel: fixes a b c :: ennreal shows "c \ top \ a \ c \ b \ c \ c - a = c - b \ a = b" - apply transfer - subgoal for a b c - by (cases a b c rule: ereal3_cases) - (auto simp: top_ereal_def max_def split: if_splits) - done + by (metis ennreal_add_diff_cancel_left ennreal_add_diff_cancel_right ennreal_add_eq_top less_eqE) lemma sup_const_add_ennreal: fixes a b c :: "ennreal" shows "sup (c + a) (c + b) = c + sup a b" by transfer (metis add_left_mono le_cases sup.absorb2 sup.orderE) lemma ennreal_diff_add_assoc: fixes a b c :: ennreal shows "a \ b \ c + b - a = c + (b - a)" - apply transfer - subgoal for a b c - by (cases a b c rule: ereal3_cases) (auto simp: field_simps max_absorb2) - done + by (metis add.left_commute ennreal_add_diff_cancel_left ennreal_add_eq_top ennreal_top_minus less_eqE) lemma mult_divide_eq_ennreal: fixes a b :: ennreal shows "b \ 0 \ b \ top \ (a * b) / b = a" unfolding divide_ennreal_def apply transfer - apply (subst mult.assoc) - apply (simp add: top_ereal_def flip: divide_ereal_def) - done + by (metis abs_ereal_ge0 divide_ereal_def ereal_divide_eq ereal_times_divide_eq top_ereal_def) lemma divide_mult_eq: "a \ 0 \ a \ \ \ x * a / (b * a) = x / (b::ennreal)" unfolding divide_ennreal_def infinity_ennreal_def apply transfer subgoal for a b c apply (cases a b c rule: ereal3_cases) apply (auto simp: top_ereal_def) done done lemma ennreal_mult_divide_eq: fixes a b :: ennreal shows "b \ 0 \ b \ top \ (a * b) / b = a" - unfolding divide_ennreal_def - apply transfer - apply (subst mult.assoc) - apply (simp add: top_ereal_def flip: divide_ereal_def) - done + by (fact mult_divide_eq_ennreal) lemma ennreal_add_diff_cancel: fixes a b :: ennreal shows "b \ \ \ (a + b) - b = a" - unfolding infinity_ennreal_def - by transfer (simp add: max_absorb2 top_ereal_def ereal_add_diff_cancel) + by simp lemma ennreal_minus_eq_0: "a - b = 0 \ a \ (b::ennreal)" by transfer (metis ereal_diff_gr0 le_cases max.absorb2 not_less) lemma ennreal_mono_minus_cancel: fixes a b c :: ennreal shows "a - b \ a - c \ a < top \ b \ a \ c \ a \ c \ b" by transfer (auto simp add: max.absorb2 ereal_diff_positive top_ereal_def dest: ereal_mono_minus_cancel) lemma ennreal_mono_minus: fixes a b c :: ennreal shows "c \ b \ a - b \ a - c" by transfer (meson ereal_minus_mono max.mono order_refl) lemma ennreal_minus_pos_iff: fixes a b :: ennreal shows "a < top \ b < top \ 0 < a - b \ b < a" by transfer (use add.left_neutral ereal_minus_le_iff less_irrefl not_less in fastforce) lemma ennreal_inverse_top[simp]: "inverse top = (0::ennreal)" by transfer (simp add: top_ereal_def ereal_inverse_eq_0) lemma ennreal_inverse_zero[simp]: "inverse 0 = (top::ennreal)" by transfer (simp add: top_ereal_def ereal_inverse_eq_0) lemma ennreal_top_divide: "top / (x::ennreal) = (if x = top then 0 else top)" unfolding divide_ennreal_def by transfer (simp add: top_ereal_def ereal_inverse_eq_0 ereal_0_gt_inverse) lemma ennreal_zero_divide[simp]: "0 / (x::ennreal) = 0" by (simp add: divide_ennreal_def) lemma ennreal_divide_zero[simp]: "x / (0::ennreal) = (if x = 0 then 0 else top)" by (simp add: divide_ennreal_def ennreal_mult_top) lemma ennreal_divide_top[simp]: "x / (top::ennreal) = 0" by (simp add: divide_ennreal_def ennreal_top_mult) lemma ennreal_times_divide: "a * (b / c) = a * b / (c::ennreal)" unfolding divide_ennreal_def by transfer (simp add: divide_ereal_def[symmetric] ereal_times_divide_eq) lemma ennreal_zero_less_divide: "0 < a / b \ (0 < a \ b < (top::ennreal))" unfolding divide_ennreal_def by transfer (auto simp: ereal_zero_less_0_iff top_ereal_def ereal_0_gt_inverse) lemma add_divide_distrib_ennreal: "(a + b) / c = a / c + b / (c :: ennreal)" by (simp add: divide_ennreal_def ring_distribs) lemma divide_right_mono_ennreal: fixes a b c :: ennreal shows "a \ b \ a / c \ b / c" unfolding divide_ennreal_def by (intro mult_mono) auto lemma ennreal_mult_strict_right_mono: "(a::ennreal) < c \ 0 < b \ b < top \ a * b < c * b" by transfer (auto intro!: ereal_mult_strict_right_mono) lemma ennreal_indicator_less[simp]: "indicator A x \ (indicator B x::ennreal) \ (x \ A \ x \ B)" by (simp add: indicator_def not_le) lemma ennreal_inverse_positive: "0 < inverse x \ (x::ennreal) \ top" by transfer (simp add: ereal_0_gt_inverse top_ereal_def) lemma ennreal_inverse_mult': "((0 < b \ a < top) \ (0 < a \ b < top)) \ inverse (a * b::ennreal) = inverse a * inverse b" apply transfer subgoal for a b by (cases a b rule: ereal2_cases) (auto simp: top_ereal_def) done lemma ennreal_inverse_mult: "a < top \ b < top \ inverse (a * b::ennreal) = inverse a * inverse b" apply transfer subgoal for a b by (cases a b rule: ereal2_cases) (auto simp: top_ereal_def) done lemma ennreal_inverse_1[simp]: "inverse (1::ennreal) = 1" by transfer simp lemma ennreal_inverse_eq_0_iff[simp]: "inverse (a::ennreal) = 0 \ a = top" by transfer (simp add: ereal_inverse_eq_0 top_ereal_def) lemma ennreal_inverse_eq_top_iff[simp]: "inverse (a::ennreal) = top \ a = 0" by transfer (simp add: top_ereal_def) lemma ennreal_divide_eq_0_iff[simp]: "(a::ennreal) / b = 0 \ (a = 0 \ b = top)" by (simp add: divide_ennreal_def) lemma ennreal_divide_eq_top_iff: "(a::ennreal) / b = top \ ((a \ 0 \ b = 0) \ (a = top \ b \ top))" by (auto simp add: divide_ennreal_def ennreal_mult_eq_top_iff) lemma one_divide_one_divide_ennreal[simp]: "1 / (1 / c) = (c::ennreal)" including ennreal.lifting unfolding divide_ennreal_def by transfer auto lemma ennreal_mult_left_cong: "((a::ennreal) \ 0 \ b = c) \ a * b = a * c" by (cases "a = 0") simp_all lemma ennreal_mult_right_cong: "((a::ennreal) \ 0 \ b = c) \ b * a = c * a" by (cases "a = 0") simp_all lemma ennreal_zero_less_mult_iff: "0 < a * b \ 0 < a \ 0 < (b::ennreal)" by transfer (auto simp add: ereal_zero_less_0_iff le_less) lemma less_diff_eq_ennreal: fixes a b c :: ennreal shows "b < top \ c < top \ a < b - c \ a + c < b" apply transfer subgoal for a b c by (cases a b c rule: ereal3_cases) (auto split: split_max) done lemma diff_add_cancel_ennreal: fixes a b :: ennreal shows "a \ b \ b - a + a = b" unfolding infinity_ennreal_def by transfer (metis (no_types) add.commute ereal_diff_positive ereal_ineq_diff_add max_def not_MInfty_nonneg) lemma ennreal_diff_self[simp]: "a \ top \ a - a = (0::ennreal)" by transfer (simp add: top_ereal_def) lemma ennreal_minus_mono: fixes a b c :: ennreal shows "a \ c \ d \ b \ a - b \ c - d" by transfer (meson ereal_minus_mono max.mono order_refl) lemma ennreal_minus_eq_top[simp]: "a - (b::ennreal) = top \ a = top" - by transfer (auto simp: top_ereal_def max.absorb2 ereal_minus_eq_PInfty_iff split: split_max) + by (metis add_top diff_add_cancel_ennreal ennreal_mono_minus ennreal_top_minus zero_le) lemma ennreal_divide_self[simp]: "a \ 0 \ a < top \ a / a = (1::ennreal)" - unfolding divide_ennreal_def - apply transfer - subgoal for a - by (cases a) (auto simp: top_ereal_def) - done + by (metis mult_1 mult_divide_eq_ennreal top.not_eq_extremum) subsection \Coercion from \<^typ>\real\ to \<^typ>\ennreal\\ lift_definition ennreal :: "real \ ennreal" is "sup 0 \ ereal" by simp declare [[coercion ennreal]] -lemma ennreal_cong: "x = y \ ennreal x = ennreal y" by simp +lemma ennreal_cong: "x = y \ ennreal x = ennreal y" + by simp lemma ennreal_cases[cases type: ennreal]: fixes x :: ennreal obtains (real) r :: real where "0 \ r" "x = ennreal r" | (top) "x = top" apply transfer subgoal for x thesis by (cases x) (auto simp: max.absorb2 top_ereal_def) done lemmas ennreal2_cases = ennreal_cases[case_product ennreal_cases] lemmas ennreal3_cases = ennreal_cases[case_product ennreal2_cases] lemma ennreal_neq_top[simp]: "ennreal r \ top" by transfer (simp add: top_ereal_def zero_ereal_def flip: ereal_max) lemma top_neq_ennreal[simp]: "top \ ennreal r" using ennreal_neq_top[of r] by (auto simp del: ennreal_neq_top) lemma ennreal_less_top[simp]: "ennreal x < top" by transfer (simp add: top_ereal_def max_def) lemma ennreal_neg: "x \ 0 \ ennreal x = 0" by transfer (simp add: max.absorb1) lemma ennreal_inj[simp]: "0 \ a \ 0 \ b \ ennreal a = ennreal b \ a = b" by (transfer fixing: a b) (auto simp: max_absorb2) lemma ennreal_le_iff[simp]: "0 \ y \ ennreal x \ ennreal y \ x \ y" by (auto simp: ennreal_def zero_ereal_def less_eq_ennreal.abs_eq eq_onp_def split: split_max) lemma le_ennreal_iff: "0 \ r \ x \ ennreal r \ (\q\0. x = ennreal q \ q \ r)" by (cases x) (auto simp: top_unique) lemma ennreal_less_iff: "0 \ r \ ennreal r < ennreal q \ r < q" unfolding not_le[symmetric] by auto lemma ennreal_eq_zero_iff[simp]: "0 \ x \ ennreal x = 0 \ x = 0" by transfer (auto simp: max_absorb2) lemma ennreal_less_zero_iff[simp]: "0 < ennreal x \ 0 < x" by transfer (auto simp: max_def) lemma ennreal_lessI: "0 < q \ r < q \ ennreal r < ennreal q" by (cases "0 \ r") (auto simp: ennreal_less_iff ennreal_neg) lemma ennreal_leI: "x \ y \ ennreal x \ ennreal y" by (cases "0 \ y") (auto simp: ennreal_neg) lemma enn2ereal_ennreal[simp]: "0 \ x \ enn2ereal (ennreal x) = x" by transfer (simp add: max_absorb2) lemma e2ennreal_enn2ereal[simp]: "e2ennreal (enn2ereal x) = x" by (simp add: e2ennreal_def max_absorb2 ennreal.enn2ereal_inverse) lemma enn2ereal_e2ennreal: "x \ 0 \ enn2ereal (e2ennreal x) = x" by (metis e2ennreal_enn2ereal ereal_ennreal_cases not_le) lemma e2ennreal_ereal [simp]: "e2ennreal (ereal x) = ennreal x" by (metis e2ennreal_def enn2ereal_inverse ennreal.rep_eq sup_ereal_def) lemma ennreal_0[simp]: "ennreal 0 = 0" by (simp add: ennreal_def max.absorb1 zero_ennreal.abs_eq) lemma ennreal_1[simp]: "ennreal 1 = 1" by transfer (simp add: max_absorb2) lemma ennreal_eq_0_iff: "ennreal x = 0 \ x \ 0" by (cases "0 \ x") (auto simp: ennreal_neg) lemma ennreal_le_iff2: "ennreal x \ ennreal y \ ((0 \ y \ x \ y) \ (x \ 0 \ y \ 0))" by (cases "0 \ y") (auto simp: ennreal_eq_0_iff ennreal_neg) lemma ennreal_eq_1[simp]: "ennreal x = 1 \ x = 1" by (cases "0 \ x") (auto simp: ennreal_neg simp flip: ennreal_1) lemma ennreal_le_1[simp]: "ennreal x \ 1 \ x \ 1" by (cases "0 \ x") (auto simp: ennreal_neg simp flip: ennreal_1) lemma ennreal_ge_1[simp]: "ennreal x \ 1 \ x \ 1" by (cases "0 \ x") (auto simp: ennreal_neg simp flip: ennreal_1) lemma one_less_ennreal[simp]: "1 < ennreal x \ 1 < x" - by transfer (auto simp: max.absorb2 less_max_iff_disj) + by (meson ennreal_le_1 linorder_not_le) lemma ennreal_plus[simp]: "0 \ a \ 0 \ b \ ennreal (a + b) = ennreal a + ennreal b" by (transfer fixing: a b) (auto simp: max_absorb2) lemma add_mono_ennreal: "x < ennreal y \ x' < ennreal y' \ x + x' < ennreal (y + y')" by (metis (full_types) add_strict_mono ennreal_less_zero_iff ennreal_plus less_le not_less zero_le) lemma sum_ennreal[simp]: "(\i. i \ I \ 0 \ f i) \ (\i\I. ennreal (f i)) = ennreal (sum f I)" by (induction I rule: infinite_finite_induct) (auto simp: sum_nonneg) lemma sum_list_ennreal[simp]: assumes "\x. x \ set xs \ f x \ 0" shows "sum_list (map (\x. ennreal (f x)) xs) = ennreal (sum_list (map f xs))" using assms proof (induction xs) case (Cons x xs) from Cons have "(\x\x # xs. ennreal (f x)) = ennreal (f x) + ennreal (sum_list (map f xs))" by simp also from Cons.prems have "\ = ennreal (f x + sum_list (map f xs))" by (intro ennreal_plus [symmetric] sum_list_nonneg) auto finally show ?case by simp qed simp_all lemma ennreal_of_nat_eq_real_of_nat: "of_nat i = ennreal (of_nat i)" by (induction i) simp_all lemma of_nat_le_ennreal_iff[simp]: "0 \ r \ of_nat i \ ennreal r \ of_nat i \ r" by (simp add: ennreal_of_nat_eq_real_of_nat) lemma ennreal_le_of_nat_iff[simp]: "ennreal r \ of_nat i \ r \ of_nat i" by (simp add: ennreal_of_nat_eq_real_of_nat) lemma ennreal_indicator: "ennreal (indicator A x) = indicator A x" by (auto split: split_indicator) lemma ennreal_numeral[simp]: "ennreal (numeral n) = numeral n" using ennreal_of_nat_eq_real_of_nat[of "numeral n"] by simp lemma ennreal_less_numeral_iff [simp]: "ennreal n < numeral w \ n < numeral w" by (metis ennreal_less_iff ennreal_numeral less_le not_less zero_less_numeral) lemma numeral_less_ennreal_iff [simp]: "numeral w < ennreal n \ numeral w < n" using ennreal_less_iff zero_le_numeral by fastforce lemma numeral_le_ennreal_iff [simp]: "numeral n \ ennreal m \ numeral n \ m" by (metis not_le ennreal_less_numeral_iff) lemma min_ennreal: "0 \ x \ 0 \ y \ min (ennreal x) (ennreal y) = ennreal (min x y)" by (auto split: split_min) lemma ennreal_half[simp]: "ennreal (1/2) = inverse 2" by transfer (simp add: max.absorb2) lemma ennreal_minus: "0 \ q \ ennreal r - ennreal q = ennreal (r - q)" by transfer (simp add: max.absorb2 zero_ereal_def flip: ereal_max) lemma ennreal_minus_top[simp]: "ennreal a - top = 0" by (simp add: minus_top_ennreal) lemma e2eenreal_enn2ereal_diff [simp]: "e2ennreal(enn2ereal x - enn2ereal y) = x - y" for x y by (cases x, cases y, auto simp add: ennreal_minus e2ennreal_neg) lemma ennreal_mult: "0 \ a \ 0 \ b \ ennreal (a * b) = ennreal a * ennreal b" by transfer (simp add: max_absorb2) lemma ennreal_mult': "0 \ a \ ennreal (a * b) = ennreal a * ennreal b" by (cases "0 \ b") (auto simp: ennreal_mult ennreal_neg mult_nonneg_nonpos) lemma indicator_mult_ennreal: "indicator A x * ennreal r = ennreal (indicator A x * r)" by (simp split: split_indicator) lemma ennreal_mult'': "0 \ b \ ennreal (a * b) = ennreal a * ennreal b" by (cases "0 \ a") (auto simp: ennreal_mult ennreal_neg mult_nonpos_nonneg) lemma numeral_mult_ennreal: "0 \ x \ numeral b * ennreal x = ennreal (numeral b * x)" by (simp add: ennreal_mult) lemma ennreal_power: "0 \ r \ ennreal r ^ n = ennreal (r ^ n)" by (induction n) (auto simp: ennreal_mult) lemma power_eq_top_ennreal: "x ^ n = top \ (n \ 0 \ (x::ennreal) = top)" by (cases x rule: ennreal_cases) (auto simp: ennreal_power top_power_ennreal) lemma inverse_ennreal: "0 < r \ inverse (ennreal r) = ennreal (inverse r)" by transfer (simp add: max.absorb2) lemma divide_ennreal: "0 \ r \ 0 < q \ ennreal r / ennreal q = ennreal (r / q)" by (simp add: divide_ennreal_def inverse_ennreal ennreal_mult[symmetric] inverse_eq_divide) lemma ennreal_inverse_power: "inverse (x ^ n :: ennreal) = inverse x ^ n" proof (cases x rule: ennreal_cases) case top with power_eq_top_ennreal[of x n] show ?thesis by (cases "n = 0") auto next case (real r) then show ?thesis - proof cases - assume "x = 0" then show ?thesis - using power_eq_top_ennreal[of top "n - 1"] - by (cases n) (auto simp: ennreal_top_mult) - next - assume "x \ 0" - with real have "0 < r" by auto - with real show ?thesis - by (induction n) - (auto simp add: ennreal_power ennreal_mult[symmetric] inverse_ennreal) - qed + proof (cases "x = 0") + case False then show ?thesis + by (smt (verit, best) ennreal_0 ennreal_power inverse_ennreal + inverse_nonnegative_iff_nonnegative power_inverse real zero_less_power) + qed (simp add: top_power_ennreal) qed lemma power_divide_distrib_ennreal [algebra_simps]: "(x / y) ^ n = x ^ n / (y ^ n :: ennreal)" by (simp add: divide_ennreal_def algebra_simps ennreal_inverse_power) lemma ennreal_divide_numeral: "0 \ x \ ennreal x / numeral b = ennreal (x / numeral b)" by (subst divide_ennreal[symmetric]) auto lemma prod_ennreal: "(\i. i \ A \ 0 \ f i) \ (\i\A. ennreal (f i)) = ennreal (prod f A)" by (induction A rule: infinite_finite_induct) (auto simp: ennreal_mult prod_nonneg) lemma prod_mono_ennreal: assumes "\x. x \ A \ f x \ (g x :: ennreal)" shows "prod f A \ prod g A" using assms by (induction A rule: infinite_finite_induct) (auto intro!: mult_mono) lemma mult_right_ennreal_cancel: "a * ennreal c = b * ennreal c \ (a = b \ c \ 0)" proof (cases "0 \ c") case True then show ?thesis by (metis ennreal_eq_0_iff ennreal_mult_right_cong ennreal_neq_top mult_divide_eq_ennreal) qed (use ennreal_neg in auto) lemma ennreal_le_epsilon: "(\e::real. y < top \ 0 < e \ x \ y + ennreal e) \ x \ y" apply (cases y rule: ennreal_cases) apply (cases x rule: ennreal_cases) apply (auto simp flip: ennreal_plus simp add: top_unique intro: zero_less_one field_le_epsilon) done lemma ennreal_rat_dense: fixes x y :: ennreal shows "x < y \ \r::rat. x < real_of_rat r \ real_of_rat r < y" proof transfer fix x y :: ereal assume xy: "0 \ x" "0 \ y" "x < y" moreover from ereal_dense3[OF \x < y\] obtain r where r: "x < ereal (real_of_rat r)" "ereal (real_of_rat r) < y" by auto then have "0 \ r" using le_less_trans[OF \0 \ x\ \x < ereal (real_of_rat r)\] by auto with r show "\r. x < (sup 0 \ ereal) (real_of_rat r) \ (sup 0 \ ereal) (real_of_rat r) < y" by (intro exI[of _ r]) (auto simp: max_absorb2) qed lemma ennreal_Ex_less_of_nat: "(x::ennreal) < top \ \n. x < of_nat n" by (cases x rule: ennreal_cases) (auto simp: ennreal_of_nat_eq_real_of_nat ennreal_less_iff reals_Archimedean2) subsection \Coercion from \<^typ>\ennreal\ to \<^typ>\real\\ definition "enn2real x = real_of_ereal (enn2ereal x)" lemma enn2real_nonneg[simp]: "0 \ enn2real x" by (auto simp: enn2real_def intro!: real_of_ereal_pos enn2ereal_nonneg) lemma enn2real_mono: "a \ b \ b < top \ enn2real a \ enn2real b" by (auto simp add: enn2real_def less_eq_ennreal.rep_eq intro!: real_of_ereal_positive_mono enn2ereal_nonneg) lemma enn2real_of_nat[simp]: "enn2real (of_nat n) = n" by (auto simp: enn2real_def) lemma enn2real_ennreal[simp]: "0 \ r \ enn2real (ennreal r) = r" by (simp add: enn2real_def) lemma ennreal_enn2real[simp]: "r < top \ ennreal (enn2real r) = r" by (cases r rule: ennreal_cases) auto lemma real_of_ereal_enn2ereal[simp]: "real_of_ereal (enn2ereal x) = enn2real x" by (simp add: enn2real_def) lemma enn2real_top[simp]: "enn2real top = 0" unfolding enn2real_def top_ennreal.rep_eq top_ereal_def by simp lemma enn2real_0[simp]: "enn2real 0 = 0" unfolding enn2real_def zero_ennreal.rep_eq by simp lemma enn2real_1[simp]: "enn2real 1 = 1" unfolding enn2real_def one_ennreal.rep_eq by simp lemma enn2real_numeral[simp]: "enn2real (numeral n) = (numeral n)" unfolding enn2real_def by simp lemma enn2real_mult: "enn2real (a * b) = enn2real a * enn2real b" unfolding enn2real_def by (simp del: real_of_ereal_enn2ereal add: times_ennreal.rep_eq) lemma enn2real_leI: "0 \ B \ x \ ennreal B \ enn2real x \ B" by (cases x rule: ennreal_cases) (auto simp: top_unique) lemma enn2real_positive_iff: "0 < enn2real x \ (0 < x \ x < top)" by (cases x rule: ennreal_cases) auto lemma enn2real_eq_posreal_iff[simp]: "c > 0 \ enn2real x = c \ x = c" by (cases x) auto lemma ennreal_enn2real_if: "ennreal (enn2real r) = (if r = top then 0 else r)" by(auto intro!: ennreal_enn2real simp add: less_top) subsection \Coercion from \<^typ>\enat\ to \<^typ>\ennreal\\ definition ennreal_of_enat :: "enat \ ennreal" where "ennreal_of_enat n = (case n of \ \ top | enat n \ of_nat n)" declare [[coercion ennreal_of_enat]] declare [[coercion "of_nat :: nat \ ennreal"]] lemma ennreal_of_enat_infty[simp]: "ennreal_of_enat \ = \" by (simp add: ennreal_of_enat_def) lemma ennreal_of_enat_enat[simp]: "ennreal_of_enat (enat n) = of_nat n" by (simp add: ennreal_of_enat_def) lemma ennreal_of_enat_0[simp]: "ennreal_of_enat 0 = 0" using ennreal_of_enat_enat[of 0] unfolding enat_0 by simp lemma ennreal_of_enat_1[simp]: "ennreal_of_enat 1 = 1" using ennreal_of_enat_enat[of 1] unfolding enat_1 by simp lemma ennreal_top_neq_of_nat[simp]: "(top::ennreal) \ of_nat i" using ennreal_of_nat_neq_top[of i] by metis lemma ennreal_of_enat_inj[simp]: "ennreal_of_enat i = ennreal_of_enat j \ i = j" by (cases i j rule: enat.exhaust[case_product enat.exhaust]) auto lemma ennreal_of_enat_le_iff[simp]: "ennreal_of_enat m \ ennreal_of_enat n \ m \ n" by (auto simp: ennreal_of_enat_def top_unique split: enat.split) lemma of_nat_less_ennreal_of_nat[simp]: "of_nat n \ ennreal_of_enat x \ of_nat n \ x" by (cases x) (auto simp: of_nat_eq_enat) lemma ennreal_of_enat_Sup: "ennreal_of_enat (Sup X) = (SUP x\X. ennreal_of_enat x)" proof - have "ennreal_of_enat (Sup X) \ (SUP x \ X. ennreal_of_enat x)" unfolding Sup_enat_def proof (clarsimp, intro conjI impI) fix x assume "finite X" "X \ {}" then show "ennreal_of_enat (Max X) \ (SUP x \ X. ennreal_of_enat x)" by (intro SUP_upper Max_in) next assume "infinite X" "X \ {}" have "\y\X. r < ennreal_of_enat y" if r: "r < top" for r proof - obtain n where n: "r < of_nat n" using ennreal_Ex_less_of_nat[OF r] .. have "\ (X \ enat ` {.. n})" using \infinite X\ by (auto dest: finite_subset) then obtain x where x: "x \ X" "x \ enat ` {..n}" by blast then have "of_nat n \ x" by (cases x) (auto simp: of_nat_eq_enat) with x show ?thesis by (auto intro!: bexI[of _ x] less_le_trans[OF n]) qed then have "(SUP x \ X. ennreal_of_enat x) = top" by simp then show "top \ (SUP x \ X. ennreal_of_enat x)" unfolding top_unique by simp qed then show ?thesis by (auto intro!: antisym Sup_least intro: Sup_upper) qed lemma ennreal_of_enat_eSuc[simp]: "ennreal_of_enat (eSuc x) = 1 + ennreal_of_enat x" by (cases x) (auto simp: eSuc_enat) (* Contributed by Dominique Unruh *) lemma ennreal_of_enat_plus[simp]: \ennreal_of_enat (a+b) = ennreal_of_enat a + ennreal_of_enat b\ apply (induct a) apply (metis enat.exhaust ennreal_add_eq_top ennreal_of_enat_enat ennreal_of_enat_infty infinity_ennreal_def of_nat_add plus_enat_simps(1) plus_eq_infty_iff_enat) apply simp done (* Contributed by Dominique Unruh *) lemma sum_ennreal_of_enat[simp]: "(\i\I. ennreal_of_enat (f i)) = ennreal_of_enat (sum f I)" by (induct I rule: infinite_finite_induct) (auto simp: sum_nonneg) subsection \Topology on \<^typ>\ennreal\\ lemma enn2ereal_Iio: "enn2ereal -` {.. a then {..< e2ennreal a} else {})" using enn2ereal_nonneg by (cases a rule: ereal_ennreal_cases) (auto simp add: vimage_def set_eq_iff ennreal.enn2ereal_inverse less_ennreal.rep_eq e2ennreal_def max_absorb2 simp del: enn2ereal_nonneg intro: le_less_trans less_imp_le) lemma enn2ereal_Ioi: "enn2ereal -` {a <..} = (if 0 \ a then {e2ennreal a <..} else UNIV)" by (cases a rule: ereal_ennreal_cases) (auto simp add: vimage_def set_eq_iff ennreal.enn2ereal_inverse less_ennreal.rep_eq e2ennreal_def max_absorb2 intro: less_le_trans) instantiation ennreal :: linear_continuum_topology begin definition open_ennreal :: "ennreal set \ bool" where "(open :: ennreal set \ bool) = generate_topology (range lessThan \ range greaterThan)" instance proof show "\a b::ennreal. a \ b" using zero_neq_one by (intro exI) show "\x y::ennreal. x < y \ \z>x. z < y" proof transfer fix x y :: ereal assume *: "0 \ x" assume "x < y" from dense[OF this] obtain z where "x < z \ z < y" .. with * show "\z\Collect ((\) 0). x < z \ z < y" by (intro bexI[of _ z]) auto qed qed (rule open_ennreal_def) end lemma continuous_on_e2ennreal: "continuous_on A e2ennreal" proof (rule continuous_on_subset) show "continuous_on ({0..} \ {..0}) e2ennreal" proof (rule continuous_on_closed_Un) show "continuous_on {0 ..} e2ennreal" by (rule continuous_onI_mono) (auto simp add: less_eq_ennreal.abs_eq eq_onp_def enn2ereal_range) show "continuous_on {.. 0} e2ennreal" by (subst continuous_on_cong[OF refl, of _ _ "\_. 0"]) (auto simp add: e2ennreal_neg continuous_on_const) qed auto show "A \ {0..} \ {..0::ereal}" by auto qed lemma continuous_at_e2ennreal: "continuous (at x within A) e2ennreal" by (rule continuous_on_imp_continuous_within[OF continuous_on_e2ennreal, of _ UNIV]) auto lemma continuous_on_enn2ereal: "continuous_on UNIV enn2ereal" by (rule continuous_on_generate_topology[OF open_generated_order]) (auto simp add: enn2ereal_Iio enn2ereal_Ioi) lemma continuous_at_enn2ereal: "continuous (at x within A) enn2ereal" by (rule continuous_on_imp_continuous_within[OF continuous_on_enn2ereal]) auto lemma sup_continuous_e2ennreal[order_continuous_intros]: assumes f: "sup_continuous f" shows "sup_continuous (\x. e2ennreal (f x))" proof (rule sup_continuous_compose[OF _ f]) show "sup_continuous e2ennreal" by (simp add: continuous_at_e2ennreal continuous_at_left_imp_sup_continuous e2ennreal_mono mono_def) qed lemma sup_continuous_enn2ereal[order_continuous_intros]: assumes f: "sup_continuous f" shows "sup_continuous (\x. enn2ereal (f x))" proof (rule sup_continuous_compose[OF _ f]) show "sup_continuous enn2ereal" by (simp add: continuous_at_enn2ereal continuous_at_left_imp_sup_continuous less_eq_ennreal.rep_eq mono_def) qed lemma sup_continuous_mult_left_ennreal': fixes c :: "ennreal" shows "sup_continuous (\x. c * x)" unfolding sup_continuous_def by transfer (auto simp: SUP_ereal_mult_left max.absorb2 SUP_upper2) lemma sup_continuous_mult_left_ennreal[order_continuous_intros]: "sup_continuous f \ sup_continuous (\x. c * f x :: ennreal)" by (rule sup_continuous_compose[OF sup_continuous_mult_left_ennreal']) lemma sup_continuous_mult_right_ennreal[order_continuous_intros]: "sup_continuous f \ sup_continuous (\x. f x * c :: ennreal)" using sup_continuous_mult_left_ennreal[of f c] by (simp add: mult.commute) lemma sup_continuous_divide_ennreal[order_continuous_intros]: fixes f g :: "'a::complete_lattice \ ennreal" shows "sup_continuous f \ sup_continuous (\x. f x / c)" unfolding divide_ennreal_def by (rule sup_continuous_mult_right_ennreal) lemma transfer_enn2ereal_continuous_on [transfer_rule]: "rel_fun (=) (rel_fun (rel_fun (=) pcr_ennreal) (=)) continuous_on continuous_on" proof - have "continuous_on A f" if "continuous_on A (\x. enn2ereal (f x))" for A and f :: "'a \ ennreal" using continuous_on_compose2[OF continuous_on_e2ennreal[of "{0..}"] that] by (auto simp: ennreal.enn2ereal_inverse subset_eq e2ennreal_def max_absorb2) moreover have "continuous_on A (\x. enn2ereal (f x))" if "continuous_on A f" for A and f :: "'a \ ennreal" using continuous_on_compose2[OF continuous_on_enn2ereal that] by auto ultimately show ?thesis by (auto simp add: rel_fun_def ennreal.pcr_cr_eq cr_ennreal_def) qed lemma transfer_sup_continuous[transfer_rule]: "(rel_fun (rel_fun (=) pcr_ennreal) (=)) sup_continuous sup_continuous" proof (safe intro!: rel_funI dest!: rel_fun_eq_pcr_ennreal[THEN iffD1]) show "sup_continuous (enn2ereal \ f) \ sup_continuous f" for f :: "'a \ _" using sup_continuous_e2ennreal[of "enn2ereal \ f"] by simp show "sup_continuous f \ sup_continuous (enn2ereal \ f)" for f :: "'a \ _" using sup_continuous_enn2ereal[of f] by (simp add: comp_def) qed lemma continuous_on_ennreal[tendsto_intros]: "continuous_on A f \ continuous_on A (\x. ennreal (f x))" by transfer (auto intro!: continuous_on_max continuous_on_const continuous_on_ereal) lemma tendsto_ennrealD: assumes lim: "((\x. ennreal (f x)) \ ennreal x) F" assumes *: "\\<^sub>F x in F. 0 \ f x" and x: "0 \ x" shows "(f \ x) F" proof - have "((\x. enn2ereal (ennreal (f x))) \ enn2ereal (ennreal x)) F \ (f \ enn2ereal (ennreal x)) F" using "*" eventually_mono by (intro tendsto_cong) fastforce then show ?thesis using assms(1) continuous_at_enn2ereal isCont_tendsto_compose x by fastforce qed lemma tendsto_ennreal_iff [simp]: \((\x. ennreal (f x)) \ ennreal x) F \ (f \ x) F\ (is \?P \ ?Q\) if \\\<^sub>F x in F. 0 \ f x\ \0 \ x\ proof assume \?P\ then show \?Q\ using that by (rule tendsto_ennrealD) next assume \?Q\ have \continuous_on UNIV ereal\ using continuous_on_ereal [of _ id] by simp then have \continuous_on UNIV (e2ennreal \ ereal)\ by (rule continuous_on_compose) (simp_all add: continuous_on_e2ennreal) then have \((\x. (e2ennreal \ ereal) (f x)) \ (e2ennreal \ ereal) x) F\ using \?Q\ by (rule continuous_on_tendsto_compose) simp_all then show \?P\ by (simp flip: e2ennreal_ereal) qed lemma tendsto_enn2ereal_iff[simp]: "((\i. enn2ereal (f i)) \ enn2ereal x) F \ (f \ x) F" using continuous_on_enn2ereal[THEN continuous_on_tendsto_compose, of f x F] continuous_on_e2ennreal[THEN continuous_on_tendsto_compose, of "\x. enn2ereal (f x)" "enn2ereal x" F UNIV] by auto lemma ennreal_tendsto_0_iff: "(\n. f n \ 0) \ ((\n. ennreal (f n)) \ 0) \ (f \ 0)" by (metis (mono_tags) ennreal_0 eventuallyI order_refl tendsto_ennreal_iff) lemma continuous_on_add_ennreal: fixes f g :: "'a::topological_space \ ennreal" shows "continuous_on A f \ continuous_on A g \ continuous_on A (\x. f x + g x)" by (transfer fixing: A) (auto intro!: tendsto_add_ereal_nonneg simp: continuous_on_def) lemma continuous_on_inverse_ennreal[continuous_intros]: fixes f :: "'a::topological_space \ ennreal" shows "continuous_on A f \ continuous_on A (\x. inverse (f x))" proof (transfer fixing: A) show "pred_fun top ((\) 0) f \ continuous_on A (\x. inverse (f x))" if "continuous_on A f" for f :: "'a \ ereal" using continuous_on_compose2[OF continuous_on_inverse_ereal that] by (auto simp: subset_eq) qed instance ennreal :: topological_comm_monoid_add proof show "((\x. fst x + snd x) \ a + b) (nhds a \\<^sub>F nhds b)" for a b :: ennreal using continuous_on_add_ennreal[of UNIV fst snd] using tendsto_at_iff_tendsto_nhds[symmetric, of "\x::(ennreal \ ennreal). fst x + snd x"] by (auto simp: continuous_on_eq_continuous_at) (simp add: isCont_def nhds_prod[symmetric]) qed lemma sup_continuous_add_ennreal[order_continuous_intros]: fixes f g :: "'a::complete_lattice \ ennreal" shows "sup_continuous f \ sup_continuous g \ sup_continuous (\x. f x + g x)" by transfer (auto intro!: sup_continuous_add) lemma ennreal_suminf_lessD: "(\i. f i :: ennreal) < x \ f i < x" using le_less_trans[OF sum_le_suminf[OF summableI, of "{i}" f]] by simp lemma sums_ennreal[simp]: "(\i. 0 \ f i) \ 0 \ x \ (\i. ennreal (f i)) sums ennreal x \ f sums x" unfolding sums_def by (simp add: always_eventually sum_nonneg) lemma summable_suminf_not_top: "(\i. 0 \ f i) \ (\i. ennreal (f i)) \ top \ summable f" using summable_sums[OF summableI, of "\i. ennreal (f i)"] by (cases "\i. ennreal (f i)" rule: ennreal_cases) (auto simp: summable_def) lemma suminf_ennreal[simp]: "(\i. 0 \ f i) \ (\i. ennreal (f i)) \ top \ (\i. ennreal (f i)) = ennreal (\i. f i)" by (rule sums_unique[symmetric]) (simp add: summable_suminf_not_top suminf_nonneg summable_sums) lemma sums_enn2ereal[simp]: "(\i. enn2ereal (f i)) sums enn2ereal x \ f sums x" unfolding sums_def by (simp add: always_eventually sum_nonneg) lemma suminf_enn2ereal[simp]: "(\i. enn2ereal (f i)) = enn2ereal (suminf f)" by (rule sums_unique[symmetric]) (simp add: summable_sums) lemma transfer_e2ennreal_suminf [transfer_rule]: "rel_fun (rel_fun (=) pcr_ennreal) pcr_ennreal suminf suminf" by (auto simp: rel_funI rel_fun_eq_pcr_ennreal comp_def) lemma ennreal_suminf_cmult[simp]: "(\i. r * f i) = r * (\i. f i::ennreal)" by transfer (auto intro!: suminf_cmult_ereal) lemma ennreal_suminf_multc[simp]: "(\i. f i * r) = (\i. f i::ennreal) * r" using ennreal_suminf_cmult[of r f] by (simp add: ac_simps) lemma ennreal_suminf_divide[simp]: "(\i. f i / r) = (\i. f i::ennreal) / r" by (simp add: divide_ennreal_def) lemma ennreal_suminf_neq_top: "summable f \ (\i. 0 \ f i) \ (\i. ennreal (f i)) \ top" using sums_ennreal[of f "suminf f"] by (simp add: suminf_nonneg flip: sums_unique summable_sums_iff del: sums_ennreal) lemma suminf_ennreal_eq: "(\i. 0 \ f i) \ f sums x \ (\i. ennreal (f i)) = ennreal x" using suminf_nonneg[of f] sums_unique[of f x] by (intro sums_unique[symmetric]) (auto simp: summable_sums_iff) lemma ennreal_suminf_bound_add: fixes f :: "nat \ ennreal" shows "(\N. (\n x) \ suminf f + y \ x" by transfer (auto intro!: suminf_bound_add) lemma ennreal_suminf_SUP_eq_directed: fixes f :: "'a \ nat \ ennreal" assumes *: "\N i j. i \ I \ j \ I \ finite N \ \k\I. \n\N. f i n \ f k n \ f j n \ f k n" shows "(\n. SUP i\I. f i n) = (SUP i\I. \n. f i n)" proof cases assume "I \ {}" then obtain i where "i \ I" by auto from * show ?thesis by (transfer fixing: I) (auto simp: max_absorb2 SUP_upper2[OF \i \ I\] suminf_nonneg summable_ereal_pos \I \ {}\ intro!: suminf_SUP_eq_directed) qed (simp add: bot_ennreal) lemma INF_ennreal_add_const: fixes f g :: "nat \ ennreal" shows "(INF i. f i + c) = (INF i. f i) + c" using continuous_at_Inf_mono[of "\x. x + c" "f`UNIV"] using continuous_add[of "at_right (Inf (range f))", of "\x. x" "\x. c"] by (auto simp: mono_def image_comp) lemma INF_ennreal_const_add: fixes f g :: "nat \ ennreal" shows "(INF i. c + f i) = c + (INF i. f i)" using INF_ennreal_add_const[of f c] by (simp add: ac_simps) lemma SUP_mult_left_ennreal: "c * (SUP i\I. f i) = (SUP i\I. c * f i ::ennreal)" proof cases assume "I \ {}" then show ?thesis by transfer (auto simp add: SUP_ereal_mult_left max_absorb2 SUP_upper2) qed (simp add: bot_ennreal) lemma SUP_mult_right_ennreal: "(SUP i\I. f i) * c = (SUP i\I. f i * c ::ennreal)" using SUP_mult_left_ennreal by (simp add: mult.commute) lemma SUP_divide_ennreal: "(SUP i\I. f i) / c = (SUP i\I. f i / c ::ennreal)" using SUP_mult_right_ennreal by (simp add: divide_ennreal_def) lemma ennreal_SUP_of_nat_eq_top: "(SUP x. of_nat x :: ennreal) = top" proof (intro antisym top_greatest le_SUP_iff[THEN iffD2] allI impI) fix y :: ennreal assume "y < top" then obtain r where "y = ennreal r" by (cases y rule: ennreal_cases) auto then show "\i\UNIV. y < of_nat i" using reals_Archimedean2[of "max 1 r"] zero_less_one by (simp add: ennreal_Ex_less_of_nat) qed lemma ennreal_SUP_eq_top: fixes f :: "'a \ ennreal" assumes "\n. \i\I. of_nat n \ f i" shows "(SUP i \ I. f i) = top" proof - have "(SUP x. of_nat x :: ennreal) \ (SUP i \ I. f i)" using assms by (auto intro!: SUP_least intro: SUP_upper2) then show ?thesis by (auto simp: ennreal_SUP_of_nat_eq_top top_unique) qed lemma ennreal_INF_const_minus: fixes f :: "'a \ ennreal" shows "I \ {} \ (SUP x\I. c - f x) = c - (INF x\I. f x)" by (transfer fixing: I) (simp add: sup_max[symmetric] SUP_sup_const1 SUP_ereal_minus_right del: sup_ereal_def) lemma of_nat_Sup_ennreal: assumes "A \ {}" "bdd_above A" shows "of_nat (Sup A) = (SUP a\A. of_nat a :: ennreal)" proof (intro antisym) show "(SUP a\A. of_nat a::ennreal) \ of_nat (Sup A)" by (intro SUP_least of_nat_mono) (auto intro: cSup_upper assms) have "Sup A \ A" using assms by (auto simp: Sup_nat_def bdd_above_nat) then show "of_nat (Sup A) \ (SUP a\A. of_nat a::ennreal)" by (intro SUP_upper) qed lemma ennreal_tendsto_const_minus: fixes g :: "'a \ ennreal" assumes ae: "\\<^sub>F x in F. g x \ c" assumes g: "((\x. c - g x) \ 0) F" shows "(g \ c) F" proof (cases c rule: ennreal_cases) case top with tendsto_unique[OF _ g, of "top"] show ?thesis by (cases "F = bot") auto next case (real r) then have "\x. \q\0. g x \ c \ (g x = ennreal q \ q \ r)" by (auto simp: le_ennreal_iff) then obtain f where *: "0 \ f x" "g x = ennreal (f x)" "f x \ r" if "g x \ c" for x by metis from ae have ae2: "\\<^sub>F x in F. c - g x = ennreal (r - f x) \ f x \ r \ g x = ennreal (f x) \ 0 \ f x" proof eventually_elim fix x assume "g x \ c" with *[of x] \0 \ r\ show "c - g x = ennreal (r - f x) \ f x \ r \ g x = ennreal (f x) \ 0 \ f x" by (auto simp: real ennreal_minus) qed with g have "((\x. ennreal (r - f x)) \ ennreal 0) F" by (auto simp add: tendsto_cong eventually_conj_iff) with ae2 have "((\x. r - f x) \ 0) F" by (subst (asm) tendsto_ennreal_iff) (auto elim: eventually_mono) then have "(f \ r) F" by (rule Lim_transform2[OF tendsto_const]) with ae2 have "((\x. ennreal (f x)) \ ennreal r) F" by (subst tendsto_ennreal_iff) (auto elim: eventually_mono simp: real) with ae2 show ?thesis by (auto simp: real tendsto_cong eventually_conj_iff) qed lemma ennreal_SUP_add: fixes f g :: "nat \ ennreal" shows "incseq f \ incseq g \ (SUP i. f i + g i) = Sup (f ` UNIV) + Sup (g ` UNIV)" unfolding incseq_def le_fun_def by transfer (simp add: SUP_ereal_add incseq_def le_fun_def max_absorb2 SUP_upper2) lemma ennreal_SUP_sum: fixes f :: "'a \ nat \ ennreal" shows "(\i. i \ I \ incseq (f i)) \ (SUP n. \i\I. f i n) = (\i\I. SUP n. f i n)" unfolding incseq_def by transfer (simp add: SUP_ereal_sum incseq_def SUP_upper2 max_absorb2 sum_nonneg) lemma ennreal_liminf_minus: fixes f :: "nat \ ennreal" shows "(\n. f n \ c) \ liminf (\n. c - f n) = c - limsup f" apply transfer - apply (simp add: ereal_diff_positive max.absorb2 liminf_ereal_cminus) - apply (subst max.absorb2) - apply (rule ereal_diff_positive) - apply (rule Limsup_bounded) - apply auto - done + apply (simp add: ereal_diff_positive liminf_ereal_cminus) + by (metis max.absorb2 ereal_diff_positive Limsup_bounded eventually_sequentiallyI) lemma ennreal_continuous_on_cmult: "(c::ennreal) < top \ continuous_on A f \ continuous_on A (\x. c * f x)" by (transfer fixing: A) (auto intro: continuous_on_cmult_ereal) lemma ennreal_tendsto_cmult: "(c::ennreal) < top \ (f \ x) F \ ((\x. c * f x) \ c * x) F" by (rule continuous_on_tendsto_compose[where g=f, OF ennreal_continuous_on_cmult, where s=UNIV]) (auto simp: continuous_on_id) lemma tendsto_ennrealI[intro, simp, tendsto_intros]: "(f \ x) F \ ((\x. ennreal (f x)) \ ennreal x) F" by (auto simp: ennreal_def intro!: continuous_on_tendsto_compose[OF continuous_on_e2ennreal[of UNIV]] tendsto_max) lemma tendsto_enn2erealI [tendsto_intros]: assumes "(f \ l) F" shows "((\i. enn2ereal(f i)) \ enn2ereal l) F" using tendsto_enn2ereal_iff assms by auto lemma tendsto_e2ennrealI [tendsto_intros]: assumes "(f \ l) F" shows "((\i. e2ennreal(f i)) \ e2ennreal l) F" proof - have *: "e2ennreal (max x 0) = e2ennreal x" for x by (simp add: e2ennreal_def max.commute) have "((\i. max (f i) 0) \ max l 0) F" apply (intro tendsto_intros) using assms by auto then have "((\i. enn2ereal(e2ennreal (max (f i) 0))) \ enn2ereal (e2ennreal (max l 0))) F" by (subst enn2ereal_e2ennreal, auto)+ then have "((\i. e2ennreal (max (f i) 0)) \ e2ennreal (max l 0)) F" using tendsto_enn2ereal_iff by auto then show ?thesis unfolding * by auto qed lemma ennreal_suminf_minus: fixes f g :: "nat \ ennreal" shows "(\i. g i \ f i) \ suminf f \ top \ suminf g \ top \ (\i. f i - g i) = suminf f - suminf g" by transfer (auto simp add: max.absorb2 ereal_diff_positive suminf_le_pos top_ereal_def intro!: suminf_ereal_minus) lemma ennreal_Sup_countable_SUP: "A \ {} \ \f::nat \ ennreal. incseq f \ range f \ A \ Sup A = (SUP i. f i)" unfolding incseq_def apply transfer subgoal for A using Sup_countable_SUP[of A] by (force simp add: incseq_def[symmetric] SUP_upper2 max.absorb2 image_subset_iff Sup_upper2 cong: conj_cong) done lemma ennreal_Inf_countable_INF: "A \ {} \ \f::nat \ ennreal. decseq f \ range f \ A \ Inf A = (INF i. f i)" - including ennreal.lifting unfolding decseq_def apply transfer subgoal for A using Inf_countable_INF[of A] apply (clarsimp simp flip: decseq_def) subgoal for f by (intro exI[of _ f]) auto done done lemma ennreal_SUP_countable_SUP: "A \ {} \ \f::nat \ ennreal. range f \ g`A \ Sup (g ` A) = Sup (f ` UNIV)" using ennreal_Sup_countable_SUP [of "g`A"] by auto lemma of_nat_tendsto_top_ennreal: "(\n::nat. of_nat n :: ennreal) \ top" using LIMSEQ_SUP[of "of_nat :: nat \ ennreal"] by (simp add: ennreal_SUP_of_nat_eq_top incseq_def) lemma SUP_sup_continuous_ennreal: fixes f :: "ennreal \ 'a::complete_lattice" assumes f: "sup_continuous f" and "I \ {}" shows "(SUP i\I. f (g i)) = f (SUP i\I. g i)" proof (rule antisym) show "(SUP i\I. f (g i)) \ f (SUP i\I. g i)" by (rule mono_SUP[OF sup_continuous_mono[OF f]]) from ennreal_Sup_countable_SUP[of "g`I"] \I \ {}\ obtain M :: "nat \ ennreal" where "incseq M" and M: "range M \ g ` I" and eq: "(SUP i \ I. g i) = (SUP i. M i)" by auto have "f (SUP i \ I. g i) = (SUP i \ range M. f i)" unfolding eq sup_continuousD[OF f \mono M\] by (simp add: image_comp) also have "\ \ (SUP i \ I. f (g i))" by (insert M, drule SUP_subset_mono) (auto simp add: image_comp) finally show "f (SUP i \ I. g i) \ (SUP i \ I. f (g i))" . qed lemma ennreal_suminf_SUP_eq: fixes f :: "nat \ nat \ ennreal" shows "(\i. incseq (\n. f n i)) \ (\i. SUP n. f n i) = (SUP n. \i. f n i)" apply (rule ennreal_suminf_SUP_eq_directed) subgoal for N n j by (auto simp: incseq_def intro!:exI[of _ "max n j"]) done lemma ennreal_SUP_add_left: fixes c :: ennreal shows "I \ {} \ (SUP i\I. f i + c) = (SUP i\I. f i) + c" apply transfer apply (simp add: SUP_ereal_add_left) - apply (subst (1 2) max.absorb2) - apply (auto intro: SUP_upper2 add_nonneg_nonneg) - done + by (metis SUP_upper all_not_in_conv ereal_le_add_mono1 max.absorb2 max.bounded_iff) lemma ennreal_SUP_const_minus: fixes f :: "'a \ ennreal" shows "I \ {} \ c < top \ (INF x\I. c - f x) = c - (SUP x\I. f x)" apply (transfer fixing: I) unfolding ex_in_conv[symmetric] apply (auto simp add: SUP_upper2 sup_absorb2 simp flip: sup_ereal_def) apply (subst INF_ereal_minus_right[symmetric]) apply (auto simp del: sup_ereal_def simp add: sup_INF) done (* Contributed by Dominique Unruh *) lemma isCont_ennreal[simp]: \isCont ennreal x\ apply (auto intro!: sequentially_imp_eventually_within simp: continuous_within tendsto_def) by (metis tendsto_def tendsto_ennrealI) (* Contributed by Dominique Unruh *) lemma isCont_ennreal_of_enat[simp]: \isCont ennreal_of_enat x\ proof - have continuous_at_open: \ \Copied lemma from \<^session>\HOL-Analysis\ to avoid dependency.\ "continuous (at x) f \ (\t. open t \ f x \ t --> (\s. open s \ x \ s \ (\x' \ s. (f x') \ t)))" for f :: \enat \ 'z::topological_space\ unfolding continuous_within_topological [of x UNIV f] unfolding imp_conjL by (intro all_cong imp_cong ex_cong conj_cong refl) auto show ?thesis proof (subst continuous_at_open, intro allI impI, cases \x = \\) case True fix t assume \open t \ ennreal_of_enat x \ t\ then have \\y<\. {y <.. \} \ t\ - apply (rule_tac open_left[where y=0]) - by (auto simp: True) + by (rule_tac open_left[where y=0]) (auto simp: True) then obtain y where \{y<..} \ t\ and \y \ \\ - apply atomize_elim - apply (auto simp: greaterThanAtMost_def) - by (metis atMost_iff inf.orderE subsetI top.not_eq_extremum top_greatest) - + by fastforce from \y \ \\ obtain x' where x'y: \ennreal_of_enat x' > y\ and \x' \ \\ by (metis enat.simps(3) ennreal_Ex_less_of_nat ennreal_of_enat_enat infinity_ennreal_def top.not_eq_extremum) define s where \s = {x'<..}\ have \open s\ by (simp add: s_def) moreover have \x \ s\ by (simp add: \x' \ \\ s_def True) moreover have \ennreal_of_enat z \ t\ if \z \ s\ for z by (metis x'y \{y<..} \ t\ ennreal_of_enat_le_iff greaterThan_iff le_less_trans less_imp_le not_less s_def subsetD that) ultimately show \\s. open s \ x \ s \ (\z\s. ennreal_of_enat z \ t)\ by auto next case False fix t assume asm: \open t \ ennreal_of_enat x \ t\ define s where \s = {x}\ have \open s\ using False open_enat_iff s_def by blast moreover have \x \ s\ using s_def by auto moreover have \ennreal_of_enat z \ t\ if \z \ s\ for z using asm s_def that by blast ultimately show \\s. open s \ x \ s \ (\z\s. ennreal_of_enat z \ t)\ by auto qed qed subsection \Approximation lemmas\ lemma INF_approx_ennreal: fixes x::ennreal and e::real assumes "e > 0" assumes INF: "x = (INF i \ A. f i)" assumes "x \ \" shows "\i \ A. f i < x + e" proof - have "(INF i \ A. f i) < x + e" unfolding INF[symmetric] using \0 \x \ \\ by (cases x) auto then show ?thesis unfolding INF_less_iff . qed lemma SUP_approx_ennreal: fixes x::ennreal and e::real assumes "e > 0" "A \ {}" assumes SUP: "x = (SUP i \ A. f i)" assumes "x \ \" shows "\i \ A. x < f i + e" proof - have "x < x + e" using \0 \x \ \\ by (cases x) auto also have "x + e = (SUP i \ A. f i + e)" unfolding SUP ennreal_SUP_add_left[OF \A \ {}\] .. finally show ?thesis unfolding less_SUP_iff . qed lemma ennreal_approx_SUP: fixes x::ennreal assumes f_bound: "\i. i \ A \ f i \ x" assumes approx: "\e. (e::real) > 0 \ \i \ A. x \ f i + e" shows "x = (SUP i \ A. f i)" proof (rule antisym) show "x \ (SUP i\A. f i)" proof (rule ennreal_le_epsilon) fix e :: real assume "0 < e" from approx[OF this] obtain i where "i \ A" and *: "x \ f i + ennreal e" by blast from * have "x \ f i + e" by simp also have "\ \ (SUP i\A. f i) + e" by (intro add_mono \i \ A\ SUP_upper order_refl) finally show "x \ (SUP i\A. f i) + e" . qed qed (intro SUP_least f_bound) lemma ennreal_approx_INF: fixes x::ennreal assumes f_bound: "\i. i \ A \ x \ f i" assumes approx: "\e. (e::real) > 0 \ \i \ A. f i \ x + e" shows "x = (INF i \ A. f i)" proof (rule antisym) show "(INF i\A. f i) \ x" proof (rule ennreal_le_epsilon) fix e :: real assume "0 < e" from approx[OF this] obtain i where "i\A" "f i \ x + ennreal e" by blast then have "(INF i\A. f i) \ f i" by (intro INF_lower) also have "\ \ x + e" by fact finally show "(INF i\A. f i) \ x + e" . qed qed (intro INF_greatest f_bound) lemma ennreal_approx_unit: "(\a::ennreal. 0 < a \ a < 1 \ a * z \ y) \ z \ y" apply (subst SUP_mult_right_ennreal[of "\x. x" "{0 <..< 1}" z, simplified]) apply (auto intro: SUP_least) done lemma suminf_ennreal2: "(\i. 0 \ f i) \ summable f \ (\i. ennreal (f i)) = ennreal (\i. f i)" using suminf_ennreal_eq by blast lemma less_top_ennreal: "x < top \ (\r\0. x = ennreal r)" by (cases x) auto lemma enn2real_less_iff[simp]: "x < top \ enn2real x < c \ x < c" using ennreal_less_iff less_top_ennreal by auto lemma enn2real_le_iff[simp]: "\x < top; c > 0\ \ enn2real x \ c \ x \ c" by (cases x) auto lemma enn2real_less: assumes "enn2real e < r" "e \ top" shows "e < ennreal r" using enn2real_less_iff assms top.not_eq_extremum by blast lemma enn2real_le: assumes "enn2real e \ r" "e \ top" shows "e \ ennreal r" by (metis assms enn2real_less ennreal_enn2real_if eq_iff less_le) lemma tendsto_top_iff_ennreal: fixes f :: "'a \ ennreal" shows "(f \ top) F \ (\l\0. eventually (\x. ennreal l < f x) F)" by (auto simp: less_top_ennreal order_tendsto_iff ) lemma ennreal_tendsto_top_eq_at_top: "((\z. ennreal (f z)) \ top) F \ (LIM z F. f z :> at_top)" unfolding filterlim_at_top_dense tendsto_top_iff_ennreal apply (auto simp: ennreal_less_iff) subgoal for y by (auto elim!: eventually_mono allE[of _ "max 0 y"]) done lemma tendsto_0_if_Limsup_eq_0_ennreal: fixes f :: "_ \ ennreal" shows "Limsup F f = 0 \ (f \ 0) F" using Liminf_le_Limsup[of F f] tendsto_iff_Liminf_eq_Limsup[of F f 0] by (cases "F = bot") auto lemma diff_le_self_ennreal[simp]: "a - b \ (a::ennreal)" by (cases a b rule: ennreal2_cases) (auto simp: ennreal_minus) lemma ennreal_ineq_diff_add: "b \ a \ a = b + (a - b::ennreal)" by transfer (auto simp: ereal_diff_positive max.absorb2 ereal_ineq_diff_add) lemma ennreal_mult_strict_left_mono: "(a::ennreal) < c \ 0 < b \ b < top \ b * a < b * c" by transfer (auto intro!: ereal_mult_strict_left_mono) lemma ennreal_between: "0 < e \ 0 < x \ x < top \ x - e < (x::ennreal)" by transfer (auto intro!: ereal_between) lemma minus_less_iff_ennreal: "b < top \ b \ a \ a - b < c \ a < c + (b::ennreal)" by transfer (auto simp: top_ereal_def ereal_minus_less le_less) lemma tendsto_zero_ennreal: assumes ev: "\r. 0 < r \ \\<^sub>F x in F. f x < ennreal r" shows "(f \ 0) F" proof (rule order_tendstoI) fix e::ennreal assume "e > 0" obtain e'::real where "e' > 0" "ennreal e' < e" using \0 < e\ dense[of 0 "if e = top then 1 else (enn2real e)"] by (cases e) (auto simp: ennreal_less_iff) from ev[OF \e' > 0\] show "\\<^sub>F x in F. f x < e" by eventually_elim (insert \ennreal e' < e\, auto) qed simp lifting_update ennreal.lifting lifting_forget ennreal.lifting subsection \\<^typ>\ennreal\ theorems\ lemma neq_top_trans: fixes x y :: ennreal shows "\ y \ top; x \ y \ \ x \ top" by (auto simp: top_unique) lemma diff_diff_ennreal: fixes a b :: ennreal shows "a \ b \ b \ \ \ b - (b - a) = a" by (cases a b rule: ennreal2_cases) (auto simp: ennreal_minus top_unique) lemma ennreal_less_one_iff[simp]: "ennreal x < 1 \ x < 1" by (cases "0 \ x") (auto simp: ennreal_neg ennreal_less_iff simp flip: ennreal_1) lemma SUP_const_minus_ennreal: fixes f :: "'a \ ennreal" shows "I \ {} \ (SUP x\I. c - f x) = c - (INF x\I. f x)" including ennreal.lifting by (transfer fixing: I) (simp add: SUP_sup_distrib[symmetric] SUP_ereal_minus_right flip: sup_ereal_def) lemma zero_minus_ennreal[simp]: "0 - (a::ennreal) = 0" including ennreal.lifting by transfer (simp split: split_max) lemma diff_diff_commute_ennreal: fixes a b c :: ennreal shows "a - b - c = a - c - b" by (cases a b c rule: ennreal3_cases) (simp_all add: ennreal_minus field_simps) lemma diff_gr0_ennreal: "b < (a::ennreal) \ 0 < a - b" including ennreal.lifting by transfer (auto simp: ereal_diff_gr0 ereal_diff_positive split: split_max) lemma divide_le_posI_ennreal: fixes x y z :: ennreal shows "x > 0 \ z \ x * y \ z / x \ y" by (cases x y z rule: ennreal3_cases) (auto simp: divide_ennreal ennreal_mult[symmetric] field_simps top_unique) lemma add_diff_eq_ennreal: fixes x y z :: ennreal shows "z \ y \ x + (y - z) = x + y - z" - including ennreal.lifting - by transfer - (insert add_mono[of "0::ereal"], auto simp add: ereal_diff_positive max.absorb2 add_diff_eq_ereal) + using ennreal_diff_add_assoc by auto lemma add_diff_inverse_ennreal: fixes x y :: ennreal shows "x \ y \ x + (y - x) = y" by (cases x) (simp_all add: top_unique add_diff_eq_ennreal) lemma add_diff_eq_iff_ennreal[simp]: fixes x y :: ennreal shows "x + (y - x) = y \ x \ y" proof assume *: "x + (y - x) = y" show "x \ y" by (subst *[symmetric]) simp qed (simp add: add_diff_inverse_ennreal) lemma add_diff_le_ennreal: "a + b - c \ a + (b - c::ennreal)" apply (cases a b c rule: ennreal3_cases) subgoal for a' b' c' by (cases "0 \ b' - c'") (simp_all add: ennreal_minus top_add ennreal_neg flip: ennreal_plus) apply (simp_all add: top_add flip: ennreal_plus) done lemma diff_eq_0_ennreal: "a < top \ a \ b \ a - b = (0::ennreal)" using ennreal_minus_pos_iff gr_zeroI not_less by blast lemma diff_diff_ennreal': fixes x y z :: ennreal shows "z \ y \ y - z \ x \ x - (y - z) = x + z - y" by (cases x; cases y; cases z) (auto simp add: top_add add_top minus_top_ennreal ennreal_minus top_unique simp flip: ennreal_plus) lemma diff_diff_ennreal'': fixes x y z :: ennreal shows "z \ y \ x - (y - z) = (if y - z \ x then x + z - y else 0)" by (cases x; cases y; cases z) (auto simp add: top_add add_top minus_top_ennreal ennreal_minus top_unique ennreal_neg simp flip: ennreal_plus) lemma power_less_top_ennreal: fixes x :: ennreal shows "x ^ n < top \ x < top \ n = 0" using power_eq_top_ennreal[of x n] by (auto simp: less_top) lemma ennreal_divide_times: "(a / b) * c = a * (c / b :: ennreal)" by (simp add: mult.commute ennreal_times_divide) lemma diff_less_top_ennreal: "a - b < top \ a < (top :: ennreal)" by (cases a; cases b) (auto simp: ennreal_minus) lemma divide_less_ennreal: "b \ 0 \ b < top \ a / b < c \ a < (c * b :: ennreal)" by (cases a; cases b; cases c) (auto simp: divide_ennreal ennreal_mult[symmetric] ennreal_less_iff field_simps ennreal_top_mult ennreal_top_divide) lemma one_less_numeral[simp]: "1 < (numeral n::ennreal) \ (num.One < n)" by (simp flip: ennreal_1 ennreal_numeral add: ennreal_less_iff) lemma divide_eq_1_ennreal: "a / b = (1::ennreal) \ (b \ top \ b \ 0 \ b = a)" by (cases a ; cases b; cases "b = 0") (auto simp: ennreal_top_divide divide_ennreal split: if_split_asm) lemma ennreal_mult_cancel_left: "(a * b = a * c) = (a = top \ b \ 0 \ c \ 0 \ a = 0 \ b = (c::ennreal))" by (cases a; cases b; cases c) (auto simp: ennreal_mult[symmetric] ennreal_mult_top ennreal_top_mult) lemma ennreal_minus_if: "ennreal a - ennreal b = ennreal (if 0 \ b then (if b \ a then a - b else 0) else a)" by (auto simp: ennreal_minus ennreal_neg) lemma ennreal_plus_if: "ennreal a + ennreal b = ennreal (if 0 \ a then (if 0 \ b then a + b else a) else b)" by (auto simp: ennreal_neg) lemma power_le_one_iff: "0 \ (a::real) \ a ^ n \ 1 \ (n = 0 \ a \ 1)" by (metis (mono_tags, opaque_lifting) le_less neq0_conv not_le one_le_power power_0 power_eq_imp_eq_base power_le_one zero_le_one) lemma ennreal_diff_le_mono_left: "a \ b \ a - c \ (b::ennreal)" using ennreal_mono_minus[of 0 c a, THEN order_trans, of b] by simp lemma ennreal_minus_le_iff: "a - b \ c \ (a \ b + (c::ennreal) \ (a = top \ b = top \ c = top))" by (cases a; cases b; cases c) (auto simp: top_unique top_add add_top ennreal_minus simp flip: ennreal_plus) lemma ennreal_le_minus_iff: "a \ b - c \ (a + c \ (b::ennreal) \ (a = 0 \ b \ c))" by (cases a; cases b; cases c) (auto simp: top_unique top_add add_top ennreal_minus ennreal_le_iff2 simp flip: ennreal_plus) lemma diff_add_eq_diff_diff_swap_ennreal: "x - (y + z :: ennreal) = x - y - z" by (cases x; cases y; cases z) (auto simp: ennreal_minus_if add_top top_add simp flip: ennreal_plus) lemma diff_add_assoc2_ennreal: "b \ a \ (a - b + c::ennreal) = a + c - b" by (cases a; cases b; cases c) (auto simp add: ennreal_minus_if ennreal_plus_if add_top top_add top_unique simp del: ennreal_plus) lemma diff_gt_0_iff_gt_ennreal: "0 < a - b \ (a = top \ b = top \ b < (a::ennreal))" by (cases a; cases b) (auto simp: ennreal_minus_if ennreal_less_iff) lemma diff_eq_0_iff_ennreal: "(a - b::ennreal) = 0 \ (a < top \ a \ b)" by (cases a) (auto simp: ennreal_minus_eq_0 diff_eq_0_ennreal) lemma add_diff_self_ennreal: "a + (b - a::ennreal) = (if a \ b then b else a)" by (auto simp: diff_eq_0_iff_ennreal less_top) lemma diff_add_self_ennreal: "(b - a + a::ennreal) = (if a \ b then b else a)" by (auto simp: diff_add_cancel_ennreal diff_eq_0_iff_ennreal less_top) lemma ennreal_minus_cancel_iff: fixes a b c :: ennreal shows "a - b = a - c \ (b = c \ (a \ b \ a \ c) \ a = top)" by (cases a; cases b; cases c) (auto simp: ennreal_minus_if) text \The next lemma is wrong for $a = top$, for $b = c = 1$ for instance.\ lemma ennreal_right_diff_distrib: fixes a b c :: ennreal assumes "a \ top" shows "a * (b - c) = a * b - a * c" apply (cases a; cases b; cases c) apply (use assms in \auto simp add: ennreal_mult_top ennreal_minus ennreal_mult' [symmetric]\) apply (simp add: algebra_simps) done lemma SUP_diff_ennreal: "c < top \ (SUP i\I. f i - c :: ennreal) = (SUP i\I. f i) - c" by (auto intro!: SUP_eqI ennreal_minus_mono SUP_least intro: SUP_upper simp: ennreal_minus_cancel_iff ennreal_minus_le_iff less_top[symmetric]) lemma ennreal_SUP_add_right: fixes c :: ennreal shows "I \ {} \ c + (SUP i\I. f i) = (SUP i\I. c + f i)" using ennreal_SUP_add_left[of I f c] by (simp add: add.commute) lemma SUP_add_directed_ennreal: fixes f g :: "_ \ ennreal" assumes directed: "\i j. i \ I \ j \ I \ \k\I. f i + g j \ f k + g k" shows "(SUP i\I. f i + g i) = (SUP i\I. f i) + (SUP i\I. g i)" -proof cases - assume "I = {}" then show ?thesis - by (simp add: bot_ereal_def) -next - assume "I \ {}" +proof (cases "I = {}") + case False show ?thesis proof (rule antisym) show "(SUP i\I. f i + g i) \ (SUP i\I. f i) + (SUP i\I. g i)" by (rule SUP_least; intro add_mono SUP_upper) next have "(SUP i\I. f i) + (SUP i\I. g i) = (SUP i\I. f i + (SUP i\I. g i))" by (intro ennreal_SUP_add_left[symmetric] \I \ {}\) also have "\ = (SUP i\I. (SUP j\I. f i + g j))" using \I \ {}\ by (simp add: ennreal_SUP_add_right) also have "\ \ (SUP i\I. f i + g i)" using directed by (intro SUP_least) (blast intro: SUP_upper2) finally show "(SUP i\I. f i) + (SUP i\I. g i) \ (SUP i\I. f i + g i)" . qed -qed +qed (simp add: bot_ereal_def) + lemma enn2real_eq_0_iff: "enn2real x = 0 \ x = 0 \ x = top" by (cases x) auto lemma continuous_on_diff_ennreal: "continuous_on A f \ continuous_on A g \ (\x. x \ A \ f x \ top) \ (\x. x \ A \ g x \ top) \ continuous_on A (\z. f z - g z::ennreal)" including ennreal.lifting proof (transfer fixing: A, simp add: top_ereal_def) fix f g :: "'a \ ereal" assume "\x. 0 \ f x" "\x. 0 \ g x" "continuous_on A f" "continuous_on A g" moreover assume "f x \ \" "g x \ \" if "x \ A" for x ultimately show "continuous_on A (\z. max 0 (f z - g z))" by (intro continuous_on_max continuous_on_const continuous_on_diff_ereal) auto qed lemma tendsto_diff_ennreal: "(f \ x) F \ (g \ y) F \ x \ top \ y \ top \ ((\z. f z - g z::ennreal) \ x - y) F" using continuous_on_tendsto_compose[where f="\x. fst x - snd x::ennreal" and s="{(x, y). x \ top \ y \ top}" and g="\x. (f x, g x)" and l="(x, y)" and F="F", OF continuous_on_diff_ennreal] by (auto simp: tendsto_Pair eventually_conj_iff less_top order_tendstoD continuous_on_fst continuous_on_snd continuous_on_id) declare lim_real_of_ereal [tendsto_intros] lemma tendsto_enn2real [tendsto_intros]: assumes "(u \ ennreal l) F" "l \ 0" shows "((\n. enn2real (u n)) \ l) F" unfolding enn2real_def by (metis assms enn2ereal_ennreal lim_real_of_ereal tendsto_enn2erealI) end