src/HOL/NewNumberTheory/Binomial.thy
changeset 32805 9b535493ac8d
parent 32804 ca430e6aee1c
parent 32783 e43d761a742d
child 32806 06561afcadaa
child 32845 d2d0b9b1a69d
equal deleted inserted replaced
32804:ca430e6aee1c 32805:9b535493ac8d
     1 (*  Title:      Binomial.thy
       
     2     Authors:    Lawrence C. Paulson, Jeremy Avigad, Tobias Nipkow
       
     3 
       
     4 
       
     5 Defines the "choose" function, and establishes basic properties.
       
     6 
       
     7 The original theory "Binomial" was by Lawrence C. Paulson, based on
       
     8 the work of Andy Gordon and Florian Kammueller. The approach here,
       
     9 which derives the definition of binomial coefficients in terms of the
       
    10 factorial function, is due to Jeremy Avigad. The binomial theorem was
       
    11 formalized by Tobias Nipkow.
       
    12 
       
    13 *)
       
    14 
       
    15 
       
    16 header {* Binomial *}
       
    17 
       
    18 theory Binomial
       
    19 imports Cong Fact
       
    20 begin
       
    21 
       
    22 
       
    23 subsection {* Main definitions *}
       
    24 
       
    25 class binomial =
       
    26 
       
    27 fixes 
       
    28   binomial :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "choose" 65)
       
    29 
       
    30 (* definitions for the natural numbers *)
       
    31 
       
    32 instantiation nat :: binomial
       
    33 
       
    34 begin 
       
    35 
       
    36 fun
       
    37   binomial_nat :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
    38 where
       
    39   "binomial_nat n k =
       
    40    (if k = 0 then 1 else
       
    41     if n = 0 then 0 else
       
    42       (binomial (n - 1) k) + (binomial (n - 1) (k - 1)))"
       
    43 
       
    44 instance proof qed
       
    45 
       
    46 end
       
    47 
       
    48 (* definitions for the integers *)
       
    49 
       
    50 instantiation int :: binomial
       
    51 
       
    52 begin 
       
    53 
       
    54 definition
       
    55   binomial_int :: "int => int \<Rightarrow> int"
       
    56 where
       
    57   "binomial_int n k = (if n \<ge> 0 \<and> k \<ge> 0 then int (binomial (nat n) (nat k))
       
    58       else 0)"
       
    59 instance proof qed
       
    60 
       
    61 end
       
    62 
       
    63 
       
    64 subsection {* Set up Transfer *}
       
    65 
       
    66 lemma transfer_nat_int_binomial:
       
    67   "(n::int) >= 0 \<Longrightarrow> k >= 0 \<Longrightarrow> binomial (nat n) (nat k) = 
       
    68       nat (binomial n k)"
       
    69   unfolding binomial_int_def 
       
    70   by auto
       
    71 
       
    72 lemma transfer_nat_int_binomial_closure:
       
    73   "n >= (0::int) \<Longrightarrow> k >= 0 \<Longrightarrow> binomial n k >= 0"
       
    74   by (auto simp add: binomial_int_def)
       
    75 
       
    76 declare TransferMorphism_nat_int[transfer add return: 
       
    77     transfer_nat_int_binomial transfer_nat_int_binomial_closure]
       
    78 
       
    79 lemma transfer_int_nat_binomial:
       
    80   "binomial (int n) (int k) = int (binomial n k)"
       
    81   unfolding fact_int_def binomial_int_def by auto
       
    82 
       
    83 lemma transfer_int_nat_binomial_closure:
       
    84   "is_nat n \<Longrightarrow> is_nat k \<Longrightarrow> binomial n k >= 0"
       
    85   by (auto simp add: binomial_int_def)
       
    86 
       
    87 declare TransferMorphism_int_nat[transfer add return: 
       
    88     transfer_int_nat_binomial transfer_int_nat_binomial_closure]
       
    89 
       
    90 
       
    91 subsection {* Binomial coefficients *}
       
    92 
       
    93 lemma choose_zero_nat [simp]: "(n::nat) choose 0 = 1"
       
    94   by simp
       
    95 
       
    96 lemma choose_zero_int [simp]: "n \<ge> 0 \<Longrightarrow> (n::int) choose 0 = 1"
       
    97   by (simp add: binomial_int_def)
       
    98 
       
    99 lemma zero_choose_nat [rule_format,simp]: "ALL (k::nat) > n. n choose k = 0"
       
   100   by (induct n rule: induct'_nat, auto)
       
   101 
       
   102 lemma zero_choose_int [rule_format,simp]: "(k::int) > n \<Longrightarrow> n choose k = 0"
       
   103   unfolding binomial_int_def apply (case_tac "n < 0")
       
   104   apply force
       
   105   apply (simp del: binomial_nat.simps)
       
   106 done
       
   107 
       
   108 lemma choose_reduce_nat: "(n::nat) > 0 \<Longrightarrow> 0 < k \<Longrightarrow>
       
   109     (n choose k) = ((n - 1) choose k) + ((n - 1) choose (k - 1))"
       
   110   by simp
       
   111 
       
   112 lemma choose_reduce_int: "(n::int) > 0 \<Longrightarrow> 0 < k \<Longrightarrow>
       
   113     (n choose k) = ((n - 1) choose k) + ((n - 1) choose (k - 1))"
       
   114   unfolding binomial_int_def apply (subst choose_reduce_nat)
       
   115     apply (auto simp del: binomial_nat.simps 
       
   116       simp add: nat_diff_distrib)
       
   117 done
       
   118 
       
   119 lemma choose_plus_one_nat: "((n::nat) + 1) choose (k + 1) = 
       
   120     (n choose (k + 1)) + (n choose k)"
       
   121   by (simp add: choose_reduce_nat)
       
   122 
       
   123 lemma choose_Suc_nat: "(Suc n) choose (Suc k) = 
       
   124     (n choose (Suc k)) + (n choose k)"
       
   125   by (simp add: choose_reduce_nat One_nat_def)
       
   126 
       
   127 lemma choose_plus_one_int: "n \<ge> 0 \<Longrightarrow> k \<ge> 0 \<Longrightarrow> ((n::int) + 1) choose (k + 1) = 
       
   128     (n choose (k + 1)) + (n choose k)"
       
   129   by (simp add: binomial_int_def choose_plus_one_nat nat_add_distrib del: binomial_nat.simps)
       
   130 
       
   131 declare binomial_nat.simps [simp del]
       
   132 
       
   133 lemma choose_self_nat [simp]: "((n::nat) choose n) = 1"
       
   134   by (induct n rule: induct'_nat, auto simp add: choose_plus_one_nat)
       
   135 
       
   136 lemma choose_self_int [simp]: "n \<ge> 0 \<Longrightarrow> ((n::int) choose n) = 1"
       
   137   by (auto simp add: binomial_int_def)
       
   138 
       
   139 lemma choose_one_nat [simp]: "(n::nat) choose 1 = n"
       
   140   by (induct n rule: induct'_nat, auto simp add: choose_reduce_nat)
       
   141 
       
   142 lemma choose_one_int [simp]: "n \<ge> 0 \<Longrightarrow> (n::int) choose 1 = n"
       
   143   by (auto simp add: binomial_int_def)
       
   144 
       
   145 lemma plus_one_choose_self_nat [simp]: "(n::nat) + 1 choose n = n + 1"
       
   146   apply (induct n rule: induct'_nat, force)
       
   147   apply (case_tac "n = 0")
       
   148   apply auto
       
   149   apply (subst choose_reduce_nat)
       
   150   apply (auto simp add: One_nat_def)  
       
   151   (* natdiff_cancel_numerals introduces Suc *)
       
   152 done
       
   153 
       
   154 lemma Suc_choose_self_nat [simp]: "(Suc n) choose n = Suc n"
       
   155   using plus_one_choose_self_nat by (simp add: One_nat_def)
       
   156 
       
   157 lemma plus_one_choose_self_int [rule_format, simp]: 
       
   158     "(n::int) \<ge> 0 \<longrightarrow> n + 1 choose n = n + 1"
       
   159    by (auto simp add: binomial_int_def nat_add_distrib)
       
   160 
       
   161 (* bounded quantification doesn't work with the unicode characters? *)
       
   162 lemma choose_pos_nat [rule_format]: "ALL k <= (n::nat). 
       
   163     ((n::nat) choose k) > 0"
       
   164   apply (induct n rule: induct'_nat) 
       
   165   apply force
       
   166   apply clarify
       
   167   apply (case_tac "k = 0")
       
   168   apply force
       
   169   apply (subst choose_reduce_nat)
       
   170   apply auto
       
   171 done
       
   172 
       
   173 lemma choose_pos_int: "n \<ge> 0 \<Longrightarrow> k >= 0 \<Longrightarrow> k \<le> n \<Longrightarrow>
       
   174     ((n::int) choose k) > 0"
       
   175   by (auto simp add: binomial_int_def choose_pos_nat)
       
   176 
       
   177 lemma binomial_induct [rule_format]: "(ALL (n::nat). P n n) \<longrightarrow> 
       
   178     (ALL n. P (n + 1) 0) \<longrightarrow> (ALL n. (ALL k < n. P n k \<longrightarrow> P n (k + 1) \<longrightarrow>
       
   179     P (n + 1) (k + 1))) \<longrightarrow> (ALL k <= n. P n k)"
       
   180   apply (induct n rule: induct'_nat)
       
   181   apply auto
       
   182   apply (case_tac "k = 0")
       
   183   apply auto
       
   184   apply (case_tac "k = n + 1")
       
   185   apply auto
       
   186   apply (drule_tac x = n in spec) back back 
       
   187   apply (drule_tac x = "k - 1" in spec) back back back
       
   188   apply auto
       
   189 done
       
   190 
       
   191 lemma choose_altdef_aux_nat: "(k::nat) \<le> n \<Longrightarrow> 
       
   192     fact k * fact (n - k) * (n choose k) = fact n"
       
   193   apply (rule binomial_induct [of _ k n])
       
   194   apply auto
       
   195 proof -
       
   196   fix k :: nat and n
       
   197   assume less: "k < n"
       
   198   assume ih1: "fact k * fact (n - k) * (n choose k) = fact n"
       
   199   hence one: "fact (k + 1) * fact (n - k) * (n choose k) = (k + 1) * fact n"
       
   200     by (subst fact_plus_one_nat, auto)
       
   201   assume ih2: "fact (k + 1) * fact (n - (k + 1)) * (n choose (k + 1)) = 
       
   202       fact n"
       
   203   with less have "fact (k + 1) * fact ((n - (k + 1)) + 1) * 
       
   204       (n choose (k + 1)) = (n - k) * fact n"
       
   205     by (subst (2) fact_plus_one_nat, auto)
       
   206   with less have two: "fact (k + 1) * fact (n - k) * (n choose (k + 1)) = 
       
   207       (n - k) * fact n" by simp
       
   208   have "fact (k + 1) * fact (n - k) * (n + 1 choose (k + 1)) =
       
   209       fact (k + 1) * fact (n - k) * (n choose (k + 1)) + 
       
   210       fact (k + 1) * fact (n - k) * (n choose k)" 
       
   211     by (subst choose_reduce_nat, auto simp add: ring_simps)
       
   212   also note one
       
   213   also note two
       
   214   also with less have "(n - k) * fact n + (k + 1) * fact n= fact (n + 1)" 
       
   215     apply (subst fact_plus_one_nat)
       
   216     apply (subst left_distrib [symmetric])
       
   217     apply simp
       
   218     done
       
   219   finally show "fact (k + 1) * fact (n - k) * (n + 1 choose (k + 1)) = 
       
   220     fact (n + 1)" .
       
   221 qed
       
   222 
       
   223 lemma choose_altdef_nat: "(k::nat) \<le> n \<Longrightarrow> 
       
   224     n choose k = fact n div (fact k * fact (n - k))"
       
   225   apply (frule choose_altdef_aux_nat)
       
   226   apply (erule subst)
       
   227   apply (simp add: mult_ac)
       
   228 done
       
   229 
       
   230 
       
   231 lemma choose_altdef_int: 
       
   232   assumes "(0::int) <= k" and "k <= n"
       
   233   shows "n choose k = fact n div (fact k * fact (n - k))"
       
   234   
       
   235   apply (subst tsub_eq [symmetric], rule prems)
       
   236   apply (rule choose_altdef_nat [transferred])
       
   237   using prems apply auto
       
   238 done
       
   239 
       
   240 lemma choose_dvd_nat: "(k::nat) \<le> n \<Longrightarrow> fact k * fact (n - k) dvd fact n"
       
   241   unfolding dvd_def apply (frule choose_altdef_aux_nat)
       
   242   (* why don't blast and auto get this??? *)
       
   243   apply (rule exI)
       
   244   apply (erule sym)
       
   245 done
       
   246 
       
   247 lemma choose_dvd_int: 
       
   248   assumes "(0::int) <= k" and "k <= n"
       
   249   shows "fact k * fact (n - k) dvd fact n"
       
   250  
       
   251   apply (subst tsub_eq [symmetric], rule prems)
       
   252   apply (rule choose_dvd_nat [transferred])
       
   253   using prems apply auto
       
   254 done
       
   255 
       
   256 (* generalizes Tobias Nipkow's proof to any commutative semiring *)
       
   257 theorem binomial: "(a+b::'a::{comm_ring_1,power})^n = 
       
   258   (SUM k=0..n. (of_nat (n choose k)) * a^k * b^(n-k))" (is "?P n")
       
   259 proof (induct n rule: induct'_nat)
       
   260   show "?P 0" by simp
       
   261 next
       
   262   fix n
       
   263   assume ih: "?P n"
       
   264   have decomp: "{0..n+1} = {0} Un {n+1} Un {1..n}"
       
   265     by auto
       
   266   have decomp2: "{0..n} = {0} Un {1..n}"
       
   267     by auto
       
   268   have decomp3: "{1..n+1} = {n+1} Un {1..n}"
       
   269     by auto
       
   270   have "(a+b)^(n+1) = 
       
   271       (a+b) * (SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
       
   272     using ih by (simp add: power_plus_one)
       
   273   also have "... =  a*(SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k)) +
       
   274                    b*(SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
       
   275     by (rule distrib)
       
   276   also have "... = (SUM k=0..n. of_nat (n choose k) * a^(k+1) * b^(n-k)) +
       
   277                   (SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k+1))"
       
   278     by (subst (1 2) power_plus_one, simp add: setsum_right_distrib mult_ac)
       
   279   also have "... = (SUM k=0..n. of_nat (n choose k) * a^k * b^(n+1-k)) +
       
   280                   (SUM k=1..n+1. of_nat (n choose (k - 1)) * a^k * b^(n+1-k))"
       
   281     by (simp add:setsum_shift_bounds_cl_Suc_ivl Suc_diff_le 
       
   282              power_Suc ring_simps One_nat_def del:setsum_cl_ivl_Suc)
       
   283   also have "... = a^(n+1) + b^(n+1) +
       
   284                   (SUM k=1..n. of_nat (n choose (k - 1)) * a^k * b^(n+1-k)) +
       
   285                   (SUM k=1..n. of_nat (n choose k) * a^k * b^(n+1-k))"
       
   286     by (simp add: decomp2 decomp3)
       
   287   also have
       
   288       "... = a^(n+1) + b^(n+1) + 
       
   289          (SUM k=1..n. of_nat(n+1 choose k) * a^k * b^(n+1-k))"
       
   290     by (auto simp add: ring_simps setsum_addf [symmetric]
       
   291       choose_reduce_nat)
       
   292   also have "... = (SUM k=0..n+1. of_nat (n+1 choose k) * a^k * b^(n+1-k))"
       
   293     using decomp by (simp add: ring_simps)
       
   294   finally show "?P (n + 1)" by simp
       
   295 qed
       
   296 
       
   297 lemma set_explicit: "{S. S = T \<and> P S} = (if P T then {T} else {})"
       
   298   by auto
       
   299 
       
   300 lemma card_subsets_nat [rule_format]:
       
   301   fixes S :: "'a set"
       
   302   assumes "finite S"
       
   303   shows "ALL k. card {T. T \<le> S \<and> card T = k} = card S choose k" 
       
   304       (is "?P S")
       
   305 using `finite S`
       
   306 proof (induct set: finite)
       
   307   show "?P {}" by (auto simp add: set_explicit)
       
   308   next fix x :: "'a" and F
       
   309   assume iassms: "finite F" "x ~: F"
       
   310   assume ih: "?P F"
       
   311   show "?P (insert x F)" (is "ALL k. ?Q k")
       
   312   proof
       
   313     fix k
       
   314     show "card {T. T \<subseteq> (insert x F) \<and> card T = k} = 
       
   315         card (insert x F) choose k" (is "?Q k")
       
   316     proof (induct k rule: induct'_nat)
       
   317       from iassms have "{T. T \<le> (insert x F) \<and> card T = 0} = {{}}"
       
   318         apply auto
       
   319         apply (subst (asm) card_0_eq)
       
   320         apply (auto elim: finite_subset)
       
   321         done
       
   322       thus "?Q 0" 
       
   323         by auto
       
   324       next fix k
       
   325       show "?Q (k + 1)"
       
   326       proof -
       
   327         from iassms have fin: "finite (insert x F)" by auto
       
   328         hence "{ T. T \<subseteq> insert x F \<and> card T = k + 1} =
       
   329           {T. T \<le> F & card T = k + 1} Un 
       
   330           {T. T \<le> insert x F & x : T & card T = k + 1}"
       
   331           by (auto intro!: subsetI)
       
   332         with iassms fin have "card ({T. T \<le> insert x F \<and> card T = k + 1}) = 
       
   333           card ({T. T \<subseteq> F \<and> card T = k + 1}) + 
       
   334           card ({T. T \<subseteq> insert x F \<and> x : T \<and> card T = k + 1})"
       
   335           apply (subst card_Un_disjoint [symmetric])
       
   336           apply auto
       
   337           (* note: nice! Didn't have to say anything here *)
       
   338           done
       
   339         also from ih have "card ({T. T \<subseteq> F \<and> card T = k + 1}) = 
       
   340           card F choose (k+1)" by auto
       
   341         also have "card ({T. T \<subseteq> insert x F \<and> x : T \<and> card T = k + 1}) =
       
   342           card ({T. T <= F & card T = k})"
       
   343         proof -
       
   344           let ?f = "%T. T Un {x}"
       
   345           from iassms have "inj_on ?f {T. T <= F & card T = k}"
       
   346             unfolding inj_on_def by (auto intro!: subsetI)
       
   347           hence "card ({T. T <= F & card T = k}) = 
       
   348             card(?f ` {T. T <= F & card T = k})"
       
   349             by (rule card_image [symmetric])
       
   350           also from iassms fin have "?f ` {T. T <= F & card T = k} = 
       
   351             {T. T \<subseteq> insert x F \<and> x : T \<and> card T = k + 1}"
       
   352             unfolding image_def 
       
   353             (* I can't figure out why this next line takes so long *)
       
   354             apply auto
       
   355             apply (frule (1) finite_subset, force)
       
   356             apply (rule_tac x = "xa - {x}" in exI)
       
   357             apply (subst card_Diff_singleton)
       
   358             apply (auto elim: finite_subset)
       
   359             done
       
   360           finally show ?thesis by (rule sym)
       
   361         qed
       
   362         also from ih have "card ({T. T <= F & card T = k}) = card F choose k"
       
   363           by auto
       
   364         finally have "card ({T. T \<le> insert x F \<and> card T = k + 1}) = 
       
   365           card F choose (k + 1) + (card F choose k)".
       
   366         with iassms choose_plus_one_nat show ?thesis
       
   367           by auto
       
   368       qed
       
   369     qed
       
   370   qed
       
   371 qed
       
   372 
       
   373 end