Restored Suc rather than +1, and using Library/Binimial
authorpaulson <lp15@cam.ac.uk>
Fri Jan 24 15:21:00 2014 +0000 (2014-01-24)
changeset 5513070db8d380d62
parent 55127 11408b65e9a6
child 55131 9808f186795c
Restored Suc rather than +1, and using Library/Binimial
src/HOL/Number_Theory/Binomial.thy
src/HOL/Number_Theory/Cong.thy
src/HOL/Number_Theory/Eratosthenes.thy
src/HOL/Number_Theory/Primes.thy
src/HOL/Number_Theory/UniqueFactorization.thy
     1.1 --- a/src/HOL/Number_Theory/Binomial.thy	Thu Jan 23 16:09:28 2014 +0100
     1.2 +++ b/src/HOL/Number_Theory/Binomial.thy	Fri Jan 24 15:21:00 2014 +0000
     1.3 @@ -2,238 +2,638 @@
     1.4      Authors:    Lawrence C. Paulson, Jeremy Avigad, Tobias Nipkow
     1.5  
     1.6  Defines the "choose" function, and establishes basic properties.
     1.7 -
     1.8 -The original theory "Binomial" was by Lawrence C. Paulson, based on
     1.9 -the work of Andy Gordon and Florian Kammueller. The approach here,
    1.10 -which derives the definition of binomial coefficients in terms of the
    1.11 -factorial function, is due to Jeremy Avigad. The binomial theorem was
    1.12 -formalized by Tobias Nipkow.
    1.13  *)
    1.14  
    1.15  header {* Binomial *}
    1.16  
    1.17  theory Binomial
    1.18 -imports Cong Fact
    1.19 +imports Cong Fact Complex_Main
    1.20  begin
    1.21  
    1.22  
    1.23 -subsection {* Main definitions *}
    1.24 +text {* This development is based on the work of Andy Gordon and
    1.25 +  Florian Kammueller. *}
    1.26 +
    1.27 +subsection {* Basic definitions and lemmas *}
    1.28 +
    1.29 +primrec binomial :: "nat \<Rightarrow> nat \<Rightarrow> nat" (infixl "choose" 65)
    1.30 +where
    1.31 +  "0 choose k = (if k = 0 then 1 else 0)"
    1.32 +| "Suc n choose k = (if k = 0 then 1 else (n choose (k - 1)) + (n choose k))"
    1.33 +
    1.34 +lemma binomial_n_0 [simp]: "(n choose 0) = 1"
    1.35 +  by (cases n) simp_all
    1.36 +
    1.37 +lemma binomial_0_Suc [simp]: "(0 choose Suc k) = 0"
    1.38 +  by simp
    1.39 +
    1.40 +lemma binomial_Suc_Suc [simp]: "(Suc n choose Suc k) = (n choose k) + (n choose Suc k)"
    1.41 +  by simp
    1.42 +
    1.43 +lemma choose_reduce_nat: 
    1.44 +  "0 < (n::nat) \<Longrightarrow> 0 < k \<Longrightarrow>
    1.45 +    (n choose k) = ((n - 1) choose k) + ((n - 1) choose (k - 1))"
    1.46 +  by (metis Suc_diff_1 binomial.simps(2) nat_add_commute neq0_conv)
    1.47 +
    1.48 +lemma binomial_eq_0: "n < k \<Longrightarrow> n choose k = 0"
    1.49 +  by (induct n arbitrary: k) auto
    1.50 +
    1.51 +declare binomial.simps [simp del]
    1.52  
    1.53 -class binomial =
    1.54 -  fixes binomial :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "choose" 65)
    1.55 +lemma binomial_n_n [simp]: "n choose n = 1"
    1.56 +  by (induct n) (simp_all add: binomial_eq_0)
    1.57 +
    1.58 +lemma binomial_Suc_n [simp]: "Suc n choose n = Suc n"
    1.59 +  by (induct n) simp_all
    1.60 +
    1.61 +lemma binomial_1 [simp]: "n choose Suc 0 = n"
    1.62 +  by (induct n) simp_all
    1.63 +
    1.64 +lemma zero_less_binomial: "k \<le> n \<Longrightarrow> n choose k > 0"
    1.65 +  by (induct n k rule: diff_induct) simp_all
    1.66 +
    1.67 +lemma binomial_eq_0_iff [simp]: "n choose k = 0 \<longleftrightarrow> n < k"
    1.68 +  by (metis binomial_eq_0 less_numeral_extra(3) not_less zero_less_binomial)
    1.69  
    1.70 -(* definitions for the natural numbers *)
    1.71 +lemma zero_less_binomial_iff [simp]: "n choose k > 0 \<longleftrightarrow> k \<le> n"
    1.72 +  by (metis binomial_eq_0_iff not_less0 not_less zero_less_binomial)
    1.73 +
    1.74 +(*Might be more useful if re-oriented*)
    1.75 +lemma Suc_times_binomial_eq:
    1.76 +  "k \<le> n \<Longrightarrow> Suc n * (n choose k) = (Suc n choose Suc k) * Suc k"
    1.77 +  apply (induct n arbitrary: k)
    1.78 +   apply (simp add: binomial.simps)
    1.79 +   apply (case_tac k)
    1.80 +  apply (auto simp add: add_mult_distrib add_mult_distrib2 le_Suc_eq binomial_eq_0)
    1.81 +  done
    1.82 +
    1.83 +text{*This is the well-known version, but it's harder to use because of the
    1.84 +  need to reason about division.*}
    1.85 +lemma binomial_Suc_Suc_eq_times:
    1.86 +    "k \<le> n \<Longrightarrow> (Suc n choose Suc k) = (Suc n * (n choose k)) div Suc k"
    1.87 +  by (simp add: Suc_times_binomial_eq del: mult_Suc mult_Suc_right)
    1.88  
    1.89 -instantiation nat :: binomial
    1.90 -begin 
    1.91 +text{*Another version, with -1 instead of Suc.*}
    1.92 +lemma times_binomial_minus1_eq:
    1.93 +  "k \<le> n \<Longrightarrow> 0 < k \<Longrightarrow> (n choose k) * k = n * ((n - 1) choose (k - 1))"
    1.94 +  using Suc_times_binomial_eq [where n = "n - 1" and k = "k - 1"]
    1.95 +  by (auto split add: nat_diff_split)
    1.96 +
    1.97 +
    1.98 +subsection {* Combinatorial theorems involving @{text "choose"} *}
    1.99 +
   1.100 +text {*By Florian Kamm\"uller, tidied by LCP.*}
   1.101 +
   1.102 +lemma card_s_0_eq_empty: "finite A \<Longrightarrow> card {B. B \<subseteq> A & card B = 0} = 1"
   1.103 +  by (simp cong add: conj_cong add: finite_subset [THEN card_0_eq])
   1.104 +
   1.105 +lemma choose_deconstruct: "finite M \<Longrightarrow> x \<notin> M \<Longrightarrow>
   1.106 +    {s. s \<subseteq> insert x M \<and> card s = Suc k} =
   1.107 +    {s. s \<subseteq> M \<and> card s = Suc k} \<union> {s. \<exists>t. t \<subseteq> M \<and> card t = k \<and> s = insert x t}"
   1.108 +  apply safe
   1.109 +     apply (auto intro: finite_subset [THEN card_insert_disjoint])
   1.110 +  by (metis (full_types) Diff_insert_absorb Set.set_insert Zero_neq_Suc card_Diff_singleton_if 
   1.111 +     card_eq_0_iff diff_Suc_1 in_mono subset_insert_iff)
   1.112 +
   1.113 +lemma finite_bex_subset [simp]:
   1.114 +  assumes "finite B"
   1.115 +    and "\<And>A. A \<subseteq> B \<Longrightarrow> finite {x. P x A}"
   1.116 +  shows "finite {x. \<exists>A \<subseteq> B. P x A}"
   1.117 +  by (metis (no_types) assms finite_Collect_bounded_ex finite_Collect_subsets)
   1.118  
   1.119 -fun binomial_nat :: "nat \<Rightarrow> nat \<Rightarrow> nat"
   1.120 -where
   1.121 -  "binomial_nat n k =
   1.122 -   (if k = 0 then 1 else
   1.123 -    if n = 0 then 0 else
   1.124 -      (binomial (n - 1) k) + (binomial (n - 1) (k - 1)))"
   1.125 +text{*There are as many subsets of @{term A} having cardinality @{term k}
   1.126 + as there are sets obtained from the former by inserting a fixed element
   1.127 + @{term x} into each.*}
   1.128 +lemma constr_bij:
   1.129 +   "finite A \<Longrightarrow> x \<notin> A \<Longrightarrow>
   1.130 +    card {B. \<exists>C. C \<subseteq> A \<and> card C = k \<and> B = insert x C} =
   1.131 +    card {B. B \<subseteq> A & card(B) = k}"
   1.132 +  apply (rule card_bij_eq [where f = "\<lambda>s. s - {x}" and g = "insert x"])
   1.133 +  apply (auto elim!: equalityE simp add: inj_on_def)
   1.134 +  apply (metis card_Diff_singleton_if finite_subset in_mono)
   1.135 +  done
   1.136 +
   1.137 +text {*
   1.138 +  Main theorem: combinatorial statement about number of subsets of a set.
   1.139 +*}
   1.140 +
   1.141 +theorem n_subsets: "finite A \<Longrightarrow> card {B. B \<subseteq> A \<and> card B = k} = (card A choose k)"
   1.142 +proof (induct k arbitrary: A)
   1.143 +  case 0 then show ?case by (simp add: card_s_0_eq_empty)
   1.144 +next
   1.145 +  case (Suc k)
   1.146 +  show ?case using `finite A`
   1.147 +  proof (induct A)
   1.148 +    case empty show ?case by (simp add: card_s_0_eq_empty)
   1.149 +  next
   1.150 +    case (insert x A)
   1.151 +    then show ?case using Suc.hyps
   1.152 +      apply (simp add: card_s_0_eq_empty choose_deconstruct)
   1.153 +      apply (subst card_Un_disjoint)
   1.154 +         prefer 4 apply (force simp add: constr_bij)
   1.155 +        prefer 3 apply force
   1.156 +       prefer 2 apply (blast intro: finite_Pow_iff [THEN iffD2]
   1.157 +         finite_subset [of _ "Pow (insert x F)", standard])
   1.158 +      apply (blast intro: finite_Pow_iff [THEN iffD2, THEN [2] finite_subset])
   1.159 +      done
   1.160 +  qed
   1.161 +qed
   1.162 +
   1.163 +
   1.164 +subsection {* The binomial theorem (courtesy of Tobias Nipkow): *}
   1.165  
   1.166 -instance ..
   1.167 -
   1.168 -end
   1.169 +text{* Avigad's version, generalized to any commutative ring *}
   1.170 +theorem binomial_ring: "(a+b::'a::{comm_ring_1,power})^n = 
   1.171 +  (\<Sum>k=0..n. (of_nat (n choose k)) * a^k * b^(n-k))" (is "?P n")
   1.172 +proof (induct n)
   1.173 +  case 0 then show "?P 0" by simp
   1.174 +next
   1.175 +  case (Suc n)
   1.176 +  have decomp: "{0..n+1} = {0} Un {n+1} Un {1..n}"
   1.177 +    by auto
   1.178 +  have decomp2: "{0..n} = {0} Un {1..n}"
   1.179 +    by auto
   1.180 +  have "(a+b)^(n+1) = 
   1.181 +      (a+b) * (\<Sum>k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
   1.182 +    using Suc.hyps by simp
   1.183 +  also have "\<dots> = a*(\<Sum>k=0..n. of_nat (n choose k) * a^k * b^(n-k)) +
   1.184 +                   b*(\<Sum>k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
   1.185 +    by (rule distrib)
   1.186 +  also have "\<dots> = (\<Sum>k=0..n. of_nat (n choose k) * a^(k+1) * b^(n-k)) +
   1.187 +                  (\<Sum>k=0..n. of_nat (n choose k) * a^k * b^(n-k+1))"
   1.188 +    by (auto simp add: setsum_right_distrib mult_ac)
   1.189 +  also have "\<dots> = (\<Sum>k=0..n. of_nat (n choose k) * a^k * b^(n+1-k)) +
   1.190 +                  (\<Sum>k=1..n+1. of_nat (n choose (k - 1)) * a^k * b^(n+1-k))"
   1.191 +    by (simp add:setsum_shift_bounds_cl_Suc_ivl Suc_diff_le field_simps  
   1.192 +        del:setsum_cl_ivl_Suc)
   1.193 +  also have "\<dots> = a^(n+1) + b^(n+1) +
   1.194 +                  (\<Sum>k=1..n. of_nat (n choose (k - 1)) * a^k * b^(n+1-k)) +
   1.195 +                  (\<Sum>k=1..n. of_nat (n choose k) * a^k * b^(n+1-k))"
   1.196 +    by (simp add: decomp2)
   1.197 +  also have
   1.198 +      "\<dots> = a^(n+1) + b^(n+1) + 
   1.199 +            (\<Sum>k=1..n. of_nat(n+1 choose k) * a^k * b^(n+1-k))"
   1.200 +    by (auto simp add: field_simps setsum_addf [symmetric] choose_reduce_nat)
   1.201 +  also have "\<dots> = (\<Sum>k=0..n+1. of_nat (n+1 choose k) * a^k * b^(n+1-k))"
   1.202 +    using decomp by (simp add: field_simps)
   1.203 +  finally show "?P (Suc n)" by simp
   1.204 +qed
   1.205  
   1.206 -(* definitions for the integers *)
   1.207 +text{* Original version for the naturals *}
   1.208 +corollary binomial: "(a+b::nat)^n = (\<Sum>k=0..n. (of_nat (n choose k)) * a^k * b^(n-k))"
   1.209 +    using binomial_ring [of "int a" "int b" n]
   1.210 +  by (simp only: of_nat_add [symmetric] of_nat_mult [symmetric] of_nat_power [symmetric]
   1.211 +           of_nat_setsum [symmetric]
   1.212 +           of_nat_eq_iff of_nat_id)
   1.213 +
   1.214 +subsection{* Pochhammer's symbol : generalized rising factorial *}
   1.215 +
   1.216 +text {* See @{url "http://en.wikipedia.org/wiki/Pochhammer_symbol"} *}
   1.217 +
   1.218 +definition "pochhammer (a::'a::comm_semiring_1) n =
   1.219 +  (if n = 0 then 1 else setprod (\<lambda>n. a + of_nat n) {0 .. n - 1})"
   1.220 +
   1.221 +lemma pochhammer_0 [simp]: "pochhammer a 0 = 1"
   1.222 +  by (simp add: pochhammer_def)
   1.223  
   1.224 -instantiation int :: binomial
   1.225 -begin 
   1.226 +lemma pochhammer_1 [simp]: "pochhammer a 1 = a"
   1.227 +  by (simp add: pochhammer_def)
   1.228 +
   1.229 +lemma pochhammer_Suc0 [simp]: "pochhammer a (Suc 0) = a"
   1.230 +  by (simp add: pochhammer_def)
   1.231 +
   1.232 +lemma pochhammer_Suc_setprod: "pochhammer a (Suc n) = setprod (\<lambda>n. a + of_nat n) {0 .. n}"
   1.233 +  by (simp add: pochhammer_def)
   1.234 +
   1.235 +lemma setprod_nat_ivl_Suc: "setprod f {0 .. Suc n} = setprod f {0..n} * f (Suc n)"
   1.236 +proof -
   1.237 +  have "{0..Suc n} = {0..n} \<union> {Suc n}" by auto
   1.238 +  then show ?thesis by (simp add: field_simps)
   1.239 +qed
   1.240 +
   1.241 +lemma setprod_nat_ivl_1_Suc: "setprod f {0 .. Suc n} = f 0 * setprod f {1.. Suc n}"
   1.242 +proof -
   1.243 +  have "{0..Suc n} = {0} \<union> {1 .. Suc n}" by auto
   1.244 +  then show ?thesis by simp
   1.245 +qed
   1.246 +
   1.247  
   1.248 -definition binomial_int :: "int => int \<Rightarrow> int" where
   1.249 -  "binomial_int n k =
   1.250 -   (if n \<ge> 0 \<and> k \<ge> 0 then int (binomial (nat n) (nat k))
   1.251 -    else 0)"
   1.252 +lemma pochhammer_Suc: "pochhammer a (Suc n) = pochhammer a n * (a + of_nat n)"
   1.253 +proof (cases n)
   1.254 +  case 0
   1.255 +  then show ?thesis by simp
   1.256 +next
   1.257 +  case (Suc n)
   1.258 +  show ?thesis unfolding Suc pochhammer_Suc_setprod setprod_nat_ivl_Suc ..
   1.259 +qed
   1.260 +
   1.261 +lemma pochhammer_rec: "pochhammer a (Suc n) = a * pochhammer (a + 1) n"
   1.262 +proof (cases "n = 0")
   1.263 +  case True
   1.264 +  then show ?thesis by (simp add: pochhammer_Suc_setprod)
   1.265 +next
   1.266 +  case False
   1.267 +  have *: "finite {1 .. n}" "0 \<notin> {1 .. n}" by auto
   1.268 +  have eq: "insert 0 {1 .. n} = {0..n}" by auto
   1.269 +  have **: "(\<Prod>n\<in>{1\<Colon>nat..n}. a + of_nat n) = (\<Prod>n\<in>{0\<Colon>nat..n - 1}. a + 1 + of_nat n)"
   1.270 +    apply (rule setprod_reindex_cong [where f = Suc])
   1.271 +    using False
   1.272 +    apply (auto simp add: fun_eq_iff field_simps)
   1.273 +    done
   1.274 +  show ?thesis
   1.275 +    apply (simp add: pochhammer_def)
   1.276 +    unfolding setprod_insert [OF *, unfolded eq]
   1.277 +    using ** apply (simp add: field_simps)
   1.278 +    done
   1.279 +qed
   1.280 +
   1.281 +lemma pochhammer_fact: "of_nat (fact n) = pochhammer 1 n"
   1.282 +  unfolding fact_altdef_nat
   1.283 +  apply (cases n)
   1.284 +   apply (simp_all add: of_nat_setprod pochhammer_Suc_setprod)
   1.285 +  apply (rule setprod_reindex_cong[where f=Suc])
   1.286 +    apply (auto simp add: fun_eq_iff)
   1.287 +  done
   1.288  
   1.289 -instance ..
   1.290 +lemma pochhammer_of_nat_eq_0_lemma:
   1.291 +  assumes "k > n"
   1.292 +  shows "pochhammer (- (of_nat n :: 'a:: idom)) k = 0"
   1.293 +proof (cases "n = 0")
   1.294 +  case True
   1.295 +  then show ?thesis
   1.296 +    using assms by (cases k) (simp_all add: pochhammer_rec)
   1.297 +next
   1.298 +  case False
   1.299 +  from assms obtain h where "k = Suc h" by (cases k) auto
   1.300 +  then show ?thesis
   1.301 +    by (simp add: pochhammer_Suc_setprod)
   1.302 +       (metis Suc_leI Suc_le_mono assms atLeastAtMost_iff less_eq_nat.simps(1))
   1.303 +qed
   1.304  
   1.305 -end
   1.306 +lemma pochhammer_of_nat_eq_0_lemma':
   1.307 +  assumes kn: "k \<le> n"
   1.308 +  shows "pochhammer (- (of_nat n :: 'a:: {idom,ring_char_0})) k \<noteq> 0"
   1.309 +proof (cases k)
   1.310 +  case 0
   1.311 +  then show ?thesis by simp
   1.312 +next
   1.313 +  case (Suc h)
   1.314 +  then show ?thesis
   1.315 +    apply (simp add: pochhammer_Suc_setprod)
   1.316 +    using Suc kn apply (auto simp add: algebra_simps)
   1.317 +    done
   1.318 +qed
   1.319 +
   1.320 +lemma pochhammer_of_nat_eq_0_iff:
   1.321 +  shows "pochhammer (- (of_nat n :: 'a:: {idom,ring_char_0})) k = 0 \<longleftrightarrow> k > n"
   1.322 +  (is "?l = ?r")
   1.323 +  using pochhammer_of_nat_eq_0_lemma[of n k, where ?'a='a]
   1.324 +    pochhammer_of_nat_eq_0_lemma'[of k n, where ?'a = 'a]
   1.325 +  by (auto simp add: not_le[symmetric])
   1.326 +
   1.327 +
   1.328 +lemma pochhammer_eq_0_iff: "pochhammer a n = (0::'a::field_char_0) \<longleftrightarrow> (\<exists>k < n. a = - of_nat k)"
   1.329 +  apply (auto simp add: pochhammer_of_nat_eq_0_iff)
   1.330 +  apply (cases n)
   1.331 +   apply (auto simp add: pochhammer_def algebra_simps group_add_class.eq_neg_iff_add_eq_0)
   1.332 +  apply (metis leD not_less_eq)
   1.333 +  done
   1.334  
   1.335  
   1.336 -subsection {* Set up Transfer *}
   1.337 +lemma pochhammer_eq_0_mono:
   1.338 +  "pochhammer a n = (0::'a::field_char_0) \<Longrightarrow> m \<ge> n \<Longrightarrow> pochhammer a m = 0"
   1.339 +  unfolding pochhammer_eq_0_iff by auto
   1.340 +
   1.341 +lemma pochhammer_neq_0_mono:
   1.342 +  "pochhammer a m \<noteq> (0::'a::field_char_0) \<Longrightarrow> m \<ge> n \<Longrightarrow> pochhammer a n \<noteq> 0"
   1.343 +  unfolding pochhammer_eq_0_iff by auto
   1.344 +
   1.345 +lemma pochhammer_minus:
   1.346 +  assumes kn: "k \<le> n"
   1.347 +  shows "pochhammer (- b) k = ((- 1) ^ k :: 'a::comm_ring_1) * pochhammer (b - of_nat k + 1) k"
   1.348 +proof (cases k)
   1.349 +  case 0
   1.350 +  then show ?thesis by simp
   1.351 +next
   1.352 +  case (Suc h)
   1.353 +  have eq: "((- 1) ^ Suc h :: 'a) = setprod (%i. - 1) {0 .. h}"
   1.354 +    using setprod_constant[where A="{0 .. h}" and y="- 1 :: 'a"]
   1.355 +    by auto
   1.356 +  show ?thesis
   1.357 +    unfolding Suc pochhammer_Suc_setprod eq setprod_timesf[symmetric]
   1.358 +    apply (rule strong_setprod_reindex_cong[where f = "%i. h - i"])
   1.359 +    using Suc
   1.360 +    apply (auto simp add: inj_on_def image_def of_nat_diff)
   1.361 +    apply (metis atLeast0AtMost atMost_iff diff_diff_cancel diff_le_self)
   1.362 +    done
   1.363 +qed
   1.364 +
   1.365 +lemma pochhammer_minus':
   1.366 +  assumes kn: "k \<le> n"
   1.367 +  shows "pochhammer (b - of_nat k + 1) k = ((- 1) ^ k :: 'a::comm_ring_1) * pochhammer (- b) k"
   1.368 +  unfolding pochhammer_minus[OF kn, where b=b]
   1.369 +  unfolding mult_assoc[symmetric]
   1.370 +  unfolding power_add[symmetric]
   1.371 +  by simp
   1.372 +
   1.373 +lemma pochhammer_same: "pochhammer (- of_nat n) n =
   1.374 +    ((- 1) ^ n :: 'a::comm_ring_1) * of_nat (fact n)"
   1.375 +  unfolding pochhammer_minus[OF le_refl[of n]]
   1.376 +  by (simp add: of_nat_diff pochhammer_fact)
   1.377 +
   1.378 +
   1.379 +subsection{* Generalized binomial coefficients *}
   1.380 +
   1.381 +definition gbinomial :: "'a::field_char_0 \<Rightarrow> nat \<Rightarrow> 'a" (infixl "gchoose" 65)
   1.382 +  where "a gchoose n =
   1.383 +    (if n = 0 then 1 else (setprod (\<lambda>i. a - of_nat i) {0 .. n - 1}) / of_nat (fact n))"
   1.384  
   1.385 -lemma transfer_nat_int_binomial:
   1.386 -  "(n::int) >= 0 \<Longrightarrow> k >= 0 \<Longrightarrow> binomial (nat n) (nat k) = 
   1.387 -      nat (binomial n k)"
   1.388 -  unfolding binomial_int_def 
   1.389 -  by auto
   1.390 +lemma gbinomial_0 [simp]: "a gchoose 0 = 1" "0 gchoose (Suc n) = 0"
   1.391 +  apply (simp_all add: gbinomial_def)
   1.392 +  apply (subgoal_tac "(\<Prod>i\<Colon>nat\<in>{0\<Colon>nat..n}. - of_nat i) = (0::'b)")
   1.393 +   apply (simp del:setprod_zero_iff)
   1.394 +  apply simp
   1.395 +  done
   1.396 +
   1.397 +lemma gbinomial_pochhammer: "a gchoose n = (- 1) ^ n * pochhammer (- a) n / of_nat (fact n)"
   1.398 +proof (cases "n = 0")
   1.399 +  case True
   1.400 +  then show ?thesis by simp
   1.401 +next
   1.402 +  case False
   1.403 +  from this setprod_constant[of "{0 .. n - 1}" "- (1:: 'a)"]
   1.404 +  have eq: "(- (1\<Colon>'a)) ^ n = setprod (\<lambda>i. - 1) {0 .. n - 1}"
   1.405 +    by auto
   1.406 +  from False show ?thesis
   1.407 +    by (simp add: pochhammer_def gbinomial_def field_simps
   1.408 +      eq setprod_timesf[symmetric])
   1.409 +qed
   1.410  
   1.411 -lemma transfer_nat_int_binomial_closure:
   1.412 -  "n >= (0::int) \<Longrightarrow> k >= 0 \<Longrightarrow> binomial n k >= 0"
   1.413 -  by (auto simp add: binomial_int_def)
   1.414 +lemma binomial_fact_lemma: "k \<le> n \<Longrightarrow> fact k * fact (n - k) * (n choose k) = fact n"
   1.415 +proof (induct n arbitrary: k rule: nat_less_induct)
   1.416 +  fix n k assume H: "\<forall>m<n. \<forall>x\<le>m. fact x * fact (m - x) * (m choose x) =
   1.417 +                      fact m" and kn: "k \<le> n"
   1.418 +  let ?ths = "fact k * fact (n - k) * (n choose k) = fact n"
   1.419 +  { assume "n=0" then have ?ths using kn by simp }
   1.420 +  moreover
   1.421 +  { assume "k=0" then have ?ths using kn by simp }
   1.422 +  moreover
   1.423 +  { assume nk: "n=k" then have ?ths by simp }
   1.424 +  moreover
   1.425 +  { fix m h assume n: "n = Suc m" and h: "k = Suc h" and hm: "h < m"
   1.426 +    from n have mn: "m < n" by arith
   1.427 +    from hm have hm': "h \<le> m" by arith
   1.428 +    from hm h n kn have km: "k \<le> m" by arith
   1.429 +    have "m - h = Suc (m - Suc h)" using  h km hm by arith
   1.430 +    with km h have th0: "fact (m - h) = (m - h) * fact (m - k)"
   1.431 +      by simp
   1.432 +    from n h th0
   1.433 +    have "fact k * fact (n - k) * (n choose k) =
   1.434 +        k * (fact h * fact (m - h) * (m choose h)) + 
   1.435 +        (m - h) * (fact k * fact (m - k) * (m choose k))"
   1.436 +      by (simp add: field_simps)
   1.437 +    also have "\<dots> = (k + (m - h)) * fact m"
   1.438 +      using H[rule_format, OF mn hm'] H[rule_format, OF mn km]
   1.439 +      by (simp add: field_simps)
   1.440 +    finally have ?ths using h n km by simp }
   1.441 +  moreover have "n=0 \<or> k = 0 \<or> k = n \<or> (\<exists>m h. n = Suc m \<and> k = Suc h \<and> h < m)"
   1.442 +    using kn by presburger
   1.443 +  ultimately show ?ths by blast
   1.444 +qed
   1.445 +
   1.446 +lemma binomial_fact:
   1.447 +  assumes kn: "k \<le> n"
   1.448 +  shows "(of_nat (n choose k) :: 'a::field_char_0) =
   1.449 +    of_nat (fact n) / (of_nat (fact k) * of_nat (fact (n - k)))"
   1.450 +  using binomial_fact_lemma[OF kn]
   1.451 +  by (simp add: field_simps of_nat_mult [symmetric])
   1.452  
   1.453 -declare transfer_morphism_nat_int[transfer add return: 
   1.454 -    transfer_nat_int_binomial transfer_nat_int_binomial_closure]
   1.455 +lemma binomial_gbinomial: "of_nat (n choose k) = of_nat n gchoose k"
   1.456 +proof -
   1.457 +  { assume kn: "k > n"
   1.458 +    then have ?thesis
   1.459 +      by (subst binomial_eq_0[OF kn]) 
   1.460 +         (simp add: gbinomial_pochhammer field_simps  pochhammer_of_nat_eq_0_iff) }
   1.461 +  moreover
   1.462 +  { assume "k=0" then have ?thesis by simp }
   1.463 +  moreover
   1.464 +  { assume kn: "k \<le> n" and k0: "k\<noteq> 0"
   1.465 +    from k0 obtain h where h: "k = Suc h" by (cases k) auto
   1.466 +    from h
   1.467 +    have eq:"(- 1 :: 'a) ^ k = setprod (\<lambda>i. - 1) {0..h}"
   1.468 +      by (subst setprod_constant) auto
   1.469 +    have eq': "(\<Prod>i\<in>{0..h}. of_nat n + - (of_nat i :: 'a)) = (\<Prod>i\<in>{n - h..n}. of_nat i)"
   1.470 +      apply (rule strong_setprod_reindex_cong[where f="op - n"])
   1.471 +        using h kn
   1.472 +        apply (simp_all add: inj_on_def image_iff Bex_def set_eq_iff)
   1.473 +        apply clarsimp
   1.474 +        apply presburger
   1.475 +       apply presburger
   1.476 +      apply (simp add: fun_eq_iff field_simps of_nat_add[symmetric] del: of_nat_add)
   1.477 +      done
   1.478 +    have th0: "finite {1..n - Suc h}" "finite {n - h .. n}"
   1.479 +        "{1..n - Suc h} \<inter> {n - h .. n} = {}" and
   1.480 +        eq3: "{1..n - Suc h} \<union> {n - h .. n} = {1..n}"
   1.481 +      using h kn by auto
   1.482 +    from eq[symmetric]
   1.483 +    have ?thesis using kn
   1.484 +      apply (simp add: binomial_fact[OF kn, where ?'a = 'a]
   1.485 +        gbinomial_pochhammer field_simps pochhammer_Suc_setprod)
   1.486 +      apply (simp add: pochhammer_Suc_setprod fact_altdef_nat h
   1.487 +        of_nat_setprod setprod_timesf[symmetric] eq' del: One_nat_def power_Suc)
   1.488 +      unfolding setprod_Un_disjoint[OF th0, unfolded eq3, of "of_nat:: nat \<Rightarrow> 'a"] eq[unfolded h]
   1.489 +      unfolding mult_assoc[symmetric]
   1.490 +      unfolding setprod_timesf[symmetric]
   1.491 +      apply simp
   1.492 +      apply (rule strong_setprod_reindex_cong[where f= "op - n"])
   1.493 +        apply (auto simp add: inj_on_def image_iff Bex_def)
   1.494 +       apply presburger
   1.495 +      apply (subgoal_tac "(of_nat (n - x) :: 'a) = of_nat n - of_nat x")
   1.496 +       apply simp
   1.497 +      apply (rule of_nat_diff)
   1.498 +      apply simp
   1.499 +      done
   1.500 +  }
   1.501 +  moreover
   1.502 +  have "k > n \<or> k = 0 \<or> (k \<le> n \<and> k \<noteq> 0)" by arith
   1.503 +  ultimately show ?thesis by blast
   1.504 +qed
   1.505  
   1.506 -lemma transfer_int_nat_binomial:
   1.507 -  "binomial (int n) (int k) = int (binomial n k)"
   1.508 -  unfolding fact_int_def binomial_int_def by auto
   1.509 +lemma gbinomial_1[simp]: "a gchoose 1 = a"
   1.510 +  by (simp add: gbinomial_def)
   1.511 +
   1.512 +lemma gbinomial_Suc0[simp]: "a gchoose (Suc 0) = a"
   1.513 +  by (simp add: gbinomial_def)
   1.514 +
   1.515 +lemma gbinomial_mult_1:
   1.516 +  "a * (a gchoose n) =
   1.517 +    of_nat n * (a gchoose n) + of_nat (Suc n) * (a gchoose (Suc n))"  (is "?l = ?r")
   1.518 +proof -
   1.519 +  have "?r = ((- 1) ^n * pochhammer (- a) n / of_nat (fact n)) * (of_nat n - (- a + of_nat n))"
   1.520 +    unfolding gbinomial_pochhammer
   1.521 +      pochhammer_Suc fact_Suc of_nat_mult right_diff_distrib power_Suc
   1.522 +    by (simp add:  field_simps del: of_nat_Suc)
   1.523 +  also have "\<dots> = ?l" unfolding gbinomial_pochhammer
   1.524 +    by (simp add: field_simps)
   1.525 +  finally show ?thesis ..
   1.526 +qed
   1.527 +
   1.528 +lemma gbinomial_mult_1':
   1.529 +    "(a gchoose n) * a = of_nat n * (a gchoose n) + of_nat (Suc n) * (a gchoose (Suc n))"
   1.530 +  by (simp add: mult_commute gbinomial_mult_1)
   1.531 +
   1.532 +lemma gbinomial_Suc:
   1.533 +    "a gchoose (Suc k) = (setprod (\<lambda>i. a - of_nat i) {0 .. k}) / of_nat (fact (Suc k))"
   1.534 +  by (simp add: gbinomial_def)
   1.535 +
   1.536 +lemma gbinomial_mult_fact:
   1.537 +  "(of_nat (fact (Suc k)) :: 'a) * ((a::'a::field_char_0) gchoose (Suc k)) =
   1.538 +    (setprod (\<lambda>i. a - of_nat i) {0 .. k})"
   1.539 +  by (simp_all add: gbinomial_Suc field_simps del: fact_Suc)
   1.540 +
   1.541 +lemma gbinomial_mult_fact':
   1.542 +  "((a::'a::field_char_0) gchoose (Suc k)) * (of_nat (fact (Suc k)) :: 'a) =
   1.543 +    (setprod (\<lambda>i. a - of_nat i) {0 .. k})"
   1.544 +  using gbinomial_mult_fact[of k a]
   1.545 +  by (subst mult_commute)
   1.546 +
   1.547  
   1.548 -lemma transfer_int_nat_binomial_closure:
   1.549 -  "is_nat n \<Longrightarrow> is_nat k \<Longrightarrow> binomial n k >= 0"
   1.550 -  by (auto simp add: binomial_int_def)
   1.551 +lemma gbinomial_Suc_Suc:
   1.552 +  "((a::'a::field_char_0) + 1) gchoose (Suc k) = a gchoose k + (a gchoose (Suc k))"
   1.553 +proof (cases k)
   1.554 +  case 0
   1.555 +  then show ?thesis by simp
   1.556 +next
   1.557 +  case (Suc h)
   1.558 +  have eq0: "(\<Prod>i\<in>{1..k}. (a + 1) - of_nat i) = (\<Prod>i\<in>{0..h}. a - of_nat i)"
   1.559 +    apply (rule strong_setprod_reindex_cong[where f = Suc])
   1.560 +      using Suc
   1.561 +      apply auto
   1.562 +    done
   1.563 +
   1.564 +  have "of_nat (fact (Suc k)) * (a gchoose k + (a gchoose (Suc k))) =
   1.565 +    ((a gchoose Suc h) * of_nat (fact (Suc h)) * of_nat (Suc k)) + (\<Prod>i\<in>{0\<Colon>nat..Suc h}. a - of_nat i)"
   1.566 +    apply (simp add: Suc field_simps del: fact_Suc)
   1.567 +    unfolding gbinomial_mult_fact'
   1.568 +    apply (subst fact_Suc)
   1.569 +    unfolding of_nat_mult
   1.570 +    apply (subst mult_commute)
   1.571 +    unfolding mult_assoc
   1.572 +    unfolding gbinomial_mult_fact
   1.573 +    apply (simp add: field_simps)
   1.574 +    done
   1.575 +  also have "\<dots> = (\<Prod>i\<in>{0..h}. a - of_nat i) * (a + 1)"
   1.576 +    unfolding gbinomial_mult_fact' setprod_nat_ivl_Suc
   1.577 +    by (simp add: field_simps Suc)
   1.578 +  also have "\<dots> = (\<Prod>i\<in>{0..k}. (a + 1) - of_nat i)"
   1.579 +    using eq0
   1.580 +    by (simp add: Suc setprod_nat_ivl_1_Suc)
   1.581 +  also have "\<dots> = of_nat (fact (Suc k)) * ((a + 1) gchoose (Suc k))"
   1.582 +    unfolding gbinomial_mult_fact ..
   1.583 +  finally show ?thesis by (simp del: fact_Suc)
   1.584 +qed
   1.585 +
   1.586 +
   1.587 +lemma binomial_symmetric:
   1.588 +  assumes kn: "k \<le> n"
   1.589 +  shows "n choose k = n choose (n - k)"
   1.590 +proof-
   1.591 +  from kn have kn': "n - k \<le> n" by arith
   1.592 +  from binomial_fact_lemma[OF kn] binomial_fact_lemma[OF kn']
   1.593 +  have "fact k * fact (n - k) * (n choose k) =
   1.594 +    fact (n - k) * fact (n - (n - k)) * (n choose (n - k))" by simp
   1.595 +  then show ?thesis using kn by simp
   1.596 +qed
   1.597  
   1.598 -declare transfer_morphism_int_nat[transfer add return: 
   1.599 -    transfer_int_nat_binomial transfer_int_nat_binomial_closure]
   1.600 +(* Contributed by Manuel Eberl *)
   1.601 +(* Alternative definition of the binomial coefficient as \<Prod>i<k. (n - i) / (k - i) *)
   1.602 +lemma binomial_altdef_of_nat:
   1.603 +  fixes n k :: nat
   1.604 +    and x :: "'a :: {field_char_0,field_inverse_zero}"
   1.605 +  assumes "k \<le> n"
   1.606 +  shows "of_nat (n choose k) = (\<Prod>i<k. of_nat (n - i) / of_nat (k - i) :: 'a)"
   1.607 +proof (cases "0 < k")
   1.608 +  case True
   1.609 +  then have "(of_nat (n choose k) :: 'a) = (\<Prod>i<k. of_nat n - of_nat i) / of_nat (fact k)"
   1.610 +    unfolding binomial_gbinomial gbinomial_def
   1.611 +    by (auto simp: gr0_conv_Suc lessThan_Suc_atMost atLeast0AtMost)
   1.612 +  also have "\<dots> = (\<Prod>i<k. of_nat (n - i) / of_nat (k - i) :: 'a)"
   1.613 +    using `k \<le> n` unfolding fact_eq_rev_setprod_nat of_nat_setprod
   1.614 +    by (auto simp add: setprod_dividef intro!: setprod_cong of_nat_diff[symmetric])
   1.615 +  finally show ?thesis .
   1.616 +next
   1.617 +  case False
   1.618 +  then show ?thesis by simp
   1.619 +qed
   1.620 +
   1.621 +lemma binomial_ge_n_over_k_pow_k:
   1.622 +  fixes k n :: nat
   1.623 +    and x :: "'a :: linordered_field_inverse_zero"
   1.624 +  assumes "0 < k"
   1.625 +    and "k \<le> n"
   1.626 +  shows "(of_nat n / of_nat k :: 'a) ^ k \<le> of_nat (n choose k)"
   1.627 +proof -
   1.628 +  have "(of_nat n / of_nat k :: 'a) ^ k = (\<Prod>i<k. of_nat n / of_nat k :: 'a)"
   1.629 +    by (simp add: setprod_constant)
   1.630 +  also have "\<dots> \<le> of_nat (n choose k)"
   1.631 +    unfolding binomial_altdef_of_nat[OF `k\<le>n`]
   1.632 +  proof (safe intro!: setprod_mono)
   1.633 +    fix i :: nat
   1.634 +    assume  "i < k"
   1.635 +    from assms have "n * i \<ge> i * k" by simp
   1.636 +    then have "n * k - n * i \<le> n * k - i * k" by arith
   1.637 +    then have "n * (k - i) \<le> (n - i) * k"
   1.638 +      by (simp add: diff_mult_distrib2 nat_mult_commute)
   1.639 +    then have "of_nat n * of_nat (k - i) \<le> of_nat (n - i) * (of_nat k :: 'a)"
   1.640 +      unfolding of_nat_mult[symmetric] of_nat_le_iff .
   1.641 +    with assms show "of_nat n / of_nat k \<le> of_nat (n - i) / (of_nat (k - i) :: 'a)"
   1.642 +      using `i < k` by (simp add: field_simps)
   1.643 +  qed (simp add: zero_le_divide_iff)
   1.644 +  finally show ?thesis .
   1.645 +qed
   1.646 +
   1.647 +lemma binomial_le_pow:
   1.648 +  assumes "r \<le> n"
   1.649 +  shows "n choose r \<le> n ^ r"
   1.650 +proof -
   1.651 +  have "n choose r \<le> fact n div fact (n - r)"
   1.652 +    using `r \<le> n` by (subst binomial_fact_lemma[symmetric]) auto
   1.653 +  with fact_div_fact_le_pow [OF assms] show ?thesis by auto
   1.654 +qed
   1.655 +
   1.656 +lemma binomial_altdef_nat: "(k::nat) \<le> n \<Longrightarrow>
   1.657 +    n choose k = fact n div (fact k * fact (n - k))"
   1.658 + by (subst binomial_fact_lemma [symmetric]) auto
   1.659 +
   1.660  
   1.661  
   1.662  subsection {* Binomial coefficients *}
   1.663  
   1.664 -lemma choose_zero_nat [simp]: "(n::nat) choose 0 = 1"
   1.665 -  by simp
   1.666 -
   1.667 -lemma choose_zero_int [simp]: "n \<ge> 0 \<Longrightarrow> (n::int) choose 0 = 1"
   1.668 -  by (simp add: binomial_int_def)
   1.669 -
   1.670 -lemma zero_choose_nat [rule_format,simp]: "ALL (k::nat) > n. n choose k = 0"
   1.671 -  by (induct n rule: induct'_nat, auto)
   1.672 +lemma choose_plus_one_nat:
   1.673 +     "((n::nat) + 1) choose (k + 1) =(n choose (k + 1)) + (n choose k)"
   1.674 +  by (simp add: choose_reduce_nat)
   1.675  
   1.676 -lemma zero_choose_int [rule_format,simp]: "(k::int) > n \<Longrightarrow> n choose k = 0"
   1.677 -  unfolding binomial_int_def
   1.678 -  apply (cases "n < 0")
   1.679 -  apply force
   1.680 -  apply (simp del: binomial_nat.simps)
   1.681 -  done
   1.682 -
   1.683 -lemma choose_reduce_nat: "(n::nat) > 0 \<Longrightarrow> 0 < k \<Longrightarrow>
   1.684 -    (n choose k) = ((n - 1) choose k) + ((n - 1) choose (k - 1))"
   1.685 -  by simp
   1.686 -
   1.687 -lemma choose_reduce_int: "(n::int) > 0 \<Longrightarrow> 0 < k \<Longrightarrow>
   1.688 -    (n choose k) = ((n - 1) choose k) + ((n - 1) choose (k - 1))"
   1.689 -  unfolding binomial_int_def
   1.690 -  apply (subst choose_reduce_nat)
   1.691 -    apply (auto simp del: binomial_nat.simps simp add: nat_diff_distrib)
   1.692 -  done
   1.693 -
   1.694 -lemma choose_plus_one_nat: "((n::nat) + 1) choose (k + 1) = 
   1.695 -    (n choose (k + 1)) + (n choose k)"
   1.696 +lemma choose_Suc_nat: 
   1.697 +     "(Suc n) choose (Suc k) = (n choose (Suc k)) + (n choose k)"
   1.698    by (simp add: choose_reduce_nat)
   1.699  
   1.700 -lemma choose_Suc_nat: "(Suc n) choose (Suc k) = 
   1.701 -    (n choose (Suc k)) + (n choose k)"
   1.702 -  by (simp add: choose_reduce_nat One_nat_def)
   1.703 -
   1.704 -lemma choose_plus_one_int: "n \<ge> 0 \<Longrightarrow> k \<ge> 0 \<Longrightarrow> ((n::int) + 1) choose (k + 1) = 
   1.705 -    (n choose (k + 1)) + (n choose k)"
   1.706 -  by (simp add: binomial_int_def choose_plus_one_nat nat_add_distrib del: binomial_nat.simps)
   1.707 -
   1.708 -declare binomial_nat.simps [simp del]
   1.709 -
   1.710 -lemma choose_self_nat [simp]: "((n::nat) choose n) = 1"
   1.711 -  by (induct n rule: induct'_nat) (auto simp add: choose_plus_one_nat)
   1.712 -
   1.713 -lemma choose_self_int [simp]: "n \<ge> 0 \<Longrightarrow> ((n::int) choose n) = 1"
   1.714 -  by (auto simp add: binomial_int_def)
   1.715 -
   1.716 -lemma choose_one_nat [simp]: "(n::nat) choose 1 = n"
   1.717 -  by (induct n rule: induct'_nat) (auto simp add: choose_reduce_nat)
   1.718 -
   1.719 -lemma choose_one_int [simp]: "n \<ge> 0 \<Longrightarrow> (n::int) choose 1 = n"
   1.720 -  by (auto simp add: binomial_int_def)
   1.721 -
   1.722 -lemma plus_one_choose_self_nat [simp]: "(n::nat) + 1 choose n = n + 1"
   1.723 -  apply (induct n rule: induct'_nat, force)
   1.724 -  apply (case_tac "n = 0")
   1.725 -  apply auto
   1.726 -  apply (subst choose_reduce_nat)
   1.727 -  apply (auto simp add: One_nat_def)  
   1.728 -  (* natdiff_cancel_numerals introduces Suc *)
   1.729 -done
   1.730 -
   1.731 -lemma Suc_choose_self_nat [simp]: "(Suc n) choose n = Suc n"
   1.732 -  using plus_one_choose_self_nat by (simp add: One_nat_def)
   1.733 -
   1.734 -lemma plus_one_choose_self_int [rule_format, simp]: 
   1.735 -    "(n::int) \<ge> 0 \<longrightarrow> n + 1 choose n = n + 1"
   1.736 -   by (auto simp add: binomial_int_def nat_add_distrib)
   1.737 -
   1.738 -(* bounded quantification doesn't work with the unicode characters? *)
   1.739 -lemma choose_pos_nat [rule_format]: "ALL k <= (n::nat). 
   1.740 -    ((n::nat) choose k) > 0"
   1.741 -  apply (induct n rule: induct'_nat) 
   1.742 -  apply force
   1.743 -  apply clarify
   1.744 -  apply (case_tac "k = 0")
   1.745 -  apply force
   1.746 -  apply (subst choose_reduce_nat)
   1.747 -  apply auto
   1.748 -  done
   1.749 -
   1.750 -lemma choose_pos_int: "n \<ge> 0 \<Longrightarrow> k >= 0 \<Longrightarrow> k \<le> n \<Longrightarrow>
   1.751 -    ((n::int) choose k) > 0"
   1.752 -  by (auto simp add: binomial_int_def choose_pos_nat)
   1.753 +lemma choose_one: "(n::nat) choose 1 = n"
   1.754 +  by simp
   1.755  
   1.756  lemma binomial_induct [rule_format]: "(ALL (n::nat). P n n) \<longrightarrow> 
   1.757 -    (ALL n. P (n + 1) 0) \<longrightarrow> (ALL n. (ALL k < n. P n k \<longrightarrow> P n (k + 1) \<longrightarrow>
   1.758 -    P (n + 1) (k + 1))) \<longrightarrow> (ALL k <= n. P n k)"
   1.759 -  apply (induct n rule: induct'_nat)
   1.760 +    (ALL n. P (Suc n) 0) \<longrightarrow> (ALL n. (ALL k < n. P n k \<longrightarrow> P n (Suc k) \<longrightarrow>
   1.761 +    P (Suc n) (Suc k))) \<longrightarrow> (ALL k <= n. P n k)"
   1.762 +  apply (induct n)
   1.763    apply auto
   1.764    apply (case_tac "k = 0")
   1.765    apply auto
   1.766 -  apply (case_tac "k = n + 1")
   1.767 -  apply auto
   1.768 -  apply (drule_tac x = n in spec) back back 
   1.769 -  apply (drule_tac x = "k - 1" in spec) back back back
   1.770 -  apply auto
   1.771 -  done
   1.772 -
   1.773 -lemma choose_altdef_aux_nat: "(k::nat) \<le> n \<Longrightarrow> 
   1.774 -    fact k * fact (n - k) * (n choose k) = fact n"
   1.775 -  apply (rule binomial_induct [of _ k n])
   1.776 +  apply (case_tac "k = Suc n")
   1.777    apply auto
   1.778 -proof -
   1.779 -  fix k :: nat and n
   1.780 -  assume less: "k < n"
   1.781 -  assume ih1: "fact k * fact (n - k) * (n choose k) = fact n"
   1.782 -  then have one: "fact (k + 1) * fact (n - k) * (n choose k) = (k + 1) * fact n"
   1.783 -    by (subst fact_plus_one_nat, auto)
   1.784 -  assume ih2: "fact (k + 1) * fact (n - (k + 1)) * (n choose (k + 1)) =  fact n"
   1.785 -  with less have "fact (k + 1) * fact ((n - (k + 1)) + 1) * 
   1.786 -      (n choose (k + 1)) = (n - k) * fact n"
   1.787 -    by (subst (2) fact_plus_one_nat, auto)
   1.788 -  with less have two: "fact (k + 1) * fact (n - k) * (n choose (k + 1)) = 
   1.789 -      (n - k) * fact n" by simp
   1.790 -  have "fact (k + 1) * fact (n - k) * (n + 1 choose (k + 1)) =
   1.791 -      fact (k + 1) * fact (n - k) * (n choose (k + 1)) + 
   1.792 -      fact (k + 1) * fact (n - k) * (n choose k)" 
   1.793 -    by (subst choose_reduce_nat, auto simp add: field_simps)
   1.794 -  also note one
   1.795 -  also note two
   1.796 -  also from less have "(n - k) * fact n + (k + 1) * fact n= fact (n + 1)" 
   1.797 -    apply (subst fact_plus_one_nat)
   1.798 -    apply (subst distrib_right [symmetric])
   1.799 -    apply simp
   1.800 -    done
   1.801 -  finally show "fact (k + 1) * fact (n - k) * (n + 1 choose (k + 1)) = 
   1.802 -    fact (n + 1)" .
   1.803 -qed
   1.804 -
   1.805 -lemma choose_altdef_nat: "(k::nat) \<le> n \<Longrightarrow> 
   1.806 -    n choose k = fact n div (fact k * fact (n - k))"
   1.807 -  apply (frule choose_altdef_aux_nat)
   1.808 -  apply (erule subst)
   1.809 -  apply (simp add: mult_ac)
   1.810 -  done
   1.811 -
   1.812 -
   1.813 -lemma choose_altdef_int: 
   1.814 -  assumes "(0::int) <= k" and "k <= n"
   1.815 -  shows "n choose k = fact n div (fact k * fact (n - k))"
   1.816 -  apply (subst tsub_eq [symmetric], rule assms)
   1.817 -  apply (rule choose_altdef_nat [transferred])
   1.818 -  using assms apply auto
   1.819 +  apply (metis Suc_le_eq fact_nat.cases le_Suc_eq le_eq_less_or_eq)
   1.820    done
   1.821  
   1.822  lemma choose_dvd_nat: "(k::nat) \<le> n \<Longrightarrow> fact k * fact (n - k) dvd fact n"
   1.823 -  unfolding dvd_def apply (frule choose_altdef_aux_nat)
   1.824 -  (* why don't blast and auto get this??? *)
   1.825 -  apply (rule exI)
   1.826 -  apply (erule sym)
   1.827 -  done
   1.828 +by (metis binomial_fact_lemma dvd_def)
   1.829  
   1.830  lemma choose_dvd_int: 
   1.831    assumes "(0::int) <= k" and "k <= n"
   1.832 @@ -243,125 +643,6 @@
   1.833    using assms apply auto
   1.834    done
   1.835  
   1.836 -(* generalizes Tobias Nipkow's proof to any commutative semiring *)
   1.837 -theorem binomial: "(a+b::'a::{comm_ring_1,power})^n = 
   1.838 -  (SUM k=0..n. (of_nat (n choose k)) * a^k * b^(n-k))" (is "?P n")
   1.839 -proof (induct n rule: induct'_nat)
   1.840 -  show "?P 0" by simp
   1.841 -next
   1.842 -  fix n
   1.843 -  assume ih: "?P n"
   1.844 -  have decomp: "{0..n+1} = {0} Un {n+1} Un {1..n}"
   1.845 -    by auto
   1.846 -  have decomp2: "{0..n} = {0} Un {1..n}"
   1.847 -    by auto
   1.848 -  have decomp3: "{1..n+1} = {n+1} Un {1..n}"
   1.849 -    by auto
   1.850 -  have "(a+b)^(n+1) = 
   1.851 -      (a+b) * (SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
   1.852 -    using ih by simp
   1.853 -  also have "... =  a*(SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k)) +
   1.854 -                   b*(SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
   1.855 -    by (rule distrib)
   1.856 -  also have "... = (SUM k=0..n. of_nat (n choose k) * a^(k+1) * b^(n-k)) +
   1.857 -                  (SUM k=0..n. of_nat (n choose k) * a^k * b^(n-k+1))"
   1.858 -    by (subst (1 2) power_plus_one, simp add: setsum_right_distrib mult_ac)
   1.859 -  also have "... = (SUM k=0..n. of_nat (n choose k) * a^k * b^(n+1-k)) +
   1.860 -                  (SUM k=1..n+1. of_nat (n choose (k - 1)) * a^k * b^(n+1-k))"
   1.861 -    by (simp add:setsum_shift_bounds_cl_Suc_ivl Suc_diff_le
   1.862 -      field_simps One_nat_def del:setsum_cl_ivl_Suc)
   1.863 -  also have "... = a^(n+1) + b^(n+1) +
   1.864 -                  (SUM k=1..n. of_nat (n choose (k - 1)) * a^k * b^(n+1-k)) +
   1.865 -                  (SUM k=1..n. of_nat (n choose k) * a^k * b^(n+1-k))"
   1.866 -    by (simp add: decomp2 decomp3)
   1.867 -  also have
   1.868 -      "... = a^(n+1) + b^(n+1) + 
   1.869 -         (SUM k=1..n. of_nat(n+1 choose k) * a^k * b^(n+1-k))"
   1.870 -    by (auto simp add: field_simps setsum_addf [symmetric]
   1.871 -      choose_reduce_nat)
   1.872 -  also have "... = (SUM k=0..n+1. of_nat (n+1 choose k) * a^k * b^(n+1-k))"
   1.873 -    using decomp by (simp add: field_simps)
   1.874 -  finally show "?P (n + 1)" by simp
   1.875 -qed
   1.876 -
   1.877 -lemma card_subsets_nat:
   1.878 -  fixes S :: "'a set"
   1.879 -  shows "finite S \<Longrightarrow> card {T. T \<le> S \<and> card T = k} = card S choose k"
   1.880 -proof (induct arbitrary: k set: finite)
   1.881 -  case empty
   1.882 -  show ?case by (auto simp add: Collect_conv_if)
   1.883 -next
   1.884 -  case (insert x F)
   1.885 -  note iassms = insert(1,2)
   1.886 -  note ih = insert(3)
   1.887 -  show ?case
   1.888 -  proof (induct k rule: induct'_nat)
   1.889 -    case zero
   1.890 -    from iassms have "{T. T \<le> (insert x F) \<and> card T = 0} = {{}}"
   1.891 -      by (auto simp: finite_subset)
   1.892 -    then show ?case by auto
   1.893 -  next
   1.894 -    case (plus1 k)
   1.895 -    from iassms have fin: "finite (insert x F)" by auto
   1.896 -    then have "{ T. T \<subseteq> insert x F \<and> card T = k + 1} =
   1.897 -      {T. T \<le> F & card T = k + 1} Un 
   1.898 -      {T. T \<le> insert x F & x : T & card T = k + 1}"
   1.899 -      by auto
   1.900 -    with iassms fin have "card ({T. T \<le> insert x F \<and> card T = k + 1}) = 
   1.901 -      card ({T. T \<subseteq> F \<and> card T = k + 1}) + 
   1.902 -      card ({T. T \<subseteq> insert x F \<and> x : T \<and> card T = k + 1})"
   1.903 -      apply (subst card_Un_disjoint [symmetric])
   1.904 -      apply auto
   1.905 -        (* note: nice! Didn't have to say anything here *)
   1.906 -      done
   1.907 -    also from ih have "card ({T. T \<subseteq> F \<and> card T = k + 1}) = 
   1.908 -      card F choose (k+1)" by auto
   1.909 -    also have "card ({T. T \<subseteq> insert x F \<and> x : T \<and> card T = k + 1}) =
   1.910 -      card ({T. T <= F & card T = k})"
   1.911 -    proof -
   1.912 -      let ?f = "%T. T Un {x}"
   1.913 -      from iassms have "inj_on ?f {T. T <= F & card T = k}"
   1.914 -        unfolding inj_on_def by auto
   1.915 -      then have "card ({T. T <= F & card T = k}) = 
   1.916 -        card(?f ` {T. T <= F & card T = k})"
   1.917 -        by (rule card_image [symmetric])
   1.918 -      also have "?f ` {T. T <= F & card T = k} = 
   1.919 -        {T. T \<subseteq> insert x F \<and> x : T \<and> card T = k + 1}" (is "?L=?R")
   1.920 -      proof-
   1.921 -        { fix S assume "S \<subseteq> F"
   1.922 -          then have "card(insert x S) = card S +1"
   1.923 -            using iassms by (auto simp: finite_subset) }
   1.924 -        moreover
   1.925 -        { fix T assume 1: "T \<subseteq> insert x F" "x : T" "card T = k+1"
   1.926 -          let ?S = "T - {x}"
   1.927 -          have "?S <= F & card ?S = k \<and> T = insert x ?S"
   1.928 -            using 1 fin by (auto simp: finite_subset) }
   1.929 -        ultimately show ?thesis by(auto simp: image_def)
   1.930 -      qed
   1.931 -      finally show ?thesis by (rule sym)
   1.932 -    qed
   1.933 -    also from ih have "card ({T. T <= F & card T = k}) = card F choose k"
   1.934 -      by auto
   1.935 -    finally have "card ({T. T \<le> insert x F \<and> card T = k + 1}) = 
   1.936 -      card F choose (k + 1) + (card F choose k)".
   1.937 -    with iassms choose_plus_one_nat show ?case
   1.938 -      by (auto simp del: card.insert)
   1.939 -  qed
   1.940 -qed
   1.941 -
   1.942 -lemma choose_le_pow:
   1.943 -  assumes "r \<le> n" shows "n choose r \<le> n ^ r"
   1.944 -proof -
   1.945 -  have X: "\<And>r. r \<le> n \<Longrightarrow> \<Prod>{n - r..n} = (n - r) * \<Prod>{Suc (n - r)..n}"
   1.946 -    by (subst setprod_insert[symmetric]) (auto simp: atLeastAtMost_insertL)
   1.947 -  have "n choose r \<le> fact n div fact (n - r)"
   1.948 -    using `r \<le> n` by (simp add: choose_altdef_nat div_le_mono2)
   1.949 -  also have "\<dots> \<le> n ^ r" using `r \<le> n`
   1.950 -    by (induct r rule: nat.induct)
   1.951 -     (auto simp add: fact_div_fact Suc_diff_Suc X One_nat_def mult_le_mono)
   1.952 - finally show ?thesis .
   1.953 -qed
   1.954 -
   1.955  lemma card_UNION:
   1.956    assumes "finite A" and "\<forall>k \<in> A. finite k"
   1.957    shows "card (\<Union>A) = nat (\<Sum>I | I \<subseteq> A \<and> I \<noteq> {}. -1 ^ (card I + 1) * int (card (\<Inter>I)))"
   1.958 @@ -384,12 +665,11 @@
   1.959      assume x: "x \<in> \<Union>A"
   1.960      def K \<equiv> "{X \<in> A. x \<in> X}"
   1.961      with `finite A` have K: "finite K" by auto
   1.962 -
   1.963      let ?I = "\<lambda>i. {I. I \<subseteq> A \<and> card I = i \<and> x \<in> \<Inter>I}"
   1.964      have "inj_on snd (SIGMA i:{1..card A}. ?I i)"
   1.965        using assms by(auto intro!: inj_onI)
   1.966      moreover have [symmetric]: "snd ` (SIGMA i:{1..card A}. ?I i) = {I. I \<subseteq> A \<and> I \<noteq> {} \<and> x \<in> \<Inter>I}"
   1.967 -      using assms by(auto intro!: rev_image_eqI[where x="(card a, a)", standard] simp add: card_gt_0_iff[folded Suc_le_eq] One_nat_def dest: finite_subset intro: card_mono)
   1.968 +      using assms by(auto intro!: rev_image_eqI[where x="(card a, a)", standard] simp add: card_gt_0_iff[folded Suc_le_eq]  dest: finite_subset intro: card_mono)
   1.969      ultimately have "?lhs x = (\<Sum>(i, I)\<in>(SIGMA i:{1..card A}. ?I i). -1 ^ (i + 1))"
   1.970        by(rule setsum_reindex_cong[where f=snd]) fastforce
   1.971      also have "\<dots> = (\<Sum>i=1..card A. (\<Sum>I|I \<subseteq> A \<and> card I = i \<and> x \<in> \<Inter>I. -1 ^ (i + 1)))"
   1.972 @@ -420,13 +700,13 @@
   1.973      also have "{I. I \<subseteq> K \<and> card I = 0} = {{}}" using assms
   1.974        by(auto simp add: card_eq_0_iff K_def dest: finite_subset)
   1.975      hence "?rhs = (\<Sum>i = 0..card K. -1 ^ (i + 1) * (\<Sum>I | I \<subseteq> K \<and> card I = i. 1 :: int)) + 1"
   1.976 -      by(subst (2) setsum_head_Suc)(simp_all add: One_nat_def)
   1.977 +      by(subst (2) setsum_head_Suc)(simp_all )
   1.978      also have "\<dots> = (\<Sum>i = 0..card K. -1 * (-1 ^ i * int (card K choose i))) + 1"
   1.979 -      using K by(subst card_subsets_nat[symmetric]) simp_all
   1.980 +      using K by(subst n_subsets[symmetric]) simp_all
   1.981      also have "\<dots> = - (\<Sum>i = 0..card K. -1 ^ i * int (card K choose i)) + 1"
   1.982        by(subst setsum_right_distrib[symmetric]) simp
   1.983      also have "\<dots> =  - ((-1 + 1) ^ card K) + 1"
   1.984 -      by(subst binomial)(simp add: mult_ac)
   1.985 +      by(subst binomial_ring)(simp add: mult_ac)
   1.986      also have "\<dots> = 1" using x K by(auto simp add: K_def card_gt_0_iff)
   1.987      finally show "?lhs x = 1" .
   1.988    qed
     2.1 --- a/src/HOL/Number_Theory/Cong.thy	Thu Jan 23 16:09:28 2014 +0100
     2.2 +++ b/src/HOL/Number_Theory/Cong.thy	Fri Jan 24 15:21:00 2014 +0000
     2.3 @@ -31,34 +31,9 @@
     2.4  
     2.5  subsection {* Turn off @{text One_nat_def} *}
     2.6  
     2.7 -lemma induct'_nat [case_names zero plus1, induct type: nat]:
     2.8 -    "P (0::nat) \<Longrightarrow> (\<And>n. P n \<Longrightarrow> P (n + 1)) \<Longrightarrow> P n"
     2.9 -  by (induct n) (simp_all add: One_nat_def)
    2.10 -
    2.11 -lemma cases_nat [case_names zero plus1, cases type: nat]:
    2.12 -    "P (0::nat) \<Longrightarrow> (\<And>n. P (n + 1)) \<Longrightarrow> P n"
    2.13 -  by (rule induct'_nat)
    2.14 -
    2.15 -lemma power_plus_one [simp]: "(x::'a::power)^(n + 1) = x * x^n"
    2.16 -  by (simp add: One_nat_def)
    2.17 -
    2.18  lemma power_eq_one_eq_nat [simp]: "((x::nat)^m = 1) = (m = 0 | x = 1)"
    2.19    by (induct m) auto
    2.20  
    2.21 -lemma card_insert_if' [simp]: "finite A \<Longrightarrow>
    2.22 -    card (insert x A) = (if x \<in> A then (card A) else (card A) + 1)"
    2.23 -  by (auto simp add: insert_absorb)
    2.24 -
    2.25 -lemma nat_1' [simp]: "nat 1 = 1"
    2.26 -  by simp
    2.27 -
    2.28 -(* For those annoying moments where Suc reappears, use Suc_eq_plus1 *)
    2.29 -
    2.30 -declare nat_1 [simp del]
    2.31 -declare add_2_eq_Suc [simp del]
    2.32 -declare add_2_eq_Suc' [simp del]
    2.33 -
    2.34 -
    2.35  declare mod_pos_pos_trivial [simp]
    2.36  
    2.37  
    2.38 @@ -106,11 +81,8 @@
    2.39    "(x::int) >= 0 \<Longrightarrow> y >= 0 \<Longrightarrow> m >= 0 \<Longrightarrow>
    2.40      ([(nat x) = (nat y)] (mod (nat m))) = ([x = y] (mod m))"
    2.41    unfolding cong_int_def cong_nat_def
    2.42 -  apply (auto simp add: nat_mod_distrib [symmetric])
    2.43 -  apply (subst (asm) eq_nat_nat_iff)
    2.44 -  apply (cases "m = 0", force, rule pos_mod_sign, force)+
    2.45 -  apply assumption
    2.46 -  done
    2.47 +  by (metis Divides.transfer_int_nat_functions(2) nat_0_le nat_mod_distrib)
    2.48 +
    2.49  
    2.50  declare transfer_morphism_nat_int[transfer add return:
    2.51      transfer_nat_int_cong]
    2.52 @@ -138,7 +110,7 @@
    2.53    unfolding cong_nat_def by auto
    2.54  
    2.55  lemma cong_Suc_0_nat [simp, presburger]: "[(a::nat) = b] (mod Suc 0)"
    2.56 -  unfolding cong_nat_def by (auto simp add: One_nat_def)
    2.57 +  unfolding cong_nat_def by auto
    2.58  
    2.59  lemma cong_1_int [simp, presburger]: "[(a::int) = b] (mod 1)"
    2.60    unfolding cong_int_def by auto
    2.61 @@ -171,32 +143,20 @@
    2.62  
    2.63  lemma cong_add_nat:
    2.64      "[(a::nat) = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a + c = b + d] (mod m)"
    2.65 -  apply (unfold cong_nat_def)
    2.66 -  apply (subst (1 2) mod_add_eq)
    2.67 -  apply simp
    2.68 -  done
    2.69 +  unfolding cong_nat_def  by (metis mod_add_cong)
    2.70  
    2.71  lemma cong_add_int:
    2.72      "[(a::int) = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a + c = b + d] (mod m)"
    2.73 -  apply (unfold cong_int_def)
    2.74 -  apply (subst (1 2) mod_add_left_eq)
    2.75 -  apply (subst (1 2) mod_add_right_eq)
    2.76 -  apply simp
    2.77 -  done
    2.78 +  unfolding cong_int_def  by (metis mod_add_cong)
    2.79  
    2.80  lemma cong_diff_int:
    2.81      "[(a::int) = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a - c = b - d] (mod m)"
    2.82 -  apply (unfold cong_int_def)
    2.83 -  apply (subst (1 2) mod_diff_eq)
    2.84 -  apply simp
    2.85 -  done
    2.86 +  unfolding cong_int_def  by (metis mod_diff_cong) 
    2.87  
    2.88  lemma cong_diff_aux_int:
    2.89    "(a::int) >= c \<Longrightarrow> b >= d \<Longrightarrow> [(a::int) = b] (mod m) \<Longrightarrow>
    2.90        [c = d] (mod m) \<Longrightarrow> [tsub a c = tsub b d] (mod m)"
    2.91 -  apply (subst (1 2) tsub_eq)
    2.92 -  apply (auto intro: cong_diff_int)
    2.93 -  done
    2.94 +  by (metis cong_diff_int tsub_eq)
    2.95  
    2.96  lemma cong_diff_nat:
    2.97    assumes "(a::nat) >= c" and "b >= d" and "[a = b] (mod m)" and
    2.98 @@ -206,19 +166,11 @@
    2.99  
   2.100  lemma cong_mult_nat:
   2.101      "[(a::nat) = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a * c = b * d] (mod m)"
   2.102 -  apply (unfold cong_nat_def)
   2.103 -  apply (subst (1 2) mod_mult_eq)
   2.104 -  apply simp
   2.105 -  done
   2.106 +  unfolding cong_nat_def  by (metis mod_mult_cong) 
   2.107  
   2.108  lemma cong_mult_int:
   2.109      "[(a::int) = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a * c = b * d] (mod m)"
   2.110 -  apply (unfold cong_int_def)
   2.111 -  apply (subst (1 2) mod_mult_right_eq)
   2.112 -  apply (subst (1 2) mult_commute)
   2.113 -  apply (subst (1 2) mod_mult_right_eq)
   2.114 -  apply simp
   2.115 -  done
   2.116 +  unfolding cong_int_def  by (metis mod_mult_cong) 
   2.117  
   2.118  lemma cong_exp_nat: "[(x::nat) = y] (mod n) \<Longrightarrow> [x^k = y^k] (mod n)"
   2.119    by (induct k) (auto simp add: cong_mult_nat)
   2.120 @@ -277,10 +229,7 @@
   2.121    unfolding cong_int_def by auto
   2.122  
   2.123  lemma cong_eq_diff_cong_0_int: "[(a::int) = b] (mod m) = [a - b = 0] (mod m)"
   2.124 -  apply (rule iffI)
   2.125 -  apply (erule cong_diff_int [of a b m b b, simplified])
   2.126 -  apply (erule cong_add_int [of "a - b" 0 m b b, simplified])
   2.127 -  done
   2.128 +  by (metis cong_add_int cong_diff_int cong_refl_int diff_add_cancel diff_self)
   2.129  
   2.130  lemma cong_eq_diff_cong_0_aux_int: "a >= b \<Longrightarrow>
   2.131      [(a::int) = b] (mod m) = [tsub a b = 0] (mod m)"
   2.132 @@ -294,14 +243,7 @@
   2.133  lemma cong_diff_cong_0'_nat:
   2.134    "[(x::nat) = y] (mod n) \<longleftrightarrow>
   2.135      (if x <= y then [y - x = 0] (mod n) else [x - y = 0] (mod n))"
   2.136 -  apply (cases "y <= x")
   2.137 -  apply (frule cong_eq_diff_cong_0_nat [where m = n])
   2.138 -  apply auto [1]
   2.139 -  apply (subgoal_tac "x <= y")
   2.140 -  apply (frule cong_eq_diff_cong_0_nat [where m = n])
   2.141 -  apply (subst cong_sym_eq_nat)
   2.142 -  apply auto
   2.143 -  done
   2.144 +  by (metis cong_eq_diff_cong_0_nat cong_sym_nat nat_le_linear)
   2.145  
   2.146  lemma cong_altdef_nat: "(a::nat) >= b \<Longrightarrow> [a = b] (mod m) = (m dvd (a - b))"
   2.147    apply (subst cong_eq_diff_cong_0_nat, assumption)
   2.148 @@ -447,12 +389,6 @@
   2.149    apply auto
   2.150    done
   2.151  
   2.152 -lemma cong_zero_nat: "[(a::nat) = b] (mod 0) = (a = b)"
   2.153 -  by auto
   2.154 -
   2.155 -lemma cong_zero_int: "[(a::int) = b] (mod 0) = (a = b)"
   2.156 -  by auto
   2.157 -
   2.158  (*
   2.159  lemma mod_dvd_mod_int:
   2.160      "0 < (m::int) \<Longrightarrow> m dvd b \<Longrightarrow> (a mod b mod m) = (a mod m)"
   2.161 @@ -552,6 +488,9 @@
   2.162    apply auto
   2.163    done
   2.164  
   2.165 +lemma cong_0_1_nat': "[(0::nat) = Suc 0] (mod n) = (n = Suc 0)"
   2.166 +  unfolding cong_nat_def by auto
   2.167 +
   2.168  lemma cong_0_1_nat: "[(0::nat) = 1] (mod n) = (n = 1)"
   2.169    unfolding cong_nat_def by auto
   2.170  
   2.171 @@ -565,7 +504,7 @@
   2.172    apply (drule_tac x = "a - 1" in spec)
   2.173    apply force
   2.174    apply (cases "a = 0")
   2.175 -  apply (auto simp add: cong_0_1_nat) [1]
   2.176 +  apply (auto simp add: cong_0_1_nat') [1]
   2.177    apply (rule iffI)
   2.178    apply (drule cong_to_1_nat)
   2.179    apply (unfold dvd_def)
   2.180 @@ -667,9 +606,10 @@
   2.181    apply auto
   2.182    done
   2.183  
   2.184 -lemma coprime_iff_invertible_nat: "m > (1::nat) \<Longrightarrow> coprime a m = (EX x. [a * x = 1] (mod m))"
   2.185 +lemma coprime_iff_invertible_nat: "m > Suc 0 \<Longrightarrow> coprime a m = (EX x. [a * x = Suc 0] (mod m))"
   2.186    apply (auto intro: cong_solve_coprime_nat)
   2.187 -  apply (unfold cong_nat_def, auto intro: invertible_coprime_nat)
   2.188 +  apply (metis cong_solve_nat gcd_nat.left_neutral nat_neq_iff)
   2.189 +  apply (unfold cong_nat_def, auto intro: invertible_coprime_nat [unfolded One_nat_def])
   2.190    done
   2.191  
   2.192  lemma coprime_iff_invertible_int: "m > (1::int) \<Longrightarrow> coprime a m = (EX x. [a * x = 1] (mod m))"
     3.1 --- a/src/HOL/Number_Theory/Eratosthenes.thy	Thu Jan 23 16:09:28 2014 +0100
     3.2 +++ b/src/HOL/Number_Theory/Eratosthenes.thy	Fri Jan 24 15:21:00 2014 +0000
     3.3 @@ -257,7 +257,7 @@
     3.4  proof (cases "n > 1")
     3.5    case False then have "n = 0 \<or> n = 1" by arith
     3.6    then show ?thesis
     3.7 -    by (auto simp add: numbers_of_marks_sieve One_nat_def numeral_2_eq_2 set_primes_upto dest: prime_gt_Suc_0_nat)
     3.8 +    by (auto simp add: numbers_of_marks_sieve numeral_2_eq_2 set_primes_upto dest: prime_gt_Suc_0_nat)
     3.9  next
    3.10    { fix m q
    3.11      assume "Suc (Suc 0) \<le> q"
    3.12 @@ -280,9 +280,9 @@
    3.13      \<forall>m\<in>{Suc (Suc 0)..<Suc n}. m dvd q \<longrightarrow> q dvd m \<Longrightarrow>
    3.14      m dvd q \<Longrightarrow> m \<noteq> q \<Longrightarrow> m = 1" by auto
    3.15    case True then show ?thesis
    3.16 -    apply (auto simp add: numbers_of_marks_sieve One_nat_def numeral_2_eq_2 set_primes_upto dest: prime_gt_Suc_0_nat)
    3.17 -    apply (simp add: prime_nat_def dvd_def)
    3.18 -    apply (auto simp add: prime_nat_def aux)
    3.19 +    apply (auto simp add: numbers_of_marks_sieve numeral_2_eq_2 set_primes_upto dest: prime_gt_Suc_0_nat)
    3.20 +    apply (metis One_nat_def Suc_le_eq less_not_refl prime_nat_def)
    3.21 +    apply (metis One_nat_def Suc_le_eq aux prime_nat_def)
    3.22      done
    3.23  qed
    3.24  
     4.1 --- a/src/HOL/Number_Theory/Primes.thy	Thu Jan 23 16:09:28 2014 +0100
     4.2 +++ b/src/HOL/Number_Theory/Primes.thy	Fri Jan 24 15:21:00 2014 +0000
     4.3 @@ -31,6 +31,8 @@
     4.4  imports "~~/src/HOL/GCD"
     4.5  begin
     4.6  
     4.7 +declare One_nat_def [simp]
     4.8 +
     4.9  class prime = one +
    4.10    fixes prime :: "'a \<Rightarrow> bool"
    4.11  
    4.12 @@ -172,10 +174,7 @@
    4.13    by (induct n) auto
    4.14  
    4.15  lemma prime_dvd_power_int: "prime (p::int) \<Longrightarrow> p dvd x^n \<Longrightarrow> p dvd x"
    4.16 -  apply (induct n)
    4.17 -  apply (frule prime_ge_0_int)
    4.18 -  apply auto
    4.19 -  done
    4.20 +  by (induct n) (auto simp: prime_ge_0_int)
    4.21  
    4.22  lemma prime_dvd_power_nat_iff: "prime (p::nat) \<Longrightarrow> n > 0 \<Longrightarrow>
    4.23      p dvd x^n \<longleftrightarrow> p dvd x"
    4.24 @@ -198,7 +197,7 @@
    4.25    by (simp add: prime_nat_def)
    4.26  
    4.27  lemma Suc_0_not_prime_nat [simp]: "~prime (Suc 0)"
    4.28 -  by (simp add: prime_nat_def One_nat_def)
    4.29 +  by (simp add: prime_nat_def)
    4.30  
    4.31  lemma one_not_prime_int [simp]: "~prime (1::int)"
    4.32    by (simp add: prime_int_def)
    4.33 @@ -206,7 +205,7 @@
    4.34  lemma prime_nat_code [code]:
    4.35      "prime (p::nat) \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p)"
    4.36    apply (simp add: Ball_def)
    4.37 -  apply (metis less_not_refl prime_nat_def dvd_triv_right not_prime_eq_prod_nat)
    4.38 +  apply (metis One_nat_def less_not_refl prime_nat_def dvd_triv_right not_prime_eq_prod_nat)
    4.39    done
    4.40  
    4.41  lemma prime_nat_simp:
    4.42 @@ -246,28 +245,16 @@
    4.43  
    4.44  
    4.45  lemma prime_imp_power_coprime_nat: "prime (p::nat) \<Longrightarrow> ~ p dvd a \<Longrightarrow> coprime a (p^m)"
    4.46 -  apply (rule coprime_exp_nat)
    4.47 -  apply (subst gcd_commute_nat)
    4.48 -  apply (erule (1) prime_imp_coprime_nat)
    4.49 -  done
    4.50 +  by (metis coprime_exp_nat gcd_nat.commute prime_imp_coprime_nat)
    4.51  
    4.52  lemma prime_imp_power_coprime_int: "prime (p::int) \<Longrightarrow> ~ p dvd a \<Longrightarrow> coprime a (p^m)"
    4.53 -  apply (rule coprime_exp_int)
    4.54 -  apply (subst gcd_commute_int)
    4.55 -  apply (erule (1) prime_imp_coprime_int)
    4.56 -  done
    4.57 +  by (metis coprime_exp_int gcd_int.commute prime_imp_coprime_int)
    4.58  
    4.59  lemma primes_coprime_nat: "prime (p::nat) \<Longrightarrow> prime q \<Longrightarrow> p \<noteq> q \<Longrightarrow> coprime p q"
    4.60 -  apply (rule prime_imp_coprime_nat, assumption)
    4.61 -  apply (unfold prime_nat_def)
    4.62 -  apply auto
    4.63 -  done
    4.64 +  by (metis gcd_nat.absorb1 gcd_nat.absorb2 prime_imp_coprime_nat)
    4.65  
    4.66  lemma primes_coprime_int: "prime (p::int) \<Longrightarrow> prime q \<Longrightarrow> p \<noteq> q \<Longrightarrow> coprime p q"
    4.67 -  apply (rule prime_imp_coprime_int, assumption)
    4.68 -  apply (unfold prime_int_altdef)
    4.69 -  apply (metis int_one_le_iff_zero_less less_le)
    4.70 -  done
    4.71 +  by (metis leD linear prime_gt_0_int prime_imp_coprime_int prime_int_altdef)
    4.72  
    4.73  lemma primes_imp_powers_coprime_nat:
    4.74      "prime (p::nat) \<Longrightarrow> prime q \<Longrightarrow> p ~= q \<Longrightarrow> coprime (p^m) (q^n)"
    4.75 @@ -286,46 +273,6 @@
    4.76      nat_dvd_not_less neq0_conv prime_nat_def)
    4.77    done
    4.78  
    4.79 -(* An Isar version:
    4.80 -
    4.81 -lemma prime_factor_b_nat:
    4.82 -  fixes n :: nat
    4.83 -  assumes "n \<noteq> 1"
    4.84 -  shows "\<exists>p. prime p \<and> p dvd n"
    4.85 -
    4.86 -using `n ~= 1`
    4.87 -proof (induct n rule: less_induct_nat)
    4.88 -  fix n :: nat
    4.89 -  assume "n ~= 1" and
    4.90 -    ih: "\<forall>m<n. m \<noteq> 1 \<longrightarrow> (\<exists>p. prime p \<and> p dvd m)"
    4.91 -  then show "\<exists>p. prime p \<and> p dvd n"
    4.92 -  proof -
    4.93 -  {
    4.94 -    assume "n = 0"
    4.95 -    moreover note two_is_prime_nat
    4.96 -    ultimately have ?thesis
    4.97 -      by (auto simp del: two_is_prime_nat)
    4.98 -  }
    4.99 -  moreover
   4.100 -  {
   4.101 -    assume "prime n"
   4.102 -    then have ?thesis by auto
   4.103 -  }
   4.104 -  moreover
   4.105 -  {
   4.106 -    assume "n ~= 0" and "~ prime n"
   4.107 -    with `n ~= 1` have "n > 1" by auto
   4.108 -    with `~ prime n` and not_prime_eq_prod_nat obtain m k where
   4.109 -      "n = m * k" and "1 < m" and "m < n" by blast
   4.110 -    with ih obtain p where "prime p" and "p dvd m" by blast
   4.111 -    with `n = m * k` have ?thesis by auto
   4.112 -  }
   4.113 -  ultimately show ?thesis by blast
   4.114 -  qed
   4.115 -qed
   4.116 -
   4.117 -*)
   4.118 -
   4.119  text {* One property of coprimality is easier to prove via prime factors. *}
   4.120  
   4.121  lemma prime_divprod_pow_nat:
     5.1 --- a/src/HOL/Number_Theory/UniqueFactorization.thy	Thu Jan 23 16:09:28 2014 +0100
     5.2 +++ b/src/HOL/Number_Theory/UniqueFactorization.thy	Fri Jan 24 15:21:00 2014 +0000
     5.3 @@ -14,9 +14,6 @@
     5.4  imports Cong "~~/src/HOL/Library/Multiset"
     5.5  begin
     5.6  
     5.7 -(* inherited from Multiset *)
     5.8 -declare One_nat_def [simp del] 
     5.9 -
    5.10  (* As a simp or intro rule,
    5.11  
    5.12       prime p \<Longrightarrow> p > 0
    5.13 @@ -290,9 +287,6 @@
    5.14    using assms apply auto
    5.15    done
    5.16  
    5.17 -lemma neq_zero_eq_gt_zero_nat: "((x::nat) ~= 0) = (x > 0)"
    5.18 -  by auto
    5.19 -
    5.20  lemma prime_factorization_unique_nat: 
    5.21    fixes f :: "nat \<Rightarrow> _"
    5.22    assumes S_eq: "S = {p. 0 < f p}" and "finite S"
    5.23 @@ -412,18 +406,19 @@
    5.24  lemma multiplicity_zero_int [simp]: "multiplicity (p::int) 0 = 0"
    5.25    by (simp add: multiplicity_int_def) 
    5.26  
    5.27 -lemma multiplicity_one_nat [simp]: "multiplicity p (1::nat) = 0"
    5.28 +lemma multiplicity_one_nat': "multiplicity p (1::nat) = 0"
    5.29    by (subst multiplicity_characterization_nat [where f = "%x. 0"], auto)
    5.30  
    5.31 +lemma multiplicity_one_nat [simp]: "multiplicity p (Suc 0) = 0"
    5.32 +  by (metis One_nat_def multiplicity_one_nat')
    5.33 +
    5.34  lemma multiplicity_one_int [simp]: "multiplicity p (1::int) = 0"
    5.35 -  by (simp add: multiplicity_int_def)
    5.36 +  by (metis multiplicity_int_def multiplicity_one_nat' transfer_nat_int_numerals(2))
    5.37  
    5.38  lemma multiplicity_prime_nat [simp]: "prime (p::nat) \<Longrightarrow> multiplicity p p = 1"
    5.39    apply (subst multiplicity_characterization_nat [where f = "(%q. if q = p then 1 else 0)"])
    5.40    apply auto
    5.41 -  apply (case_tac "x = p")
    5.42 -  apply auto
    5.43 -  done
    5.44 +  by (metis (full_types) less_not_refl)
    5.45  
    5.46  lemma multiplicity_prime_int [simp]: "prime (p::int) \<Longrightarrow> multiplicity p p = 1"
    5.47    unfolding prime_int_def multiplicity_int_def by auto
    5.48 @@ -433,9 +428,7 @@
    5.49    apply auto
    5.50    apply (subst multiplicity_characterization_nat [where f = "(%q. if q = p then n else 0)"])
    5.51    apply auto
    5.52 -  apply (case_tac "x = p")
    5.53 -  apply auto
    5.54 -  done
    5.55 +  by (metis (full_types) less_not_refl)
    5.56  
    5.57  lemma multiplicity_prime_power_int [simp]: "prime (p::int) \<Longrightarrow> multiplicity p (p^n) = n"
    5.58    apply (frule prime_ge_0_int)
    5.59 @@ -464,6 +457,7 @@
    5.60    apply auto
    5.61    done
    5.62  
    5.63 +(*FIXME: messy*)
    5.64  lemma multiplicity_product_aux_nat: "(k::nat) > 0 \<Longrightarrow> l > 0 \<Longrightarrow>
    5.65      (prime_factors k) Un (prime_factors l) = prime_factors (k * l) &
    5.66      (ALL p. multiplicity p k + multiplicity p l = multiplicity p (k * l))"
    5.67 @@ -472,13 +466,13 @@
    5.68    apply auto
    5.69    apply (subst power_add)
    5.70    apply (subst setprod_timesf)
    5.71 -  apply (rule arg_cong2)back back
    5.72 +  apply (rule arg_cong2 [where f = "\<lambda>x y. x*y"])
    5.73    apply (subgoal_tac "prime_factors k Un prime_factors l = prime_factors k Un 
    5.74        (prime_factors l - prime_factors k)")
    5.75    apply (erule ssubst)
    5.76    apply (subst setprod_Un_disjoint)
    5.77    apply auto
    5.78 -  apply(simp add: prime_factorization_nat)
    5.79 +  apply (metis One_nat_def nat_mult_1_right prime_factorization_nat setprod.neutral_const)
    5.80    apply (subgoal_tac "prime_factors k Un prime_factors l = prime_factors l Un 
    5.81        (prime_factors k - prime_factors l)")
    5.82    apply (erule ssubst)
    5.83 @@ -486,8 +480,8 @@
    5.84    apply auto
    5.85    apply (subgoal_tac "(\<Prod>p\<in>prime_factors k - prime_factors l. p ^ multiplicity p l) = 
    5.86        (\<Prod>p\<in>prime_factors k - prime_factors l. 1)")
    5.87 -  apply (simp add: prime_factorization_nat)
    5.88 -  apply (rule setprod_cong, auto)
    5.89 +  apply auto
    5.90 +  apply (metis One_nat_def nat_mult_1_right prime_factorization_nat setprod.neutral_const)
    5.91    done
    5.92  
    5.93  (* transfer doesn't have the same problem here with the right 
    5.94 @@ -639,13 +633,13 @@
    5.95      "0 < (y::nat) \<Longrightarrow> x dvd y \<Longrightarrow> prime_factors x <= prime_factors y"
    5.96    apply (simp only: prime_factors_altdef_nat)
    5.97    apply auto
    5.98 -  apply (metis dvd_multiplicity_nat le_0_eq neq_zero_eq_gt_zero_nat)
    5.99 +  apply (metis dvd_multiplicity_nat le_0_eq neq0_conv)
   5.100    done
   5.101  
   5.102  lemma dvd_prime_factors_int [intro]:
   5.103      "0 < (y::int) \<Longrightarrow> 0 <= x \<Longrightarrow> x dvd y \<Longrightarrow> prime_factors x <= prime_factors y"
   5.104    apply (auto simp add: prime_factors_altdef_int)
   5.105 -  apply (metis dvd_multiplicity_int le_0_eq neq_zero_eq_gt_zero_nat)
   5.106 +  apply (metis dvd_multiplicity_int le_0_eq neq0_conv)
   5.107    done
   5.108  
   5.109  lemma multiplicity_dvd_nat: "0 < (x::nat) \<Longrightarrow> 0 < y \<Longrightarrow>