# HG changeset patch # User paulson # Date 1525602820 -3600 # Node ID 4fa3e63ecc7e22776b5f4450f7d23e3e9fe3cb3b # Parent b25ccd85b1fd2f696ab487cbb18085172b711d92 starting to tidy up Interval_Integral.thy diff -r b25ccd85b1fd -r 4fa3e63ecc7e src/HOL/Analysis/Derivative.thy --- a/src/HOL/Analysis/Derivative.thy Fri May 04 22:26:25 2018 +0200 +++ b/src/HOL/Analysis/Derivative.thy Sun May 06 11:33:40 2018 +0100 @@ -72,8 +72,8 @@ by blast lemma has_derivative_within_open: - "a \ s \ open s \ - (f has_derivative f') (at a within s) \ (f has_derivative f') (at a)" + "a \ S \ open S \ + (f has_derivative f') (at a within S) \ (f has_derivative f') (at a)" by (simp only: at_within_interior interior_open) lemma has_derivative_right: @@ -98,8 +98,8 @@ lemmas DERIV_within_iff = has_field_derivative_iff lemma DERIV_caratheodory_within: - "(f has_field_derivative l) (at x within s) \ - (\g. (\z. f z - f x = g z * (z - x)) \ continuous (at x within s) g \ g x = l)" + "(f has_field_derivative l) (at x within S) \ + (\g. (\z. f z - f x = g z * (z - x)) \ continuous (at x within S) g \ g x = l)" (is "?lhs = ?rhs") proof assume ?lhs @@ -107,14 +107,14 @@ proof (intro exI conjI) let ?g = "(%z. if z = x then l else (f z - f x) / (z-x))" show "\z. f z - f x = ?g z * (z-x)" by simp - show "continuous (at x within s) ?g" using \?lhs\ + show "continuous (at x within S) ?g" using \?lhs\ by (auto simp add: continuous_within DERIV_within_iff cong: Lim_cong_within) show "?g x = l" by simp qed next assume ?rhs then obtain g where - "(\z. f z - f x = g z * (z-x))" and "continuous (at x within s) g" and "g x = l" by blast + "(\z. f z - f x = g z * (z-x))" and "continuous (at x within S) g" and "g x = l" by blast thus ?lhs by (auto simp add: continuous_within DERIV_within_iff cong: Lim_cong_within) qed @@ -330,18 +330,23 @@ using has_derivative_compose[of f f' x UNIV g g'] by (simp add: comp_def) +lemma has_vector_derivative_within_open: + "a \ S \ open S \ + (f has_vector_derivative f') (at a within S) \ (f has_vector_derivative f') (at a)" + by (simp only: at_within_interior interior_open) + lemma field_vector_diff_chain_within: - assumes Df: "(f has_vector_derivative f') (at x within s)" - and Dg: "(g has_field_derivative g') (at (f x) within f`s)" - shows "((g \ f) has_vector_derivative (f' * g')) (at x within s)" + assumes Df: "(f has_vector_derivative f') (at x within S)" + and Dg: "(g has_field_derivative g') (at (f x) within f ` S)" + shows "((g \ f) has_vector_derivative (f' * g')) (at x within S)" using diff_chain_within[OF Df[unfolded has_vector_derivative_def] Dg [unfolded has_field_derivative_def]] by (auto simp: o_def mult.commute has_vector_derivative_def) lemma vector_derivative_diff_chain_within: - assumes Df: "(f has_vector_derivative f') (at x within s)" - and Dg: "(g has_derivative g') (at (f x) within f`s)" - shows "((g \ f) has_vector_derivative (g' f')) (at x within s)" + assumes Df: "(f has_vector_derivative f') (at x within S)" + and Dg: "(g has_derivative g') (at (f x) within f`S)" + shows "((g \ f) has_vector_derivative (g' f')) (at x within S)" using diff_chain_within[OF Df[unfolded has_vector_derivative_def] Dg] linear.scaleR[OF has_derivative_linear[OF Dg]] unfolding has_vector_derivative_def o_def @@ -357,8 +362,8 @@ by (meson diff_chain_at) lemma differentiable_chain_within: - "f differentiable (at x within s) \ - g differentiable (at(f x) within (f ` s)) \ (g \ f) differentiable (at x within s)" + "f differentiable (at x within S) \ + g differentiable (at(f x) within (f ` S)) \ (g \ f) differentiable (at x within S)" unfolding differentiable_def by (meson diff_chain_within) diff -r b25ccd85b1fd -r 4fa3e63ecc7e src/HOL/Analysis/Interval_Integral.thy --- a/src/HOL/Analysis/Interval_Integral.thy Fri May 04 22:26:25 2018 +0200 +++ b/src/HOL/Analysis/Interval_Integral.thy Sun May 06 11:33:40 2018 +0100 @@ -12,20 +12,6 @@ "(\x. x \ S \ (f has_vector_derivative f' x) (at x within S)) \ continuous_on S f" by (auto simp: continuous_on_eq_continuous_within intro!: has_vector_derivative_continuous) -lemma has_vector_derivative_weaken: - fixes x D and f g s t - assumes f: "(f has_vector_derivative D) (at x within t)" - and "x \ s" "s \ t" - and "\x. x \ s \ f x = g x" - shows "(g has_vector_derivative D) (at x within s)" -proof - - have "(f has_vector_derivative D) (at x within s) \ (g has_vector_derivative D) (at x within s)" - unfolding has_vector_derivative_def has_derivative_iff_norm - using assms by (intro conj_cong Lim_cong_within refl) auto - then show ?thesis - using has_vector_derivative_within_subset[OF f \s \ t\] by simp -qed - definition "einterval a b = {x. a < ereal x \ ereal x < b}" lemma einterval_eq[simp]: @@ -59,8 +45,7 @@ lemma ereal_incseq_approx: fixes a b :: ereal assumes "a < b" - obtains X :: "nat \ real" where - "incseq X" "\i. a < X i" "\i. X i < b" "X \ b" + obtains X :: "nat \ real" where "incseq X" "\i. a < X i" "\i. X i < b" "X \ b" proof (cases b) case PInf with \a < b\ have "a = -\ \ (\r. a = ereal r)" @@ -87,13 +72,12 @@ by (intro mult_strict_left_mono) auto with \a < b\ a' have "\i. a < ereal (b' - d / real (Suc (Suc i)))" by (cases a) (auto simp: real d_def field_simps) - moreover have "(\i. b' - d / Suc (Suc i)) \ b'" - apply (subst filterlim_sequentially_Suc) - apply (subst filterlim_sequentially_Suc) - apply (rule tendsto_eq_intros) - apply (auto intro!: tendsto_divide_0[OF tendsto_const] filterlim_sup1 - simp: at_infinity_eq_at_top_bot filterlim_real_sequentially) - done + moreover + have "(\i. b' - d / real i) \ b'" + by (force intro: tendsto_eq_intros tendsto_divide_0[OF tendsto_const] filterlim_sup1 + simp: at_infinity_eq_at_top_bot filterlim_real_sequentially) + then have "(\i. b' - d / Suc (Suc i)) \ b'" + by (blast intro: dest: filterlim_sequentially_Suc [THEN iffD2]) ultimately show thesis by (intro that[of "\i. b' - d / Suc (Suc i)"]) (auto simp add: real incseq_def intro!: divide_left_mono) @@ -601,14 +585,6 @@ TODO: make the older versions corollaries of these (using continuous_at_imp_continuous_on, etc.) *) -(* -TODO: many proofs below require inferences like - - a < ereal x \ x < y \ a < ereal y - -where x and y are real. These should be better automated. -*) - lemma interval_integral_FTC_finite: fixes f F :: "real \ 'a::euclidean_space" and a b :: real assumes f: "continuous_on {min a b..max a b} f" @@ -646,7 +622,6 @@ qed - lemma interval_integral_FTC_nonneg: fixes f F :: "real \ real" and a b :: ereal assumes "a < b" @@ -659,7 +634,11 @@ "set_integrable lborel (einterval a b) f" "(LBINT x=a..b. f x) = B - A" proof - - from einterval_Icc_approximation[OF \a < b\] guess u l . note approx = this + obtain u l where approx: + "einterval a b = (\i. {l i .. u i})" + "incseq u" "decseq l" "\i. l i < u i" "\i. a < l i" "\i. u i < b" + "l \ a" "u \ b" + by (blast intro: einterval_Icc_approximation[OF \a < b\]) have [simp]: "\x i. l i \ x \ a < ereal x" by (rule order_less_le_trans, rule approx, force) have [simp]: "\x i. x \ u i \ ereal x < b" @@ -705,7 +684,11 @@ assumes B: "((F \ real_of_ereal) \ B) (at_left b)" shows "(LBINT x=a..b. f x) = B - A" proof - - from einterval_Icc_approximation[OF \a < b\] guess u l . note approx = this + obtain u l where approx: + "einterval a b = (\i. {l i .. u i})" + "incseq u" "decseq l" "\i. l i < u i" "\i. a < l i" "\i. u i < b" + "l \ a" "u \ b" + by (blast intro: einterval_Icc_approximation[OF \a < b\]) have [simp]: "\x i. l i \ x \ a < ereal x" by (rule order_less_le_trans, rule approx, force) have [simp]: "\x i. x \ u i \ ereal x < b" @@ -783,18 +766,20 @@ have 2: "max c x < b" by simp from einterval_nonempty [OF 2] obtain e :: real where [simp]: "c < e" "x < e" "e < b" by (auto simp add: einterval_def) - show "(?F has_vector_derivative f x) (at x)" - (* TODO: factor out the next three lines to has_field_derivative_within_open *) - unfolding has_vector_derivative_def - apply (subst has_derivative_within_open [of _ "{d<..a < d\, auto) - apply (rule order_le_less_trans) prefer 2 - by (rule \e < b\, auto) + have "(?F has_vector_derivative f x) (at x within {d<..x. \d \ x; x \ e\ \ a < ereal x" + using \a < ereal d\ ereal_less_ereal_Ex by auto + show "\x. \d \ x; x \ e\ \ ereal x < b" + using \ereal e < b\ ereal_less_eq(3) le_less_trans by blast + qed + then show "(?F has_vector_derivative f x) (at x within {d..e})" + by (intro interval_integral_FTC2) (use \d < c\ \c < e\ \d < x\ \x < e\ in \linarith+\) + qed auto + then show "(?F has_vector_derivative f x) (at x)" + by (force simp add: has_vector_derivative_within_open [of _ "{d<..x. f x)" shows "(LBINT x=A..B. f x) = (LBINT x=a..b. g' x *\<^sub>R f (g x))" proof - - from einterval_Icc_approximation[OF \a < b\] guess u l . note approx [simp] = this + obtain u l where approx [simp]: + "einterval a b = (\i. {l i .. u i})" + "incseq u" "decseq l" "\i. l i < u i" "\i. a < l i" "\i. u i < b" + "l \ a" "u \ b" + by (blast intro: einterval_Icc_approximation[OF \a < b\]) note less_imp_le [simp] have [simp]: "\x i. l i \ x \ a < ereal x" by (rule order_less_le_trans, rule approx, force) have [simp]: "\x i. x \ u i \ ereal x < b" by (rule order_le_less_trans, subst ereal_less_eq(3), assumption, rule approx) - have [simp]: "\i. l i < b" - apply (rule order_less_trans) prefer 2 - by (rule approx, auto, rule approx) + then have lessb[simp]: "\i. l i < b" + using approx(4) less_eq_real_def by blast have [simp]: "\i. a < u i" by (rule order_less_trans, rule approx, auto, rule approx) - have [simp]: "\i j. i \ j \ l j \ l i" by (rule decseqD, rule approx) + have lle[simp]: "\i j. i \ j \ l j \ l i" by (rule decseqD, rule approx) have [simp]: "\i j. i \ j \ u i \ u j" by (rule incseqD, rule approx) - have g_nondec [simp]: "\x y. a < x \ x \ y \ y < b \ g x \ g y" - apply (erule DERIV_nonneg_imp_nondecreasing, auto) - apply (rule exI, rule conjI, rule deriv_g) - apply (erule order_less_le_trans, auto) - apply (rule order_le_less_trans, subst ereal_less_eq(3), assumption, auto) - apply (rule g'_nonneg) - apply (rule less_imp_le, erule order_less_le_trans, auto) - by (rule less_imp_le, rule le_less_trans, subst ereal_less_eq(3), assumption, auto) + have g_nondec [simp]: "g x \ g y" if "a < x" "x \ y" "y < b" for x y + proof (rule DERIV_nonneg_imp_nondecreasing [OF \x \ y\], intro exI conjI allI impI) + show "\u. x \ u \ u \ y \ (g has_real_derivative g' u) (at u)" + by (meson deriv_g ereal_less_eq(3) le_less_trans less_le_trans that) + show "\u. x \ u \ u \ y \ 0 \ g' u" + by (meson assms(5) dual_order.trans le_ereal_le less_imp_le order_refl that) + qed have "A \ B" and un: "einterval A B = (\i. {g(l i)<..i. g (l i)) \ A" @@ -904,36 +891,36 @@ by (drule_tac x = "\i. ereal (u i)" in spec, auto) hence B3: "\i. g (u i) \ B" by (intro incseq_le, auto simp add: incseq_def) - show "A \ B" - apply (rule order_trans [OF A3 [of 0]]) - apply (rule order_trans [OF _ B3 [of 0]]) + have "ereal (g (l 0)) \ ereal (g (u 0))" by auto + then show "A \ B" + by (meson A3 B3 order.trans) { fix x :: real assume "A < x" and "x < B" then have "eventually (\i. ereal (g (l i)) < x \ x < ereal (g (u i))) sequentially" - apply (intro eventually_conj order_tendstoD) - by (rule A2, assumption, rule B2, assumption) + by (fast intro: eventually_conj order_tendstoD A2 B2) hence "\i. g (l i) < x \ x < g (u i)" by (simp add: eventually_sequentially, auto) } note AB = this show "einterval A B = (\i. {g(l i)<.. (\i. {g(l i)<..i. {g(l i)<.. einterval A B" + proof (clarsimp simp add: einterval_def, intro conjI) + show "\x i. \g (l i) < x; x < g (u i)\ \ A < ereal x" + using A3 le_ereal_less by blast + show "\x i. \g (l i) < x; x < g (u i)\ \ ereal x < B" + using B3 ereal_le_less by blast + qed + qed qed (* finally, the main argument *) - { - fix i - have "(LBINT x=l i.. u i. g' x *\<^sub>R f (g x)) = (LBINT y=g (l i)..g (u i). f y)" - apply (rule interval_integral_substitution_finite, auto) - apply (rule DERIV_subset) - unfolding has_field_derivative_iff_has_vector_derivative[symmetric] - apply (rule deriv_g) - apply (auto intro!: continuous_at_imp_continuous_on contf contg') - done - } note eq1 = this + have eq1: "(LBINT x=l i.. u i. g' x *\<^sub>R f (g x)) = (LBINT y=g (l i)..g (u i). f y)" for i + apply (rule interval_integral_substitution_finite [OF _ DERIV_subset [OF deriv_g]]) + unfolding has_field_derivative_iff_has_vector_derivative[symmetric] + apply (auto intro!: continuous_at_imp_continuous_on contf contg') + done have "(\i. LBINT x=l i..u i. g' x *\<^sub>R f (g x)) \ (LBINT x=a..b. g' x *\<^sub>R f (g x))" apply (rule interval_integral_Icc_approx_integrable [OF \a < b\ approx]) by (rule assms) @@ -941,9 +928,8 @@ by (simp add: eq1) have incseq: "incseq (\i. {g (l i)<..i. (LBINT y=g (l i)..g (u i). f y)) \ (LBINT x = A..B. f x)" apply (subst interval_lebesgue_integral_le_eq, auto simp del: real_scaleR_def) apply (subst interval_lebesgue_integral_le_eq, rule \A \ B\) @@ -977,23 +963,21 @@ note less_imp_le [simp] have [simp]: "\x i. l i \ x \ a < ereal x" by (rule order_less_le_trans, rule approx, force) - have [simp]: "\x i. x \ u i \ ereal x < b" + have lessb[simp]: "\x i. x \ u i \ ereal x < b" by (rule order_le_less_trans, subst ereal_less_eq(3), assumption, rule approx) - have [simp]: "\i. l i < b" - apply (rule order_less_trans) prefer 2 - by (rule approx, auto, rule approx) - have [simp]: "\i. a < u i" + have llb[simp]: "\i. l i < b" + using lessb approx(4) less_eq_real_def by blast + have alu[simp]: "\i. a < u i" by (rule order_less_trans, rule approx, auto, rule approx) have [simp]: "\i j. i \ j \ l j \ l i" by (rule decseqD, rule approx) - have [simp]: "\i j. i \ j \ u i \ u j" by (rule incseqD, rule approx) - have g_nondec [simp]: "\x y. a < x \ x \ y \ y < b \ g x \ g y" - apply (erule DERIV_nonneg_imp_nondecreasing, auto) - apply (rule exI, rule conjI, rule deriv_g) - apply (erule order_less_le_trans, auto) - apply (rule order_le_less_trans, subst ereal_less_eq(3), assumption, auto) - apply (rule g'_nonneg) - apply (rule less_imp_le, erule order_less_le_trans, auto) - by (rule less_imp_le, rule le_less_trans, subst ereal_less_eq(3), assumption, auto) + have uleu[simp]: "\i j. i \ j \ u i \ u j" by (rule incseqD, rule approx) + have g_nondec [simp]: "g x \ g y" if "a < x" "x \ y" "y < b" for x y + proof (rule DERIV_nonneg_imp_nondecreasing [OF \x \ y\], intro exI conjI allI impI) + show "\u. x \ u \ u \ y \ (g has_real_derivative g' u) (at u)" + by (meson deriv_g ereal_less_eq(3) le_less_trans less_le_trans that) + show "\u. x \ u \ u \ y \ 0 \ g' u" + by (meson g'_nonneg less_ereal.simps(1) less_trans not_less that) + qed have "A \ B" and un: "einterval A B = (\i. {g(l i)<..i. g (l i)) \ A" @@ -1006,10 +990,10 @@ by (drule_tac x = "\i. ereal (u i)" in spec, auto) hence B3: "\i. g (u i) \ B" by (intro incseq_le, auto simp add: incseq_def) - show "A \ B" - apply (rule order_trans [OF A3 [of 0]]) - apply (rule order_trans [OF _ B3 [of 0]]) + have "ereal (g (l 0)) \ ereal (g (u 0))" by auto + then show "A \ B" + by (meson A3 B3 order.trans) { fix x :: real assume "A < x" and "x < B" then have "eventually (\i. ereal (g (l i)) < x \ x < ereal (g (u i))) sequentially" @@ -1019,23 +1003,26 @@ by (simp add: eventually_sequentially, auto) } note AB = this show "einterval A B = (\i. {g(l i)<.. (\i. {g (l i)<..i. {g (l i)<.. einterval A B" + apply (clarsimp simp: einterval_def, intro conjI) + using A3 le_ereal_less apply blast + using B3 ereal_le_less by blast + qed qed - (* finally, the main argument *) - { - fix i - have "(LBINT x=l i.. u i. g' x *\<^sub>R f (g x)) = (LBINT y=g (l i)..g (u i). f y)" - apply (rule interval_integral_substitution_finite, auto) - apply (rule DERIV_subset, rule deriv_g, auto) - apply (rule continuous_at_imp_continuous_on, auto, rule contf, auto) - by (rule continuous_at_imp_continuous_on, auto, rule contg', auto) - then have "(LBINT x=l i.. u i. (f (g x) * g' x)) = (LBINT y=g (l i)..g (u i). f y)" - by (simp add: ac_simps) - } note eq1 = this + (* finally, the main argument *) + have eq1: "(LBINT x=l i.. u i. (f (g x) * g' x)) = (LBINT y=g (l i)..g (u i). f y)" for i + proof - + have "(LBINT x=l i.. u i. g' x *\<^sub>R f (g x)) = (LBINT y=g (l i)..g (u i). f y)" + apply (rule interval_integral_substitution_finite [OF _ DERIV_subset [OF deriv_g]]) + unfolding has_field_derivative_iff_has_vector_derivative[symmetric] + apply (auto intro!: continuous_at_imp_continuous_on contf contg') + done + then show ?thesis + by (simp add: ac_simps) + qed have "(\i. LBINT x=l i..u i. f (g x) * g' x) \ (LBINT x=a..b. f (g x) * g' x)" apply (rule interval_integral_Icc_approx_integrable [OF \a < b\ approx]) @@ -1043,15 +1030,16 @@ hence 2: "(\i. (LBINT y=g (l i)..g (u i). f y)) \ (LBINT x=a..b. f (g x) * g' x)" by (simp add: eq1) have incseq: "incseq (\i. {g (l i)<..x i. g (l i) \ x \ x \ g (u i) \ \c \ l i. c \ u i \ x = g c" - apply (frule (1) IVT' [of g], auto) - apply (rule continuous_at_imp_continuous_on, auto) - by (rule DERIV_isCont, rule deriv_g, auto) + apply (clarsimp simp add: incseq_def, intro conjI) + apply (meson llb antimono_def approx(3) approx(5) g_nondec le_less_trans) + using alu uleu approx(6) g_nondec less_le_trans by blast + have img: "\c \ l i. c \ u i \ x = g c" if "g (l i) \ x" "x \ g (u i)" for x i + proof - + have "continuous_on {l i..u i} g" + by (force intro!: DERIV_isCont deriv_g continuous_at_imp_continuous_on) + with that show ?thesis + using IVT' [of g] approx(4) dual_order.strict_implies_order by blast + qed have nonneg_f2: "\x i. g (l i) \ x \ x \ g (u i) \ 0 \ f x" by (frule (1) img, auto, rule f_nonneg, auto) have contf_2: "\x i. g (l i) \ x \ x \ g (u i) \ isCont f x" diff -r b25ccd85b1fd -r 4fa3e63ecc7e src/HOL/Library/Extended_Real.thy --- a/src/HOL/Library/Extended_Real.thy Fri May 04 22:26:25 2018 +0200 +++ b/src/HOL/Library/Extended_Real.thy Sun May 06 11:33:40 2018 +0100 @@ -627,6 +627,28 @@ "real_of_ereal y < x \ (\y\ \ \ \ y < ereal x) \ (\y\ = \ \ 0 < x)" by (cases y) auto +(*To help with inferences like a < ereal x \ x < y \ a < ereal y, + where x and y are real. +*) + +lemma le_ereal_le: "a \ ereal x \ x \ y \ a \ ereal y" + using ereal_less_eq(3) order.trans by blast + +lemma le_ereal_less: "a \ ereal x \ x < y \ a < ereal y" + by (simp add: le_less_trans) + +lemma less_ereal_le: "a < ereal x \ x \ y \ a < ereal y" + using ereal_less_ereal_Ex by auto + +lemma ereal_le_le: "ereal y \ a \ x \ y \ ereal x \ a" + by (simp add: order_subst2) + +lemma ereal_le_less: "ereal y \ a \ x < y \ ereal x < a" + by (simp add: dual_order.strict_trans1) + +lemma ereal_less_le: "ereal y < a \ x \ y \ ereal x < a" + using ereal_less_eq(3) le_less_trans by blast + lemma real_of_ereal_pos: fixes x :: ereal shows "0 \ x \ 0 \ real_of_ereal x" by (cases x) auto