src/HOL/Binomial.thy
changeset 71699 8e5c20e4e11a
parent 71351 b3a93a91803b
child 71720 1d8a1f727879
equal deleted inserted replaced
71698:b69dc6bcbea3 71699:8e5c20e4e11a
   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