@@ -4,8 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Chris Hughes, Bhavik Mehta, Stuart Presnell
5
5
-/
6
6
import Mathlib.Data.Nat.Factorial.Basic
7
- import Mathlib.Algebra.Divisibility.Basic
8
- import Mathlib.Algebra.GroupWithZero.Basic
7
+ import Mathlib.Order.Monotone.Basic
9
8
10
9
#align_import data.nat.choose.basic from "leanprover-community/mathlib" @"2f3994e1b117b1e1da49bcfb67334f33460c3ce4"
11
10
@@ -87,12 +86,12 @@ theorem choose_succ_self (n : ℕ) : choose n (succ n) = 0 :=
87
86
#align nat.choose_succ_self Nat.choose_succ_self
88
87
89
88
@[simp]
90
- theorem choose_one_right (n : ℕ) : choose n 1 = n := by induction n <;> simp [*, choose, add_comm]
89
+ lemma choose_one_right (n : ℕ) : choose n 1 = n := by induction n <;> simp [*, choose, Nat. add_comm]
91
90
#align nat.choose_one_right Nat.choose_one_right
92
91
93
92
-- The `n+1`-st triangle number is `n` more than the `n`-th triangle number
94
93
theorem triangle_succ (n : ℕ) : (n + 1 ) * (n + 1 - 1 ) / 2 = n * (n - 1 ) / 2 + n := by
95
- rw [← add_mul_div_left, mul_comm 2 n, ← mul_add, Nat.add_sub_cancel, mul_comm]
94
+ rw [← add_mul_div_left, Nat. mul_comm 2 n, ← Nat. mul_add, Nat.add_sub_cancel, Nat. mul_comm]
96
95
cases n <;> rfl; apply zero_lt_succ
97
96
#align nat.triangle_succ Nat.triangle_succ
98
97
@@ -101,7 +100,7 @@ theorem choose_two_right (n : ℕ) : choose n 2 = n * (n - 1) / 2 := by
101
100
induction' n with n ih
102
101
· simp
103
102
· rw [triangle_succ n, choose, ih]
104
- simp [add_comm]
103
+ simp [Nat. add_comm]
105
104
#align nat.choose_two_right Nat.choose_two_right
106
105
107
106
theorem choose_pos : ∀ {n k}, k ≤ n → 0 < choose n k
@@ -117,10 +116,10 @@ theorem choose_eq_zero_iff {n k : ℕ} : n.choose k = 0 ↔ n < k :=
117
116
theorem succ_mul_choose_eq : ∀ n k, succ n * choose n k = choose (succ n) (succ k) * succ k
118
117
| 0 , 0 => by decide
119
118
| 0 , k + 1 => by simp [choose]
120
- | n + 1 , 0 => by simp [choose, mul_succ, succ_eq_add_one, add_comm]
119
+ | n + 1 , 0 => by simp [choose, mul_succ, succ_eq_add_one, Nat. add_comm]
121
120
| n + 1 , k + 1 => by
122
- rw [choose_succ_succ (succ n) (succ k), add_mul, ← succ_mul_choose_eq n, mul_succ, ←
123
- succ_mul_choose_eq n, add_right_comm, ← mul_add, ← choose_succ_succ, ← succ_mul]
121
+ rw [choose_succ_succ (succ n) (succ k), Nat. add_mul, ← succ_mul_choose_eq n, mul_succ, ←
122
+ succ_mul_choose_eq n, Nat. add_right_comm, ← Nat. mul_add, ← choose_succ_succ, ← succ_mul]
124
123
#align nat.succ_mul_choose_eq Nat.succ_mul_choose_eq
125
124
126
125
theorem choose_mul_factorial_mul_factorial : ∀ {n k}, k ≤ n → choose n k * k ! * (n - k)! = n !
@@ -130,56 +129,57 @@ theorem choose_mul_factorial_mul_factorial : ∀ {n k}, k ≤ n → choose n k *
130
129
rcases lt_or_eq_of_le hk with hk₁ | hk₁
131
130
· have h : choose n k * k.succ ! * (n - k)! = (k + 1 ) * n ! := by
132
131
rw [← choose_mul_factorial_mul_factorial (le_of_succ_le_succ hk)]
133
- simp [factorial_succ, mul_comm, mul_left_comm, mul_assoc]
132
+ simp [factorial_succ, Nat. mul_comm, Nat. mul_left_comm, Nat. mul_assoc]
134
133
have h₁ : (n - k)! = (n - k) * (n - k.succ)! := by
135
134
rw [← succ_sub_succ, succ_sub (le_of_lt_succ hk₁), factorial_succ]
136
135
have h₂ : choose n (succ k) * k.succ ! * ((n - k) * (n - k.succ)!) = (n - k) * n ! := by
137
136
rw [← choose_mul_factorial_mul_factorial (le_of_lt_succ hk₁)]
138
- simp [factorial_succ, mul_comm, mul_left_comm, mul_assoc]
137
+ simp [factorial_succ, Nat. mul_comm, Nat. mul_left_comm, Nat. mul_assoc]
139
138
have h₃ : k * n ! ≤ n * n ! := Nat.mul_le_mul_right _ (le_of_succ_le_succ hk)
140
- rw [choose_succ_succ, add_mul, add_mul, succ_sub_succ, h, h₁, h₂, add_mul,
141
- Nat.mul_sub_right_distrib, factorial_succ, ← Nat.add_sub_assoc h₃, add_assoc, ← add_mul ,
142
- Nat.add_sub_cancel_left, add_comm]
143
- · rw [hk₁]; simp [hk₁, mul_comm, choose, Nat.sub_self]
139
+ rw [choose_succ_succ, Nat. add_mul, Nat. add_mul, succ_sub_succ, h, h₁, h₂, Nat. add_mul,
140
+ Nat.mul_sub_right_distrib, factorial_succ, ← Nat.add_sub_assoc h₃, Nat. add_assoc,
141
+ ← Nat.add_mul, Nat. add_sub_cancel_left, Nat. add_comm]
142
+ · rw [hk₁]; simp [hk₁, Nat. mul_comm, choose, Nat.sub_self]
144
143
#align nat.choose_mul_factorial_mul_factorial Nat.choose_mul_factorial_mul_factorial
145
144
146
145
theorem choose_mul {n k s : ℕ} (hkn : k ≤ n) (hsk : s ≤ k) :
147
146
n.choose k * k.choose s = n.choose s * (n - s).choose (k - s) :=
148
- have h : (n - k)! * (k - s)! * s ! ≠ 0 := by apply_rules [factorial_ne_zero, mul_ne_zero ]
149
- mul_right_cancel₀ h <|
147
+ have h : 0 < (n - k)! * (k - s)! * s ! := by apply_rules [factorial_pos, Nat.mul_pos ]
148
+ Nat. mul_right_cancel h <|
150
149
calc
151
150
n.choose k * k.choose s * ((n - k)! * (k - s)! * s !) =
152
151
n.choose k * (k.choose s * s ! * (k - s)!) * (n - k)! :=
153
- by rw [mul_assoc, mul_assoc, mul_assoc, mul_assoc _ s !, mul_assoc, mul_comm (n - k)! ,
154
- mul_comm s !]
152
+ by rw [Nat. mul_assoc, Nat. mul_assoc, Nat. mul_assoc, Nat. mul_assoc _ s !, Nat. mul_assoc,
153
+ Nat.mul_comm (n - k)!, Nat. mul_comm s !]
155
154
_ = n ! :=
156
155
by rw [choose_mul_factorial_mul_factorial hsk, choose_mul_factorial_mul_factorial hkn]
157
156
_ = n.choose s * s ! * ((n - s).choose (k - s) * (k - s)! * (n - s - (k - s))!) :=
158
157
by rw [choose_mul_factorial_mul_factorial (Nat.sub_le_sub_right hkn _),
159
158
choose_mul_factorial_mul_factorial (hsk.trans hkn)]
160
159
_ = n.choose s * (n - s).choose (k - s) * ((n - k)! * (k - s)! * s !) := by
161
- rw [Nat.sub_sub_sub_cancel_right hsk, mul_assoc, mul_left_comm s !, mul_assoc,
162
- mul_comm (k - s)!, mul_comm s !, mul_right_comm, ← mul_assoc]
160
+ rw [Nat.sub_sub_sub_cancel_right hsk, Nat. mul_assoc, Nat. mul_left_comm s !, Nat. mul_assoc,
161
+ Nat. mul_comm (k - s)!, Nat. mul_comm s !, Nat. mul_right_comm, ← Nat. mul_assoc]
163
162
#align nat.choose_mul Nat.choose_mul
164
163
165
164
theorem choose_eq_factorial_div_factorial {n k : ℕ} (hk : k ≤ n) :
166
165
choose n k = n ! / (k ! * (n - k)!) := by
167
- rw [← choose_mul_factorial_mul_factorial hk, mul_assoc]
166
+ rw [← choose_mul_factorial_mul_factorial hk, Nat. mul_assoc]
168
167
exact (mul_div_left _ (Nat.mul_pos (factorial_pos _) (factorial_pos _))).symm
169
168
#align nat.choose_eq_factorial_div_factorial Nat.choose_eq_factorial_div_factorial
170
169
171
170
theorem add_choose (i j : ℕ) : (i + j).choose j = (i + j)! / (i ! * j !) := by
172
- rw [choose_eq_factorial_div_factorial (Nat.le_add_left j i), Nat.add_sub_cancel_right, mul_comm]
171
+ rw [choose_eq_factorial_div_factorial (Nat.le_add_left j i), Nat.add_sub_cancel_right,
172
+ Nat.mul_comm]
173
173
#align nat.add_choose Nat.add_choose
174
174
175
175
theorem add_choose_mul_factorial_mul_factorial (i j : ℕ) :
176
176
(i + j).choose j * i ! * j ! = (i + j)! := by
177
177
rw [← choose_mul_factorial_mul_factorial (Nat.le_add_left _ _), Nat.add_sub_cancel_right,
178
- mul_right_comm]
178
+ Nat. mul_right_comm]
179
179
#align nat.add_choose_mul_factorial_mul_factorial Nat.add_choose_mul_factorial_mul_factorial
180
180
181
181
theorem factorial_mul_factorial_dvd_factorial {n k : ℕ} (hk : k ≤ n) : k ! * (n - k)! ∣ n ! := by
182
- rw [← choose_mul_factorial_mul_factorial hk, mul_assoc]; exact dvd_mul_left _ _
182
+ rw [← choose_mul_factorial_mul_factorial hk, Nat. mul_assoc]; exact Nat. dvd_mul_left _ _
183
183
#align nat.factorial_mul_factorial_dvd_factorial Nat.factorial_mul_factorial_dvd_factorial
184
184
185
185
theorem factorial_mul_factorial_dvd_factorial_add (i j : ℕ) : i ! * j ! ∣ (i + j)! := by
@@ -191,7 +191,7 @@ theorem factorial_mul_factorial_dvd_factorial_add (i j : ℕ) : i ! * j ! ∣ (i
191
191
@[simp]
192
192
theorem choose_symm {n k : ℕ} (hk : k ≤ n) : choose n (n - k) = choose n k := by
193
193
rw [choose_eq_factorial_div_factorial hk, choose_eq_factorial_div_factorial (Nat.sub_le _ _),
194
- Nat.sub_sub_self hk, mul_comm]
194
+ Nat.sub_sub_self hk, Nat. mul_comm]
195
195
#align nat.choose_symm Nat.choose_symm
196
196
197
197
theorem choose_symm_of_eq_add {n a b : ℕ} (h : n = a + b) : Nat.choose n a = Nat.choose n b := by
@@ -206,13 +206,13 @@ theorem choose_symm_add {a b : ℕ} : choose (a + b) a = choose (a + b) b :=
206
206
207
207
theorem choose_symm_half (m : ℕ) : choose (2 * m + 1 ) (m + 1 ) = choose (2 * m + 1 ) m := by
208
208
apply choose_symm_of_eq_add
209
- rw [add_comm m 1 , add_assoc 1 m m, add_comm (2 * m) 1 , two_mul m]
209
+ rw [Nat. add_comm m 1 , Nat. add_assoc 1 m m, Nat. add_comm (2 * m) 1 , Nat. two_mul m]
210
210
#align nat.choose_symm_half Nat.choose_symm_half
211
211
212
212
theorem choose_succ_right_eq (n k : ℕ) : choose n (k + 1 ) * (k + 1 ) = choose n k * (n - k) := by
213
213
have e : (n + 1 ) * choose n k = choose n (k + 1 ) * (k + 1 ) + choose n k * (k + 1 ) := by
214
- rw [← right_distrib, add_comm (choose _ _), ← choose_succ_succ, succ_mul_choose_eq]
215
- rw [← Nat.sub_eq_of_eq_add e, mul_comm, ← Nat.mul_sub_left_distrib, Nat.add_sub_add_right]
214
+ rw [← Nat.add_mul, Nat. add_comm (choose _ _), ← choose_succ_succ, succ_mul_choose_eq]
215
+ rw [← Nat.sub_eq_of_eq_add e, Nat. mul_comm, ← Nat.mul_sub_left_distrib, Nat.add_sub_add_right]
216
216
#align nat.choose_succ_right_eq Nat.choose_succ_right_eq
217
217
218
218
@[simp]
@@ -226,63 +226,59 @@ theorem choose_mul_succ_eq (n k : ℕ) : n.choose k * (n + 1) = (n + 1).choose k
226
226
| zero => simp
227
227
| succ k =>
228
228
obtain hk | hk := le_or_lt (k + 1 ) (n + 1 )
229
- · rw [choose_succ_succ, add_mul, succ_sub_succ, ← choose_succ_right_eq, ← succ_sub_succ,
229
+ · rw [choose_succ_succ, Nat. add_mul, succ_sub_succ, ← choose_succ_right_eq, ← succ_sub_succ,
230
230
Nat.mul_sub_left_distrib, Nat.add_sub_cancel' (Nat.mul_le_mul_left _ hk)]
231
- · rw [choose_eq_zero_of_lt hk, choose_eq_zero_of_lt (n.lt_succ_self.trans hk), zero_mul,
232
- zero_mul]
231
+ · rw [choose_eq_zero_of_lt hk, choose_eq_zero_of_lt (n.lt_succ_self.trans hk), Nat. zero_mul,
232
+ Nat. zero_mul]
233
233
#align nat.choose_mul_succ_eq Nat.choose_mul_succ_eq
234
234
235
235
theorem ascFactorial_eq_factorial_mul_choose (n k : ℕ) :
236
236
(n + 1 ).ascFactorial k = k ! * (n + k).choose k := by
237
- rw [mul_comm]
238
- apply mul_right_cancel₀ (factorial_ne_zero ( n + k - k))
237
+ rw [Nat. mul_comm]
238
+ apply Nat. mul_right_cancel ( n + k - k).factorial_pos
239
239
rw [choose_mul_factorial_mul_factorial <| Nat.le_add_left k n, Nat.add_sub_cancel_right,
240
- ← factorial_mul_ascFactorial, mul_comm]
240
+ ← factorial_mul_ascFactorial, Nat. mul_comm]
241
241
#align nat.asc_factorial_eq_factorial_mul_choose Nat.ascFactorial_eq_factorial_mul_choose
242
242
243
243
theorem ascFactorial_eq_factorial_mul_choose' (n k : ℕ) :
244
244
n.ascFactorial k = k ! * (n + k - 1 ).choose k := by
245
245
cases n
246
246
· cases k
247
- · rw [ascFactorial_zero, choose_zero_right, factorial_zero, mul_one]
248
- · simp only [zero_ascFactorial, zero_eq, zero_add, ge_iff_le , succ_sub_succ_eq_sub,
249
- Nat.le_zero_eq, Nat.sub_zero, choose_succ_self, mul_zero]
247
+ · rw [ascFactorial_zero, choose_zero_right, factorial_zero, Nat. mul_one]
248
+ · simp only [zero_ascFactorial, zero_eq, Nat. zero_add, succ_sub_succ_eq_sub,
249
+ Nat.le_zero_eq, Nat.sub_zero, choose_succ_self, Nat. mul_zero]
250
250
rw [ascFactorial_eq_factorial_mul_choose]
251
- simp only [ge_iff_le, succ_add_sub_one]
251
+ simp only [succ_add_sub_one]
252
252
253
253
theorem factorial_dvd_ascFactorial (n k : ℕ) : k ! ∣ n.ascFactorial k :=
254
254
⟨(n + k - 1 ).choose k, ascFactorial_eq_factorial_mul_choose' _ _⟩
255
255
#align nat.factorial_dvd_asc_factorial Nat.factorial_dvd_ascFactorial
256
256
257
257
theorem choose_eq_asc_factorial_div_factorial (n k : ℕ) :
258
258
(n + k).choose k = (n + 1 ).ascFactorial k / k ! := by
259
- apply mul_left_cancel₀ (factorial_ne_zero k)
259
+ apply Nat. mul_left_cancel k.factorial_pos
260
260
rw [← ascFactorial_eq_factorial_mul_choose]
261
261
exact (Nat.mul_div_cancel' <| factorial_dvd_ascFactorial _ _).symm
262
262
#align nat.choose_eq_asc_factorial_div_factorial Nat.choose_eq_asc_factorial_div_factorial
263
263
264
264
theorem choose_eq_asc_factorial_div_factorial' (n k : ℕ) :
265
- (n + k - 1 ).choose k = n.ascFactorial k / k ! := by
266
- apply mul_left_cancel₀ (factorial_ne_zero k)
267
- rw [← ascFactorial_eq_factorial_mul_choose']
268
- exact (Nat.mul_div_cancel' <| factorial_dvd_ascFactorial _ _).symm
265
+ (n + k - 1 ).choose k = n.ascFactorial k / k ! :=
266
+ Nat.eq_div_of_mul_eq_right k.factorial_ne_zero (ascFactorial_eq_factorial_mul_choose' _ _).symm
269
267
270
268
theorem descFactorial_eq_factorial_mul_choose (n k : ℕ) : n.descFactorial k = k ! * n.choose k := by
271
269
obtain h | h := Nat.lt_or_ge n k
272
- · rw [descFactorial_eq_zero_iff_lt.2 h, choose_eq_zero_of_lt h, mul_zero]
273
- rw [mul_comm]
274
- apply mul_right_cancel₀ (factorial_ne_zero ( n - k))
275
- rw [choose_mul_factorial_mul_factorial h, ← factorial_mul_descFactorial h, mul_comm]
270
+ · rw [descFactorial_eq_zero_iff_lt.2 h, choose_eq_zero_of_lt h, Nat. mul_zero]
271
+ rw [Nat. mul_comm]
272
+ apply Nat. mul_right_cancel ( n - k).factorial_pos
273
+ rw [choose_mul_factorial_mul_factorial h, ← factorial_mul_descFactorial h, Nat. mul_comm]
276
274
#align nat.desc_factorial_eq_factorial_mul_choose Nat.descFactorial_eq_factorial_mul_choose
277
275
278
276
theorem factorial_dvd_descFactorial (n k : ℕ) : k ! ∣ n.descFactorial k :=
279
277
⟨n.choose k, descFactorial_eq_factorial_mul_choose _ _⟩
280
278
#align nat.factorial_dvd_desc_factorial Nat.factorial_dvd_descFactorial
281
279
282
- theorem choose_eq_descFactorial_div_factorial (n k : ℕ) : n.choose k = n.descFactorial k / k ! := by
283
- apply mul_left_cancel₀ (factorial_ne_zero k)
284
- rw [← descFactorial_eq_factorial_mul_choose]
285
- exact (Nat.mul_div_cancel' <| factorial_dvd_descFactorial _ _).symm
280
+ theorem choose_eq_descFactorial_div_factorial (n k : ℕ) : n.choose k = n.descFactorial k / k ! :=
281
+ Nat.eq_div_of_mul_eq_right k.factorial_ne_zero (descFactorial_eq_factorial_mul_choose _ _).symm
286
282
#align nat.choose_eq_desc_factorial_div_factorial Nat.choose_eq_descFactorial_div_factorial
287
283
288
284
/-- A faster implementation of `choose`, to be used during bytecode evaluation
@@ -302,7 +298,7 @@ theorem choose_le_succ_of_lt_half_left {r n : ℕ} (h : r < n / 2) :
302
298
refine Nat.le_of_mul_le_mul_right ?_ (Nat.sub_pos_of_lt (h.trans_le (n.div_le_self 2 )))
303
299
rw [← choose_succ_right_eq]
304
300
apply Nat.mul_le_mul_left
305
- rw [← Nat.lt_iff_add_one_le, Nat.lt_sub_iff_add_lt, ← mul_two]
301
+ rw [← Nat.lt_iff_add_one_le, Nat.lt_sub_iff_add_lt, ← Nat. mul_two]
306
302
exact lt_of_lt_of_le (Nat.mul_lt_mul_of_pos_right h Nat.zero_lt_two) (n.div_mul_le_self 2 )
307
303
#align nat.choose_le_succ_of_lt_half_left Nat.choose_le_succ_of_lt_half_left
308
304
@@ -324,7 +320,7 @@ theorem choose_le_middle (r n : ℕ) : choose n r ≤ choose n (n / 2) := by
324
320
apply choose_le_middle_of_le_half_left
325
321
rw [div_lt_iff_lt_mul' Nat.zero_lt_two] at h
326
322
rw [le_div_iff_mul_le' Nat.zero_lt_two, Nat.mul_sub_right_distrib, Nat.sub_le_iff_le_add,
327
- ← Nat.sub_le_iff_le_add', mul_two, Nat.add_sub_cancel]
323
+ ← Nat.sub_le_iff_le_add', Nat. mul_two, Nat.add_sub_cancel]
328
324
exact le_of_lt h
329
325
· rw [choose_eq_zero_of_lt b]
330
326
apply zero_le
@@ -401,7 +397,7 @@ theorem multichoose_one (k : ℕ) : multichoose 1 k = 1 := by
401
397
theorem multichoose_two (k : ℕ) : multichoose 2 k = k + 1 := by
402
398
induction' k with k IH; · simp
403
399
rw [multichoose, IH]
404
- simp [add_comm, succ_eq_add_one]
400
+ simp [Nat. add_comm, succ_eq_add_one]
405
401
#align nat.multichoose_two Nat.multichoose_two
406
402
407
403
@[simp]
@@ -416,7 +412,8 @@ theorem multichoose_eq : ∀ n k : ℕ, multichoose n k = (n + k - 1).choose k
416
412
| n + 1 , k + 1 => by
417
413
have : n + (k + 1 ) < (n + 1 ) + (k + 1 ) := Nat.add_lt_add_right (Nat.lt_succ_self _) _
418
414
have : (n + 1 ) + k < (n + 1 ) + (k + 1 ) := Nat.add_lt_add_left (Nat.lt_succ_self _) _
419
- erw [multichoose_succ_succ, add_comm, Nat.succ_add_sub_one, ← add_assoc, Nat.choose_succ_succ]
415
+ erw [multichoose_succ_succ, Nat.add_comm, Nat.succ_add_sub_one, ← Nat.add_assoc,
416
+ Nat.choose_succ_succ]
420
417
simp [multichoose_eq n (k+1 ), multichoose_eq (n+1 ) k]
421
418
termination_by a b => a + b
422
419
decreasing_by all_goals assumption
0 commit comments