@@ -17,13 +17,9 @@ import Mathlib.Tactic.Ring
17
17
This file includes variants of the binomial theorem and other results on sums of binomial
18
18
coefficients. Theorems whose proofs depend on such sums may also go in this file for import
19
19
reasons.
20
-
21
20
-/
22
21
23
-
24
- open Nat
25
-
26
- open Finset
22
+ open Nat Finset
27
23
28
24
variable {R : Type *}
29
25
@@ -33,114 +29,116 @@ variable [Semiring R] {x y : R}
33
29
34
30
/-- A version of the **binomial theorem** for commuting elements in noncommutative semirings. -/
35
31
theorem add_pow (h : Commute x y) (n : ℕ) :
36
- (x + y) ^ n = ∑ m ∈ range (n + 1 ), x ^ m * y ^ (n - m) * choose n m := by
37
- let t : ℕ → ℕ → R := fun n m ↦ x ^ m * y ^ (n - m) * choose n m
32
+ (x + y) ^ n = ∑ m ∈ range (n + 1 ), x ^ m * y ^ (n - m) * n.choose m := by
33
+ let t : ℕ → ℕ → R := fun n m ↦ x ^ m * y ^ (n - m) * n.choose m
38
34
change (x + y) ^ n = ∑ m ∈ range (n + 1 ), t n m
39
35
have h_first : ∀ n, t n 0 = y ^ n := fun n ↦ by
40
- simp only [t, choose_zero_right, _root_. pow_zero, Nat. cast_one, mul_one, one_mul, tsub_zero]
36
+ simp only [t, choose_zero_right, pow_zero, cast_one, mul_one, one_mul, tsub_zero]
41
37
have h_last : ∀ n, t n n.succ = 0 := fun n ↦ by
42
38
simp only [t, choose_succ_self, cast_zero, mul_zero]
43
39
have h_middle :
44
- ∀ n i : ℕ, i ∈ range n.succ → (t n.succ (Nat.succ i)) =
45
- x * t n i + y * t n i.succ := by
40
+ ∀ n i : ℕ, i ∈ range n.succ → (t n.succ i.succ) = x * t n i + y * t n i.succ := by
46
41
intro n i h_mem
47
- have h_le : i ≤ n := Nat. le_of_lt_succ (mem_range.mp h_mem)
42
+ have h_le : i ≤ n := le_of_lt_succ (mem_range.mp h_mem)
48
43
dsimp only [t]
49
- rw [choose_succ_succ, Nat. cast_add, mul_add]
44
+ rw [choose_succ_succ, cast_add, mul_add]
50
45
congr 1
51
46
· rw [pow_succ' x, succ_sub_succ, mul_assoc, mul_assoc, mul_assoc]
52
47
· rw [← mul_assoc y, ← mul_assoc y, (h.symm.pow_right i.succ).eq]
53
48
by_cases h_eq : i = n
54
- · rw [h_eq, choose_succ_self, Nat. cast_zero, mul_zero, mul_zero]
49
+ · rw [h_eq, choose_succ_self, cast_zero, mul_zero, mul_zero]
55
50
· rw [succ_sub (lt_of_le_of_ne h_le h_eq)]
56
51
rw [pow_succ' y, mul_assoc, mul_assoc, mul_assoc, mul_assoc]
57
- induction' n with n ih
58
- · rw [_root_.pow_zero, sum_range_succ, range_zero, sum_empty, zero_add]
52
+ induction n with
53
+ | zero =>
54
+ rw [pow_zero, sum_range_succ, range_zero, sum_empty, zero_add]
59
55
dsimp only [t]
60
- rw [_root_.pow_zero, _root_.pow_zero, choose_self, Nat.cast_one, mul_one, mul_one]
61
- · rw [sum_range_succ', h_first, sum_congr rfl (h_middle n), sum_add_distrib, add_assoc,
56
+ rw [pow_zero, pow_zero, choose_self, cast_one, mul_one, mul_one]
57
+ | succ n ih =>
58
+ rw [sum_range_succ', h_first, sum_congr rfl (h_middle n), sum_add_distrib, add_assoc,
62
59
pow_succ' (x + y), ih, add_mul, mul_sum, mul_sum]
63
60
congr 1
64
61
rw [sum_range_succ', sum_range_succ, h_first, h_last, mul_zero, add_zero, _root_.pow_succ']
65
62
66
63
/-- A version of `Commute.add_pow` that avoids ℕ-subtraction by summing over the antidiagonal and
67
64
also with the binomial coefficient applied via scalar action of ℕ. -/
68
65
theorem add_pow' (h : Commute x y) (n : ℕ) :
69
- (x + y) ^ n = ∑ m ∈ antidiagonal n, choose n m.fst • (x ^ m.fst * y ^ m.snd ) := by
70
- simp_rw [Finset. Nat.sum_antidiagonal_eq_sum_range_succ fun m p ↦ choose n m • (x ^ m * y ^ p),
71
- _root_. nsmul_eq_mul, cast_comm, h.add_pow]
66
+ (x + y) ^ n = ∑ m ∈ antidiagonal n, n. choose m. 1 • (x ^ m.1 * y ^ m.2 ) := by
67
+ simp_rw [Nat.sum_antidiagonal_eq_sum_range_succ fun m p ↦ n.choose m • (x ^ m * y ^ p),
68
+ nsmul_eq_mul, cast_comm, h.add_pow]
72
69
73
70
end Commute
74
71
75
72
/-- The **binomial theorem** -/
76
73
theorem add_pow [CommSemiring R] (x y : R) (n : ℕ) :
77
- (x + y) ^ n = ∑ m ∈ range (n + 1 ), x ^ m * y ^ (n - m) * choose n m :=
74
+ (x + y) ^ n = ∑ m ∈ range (n + 1 ), x ^ m * y ^ (n - m) * n.choose m :=
78
75
(Commute.all x y).add_pow n
79
76
80
77
namespace Nat
81
78
82
79
/-- The sum of entries in a row of Pascal's triangle -/
83
- theorem sum_range_choose (n : ℕ) : (∑ m ∈ range (n + 1 ), choose n m) = 2 ^ n := by
80
+ theorem sum_range_choose (n : ℕ) : (∑ m ∈ range (n + 1 ), n.choose m) = 2 ^ n := by
84
81
have := (add_pow 1 1 n).symm
85
82
simpa [one_add_one_eq_two] using this
86
83
87
- theorem sum_range_choose_halfway (m : Nat ) : (∑ i ∈ range (m + 1 ), choose (2 * m + 1 ) i) = 4 ^ m :=
88
- have : (∑ i ∈ range (m + 1 ), choose (2 * m + 1 ) (2 * m + 1 - i)) =
89
- ∑ i ∈ range (m + 1 ), choose (2 * m + 1 ) i :=
84
+ theorem sum_range_choose_halfway (m : ℕ ) : (∑ i ∈ range (m + 1 ), (2 * m + 1 ).choose i) = 4 ^ m :=
85
+ have : (∑ i ∈ range (m + 1 ), (2 * m + 1 ).choose (2 * m + 1 - i)) =
86
+ ∑ i ∈ range (m + 1 ), (2 * m + 1 ).choose i :=
90
87
sum_congr rfl fun i hi ↦ choose_symm <| by linarith [mem_range.1 hi]
91
88
mul_right_injective₀ two_ne_zero <|
92
89
calc
93
- (2 * ∑ i ∈ range (m + 1 ), choose (2 * m + 1 ) i) =
94
- (∑ i ∈ range (m + 1 ), choose (2 * m + 1 ) i) +
95
- ∑ i ∈ range (m + 1 ), choose (2 * m + 1 ) (2 * m + 1 - i) := by rw [two_mul, this]
96
- _ = (∑ i ∈ range (m + 1 ), choose (2 * m + 1 ) i) +
97
- ∑ i ∈ Ico (m + 1 ) (2 * m + 2 ), choose (2 * m + 1 ) i := by
98
- { rw [range_eq_Ico, sum_Ico_reflect]
99
- · congr
100
- have A : m + 1 ≤ 2 * m + 1 := by omega
101
- rw [add_comm, add_tsub_assoc_of_le A, ← add_comm]
102
- congr
103
- rw [tsub_eq_iff_eq_add_of_le A]
104
- ring
105
- · omega }
106
- _ = ∑ i ∈ range (2 * m + 2 ), choose (2 * m + 1 ) i := sum_range_add_sum_Ico _ (by omega)
90
+ (2 * ∑ i ∈ range (m + 1 ), (2 * m + 1 ).choose i) =
91
+ (∑ i ∈ range (m + 1 ), (2 * m + 1 ).choose i) +
92
+ ∑ i ∈ range (m + 1 ), (2 * m + 1 ).choose (2 * m + 1 - i) := by rw [two_mul, this]
93
+ _ = (∑ i ∈ range (m + 1 ), (2 * m + 1 ).choose i) +
94
+ ∑ i ∈ Ico (m + 1 ) (2 * m + 2 ), (2 * m + 1 ).choose i := by
95
+ rw [range_eq_Ico, sum_Ico_reflect _ _ (by omega)]
96
+ congr
97
+ have A : m + 1 ≤ 2 * m + 1 := by omega
98
+ rw [add_comm, add_tsub_assoc_of_le A, ← add_comm]
99
+ congr
100
+ rw [tsub_eq_iff_eq_add_of_le A]
101
+ ring
102
+ _ = ∑ i ∈ range (2 * m + 2 ), (2 * m + 1 ).choose i := sum_range_add_sum_Ico _ (by omega)
107
103
_ = 2 ^ (2 * m + 1 ) := sum_range_choose (2 * m + 1 )
108
- _ = 2 * 4 ^ m := by rw [Nat. pow_succ, pow_mul, mul_comm]; rfl
104
+ _ = 2 * 4 ^ m := by rw [pow_succ, pow_mul, mul_comm]; rfl
109
105
110
- theorem choose_middle_le_pow (n : ℕ) : choose (2 * n + 1 ) n ≤ 4 ^ n := by
111
- have t : choose (2 * n + 1 ) n ≤ ∑ i ∈ range (n + 1 ), choose (2 * n + 1 ) i :=
106
+ theorem choose_middle_le_pow (n : ℕ) : (2 * n + 1 ).choose n ≤ 4 ^ n := by
107
+ have t : (2 * n + 1 ).choose n ≤ ∑ i ∈ range (n + 1 ), (2 * n + 1 ).choose i :=
112
108
single_le_sum (fun x _ ↦ by omega) (self_mem_range_succ n)
113
109
simpa [sum_range_choose_halfway n] using t
114
110
115
111
theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) :
116
- 4 ^ n ≤ (2 * n + 1 ) * choose (2 * n) n :=
112
+ 4 ^ n ≤ (2 * n + 1 ) * (2 * n).choose n :=
117
113
calc
118
114
4 ^ n = (1 + 1 ) ^ (2 * n) := by norm_num [pow_mul]
119
- _ = ∑ m ∈ range (2 * n + 1 ), choose (2 * n) m := by set_option simprocs false in simp [add_pow]
120
- _ ≤ ∑ m ∈ range (2 * n + 1 ), choose (2 * n) (2 * n / 2 ) := by gcongr; apply choose_le_middle
115
+ _ = ∑ m ∈ range (2 * n + 1 ), (2 * n).choose m := by set_option simprocs false in simp [add_pow]
116
+ _ ≤ ∑ m ∈ range (2 * n + 1 ), (2 * n).choose (2 * n / 2 ) := by gcongr; apply choose_le_middle
121
117
_ = (2 * n + 1 ) * choose (2 * n) n := by simp
122
118
123
119
/-- **Zhu Shijie's identity** aka hockey-stick identity. -/
124
120
theorem sum_Icc_choose (n k : ℕ) : ∑ m ∈ Icc k n, m.choose k = (n + 1 ).choose (k + 1 ) := by
125
- cases' le_or_gt k n with h h
126
- · induction' n, h using le_induction with n _ ih; · simp
127
- rw [← Ico_insert_right (by omega), sum_insert (by simp),
128
- show Ico k (n + 1 ) = Icc k n by rfl, ih, choose_succ_succ' (n + 1 )]
121
+ rcases lt_or_le n k with h | h
129
122
· rw [choose_eq_zero_of_lt (by omega), Icc_eq_empty_of_lt h, sum_empty]
123
+ · induction n, h using le_induction with
124
+ | base => simp
125
+ | succ n _ ih =>
126
+ rw [← Ico_insert_right (by omega), sum_insert (by simp),
127
+ show Ico k (n + 1 ) = Icc k n by rfl, ih, choose_succ_succ' (n + 1 )]
130
128
131
129
end Nat
132
130
133
131
theorem Int.alternating_sum_range_choose {n : ℕ} :
134
- (∑ m ∈ range (n + 1 ), ((-1 ) ^ m * ↑( choose n m) : ℤ)) = if n = 0 then 1 else 0 := by
132
+ (∑ m ∈ range (n + 1 ), ((-1 ) ^ m * n. choose m : ℤ)) = if n = 0 then 1 else 0 := by
135
133
cases n with
136
134
| zero => simp
137
135
| succ n =>
138
136
have h := add_pow (-1 : ℤ) 1 n.succ
139
137
simp only [one_pow, mul_one, neg_add_cancel] at h
140
- rw [← h, zero_pow n.succ_ne_zero, if_neg (Nat .succ_ne_zero n) ]
138
+ rw [← h, zero_pow n.succ_ne_zero, if_neg n .succ_ne_zero]
141
139
142
140
theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0 ) :
143
- (∑ m ∈ range (n + 1 ), ((-1 ) ^ m * ↑( choose n m) : ℤ)) = 0 := by
141
+ (∑ m ∈ range (n + 1 ), ((-1 ) ^ m * n. choose m : ℤ)) = 0 := by
144
142
rw [Int.alternating_sum_range_choose, if_neg h0]
145
143
146
144
namespace Finset
@@ -166,9 +164,8 @@ theorem sum_powerset_neg_one_pow_card {α : Type*} [DecidableEq α] {x : Finset
166
164
theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type *} {x : Finset α} (h0 : x.Nonempty) :
167
165
(∑ m ∈ x.powerset, (-1 : ℤ) ^ m.card) = 0 := by
168
166
classical
169
- rw [sum_powerset_neg_one_pow_card, if_neg]
170
- rw [← Ne, ← nonempty_iff_ne_empty]
171
- apply h0
167
+ rw [sum_powerset_neg_one_pow_card]
168
+ exact if_neg (nonempty_iff_ne_empty.mp h0)
172
169
173
170
variable {M R : Type *} [CommMonoid M] [NonAssocSemiring R]
174
171
@@ -179,10 +176,9 @@ theorem prod_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M)
179
176
∏ i ∈ range (n + 1 ), f (i + 1 ) (n - i) ^ n.choose i := by
180
177
have A : (∏ i ∈ range (n + 1 ), f (i + 1 ) (n - i) ^ (n.choose (i + 1 ))) * f 0 (n + 1 ) =
181
178
∏ i ∈ range (n + 1 ), f i (n + 1 - i) ^ (n.choose i) := by
182
- rw [prod_range_succ, prod_range_succ']
183
- simp
179
+ rw [prod_range_succ, prod_range_succ']; simp
184
180
rw [prod_range_succ']
185
- simpa [Nat. choose_succ_succ, pow_add, prod_mul_distrib, A, mul_assoc] using mul_comm _ _
181
+ simpa [choose_succ_succ, pow_add, prod_mul_distrib, A, mul_assoc] using mul_comm _ _
186
182
187
183
@[to_additive sum_antidiagonal_choose_succ_nsmul]
188
184
theorem prod_antidiagonal_pow_choose_succ {M : Type *} [CommMonoid M] (f : ℕ → ℕ → M) (n : ℕ) :
@@ -195,9 +191,8 @@ theorem prod_antidiagonal_pow_choose_succ {M : Type*} [CommMonoid M] (f : ℕ
195
191
· refine prod_congr rfl fun i hi ↦ ?_
196
192
rw [tsub_add_eq_add_tsub (this _ hi)]
197
193
· refine prod_congr rfl fun i hi ↦ ?_
198
- rw [Nat. choose_symm (this _ hi)]
194
+ rw [choose_symm (this _ hi)]
199
195
200
- -- Porting note: moved from `Mathlib.Analysis.Calculus.ContDiff`
201
196
/-- The sum of `(n+1).choose i * f i (n+1-i)` can be split into two sums at rank `n`,
202
197
respectively of `n.choose i * f i (n+1-i)` and `n.choose i * f (i+1) (n-i)`. -/
203
198
theorem sum_choose_succ_mul (f : ℕ → ℕ → R) (n : ℕ) :
@@ -215,8 +210,7 @@ theorem sum_antidiagonal_choose_succ_mul (f : ℕ → ℕ → R) (n : ℕ) :
215
210
simpa only [nsmul_eq_mul] using sum_antidiagonal_choose_succ_nsmul f n
216
211
217
212
theorem sum_antidiagonal_choose_add (d n : ℕ) :
218
- (Finset.sum (antidiagonal n) fun ij => (d + ij.2 ).choose d) =
219
- (d + n).choose d + (d + n).choose (succ d) := by
213
+ (∑ ij ∈ antidiagonal n, (d + ij.2 ).choose d) = (d + n).choose d + (d + n).choose (d + 1 ) := by
220
214
induction n with
221
215
| zero => simp
222
216
| succ n hn => simpa [Nat.sum_antidiagonal_succ] using hn
0 commit comments