paulson@12224: (* Title : MacLaurin.thy paulson@12224: Author : Jacques D. Fleuriot paulson@12224: Copyright : 2001 University of Edinburgh paulson@12224: Description : MacLaurin series paulson@15079: Conversion to Isar and new proofs by Lawrence C Paulson, 2004 paulson@12224: *) paulson@12224: nipkow@15131: theory MacLaurin nipkow@15140: imports Log nipkow@15131: begin paulson@15079: paulson@15079: lemma sumr_offset: "sumr 0 n (%m. f (m+k)) = sumr 0 (n+k) f - sumr 0 k f" paulson@15079: by (induct_tac "n", auto) paulson@15079: paulson@15079: lemma sumr_offset2: "\f. sumr 0 n (%m. f (m+k)) = sumr 0 (n+k) f - sumr 0 k f" paulson@15079: by (induct_tac "n", auto) paulson@15079: paulson@15079: lemma sumr_offset3: "sumr 0 (n+k) f = sumr 0 n (%m. f (m+k)) + sumr 0 k f" paulson@15079: by (simp add: sumr_offset) paulson@15079: paulson@15079: lemma sumr_offset4: "\n f. sumr 0 (n+k) f = sumr 0 n (%m. f (m+k)) + sumr 0 k f" paulson@15079: by (simp add: sumr_offset) paulson@15079: paulson@15079: lemma sumr_from_1_from_0: "0 < n ==> paulson@15079: sumr (Suc 0) (Suc n) (%n. (if even(n) then 0 else paulson@15079: ((- 1) ^ ((n - (Suc 0)) div 2))/(real (fact n))) * a ^ n) = paulson@15079: sumr 0 (Suc n) (%n. (if even(n) then 0 else paulson@15079: ((- 1) ^ ((n - (Suc 0)) div 2))/(real (fact n))) * a ^ n)" paulson@15079: by (rule_tac n1 = 1 in sumr_split_add [THEN subst], auto) paulson@15079: paulson@15079: paulson@15079: subsection{*Maclaurin's Theorem with Lagrange Form of Remainder*} paulson@15079: paulson@15079: text{*This is a very long, messy proof even now that it's been broken down paulson@15079: into lemmas.*} paulson@15079: paulson@15079: lemma Maclaurin_lemma: paulson@15079: "0 < h ==> paulson@15079: \B. f h = sumr 0 n (%m. (j m / real (fact m)) * (h^m)) + paulson@15079: (B * ((h^n) / real(fact n)))" paulson@15079: by (rule_tac x = "(f h - sumr 0 n (%m. (j m / real (fact m)) * h^m)) * paulson@15079: real(fact n) / (h^n)" paulson@15079: in exI, auto) paulson@15079: paulson@15079: paulson@15079: lemma eq_diff_eq': "(x = y - z) = (y = x + (z::real))" paulson@15079: by arith paulson@15079: paulson@15079: text{*A crude tactic to differentiate by proof.*} paulson@15079: ML paulson@15079: {* paulson@15079: exception DERIV_name; paulson@15079: fun get_fun_name (_ $ (Const ("Lim.deriv",_) $ Abs(_,_, Const (f,_) $ _) $ _ $ _)) = f paulson@15079: | get_fun_name (_ $ (_ $ (Const ("Lim.deriv",_) $ Abs(_,_, Const (f,_) $ _) $ _ $ _))) = f paulson@15079: | get_fun_name _ = raise DERIV_name; paulson@15079: paulson@15079: val deriv_rulesI = [DERIV_Id,DERIV_const,DERIV_cos,DERIV_cmult, paulson@15079: DERIV_sin, DERIV_exp, DERIV_inverse,DERIV_pow, paulson@15079: DERIV_add, DERIV_diff, DERIV_mult, DERIV_minus, paulson@15079: DERIV_inverse_fun,DERIV_quotient,DERIV_fun_pow, paulson@15079: DERIV_fun_exp,DERIV_fun_sin,DERIV_fun_cos, paulson@15079: DERIV_Id,DERIV_const,DERIV_cos]; paulson@15079: paulson@15079: val deriv_tac = paulson@15079: SUBGOAL (fn (prem,i) => paulson@15079: (resolve_tac deriv_rulesI i) ORELSE paulson@15079: ((rtac (read_instantiate [("f",get_fun_name prem)] paulson@15079: DERIV_chain2) i) handle DERIV_name => no_tac));; paulson@15079: paulson@15079: val DERIV_tac = ALLGOALS(fn i => REPEAT(deriv_tac i)); paulson@15079: *} paulson@15079: paulson@15079: lemma Maclaurin_lemma2: paulson@15079: "[| \m t. m < n \ 0\t \ t\h \ DERIV (diff m) t :> diff (Suc m) t; paulson@15079: n = Suc k; paulson@15079: difg = paulson@15079: (\m t. diff m t - paulson@15079: ((\p = 0.. paulson@15079: \m t. m < n & 0 \ t & t \ h --> paulson@15079: DERIV (difg m) t :> difg (Suc m) t" paulson@15079: apply clarify paulson@15079: apply (rule DERIV_diff) paulson@15079: apply (simp (no_asm_simp)) paulson@15079: apply (tactic DERIV_tac) paulson@15079: apply (tactic DERIV_tac) paulson@15079: apply (rule_tac [2] lemma_DERIV_subst) paulson@15079: apply (rule_tac [2] DERIV_quotient) paulson@15079: apply (rule_tac [3] DERIV_const) paulson@15079: apply (rule_tac [2] DERIV_pow) paulson@15079: prefer 3 apply (simp add: fact_diff_Suc) paulson@15079: prefer 2 apply simp paulson@15079: apply (frule_tac m = m in less_add_one, clarify) paulson@15079: apply (simp del: sumr_Suc) paulson@15079: apply (insert sumr_offset4 [of 1]) paulson@15079: apply (simp del: sumr_Suc fact_Suc realpow_Suc) paulson@15079: apply (rule lemma_DERIV_subst) paulson@15079: apply (rule DERIV_add) paulson@15079: apply (rule_tac [2] DERIV_const) paulson@15079: apply (rule DERIV_sumr, clarify) paulson@15079: prefer 2 apply simp paulson@15079: apply (simp (no_asm) add: divide_inverse mult_assoc del: fact_Suc realpow_Suc) paulson@15079: apply (rule DERIV_cmult) paulson@15079: apply (rule lemma_DERIV_subst) paulson@15079: apply (best intro: DERIV_chain2 intro!: DERIV_intros) paulson@15079: apply (subst fact_Suc) paulson@15079: apply (subst real_of_nat_mult) paulson@15079: apply (simp add: inverse_mult_distrib mult_ac) paulson@15079: done paulson@15079: paulson@15079: paulson@15079: lemma Maclaurin_lemma3: paulson@15079: "[|\k t. k < Suc m \ 0\t & t\h \ DERIV (difg k) t :> difg (Suc k) t; paulson@15079: \k 0; n < m; 0 < t; paulson@15079: t < h|] paulson@15079: ==> \ta. 0 < ta & ta < t & DERIV (difg (Suc n)) ta :> 0" paulson@15079: apply (rule Rolle, assumption, simp) paulson@15079: apply (drule_tac x = n and P="%k. k difg k 0 = 0" in spec) paulson@15079: apply (rule DERIV_unique) paulson@15079: prefer 2 apply assumption paulson@15079: apply force paulson@15079: apply (subgoal_tac "\ta. 0 \ ta & ta \ t --> (difg (Suc n)) differentiable ta") paulson@15079: apply (simp add: differentiable_def) paulson@15079: apply (blast dest!: DERIV_isCont) paulson@15079: apply (simp add: differentiable_def, clarify) paulson@15079: apply (rule_tac x = "difg (Suc (Suc n)) ta" in exI) paulson@15079: apply force paulson@15079: apply (simp add: differentiable_def, clarify) paulson@15079: apply (rule_tac x = "difg (Suc (Suc n)) x" in exI) paulson@15079: apply force paulson@15079: done obua@14738: paulson@15079: lemma Maclaurin: paulson@15079: "[| 0 < h; 0 < n; diff 0 = f; paulson@15079: \m t. m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t |] paulson@15079: ==> \t. 0 < t & paulson@15079: t < h & paulson@15079: f h = paulson@15079: sumr 0 n (%m. (diff m 0 / real (fact m)) * h ^ m) + paulson@15079: (diff n t / real (fact n)) * h ^ n" paulson@15079: apply (case_tac "n = 0", force) paulson@15079: apply (drule not0_implies_Suc) paulson@15079: apply (erule exE) paulson@15079: apply (frule_tac f=f and n=n and j="%m. diff m 0" in Maclaurin_lemma) paulson@15079: apply (erule exE) paulson@15079: apply (subgoal_tac "\g. paulson@15079: g = (%t. f t - (sumr 0 n (%m. (diff m 0 / real(fact m)) * t^m) + (B * (t^n / real(fact n)))))") paulson@15079: prefer 2 apply blast paulson@15079: apply (erule exE) paulson@15079: apply (subgoal_tac "g 0 = 0 & g h =0") paulson@15079: prefer 2 paulson@15079: apply (simp del: sumr_Suc) paulson@15079: apply (cut_tac n = m and k = 1 in sumr_offset2) paulson@15079: apply (simp add: eq_diff_eq' del: sumr_Suc) paulson@15079: apply (subgoal_tac "\difg. difg = (%m t. diff m t - (sumr 0 (n - m) (%p. (diff (m + p) 0 / real (fact p)) * (t ^ p)) + (B * ((t ^ (n - m)) / real (fact (n - m))))))") paulson@15079: prefer 2 apply blast paulson@15079: apply (erule exE) paulson@15079: apply (subgoal_tac "difg 0 = g") paulson@15079: prefer 2 apply simp paulson@15079: apply (frule Maclaurin_lemma2, assumption+) paulson@15079: apply (subgoal_tac "\ma. ma < n --> (\t. 0 < t & t < h & difg (Suc ma) t = 0) ") paulson@15079: apply (drule_tac x = m and P="%m. m (\t. ?QQ m t)" in spec) paulson@15079: apply (erule impE) paulson@15079: apply (simp (no_asm_simp)) paulson@15079: apply (erule exE) paulson@15079: apply (rule_tac x = t in exI) paulson@15079: apply (simp del: realpow_Suc fact_Suc) paulson@15079: apply (subgoal_tac "\m. m < n --> difg m 0 = 0") paulson@15079: prefer 2 paulson@15079: apply clarify paulson@15079: apply simp paulson@15079: apply (frule_tac m = ma in less_add_one, clarify) paulson@15079: apply (simp del: sumr_Suc) paulson@15079: apply (insert sumr_offset4 [of 1]) paulson@15079: apply (simp del: sumr_Suc fact_Suc realpow_Suc) paulson@15079: apply (subgoal_tac "\m. m < n --> (\t. 0 < t & t < h & DERIV (difg m) t :> 0) ") paulson@15079: apply (rule allI, rule impI) paulson@15079: apply (drule_tac x = ma and P="%m. m (\t. ?QQ m t)" in spec) paulson@15079: apply (erule impE, assumption) paulson@15079: apply (erule exE) paulson@15079: apply (rule_tac x = t in exI) paulson@15079: (* do some tidying up *) paulson@15079: apply (erule_tac [!] V= "difg = (%m t. diff m t - (sumr 0 (n - m) (%p. diff (m + p) 0 / real (fact p) * t ^ p) + B * (t ^ (n - m) / real (fact (n - m)))))" paulson@15079: in thin_rl) paulson@15079: apply (erule_tac [!] V="g = (%t. f t - (sumr 0 n (%m. diff m 0 / real (fact m) * t ^ m) + B * (t ^ n / real (fact n))))" paulson@15079: in thin_rl) paulson@15079: apply (erule_tac [!] V="f h = sumr 0 n (%m. diff m 0 / real (fact m) * h ^ m) + B * (h ^ n / real (fact n))" paulson@15079: in thin_rl) paulson@15079: (* back to business *) paulson@15079: apply (simp (no_asm_simp)) paulson@15079: apply (rule DERIV_unique) paulson@15079: prefer 2 apply blast paulson@15079: apply force paulson@15079: apply (rule allI, induct_tac "ma") paulson@15079: apply (rule impI, rule Rolle, assumption, simp, simp) paulson@15079: apply (subgoal_tac "\t. 0 \ t & t \ h --> g differentiable t") paulson@15079: apply (simp add: differentiable_def) paulson@15079: apply (blast dest: DERIV_isCont) paulson@15079: apply (simp add: differentiable_def, clarify) paulson@15079: apply (rule_tac x = "difg (Suc 0) t" in exI) paulson@15079: apply force paulson@15079: apply (simp add: differentiable_def, clarify) paulson@15079: apply (rule_tac x = "difg (Suc 0) x" in exI) paulson@15079: apply force paulson@15079: apply safe paulson@15079: apply force paulson@15079: apply (frule Maclaurin_lemma3, assumption+, safe) paulson@15079: apply (rule_tac x = ta in exI, force) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_objl: paulson@15079: "0 < h & 0 < n & diff 0 = f & paulson@15079: (\m t. m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t) paulson@15079: --> (\t. 0 < t & paulson@15079: t < h & paulson@15079: f h = paulson@15079: sumr 0 n (%m. diff m 0 / real (fact m) * h ^ m) + paulson@15079: diff n t / real (fact n) * h ^ n)" paulson@15079: by (blast intro: Maclaurin) paulson@15079: paulson@15079: paulson@15079: lemma Maclaurin2: paulson@15079: "[| 0 < h; diff 0 = f; paulson@15079: \m t. paulson@15079: m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t |] paulson@15079: ==> \t. 0 < t & paulson@15079: t \ h & paulson@15079: f h = paulson@15079: sumr 0 n (%m. diff m 0 / real (fact m) * h ^ m) + paulson@15079: diff n t / real (fact n) * h ^ n" paulson@15079: apply (case_tac "n", auto) paulson@15079: apply (drule Maclaurin, auto) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin2_objl: paulson@15079: "0 < h & diff 0 = f & paulson@15079: (\m t. paulson@15079: m < n & 0 \ t & t \ h --> DERIV (diff m) t :> diff (Suc m) t) paulson@15079: --> (\t. 0 < t & paulson@15079: t \ h & paulson@15079: f h = paulson@15079: sumr 0 n (%m. diff m 0 / real (fact m) * h ^ m) + paulson@15079: diff n t / real (fact n) * h ^ n)" paulson@15079: by (blast intro: Maclaurin2) paulson@15079: paulson@15079: lemma Maclaurin_minus: paulson@15079: "[| h < 0; 0 < n; diff 0 = f; paulson@15079: \m t. m < n & h \ t & t \ 0 --> DERIV (diff m) t :> diff (Suc m) t |] paulson@15079: ==> \t. h < t & paulson@15079: t < 0 & paulson@15079: f h = paulson@15079: sumr 0 n (%m. diff m 0 / real (fact m) * h ^ m) + paulson@15079: diff n t / real (fact n) * h ^ n" paulson@15079: apply (cut_tac f = "%x. f (-x)" paulson@15079: and diff = "%n x. ((- 1) ^ n) * diff n (-x)" paulson@15079: and h = "-h" and n = n in Maclaurin_objl) paulson@15079: apply simp paulson@15079: apply safe paulson@15079: apply (subst minus_mult_right) paulson@15079: apply (rule DERIV_cmult) paulson@15079: apply (rule lemma_DERIV_subst) paulson@15079: apply (rule DERIV_chain2 [where g=uminus]) paulson@15079: apply (rule_tac [2] DERIV_minus, rule_tac [2] DERIV_Id) paulson@15079: prefer 2 apply force paulson@15079: apply force paulson@15079: apply (rule_tac x = "-t" in exI, auto) paulson@15079: apply (subgoal_tac "(\m = 0..m = 0..m t. paulson@15079: m < n & h \ t & t \ 0 --> DERIV (diff m) t :> diff (Suc m) t)) paulson@15079: --> (\t. h < t & paulson@15079: t < 0 & paulson@15079: f h = paulson@15079: sumr 0 n (%m. diff m 0 / real (fact m) * h ^ m) + paulson@15079: diff n t / real (fact n) * h ^ n)" paulson@15079: by (blast intro: Maclaurin_minus) paulson@15079: paulson@15079: paulson@15079: subsection{*More Convenient "Bidirectional" Version.*} paulson@15079: paulson@15079: (* not good for PVS sin_approx, cos_approx *) paulson@15079: paulson@15079: lemma Maclaurin_bi_le_lemma [rule_format]: paulson@15079: "0 < n \ paulson@15079: diff 0 0 = paulson@15079: (\m = 0..m t. m < n & abs t \ abs x --> DERIV (diff m) t :> diff (Suc m) t |] paulson@15079: ==> \t. abs t \ abs x & paulson@15079: f x = paulson@15079: sumr 0 n (%m. diff m 0 / real (fact m) * x ^ m) + paulson@15079: diff n t / real (fact n) * x ^ n" paulson@15079: apply (case_tac "n = 0", force) paulson@15079: apply (case_tac "x = 0") paulson@15079: apply (rule_tac x = 0 in exI) paulson@15079: apply (force simp add: Maclaurin_bi_le_lemma) paulson@15079: apply (cut_tac x = x and y = 0 in linorder_less_linear, auto) paulson@15079: txt{*Case 1, where @{term "x < 0"}*} paulson@15079: apply (cut_tac f = "diff 0" and diff = diff and h = x and n = n in Maclaurin_minus_objl, safe) paulson@15079: apply (simp add: abs_if) paulson@15079: apply (rule_tac x = t in exI) paulson@15079: apply (simp add: abs_if) paulson@15079: txt{*Case 2, where @{term "0 < x"}*} paulson@15079: apply (cut_tac f = "diff 0" and diff = diff and h = x and n = n in Maclaurin_objl, safe) paulson@15079: apply (simp add: abs_if) paulson@15079: apply (rule_tac x = t in exI) paulson@15079: apply (simp add: abs_if) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_all_lt: paulson@15079: "[| diff 0 = f; paulson@15079: \m x. DERIV (diff m) x :> diff(Suc m) x; paulson@15079: x ~= 0; 0 < n paulson@15079: |] ==> \t. 0 < abs t & abs t < abs x & paulson@15079: f x = sumr 0 n (%m. (diff m 0 / real (fact m)) * x ^ m) + paulson@15079: (diff n t / real (fact n)) * x ^ n" paulson@15079: apply (rule_tac x = x and y = 0 in linorder_cases) paulson@15079: prefer 2 apply blast paulson@15079: apply (drule_tac [2] diff=diff in Maclaurin) paulson@15079: apply (drule_tac diff=diff in Maclaurin_minus, simp_all, safe) paulson@15229: apply (rule_tac [!] x = t in exI, auto) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_all_lt_objl: paulson@15079: "diff 0 = f & paulson@15079: (\m x. DERIV (diff m) x :> diff(Suc m) x) & paulson@15079: x ~= 0 & 0 < n paulson@15079: --> (\t. 0 < abs t & abs t < abs x & paulson@15079: f x = sumr 0 n (%m. (diff m 0 / real (fact m)) * x ^ m) + paulson@15079: (diff n t / real (fact n)) * x ^ n)" paulson@15079: by (blast intro: Maclaurin_all_lt) paulson@15079: paulson@15079: lemma Maclaurin_zero [rule_format]: paulson@15079: "x = (0::real) paulson@15079: ==> 0 < n --> paulson@15079: sumr 0 n (%m. (diff m (0::real) / real (fact m)) * x ^ m) = paulson@15079: diff 0 0" paulson@15079: by (induct n, auto) paulson@15079: paulson@15079: lemma Maclaurin_all_le: "[| diff 0 = f; paulson@15079: \m x. DERIV (diff m) x :> diff (Suc m) x paulson@15079: |] ==> \t. abs t \ abs x & paulson@15079: f x = sumr 0 n (%m. (diff m 0 / real (fact m)) * x ^ m) + paulson@15079: (diff n t / real (fact n)) * x ^ n" paulson@15079: apply (insert linorder_le_less_linear [of n 0]) paulson@15079: apply (erule disjE, force) paulson@15079: apply (case_tac "x = 0") paulson@15079: apply (frule_tac diff = diff and n = n in Maclaurin_zero, assumption) paulson@15079: apply (drule gr_implies_not0 [THEN not0_implies_Suc]) paulson@15079: apply (rule_tac x = 0 in exI, force) paulson@15079: apply (frule_tac diff = diff and n = n in Maclaurin_all_lt, auto) paulson@15079: apply (rule_tac x = t in exI, auto) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_all_le_objl: "diff 0 = f & paulson@15079: (\m x. DERIV (diff m) x :> diff (Suc m) x) paulson@15079: --> (\t. abs t \ abs x & paulson@15079: f x = sumr 0 n (%m. (diff m 0 / real (fact m)) * x ^ m) + paulson@15079: (diff n t / real (fact n)) * x ^ n)" paulson@15079: by (blast intro: Maclaurin_all_le) paulson@15079: paulson@15079: paulson@15079: subsection{*Version for Exponential Function*} paulson@15079: paulson@15079: lemma Maclaurin_exp_lt: "[| x ~= 0; 0 < n |] paulson@15079: ==> (\t. 0 < abs t & paulson@15079: abs t < abs x & paulson@15079: exp x = sumr 0 n (%m. (x ^ m) / real (fact m)) + paulson@15079: (exp t / real (fact n)) * x ^ n)" paulson@15079: by (cut_tac diff = "%n. exp" and f = exp and x = x and n = n in Maclaurin_all_lt_objl, auto) paulson@15079: paulson@15079: paulson@15079: lemma Maclaurin_exp_le: paulson@15079: "\t. abs t \ abs x & paulson@15079: exp x = sumr 0 n (%m. (x ^ m) / real (fact m)) + paulson@15079: (exp t / real (fact n)) * x ^ n" paulson@15079: by (cut_tac diff = "%n. exp" and f = exp and x = x and n = n in Maclaurin_all_le_objl, auto) paulson@15079: paulson@15079: paulson@15079: subsection{*Version for Sine Function*} paulson@15079: paulson@15079: lemma MVT2: paulson@15079: "[| a < b; \x. a \ x & x \ b --> DERIV f x :> f'(x) |] paulson@15079: ==> \z. a < z & z < b & (f b - f a = (b - a) * f'(z))" paulson@15079: apply (drule MVT) paulson@15079: apply (blast intro: DERIV_isCont) paulson@15079: apply (force dest: order_less_imp_le simp add: differentiable_def) paulson@15079: apply (blast dest: DERIV_unique order_less_imp_le) paulson@15079: done paulson@15079: paulson@15079: lemma mod_exhaust_less_4: paulson@15079: "m mod 4 = 0 | m mod 4 = 1 | m mod 4 = 2 | m mod 4 = (3::nat)" paulson@15079: by (case_tac "m mod 4", auto, arith) paulson@15079: paulson@15079: lemma Suc_Suc_mult_two_diff_two [rule_format, simp]: paulson@15079: "0 < n --> Suc (Suc (2 * n - 2)) = 2*n" paulson@15079: by (induct_tac "n", auto) paulson@15079: paulson@15079: lemma lemma_Suc_Suc_4n_diff_2 [rule_format, simp]: paulson@15079: "0 < n --> Suc (Suc (4*n - 2)) = 4*n" paulson@15079: by (induct_tac "n", auto) paulson@15079: paulson@15079: lemma Suc_mult_two_diff_one [rule_format, simp]: paulson@15079: "0 < n --> Suc (2 * n - 1) = 2*n" paulson@15079: by (induct_tac "n", auto) paulson@15079: paulson@15079: lemma Maclaurin_sin_expansion: paulson@15079: "\t. sin x = paulson@15079: (sumr 0 n (%m. (if even m then 0 paulson@15079: else ((- 1) ^ ((m - (Suc 0)) div 2)) / real (fact m)) * paulson@15079: x ^ m)) paulson@15079: + ((sin(t + 1/2 * real (n) *pi) / real (fact n)) * x ^ n)" paulson@15079: apply (cut_tac f = sin and n = n and x = x and diff = "%n x. sin (x + 1/2*real (n) *pi)" in Maclaurin_all_lt_objl) paulson@15079: apply safe paulson@15079: apply (simp (no_asm)) paulson@15079: apply (simp (no_asm)) paulson@15079: apply (case_tac "n", clarify, simp) paulson@15079: apply (drule_tac x = 0 in spec, simp, simp) paulson@15079: apply (rule ccontr, simp) paulson@15079: apply (drule_tac x = x in spec, simp) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule_tac x = t in exI, simp) paulson@15079: apply (rule sumr_fun_eq) paulson@15079: apply (auto simp add: odd_Suc_mult_two_ex) paulson@15079: apply (auto simp add: even_mult_two_ex simp del: fact_Suc realpow_Suc) paulson@15079: (*Could sin_zero_iff help?*) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_sin_expansion2: paulson@15079: "\t. abs t \ abs x & paulson@15079: sin x = paulson@15079: (sumr 0 n (%m. (if even m then 0 paulson@15079: else ((- 1) ^ ((m - (Suc 0)) div 2)) / real (fact m)) * paulson@15079: x ^ m)) paulson@15079: + ((sin(t + 1/2 * real (n) *pi) / real (fact n)) * x ^ n)" paulson@15079: apply (cut_tac f = sin and n = n and x = x paulson@15079: and diff = "%n x. sin (x + 1/2*real n * pi)" in Maclaurin_all_lt_objl) paulson@15079: apply safe paulson@15079: apply (simp (no_asm)) paulson@15079: apply (simp (no_asm)) paulson@15079: apply (case_tac "n", clarify, simp, simp) paulson@15079: apply (rule ccontr, simp) paulson@15079: apply (drule_tac x = x in spec, simp) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule_tac x = t in exI, simp) paulson@15079: apply (rule sumr_fun_eq) paulson@15079: apply (auto simp add: odd_Suc_mult_two_ex) paulson@15079: apply (auto simp add: even_mult_two_ex simp del: fact_Suc realpow_Suc) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_sin_expansion3: paulson@15079: "[| 0 < n; 0 < x |] ==> paulson@15079: \t. 0 < t & t < x & paulson@15079: sin x = paulson@15079: (sumr 0 n (%m. (if even m then 0 paulson@15079: else ((- 1) ^ ((m - (Suc 0)) div 2)) / real (fact m)) * paulson@15079: x ^ m)) paulson@15079: + ((sin(t + 1/2 * real(n) *pi) / real (fact n)) * x ^ n)" paulson@15079: apply (cut_tac f = sin and n = n and h = x and diff = "%n x. sin (x + 1/2*real (n) *pi)" in Maclaurin_objl) paulson@15079: apply safe paulson@15079: apply simp paulson@15079: apply (simp (no_asm)) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule_tac x = t in exI, simp) paulson@15079: apply (rule sumr_fun_eq) paulson@15079: apply (auto simp add: odd_Suc_mult_two_ex) paulson@15079: apply (auto simp add: even_mult_two_ex simp del: fact_Suc realpow_Suc) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_sin_expansion4: paulson@15079: "0 < x ==> paulson@15079: \t. 0 < t & t \ x & paulson@15079: sin x = paulson@15079: (sumr 0 n (%m. (if even m then 0 paulson@15079: else ((- 1) ^ ((m - (Suc 0)) div 2)) / real (fact m)) * paulson@15079: x ^ m)) paulson@15079: + ((sin(t + 1/2 * real (n) *pi) / real (fact n)) * x ^ n)" paulson@15079: apply (cut_tac f = sin and n = n and h = x and diff = "%n x. sin (x + 1/2*real (n) *pi)" in Maclaurin2_objl) paulson@15079: apply safe paulson@15079: apply simp paulson@15079: apply (simp (no_asm)) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule_tac x = t in exI, simp) paulson@15079: apply (rule sumr_fun_eq) paulson@15079: apply (auto simp add: odd_Suc_mult_two_ex) paulson@15079: apply (auto simp add: even_mult_two_ex simp del: fact_Suc realpow_Suc) paulson@15079: done paulson@15079: paulson@15079: paulson@15079: subsection{*Maclaurin Expansion for Cosine Function*} paulson@15079: paulson@15079: lemma sumr_cos_zero_one [simp]: paulson@15079: "sumr 0 (Suc n) paulson@15079: (%m. (if even m paulson@15079: then (- 1) ^ (m div 2)/(real (fact m)) paulson@15079: else 0) * paulson@15079: 0 ^ m) = 1" paulson@15079: by (induct_tac "n", auto) paulson@15079: paulson@15079: lemma Maclaurin_cos_expansion: paulson@15079: "\t. abs t \ abs x & paulson@15079: cos x = paulson@15079: (sumr 0 n (%m. (if even m paulson@15079: then (- 1) ^ (m div 2)/(real (fact m)) paulson@15079: else 0) * paulson@15079: x ^ m)) paulson@15079: + ((cos(t + 1/2 * real (n) *pi) / real (fact n)) * x ^ n)" paulson@15079: apply (cut_tac f = cos and n = n and x = x and diff = "%n x. cos (x + 1/2*real (n) *pi)" in Maclaurin_all_lt_objl) paulson@15079: apply safe paulson@15079: apply (simp (no_asm)) paulson@15079: apply (simp (no_asm)) paulson@15079: apply (case_tac "n", simp) paulson@15079: apply (simp del: sumr_Suc) paulson@15079: apply (rule ccontr, simp) paulson@15079: apply (drule_tac x = x in spec, simp) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule_tac x = t in exI, simp) paulson@15079: apply (rule sumr_fun_eq) paulson@15079: apply (auto simp add: odd_Suc_mult_two_ex) paulson@15079: apply (auto simp add: even_mult_two_ex left_distrib cos_add simp del: fact_Suc realpow_Suc) paulson@15079: apply (simp add: mult_commute [of _ pi]) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_cos_expansion2: paulson@15079: "[| 0 < x; 0 < n |] ==> paulson@15079: \t. 0 < t & t < x & paulson@15079: cos x = paulson@15079: (sumr 0 n (%m. (if even m paulson@15079: then (- 1) ^ (m div 2)/(real (fact m)) paulson@15079: else 0) * paulson@15079: x ^ m)) paulson@15079: + ((cos(t + 1/2 * real (n) *pi) / real (fact n)) * x ^ n)" paulson@15079: apply (cut_tac f = cos and n = n and h = x and diff = "%n x. cos (x + 1/2*real (n) *pi)" in Maclaurin_objl) paulson@15079: apply safe paulson@15079: apply simp paulson@15079: apply (simp (no_asm)) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule_tac x = t in exI, simp) paulson@15079: apply (rule sumr_fun_eq) paulson@15079: apply (auto simp add: odd_Suc_mult_two_ex) paulson@15079: apply (auto simp add: even_mult_two_ex left_distrib cos_add simp del: fact_Suc realpow_Suc) paulson@15079: apply (simp add: mult_commute [of _ pi]) paulson@15079: done paulson@15079: paulson@15079: lemma Maclaurin_minus_cos_expansion: "[| x < 0; 0 < n |] ==> paulson@15079: \t. x < t & t < 0 & paulson@15079: cos x = paulson@15079: (sumr 0 n (%m. (if even m paulson@15079: then (- 1) ^ (m div 2)/(real (fact m)) paulson@15079: else 0) * paulson@15079: x ^ m)) paulson@15079: + ((cos(t + 1/2 * real (n) *pi) / real (fact n)) * x ^ n)" paulson@15079: apply (cut_tac f = cos and n = n and h = x and diff = "%n x. cos (x + 1/2*real (n) *pi)" in Maclaurin_minus_objl) paulson@15079: apply safe paulson@15079: apply simp paulson@15079: apply (simp (no_asm)) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule_tac x = t in exI, simp) paulson@15079: apply (rule sumr_fun_eq) paulson@15079: apply (auto simp add: odd_Suc_mult_two_ex) paulson@15079: apply (auto simp add: even_mult_two_ex left_distrib cos_add simp del: fact_Suc realpow_Suc) paulson@15079: apply (simp add: mult_commute [of _ pi]) paulson@15079: done paulson@15079: paulson@15079: (* ------------------------------------------------------------------------- *) paulson@15079: (* Version for ln(1 +/- x). Where is it?? *) paulson@15079: (* ------------------------------------------------------------------------- *) paulson@15079: paulson@15079: lemma sin_bound_lemma: paulson@15081: "[|x = y; abs u \ (v::real) |] ==> \(x + u) - y\ \ v" paulson@15079: by auto paulson@15079: paulson@15079: lemma Maclaurin_sin_bound: paulson@15079: "abs(sin x - sumr 0 n (%m. (if even m then 0 else ((- 1) ^ ((m - (Suc 0)) div 2)) / real (fact m)) * paulson@15081: x ^ m)) \ inverse(real (fact n)) * \x\ ^ n" obua@14738: proof - paulson@15079: have "!! x (y::real). x \ 1 \ 0 \ y \ x * y \ 1 * y" obua@14738: by (rule_tac mult_right_mono,simp_all) obua@14738: note est = this[simplified] obua@14738: show ?thesis paulson@15079: apply (cut_tac f=sin and n=n and x=x and obua@14738: diff = "%n 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)" obua@14738: in Maclaurin_all_le_objl) paulson@15079: apply safe paulson@15079: apply simp obua@14738: apply (subst mod_Suc_eq_Suc_mod) paulson@15079: apply (cut_tac m=m in mod_exhaust_less_4, safe, simp+) obua@14738: apply (rule DERIV_minus, simp+) obua@14738: apply (rule lemma_DERIV_subst, rule DERIV_minus, rule DERIV_cos, simp) paulson@15079: apply (erule ssubst) paulson@15079: apply (rule sin_bound_lemma) paulson@15079: apply (rule sumr_fun_eq, safe) paulson@15079: apply (rule_tac f = "%u. u * (x^r)" in arg_cong) obua@14738: apply (subst even_even_mod_4_iff) paulson@15079: apply (cut_tac m=r in mod_exhaust_less_4, simp, safe) obua@14738: apply (simp_all add:even_num_iff) obua@14738: apply (drule lemma_even_mod_4_div_2[simplified]) paulson@15079: apply(simp add: numeral_2_eq_2 divide_inverse) paulson@15079: apply (drule lemma_odd_mod_4_div_2) paulson@15079: apply (simp add: numeral_2_eq_2 divide_inverse) paulson@15079: apply (auto intro: mult_right_mono [where b=1, simplified] mult_right_mono paulson@15079: simp add: est mult_pos_le mult_ac divide_inverse paulson@15079: power_abs [symmetric]) obua@14738: done obua@14738: qed obua@14738: paulson@15079: end