@@ -3,10 +3,8 @@ Copyright (c) 2017 Mario Carneiro. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Mario Carneiro
5
5
-/
6
- import Mathlib.Algebra.Ring.Regular
6
+ import Mathlib.Algebra.Order.Group.Unbundled.Int
7
7
import Mathlib.Data.Int.GCD
8
- import Mathlib.Data.Int.Order.Lemmas
9
- import Mathlib.Tactic.NormNum.Basic
10
8
11
9
/-!
12
10
# Congruences modulo a natural number
@@ -24,6 +22,7 @@ and proves basic properties about it such as the Chinese Remainder Theorem
24
22
ModEq, congruence, mod, MOD, modulo
25
23
-/
26
24
25
+ assert_not_exists OrderedAddCommMonoid
27
26
assert_not_exists Function.support
28
27
29
28
namespace Nat
@@ -37,8 +36,8 @@ notation:50 a " ≡ " b " [MOD " n "]" => ModEq n a b
37
36
38
37
variable {m n a b c d : ℕ}
39
38
40
- -- Porting note: This instance should be derivable automatically
41
- instance : Decidable (ModEq n a b) := decEq (a % n) ( b % n)
39
+ -- Since `ModEq` is semi-reducible, we need to provide the decidable instance manually
40
+ instance : Decidable (ModEq n a b) := inferInstanceAs <| Decidable (a % n = b % n)
42
41
43
42
namespace ModEq
44
43
@@ -91,7 +90,7 @@ theorem mod_modEq (a n) : a % n ≡ a [MOD n] :=
91
90
namespace ModEq
92
91
93
92
lemma of_dvd (d : m ∣ n) (h : a ≡ b [MOD n]) : a ≡ b [MOD m] :=
94
- modEq_of_dvd <| d.natCast .trans h.dvd
93
+ modEq_of_dvd <| Int.ofNat_dvd.mpr d |> .trans h.dvd
95
94
96
95
protected theorem mul_left' (c : ℕ) (h : a ≡ b [MOD n]) : c * a ≡ c * b [MOD c * n] := by
97
96
unfold ModEq at *; rw [mul_mod_mul_left, mul_mod_mul_left, h]
@@ -122,7 +121,7 @@ protected theorem pow (m : ℕ) (h : a ≡ b [MOD n]) : a ^ m ≡ b ^ m [MOD n]
122
121
@[gcongr]
123
122
protected theorem add (h₁ : a ≡ b [MOD n]) (h₂ : c ≡ d [MOD n]) : a + c ≡ b + d [MOD n] := by
124
123
rw [modEq_iff_dvd, Int.ofNat_add, Int.ofNat_add, add_sub_add_comm]
125
- exact dvd_add h₁.dvd h₂.dvd
124
+ exact Int. dvd_add h₁.dvd h₂.dvd
126
125
127
126
@[gcongr]
128
127
protected theorem add_left (c : ℕ) (h : a ≡ b [MOD n]) : c + a ≡ c + b [MOD n] :=
@@ -136,7 +135,7 @@ protected theorem add_left_cancel (h₁ : a ≡ b [MOD n]) (h₂ : a + c ≡ b +
136
135
c ≡ d [MOD n] := by
137
136
simp only [modEq_iff_dvd, Int.ofNat_add] at *
138
137
rw [add_sub_add_comm] at h₂
139
- convert _root_ .dvd_sub h₂ h₁ using 1
138
+ convert Int .dvd_sub h₂ h₁ using 1
140
139
rw [add_sub_cancel_left]
141
140
142
141
protected theorem add_left_cancel' (c : ℕ) (h : c + a ≡ c + b [MOD n]) : a ≡ b [MOD n] :=
@@ -155,7 +154,8 @@ protected theorem add_right_cancel' (c : ℕ) (h : a + c ≡ b + c [MOD n]) : a
155
154
For cancelling left multiplication in the modulus, see `Nat.ModEq.of_mul_left`. -/
156
155
protected theorem mul_left_cancel' {a b c m : ℕ} (hc : c ≠ 0 ) :
157
156
c * a ≡ c * b [MOD c * m] → a ≡ b [MOD m] := by
158
- simp [modEq_iff_dvd, ← mul_sub, mul_dvd_mul_iff_left (by simp [hc] : (c : ℤ) ≠ 0 )]
157
+ simp only [modEq_iff_dvd, Int.natCast_mul, ← Int.mul_sub]
158
+ exact fun h => (Int.dvd_of_mul_dvd_mul_left (Int.ofNat_ne_zero.mpr hc) h)
159
159
160
160
protected theorem mul_left_cancel_iff' {a b c m : ℕ} (hc : c ≠ 0 ) :
161
161
c * a ≡ c * b [MOD c * m] ↔ a ≡ b [MOD m] :=
@@ -166,7 +166,8 @@ protected theorem mul_left_cancel_iff' {a b c m : ℕ} (hc : c ≠ 0) :
166
166
For cancelling right multiplication in the modulus, see `Nat.ModEq.of_mul_right`. -/
167
167
protected theorem mul_right_cancel' {a b c m : ℕ} (hc : c ≠ 0 ) :
168
168
a * c ≡ b * c [MOD m * c] → a ≡ b [MOD m] := by
169
- simp [modEq_iff_dvd, ← sub_mul, mul_dvd_mul_iff_right (by simp [hc] : (c : ℤ) ≠ 0 )]
169
+ simp only [modEq_iff_dvd, Int.natCast_mul, ← Int.sub_mul]
170
+ exact fun h => (Int.dvd_of_mul_dvd_mul_right (Int.ofNat_ne_zero.mpr hc) h)
170
171
171
172
protected theorem mul_right_cancel_iff' {a b c m : ℕ} (hc : c ≠ 0 ) :
172
173
a * c ≡ b * c [MOD m * c] ↔ a ≡ b [MOD m] :=
@@ -204,10 +205,10 @@ namespace ModEq
204
205
theorem le_of_lt_add (h1 : a ≡ b [MOD m]) (h2 : a < b + m) : a ≤ b :=
205
206
(le_total a b).elim id fun h3 =>
206
207
Nat.le_of_sub_eq_zero
207
- (eq_zero_of_dvd_of_lt ((modEq_iff_dvd' h3).mp h1.symm) ((tsub_lt_iff_left h3).mpr h2 ))
208
+ (eq_zero_of_dvd_of_lt ((modEq_iff_dvd' h3).mp h1.symm) (by omega ))
208
209
209
210
theorem add_le_of_lt (h1 : a ≡ b [MOD m]) (h2 : a < b) : a + m ≤ b :=
210
- le_of_lt_add (add_modEq_right.trans h1) (add_lt_add_right h2 m )
211
+ le_of_lt_add (add_modEq_right.trans h1) (by omega )
211
212
212
213
theorem dvd_iff (h : a ≡ b [MOD m]) (hdm : d ∣ m) : d ∣ a ↔ d ∣ b := by
213
214
simp only [← modEq_zero_iff_dvd]
@@ -227,9 +228,7 @@ lemma eq_of_abs_lt (h : a ≡ b [MOD m]) (h2 : |(b : ℤ) - a| < m) : a = b := b
227
228
exact Int.eq_zero_of_abs_lt_dvd h.dvd h2
228
229
229
230
lemma eq_of_lt_of_lt (h : a ≡ b [MOD m]) (ha : a < m) (hb : b < m) : a = b :=
230
- h.eq_of_abs_lt <| abs_sub_lt_iff.2
231
- ⟨(sub_le_self _ <| Int.natCast_nonneg _).trans_lt <| Int.ofNat_lt.2 hb,
232
- (sub_le_self _ <| Int.natCast_nonneg _).trans_lt <| Int.ofNat_lt.2 ha⟩
231
+ h.eq_of_abs_lt <| Int.abs_sub_lt_of_lt_lt ha hb
233
232
234
233
/-- To cancel a common factor `c` from a `ModEq` we must divide the modulus `m` by `gcd m c` -/
235
234
lemma cancel_left_div_gcd (hm : 0 < m) (h : c * a ≡ c * b [MOD m]) : a ≡ b [MOD m / gcd m c] := by
@@ -241,7 +240,7 @@ lemma cancel_left_div_gcd (hm : 0 < m) (h : c * a ≡ c * b [MOD m]) : a ≡ b
241
240
· show (m / d : ℤ) ∣ c / d * (b - a)
242
241
rw [mul_comm, ← Int.mul_ediv_assoc (b - a) (Int.natCast_dvd_natCast.mpr hcd), mul_comm]
243
242
apply Int.ediv_dvd_ediv (Int.natCast_dvd_natCast.mpr hmd)
244
- rw [mul_sub]
243
+ rw [Int. mul_sub]
245
244
exact modEq_iff_dvd.mp h
246
245
· show Int.gcd (m / d) (c / d) = 1
247
246
simp only [← Int.natCast_div, Int.gcd_natCast_natCast (m / d) (c / d), gcd_div hmd hcd,
@@ -299,18 +298,18 @@ def chineseRemainder' (h : a ≡ b [MOD gcd n m]) : { k // k ≡ a [MOD n] ∧ k
299
298
have hcoedvd : ∀ t, (gcd n m : ℤ) ∣ t * (b - a) := fun t => h.dvd.mul_left _
300
299
have := gcd_eq_gcd_ab n m
301
300
constructor <;> rw [Int.emod_def, ← sub_add] <;>
302
- refine dvd_add ?_ (dvd_mul_of_dvd_left ?_ _) <;>
301
+ refine Int. dvd_add ?_ (dvd_mul_of_dvd_left ?_ _) <;>
303
302
try norm_cast
304
303
· rw [← sub_eq_iff_eq_add'] at this
305
- rw [← this, sub_mul, ← add_sub_assoc, add_comm, add_sub_assoc, ← mul_sub,
304
+ rw [← this, Int. sub_mul, ← add_sub_assoc, add_comm, add_sub_assoc, ← Int. mul_sub,
306
305
Int.add_ediv_of_dvd_left, Int.mul_ediv_cancel_left _ hnonzero,
307
- Int.mul_ediv_assoc _ h.dvd, ← sub_sub, sub_self, zero_sub, dvd_neg, mul_assoc]
306
+ Int.mul_ediv_assoc _ h.dvd, ← sub_sub, sub_self, zero_sub, Int. dvd_neg, mul_assoc]
308
307
· exact dvd_mul_right _ _
309
308
norm_cast
310
309
exact dvd_mul_right _ _
311
310
· exact dvd_lcm_left n m
312
311
· rw [← sub_eq_iff_eq_add] at this
313
- rw [← this, sub_mul, sub_add, ← mul_sub, Int.sub_ediv_of_dvd,
312
+ rw [← this, Int. sub_mul, sub_add, ← Int. mul_sub, Int.sub_ediv_of_dvd,
314
313
Int.mul_ediv_cancel_left _ hnonzero, Int.mul_ediv_assoc _ h.dvd, ← sub_add, sub_self,
315
314
zero_add, mul_assoc]
316
315
· exact dvd_mul_right _ _
@@ -407,7 +406,7 @@ protected theorem add_div_of_dvd_right {a b c : ℕ} (hca : c ∣ a) : (a + b) /
407
406
add_div_eq_of_add_mod_lt
408
407
(by
409
408
rw [Nat.mod_eq_zero_of_dvd hca, zero_add]
410
- exact Nat.mod_lt _ (pos_iff_ne_zero.mpr h))
409
+ exact Nat.mod_lt _ (zero_lt_of_ne_zero h))
411
410
412
411
protected theorem add_div_of_dvd_left {a b c : ℕ} (hca : c ∣ b) : (a + b) / c = a / c + b / c := by
413
412
rwa [add_comm, Nat.add_div_of_dvd_right, add_comm]
@@ -430,27 +429,24 @@ theorem odd_mul_odd {n m : ℕ} : n % 2 = 1 → m % 2 = 1 → n * m % 2 = 1 := b
430
429
431
430
theorem odd_mul_odd_div_two {m n : ℕ} (hm1 : m % 2 = 1 ) (hn1 : n % 2 = 1 ) :
432
431
m * n / 2 = m * (n / 2 ) + m / 2 :=
433
- have hm0 : 0 < m := Nat.pos_of_ne_zero fun h => by simp_all
434
432
have hn0 : 0 < n := Nat.pos_of_ne_zero fun h => by simp_all
435
433
mul_right_injective₀ two_ne_zero <| by
436
434
dsimp
437
435
rw [mul_add, two_mul_odd_div_two hm1, mul_left_comm, two_mul_odd_div_two hn1,
438
- two_mul_odd_div_two (Nat.odd_mul_odd hm1 hn1), mul_tsub, mul_one, ←
439
- add_tsub_assoc_of_le (succ_le_of_lt hm0),
440
- tsub_add_cancel_of_le (le_mul_of_one_le_right (Nat.zero_le _) hn0)]
436
+ two_mul_odd_div_two (Nat.odd_mul_odd hm1 hn1), Nat.mul_sub, mul_one, ←
437
+ Nat.add_sub_assoc (by omega), Nat.sub_add_cancel (Nat.le_mul_of_pos_right m hn0)]
441
438
442
439
theorem odd_of_mod_four_eq_one {n : ℕ} : n % 4 = 1 → n % 2 = 1 := by
443
- simpa [ModEq, show 2 * 2 = 4 by norm_num ] using @ModEq.of_mul_left 2 n 1 2
440
+ simpa [ModEq] using @ModEq.of_mul_left 2 n 1 2
444
441
445
442
theorem odd_of_mod_four_eq_three {n : ℕ} : n % 4 = 3 → n % 2 = 1 := by
446
- simpa [ModEq, show 2 * 2 = 4 by norm_num, show 3 % 4 = 3 by norm_num] using
447
- @ModEq.of_mul_left 2 n 3 2
443
+ simpa [ModEq] using @ModEq.of_mul_left 2 n 3 2
448
444
449
445
/-- A natural number is odd iff it has residue `1` or `3` mod `4`-/
450
446
theorem odd_mod_four_iff {n : ℕ} : n % 2 = 1 ↔ n % 4 = 1 ∨ n % 4 = 3 :=
451
447
have help : ∀ m : ℕ, m < 4 → m % 2 = 1 → m = 1 ∨ m = 3 := by decide
452
448
⟨fun hn =>
453
- help (n % 4 ) (mod_lt n (by norm_num )) <| (mod_mod_of_dvd n (by decide : 2 ∣ 4 )).trans hn,
449
+ help (n % 4 ) (mod_lt n (by omega )) <| (mod_mod_of_dvd n (by decide : 2 ∣ 4 )).trans hn,
454
450
fun h => Or.elim h odd_of_mod_four_eq_one odd_of_mod_four_eq_three⟩
455
451
456
452
lemma mod_eq_of_modEq {a b n} (h : a ≡ b [MOD n]) (hb : b < n) : a % n = b :=
0 commit comments