Skip to content

Commit 48efc23

Browse files
committed
chore(Data/Nat/Factorial): Use Std lemmas (#11715)
Make use of `Nat`-specific lemmas from Std rather than the general ones provided by mathlib. The ultimate goal here is to carve out `Data`, `Algebra` and `Order` sublibraries.
1 parent 85b063b commit 48efc23

File tree

6 files changed

+129
-143
lines changed

6 files changed

+129
-143
lines changed

Archive/Imo/Imo2019Q4.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ Copyright (c) 2020 Floris van Doorn. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Floris van Doorn
55
-/
6-
import Mathlib.Tactic.IntervalCases
7-
import Mathlib.Algebra.BigOperators.Order
6+
import Mathlib.Data.Nat.Factorial.BigOperators
87
import Mathlib.Data.Nat.Multiplicity
8+
import Mathlib.Tactic.IntervalCases
99
import Mathlib.Tactic.GCongr
1010

1111
#align_import imo.imo2019_q4 from "leanprover-community/mathlib"@"308826471968962c6b59c7ff82a22757386603e3"

Mathlib/Analysis/SpecificLimits/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ end ENNReal
604604

605605

606606
theorem factorial_tendsto_atTop : Tendsto Nat.factorial atTop atTop :=
607-
tendsto_atTop_atTop_of_monotone Nat.monotone_factorial fun n ↦ ⟨n, n.self_le_factorial⟩
607+
tendsto_atTop_atTop_of_monotone (fun _ _ ↦ Nat.factorial_le) fun n ↦ ⟨n, n.self_le_factorial⟩
608608
#align factorial_tendsto_at_top factorial_tendsto_atTop
609609

610610
theorem tendsto_factorial_div_pow_self_atTop :

Mathlib/Data/Nat/Choose/Basic.lean

Lines changed: 52 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Chris Hughes, Bhavik Mehta, Stuart Presnell
55
-/
66
import Mathlib.Data.Nat.Factorial.Basic
7-
import Mathlib.Algebra.Divisibility.Basic
8-
import Mathlib.Algebra.GroupWithZero.Basic
7+
import Mathlib.Order.Monotone.Basic
98

109
#align_import data.nat.choose.basic from "leanprover-community/mathlib"@"2f3994e1b117b1e1da49bcfb67334f33460c3ce4"
1110

@@ -87,12 +86,12 @@ theorem choose_succ_self (n : ℕ) : choose n (succ n) = 0 :=
8786
#align nat.choose_succ_self Nat.choose_succ_self
8887

8988
@[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]
9190
#align nat.choose_one_right Nat.choose_one_right
9291

9392
-- The `n+1`-st triangle number is `n` more than the `n`-th triangle number
9493
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]
9695
cases n <;> rfl; apply zero_lt_succ
9796
#align nat.triangle_succ Nat.triangle_succ
9897

@@ -101,7 +100,7 @@ theorem choose_two_right (n : ℕ) : choose n 2 = n * (n - 1) / 2 := by
101100
induction' n with n ih
102101
· simp
103102
· rw [triangle_succ n, choose, ih]
104-
simp [add_comm]
103+
simp [Nat.add_comm]
105104
#align nat.choose_two_right Nat.choose_two_right
106105

107106
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 :=
117116
theorem succ_mul_choose_eq : ∀ n k, succ n * choose n k = choose (succ n) (succ k) * succ k
118117
| 0, 0 => by decide
119118
| 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]
121120
| 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]
124123
#align nat.succ_mul_choose_eq Nat.succ_mul_choose_eq
125124

126125
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 *
130129
rcases lt_or_eq_of_le hk with hk₁ | hk₁
131130
· have h : choose n k * k.succ ! * (n - k)! = (k + 1) * n ! := by
132131
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]
134133
have h₁ : (n - k)! = (n - k) * (n - k.succ)! := by
135134
rw [← succ_sub_succ, succ_sub (le_of_lt_succ hk₁), factorial_succ]
136135
have h₂ : choose n (succ k) * k.succ ! * ((n - k) * (n - k.succ)!) = (n - k) * n ! := by
137136
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]
139138
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]
144143
#align nat.choose_mul_factorial_mul_factorial Nat.choose_mul_factorial_mul_factorial
145144

146145
theorem choose_mul {n k s : ℕ} (hkn : k ≤ n) (hsk : s ≤ k) :
147146
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 <|
150149
calc
151150
n.choose k * k.choose s * ((n - k)! * (k - s)! * s !) =
152151
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 !]
155154
_ = n ! :=
156155
by rw [choose_mul_factorial_mul_factorial hsk, choose_mul_factorial_mul_factorial hkn]
157156
_ = n.choose s * s ! * ((n - s).choose (k - s) * (k - s)! * (n - s - (k - s))!) :=
158157
by rw [choose_mul_factorial_mul_factorial (Nat.sub_le_sub_right hkn _),
159158
choose_mul_factorial_mul_factorial (hsk.trans hkn)]
160159
_ = 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]
163162
#align nat.choose_mul Nat.choose_mul
164163

165164
theorem choose_eq_factorial_div_factorial {n k : ℕ} (hk : k ≤ n) :
166165
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]
168167
exact (mul_div_left _ (Nat.mul_pos (factorial_pos _) (factorial_pos _))).symm
169168
#align nat.choose_eq_factorial_div_factorial Nat.choose_eq_factorial_div_factorial
170169

171170
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]
173173
#align nat.add_choose Nat.add_choose
174174

175175
theorem add_choose_mul_factorial_mul_factorial (i j : ℕ) :
176176
(i + j).choose j * i ! * j ! = (i + j)! := by
177177
rw [← choose_mul_factorial_mul_factorial (Nat.le_add_left _ _), Nat.add_sub_cancel_right,
178-
mul_right_comm]
178+
Nat.mul_right_comm]
179179
#align nat.add_choose_mul_factorial_mul_factorial Nat.add_choose_mul_factorial_mul_factorial
180180

181181
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 _ _
183183
#align nat.factorial_mul_factorial_dvd_factorial Nat.factorial_mul_factorial_dvd_factorial
184184

185185
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
191191
@[simp]
192192
theorem choose_symm {n k : ℕ} (hk : k ≤ n) : choose n (n - k) = choose n k := by
193193
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]
195195
#align nat.choose_symm Nat.choose_symm
196196

197197
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 :=
206206

207207
theorem choose_symm_half (m : ℕ) : choose (2 * m + 1) (m + 1) = choose (2 * m + 1) m := by
208208
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]
210210
#align nat.choose_symm_half Nat.choose_symm_half
211211

212212
theorem choose_succ_right_eq (n k : ℕ) : choose n (k + 1) * (k + 1) = choose n k * (n - k) := by
213213
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]
216216
#align nat.choose_succ_right_eq Nat.choose_succ_right_eq
217217

218218
@[simp]
@@ -226,63 +226,59 @@ theorem choose_mul_succ_eq (n k : ℕ) : n.choose k * (n + 1) = (n + 1).choose k
226226
| zero => simp
227227
| succ k =>
228228
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,
230230
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]
233233
#align nat.choose_mul_succ_eq Nat.choose_mul_succ_eq
234234

235235
theorem ascFactorial_eq_factorial_mul_choose (n k : ℕ) :
236236
(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
239239
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]
241241
#align nat.asc_factorial_eq_factorial_mul_choose Nat.ascFactorial_eq_factorial_mul_choose
242242

243243
theorem ascFactorial_eq_factorial_mul_choose' (n k : ℕ) :
244244
n.ascFactorial k = k ! * (n + k - 1).choose k := by
245245
cases n
246246
· 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]
250250
rw [ascFactorial_eq_factorial_mul_choose]
251-
simp only [ge_iff_le, succ_add_sub_one]
251+
simp only [succ_add_sub_one]
252252

253253
theorem factorial_dvd_ascFactorial (n k : ℕ) : k ! ∣ n.ascFactorial k :=
254254
⟨(n + k - 1).choose k, ascFactorial_eq_factorial_mul_choose' _ _⟩
255255
#align nat.factorial_dvd_asc_factorial Nat.factorial_dvd_ascFactorial
256256

257257
theorem choose_eq_asc_factorial_div_factorial (n k : ℕ) :
258258
(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
260260
rw [← ascFactorial_eq_factorial_mul_choose]
261261
exact (Nat.mul_div_cancel' <| factorial_dvd_ascFactorial _ _).symm
262262
#align nat.choose_eq_asc_factorial_div_factorial Nat.choose_eq_asc_factorial_div_factorial
263263

264264
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
269267

270268
theorem descFactorial_eq_factorial_mul_choose (n k : ℕ) : n.descFactorial k = k ! * n.choose k := by
271269
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]
276274
#align nat.desc_factorial_eq_factorial_mul_choose Nat.descFactorial_eq_factorial_mul_choose
277275

278276
theorem factorial_dvd_descFactorial (n k : ℕ) : k ! ∣ n.descFactorial k :=
279277
⟨n.choose k, descFactorial_eq_factorial_mul_choose _ _⟩
280278
#align nat.factorial_dvd_desc_factorial Nat.factorial_dvd_descFactorial
281279

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
286282
#align nat.choose_eq_desc_factorial_div_factorial Nat.choose_eq_descFactorial_div_factorial
287283

288284
/-- 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) :
302298
refine Nat.le_of_mul_le_mul_right ?_ (Nat.sub_pos_of_lt (h.trans_le (n.div_le_self 2)))
303299
rw [← choose_succ_right_eq]
304300
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]
306302
exact lt_of_lt_of_le (Nat.mul_lt_mul_of_pos_right h Nat.zero_lt_two) (n.div_mul_le_self 2)
307303
#align nat.choose_le_succ_of_lt_half_left Nat.choose_le_succ_of_lt_half_left
308304

@@ -324,7 +320,7 @@ theorem choose_le_middle (r n : ℕ) : choose n r ≤ choose n (n / 2) := by
324320
apply choose_le_middle_of_le_half_left
325321
rw [div_lt_iff_lt_mul' Nat.zero_lt_two] at h
326322
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]
328324
exact le_of_lt h
329325
· rw [choose_eq_zero_of_lt b]
330326
apply zero_le
@@ -401,7 +397,7 @@ theorem multichoose_one (k : ℕ) : multichoose 1 k = 1 := by
401397
theorem multichoose_two (k : ℕ) : multichoose 2 k = k + 1 := by
402398
induction' k with k IH; · simp
403399
rw [multichoose, IH]
404-
simp [add_comm, succ_eq_add_one]
400+
simp [Nat.add_comm, succ_eq_add_one]
405401
#align nat.multichoose_two Nat.multichoose_two
406402

407403
@[simp]
@@ -416,7 +412,8 @@ theorem multichoose_eq : ∀ n k : ℕ, multichoose n k = (n + k - 1).choose k
416412
| n + 1, k + 1 => by
417413
have : n + (k + 1) < (n + 1) + (k + 1) := Nat.add_lt_add_right (Nat.lt_succ_self _) _
418414
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]
420417
simp [multichoose_eq n (k+1), multichoose_eq (n+1) k]
421418
termination_by a b => a + b
422419
decreasing_by all_goals assumption

Mathlib/Data/Nat/Defs.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,12 @@ lemma div_eq_sub_mod_div : m / n = (m - m % n) / n := by
636636
rw [this, mul_div_right _ hn]
637637
#align nat.div_eq_sub_mod_div Nat.div_eq_sub_mod_div
638638

639+
protected lemma eq_div_of_mul_eq_left (hc : c ≠ 0) (h : a * c = b) : a = b / c := by
640+
rw [← h, Nat.mul_div_cancel _ (Nat.pos_iff_ne_zero.2 hc)]
641+
642+
protected lemma eq_div_of_mul_eq_right (hc : c ≠ 0) (h : c * a = b) : a = b / c := by
643+
rw [← h, Nat.mul_div_cancel_left _ (Nat.pos_iff_ne_zero.2 hc)]
644+
639645
/-!
640646
### `pow`
641647

0 commit comments

Comments
 (0)