author | wenzelm |
Fri, 29 Nov 2024 17:40:15 +0100 | |
changeset 81507 | 08574da77b4a |
parent 80654 | 10c712405854 |
permissions | -rw-r--r-- |
80177 | 1 |
section \<open>More facts about binomial coefficients\<close> |
2 |
||
3 |
text \<open> |
|
4 |
These facts could have been proven before, but having real numbers |
|
5 |
makes the proofs a lot easier. Thanks to Alexander Maletzky among others. |
|
6 |
\<close> |
|
7 |
||
8 |
theory Binomial_Plus |
|
9 |
imports Real |
|
10 |
begin |
|
11 |
||
12 |
subsection \<open>More facts about binomial coefficients\<close> |
|
13 |
||
14 |
text \<open> |
|
15 |
These facts could have been proven before, but having real numbers |
|
16 |
makes the proofs a lot easier. |
|
17 |
\<close> |
|
18 |
||
19 |
lemma central_binomial_odd: |
|
20 |
"odd n \<Longrightarrow> n choose (Suc (n div 2)) = n choose (n div 2)" |
|
21 |
proof - |
|
22 |
assume "odd n" |
|
23 |
hence "Suc (n div 2) \<le> n" by presburger |
|
24 |
hence "n choose (Suc (n div 2)) = n choose (n - Suc (n div 2))" |
|
25 |
by (rule binomial_symmetric) |
|
26 |
also from \<open>odd n\<close> have "n - Suc (n div 2) = n div 2" by presburger |
|
27 |
finally show ?thesis . |
|
28 |
qed |
|
29 |
||
30 |
lemma binomial_less_binomial_Suc: |
|
31 |
assumes k: "k < n div 2" |
|
32 |
shows "n choose k < n choose (Suc k)" |
|
33 |
proof - |
|
34 |
from k have k': "k \<le> n" "Suc k \<le> n" by simp_all |
|
35 |
from k' have "real (n choose k) = fact n / (fact k * fact (n - k))" |
|
36 |
by (simp add: binomial_fact) |
|
37 |
also from k' have "n - k = Suc (n - Suc k)" by simp |
|
38 |
also from k' have "fact \<dots> = (real n - real k) * fact (n - Suc k)" |
|
39 |
by (subst fact_Suc) (simp_all add: of_nat_diff) |
|
40 |
also from k have "fact k = fact (Suc k) / (real k + 1)" by (simp add: field_simps) |
|
41 |
also have "fact n / (fact (Suc k) / (real k + 1) * ((real n - real k) * fact (n - Suc k))) = |
|
42 |
(n choose (Suc k)) * ((real k + 1) / (real n - real k))" |
|
43 |
using k by (simp add: field_split_simps binomial_fact) |
|
44 |
also from assms have "(real k + 1) / (real n - real k) < 1" by simp |
|
45 |
finally show ?thesis using k by (simp add: mult_less_cancel_left) |
|
46 |
qed |
|
47 |
||
48 |
lemma binomial_strict_mono: |
|
49 |
assumes "k < k'" "2*k' \<le> n" |
|
50 |
shows "n choose k < n choose k'" |
|
51 |
proof - |
|
52 |
from assms have "k \<le> k' - 1" by simp |
|
53 |
thus ?thesis |
|
54 |
proof (induction rule: inc_induct) |
|
55 |
case base |
|
56 |
with assms binomial_less_binomial_Suc[of "k' - 1" n] |
|
57 |
show ?case by simp |
|
58 |
next |
|
59 |
case (step k) |
|
60 |
from step.prems step.hyps assms have "n choose k < n choose (Suc k)" |
|
61 |
by (intro binomial_less_binomial_Suc) simp_all |
|
62 |
also have "\<dots> < n choose k'" by (rule step.IH) |
|
63 |
finally show ?case . |
|
64 |
qed |
|
65 |
qed |
|
66 |
||
67 |
lemma binomial_mono: |
|
68 |
assumes "k \<le> k'" "2*k' \<le> n" |
|
69 |
shows "n choose k \<le> n choose k'" |
|
70 |
using assms binomial_strict_mono[of k k' n] by (cases "k = k'") simp_all |
|
71 |
||
72 |
lemma binomial_strict_antimono: |
|
73 |
assumes "k < k'" "2 * k \<ge> n" "k' \<le> n" |
|
74 |
shows "n choose k > n choose k'" |
|
75 |
proof - |
|
76 |
from assms have "n choose (n - k) > n choose (n - k')" |
|
77 |
by (intro binomial_strict_mono) (simp_all add: algebra_simps) |
|
78 |
with assms show ?thesis by (simp add: binomial_symmetric [symmetric]) |
|
79 |
qed |
|
80 |
||
81 |
lemma binomial_antimono: |
|
82 |
assumes "k \<le> k'" "k \<ge> n div 2" "k' \<le> n" |
|
83 |
shows "n choose k \<ge> n choose k'" |
|
84 |
proof (cases "k = k'") |
|
85 |
case False |
|
86 |
note not_eq = False |
|
87 |
show ?thesis |
|
88 |
proof (cases "k = n div 2 \<and> odd n") |
|
89 |
case False |
|
90 |
with assms(2) have "2*k \<ge> n" by presburger |
|
91 |
with not_eq assms binomial_strict_antimono[of k k' n] |
|
92 |
show ?thesis by simp |
|
93 |
next |
|
94 |
case True |
|
95 |
have "n choose k' \<le> n choose (Suc (n div 2))" |
|
96 |
proof (cases "k' = Suc (n div 2)") |
|
97 |
case False |
|
98 |
with assms True not_eq have "Suc (n div 2) < k'" by simp |
|
99 |
with assms binomial_strict_antimono[of "Suc (n div 2)" k' n] True |
|
100 |
show ?thesis by auto |
|
101 |
qed simp_all |
|
102 |
also from True have "\<dots> = n choose k" by (simp add: central_binomial_odd) |
|
103 |
finally show ?thesis . |
|
104 |
qed |
|
105 |
qed simp_all |
|
106 |
||
107 |
lemma binomial_maximum: "n choose k \<le> n choose (n div 2)" |
|
108 |
proof - |
|
109 |
have "k \<le> n div 2 \<longleftrightarrow> 2*k \<le> n" by linarith |
|
110 |
consider "2*k \<le> n" | "2*k \<ge> n" "k \<le> n" | "k > n" by linarith |
|
111 |
thus ?thesis |
|
112 |
proof cases |
|
113 |
case 1 |
|
114 |
thus ?thesis by (intro binomial_mono) linarith+ |
|
115 |
next |
|
116 |
case 2 |
|
117 |
thus ?thesis by (intro binomial_antimono) simp_all |
|
118 |
qed (simp_all add: binomial_eq_0) |
|
119 |
qed |
|
120 |
||
121 |
lemma binomial_maximum': "(2*n) choose k \<le> (2*n) choose n" |
|
122 |
using binomial_maximum[of "2*n"] by simp |
|
123 |
||
124 |
lemma central_binomial_lower_bound: |
|
125 |
assumes "n > 0" |
|
126 |
shows "4^n / (2*real n) \<le> real ((2*n) choose n)" |
|
127 |
proof - |
|
128 |
from binomial[of 1 1 "2*n"] |
|
129 |
have "4 ^ n = (\<Sum>k\<le>2*n. (2*n) choose k)" |
|
130 |
by (simp add: power_mult power2_eq_square One_nat_def [symmetric] del: One_nat_def) |
|
131 |
also have "{..2*n} = {0<..<2*n} \<union> {0,2*n}" by auto |
|
132 |
also have "(\<Sum>k\<in>\<dots>. (2*n) choose k) = |
|
133 |
(\<Sum>k\<in>{0<..<2*n}. (2*n) choose k) + (\<Sum>k\<in>{0,2*n}. (2*n) choose k)" |
|
134 |
by (subst sum.union_disjoint) auto |
|
135 |
also have "(\<Sum>k\<in>{0,2*n}. (2*n) choose k) \<le> (\<Sum>k\<le>1. (n choose k)\<^sup>2)" |
|
136 |
by (cases n) simp_all |
|
137 |
also from assms have "\<dots> \<le> (\<Sum>k\<le>n. (n choose k)\<^sup>2)" |
|
138 |
by (intro sum_mono2) auto |
|
139 |
also have "\<dots> = (2*n) choose n" by (rule choose_square_sum) |
|
140 |
also have "(\<Sum>k\<in>{0<..<2*n}. (2*n) choose k) \<le> (\<Sum>k\<in>{0<..<2*n}. (2*n) choose n)" |
|
141 |
by (intro sum_mono binomial_maximum') |
|
142 |
also have "\<dots> = card {0<..<2*n} * ((2*n) choose n)" by simp |
|
143 |
also have "card {0<..<2*n} \<le> 2*n - 1" by (cases n) simp_all |
|
144 |
also have "(2 * n - 1) * (2 * n choose n) + (2 * n choose n) = ((2*n) choose n) * (2*n)" |
|
145 |
using assms by (simp add: algebra_simps) |
|
146 |
finally have "4 ^ n \<le> (2 * n choose n) * (2 * n)" by simp_all |
|
147 |
hence "real (4 ^ n) \<le> real ((2 * n choose n) * (2 * n))" |
|
148 |
by (subst of_nat_le_iff) |
|
149 |
with assms show ?thesis by (simp add: field_simps) |
|
150 |
qed |
|
151 |
||
152 |
lemma upper_le_binomial: |
|
153 |
assumes "0 < k" and "k < n" |
|
154 |
shows "n \<le> n choose k" |
|
155 |
proof - |
|
156 |
from assms have "1 \<le> n" by simp |
|
157 |
define k' where "k' = (if n div 2 \<le> k then k else n - k)" |
|
158 |
from assms have 1: "k' \<le> n - 1" and 2: "n div 2 \<le> k'" by (auto simp: k'_def) |
|
159 |
from assms(2) have "k \<le> n" by simp |
|
160 |
have "n choose k = n choose k'" by (simp add: k'_def binomial_symmetric[OF \<open>k \<le> n\<close>]) |
|
161 |
have "n = n choose 1" by (simp only: choose_one) |
|
162 |
also from \<open>1 \<le> n\<close> have "\<dots> = n choose (n - 1)" by (rule binomial_symmetric) |
|
163 |
also from 1 2 have "\<dots> \<le> n choose k'" by (rule binomial_antimono) simp |
|
164 |
also have "\<dots> = n choose k" by (simp add: k'_def binomial_symmetric[OF \<open>k \<le> n\<close>]) |
|
165 |
finally show ?thesis . |
|
166 |
qed |
|
167 |
||
168 |
subsection \<open>Results about binomials and integers, thanks to Alexander Maletzky\<close> |
|
169 |
||
170 |
text \<open>Restore original sort constraints: semidom rather than field of char 0\<close> |
|
171 |
setup \<open>Sign.add_const_constraint (@{const_name gbinomial}, SOME @{typ "'a::{semidom_divide,semiring_char_0} \<Rightarrow> nat \<Rightarrow> 'a"})\<close> |
|
172 |
||
173 |
lemma gbinomial_eq_0_int: |
|
174 |
assumes "n < k" |
|
175 |
shows "(int n) gchoose k = 0" |
|
176 |
by (simp add: assms gbinomial_prod_rev prod_zero) |
|
177 |
||
178 |
corollary gbinomial_eq_0: "0 \<le> a \<Longrightarrow> a < int k \<Longrightarrow> a gchoose k = 0" |
|
179 |
by (metis nat_eq_iff2 nat_less_iff gbinomial_eq_0_int) |
|
180 |
||
80654 | 181 |
lemma gbinomial_mono: |
182 |
fixes k::nat and a::real |
|
183 |
assumes "of_nat k \<le> a" "a \<le> b" shows "a gchoose k \<le> b gchoose k" |
|
184 |
using assms |
|
185 |
by (force simp: gbinomial_prod_rev intro!: divide_right_mono prod_mono) |
|
186 |
||
80177 | 187 |
lemma int_binomial: "int (n choose k) = (int n) gchoose k" |
188 |
proof (cases "k \<le> n") |
|
189 |
case True |
|
190 |
from refl have eq: "(\<Prod>i = 0..<k. int (n - i)) = (\<Prod>i = 0..<k. int n - int i)" |
|
191 |
proof (rule prod.cong) |
|
192 |
fix i |
|
193 |
assume "i \<in> {0..<k}" |
|
194 |
with True show "int (n - i) = int n - int i" by simp |
|
195 |
qed |
|
196 |
show ?thesis |
|
197 |
by (simp add: gbinomial_binomial[symmetric] gbinomial_prod_rev zdiv_int eq) |
|
198 |
next |
|
199 |
case False |
|
200 |
thus ?thesis by (simp add: gbinomial_eq_0_int) |
|
201 |
qed |
|
202 |
||
203 |
lemma falling_fact_pochhammer: "prod (\<lambda>i. a - int i) {0..<k} = (- 1) ^ k * pochhammer (- a) k" |
|
204 |
proof - |
|
205 |
have eq: "z ^ Suc n * prod f {0..n} = prod (\<lambda>x. z * f x) {0..n}" for z::int and n f |
|
206 |
by (induct n) (simp_all add: ac_simps) |
|
207 |
show ?thesis |
|
208 |
proof (cases k) |
|
209 |
case 0 |
|
210 |
thus ?thesis by (simp add: pochhammer_minus) |
|
211 |
next |
|
212 |
case (Suc n) |
|
213 |
thus ?thesis |
|
214 |
by (simp only: pochhammer_prod atLeastLessThanSuc_atLeastAtMost |
|
215 |
prod.atLeast_Suc_atMost_Suc_shift eq flip: power_mult_distrib) (simp add: of_nat_diff) |
|
216 |
qed |
|
217 |
qed |
|
218 |
||
219 |
lemma falling_fact_pochhammer': "prod (\<lambda>i. a - int i) {0..<k} = pochhammer (a - int k + 1) k" |
|
220 |
by (simp add: falling_fact_pochhammer pochhammer_minus') |
|
221 |
||
222 |
lemma gbinomial_int_pochhammer: "(a::int) gchoose k = (- 1) ^ k * pochhammer (- a) k div fact k" |
|
223 |
by (simp only: gbinomial_prod_rev falling_fact_pochhammer) |
|
224 |
||
225 |
lemma gbinomial_int_pochhammer': "a gchoose k = pochhammer (a - int k + 1) k div fact k" |
|
226 |
by (simp only: gbinomial_prod_rev falling_fact_pochhammer') |
|
227 |
||
228 |
lemma fact_dvd_pochhammer: "fact k dvd pochhammer (a::int) k" |
|
229 |
proof - |
|
230 |
have dvd: "y \<noteq> 0 \<Longrightarrow> ((of_int (x div y))::'a::field_char_0) = of_int x / of_int y \<Longrightarrow> y dvd x" |
|
231 |
for x y :: int |
|
80276
360e6217cda6
tuned proof: avoid smt/z3 to make this work with arm64-linux;
wenzelm
parents:
80177
diff
changeset
|
232 |
by (metis dvd_triv_right nonzero_eq_divide_eq of_int_0_eq_iff of_int_eq_iff of_int_mult) |
80177 | 233 |
show ?thesis |
234 |
proof (cases "0 < a") |
|
235 |
case True |
|
236 |
moreover define n where "n = nat (a - 1) + k" |
|
237 |
ultimately have a: "a = int n - int k + 1" by simp |
|
238 |
from fact_nonzero show ?thesis unfolding a |
|
239 |
proof (rule dvd) |
|
240 |
have "of_int (pochhammer (int n - int k + 1) k div fact k) = (of_int (int n gchoose k)::rat)" |
|
241 |
by (simp only: gbinomial_int_pochhammer') |
|
242 |
also have "\<dots> = of_nat (n choose k)" |
|
243 |
by (metis int_binomial of_int_of_nat_eq) |
|
244 |
also have "\<dots> = (of_nat n) gchoose k" by (fact binomial_gbinomial) |
|
245 |
also have "\<dots> = pochhammer (of_nat n - of_nat k + 1) k / fact k" |
|
246 |
by (fact gbinomial_pochhammer') |
|
247 |
also have "\<dots> = pochhammer (of_int (int n - int k + 1)) k / fact k" by simp |
|
248 |
also have "\<dots> = (of_int (pochhammer (int n - int k + 1) k)) / (of_int (fact k))" |
|
249 |
by (simp only: of_int_fact pochhammer_of_int) |
|
250 |
finally show "of_int (pochhammer (int n - int k + 1) k div fact k) = |
|
251 |
of_int (pochhammer (int n - int k + 1) k) / rat_of_int (fact k)" . |
|
252 |
qed |
|
253 |
next |
|
254 |
case False |
|
255 |
moreover define n where "n = nat (- a)" |
|
256 |
ultimately have a: "a = - int n" by simp |
|
257 |
from fact_nonzero have "fact k dvd (-1)^k * pochhammer (- int n) k" |
|
258 |
proof (rule dvd) |
|
259 |
have "of_int ((-1)^k * pochhammer (- int n) k div fact k) = (of_int (int n gchoose k)::rat)" |
|
260 |
by (metis falling_fact_pochhammer gbinomial_prod_rev) |
|
261 |
also have "\<dots> = of_int (int (n choose k))" by (simp only: int_binomial) |
|
262 |
also have "\<dots> = of_nat (n choose k)" by simp |
|
263 |
also have "\<dots> = (of_nat n) gchoose k" by (fact binomial_gbinomial) |
|
264 |
also have "\<dots> = (-1)^k * pochhammer (- of_nat n) k / fact k" |
|
265 |
by (fact gbinomial_pochhammer) |
|
266 |
also have "\<dots> = (-1)^k * pochhammer (of_int (- int n)) k / fact k" by simp |
|
267 |
also have "\<dots> = (-1)^k * (of_int (pochhammer (- int n) k)) / (of_int (fact k))" |
|
268 |
by (simp only: of_int_fact pochhammer_of_int) |
|
269 |
also have "\<dots> = (of_int ((-1)^k * pochhammer (- int n) k)) / (of_int (fact k))" by simp |
|
270 |
finally show "of_int ((- 1) ^ k * pochhammer (- int n) k div fact k) = |
|
271 |
of_int ((- 1) ^ k * pochhammer (- int n) k) / rat_of_int (fact k)" . |
|
272 |
qed |
|
273 |
thus ?thesis unfolding a by (metis dvdI dvd_mult_unit_iff' minus_one_mult_self) |
|
274 |
qed |
|
275 |
qed |
|
276 |
||
277 |
lemma gbinomial_int_negated_upper: "(a gchoose k) = (-1) ^ k * ((int k - a - 1) gchoose k)" |
|
278 |
by (simp add: gbinomial_int_pochhammer pochhammer_minus algebra_simps fact_dvd_pochhammer div_mult_swap) |
|
279 |
||
280 |
lemma gbinomial_int_mult_fact: "fact k * (a gchoose k) = (\<Prod>i = 0..<k. a - int i)" |
|
281 |
by (simp only: gbinomial_int_pochhammer' fact_dvd_pochhammer dvd_mult_div_cancel falling_fact_pochhammer') |
|
282 |
||
283 |
corollary gbinomial_int_mult_fact': "(a gchoose k) * fact k = (\<Prod>i = 0..<k. a - int i)" |
|
284 |
using gbinomial_int_mult_fact[of k a] by (simp add: ac_simps) |
|
285 |
||
286 |
lemma gbinomial_int_binomial: |
|
287 |
"a gchoose k = (if 0 \<le> a then int ((nat a) choose k) else (-1::int)^k * int ((k + (nat (- a)) - 1) choose k))" |
|
288 |
by (auto simp: int_binomial gbinomial_int_negated_upper[of a] int_ops(6)) |
|
289 |
||
290 |
corollary gbinomial_nneg: "0 \<le> a \<Longrightarrow> a gchoose k = int ((nat a) choose k)" |
|
291 |
by (simp add: gbinomial_int_binomial) |
|
292 |
||
293 |
corollary gbinomial_neg: "a < 0 \<Longrightarrow> a gchoose k = (-1::int)^k * int ((k + (nat (- a)) - 1) choose k)" |
|
294 |
by (simp add: gbinomial_int_binomial) |
|
295 |
||
296 |
lemma of_int_gbinomial: "of_int (a gchoose k) = (of_int a :: 'a::field_char_0) gchoose k" |
|
297 |
proof - |
|
298 |
have of_int_div: "y dvd x \<Longrightarrow> of_int (x div y) = of_int x / (of_int y :: 'a)" for x y :: int by auto |
|
299 |
show ?thesis |
|
300 |
by (simp add: gbinomial_int_pochhammer' gbinomial_pochhammer' of_int_div fact_dvd_pochhammer |
|
301 |
pochhammer_of_int[symmetric]) |
|
302 |
qed |
|
303 |
||
304 |
lemma uminus_one_gbinomial [simp]: "(- 1::int) gchoose k = (- 1) ^ k" |
|
305 |
by (simp add: gbinomial_int_binomial) |
|
306 |
||
307 |
lemma gbinomial_int_Suc_Suc: "(x + 1::int) gchoose (Suc k) = (x gchoose k) + (x gchoose (Suc k))" |
|
308 |
proof (rule linorder_cases) |
|
309 |
assume 1: "x + 1 < 0" |
|
310 |
hence 2: "x < 0" by simp |
|
311 |
then obtain n where 3: "nat (- x) = Suc n" using not0_implies_Suc by fastforce |
|
312 |
hence 4: "nat (- x - 1) = n" by simp |
|
313 |
show ?thesis |
|
314 |
proof (cases k) |
|
315 |
case 0 |
|
316 |
show ?thesis by (simp add: \<open>k = 0\<close>) |
|
317 |
next |
|
318 |
case (Suc k') |
|
319 |
from 1 2 3 4 show ?thesis by (simp add: \<open>k = Suc k'\<close> gbinomial_int_binomial int_distrib(2)) |
|
320 |
qed |
|
321 |
next |
|
322 |
assume "x + 1 = 0" |
|
323 |
hence "x = - 1" by simp |
|
324 |
thus ?thesis by simp |
|
325 |
next |
|
326 |
assume "0 < x + 1" |
|
327 |
hence "0 \<le> x + 1" and "0 \<le> x" and "nat (x + 1) = Suc (nat x)" by simp_all |
|
328 |
thus ?thesis by (simp add: gbinomial_int_binomial) |
|
329 |
qed |
|
330 |
||
331 |
corollary plus_Suc_gbinomial: |
|
332 |
"(x + (1 + int k)) gchoose (Suc k) = ((x + int k) gchoose k) + ((x + int k) gchoose (Suc k))" |
|
333 |
(is "?l = ?r") |
|
334 |
proof - |
|
335 |
have "?l = (x + int k + 1) gchoose (Suc k)" by (simp only: ac_simps) |
|
336 |
also have "\<dots> = ?r" by (fact gbinomial_int_Suc_Suc) |
|
337 |
finally show ?thesis . |
|
338 |
qed |
|
339 |
||
340 |
lemma gbinomial_int_n_n [simp]: "(int n) gchoose n = 1" |
|
341 |
proof (induct n) |
|
342 |
case 0 |
|
343 |
show ?case by simp |
|
344 |
next |
|
345 |
case (Suc n) |
|
346 |
have "int (Suc n) gchoose Suc n = (int n + 1) gchoose Suc n" by (simp add: add.commute) |
|
347 |
also have "\<dots> = (int n gchoose n) + (int n gchoose (Suc n))" by (fact gbinomial_int_Suc_Suc) |
|
348 |
finally show ?case by (simp add: Suc gbinomial_eq_0) |
|
349 |
qed |
|
350 |
||
351 |
lemma gbinomial_int_Suc_n [simp]: "(1 + int n) gchoose n = 1 + int n" |
|
352 |
proof (induct n) |
|
353 |
case 0 |
|
354 |
show ?case by simp |
|
355 |
next |
|
356 |
case (Suc n) |
|
357 |
have "1 + int (Suc n) gchoose Suc n = (1 + int n) + 1 gchoose Suc n" by simp |
|
358 |
also have "\<dots> = (1 + int n gchoose n) + (1 + int n gchoose (Suc n))" by (fact gbinomial_int_Suc_Suc) |
|
359 |
also have "\<dots> = 1 + int n + (int (Suc n) gchoose (Suc n))" by (simp add: Suc) |
|
360 |
also have "\<dots> = 1 + int (Suc n)" by (simp only: gbinomial_int_n_n) |
|
361 |
finally show ?case . |
|
362 |
qed |
|
363 |
||
364 |
lemma zbinomial_eq_0_iff [simp]: "a gchoose k = 0 \<longleftrightarrow> (0 \<le> a \<and> a < int k)" |
|
365 |
proof |
|
366 |
assume a: "a gchoose k = 0" |
|
367 |
have 1: "b < int k" if "b gchoose k = 0" for b |
|
368 |
proof (rule ccontr) |
|
369 |
assume "\<not> b < int k" |
|
370 |
hence "0 \<le> b" and "k \<le> nat b" by simp_all |
|
371 |
from this(1) have "int ((nat b) choose k) = b gchoose k" by (simp add: gbinomial_int_binomial) |
|
372 |
also have "\<dots> = 0" by (fact that) |
|
373 |
finally show False using \<open>k \<le> nat b\<close> by simp |
|
374 |
qed |
|
375 |
show "0 \<le> a \<and> a < int k" |
|
376 |
proof |
|
377 |
show "0 \<le> a" |
|
378 |
proof (rule ccontr) |
|
379 |
assume "\<not> 0 \<le> a" |
|
380 |
hence "(-1) ^ k * ((int k - a - 1) gchoose k) = a gchoose k" |
|
381 |
by (simp add: gbinomial_int_negated_upper[of a]) |
|
382 |
also have "\<dots> = 0" by (fact a) |
|
383 |
finally have "(int k - a - 1) gchoose k = 0" by simp |
|
384 |
hence "int k - a - 1 < int k" by (rule 1) |
|
385 |
with \<open>\<not> 0 \<le> a\<close> show False by simp |
|
386 |
qed |
|
387 |
next |
|
388 |
from a show "a < int k" by (rule 1) |
|
389 |
qed |
|
390 |
qed (auto intro: gbinomial_eq_0) |
|
391 |
||
392 |
subsection \<open>Sums\<close> |
|
393 |
||
394 |
lemma gchoose_rising_sum_nat: "(\<Sum>j\<le>n. int j + int k gchoose k) = (int n + int k + 1) gchoose (Suc k)" |
|
395 |
proof - |
|
396 |
have "(\<Sum>j\<le>n. int j + int k gchoose k) = int (\<Sum>j\<le>n. k + j choose k)" |
|
397 |
by (simp add: int_binomial add.commute) |
|
398 |
also have "(\<Sum>j\<le>n. k + j choose k) = (k + n + 1) choose (k + 1)" by (fact choose_rising_sum(1)) |
|
399 |
also have "int \<dots> = (int n + int k + 1) gchoose (Suc k)" |
|
400 |
by (simp add: int_binomial ac_simps del: binomial_Suc_Suc) |
|
401 |
finally show ?thesis . |
|
402 |
qed |
|
403 |
||
404 |
lemma gchoose_rising_sum: |
|
405 |
assumes "0 \<le> n" \<comment>\<open>Necessary condition.\<close> |
|
406 |
shows "(\<Sum>j=0..n. j + int k gchoose k) = (n + int k + 1) gchoose (Suc k)" |
|
407 |
proof - |
|
408 |
from _ refl have "(\<Sum>j=0..n. j + int k gchoose k) = (\<Sum>j\<in>int ` {0..nat n}. j + int k gchoose k)" |
|
409 |
proof (rule sum.cong) |
|
410 |
from assms show "{0..n} = int ` {0..nat n}" by (simp add: image_int_atLeastAtMost) |
|
411 |
qed |
|
412 |
also have "\<dots> = (\<Sum>j\<le>nat n. int j + int k gchoose k)" by (simp add: sum.reindex atMost_atLeast0) |
|
413 |
also have "\<dots> = (int (nat n) + int k + 1) gchoose (Suc k)" by (fact gchoose_rising_sum_nat) |
|
414 |
also from assms have "\<dots> = (n + int k + 1) gchoose (Suc k)" by (simp add: add.assoc add.commute) |
|
415 |
finally show ?thesis . |
|
416 |
qed |
|
417 |
||
418 |
end |