diff -r e04536f7c5ea -r 780161d4b55c src/HOL/Limits.thy --- a/src/HOL/Limits.thy Wed Jan 25 22:00:21 2023 +0100 +++ b/src/HOL/Limits.thy Thu Jan 26 13:59:51 2023 +0000 @@ -11,15 +11,6 @@ imports Real_Vector_Spaces begin -text \Lemmas related to shifting/scaling\ -lemma range_add [simp]: - fixes a::"'a::group_add" shows "range ((+) a) = UNIV" - by simp - -lemma range_diff [simp]: - fixes a::"'a::group_add" shows "range ((-) a) = UNIV" - by (metis (full_types) add_minus_cancel diff_minus_eq_add surj_def) - lemma range_mult [simp]: fixes a::"real" shows "range ((*) a) = (if a=0 then {0} else UNIV)" by (simp add: surj_def) (meson dvdE dvd_field_iff) @@ -2533,6 +2524,147 @@ by (metis B abs_le_iff add.inverse_inverse neg_le_iff_le) qed +subsection \More about @{term filterlim} (thanks to Wenda Li)\ + +lemma filterlim_at_infinity_times: + fixes f :: "'a \ 'b::real_normed_field" + assumes "filterlim f at_infinity F" "filterlim g at_infinity F" + shows "filterlim (\x. f x * g x) at_infinity F" +proof - + have "((\x. inverse (f x) * inverse (g x)) \ 0 * 0) F" + by (intro tendsto_mult tendsto_inverse assms filterlim_compose[OF tendsto_inverse_0]) + then have "filterlim (\x. inverse (f x) * inverse (g x)) (at 0) F" + unfolding filterlim_at using assms + by (auto intro: filterlim_at_infinity_imp_eventually_ne tendsto_imp_eventually_ne eventually_conj) + then show ?thesis + by (subst filterlim_inverse_at_iff[symmetric]) simp_all +qed + +lemma filterlim_at_top_at_bot[elim]: + fixes f::"'a \ 'b::unbounded_dense_linorder" and F::"'a filter" + assumes top:"filterlim f at_top F" and bot: "filterlim f at_bot F" and "F\bot" + shows False +proof - + obtain c::'b where True by auto + have "\\<^sub>F x in F. c < f x" + using top unfolding filterlim_at_top_dense by auto + moreover have "\\<^sub>F x in F. f x < c" + using bot unfolding filterlim_at_bot_dense by auto + ultimately have "\\<^sub>F x in F. c < f x \ f x < c" + using eventually_conj by auto + then have "\\<^sub>F x in F. False" by (auto elim:eventually_mono) + then show False using \F\bot\ by auto +qed + +lemma filterlim_at_top_nhds[elim]: + fixes f::"'a \ 'b::{unbounded_dense_linorder,order_topology}" and F::"'a filter" + assumes top:"filterlim f at_top F" and tendsto: "(f \ c) F" and "F\bot" + shows False +proof - + obtain c'::'b where "c'>c" using gt_ex by blast + have "\\<^sub>F x in F. c' < f x" + using top unfolding filterlim_at_top_dense by auto + moreover have "\\<^sub>F x in F. f x < c'" + using order_tendstoD[OF tendsto,of c'] \c'>c\ by auto + ultimately have "\\<^sub>F x in F. c' < f x \ f x < c'" + using eventually_conj by auto + then have "\\<^sub>F x in F. False" by (auto elim:eventually_mono) + then show False using \F\bot\ by auto +qed + +lemma filterlim_at_bot_nhds[elim]: + fixes f::"'a \ 'b::{unbounded_dense_linorder,order_topology}" and F::"'a filter" + assumes top:"filterlim f at_bot F" and tendsto: "(f \ c) F" and "F\bot" + shows False +proof - + obtain c'::'b where "c'\<^sub>F x in F. c' > f x" + using top unfolding filterlim_at_bot_dense by auto + moreover have "\\<^sub>F x in F. f x > c'" + using order_tendstoD[OF tendsto,of c'] \c' by auto + ultimately have "\\<^sub>F x in F. c' < f x \ f x < c'" + using eventually_conj by auto + then have "\\<^sub>F x in F. False" by (auto elim:eventually_mono) + then show False using \F\bot\ by auto +qed + +lemma eventually_times_inverse_1: + fixes f::"'a \ 'b::{field,t2_space}" + assumes "(f \ c) F" "c\0" + shows "\\<^sub>F x in F. inverse (f x) * f x = 1" + by (smt (verit) assms eventually_mono mult.commute right_inverse tendsto_imp_eventually_ne) + +lemma filterlim_at_infinity_divide_iff: + fixes f::"'a \ 'b::real_normed_field" + assumes "(f \ c) F" "c\0" + shows "(LIM x F. f x / g x :> at_infinity) \ (LIM x F. g x :> at 0)" +proof + assume "LIM x F. f x / g x :> at_infinity" + then have "LIM x F. inverse (f x) * (f x / g x) :> at_infinity" + using assms tendsto_inverse tendsto_mult_filterlim_at_infinity by fastforce + then have "LIM x F. inverse (g x) :> at_infinity" + apply (elim filterlim_mono_eventually) + using eventually_times_inverse_1[OF assms] + by (auto elim:eventually_mono simp add:field_simps) + then show "filterlim g (at 0) F" using filterlim_inverse_at_iff[symmetric] by force +next + assume "filterlim g (at 0) F" + then have "filterlim (\x. inverse (g x)) at_infinity F" + using filterlim_compose filterlim_inverse_at_infinity by blast + then have "LIM x F. f x * inverse (g x) :> at_infinity" + using tendsto_mult_filterlim_at_infinity[OF assms, of "\x. inverse(g x)"] + by simp + then show "LIM x F. f x / g x :> at_infinity" by (simp add: divide_inverse) +qed + +lemma filterlim_tendsto_pos_mult_at_top_iff: + fixes f::"'a \ real" + assumes "(f \ c) F" and "0 < c" + shows "(LIM x F. (f x * g x) :> at_top) \ (LIM x F. g x :> at_top)" +proof + assume "filterlim g at_top F" + then show "LIM x F. f x * g x :> at_top" + using filterlim_tendsto_pos_mult_at_top[OF assms] by auto +next + assume asm:"LIM x F. f x * g x :> at_top" + have "((\x. inverse (f x)) \ inverse c) F" + using tendsto_inverse[OF assms(1)] \0 by auto + moreover have "inverse c >0" using assms(2) by auto + ultimately have "LIM x F. inverse (f x) * (f x * g x) :> at_top" + using filterlim_tendsto_pos_mult_at_top[OF _ _ asm,of "\x. inverse (f x)" "inverse c"] by auto + then show "LIM x F. g x :> at_top" + apply (elim filterlim_mono_eventually) + apply simp_all[2] + using eventually_times_inverse_1[OF assms(1)] \c>0\ eventually_mono by fastforce +qed + +lemma filterlim_tendsto_pos_mult_at_bot_iff: + fixes c :: real + assumes "(f \ c) F" "0 < c" + shows "(LIM x F. f x * g x :> at_bot) \ filterlim g at_bot F" + using filterlim_tendsto_pos_mult_at_top_iff[OF assms(1,2), of "\x. - g x"] + unfolding filterlim_uminus_at_bot by simp + +lemma filterlim_tendsto_neg_mult_at_top_iff: + fixes f::"'a \ real" + assumes "(f \ c) F" and "c < 0" + shows "(LIM x F. (f x * g x) :> at_top) \ (LIM x F. g x :> at_bot)" +proof - + have "(LIM x F. f x * g x :> at_top) = (LIM x F. - g x :> at_top)" + apply (rule filterlim_tendsto_pos_mult_at_top_iff[of "\x. - f x" "-c" F "\x. - g x", simplified]) + using assms by (auto intro: tendsto_intros ) + also have "... = (LIM x F. g x :> at_bot)" + using filterlim_uminus_at_bot[symmetric] by auto + finally show ?thesis . +qed + +lemma filterlim_tendsto_neg_mult_at_bot_iff: + fixes c :: real + assumes "(f \ c) F" "0 > c" + shows "(LIM x F. f x * g x :> at_bot) \ filterlim g at_top F" + using filterlim_tendsto_neg_mult_at_top_iff[OF assms(1,2), of "\x. - g x"] + unfolding filterlim_uminus_at_top by simp + subsection \Power Sequences\ lemma Bseq_realpow: "0 \ x \ x \ 1 \ Bseq (\n. x ^ n)"