# HG changeset patch # User eberlm # Date 1446461788 -3600 # Node ID ab2e862263e72484dd964bd873bb1bb741e6fda5 # Parent f2e51e704a962fbdb3f62b28a11c73eabc62d97f Rounding function, uniform limits, cotangent, binomial identities diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Archimedean_Field.thy --- a/src/HOL/Archimedean_Field.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Archimedean_Field.thy Mon Nov 02 11:56:28 2015 +0100 @@ -486,6 +486,11 @@ "- numeral v < ceiling x \ - numeral v < x" by (simp add: less_ceiling_iff) +lemma ceiling_altdef: "ceiling x = (if x = of_int (floor x) then floor x else floor x + 1)" + by (intro ceiling_unique, (simp, linarith?)+) + +lemma floor_le_ceiling [simp]: "floor x \ ceiling x" by (simp add: ceiling_altdef) + text \Addition and subtraction of integers\ lemma ceiling_add_of_int [simp]: "ceiling (x + of_int z) = ceiling x + z" @@ -592,4 +597,79 @@ apply (simp add: frac_def) by (meson frac_lt_1 less_iff_diff_less_0 not_le not_less_iff_gr_or_eq) + +subsection \Rounding to the nearest integer\ + +definition round where "round x = \x + 1/2\" + +lemma of_int_round_ge: "of_int (round x) \ x - 1/2" + and of_int_round_le: "of_int (round x) \ x + 1/2" + and of_int_round_abs_le: "\of_int (round x) - x\ \ 1/2" + and of_int_round_gt: "of_int (round x) > x - 1/2" +proof - + from floor_correct[of "x + 1/2"] have "x + 1/2 < of_int (round x) + 1" by (simp add: round_def) + from add_strict_right_mono[OF this, of "-1"] show A: "of_int (round x) > x - 1/2" by simp + thus "of_int (round x) \ x - 1/2" by simp + from floor_correct[of "x + 1/2"] show "of_int (round x) \ x + 1/2" by (simp add: round_def) + with A show "\of_int (round x) - x\ \ 1/2" by linarith +qed + +lemma round_of_int [simp]: "round (of_int n) = n" + unfolding round_def by (subst floor_unique_iff) force + +lemma round_0 [simp]: "round 0 = 0" + using round_of_int[of 0] by simp + +lemma round_1 [simp]: "round 1 = 1" + using round_of_int[of 1] by simp + +lemma round_numeral [simp]: "round (numeral n) = numeral n" + using round_of_int[of "numeral n"] by simp + +lemma round_neg_numeral [simp]: "round (-numeral n) = -numeral n" + using round_of_int[of "-numeral n"] by simp + +lemma round_of_nat [simp]: "round (of_nat n) = of_nat n" + using round_of_int[of "int n"] by simp + +lemma round_mono: "x \ y \ round x \ round y" + unfolding round_def by (intro floor_mono) simp + +lemma round_unique: "of_int y > x - 1/2 \ of_int y \ x + 1/2 \ round x = y" +unfolding round_def +proof (rule floor_unique) + assume "x - 1 / 2 < of_int y" + from add_strict_left_mono[OF this, of 1] show "x + 1 / 2 < of_int y + 1" by simp +qed + +lemma round_altdef: "round x = (if frac x \ 1/2 then ceiling x else floor x)" + by (cases "frac x \ 1/2") + (rule round_unique, ((simp add: frac_def field_simps ceiling_altdef, linarith?)+)[2])+ + +lemma floor_le_round: "\x\ \ round x" + unfolding round_def by (intro floor_mono) simp + +lemma ceiling_ge_round: "\x\ \ round x" unfolding round_altdef by simp + +lemma round_diff_minimal: + fixes z :: "'a :: floor_ceiling" + shows "abs (z - of_int (round z)) \ abs (z - of_int m)" +proof (cases "of_int m \ z") + case True + hence "\z - of_int (round z)\ \ \of_int (ceiling z) - z\" + unfolding round_altdef by (simp add: ceiling_altdef frac_def) linarith? + also have "of_int \z\ - z \ 0" by linarith + with True have "\of_int (ceiling z) - z\ \ \z - of_int m\" + by (simp add: ceiling_le_iff) + finally show ?thesis . +next + case False + hence "\z - of_int (round z)\ \ \of_int (floor z) - z\" + unfolding round_altdef by (simp add: ceiling_altdef frac_def) linarith? + also have "z - of_int \z\ \ 0" by linarith + with False have "\of_int (floor z) - z\ \ \z - of_int m\" + by (simp add: le_floor_iff) + finally show ?thesis . +qed + end diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Binomial.thy --- a/src/HOL/Binomial.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Binomial.thy Mon Nov 02 11:56:28 2015 +0100 @@ -38,6 +38,10 @@ lemma fact_mono_nat: "m \ n \ fact m \ (fact n :: nat)" by (induct n) (auto simp: le_Suc_eq) +lemma fact_in_Nats: "fact n \ \" by (induction n) auto + +lemma fact_in_Ints: "fact n \ \" by (induction n) auto + context assumes "SORT_CONSTRAINT('a::linordered_semidom)" begin @@ -381,6 +385,41 @@ lemma sum_choose_upper: "(\k=0..n. k choose m) = Suc n choose Suc m" by (induct n) auto +lemma choose_alternating_sum: + "n > 0 \ (\i\n. (-1)^i * of_nat (n choose i)) = (0 :: 'a :: comm_ring_1)" + using binomial_ring[of "-1 :: 'a" 1 n] by (simp add: atLeast0AtMost mult_of_nat_commute zero_power) + +lemma choose_even_sum: + assumes "n > 0" + shows "2 * (\i\n. if even i then of_nat (n choose i) else 0) = (2 ^ n :: 'a :: comm_ring_1)" +proof - + have "2 ^ n = (\i\n. of_nat (n choose i)) + (\i\n. (-1) ^ i * of_nat (n choose i) :: 'a)" + using choose_row_sum[of n] + by (simp add: choose_alternating_sum assms atLeast0AtMost of_nat_setsum[symmetric] of_nat_power) + also have "\ = (\i\n. of_nat (n choose i) + (-1) ^ i * of_nat (n choose i))" + by (simp add: setsum.distrib) + also have "\ = 2 * (\i\n. if even i then of_nat (n choose i) else 0)" + by (subst setsum_right_distrib, intro setsum.cong) simp_all + finally show ?thesis .. +qed + +lemma choose_odd_sum: + assumes "n > 0" + shows "2 * (\i\n. if odd i then of_nat (n choose i) else 0) = (2 ^ n :: 'a :: comm_ring_1)" +proof - + have "2 ^ n = (\i\n. of_nat (n choose i)) - (\i\n. (-1) ^ i * of_nat (n choose i) :: 'a)" + using choose_row_sum[of n] + by (simp add: choose_alternating_sum assms atLeast0AtMost of_nat_setsum[symmetric] of_nat_power) + also have "\ = (\i\n. of_nat (n choose i) - (-1) ^ i * of_nat (n choose i))" + by (simp add: setsum_subtractf) + also have "\ = 2 * (\i\n. if odd i then of_nat (n choose i) else 0)" + by (subst setsum_right_distrib, intro setsum.cong) simp_all + finally show ?thesis .. +qed + +lemma choose_row_sum': "(\k\n. (n choose k)) = 2 ^ n" + using choose_row_sum[of n] by (simp add: atLeast0AtMost) + lemma natsum_reverse_index: fixes m::nat shows "(\k. m \ k \ k \ n \ g k = f (m + n - k)) \ (\k=m..n. f k) = (\k=m..n. g k)" @@ -417,6 +456,12 @@ lemma pochhammer_Suc_setprod: "pochhammer a (Suc n) = setprod (\n. a + of_nat n) {0 .. n}" by (simp add: pochhammer_def) + +lemma pochhammer_of_nat: "pochhammer (of_nat x) n = of_nat (pochhammer x n)" + by (simp add: pochhammer_def of_nat_setprod) + +lemma pochhammer_of_int: "pochhammer (of_int x) n = of_int (pochhammer x n)" + by (simp add: pochhammer_def of_int_setprod) lemma setprod_nat_ivl_Suc: "setprod f {0 .. Suc n} = setprod f {0..n} * f (Suc n)" proof - @@ -460,6 +505,18 @@ done qed +lemma pochhammer_rec': "pochhammer z (Suc n) = (z + of_nat n) * pochhammer z n" +proof (induction n arbitrary: z) + case (Suc n z) + have "pochhammer z (Suc (Suc n)) = z * pochhammer (z + 1) (Suc n)" + by (simp add: pochhammer_rec) + also note Suc + also have "z * ((z + 1 + of_nat n) * pochhammer (z + 1) n) = + (z + of_nat (Suc n)) * pochhammer z (Suc n)" + by (simp_all add: pochhammer_rec algebra_simps) + finally show ?case . +qed simp_all + lemma pochhammer_fact: "fact n = pochhammer 1 n" unfolding fact_altdef apply (cases n) @@ -547,6 +604,32 @@ unfolding pochhammer_minus by (simp add: of_nat_diff pochhammer_fact) +lemma pochhammer_product': + "pochhammer z (n + m) = pochhammer z n * pochhammer (z + of_nat n) m" +proof (induction n arbitrary: z) + case (Suc n z) + have "pochhammer z (Suc n) * pochhammer (z + of_nat (Suc n)) m = + z * (pochhammer (z + 1) n * pochhammer (z + 1 + of_nat n) m)" + by (simp add: pochhammer_rec ac_simps) + also note Suc[symmetric] + also have "z * pochhammer (z + 1) (n + m) = pochhammer z (Suc (n + m))" + by (subst pochhammer_rec) simp + finally show ?case by simp +qed simp + +lemma pochhammer_product: + "m \ n \ pochhammer z n = pochhammer z m * pochhammer (z + of_nat m) (n - m)" + using pochhammer_product'[of z m "n - m"] by simp + +lemma pochhammer_absorb_comp: + "((r :: 'a :: comm_ring_1) - of_nat k) * pochhammer (- r) k = r * pochhammer (-r + 1) k" + (is "?lhs = ?rhs") +proof - + have "?lhs = -pochhammer (-r) (Suc k)" by (subst pochhammer_rec') (simp add: algebra_simps) + also have "\ = ?rhs" by (subst pochhammer_rec) simp + finally show ?thesis . +qed + subsection\Generalized binomial coefficients\ @@ -729,6 +812,89 @@ then show ?thesis using kn by simp qed +lemma choose_rising_sum: + "(\j\m. ((n + j) choose n)) = ((n + m + 1) choose (n + 1))" + "(\j\m. ((n + j) choose n)) = ((n + m + 1) choose m)" +proof - + show "(\j\m. ((n + j) choose n)) = ((n + m + 1) choose (n + 1))" by (induction m) simp_all + also have "... = ((n + m + 1) choose m)" by (subst binomial_symmetric) simp_all + finally show "(\j\m. ((n + j) choose n)) = ((n + m + 1) choose m)" . +qed + +lemma choose_linear_sum: + "(\i\n. i * (n choose i)) = n * 2 ^ (n - 1)" +proof (cases n) + case (Suc m) + have "(\i\n. i * (n choose i)) = (\i\Suc m. i * (Suc m choose i))" by (simp add: Suc) + also have "... = Suc m * 2 ^ m" + by (simp only: setsum_atMost_Suc_shift Suc_times_binomial setsum_right_distrib[symmetric]) + (simp add: choose_row_sum') + finally show ?thesis using Suc by simp +qed simp_all + +lemma choose_alternating_linear_sum: + assumes "n \ 1" + shows "(\i\n. (-1)^i * of_nat i * of_nat (n choose i) :: 'a :: comm_ring_1) = 0" +proof (cases n) + case (Suc m) + with assms have "m > 0" by simp + have "(\i\n. (-1) ^ i * of_nat i * of_nat (n choose i) :: 'a) = + (\i\Suc m. (-1) ^ i * of_nat i * of_nat (Suc m choose i))" by (simp add: Suc) + also have "... = (\i\m. (-1) ^ (Suc i) * of_nat (Suc i * (Suc m choose Suc i)))" + by (simp only: setsum_atMost_Suc_shift setsum_right_distrib[symmetric] of_nat_mult mult_ac) simp + also have "... = -of_nat (Suc m) * (\i\m. (-1) ^ i * of_nat ((m choose i)))" + by (subst setsum_right_distrib, rule setsum.cong[OF refl], subst Suc_times_binomial) + (simp add: algebra_simps of_nat_mult) + also have "(\i\m. (-1 :: 'a) ^ i * of_nat ((m choose i))) = 0" + using choose_alternating_sum[OF `m > 0`] by simp + finally show ?thesis by simp +qed simp + +lemma vandermonde: + "(\k\r. (m choose k) * (n choose (r - k))) = (m + n) choose r" +proof (induction n arbitrary: r) + case 0 + have "(\k\r. (m choose k) * (0 choose (r - k))) = (\k\r. if k = r then (m choose k) else 0)" + by (intro setsum.cong) simp_all + also have "... = m choose r" by (simp add: setsum.delta) + finally show ?case by simp +next + case (Suc n r) + show ?case by (cases r) (simp_all add: Suc [symmetric] algebra_simps setsum.distrib Suc_diff_le) +qed + +lemma choose_square_sum: + "(\k\n. (n choose k)^2) = ((2*n) choose n)" + using vandermonde[of n n n] by (simp add: power2_eq_square mult_2 binomial_symmetric [symmetric]) + +lemma pochhammer_binomial_sum: + fixes a b :: "'a :: comm_ring_1" + shows "pochhammer (a + b) n = (\k\n. of_nat (n choose k) * pochhammer a k * pochhammer b (n - k))" +proof (induction n arbitrary: a b) + case (Suc n a b) + have "(\k\Suc n. of_nat (Suc n choose k) * pochhammer a k * pochhammer b (Suc n - k)) = + (\i\n. of_nat (n choose i) * pochhammer a (Suc i) * pochhammer b (n - i)) + + ((\i\n. of_nat (n choose Suc i) * pochhammer a (Suc i) * pochhammer b (n - i)) + + pochhammer b (Suc n))" + by (subst setsum_atMost_Suc_shift) (simp add: ring_distribs setsum.distrib) + also have "(\i\n. of_nat (n choose i) * pochhammer a (Suc i) * pochhammer b (n - i)) = + a * pochhammer ((a + 1) + b) n" + by (subst Suc) (simp add: setsum_right_distrib pochhammer_rec mult_ac) + also have "(\i\n. of_nat (n choose Suc i) * pochhammer a (Suc i) * pochhammer b (n - i)) + pochhammer b (Suc n) = + (\i=0..Suc n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc n - i))" + by (subst setsum_head_Suc, simp, subst setsum_shift_bounds_cl_Suc_ivl) (simp add: atLeast0AtMost) + also have "... = (\i\n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc n - i))" + using Suc by (intro setsum.mono_neutral_right) (auto simp: not_le binomial_eq_0) + also have "... = (\i\n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc (n - i)))" + by (intro setsum.cong) (simp_all add: Suc_diff_le) + also have "... = b * pochhammer (a + (b + 1)) n" + by (subst Suc) (simp add: setsum_right_distrib mult_ac pochhammer_rec) + also have "a * pochhammer ((a + 1) + b) n + b * pochhammer (a + (b + 1)) n = + pochhammer (a + b) (Suc n)" by (simp add: pochhammer_rec algebra_simps) + finally show ?case .. +qed simp_all + + text\Contributed by Manuel Eberl, generalised by LCP. Alternative definition of the binomial coefficient as @{term "\i lemma gbinomial_altdef_of_nat: @@ -774,6 +940,285 @@ finally show ?thesis . qed +lemma gbinomial_negated_upper: "(a gchoose b) = (-1) ^ b * ((of_nat b - a - 1) gchoose b)" + by (simp add: gbinomial_pochhammer pochhammer_minus algebra_simps) + +lemma gbinomial_minus: "((-a) gchoose b) = (-1) ^ b * ((a + of_nat b - 1) gchoose b)" + by (subst gbinomial_negated_upper) (simp add: add_ac) + +lemma Suc_times_gbinomial: + "of_nat (Suc b) * ((a + 1) gchoose (Suc b)) = (a + 1) * (a gchoose b)" +proof (cases b) + case (Suc b) + hence "((a + 1) gchoose (Suc (Suc b))) = + (\i = 0..Suc b. a + (1 - of_nat i)) / fact (b + 2)" + by (simp add: field_simps gbinomial_def) + also have "(\i = 0..Suc b. a + (1 - of_nat i)) = (a + 1) * (\i = 0..b. a - of_nat i)" + by (simp add: setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) + also have "... / fact (b + 2) = (a + 1) / of_nat (Suc (Suc b)) * (a gchoose Suc b)" + by (simp_all add: gbinomial_def setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) + finally show ?thesis by (simp add: Suc field_simps del: of_nat_Suc) +qed simp + +lemma gbinomial_factors: + "((a + 1) gchoose (Suc b)) = (a + 1) / of_nat (Suc b) * (a gchoose b)" +proof (cases b) + case (Suc b) + hence "((a + 1) gchoose (Suc (Suc b))) = + (\i = 0..Suc b. a + (1 - of_nat i)) / fact (b + 2)" + by (simp add: field_simps gbinomial_def) + also have "(\i = 0..Suc b. a + (1 - of_nat i)) = (a + 1) * (\i = 0..b. a - of_nat i)" + by (simp add: setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) + also have "... / fact (b + 2) = (a + 1) / of_nat (Suc (Suc b)) * (a gchoose Suc b)" + by (simp_all add: gbinomial_def setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) + finally show ?thesis by (simp add: Suc) +qed simp + +lemma gbinomial_rec: "((r + 1) gchoose (Suc k)) = (r gchoose k) * ((r + 1) / of_nat (Suc k))" + using gbinomial_mult_1[of r k] + by (subst gbinomial_Suc_Suc) (simp add: field_simps del: of_nat_Suc, simp add: algebra_simps) + +lemma gbinomial_of_nat_symmetric: "k \ n \ (of_nat n) gchoose k = (of_nat n) gchoose (n - k)" + using binomial_symmetric[of k n] by (simp add: binomial_gbinomial [symmetric]) + + +text \The absorption identity (equation 5.5 \cite[p.~157]{GKP}):\[ +{r \choose k} = \frac{r}{k}{r - 1 \choose k - 1},\quad \textnormal{integer } k \neq 0. +\]\ +lemma gbinomial_absorption': + "k > 0 \ (r gchoose k) = (r / of_nat(k)) * (r - 1 gchoose (k - 1))" + using gbinomial_rec[of "r - 1" "k - 1"] + by (simp_all add: gbinomial_rec field_simps del: of_nat_Suc) + +text \The absorption identity is written in the following form to avoid +division by $k$ (the lower index) and therefore remove the $k \neq 0$ +restriction\cite[p.~157]{GKP}:\[ +k{r \choose k} = r{r - 1 \choose k - 1}, \quad \textnormal{integer } k. +\]\ +lemma gbinomial_absorption: + "of_nat (Suc k) * (r gchoose Suc k) = r * ((r - 1) gchoose k)" + using gbinomial_absorption'[of "Suc k" r] by (simp add: field_simps del: of_nat_Suc) + +text \The absorption identity for natural number binomial coefficients:\ +lemma binomial_absorption: + "Suc k * (n choose Suc k) = n * ((n - 1) choose k)" + by (cases n) (simp_all add: binomial_eq_0 Suc_times_binomial del: binomial_Suc_Suc mult_Suc) + +text \The absorption companion identity for natural number coefficients, +following the proof by GKP \cite[p.~157]{GKP}:\ +lemma binomial_absorb_comp: + "(n - k) * (n choose k) = n * ((n - 1) choose k)" (is "?lhs = ?rhs") +proof (cases "n \ k") + case False + then have "?rhs = Suc ((n - 1) - k) * (n choose Suc ((n - 1) - k))" + using binomial_symmetric[of k "n - 1"] binomial_absorption[of "(n - 1) - k" n] + by simp + also from False have "Suc ((n - 1) - k) = n - k" by simp + also from False have "n choose \ = n choose k" by (intro binomial_symmetric [symmetric]) simp_all + finally show ?thesis .. +qed auto + +text \The generalised absorption companion identity:\ +lemma gbinomial_absorb_comp: "(r - of_nat k) * (r gchoose k) = r * ((r - 1) gchoose k)" + using pochhammer_absorb_comp[of r k] by (simp add: gbinomial_pochhammer) + +lemma gbinomial_addition_formula: + "r gchoose (Suc k) = ((r - 1) gchoose (Suc k)) + ((r - 1) gchoose k)" + using gbinomial_Suc_Suc[of "r - 1" k] by (simp add: algebra_simps) + +lemma binomial_addition_formula: + "0 < n \ n choose (Suc k) = ((n - 1) choose (Suc k)) + ((n - 1) choose k)" + by (subst choose_reduce_nat) simp_all + + +text \ + Equation 5.9 of the reference material \cite[p.~159]{GKP} is a useful + summation formula, operating on both indices:\[ + \sum\limits_{k \leq n}{r + k \choose k} = {r + n + 1 \choose n}, + \quad \textnormal{integer } n. + \] +\ +lemma gbinomial_parallel_sum: +"(\k\n. (r + of_nat k) gchoose k) = (r + of_nat n + 1) gchoose n" +proof (induction n) + case (Suc m) + thus ?case using gbinomial_Suc_Suc[of "(r + of_nat m + 1)" m] by (simp add: add_ac) +qed auto + +subsection \Summation on the upper index\ +text \ + Another summation formula is equation 5.10 of the reference material \cite[p.~160]{GKP}, + aptly named \emph{summation on the upper index}:\[\sum_{0 \leq k \leq n} {k \choose m} = + {n + 1 \choose m + 1}, \quad \textnormal{integers } m, n \geq 0.\] +\ +lemma gbinomial_sum_up_index: + "(\k = 0..n. (of_nat k gchoose m) :: 'a :: field_char_0) = (of_nat n + 1) gchoose (m + 1)" +proof (induction n) + case 0 + show ?case using gbinomial_Suc_Suc[of 0 m] by (cases m) auto +next + case (Suc n) + thus ?case using gbinomial_Suc_Suc[of "of_nat (Suc n) :: 'a" m] by (simp add: add_ac) +qed + +lemma gbinomial_index_swap: + "((-1) ^ m) * ((- (of_nat n) - 1) gchoose m) = ((-1) ^ n) * ((- (of_nat m) - 1) gchoose n)" + (is "?lhs = ?rhs") +proof - + have "?lhs = (of_nat (m + n) gchoose m)" + by (subst gbinomial_negated_upper) (simp add: power_mult_distrib [symmetric]) + also have "\ = (of_nat (m + n) gchoose n)" by (subst gbinomial_of_nat_symmetric) simp_all + also have "\ = ?rhs" by (subst gbinomial_negated_upper) simp + finally show ?thesis . +qed + +lemma gbinomial_sum_lower_neg: + "(\k\m. (r gchoose k) * (- 1) ^ k) = (- 1) ^ m * (r - 1 gchoose m)" (is "?lhs = ?rhs") +proof - + have "?lhs = (\k\m. -(r + 1) + of_nat k gchoose k)" + by (intro setsum.cong[OF refl]) (subst gbinomial_negated_upper, simp add: power_mult_distrib) + also have "\ = -r + of_nat m gchoose m" by (subst gbinomial_parallel_sum) simp + also have "\ = ?rhs" by (subst gbinomial_negated_upper) (simp add: power_mult_distrib) + finally show ?thesis . +qed + +lemma gbinomial_partial_row_sum: +"(\k\m. (r gchoose k) * ((r / 2) - of_nat k)) = ((of_nat m + 1)/2) * (r gchoose (m + 1))" +proof (induction m) + case (Suc mm) + hence "(\k\Suc mm. (r gchoose k) * (r / 2 - of_nat k)) = + (r - of_nat (Suc mm)) * (r gchoose Suc mm) / 2" by (simp add: algebra_simps) + also have "\ = r * (r - 1 gchoose Suc mm) / 2" by (subst gbinomial_absorb_comp) (rule refl) + also have "\ = (of_nat (Suc mm) + 1) / 2 * (r gchoose (Suc mm + 1))" + by (subst gbinomial_absorption [symmetric]) simp + finally show ?case . +qed simp_all + +lemma setsum_bounds_lt_plus1: "(\kk=1..mm. f k)" + by (induction mm) simp_all + +lemma gbinomial_partial_sum_poly: + "(\k\m. (of_nat m + r gchoose k) * x^k * y^(m-k)) = + (\k\m. (-r gchoose k) * (-x)^k * (x + y)^(m-k))" (is "?lhs m = ?rhs m") +proof (induction m) + case (Suc mm) + def G \ "\i k. (of_nat i + r gchoose k) * x^k * y^(i-k)" and S \ ?lhs + have SG_def: "S = (\i. (\k\i. (G i k)))" unfolding S_def G_def .. + + have "S (Suc mm) = G (Suc mm) 0 + (\k=Suc 0..Suc mm. G (Suc mm) k)" + using SG_def by (simp add: setsum_head_Suc atLeast0AtMost [symmetric]) + also have "(\k=Suc 0..Suc mm. G (Suc mm) k) = (\k=0..mm. G (Suc mm) (Suc k))" + by (subst setsum_shift_bounds_cl_Suc_ivl) simp + also have "\ = (\k=0..mm. ((of_nat mm + r gchoose (Suc k)) + + (of_nat mm + r gchoose k)) * x^(Suc k) * y^(mm - k))" + unfolding G_def by (subst gbinomial_addition_formula) simp + also have "\ = (\k=0..mm. (of_nat mm + r gchoose (Suc k)) * x^(Suc k) * y^(mm - k)) + + (\k=0..mm. (of_nat mm + r gchoose k) * x^(Suc k) * y^(mm - k))" + by (subst setsum.distrib [symmetric]) (simp add: algebra_simps) + also have "(\k=0..mm. (of_nat mm + r gchoose (Suc k)) * x^(Suc k) * y^(mm - k)) = + (\k = (\kk=1..mm. (of_nat mm + r gchoose k) * x^k * y^(mm - k + 1))" + proof (subst setsum_bounds_lt_plus1 [symmetric], intro setsum.cong[OF refl], clarify) + fix k assume "k < mm" + hence "mm - k = mm - Suc k + 1" by linarith + thus "(of_nat mm + r gchoose Suc k) * x ^ Suc k * y ^ (mm - k) = + (of_nat mm + r gchoose Suc k) * x ^ Suc k * y ^ (mm - Suc k + 1)" by (simp only:) + qed + also have "\ + ?B = y * (\k=1..mm. (G mm k)) + (of_nat mm + r gchoose (Suc mm)) * x^(Suc mm)" + unfolding G_def by (subst setsum_right_distrib) (simp add: algebra_simps) + also have "(\k=0..mm. (of_nat mm + r gchoose k) * x^(Suc k) * y^(mm - k)) = x * (S mm)" + unfolding S_def by (subst setsum_right_distrib) (simp add: atLeast0AtMost algebra_simps) + also have "(G (Suc mm) 0) = y * (G mm 0)" by (simp add: G_def) + finally have "S (Suc mm) = y * ((G mm 0) + (\k=1..mm. (G mm k))) + + (of_nat mm + r gchoose (Suc mm)) * x^(Suc mm) + x * (S mm)" + by (simp add: ring_distribs) + also have "(G mm 0) + (\k=1..mm. (G mm k)) = S mm" + by (simp add: setsum_head_Suc[symmetric] SG_def atLeast0AtMost) + finally have "S (Suc mm) = (x + y) * (S mm) + (of_nat mm + r gchoose (Suc mm)) * x^(Suc mm)" + by (simp add: algebra_simps) + also have "(of_nat mm + r gchoose (Suc mm)) = (-1) ^ (Suc mm) * (-r gchoose (Suc mm))" + by (subst gbinomial_negated_upper) simp + also have "(-1) ^ Suc mm * (- r gchoose Suc mm) * x ^ Suc mm = + (-r gchoose (Suc mm)) * (-x) ^ Suc mm" by (simp add: power_minus[of x]) + also have "(x + y) * S mm + \ = (x + y) * ?rhs mm + (-r gchoose (Suc mm)) * (-x)^Suc mm" + unfolding S_def by (subst Suc.IH) simp + also have "(x + y) * ?rhs mm = (\n\mm. ((- r gchoose n) * (- x) ^ n * (x + y) ^ (Suc mm - n)))" + by (subst setsum_right_distrib, rule setsum.cong) (simp_all add: Suc_diff_le) + also have "\ + (-r gchoose (Suc mm)) * (-x)^Suc mm = + (\n\Suc mm. (- r gchoose n) * (- x) ^ n * (x + y) ^ (Suc mm - n))" by simp + finally show ?case unfolding S_def . +qed simp_all + +lemma gbinomial_partial_sum_poly_xpos: + "(\k\m. (of_nat m + r gchoose k) * x^k * y^(m-k)) = + (\k\m. (of_nat k + r - 1 gchoose k) * x^k * (x + y)^(m-k))" + apply (subst gbinomial_partial_sum_poly) + apply (subst gbinomial_negated_upper) + apply (intro setsum.cong, rule refl) + apply (simp add: power_mult_distrib [symmetric]) + done + +lemma setsum_nat_symmetry: + "(\k = 0..(m::nat). f k) = (\k = 0..m. f (m - k))" + by (rule setsum.reindex_bij_witness[where i="\i. m - i" and j="\i. m - i"]) auto + +lemma binomial_r_part_sum: "(\k\m. (2 * m + 1 choose k)) = 2 ^ (2 * m)" +proof - + have "2 * 2^(2*m) = (\k = 0..(2 * m + 1). (2 * m + 1 choose k))" + using choose_row_sum[where n="2 * m + 1"] by simp + also have "(\k = 0..(2 * m + 1). (2 * m + 1 choose k)) = (\k = 0..m. (2 * m + 1 choose k)) + + (\k = m+1..2*m+1. (2 * m + 1 choose k))" + using setsum_ub_add_nat[of 0 m "\k. 2 * m + 1 choose k" "m+1"] by (simp add: mult_2) + also have "(\k = m+1..2*m+1. (2 * m + 1 choose k)) = + (\k = 0..m. (2 * m + 1 choose (k + (m + 1))))" + by (subst setsum_shift_bounds_cl_nat_ivl [symmetric]) (simp add: mult_2) + also have "\ = (\k = 0..m. (2 * m + 1 choose (m - k)))" + by (intro setsum.cong[OF refl], subst binomial_symmetric) simp_all + also have "\ = (\k = 0..m. (2 * m + 1 choose k))" + by (subst (2) setsum_nat_symmetry) (rule refl) + also have "\ + \ = 2 * \" by simp + finally show ?thesis by (subst (asm) mult_cancel1) (simp add: atLeast0AtMost) +qed + +lemma gbinomial_r_part_sum: + "(\k\m. (2 * (of_nat m) + 1 gchoose k)) = 2 ^ (2 * m)" (is "?lhs = ?rhs") +proof - + have "?lhs = of_nat (\k\m. (2 * m + 1) choose k)" + by (simp add: binomial_gbinomial of_nat_mult add_ac of_nat_setsum) + also have "\ = of_nat (2 ^ (2 * m))" by (subst binomial_r_part_sum) (rule refl) + finally show ?thesis by (simp add: of_nat_power) +qed + +lemma gbinomial_sum_nat_pow2: + "(\k\m. (of_nat (m + k) gchoose k :: 'a :: field_char_0) / 2 ^ k) = 2 ^ m" (is "?lhs = ?rhs") +proof - + have "2 ^ m * 2 ^ m = (2 ^ (2*m) :: 'a)" by (induction m) simp_all + also have "\ = (\k\m. (2 * (of_nat m) + 1 gchoose k))" using gbinomial_r_part_sum .. + also have "\ = (\k\m. (of_nat (m + k) gchoose k) * 2 ^ (m - k))" + using gbinomial_partial_sum_poly_xpos[where x="1" and y="1" and r="of_nat m + 1" and m="m"] + by (simp add: add_ac) + also have "\ = 2 ^ m * (\k\m. (of_nat (m + k) gchoose k) / 2 ^ k)" + by (subst setsum_right_distrib) (simp add: algebra_simps power_diff) + finally show ?thesis by (subst (asm) mult_left_cancel) simp_all +qed + +lemma gbinomial_trinomial_revision: + assumes "k \ m" + shows "(r gchoose m) * (of_nat m gchoose k) = (r gchoose k) * (r - of_nat k gchoose (m - k))" +proof - + have "(r gchoose m) * (of_nat m gchoose k) = + (r gchoose m) * fact m / (fact k * fact (m - k))" + using assms by (simp add: binomial_gbinomial [symmetric] binomial_fact) + also have "\ = (r gchoose k) * (r - of_nat k gchoose (m - k))" using assms + by (simp add: gbinomial_pochhammer power_diff pochhammer_product) + finally show ?thesis . +qed + + text\Versions of the theorems above for the natural-number version of "choose"\ lemma binomial_altdef_of_nat: fixes n k :: nat diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Complex.thy --- a/src/HOL/Complex.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Complex.thy Mon Nov 02 11:56:28 2015 +0100 @@ -171,6 +171,17 @@ "z \ \ \ of_real (Re z) = z" by (auto simp: Reals_def) +lemma complex_Re_fact [simp]: "Re (fact n) = fact n" +proof - + have "(fact n :: complex) = of_real (fact n)" by simp + also have "Re \ = fact n" by (subst Re_complex_of_real) simp_all + finally show ?thesis . +qed + +lemma complex_Im_fact [simp]: "Im (fact n) = 0" + by (subst of_nat_fact [symmetric]) (simp only: complex_Im_of_nat) + + subsection \The Complex Number $i$\ primcorec "ii" :: complex ("\") where @@ -497,6 +508,12 @@ lemma complex_In_mult_cnj_zero [simp]: "Im (z * cnj z) = 0" by simp +lemma complex_cnj_fact [simp]: "cnj (fact n) = fact n" + by (subst of_nat_fact [symmetric], subst complex_cnj_of_nat) simp + +lemma complex_cnj_pochhammer [simp]: "cnj (pochhammer z n) = pochhammer (cnj z) n" + by (induction n arbitrary: z) (simp_all add: pochhammer_rec) + lemma bounded_linear_cnj: "bounded_linear cnj" using complex_cnj_add complex_cnj_scaleR by (rule bounded_linear_intro [where K=1], simp) diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Filter.thy --- a/src/HOL/Filter.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Filter.thy Mon Nov 02 11:56:28 2015 +0100 @@ -393,6 +393,11 @@ lemma eventually_happens: "eventually P net \ net = bot \ (\x. P x)" by (metis frequentlyE eventually_frequently) +lemma eventually_happens': + assumes "F \ bot" "eventually P F" + shows "\x. P x" + using assms eventually_frequently frequentlyE by blast + abbreviation (input) trivial_limit :: "'a filter \ bool" where "trivial_limit F \ F = bot" @@ -611,6 +616,15 @@ lemma eventually_gt_at_top: "eventually (\x. (c::_::{no_top, linorder}) < x) at_top" unfolding eventually_at_top_dense by auto +lemma eventually_all_ge_at_top: + assumes "eventually P (at_top :: ('a :: linorder) filter)" + shows "eventually (\x. \y\x. P y) at_top" +proof - + from assms obtain x where "\y. y \ x \ P y" by (auto simp: eventually_at_top_linorder) + hence "\z\y. P z" if "y \ x" for y using that by simp + thus ?thesis by (auto simp: eventually_at_top_linorder) +qed + definition at_bot :: "('a::order) filter" where "at_bot = (INF k. principal {.. k})" diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Int.thy --- a/src/HOL/Int.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Int.thy Mon Nov 02 11:56:28 2015 +0100 @@ -225,6 +225,9 @@ lemma of_int_mult [simp]: "of_int (w*z) = of_int w * of_int z" by (transfer fixing: times) (clarsimp simp add: algebra_simps of_nat_mult) +lemma mult_of_int_commute: "of_int x * y = y * of_int x" + by (transfer fixing: times) (auto simp: algebra_simps mult_of_nat_commute) + text\Collapse nested embeddings\ lemma of_int_of_nat_eq [simp]: "of_int (int n) = of_nat n" by (induct n) auto diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Library/Convex.thy --- a/src/HOL/Library/Convex.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Library/Convex.thy Mon Nov 02 11:56:28 2015 +0100 @@ -304,6 +304,42 @@ where "convex_on s f \ (\x\s. \y\s. \u\0. \v\0. u + v = 1 \ f (u *\<^sub>R x + v *\<^sub>R y) \ u * f x + v * f y)" +lemma convex_onI [intro?]: + assumes "\t x y. t > 0 \ t < 1 \ x \ A \ y \ A \ + f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \ (1 - t) * f x + t * f y" + shows "convex_on A f" + unfolding convex_on_def +proof clarify + fix x y u v assume A: "x \ A" "y \ A" "(u::real) \ 0" "v \ 0" "u + v = 1" + from A(5) have [simp]: "v = 1 - u" by (simp add: algebra_simps) + from A(1-4) show "f (u *\<^sub>R x + v *\<^sub>R y) \ u * f x + v * f y" using assms[of u y x] + by (cases "u = 0 \ u = 1") (auto simp: algebra_simps) +qed + +lemma convex_on_linorderI [intro?]: + fixes A :: "('a::{linorder,real_vector}) set" + assumes "\t x y. t > 0 \ t < 1 \ x \ A \ y \ A \ x < y \ + f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \ (1 - t) * f x + t * f y" + shows "convex_on A f" +proof + fix t x y assume A: "x \ A" "y \ A" "(t::real) > 0" "t < 1" + case (goal1 t x y) + with goal1 assms[of t x y] assms[of "1 - t" y x] + show ?case by (cases x y rule: linorder_cases) (auto simp: algebra_simps) +qed + +lemma convex_onD: + assumes "convex_on A f" + shows "\t x y. t \ 0 \ t \ 1 \ x \ A \ y \ A \ + f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \ (1 - t) * f x + t * f y" + using assms unfolding convex_on_def by auto + +lemma convex_onD_Icc: + assumes "convex_on {x..y} f" "x \ (y :: _ :: {real_vector,preorder})" + shows "\t. t \ 0 \ t \ 1 \ + f ((1 - t) *\<^sub>R x + t *\<^sub>R y) \ (1 - t) * f x + t * f y" + using assms(2) by (intro convex_onD[OF assms(1)]) simp_all + lemma convex_on_subset: "convex_on t f \ s \ t \ convex_on s f" unfolding convex_on_def by auto @@ -835,4 +871,91 @@ show ?thesis by auto qed + +subsection \Convexity of real functions\ + +lemma convex_on_realI: + assumes "connected A" + assumes "\x. x \ A \ (f has_real_derivative f' x) (at x)" + assumes "\x y. x \ A \ y \ A \ x \ y \ f' x \ f' y" + shows "convex_on A f" +proof (rule convex_on_linorderI) + fix t x y :: real + assume t: "t > 0" "t < 1" and xy: "x \ A" "y \ A" "x < y" + def z \ "(1 - t) * x + t * y" + with `connected A` and xy have ivl: "{x..y} \ A" using connected_contains_Icc by blast + + from xy t have xz: "z > x" by (simp add: z_def algebra_simps) + have "y - z = (1 - t) * (y - x)" by (simp add: z_def algebra_simps) + also from xy t have "... > 0" by (intro mult_pos_pos) simp_all + finally have yz: "z < y" by simp + + from assms xz yz ivl t have "\\. \ > x \ \ < z \ f z - f x = (z - x) * f' \" + by (intro MVT2) (auto intro!: assms(2)) + then obtain \ where \: "\ > x" "\ < z" "f' \ = (f z - f x) / (z - x)" by auto + from assms xz yz ivl t have "\\. \ > z \ \ < y \ f y - f z = (y - z) * f' \" + by (intro MVT2) (auto intro!: assms(2)) + then obtain \ where \: "\ > z" "\ < y" "f' \ = (f y - f z) / (y - z)" by auto + + from \(3) have "(f y - f z) / (y - z) = f' \" .. + also from \ \ ivl have "\ \ A" "\ \ A" by auto + with \ \ have "f' \ \ f' \" by (intro assms(3)) auto + also from \(3) have "f' \ = (f z - f x) / (z - x)" . + finally have "(f y - f z) * (z - x) \ (f z - f x) * (y - z)" + using xz yz by (simp add: field_simps) + also have "z - x = t * (y - x)" by (simp add: z_def algebra_simps) + also have "y - z = (1 - t) * (y - x)" by (simp add: z_def algebra_simps) + finally have "(f y - f z) * t \ (f z - f x) * (1 - t)" using xy by simp + thus "(1 - t) * f x + t * f y \ f ((1 - t) *\<^sub>R x + t *\<^sub>R y)" + by (simp add: z_def algebra_simps) +qed + +lemma convex_on_inverse: + assumes "A \ {0<..}" + shows "convex_on A (inverse :: real \ real)" +proof (rule convex_on_subset[OF _ assms], intro convex_on_realI[of _ _ "\x. -inverse (x^2)"]) + fix u v :: real assume "u \ {0<..}" "v \ {0<..}" "u \ v" + with assms show "-inverse (u^2) \ -inverse (v^2)" + by (intro le_imp_neg_le le_imp_inverse_le power_mono) (simp_all) +qed (insert assms, auto intro!: derivative_eq_intros simp: divide_simps power2_eq_square) + +lemma convex_onD_Icc': + assumes "convex_on {x..y} f" "c \ {x..y}" + defines "d \ y - x" + shows "f c \ (f y - f x) / d * (c - x) + f x" +proof (cases y x rule: linorder_cases) + assume less: "x < y" + hence d: "d > 0" by (simp add: d_def) + from assms(2) less have A: "0 \ (c - x) / d" "(c - x) / d \ 1" + by (simp_all add: d_def divide_simps) + have "f c = f (x + (c - x) * 1)" by simp + also from less have "1 = ((y - x) / d)" by (simp add: d_def) + also from d have "x + (c - x) * \ = (1 - (c - x) / d) *\<^sub>R x + ((c - x) / d) *\<^sub>R y" + by (simp add: field_simps) + also have "f \ \ (1 - (c - x) / d) * f x + (c - x) / d * f y" using assms less + by (intro convex_onD_Icc) simp_all + also from d have "\ = (f y - f x) / d * (c - x) + f x" by (simp add: field_simps) + finally show ?thesis . +qed (insert assms(2), simp_all) + +lemma convex_onD_Icc'': + assumes "convex_on {x..y} f" "c \ {x..y}" + defines "d \ y - x" + shows "f c \ (f x - f y) / d * (y - c) + f y" +proof (cases y x rule: linorder_cases) + assume less: "x < y" + hence d: "d > 0" by (simp add: d_def) + from assms(2) less have A: "0 \ (y - c) / d" "(y - c) / d \ 1" + by (simp_all add: d_def divide_simps) + have "f c = f (y - (y - c) * 1)" by simp + also from less have "1 = ((y - x) / d)" by (simp add: d_def) + also from d have "y - (y - c) * \ = (1 - (1 - (y - c) / d)) *\<^sub>R x + (1 - (y - c) / d) *\<^sub>R y" + by (simp add: field_simps) + also have "f \ \ (1 - (1 - (y - c) / d)) * f x + (1 - (y - c) / d) * f y" using assms less + by (intro convex_onD_Icc) (simp_all add: field_simps) + also from d have "\ = (f x - f y) / d * (y - c) + f y" by (simp add: field_simps) + finally show ?thesis . +qed (insert assms(2), simp_all) + + end diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Limits.thy --- a/src/HOL/Limits.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Limits.thy Mon Nov 02 11:56:28 2015 +0100 @@ -137,12 +137,34 @@ by (auto elim!: allE[of _ n]) qed +lemma Bseq_bdd_above': + "Bseq (X::nat \ 'a :: real_normed_vector) \ bdd_above (range (\n. norm (X n)))" +proof (elim BseqE, intro bdd_aboveI2) + fix K n assume "0 < K" "\n. norm (X n) \ K" then show "norm (X n) \ K" + by (auto elim!: allE[of _ n]) +qed + lemma Bseq_bdd_below: "Bseq (X::nat \ real) \ bdd_below (range X)" proof (elim BseqE, intro bdd_belowI2) fix K n assume "0 < K" "\n. norm (X n) \ K" then show "- K \ X n" by (auto elim!: allE[of _ n]) qed +lemma Bseq_eventually_mono: + assumes "eventually (\n. norm (f n) \ norm (g n)) sequentially" "Bseq g" + shows "Bseq f" +proof - + from assms(1) obtain N where N: "\n. n \ N \ norm (f n) \ norm (g n)" + by (auto simp: eventually_at_top_linorder) + moreover from assms(2) obtain K where K: "\n. norm (g n) \ K" by (blast elim!: BseqE) + ultimately have "norm (f n) \ max K (Max {norm (f n) |n. n < N})" for n + apply (cases "n < N") + apply (rule max.coboundedI2, rule Max.coboundedI, auto) [] + apply (rule max.coboundedI1, force intro: order.trans[OF N K]) + done + thus ?thesis by (blast intro: BseqI') +qed + lemma lemma_NBseq_def: "(\K > 0. \n. norm (X n) \ K) = (\N. \n. norm (X n) \ real(Suc N))" proof safe @@ -218,6 +240,73 @@ lemma Bseq_minus_iff: "Bseq (%n. -(X n) :: 'a :: real_normed_vector) = Bseq X" by (simp add: Bseq_def) +lemma Bseq_add: + assumes "Bseq (f :: nat \ 'a :: real_normed_vector)" + shows "Bseq (\x. f x + c)" +proof - + from assms obtain K where K: "\x. norm (f x) \ K" unfolding Bseq_def by blast + { + fix x :: nat + have "norm (f x + c) \ norm (f x) + norm c" by (rule norm_triangle_ineq) + also have "norm (f x) \ K" by (rule K) + finally have "norm (f x + c) \ K + norm c" by simp + } + thus ?thesis by (rule BseqI') +qed + +lemma Bseq_add_iff: "Bseq (\x. f x + c) \ Bseq (f :: nat \ 'a :: real_normed_vector)" + using Bseq_add[of f c] Bseq_add[of "\x. f x + c" "-c"] by auto + +lemma Bseq_mult: + assumes "Bseq (f :: nat \ 'a :: real_normed_field)" + assumes "Bseq (g :: nat \ 'a :: real_normed_field)" + shows "Bseq (\x. f x * g x)" +proof - + from assms obtain K1 K2 where K: "\x. norm (f x) \ K1" "K1 > 0" "\x. norm (g x) \ K2" "K2 > 0" + unfolding Bseq_def by blast + hence "\x. norm (f x * g x) \ K1 * K2" by (auto simp: norm_mult intro!: mult_mono) + thus ?thesis by (rule BseqI') +qed + +lemma Bfun_const [simp]: "Bfun (\_. c) F" + unfolding Bfun_metric_def by (auto intro!: exI[of _ c] exI[of _ "1::real"]) + +lemma Bseq_cmult_iff: "(c :: 'a :: real_normed_field) \ 0 \ Bseq (\x. c * f x) \ Bseq f" +proof + assume "c \ 0" "Bseq (\x. c * f x)" + find_theorems "Bfun (\_. ?c) _" + from Bfun_const this(2) have "Bseq (\x. inverse c * (c * f x))" by (rule Bseq_mult) + with `c \ 0` show "Bseq f" by (simp add: divide_simps) +qed (intro Bseq_mult Bfun_const) + +lemma Bseq_subseq: "Bseq (f :: nat \ 'a :: real_normed_vector) \ Bseq (\x. f (g x))" + unfolding Bseq_def by auto + +lemma Bseq_Suc_iff: "Bseq (\n. f (Suc n)) \ Bseq (f :: nat \ 'a :: real_normed_vector)" + using Bseq_offset[of f 1] by (auto intro: Bseq_subseq) + +lemma increasing_Bseq_subseq_iff: + assumes "\x y. x \ y \ norm (f x :: 'a :: real_normed_vector) \ norm (f y)" "subseq g" + shows "Bseq (\x. f (g x)) \ Bseq f" +proof + assume "Bseq (\x. f (g x))" + then obtain K where K: "\x. norm (f (g x)) \ K" unfolding Bseq_def by auto + { + fix x :: nat + from filterlim_subseq[OF assms(2)] obtain y where "g y \ x" + by (auto simp: filterlim_at_top eventually_at_top_linorder) + hence "norm (f x) \ norm (f (g y))" using assms(1) by blast + also have "norm (f (g y)) \ K" by (rule K) + finally have "norm (f x) \ K" . + } + thus "Bseq f" by (rule BseqI') +qed (insert Bseq_subseq[of f g], simp_all) + +lemma nonneg_incseq_Bseq_subseq_iff: + assumes "\x. f x \ 0" "incseq (f :: nat \ real)" "subseq g" + shows "Bseq (\x. f (g x)) \ Bseq f" + using assms by (intro increasing_Bseq_subseq_iff) (auto simp: incseq_def) + lemma Bseq_eq_bounded: "range f \ {a .. b::real} \ Bseq f" apply (simp add: subset_eq) apply (rule BseqI'[where K="max (norm a) (norm b)"]) @@ -679,6 +768,16 @@ shows "(\i. i \ S \ continuous_on s (f i)) \ continuous_on s (\x. \i\S. f i x)" unfolding continuous_on_def by (auto intro: tendsto_setprod) +lemma tendsto_of_real_iff: + "((\x. of_real (f x) :: 'a :: real_normed_div_algebra) ---> of_real c) F \ (f ---> c) F" + unfolding tendsto_iff by simp + +lemma tendsto_add_const_iff: + "((\x. c + f x :: 'a :: real_normed_vector) ---> c + d) F \ (f ---> d) F" + using tendsto_add[OF tendsto_const[of c], of f d] + tendsto_add[OF tendsto_const[of "-c"], of "\x. c + f x" "c + d"] by auto + + subsubsection \Inverse and division\ lemma (in bounded_bilinear) Zfun_prod_Bfun: @@ -892,6 +991,55 @@ qed qed force +lemma not_tendsto_and_filterlim_at_infinity: + assumes "F \ bot" + assumes "(f ---> (c :: 'a :: real_normed_vector)) F" + assumes "filterlim f at_infinity F" + shows False +proof - + from tendstoD[OF assms(2), of "1/2"] + have "eventually (\x. dist (f x) c < 1/2) F" by simp + moreover from filterlim_at_infinity[of "norm c" f F] assms(3) + have "eventually (\x. norm (f x) \ norm c + 1) F" by simp + ultimately have "eventually (\x. False) F" + proof eventually_elim + fix x assume A: "dist (f x) c < 1/2" and B: "norm (f x) \ norm c + 1" + note B + also have "norm (f x) = dist (f x) 0" by (simp add: norm_conv_dist) + also have "... \ dist (f x) c + dist c 0" by (rule dist_triangle) + also note A + finally show False by (simp add: norm_conv_dist) + qed + with assms show False by simp +qed + +lemma filterlim_at_infinity_imp_not_convergent: + assumes "filterlim f at_infinity sequentially" + shows "\convergent f" + by (rule notI, rule not_tendsto_and_filterlim_at_infinity[OF _ _ assms]) + (simp_all add: convergent_LIMSEQ_iff) + +lemma filterlim_at_infinity_imp_eventually_ne: + assumes "filterlim f at_infinity F" + shows "eventually (\z. f z \ c) F" +proof - + have "norm c + 1 > 0" by (intro add_nonneg_pos) simp_all + with filterlim_at_infinity[OF order.refl, of f F] assms + have "eventually (\z. norm (f z) \ norm c + 1) F" by blast + thus ?thesis by eventually_elim auto +qed + +lemma tendsto_of_nat [tendsto_intros]: + "filterlim (of_nat :: nat \ 'a :: real_normed_algebra_1) at_infinity sequentially" +proof (subst filterlim_at_infinity[OF order.refl], intro allI impI) + fix r :: real assume r: "r > 0" + def n \ "nat \r\" + from r have n: "\m\n. of_nat m \ r" unfolding n_def by linarith + from eventually_ge_at_top[of n] show "eventually (\m. norm (of_nat m :: 'a) \ r) sequentially" + by eventually_elim (insert n, simp_all) +qed + + subsection \Relate @{const at}, @{const at_left} and @{const at_right}\ text \ @@ -1075,9 +1223,27 @@ by (auto intro: order_trans simp: filterlim_def filtermap_filtermap) qed +lemma tendsto_mult_filterlim_at_infinity: + assumes "F \ bot" "(f ---> (c :: 'a :: real_normed_field)) F" "c \ 0" + assumes "filterlim g at_infinity F" + shows "filterlim (\x. f x * g x) at_infinity F" +proof - + have "((\x. inverse (f x) * inverse (g x)) ---> inverse c * 0) F" + by (intro tendsto_mult tendsto_inverse assms filterlim_compose[OF tendsto_inverse_0]) + hence "filterlim (\x. inverse (f x) * inverse (g x)) (at (inverse c * 0)) F" + unfolding filterlim_at using assms + by (auto intro: filterlim_at_infinity_imp_eventually_ne tendsto_imp_eventually_ne eventually_conj) + thus ?thesis by (subst filterlim_inverse_at_iff[symmetric]) simp_all +qed + lemma tendsto_inverse_0_at_top: "LIM x F. f x :> at_top \ ((\x. inverse (f x) :: real) ---> 0) F" by (metis filterlim_at filterlim_mono[OF _ at_top_le_at_infinity order_refl] filterlim_inverse_at_iff) +lemma mult_nat_left_at_top: "c > 0 \ filterlim (\x. c * x :: nat) at_top sequentially" + by (rule filterlim_subseq) (auto simp: subseq_def) + +lemma mult_nat_right_at_top: "c > 0 \ filterlim (\x. x * c :: nat) at_top sequentially" + by (rule filterlim_subseq) (auto simp: subseq_def) lemma at_to_infinity: fixes x :: "'a :: {real_normed_field,field}" @@ -1471,6 +1637,23 @@ subsection \Convergence on sequences\ +lemma convergent_cong: + assumes "eventually (\x. f x = g x) sequentially" + shows "convergent f \ convergent g" + unfolding convergent_def by (subst filterlim_cong[OF refl refl assms]) (rule refl) + +lemma convergent_Suc_iff: "convergent (\n. f (Suc n)) \ convergent f" + by (auto simp: convergent_def LIMSEQ_Suc_iff) + +lemma convergent_ignore_initial_segment: "convergent (\n. f (n + m)) = convergent f" +proof (induction m arbitrary: f) + case (Suc m) + have "convergent (\n. f (n + Suc m)) \ convergent (\n. f (Suc n + m))" by simp + also have "\ \ convergent (\n. f (n + m))" by (rule convergent_Suc_iff) + also have "\ \ convergent f" by (rule Suc) + finally show ?case . +qed simp_all + lemma convergent_add: fixes X Y :: "nat \ 'a::real_normed_vector" assumes "convergent (\n. X n)" @@ -1505,6 +1688,71 @@ apply (drule tendsto_minus, auto) done +lemma convergent_diff: + fixes X Y :: "nat \ 'a::real_normed_vector" + assumes "convergent (\n. X n)" + assumes "convergent (\n. Y n)" + shows "convergent (\n. X n - Y n)" + using assms unfolding convergent_def by (fast intro: tendsto_diff) + +lemma convergent_norm: + assumes "convergent f" + shows "convergent (\n. norm (f n))" +proof - + from assms have "f ----> lim f" by (simp add: convergent_LIMSEQ_iff) + hence "(\n. norm (f n)) ----> norm (lim f)" by (rule tendsto_norm) + thus ?thesis by (auto simp: convergent_def) +qed + +lemma convergent_of_real: + "convergent f \ convergent (\n. of_real (f n) :: 'a :: real_normed_algebra_1)" + unfolding convergent_def by (blast intro!: tendsto_of_real) + +lemma convergent_add_const_iff: + "convergent (\n. c + f n :: 'a :: real_normed_vector) \ convergent f" +proof + assume "convergent (\n. c + f n)" + from convergent_diff[OF this convergent_const[of c]] show "convergent f" by simp +next + assume "convergent f" + from convergent_add[OF convergent_const[of c] this] show "convergent (\n. c + f n)" by simp +qed + +lemma convergent_add_const_right_iff: + "convergent (\n. f n + c :: 'a :: real_normed_vector) \ convergent f" + using convergent_add_const_iff[of c f] by (simp add: add_ac) + +lemma convergent_diff_const_right_iff: + "convergent (\n. f n - c :: 'a :: real_normed_vector) \ convergent f" + using convergent_add_const_right_iff[of f "-c"] by (simp add: add_ac) + +lemma convergent_mult: + fixes X Y :: "nat \ 'a::real_normed_field" + assumes "convergent (\n. X n)" + assumes "convergent (\n. Y n)" + shows "convergent (\n. X n * Y n)" + using assms unfolding convergent_def by (fast intro: tendsto_mult) + +lemma convergent_mult_const_iff: + assumes "c \ 0" + shows "convergent (\n. c * f n :: 'a :: real_normed_field) \ convergent f" +proof + assume "convergent (\n. c * f n)" + from assms convergent_mult[OF this convergent_const[of "inverse c"]] + show "convergent f" by (simp add: field_simps) +next + assume "convergent f" + from convergent_mult[OF convergent_const[of c] this] show "convergent (\n. c * f n)" by simp +qed + +lemma convergent_mult_const_right_iff: + assumes "c \ 0" + shows "convergent (\n. (f n :: 'a :: real_normed_field) * c) \ convergent f" + using convergent_mult_const_iff[OF assms, of f] by (simp add: mult_ac) + +lemma convergent_imp_Bseq: "convergent f \ Bseq f" + by (simp add: Cauchy_Bseq convergent_Cauchy) + text \A monotone sequence converges to its least upper bound.\ @@ -1532,6 +1780,19 @@ lemma Bseq_mono_convergent: "Bseq X \ (\m n. m \ n \ X m \ X n) \ convergent (X::nat\real)" by (auto intro!: Bseq_monoseq_convergent incseq_imp_monoseq simp: incseq_def) +lemma monoseq_imp_convergent_iff_Bseq: "monoseq (f :: nat \ real) \ convergent f \ Bseq f" + using Bseq_monoseq_convergent[of f] convergent_imp_Bseq[of f] by blast + +lemma Bseq_monoseq_convergent'_inc: + "Bseq (\n. f (n + M) :: real) \ (\m n. M \ m \ m \ n \ f m \ f n) \ convergent f" + by (subst convergent_ignore_initial_segment [symmetric, of _ M]) + (auto intro!: Bseq_monoseq_convergent simp: monoseq_def) + +lemma Bseq_monoseq_convergent'_dec: + "Bseq (\n. f (n + M) :: real) \ (\m n. M \ m \ m \ n \ f m \ f n) \ convergent f" + by (subst convergent_ignore_initial_segment [symmetric, of _ M]) + (auto intro!: Bseq_monoseq_convergent simp: monoseq_def) + lemma Cauchy_iff: fixes X :: "nat \ 'a::real_normed_vector" shows "Cauchy X \ (\e>0. \M. \m\M. \n\M. norm (X m - X n) < e)" diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Multivariate_Analysis/Complex_Analysis_Basics.thy --- a/src/HOL/Multivariate_Analysis/Complex_Analysis_Basics.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Complex_Analysis_Basics.thy Mon Nov 02 11:56:28 2015 +0100 @@ -819,6 +819,7 @@ subsection\Complex differentiation of sequences and series\ +(* TODO: Could probably be simplified using Uniform_Limit *) lemma has_complex_derivative_sequence: fixes s :: "complex set" assumes cvs: "convex s" @@ -899,6 +900,41 @@ qed qed + +lemma complex_differentiable_series: + fixes f :: "nat \ complex \ complex" + assumes "convex s" "open s" + assumes "\n x. x \ s \ (f n has_field_derivative f' n x) (at x)" + assumes "uniformly_convergent_on s (\n x. \i s" "summable (\n. f n x0)" and x: "x \ s" + shows "summable (\n. f n x)" and "(\x. \n. f n x) complex_differentiable (at x)" +proof - + from assms(4) obtain g' where A: "uniform_limit s (\n x. \ig. \x\s. (\n. f n x) sums g x \ (g has_field_derivative g' x) (at x within s)" + by (intro has_field_derivative_series[of s f f' g' x0] assms A has_field_derivative_at_within) + then obtain g where g: "\x. x \ s \ (\n. f n x) sums g x" + "\x. x \ s \ (g has_field_derivative g' x) (at x within s)" by blast + from g[OF x] show "summable (\n. f n x)" by (auto simp: summable_def) + from g(2)[OF x] have g': "(g has_derivative op * (g' x)) (at x)" + by (simp add: has_field_derivative_def s) + have "((\x. \n. f n x) has_derivative op * (g' x)) (at x)" + by (rule has_derivative_transform_within_open[OF `open s` x _ g']) + (insert g, auto simp: sums_iff) + thus "(\x. \n. f n x) complex_differentiable (at x)" unfolding differentiable_def + by (auto simp: summable_def complex_differentiable_def has_field_derivative_def) +qed + +lemma complex_differentiable_series': + fixes f :: "nat \ complex \ complex" + assumes "convex s" "open s" + assumes "\n x. x \ s \ (f n has_field_derivative f' n x) (at x)" + assumes "uniformly_convergent_on s (\n x. \i s" "summable (\n. f n x0)" + shows "(\x. \n. f n x) complex_differentiable (at x0)" + using complex_differentiable_series[OF assms, of x0] `x0 \ s` by blast+ + subsection\Bound theorem\ lemma complex_differentiable_bound: diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Multivariate_Analysis/Convex_Euclidean_Space.thy --- a/src/HOL/Multivariate_Analysis/Convex_Euclidean_Space.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Convex_Euclidean_Space.thy Mon Nov 02 11:56:28 2015 +0100 @@ -1788,14 +1788,6 @@ subsubsection \Another formulation from Lars Schewe\ -lemma setsum_constant_scaleR: - fixes y :: "'a::real_vector" - shows "(\x\A. y) = of_nat (card A) *\<^sub>R y" - apply (cases "finite A") - apply (induct set: finite) - apply (simp_all add: algebra_simps) - done - lemma convex_hull_explicit: fixes p :: "'a::real_vector set" shows "convex hull p = diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Multivariate_Analysis/Derivative.thy --- a/src/HOL/Multivariate_Analysis/Derivative.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Derivative.thy Mon Nov 02 11:56:28 2015 +0100 @@ -6,7 +6,7 @@ section \Multivariate calculus in Euclidean space\ theory Derivative -imports Brouwer_Fixpoint Operator_Norm +imports Brouwer_Fixpoint Operator_Norm "~~/src/HOL/Multivariate_Analysis/Uniform_Limit" begin lemma netlimit_at_vector: (* TODO: move *) @@ -2202,6 +2202,92 @@ apply auto done +lemma has_field_derivative_series: + fixes f :: "nat \ ('a :: {real_normed_field,banach}) \ 'a" + assumes "convex s" + assumes "\n x. x \ s \ (f n has_field_derivative f' n x) (at x within s)" + assumes "uniform_limit s (\n x. \i s" "summable (\n. f n x0)" + shows "\g. \x\s. (\n. f n x) sums g x \ (g has_field_derivative g' x) (at x within s)" +unfolding has_field_derivative_def +proof (rule has_derivative_series) + show "\e>0. \N. \n\N. \x\s. \h. norm ((\i e * norm h" + proof (intro allI impI) + fix e :: real assume "e > 0" + with assms(3) obtain N where N: "\n x. n \ N \ x \ s \ norm ((\i N" "x \ s" + have "norm ((\iii e" by simp + hence "norm ((\i e * norm h" + by (intro mult_right_mono) simp_all + finally have "norm ((\i e * norm h" . + } + thus "\N. \n\N. \x\s. \h. norm ((\i e * norm h" by blast + qed +qed (insert assms, auto simp: has_field_derivative_def) + +lemma has_field_derivative_series': + fixes f :: "nat \ ('a :: {real_normed_field,banach}) \ 'a" + assumes "convex s" + assumes "\n x. x \ s \ (f n has_field_derivative f' n x) (at x within s)" + assumes "uniformly_convergent_on s (\n x. \i s" "summable (\n. f n x0)" "x \ interior s" + shows "summable (\n. f n x)" "((\x. \n. f n x) has_field_derivative (\n. f' n x)) (at x)" +proof - + from \x \ interior s\ have "x \ s" using interior_subset by blast + def g' \ "\x. \i. f' i x" + from assms(3) have "uniform_limit s (\n x. \ix. x \ s \ (\n. f n x) sums g x" + "\x. x \ s \ (g has_field_derivative g' x) (at x within s)" by blast + from g(1)[OF \x \ s\] show "summable (\n. f n x)" by (simp add: sums_iff) + from g(2)[OF \x \ s\] \x \ interior s\ have "(g has_field_derivative g' x) (at x)" + by (simp add: at_within_interior[of x s]) + also have "(g has_field_derivative g' x) (at x) \ + ((\x. \n. f n x) has_field_derivative g' x) (at x)" + using eventually_nhds_in_nhd[OF \x \ interior s\] interior_subset[of s] g(1) + by (intro DERIV_cong_ev) (auto elim!: eventually_elim1 simp: sums_iff) + finally show "((\x. \n. f n x) has_field_derivative g' x) (at x)" . +qed + +lemma differentiable_series: + fixes f :: "nat \ ('a :: {real_normed_field,banach}) \ 'a" + assumes "convex s" "open s" + assumes "\n x. x \ s \ (f n has_field_derivative f' n x) (at x)" + assumes "uniformly_convergent_on s (\n x. \i s" "summable (\n. f n x0)" and x: "x \ s" + shows "summable (\n. f n x)" and "(\x. \n. f n x) differentiable (at x)" +proof - + from assms(4) obtain g' where A: "uniform_limit s (\n x. \ig. \x\s. (\n. f n x) sums g x \ (g has_field_derivative g' x) (at x within s)" + by (intro has_field_derivative_series[of s f f' g' x0] assms A has_field_derivative_at_within) + then obtain g where g: "\x. x \ s \ (\n. f n x) sums g x" + "\x. x \ s \ (g has_field_derivative g' x) (at x within s)" by blast + from g[OF x] show "summable (\n. f n x)" by (auto simp: summable_def) + from g(2)[OF x] have g': "(g has_derivative op * (g' x)) (at x)" + by (simp add: has_field_derivative_def s) + have "((\x. \n. f n x) has_derivative op * (g' x)) (at x)" + by (rule has_derivative_transform_within_open[OF `open s` x _ g']) + (insert g, auto simp: sums_iff) + thus "(\x. \n. f n x) differentiable (at x)" unfolding differentiable_def + by (auto simp: summable_def differentiable_def has_field_derivative_def) +qed + +lemma differentiable_series': + fixes f :: "nat \ ('a :: {real_normed_field,banach}) \ 'a" + assumes "convex s" "open s" + assumes "\n x. x \ s \ (f n has_field_derivative f' n x) (at x)" + assumes "uniformly_convergent_on s (\n x. \i s" "summable (\n. f n x0)" + shows "(\x. \n. f n x) differentiable (at x0)" + using differentiable_series[OF assms, of x0] `x0 \ s` by blast+ + text \Considering derivative @{typ "real \ 'b::real_normed_vector"} as a vector.\ definition "vector_derivative f net = (SOME f'. (f has_vector_derivative f') net)" @@ -2445,4 +2531,61 @@ vector_derivative f (at x) *\<^sub>R vector_derivative g (at (f x))" by (metis vector_diff_chain_at vector_derivative_at vector_derivative_works assms) + +subsection \Relation between convexity and derivative\ + +(* TODO: Generalise to real vector spaces? *) +lemma convex_on_imp_above_tangent: + assumes convex: "convex_on A f" and connected: "connected A" + assumes c: "c \ interior A" and x : "x \ A" + assumes deriv: "(f has_field_derivative f') (at c within A)" + shows "f x - f c \ f' * (x - c)" +proof (cases x c rule: linorder_cases) + assume xc: "x > c" + let ?A' = "interior A \ {c<..}" + from c have "c \ interior A \ closure {c<..}" by auto + also have "\ \ closure (interior A \ {c<..})" by (intro open_inter_closure_subset) auto + finally have "at c within ?A' \ bot" by (subst at_within_eq_bot_iff) auto + moreover from deriv have "((\y. (f y - f c) / (y - c)) ---> f') (at c within ?A')" + unfolding DERIV_within_iff using interior_subset[of A] by (blast intro: tendsto_mono at_le) + moreover from eventually_at_right_real[OF xc] + have "eventually (\y. (f y - f c) / (y - c) \ (f x - f c) / (x - c)) (at_right c)" + proof eventually_elim + fix y assume y: "y \ {c<.. (f x - f c) / (x - c) * (y - c) + f c" + using interior_subset[of A] + by (intro convex_onD_Icc' convex_on_subset[OF convex] connected_contains_Icc) auto + hence "f y - f c \ (f x - f c) / (x - c) * (y - c)" by simp + thus "(f y - f c) / (y - c) \ (f x - f c) / (x - c)" using y xc by (simp add: divide_simps) + qed + hence "eventually (\y. (f y - f c) / (y - c) \ (f x - f c) / (x - c)) (at c within ?A')" + by (blast intro: filter_leD at_le) + ultimately have "f' \ (f x - f c) / (x - c)" by (rule tendsto_ge_const) + thus ?thesis using xc by (simp add: field_simps) +next + assume xc: "x < c" + let ?A' = "interior A \ {.. interior A \ closure {.. \ closure (interior A \ {.. bot" by (subst at_within_eq_bot_iff) auto + moreover from deriv have "((\y. (f y - f c) / (y - c)) ---> f') (at c within ?A')" + unfolding DERIV_within_iff using interior_subset[of A] by (blast intro: tendsto_mono at_le) + moreover from eventually_at_left_real[OF xc] + have "eventually (\y. (f y - f c) / (y - c) \ (f x - f c) / (x - c)) (at_left c)" + proof eventually_elim + fix y assume y: "y \ {x<.. (f x - f c) / (c - x) * (c - y) + f c" + using interior_subset[of A] + by (intro convex_onD_Icc'' convex_on_subset[OF convex] connected_contains_Icc) auto + hence "f y - f c \ (f x - f c) * ((c - y) / (c - x))" by simp + also have "(c - y) / (c - x) = (y - c) / (x - c)" using y xc by (simp add: field_simps) + finally show "(f y - f c) / (y - c) \ (f x - f c) / (x - c)" using y xc + by (simp add: divide_simps) + qed + hence "eventually (\y. (f y - f c) / (y - c) \ (f x - f c) / (x - c)) (at c within ?A')" + by (blast intro: filter_leD at_le) + ultimately have "f' \ (f x - f c) / (x - c)" by (rule tendsto_le_const) + thus ?thesis using xc by (simp add: field_simps) +qed simp_all + end diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy --- a/src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy Mon Nov 02 11:56:28 2015 +0100 @@ -896,6 +896,15 @@ unfolding dist_norm norm_eq_sqrt_inner setL2_def by (subst euclidean_inner) (simp add: power2_eq_square inner_diff_left) +lemma eventually_nhds_ball: "d > 0 \ eventually (\x. x \ ball z d) (nhds z)" + by (rule eventually_nhds_in_open) simp_all + +lemma eventually_at_ball: "d > 0 \ eventually (\t. t \ ball z d \ t \ A) (at z within A)" + unfolding eventually_at by (intro exI[of _ d]) (simp_all add: dist_commute) + +lemma eventually_at_ball': "d > 0 \ eventually (\t. t \ ball z d \ t \ z \ t \ A) (at z within A)" + unfolding eventually_at by (intro exI[of _ d]) (simp_all add: dist_commute) + subsection \Boxes\ @@ -1582,6 +1591,9 @@ using open_contains_ball_eq [where S="interior S"] by (simp add: open_subset_interior) +lemma eventually_nhds_in_nhd: "x \ interior s \ eventually (\y. y \ s) (nhds x)" + using interior_subset[of s] by (subst eventually_nhds) blast + lemma interior_limit_point [intro]: fixes x :: "'a::perfect_space" assumes x: "x \ interior S" @@ -1832,6 +1844,7 @@ "closed s \ (closedin (subtopology euclidean s) t \ closed t \ t \ s)" by (meson closed_in_limpt closed_subset closedin_closed_trans) + subsection\Connected components, considered as a connectedness relation or a set\ definition @@ -2258,6 +2271,9 @@ using islimpt_in_closure by (metis trivial_limit_within) +lemma at_within_eq_bot_iff: "(at c within A = bot) \ (c \ closure (A - {c}))" + using not_trivial_limit_within[of c A] by blast + text \Some property holds "sufficiently close" to the limit point.\ lemma trivial_limit_eventually: "trivial_limit net \ eventually P net" diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Multivariate_Analysis/Uniform_Limit.thy --- a/src/HOL/Multivariate_Analysis/Uniform_Limit.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Uniform_Limit.thy Mon Nov 02 11:56:28 2015 +0100 @@ -15,6 +15,12 @@ abbreviation "uniform_limit S f l \ filterlim f (uniformly_on S l)" +definition uniformly_convergent_on where + "uniformly_convergent_on X f \ (\l. uniform_limit X f l sequentially)" + +definition uniformly_Cauchy_on where + "uniformly_Cauchy_on X f \ (\e>0. \M. \x\X. \(m::nat)\M. \n\M. dist (f m x) (f n x) < e)" + lemma uniform_limit_iff: "uniform_limit S f l F \ (\e>0. \\<^sub>F n in F. \x\S. dist (f n x) (l x) < e)" unfolding filterlim_iff uniformly_on_def @@ -114,9 +120,115 @@ by (rule swap_uniform_limit) fact+ qed -lemma weierstrass_m_test: +lemma uniformly_Cauchy_onI: + assumes "\e. e > 0 \ \M. \x\X. \m\M. \n\M. dist (f m x) (f n x) < e" + shows "uniformly_Cauchy_on X f" + using assms unfolding uniformly_Cauchy_on_def by blast + +lemma uniformly_Cauchy_onI': + assumes "\e. e > 0 \ \M. \x\X. \m\M. \n>m. dist (f m x) (f n x) < e" + shows "uniformly_Cauchy_on X f" +proof (rule uniformly_Cauchy_onI) + fix e :: real assume e: "e > 0" + from assms[OF this] obtain M + where M: "\x m n. x \ X \ m \ M \ n > m \ dist (f m x) (f n x) < e" by fast + { + fix x m n assume x: "x \ X" and m: "m \ M" and n: "n \ M" + with M[OF this(1,2), of n] M[OF this(1,3), of m] e have "dist (f m x) (f n x) < e" + by (cases m n rule: linorder_cases) (simp_all add: dist_commute) + } + thus "\M. \x\X. \m\M. \n\M. dist (f m x) (f n x) < e" by fast +qed + +lemma uniformly_Cauchy_imp_Cauchy: + "uniformly_Cauchy_on X f \ x \ X \ Cauchy (\n. f n x)" + unfolding Cauchy_def uniformly_Cauchy_on_def by fast + +lemma uniform_limit_cong: + fixes f g :: "'a \ 'b \ ('c :: metric_space)" and h i :: "'b \ 'c" + assumes "eventually (\y. \x\X. f y x = g y x) F" + assumes "\x. x \ X \ h x = i x" + shows "uniform_limit X f h F \ uniform_limit X g i F" +proof - + { + fix f g :: "'a \ 'b \ 'c" and h i :: "'b \ 'c" + assume C: "uniform_limit X f h F" and A: "eventually (\y. \x\X. f y x = g y x) F" + and B: "\x. x \ X \ h x = i x" + { + fix e ::real assume "e > 0" + with C have "eventually (\y. \x\X. dist (f y x) (h x) < e) F" + unfolding uniform_limit_iff by blast + with A have "eventually (\y. \x\X. dist (g y x) (i x) < e) F" + by eventually_elim (insert B, simp_all) + } + hence "uniform_limit X g i F" unfolding uniform_limit_iff by blast + } note A = this + show ?thesis by (rule iffI) (erule A; insert assms; simp add: eq_commute)+ +qed + +lemma uniform_limit_cong': + fixes f g :: "'a \ 'b \ ('c :: metric_space)" and h i :: "'b \ 'c" + assumes "\y x. x \ X \ f y x = g y x" + assumes "\x. x \ X \ h x = i x" + shows "uniform_limit X f h F \ uniform_limit X g i F" + using assms by (intro uniform_limit_cong always_eventually) blast+ + +lemma uniformly_convergent_uniform_limit_iff: + "uniformly_convergent_on X f \ uniform_limit X f (\x. lim (\n. f n x)) sequentially" +proof + assume "uniformly_convergent_on X f" + then obtain l where l: "uniform_limit X f l sequentially" + unfolding uniformly_convergent_on_def by blast + from l have "uniform_limit X f (\x. lim (\n. f n x)) sequentially \ + uniform_limit X f l sequentially" + by (intro uniform_limit_cong' limI tendsto_uniform_limitI[of f X l]) simp_all + also note l + finally show "uniform_limit X f (\x. lim (\n. f n x)) sequentially" . +qed (auto simp: uniformly_convergent_on_def) + +lemma uniformly_convergentI: "uniform_limit X f l sequentially \ uniformly_convergent_on X f" + unfolding uniformly_convergent_on_def by blast + +lemma Cauchy_uniformly_convergent: + fixes f :: "nat \ 'a \ 'b :: complete_space" + assumes "uniformly_Cauchy_on X f" + shows "uniformly_convergent_on X f" +unfolding uniformly_convergent_uniform_limit_iff uniform_limit_iff +proof safe + let ?f = "\x. lim (\n. f n x)" + fix e :: real assume e: "e > 0" + hence "e/2 > 0" by simp + with assms obtain N where N: "\x m n. x \ X \ m \ N \ n \ N \ dist (f m x) (f n x) < e/2" + unfolding uniformly_Cauchy_on_def by fast + show "eventually (\n. \x\X. dist (f n x) (?f x) < e) sequentially" + using eventually_ge_at_top[of N] + proof eventually_elim + fix n assume n: "n \ N" + show "\x\X. dist (f n x) (?f x) < e" + proof + fix x assume x: "x \ X" + with assms have "(\n. f n x) ----> ?f x" + by (auto dest!: Cauchy_convergent uniformly_Cauchy_imp_Cauchy simp: convergent_LIMSEQ_iff) + with `e/2 > 0` have "eventually (\m. m \ N \ dist (f m x) (?f x) < e/2) sequentially" + by (intro tendstoD eventually_conj eventually_ge_at_top) + then obtain m where m: "m \ N" "dist (f m x) (?f x) < e/2" + unfolding eventually_at_top_linorder by blast + have "dist (f n x) (?f x) \ dist (f n x) (f m x) + dist (f m x) (?f x)" + by (rule dist_triangle) + also from x n have "... < e/2 + e/2" by (intro add_strict_mono N m) + finally show "dist (f n x) (?f x) < e" by simp + qed + qed +qed + +lemma uniformly_convergent_imp_convergent: + "uniformly_convergent_on X f \ x \ X \ convergent (\n. f n x)" + unfolding uniformly_convergent_on_def convergent_def + by (auto dest: tendsto_uniform_limitI) + +lemma weierstrass_m_test_ev: fixes f :: "_ \ _ \ _ :: banach" -assumes "\n x. x \ A \ norm (f n x) \ M n" +assumes "eventually (\n. \x\A. norm (f n x) \ M n) sequentially" assumes "summable M" shows "uniform_limit A (\n x. \ix. suminf (\i. f i x)) sequentially" proof (rule uniform_limitI) @@ -125,14 +237,15 @@ from suminf_exist_split[OF \0 < e\ \summable M\] have "\\<^sub>F k in sequentially. norm (\i. M (i + k)) < e" by (auto simp: eventually_sequentially) - thus "\\<^sub>F n in sequentially. \x\A. dist (\ii. f i x) < e" + with eventually_all_ge_at_top[OF assms(1)] + show "\\<^sub>F n in sequentially. \x\A. dist (\ii. f i x) < e" proof eventually_elim case (elim k) show ?case proof safe fix x assume "x \ A" have "\N. \n\N. norm (f n x) \ M n" - using assms(1)[OF \x \ A\] by simp + using assms(1) \x \ A\ by (force simp: eventually_at_top_linorder) hence summable_norm_f: "summable (\n. norm (f n x))" by(rule summable_norm_comparison_test[OF _ \summable M\]) have summable_f: "summable (\n. f n x)" @@ -152,13 +265,32 @@ using summable_norm[OF summable_norm_f_plus_k] . also have "... \ (\i. M (i + k))" by (rule suminf_le[OF _ summable_norm_f_plus_k summable_M_plus_k]) - (simp add: assms(1)[OF \x \ A\]) + (insert elim(1) \x \ A\, simp) finally show "dist (\ii. f i x) < e" using elim by auto qed qed qed +lemma weierstrass_m_test: +fixes f :: "_ \ _ \ _ :: banach" +assumes "\n x. x \ A \ norm (f n x) \ M n" +assumes "summable M" +shows "uniform_limit A (\n x. \ix. suminf (\i. f i x)) sequentially" + using assms by (intro weierstrass_m_test_ev always_eventually) auto + +lemma weierstrass_m_test'_ev: + fixes f :: "_ \ _ \ _ :: banach" + assumes "eventually (\n. \x\A. norm (f n x) \ M n) sequentially" "summable M" + shows "uniformly_convergent_on A (\n x. \i _ \ _ :: banach" + assumes "\n x. x \ A \ norm (f n x) \ M n" "summable M" + shows "uniformly_convergent_on A (\n x. \i l = m \ uniform_limit X f m F" by simp diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Nat.thy --- a/src/HOL/Nat.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Nat.thy Mon Nov 02 11:56:28 2015 +0100 @@ -1472,6 +1472,9 @@ lemma of_nat_mult: "of_nat (m * n) = of_nat m * of_nat n" by (induct m) (simp_all add: ac_simps distrib_right) +lemma mult_of_nat_commute: "of_nat x * y = y * of_nat x" + by (induction x) (simp_all add: algebra_simps) + primrec of_nat_aux :: "('a \ 'a) \ nat \ 'a \ 'a" where "of_nat_aux inc 0 i = i" | "of_nat_aux inc (Suc n) i = of_nat_aux inc n (inc i)" -- \tail recursive\ diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Parity.thy --- a/src/HOL/Parity.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Parity.thy Mon Nov 02 11:56:28 2015 +0100 @@ -233,7 +233,7 @@ subsection \Parity and powers\ -context comm_ring_1 +context ring_1 begin lemma power_minus_even [simp]: diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Power.thy --- a/src/HOL/Power.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Power.thy Mon Nov 02 11:56:28 2015 +0100 @@ -283,6 +283,9 @@ by (simp del: power_Suc add: power_Suc2 mult.assoc) qed +lemma power_minus': "NO_MATCH 1 x \ (-x) ^ n = (-1)^n * x ^ n" + by (rule power_minus) + lemma power_minus_Bit0: "(- x) ^ numeral (Num.Bit0 k) = x ^ numeral (Num.Bit0 k)" by (induct k, simp_all only: numeral_class.numeral.simps power_add @@ -307,7 +310,7 @@ lemma power_minus1_odd: "(- 1) ^ Suc (2*n) = -1" by simp - + lemma power_minus_even [simp]: "(-a) ^ (2*n) = a ^ (2*n)" by (simp add: power_minus [of a]) diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Real_Vector_Spaces.thy --- a/src/HOL/Real_Vector_Spaces.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Real_Vector_Spaces.thy Mon Nov 02 11:56:28 2015 +0100 @@ -228,6 +228,14 @@ apply (erule (1) nonzero_inverse_scaleR_distrib) done +lemma setsum_constant_scaleR: + fixes y :: "'a::real_vector" + shows "(\x\A. y) = of_nat (card A) *\<^sub>R y" + apply (cases "finite A") + apply (induct set: finite) + apply (simp_all add: algebra_simps) + done + lemma real_vector_affinity_eq: fixes x :: "'a :: real_vector" assumes m0: "m \ 0" @@ -1614,6 +1622,12 @@ apply auto done +lemma eventually_at_left_real: "a > (b :: real) \ eventually (\x. x \ {b<.. eventually (\x. x \ {a<.. a) F" @@ -1709,12 +1723,36 @@ definition (in metric_space) Cauchy :: "(nat \ 'a) \ bool" where "Cauchy X = (\e>0. \M. \m \ M. \n \ M. dist (X m) (X n) < e)" -subsection \Cauchy Sequences\ +lemma Cauchy_altdef: + "Cauchy f = (\e>0. \M. \m\M. \n>m. dist (f m) (f n) < e)" +proof + assume A: "\e>0. \M. \m\M. \n>m. dist (f m) (f n) < e" + show "Cauchy f" unfolding Cauchy_def + proof (intro allI impI) + fix e :: real assume e: "e > 0" + with A obtain M where M: "\m n. m \ M \ n > m \ dist (f m) (f n) < e" by blast + have "dist (f m) (f n) < e" if "m \ M" "n \ M" for m n + using M[of m n] M[of n m] e that by (cases m n rule: linorder_cases) (auto simp: dist_commute) + thus "\M. \m\M. \n\M. dist (f m) (f n) < e" by blast + qed +next + assume "Cauchy f" + show "\e>0. \M. \m\M. \n>m. dist (f m) (f n) < e" + proof (intro allI impI) + fix e :: real assume e: "e > 0" + with `Cauchy f` obtain M where "\m n. m \ M \ n \ M \ dist (f m) (f n) < e" + unfolding Cauchy_def by fast + thus "\M. \m\M. \n>m. dist (f m) (f n) < e" by (intro exI[of _ M]) force + qed +qed lemma metric_CauchyI: "(\e. 0 < e \ \M. \m\M. \n\M. dist (X m) (X n) < e) \ Cauchy X" by (simp add: Cauchy_def) +lemma CauchyI': "(\e. 0 < e \ \M. \m\M. \n>m. dist (X m) (X n) < e) \ Cauchy X" + unfolding Cauchy_altdef by blast + lemma metric_CauchyD: "Cauchy X \ 0 < e \ \M. \m\M. \n\M. dist (X m) (X n) < e" by (simp add: Cauchy_def) diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Series.thy --- a/src/HOL/Series.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Series.thy Mon Nov 02 11:56:28 2015 +0100 @@ -35,12 +35,20 @@ lemma sums_subst[trans]: "f = g \ g sums z \ f sums z" by simp +lemma sums_cong: "(\n. f n = g n) \ f sums c \ g sums c" + by (drule ext) simp + lemma sums_summable: "f sums l \ summable f" by (simp add: sums_def summable_def, blast) lemma summable_iff_convergent: "summable f \ convergent (\n. \i convergent (\n. setsum f {..n})" + by (simp_all only: summable_iff_convergent convergent_def + lessThan_Suc_atMost [symmetric] LIMSEQ_Suc_iff[of "\n. setsum f {..n. \in. f n = g n) \ suminf f = suminf g" + by (rule arg_cong[of f g], rule ext) simp + +lemma summable_cong: + assumes "eventually (\x. f x = (g x :: 'a :: real_normed_vector)) sequentially" + shows "summable f = summable g" +proof - + from assms obtain N where N: "\n\N. f n = g n" by (auto simp: eventually_at_top_linorder) + def C \ "(\kn. setsum f {.. N" + from n have "{.. {N.. {N.. {N..n. n \ N \ f n = 0" shows "f sums (\n\N. f n)" @@ -125,6 +161,10 @@ lemma sums_iff: "f sums x \ summable f \ (suminf f = x)" by (metis summable_sums sums_summable sums_unique) +lemma summable_sums_iff: + "summable (f :: nat \ 'a :: {comm_monoid_add,t2_space}) \ f sums suminf f" + by (auto simp: sums_iff summable_sums) + lemma sums_unique2: fixes a b :: "'a::{comm_monoid_add,t2_space}" shows "f sums a \ f sums b \ a = b" @@ -221,6 +261,7 @@ by (auto intro: le_less_trans simp: eventually_sequentially) } qed + subsection \Infinite summability on real normed vector spaces\ lemma sums_Suc_iff: @@ -241,6 +282,14 @@ finally show ?thesis .. qed +lemma summable_Suc_iff: "summable (\n. f (Suc n) :: 'a :: real_normed_vector) = summable f" +proof + assume "summable f" + hence "f sums suminf f" by (rule summable_sums) + hence "(\n. f (Suc n)) sums (suminf f - f 0)" by (simp add: sums_Suc_iff) + thus "summable (\n. f (Suc n))" unfolding summable_def by blast +qed (auto simp: sums_Suc_iff summable_def) + context fixes f :: "nat \ 'a::real_normed_vector" begin @@ -299,6 +348,9 @@ lemma suminf_split_initial_segment: "summable f \ suminf f = (\n. f(n + k)) + (\i (\n. f (Suc n)) = suminf f - f 0" + using suminf_split_initial_segment[of 1] by simp + lemma suminf_exist_split: fixes r :: real assumes "0 < r" and "summable f" shows "\N. \n\N. norm (\i. f (i + n)) < r" @@ -319,6 +371,14 @@ apply (drule_tac x="n" in spec, simp) done +lemma summable_imp_convergent: + "summable (f :: nat \ 'a) \ convergent f" + by (force dest!: summable_LIMSEQ_zero simp: convergent_def) + +lemma summable_imp_Bseq: + "summable f \ Bseq (f :: nat \ 'a :: real_normed_vector)" + by (simp add: convergent_imp_Bseq summable_imp_convergent) + end lemma summable_minus_iff: @@ -363,6 +423,23 @@ lemmas summable_scaleR_right = bounded_linear.summable[OF bounded_linear_scaleR_right] lemmas suminf_scaleR_right = bounded_linear.suminf[OF bounded_linear_scaleR_right] +lemma summable_const_iff: "summable (\_. c) \ (c :: 'a :: real_normed_vector) = 0" +proof - + { + assume "c \ 0" + hence "filterlim (\n. of_nat n * norm c) at_top sequentially" + unfolding real_of_nat_def[symmetric] + by (subst mult.commute) + (auto intro!: filterlim_tendsto_pos_mult_at_top filterlim_real_sequentially) + hence "\convergent (\n. norm (\ksummable (\_. c)" unfolding summable_iff_convergent using convergent_norm by blast + } + thus ?thesis by auto +qed + + subsection \Infinite summability on real normed algebras\ context @@ -389,6 +466,22 @@ end +lemma sums_mult_iff: + assumes "c \ 0" + shows "(\n. c * f n :: 'a :: {real_normed_algebra,field}) sums (c * d) \ f sums d" + using sums_mult[of f d c] sums_mult[of "\n. c * f n" "c * d" "inverse c"] + by (force simp: field_simps assms) + +lemma sums_mult2_iff: + assumes "c \ (0 :: 'a :: {real_normed_algebra, field})" + shows "(\n. f n * c) sums (d * c) \ f sums d" + using sums_mult_iff[OF assms, of f d] by (simp add: mult.commute) + +lemma sums_of_real_iff: + "(\n. of_real (f n) :: 'a :: real_normed_div_algebra) sums of_real c \ f sums c" + by (simp add: sums_def of_real_setsum[symmetric] tendsto_of_real_iff del: of_real_setsum) + + subsection \Infinite summability on real normed fields\ context @@ -427,6 +520,16 @@ lemma suminf_geometric: "norm c < 1 \ suminf (\n. c^n) = 1 / (1 - c)" by (rule sums_unique[symmetric]) (rule geometric_sums) +lemma summable_geometric_iff: "summable (\n. c ^ n) \ norm c < 1" +proof + assume "summable (\n. c ^ n :: 'a :: real_normed_field)" + hence "(\n. norm c ^ n) ----> 0" + by (simp add: norm_power [symmetric] tendsto_norm_zero_iff summable_LIMSEQ_zero) + from order_tendstoD(2)[OF this zero_less_one] obtain n where "norm c ^ n < 1" + by (auto simp: eventually_at_top_linorder) + thus "norm c < 1" using one_le_power[of "norm c" n] by (cases "norm c \ 1") (linarith, simp) +qed (rule summable_geometric) + end lemma power_half_series: "(\n. (1/2::real)^Suc n) sums 1" @@ -439,6 +542,36 @@ by simp qed + +subsection \Telescoping\ + +lemma telescope_sums: + assumes "f ----> (c :: 'a :: real_normed_vector)" + shows "(\n. f (Suc n) - f n) sums (c - f 0)" + unfolding sums_def +proof (subst LIMSEQ_Suc_iff [symmetric]) + have "(\n. \kn. f (Suc n) - f 0)" + by (simp add: lessThan_Suc_atMost atLeast0AtMost [symmetric] setsum_Suc_diff) + also have "\ ----> c - f 0" by (intro tendsto_diff LIMSEQ_Suc[OF assms] tendsto_const) + finally show "(\n. \n c - f 0" . +qed + +lemma telescope_sums': + assumes "f ----> (c :: 'a :: real_normed_vector)" + shows "(\n. f n - f (Suc n)) sums (f 0 - c)" + using sums_minus[OF telescope_sums[OF assms]] by (simp add: algebra_simps) + +lemma telescope_summable: + assumes "f ----> (c :: 'a :: real_normed_vector)" + shows "summable (\n. f (Suc n) - f n)" + using telescope_sums[OF assms] by (simp add: sums_iff) + +lemma telescope_summable': + assumes "f ----> (c :: 'a :: real_normed_vector)" + shows "summable (\n. f n - f (Suc n))" + using summable_minus[OF telescope_summable[OF assms]] by (simp add: algebra_simps) + + subsection \Infinite summability on Banach spaces\ text\Cauchy-type criterion for convergence of series (c.f. Harrison)\ @@ -463,7 +596,7 @@ context fixes f :: "nat \ 'a::banach" -begin +begin text\Absolute convergence imples normal convergence\ @@ -495,6 +628,10 @@ apply (auto intro: setsum_mono simp add: abs_less_iff) done +lemma summable_comparison_test_ev: + shows "eventually (\n. norm (f n) \ g n) sequentially \ summable g \ summable f" + by (rule summable_comparison_test) (auto simp: eventually_at_top_linorder) + (*A better argument order*) lemma summable_comparison_test': "summable g \ (\n. n \ N \ norm(f n) \ g n) \ summable f" by (rule summable_comparison_test) auto @@ -669,6 +806,21 @@ lemma summable_rabs: "summable (\n. \f n :: real\) \ \suminf f\ \ (\n. \f n\)" by (fold real_norm_def) (rule summable_norm) +lemma summable_zero_power [simp]: "summable (\n. 0 ^ n :: 'a :: {comm_ring_1,topological_space})" +proof - + have "(\n. 0 ^ n :: 'a) = (\n. if n = 0 then 0^0 else 0)" by (intro ext) (simp add: zero_power) + moreover have "summable \" by simp + ultimately show ?thesis by simp +qed + +lemma summable_zero_power' [simp]: "summable (\n. f n * 0 ^ n :: 'a :: {ring_1,topological_space})" +proof - + have "(\n. f n * 0 ^ n :: 'a) = (\n. if n = 0 then f 0 * 0^0 else 0)" + by (intro ext) (simp add: zero_power) + moreover have "summable \" by simp + ultimately show ?thesis by simp +qed + lemma summable_power_series: fixes z :: real assumes le_1: "\i. f i \ 1" and nonneg: "\i. 0 \ f i" and z: "0 \ z" "z < 1" @@ -679,6 +831,79 @@ using z by (auto intro!: exI[of _ 0] mult_left_le_one_le simp: abs_mult nonneg power_abs less_imp_le le_1) qed +lemma summable_0_powser: + "summable (\n. f n * 0 ^ n :: 'a :: real_normed_div_algebra)" +proof - + have A: "(\n. f n * 0 ^ n) = (\n. if n = 0 then f n else 0)" + by (intro ext) auto + thus ?thesis by (subst A) simp_all +qed + +lemma summable_powser_split_head: + "summable (\n. f (Suc n) * z ^ n :: 'a :: real_normed_div_algebra) = summable (\n. f n * z ^ n)" +proof - + have "summable (\n. f (Suc n) * z ^ n) \ summable (\n. f (Suc n) * z ^ Suc n)" + proof + assume "summable (\n. f (Suc n) * z ^ n)" + from summable_mult2[OF this, of z] show "summable (\n. f (Suc n) * z ^ Suc n)" + by (simp add: power_commutes algebra_simps) + next + assume "summable (\n. f (Suc n) * z ^ Suc n)" + from summable_mult2[OF this, of "inverse z"] show "summable (\n. f (Suc n) * z ^ n)" + by (cases "z \ 0", subst (asm) power_Suc2) (simp_all add: algebra_simps) + qed + also have "\ \ summable (\n. f n * z ^ n)" by (rule summable_Suc_iff) + finally show ?thesis . +qed + +lemma powser_split_head: + assumes "summable (\n. f n * z ^ n :: 'a :: {real_normed_div_algebra,banach})" + shows "suminf (\n. f n * z ^ n) = f 0 + suminf (\n. f (Suc n) * z ^ n) * z" + "suminf (\n. f (Suc n) * z ^ n) * z = suminf (\n. f n * z ^ n) - f 0" + "summable (\n. f (Suc n) * z ^ n)" +proof - + from assms show "summable (\n. f (Suc n) * z ^ n)" by (subst summable_powser_split_head) + + from suminf_mult2[OF this, of z] + have "(\n. f (Suc n) * z ^ n) * z = (\n. f (Suc n) * z ^ Suc n)" + by (simp add: power_commutes algebra_simps) + also from assms have "\ = suminf (\n. f n * z ^ n) - f 0" + by (subst suminf_split_head) simp_all + finally show "suminf (\n. f n * z ^ n) = f 0 + suminf (\n. f (Suc n) * z ^ n) * z" by simp + thus "suminf (\n. f (Suc n) * z ^ n) * z = suminf (\n. f n * z ^ n) - f 0" by simp +qed + +lemma summable_partial_sum_bound: + fixes f :: "nat \ 'a :: banach" + assumes summable: "summable f" and e: "e > (0::real)" + obtains N where "\m n. m \ N \ norm (\k=m..n. f k) < e" +proof - + from summable have "Cauchy (\n. \km n. m \ N \ n \ N \ norm ((\kk N" + have "norm (\k=m..n. f k) < e" + proof (cases "n \ m") + assume n: "n \ m" + with m have "norm ((\kkkkk=m..n. f k)" + by (subst setsum_diff [symmetric]) (simp_all add: setsum_last_plus) + finally show ?thesis . + qed (insert e, simp_all) + } + thus ?thesis by (rule that) +qed + +lemma powser_sums_if: + "(\n. (if n = m then (1 :: 'a :: {ring_1,topological_space}) else 0) * z^n) sums z^m" +proof - + have "(\n. (if n = m then 1 else 0) * z^n) = (\n. if n = m then z^n else 0)" + by (intro ext) auto + thus ?thesis by (simp add: sums_single) +qed + lemma fixes f :: "nat \ real" assumes "summable f" @@ -742,4 +967,82 @@ with le show "suminf (f \ g) = suminf f" by(rule antisym) qed +lemma sums_mono_reindex: + assumes subseq: "subseq g" and zero: "\n. n \ range g \ f n = 0" + shows "(\n. f (g n)) sums c \ f sums c" +unfolding sums_def +proof + assume lim: "(\n. \k c" + have "(\n. \kn. \kkk\g`{.. = (\kkk ----> c" unfolding o_def . + finally show "(\n. \k c" . +next + assume lim: "(\n. \k c" + def g_inv \ "\n. LEAST m. g m \ n" + from filterlim_subseq[OF subseq] have g_inv_ex: "\m. g m \ n" for n + by (auto simp: filterlim_at_top eventually_at_top_linorder) + hence g_inv: "g (g_inv n) \ n" for n unfolding g_inv_def by (rule LeastI_ex) + have g_inv_least: "m \ g_inv n" if "g m \ n" for m n using that + unfolding g_inv_def by (rule Least_le) + have g_inv_least': "g m < n" if "m < g_inv n" for m n using that g_inv_least[of n m] by linarith + have "(\n. \kn. \k {.. range g" + proof (rule notI, elim imageE) + fix l assume l: "k = g l" + have "g l < g (g_inv n)" by (rule less_le_trans[OF _ g_inv]) (insert k l, simp_all) + with subseq have "l < g_inv n" by (simp add: subseq_strict_mono strict_mono_less) + with k l show False by simp + qed + hence "f k = 0" by (rule zero) + } + with g_inv_least' g_inv have "(\kk\g`{.. = (\kkk n" + also have "n \ g (g_inv n)" by (rule g_inv) + finally have "K \ g_inv n" using subseq by (simp add: strict_mono_less_eq subseq_strict_mono) + } + hence "filterlim g_inv at_top sequentially" + by (auto simp: filterlim_at_top eventually_at_top_linorder) + from lim and this have "(\n. \k c" by (rule filterlim_compose) + finally show "(\n. \k c" . +qed + +lemma summable_mono_reindex: + assumes subseq: "subseq g" and zero: "\n. n \ range g \ f n = 0" + shows "summable (\n. f (g n)) \ summable f" + using sums_mono_reindex[of g f, OF assms] by (simp add: summable_def) + +lemma suminf_mono_reindex: + assumes "subseq g" "\n. n \ range g \ f n = (0 :: 'a :: {t2_space,comm_monoid_add})" + shows "suminf (\n. f (g n)) = suminf f" +proof (cases "summable f") + case False + hence "\(\c. f sums c)" unfolding summable_def by blast + hence "suminf f = The (\_. False)" by (simp add: suminf_def) + moreover from False have "\summable (\n. f (g n))" + using summable_mono_reindex[of g f, OF assms] by simp + hence "\(\c. (\n. f (g n)) sums c)" unfolding summable_def by blast + hence "suminf (\n. f (g n)) = The (\_. False)" by (simp add: suminf_def) + ultimately show ?thesis by simp +qed (insert sums_mono_reindex[of g f, OF assms] summable_mono_reindex[of g f, OF assms], + simp_all add: sums_iff) + end diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Topological_Spaces.thy --- a/src/HOL/Topological_Spaces.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Topological_Spaces.thy Mon Nov 02 11:56:28 2015 +0100 @@ -353,6 +353,10 @@ "eventually P (nhds a) \ (\S. open S \ a \ S \ (\x\S. P x))" unfolding nhds_def by (subst eventually_INF_base) (auto simp: eventually_principal) +lemma (in topological_space) eventually_nhds_in_open: + "open s \ x \ s \ eventually (\y. y \ s) (nhds x)" + by (subst eventually_nhds) blast + lemma nhds_neq_bot [simp]: "nhds a \ bot" unfolding trivial_limit_def eventually_nhds by simp @@ -497,6 +501,12 @@ "(f ---> l) F \ (\S. open S \ l \ S \ eventually (\x. f x \ S) F)" unfolding nhds_def filterlim_INF filterlim_principal by auto +lemma tendsto_cong: + assumes "eventually (\x. f x = g x) F" + shows "(f ---> c) F \ (g ---> c) F" + by (rule filterlim_cong[OF refl refl assms]) + + lemma tendsto_mono: "F \ F' \ (f ---> l) F' \ (f ---> l) F" unfolding tendsto_def le_filter_def by fast @@ -625,6 +635,28 @@ using order_tendstoD[OF lim(2), of a] ev by (auto elim: eventually_elim2) qed +lemma limit_frequently_eq: + assumes "F \ bot" + assumes "frequently (\x. f x = c) F" + assumes "(f ---> d) F" + shows "d = (c :: 'a :: t1_space)" +proof (rule ccontr) + assume "d \ c" + from t1_space[OF this] obtain U where "open U" "d \ U" "c \ U" by blast + from this assms have "eventually (\x. f x \ U) F" unfolding tendsto_def by blast + hence "eventually (\x. f x \ c) F" by eventually_elim (insert `c \ U`, blast) + with assms(2) show False unfolding frequently_def by contradiction +qed + +lemma tendsto_imp_eventually_ne: + assumes "F \ bot" "(f ---> c) F" "c \ (c' :: 'a :: t1_space)" + shows "eventually (\z. f z \ c') F" +proof (rule ccontr) + assume "\eventually (\z. f z \ c') F" + hence "frequently (\z. f z = c') F" by (simp add: frequently_def) + from limit_frequently_eq[OF assms(1) this assms(2)] and assms(3) show False by contradiction +qed + lemma tendsto_le: fixes f g :: "'a \ 'b::linorder_topology" assumes F: "\ trivial_limit F" @@ -657,6 +689,9 @@ shows "a \ x" by (rule tendsto_le [OF F tendsto_const x a]) + + + subsubsection \Rules about @{const Lim}\ lemma tendsto_Lim: @@ -924,6 +959,17 @@ lemma subseq_mono: assumes "subseq r" "m < n" shows "r m < r n" using assms by (auto simp: subseq_def) +lemma subseq_imp_inj_on: "subseq g \ inj_on g A" +proof (rule inj_onI) + assume g: "subseq g" + fix x y assume "g x = g y" + with subseq_mono[OF g, of x y] subseq_mono[OF g, of y x] show "x = y" + by (cases x y rule: linorder_cases) simp_all +qed + +lemma subseq_strict_mono: "subseq g \ strict_mono g" + by (intro strict_monoI subseq_mono[of g]) + lemma incseq_imp_monoseq: "incseq X \ monoseq X" by (simp add: incseq_def monoseq_def) @@ -2142,6 +2188,15 @@ assumes A: "connected A" "a \ A" "b \ A" shows "{a <..< b} \ A" using connectedD_interval[OF A] by (simp add: subset_eq Ball_def less_imp_le) +lemma connected_contains_Icc: + assumes "connected (A :: ('a :: {linorder_topology}) set)" "a \ A" "b \ A" + shows "{a..b} \ A" +proof + fix x assume "x \ {a..b}" + hence "x = a \ x = b \ x \ {a<.. A" using assms connected_contains_Ioo[of A a b] by auto +qed + subsection \Intermediate Value Theorem\ lemma IVT': diff -r f2e51e704a96 -r ab2e862263e7 src/HOL/Transcendental.thy --- a/src/HOL/Transcendental.thy Thu Oct 29 15:40:52 2015 +0100 +++ b/src/HOL/Transcendental.thy Mon Nov 02 11:56:28 2015 +0100 @@ -16,6 +16,11 @@ using floor_correct [of "x/y"] assms by (auto simp: Real.real_of_nat_Suc field_simps intro: that [of "nat (floor (x/y))"]) +lemma fact_in_Reals: "fact n \ \" by (induction n) auto + +lemma pochhammer_of_real: "pochhammer (of_real x) n = of_real (pochhammer x n)" + by (simp add: pochhammer_def) + lemma of_real_fact [simp]: "of_real (fact n) = fact n" by (metis of_nat_fact of_real_of_nat_eq) @@ -1081,6 +1086,15 @@ qed +lemma isCont_pochhammer [continuous_intros]: "isCont (\z::'a::real_normed_field. pochhammer z n) z" + by (induction n) (auto intro!: continuous_intros simp: pochhammer_rec') + +lemma continuous_on_pochhammer [continuous_intros]: + fixes A :: "'a :: real_normed_field set" + shows "continuous_on A (\z. pochhammer z n)" + by (intro continuous_at_imp_continuous_on ballI isCont_pochhammer) + + subsection \Exponential Function\ definition exp :: "'a \ 'a::{real_normed_algebra_1,banach}" @@ -4227,6 +4241,93 @@ lemma tan_cot: "tan(pi/2 - x) = inverse(tan x)" by (simp add: tan_def sin_diff cos_diff) +subsection \Cotangent\ + +definition cot :: "'a \ 'a::{real_normed_field,banach}" + where "cot = (\x. cos x / sin x)" + +lemma cot_of_real: + "of_real (cot x) = (cot (of_real x) :: 'a::{real_normed_field,banach})" + by (simp add: cot_def sin_of_real cos_of_real) + +lemma cot_in_Reals [simp]: + fixes z :: "'a::{real_normed_field,banach}" + shows "z \ \ \ cot z \ \" + by (simp add: cot_def) + +lemma cot_zero [simp]: "cot 0 = 0" + by (simp add: cot_def) + +lemma cot_pi [simp]: "cot pi = 0" + by (simp add: cot_def) + +lemma cot_npi [simp]: "cot (real (n::nat) * pi) = 0" + by (simp add: cot_def) + +lemma cot_minus [simp]: "cot (-x) = - cot x" + by (simp add: cot_def) + +lemma cot_periodic [simp]: "cot (x + 2*pi) = cot x" + by (simp add: cot_def) + +lemma cot_altdef: "cot x = inverse (tan x)" + by (simp add: cot_def tan_def) + +lemma tan_altdef: "tan x = inverse (cot x)" + by (simp add: cot_def tan_def) + +lemma tan_cot': "tan(pi/2 - x) = cot x" + by (simp add: tan_cot cot_altdef) + +lemma cot_gt_zero: "\0 < x; x < pi/2\ \ 0 < cot x" + by (simp add: cot_def zero_less_divide_iff sin_gt_zero2 cos_gt_zero_pi) + +lemma cot_less_zero: + assumes lb: "- pi/2 < x" and "x < 0" + shows "cot x < 0" +proof - + have "0 < cot (- x)" using assms by (simp only: cot_gt_zero) + thus ?thesis by simp +qed + +lemma DERIV_cot [simp]: + fixes x :: "'a::{real_normed_field,banach}" + shows "sin x \ 0 \ DERIV cot x :> -inverse ((sin x)\<^sup>2)" + unfolding cot_def using cos_squared_eq[of x] + by (auto intro!: derivative_eq_intros, simp add: divide_inverse power2_eq_square) + +lemma isCont_cot: + fixes x :: "'a::{real_normed_field,banach}" + shows "sin x \ 0 \ isCont cot x" + by (rule DERIV_cot [THEN DERIV_isCont]) + +lemma isCont_cot' [simp,continuous_intros]: + fixes a :: "'a::{real_normed_field,banach}" and f :: "'a \ 'a" + shows "\isCont f a; sin (f a) \ 0\ \ isCont (\x. cot (f x)) a" + by (rule isCont_o2 [OF _ isCont_cot]) + +lemma tendsto_cot [tendsto_intros]: + fixes f :: "'a \ 'a::{real_normed_field,banach}" + shows "\(f ---> a) F; sin a \ 0\ \ ((\x. cot (f x)) ---> cot a) F" + by (rule isCont_tendsto_compose [OF isCont_cot]) + +lemma continuous_cot: + fixes f :: "'a \ 'a::{real_normed_field,banach}" + shows "continuous F f \ sin (f (Lim F (\x. x))) \ 0 \ continuous F (\x. cot (f x))" + unfolding continuous_def by (rule tendsto_cot) + +lemma continuous_on_cot [continuous_intros]: + fixes f :: "'a \ 'a::{real_normed_field,banach}" + shows "continuous_on s f \ (\x\s. sin (f x) \ 0) \ continuous_on s (\x. cot (f x))" + unfolding continuous_on_def by (auto intro: tendsto_cot) + +lemma continuous_within_cot [continuous_intros]: + fixes f :: "'a \ 'a::{real_normed_field,banach}" + shows + "continuous (at x within s) f \ sin (f x) \ 0 \ continuous (at x within s) (\x. cot (f x))" + unfolding continuous_within by (rule tendsto_cot) + + subsection \Inverse Trigonometric Functions\ definition arcsin :: "real => real"