diff -r 829e684b02ef -r 49f602ae24e5 src/HOL/Hyperreal/Series.thy --- a/src/HOL/Hyperreal/Series.thy Fri Dec 05 11:26:07 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,654 +0,0 @@ -(* Title : Series.thy - Author : Jacques D. Fleuriot - Copyright : 1998 University of Cambridge - -Converted to Isar and polished by lcp -Converted to setsum and polished yet more by TNN -Additional contributions by Jeremy Avigad -*) - -header{*Finite Summation and Infinite Series*} - -theory Series -imports SEQ -begin - -definition - sums :: "(nat \ 'a::real_normed_vector) \ 'a \ bool" - (infixr "sums" 80) where - "f sums s = (%n. setsum f {0.. s" - -definition - summable :: "(nat \ 'a::real_normed_vector) \ bool" where - "summable f = (\s. f sums s)" - -definition - suminf :: "(nat \ 'a::real_normed_vector) \ 'a" where - "suminf f = (THE s. f sums s)" - -syntax - "_suminf" :: "idt \ 'a \ 'a" ("\_. _" [0, 10] 10) -translations - "\i. b" == "CONST suminf (%i. b)" - - -lemma sumr_diff_mult_const: - "setsum f {0.. f(p) \ K) - \ setsum f {0.. real n * K" -using setsum_bounded[where A = "{0..i=0..<2*n. (-1) ^ Suc i) = (0::real)" -by (induct "n", auto) - -(* FIXME this is an awful lemma! *) -lemma sumr_one_lb_realpow_zero [simp]: - "(\n=Suc 0..m=0..m=0.. 'a::ab_group_add" - shows "(\m=0..f. (\m=0..n f. setsum f {0::nat..m=0.. - (\n=Suc 0 ..< Suc n. if even(n) then 0 else - ((- 1) ^ ((n - (Suc 0)) div 2))/(real (fact n))) * a ^ n = - (\n=0.. summable f" -by (simp add: sums_def summable_def, blast) - -lemma summable_sums: "summable f ==> f sums (suminf f)" -apply (simp add: summable_def suminf_def sums_def) -apply (blast intro: theI LIMSEQ_unique) -done - -lemma summable_sumr_LIMSEQ_suminf: - "summable f ==> (%n. setsum f {0.. (suminf f)" -by (rule summable_sums [unfolded sums_def]) - -(*------------------- - sum is unique - ------------------*) -lemma sums_unique: "f sums s ==> (s = suminf f)" -apply (frule sums_summable [THEN summable_sums]) -apply (auto intro!: LIMSEQ_unique simp add: sums_def) -done - -lemma sums_split_initial_segment: "f sums s ==> - (%n. f(n + k)) sums (s - (SUM i = 0..< k. f i))" - apply (unfold sums_def); - apply (simp add: sumr_offset); - apply (rule LIMSEQ_diff_const) - apply (rule LIMSEQ_ignore_initial_segment) - apply assumption -done - -lemma summable_ignore_initial_segment: "summable f ==> - summable (%n. f(n + k))" - apply (unfold summable_def) - apply (auto intro: sums_split_initial_segment) -done - -lemma suminf_minus_initial_segment: "summable f ==> - suminf f = s ==> suminf (%n. f(n + k)) = s - (SUM i = 0..< k. f i)" - apply (frule summable_ignore_initial_segment) - apply (rule sums_unique [THEN sym]) - apply (frule summable_sums) - apply (rule sums_split_initial_segment) - apply auto -done - -lemma suminf_split_initial_segment: "summable f ==> - suminf f = (SUM i = 0..< k. f i) + suminf (%n. f(n + k))" -by (auto simp add: suminf_minus_initial_segment) - -lemma series_zero: - "(\m. n \ m --> f(m) = 0) ==> f sums (setsum f {0..n. 0) sums 0" -unfolding sums_def by (simp add: LIMSEQ_const) - -lemma summable_zero: "summable (\n. 0)" -by (rule sums_zero [THEN sums_summable]) - -lemma suminf_zero: "suminf (\n. 0) = 0" -by (rule sums_zero [THEN sums_unique, symmetric]) - -lemma (in bounded_linear) sums: - "(\n. X n) sums a \ (\n. f (X n)) sums (f a)" -unfolding sums_def by (drule LIMSEQ, simp only: setsum) - -lemma (in bounded_linear) summable: - "summable (\n. X n) \ summable (\n. f (X n))" -unfolding summable_def by (auto intro: sums) - -lemma (in bounded_linear) suminf: - "summable (\n. X n) \ f (\n. X n) = (\n. f (X n))" -by (intro sums_unique sums summable_sums) - -lemma sums_mult: - fixes c :: "'a::real_normed_algebra" - shows "f sums a \ (\n. c * f n) sums (c * a)" -by (rule mult_right.sums) - -lemma summable_mult: - fixes c :: "'a::real_normed_algebra" - shows "summable f \ summable (%n. c * f n)" -by (rule mult_right.summable) - -lemma suminf_mult: - fixes c :: "'a::real_normed_algebra" - shows "summable f \ suminf (\n. c * f n) = c * suminf f"; -by (rule mult_right.suminf [symmetric]) - -lemma sums_mult2: - fixes c :: "'a::real_normed_algebra" - shows "f sums a \ (\n. f n * c) sums (a * c)" -by (rule mult_left.sums) - -lemma summable_mult2: - fixes c :: "'a::real_normed_algebra" - shows "summable f \ summable (\n. f n * c)" -by (rule mult_left.summable) - -lemma suminf_mult2: - fixes c :: "'a::real_normed_algebra" - shows "summable f \ suminf f * c = (\n. f n * c)" -by (rule mult_left.suminf) - -lemma sums_divide: - fixes c :: "'a::real_normed_field" - shows "f sums a \ (\n. f n / c) sums (a / c)" -by (rule divide.sums) - -lemma summable_divide: - fixes c :: "'a::real_normed_field" - shows "summable f \ summable (\n. f n / c)" -by (rule divide.summable) - -lemma suminf_divide: - fixes c :: "'a::real_normed_field" - shows "summable f \ suminf (\n. f n / c) = suminf f / c" -by (rule divide.suminf [symmetric]) - -lemma sums_add: "\X sums a; Y sums b\ \ (\n. X n + Y n) sums (a + b)" -unfolding sums_def by (simp add: setsum_addf LIMSEQ_add) - -lemma summable_add: "\summable X; summable Y\ \ summable (\n. X n + Y n)" -unfolding summable_def by (auto intro: sums_add) - -lemma suminf_add: - "\summable X; summable Y\ \ suminf X + suminf Y = (\n. X n + Y n)" -by (intro sums_unique sums_add summable_sums) - -lemma sums_diff: "\X sums a; Y sums b\ \ (\n. X n - Y n) sums (a - b)" -unfolding sums_def by (simp add: setsum_subtractf LIMSEQ_diff) - -lemma summable_diff: "\summable X; summable Y\ \ summable (\n. X n - Y n)" -unfolding summable_def by (auto intro: sums_diff) - -lemma suminf_diff: - "\summable X; summable Y\ \ suminf X - suminf Y = (\n. X n - Y n)" -by (intro sums_unique sums_diff summable_sums) - -lemma sums_minus: "X sums a ==> (\n. - X n) sums (- a)" -unfolding sums_def by (simp add: setsum_negf LIMSEQ_minus) - -lemma summable_minus: "summable X \ summable (\n. - X n)" -unfolding summable_def by (auto intro: sums_minus) - -lemma suminf_minus: "summable X \ (\n. - X n) = - (\n. X n)" -by (intro sums_unique [symmetric] sums_minus summable_sums) - -lemma sums_group: - "[|summable f; 0 < k |] ==> (%n. setsum f {n*k.. real" - shows "\summable f; \m\n. 0 \ f m\ \ setsum f {0.. suminf f" -apply (drule summable_sums) -apply (simp add: sums_def) -apply (cut_tac k = "setsum f {0.. real" - shows "\summable f; \m\n. 0 < f m\ \ setsum f {0.. real" - shows "\summable f; \n. 0 < f n\ \ 0 < suminf f" -by (drule_tac n="0" in series_pos_less, simp_all) - -lemma suminf_ge_zero: - fixes f :: "nat \ real" - shows "\summable f; \n. 0 \ f n\ \ 0 \ suminf f" -by (drule_tac n="0" in series_pos_le, simp_all) - -lemma sumr_pos_lt_pair: - fixes f :: "nat \ real" - shows "\summable f; - \d. 0 < f (k + (Suc(Suc 0) * d)) + f (k + ((Suc(Suc 0) * d) + 1))\ - \ setsum f {0.. (\n. x ^ n) sums (1 / (1 - x))" -proof - - assume less_1: "norm x < 1" - hence neq_1: "x \ 1" by auto - hence neq_0: "x - 1 \ 0" by simp - from less_1 have lim_0: "(\n. x ^ n) ----> 0" - by (rule LIMSEQ_power_zero) - hence "(\n. x ^ n / (x - 1) - 1 / (x - 1)) ----> 0 / (x - 1) - 1 / (x - 1)" - using neq_0 by (intro LIMSEQ_divide LIMSEQ_diff LIMSEQ_const) - hence "(\n. (x ^ n - 1) / (x - 1)) ----> 1 / (1 - x)" - by (simp add: nonzero_minus_divide_right [OF neq_0] diff_divide_distrib) - thus "(\n. x ^ n) sums (1 / (1 - x))" - by (simp add: sums_def geometric_sum neq_1) -qed - -lemma summable_geometric: - fixes x :: "'a::{real_normed_field,recpower}" - shows "norm x < 1 \ summable (\n. x ^ n)" -by (rule geometric_sums [THEN sums_summable]) - -text{*Cauchy-type criterion for convergence of series (c.f. Harrison)*} - -lemma summable_convergent_sumr_iff: - "summable f = convergent (%n. setsum f {0.. f ----> 0" -apply (drule summable_convergent_sumr_iff [THEN iffD1]) -apply (drule convergent_Cauchy) -apply (simp only: Cauchy_def LIMSEQ_def, safe) -apply (drule_tac x="r" in spec, safe) -apply (rule_tac x="M" in exI, safe) -apply (drule_tac x="Suc n" in spec, simp) -apply (drule_tac x="n" in spec, simp) -done - -lemma summable_Cauchy: - "summable (f::nat \ 'a::banach) = - (\e > 0. \N. \m \ N. \n. norm (setsum f {m.. 'b::real_normed_vector" - shows "norm (setsum f A) \ (\i\A. norm (f i))" -apply (case_tac "finite A") -apply (erule finite_induct) -apply simp -apply simp -apply (erule order_trans [OF norm_triangle_ineq add_left_mono]) -apply simp -done - -lemma summable_comparison_test: - fixes f :: "nat \ 'a::banach" - shows "\\N. \n\N. norm (f n) \ g n; summable g\ \ summable f" -apply (simp add: summable_Cauchy, safe) -apply (drule_tac x="e" in spec, safe) -apply (rule_tac x = "N + Na" in exI, safe) -apply (rotate_tac 2) -apply (drule_tac x = m in spec) -apply (auto, rotate_tac 2, drule_tac x = n in spec) -apply (rule_tac y = "\k=m.. 'a::banach" - shows "\\N. \n\N. norm (f n) \ g n; summable g\ - \ summable (\n. norm (f n))" -apply (rule summable_comparison_test) -apply (auto) -done - -lemma summable_rabs_comparison_test: - fixes f :: "nat \ real" - shows "\\N. \n\N. \f n\ \ g n; summable g\ \ summable (\n. \f n\)" -apply (rule summable_comparison_test) -apply (auto) -done - -text{*Summability of geometric series for real algebras*} - -lemma complete_algebra_summable_geometric: - fixes x :: "'a::{real_normed_algebra_1,banach,recpower}" - shows "norm x < 1 \ summable (\n. x ^ n)" -proof (rule summable_comparison_test) - show "\N. \n\N. norm (x ^ n) \ norm x ^ n" - by (simp add: norm_power_ineq) - show "norm x < 1 \ summable (\n. norm x ^ n)" - by (simp add: summable_geometric) -qed - -text{*Limit comparison property for series (c.f. jrh)*} - -lemma summable_le: - fixes f g :: "nat \ real" - shows "\\n. f n \ g n; summable f; summable g\ \ suminf f \ suminf g" -apply (drule summable_sums)+ -apply (simp only: sums_def, erule (1) LIMSEQ_le) -apply (rule exI) -apply (auto intro!: setsum_mono) -done - -lemma summable_le2: - fixes f g :: "nat \ real" - shows "\\n. \f n\ \ g n; summable g\ \ summable f \ suminf f \ suminf g" -apply (subgoal_tac "summable f") -apply (auto intro!: summable_le) -apply (simp add: abs_le_iff) -apply (rule_tac g="g" in summable_comparison_test, simp_all) -done - -(* specialisation for the common 0 case *) -lemma suminf_0_le: - fixes f::"nat\real" - assumes gt0: "\n. 0 \ f n" and sm: "summable f" - shows "0 \ suminf f" -proof - - let ?g = "(\n. (0::real))" - from gt0 have "\n. ?g n \ f n" by simp - moreover have "summable ?g" by (rule summable_zero) - moreover from sm have "summable f" . - ultimately have "suminf ?g \ suminf f" by (rule summable_le) - then show "0 \ suminf f" by (simp add: suminf_zero) -qed - - -text{*Absolute convergence imples normal convergence*} -lemma summable_norm_cancel: - fixes f :: "nat \ 'a::banach" - shows "summable (\n. norm (f n)) \ summable f" -apply (simp only: summable_Cauchy, safe) -apply (drule_tac x="e" in spec, safe) -apply (rule_tac x="N" in exI, safe) -apply (drule_tac x="m" in spec, safe) -apply (rule order_le_less_trans [OF norm_setsum]) -apply (rule order_le_less_trans [OF abs_ge_self]) -apply simp -done - -lemma summable_rabs_cancel: - fixes f :: "nat \ real" - shows "summable (\n. \f n\) \ summable f" -by (rule summable_norm_cancel, simp) - -text{*Absolute convergence of series*} -lemma summable_norm: - fixes f :: "nat \ 'a::banach" - shows "summable (\n. norm (f n)) \ norm (suminf f) \ (\n. norm (f n))" -by (auto intro: LIMSEQ_le LIMSEQ_norm summable_norm_cancel - summable_sumr_LIMSEQ_suminf norm_setsum) - -lemma summable_rabs: - fixes f :: "nat \ real" - shows "summable (\n. \f n\) \ \suminf f\ \ (\n. \f n\)" -by (fold real_norm_def, rule summable_norm) - -subsection{* The Ratio Test*} - -lemma norm_ratiotest_lemma: - fixes x y :: "'a::real_normed_vector" - shows "\c \ 0; norm x \ c * norm y\ \ x = 0" -apply (subgoal_tac "norm x \ 0", simp) -apply (erule order_trans) -apply (simp add: mult_le_0_iff) -done - -lemma rabs_ratiotest_lemma: "[| c \ 0; abs x \ c * abs y |] ==> x = (0::real)" -by (erule norm_ratiotest_lemma, simp) - -lemma le_Suc_ex: "(k::nat) \ l ==> (\n. l = k + n)" -apply (drule le_imp_less_or_eq) -apply (auto dest: less_imp_Suc_add) -done - -lemma le_Suc_ex_iff: "((k::nat) \ l) = (\n. l = k + n)" -by (auto simp add: le_Suc_ex) - -(*All this trouble just to get 0 'a::banach" - shows "\\n\N. norm (f (Suc n)) \ c * norm (f n)\ \ 0 < c \ summable f" -apply (simp (no_asm) add: linorder_not_le [symmetric]) -apply (simp add: summable_Cauchy) -apply (safe, subgoal_tac "\n. N < n --> f (n) = 0") - prefer 2 - apply clarify - apply(erule_tac x = "n - 1" in allE) - apply (simp add:diff_Suc split:nat.splits) - apply (blast intro: norm_ratiotest_lemma) -apply (rule_tac x = "Suc N" in exI, clarify) -apply(simp cong:setsum_ivl_cong) -done - -lemma ratio_test: - fixes f :: "nat \ 'a::banach" - shows "\c < 1; \n\N. norm (f (Suc n)) \ c * norm (f n)\ \ summable f" -apply (frule ratio_test_lemma2, auto) -apply (rule_tac g = "%n. (norm (f N) / (c ^ N))*c ^ n" - in summable_comparison_test) -apply (rule_tac x = N in exI, safe) -apply (drule le_Suc_ex_iff [THEN iffD1]) -apply (auto simp add: power_add field_power_not_zero) -apply (induct_tac "na", auto) -apply (rule_tac y = "c * norm (f (N + n))" in order_trans) -apply (auto intro: mult_right_mono simp add: summable_def) -apply (simp add: mult_ac) -apply (rule_tac x = "norm (f N) * (1/ (1 - c)) / (c ^ N)" in exI) -apply (rule sums_divide) -apply (rule sums_mult) -apply (auto intro!: geometric_sums) -done - -subsection {* Cauchy Product Formula *} - -(* Proof based on Analysis WebNotes: Chapter 07, Class 41 -http://www.math.unl.edu/~webnotes/classes/class41/prp77.htm *) - -lemma setsum_triangle_reindex: - fixes n :: nat - shows "(\(i,j)\{(i,j). i+j < n}. f i j) = (\k=0..i=0..k. f i (k - i))" -proof - - have "(\(i, j)\{(i, j). i + j < n}. f i j) = - (\(k, i)\(SIGMA k:{0..(k,i). (i, k - i)) (SIGMA k:{0..(k,i). (i, k - i)) ` (SIGMA k:{0..a. (\(k, i). f i (k - i)) a = split f ((\(k, i). (i, k - i)) a)" - by clarify - qed - thus ?thesis by (simp add: setsum_Sigma) -qed - -lemma Cauchy_product_sums: - fixes a b :: "nat \ 'a::{real_normed_algebra,banach}" - assumes a: "summable (\k. norm (a k))" - assumes b: "summable (\k. norm (b k))" - shows "(\k. \i=0..k. a i * b (k - i)) sums ((\k. a k) * (\k. b k))" -proof - - let ?S1 = "\n::nat. {0.. {0..m n. m \ n \ ?S1 m \ ?S1 n" by auto - have S2_le_S1: "\n. ?S2 n \ ?S1 n" by auto - have S1_le_S2: "\n. ?S1 (n div 2) \ ?S2 n" by auto - have finite_S1: "\n. finite (?S1 n)" by simp - with S2_le_S1 have finite_S2: "\n. finite (?S2 n)" by (rule finite_subset) - - let ?g = "\(i,j). a i * b j" - let ?f = "\(i,j). norm (a i) * norm (b j)" - have f_nonneg: "\x. 0 \ ?f x" - by (auto simp add: mult_nonneg_nonneg) - hence norm_setsum_f: "\A. norm (setsum ?f A) = setsum ?f A" - unfolding real_norm_def - by (simp only: abs_of_nonneg setsum_nonneg [rule_format]) - - have "(\n. (\k=0..k=0.. (\k. a k) * (\k. b k)" - by (intro LIMSEQ_mult summable_sumr_LIMSEQ_suminf - summable_norm_cancel [OF a] summable_norm_cancel [OF b]) - hence 1: "(\n. setsum ?g (?S1 n)) ----> (\k. a k) * (\k. b k)" - by (simp only: setsum_product setsum_Sigma [rule_format] - finite_atLeastLessThan) - - have "(\n. (\k=0..k=0.. (\k. norm (a k)) * (\k. norm (b k))" - using a b by (intro LIMSEQ_mult summable_sumr_LIMSEQ_suminf) - hence "(\n. setsum ?f (?S1 n)) ----> (\k. norm (a k)) * (\k. norm (b k))" - by (simp only: setsum_product setsum_Sigma [rule_format] - finite_atLeastLessThan) - hence "convergent (\n. setsum ?f (?S1 n))" - by (rule convergentI) - hence Cauchy: "Cauchy (\n. setsum ?f (?S1 n))" - by (rule convergent_Cauchy) - have "Zseq (\n. setsum ?f (?S1 n - ?S2 n))" - proof (rule ZseqI, simp only: norm_setsum_f) - fix r :: real - assume r: "0 < r" - from CauchyD [OF Cauchy r] obtain N - where "\m\N. \n\N. norm (setsum ?f (?S1 m) - setsum ?f (?S1 n)) < r" .. - hence "\m n. \N \ n; n \ m\ \ norm (setsum ?f (?S1 m - ?S1 n)) < r" - by (simp only: setsum_diff finite_S1 S1_mono) - hence N: "\m n. \N \ n; n \ m\ \ setsum ?f (?S1 m - ?S1 n) < r" - by (simp only: norm_setsum_f) - show "\N. \n\N. setsum ?f (?S1 n - ?S2 n) < r" - proof (intro exI allI impI) - fix n assume "2 * N \ n" - hence n: "N \ n div 2" by simp - have "setsum ?f (?S1 n - ?S2 n) \ setsum ?f (?S1 n - ?S1 (n div 2))" - by (intro setsum_mono2 finite_Diff finite_S1 f_nonneg - Diff_mono subset_refl S1_le_S2) - also have "\ < r" - using n div_le_dividend by (rule N) - finally show "setsum ?f (?S1 n - ?S2 n) < r" . - qed - qed - hence "Zseq (\n. setsum ?g (?S1 n - ?S2 n))" - apply (rule Zseq_le [rule_format]) - apply (simp only: norm_setsum_f) - apply (rule order_trans [OF norm_setsum setsum_mono]) - apply (auto simp add: norm_mult_ineq) - done - hence 2: "(\n. setsum ?g (?S1 n) - setsum ?g (?S2 n)) ----> 0" - by (simp only: LIMSEQ_Zseq_iff setsum_diff finite_S1 S2_le_S1 diff_0_right) - - with 1 have "(\n. setsum ?g (?S2 n)) ----> (\k. a k) * (\k. b k)" - by (rule LIMSEQ_diff_approach_zero2) - thus ?thesis by (simp only: sums_def setsum_triangle_reindex) -qed - -lemma Cauchy_product: - fixes a b :: "nat \ 'a::{real_normed_algebra,banach}" - assumes a: "summable (\k. norm (a k))" - assumes b: "summable (\k. norm (b k))" - shows "(\k. a k) * (\k. b k) = (\k. \i=0..k. a i * b (k - i))" -using a b -by (rule Cauchy_product_sums [THEN sums_unique]) - -end