# HG changeset patch # User paulson # Date 1525963294 -3600 # Node ID f022083489d044ae72af063d65a98b7c5983dbd2 # Parent 4646124e683e7c384091b8a243c844ab8e286670 more on infinite products diff -r 4646124e683e -r f022083489d0 src/HOL/Analysis/Infinite_Products.thy --- a/src/HOL/Analysis/Infinite_Products.thy Wed May 09 15:07:20 2018 +0100 +++ b/src/HOL/Analysis/Infinite_Products.thy Thu May 10 15:41:34 2018 +0100 @@ -75,8 +75,33 @@ lemma gen_has_prod_nonzero [simp]: "\ gen_has_prod f M 0" by (simp add: gen_has_prod_def) +lemma gen_has_prod_eq_0: + fixes f :: "nat \ 'a::{idom,t2_space}" + assumes p: "gen_has_prod f m p" and i: "f i = 0" "i \ m" + shows "p = 0" +proof - + have eq0: "(\k\n. f (k+m)) = 0" if "i - m \ n" for n + by (metis i that atMost_atLeast0 atMost_iff diff_add finite_atLeastAtMost prod_zero_iff) + have "(\n. \i\n. f (i + m)) \ 0" + by (rule LIMSEQ_offset [where k = "i-m"]) (simp add: eq0) + with p show ?thesis + unfolding gen_has_prod_def + using LIMSEQ_unique by blast +qed + lemma has_prod_0_iff: "f has_prod 0 \ (\i. f i = 0 \ (\p. gen_has_prod f (Suc i) p))" by (simp add: has_prod_def) + +lemma has_prod_unique2: + fixes f :: "nat \ 'a::{idom,t2_space}" + assumes "f has_prod a" "f has_prod b" shows "a = b" + using assms + by (auto simp: has_prod_def gen_has_prod_eq_0) (meson gen_has_prod_def sequentially_bot tendsto_unique) + +lemma has_prod_unique: + fixes f :: "nat \ 'a :: {idom,t2_space}" + shows "f has_prod s \ s = prodinf f" + by (simp add: has_prod_unique2 prodinf_def the_equality) lemma convergent_prod_altdef: fixes f :: "nat \ 'a :: {t2_space,comm_semiring_1}" @@ -385,7 +410,14 @@ unfolding prod_defs by blast qed -lemma abs_convergent_prod_ignore_initial_segment: +corollary convergent_prod_ignore_nonzero_segment: + fixes f :: "nat \ 'a :: real_normed_field" + assumes f: "convergent_prod f" and nz: "\i. i \ M \ f i \ 0" + shows "\p. gen_has_prod f M p" + using convergent_prod_ignore_initial_segment [OF f] + by (metis convergent_LIMSEQ_iff convergent_prod_iff_convergent le_add_same_cancel2 nz prod_defs(1) zero_order(1)) + +corollary abs_convergent_prod_ignore_initial_segment: assumes "abs_convergent_prod f" shows "abs_convergent_prod (\n. f (n + m))" using assms unfolding abs_convergent_prod_def @@ -519,15 +551,13 @@ with L show ?thesis by (auto simp: prod_defs) qed -lemma convergent_prod_offset_0: +lemma gen_has_prod_cases: fixes f :: "nat \ 'a :: {idom,topological_semigroup_mult,t2_space}" - assumes "convergent_prod f" "\i. f i \ 0" - shows "\p. gen_has_prod f 0 p" - using assms - unfolding convergent_prod_def -proof (clarsimp simp: prod_defs) - fix M p - assume "(\n. \i\n. f (i + M)) \ p" "p \ 0" + assumes "gen_has_prod f M p" + obtains i where "in. \i\n. f (i + M)) \ p" "p \ 0" + using assms unfolding gen_has_prod_def by blast+ then have "(\n. prod f {..i\n. f (i + M))) \ prod f {..i\n. f (i + M)) = prod f {..n+M}" for n @@ -542,11 +572,18 @@ qed ultimately have "(\n. prod f {..n}) \ prod f {..p. (\n. prod f {..n}) \ p \ p \ 0" - using \p \ 0\ assms - by (rule_tac x="prod f {..i 0" + using \p \ 0\ assms that by (auto simp: gen_has_prod_def) + then show thesis + using that by blast qed +corollary convergent_prod_offset_0: + fixes f :: "nat \ 'a :: {idom,topological_semigroup_mult,t2_space}" + assumes "convergent_prod f" "\i. f i \ 0" + shows "\p. gen_has_prod f 0 p" + using assms convergent_prod_def gen_has_prod_cases by blast + lemma prodinf_eq_lim: fixes f :: "nat \ 'a :: {idom,topological_semigroup_mult,t2_space}" assumes "convergent_prod f" "\i. f i \ 0" @@ -714,5 +751,71 @@ shows "(\r. if r = i then f r else 1) has_prod f i" using has_prod_If_finite[of "\r. r = i"] by simp +context + fixes f :: "nat \ 'a :: real_normed_field" +begin + +lemma convergent_prod_imp_has_prod: + assumes "convergent_prod f" + shows "\p. f has_prod p" +proof - + obtain M p where p: "gen_has_prod f M p" + using assms convergent_prod_def by blast + then have "p \ 0" + using gen_has_prod_nonzero by blast + with p have fnz: "f i \ 0" if "i \ M" for i + using gen_has_prod_eq_0 that by blast + define C where "C = (\nn\M. f n \ 0") + case True + then have "C \ 0" + by (simp add: C_def) + then show ?thesis + by (meson True assms convergent_prod_offset_0 fnz has_prod_def nat_le_linear) + next + case False + let ?N = "GREATEST n. f n = 0" + have 0: "f ?N = 0" + using fnz False + by (metis (mono_tags, lifting) GreatestI_ex_nat nat_le_linear) + have "f i \ 0" if "i > ?N" for i + by (metis (mono_tags, lifting) Greatest_le_nat fnz leD linear that) + then have "\p. gen_has_prod f (Suc ?N) p" + using assms by (auto simp: intro!: convergent_prod_ignore_nonzero_segment) + then show ?thesis + unfolding has_prod_def using 0 by blast + qed +qed + +lemma convergent_prod_has_prod [intro]: + shows "convergent_prod f \ f has_prod (prodinf f)" + unfolding prodinf_def + by (metis convergent_prod_imp_has_prod has_prod_unique theI') + +lemma convergent_prod_LIMSEQ: + shows "convergent_prod f \ (\n. \i\n. f i) \ prodinf f" + by (metis convergent_LIMSEQ_iff convergent_prod_has_prod convergent_prod_imp_convergent + convergent_prod_to_zero_iff gen_has_prod_eq_0 has_prod_def prodinf_eq_lim zero_le) + +lemma has_prod_iff: "f has_prod x \ convergent_prod f \ prodinf f = x" +proof + assume "f has_prod x" + then show "convergent_prod f \ prodinf f = x" + apply safe + using convergent_prod_def has_prod_def apply blast + using has_prod_unique by blast +qed auto + +lemma convergent_prod_has_prod_iff: "convergent_prod f \ f has_prod prodinf f" + by (auto simp: has_prod_iff convergent_prod_has_prod) + +lemma prodinf_finite: + assumes N: "finite N" + and f: "\n. n \ N \ f n = 1" + shows "prodinf f = (\n\N. f n)" + using has_prod_finite[OF assms, THEN has_prod_unique] by simp end + +end