|
| 1 | +/- |
| 2 | +Copyright (c) 2018 Chris Hughes. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Chris Hughes |
| 5 | +-/ |
| 6 | + |
| 7 | +import data.int.basic data.nat.modeq |
| 8 | + |
| 9 | +namespace int |
| 10 | + |
| 11 | +def modeq (n a b : ℤ) := a % n = b % n |
| 12 | + |
| 13 | +notation a ` ≡ `:50 b ` [ZMOD `:50 n `]`:0 := modeq n a b |
| 14 | + |
| 15 | +namespace modeq |
| 16 | +variables {n m a b c d : ℤ} |
| 17 | + |
| 18 | +@[refl] protected theorem refl (a : ℤ) : a ≡ a [ZMOD n] := @rfl _ _ |
| 19 | + |
| 20 | +@[symm] protected theorem symm : a ≡ b [ZMOD n] → b ≡ a [ZMOD n] := eq.symm |
| 21 | + |
| 22 | +@[trans] protected theorem trans : a ≡ b [ZMOD n] → b ≡ c [ZMOD n] → a ≡ c [ZMOD n] := eq.trans |
| 23 | + |
| 24 | +lemma coe_nat_modeq_iff (a b n : ℕ) : a ≡ b [ZMOD n] ↔ a ≡ b [MOD n] := |
| 25 | +by unfold modeq nat.modeq; rw ← int.coe_nat_eq_coe_nat_iff; simp [int.coe_nat_mod] |
| 26 | + |
| 27 | +instance : decidable (a ≡ b [ZMOD n]) := by unfold modeq; apply_instance |
| 28 | + |
| 29 | +theorem modeq_zero_iff : a ≡ 0 [ZMOD n] ↔ n ∣ a := |
| 30 | +by rw [modeq, zero_mod, dvd_iff_mod_eq_zero] |
| 31 | + |
| 32 | +theorem modeq_iff_dvd : a ≡ b [ZMOD n] ↔ (n:ℤ) ∣ b - a := |
| 33 | +by rw [modeq, eq_comm]; |
| 34 | + simp [int.mod_eq_mod_iff_mod_sub_eq_zero, int.dvd_iff_mod_eq_zero] |
| 35 | + |
| 36 | +theorem modeq_of_dvd_of_modeq (d : m ∣ n) (h : a ≡ b [ZMOD n]) : a ≡ b [ZMOD m] := |
| 37 | +modeq_iff_dvd.2 $ dvd_trans d (modeq_iff_dvd.1 h) |
| 38 | + |
| 39 | +theorem modeq_mul_left' (hc : 0 ≤ c) (h : a ≡ b [ZMOD n]) : c * a ≡ c * b [ZMOD (c * n)] := |
| 40 | +or.cases_on (lt_or_eq_of_le hc) (λ hc, |
| 41 | + by unfold modeq; |
| 42 | + simp [mul_mod_mul_of_pos _ _ hc, (show _ = _, from h)] ) |
| 43 | +(λ hc, by simp [hc.symm]) |
| 44 | + |
| 45 | +theorem modeq_mul_right' (hc : 0 ≤ c) (h : a ≡ b [ZMOD n]) : a * c ≡ b * c [ZMOD (n * c)] := |
| 46 | +by rw [mul_comm a, mul_comm b, mul_comm n]; exact modeq_mul_left' hc h |
| 47 | + |
| 48 | +theorem modeq_add (h₁ : a ≡ b [ZMOD n]) (h₂ : c ≡ d [ZMOD n]) : a + c ≡ b + d [ZMOD n] := |
| 49 | +modeq_iff_dvd.2 $ by simpa using dvd_add (modeq_iff_dvd.1 h₁) (modeq_iff_dvd.1 h₂) |
| 50 | + |
| 51 | +theorem modeq_add_cancel_left (h₁ : a ≡ b [ZMOD n]) (h₂ : a + c ≡ b + d [ZMOD n]) : c ≡ d [ZMOD n] := |
| 52 | +have (n:ℤ) ∣ a + (-a + (d + -c)), |
| 53 | +by simpa using dvd_sub (modeq_iff_dvd.1 h₂) (modeq_iff_dvd.1 h₁), |
| 54 | +modeq_iff_dvd.2 $ by rwa add_neg_cancel_left at this |
| 55 | + |
| 56 | +theorem modeq_add_cancel_right (h₁ : c ≡ d [ZMOD n]) (h₂ : a + c ≡ b + d [ZMOD n]) : a ≡ b [ZMOD n] := |
| 57 | +by rw [add_comm a, add_comm b] at h₂; exact modeq_add_cancel_left h₁ h₂ |
| 58 | + |
| 59 | +theorem modeq_neg (h : a ≡ b [ZMOD n]) : -a ≡ -b [ZMOD n] := |
| 60 | +modeq_add_cancel_left h (by simp) |
| 61 | + |
| 62 | +theorem modeq_sub (h₁ : a ≡ b [ZMOD n]) (h₂ : c ≡ d [ZMOD n]) : a - c ≡ b - d [ZMOD n] := |
| 63 | +by rw [sub_eq_add_neg, sub_eq_add_neg]; exact modeq_add h₁ (modeq_neg h₂) |
| 64 | + |
| 65 | +theorem modeq_mul_left (c : ℤ) (h : a ≡ b [ZMOD n]) : c * a ≡ c * b [ZMOD n] := |
| 66 | +or.cases_on (le_total 0 c) |
| 67 | +(λ hc, modeq_of_dvd_of_modeq (dvd_mul_left _ _) (modeq_mul_left' hc h)) |
| 68 | +(λ hc, by rw [← neg_neg c, ← neg_mul_eq_neg_mul, ← neg_mul_eq_neg_mul _ b]; |
| 69 | + exact modeq_neg (modeq_of_dvd_of_modeq (dvd_mul_left _ _) |
| 70 | + (modeq_mul_left' (neg_nonneg.2 hc) h))) |
| 71 | + |
| 72 | +theorem modeq_mul_right (c : ℤ) (h : a ≡ b [ZMOD n]) : a * c ≡ b * c [ZMOD n] := |
| 73 | +by rw [mul_comm a, mul_comm b]; exact modeq_mul_left c h |
| 74 | + |
| 75 | +theorem modeq_mul (h₁ : a ≡ b [ZMOD n]) (h₂ : c ≡ d [ZMOD n]) : a * c ≡ b * d [ZMOD n] := |
| 76 | +(modeq_mul_left _ h₂).trans (modeq_mul_right _ h₁) |
| 77 | + |
| 78 | +end modeq |
| 79 | +end int |
0 commit comments