Module docstring
{"# Lemmas about units in a MonoidWithZero or a GroupWithZero.
We also define Ring.inverse, a globally defined function on any ring
(in fact any MonoidWithZero), which inverts units and sends non-units to zero.
"}
{"# Lemmas about units in a MonoidWithZero or a GroupWithZero.
We also define Ring.inverse, a globally defined function on any ring
(in fact any MonoidWithZero), which inverts units and sends non-units to zero.
"}
Units.ne_zero
theorem
[Nontrivial M₀] (u : M₀ˣ) : (u : M₀) ≠ 0
/-- An element of the unit group of a nonzero monoid with zero represented as an element
of the monoid is nonzero. -/
@[simp]
theorem ne_zero [Nontrivial M₀] (u : M₀ˣ) : (u : M₀) ≠ 0 :=
left_ne_zero_of_mul_eq_one u.mul_inv
Units.mul_left_eq_zero
theorem
(u : M₀ˣ) {a : M₀} : a * u = 0 ↔ a = 0
@[simp]
theorem mul_left_eq_zero (u : M₀ˣ) {a : M₀} : a * u = 0 ↔ a = 0 :=
⟨fun h => by simpa using mul_eq_zero_of_left h ↑u⁻¹, fun h => mul_eq_zero_of_left h u⟩
Units.mul_right_eq_zero
theorem
(u : M₀ˣ) {a : M₀} : ↑u * a = 0 ↔ a = 0
@[simp]
theorem mul_right_eq_zero (u : M₀ˣ) {a : M₀} : ↑u * a = 0 ↔ a = 0 :=
⟨fun h => by simpa using mul_eq_zero_of_right (↑u⁻¹) h, mul_eq_zero_of_right (u : M₀)⟩
IsUnit.ne_zero
theorem
[Nontrivial M₀] {a : M₀} (ha : IsUnit a) : a ≠ 0
theorem ne_zero [Nontrivial M₀] {a : M₀} (ha : IsUnit a) : a ≠ 0 :=
let ⟨u, hu⟩ := ha
hu ▸ u.ne_zero
IsUnit.mul_right_eq_zero
theorem
{a b : M₀} (ha : IsUnit a) : a * b = 0 ↔ b = 0
theorem mul_right_eq_zero {a b : M₀} (ha : IsUnit a) : a * b = 0 ↔ b = 0 :=
let ⟨u, hu⟩ := ha
hu ▸ u.mul_right_eq_zero
IsUnit.mul_left_eq_zero
theorem
{a b : M₀} (hb : IsUnit b) : a * b = 0 ↔ a = 0
theorem mul_left_eq_zero {a b : M₀} (hb : IsUnit b) : a * b = 0 ↔ a = 0 :=
let ⟨u, hu⟩ := hb
hu ▸ u.mul_left_eq_zero
isUnit_zero_iff
theorem
: IsUnit (0 : M₀) ↔ (0 : M₀) = 1
not_isUnit_zero
theorem
[Nontrivial M₀] : ¬IsUnit (0 : M₀)
theorem not_isUnit_zero [Nontrivial M₀] : ¬IsUnit (0 : M₀) :=
mt isUnit_zero_iff.1 zero_ne_one
Ring.inverse
definition
: M₀ → M₀
/-- Introduce a function `inverse` on a monoid with zero `M₀`, which sends `x` to `x⁻¹` if `x` is
invertible and to `0` otherwise. This definition is somewhat ad hoc, but one needs a fully (rather
than partially) defined inverse function for some purposes, including for calculus.
Note that while this is in the `Ring` namespace for brevity, it requires the weaker assumption
`MonoidWithZero M₀` instead of `Ring M₀`. -/
noncomputable def inverse : M₀ → M₀ := fun x => if h : IsUnit x then ((h.unit⁻¹ : M₀ˣ) : M₀) else 0
Ring.inverse_unit
theorem
(u : M₀ˣ) : inverse (u : M₀) = (u⁻¹ : M₀ˣ)
/-- By definition, if `x` is invertible then `inverse x = x⁻¹`. -/
@[simp]
theorem inverse_unit (u : M₀ˣ) : inverse (u : M₀) = (u⁻¹ : M₀ˣ) := by
rw [inverse, dif_pos u.isUnit, IsUnit.unit_of_val_units]
Ring.inverse_of_isUnit
theorem
{x : M₀} (h : IsUnit x) : inverse x = ((h.unit⁻¹ : M₀ˣ) : M₀)
Ring.inverse_non_unit
theorem
(x : M₀) (h : ¬IsUnit x) : inverse x = 0
/-- By definition, if `x` is not invertible then `inverse x = 0`. -/
@[simp]
theorem inverse_non_unit (x : M₀) (h : ¬IsUnit x) : inverse x = 0 :=
dif_neg h
Ring.mul_inverse_cancel
theorem
(x : M₀) (h : IsUnit x) : x * inverse x = 1
theorem mul_inverse_cancel (x : M₀) (h : IsUnit x) : x * inverse x = 1 := by
rcases h with ⟨u, rfl⟩
rw [inverse_unit, Units.mul_inv]
Ring.inverse_mul_cancel
theorem
(x : M₀) (h : IsUnit x) : inverse x * x = 1
theorem inverse_mul_cancel (x : M₀) (h : IsUnit x) : inverse x * x = 1 := by
rcases h with ⟨u, rfl⟩
rw [inverse_unit, Units.inv_mul]
Ring.mul_inverse_cancel_right
theorem
(x y : M₀) (h : IsUnit x) : y * x * inverse x = y
theorem mul_inverse_cancel_right (x y : M₀) (h : IsUnit x) : y * x * inverse x = y := by
rw [mul_assoc, mul_inverse_cancel x h, mul_one]
Ring.inverse_mul_cancel_right
theorem
(x y : M₀) (h : IsUnit x) : y * inverse x * x = y
theorem inverse_mul_cancel_right (x y : M₀) (h : IsUnit x) : y * inverse x * x = y := by
rw [mul_assoc, inverse_mul_cancel x h, mul_one]
Ring.mul_inverse_cancel_left
theorem
(x y : M₀) (h : IsUnit x) : x * (inverse x * y) = y
theorem mul_inverse_cancel_left (x y : M₀) (h : IsUnit x) : x * (inverse x * y) = y := by
rw [← mul_assoc, mul_inverse_cancel x h, one_mul]
Ring.inverse_mul_cancel_left
theorem
(x y : M₀) (h : IsUnit x) : inverse x * (x * y) = y
theorem inverse_mul_cancel_left (x y : M₀) (h : IsUnit x) : inverse x * (x * y) = y := by
rw [← mul_assoc, inverse_mul_cancel x h, one_mul]
Ring.inverse_mul_eq_iff_eq_mul
theorem
(x y z : M₀) (h : IsUnit x) : inverse x * y = z ↔ y = x * z
theorem inverse_mul_eq_iff_eq_mul (x y z : M₀) (h : IsUnit x) : inverseinverse x * y = z ↔ y = x * z :=
⟨fun h1 => by rw [← h1, mul_inverse_cancel_left _ _ h],
fun h1 => by rw [h1, inverse_mul_cancel_left _ _ h]⟩
Ring.inverse_one
theorem
: inverse (1 : M₀) = 1
@[simp]
theorem inverse_one : inverse (1 : M₀) = 1 :=
inverse_unit 1
Ring.inverse_zero
theorem
: inverse (0 : M₀) = 0
@[simp]
theorem inverse_zero : inverse (0 : M₀) = 0 := by
nontriviality
exact inverse_non_unit _ not_isUnit_zero
IsUnit.ringInverse
theorem
{a : M₀} : IsUnit a → IsUnit (Ring.inverse a)
theorem IsUnit.ringInverse {a : M₀} : IsUnit a → IsUnit (Ring.inverse a)
| ⟨u, hu⟩ => hu ▸ ⟨u⁻¹, (Ring.inverse_unit u).symm⟩
isUnit_ringInverse
theorem
{a : M₀} : IsUnit (Ring.inverse a) ↔ IsUnit a
Units.mk0
definition
(a : G₀) (ha : a ≠ 0) : G₀ˣ
/-- Embed a non-zero element of a `GroupWithZero` into the unit group.
By combining this function with the operations on units,
or the `/ₚ` operation, it is possible to write a division
as a partial function with three arguments. -/
def mk0 (a : G₀) (ha : a ≠ 0) : G₀ˣ :=
⟨a, a⁻¹, mul_inv_cancel₀ ha, inv_mul_cancel₀ ha⟩
Units.val_mk0
theorem
{a : G₀} (h : a ≠ 0) : (mk0 a h : G₀) = a
Units.mk0_val
theorem
(u : G₀ˣ) (h : (u : G₀) ≠ 0) : mk0 (u : G₀) h = u
Units.mul_inv'
theorem
(u : G₀ˣ) : u * (u : G₀)⁻¹ = 1
theorem mul_inv' (u : G₀ˣ) : u * (u : G₀)⁻¹ = 1 :=
mul_inv_cancel₀ u.ne_zero
Units.inv_mul'
theorem
(u : G₀ˣ) : (u⁻¹ : G₀) * u = 1
theorem inv_mul' (u : G₀ˣ) : (u⁻¹ : G₀) * u = 1 :=
inv_mul_cancel₀ u.ne_zero
Units.mk0_inj
theorem
{a b : G₀} (ha : a ≠ 0) (hb : b ≠ 0) : Units.mk0 a ha = Units.mk0 b hb ↔ a = b
@[simp]
theorem mk0_inj {a b : G₀} (ha : a ≠ 0) (hb : b ≠ 0) : Units.mk0Units.mk0 a ha = Units.mk0 b hb ↔ a = b :=
⟨fun h => by injection h, fun h => Units.ext h⟩
Units.exists0
theorem
{p : G₀ˣ → Prop} : (∃ g : G₀ˣ, p g) ↔ ∃ (g : G₀) (hg : g ≠ 0), p (Units.mk0 g hg)
/-- In a group with zero, an existential over a unit can be rewritten in terms of `Units.mk0`. -/
theorem exists0 {p : G₀ˣ → Prop} : (∃ g : G₀ˣ, p g) ↔ ∃ (g : G₀) (hg : g ≠ 0), p (Units.mk0 g hg) :=
⟨fun ⟨g, pg⟩ => ⟨g, g.ne_zero, (g.mk0_val g.ne_zero).symm ▸ pg⟩,
fun ⟨g, hg, pg⟩ => ⟨Units.mk0 g hg, pg⟩⟩
Units.exists0'
theorem
{p : ∀ g : G₀, g ≠ 0 → Prop} : (∃ (g : G₀) (hg : g ≠ 0), p g hg) ↔ ∃ g : G₀ˣ, p g g.ne_zero
/-- An alternative version of `Units.exists0`. This one is useful if Lean cannot
figure out `p` when using `Units.exists0` from right to left. -/
theorem exists0' {p : ∀ g : G₀, g ≠ 0 → Prop} :
(∃ (g : G₀) (hg : g ≠ 0), p g hg) ↔ ∃ g : G₀ˣ, p g g.ne_zero :=
Iff.trans (by simp_rw [val_mk0]) exists0.symm
Units.exists_iff_ne_zero
theorem
{p : G₀ → Prop} : (∃ u : G₀ˣ, p u) ↔ ∃ x ≠ 0, p x
@[simp]
theorem exists_iff_ne_zero {p : G₀ → Prop} : (∃ u : G₀ˣ, p u) ↔ ∃ x ≠ 0, p x := by
simp [exists0]
IsUnit.mk0
theorem
(x : G₀) (hx : x ≠ 0) : IsUnit x
theorem IsUnit.mk0 (x : G₀) (hx : x ≠ 0) : IsUnit x :=
(Units.mk0 x hx).isUnit
isUnit_iff_ne_zero
theorem
: IsUnit a ↔ a ≠ 0
@[simp]
theorem isUnit_iff_ne_zero : IsUnitIsUnit a ↔ a ≠ 0 :=
(Units.exists_iff_ne_zero (p := (· = a))).trans (by simp)
GroupWithZero.noZeroDivisors
instance
: NoZeroDivisors G₀
instance (priority := 10) GroupWithZero.noZeroDivisors : NoZeroDivisors G₀ :=
{ (‹_› : GroupWithZero G₀) with
eq_zero_or_eq_zero_of_mul_eq_zero := @fun a b h => by
contrapose! h
exact (Units.mk0 a h.1 * Units.mk0 b h.2).ne_zero }
Units.mk0_mul
theorem
(x y : G₀) (hxy) :
Units.mk0 (x * y) hxy = Units.mk0 x (mul_ne_zero_iff.mp hxy).1 * Units.mk0 y (mul_ne_zero_iff.mp hxy).2
@[simp]
theorem Units.mk0_mul (x y : G₀) (hxy) :
Units.mk0 (x * y) hxy =
Units.mk0 x (mul_ne_zero_iff.mp hxy).1 * Units.mk0 y (mul_ne_zero_iff.mp hxy).2 := by
ext; rfl
div_ne_zero
theorem
(ha : a ≠ 0) (hb : b ≠ 0) : a / b ≠ 0
theorem div_ne_zero (ha : a ≠ 0) (hb : b ≠ 0) : a / b ≠ 0 := by
rw [div_eq_mul_inv]
exact mul_ne_zero ha (inv_ne_zero hb)
div_eq_zero_iff
theorem
: a / b = 0 ↔ a = 0 ∨ b = 0
@[simp]
theorem div_eq_zero_iff : a / b = 0 ↔ a = 0 ∨ b = 0 := by simp [div_eq_mul_inv]
div_ne_zero_iff
theorem
: a / b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0
theorem div_ne_zero_iff : a / b ≠ 0a / b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 :=
div_eq_zero_iff.not.trans not_or
div_self
theorem
(h : a ≠ 0) : a / a = 1
inv_mul_eq_iff_eq_mul₀
theorem
(ha : a ≠ 0) : a⁻¹ * b = c ↔ b = a * c
lemma inv_mul_eq_iff_eq_mul₀ (ha : a ≠ 0) : a⁻¹a⁻¹ * b = c ↔ b = a * c :=
ha.isUnit.inv_mul_eq_iff_eq_mul
mul_inv_eq_iff_eq_mul₀
theorem
(hb : b ≠ 0) : a * b⁻¹ = c ↔ a = c * b
lemma mul_inv_eq_iff_eq_mul₀ (hb : b ≠ 0) : a * b⁻¹ = c ↔ a = c * b :=
hb.isUnit.mul_inv_eq_iff_eq_mul
mul_inv_eq_one₀
theorem
(hb : b ≠ 0) : a * b⁻¹ = 1 ↔ a = b
lemma mul_inv_eq_one₀ (hb : b ≠ 0) : a * b⁻¹ = 1 ↔ a = b := hb.isUnit.mul_inv_eq_one
inv_mul_eq_one₀
theorem
(ha : a ≠ 0) : a⁻¹ * b = 1 ↔ a = b
lemma inv_mul_eq_one₀ (ha : a ≠ 0) : a⁻¹a⁻¹ * b = 1 ↔ a = b := ha.isUnit.inv_mul_eq_one
mul_eq_one_iff_eq_inv₀
theorem
(hb : b ≠ 0) : a * b = 1 ↔ a = b⁻¹
lemma mul_eq_one_iff_eq_inv₀ (hb : b ≠ 0) : a * b = 1 ↔ a = b⁻¹ := hb.isUnit.mul_eq_one_iff_eq_inv
mul_eq_one_iff_inv_eq₀
theorem
(ha : a ≠ 0) : a * b = 1 ↔ a⁻¹ = b
lemma mul_eq_one_iff_inv_eq₀ (ha : a ≠ 0) : a * b = 1 ↔ a⁻¹ = b := ha.isUnit.mul_eq_one_iff_inv_eq
mul_eq_of_eq_mul_inv₀
theorem
(ha : a ≠ 0) (h : a = c * b⁻¹) : a * b = c
/-- A variant of `eq_mul_inv_iff_mul_eq₀` that moves the nonzero hypothesis to another variable. -/
lemma mul_eq_of_eq_mul_inv₀ (ha : a ≠ 0) (h : a = c * b⁻¹) : a * b = c := by
rwa [← eq_mul_inv_iff_mul_eq₀]; rintro rfl; simp [ha] at h
mul_eq_of_eq_inv_mul₀
theorem
(hb : b ≠ 0) (h : b = a⁻¹ * c) : a * b = c
/-- A variant of `eq_inv_mul_iff_mul_eq₀` that moves the nonzero hypothesis to another variable. -/
lemma mul_eq_of_eq_inv_mul₀ (hb : b ≠ 0) (h : b = a⁻¹ * c) : a * b = c := by
rwa [← eq_inv_mul_iff_mul_eq₀]; rintro rfl; simp [hb] at h
div_mul_cancel₀
theorem
(a : G₀) (h : b ≠ 0) : a / b * b = a
@[simp] lemma div_mul_cancel₀ (a : G₀) (h : b ≠ 0) : a / b * b = a := h.isUnit.div_mul_cancel _
mul_one_div_cancel
theorem
(h : a ≠ 0) : a * (1 / a) = 1
lemma mul_one_div_cancel (h : a ≠ 0) : a * (1 / a) = 1 := h.isUnit.mul_one_div_cancel
one_div_mul_cancel
theorem
(h : a ≠ 0) : 1 / a * a = 1
lemma one_div_mul_cancel (h : a ≠ 0) : 1 / a * a = 1 := h.isUnit.one_div_mul_cancel
div_left_inj'
theorem
(hc : c ≠ 0) : a / c = b / c ↔ a = b
lemma div_left_inj' (hc : c ≠ 0) : a / c = b / c ↔ a = b := hc.isUnit.div_left_inj
div_eq_iff
theorem
(hb : b ≠ 0) : a / b = c ↔ a = c * b
@[field_simps] lemma div_eq_iff (hb : b ≠ 0) : a / b = c ↔ a = c * b := hb.isUnit.div_eq_iff
div_eq_iff_mul_eq
theorem
(hb : b ≠ 0) : a / b = c ↔ c * b = a
lemma div_eq_iff_mul_eq (hb : b ≠ 0) : a / b = c ↔ c * b = a := hb.isUnit.div_eq_iff.trans eq_comm
div_eq_of_eq_mul
theorem
(hb : b ≠ 0) : a = c * b → a / b = c
lemma div_eq_of_eq_mul (hb : b ≠ 0) : a = c * b → a / b = c := hb.isUnit.div_eq_of_eq_mul
div_eq_one_iff_eq
theorem
(hb : b ≠ 0) : a / b = 1 ↔ a = b
lemma div_eq_one_iff_eq (hb : b ≠ 0) : a / b = 1 ↔ a = b := hb.isUnit.div_eq_one_iff_eq
div_mul_cancel_right₀
theorem
(hb : b ≠ 0) (a : G₀) : b / (a * b) = a⁻¹
lemma div_mul_cancel_right₀ (hb : b ≠ 0) (a : G₀) : b / (a * b) = a⁻¹ :=
hb.isUnit.div_mul_cancel_right _
mul_div_mul_right
theorem
(a b : G₀) (hc : c ≠ 0) : a * c / (b * c) = a / b
lemma mul_div_mul_right (a b : G₀) (hc : c ≠ 0) : a * c / (b * c) = a / b :=
hc.isUnit.mul_div_mul_right _ _
mul_mul_div
theorem
(a : G₀) (hb : b ≠ 0) : a = a * b * (1 / b)
lemma mul_mul_div (a : G₀) (hb : b ≠ 0) : a = a * b * (1 / b) := (hb.isUnit.mul_mul_div _).symm
div_div_div_cancel_right₀
theorem
(hc : c ≠ 0) (a b : G₀) : a / c / (b / c) = a / b
lemma div_div_div_cancel_right₀ (hc : c ≠ 0) (a b : G₀) : a / c / (b / c) = a / b := by
rw [div_div_eq_mul_div, div_mul_cancel₀ _ hc]
div_mul_div_cancel₀
theorem
(hb : b ≠ 0) : a / b * (b / c) = a / c
lemma div_mul_div_cancel₀ (hb : b ≠ 0) : a / b * (b / c) = a / c := by
rw [← mul_div_assoc, div_mul_cancel₀ _ hb]
div_mul_cancel_of_imp
theorem
(h : b = 0 → a = 0) : a / b * b = a
lemma div_mul_cancel_of_imp (h : b = 0 → a = 0) : a / b * b = a := by
obtain rfl | hb := eq_or_ne b 0 <;> simp [*]
mul_div_cancel_of_imp
theorem
(h : b = 0 → a = 0) : a * b / b = a
lemma mul_div_cancel_of_imp (h : b = 0 → a = 0) : a * b / b = a := by
obtain rfl | hb := eq_or_ne b 0 <;> simp [*]
divp_mk0
theorem
(a : G₀) (hb : b ≠ 0) : a /ₚ Units.mk0 b hb = a / b
@[simp] lemma divp_mk0 (a : G₀) (hb : b ≠ 0) : a /ₚ Units.mk0 b hb = a / b := divp_eq_div _ _
pow_sub₀
theorem
(a : G₀) (ha : a ≠ 0) (h : n ≤ m) : a ^ (m - n) = a ^ m * (a ^ n)⁻¹
lemma pow_sub₀ (a : G₀) (ha : a ≠ 0) (h : n ≤ m) : a ^ (m - n) = a ^ m * (a ^ n)⁻¹ := by
have h1 : m - n + n = m := Nat.sub_add_cancel h
have h2 : a ^ (m - n) * a ^ n = a ^ m := by rw [← pow_add, h1]
simpa only [div_eq_mul_inv] using eq_div_of_mul_eq (pow_ne_zero _ ha) h2
pow_sub_of_lt
theorem
(a : G₀) (h : n < m) : a ^ (m - n) = a ^ m * (a ^ n)⁻¹
lemma pow_sub_of_lt (a : G₀) (h : n < m) : a ^ (m - n) = a ^ m * (a ^ n)⁻¹ := by
obtain rfl | ha := eq_or_ne a 0
· rw [zero_pow (Nat.ne_of_gt <| Nat.sub_pos_of_lt h), zero_pow (by omega), zero_mul]
· exact pow_sub₀ _ ha <| Nat.le_of_lt h
inv_pow_sub₀
theorem
(ha : a ≠ 0) (h : n ≤ m) : a⁻¹ ^ (m - n) = (a ^ m)⁻¹ * a ^ n
lemma inv_pow_sub₀ (ha : a ≠ 0) (h : n ≤ m) : a⁻¹ ^ (m - n) = (a ^ m)⁻¹ * a ^ n := by
rw [pow_sub₀ _ (inv_ne_zero ha) h, inv_pow, inv_pow, inv_inv]
inv_pow_sub_of_lt
theorem
(a : G₀) (h : n < m) : a⁻¹ ^ (m - n) = (a ^ m)⁻¹ * a ^ n
lemma inv_pow_sub_of_lt (a : G₀) (h : n < m) : a⁻¹ ^ (m - n) = (a ^ m)⁻¹ * a ^ n := by
rw [pow_sub_of_lt a⁻¹ h, inv_pow, inv_pow, inv_inv]
zpow_sub₀
theorem
(ha : a ≠ 0) (m n : ℤ) : a ^ (m - n) = a ^ m / a ^ n
lemma zpow_sub₀ (ha : a ≠ 0) (m n : ℤ) : a ^ (m - n) = a ^ m / a ^ n := by
rw [Int.sub_eq_add_neg, zpow_add₀ ha, zpow_neg, div_eq_mul_inv]
zpow_natCast_sub_natCast₀
theorem
(ha : a ≠ 0) (m n : ℕ) : a ^ (m - n : ℤ) = a ^ m / a ^ n
lemma zpow_natCast_sub_natCast₀ (ha : a ≠ 0) (m n : ℕ) : a ^ (m - n : ℤ) = a ^ m / a ^ n := by
simpa using zpow_sub₀ ha m n
zpow_natCast_sub_one₀
theorem
(ha : a ≠ 0) (n : ℕ) : a ^ (n - 1 : ℤ) = a ^ n / a
lemma zpow_natCast_sub_one₀ (ha : a ≠ 0) (n : ℕ) : a ^ (n - 1 : ℤ) = a ^ n / a := by
simpa using zpow_sub₀ ha n 1
zpow_one_sub_natCast₀
theorem
(ha : a ≠ 0) (n : ℕ) : a ^ (1 - n : ℤ) = a / a ^ n
lemma zpow_one_sub_natCast₀ (ha : a ≠ 0) (n : ℕ) : a ^ (1 - n : ℤ) = a / a ^ n := by
simpa using zpow_sub₀ ha 1 n
zpow_ne_zero
theorem
{a : G₀} : ∀ n : ℤ, a ≠ 0 → a ^ n ≠ 0
lemma zpow_ne_zero {a : G₀} : ∀ n : ℤ, a ≠ 0 → a ^ n ≠ 0
| (_ : ℕ) => by rw [zpow_natCast]; exact pow_ne_zero _
| .negSucc n => fun ha ↦ by rw [zpow_negSucc]; exact inv_ne_zero (pow_ne_zero _ ha)
zpow_eq_zero_iff
theorem
{n : ℤ} (hn : n ≠ 0) : a ^ n = 0 ↔ a = 0
lemma zpow_eq_zero_iff {n : ℤ} (hn : n ≠ 0) : a ^ n = 0 ↔ a = 0 :=
⟨eq_zero_of_zpow_eq_zero, fun ha => ha.symm ▸ zero_zpow _ hn⟩
zpow_ne_zero_iff
theorem
{n : ℤ} (hn : n ≠ 0) : a ^ n ≠ 0 ↔ a ≠ 0
lemma zpow_ne_zero_iff {n : ℤ} (hn : n ≠ 0) : a ^ n ≠ 0a ^ n ≠ 0 ↔ a ≠ 0 := (zpow_eq_zero_iff hn).ne
zpow_neg_mul_zpow_self
theorem
(n : ℤ) (ha : a ≠ 0) : a ^ (-n) * a ^ n = 1
lemma zpow_neg_mul_zpow_self (n : ℤ) (ha : a ≠ 0) : a ^ (-n) * a ^ n = 1 := by
rw [zpow_neg]; exact inv_mul_cancel₀ (zpow_ne_zero n ha)
Ring.inverse_eq_inv
theorem
(a : G₀) : Ring.inverse a = a⁻¹
theorem Ring.inverse_eq_inv (a : G₀) : Ring.inverse a = a⁻¹ := by
obtain rfl | ha := eq_or_ne a 0
· simp
· exact Ring.inverse_unit (Units.mk0 a ha)
Ring.inverse_eq_inv'
theorem
: (Ring.inverse : G₀ → G₀) = Inv.inv
@[simp]
theorem Ring.inverse_eq_inv' : (Ring.inverse : G₀ → G₀) = Inv.inv :=
funext Ring.inverse_eq_inv
CommGroupWithZero.toCancelCommMonoidWithZero
instance
: CancelCommMonoidWithZero G₀
instance (priority := 10) CommGroupWithZero.toCancelCommMonoidWithZero :
CancelCommMonoidWithZero G₀ :=
{ GroupWithZero.toCancelMonoidWithZero,
CommGroupWithZero.toCommMonoidWithZero with }
CommGroupWithZero.toDivisionCommMonoid
instance
: DivisionCommMonoid G₀
instance (priority := 100) CommGroupWithZero.toDivisionCommMonoid :
DivisionCommMonoid G₀ where
__ := ‹CommGroupWithZero G₀›
__ := GroupWithZero.toDivisionMonoid
div_mul_cancel_left₀
theorem
(ha : a ≠ 0) (b : G₀) : a / (a * b) = b⁻¹
lemma div_mul_cancel_left₀ (ha : a ≠ 0) (b : G₀) : a / (a * b) = b⁻¹ :=
ha.isUnit.div_mul_cancel_left _
mul_div_cancel_left_of_imp
theorem
(h : a = 0 → b = 0) : a * b / a = b
lemma mul_div_cancel_left_of_imp (h : a = 0 → b = 0) : a * b / a = b := by
rw [mul_comm, mul_div_cancel_of_imp h]
mul_div_cancel_of_imp'
theorem
(h : b = 0 → a = 0) : b * (a / b) = a
lemma mul_div_cancel_of_imp' (h : b = 0 → a = 0) : b * (a / b) = a := by
rw [mul_comm, div_mul_cancel_of_imp h]
mul_div_cancel₀
theorem
(a : G₀) (hb : b ≠ 0) : b * (a / b) = a
lemma mul_div_cancel₀ (a : G₀) (hb : b ≠ 0) : b * (a / b) = a :=
hb.isUnit.mul_div_cancel _
mul_div_mul_left
theorem
(a b : G₀) (hc : c ≠ 0) : c * a / (c * b) = a / b
lemma mul_div_mul_left (a b : G₀) (hc : c ≠ 0) : c * a / (c * b) = a / b :=
hc.isUnit.mul_div_mul_left _ _
mul_eq_mul_of_div_eq_div
theorem
(a c : G₀) (hb : b ≠ 0) (hd : d ≠ 0) (h : a / b = c / d) : a * d = c * b
lemma mul_eq_mul_of_div_eq_div (a c : G₀) (hb : b ≠ 0) (hd : d ≠ 0)
(h : a / b = c / d) : a * d = c * b := by
rw [← mul_one a, ← div_self hb, ← mul_comm_div, h, div_mul_eq_mul_div, div_mul_cancel₀ _ hd]
div_eq_div_iff
theorem
(hb : b ≠ 0) (hd : d ≠ 0) : a / b = c / d ↔ a * d = c * b
@[field_simps] lemma div_eq_div_iff (hb : b ≠ 0) (hd : d ≠ 0) : a / b = c / d ↔ a * d = c * b :=
hb.isUnit.div_eq_div_iff hd.isUnit
div_eq_div_iff_div_eq_div'
theorem
(hb : b ≠ 0) (hc : c ≠ 0) : a / b = c / d ↔ a / c = b / d
/-- The `CommGroupWithZero` version of `div_eq_div_iff_div_eq_div`. -/
lemma div_eq_div_iff_div_eq_div' (hb : b ≠ 0) (hc : c ≠ 0) : a / b = c / d ↔ a / c = b / d := by
conv_lhs => rw [← mul_left_inj' hb, div_mul_cancel₀ _ hb]
conv_rhs => rw [← mul_left_inj' hc, div_mul_cancel₀ _ hc]
rw [mul_comm _ c, div_mul_eq_mul_div, mul_div_assoc]
div_div_cancel₀
theorem
(ha : a ≠ 0) : a / (a / b) = b
@[simp] lemma div_div_cancel₀ (ha : a ≠ 0) : a / (a / b) = b := ha.isUnit.div_div_cancel
div_div_cancel_left'
theorem
(ha : a ≠ 0) : a / b / a = b⁻¹
lemma div_div_cancel_left' (ha : a ≠ 0) : a / b / a = b⁻¹ := ha.isUnit.div_div_cancel_left
div_helper
theorem
(b : G₀) (h : a ≠ 0) : 1 / (a * b) * a = 1 / b
lemma div_helper (b : G₀) (h : a ≠ 0) : 1 / (a * b) * a = 1 / b := by
rw [div_mul_eq_mul_div, one_mul, div_mul_cancel_left₀ h, one_div]
div_div_div_cancel_left'
theorem
(a b : G₀) (hc : c ≠ 0) : c / a / (c / b) = b / a
lemma div_div_div_cancel_left' (a b : G₀) (hc : c ≠ 0) : c / a / (c / b) = b / a := by
rw [div_div_div_eq, mul_comm, mul_div_mul_right _ _ hc]
div_mul_div_cancel₀'
theorem
(ha : a ≠ 0) (b c : G₀) : a / b * (c / a) = c / b
@[simp] lemma div_mul_div_cancel₀' (ha : a ≠ 0) (b c : G₀) : a / b * (c / a) = c / b := by
rw [mul_comm, div_mul_div_cancel₀ ha]
groupWithZeroOfIsUnitOrEqZero
definition
[hM : MonoidWithZero M] (h : ∀ a : M, IsUnit a ∨ a = 0) : GroupWithZero M
/-- Constructs a `GroupWithZero` structure on a `MonoidWithZero`
consisting only of units and 0. -/
noncomputable def groupWithZeroOfIsUnitOrEqZero [hM : MonoidWithZero M]
(h : ∀ a : M, IsUnitIsUnit a ∨ a = 0) : GroupWithZero M :=
{ hM with
inv := fun a => if h0 : a = 0 then 0 else ↑((h a).resolve_right h0).unit⁻¹,
inv_zero := dif_pos rfl,
mul_inv_cancel := fun a h0 => by
change (a * if h0 : a = 0 then 0 else ↑((h a).resolve_right h0).unit⁻¹) = 1
rw [dif_neg h0, Units.mul_inv_eq_iff_eq_mul, one_mul, IsUnit.unit_spec],
exists_pair_ne := Nontrivial.exists_pair_ne }
commGroupWithZeroOfIsUnitOrEqZero
definition
[hM : CommMonoidWithZero M] (h : ∀ a : M, IsUnit a ∨ a = 0) : CommGroupWithZero M
/-- Constructs a `CommGroupWithZero` structure on a `CommMonoidWithZero`
consisting only of units and 0. -/
noncomputable def commGroupWithZeroOfIsUnitOrEqZero [hM : CommMonoidWithZero M]
(h : ∀ a : M, IsUnitIsUnit a ∨ a = 0) : CommGroupWithZero M :=
{ groupWithZeroOfIsUnitOrEqZero h, hM with }