Module docstring
{"# Divisibility in groups with zero.
Lemmas about divisibility in groups and monoids with zero.
"}
{"# Divisibility in groups with zero.
Lemmas about divisibility in groups and monoids with zero.
"}
zero_dvd_iff
theorem
: 0 ∣ a ↔ a = 0
/-- Given an element `a` of a commutative semigroup with zero, there exists another element whose
product with zero equals `a` iff `a` equals zero. -/
@[simp]
theorem zero_dvd_iff : 0 ∣ a0 ∣ a ↔ a = 0 :=
⟨eq_zero_of_zero_dvd, fun h => by
rw [h]
exact ⟨0, by simp⟩⟩
dvd_zero
theorem
(a : α) : a ∣ 0
mul_dvd_mul_iff_left
theorem
[CancelMonoidWithZero α] {a b c : α} (ha : a ≠ 0) : a * b ∣ a * c ↔ b ∣ c
/-- Given two elements `b`, `c` of a `CancelMonoidWithZero` and a nonzero element `a`,
`a*b` divides `a*c` iff `b` divides `c`. -/
theorem mul_dvd_mul_iff_left [CancelMonoidWithZero α] {a b c : α} (ha : a ≠ 0) :
a * b ∣ a * ca * b ∣ a * c ↔ b ∣ c :=
exists_congr fun d => by rw [mul_assoc, mul_right_inj' ha]
mul_dvd_mul_iff_right
theorem
[CancelCommMonoidWithZero α] {a b c : α} (hc : c ≠ 0) : a * c ∣ b * c ↔ a ∣ b
/-- Given two elements `a`, `b` of a commutative `CancelMonoidWithZero` and a nonzero
element `c`, `a*c` divides `b*c` iff `a` divides `b`. -/
theorem mul_dvd_mul_iff_right [CancelCommMonoidWithZero α] {a b c : α} (hc : c ≠ 0) :
a * c ∣ b * ca * c ∣ b * c ↔ a ∣ b :=
exists_congr fun d => by rw [mul_right_comm, mul_left_inj' hc]
DvdNotUnit
definition
(a b : α) : Prop
/-- `DvdNotUnit a b` expresses that `a` divides `b` "strictly", i.e. that `b` divided by `a`
is not a unit. -/
def DvdNotUnit (a b : α) : Prop :=
a ≠ 0a ≠ 0 ∧ ∃ x, ¬IsUnit x ∧ b = a * x
dvdNotUnit_of_dvd_of_not_dvd
theorem
{a b : α} (hd : a ∣ b) (hnd : ¬b ∣ a) : DvdNotUnit a b
theorem dvdNotUnit_of_dvd_of_not_dvd {a b : α} (hd : a ∣ b) (hnd : ¬b ∣ a) : DvdNotUnit a b := by
constructor
· rintro rfl
exact hnd (dvd_zero _)
· rcases hd with ⟨c, rfl⟩
refine ⟨c, ?_, rfl⟩
rintro ⟨u, rfl⟩
simp at hnd
isRelPrime_zero_left
theorem
: IsRelPrime 0 x ↔ IsUnit x
theorem isRelPrime_zero_left : IsRelPrimeIsRelPrime 0 x ↔ IsUnit x :=
⟨(· (dvd_zero _) dvd_rfl), IsUnit.isRelPrime_right⟩
isRelPrime_zero_right
theorem
: IsRelPrime x 0 ↔ IsUnit x
theorem isRelPrime_zero_right : IsRelPrimeIsRelPrime x 0 ↔ IsUnit x :=
isRelPrime_comm.trans isRelPrime_zero_left
not_isRelPrime_zero_zero
theorem
[Nontrivial α] : ¬IsRelPrime (0 : α) 0
theorem not_isRelPrime_zero_zero [Nontrivial α] : ¬IsRelPrime (0 : α) 0 :=
mt isRelPrime_zero_right.mp not_isUnit_zero
IsRelPrime.ne_zero_or_ne_zero
theorem
[Nontrivial α] (h : IsRelPrime x y) : x ≠ 0 ∨ y ≠ 0
theorem IsRelPrime.ne_zero_or_ne_zero [Nontrivial α] (h : IsRelPrime x y) : x ≠ 0x ≠ 0 ∨ y ≠ 0 :=
not_or_of_imp <| by rintro rfl rfl; exact not_isRelPrime_zero_zero h
isRelPrime_of_no_nonunits_factors
theorem
[MonoidWithZero α] {x y : α} (nonzero : ¬(x = 0 ∧ y = 0)) (H : ∀ z, ¬IsUnit z → z ≠ 0 → z ∣ x → ¬z ∣ y) :
IsRelPrime x y
theorem isRelPrime_of_no_nonunits_factors [MonoidWithZero α] {x y : α} (nonzero : ¬(x = 0 ∧ y = 0))
(H : ∀ z, ¬ IsUnit z → z ≠ 0 → z ∣ x → ¬z ∣ y) : IsRelPrime x y := by
refine fun z hx hy ↦ by_contra fun h ↦ H z h ?_ hx hy
rintro rfl; exact nonzero ⟨zero_dvd_iff.1 hx, zero_dvd_iff.1 hy⟩
dvd_and_not_dvd_iff
theorem
[CancelCommMonoidWithZero α] {x y : α} : x ∣ y ∧ ¬y ∣ x ↔ DvdNotUnit x y
theorem dvd_and_not_dvd_iff [CancelCommMonoidWithZero α] {x y : α} :
x ∣ yx ∣ y ∧ ¬y ∣ xx ∣ y ∧ ¬y ∣ x ↔ DvdNotUnit x y :=
⟨fun ⟨⟨d, hd⟩, hyx⟩ =>
⟨fun hx0 => by simp [hx0] at hyx,
⟨d, mt isUnit_iff_dvd_one.1 fun ⟨e, he⟩ => hyx ⟨e, by rw [hd, mul_assoc, ← he, mul_one]⟩,
hd⟩⟩,
fun ⟨hx0, d, hdu, hdx⟩ =>
⟨⟨d, hdx⟩, fun ⟨e, he⟩ =>
hdu
(isUnit_of_dvd_one
⟨e, mul_left_cancel₀ hx0 <| by conv =>
lhs
rw [he, hdx]
simp [mul_assoc]⟩)⟩⟩
ne_zero_of_dvd_ne_zero
theorem
{p q : α} (h₁ : q ≠ 0) (h₂ : p ∣ q) : p ≠ 0
theorem ne_zero_of_dvd_ne_zero {p q : α} (h₁ : q ≠ 0) (h₂ : p ∣ q) : p ≠ 0 := by
rcases h₂ with ⟨u, rfl⟩
exact left_ne_zero_of_mul h₁
isPrimal_zero
theorem
: IsPrimal (0 : α)
theorem isPrimal_zero : IsPrimal (0 : α) :=
fun a b h ↦ ⟨a, b, dvd_rfl, dvd_rfl, (zero_dvd_iff.mp h).symm⟩
IsPrimal.mul
theorem
{α} [CancelCommMonoidWithZero α] {m n : α} (hm : IsPrimal m) (hn : IsPrimal n) : IsPrimal (m * n)
theorem IsPrimal.mul {α} [CancelCommMonoidWithZero α] {m n : α}
(hm : IsPrimal m) (hn : IsPrimal n) : IsPrimal (m * n) := by
obtain rfl | h0 := eq_or_ne m 0; · rwa [zero_mul]
intro b c h
obtain ⟨a₁, a₂, ⟨b, rfl⟩, ⟨c, rfl⟩, rfl⟩ := hm (dvd_of_mul_right_dvd h)
rw [mul_mul_mul_comm, mul_dvd_mul_iff_left h0] at h
obtain ⟨a₁', a₂', h₁, h₂, rfl⟩ := hn h
exact ⟨a₁ * a₁', a₂ * a₂', mul_dvd_mul_left _ h₁, mul_dvd_mul_left _ h₂, mul_mul_mul_comm _ _ _ _⟩
dvd_antisymm
theorem
: a ∣ b → b ∣ a → a = b
theorem dvd_antisymm : a ∣ b → b ∣ a → a = b := by
rintro ⟨c, rfl⟩ ⟨d, hcd⟩
rw [mul_assoc, eq_comm, mul_right_eq_self₀, mul_eq_one] at hcd
obtain ⟨rfl, -⟩ | rfl := hcd <;> simp
dvd_antisymm'
theorem
: a ∣ b → b ∣ a → b = a
theorem dvd_antisymm' : a ∣ b → b ∣ a → b = a :=
flip dvd_antisymm
pow_dvd_pow_iff
theorem
(ha₀ : a ≠ 0) (ha : ¬IsUnit a) : a ^ n ∣ a ^ m ↔ n ≤ m
lemma pow_dvd_pow_iff (ha₀ : a ≠ 0) (ha : ¬IsUnit a) : a ^ n ∣ a ^ ma ^ n ∣ a ^ m ↔ n ≤ m := by
constructor
· intro h
rw [← not_lt]
intro hmn
apply ha
have : a ^ m * a ∣ a ^ m * 1 := by
rw [← pow_succ, mul_one]
exact (pow_dvd_pow _ (Nat.succ_le_of_lt hmn)).trans h
rwa [mul_dvd_mul_iff_left, ← isUnit_iff_dvd_one] at this
apply pow_ne_zero m ha₀
· apply pow_dvd_pow
GroupWithZero.dvd_iff
theorem
{m n : α} : m ∣ n ↔ (m = 0 → n = 0)
/-- `∣` is not a useful definition if an inverse is available. -/
@[simp]
lemma GroupWithZero.dvd_iff {m n : α} : m ∣ nm ∣ n ↔ (m = 0 → n = 0) := by
refine ⟨fun ⟨a, ha⟩ hm => ?_, fun h => ?_⟩
· simp [hm, ha]
· refine ⟨m⁻¹ * n, ?_⟩
obtain rfl | hn := eq_or_ne n 0
· simp
· rw [mul_inv_cancel_left₀ (mt h hn)]