Module docstring
{"# Typeclasses for groups with an adjoined zero element
This file provides just the typeclass definitions, and the projection lemmas that expose their members.
Main definitions
GroupWithZeroCommGroupWithZero"}
{"# Typeclasses for groups with an adjoined zero element
This file provides just the typeclass definitions, and the projection lemmas that expose their members.
GroupWithZeroCommGroupWithZero
"}MulZeroClass
structure
(M₀ : Type u) extends Mul M₀, Zero M₀
/-- Typeclass for expressing that a type `M₀` with multiplication and a zero satisfies
`0 * a = 0` and `a * 0 = 0` for all `a : M₀`. -/
class MulZeroClass (M₀ : Type u) extends Mul M₀, Zero M₀ where
/-- Zero is a left absorbing element for multiplication -/
zero_mul : ∀ a : M₀, 0 * a = 0
/-- Zero is a right absorbing element for multiplication -/
mul_zero : ∀ a : M₀, a * 0 = 0
IsLeftCancelMulZero
structure
(M₀ : Type u) [Mul M₀] [Zero M₀]
/-- A mixin for left cancellative multiplication by nonzero elements. -/
class IsLeftCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
/-- Multiplication by a nonzero element is left cancellative. -/
protected mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
mul_left_cancel₀
theorem
(ha : a ≠ 0) (h : a * b = a * c) : b = c
theorem mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha h
mul_right_injective₀
theorem
(ha : a ≠ 0) : Function.Injective (a * ·)
theorem mul_right_injective₀ (ha : a ≠ 0) : Function.Injective (a * ·) :=
fun _ _ => mul_left_cancel₀ ha
IsRightCancelMulZero
structure
(M₀ : Type u) [Mul M₀] [Zero M₀]
/-- A mixin for right cancellative multiplication by nonzero elements. -/
class IsRightCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
/-- Multiplicatin by a nonzero element is right cancellative. -/
protected mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
mul_right_cancel₀
theorem
(hb : b ≠ 0) (h : a * b = c * b) : a = c
theorem mul_right_cancel₀ (hb : b ≠ 0) (h : a * b = c * b) : a = c :=
IsRightCancelMulZero.mul_right_cancel_of_ne_zero hb h
mul_left_injective₀
theorem
(hb : b ≠ 0) : Function.Injective fun a => a * b
theorem mul_left_injective₀ (hb : b ≠ 0) : Function.Injective fun a => a * b :=
fun _ _ => mul_right_cancel₀ hb
IsCancelMulZero
structure
(M₀ : Type u) [Mul M₀] [Zero M₀] : Prop
extends IsLeftCancelMulZero M₀, IsRightCancelMulZero M₀
/-- A mixin for cancellative multiplication by nonzero elements. -/
class IsCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop
extends IsLeftCancelMulZero M₀, IsRightCancelMulZero M₀
NoZeroDivisors
structure
(M₀ : Type*) [Mul M₀] [Zero M₀]
/-- Predicate typeclass for expressing that `a * b = 0` implies `a = 0` or `b = 0`
for all `a` and `b` of type `G₀`. -/
class NoZeroDivisors (M₀ : Type*) [Mul M₀] [Zero M₀] : Prop where
/-- For all `a` and `b` of `G₀`, `a * b = 0` implies `a = 0` or `b = 0`. -/
eq_zero_or_eq_zero_of_mul_eq_zero : ∀ {a b : M₀}, a * b = 0 → a = 0 ∨ b = 0
SemigroupWithZero
structure
(S₀ : Type u) extends Semigroup S₀, MulZeroClass S₀
/-- A type `S₀` is a "semigroup with zero” if it is a semigroup with zero element, and `0` is left
and right absorbing. -/
class SemigroupWithZero (S₀ : Type u) extends Semigroup S₀, MulZeroClass S₀
MulZeroOneClass
structure
(M₀ : Type u) extends MulOneClass M₀, MulZeroClass M₀
/-- A typeclass for non-associative monoids with zero elements. -/
class MulZeroOneClass (M₀ : Type u) extends MulOneClass M₀, MulZeroClass M₀
MonoidWithZero
structure
(M₀ : Type u) extends Monoid M₀, MulZeroOneClass M₀, SemigroupWithZero M₀
/-- A type `M₀` is a “monoid with zero” if it is a monoid with zero element, and `0` is left
and right absorbing. -/
class MonoidWithZero (M₀ : Type u) extends Monoid M₀, MulZeroOneClass M₀, SemigroupWithZero M₀
pow_mul_apply_eq_pow_mul
theorem
{M : Type*} [Monoid M] (f : M₀ → M) {x : M₀} (hx : ∀ y : M₀, f (x * y) = f x * f y) (n : ℕ) :
∀ (y : M₀), f (x ^ n * y) = f x ^ n * f y
/-- If `x` is multiplicative with respect to `f`, then so is any `x^n`. -/
theorem pow_mul_apply_eq_pow_mul {M : Type*} [Monoid M] (f : M₀ → M) {x : M₀}
(hx : ∀ y : M₀, f (x * y) = f x * f y) (n : ℕ) :
∀ (y : M₀), f (x ^ n * y) = f x ^ n * f y := by
induction n with
| zero => intro y; rw [pow_zero, pow_zero, one_mul, one_mul]
| succ n hn => intro y; rw [pow_succ', pow_succ', mul_assoc, mul_assoc, hx, hn]
CancelMonoidWithZero
structure
(M₀ : Type*) extends MonoidWithZero M₀, IsCancelMulZero M₀
/-- A type `M` is a `CancelMonoidWithZero` if it is a monoid with zero element, `0` is left
and right absorbing, and left/right multiplication by a non-zero element is injective. -/
class CancelMonoidWithZero (M₀ : Type*) extends MonoidWithZero M₀, IsCancelMulZero M₀
CommMonoidWithZero
structure
(M₀ : Type*) extends CommMonoid M₀, MonoidWithZero M₀
/-- A type `M` is a commutative “monoid with zero” if it is a commutative monoid with zero
element, and `0` is left and right absorbing. -/
class CommMonoidWithZero (M₀ : Type*) extends CommMonoid M₀, MonoidWithZero M₀
mul_left_inj'
theorem
(hc : c ≠ 0) : a * c = b * c ↔ a = b
theorem mul_left_inj' (hc : c ≠ 0) : a * c = b * c ↔ a = b :=
(mul_left_injective₀ hc).eq_iff
mul_right_inj'
theorem
(ha : a ≠ 0) : a * b = a * c ↔ b = c
theorem mul_right_inj' (ha : a ≠ 0) : a * b = a * c ↔ b = c :=
(mul_right_injective₀ ha).eq_iff
IsLeftCancelMulZero.to_isRightCancelMulZero
theorem
[IsLeftCancelMulZero M₀] : IsRightCancelMulZero M₀
lemma IsLeftCancelMulZero.to_isRightCancelMulZero [IsLeftCancelMulZero M₀] :
IsRightCancelMulZero M₀ :=
{ mul_right_cancel_of_ne_zero :=
fun hb h => mul_left_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
IsRightCancelMulZero.to_isLeftCancelMulZero
theorem
[IsRightCancelMulZero M₀] : IsLeftCancelMulZero M₀
lemma IsRightCancelMulZero.to_isLeftCancelMulZero [IsRightCancelMulZero M₀] :
IsLeftCancelMulZero M₀ :=
{ mul_left_cancel_of_ne_zero :=
fun hb h => mul_right_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
IsLeftCancelMulZero.to_isCancelMulZero
theorem
[IsLeftCancelMulZero M₀] : IsCancelMulZero M₀
lemma IsLeftCancelMulZero.to_isCancelMulZero [IsLeftCancelMulZero M₀] :
IsCancelMulZero M₀ :=
{ IsLeftCancelMulZero.to_isRightCancelMulZero with }
IsRightCancelMulZero.to_isCancelMulZero
theorem
[IsRightCancelMulZero M₀] : IsCancelMulZero M₀
lemma IsRightCancelMulZero.to_isCancelMulZero [IsRightCancelMulZero M₀] :
IsCancelMulZero M₀ :=
{ IsRightCancelMulZero.to_isLeftCancelMulZero with }
CancelCommMonoidWithZero
structure
(M₀ : Type*) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
/-- A type `M` is a `CancelCommMonoidWithZero` if it is a commutative monoid with zero element,
`0` is left and right absorbing,
and left/right multiplication by a non-zero element is injective. -/
class CancelCommMonoidWithZero (M₀ : Type*) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
CancelCommMonoidWithZero.toCancelMonoidWithZero
instance
[CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀
instance (priority := 100) CancelCommMonoidWithZero.toCancelMonoidWithZero
[CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀ :=
{ IsLeftCancelMulZero.to_isCancelMulZero (M₀ := M₀) with }
MulDivCancelClass
structure
(M₀ : Type*) [MonoidWithZero M₀] [Div M₀]
/-- Prop-valued mixin for a monoid with zero to be equipped with a cancelling division.
The obvious use case is groups with zero, but this condition is also satisfied by `ℕ`, `ℤ` and, more
generally, any euclidean domain. -/
class MulDivCancelClass (M₀ : Type*) [MonoidWithZero M₀] [Div M₀] : Prop where
protected mul_div_cancel (a b : M₀) : b ≠ 0 → a * b / b = a
mul_div_cancel_right₀
theorem
(a : M₀) {b : M₀} (hb : b ≠ 0) : a * b / b = a
@[simp] lemma mul_div_cancel_right₀ (a : M₀) {b : M₀} (hb : b ≠ 0) : a * b / b = a :=
MulDivCancelClass.mul_div_cancel _ _ hb
mul_div_cancel_left₀
theorem
(b : M₀) {a : M₀} (ha : a ≠ 0) : a * b / a = b
@[simp] lemma mul_div_cancel_left₀ (b : M₀) {a : M₀} (ha : a ≠ 0) : a * b / a = b := by
rw [mul_comm, mul_div_cancel_right₀ _ ha]
GroupWithZero
structure
(G₀ : Type u) extends MonoidWithZero G₀, DivInvMonoid G₀, Nontrivial G₀
/-- A type `G₀` is a “group with zero” if it is a monoid with zero element (distinct from `1`)
such that every nonzero element is invertible.
The type is required to come with an “inverse” function, and the inverse of `0` must be `0`.
Examples include division rings and the ordered monoids that are the
target of valuations in general valuation theory. -/
class GroupWithZero (G₀ : Type u) extends MonoidWithZero G₀, DivInvMonoid G₀, Nontrivial G₀ where
/-- The inverse of `0` in a group with zero is `0`. -/
protected inv_zero : (0 : G₀)⁻¹ = 0
/-- Every nonzero element of a group with zero is invertible. -/
protected mul_inv_cancel (a : G₀) : a ≠ 0 → a * a⁻¹ = 1
inv_zero
theorem
: (0 : G₀)⁻¹ = 0
@[simp] lemma inv_zero : (0 : G₀)⁻¹ = 0 := GroupWithZero.inv_zero
mul_inv_cancel₀
theorem
(h : a ≠ 0) : a * a⁻¹ = 1
@[simp] lemma mul_inv_cancel₀ (h : a ≠ 0) : a * a⁻¹ = 1 := GroupWithZero.mul_inv_cancel a h
GroupWithZero.toMulDivCancelClass
instance
: MulDivCancelClass G₀
instance (priority := 100) GroupWithZero.toMulDivCancelClass : MulDivCancelClass G₀ where
mul_div_cancel a b hb := by rw [div_eq_mul_inv, mul_assoc, mul_inv_cancel₀ hb, mul_one]
CommGroupWithZero
structure
(G₀ : Type*) extends CommMonoidWithZero G₀, GroupWithZero G₀
/-- A type `G₀` is a commutative “group with zero”
if it is a commutative monoid with zero element (distinct from `1`)
such that every nonzero element is invertible.
The type is required to come with an “inverse” function, and the inverse of `0` must be `0`. -/
class CommGroupWithZero (G₀ : Type*) extends CommMonoidWithZero G₀, GroupWithZero G₀
mul_inv_cancel_right₀
theorem
(h : b ≠ 0) (a : G₀) : a * b * b⁻¹ = a
mul_inv_cancel_left₀
theorem
(h : a ≠ 0) (b : G₀) : a * (a⁻¹ * b) = b
mul_eq_zero_of_left
theorem
{a : M₀} (h : a = 0) (b : M₀) : a * b = 0
theorem mul_eq_zero_of_left {a : M₀} (h : a = 0) (b : M₀) : a * b = 0 := h.symm ▸ zero_mul b
mul_eq_zero_of_right
theorem
(a : M₀) {b : M₀} (h : b = 0) : a * b = 0
theorem mul_eq_zero_of_right (a : M₀) {b : M₀} (h : b = 0) : a * b = 0 := h.symm ▸ mul_zero a
mul_eq_zero
theorem
: a * b = 0 ↔ a = 0 ∨ b = 0
/-- If `α` has no zero divisors, then the product of two elements equals zero iff one of them
equals zero. -/
@[simp]
theorem mul_eq_zero : a * b = 0 ↔ a = 0 ∨ b = 0 :=
⟨eq_zero_or_eq_zero_of_mul_eq_zero,
fun o => o.elim (fun h => mul_eq_zero_of_left h b) (mul_eq_zero_of_right a)⟩
zero_eq_mul
theorem
: 0 = a * b ↔ a = 0 ∨ b = 0
/-- If `α` has no zero divisors, then the product of two elements equals zero iff one of them
equals zero. -/
@[simp]
theorem zero_eq_mul : 0 = a * b ↔ a = 0 ∨ b = 0 := by rw [eq_comm, mul_eq_zero]
mul_ne_zero_iff
theorem
: a * b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0
/-- If `α` has no zero divisors, then the product of two elements is nonzero iff both of them
are nonzero. -/
theorem mul_ne_zero_iff : a * b ≠ 0a * b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 := mul_eq_zero.not.trans not_or
mul_eq_zero_comm
theorem
: a * b = 0 ↔ b * a = 0
/-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` equals zero iff so is
`b * a`. -/
theorem mul_eq_zero_comm : a * b = 0 ↔ b * a = 0 :=
mul_eq_zero.trans <| or_comm.trans mul_eq_zero.symm
mul_ne_zero_comm
theorem
: a * b ≠ 0 ↔ b * a ≠ 0
/-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` is nonzero iff so is
`b * a`. -/
theorem mul_ne_zero_comm : a * b ≠ 0a * b ≠ 0 ↔ b * a ≠ 0 := mul_eq_zero_comm.not
mul_self_eq_zero
theorem
: a * a = 0 ↔ a = 0
theorem mul_self_eq_zero : a * a = 0 ↔ a = 0 := by simp
zero_eq_mul_self
theorem
: 0 = a * a ↔ a = 0
theorem zero_eq_mul_self : 0 = a * a ↔ a = 0 := by simp
mul_self_ne_zero
theorem
: a * a ≠ 0 ↔ a ≠ 0
theorem mul_self_ne_zero : a * a ≠ 0a * a ≠ 0 ↔ a ≠ 0 := mul_self_eq_zero.not
zero_ne_mul_self
theorem
: 0 ≠ a * a ↔ a ≠ 0
theorem zero_ne_mul_self : 0 ≠ a * a0 ≠ a * a ↔ a ≠ 0 := zero_eq_mul_self.not
mul_eq_zero_iff_left
theorem
(ha : a ≠ 0) : a * b = 0 ↔ b = 0
theorem mul_eq_zero_iff_left (ha : a ≠ 0) : a * b = 0 ↔ b = 0 := by simp [ha]
mul_eq_zero_iff_right
theorem
(hb : b ≠ 0) : a * b = 0 ↔ a = 0
theorem mul_eq_zero_iff_right (hb : b ≠ 0) : a * b = 0 ↔ a = 0 := by simp [hb]
mul_ne_zero_iff_left
theorem
(ha : a ≠ 0) : a * b ≠ 0 ↔ b ≠ 0
theorem mul_ne_zero_iff_left (ha : a ≠ 0) : a * b ≠ 0a * b ≠ 0 ↔ b ≠ 0 := by simp [ha]
mul_ne_zero_iff_right
theorem
(hb : b ≠ 0) : a * b ≠ 0 ↔ a ≠ 0
theorem mul_ne_zero_iff_right (hb : b ≠ 0) : a * b ≠ 0a * b ≠ 0 ↔ a ≠ 0 := by simp [hb]