# HG changeset patch # User hoelzl # Date 1233830082 -3600 # Node ID c56a5571f60a616214d24244a0727694fc48715a # Parent d201a838d0f7e16e7570899c97b0594483f3067f Added derivation lemmas for power series and theorems for the pi, arcus tangens and logarithm series diff -r d201a838d0f7 -r c56a5571f60a src/HOL/Deriv.thy --- a/src/HOL/Deriv.thy Wed Feb 04 18:10:07 2009 +0100 +++ b/src/HOL/Deriv.thy Thu Feb 05 11:34:42 2009 +0100 @@ -1038,6 +1038,15 @@ qed qed +lemma MVT2: + "[| a < b; \x. a \ x & x \ b --> DERIV f x :> f'(x) |] + ==> \z::real. a < z & z < b & (f b - f a = (b - a) * f'(z))" +apply (drule MVT) +apply (blast intro: DERIV_isCont) +apply (force dest: order_less_imp_le simp add: differentiable_def) +apply (blast dest: DERIV_unique order_less_imp_le) +done + text{*A function is constant if its derivative is 0 over an interval.*} @@ -1073,6 +1082,30 @@ apply (blast dest: DERIV_isconst1) done +lemma DERIV_isconst3: fixes a b x y :: real + assumes "a < b" and "x \ {a <..< b}" and "y \ {a <..< b}" + assumes derivable: "\x. x \ {a <..< b} \ DERIV f x :> 0" + shows "f x = f y" +proof (cases "x = y") + case False + let ?a = "min x y" + let ?b = "max x y" + + have "\z. ?a \ z \ z \ ?b \ DERIV f z :> 0" + proof (rule allI, rule impI) + fix z :: real assume "?a \ z \ z \ ?b" + hence "a < z" and "z < b" using `x \ {a <..< b}` and `y \ {a <..< b}` by auto + hence "z \ {a<.. 0" by (rule derivable) + qed + hence isCont: "\z. ?a \ z \ z \ ?b \ isCont f z" + and DERIV: "\z. ?a < z \ z < ?b \ DERIV f z :> 0" using DERIV_isCont by auto + + have "?a < ?b" using `x \ y` by auto + from DERIV_isconst2[OF this isCont DERIV, of x] and DERIV_isconst2[OF this isCont DERIV, of y] + show ?thesis by auto +qed auto + lemma DERIV_isconst_all: fixes f :: "real => real" shows "\x. DERIV f x :> 0 ==> f(x) = f(y)" diff -r d201a838d0f7 -r c56a5571f60a src/HOL/Lim.thy --- a/src/HOL/Lim.thy Wed Feb 04 18:10:07 2009 +0100 +++ b/src/HOL/Lim.thy Thu Feb 05 11:34:42 2009 +0100 @@ -532,6 +532,44 @@ lemma isCont_abs [simp]: "isCont abs (a::real)" by (rule isCont_rabs [OF isCont_ident]) +lemma isCont_setsum: fixes A :: "nat set" assumes "finite A" + shows "\ i \ A. isCont (f i) x \ isCont (\ x. \ i \ A. f i x) x" + using `finite A` +proof induct + case (insert a F) show "isCont (\ x. \ i \ (insert a F). f i x) x" + unfolding setsum_insert[OF `finite F` `a \ F`] by (rule isCont_add, auto simp add: insert) +qed auto + +lemma LIM_less_bound: fixes f :: "real \ real" assumes "b < x" + and all_le: "\ x' \ { b <..< x}. 0 \ f x'" and isCont: "isCont f x" + shows "0 \ f x" +proof (rule ccontr) + assume "\ 0 \ f x" hence "f x < 0" by auto + hence "0 < - f x / 2" by auto + from isCont[unfolded isCont_def, THEN LIM_D, OF this] + obtain s where "s > 0" and s_D: "\x'. \ x' \ x ; \ x' - x \ < s \ \ \ f x' - f x \ < - f x / 2" by auto + + let ?x = "x - min (s / 2) ((x - b) / 2)" + have "?x < x" and "\ ?x - x \ < s" + using `b < x` and `0 < s` by auto + have "b < ?x" + proof (cases "s < x - b") + case True thus ?thesis using `0 < s` by auto + next + case False hence "s / 2 \ (x - b) / 2" by auto + from inf_absorb2[OF this, unfolded inf_real_def] + have "?x = (x + b) / 2" by auto + thus ?thesis using `b < x` by auto + qed + hence "0 \ f ?x" using all_le `?x < x` by auto + moreover have "\f ?x - f x\ < - f x / 2" + using s_D[OF _ `\ ?x - x \ < s`] `?x < x` by auto + hence "f ?x - f x < - f x / 2" by auto + hence "f ?x < f x / 2" by auto + hence "f ?x < 0" using `f x < 0` by auto + thus False using `0 \ f ?x` by auto +qed + subsection {* Uniform Continuity *} diff -r d201a838d0f7 -r c56a5571f60a src/HOL/MacLaurin.thy --- a/src/HOL/MacLaurin.thy Wed Feb 04 18:10:07 2009 +0100 +++ b/src/HOL/MacLaurin.thy Thu Feb 05 11:34:42 2009 +0100 @@ -389,15 +389,6 @@ subsection{*Version for Sine Function*} -lemma MVT2: - "[| a < b; \x. a \ x & x \ b --> DERIV f x :> f'(x) |] - ==> \z::real. a < z & z < b & (f b - f a = (b - a) * f'(z))" -apply (drule MVT) -apply (blast intro: DERIV_isCont) -apply (force dest: order_less_imp_le simp add: differentiable_def) -apply (blast dest: DERIV_unique order_less_imp_le) -done - lemma mod_exhaust_less_4: "m mod 4 = 0 | m mod 4 = 1 | m mod 4 = 2 | m mod 4 = (3::nat)" by auto diff -r d201a838d0f7 -r c56a5571f60a src/HOL/Parity.thy --- a/src/HOL/Parity.thy Wed Feb 04 18:10:07 2009 +0100 +++ b/src/HOL/Parity.thy Thu Feb 05 11:34:42 2009 +0100 @@ -291,6 +291,40 @@ apply simp done +lemma power_mono_even: fixes x y :: "'a :: {recpower, ordered_idom}" + assumes "even n" and "\x\ \ \y\" + shows "x^n \ y^n" +proof - + have "0 \ \x\" by auto + with `\x\ \ \y\` + have "\x\^n \ \y\^n" by (rule power_mono) + thus ?thesis unfolding power_even_abs[OF `even n`] . +qed + +lemma odd_pos: "odd (n::nat) \ 0 < n" by presburger + +lemma power_mono_odd: fixes x y :: "'a :: {recpower, ordered_idom}" + assumes "odd n" and "x \ y" + shows "x^n \ y^n" +proof (cases "y < 0") + case True with `x \ y` have "-y \ -x" and "0 \ -y" by auto + hence "(-y)^n \ (-x)^n" by (rule power_mono) + thus ?thesis unfolding power_minus_odd[OF `odd n`] by auto +next + case False + show ?thesis + proof (cases "x < 0") + case True hence "n \ 0" and "x \ 0" using `odd n`[THEN odd_pos] by auto + hence "x^n \ 0" unfolding power_le_zero_eq using `odd n` by auto + moreover + from `\ y < 0` have "0 \ y" by auto + hence "0 \ y^n" by auto + ultimately show ?thesis by auto + next + case False hence "0 \ x" by auto + with `x \ y` show ?thesis using power_mono by auto + qed +qed subsection {* General Lemmas About Division *} @@ -405,8 +439,6 @@ subsection {* Miscellaneous *} -lemma odd_pos: "odd (n::nat) \ 0 < n" by presburger - lemma [presburger]:"(x + 1) div 2 = x div 2 \ even (x::int)" by presburger lemma [presburger]: "(x + 1) div 2 = x div 2 + 1 \ odd (x::int)" by presburger lemma even_plus_one_div_two: "even (x::int) ==> (x + 1) div 2 = x div 2" by presburger diff -r d201a838d0f7 -r c56a5571f60a src/HOL/SEQ.thy --- a/src/HOL/SEQ.thy Wed Feb 04 18:10:07 2009 +0100 +++ b/src/HOL/SEQ.thy Thu Feb 05 11:34:42 2009 +0100 @@ -346,6 +346,11 @@ lemma LIMSEQ_Suc_iff: "(\n. f (Suc n)) ----> l = f ----> l" by (blast intro: LIMSEQ_imp_Suc LIMSEQ_Suc) +lemma LIMSEQ_linear: "\ X ----> x ; l > 0 \ \ (\ n. X (n * l)) ----> x" + unfolding LIMSEQ_def + by (metis div_le_dividend div_mult_self1_is_m le_trans nat_mult_commute) + + lemma add_diff_add: fixes a b c d :: "'a::ab_group_add" shows "(a + c) - (b + d) = (a - b) + (c - d)" @@ -678,6 +683,69 @@ lemma mono_SucI2: "\n. X (Suc n) \ X n ==> monoseq X" by (simp add: monoseq_Suc) +lemma monoseq_minus: assumes "monoseq a" + shows "monoseq (\ n. - a n)" +proof (cases "\ m. \ n \ m. a m \ a n") + case True + hence "\ m. \ n \ m. - a n \ - a m" by auto + thus ?thesis by (rule monoI2) +next + case False + hence "\ m. \ n \ m. - a m \ - a n" using `monoseq a`[unfolded monoseq_def] by auto + thus ?thesis by (rule monoI1) +qed + +lemma monoseq_le: assumes "monoseq a" and "a ----> x" + shows "((\ n. a n \ x) \ (\m. \n\m. a m \ a n)) \ + ((\ n. x \ a n) \ (\m. \n\m. a n \ a m))" +proof - + { fix x n fix a :: "nat \ real" + assume "a ----> x" and "\ m. \ n \ m. a m \ a n" + hence monotone: "\ m n. m \ n \ a m \ a n" by auto + have "a n \ x" + proof (rule ccontr) + assume "\ a n \ x" hence "x < a n" by auto + hence "0 < a n - x" by auto + from `a ----> x`[THEN LIMSEQ_D, OF this] + obtain no where "\n'. no \ n' \ norm (a n' - x) < a n - x" by blast + hence "norm (a (max no n) - x) < a n - x" by auto + moreover + { fix n' have "n \ n' \ x < a n'" using monotone[where m=n and n=n'] and `x < a n` by auto } + hence "x < a (max no n)" by auto + ultimately + have "a (max no n) < a n" by auto + with monotone[where m=n and n="max no n"] + show False by auto + qed + } note top_down = this + { fix x n m fix a :: "nat \ real" + assume "a ----> x" and "monoseq a" and "a m < x" + have "a n \ x \ (\ m. \ n \ m. a m \ a n)" + proof (cases "\ m. \ n \ m. a m \ a n") + case True with top_down and `a ----> x` show ?thesis by auto + next + case False with `monoseq a`[unfolded monoseq_def] have "\ m. \ n \ m. - a m \ - a n" by auto + hence "- a m \ - x" using top_down[OF LIMSEQ_minus[OF `a ----> x`]] by blast + hence False using `a m < x` by auto + thus ?thesis .. + qed + } note when_decided = this + + show ?thesis + proof (cases "\ m. a m \ x") + case True then obtain m where "a m \ x" by auto + show ?thesis + proof (cases "a m < x") + case True with when_decided[OF `a ----> x` `monoseq a`, where m2=m] + show ?thesis by blast + next + case False hence "- a m < - x" using `a m \ x` by auto + with when_decided[OF LIMSEQ_minus[OF `a ----> x`] monoseq_minus[OF `monoseq a`], where m2=m] + show ?thesis by auto + qed + qed auto +qed + text{*Bounded Sequence*} lemma BseqD: "Bseq X ==> \K. 0 < K & (\n. norm (X n) \ K)" diff -r d201a838d0f7 -r c56a5571f60a src/HOL/Series.thy --- a/src/HOL/Series.thy Wed Feb 04 18:10:07 2009 +0100 +++ b/src/HOL/Series.thy Thu Feb 05 11:34:42 2009 +0100 @@ -140,6 +140,24 @@ suminf f = (SUM i = 0..< k. f i) + suminf (%n. f(n + k))" by (auto simp add: suminf_minus_initial_segment) +lemma suminf_exist_split: fixes r :: real assumes "0 < r" and "summable a" + shows "\ N. \ n \ N. \ \ i. a (i + n) \ < r" +proof - + from LIMSEQ_D[OF summable_sumr_LIMSEQ_suminf[OF `summable a`] `0 < r`] + obtain N :: nat where "\ n \ N. norm (setsum a {0.. n. f (Suc n)) sums l" shows "f sums (l + f 0)" +proof - + from sumSuc[unfolded sums_def] + have "(\i. \n = Suc 0.. l" unfolding setsum_reindex[OF inj_Suc] image_Suc_atLeastLessThan[symmetric] comp_def . + from LIMSEQ_add_const[OF this, where b="f 0"] + have "(\i. \n = 0.. l + f 0" unfolding add_commute setsum_head_upt_Suc[OF zero_less_Suc] . + thus ?thesis unfolding sums_def by (rule LIMSEQ_imp_Suc) +qed + lemma series_zero: "(\m. n \ m --> f(m) = 0) ==> f sums (setsum f {0.. summable (%n. f(n) * (z ^ n))" by (rule powser_insidea [THEN summable_norm_cancel]) +lemma sum_split_even_odd: fixes f :: "nat \ real" shows + "(\ i = 0 ..< 2 * n. if even i then f i else g i) = + (\ i = 0 ..< n. f (2 * i)) + (\ i = 0 ..< n. g (2 * i + 1))" +proof (induct n) + case (Suc n) + have "(\ i = 0 ..< 2 * Suc n. if even i then f i else g i) = + (\ i = 0 ..< n. f (2 * i)) + (\ i = 0 ..< n. g (2 * i + 1)) + (f (2 * n) + g (2 * n + 1))" + using Suc.hyps by auto + also have "\ = (\ i = 0 ..< Suc n. f (2 * i)) + (\ i = 0 ..< Suc n. g (2 * i + 1))" by auto + finally show ?case . +qed auto + +lemma sums_if': fixes g :: "nat \ real" assumes "g sums x" + shows "(\ n. if even n then 0 else g ((n - 1) div 2)) sums x" + unfolding sums_def +proof (rule LIMSEQ_I) + fix r :: real assume "0 < r" + from `g sums x`[unfolded sums_def, THEN LIMSEQ_D, OF this] + obtain no where no_eq: "\ n. n \ no \ (norm (setsum g { 0.. 2 * no" hence "m div 2 \ no" by auto + have sum_eq: "?SUM (2 * (m div 2)) = setsum g { 0 ..< m div 2 }" + using sum_split_even_odd by auto + hence "(norm (?SUM (2 * (m div 2)) - x) < r)" using no_eq unfolding sum_eq using `m div 2 \ no` by auto + moreover + have "?SUM (2 * (m div 2)) = ?SUM m" + proof (cases "even m") + case True show ?thesis unfolding even_nat_div_two_times_two[OF True, unfolded numeral_2_eq_2[symmetric]] .. + next + case False hence "even (Suc m)" by auto + from even_nat_div_two_times_two[OF this, unfolded numeral_2_eq_2[symmetric]] odd_nat_plus_one_div_two[OF False, unfolded numeral_2_eq_2[symmetric]] + have eq: "Suc (2 * (m div 2)) = m" by auto + hence "even (2 * (m div 2))" using `odd m` by auto + have "?SUM m = ?SUM (Suc (2 * (m div 2)))" unfolding eq .. + also have "\ = ?SUM (2 * (m div 2))" using `even (2 * (m div 2))` by auto + finally show ?thesis by auto + qed + ultimately have "(norm (?SUM m - x) < r)" by auto + } + thus "\ no. \ m \ no. norm (?SUM m - x) < r" by blast +qed + +lemma sums_if: fixes g :: "nat \ real" assumes "g sums x" and "f sums y" + shows "(\ n. if even n then f (n div 2) else g ((n - 1) div 2)) sums (x + y)" +proof - + let ?s = "\ n. if even n then 0 else f ((n - 1) div 2)" + { fix B T E have "(if B then (0 :: real) else E) + (if B then T else 0) = (if B then T else E)" + by (cases B) auto } note if_sum = this + have g_sums: "(\ n. if even n then 0 else g ((n - 1) div 2)) sums x" using sums_if'[OF `g sums x`] . + { + have "?s 0 = 0" by auto + have Suc_m1: "\ n. Suc n - 1 = n" by auto + { fix B T E have "(if \ B then T else E) = (if B then E else T)" by auto } note if_eq = this + + have "?s sums y" using sums_if'[OF `f sums y`] . + from this[unfolded sums_def, THEN LIMSEQ_Suc] + have "(\ n. if even n then f (n div 2) else 0) sums y" + unfolding sums_def setsum_shift_lb_Suc0_0_upt[where f="?s", OF `?s 0 = 0`, symmetric] + image_Suc_atLeastLessThan[symmetric] setsum_reindex[OF inj_Suc, unfolded comp_def] + even_nat_Suc Suc_m1 if_eq . + } from sums_add[OF g_sums this] + show ?thesis unfolding if_sum . +qed + +subsection {* Alternating series test / Leibniz formula *} + +lemma sums_alternating_upper_lower: + fixes a :: "nat \ real" + assumes mono: "\n. a (Suc n) \ a n" and a_pos: "\n. 0 \ a n" and "a ----> 0" + shows "\l. ((\n. (\i=0..<2*n. -1^i*a i) \ l) \ (\ n. \i=0..<2*n. -1^i*a i) ----> l) \ + ((\n. l \ (\i=0..<2*n + 1. -1^i*a i)) \ (\ n. \i=0..<2*n + 1. -1^i*a i) ----> l)" + (is "\l. ((\n. ?f n \ l) \ _) \ ((\n. l \ ?g n) \ _)") +proof - + have fg_diff: "\n. ?f n - ?g n = - a (2 * n)" by auto + + have "\ n. ?f n \ ?f (Suc n)" + proof fix n show "?f n \ ?f (Suc n)" using mono[of "2*n"] by auto qed + moreover + have "\ n. ?g (Suc n) \ ?g n" + proof fix n show "?g (Suc n) \ ?g n" using mono[of "Suc (2*n)"] by auto qed + moreover + have "\ n. ?f n \ ?g n" + proof fix n show "?f n \ ?g n" using fg_diff a_pos by auto qed + moreover + have "(\ n. ?f n - ?g n) ----> 0" unfolding fg_diff + proof (rule LIMSEQ_I) + fix r :: real assume "0 < r" + with `a ----> 0`[THEN LIMSEQ_D] + obtain N where "\ n. n \ N \ norm (a n - 0) < r" by auto + hence "\ n \ N. norm (- a (2 * n) - 0) < r" by auto + thus "\ N. \ n \ N. norm (- a (2 * n) - 0) < r" by auto + qed + ultimately + show ?thesis by (rule lemma_nest_unique) +qed + +lemma summable_Leibniz': fixes a :: "nat \ real" + assumes a_zero: "a ----> 0" and a_pos: "\ n. 0 \ a n" + and a_monotone: "\ n. a (Suc n) \ a n" + shows summable: "summable (\ n. (-1)^n * a n)" + and "\n. (\i=0..<2*n. (-1)^i*a i) \ (\i. (-1)^i*a i)" + and "(\n. \i=0..<2*n. (-1)^i*a i) ----> (\i. (-1)^i*a i)" + and "\n. (\i. (-1)^i*a i) \ (\i=0..<2*n+1. (-1)^i*a i)" + and "(\n. \i=0..<2*n+1. (-1)^i*a i) ----> (\i. (-1)^i*a i)" +proof - + let "?S n" = "(-1)^n * a n" + let "?P n" = "\i=0.. n. ?f n \ l" and "?f ----> l" and above_l: "\ n. l \ ?g n" and "?g ----> l" + using sums_alternating_upper_lower[OF a_monotone a_pos a_zero] by blast + + let ?Sa = "\ m. \ n = 0.. l" + proof (rule LIMSEQ_I) + fix r :: real assume "0 < r" + + with `?f ----> l`[THEN LIMSEQ_D] + obtain f_no where f: "\ n. n \ f_no \ norm (?f n - l) < r" by auto + + from `0 < r` `?g ----> l`[THEN LIMSEQ_D] + obtain g_no where g: "\ n. n \ g_no \ norm (?g n - l) < r" by auto + + { fix n :: nat + assume "n \ (max (2 * f_no) (2 * g_no))" hence "n \ 2 * f_no" and "n \ 2 * g_no" by auto + have "norm (?Sa n - l) < r" + proof (cases "even n") + case True from even_nat_div_two_times_two[OF this] + have n_eq: "2 * (n div 2) = n" unfolding numeral_2_eq_2[symmetric] by auto + with `n \ 2 * f_no` have "n div 2 \ f_no" by auto + from f[OF this] + show ?thesis unfolding n_eq atLeastLessThanSuc_atLeastAtMost . + next + case False hence "even (n - 1)" using even_num_iff odd_pos by auto + from even_nat_div_two_times_two[OF this] + have n_eq: "2 * ((n - 1) div 2) = n - 1" unfolding numeral_2_eq_2[symmetric] by auto + hence range_eq: "n - 1 + 1 = n" using odd_pos[OF False] by auto + + from n_eq `n \ 2 * g_no` have "(n - 1) div 2 \ g_no" by auto + from g[OF this] + show ?thesis unfolding n_eq atLeastLessThanSuc_atLeastAtMost range_eq . + qed + } + thus "\ no. \ n \ no. norm (?Sa n - l) < r" by blast + qed + hence sums_l: "(\i. (-1)^i * a i) sums l" unfolding sums_def atLeastLessThanSuc_atLeastAtMost[symmetric] . + thus "summable ?S" using summable_def by auto + + have "l = suminf ?S" using sums_unique[OF sums_l] . + + { fix n show "suminf ?S \ ?g n" unfolding sums_unique[OF sums_l, symmetric] using above_l by auto } + { fix n show "?f n \ suminf ?S" unfolding sums_unique[OF sums_l, symmetric] using below_l by auto } + show "?g ----> suminf ?S" using `?g ----> l` `l = suminf ?S` by auto + show "?f ----> suminf ?S" using `?f ----> l` `l = suminf ?S` by auto +qed + +theorem summable_Leibniz: fixes a :: "nat \ real" + assumes a_zero: "a ----> 0" and "monoseq a" + shows "summable (\ n. (-1)^n * a n)" (is "?summable") + and "0 < a 0 \ (\n. (\i. -1^i*a i) \ { \i=0..<2*n. -1^i * a i .. \i=0..<2*n+1. -1^i * a i})" (is "?pos") + and "a 0 < 0 \ (\n. (\i. -1^i*a i) \ { \i=0..<2*n+1. -1^i * a i .. \i=0..<2*n. -1^i * a i})" (is "?neg") + and "(\n. \i=0..<2*n. -1^i*a i) ----> (\i. -1^i*a i)" (is "?f") + and "(\n. \i=0..<2*n+1. -1^i*a i) ----> (\i. -1^i*a i)" (is "?g") +proof - + have "?summable \ ?pos \ ?neg \ ?f \ ?g" + proof (cases "(\ n. 0 \ a n) \ (\m. \n\m. a n \ a m)") + case True + hence ord: "\n m. m \ n \ a n \ a m" and ge0: "\ n. 0 \ a n" by auto + { fix n have "a (Suc n) \ a n" using ord[where n="Suc n" and m=n] by auto } + note leibniz = summable_Leibniz'[OF `a ----> 0` ge0] and mono = this + from leibniz[OF mono] + show ?thesis using `0 \ a 0` by auto + next + let ?a = "\ n. - a n" + case False + with monoseq_le[OF `monoseq a` `a ----> 0`] + have "(\ n. a n \ 0) \ (\m. \n\m. a m \ a n)" by auto + hence ord: "\n m. m \ n \ ?a n \ ?a m" and ge0: "\ n. 0 \ ?a n" by auto + { fix n have "?a (Suc n) \ ?a n" using ord[where n="Suc n" and m=n] by auto } + note monotone = this + note leibniz = summable_Leibniz'[OF _ ge0, of "\x. x", OF LIMSEQ_minus[OF `a ----> 0`, unfolded minus_zero] monotone] + have "summable (\ n. (-1)^n * ?a n)" using leibniz(1) by auto + then obtain l where "(\ n. (-1)^n * ?a n) sums l" unfolding summable_def by auto + from this[THEN sums_minus] + have "(\ n. (-1)^n * a n) sums -l" by auto + hence ?summable unfolding summable_def by auto + moreover + have "\ a b :: real. \ - a - - b \ = \a - b\" unfolding minus_diff_minus by auto + + from suminf_minus[OF leibniz(1), unfolded mult_minus_right minus_minus] + have move_minus: "(\n. - (-1 ^ n * a n)) = - (\n. -1 ^ n * a n)" by auto + + have ?pos using `0 \ ?a 0` by auto + moreover have ?neg using leibniz(2,4) unfolding mult_minus_right setsum_negf move_minus neg_le_iff_le by auto + moreover have ?f and ?g using leibniz(3,5)[unfolded mult_minus_right setsum_negf move_minus, THEN LIMSEQ_minus_cancel] by auto + ultimately show ?thesis by auto + qed + from this[THEN conjunct1] this[THEN conjunct2, THEN conjunct1] this[THEN conjunct2, THEN conjunct2, THEN conjunct1] this[THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct1] + this[THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2] + show ?summable and ?pos and ?neg and ?f and ?g . +qed subsection {* Term-by-Term Differentiability of Power Series *} @@ -432,6 +634,188 @@ lemma inv_real_of_nat_fact_ge_zero [simp]: "0 \ inverse (real (fact n))" by (auto intro: order_less_imp_le) +subsection {* Derivability of power series *} + +lemma DERIV_series': fixes f :: "real \ nat \ real" + assumes DERIV_f: "\ n. DERIV (\ x. f x n) x0 :> (f' x0 n)" + and allf_summable: "\ x. x \ {a <..< b} \ summable (f x)" and x0_in_I: "x0 \ {a <..< b}" + and "summable (f' x0)" + and "summable L" and L_def: "\ n x y. \ x \ { a <..< b} ; y \ { a <..< b} \ \ \ f x n - f y n \ \ L n * \ x - y \" + shows "DERIV (\ x. suminf (f x)) x0 :> (suminf (f' x0))" + unfolding deriv_def +proof (rule LIM_I) + fix r :: real assume "0 < r" hence "0 < r/3" by auto + + obtain N_L where N_L: "\ n. N_L \ n \ \ \ i. L (i + n) \ < r/3" + using suminf_exist_split[OF `0 < r/3` `summable L`] by auto + + obtain N_f' where N_f': "\ n. N_f' \ n \ \ \ i. f' x0 (i + n) \ < r/3" + using suminf_exist_split[OF `0 < r/3` `summable (f' x0)`] by auto + + let ?N = "Suc (max N_L N_f')" + have "\ \ i. f' x0 (i + ?N) \ < r/3" (is "?f'_part < r/3") and + L_estimate: "\ \ i. L (i + ?N) \ < r/3" using N_L[of "?N"] and N_f' [of "?N"] by auto + + let "?diff i x" = "(f (x0 + x) i - f x0 i) / x" + + let ?r = "r / (3 * real ?N)" + have "0 < 3 * real ?N" by auto + from divide_pos_pos[OF `0 < r` this] + have "0 < ?r" . + + let "?s n" = "SOME s. 0 < s \ (\ x. x \ 0 \ \ x \ < s \ \ ?diff n x - f' x0 n \ < ?r)" + def S' \ "Min (?s ` { 0 ..< ?N })" + + have "0 < S'" unfolding S'_def + proof (rule iffD2[OF Min_gr_iff]) + show "\ x \ (?s ` { 0 ..< ?N }). 0 < x" + proof (rule ballI) + fix x assume "x \ ?s ` {0.. {0.. (\x. x \ 0 \ \x\ < s \ \?diff n x - f' x0 n\ < ?r)" by auto + have "0 < ?s n" by (rule someI2[where a=s], auto simp add: s_bound) + thus "0 < x" unfolding `x = ?s n` . + qed + qed auto + + def S \ "min (min (x0 - a) (b - x0)) S'" + hence "0 < S" and S_a: "S \ x0 - a" and S_b: "S \ b - x0" and "S \ S'" using x0_in_I and `0 < S'` + by auto + + { fix x assume "x \ 0" and "\ x \ < S" + hence x_in_I: "x0 + x \ { a <..< b }" using S_a S_b by auto + + note diff_smbl = summable_diff[OF allf_summable[OF x_in_I] allf_summable[OF x0_in_I]] + note div_smbl = summable_divide[OF diff_smbl] + note all_smbl = summable_diff[OF div_smbl `summable (f' x0)`] + note ign = summable_ignore_initial_segment[where k="?N"] + note diff_shft_smbl = summable_diff[OF ign[OF allf_summable[OF x_in_I]] ign[OF allf_summable[OF x0_in_I]]] + note div_shft_smbl = summable_divide[OF diff_shft_smbl] + note all_shft_smbl = summable_diff[OF div_smbl ign[OF `summable (f' x0)`]] + + { fix n + have "\ ?diff (n + ?N) x \ \ L (n + ?N) * \ (x0 + x) - x0 \ / \ x \" + using divide_right_mono[OF L_def[OF x_in_I x0_in_I] abs_ge_zero] unfolding abs_divide . + hence "\ ( \ ?diff (n + ?N) x \) \ \ L (n + ?N)" using `x \ 0` by auto + } note L_ge = summable_le2[OF allI[OF this] ign[OF `summable L`]] + from order_trans[OF summable_rabs[OF conjunct1[OF L_ge]] L_ge[THEN conjunct2]] + have "\ \ i. ?diff (i + ?N) x \ \ (\ i. L (i + ?N))" . + hence "\ \ i. ?diff (i + ?N) x \ \ r / 3" (is "?L_part \ r/3") using L_estimate by auto + + have "\\n \ { 0 ..< ?N}. ?diff n x - f' x0 n \ \ (\n \ { 0 ..< ?N}. \?diff n x - f' x0 n \)" .. + also have "\ < (\n \ { 0 ..< ?N}. ?r)" + proof (rule setsum_strict_mono) + fix n assume "n \ { 0 ..< ?N}" + have "\ x \ < S" using `\ x \ < S` . + also have "S \ S'" using `S \ S'` . + also have "S' \ ?s n" unfolding S'_def + proof (rule Min_le_iff[THEN iffD2]) + have "?s n \ (?s ` {0.. ?s n \ ?s n" using `n \ { 0 ..< ?N}` by auto + thus "\ a \ (?s ` {0.. ?s n" by blast + qed auto + finally have "\ x \ < ?s n" . + + from DERIV_D[OF DERIV_f[where n=n], THEN LIM_D, OF `0 < ?r`, unfolded real_norm_def diff_0_right, unfolded some_eq_ex[symmetric], THEN conjunct2] + have "\x. x \ 0 \ \x\ < ?s n \ \?diff n x - f' x0 n\ < ?r" . + with `x \ 0` and `\x\ < ?s n` + show "\?diff n x - f' x0 n\ < ?r" by blast + qed auto + also have "\ = of_nat (card {0 ..< ?N}) * ?r" by (rule setsum_constant) + also have "\ = real ?N * ?r" unfolding real_eq_of_nat by auto + also have "\ = r/3" by auto + finally have "\\n \ { 0 ..< ?N}. ?diff n x - f' x0 n \ < r / 3" (is "?diff_part < r / 3") . + + from suminf_diff[OF allf_summable[OF x_in_I] allf_summable[OF x0_in_I]] + have "\ (suminf (f (x0 + x)) - (suminf (f x0))) / x - suminf (f' x0) \ = + \ \n. ?diff n x - f' x0 n \" unfolding suminf_diff[OF div_smbl `summable (f' x0)`, symmetric] using suminf_divide[OF diff_smbl, symmetric] by auto + also have "\ \ ?diff_part + \ (\n. ?diff (n + ?N) x) - (\ n. f' x0 (n + ?N)) \" unfolding suminf_split_initial_segment[OF all_smbl, where k="?N"] unfolding suminf_diff[OF div_shft_smbl ign[OF `summable (f' x0)`]] by (rule abs_triangle_ineq) + also have "\ \ ?diff_part + ?L_part + ?f'_part" using abs_triangle_ineq4 by auto + also have "\ < r /3 + r/3 + r/3" + using `?diff_part < r/3` `?L_part \ r/3` and `?f'_part < r/3` by auto + finally have "\ (suminf (f (x0 + x)) - (suminf (f x0))) / x - suminf (f' x0) \ < r" + by auto + } thus "\ s > 0. \ x. x \ 0 \ norm (x - 0) < s \ + norm (((\n. f (x0 + x) n) - (\n. f x0 n)) / x - (\n. f' x0 n)) < r" using `0 < S` + unfolding real_norm_def diff_0_right by blast +qed + +lemma DERIV_power_series': fixes f :: "nat \ real" + assumes converges: "\ x. x \ {-R <..< R} \ summable (\ n. f n * real (Suc n) * x^n)" + and x0_in_I: "x0 \ {-R <..< R}" and "0 < R" + shows "DERIV (\ x. (\ n. f n * x^(Suc n))) x0 :> (\ n. f n * real (Suc n) * x0^n)" + (is "DERIV (\ x. (suminf (?f x))) x0 :> (suminf (?f' x0))") +proof - + { fix R' assume "0 < R'" and "R' < R" and "-R' < x0" and "x0 < R'" + hence "x0 \ {-R' <..< R'}" and "R' \ {-R <..< R}" and "x0 \ {-R <..< R}" by auto + have "DERIV (\ x. (suminf (?f x))) x0 :> (suminf (?f' x0))" + proof (rule DERIV_series') + show "summable (\ n. \f n * real (Suc n) * R'^n\)" + proof - + have "(R' + R) / 2 < R" and "0 < (R' + R) / 2" using `0 < R'` `0 < R` `R' < R` by auto + hence in_Rball: "(R' + R) / 2 \ {-R <..< R}" using `R' < R` by auto + have "norm R' < norm ((R' + R) / 2)" using `0 < R'` `0 < R` `R' < R` by auto + from powser_insidea[OF converges[OF in_Rball] this] show ?thesis by auto + qed + { fix n x y assume "x \ {-R' <..< R'}" and "y \ {-R' <..< R'}" + show "\?f x n - ?f y n\ \ \f n * real (Suc n) * R'^n\ * \x-y\" + proof - + have "\f n * x ^ (Suc n) - f n * y ^ (Suc n)\ = (\f n\ * \x-y\) * \\p = 0.." + unfolding right_diff_distrib[symmetric] lemma_realpow_diff_sumr2 abs_mult by auto + also have "\ \ (\f n\ * \x-y\) * (\real (Suc n)\ * \R' ^ n\)" + proof (rule mult_left_mono) + have "\\p = 0.. \ (\p = 0..x ^ p * y ^ (n - p)\)" by (rule setsum_abs) + also have "\ \ (\p = 0.. {0.. n" by auto + { fix n fix x :: real assume "x \ {-R'<..x\ \ R'" by auto + hence "\x^n\ \ R'^n" unfolding power_abs by (rule power_mono, auto) + } from mult_mono[OF this[OF `x \ {-R'<.. {-R'<..x^p * y^(n-p)\ \ R'^p * R'^(n-p)" unfolding abs_mult by auto + thus "\x^p * y^(n-p)\ \ R'^n" unfolding power_add[symmetric] using `p \ n` by auto + qed + also have "\ = real (Suc n) * R' ^ n" unfolding setsum_constant card_atLeastLessThan real_of_nat_def by auto + finally show "\\p = 0.. \ \real (Suc n)\ * \R' ^ n\" unfolding abs_real_of_nat_cancel abs_of_nonneg[OF zero_le_power[OF less_imp_le[OF `0 < R'`]]] . + show "0 \ \f n\ * \x - y\" unfolding abs_mult[symmetric] by auto + qed + also have "\ = \f n * real (Suc n) * R' ^ n\ * \x - y\" unfolding abs_mult real_mult_assoc[symmetric] by algebra + finally show ?thesis . + qed } + { fix n + from DERIV_pow[of "Suc n" x0, THEN DERIV_cmult[where c="f n"]] + show "DERIV (\ x. ?f x n) x0 :> (?f' x0 n)" unfolding real_mult_assoc by auto } + { fix x assume "x \ {-R' <..< R'}" hence "R' \ {-R <..< R}" and "norm x < norm R'" using assms `R' < R` by auto + have "summable (\ n. f n * x^n)" + proof (rule summable_le2[THEN conjunct1, OF _ powser_insidea[OF converges[OF `R' \ {-R <..< R}`] `norm x < norm R'`]], rule allI) + fix n + have le: "\f n\ * 1 \ \f n\ * real (Suc n)" by (rule mult_left_mono, auto) + show "\f n * x ^ n\ \ norm (f n * real (Suc n) * x ^ n)" unfolding real_norm_def abs_mult + by (rule mult_right_mono, auto simp add: le[unfolded mult_1_right]) + qed + from this[THEN summable_mult2[where c=x], unfolded real_mult_assoc, unfolded real_mult_commute] + show "summable (?f x)" by auto } + show "summable (?f' x0)" using converges[OF `x0 \ {-R <..< R}`] . + show "x0 \ {-R' <..< R'}" using `x0 \ {-R' <..< R'}` . + qed + } note for_subinterval = this + let ?R = "(R + \x0\) / 2" + have "\x0\ < ?R" using assms by auto + hence "- ?R < x0" + proof (cases "x0 < 0") + case True + hence "- x0 < ?R" using `\x0\ < ?R` by auto + thus ?thesis unfolding neg_less_iff_less[symmetric, of "- x0"] by auto + next + case False + have "- ?R < 0" using assms by auto + also have "\ \ x0" using False by auto + finally show ?thesis . + qed + hence "0 < ?R" "?R < R" "- ?R < x0" and "x0 < ?R" using assms by auto + from for_subinterval[OF this] + show ?thesis . +qed subsection {* Exponential Function *} @@ -830,6 +1214,37 @@ apply (simp_all add: abs_if isCont_ln) done +lemma ln_series: assumes "0 < x" and "x < 2" + shows "ln x = (\ n. (-1)^n * (1 / real (n + 1)) * (x - 1)^(Suc n))" (is "ln x = suminf (?f (x - 1))") +proof - + let "?f' x n" = "(-1)^n * (x - 1)^n" + + have "ln x - suminf (?f (x - 1)) = ln 1 - suminf (?f (1 - 1))" + proof (rule DERIV_isconst3[where x=x]) + fix x :: real assume "x \ {0 <..< 2}" hence "0 < x" and "x < 2" by auto + have "norm (1 - x) < 1" using `0 < x` and `x < 2` by auto + have "1 / x = 1 / (1 - (1 - x))" by auto + also have "\ = (\ n. (1 - x)^n)" using geometric_sums[OF `norm (1 - x) < 1`] by (rule sums_unique) + also have "\ = suminf (?f' x)" unfolding power_mult_distrib[symmetric] by (rule arg_cong[where f=suminf], rule arg_cong[where f="op ^"], auto) + finally have "DERIV ln x :> suminf (?f' x)" using DERIV_ln[OF `0 < x`] unfolding real_divide_def by auto + moreover + have repos: "\ h x :: real. h - 1 + x = h + x - 1" by auto + have "DERIV (\x. suminf (?f x)) (x - 1) :> (\n. (-1)^n * (1 / real (n + 1)) * real (Suc n) * (x - 1) ^ n)" + proof (rule DERIV_power_series') + show "x - 1 \ {- 1<..<1}" and "(0 :: real) < 1" using `0 < x` `x < 2` by auto + { fix x :: real assume "x \ {- 1<..<1}" hence "norm (-x) < 1" by auto + show "summable (\n. -1 ^ n * (1 / real (n + 1)) * real (Suc n) * x ^ n)" + by (auto simp del: power_mult_distrib simp add: power_mult_distrib[symmetric] summable_geometric[OF `norm (-x) < 1`]) + } + qed + hence "DERIV (\x. suminf (?f x)) (x - 1) :> suminf (?f' x)" by auto + hence "DERIV (\x. suminf (?f (x - 1))) x :> suminf (?f' x)" unfolding DERIV_iff repos . + ultimately have "DERIV (\x. ln x - suminf (?f (x - 1))) x :> (suminf (?f' x) - suminf (?f' x))" + by (rule DERIV_diff) + thus "DERIV (\x. ln x - suminf (?f (x - 1))) x :> 0" by auto + qed (auto simp add: assms) + thus ?thesis by (auto simp add: suminf_zero) +qed subsection {* Sine and Cosine *} @@ -1378,6 +1793,12 @@ lemma minus_pi_half_less_zero: "-(pi/2) < 0" by simp +lemma m2pi_less_pi: "- (2 * pi) < pi" +proof - + have "- (2 * pi) < 0" and "0 < pi" by auto + from order_less_trans[OF this] show ?thesis . +qed + lemma sin_pi_half [simp]: "sin(pi/2) = 1" apply (cut_tac x = "pi/2" in sin_cos_squared_add2) apply (cut_tac sin_gt_zero [OF pi_half_gt_zero pi_half_less_two]) @@ -1487,6 +1908,24 @@ apply (auto intro!: cos_gt_zero_pi simp del: sin_cos_eq [symmetric]) done + +lemma pi_ge_two: "2 \ pi" +proof (rule ccontr) + assume "\ 2 \ pi" hence "pi < 2" by auto + have "\y > pi. y < 2 \ y < 2 * pi" + proof (cases "2 < 2 * pi") + case True with dense[OF `pi < 2`] show ?thesis by auto + next + case False have "pi < 2 * pi" by auto + from dense[OF this] and False show ?thesis by auto + qed + then obtain y where "pi < y" and "y < 2" and "y < 2 * pi" by blast + hence "0 < sin y" using sin_gt_zero by auto + moreover + have "sin y < 0" using sin_gt_zero_pi[of "y - pi"] `pi < y` and `y < 2 * pi` sin_periodic_pi[of "y - pi"] by auto + ultimately show False by auto +qed + lemma sin_ge_zero: "[| 0 \ x; x \ pi |] ==> 0 \ sin x" by (auto simp add: order_le_less sin_gt_zero_pi) @@ -1586,6 +2025,48 @@ apply (auto simp add: even_mult_two_ex) done +lemma cos_monotone_0_pi: assumes "0 \ y" and "y < x" and "x \ pi" + shows "cos x < cos y" +proof - + have "- (x - y) < 0" by (auto!) + + from MVT2[OF `y < x` DERIV_cos[THEN impI, THEN allI]] + obtain z where "y < z" and "z < x" and cos_diff: "cos x - cos y = (x - y) * - sin z" by auto + hence "0 < z" and "z < pi" by (auto!) + hence "0 < sin z" using sin_gt_zero_pi by auto + hence "cos x - cos y < 0" unfolding cos_diff minus_mult_commute[symmetric] using `- (x - y) < 0` by (rule mult_pos_neg2) + thus ?thesis by auto +qed + +lemma cos_monotone_0_pi': assumes "0 \ y" and "y \ x" and "x \ pi" shows "cos x \ cos y" +proof (cases "y < x") + case True show ?thesis using cos_monotone_0_pi[OF `0 \ y` True `x \ pi`] by auto +next + case False hence "y = x" using `y \ x` by auto + thus ?thesis by auto +qed + +lemma cos_monotone_minus_pi_0: assumes "-pi \ y" and "y < x" and "x \ 0" + shows "cos y < cos x" +proof - + have "0 \ -x" and "-x < -y" and "-y \ pi" by (auto!) + from cos_monotone_0_pi[OF this] + show ?thesis unfolding cos_minus . +qed + +lemma cos_monotone_minus_pi_0': assumes "-pi \ y" and "y \ x" and "x \ 0" shows "cos y \ cos x" +proof (cases "y < x") + case True show ?thesis using cos_monotone_minus_pi_0[OF `-pi \ y` True `x \ 0`] by auto +next + case False hence "y = x" using `y \ x` by auto + thus ?thesis by auto +qed + +lemma sin_monotone_2pi': assumes "- (pi / 2) \ y" and "y \ x" and "x \ pi / 2" shows "sin y \ sin x" +proof - + have "0 \ y + pi / 2" and "y + pi / 2 \ x + pi / 2" and "x + pi /2 \ pi" using pi_ge_two by (auto!) + from cos_monotone_0_pi'[OF this] show ?thesis unfolding minus_sin_cos_eq[symmetric] by auto +qed subsection {* Tangent *} @@ -1653,6 +2134,22 @@ thus ?thesis by simp qed +lemma tan_half: fixes x :: real assumes "- (pi / 2) < x" and "x < pi / 2" + shows "tan x = sin (2 * x) / (cos (2 * x) + 1)" +proof - + from cos_gt_zero_pi[OF `- (pi / 2) < x` `x < pi / 2`] + have "cos x \ 0" by auto + + have minus_cos_2x: "\X. X - cos (2*x) = X - (cos x) ^ 2 + (sin x) ^ 2" unfolding cos_double by algebra + + have "tan x = (tan x + tan x) / 2" by auto + also have "\ = sin (x + x) / (cos x * cos x) / 2" unfolding add_tan_eq[OF `cos x \ 0` `cos x \ 0`] .. + also have "\ = sin (2 * x) / ((cos x) ^ 2 + (cos x) ^ 2 + cos (2*x) - cos (2*x))" unfolding divide_divide_eq_left numeral_2_eq_2 by auto + also have "\ = sin (2 * x) / ((cos x) ^ 2 + cos (2*x) + (sin x)^2)" unfolding minus_cos_2x by auto + also have "\ = sin (2 * x) / (cos (2*x) + 1)" by auto + finally show ?thesis . +qed + lemma lemma_DERIV_tan: "cos x \ 0 ==> DERIV (%x. sin(x)/cos(x)) x :> inverse((cos x)\)" apply (rule lemma_DERIV_subst) @@ -1726,6 +2223,73 @@ simp add: cos_gt_zero_pi [THEN less_imp_neq, THEN not_sym]) done +lemma tan_monotone: assumes "- (pi / 2) < y" and "y < x" and "x < pi / 2" + shows "tan y < tan x" +proof - + have "\ x'. y \ x' \ x' \ x \ DERIV tan x' :> inverse (cos x'^2)" + proof (rule allI, rule impI) + fix x' :: real assume "y \ x' \ x' \ x" + hence "-(pi/2) < x'" and "x' < pi/2" by (auto!) + from cos_gt_zero_pi[OF this] + have "cos x' \ 0" by auto + thus "DERIV tan x' :> inverse (cos x'^2)" by (rule DERIV_tan) + qed + from MVT2[OF `y < x` this] + obtain z where "y < z" and "z < x" and tan_diff: "tan x - tan y = (x - y) * inverse ((cos z)\)" by auto + hence "- (pi / 2) < z" and "z < pi / 2" by (auto!) + hence "0 < cos z" using cos_gt_zero_pi by auto + hence inv_pos: "0 < inverse ((cos z)\)" by auto + have "0 < x - y" using `y < x` by auto + from real_mult_order[OF this inv_pos] + have "0 < tan x - tan y" unfolding tan_diff by auto + thus ?thesis by auto +qed + +lemma tan_monotone': assumes "- (pi / 2) < y" and "y < pi / 2" and "- (pi / 2) < x" and "x < pi / 2" + shows "(y < x) = (tan y < tan x)" +proof + assume "y < x" thus "tan y < tan x" using tan_monotone and `- (pi / 2) < y` and `x < pi / 2` by auto +next + assume "tan y < tan x" + show "y < x" + proof (rule ccontr) + assume "\ y < x" hence "x \ y" by auto + hence "tan x \ tan y" + proof (cases "x = y") + case True thus ?thesis by auto + next + case False hence "x < y" using `x \ y` by auto + from tan_monotone[OF `- (pi/2) < x` this `y < pi / 2`] show ?thesis by auto + qed + thus False using `tan y < tan x` by auto + qed +qed + +lemma tan_inverse: "1 / (tan y) = tan (pi / 2 - y)" unfolding tan_def sin_cos_eq[of y] cos_sin_eq[of y] by auto + +lemma tan_periodic_pi[simp]: "tan (x + pi) = tan x" + by (simp add: tan_def) + +lemma tan_periodic_nat[simp]: fixes n :: nat shows "tan (x + real n * pi) = tan x" +proof (induct n arbitrary: x) + case (Suc n) + have split_pi_off: "x + real (Suc n) * pi = (x + real n * pi) + pi" unfolding Suc_plus1 real_of_nat_add real_of_one real_add_mult_distrib by auto + show ?case unfolding split_pi_off using Suc by auto +qed auto + +lemma tan_periodic_int[simp]: fixes i :: int shows "tan (x + real i * pi) = tan x" +proof (cases "0 \ i") + case True hence i_nat: "real i = real (nat i)" by auto + show ?thesis unfolding i_nat by auto +next + case False hence i_nat: "real i = - real (nat (-i))" by auto + have "tan x = tan (x + real i * pi - real i * pi)" by auto + also have "\ = tan (x + real i * pi)" unfolding i_nat mult_minus_left diff_minus_eq_add by (rule tan_periodic_nat) + finally show ?thesis by auto +qed + +lemma tan_periodic_n[simp]: "tan (x + number_of n * pi) = tan x" + using tan_periodic_int[of _ "number_of n" ] unfolding real_number_of . subsection {* Inverse Trigonometric Functions *} @@ -1968,7 +2532,6 @@ apply (simp, simp, simp, rule isCont_arctan) done - subsection {* More Theorems about Sin and Cos *} lemma cos_45: "cos (pi / 4) = sqrt 2 / 2" @@ -2115,6 +2678,464 @@ lemma cos_one_sin_zero: "cos x = 1 ==> sin x = 0" by (cut_tac x = x in sin_cos_squared_add3, auto) +subsection {* Machins formula *} + +lemma tan_total_pi4: assumes "\x\ < 1" + shows "\ z. - (pi / 4) < z \ z < pi / 4 \ tan z = x" +proof - + obtain z where "- (pi / 2) < z" and "z < pi / 2" and "tan z = x" using tan_total by blast + have "tan (pi / 4) = 1" and "tan (- (pi / 4)) = - 1" using tan_45 tan_minus by auto + have "z \ pi / 4" + proof (rule ccontr) + assume "\ (z \ pi / 4)" hence "z = pi / 4" by auto + have "tan z = 1" unfolding `z = pi / 4` `tan (pi / 4) = 1` .. + thus False unfolding `tan z = x` using `\x\ < 1` by auto + qed + have "z \ - (pi / 4)" + proof (rule ccontr) + assume "\ (z \ - (pi / 4))" hence "z = - (pi / 4)" by auto + have "tan z = - 1" unfolding `z = - (pi / 4)` `tan (- (pi / 4)) = - 1` .. + thus False unfolding `tan z = x` using `\x\ < 1` by auto + qed + + have "z < pi / 4" + proof (rule ccontr) + assume "\ (z < pi / 4)" hence "pi / 4 < z" using `z \ pi / 4` by auto + have "- (pi / 2) < pi / 4" using m2pi_less_pi by auto + from tan_monotone[OF this `pi / 4 < z` `z < pi / 2`] + have "1 < x" unfolding `tan z = x` `tan (pi / 4) = 1` . + thus False using `\x\ < 1` by auto + qed + moreover + have "-(pi / 4) < z" + proof (rule ccontr) + assume "\ (-(pi / 4) < z)" hence "z < - (pi / 4)" using `z \ - (pi / 4)` by auto + have "-(pi / 4) < pi / 2" using m2pi_less_pi by auto + from tan_monotone[OF `-(pi / 2) < z` `z < -(pi / 4)` this] + have "x < - 1" unfolding `tan z = x` `tan (-(pi / 4)) = - 1` . + thus False using `\x\ < 1` by auto + qed + ultimately show ?thesis using `tan z = x` by auto +qed + +lemma arctan_add: assumes "\x\ \ 1" and "\y\ < 1" + shows "arctan x + arctan y = arctan ((x + y) / (1 - x * y))" +proof - + obtain y' where "-(pi/4) < y'" and "y' < pi/4" and "tan y' = y" using tan_total_pi4[OF `\y\ < 1`] by blast + + have "pi / 4 < pi / 2" by auto + + have "\ x'. -(pi/4) \ x' \ x' \ pi/4 \ tan x' = x" + proof (cases "\x\ < 1") + case True from tan_total_pi4[OF this] obtain x' where "-(pi/4) < x'" and "x' < pi/4" and "tan x' = x" by blast + hence "-(pi/4) \ x'" and "x' \ pi/4" and "tan x' = x" by auto + thus ?thesis by auto + next + case False + show ?thesis + proof (cases "x = 1") + case True hence "tan (pi/4) = x" using tan_45 by auto + moreover + have "- pi \ pi" unfolding minus_le_self_iff by auto + hence "-(pi/4) \ pi/4" and "pi/4 \ pi/4" by auto + ultimately show ?thesis by blast + next + case False hence "x = -1" using `\ \x\ < 1` and `\x\ \ 1` by auto + hence "tan (-(pi/4)) = x" using tan_45 tan_minus by auto + moreover + have "- pi \ pi" unfolding minus_le_self_iff by auto + hence "-(pi/4) \ pi/4" and "-(pi/4) \ -(pi/4)" by auto + ultimately show ?thesis by blast + qed + qed + then obtain x' where "-(pi/4) \ x'" and "x' \ pi/4" and "tan x' = x" by blast + hence "-(pi/2) < x'" and "x' < pi/2" using order_le_less_trans[OF `x' \ pi/4` `pi / 4 < pi / 2`] by auto + + have "cos x' \ 0" using cos_gt_zero_pi[THEN less_imp_neq] and `-(pi/2) < x'` and `x' < pi/2` by auto + moreover have "cos y' \ 0" using cos_gt_zero_pi[THEN less_imp_neq] and `-(pi/4) < y'` and `y' < pi/4` by auto + ultimately have "cos x' * cos y' \ 0" by auto + + have divide_nonzero_divide: "\ A B C :: real. C \ 0 \ (A / C) / (B / C) = A / B" by auto + have divide_mult_commute: "\ A B C D :: real. A * B / (C * D) = (A / C) * (B / D)" by auto + + have "tan (x' + y') = sin (x' + y') / (cos x' * cos y' - sin x' * sin y')" unfolding tan_def cos_add .. + also have "\ = (tan x' + tan y') / ((cos x' * cos y' - sin x' * sin y') / (cos x' * cos y'))" unfolding add_tan_eq[OF `cos x' \ 0` `cos y' \ 0`] divide_nonzero_divide[OF `cos x' * cos y' \ 0`] .. + also have "\ = (tan x' + tan y') / (1 - tan x' * tan y')" unfolding tan_def diff_divide_distrib divide_self[OF `cos x' * cos y' \ 0`] unfolding divide_mult_commute .. + finally have tan_eq: "tan (x' + y') = (x + y) / (1 - x * y)" unfolding `tan y' = y` `tan x' = x` . + + have "arctan (tan (x' + y')) = x' + y'" using `-(pi/4) < y'` `-(pi/4) \ x'` `y' < pi/4` and `x' \ pi/4` by (auto intro!: arctan_tan) + moreover have "arctan (tan (x')) = x'" using `-(pi/2) < x'` and `x' < pi/2` by (auto intro!: arctan_tan) + moreover have "arctan (tan (y')) = y'" using `-(pi/4) < y'` and `y' < pi/4` by (auto intro!: arctan_tan) + ultimately have "arctan x + arctan y = arctan (tan (x' + y'))" unfolding `tan y' = y` [symmetric] `tan x' = x`[symmetric] by auto + thus "arctan x + arctan y = arctan ((x + y) / (1 - x * y))" unfolding tan_eq . +qed + +lemma arctan1_eq_pi4: "arctan 1 = pi / 4" unfolding tan_45[symmetric] by (rule arctan_tan, auto simp add: m2pi_less_pi) + +theorem machin: "pi / 4 = 4 * arctan (1/5) - arctan (1 / 239)" +proof - + have "\1 / 5\ < (1 :: real)" by auto + from arctan_add[OF less_imp_le[OF this] this] + have "2 * arctan (1 / 5) = arctan (5 / 12)" by auto + moreover + have "\5 / 12\ < (1 :: real)" by auto + from arctan_add[OF less_imp_le[OF this] this] + have "2 * arctan (5 / 12) = arctan (120 / 119)" by auto + moreover + have "\1\ \ (1::real)" and "\1 / 239\ < (1::real)" by auto + from arctan_add[OF this] + have "arctan 1 + arctan (1 / 239) = arctan (120 / 119)" by auto + ultimately have "arctan 1 + arctan (1 / 239) = 4 * arctan (1 / 5)" by auto + thus ?thesis unfolding arctan1_eq_pi4 by algebra +qed +subsection {* Introducing the arcus tangens power series *} + +lemma monoseq_arctan_series: fixes x :: real + assumes "\x\ \ 1" shows "monoseq (\ n. 1 / real (n*2+1) * x^(n*2+1))" (is "monoseq ?a") +proof (cases "x = 0") case True thus ?thesis unfolding monoseq_def by auto +next + case False + have "norm x \ 1" and "x \ 1" and "-1 \ x" using assms by auto + show "monoseq ?a" + proof - + { fix n fix x :: real assume "0 \ x" and "x \ 1" + have "1 / real (Suc (Suc n * 2)) * x ^ Suc (Suc n * 2) \ 1 / real (Suc (n * 2)) * x ^ Suc (n * 2)" + proof (rule mult_mono) + show "1 / real (Suc (Suc n * 2)) \ 1 / real (Suc (n * 2))" by (rule frac_le) simp_all + show "0 \ 1 / real (Suc (n * 2))" by auto + show "x ^ Suc (Suc n * 2) \ x ^ Suc (n * 2)" by (rule power_decreasing) (simp_all add: `0 \ x` `x \ 1`) + show "0 \ x ^ Suc (Suc n * 2)" by (rule zero_le_power) (simp add: `0 \ x`) + qed + } note mono = this + + show ?thesis + proof (cases "0 \ x") + case True from mono[OF this `x \ 1`, THEN allI] + show ?thesis unfolding Suc_plus1[symmetric] by (rule mono_SucI2) + next + case False hence "0 \ -x" and "-x \ 1" using `-1 \ x` by auto + from mono[OF this] + have "\n. 1 / real (Suc (Suc n * 2)) * x ^ Suc (Suc n * 2) \ 1 / real (Suc (n * 2)) * x ^ Suc (n * 2)" using `0 \ -x` by auto + thus ?thesis unfolding Suc_plus1[symmetric] by (rule mono_SucI1[OF allI]) + qed + qed +qed + +lemma zeroseq_arctan_series: fixes x :: real + assumes "\x\ \ 1" shows "(\ n. 1 / real (n*2+1) * x^(n*2+1)) ----> 0" (is "?a ----> 0") +proof (cases "x = 0") case True thus ?thesis by (auto simp add: LIMSEQ_const) +next + case False + have "norm x \ 1" and "x \ 1" and "-1 \ x" using assms by auto + show "?a ----> 0" + proof (cases "\x\ < 1") + case True hence "norm x < 1" by auto + from LIMSEQ_mult[OF LIMSEQ_inverse_real_of_nat LIMSEQ_power_zero[OF `norm x < 1`, THEN LIMSEQ_Suc]] + show ?thesis unfolding inverse_eq_divide Suc_plus1 using LIMSEQ_linear[OF _ pos2] by auto + next + case False hence "x = -1 \ x = 1" using `\x\ \ 1` by auto + hence n_eq: "\ n. x ^ (n * 2 + 1) = x" by auto + from LIMSEQ_mult[OF LIMSEQ_inverse_real_of_nat[THEN LIMSEQ_linear, OF pos2, unfolded inverse_eq_divide] LIMSEQ_const[of x]] + show ?thesis unfolding n_eq by auto + qed +qed + +lemma summable_arctan_series: fixes x :: real and n :: nat + assumes "\x\ \ 1" shows "summable (\ k. (-1)^k * (1 / real (k*2+1) * x ^ (k*2+1)))" (is "summable (?c x)") + by (rule summable_Leibniz(1), rule zeroseq_arctan_series[OF assms], rule monoseq_arctan_series[OF assms]) + +lemma less_one_imp_sqr_less_one: fixes x :: real assumes "\x\ < 1" shows "x^2 < 1" +proof - + from mult_mono1[OF less_imp_le[OF `\x\ < 1`] abs_ge_zero[of x]] + have "\ x^2 \ < 1" using `\ x \ < 1` unfolding numeral_2_eq_2 power_Suc2 by auto + thus ?thesis using zero_le_power2 by auto +qed + +lemma DERIV_arctan_series: assumes "\ x \ < 1" + shows "DERIV (\ x'. \ k. (-1)^k * (1 / real (k*2+1) * x' ^ (k*2+1))) x :> (\ k. (-1)^k * x^(k*2))" (is "DERIV ?arctan _ :> ?Int") +proof - + let "?f n" = "if even n then (-1)^(n div 2) * 1 / real (Suc n) else 0" + + { fix n :: nat assume "even n" hence "2 * (n div 2) = n" by presburger } note n_even=this + have if_eq: "\ n x'. ?f n * real (Suc n) * x'^n = (if even n then (-1)^(n div 2) * x'^(2 * (n div 2)) else 0)" using n_even by auto + + { fix x :: real assume "\x\ < 1" hence "x^2 < 1" by (rule less_one_imp_sqr_less_one) + have "summable (\ n. -1 ^ n * (x^2) ^n)" + by (rule summable_Leibniz(1), auto intro!: LIMSEQ_realpow_zero monoseq_realpow `x^2 < 1` order_less_imp_le[OF `x^2 < 1`]) + hence "summable (\ n. -1 ^ n * x^(2*n))" unfolding power_mult . + } note summable_Integral = this + + { fix f :: "nat \ real" + have "\ x. f sums x = (\ n. if even n then f (n div 2) else 0) sums x" + proof + fix x :: real assume "f sums x" + from sums_if[OF sums_zero this] + show "(\ n. if even n then f (n div 2) else 0) sums x" by auto + next + fix x :: real assume "(\ n. if even n then f (n div 2) else 0) sums x" + from LIMSEQ_linear[OF this[unfolded sums_def] pos2, unfolded sum_split_even_odd[unfolded mult_commute]] + show "f sums x" unfolding sums_def by auto + qed + hence "op sums f = op sums (\ n. if even n then f (n div 2) else 0)" .. + } note sums_even = this + + have Int_eq: "(\ n. ?f n * real (Suc n) * x^n) = ?Int" unfolding if_eq mult_commute[of _ 2] suminf_def sums_even[of "\ n. -1 ^ n * x ^ (2 * n)", symmetric] + by auto + + { fix x :: real + have if_eq': "\ n. (if even n then -1 ^ (n div 2) * 1 / real (Suc n) else 0) * x ^ Suc n = + (if even n then -1 ^ (n div 2) * (1 / real (Suc (2 * (n div 2))) * x ^ Suc (2 * (n div 2))) else 0)" + using n_even by auto + have idx_eq: "\ n. n * 2 + 1 = Suc (2 * n)" by auto + have "(\ n. ?f n * x^(Suc n)) = ?arctan x" unfolding if_eq' idx_eq suminf_def sums_even[of "\ n. -1 ^ n * (1 / real (Suc (2 * n)) * x ^ Suc (2 * n))", symmetric] + by auto + } note arctan_eq = this + + have "DERIV (\ x. \ n. ?f n * x^(Suc n)) x :> (\ n. ?f n * real (Suc n) * x^n)" + proof (rule DERIV_power_series') + show "x \ {- 1 <..< 1}" using `\ x \ < 1` by auto + { fix x' :: real assume x'_bounds: "x' \ {- 1 <..< 1}" + hence "\x'\ < 1" by auto + + let ?S = "\ n. (-1)^n * x'^(2 * n)" + show "summable (\ n. ?f n * real (Suc n) * x'^n)" unfolding if_eq + by (rule sums_summable[where l="0 + ?S"], rule sums_if, rule sums_zero, rule summable_sums, rule summable_Integral[OF `\x'\ < 1`]) + } + qed auto + thus ?thesis unfolding Int_eq arctan_eq . +qed + +lemma arctan_series: assumes "\ x \ \ 1" + shows "arctan x = (\ k. (-1)^k * (1 / real (k*2+1) * x ^ (k*2+1)))" (is "_ = suminf (\ n. ?c x n)") +proof - + let "?c' x n" = "(-1)^n * x^(n*2)" + + { fix r x :: real assume "0 < r" and "r < 1" and "\ x \ < r" + have "\x\ < 1" using `r < 1` and `\x\ < r` by auto + from DERIV_arctan_series[OF this] + have "DERIV (\ x. suminf (?c x)) x :> (suminf (?c' x))" . + } note DERIV_arctan_suminf = this + + { fix x :: real assume "\x\ \ 1" note summable_Leibniz[OF zeroseq_arctan_series[OF this] monoseq_arctan_series[OF this]] } + note arctan_series_borders = this + + { fix x :: real assume "\x\ < 1" have "arctan x = (\ k. ?c x k)" + proof - + obtain r where "\x\ < r" and "r < 1" using dense[OF `\x\ < 1`] by blast + hence "0 < r" and "-r < x" and "x < r" by auto + + have suminf_eq_arctan_bounded: "\ x a b. \ -r < a ; b < r ; a < b ; a \ x ; x \ b \ \ suminf (?c x) - arctan x = suminf (?c a) - arctan a" + proof - + fix x a b assume "-r < a" and "b < r" and "a < b" and "a \ x" and "x \ b" + hence "\x\ < r" by auto + show "suminf (?c x) - arctan x = suminf (?c a) - arctan a" + proof (rule DERIV_isconst2[of "a" "b"]) + show "a < b" and "a \ x" and "x \ b" using `a < b` `a \ x` `x \ b` by auto + have "\ x. -r < x \ x < r \ DERIV (\ x. suminf (?c x) - arctan x) x :> 0" + proof (rule allI, rule impI) + fix x assume "-r < x \ x < r" hence "\x\ < r" by auto + hence "\x\ < 1" using `r < 1` by auto + have "\ - (x^2) \ < 1" using less_one_imp_sqr_less_one[OF `\x\ < 1`] by auto + hence "(\ n. (- (x^2)) ^ n) sums (1 / (1 - (- (x^2))))" unfolding real_norm_def[symmetric] by (rule geometric_sums) + hence "(?c' x) sums (1 / (1 - (- (x^2))))" unfolding power_mult_distrib[symmetric] power_mult nat_mult_commute[of _ 2] by auto + hence suminf_c'_eq_geom: "inverse (1 + x^2) = suminf (?c' x)" using sums_unique unfolding inverse_eq_divide by auto + have "DERIV (\ x. suminf (?c x)) x :> (inverse (1 + x^2))" unfolding suminf_c'_eq_geom + by (rule DERIV_arctan_suminf[OF `0 < r` `r < 1` `\x\ < r`]) + from DERIV_add_minus[OF this DERIV_arctan] + show "DERIV (\ x. suminf (?c x) - arctan x) x :> 0" unfolding diff_minus by auto + qed + hence DERIV_in_rball: "\ y. a \ y \ y \ b \ DERIV (\ x. suminf (?c x) - arctan x) y :> 0" using `-r < a` `b < r` by auto + thus "\ y. a < y \ y < b \ DERIV (\ x. suminf (?c x) - arctan x) y :> 0" using `\x\ < r` by auto + show "\ y. a \ y \ y \ b \ isCont (\ x. suminf (?c x) - arctan x) y" using DERIV_in_rball DERIV_isCont by auto + qed + qed + + have suminf_arctan_zero: "suminf (?c 0) - arctan 0 = 0" + unfolding Suc_plus1[symmetric] power_Suc2 mult_zero_right arctan_zero_zero suminf_zero by auto + + have "suminf (?c x) - arctan x = 0" + proof (cases "x = 0") + case True thus ?thesis using suminf_arctan_zero by auto + next + case False hence "0 < \x\" and "- \x\ < \x\" by auto + have "suminf (?c (-\x\)) - arctan (-\x\) = suminf (?c 0) - arctan 0" + by (rule suminf_eq_arctan_bounded[where x="0" and a="-\x\" and b="\x\", symmetric], auto simp add: `\x\ < r` `-\x\ < \x\`) + moreover + have "suminf (?c x) - arctan x = suminf (?c (-\x\)) - arctan (-\x\)" + by (rule suminf_eq_arctan_bounded[where x="x" and a="-\x\" and b="\x\"], auto simp add: `\x\ < r` `-\x\ < \x\`) + ultimately + show ?thesis using suminf_arctan_zero by auto + qed + thus ?thesis by auto + qed } note when_less_one = this + + show "arctan x = suminf (\ n. ?c x n)" + proof (cases "\x\ < 1") + case True thus ?thesis by (rule when_less_one) + next case False hence "\x\ = 1" using `\x\ \ 1` by auto + let "?a x n" = "\1 / real (n*2+1) * x^(n*2+1)\" + let "?diff x n" = "\ arctan x - (\ i = 0.." + { fix n :: nat + have "0 < (1 :: real)" by auto + moreover + { fix x :: real assume "0 < x" and "x < 1" hence "\x\ \ 1" and "\x\ < 1" by auto + from `0 < x` have "0 < 1 / real (0 * 2 + (1::nat)) * x ^ (0 * 2 + 1)" by auto + note bounds = mp[OF arctan_series_borders(2)[OF `\x\ \ 1`] this, unfolded when_less_one[OF `\x\ < 1`, symmetric], THEN spec] + have "0 < 1 / real (n*2+1) * x^(n*2+1)" by (rule mult_pos_pos, auto simp only: zero_less_power[OF `0 < x`], auto) + hence a_pos: "?a x n = 1 / real (n*2+1) * x^(n*2+1)" by (rule abs_of_pos) + have "?diff x n \ ?a x n" + proof (cases "even n") + case True hence sgn_pos: "(-1)^n = (1::real)" by auto + from `even n` obtain m where "2 * m = n" unfolding even_mult_two_ex by auto + from bounds[of m, unfolded this atLeastAtMost_iff] + have "\arctan x - (\i = 0.. \ (\i = 0..i = 0.. = ?c x n" by auto + also have "\ = ?a x n" unfolding sgn_pos a_pos by auto + finally show ?thesis . + next + case False hence sgn_neg: "(-1)^n = (-1::real)" by auto + from `odd n` obtain m where m_def: "2 * m + 1 = n" unfolding odd_Suc_mult_two_ex by auto + hence m_plus: "2 * (m + 1) = n + 1" by auto + from bounds[of "m + 1", unfolded this atLeastAtMost_iff, THEN conjunct1] bounds[of m, unfolded m_def atLeastAtMost_iff, THEN conjunct2] + have "\arctan x - (\i = 0.. \ (\i = 0..i = 0.. = - ?c x n" by auto + also have "\ = ?a x n" unfolding sgn_neg a_pos by auto + finally show ?thesis . + qed + hence "0 \ ?a x n - ?diff x n" by auto + } + hence "\ x \ { 0 <..< 1 }. 0 \ ?a x n - ?diff x n" by auto + moreover have "\x. isCont (\ x. ?a x n - ?diff x n) x" + unfolding real_diff_def divide_inverse + by (auto intro!: isCont_add isCont_rabs isCont_ident isCont_minus isCont_arctan isCont_inverse isCont_mult isCont_power isCont_const isCont_setsum) + ultimately have "0 \ ?a 1 n - ?diff 1 n" by (rule LIM_less_bound) + hence "?diff 1 n \ ?a 1 n" by auto + } + have "?a 1 ----> 0" unfolding LIMSEQ_rabs_zero power_one divide_inverse by (auto intro!: LIMSEQ_mult LIMSEQ_linear LIMSEQ_inverse_real_of_nat) + have "?diff 1 ----> 0" + proof (rule LIMSEQ_I) + fix r :: real assume "0 < r" + obtain N :: nat where N_I: "\ n. N \ n \ ?a 1 n < r" using LIMSEQ_D[OF `?a 1 ----> 0` `0 < r`] by auto + { fix n assume "N \ n" from `?diff 1 n \ ?a 1 n` N_I[OF this] + have "norm (?diff 1 n - 0) < r" by auto } + thus "\ N. \ n \ N. norm (?diff 1 n - 0) < r" by blast + qed + from this[unfolded LIMSEQ_rabs_zero real_diff_def add_commute[of "arctan 1"], THEN LIMSEQ_add_const, of "- arctan 1", THEN LIMSEQ_minus] + have "(?c 1) sums (arctan 1)" unfolding sums_def by auto + hence "arctan 1 = (\ i. ?c 1 i)" by (rule sums_unique) + + show ?thesis + proof (cases "x = 1", simp add: `arctan 1 = (\ i. ?c 1 i)`) + assume "x \ 1" hence "x = -1" using `\x\ = 1` by auto + + have "- (pi / 2) < 0" using pi_gt_zero by auto + have "- (2 * pi) < 0" using pi_gt_zero by auto + + have c_minus_minus: "\ i. ?c (- 1) i = - ?c 1 i" by auto + + have "arctan (- 1) = arctan (tan (-(pi / 4)))" unfolding tan_45 tan_minus .. + also have "\ = - (pi / 4)" by (rule arctan_tan, auto simp add: order_less_trans[OF `- (pi / 2) < 0` pi_gt_zero]) + also have "\ = - (arctan (tan (pi / 4)))" unfolding neg_equal_iff_equal by (rule arctan_tan[symmetric], auto simp add: order_less_trans[OF `- (2 * pi) < 0` pi_gt_zero]) + also have "\ = - (arctan 1)" unfolding tan_45 .. + also have "\ = - (\ i. ?c 1 i)" using `arctan 1 = (\ i. ?c 1 i)` by auto + also have "\ = (\ i. ?c (- 1) i)" using suminf_minus[OF sums_summable[OF `(?c 1) sums (arctan 1)`]] unfolding c_minus_minus by auto + finally show ?thesis using `x = -1` by auto + qed + qed +qed + +lemma arctan_half: fixes x :: real + shows "arctan x = 2 * arctan (x / (1 + sqrt(1 + x^2)))" +proof - + obtain y where low: "- (pi / 2) < y" and high: "y < pi / 2" and y_eq: "tan y = x" using tan_total by blast + hence low2: "- (pi / 2) < y / 2" and high2: "y / 2 < pi / 2" by auto + + have divide_nonzero_divide: "\ A B C :: real. C \ 0 \ A / B = (A / C) / (B / C)" by auto + + have "0 < cos y" using cos_gt_zero_pi[OF low high] . + hence "cos y \ 0" and cos_sqrt: "sqrt ((cos y) ^ 2) = cos y" by auto + + have "1 + (tan y)^2 = 1 + sin y^2 / cos y^2" unfolding tan_def power_divide .. + also have "\ = cos y^2 / cos y^2 + sin y^2 / cos y^2" using `cos y \ 0` by auto + also have "\ = 1 / cos y^2" unfolding add_divide_distrib[symmetric] sin_cos_squared_add2 .. + finally have "1 + (tan y)^2 = 1 / cos y^2" . + + have "sin y / (cos y + 1) = tan y / ((cos y + 1) / cos y)" unfolding tan_def divide_nonzero_divide[OF `cos y \ 0`, symmetric] .. + also have "\ = tan y / (1 + 1 / cos y)" using `cos y \ 0` unfolding add_divide_distrib by auto + also have "\ = tan y / (1 + 1 / sqrt(cos y^2))" unfolding cos_sqrt .. + also have "\ = tan y / (1 + sqrt(1 / cos y^2))" unfolding real_sqrt_divide by auto + finally have eq: "sin y / (cos y + 1) = tan y / (1 + sqrt(1 + (tan y)^2))" unfolding `1 + (tan y)^2 = 1 / cos y^2` . + + have "arctan x = y" using arctan_tan low high y_eq by auto + also have "\ = 2 * (arctan (tan (y/2)))" using arctan_tan[OF low2 high2] by auto + also have "\ = 2 * (arctan (sin y / (cos y + 1)))" unfolding tan_half[OF low2 high2] by auto + finally show ?thesis unfolding eq `tan y = x` . +qed + +lemma arctan_monotone: assumes "x < y" + shows "arctan x < arctan y" +proof - + obtain z where "-(pi / 2) < z" and "z < pi / 2" and "tan z = x" using tan_total by blast + obtain w where "-(pi / 2) < w" and "w < pi / 2" and "tan w = y" using tan_total by blast + have "z < w" unfolding tan_monotone'[OF `-(pi / 2) < z` `z < pi / 2` `-(pi / 2) < w` `w < pi / 2`] `tan z = x` `tan w = y` using `x < y` . + thus ?thesis + unfolding `tan z = x`[symmetric] arctan_tan[OF `-(pi / 2) < z` `z < pi / 2`] + unfolding `tan w = y`[symmetric] arctan_tan[OF `-(pi / 2) < w` `w < pi / 2`] . +qed + +lemma arctan_monotone': assumes "x \ y" shows "arctan x \ arctan y" +proof (cases "x = y") + case False hence "x < y" using `x \ y` by auto from arctan_monotone[OF this] show ?thesis by auto +qed auto + +lemma arctan_minus: "arctan (- x) = - arctan x" +proof - + obtain y where "- (pi / 2) < y" and "y < pi / 2" and "tan y = x" using tan_total by blast + thus ?thesis unfolding `tan y = x`[symmetric] tan_minus[symmetric] using arctan_tan[of y] arctan_tan[of "-y"] by auto +qed + +lemma arctan_inverse: assumes "x \ 0" shows "arctan (1 / x) = sgn x * pi / 2 - arctan x" +proof - + obtain y where "- (pi / 2) < y" and "y < pi / 2" and "tan y = x" using tan_total by blast + hence "y = arctan x" unfolding `tan y = x`[symmetric] using arctan_tan by auto + + { fix y x :: real assume "0 < y" and "y < pi /2" and "y = arctan x" and "tan y = x" hence "- (pi / 2) < y" by auto + have "tan y > 0" using tan_monotone'[OF _ _ `- (pi / 2) < y` `y < pi / 2`, of 0] tan_zero `0 < y` by auto + hence "x > 0" using `tan y = x` by auto + + have "- (pi / 2) < pi / 2 - y" using `y > 0` `y < pi / 2` by auto + moreover have "pi / 2 - y < pi / 2" using `y > 0` `y < pi / 2` by auto + ultimately have "arctan (1 / x) = pi / 2 - y" unfolding `tan y = x`[symmetric] tan_inverse using arctan_tan by auto + hence "arctan (1 / x) = sgn x * pi / 2 - arctan x" unfolding `y = arctan x` real_sgn_pos[OF `x > 0`] by auto + } note pos_y = this + + show ?thesis + proof (cases "y > 0") + case True from pos_y[OF this `y < pi / 2` `y = arctan x` `tan y = x`] show ?thesis . + next + case False hence "y \ 0" by auto + moreover have "y \ 0" + proof (rule ccontr) + assume "\ y \ 0" hence "y = 0" by auto + have "x = 0" unfolding `tan y = x`[symmetric] `y = 0` tan_zero .. + thus False using `x \ 0` by auto + qed + ultimately have "y < 0" by auto + hence "0 < - y" and "-y < pi / 2" using `- (pi / 2) < y` by auto + moreover have "-y = arctan (-x)" unfolding arctan_minus `y = arctan x` .. + moreover have "tan (-y) = -x" unfolding tan_minus `tan y = x` .. + ultimately have "arctan (1 / -x) = sgn (-x) * pi / 2 - arctan (-x)" using pos_y by blast + hence "arctan (- (1 / x)) = - (sgn x * pi / 2 - arctan x)" unfolding arctan_minus[of x] divide_minus_right sgn_minus by auto + thus ?thesis unfolding arctan_minus neg_equal_iff_equal . + qed +qed + +theorem pi_series: "pi / 4 = (\ k. (-1)^k * 1 / real (k*2+1))" (is "_ = ?SUM") +proof - + have "pi / 4 = arctan 1" using arctan1_eq_pi4 by auto + also have "\ = ?SUM" using arctan_series[of 1] by auto + finally show ?thesis by auto +qed subsection {* Existence of Polar Coordinates *}