Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 2bd5e21

Browse files
ChrisHughes24digama0
authored andcommitted
feat(data/int/modeq): Modular arithmetic for integers
1 parent 6815830 commit 2bd5e21

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

data/int/modeq.lean

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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

Comments
 (0)