119 "0 < n \<Longrightarrow> 0 < k \<Longrightarrow> |
119 "0 < n \<Longrightarrow> 0 < k \<Longrightarrow> |
120 n choose k = ((n - 1) choose (k - 1)) + ((n - 1) choose k)" |
120 n choose k = ((n - 1) choose (k - 1)) + ((n - 1) choose k)" |
121 using binomial_Suc_Suc [of "n - 1" "k - 1"] by simp |
121 using binomial_Suc_Suc [of "n - 1" "k - 1"] by simp |
122 |
122 |
123 lemma Suc_times_binomial_eq: "Suc n * (n choose k) = (Suc n choose Suc k) * Suc k" |
123 lemma Suc_times_binomial_eq: "Suc n * (n choose k) = (Suc n choose Suc k) * Suc k" |
124 apply (induct n arbitrary: k) |
124 proof (induction n arbitrary: k) |
125 apply simp |
125 case 0 |
126 apply arith |
126 then show ?case |
127 apply (case_tac k) |
127 by auto |
128 apply (auto simp add: add_mult_distrib add_mult_distrib2 le_Suc_eq binomial_eq_0) |
128 next |
129 done |
129 case (Suc n) |
|
130 show ?case |
|
131 proof (cases k) |
|
132 case (Suc k') |
|
133 then show ?thesis |
|
134 using Suc.IH |
|
135 by (auto simp add: add_mult_distrib add_mult_distrib2 le_Suc_eq binomial_eq_0) |
|
136 qed auto |
|
137 qed |
130 |
138 |
131 lemma binomial_le_pow2: "n choose k \<le> 2^n" |
139 lemma binomial_le_pow2: "n choose k \<le> 2^n" |
132 apply (induct n arbitrary: k) |
140 proof (induction n arbitrary: k) |
133 apply (case_tac k) |
141 case 0 |
134 apply simp_all |
142 then show ?case |
135 apply (case_tac k) |
143 using le_less less_le_trans by fastforce |
136 apply auto |
144 next |
137 apply (simp add: add_le_mono mult_2) |
145 case (Suc n) |
138 done |
146 show ?case |
|
147 proof (cases k) |
|
148 case (Suc k') |
|
149 then show ?thesis |
|
150 using Suc.IH by (simp add: add_le_mono mult_2) |
|
151 qed auto |
|
152 qed |
139 |
153 |
140 text \<open>The absorption property.\<close> |
154 text \<open>The absorption property.\<close> |
141 lemma Suc_times_binomial: "Suc k * (Suc n choose Suc k) = Suc n * (n choose k)" |
155 lemma Suc_times_binomial: "Suc k * (Suc n choose Suc k) = Suc n * (n choose k)" |
142 using Suc_times_binomial_eq by auto |
156 using Suc_times_binomial_eq by auto |
143 |
157 |
244 |
258 |
245 lemma binomial_fact: |
259 lemma binomial_fact: |
246 assumes kn: "k \<le> n" |
260 assumes kn: "k \<le> n" |
247 shows "(of_nat (n choose k) :: 'a::field_char_0) = fact n / (fact k * fact (n - k))" |
261 shows "(of_nat (n choose k) :: 'a::field_char_0) = fact n / (fact k * fact (n - k))" |
248 using binomial_fact_lemma[OF kn] |
262 using binomial_fact_lemma[OF kn] |
249 apply (simp add: field_simps) |
263 by (metis (mono_tags, lifting) fact_nonzero mult_eq_0_iff nonzero_mult_div_cancel_left of_nat_fact of_nat_mult) |
250 apply (metis mult.commute of_nat_fact of_nat_mult) |
|
251 done |
|
252 |
264 |
253 lemma fact_binomial: |
265 lemma fact_binomial: |
254 assumes "k \<le> n" |
266 assumes "k \<le> n" |
255 shows "fact k * of_nat (n choose k) = (fact n / fact (n - k) :: 'a::field_char_0)" |
267 shows "fact k * of_nat (n choose k) = (fact n / fact (n - k) :: 'a::field_char_0)" |
256 unfolding binomial_fact [OF assms] by (simp add: field_simps) |
268 unfolding binomial_fact [OF assms] by (simp add: field_simps) |
359 |
371 |
360 lemma gbinomial_pochhammer: "a gchoose k = (- 1) ^ k * pochhammer (- a) k / fact k" |
372 lemma gbinomial_pochhammer: "a gchoose k = (- 1) ^ k * pochhammer (- a) k / fact k" |
361 for a :: "'a::field_char_0" |
373 for a :: "'a::field_char_0" |
362 proof (cases k) |
374 proof (cases k) |
363 case (Suc k') |
375 case (Suc k') |
|
376 then have "a gchoose k = pochhammer (a - of_nat k') (Suc k') / ((1 + of_nat k') * fact k')" |
|
377 by (simp add: gbinomial_prod_rev pochhammer_prod_rev atLeastLessThanSuc_atLeastAtMost |
|
378 prod.atLeast_Suc_atMost_Suc_shift of_nat_diff flip: power_mult_distrib prod.cl_ivl_Suc) |
364 then show ?thesis |
379 then show ?thesis |
365 apply (simp add: pochhammer_minus) |
380 by (simp add: pochhammer_minus Suc) |
366 apply (simp add: gbinomial_prod_rev pochhammer_prod_rev power_mult_distrib [symmetric] atLeastLessThanSuc_atLeastAtMost |
|
367 prod.atLeast_Suc_atMost_Suc_shift of_nat_diff del: prod.cl_ivl_Suc) |
|
368 done |
|
369 qed auto |
381 qed auto |
370 |
382 |
371 lemma gbinomial_pochhammer': "a gchoose k = pochhammer (a - of_nat k + 1) k / fact k" |
383 lemma gbinomial_pochhammer': "a gchoose k = pochhammer (a - of_nat k + 1) k / fact k" |
372 for a :: "'a::field_char_0" |
384 for a :: "'a::field_char_0" |
373 proof - |
385 proof - |
435 fixes a :: "'a::field_char_0" |
447 fixes a :: "'a::field_char_0" |
436 shows "a * (a gchoose k) = of_nat k * (a gchoose k) + of_nat (Suc k) * (a gchoose (Suc k))" |
448 shows "a * (a gchoose k) = of_nat k * (a gchoose k) + of_nat (Suc k) * (a gchoose (Suc k))" |
437 (is "?l = ?r") |
449 (is "?l = ?r") |
438 proof - |
450 proof - |
439 have "?r = ((- 1) ^k * pochhammer (- a) k / fact k) * (of_nat k - (- a + of_nat k))" |
451 have "?r = ((- 1) ^k * pochhammer (- a) k / fact k) * (of_nat k - (- a + of_nat k))" |
440 apply (simp only: gbinomial_pochhammer pochhammer_Suc right_diff_distrib power_Suc) |
452 unfolding gbinomial_pochhammer pochhammer_Suc right_diff_distrib power_Suc |
441 apply (simp del: of_nat_Suc fact_Suc) |
453 by (auto simp add: field_simps simp del: of_nat_Suc) |
442 apply (auto simp add: field_simps simp del: of_nat_Suc) |
|
443 done |
|
444 also have "\<dots> = ?l" |
454 also have "\<dots> = ?l" |
445 by (simp add: field_simps gbinomial_pochhammer) |
455 by (simp add: field_simps gbinomial_pochhammer) |
446 finally show ?thesis .. |
456 finally show ?thesis .. |
447 qed |
457 qed |
448 |
458 |
457 case 0 |
467 case 0 |
458 then show ?thesis by simp |
468 then show ?thesis by simp |
459 next |
469 next |
460 case (Suc h) |
470 case (Suc h) |
461 have eq0: "(\<Prod>i\<in>{1..k}. (a + 1) - of_nat i) = (\<Prod>i\<in>{0..h}. a - of_nat i)" |
471 have eq0: "(\<Prod>i\<in>{1..k}. (a + 1) - of_nat i) = (\<Prod>i\<in>{0..h}. a - of_nat i)" |
462 apply (rule prod.reindex_cong [where l = Suc]) |
472 proof (rule prod.reindex_cong) |
463 using Suc |
473 show "{1..k} = Suc ` {0..h}" |
464 apply (auto simp add: image_Suc_atMost) |
474 using Suc by (auto simp add: image_Suc_atMost) |
465 done |
475 qed auto |
466 have "fact (Suc k) * (a gchoose k + (a gchoose (Suc k))) = |
476 have "fact (Suc k) * (a gchoose k + (a gchoose (Suc k))) = |
467 (a gchoose Suc h) * (fact (Suc (Suc h))) + |
477 (a gchoose Suc h) * (fact (Suc (Suc h))) + |
468 (a gchoose Suc (Suc h)) * (fact (Suc (Suc h)))" |
478 (a gchoose Suc (Suc h)) * (fact (Suc (Suc h)))" |
469 by (simp add: Suc field_simps del: fact_Suc) |
479 by (simp add: Suc field_simps del: fact_Suc) |
470 also have "\<dots> = |
480 also have "\<dots> = |
471 (a gchoose Suc h) * of_nat (Suc (Suc h) * fact (Suc h)) + (\<Prod>i=0..Suc h. a - of_nat i)" |
481 (a gchoose Suc h) * of_nat (Suc (Suc h) * fact (Suc h)) + (\<Prod>i=0..Suc h. a - of_nat i)" |
472 apply (simp del: fact_Suc prod.op_ivl_Suc add: gbinomial_mult_fact field_simps mult.left_commute [of _ "2"]) |
482 apply (simp only: gbinomial_mult_fact field_simps mult.left_commute [of _ "2"]) |
473 apply (simp del: fact_Suc add: fact_Suc [of "Suc h"] field_simps gbinomial_mult_fact |
483 apply (simp del: fact_Suc add: fact_Suc [of "Suc h"] field_simps gbinomial_mult_fact |
474 mult.left_commute [of _ "2"] atLeastLessThanSuc_atLeastAtMost) |
484 mult.left_commute [of _ "2"] atLeastLessThanSuc_atLeastAtMost) |
475 done |
485 done |
476 also have "\<dots> = |
486 also have "\<dots> = |
477 (fact (Suc h) * (a gchoose Suc h)) * of_nat (Suc (Suc h)) + (\<Prod>i=0..Suc h. a - of_nat i)" |
487 (fact (Suc h) * (a gchoose Suc h)) * of_nat (Suc (Suc h)) + (\<Prod>i=0..Suc h. a - of_nat i)" |
606 a * pochhammer ((a + 1) + b) n" |
616 a * pochhammer ((a + 1) + b) n" |
607 by (subst Suc) (simp add: sum_distrib_left pochhammer_rec mult_ac) |
617 by (subst Suc) (simp add: sum_distrib_left pochhammer_rec mult_ac) |
608 also have "(\<Sum>i\<le>n. of_nat (n choose Suc i) * pochhammer a (Suc i) * pochhammer b (n - i)) + |
618 also have "(\<Sum>i\<le>n. of_nat (n choose Suc i) * pochhammer a (Suc i) * pochhammer b (n - i)) + |
609 pochhammer b (Suc n) = |
619 pochhammer b (Suc n) = |
610 (\<Sum>i=0..Suc n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc n - i))" |
620 (\<Sum>i=0..Suc n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc n - i))" |
611 apply (subst sum.atLeast_Suc_atMost) |
621 apply (subst sum.atLeast_Suc_atMost, simp) |
612 apply simp |
622 apply (simp add: sum.shift_bounds_cl_Suc_ivl atLeast0AtMost del: sum.cl_ivl_Suc) |
613 apply (subst sum.shift_bounds_cl_Suc_ivl) |
|
614 apply (simp add: atLeast0AtMost) |
|
615 done |
623 done |
616 also have "\<dots> = (\<Sum>i\<le>n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc n - i))" |
624 also have "\<dots> = (\<Sum>i\<le>n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc n - i))" |
617 using Suc by (intro sum.mono_neutral_right) (auto simp: not_le binomial_eq_0) |
625 using Suc by (intro sum.mono_neutral_right) (auto simp: not_le binomial_eq_0) |
618 also have "\<dots> = (\<Sum>i\<le>n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc (n - i)))" |
626 also have "\<dots> = (\<Sum>i\<le>n. of_nat (n choose i) * pochhammer a i * pochhammer b (Suc (n - i)))" |
619 by (intro sum.cong) (simp_all add: Suc_diff_le) |
627 by (intro sum.cong) (simp_all add: Suc_diff_le) |
639 proof - |
647 proof - |
640 have x: "0 \<le> a" |
648 have x: "0 \<le> a" |
641 using assms of_nat_0_le_iff order_trans by blast |
649 using assms of_nat_0_le_iff order_trans by blast |
642 have "(a / of_nat k :: 'a) ^ k = (\<Prod>i = 0..<k. a / of_nat k :: 'a)" |
650 have "(a / of_nat k :: 'a) ^ k = (\<Prod>i = 0..<k. a / of_nat k :: 'a)" |
643 by simp |
651 by simp |
644 also have "\<dots> \<le> a gchoose k" (* FIXME *) |
652 also have "\<dots> \<le> a gchoose k" |
645 unfolding gbinomial_altdef_of_nat |
653 proof - |
646 apply (safe intro!: prod_mono) |
654 have "\<And>i. i < k \<Longrightarrow> 0 \<le> a / of_nat k" |
647 apply simp_all |
655 by (simp add: x zero_le_divide_iff) |
648 prefer 2 |
656 moreover have "a / of_nat k \<le> (a - of_nat i) / of_nat (k - i)" if "i < k" for i |
649 subgoal premises for i |
|
650 proof - |
657 proof - |
651 from assms have "a * of_nat i \<ge> of_nat (i * k)" |
658 from assms have "a * of_nat i \<ge> of_nat (i * k)" |
652 by (metis mult.commute mult_le_cancel_right of_nat_less_0_iff of_nat_mult) |
659 by (metis mult.commute mult_le_cancel_right of_nat_less_0_iff of_nat_mult) |
653 then have "a * of_nat k - a * of_nat i \<le> a * of_nat k - of_nat (i * k)" |
660 then have "a * of_nat k - a * of_nat i \<le> a * of_nat k - of_nat (i * k)" |
654 by arith |
661 by arith |
655 then have "a * of_nat (k - i) \<le> (a - of_nat i) * of_nat k" |
662 then have "a * of_nat (k - i) \<le> (a - of_nat i) * of_nat k" |
656 using \<open>i < k\<close> by (simp add: algebra_simps zero_less_mult_iff of_nat_diff) |
663 using \<open>i < k\<close> by (simp add: algebra_simps zero_less_mult_iff of_nat_diff) |
657 then have "a * of_nat (k - i) \<le> (a - of_nat i) * (of_nat k :: 'a)" |
664 then have "a * of_nat (k - i) \<le> (a - of_nat i) * (of_nat k :: 'a)" |
658 by (simp only: of_nat_mult[symmetric] of_nat_le_iff) |
665 by blast |
659 with assms show ?thesis |
666 with assms show ?thesis |
660 using \<open>i < k\<close> by (simp add: field_simps) |
667 using \<open>i < k\<close> by (simp add: field_simps) |
661 qed |
668 qed |
662 apply (simp add: x zero_le_divide_iff) |
669 ultimately show ?thesis |
663 done |
670 unfolding gbinomial_altdef_of_nat |
|
671 by (intro prod_mono) auto |
|
672 qed |
664 finally show ?thesis . |
673 finally show ?thesis . |
665 qed |
674 qed |
666 |
675 |
667 lemma gbinomial_negated_upper: "(a gchoose k) = (-1) ^ k * ((of_nat k - a - 1) gchoose k)" |
676 lemma gbinomial_negated_upper: "(a gchoose k) = (-1) ^ k * ((of_nat k - a - 1) gchoose k)" |
668 by (simp add: gbinomial_pochhammer pochhammer_minus algebra_simps) |
677 by (simp add: gbinomial_pochhammer pochhammer_minus algebra_simps) |
917 by (simp only: S_def) |
926 by (simp only: S_def) |
918 qed |
927 qed |
919 |
928 |
920 lemma gbinomial_partial_sum_poly_xpos: |
929 lemma gbinomial_partial_sum_poly_xpos: |
921 "(\<Sum>k\<le>m. (of_nat m + a gchoose k) * x^k * y^(m-k)) = |
930 "(\<Sum>k\<le>m. (of_nat m + a gchoose k) * x^k * y^(m-k)) = |
922 (\<Sum>k\<le>m. (of_nat k + a - 1 gchoose k) * x^k * (x + y)^(m-k))" |
931 (\<Sum>k\<le>m. (of_nat k + a - 1 gchoose k) * x^k * (x + y)^(m-k))" (is "?lhs = ?rhs") |
923 apply (subst gbinomial_partial_sum_poly) |
932 proof - |
924 apply (subst gbinomial_negated_upper) |
933 have "?lhs = (\<Sum>k\<le>m. (- a gchoose k) * (- x) ^ k * (x + y) ^ (m - k))" |
925 apply (intro sum.cong, rule refl) |
934 by (simp add: gbinomial_partial_sum_poly) |
926 apply (simp add: power_mult_distrib [symmetric]) |
935 also have "... = (\<Sum>k\<le>m. (-1) ^ k * (of_nat k - - a - 1 gchoose k) * (- x) ^ k * (x + y) ^ (m - k))" |
927 done |
936 by (metis (no_types, hide_lams) gbinomial_negated_upper) |
|
937 also have "... = ?rhs" |
|
938 by (intro sum.cong) (auto simp flip: power_mult_distrib) |
|
939 finally show ?thesis . |
|
940 qed |
928 |
941 |
929 lemma binomial_r_part_sum: "(\<Sum>k\<le>m. (2 * m + 1 choose k)) = 2 ^ (2 * m)" |
942 lemma binomial_r_part_sum: "(\<Sum>k\<le>m. (2 * m + 1 choose k)) = 2 ^ (2 * m)" |
930 proof - |
943 proof - |
931 have "2 * 2^(2*m) = (\<Sum>k = 0..(2 * m + 1). (2 * m + 1 choose k))" |
944 have "2 * 2^(2*m) = (\<Sum>k = 0..(2 * m + 1). (2 * m + 1 choose k))" |
932 using choose_row_sum[where n="2 * m + 1"] by (simp add: atMost_atLeast0) |
945 using choose_row_sum[where n="2 * m + 1"] by (simp add: atMost_atLeast0) |
1010 lemma binomial_altdef_nat: "k \<le> n \<Longrightarrow> n choose k = fact n div (fact k * fact (n - k))" |
1023 lemma binomial_altdef_nat: "k \<le> n \<Longrightarrow> n choose k = fact n div (fact k * fact (n - k))" |
1011 for k n :: nat |
1024 for k n :: nat |
1012 by (subst binomial_fact_lemma [symmetric]) auto |
1025 by (subst binomial_fact_lemma [symmetric]) auto |
1013 |
1026 |
1014 lemma choose_dvd: |
1027 lemma choose_dvd: |
1015 "k \<le> n \<Longrightarrow> fact k * fact (n - k) dvd (fact n :: 'a::linordered_semidom)" |
1028 assumes "k \<le> n" shows "fact k * fact (n - k) dvd (fact n :: 'a::linordered_semidom)" |
1016 unfolding dvd_def |
1029 unfolding dvd_def |
1017 apply (rule exI [where x="of_nat (n choose k)"]) |
1030 proof |
1018 using binomial_fact_lemma [of k n, THEN arg_cong [where f = of_nat and 'b='a]] |
1031 show "fact n = fact k * fact (n - k) * of_nat (n choose k)" |
1019 apply auto |
1032 by (metis assms binomial_fact_lemma of_nat_fact of_nat_mult) |
1020 done |
1033 qed |
1021 |
1034 |
1022 lemma fact_fact_dvd_fact: |
1035 lemma fact_fact_dvd_fact: |
1023 "fact k * fact n dvd (fact (k + n) :: 'a::linordered_semidom)" |
1036 "fact k * fact n dvd (fact (k + n) :: 'a::linordered_semidom)" |
1024 by (metis add.commute add_diff_cancel_left' choose_dvd le_add2) |
1037 by (metis add.commute add_diff_cancel_left' choose_dvd le_add2) |
1025 |
1038 |
1028 (is "?lhs = _") |
1041 (is "?lhs = _") |
1029 proof - |
1042 proof - |
1030 have "?lhs = |
1043 have "?lhs = |
1031 fact (m + r + k) div (fact (m + k) * fact (m + r - m)) * (fact (m + k) div (fact k * fact m))" |
1044 fact (m + r + k) div (fact (m + k) * fact (m + r - m)) * (fact (m + k) div (fact k * fact m))" |
1032 by (simp add: binomial_altdef_nat) |
1045 by (simp add: binomial_altdef_nat) |
1033 also have "\<dots> = fact (m + r + k) div (fact r * (fact k * fact m))" |
1046 also have "... = fact (m + r + k) * fact (m + k) div |
|
1047 (fact (m + k) * fact (m + r - m) * (fact k * fact m))" |
1034 apply (subst div_mult_div_if_dvd) |
1048 apply (subst div_mult_div_if_dvd) |
1035 apply (auto simp: algebra_simps fact_fact_dvd_fact) |
1049 apply (auto simp: algebra_simps fact_fact_dvd_fact) |
1036 apply (metis add.assoc add.commute fact_fact_dvd_fact) |
1050 apply (metis add.assoc add.commute fact_fact_dvd_fact) |
1037 done |
1051 done |
|
1052 also have "\<dots> = fact (m + r + k) div (fact r * (fact k * fact m))" |
|
1053 by (auto simp: algebra_simps fact_fact_dvd_fact) |
1038 also have "\<dots> = (fact (m + r + k) * fact (m + r)) div (fact r * (fact k * fact m) * fact (m + r))" |
1054 also have "\<dots> = (fact (m + r + k) * fact (m + r)) div (fact r * (fact k * fact m) * fact (m + r))" |
1039 apply (subst div_mult_div_if_dvd [symmetric]) |
1055 apply (subst div_mult_div_if_dvd [symmetric]) |
1040 apply (auto simp add: algebra_simps) |
1056 apply (auto simp add: algebra_simps) |
1041 apply (metis fact_fact_dvd_fact dvd_trans nat_mult_dvd_cancel_disj) |
1057 apply (metis fact_fact_dvd_fact dvd_trans nat_mult_dvd_cancel_disj) |
1042 done |
1058 done |