diff -r 1860f016886d -r 15a4b2cf8c34 src/HOL/MacLaurin.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/MacLaurin.thy Wed Dec 03 15:58:44 2008 +0100 @@ -0,0 +1,576 @@ +(* Author : Jacques D. Fleuriot + Copyright : 2001 University of Edinburgh + Conversion to Isar and new proofs by Lawrence C Paulson, 2004 +*) + +header{*MacLaurin Series*} + +theory MacLaurin +imports Dense_Linear_Order Transcendental +begin + +subsection{*Maclaurin's Theorem with Lagrange Form of Remainder*} + +text{*This is a very long, messy proof even now that it's been broken down +into lemmas.*} + +lemma Maclaurin_lemma: + "0 < h ==> + \B. f h = (\m=0.. + resolve_tac @{thms deriv_rulesI} i ORELSE + ((rtac (read_instantiate ctxt [(("f", 0), get_fun_name prem)] + @{thm DERIV_chain2}) i) handle DERIV_name => no_tac)); + +fun DERIV_tac ctxt = ALLGOALS (fn i => REPEAT (deriv_tac ctxt i)); + +end +*} + +lemma Maclaurin_lemma2: + "[| \m t. m < n \ 0\t \ t\h \ DERIV (diff m) t :> diff (Suc m) t; + n = Suc k; + difg = + (\m t. diff m t - + ((\p = 0.. + \m t. m < n & 0 \ t & t \ h --> + DERIV (difg m) t :> difg (Suc m) t" +apply clarify +apply (rule DERIV_diff) +apply (simp (no_asm_simp)) +apply (tactic {* DERIV_tac @{context} *}) +apply (tactic {* DERIV_tac @{context} *}) +apply (rule_tac [2] lemma_DERIV_subst) +apply (rule_tac [2] DERIV_quotient) +apply (rule_tac [3] DERIV_const) +apply (rule_tac [2] DERIV_pow) + prefer 3 apply (simp add: fact_diff_Suc) + prefer 2 apply simp +apply (frule_tac m = m in less_add_one, clarify) +apply (simp del: setsum_op_ivl_Suc) +apply (insert sumr_offset4 [of 1]) +apply (simp del: setsum_op_ivl_Suc fact_Suc realpow_Suc) +apply (rule lemma_DERIV_subst) +apply (rule DERIV_add) +apply (rule_tac [2] DERIV_const) +apply (rule DERIV_sumr, clarify) + prefer 2 apply simp +apply (simp (no_asm) add: divide_inverse mult_assoc del: fact_Suc realpow_Suc) +apply (rule DERIV_cmult) +apply (rule lemma_DERIV_subst) +apply (best intro: DERIV_chain2 intro!: DERIV_intros) +apply (subst fact_Suc) +apply (subst real_of_nat_mult) +apply (simp add: mult_ac) +done + + +lemma Maclaurin_lemma3: + fixes difg :: "nat => real => real" shows + "[|\k t. k < Suc m \ 0\t & t\h \ DERIV (difg k) t :> difg (Suc k) t; + \k 0; n < m; 0 < t; + t < h|] + ==> \ta. 0 < ta & ta < t & DERIV (difg (Suc n)) ta :> 0" +apply (rule Rolle, assumption, simp) +apply (drule_tac x = n and P="%k. k difg k 0 = 0" in spec) +apply (rule DERIV_unique) +prefer 2 apply assumption +apply force +apply (metis DERIV_isCont dlo_simps(4) dlo_simps(9) less_trans_Suc nat_less_le not_less_eq real_le_trans) +apply (metis Suc_less_eq differentiableI dlo_simps(7) dlo_simps(8) dlo_simps(9) real_le_trans xt1(8)) +done + +lemma Maclaurin: + "[| 0 < h; n > 0; diff 0 = f; + \m t. m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t |] + ==> \t. 0 < t & + t < h & + f h = + setsum (%m. (diff m 0 / real (fact m)) * h ^ m) {0..g. + g = (%t. f t - (setsum (%m. (diff m 0 / real(fact m)) * t^m) {0..difg. difg = (%m t. diff m t - (setsum (%p. (diff (m + p) 0 / real (fact p)) * (t ^ p)) {0..ma. ma < n --> (\t. 0 < t & t < h & difg (Suc ma) t = 0) ") + apply (drule_tac x = m and P="%m. m (\t. ?QQ m t)" in spec) + apply (erule impE) + apply (simp (no_asm_simp)) + apply (erule exE) + apply (rule_tac x = t in exI) + apply (simp del: realpow_Suc fact_Suc) +apply (subgoal_tac "\m. m < n --> difg m 0 = 0") + prefer 2 + apply clarify + apply simp + apply (frule_tac m = ma in less_add_one, clarify) + apply (simp del: setsum_op_ivl_Suc) +apply (insert sumr_offset4 [of 1]) +apply (simp del: setsum_op_ivl_Suc fact_Suc realpow_Suc) +apply (subgoal_tac "\m. m < n --> (\t. 0 < t & t < h & DERIV (difg m) t :> 0) ") +apply (rule allI, rule impI) +apply (drule_tac x = ma and P="%m. m (\t. ?QQ m t)" in spec) +apply (erule impE, assumption) +apply (erule exE) +apply (rule_tac x = t in exI) +(* do some tidying up *) +apply (erule_tac [!] V= "difg = (%m t. diff m t - (setsum (%p. diff (m + p) 0 / real (fact p) * t ^ p) {0..0 & diff 0 = f & + (\m t. m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t) + --> (\t. 0 < t & t < h & + f h = (\m=0..m t. + m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t |] + ==> \t. 0 < t & + t \ h & + f h = + (\m=0..m t. + m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t) + --> (\t. 0 < t & + t \ h & + f h = + (\m=0.. 0; diff 0 = f; + \m t. m < n & h \ t & t \ 0 --> DERIV (diff m) t :> diff (Suc m) t |] + ==> \t. h < t & + t < 0 & + f h = + (\m=0..m = 0..m = 0.. 0 & diff 0 = f & + (\m t. + m < n & h \ t & t \ 0 --> DERIV (diff m) t :> diff (Suc m) t)) + --> (\t. h < t & + t < 0 & + f h = + (\m=0..0 \ + diff 0 0 = + (\m = 0..m t. m < n & abs t \ abs x --> DERIV (diff m) t :> diff (Suc m) t |] + ==> \t. abs t \ abs x & + f x = + (\m=0..m x. DERIV (diff m) x :> diff(Suc m) x; + x ~= 0; n > 0 + |] ==> \t. 0 < abs t & abs t < abs x & + f x = (\m=0..m x. DERIV (diff m) x :> diff(Suc m) x) & + x ~= 0 & n > 0 + --> (\t. 0 < abs t & abs t < abs x & + f x = (\m=0.. n \ 0 --> + (\m=0..m x. DERIV (diff m) x :> diff (Suc m) x + |] ==> \t. abs t \ abs x & + f x = (\m=0..m x. DERIV (diff m) x :> diff (Suc m) x) + --> (\t. abs t \ abs x & + f x = (\m=0.. 0 |] + ==> (\t. 0 < abs t & + abs t < abs x & + exp x = (\m=0..t. abs t \ abs x & + exp x = (\m=0..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 + +lemma Suc_Suc_mult_two_diff_two [rule_format, simp]: + "n\0 --> Suc (Suc (2 * n - 2)) = 2*n" +by (induct "n", auto) + +lemma lemma_Suc_Suc_4n_diff_2 [rule_format, simp]: + "n\0 --> Suc (Suc (4*n - 2)) = 4*n" +by (induct "n", auto) + +lemma Suc_mult_two_diff_one [rule_format, simp]: + "n\0 --> Suc (2 * n - 1) = 2*n" +by (induct "n", auto) + + +text{*It is unclear why so many variant results are needed.*} + +lemma Maclaurin_sin_expansion2: + "\t. abs t \ abs x & + sin x = + (\m=0..t. sin x = + (\m=0.. 0; 0 < x |] ==> + \t. 0 < t & t < x & + sin x = + (\m=0.. + \t. 0 < t & t \ x & + sin x = + (\m=0..m=0..<(Suc n). + (if even m then -1 ^ (m div 2)/(real (fact m)) else 0) * 0 ^ m) = 1" +by (induct "n", auto) + +lemma Maclaurin_cos_expansion: + "\t. abs t \ abs x & + cos x = + (\m=0.. 0 |] ==> + \t. 0 < t & t < x & + cos x = + (\m=0.. 0 |] ==> + \t. x < t & t < 0 & + cos x = + (\m=0.. (v::real) |] ==> \(x + u) - y\ \ v" +by auto + +lemma Maclaurin_sin_bound: + "abs(sin x - (\m=0.. inverse(real (fact n)) * \x\ ^ n" +proof - + have "!! x (y::real). x \ 1 \ 0 \ y \ x * y \ 1 * y" + by (rule_tac mult_right_mono,simp_all) + note est = this[simplified] + let ?diff = "\(n::nat) x. if n mod 4 = 0 then sin(x) else if n mod 4 = 1 then cos(x) else if n mod 4 = 2 then -sin(x) else -cos(x)" + have diff_0: "?diff 0 = sin" by simp + have DERIV_diff: "\m x. DERIV (?diff m) x :> ?diff (Suc m) x" + apply (clarify) + apply (subst (1 2 3) mod_Suc_eq_Suc_mod) + apply (cut_tac m=m in mod_exhaust_less_4) + apply (safe, simp_all) + apply (rule DERIV_minus, simp) + apply (rule lemma_DERIV_subst, rule DERIV_minus, rule DERIV_cos, simp) + done + from Maclaurin_all_le [OF diff_0 DERIV_diff] + obtain t where t1: "\t\ \ \x\" and + t2: "sin x = (\m = 0..m. ?diff m 0 = (if even m then 0 + else -1 ^ ((m - Suc 0) div 2))" + apply (subst even_even_mod_4_iff) + apply (cut_tac m=m in mod_exhaust_less_4) + apply (elim disjE, simp_all) + apply (safe dest!: mod_eqD, simp_all) + done + show ?thesis + apply (subst t2) + apply (rule sin_bound_lemma) + apply (rule setsum_cong[OF refl]) + apply (subst diff_m_0, simp) + apply (auto intro: mult_right_mono [where b=1, simplified] mult_right_mono + simp add: est mult_nonneg_nonneg mult_ac divide_inverse + power_abs [symmetric] abs_mult) + done +qed + +end