# HG changeset patch # User haftmann # Date 1468063576 -7200 # Node ID c184ec919c7073ac87186992c3865b32766de25c # Parent 6af79184bef3dc9cfa15111ca70a0ab73eab4b2b more lemmas to emphasize {0::nat..(<)n} as canonical representation of intervals on nat * * * more rules for setsum, setprod on intervals diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Binomial.thy --- a/src/HOL/Binomial.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Binomial.thy Sat Jul 09 13:26:16 2016 +0200 @@ -14,38 +14,53 @@ subsection \Factorial\ -definition (in semiring_char_0) fact :: "nat \ 'a" +context semiring_char_0 +begin + +definition fact :: "nat \ 'a" where - "fact n = of_nat (\{1..n})" + fact_setprod: "fact n = of_nat (\{1..n})" -lemma fact_altdef': "fact n = of_nat (\{1..n})" - by (fact fact_def) +lemma fact_setprod_Suc: + "fact n = of_nat (setprod Suc {0..{1..n}" - by (simp add: fact_def) - -lemma fact_altdef: "fact n = (\i=1..n. of_nat i)" - by (simp add: fact_def) +lemma fact_setprod_rev: + "fact n = of_nat (\i = 0..i. i" 1 n] + by (cases n) (simp_all add: fact_setprod_Suc setprod.atLeast_Suc_atMost_Suc_shift atLeastLessThanSuc_atLeastAtMost) lemma fact_0 [simp]: "fact 0 = 1" - by (simp add: fact_def) + by (simp add: fact_setprod) lemma fact_1 [simp]: "fact 1 = 1" - by (simp add: fact_def) + by (simp add: fact_setprod) -lemma fact_Suc_0 [simp]: "fact (Suc 0) = Suc 0" - by (simp add: fact_def) +lemma fact_Suc_0 [simp]: "fact (Suc 0) = 1" + by (simp add: fact_setprod) lemma fact_Suc [simp]: "fact (Suc n) = of_nat (Suc n) * fact n" - by (simp add: fact_def atLeastAtMostSuc_conv algebra_simps) + by (simp add: fact_setprod atLeastAtMostSuc_conv algebra_simps) + +lemma fact_2 [simp]: + "fact 2 = 2" + by (simp add: numeral_2_eq_2) + +lemma fact_split: + assumes "k \ n" + shows "fact n = of_nat (setprod Suc {n - k.. 0 \ fact n = of_nat n * fact (n - 1)" by (cases n) auto @@ -149,10 +164,6 @@ "fact m = (if m=0 then 1 else of_nat m * fact (m - 1))" by (cases m) auto -lemma fact_eq_rev_setprod_nat: "fact k = (\i n" shows "fact n div fact (n - r) \ n ^ r" proof - @@ -177,30 +188,30 @@ definition binomial :: "nat \ nat \ nat" (infixl "choose" 65) where - "n choose k = card {K\Pow {..Pow {0.. A \ card B = k} = card A choose k" proof - - from assms obtain f where bij: "bij_betw f {.. {.. {0.. {.. card K = k} \ Pow {.. {0.. card K = k} \ Pow {0.. {.. card K = k}" + ultimately have "inj_on (image f) {K. K \ {0.. card K = k}" by (rule inj_on_subset) - then have "card {K. K \ {.. card K = k} = - card (image f ` {K. K \ {.. card K = k})" (is "_ = card ?C") + then have "card {K. K \ {0.. card K = k} = + card (image f ` {K. K \ {0.. card K = k})" (is "_ = card ?C") by (simp add: card_image) - also have "?C = {K. K \ f ` {.. card K = k}" + also have "?C = {K. K \ f ` {0.. card K = k}" by (auto elim!: subset_imageE) - also have "f ` {.. Pow {.. Pow {0.. ?P n (Suc k) = {}" by auto have "?Q = {K\?Q. n \ K} \ {K\?Q. n \ K}" @@ -235,7 +246,7 @@ also have "{K\?Q. n \ K} = insert n ` ?P n k" (is "?A = ?B") proof (rule set_eqI) fix K - have K_finite: "finite K" if "K \ insert n {.. insert n {0.. K" and "finite K" @@ -246,17 +257,17 @@ qed show "K \ ?A \ K \ ?B" by (subst in_image_insert_iff) - (auto simp add: card_insert subset_eq_range_finite Diff_subset_conv K_finite Suc_card_K) + (auto simp add: card_insert subset_eq_atLeast0_lessThan_finite Diff_subset_conv K_finite Suc_card_K) qed also have "{K\?Q. n \ K} = ?P n (Suc k)" - by (auto simp add: lessThan_Suc) + by (auto simp add: atLeast0_lessThan_Suc) finally show ?thesis using inj disjoint by (simp add: binomial_def card_Un_disjoint card_image) qed lemma binomial_eq_0: "n < k \ n choose k = 0" - by (auto simp add: binomial_def dest: subset_eq_range_card) + by (auto simp add: binomial_def dest: subset_eq_atLeast0_lessThan_card) lemma zero_less_binomial: "k \ n \ n choose k > 0" by (induct n k rule: diff_induct) simp_all @@ -409,6 +420,29 @@ apply (simp add: field_simps) by (metis mult.commute of_nat_fact of_nat_mult) +lemma fact_binomial: + assumes "k \ n" + shows "fact k * of_nat (n choose k) = (fact n / fact (n - k) :: 'a::field_char_0)" + unfolding binomial_fact [OF assms] by (simp add: field_simps) + +lemma choose_two: + "n choose 2 = n * (n - 1) div 2" +proof (cases "n \ 2") + case False + then have "n = 0 \ n = 1" + by auto + then show ?thesis by auto +next + case True + define m where "m = n - 2" + with True have "n = m + 2" + by simp + then have "fact n = n * (n - 1) * fact (n - 2)" + by (simp add: fact_setprod_Suc atLeast0_lessThan_Suc algebra_simps) + with True show ?thesis + by (simp add: binomial_fact') +qed + lemma choose_row_sum: "(\k=0..n. n choose k) = 2^n" using binomial [of 1 "1" n] by (simp add: numeral_2_eq_2) @@ -454,17 +488,13 @@ 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)" - by (rule setsum.reindex_bij_witness[where i="\k. m+n-k" and j="\k. m+n-k"]) auto - text\NW diagonal sum property\ lemma sum_choose_diagonal: assumes "m\n" shows "(\k=0..m. (n-k) choose (m-k)) = Suc n choose m" proof - have "(\k=0..m. (n-k) choose (m-k)) = (\k=0..m. (n-m+k) choose k)" - by (rule natsum_reverse_index) (simp add: assms) + using setsum.atLeast_atMost_rev [of "\k. (n - k) choose (m - k)" 0 m] assms + by simp also have "... = Suc (n-m+m) choose m" by (rule sum_choose_lower) also have "... = Suc n choose m" using assms @@ -477,86 +507,59 @@ text \See @{url "http://en.wikipedia.org/wiki/Pochhammer_symbol"}\ -definition (in comm_semiring_1) pochhammer :: "'a \ nat \ 'a" +context comm_semiring_1 +begin + +definition pochhammer :: "'a \ nat \ 'a" where - "pochhammer (a :: 'a) n = setprod (\n. a + of_nat n) {..i. a + of_nat i) {0..i. a + of_nat (n - i)) {1..n}" + using setprod.atLeast_lessThan_rev_at_least_Suc_atMost [of "\i. a + of_nat i" 0 n] + by (simp add: pochhammer_setprod) lemma pochhammer_Suc_setprod: - "pochhammer a (Suc n) = setprod (\n. a + of_nat n) {..n}" - by (simp add: pochhammer_def lessThan_Suc_atMost) - + "pochhammer a (Suc n) = setprod (\i. a + of_nat i) {0..n}" + by (simp add: pochhammer_setprod atLeastLessThanSuc_atLeastAtMost) + +lemma pochhammer_Suc_setprod_rev: + "pochhammer a (Suc n) = setprod (\i. a + of_nat (n - i)) {0..n}" + by (simp add: pochhammer_setprod_rev setprod.atLeast_Suc_atMost_Suc_shift) + lemma pochhammer_0 [simp]: "pochhammer a 0 = 1" - by (simp add: pochhammer_def) + by (simp add: pochhammer_setprod) lemma pochhammer_1 [simp]: "pochhammer a 1 = a" - by (simp add: pochhammer_def lessThan_Suc) + by (simp add: pochhammer_setprod lessThan_Suc) lemma pochhammer_Suc0 [simp]: "pochhammer a (Suc 0) = a" - by (simp add: pochhammer_def lessThan_Suc) + by (simp add: pochhammer_setprod lessThan_Suc) lemma pochhammer_Suc: "pochhammer a (Suc n) = pochhammer a n * (a + of_nat n)" - by (simp add: pochhammer_def lessThan_Suc ac_simps) + by (simp add: pochhammer_setprod atLeast0_lessThan_Suc ac_simps) +end + lemma pochhammer_of_nat: "pochhammer (of_nat x) n = of_nat (pochhammer x n)" - by (simp add: pochhammer_def) + by (simp add: pochhammer_setprod) lemma pochhammer_of_int: "pochhammer (of_int x) n = of_int (pochhammer x n)" - by (simp add: pochhammer_def) - -lemma setprod_nat_ivl_Suc: "setprod f {.. Suc n} = setprod f {..n} * f (Suc n)" -proof - - have "{..Suc n} = {..n} \ {Suc n}" by auto - then show ?thesis by (simp add: field_simps) -qed - -lemma setprod_nat_ivl_1_Suc: "setprod f {.. Suc n} = f 0 * setprod f {1.. Suc n}" -proof - - have "{..Suc n} = {0} \ {1 .. Suc n}" by auto - then show ?thesis by simp -qed + by (simp add: pochhammer_setprod) lemma pochhammer_rec: "pochhammer a (Suc n) = a * pochhammer (a + 1) n" -proof (cases "n = 0") - case True - then show ?thesis by (simp add: pochhammer_Suc_setprod) -next - case False - have *: "finite {1 .. n}" "0 \ {1 .. n}" by auto - have eq: "insert 0 {1 .. n} = {..n}" by auto - have **: "(\n\{1..n}. a + of_nat n) = (\n\{.. n" shows "pochhammer (- (of_nat n :: 'a:: idom)) k = 0" - using assms by (auto simp add: pochhammer_def) + using assms by (auto simp add: pochhammer_setprod) lemma pochhammer_of_nat_eq_0_lemma': assumes kn: "k \ n" @@ -580,7 +583,7 @@ by (auto simp add: not_le[symmetric]) lemma pochhammer_eq_0_iff: "pochhammer a n = (0::'a::field_char_0) \ (\k < n. a = - of_nat k)" - by (auto simp add: pochhammer_def eq_neg_iff_add_eq_0) + by (auto simp add: pochhammer_setprod eq_neg_iff_add_eq_0) lemma pochhammer_eq_0_mono: "pochhammer a n = (0::'a::field_char_0) \ m \ n \ pochhammer a m = 0" @@ -591,19 +594,18 @@ unfolding pochhammer_eq_0_iff by auto lemma pochhammer_minus: - "pochhammer (- b) k = ((- 1) ^ k :: 'a::comm_ring_1) * pochhammer (b - of_nat k + 1) k" + "pochhammer (- b) k = ((- 1) ^ k :: 'a::comm_ring_1) * pochhammer (b - of_nat k + 1) k" proof (cases k) case 0 then show ?thesis by simp next case (Suc h) - have eq: "((- 1) ^ Suc h :: 'a) = (\i\h. - 1)" - using setprod_constant[where A="{.. h}" and y="- 1 :: 'a"] + have eq: "((- 1) ^ Suc h :: 'a) = (\i = 0..h. - 1)" + using setprod_constant [where A="{0.. h}" and y="- 1 :: 'a"] by auto - show ?thesis - unfolding Suc pochhammer_Suc_setprod eq setprod.distrib[symmetric] - by (rule setprod.reindex_bij_witness[where i="op - h" and j="op - h"]) - (auto simp: of_nat_diff) + with Suc show ?thesis + using pochhammer_Suc_setprod_rev [of "b - of_nat k + 1"] + by (auto simp add: pochhammer_Suc_setprod setprod.distrib [symmetric] eq of_nat_diff) qed lemma pochhammer_minus': @@ -637,7 +639,7 @@ lemma pochhammer_times_pochhammer_half: fixes z :: "'a :: field_char_0" - shows "pochhammer z (Suc n) * pochhammer (z + 1/2) (Suc n) = (\k\2*n+1. z + of_nat k / 2)" + shows "pochhammer z (Suc n) * pochhammer (z + 1/2) (Suc n) = (\k=0..2*n+1. z + of_nat k / 2)" proof (induction n) case (Suc n) define n' where "n' = Suc n" @@ -648,10 +650,10 @@ also have "?A = (z + of_nat (Suc (2 * n + 1)) / 2) * (z + of_nat (Suc (Suc (2 * n + 1))) / 2)" (is "_ = ?A") by (simp add: field_simps n'_def) also note Suc[folded n'_def] - also have "(\k\2 * n + 1. z + of_nat k / 2) * ?A = (\k\2 * Suc n + 1. z + of_nat k / 2)" - by (simp add: setprod_nat_ivl_Suc) + also have "(\k=0..2 * n + 1. z + of_nat k / 2) * ?A = (\k=0..2 * Suc n + 1. z + of_nat k / 2)" + by (simp add: atLeast0_atMost_Suc) finally show ?case by (simp add: n'_def) -qed (simp add: setprod_nat_ivl_Suc) +qed (simp add: atLeast0_atMost_Suc) lemma pochhammer_double: fixes z :: "'a :: field_char_0" @@ -687,34 +689,39 @@ definition gbinomial :: "'a :: {semidom_divide, semiring_char_0} \ nat \ 'a" (infixl "gchoose" 65) where - "a gchoose n = setprod (\i. a - of_nat i) {..i. a - of_nat i) {0..i. a - of_nat i) {..k} / fact (Suc k)" - by (simp add: gbinomial_def lessThan_Suc_atMost) + "a gchoose (Suc k) = setprod (\i. a - of_nat i) {0..k} div fact (Suc k)" + by (simp add: gbinomial_setprod_rev atLeastLessThanSuc_atLeastAtMost) -lemma gbinomial_0 [simp]: +lemma gbinomial_mult_fact: fixes a :: "'a::field_char_0" - shows "a gchoose 0 = 1" "(0::'a) gchoose (Suc n) = 0" - by (simp_all add: gbinomial_def) + shows + "fact n * (a gchoose n) = (\i = 0..i = 0..i n") case False then have "n < k" by (simp add: not_le) - then have "0 \ (op - n) ` {.. (op - n) ` {0..n < k\ show ?thesis - by (simp add: binomial_eq_0 gbinomial_def setprod_zero) + by (simp add: binomial_eq_0 gbinomial_setprod_rev setprod_zero) next case True - then have "inj_on (op - n) {..(op - n ` {..(op - n ` {0..q. n - q) {..{Suc (n - k)..n}" .. + finally have *: "setprod (\q. n - q) {0..{Suc (n - k)..n}" .. from True have "(n choose k) = fact n div (fact k * fact (n - k))" by (rule binomial_fact') with * show ?thesis - by (simp add: gbinomial_def mult.commute [of "fact k"] div_mult2_eq fact_div_fact) + by (simp add: gbinomial_setprod_rev mult.commute [of "fact k"] div_mult2_eq fact_div_fact) +qed + +lemma of_nat_gbinomial: + "of_nat (n gchoose k) = (of_nat n gchoose k :: 'a::field_char_0)" +proof (cases "k \ n") + case False then show ?thesis + by (simp add: not_le gbinomial_binomial binomial_eq_0 gbinomial_setprod_rev) +next + case True + moreover define m where "m = n - k" + ultimately have n: "n = m + k" + by arith + from n have "fact n = ((\i = 0.. = ((\i\{0.. {k..i = 0..i. of_nat (m + k - i) :: 'a" 0 k m] + by (simp add: fact_setprod_rev [of m] setprod.union_disjoint of_nat_diff) + then have "fact n / fact (n - k) = + ((\i = 0.. n" - then have ?thesis - by (subst binomial_eq_0[OF kn]) - (simp add: gbinomial_pochhammer field_simps pochhammer_of_nat_eq_0_iff) } - moreover - { assume "k=0" then have ?thesis by simp } - moreover - { assume kn: "k \ n" and k0: "k\ 0" - from k0 obtain h where h: "k = Suc h" by (cases k) auto - from h - have eq:"(- 1 :: 'a) ^ k = setprod (\i. - 1) {..h}" - by (subst setprod_constant) auto - have eq': "(\i\h. of_nat n + - (of_nat i :: 'a)) = (\i\{n - h..n}. of_nat i)" - using h kn - by (intro setprod.reindex_bij_witness[where i="op - n" and j="op - n"]) - (auto simp: of_nat_diff) - have th0: "finite {1..n - Suc h}" "finite {n - h .. n}" - "{1..n - Suc h} \ {n - h .. n} = {}" and - eq3: "{1..n - Suc h} \ {n - h .. n} = {1..n}" - using h kn by auto - from eq[symmetric] - have ?thesis using kn - apply (simp add: binomial_fact[OF kn, where ?'a = 'a] - gbinomial_pochhammer field_simps pochhammer_Suc_setprod) - apply (simp add: pochhammer_Suc_setprod fact_altdef h - setprod.distrib[symmetric] eq' del: One_nat_def power_Suc) - unfolding setprod.union_disjoint[OF th0, unfolded eq3, of "of_nat:: nat \ 'a"] eq[unfolded h] - unfolding mult.assoc - unfolding setprod.distrib[symmetric] - apply simp - apply (intro setprod.reindex_bij_witness[where i="op - n" and j="op - n"]) - apply (auto simp: of_nat_diff) - done - } - moreover - have "k > n \ k = 0 \ (k \ n \ k \ 0)" by arith - ultimately show ?thesis by blast -qed + "of_nat (n choose k) = (of_nat n gchoose k :: 'a::field_char_0)" + by (simp add: gbinomial_binomial [symmetric] of_nat_gbinomial) setup \Sign.add_const_constraint (@{const_name gbinomial}, SOME @{typ "'a::field_char_0 \ nat \ 'a"})\ lemma gbinomial_1[simp]: "a gchoose 1 = a" - by (simp add: gbinomial_def lessThan_Suc) + by (simp add: gbinomial_setprod_rev lessThan_Suc) lemma gbinomial_Suc0[simp]: "a gchoose (Suc 0) = a" - by (simp add: gbinomial_def lessThan_Suc) + by (simp add: gbinomial_setprod_rev lessThan_Suc) lemma gbinomial_mult_1: fixes a :: "'a :: field_char_0" @@ -819,19 +816,6 @@ shows "(a gchoose n) * a = of_nat n * (a gchoose n) + of_nat (Suc n) * (a gchoose (Suc n))" by (simp add: mult.commute gbinomial_mult_1) -lemma gbinomial_mult_fact: - fixes a :: "'a::field_char_0" - shows - "fact (Suc k) * (a gchoose (Suc k)) = - (setprod (\i. a - of_nat i) {.. k})" - by (simp_all add: gbinomial_Suc field_simps del: fact_Suc) - -lemma gbinomial_mult_fact': - fixes a :: "'a::field_char_0" - shows "(a gchoose (Suc k)) * fact (Suc k) = (setprod (\i. a - of_nat i) {.. k})" - using gbinomial_mult_fact[of k a] - by (subst mult.commute) - lemma gbinomial_Suc_Suc: fixes a :: "'a :: field_char_0" shows "(a + 1) gchoose (Suc k) = a gchoose k + (a gchoose (Suc k))" @@ -840,7 +824,7 @@ then show ?thesis by simp next case (Suc h) - have eq0: "(\i\{1..k}. (a + 1) - of_nat i) = (\i\{..h}. a - of_nat i)" + have eq0: "(\i\{1..k}. (a + 1) - of_nat i) = (\i\{0..h}. a - of_nat i)" apply (rule setprod.reindex_cong [where l = Suc]) using Suc apply (auto simp add: image_Suc_atMost) @@ -850,32 +834,33 @@ (a gchoose Suc (Suc h)) * (fact (Suc (Suc h)))" by (simp add: Suc field_simps del: fact_Suc) also have "... = (a gchoose Suc h) * of_nat (Suc (Suc h) * fact (Suc h)) + - (\i\Suc h. a - of_nat i)" - by (metis fact_Suc gbinomial_mult_fact' of_nat_fact of_nat_id) + (\i=0..Suc h. a - of_nat i)" + apply (simp del: fact_Suc add: gbinomial_mult_fact field_simps mult.left_commute [of _ "2"]) + apply (simp del: fact_Suc add: fact_Suc [of "Suc h"] field_simps gbinomial_mult_fact mult.left_commute [of _ "2"] atLeastLessThanSuc_atLeastAtMost) + done also have "... = (fact (Suc h) * (a gchoose Suc h)) * of_nat (Suc (Suc h)) + - (\i\Suc h. a - of_nat i)" + (\i=0..Suc h. a - of_nat i)" by (simp only: fact_Suc mult.commute mult.left_commute of_nat_fact of_nat_id of_nat_mult) - also have "... = of_nat (Suc (Suc h)) * (\i\h. a - of_nat i) + - (\i\Suc h. a - of_nat i)" - by (metis gbinomial_mult_fact mult.commute) - also have "... = (\i\Suc h. a - of_nat i) + - (of_nat h * (\i\h. a - of_nat i) + 2 * (\i\h. a - of_nat i))" + also have "... = of_nat (Suc (Suc h)) * (\i=0..h. a - of_nat i) + + (\i=0..Suc h. a - of_nat i)" + unfolding gbinomial_mult_fact atLeastLessThanSuc_atLeastAtMost by auto + also have "... = (\i=0..Suc h. a - of_nat i) + + (of_nat h * (\i=0..h. a - of_nat i) + 2 * (\i=0..h. a - of_nat i))" by (simp add: field_simps) also have "... = - ((a gchoose Suc h) * (fact (Suc h)) * of_nat (Suc k)) + (\i\{..Suc h}. a - of_nat i)" + ((a gchoose Suc h) * (fact (Suc h)) * of_nat (Suc k)) + (\i\{0..Suc h}. a - of_nat i)" unfolding gbinomial_mult_fact' - by (simp add: comm_semiring_class.distrib field_simps Suc) - also have "\ = (\i\{..h}. a - of_nat i) * (a + 1)" - unfolding gbinomial_mult_fact' setprod_nat_ivl_Suc - atMost_Suc - by (simp add: field_simps Suc) - also have "\ = (\i\{..k}. (a + 1) - of_nat i)" - using eq0 setprod_nat_ivl_1_Suc - by (simp add: Suc setprod_nat_ivl_1_Suc) + by (simp add: comm_semiring_class.distrib field_simps Suc atLeastLessThanSuc_atLeastAtMost) + also have "\ = (\i\{0..h}. a - of_nat i) * (a + 1)" + unfolding gbinomial_mult_fact' atLeast0_atMost_Suc + by (simp add: field_simps Suc atLeastLessThanSuc_atLeastAtMost) + also have "\ = (\i\{0..k}. (a + 1) - of_nat i)" + using eq0 + by (simp add: Suc setprod.atLeast0_atMost_Suc_shift) also have "\ = (fact (Suc k)) * ((a + 1) gchoose (Suc k))" - unfolding gbinomial_mult_fact .. + unfolding gbinomial_mult_fact atLeastLessThanSuc_atLeastAtMost .. finally show ?thesis - by (metis fact_nonzero mult_cancel_left) + using fact_nonzero [of "Suc k"] by auto qed lemma gbinomial_reduce_nat: @@ -992,17 +977,9 @@ Alternative definition of the binomial coefficient as @{term "\i lemma gbinomial_altdef_of_nat: fixes k :: nat - and x :: "'a :: {field_char_0,field}" - shows "x gchoose k = (\ii = (\ii = 0.. x" using assms of_nat_0_le_iff order_trans by blast - have "(x / of_nat k :: 'a) ^ k = (\ii = 0.. \ x gchoose k" unfolding gbinomial_altdef_of_nat - proof (safe intro!: setprod_mono) + proof (safe intro!: setprod_mono, simp_all) -- \FIXME\ fix i :: nat assume ik: "i < k" from assms have "x * of_nat i \ of_nat (i * k)" @@ -1044,12 +1021,12 @@ proof (cases b) case (Suc b) hence "((a + 1) gchoose (Suc (Suc b))) = - (\i\Suc b. a + (1 - of_nat i)) / fact (b + 2)" - by (simp add: field_simps gbinomial_def lessThan_Suc_atMost) - also have "(\i\Suc b. a + (1 - of_nat i)) = (a + 1) * (\i\b. a - of_nat i)" - by (simp add: setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl atLeast0AtMost) + (\i = 0..Suc b. a + (1 - of_nat i)) / fact (b + 2)" + by (simp add: field_simps gbinomial_setprod_rev atLeastLessThanSuc_atLeastAtMost) + also have "(\i = 0..Suc b. a + (1 - of_nat i)) = (a + 1) * (\i = 0..b. a - of_nat i)" + by (simp add: setprod.atLeast0_atMost_Suc_shift) 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 lessThan_Suc_atMost) + by (simp_all add: gbinomial_setprod_rev atLeastLessThanSuc_atLeastAtMost) finally show ?thesis by (simp add: Suc field_simps del: of_nat_Suc) qed simp @@ -1058,12 +1035,12 @@ proof (cases b) case (Suc b) hence "((a + 1) gchoose (Suc (Suc b))) = - (\i\Suc b. a + (1 - of_nat i)) / fact (b + 2)" - by (simp add: field_simps gbinomial_def lessThan_Suc_atMost) - also have "(\i\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) + (\i = 0 .. Suc b. a + (1 - of_nat i)) / fact (b + 2)" + by (simp add: field_simps gbinomial_setprod_rev atLeastLessThanSuc_atLeastAtMost) + also have "(\i = 0 .. Suc b. a + (1 - of_nat i)) = (a + 1) * (\i = 0..b. a - of_nat i)" + by (simp add: setprod.atLeast0_atMost_Suc_shift) 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 lessThan_Suc_atMost atLeast0AtMost) + by (simp_all add: gbinomial_setprod_rev atLeastLessThanSuc_atLeastAtMost atLeast0AtMost) finally show ?thesis by (simp add: Suc) qed simp @@ -1256,10 +1233,6 @@ 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))" @@ -1273,7 +1246,8 @@ 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) + using setsum.atLeast_atMost_rev [of "\k. 2 * m + 1 choose (m - k)" 0 m] + by simp also have "\ + \ = 2 * \" by simp finally show ?thesis by (subst (asm) mult_cancel1) (simp add: atLeast0AtMost) qed @@ -1316,11 +1290,10 @@ text\Versions of the theorems above for the natural-number version of "choose"\ lemma binomial_altdef_of_nat: fixes n k :: nat - and x :: "'a :: {field_char_0,field}" \\the point is to constrain @{typ 'a}\ + and x :: "'a :: field_char_0" assumes "k \ n" - shows "of_nat (n choose k) = (\ii = 0..{1..n}) :: 'a)" by (simp add: fact_altdef') + have "fact n = (of_nat (\{1..n}) :: 'a)" + by (simp add: fact_setprod) also have "\{1..n} = \{2..n}" by (intro setprod.mono_neutral_right) auto also have "\ = fold_atLeastAtMost_nat (op *) 2 n 1" @@ -1601,19 +1575,15 @@ finally show ?thesis . qed -lemma setprod_lessThan_fold_atLeastAtMost_nat: - "setprod f {.. f) 0 n 1" - by (simp add: lessThan_Suc_atMost atLeast0AtMost [symmetric] setprod_atLeastAtMost_code comp_def) - lemma pochhammer_code [code]: "pochhammer a n = (if n = 0 then 1 else - fold_atLeastAtMost_nat (\n acc. (a + of_nat n) * acc) 0 (n - 1) 1)" - by (cases n) (simp_all add: pochhammer_def setprod_lessThan_fold_atLeastAtMost_nat comp_def) + fold_atLeastAtMost_nat (\n acc. (a + of_nat n) * acc) 0 (n - 1) 1)" + by (cases n) (simp_all add: pochhammer_setprod setprod_atLeastAtMost_code [symmetric] atLeastLessThanSuc_atLeastAtMost) lemma gbinomial_code [code]: "a gchoose n = (if n = 0 then 1 else fold_atLeastAtMost_nat (\n acc. (a - of_nat n) * acc) 0 (n - 1) 1 / fact n)" - by (cases n) (simp_all add: gbinomial_def setprod_lessThan_fold_atLeastAtMost_nat comp_def) + by (cases n) (simp_all add: gbinomial_setprod_rev setprod_atLeastAtMost_code [symmetric] atLeastLessThanSuc_atLeastAtMost) (*TODO: This code equation breaks Scala code generation in HOL-Codegenerator_Test. We have to figure out why and how to prevent that. *) diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Decision_Procs/Approximation.thy --- a/src/HOL/Decision_Procs/Approximation.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Decision_Procs/Approximation.thy Sat Jul 09 13:26:16 2016 +0200 @@ -4027,7 +4027,7 @@ qed lemma setprod_fact: "real (\ {1..<1 + k}) = fact (k :: nat)" -by (metis Suc_eq_plus1_left atLeastLessThanSuc_atLeastAtMost fact_altdef_nat of_nat_fact) + by (simp add: fact_setprod atLeastLessThanSuc_atLeastAtMost) lemma approx_tse: assumes "bounded_by xs vs" diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Divides.thy --- a/src/HOL/Divides.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Divides.thy Sat Jul 09 13:26:16 2016 +0200 @@ -1432,6 +1432,15 @@ apply (metis (full_types) One_nat_def Suc_lessI div_less_dividend less_not_refl3) done +lemma (in field_char_0) of_nat_div: + "of_nat (m div n) = ((of_nat m - of_nat (m mod n)) / of_nat n)" +proof - + have "of_nat (m div n) = ((of_nat (m div n * n + m mod n) - of_nat (m mod n)) / of_nat n :: 'a)" + unfolding of_nat_add by (cases "n = 0") simp_all + then show ?thesis + by simp +qed + subsubsection \An ``induction'' law for modulus arithmetic.\ diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Library/Formal_Power_Series.thy --- a/src/HOL/Library/Formal_Power_Series.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Library/Formal_Power_Series.thy Sat Jul 09 13:26:16 2016 +0200 @@ -1711,7 +1711,7 @@ lemma fps_deriv_maclauren_0: "(fps_nth_deriv k (f :: 'a::comm_semiring_1 fps)) $ 0 = of_nat (fact k) * f $ k" - by (induct k arbitrary: f) (auto simp add: field_simps of_nat_mult) + by (induct k arbitrary: f) (auto simp add: field_simps) subsection \Powers\ @@ -3701,7 +3701,7 @@ have "?l$n = ?r $ n" for n apply (auto simp add: E_def field_simps power_Suc[symmetric] simp del: fact_Suc of_nat_Suc power_Suc) - apply (simp add: of_nat_mult field_simps) + apply (simp add: field_simps) done then show ?thesis by (simp add: fps_eq_iff) @@ -4110,6 +4110,7 @@ (is ?pochhammer) if kn: "k \ {0..n}" for k proof - + from kn have "k \ n" by simp have nz: "pochhammer (1 + b - of_nat n) n \ 0" proof assume "pochhammer (1 + b - of_nat n) n = 0" @@ -4169,32 +4170,25 @@ by (intro setprod.reindex_bij_witness[where i="\k. Suc m - k" and j="\k. Suc m - k"]) (auto simp: of_nat_diff) have th1: "(?m1 k * ?p (of_nat n) k) / ?f n = 1 / of_nat(fact (n - k))" - unfolding m1nk - apply (simp add: field_simps m h pochhammer_Suc_setprod del: fact_Suc) - apply (simp add: fact_altdef id_def atLeast0AtMost setprod.distrib [symmetric] eq1) - apply (subst setprod.union_disjoint [symmetric]) - apply (auto intro!: setprod.cong) + apply (simp add: pochhammer_minus field_simps) + using \k \ n\ apply (simp add: fact_split [of k n]) + apply (simp add: pochhammer_setprod) + using setprod.atLeast_lessThan_shift_bounds [where ?'a = 'a, of "\i. 1 + of_nat i" 0 "n - k" k] + apply (auto simp add: of_nat_diff field_simps) done - have th20: "?m1 n * ?p b n = setprod (\i. b - of_nat i) {..m}" - unfolding m1nk - unfolding m h pochhammer_Suc_setprod - unfolding setprod.distrib[symmetric] - apply (rule setprod.cong) - apply auto + have th20: "?m1 n * ?p b n = setprod (\i. b - of_nat i) {0..m}" + apply (simp add: pochhammer_minus field_simps m) + apply (auto simp add: pochhammer_setprod_rev of_nat_diff setprod.atLeast_Suc_atMost_Suc_shift) done have th21:"pochhammer (b - of_nat n + 1) k = setprod (\i. b - of_nat i) {n - k .. n - 1}" - unfolding h m - unfolding pochhammer_Suc_setprod - using kn m h - by (intro setprod.reindex_bij_witness[where i="\k. n - 1 - k" and j="\i. m-i"]) - (auto simp: of_nat_diff) - + using kn apply (simp add: pochhammer_setprod_rev m h setprod.atLeast_Suc_atMost_Suc_shift) + using setprod.atLeast_atMost_shift_0 [of "m - h" m, where ?'a = 'a] + apply (auto simp add: of_nat_diff field_simps) + done have "?m1 n * ?p b n = - pochhammer (b - of_nat n + 1) k * setprod (\i. b - of_nat i) {0.. n - k - 1}" - unfolding th20 th21 - unfolding h m - apply (subst setprod.union_disjoint[symmetric]) - using kn' h m + setprod (\i. b - of_nat i) {0.. n - k - 1} * pochhammer (b - of_nat n + 1) k" + using kn' m h unfolding th20 th21 apply simp + apply (subst setprod.union_disjoint [symmetric]) apply auto apply (rule setprod.cong) apply auto @@ -4208,10 +4202,11 @@ by (simp add: field_simps) also have "\ = b gchoose (n - k)" unfolding th1 th2 - using kn' apply (simp add: gbinomial_def atLeast0AtMost) - apply (rule setprod.cong) - apply auto - done + using kn' m h + apply (simp add: field_simps gbinomial_mult_fact) + apply (rule setprod.cong) + apply auto + done finally show ?thesis by simp qed qed @@ -4230,10 +4225,6 @@ unfolding gbinomial_pochhammer using bn0 apply (simp add: setsum_left_distrib setsum_right_distrib field_simps) - apply (rule setsum.cong) - apply (rule refl) - apply (drule th00(2)) - apply (simp add: field_simps power_add[symmetric]) done finally show ?thesis by simp qed @@ -4355,7 +4346,7 @@ apply (cases n) apply simp apply (simp add: nonzero_divide_eq_eq nonzero_eq_divide_eq del: of_nat_Suc fact_Suc) - apply (simp add: of_nat_mult del: of_nat_Suc mult_Suc) + apply simp done lemma fps_cos_nth_0 [simp]: "fps_cos c $ 0 = 1" @@ -4368,7 +4359,7 @@ "fps_cos c $ (n + 2) = - (c * c * fps_cos c $ n / (of_nat (n + 1) * of_nat (n + 2)))" unfolding fps_cos_def apply (simp add: nonzero_divide_eq_eq nonzero_eq_divide_eq del: of_nat_Suc fact_Suc) - apply (simp add: of_nat_mult del: of_nat_Suc mult_Suc) + apply simp done lemma nat_induct2: "P 0 \ P 1 \ (\n. P n \ P (n + 2)) \ P (n::nat)" @@ -4593,7 +4584,7 @@ apply (simp del: of_nat_Suc of_nat_add fact_Suc) apply (simp add: foldl_mult_start del: fact_Suc of_nat_Suc) unfolding foldl_prod_prod[unfolded foldl_mult_start] pochhammer_Suc - apply (simp add: algebra_simps of_nat_mult) + apply (simp add: algebra_simps) done lemma XD_nth[simp]: "XD a $ n = (if n = 0 then 0 else of_nat n * a$n)" diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Multivariate_Analysis/Gamma.thy --- a/src/HOL/Multivariate_Analysis/Gamma.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Multivariate_Analysis/Gamma.thy Sat Jul 09 13:26:16 2016 +0200 @@ -504,18 +504,21 @@ assumes "n > 0" "z \ \\<^sub>\\<^sub>0" shows "exp (ln_Gamma_series z n :: complex) = Gamma_series z n" proof - + from assms obtain m where m: "n = Suc m" by (cases n) blast from assms have "z \ 0" by (intro notI) auto with assms have "exp (ln_Gamma_series z n) = (of_nat n) powr z / (z * (\k=1..n. exp (Ln (z / of_nat k + 1))))" unfolding ln_Gamma_series_def powr_def by (simp add: exp_diff exp_setsum) also from assms have "(\k=1..n. exp (Ln (z / of_nat k + 1))) = (\k=1..n. z / of_nat k + 1)" by (intro setprod.cong[OF refl], subst exp_Ln) (auto simp: field_simps plus_of_nat_eq_0_imp) - also have "... = (\k=1..n. z + k) / fact n" unfolding fact_altdef - by (subst setprod_dividef [symmetric]) (simp_all add: field_simps) - also from assms have "z * ... = (\k\n. z + k) / fact n" - by (cases n) (simp_all add: setprod_nat_ivl_1_Suc) - also have "(\k\n. z + k) = pochhammer z (Suc n)" unfolding pochhammer_def - by (simp add: lessThan_Suc_atMost) + also have "... = (\k=1..n. z + k) / fact n" + by (simp add: fact_setprod) + (subst setprod_dividef [symmetric], simp_all add: field_simps) + also from m have "z * ... = (\k=0..n. z + k) / fact n" + by (simp add: setprod.atLeast0_atMost_Suc_shift setprod.atLeast_Suc_atMost_Suc_shift) + also have "(\k=0..n. z + k) = pochhammer z (Suc n)" + unfolding pochhammer_setprod + by (simp add: setprod.atLeast0_atMost_Suc atLeastLessThanSuc_atLeastAtMost) also have "of_nat n powr z / (pochhammer z (Suc n) / fact n) = Gamma_series z n" unfolding Gamma_series_def using assms by (simp add: divide_simps powr_def Ln_of_nat) finally show ?thesis . @@ -999,7 +1002,7 @@ case False hence "z \ - of_nat n" for n by auto from rGamma_series_aux[OF this] show ?thesis - by (simp add: rGamma_series_def[abs_def] fact_altdef pochhammer_Suc_setprod + by (simp add: rGamma_series_def[abs_def] fact_setprod pochhammer_Suc_setprod exp_def of_real_def[symmetric] suminf_def sums_def[abs_def] atLeast0AtMost) qed (insert rGamma_eq_zero_iff[of z], simp_all add: rGamma_series_nonpos_Ints_LIMSEQ) @@ -1149,7 +1152,7 @@ apply (rule has_field_derivative_at_within) using differentiable_rGamma_aux2[of n] unfolding Let_def has_field_derivative_def has_derivative_def netlimit_at - by (simp only: bounded_linear_mult_right mult_ac of_real_def [symmetric] fact_altdef) + by (simp only: bounded_linear_mult_right mult_ac of_real_def [symmetric] fact_setprod) simp lemma has_field_derivative_rGamma [derivative_intros]: "(rGamma has_field_derivative (if z \ \\<^sub>\\<^sub>0 then (-1)^(nat \norm z\) * fact (nat \norm z\) @@ -1355,7 +1358,7 @@ from has_field_derivative_rGamma_complex_nonpos_Int[of n] show "let z = - of_nat n in (\y. (rGamma y - rGamma z - (- 1) ^ n * setprod of_nat {1..n} * (y - z)) /\<^sub>R cmod (y - z)) \z\ 0" - by (simp add: has_field_derivative_def has_derivative_def fact_altdef netlimit_at Let_def) + by (simp add: has_field_derivative_def has_derivative_def fact_setprod netlimit_at Let_def) next fix z :: complex from rGamma_series_complex_converges[of z] have "rGamma_series z \ rGamma z" @@ -1364,7 +1367,7 @@ exp = \x. THE e. (\n. \kR fact k) \ e; pochhammer' = \a n. \n = 0..n. a + of_nat n in (\n. pochhammer' z n / (fact' n * exp (z * ln (real_of_nat n) *\<^sub>R 1))) \ rGamma z" - by (simp add: fact_altdef pochhammer_Suc_setprod rGamma_series_def [abs_def] exp_def + by (simp add: fact_setprod pochhammer_Suc_setprod rGamma_series_def [abs_def] exp_def of_real_def [symmetric] suminf_def sums_def [abs_def] atLeast0AtMost) qed @@ -1485,7 +1488,7 @@ simp: Polygamma_of_real rGamma_real_def [abs_def]) thus "let x = - of_nat n in (\y. (rGamma y - rGamma x - (- 1) ^ n * setprod of_nat {1..n} * (y - x)) /\<^sub>R norm (y - x)) \x::real\ 0" - by (simp add: has_field_derivative_def has_derivative_def fact_altdef netlimit_at Let_def) + by (simp add: has_field_derivative_def has_derivative_def fact_setprod netlimit_at Let_def) next fix x :: real have "rGamma_series x \ rGamma x" @@ -1497,7 +1500,7 @@ exp = \x. THE e. (\n. \kR fact k) \ e; pochhammer' = \a n. \n = 0..n. a + of_nat n in (\n. pochhammer' x n / (fact' n * exp (x * ln (real_of_nat n) *\<^sub>R 1))) \ rGamma x" - by (simp add: fact_altdef pochhammer_Suc_setprod rGamma_series_def [abs_def] exp_def + by (simp add: fact_setprod pochhammer_Suc_setprod rGamma_series_def [abs_def] exp_def of_real_def [symmetric] suminf_def sums_def [abs_def] atLeast0AtMost) qed @@ -2424,8 +2427,8 @@ (simp_all add: Gamma_series_euler'_def setprod.distrib setprod_inversef[symmetric] divide_inverse) also have "(\k=1..n. (1 + z / of_nat k)) = pochhammer (z + 1) n / fact n" - by (cases n) (simp_all add: pochhammer_def fact_altdef setprod_shift_bounds_cl_Suc_ivl - setprod_dividef[symmetric] divide_simps add_ac atLeast0AtMost lessThan_Suc_atMost) + by (cases n) (simp_all add: pochhammer_setprod fact_setprod atLeastLessThanSuc_atLeastAtMost + setprod_dividef [symmetric] field_simps setprod.atLeast_Suc_atMost_Suc_shift) also have "z * \ = pochhammer z (Suc n) / fact n" by (simp add: pochhammer_rec) finally show "?r n = Gamma_series_euler' z n / Gamma_series z n" by simp qed @@ -2679,7 +2682,7 @@ using Suc.IH[of "z+1"] Suc.prems by (intro has_integral_mult_left) (simp_all add: add_ac pochhammer_rec) also have "?A = (\t. ?f t * ?g' t)" by (intro ext) (simp_all add: field_simps) also have "?B = - (of_nat (Suc n) * fact n / pochhammer z (n+2))" - by (simp add: divide_simps setprod_nat_ivl_1_Suc pochhammer_rec + by (simp add: divide_simps pochhammer_rec setprod_shift_bounds_cl_Suc_ivl del: of_nat_Suc) finally show "((\t. ?f t * ?g' t) has_integral (?f 1 * ?g 1 - ?f 0 * ?g 0 - ?I)) {0..1}" by simp diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Multivariate_Analysis/Generalised_Binomial_Theorem.thy --- a/src/HOL/Multivariate_Analysis/Generalised_Binomial_Theorem.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Multivariate_Analysis/Generalised_Binomial_Theorem.thy Sat Jul 09 13:26:16 2016 +0200 @@ -27,12 +27,13 @@ show "eventually (\n. ?f n = (a gchoose n) /(a gchoose Suc n)) sequentially" proof eventually_elim fix n :: nat assume n: "n > 0" - let ?P = "\ii\n. a - of_nat i))" - by (simp add: gbinomial_def lessThan_Suc_atMost) - also from n have "(\i\n. a - of_nat i) = ?P * (a - of_nat n)" - by (cases n) (simp_all add: setprod_nat_ivl_Suc lessThan_Suc_atMost) + (?P / (\i=0..n. a - of_nat i))" + by (simp add: gbinomial_setprod_rev atLeastLessThanSuc_atLeastAtMost) + also from q have "(\i=0..n. a - of_nat i) = ?P * (a - of_nat n)" + by (simp add: setprod.atLeast0_atMost_Suc atLeastLessThanSuc_atLeastAtMost) also have "?P / \ = (?P / ?P) / (a - of_nat n)" by (rule divide_divide_eq_left[symmetric]) also from assms have "?P / ?P = 1" by auto also have "of_nat (Suc n) * (1 / (a - of_nat n)) = @@ -119,7 +120,7 @@ have "\c. \z\ball 0 K. f z * (1 + z) powr (-a) = c" proof (rule has_field_derivative_zero_constant) fix z :: complex assume z': "z \ ball 0 K" - hence z: "norm z < K" by (simp add: dist_0_norm) + hence z: "norm z < K" by simp with K have nz: "1 + z \ 0" by (auto dest!: minus_unique) from z K have "norm z < 1" by simp hence "(1 + z) \ \\<^sub>\\<^sub>0" by (cases z) (auto simp: complex_nonpos_Reals_iff) @@ -209,7 +210,7 @@ also have "(of_real (1 + z) :: complex) powr (of_real a) = of_real ((1 + z) powr a)" using assms by (subst powr_of_real) simp_all also have "(of_real a gchoose n :: complex) = of_real (a gchoose n)" for n - by (simp add: gbinomial_def) + by (simp add: gbinomial_setprod_rev) hence "(\n. (of_real a gchoose n :: complex) * of_real z ^ n) = (\n. of_real ((a gchoose n) * z ^ n))" by (intro ext) simp finally show ?thesis by (simp only: sums_of_real_iff) diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Multivariate_Analysis/ex/Approximations.thy --- a/src/HOL/Multivariate_Analysis/ex/Approximations.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Multivariate_Analysis/ex/Approximations.thy Sat Jul 09 13:26:16 2016 +0200 @@ -185,11 +185,11 @@ also have "\ = (\k\n. 1 / fact k)" proof (intro setsum.cong refl) fix k assume k: "k \ {..n}" - have "fact n = (\i=1..n. real i)" by (rule fact_altdef) + have "fact n = (\i=1..n. real i)" by (simp add: fact_setprod) also from k have "{1..n} = {1..k} \ {k+1..n}" by auto also have "setprod real \ / (\i=k+1..n. real i) = (\i=1..k. real i)" by (subst nonzero_divide_eq_eq, simp, subst setprod.union_disjoint [symmetric]) auto - also have "\ = fact k" by (simp only: fact_altdef) + also have "\ = fact k" by (simp add: fact_setprod) finally show "1 / (fact n / setprod real {k + 1..n}) = 1 / fact k" by simp qed also have "\ = euler_approx n" by (simp add: euler_approx_def field_simps) diff -r 6af79184bef3 -r c184ec919c70 src/HOL/NthRoot.thy --- a/src/HOL/NthRoot.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/NthRoot.thy Sat Jul 09 13:26:16 2016 +0200 @@ -246,7 +246,7 @@ have "continuous_on ({0..} \ {.. 0}) (\x. if 0 < x then x ^ n else - ((-x) ^ n) :: real)" using n by (intro continuous_on_If continuous_intros) auto then have "continuous_on UNIV ?f" - by (rule continuous_on_cong[THEN iffD1, rotated 2]) (auto simp: not_less sgn_neg le_less n) + by (rule continuous_on_cong[THEN iffD1, rotated 2]) (auto simp: not_less le_less n) then have [simp]: "\x. isCont ?f x" by (simp add: continuous_on_eq_continuous_at) @@ -654,8 +654,7 @@ (simp_all add: at_infinity_eq_at_top_bot) { fix n :: nat assume "2 < n" have "1 + (real (n - 1) * n) / 2 * x n^2 = 1 + of_nat (n choose 2) * x n^2" - using \2 < n\ unfolding gbinomial_def binomial_gbinomial - by (simp add: atLeast0AtMost lessThan_Suc field_simps of_nat_diff numeral_2_eq_2) + by (auto simp add: choose_two of_nat_div mod_eq_0_iff_dvd) also have "\ \ (\k\{0, 2}. of_nat (n choose k) * x n^k)" by (simp add: x_def) also have "\ \ (\k=0..n. of_nat (n choose k) * x n^k)" @@ -692,8 +691,7 @@ (simp_all add: at_infinity_eq_at_top_bot) { fix n :: nat assume "1 < n" have "1 + x n * n = 1 + of_nat (n choose 1) * x n^1" - using \1 < n\ unfolding gbinomial_def binomial_gbinomial - by (simp add: lessThan_Suc) + by (simp add: choose_one) also have "\ \ (\k\{0, 1}. of_nat (n choose k) * x n^k)" by (simp add: x_def) also have "\ \ (\k=0..n. of_nat (n choose k) * x n^k)" diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Number_Theory/Residues.thy --- a/src/HOL/Number_Theory/Residues.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Number_Theory/Residues.thy Sat Jul 09 13:26:16 2016 +0200 @@ -426,7 +426,7 @@ apply auto done also have "\ = fact (p - 1) mod p" - apply (subst fact_altdef_nat) + apply (simp add: fact_setprod) apply (insert assms) apply (subst res_prime_units_eq) apply (simp add: int_setprod zmod_int setprod_int_eq) @@ -443,7 +443,7 @@ proof (cases "p = 2") case True then show ?thesis - by (simp add: cong_int_def fact_altdef_nat) + by (simp add: cong_int_def fact_setprod) next case False then show ?thesis diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Power.thy --- a/src/HOL/Power.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Power.thy Sat Jul 09 13:26:16 2016 +0200 @@ -164,7 +164,7 @@ lemma of_nat_power [simp]: "of_nat (m ^ n) = of_nat m ^ n" - by (induct n) (simp_all add: of_nat_mult) + by (induct n) simp_all lemma zero_power: "0 < n \ 0 ^ n = 0" @@ -645,10 +645,10 @@ by (simp add: le_less) lemma abs_power2 [simp]: "\a\<^sup>2\ = a\<^sup>2" - by (simp add: power2_eq_square abs_mult abs_mult_self) + by (simp add: power2_eq_square) lemma power2_abs [simp]: "\a\\<^sup>2 = a\<^sup>2" - by (simp add: power2_eq_square abs_mult_self) + by (simp add: power2_eq_square) lemma odd_power_less_zero: "a < 0 \ a ^ Suc (2*n) < 0" @@ -749,6 +749,18 @@ "(x - y)\<^sup>2 = (y - x)\<^sup>2" by (simp add: algebra_simps power2_eq_square) +lemma (in comm_ring_1) minus_power_mult_self: + "(- a) ^ n * (- a) ^ n = a ^ (2 * n)" + by (simp add: power_mult_distrib [symmetric]) (simp add: power2_eq_square [symmetric] power_mult [symmetric]) + +lemma (in comm_ring_1) minus_one_mult_self [simp]: + "(- 1) ^ n * (- 1) ^ n = 1" + using minus_power_mult_self [of 1 n] by simp + +lemma (in comm_ring_1) left_minus_one_mult_self [simp]: + "(- 1) ^ n * ((- 1) ^ n * a) = a" + by (simp add: mult.assoc [symmetric]) + text \Simprules for comparisons where common factors can be cancelled.\ lemmas zero_compare_simps = diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Set_Interval.thy --- a/src/HOL/Set_Interval.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Set_Interval.thy Sat Jul 09 13:26:16 2016 +0200 @@ -743,18 +743,43 @@ used, the opposite orientation seems preferable because it reduces a specific concept to a more general one.\ -lemma atLeast0LessThan: "{0::nat..The Constant @{term atLeastAtMost}\ + +lemma atLeast0_atMost_Suc: + "{0..Suc n} = insert (Suc n) {0..n}" + by (simp add: atLeast0AtMost atMost_Suc) + +lemma atLeast0_atMost_Suc_eq_insert_0: + "{0..Suc n} = insert 0 (Suc ` {0..n})" + by (simp add: atLeast0AtMost Iic_Suc_eq_insert_0) + + subsubsection \Intervals of nats with @{term Suc}\ text\Not a simprule because the RHS is too messy.\ @@ -1164,11 +1189,17 @@ lemma card_greaterThanLessThan [simp]: "card {l<.. {.. {0.. {0..n}" + shows "finite N" + using assms finite_atLeastAtMost by (rule finite_subset) lemma ex_bij_betw_nat_finite: "finite M \ \h. bij_betw h {0.. \h. bij_betw h M {0.. finite B \ card A = card B \ EX h. bij_betw h A B" apply(drule ex_bij_betw_finite_nat) @@ -1236,12 +1255,12 @@ ultimately show "(\f. inj_on f A \ f ` A \ B)" by blast qed (insert assms, auto) -lemma subset_eq_range_card: +lemma subset_eq_atLeast0_lessThan_card: fixes n :: nat - assumes "N \ {.. {0.. n" proof - - from assms finite_lessThan have "card N \ card {.. card {0..Generic big monoid operation over intervals\ + +lemma inj_on_add_nat' [simp]: + "inj_on (plus k) N" for k :: nat + by rule simp + +context comm_monoid_set +begin + +lemma atLeast_lessThan_shift_bounds: + fixes m n k :: nat + shows "F g {m + k.. plus k) {m.. plus k) {m.. plus k) {m..n}" +proof - + have "{m + k..n + k} = plus k ` {m..n}" + by (auto simp del: image_add_atLeastAtMost simp add: image_add_atLeastAtMost [symmetric]) + also have "F g (plus k ` {m..n}) = F (g \ plus k) {m..n}" + by (rule reindex) simp + finally show ?thesis . +qed + +lemma atLeast_Suc_lessThan_Suc_shift: + "F g {Suc m.. Suc) {m.. Suc) {m..n}" + using atLeast_atMost_shift_bounds [of _ _ 1] by simp + +lemma atLeast0_lessThan_Suc: + "F g {0..* g n" + by (simp add: atLeast0_lessThan_Suc ac_simps) + +lemma atLeast0_atMost_Suc: + "F g {0..Suc n} = F g {0..n} \<^bold>* g (Suc n)" + by (simp add: atLeast0_atMost_Suc ac_simps) + +lemma atLeast0_lessThan_Suc_shift: + "F g {0..* F (g \ Suc) {0..* F (g \ Suc) {0..n}" + by (simp add: atLeast0_atMost_Suc_eq_insert_0 atLeast_Suc_atMost_Suc_shift) + +lemma ivl_cong: + "a = c \ b = d \ (\x. c \ x \ x < d \ g x = h x) + \ F g {a.. plus m) {0.. n") simp_all + +lemma atLeast_atMost_shift_0: + fixes m n p :: nat + assumes "m \ n" + shows "F g {m..n} = F (g \ plus m) {0..n - m}" + using assms atLeast_atMost_shift_bounds [of g 0 m "n - m"] by simp + +lemma atLeast_lessThan_concat: + fixes m n p :: nat + shows "m \ n \ n \ p \ F g {m..* F g {n..i. g (m + n - Suc i)) {n..i. g (m + n - i)) {n..m}" + by (rule reindex_bij_witness [where i="\i. m + n - i" and j="\i. m + n - i"]) auto + +lemma atLeast_lessThan_rev_at_least_Suc_atMost: + "F g {n..i. g (m + n - i)) {Suc n..m}" + unfolding atLeast_lessThan_rev [of g n m] + by (cases m) (simp_all add: atLeast_Suc_atMost_Suc_shift atLeastLessThanSuc_atLeastAtMost) + +end + + subsection \Summation indexed over intervals\ syntax (ASCII) @@ -1539,27 +1652,26 @@ with the simplifier who adds the unsimplified premise @{term"x:B"} to the context.\ -lemma setsum_ivl_cong: - "\a = c; b = d; !!x. \ c \ x; x < d \ \ f x = g x \ \ - setsum f {a..i \ Suc n. f i) = (\i \ n. f i) + f(Suc n)" -by (simp add:atMost_Suc ac_simps) +lemma setsum_atMost_Suc [simp]: + "(\i \ Suc n. f i) = (\i \ n. f i) + f (Suc n)" + by (simp add: atMost_Suc ac_simps) -lemma setsum_lessThan_Suc[simp]: "(\i < Suc n. f i) = (\i < n. f i) + f n" -by (simp add:lessThan_Suc ac_simps) +lemma setsum_lessThan_Suc [simp]: + "(\i < Suc n. f i) = (\i < n. f i) + f n" + by (simp add: lessThan_Suc ac_simps) -lemma setsum_cl_ivl_Suc[simp]: +lemma setsum_cl_ivl_Suc [simp]: "setsum f {m..Suc n} = (if Suc n < m then 0 else setsum f {m..n} + f(Suc n))" -by (auto simp:ac_simps atLeastAtMostSuc_conv) + by (auto simp: ac_simps atLeastAtMostSuc_conv) -lemma setsum_op_ivl_Suc[simp]: +lemma setsum_op_ivl_Suc [simp]: "setsum f {m.. (\i=n..m+1. f i) = (\i=n..m. f i) + f(m + 1)" @@ -1598,9 +1710,7 @@ atLeastSucAtMost_greaterThanAtMost) qed -lemma setsum_add_nat_ivl: "\ m \ n; n \ p \ \ - setsum f {m.. 'a::ab_group_add" @@ -1639,7 +1749,8 @@ lemma nat_diff_setsum_reindex: "(\iiShifting bounds\ + +subsubsection \Shifting bounds\ lemma setsum_shift_bounds_nat_ivl: "setsum f {m+k..Telescoping\ +subsubsection \Telescoping\ lemma setsum_telescope: fixes f::"nat \ 'a::ab_group_add" @@ -1735,7 +1846,8 @@ shows "(\k\{Suc m..n}. f k - f (k - 1)) = f n - (f m :: 'a :: ab_group_add)" by (rule dec_induct[OF assms]) (simp_all add: algebra_simps) -subsection \The formula for geometric sums\ + +subsubsection \The formula for geometric sums\ lemma geometric_sum: assumes "x \ 1" @@ -1743,7 +1855,7 @@ proof - from assms obtain y where "y = x - 1" and "y \ 0" by simp_all moreover have "(\iy \ 0\) + by (induct n) (simp_all add: field_simps \y \ 0\) ultimately show ?thesis by simp qed @@ -1755,15 +1867,15 @@ proof (induct n) case (Suc n) have "x ^ Suc (Suc n) - y ^ Suc (Suc n) = x * (x * x^n) - y * (y * y ^ n)" - by (simp add: power_Suc) + by simp also have "... = y * (x ^ (Suc n) - y ^ (Suc n)) + (x - y) * (x * x^n)" - by (simp add: power_Suc algebra_simps) + by (simp add: algebra_simps) also have "... = y * ((x - y) * (\pppThe formula for arithmetic sums\ +subsubsection \The formula for arithmetic sums\ lemma gauss_sum: "(2::'a::comm_semiring_1)*(\i\{1..n}. of_nat i) = of_nat n*((of_nat n)+1)" @@ -1854,6 +1966,29 @@ by (subst setsum_subtractf_nat) auto +subsubsection \Division remainder\ + +lemma range_mod: + fixes n :: nat + assumes "n > 0" + shows "range (\m. m mod n) = {0.. ?A \ m \ ?B" + proof + assume "m \ ?A" + with assms show "m \ ?B" + by auto + next + assume "m \ ?B" + moreover have "m mod n \ ?A" + by (rule rangeI) + ultimately show "m \ ?A" + by simp + qed +qed + + subsection \Products indexed over intervals\ syntax (ASCII) @@ -1884,44 +2019,6 @@ "\i\n. t" \ "CONST setprod (\i. t) {..n}" "\i "CONST setprod (\i. t) {..Transfer setup\ - -lemma transfer_nat_int_set_functions: - "{..n} = nat ` {0..int n}" - "{m..n} = nat ` {int m..int n}" (* need all variants of these! *) - apply (auto simp add: image_def) - apply (rule_tac x = "int x" in bexI) - apply auto - apply (rule_tac x = "int x" in bexI) - apply auto - done - -lemma transfer_nat_int_set_function_closures: - "x >= 0 \ nat_set {x..y}" - by (simp add: nat_set_def) - -declare transfer_morphism_nat_int[transfer add - return: transfer_nat_int_set_functions - transfer_nat_int_set_function_closures -] - -lemma transfer_int_nat_set_functions: - "is_nat m \ is_nat n \ {m..n} = int ` {nat m..nat n}" - by (simp only: is_nat_def transfer_nat_int_set_functions - transfer_nat_int_set_function_closures - transfer_nat_int_set_return_embed nat_0_le - cong: transfer_nat_int_set_cong) - -lemma transfer_int_nat_set_function_closures: - "is_nat x \ nat_set {x..y}" - by (simp only: transfer_nat_int_set_function_closures is_nat_def) - -declare transfer_morphism_int_nat[transfer add - return: transfer_int_nat_set_functions - transfer_int_nat_set_function_closures -] - lemma setprod_int_plus_eq: "setprod int {i..i+j} = \{int i..int (i+j)}" by (induct j) (auto simp add: atLeastAtMostSuc_conv atLeastAtMostPlus1_int_conv) @@ -1937,7 +2034,7 @@ qed -subsection \Shifting bounds\ +subsubsection \Shifting bounds\ lemma setprod_shift_bounds_nat_ivl: "setprod f {m+k..Division remainder\ - -lemma range_mod: - fixes n :: nat - assumes "n > 0" - shows "range (\m. m mod n) = {0.. ?A \ m \ ?B" - proof - assume "m \ ?A" - with assms show "m \ ?B" - by auto - next - assume "m \ ?B" - moreover have "m mod n \ ?A" - by (rule rangeI) - ultimately show "m \ ?A" - by simp - qed -qed - - subsection \Efficient folding over intervals\ function fold_atLeastAtMost_nat where @@ -2044,4 +2118,42 @@ (* TODO: Add support for more kinds of intervals here *) + +subsection \Transfer setup\ + +lemma transfer_nat_int_set_functions: + "{..n} = nat ` {0..int n}" + "{m..n} = nat ` {int m..int n}" (* need all variants of these! *) + apply (auto simp add: image_def) + apply (rule_tac x = "int x" in bexI) + apply auto + apply (rule_tac x = "int x" in bexI) + apply auto + done + +lemma transfer_nat_int_set_function_closures: + "x >= 0 \ nat_set {x..y}" + by (simp add: nat_set_def) + +declare transfer_morphism_nat_int[transfer add + return: transfer_nat_int_set_functions + transfer_nat_int_set_function_closures +] + +lemma transfer_int_nat_set_functions: + "is_nat m \ is_nat n \ {m..n} = int ` {nat m..nat n}" + by (simp only: is_nat_def transfer_nat_int_set_functions + transfer_nat_int_set_function_closures + transfer_nat_int_set_return_embed nat_0_le + cong: transfer_nat_int_set_cong) + +lemma transfer_int_nat_set_function_closures: + "is_nat x \ nat_set {x..y}" + by (simp only: transfer_nat_int_set_function_closures is_nat_def) + +declare transfer_morphism_int_nat[transfer add + return: transfer_int_nat_set_functions + transfer_int_nat_set_function_closures +] + end diff -r 6af79184bef3 -r c184ec919c70 src/HOL/Transcendental.thy --- a/src/HOL/Transcendental.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/Transcendental.thy Sat Jul 09 13:26:16 2016 +0200 @@ -36,7 +36,7 @@ by (metis of_nat_fact of_real_of_nat_eq) lemma pochhammer_of_real: "pochhammer (of_real x) n = of_real (pochhammer x n)" - by (simp add: pochhammer_def) + by (simp add: pochhammer_setprod) lemma norm_fact [simp]: "norm (fact n :: 'a :: {real_normed_algebra_1}) = fact n" diff -r 6af79184bef3 -r c184ec919c70 src/HOL/ex/Sum_of_Powers.thy --- a/src/HOL/ex/Sum_of_Powers.thy Fri Jul 08 23:43:11 2016 +0200 +++ b/src/HOL/ex/Sum_of_Powers.thy Sat Jul 09 13:26:16 2016 +0200 @@ -7,32 +7,32 @@ subsection \Additions to @{theory Binomial} Theory\ +lemma (in field_char_0) one_plus_of_nat_neq_zero [simp]: + "1 + of_nat n \ 0" +proof - + have "of_nat (Suc n) \ of_nat 0" + unfolding of_nat_eq_iff by simp + then show ?thesis by simp +qed + lemma of_nat_binomial_eq_mult_binomial_Suc: assumes "k \ n" shows "(of_nat :: (nat \ ('a :: field_char_0))) (n choose k) = of_nat (n + 1 - k) / of_nat (n + 1) * of_nat (Suc n choose k)" -proof - - have "of_nat (n + 1) * (\i 'a)) (n + 1 - k) * (\ii 'a)) (n + 1) * (\i\Suc ` {..i\k. of_nat (Suc n - i))" - proof (cases k) - case (Suc k') - have "of_nat (n + 1) * (\i\Suc ` {..i\insert 0 (Suc ` {..k'}). of_nat (Suc n - i))" - by (subst setprod.insert) (auto simp add: lessThan_Suc_atMost) - also have "... = (\i\Suc k'. of_nat (Suc n - i))" by (simp only: Iic_Suc_eq_insert_0) - finally show ?thesis using Suc by simp - qed (simp) - also have "... = (of_nat :: (nat \ 'a)) (Suc n - k) * (\i 'a)) (n + 1 - k) * (\ii 'a)) (n + 1 - k) / of_nat (n + 1) * (\ii=0.. 'a)) (n + 1 - k) * (\i=0..i=0.. 'a)) (n + 1 - k) * (\i=0..i=0.. 'a)) (n + 1 - k) / of_nat (n + 1) * (\i=0..