Skip to content

Commit d29ce21

Browse files
committed
feat({Nat,Int}/ModEq): add lemmas (#29072)
1 parent 7a71f83 commit d29ce21

File tree

2 files changed

+189
-26
lines changed

2 files changed

+189
-26
lines changed

Mathlib/Data/Int/ModEq.lean

Lines changed: 108 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,100 @@ protected theorem mul_right_cancel_iff' (hc : c ≠ 0) :
215215
a * c ≡ b * c [ZMOD m * c] ↔ a ≡ b [ZMOD m] :=
216216
⟨ModEq.mul_right_cancel' hc, ModEq.mul_right'⟩
217217

218+
theorem dvd_iff (h : a ≡ b [ZMOD n]) : n ∣ a ↔ n ∣ b := by
219+
simp only [← modEq_zero_iff_dvd]
220+
exact ⟨fun ha ↦ h.symm.trans ha, h.trans⟩
221+
218222
end ModEq
219223

224+
@[simp]
225+
theorem modulus_modEq_zero : n ≡ 0 [ZMOD n] := by simp [ModEq]
226+
227+
@[simp]
228+
theorem modEq_abs : a ≡ b [ZMOD |n|] ↔ a ≡ b [ZMOD n] := by simp [ModEq]
229+
230+
theorem modEq_natAbs : a ≡ b [ZMOD n.natAbs] ↔ a ≡ b [ZMOD n] := by simp [natCast_natAbs]
231+
232+
@[simp]
233+
theorem add_modEq_left_iff : a + b ≡ a [ZMOD n] ↔ n ∣ b := by
234+
simp [modEq_iff_dvd]
235+
236+
@[simp]
237+
theorem add_modEq_right_iff : a + b ≡ b [ZMOD n] ↔ n ∣ a := by
238+
rw [add_comm, add_modEq_left_iff]
239+
240+
@[simp]
241+
theorem left_modEq_add_iff : a ≡ a + b [ZMOD n] ↔ n ∣ b := by
242+
rw [modEq_comm, add_modEq_left_iff]
243+
244+
@[simp]
245+
theorem right_modEq_add_iff : b ≡ a + b [ZMOD n] ↔ n ∣ a := by
246+
rw [modEq_comm, add_modEq_right_iff]
247+
248+
@[simp]
249+
theorem add_modulus_modEq_iff : a + n ≡ b [ZMOD n] ↔ a ≡ b [ZMOD n] := by
250+
simp [ModEq]
251+
252+
@[simp]
253+
theorem modulus_add_modEq_iff : n + a ≡ b [ZMOD n] ↔ a ≡ b [ZMOD n] := by
254+
rw [add_comm, add_modulus_modEq_iff]
255+
256+
@[simp]
257+
theorem modEq_add_modulus_iff : a ≡ b + n [ZMOD n] ↔ a ≡ b [ZMOD n] := by
258+
simp [ModEq]
259+
260+
@[simp]
261+
theorem modEq_modulus_add_iff : a ≡ n + b [ZMOD n] ↔ a ≡ b [ZMOD n] := by
262+
simp [ModEq]
263+
264+
@[simp]
265+
theorem add_mul_modulus_modEq_iff : a + b * n ≡ c [ZMOD n] ↔ a ≡ c [ZMOD n] := by
266+
simp [ModEq]
267+
268+
@[simp]
269+
theorem mul_modulus_add_modEq_iff : b * n + a ≡ c [ZMOD n] ↔ a ≡ c [ZMOD n] := by
270+
rw [add_comm, add_mul_modulus_modEq_iff]
271+
272+
@[simp]
273+
theorem modEq_add_mul_modulus_iff : a ≡ b + c * n [ZMOD n] ↔ a ≡ b [ZMOD n] := by
274+
simp [ModEq]
275+
276+
@[simp]
277+
theorem modEq_mul_modulus_add_iff : a ≡ b * n + c [ZMOD n] ↔ a ≡ c [ZMOD n] := by
278+
rw [add_comm, modEq_add_mul_modulus_iff]
279+
280+
@[simp]
281+
theorem add_modulus_mul_modEq_iff : a + n * b ≡ c [ZMOD n] ↔ a ≡ c [ZMOD n] := by
282+
simp [ModEq]
283+
284+
@[simp]
285+
theorem modulus_mul_add_modEq_iff : n * b + a ≡ c [ZMOD n] ↔ a ≡ c [ZMOD n] := by
286+
rw [add_comm, add_modulus_mul_modEq_iff]
287+
288+
@[simp]
289+
theorem modEq_add_modulus_mul_iff : a ≡ b + n * c [ZMOD n] ↔ a ≡ b [ZMOD n] := by
290+
simp [ModEq]
291+
292+
@[simp]
293+
theorem modEq_modulus_mul_add_iff : a ≡ n * b + c [ZMOD n] ↔ a ≡ c [ZMOD n] := by
294+
rw [add_comm, modEq_add_modulus_mul_iff]
295+
296+
@[simp]
297+
theorem sub_modulus_modEq_iff : a - n ≡ b [ZMOD n] ↔ a ≡ b [ZMOD n] := by
298+
rw [← add_modulus_modEq_iff, sub_add_cancel]
299+
300+
@[simp]
301+
theorem sub_modulus_mul_modEq_iff : a - n * b ≡ c [ZMOD n] ↔ a ≡ c [ZMOD n] := by
302+
rw [← add_modulus_mul_modEq_iff, sub_add_cancel]
303+
304+
@[simp]
305+
theorem modEq_sub_modulus_iff : a ≡ b - n [ZMOD n] ↔ a ≡ b [ZMOD n] := by
306+
rw [← modEq_add_modulus_iff, sub_add_cancel]
307+
308+
@[simp]
309+
theorem modEq_sub_modulus_mul_iff : a ≡ b - n * c [ZMOD n] ↔ a ≡ b [ZMOD n] := by
310+
rw [← modEq_add_modulus_mul_iff, sub_add_cancel]
311+
220312
theorem modEq_one : a ≡ b [ZMOD 1] :=
221313
modEq_of_dvd (one_dvd _)
222314

@@ -226,44 +318,38 @@ theorem modEq_sub (a b : ℤ) : a ≡ b [ZMOD a - b] :=
226318
@[simp]
227319
theorem modEq_zero_iff : a ≡ b [ZMOD 0] ↔ a = b := by rw [ModEq, emod_zero, emod_zero]
228320

229-
@[simp]
230-
theorem add_modEq_left : n + a ≡ a [ZMOD n] := ModEq.symm <| modEq_iff_dvd.2 <| by simp
321+
theorem add_modEq_left : n + a ≡ a [ZMOD n] := by simp
231322

232-
@[simp]
233-
theorem add_modEq_right : a + n ≡ a [ZMOD n] := ModEq.symm <| modEq_iff_dvd.2 <| by simp
323+
theorem add_modEq_right : a + n ≡ a [ZMOD n] := by simp
324+
325+
theorem modEq_and_modEq_iff_modEq_lcm {a b m n : ℤ} :
326+
a ≡ b [ZMOD m] ∧ a ≡ b [ZMOD n] ↔ a ≡ b [ZMOD m.lcm n] := by
327+
simp only [modEq_iff_dvd, coe_lcm_dvd_iff]
234328

235329
theorem modEq_and_modEq_iff_modEq_mul {a b m n : ℤ} (hmn : m.natAbs.Coprime n.natAbs) :
236-
a ≡ b [ZMOD m] ∧ a ≡ b [ZMOD n] ↔ a ≡ b [ZMOD m * n] :=
237-
fun h => by
238-
rw [modEq_iff_dvd, modEq_iff_dvd] at h
239-
rw [modEq_iff_dvd, ← natAbs_dvd, ← dvd_natAbs, natCast_dvd_natCast, natAbs_mul]
240-
refine hmn.mul_dvd_of_dvd_of_dvd ?_ ?_ <;>
241-
rw [← natCast_dvd_natCast, natAbs_dvd, dvd_natAbs] <;>
242-
tauto,
243-
fun h => ⟨h.of_mul_right _, h.of_mul_left _⟩⟩
330+
a ≡ b [ZMOD m] ∧ a ≡ b [ZMOD n] ↔ a ≡ b [ZMOD m * n] := by
331+
convert ← modEq_and_modEq_iff_modEq_lcm using 1
332+
rw [lcm_eq_mul_iff.mpr (.inr <| .inr hmn), ← natAbs_mul, modEq_natAbs]
244333

245334
theorem gcd_a_modEq (a b : ℕ) : (a : ℤ) * Nat.gcdA a b ≡ Nat.gcd a b [ZMOD b] := by
246335
rw [← add_zero ((a : ℤ) * _), Nat.gcd_eq_gcd_ab]
247336
exact (dvd_mul_right _ _).zero_modEq_int.add_left _
248337

249-
theorem modEq_add_fac {a b n : ℤ} (c : ℤ) (ha : a ≡ b [ZMOD n]) : a + n * c ≡ b [ZMOD n] :=
250-
calc
251-
a + n * c ≡ b + n * c [ZMOD n] := ha.add_right _
252-
_ ≡ b + 0 [ZMOD n] := (dvd_mul_right _ _).modEq_zero_int.add_left _
253-
_ ≡ b [ZMOD n] := by rw [add_zero]
338+
@[deprecated add_modulus_mul_modEq_iff (since := "2025-10-16")]
339+
theorem modEq_add_fac {a b n : ℤ} (c : ℤ) (ha : a ≡ b [ZMOD n]) : a + n * c ≡ b [ZMOD n] := by
340+
simpa
254341

342+
@[deprecated sub_modulus_mul_modEq_iff (since := "2025-10-16")]
255343
theorem modEq_sub_fac {a b n : ℤ} (c : ℤ) (ha : a ≡ b [ZMOD n]) : a - n * c ≡ b [ZMOD n] := by
256-
convert Int.modEq_add_fac (-c) ha using 1; rw [Int.mul_neg, sub_eq_add_neg]
344+
simpa
257345

258-
theorem modEq_add_fac_self {a t n : ℤ} : a + n * t ≡ a [ZMOD n] :=
259-
modEq_add_fac _ ModEq.rfl
346+
theorem modEq_add_fac_self {a t n : ℤ} : a + n * t ≡ a [ZMOD n] := by simp
260347

261348
theorem mod_coprime {a b : ℕ} (hab : Nat.Coprime a b) : ∃ y : ℤ, a * y ≡ 1 [ZMOD b] :=
262349
⟨Nat.gcdA a b,
263350
have hgcd : Nat.gcd a b = 1 := Nat.Coprime.gcd_eq_one hab
264351
calc
265-
↑a * Nat.gcdA a b ≡ ↑a * Nat.gcdA a b + ↑b * Nat.gcdB a b [ZMOD ↑b] :=
266-
ModEq.symm <| modEq_add_fac _ <| ModEq.refl _
352+
↑a * Nat.gcdA a b ≡ ↑a * Nat.gcdA a b + ↑b * Nat.gcdB a b [ZMOD ↑b] := by simp
267353
_ ≡ 1 [ZMOD ↑b] := by rw [← Nat.gcd_eq_gcd_ab, hgcd]; rfl
268354
269355

Mathlib/Data/Nat/ModEq.lean

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ theorem mod_modEq (a n) : a % n ≡ a [MOD n] :=
9090

9191
namespace ModEq
9292

93-
theorem self_mul_add : ModEq m (m * a + b) b := by
94-
simp [Nat.ModEq]
93+
theorem modulus_mul_add : m * a + b ≡ b [MOD m] := by simp [Nat.ModEq]
94+
95+
@[deprecated (since := "2025-10-16")]
96+
alias self_mul_add := modulus_mul_add
9597

9698
lemma of_dvd (d : m ∣ n) (h : a ≡ b [MOD n]) : a ≡ b [MOD m] :=
9799
modEq_of_dvd <| Int.ofNat_dvd.mpr d |>.trans h.dvd
@@ -223,15 +225,90 @@ theorem of_div (h : a / c ≡ b / c [MOD m / c]) (ha : c ∣ a) (ha : c ∣ b) (
223225

224226
end ModEq
225227

228+
@[simp]
229+
theorem modulus_modEq_zero : n ≡ 0 [MOD n] := by simp [ModEq]
230+
231+
@[simp]
232+
theorem add_modEq_left_iff : a + b ≡ a [MOD n] ↔ n ∣ b := by
233+
simp [modEq_iff_dvd, Int.natCast_dvd_natCast]
234+
235+
@[simp]
236+
theorem add_modEq_right_iff : a + b ≡ b [MOD n] ↔ n ∣ a := by
237+
rw [add_comm, add_modEq_left_iff]
238+
239+
@[simp]
240+
theorem left_modEq_add_iff : a ≡ a + b [MOD n] ↔ n ∣ b := by
241+
rw [ModEq.comm, add_modEq_left_iff]
242+
243+
@[simp]
244+
theorem right_modEq_add_iff : b ≡ a + b [MOD n] ↔ n ∣ a := by
245+
rw [ModEq.comm, add_modEq_right_iff]
246+
247+
@[simp]
248+
theorem add_modulus_modEq_iff : a + n ≡ b [MOD n] ↔ a ≡ b [MOD n] := by
249+
simp [ModEq]
250+
251+
@[simp]
252+
theorem modulus_add_modEq_iff : n + a ≡ b [MOD n] ↔ a ≡ b [MOD n] := by
253+
rw [add_comm, add_modulus_modEq_iff]
254+
255+
@[simp]
256+
theorem modEq_add_modulus_iff : a ≡ b + n [MOD n] ↔ a ≡ b [MOD n] := by
257+
simp [ModEq]
258+
259+
@[simp]
260+
theorem modEq_modulus_add_iff : a ≡ n + b [MOD n] ↔ a ≡ b [MOD n] := by
261+
simp [ModEq]
262+
263+
@[simp]
264+
theorem add_mul_modulus_modEq_iff : a + b * n ≡ c [MOD n] ↔ a ≡ c [MOD n] := by
265+
simp [ModEq]
266+
267+
@[simp]
268+
theorem mul_modulus_add_modEq_iff : b * n + a ≡ c [MOD n] ↔ a ≡ c [MOD n] := by
269+
rw [add_comm, add_mul_modulus_modEq_iff]
270+
271+
@[simp]
272+
theorem modEq_add_mul_modulus_iff : a ≡ b + c * n [MOD n] ↔ a ≡ b [MOD n] := by
273+
simp [ModEq]
274+
275+
@[simp]
276+
theorem modEq_mul_modulus_add_iff : a ≡ b * n + c [MOD n] ↔ a ≡ c [MOD n] := by
277+
rw [add_comm, modEq_add_mul_modulus_iff]
278+
279+
@[simp]
280+
theorem add_modulus_mul_modEq_iff : a + n * b ≡ c [MOD n] ↔ a ≡ c [MOD n] := by
281+
simp [ModEq]
282+
283+
@[simp]
284+
theorem modulus_mul_add_modEq_iff : n * b + a ≡ c [MOD n] ↔ a ≡ c [MOD n] := by
285+
rw [add_comm, add_modulus_mul_modEq_iff]
286+
287+
@[simp]
288+
theorem modEq_add_modulus_mul_iff : a ≡ b + n * c [MOD n] ↔ a ≡ b [MOD n] := by
289+
simp [ModEq]
290+
291+
@[simp]
292+
theorem modEq_modulus_mul_add_iff : a ≡ n * b + c [MOD n] ↔ a ≡ c [MOD n] := by
293+
rw [add_comm, modEq_add_modulus_mul_iff]
294+
295+
@[simp]
296+
theorem sub_modulus_modEq_iff (h : n ≤ a) : a - n ≡ b [MOD n] ↔ a ≡ b [MOD n] := by
297+
rw [← add_modulus_modEq_iff, Nat.sub_add_cancel h]
298+
299+
@[simp]
300+
theorem modEq_sub_modulus_iff (h : n ≤ b) : a ≡ b - n [MOD n] ↔ a ≡ b [MOD n] := by
301+
rw [← modEq_add_modulus_iff, Nat.sub_add_cancel h]
302+
226303
lemma modEq_sub (h : b ≤ a) : a ≡ b [MOD a - b] := (modEq_of_dvd <| by rw [Int.ofNat_sub h]).symm
227304

228305
lemma modEq_one : a ≡ b [MOD 1] := modEq_of_dvd <| one_dvd _
229306

230307
@[simp] lemma modEq_zero_iff : a ≡ b [MOD 0] ↔ a = b := by rw [ModEq, mod_zero, mod_zero]
231308

232-
@[simp] lemma add_modEq_left : n + a ≡ a [MOD n] := by rw [ModEq, add_mod_left]
309+
lemma add_modEq_left : n + a ≡ a [MOD n] := by simp
233310

234-
@[simp] lemma add_modEq_right : a + n ≡ a [MOD n] := by rw [ModEq, add_mod_right]
311+
lemma add_modEq_right : a + n ≡ a [MOD n] := by simp
235312

236313
namespace ModEq
237314

0 commit comments

Comments
 (0)