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

Commit 89ada87

Browse files
committed
chore(algebra, data/pnat): refactoring comm_semiring_has_dvd into comm_monoid_has_dvd (#3702)
changes the instance comm_semiring_has_dvd to apply to any comm_monoid cleans up the pnat API to use this new definition
1 parent 13d4fbe commit 89ada87

File tree

5 files changed

+116
-117
lines changed

5 files changed

+116
-117
lines changed

src/algebra/divisibility.lean

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import algebra.group_with_zero
2+
3+
variables {α : Type*}
4+
5+
section comm_monoid
6+
7+
variables [comm_monoid α] {a b c : α}
8+
9+
@[priority 100]
10+
instance comm_monoid_has_dvd : has_dvd α :=
11+
has_dvd.mk (λ a b, ∃ c, b = a * c)
12+
13+
-- TODO: this used to not have c explicit, but that seems to be important
14+
-- for use with tactics, similar to exist.intro
15+
theorem dvd.intro (c : α) (h : a * c = b) : a ∣ b :=
16+
exists.intro c h^.symm
17+
18+
alias dvd.intro ← dvd_of_mul_right_eq
19+
20+
theorem dvd.intro_left (c : α) (h : c * a = b) : a ∣ b :=
21+
dvd.intro _ (begin rewrite mul_comm at h, apply h end)
22+
23+
alias dvd.intro_left ← dvd_of_mul_left_eq
24+
25+
theorem exists_eq_mul_right_of_dvd (h : a ∣ b) : ∃ c, b = a * c := h
26+
27+
theorem dvd.elim {P : Prop} {a b : α} (H₁ : a ∣ b) (H₂ : ∀ c, b = a * c → P) : P :=
28+
exists.elim H₁ H₂
29+
30+
theorem exists_eq_mul_left_of_dvd (h : a ∣ b) : ∃ c, b = c * a :=
31+
dvd.elim h (assume c, assume H1 : b = a * c, exists.intro c (eq.trans H1 (mul_comm a c)))
32+
33+
theorem dvd.elim_left {P : Prop} (h₁ : a ∣ b) (h₂ : ∀ c, b = c * a → P) : P :=
34+
exists.elim (exists_eq_mul_left_of_dvd h₁) (assume c, assume h₃ : b = c * a, h₂ c h₃)
35+
36+
@[refl, simp] theorem dvd_refl (a : α) : a ∣ a :=
37+
dvd.intro 1 (by simp)
38+
39+
local attribute [simp] mul_assoc mul_comm mul_left_comm
40+
41+
@[trans] theorem dvd_trans (h₁ : a ∣ b) (h₂ : b ∣ c) : a ∣ c :=
42+
match h₁, h₂ with
43+
| ⟨d, (h₃ : b = a * d)⟩, ⟨e, (h₄ : c = b * e)⟩ :=
44+
⟨d * e, show c = a * (d * e), by simp [h₃, h₄]⟩
45+
end
46+
47+
alias dvd_trans ← dvd.trans
48+
49+
@[simp] theorem one_dvd (a : α) : 1 ∣ a := dvd.intro a (by simp)
50+
51+
@[simp] theorem dvd_mul_right (a b : α) : a ∣ a * b := dvd.intro b rfl
52+
53+
@[simp] theorem dvd_mul_left (a b : α) : a ∣ b * a := dvd.intro b (by simp)
54+
55+
theorem dvd_mul_of_dvd_left (h : a ∣ b) (c : α) : a ∣ b * c :=
56+
dvd.elim h (λ d h', begin rw [h', mul_assoc], apply dvd_mul_right end)
57+
58+
theorem dvd_mul_of_dvd_right (h : a ∣ b) (c : α) : a ∣ c * b :=
59+
begin rw mul_comm, exact dvd_mul_of_dvd_left h _ end
60+
61+
theorem mul_dvd_mul : ∀ {a b c d : α}, a ∣ b → c ∣ d → a * c ∣ b * d
62+
| a ._ c ._ ⟨e, rfl⟩ ⟨f, rfl⟩ := ⟨e * f, by simp⟩
63+
64+
theorem mul_dvd_mul_left (a : α) {b c : α} (h : b ∣ c) : a * b ∣ a * c :=
65+
mul_dvd_mul (dvd_refl a) h
66+
67+
theorem mul_dvd_mul_right (h : a ∣ b) (c : α) : a * c ∣ b * c :=
68+
mul_dvd_mul h (dvd_refl c)
69+
70+
theorem dvd_of_mul_right_dvd (h : a * b ∣ c) : a ∣ c :=
71+
dvd.elim h (begin intros d h₁, rw [h₁, mul_assoc], apply dvd_mul_right end)
72+
73+
theorem dvd_of_mul_left_dvd (h : a * b ∣ c) : b ∣ c :=
74+
dvd.elim h (λ d ceq, dvd.intro (a * d) (by simp [ceq]))
75+
76+
end comm_monoid
77+
78+
section comm_monoid_with_zero
79+
80+
variables [comm_monoid_with_zero α] {a : α}
81+
82+
theorem eq_zero_of_zero_dvd (h : 0 ∣ a) : a = 0 :=
83+
dvd.elim h (assume c, assume H' : a = 0 * c, eq.trans H' (zero_mul c))
84+
85+
/-- Given an element a of a commutative monoid with zero, there exists another element whose product
86+
with zero equals a iff a equals zero. -/
87+
@[simp] lemma zero_dvd_iff : 0 ∣ a ↔ a = 0 :=
88+
⟨eq_zero_of_zero_dvd, λ h, by rw h⟩
89+
90+
@[simp] theorem dvd_zero (a : α) : a ∣ 0 := dvd.intro 0 (by simp)
91+
92+
end comm_monoid_with_zero

src/algebra/ring/basic.lean

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Amelia Livingston, Yury Kudryashov,
55
Neil Strickland
66
-/
7-
import algebra.group_with_zero
7+
import algebra.divisibility
88
import data.set.basic
99

1010
/-!
@@ -378,85 +378,9 @@ lemma add_mul_self_eq (a b : α) : (a + b) * (a + b) = a*a + 2*a*b + b*b :=
378378
calc (a + b)*(a + b) = a*a + (1+1)*a*b + b*b : by simp [add_mul, mul_add, mul_comm, add_assoc]
379379
... = a*a + 2*a*b + b*b : by rw one_add_one_eq_two
380380

381-
instance comm_semiring_has_dvd : has_dvd α :=
382-
has_dvd.mk (λ a b, ∃ c, b = a * c)
383-
384-
-- TODO: this used to not have c explicit, but that seems to be important
385-
-- for use with tactics, similar to exist.intro
386-
theorem dvd.intro (c : α) (h : a * c = b) : a ∣ b :=
387-
exists.intro c h^.symm
388-
389-
alias dvd.intro ← dvd_of_mul_right_eq
390-
391-
theorem dvd.intro_left (c : α) (h : c * a = b) : a ∣ b :=
392-
dvd.intro _ (begin rewrite mul_comm at h, apply h end)
393-
394-
alias dvd.intro_left ← dvd_of_mul_left_eq
395-
396-
theorem exists_eq_mul_right_of_dvd (h : a ∣ b) : ∃ c, b = a * c := h
397-
398-
theorem dvd.elim {P : Prop} {a b : α} (H₁ : a ∣ b) (H₂ : ∀ c, b = a * c → P) : P :=
399-
exists.elim H₁ H₂
400-
401-
theorem exists_eq_mul_left_of_dvd (h : a ∣ b) : ∃ c, b = c * a :=
402-
dvd.elim h (assume c, assume H1 : b = a * c, exists.intro c (eq.trans H1 (mul_comm a c)))
403-
404-
theorem dvd.elim_left {P : Prop} (h₁ : a ∣ b) (h₂ : ∀ c, b = c * a → P) : P :=
405-
exists.elim (exists_eq_mul_left_of_dvd h₁) (assume c, assume h₃ : b = c * a, h₂ c h₃)
406-
407-
@[refl, simp] theorem dvd_refl (a : α) : a ∣ a :=
408-
dvd.intro 1 (by simp)
409-
410-
local attribute [simp] mul_assoc mul_comm mul_left_comm
411-
412-
@[trans] theorem dvd_trans (h₁ : a ∣ b) (h₂ : b ∣ c) : a ∣ c :=
413-
match h₁, h₂ with
414-
| ⟨d, (h₃ : b = a * d)⟩, ⟨e, (h₄ : c = b * e)⟩ :=
415-
⟨d * e, show c = a * (d * e), by simp [h₃, h₄]⟩
416-
end
417-
418-
alias dvd_trans ← dvd.trans
419-
420-
theorem eq_zero_of_zero_dvd (h : 0 ∣ a) : a = 0 :=
421-
dvd.elim h (assume c, assume H' : a = 0 * c, eq.trans H' (zero_mul c))
422-
423-
/-- Given an element a of a commutative semiring, there exists another element whose product
424-
with zero equals a iff a equals zero. -/
425-
@[simp] lemma zero_dvd_iff : 0 ∣ a ↔ a = 0 :=
426-
⟨eq_zero_of_zero_dvd, λ h, by rw h⟩
427-
428-
@[simp] theorem dvd_zero (a : α) : a ∣ 0 := dvd.intro 0 (by simp)
429-
430-
@[simp] theorem one_dvd (a : α) : 1 ∣ a := dvd.intro a (by simp)
431-
432-
@[simp] theorem dvd_mul_right (a b : α) : a ∣ a * b := dvd.intro b rfl
433-
434-
@[simp] theorem dvd_mul_left (a b : α) : a ∣ b * a := dvd.intro b (by simp)
435-
436-
theorem dvd_mul_of_dvd_left (h : a ∣ b) (c : α) : a ∣ b * c :=
437-
dvd.elim h (λ d h', begin rw [h', mul_assoc], apply dvd_mul_right end)
438-
439-
theorem dvd_mul_of_dvd_right (h : a ∣ b) (c : α) : a ∣ c * b :=
440-
begin rw mul_comm, exact dvd_mul_of_dvd_left h _ end
441-
442-
theorem mul_dvd_mul : ∀ {a b c d : α}, a ∣ b → c ∣ d → a * c ∣ b * d
443-
| a ._ c ._ ⟨e, rfl⟩ ⟨f, rfl⟩ := ⟨e * f, by simp⟩
444-
445-
theorem mul_dvd_mul_left (a : α) {b c : α} (h : b ∣ c) : a * b ∣ a * c :=
446-
mul_dvd_mul (dvd_refl a) h
447-
448-
theorem mul_dvd_mul_right (h : a ∣ b) (c : α) : a * c ∣ b * c :=
449-
mul_dvd_mul h (dvd_refl c)
450-
451381
theorem dvd_add (h₁ : a ∣ b) (h₂ : a ∣ c) : a ∣ b + c :=
452382
dvd.elim h₁ (λ d hd, dvd.elim h₂ (λ e he, dvd.intro (d + e) (by simp [left_distrib, hd, he])))
453383

454-
theorem dvd_of_mul_right_dvd (h : a * b ∣ c) : a ∣ c :=
455-
dvd.elim h (begin intros d h₁, rw [h₁, mul_assoc], apply dvd_mul_right end)
456-
457-
theorem dvd_of_mul_left_dvd (h : a * b ∣ c) : b ∣ c :=
458-
dvd.elim h (λ d ceq, dvd.intro (a * d) (by simp [ceq]))
459-
460384
@[simp] theorem two_dvd_bit0 : 2 ∣ bit0 a := ⟨a, bit0_eq_two_mul _⟩
461385

462386
lemma ring_hom.map_dvd (f : α →+* β) {a b : α} : a ∣ b → f a ∣ f b :=

src/data/pnat/basic.lean

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,16 @@ begin
286286
{ exact ⟨nat.mod_le (m : ℕ) (k : ℕ), le_of_lt (nat.mod_lt (m : ℕ) k.pos)⟩ }
287287
end
288288

289-
instance : has_dvd ℕ+ := ⟨λ k m, (k : ℕ) ∣ (m : ℕ)⟩
290-
291-
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by {refl}
289+
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) :=
290+
begin
291+
split; intro h, rcases h with ⟨_, rfl⟩, apply dvd_mul_right,
292+
rcases h with ⟨a, h⟩, cases a, { contrapose h, apply ne_zero, },
293+
use a.succ, apply nat.succ_pos, rw [← coe_inj, h, mul_coe, mk_coe],
294+
end
292295

293296
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k :=
294297
begin
295-
change (k : ℕ) ∣ (m : ℕ) ↔ mod m k = k,
298+
rw dvd_iff,
296299
rw [nat.dvd_iff_mod_eq_zero], split,
297300
{ intro h, apply eq, rw [mod_coe, if_pos h] },
298301
{ intro h, by_cases h' : (m : ℕ) % (k : ℕ) = 0,
@@ -315,24 +318,8 @@ begin
315318
rw [mod_add_div m k, dvd_iff'.mp h, nat.mul_succ, add_comm],
316319
end
317320

318-
theorem dvd_iff'' {k n : ℕ+} : k ∣ n ↔ ∃ m, k * m = n :=
319-
⟨λ h, ⟨div_exact h, mul_div_exact h⟩,
320-
λ ⟨m, h⟩, dvd.intro (m : ℕ)
321-
((mul_coe k m).symm.trans (congr_arg subtype.val h))⟩
322-
323-
theorem dvd_intro {k n : ℕ+} (m : ℕ+) (h : k * m = n) : k ∣ n :=
324-
dvd_iff''.mpr ⟨m, h⟩
325-
326-
@[simp]
327-
theorem dvd_refl (m : ℕ+) : m ∣ m := dvd_intro 1 (mul_one m)
328-
329321
theorem dvd_antisymm {m n : ℕ+} : m ∣ n → n ∣ m → m = n :=
330-
λ hmn hnm, subtype.eq (nat.dvd_antisymm hmn hnm)
331-
332-
protected theorem dvd_trans {k m n : ℕ+} : k ∣ m → m ∣ n → k ∣ n :=
333-
@dvd_trans ℕ _ (k : ℕ) (m : ℕ) (n : ℕ)
334-
335-
theorem one_dvd (n : ℕ+) : 1 ∣ n := dvd_intro n (one_mul n)
322+
λ hmn hnm, le_antisymm (le_of_dvd hmn) (le_of_dvd hnm)
336323

337324
theorem dvd_one_iff (n : ℕ+) : n ∣ 1 ↔ n = 1 :=
338325
⟨λ h, dvd_antisymm h (one_dvd n), λ h, h.symm ▸ (dvd_refl 1)⟩
@@ -350,19 +337,19 @@ def lcm (n m : ℕ+) : ℕ+ :=
350337

351338
@[simp] theorem lcm_coe (n m : ℕ+) : ((lcm n m) : ℕ) = nat.lcm n m := rfl
352339

353-
theorem gcd_dvd_left (n m : ℕ+) : (gcd n m) ∣ n := nat.gcd_dvd_left (n : ℕ) (m : ℕ)
340+
theorem gcd_dvd_left (n m : ℕ+) : (gcd n m) ∣ n := dvd_iff.2 (nat.gcd_dvd_left (n : ℕ) (m : ℕ))
354341

355-
theorem gcd_dvd_right (n m : ℕ+) : (gcd n m) ∣ m := nat.gcd_dvd_right (n : ℕ) (m : ℕ)
342+
theorem gcd_dvd_right (n m : ℕ+) : (gcd n m) ∣ m := dvd_iff.2 (nat.gcd_dvd_right (n : ℕ) (m : ℕ))
356343

357344
theorem dvd_gcd {m n k : ℕ+} (hm : k ∣ m) (hn : k ∣ n) : k ∣ gcd m n :=
358-
@nat.dvd_gcd (m : ℕ) (n : ℕ) (k : ℕ) hm hn
345+
dvd_iff.2 (@nat.dvd_gcd (m : ℕ) (n : ℕ) (k : ℕ) (dvd_iff.1 hm) (dvd_iff.1 hn))
359346

360-
theorem dvd_lcm_left (n m : ℕ+) : n ∣ lcm n m := nat.dvd_lcm_left (n : ℕ) (m : ℕ)
347+
theorem dvd_lcm_left (n m : ℕ+) : n ∣ lcm n m := dvd_iff.2 (nat.dvd_lcm_left (n : ℕ) (m : ℕ))
361348

362-
theorem dvd_lcm_right (n m : ℕ+) : m ∣ lcm n m := nat.dvd_lcm_right (n : ℕ) (m : ℕ)
349+
theorem dvd_lcm_right (n m : ℕ+) : m ∣ lcm n m := dvd_iff.2 (nat.dvd_lcm_right (n : ℕ) (m : ℕ))
363350

364351
theorem lcm_dvd {m n k : ℕ+} (hm : m ∣ k) (hn : n ∣ k) : lcm m n ∣ k :=
365-
@nat.lcm_dvd (m : ℕ) (n : ℕ) (k : ℕ) hm hn
352+
dvd_iff.2 (@nat.lcm_dvd (m : ℕ) (n : ℕ) (k : ℕ) (dvd_iff.1 hm) (dvd_iff.1 hn))
366353

367354
theorem gcd_mul_lcm (n m : ℕ+) : (gcd n m) * (lcm n m) = n * m :=
368355
subtype.eq (nat.gcd_mul_lcm (n : ℕ) (m : ℕ))
@@ -393,12 +380,12 @@ by { intro pp, intro contra, apply nat.prime.ne_one pp, rw pnat.coe_eq_one_iff,
393380
lemma not_prime_one : ¬ (1: ℕ+).prime := nat.not_prime_one
394381

395382
lemma prime.not_dvd_one {p : ℕ+} :
396-
p.prime → ¬ p ∣ 1 := λ pp : p.prime, nat.prime.not_dvd_one pp
383+
p.prime → ¬ p ∣ 1 := λ pp : p.prime, by {rw dvd_iff, apply nat.prime.not_dvd_one pp}
397384

398385
lemma exists_prime_and_dvd {n : ℕ+} : 2 ≤ n → (∃ (p : ℕ+), p.prime ∧ p ∣ n) :=
399386
begin
400387
intro h, cases nat.exists_prime_and_dvd h with p hp,
401-
existsi (⟨p, nat.prime.pos hp.left⟩ : ℕ+), apply hp
388+
existsi (⟨p, nat.prime.pos hp.left⟩ : ℕ+), rw dvd_iff, apply hp
402389
end
403390

404391
end prime

src/data/pnat/factors.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ begin
274274
split,
275275
{ intro h,
276276
rw [← prod_factor_multiset m, ← prod_factor_multiset m],
277-
apply dvd_intro (n.factor_multiset - m.factor_multiset).prod,
277+
apply dvd.intro (n.factor_multiset - m.factor_multiset).prod,
278278
rw [← prime_multiset.prod_add, prime_multiset.factor_multiset_prod,
279279
prime_multiset.add_sub_of_le h, prod_factor_multiset] },
280280
{ intro h,

src/data/pnat/xgcd.lean

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -323,16 +323,12 @@ begin
323323
rcases gcd_props a b with ⟨h₀, h₁, h₂, h₃, h₄, h₅, h₆⟩,
324324
apply dvd_antisymm,
325325
{ apply dvd_gcd,
326-
exact dvd_intro (gcd_a' a b) (h₁.trans (mul_comm _ _)).symm,
327-
exact dvd_intro (gcd_b' a b) (h₂.trans (mul_comm _ _)).symm},
328-
{ have h₇ := calc
329-
((gcd a b) : ℕ) ∣ a : nat.gcd_dvd_left a b
330-
... ∣ (gcd_z a b) * a : dvd_mul_left _ _,
331-
have h₈ := calc
332-
((gcd a b) : ℕ) ∣ b : nat.gcd_dvd_right a b
333-
... ∣ (gcd_x a b) * b : dvd_mul_left _ _,
334-
rw[h₅] at h₇,
335-
exact (nat.dvd_add_iff_right h₈).mpr h₇}
326+
exact dvd.intro (gcd_a' a b) (h₁.trans (mul_comm _ _)).symm,
327+
exact dvd.intro (gcd_b' a b) (h₂.trans (mul_comm _ _)).symm},
328+
{ have h₇ : (gcd a b : ℕ) ∣ (gcd_z a b) * a := dvd_trans (nat.gcd_dvd_left a b) (dvd_mul_left _ _),
329+
have h₈ : (gcd a b : ℕ) ∣ (gcd_x a b) * b := dvd_trans (nat.gcd_dvd_right a b) (dvd_mul_left _ _),
330+
rw[h₅] at h₇, rw dvd_iff,
331+
exact (nat.dvd_add_iff_right h₈).mpr h₇,}
336332
end
337333

338334
theorem gcd_det_eq :

0 commit comments

Comments
 (0)