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

Commit dbb3ff0

Browse files
ChrisHughes24johoelzl
authored andcommitted
feat(data/zmod/quadratic_reciprocity): quadratic reciprocity (#327)
* multiplicative group of finite field is cyclic * more stuff * change chinese remainder to def * get rid of nonsense * delete extra line break * one prod_bij left * move lemmas to correct places * delete prod_instances * almost done * move lamms to correct places * more moving lemmas * finished off moving lemmas * fix build * move quadratic reciprocity to zmod * improve readability * remove unnecessary alphas * move `prod_range_id` * fix build * fix build * fix build * fix build * delete mk_of_ne_zero * move odd_mul_odd_div_two * extra a few lemmas * improving readability * delete duplicate lemmas * forgot to save * delete duplicate lemma * indent calc proofs * fix build * fix build * forgot to save * fix build
1 parent f3850c2 commit dbb3ff0

24 files changed

+1259
-26
lines changed

algebra/big_operators.lean

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ by simp [finset.prod]
5454
attribute [to_additive finset.sum_const_zero] prod_const_one
5555

5656
@[simp, to_additive finset.sum_image]
57-
lemma prod_image [decidable_eq α] [decidable_eq γ] {s : finset γ} {g : γ → α} :
57+
lemma prod_image [decidable_eq α] {s : finset γ} {g : γ → α} :
5858
(∀x∈s, ∀y∈s, g x = g y → x = y) → (s.image g).prod f = s.prod (λx, f (g x)) :=
5959
fold_image
6060

@@ -229,14 +229,70 @@ lemma prod_range_succ' (f : ℕ → β) :
229229
| (n + 1) := by rw [prod_range_succ (λ m, f (nat.succ m)), mul_assoc, ← prod_range_succ'];
230230
exact prod_range_succ _ _
231231

232-
@[simp] lemma prod_const [decidable_eq α] (b : β) : s.prod (λ a, b) = b ^ s.card :=
232+
@[simp] lemma prod_const (b : β) : s.prod (λ a, b) = b ^ s.card :=
233+
by haveI := classical.dec_eq α; exact
233234
finset.induction_on s rfl (by simp [pow_add, mul_comm] {contextual := tt})
234235

236+
lemma prod_pow (s : finset α) (n : ℕ) (f : α → β) :
237+
s.prod (λ x, f x ^ n) = s.prod f ^ n :=
238+
by haveI := classical.dec_eq α; exact
239+
finset.induction_on s (by simp) (by simp [_root_.mul_pow] {contextual := tt})
240+
241+
lemma prod_nat_pow (s : finset α) (n : ℕ) (f : α → ℕ) :
242+
s.prod (λ x, f x ^ n) = s.prod f ^ n :=
243+
by haveI := classical.dec_eq α; exact
244+
finset.induction_on s (by simp) (by simp [nat.mul_pow] {contextual := tt})
245+
246+
@[to_additive finset.sum_involution]
247+
lemma prod_involution {s : finset α} {f : α → β} :
248+
∀ (g : Π a ∈ s, α)
249+
(h₁ : ∀ a ha, f a * f (g a ha) = 1)
250+
(h₂ : ∀ a ha, f a ≠ 1 → g a ha ≠ a)
251+
(h₃ : ∀ a ha, g a ha ∈ s)
252+
(h₄ : ∀ a ha, g (g a ha) (h₃ a ha) = a),
253+
s.prod f = 1 :=
254+
by haveI := classical.dec_eq α;
255+
haveI := classical.dec_eq β; exact
256+
finset.strong_induction_on s
257+
(λ s ih g h₁ h₂ h₃ h₄,
258+
if hs : s = ∅ then hs.symm ▸ rfl
259+
else let ⟨x, hx⟩ := exists_mem_of_ne_empty hs in
260+
have hmem : ∀ y ∈ (s.erase x).erase (g x hx), y ∈ s,
261+
from λ y hy, (mem_of_mem_erase (mem_of_mem_erase hy)),
262+
have g_inj : ∀ {x hx y hy}, g x hx = g y hy → x = y,
263+
from λ x hx y hy h, by rw [← h₄ x hx, ← h₄ y hy]; simp [h],
264+
have ih': (erase (erase s x) (g x hx)).prod f = (1 : β) :=
265+
ih ((s.erase x).erase (g x hx))
266+
⟨subset.trans (erase_subset _ _) (erase_subset _ _),
267+
λ h, not_mem_erase (g x hx) (s.erase x) (h (h₃ x hx))⟩
268+
(λ y hy, g y (hmem y hy))
269+
(λ y hy, h₁ y (hmem y hy))
270+
(λ y hy, h₂ y (hmem y hy))
271+
(λ y hy, mem_erase.2 ⟨λ (h : g y _ = g x hx), by simpa [g_inj h] using hy,
272+
mem_erase.2 ⟨λ (h : g y _ = x),
273+
have y = g x hx, from h₄ y (hmem y hy) ▸ by simp [h],
274+
by simpa [this] using hy, h₃ y (hmem y hy)⟩⟩)
275+
(λ y hy, h₄ y (hmem y hy)),
276+
if hx1 : f x = 1
277+
then ih' ▸ eq.symm (prod_subset hmem
278+
(λ y hy hy₁,
279+
have y = x ∨ y = g x hx, by simp [hy] at hy₁; tauto,
280+
this.elim (λ h, h.symm ▸ hx1)
281+
(λ h, h₁ x hx ▸ h ▸ hx1.symm ▸ (one_mul _).symm)))
282+
else by rw [← insert_erase hx, prod_insert (not_mem_erase _ _),
283+
← insert_erase (mem_erase.2 ⟨h₂ x hx hx1, h₃ x hx⟩),
284+
prod_insert (not_mem_erase _ _), ih', mul_one, h₁ x hx])
285+
235286
end comm_monoid
236287

237-
@[simp] lemma sum_const [add_comm_monoid β] [decidable_eq α] (b : β) :
288+
lemma sum_smul [add_comm_monoid β] (s : finset α) (n : ℕ) (f : α → β) :
289+
s.sum (λ x, add_monoid.smul n (f x)) = add_monoid.smul n (s.sum f) :=
290+
@prod_pow _ (multiplicative β) _ _ _ _
291+
attribute [to_additive finset.sum_smul] prod_pow
292+
293+
@[simp] lemma sum_const [add_comm_monoid β] (b : β) :
238294
s.sum (λ a, b) = add_monoid.smul s.card b :=
239-
@prod_const _ (multiplicative β) _ _ _ _
295+
@prod_const _ (multiplicative β) _ _ _
240296
attribute [to_additive finset.sum_const] prod_const
241297

242298
lemma sum_range_succ' [add_comm_monoid β] (f : ℕ → β) :
@@ -257,6 +313,23 @@ end comm_group
257313
card (s.sigma t) = s.sum (λ a, card (t a)) :=
258314
multiset.card_sigma _ _
259315

316+
lemma card_bind [decidable_eq β] {s : finset α} {t : α → finset β}
317+
(h : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → t x ∩ t y = ∅) :
318+
(s.bind t).card = s.sum (λ u, card (t u)) :=
319+
calc (s.bind t).card = (s.bind t).sum (λ _, 1) : by simp
320+
... = s.sum (λ a, (t a).sum (λ _, 1)) : finset.sum_bind h
321+
... = s.sum (λ u, card (t u)) : by simp
322+
323+
lemma card_bind_le [decidable_eq β] {s : finset α} {t : α → finset β} :
324+
(s.bind t).card ≤ s.sum (λ a, (t a).card) :=
325+
by haveI := classical.dec_eq α; exact
326+
finset.induction_on s (by simp)
327+
(λ a s has ih,
328+
calc ((insert a s).bind t).card ≤ (t a).card + (s.bind t).card :
329+
by rw bind_insert; exact finset.card_union_le _ _
330+
... ≤ (insert a s).sum (λ a, card (t a)) :
331+
by rw sum_insert has; exact add_le_add_left ih _)
332+
260333
end finset
261334

262335
namespace finset
@@ -402,6 +475,17 @@ end discrete_linear_ordered_field
402475
(s.pi t).card = s.prod (λ a, card (t a)) :=
403476
multiset.card_pi _ _
404477

478+
@[simp] lemma prod_range_id_eq_fact (n : ℕ) : ((range n.succ).erase 0).prod (λ x, x) = nat.fact n :=
479+
calc ((range n.succ).erase 0).prod (λ x, x) = (range n).prod nat.succ :
480+
eq.symm (prod_bij (λ x _, nat.succ x)
481+
(λ a h₁, mem_erase.2 ⟨nat.succ_ne_zero _, mem_range.2 $ nat.succ_lt_succ $ by simpa using h₁⟩)
482+
(by simp) (λ _ _ _ _, nat.succ_inj)
483+
(λ b h,
484+
have b.pred.succ = b, from nat.succ_pred_eq_of_pos $
485+
by simp [nat.pos_iff_ne_zero] at *; tauto,
486+
⟨nat.pred b, mem_range.2 $ nat.lt_of_succ_lt_succ (by simp [*, - range_succ] at *), this.symm⟩))
487+
... = nat.fact n : by induction n; simp *
488+
405489
end finset
406490

407491
section group

algebra/field.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def mk0 (a : α) (ha : a ≠ 0) : units α :=
3232

3333
@[simp] theorem mk0_inv (ha : a ≠ 0) : ((mk0 a ha)⁻¹ : α) = a⁻¹ := rfl
3434

35+
@[simp] lemma units.mk0_inj [field α] {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) :
36+
units.mk0 a ha = units.mk0 b hb ↔ a = b :=
37+
⟨λ h, by injection h, λ h, units.ext h⟩
38+
3539
end units
3640

3741
section division_ring

algebra/field_power.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ lemma fpow_ne_zero_of_ne_zero {a : α} (ha : a ≠ 0) : ∀ (z : ℤ), fpow a z
4242
pow_zero _
4343

4444
lemma fpow_add {a : α} (ha : a ≠ 0) (z1 z2 : ℤ) : fpow a (z1 + z2) = fpow a z1 * fpow a z2 :=
45-
begin simp only [fpow_eq_gpow ha], rw ←units.mul_coe, congr, apply gpow_add end
45+
begin simp only [fpow_eq_gpow ha], rw ← units.coe_mul, congr, apply gpow_add end
4646

4747
end field_power
4848

algebra/group.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,10 @@ instance : has_one (units α) := ⟨⟨1, 1, mul_one 1, one_mul 1⟩⟩
226226
instance : has_inv (units α) := ⟨units.inv'⟩
227227

228228
variables (a b)
229-
@[simp] lemma mul_coe : (↑(a * b) : α) = a * b := rfl
230-
@[simp] lemma one_coe : ((1 : units α) : α) = 1 := rfl
229+
@[simp] lemma coe_mul : (↑(a * b) : α) = a * b := rfl
230+
@[simp] lemma coe_one : ((1 : units α) : α) = 1 := rfl
231231
lemma val_coe : (↑a : α) = a.val := rfl
232-
lemma inv_coe : ((a⁻¹ : units α) : α) = a.inv := rfl
232+
lemma coe_inv : ((a⁻¹ : units α) : α) = a.inv := rfl
233233
@[simp] lemma inv_mul : (↑a⁻¹ * a : α) = 1 := inv_val _
234234
@[simp] lemma mul_inv : (a * ↑a⁻¹ : α) = 1 := val_inv _
235235

algebra/group_power.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ attribute [to_additive smul_add_comm] pow_mul_comm
118118
@list.prod_repeat (multiplicative β) _
119119
attribute [to_additive list.sum_repeat] list.prod_repeat
120120

121+
@[simp] lemma units.coe_pow (u : units α) (n : ℕ) : ((u ^ n : units α) : α) = u ^ n :=
122+
by induction n; simp [*, pow_succ]
123+
121124
end monoid
122125

123126
@[simp] theorem nat.pow_eq_pow (p q : ℕ) :
@@ -366,6 +369,9 @@ by rw [gsmul_eq_mul, gsmul_eq_mul, mul_assoc]
366369
@[simp] theorem int.cast_pow [ring α] (n : ℤ) (m : ℕ) : (↑(n ^ m) : α) = ↑n ^ m :=
367370
by induction m; simp [*, nat.succ_eq_add_one,pow_add]
368371

372+
lemma neg_one_pow_eq_pow_mod_two [ring α] {n : ℕ} : (-1 : α) ^ n = -1 ^ (n % 2) :=
373+
by rw [← nat.mod_add_div n 2, pow_add, pow_mul]; simp [pow_two]
374+
369375
theorem pow_ne_zero [domain α] {a : α} (n : ℕ) (h : a ≠ 0) : a ^ n ≠ 0 :=
370376
by induction n with n ih; simp [pow_succ, mul_eq_zero, *]
371377

algebra/ordered_ring.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ lt_add_of_le_of_pos (le_refl _) zero_lt_one
7575

7676
lemma one_lt_two : 1 < (2 : α) := lt_add_one _
7777

78+
lemma one_lt_mul {a b : α} (ha : 1 ≤ a) (hb : 1 < b) : 1 < a * b :=
79+
(one_mul (1 : α)) ▸ mul_lt_mul' ha hb zero_le_one (lt_of_lt_of_le zero_lt_one ha)
80+
7881
lemma mul_le_one {a b : α} (ha : a ≤ 1) (hb' : 0 ≤ b) (hb : b ≤ 1) : a * b ≤ 1 :=
7982
begin rw ← one_mul (1 : α), apply mul_le_mul; {assumption <|> apply zero_le_one} end
8083

algebra/pi_instances.lean

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,14 @@ instance {r : ring α} [module α β] [module α γ] : module α (β × γ) :=
224224

225225
instance {r : field α} [vector_space α β] [vector_space α γ] : vector_space α (β × γ) := {}
226226

227-
end prod
227+
end prod
228+
229+
namespace finset
230+
231+
@[to_additive finset.prod_mk_sum]
232+
lemma prod_mk_prod {α β γ : Type*} [comm_monoid α] [comm_monoid β] (s : finset γ)
233+
(f : γ → α) (g : γ → β) : (s.prod f, s.prod g) = s.prod (λ x, (f x, g x)) :=
234+
by haveI := classical.dec_eq γ; exact
235+
finset.induction_on s rfl (by simp [prod.ext_iff] {contextual := tt})
236+
237+
end finset

algebra/ring.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ instance integral_domain.to_nonzero_comm_ring (α : Type*) [id : integral_domain
191191
nonzero_comm_ring α :=
192192
{ ..id }
193193

194+
lemma units.coe_ne_zero [nonzero_comm_ring α] (u : units α) : (u : α) ≠ 0 :=
195+
λ h : u.1 = 0, by simpa [h, zero_ne_one] using u.3
196+
194197
/-- A domain is a ring with no zero divisors, i.e. satisfying
195198
the condition `a * b = 0 ↔ a = 0 ∨ b = 0`. Alternatively, a domain
196199
is an integral domain without assuming commutativity of multiplication. -/
@@ -256,6 +259,10 @@ section
256259
theorem mul_dvd_mul_iff_right {a b c : α} (hc : c ≠ 0) : a * c ∣ b * c ↔ a ∣ b :=
257260
exists_congr $ λ d, by rw [mul_right_comm, domain.mul_right_inj hc]
258261

262+
lemma units.inv_eq_self_iff (u : units α) : u⁻¹ = u ↔ u = 1 ∨ u = -1 :=
263+
by conv {to_lhs, rw [inv_eq_iff_mul_eq_one, ← mul_one (1 : units α), units.ext_iff, units.coe_mul,
264+
units.coe_mul, mul_self_eq_mul_self_iff, ← units.ext_iff, ← units.coe_neg, ← units.ext_iff] }
265+
259266
end
260267

261268
/- units in various rings -/

data/finset.lean

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -853,9 +853,9 @@ by by_cases a ∈ s; simp [h, nat.le_add_right]
853853

854854
theorem card_erase_of_mem [decidable_eq α] {a : α} {s : finset α} : a ∈ s → card (erase s a) = pred (card s) := card_erase_of_mem
855855

856-
theorem card_range (n : ℕ) : card (range n) = n := card_range n
856+
@[simp] theorem card_range (n : ℕ) : card (range n) = n := card_range n
857857

858-
theorem card_attach {s : finset α} : card (attach s) = card s := multiset.card_attach
858+
@[simp] theorem card_attach {s : finset α} : card (attach s) = card s := multiset.card_attach
859859

860860
theorem card_image_of_inj_on [decidable_eq β] {f : α → β} {s : finset α}
861861
(H : ∀x∈s, ∀y∈s, f x = f y → x = y) : card (image f s) = card s :=
@@ -926,6 +926,44 @@ finset.strong_induction_on s $ λ s,
926926
finset.induction_on s (λ _, h₀) $ λ a s n _ ih, h₁ a s n $
927927
λ t ss, ih _ (lt_of_le_of_lt ss (ssubset_insert n) : t < _)
928928

929+
lemma card_congr {s : finset α} {t : finset β} (f : Π a ∈ s, β)
930+
(h₁ : ∀ a ha, f a ha ∈ t) (h₂ : ∀ a b ha hb, f a ha = f b hb → a = b)
931+
(h₃ : ∀ b ∈ t, ∃ a ha, f a ha = b) : s.card = t.card :=
932+
by haveI := classical.prop_decidable; exact
933+
calc s.card = s.attach.card : card_attach.symm
934+
... = (s.attach.image (λ (a : {a // a ∈ s}), f a.1 a.2)).card :
935+
eq.symm (card_image_of_injective _ (λ a b h, subtype.eq (h₂ _ _ _ _ h)))
936+
... = t.card : congr_arg card (finset.ext.2 $ λ b,
937+
⟨λ h, let ⟨a, ha₁, ha₂⟩ := mem_image.1 h in ha₂ ▸ h₁ _ _,
938+
λ h, let ⟨a, ha₁, ha₂⟩ := h₃ b h in mem_image.2 ⟨⟨a, ha₁⟩, by simp [ha₂]⟩⟩)
939+
940+
lemma card_union_add_card_inter [decidable_eq α] (s t : finset α) :
941+
(s ∪ t).card + (s ∩ t).card = s.card + t.card :=
942+
finset.induction_on t (by simp) (λ a, by by_cases a ∈ s; simp * {contextual := tt})
943+
944+
lemma card_union_le [decidable_eq α] (s t : finset α) :
945+
(s ∪ t).card ≤ s.card + t.card :=
946+
card_union_add_card_inter s t ▸ le_add_right _ _
947+
948+
lemma surj_on_of_inj_on_of_card_le {s : finset α} {t : finset β}
949+
(f : Π a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
950+
(hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂)
951+
(hst : card t ≤ card s) :
952+
(∀ b ∈ t, ∃ a ha, b = f a ha) :=
953+
by haveI := classical.dec_eq β; exact
954+
λ b hb,
955+
have h : card (image (λ (a : {a // a ∈ s}), f (a.val) a.2) (attach s)) = card s,
956+
from @card_attach _ s ▸ card_image_of_injective _
957+
(λ ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h, subtype.eq $ hinj _ _ _ _ h),
958+
have h₁ : image (λ a : {a // a ∈ s}, f a.1 a.2) s.attach = t :=
959+
eq_of_subset_of_card_le (λ b h, let ⟨a, ha₁, ha₂⟩ := mem_image.1 h in
960+
ha₂ ▸ hf _ _) (by simp [hst, h]),
961+
begin
962+
rw ← h₁ at hb,
963+
rcases mem_image.1 hb with ⟨a, ha₁, ha₂⟩,
964+
exact ⟨a, a.2, ha₂.symm⟩,
965+
end
966+
929967
end card
930968

931969
section bind
@@ -1124,7 +1162,7 @@ by simp [fold, ndinsert_of_not_mem h]
11241162
@[simp] theorem fold_singleton : (singleton a).fold op b f = f a * b :=
11251163
by simp [fold]
11261164

1127-
@[simp] theorem fold_image [decidable_eq α] [decidable_eq γ] {g : γ → α} {s : finset γ}
1165+
@[simp] theorem fold_image [decidable_eq α] {g : γ → α} {s : finset γ}
11281166
(H : ∀ (x ∈ s) (y ∈ s), g x = g y → x = y) : (s.image g).fold op b f = s.fold op b (f ∘ g) :=
11291167
by simp [fold, image_val_of_inj_on H, map_map]
11301168

data/int/modeq.lean

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ modeq_iff_dvd.2 $ by rwa add_neg_cancel_left at this
5656
theorem modeq_add_cancel_right (h₁ : c ≡ d [ZMOD n]) (h₂ : a + c ≡ b + d [ZMOD n]) : a ≡ b [ZMOD n] :=
5757
by rw [add_comm a, add_comm b] at h₂; exact modeq_add_cancel_left h₁ h₂
5858

59+
theorem mod_modeq (a n) : a % n ≡ a [ZMOD n] := int.mod_mod _ _
60+
5961
theorem modeq_neg (h : a ≡ b [ZMOD n]) : -a ≡ -b [ZMOD n] :=
6062
modeq_add_cancel_left h (by simp)
6163

@@ -75,5 +77,33 @@ by rw [mul_comm a, mul_comm b]; exact modeq_mul_left c h
7577
theorem modeq_mul (h₁ : a ≡ b [ZMOD n]) (h₂ : c ≡ d [ZMOD n]) : a * c ≡ b * d [ZMOD n] :=
7678
(modeq_mul_left _ h₂).trans (modeq_mul_right _ h₁)
7779

80+
theorem modeq_of_modeq_mul_left (m : ℤ) (h : a ≡ b [ZMOD m * n]) : a ≡ b [ZMOD n] :=
81+
by rw [modeq_iff_dvd] at *; exact dvd.trans (dvd_mul_left n m) h
82+
83+
theorem modeq_of_modeq_mul_right (m : ℤ) : a ≡ b [ZMOD n * m] → a ≡ b [ZMOD n] :=
84+
mul_comm m n ▸ modeq_of_modeq_mul_left _
85+
86+
lemma modeq_and_modeq_iff_modeq_mul {a b m n : ℤ} (hmn : nat.coprime m.nat_abs n.nat_abs) :
87+
a ≡ b [ZMOD m] ∧ a ≡ b [ZMOD n] ↔ (a ≡ b [ZMOD m * n]) :=
88+
⟨λ h, begin
89+
rw [int.modeq.modeq_iff_dvd, int.modeq.modeq_iff_dvd] at h,
90+
rw [int.modeq.modeq_iff_dvd, ← int.nat_abs_dvd, ← int.dvd_nat_abs,
91+
int.coe_nat_dvd, int.nat_abs_mul],
92+
refine hmn.mul_dvd_of_dvd_of_dvd _ _;
93+
rw [← int.coe_nat_dvd, int.nat_abs_dvd, int.dvd_nat_abs]; tauto
94+
end,
95+
λ h, ⟨int.modeq.modeq_of_modeq_mul_right _ h, int.modeq.modeq_of_modeq_mul_left _ h⟩⟩
96+
97+
lemma gcd_a_modeq (a b : ℕ) : (a : ℤ) * nat.gcd_a a b ≡ nat.gcd a b [ZMOD b] :=
98+
by rw [← add_zero ((a : ℤ) * _), nat.gcd_eq_gcd_ab];
99+
exact int.modeq.modeq_add rfl (int.modeq.modeq_zero_iff.2 (dvd_mul_right _ _)).symm
100+
78101
end modeq
102+
103+
@[simp] lemma mod_mul_right_mod (a b c : ℤ) : a % (b * c) % b = a % b :=
104+
int.modeq.modeq_of_modeq_mul_right _ (int.modeq.mod_modeq _ _)
105+
106+
@[simp] lemma mod_mul_left_mod (a b c : ℤ) : a % (b * c) % c = a % c :=
107+
int.modeq.modeq_of_modeq_mul_left _ (int.modeq.mod_modeq _ _)
108+
79109
end int

0 commit comments

Comments
 (0)