mathlib3 documentation

algebra.group.defs

Typeclasses for (semi)groups and monoids #

THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.

In this file we define typeclasses for algebraic structures with one binary operation. The classes are named (add_)?(comm_)?(semigroup|monoid|group), where add_ means that the class uses additive notation and comm_ means that the class assumes that the binary operation is commutative.

The file does not contain any lemmas except for

For basic lemmas about these classes see algebra.group.basic.

We also introduce notation classes has_smul and has_vadd for multiplicative and additive actions and register the following instances:

Notation #

@[class]
structure has_vsub (G : out_param (Type u_1)) (P : Type u_2) :
Type (max u_1 u_2)

Type class for the -ᵥ notation.

Instances of this typeclass
Instances of other typeclasses for has_vsub
  • has_vsub.has_sizeof_inst
theorem has_smul.ext {M : Type u_1} {α : Type u_2} (x y : has_smul M α) (h : has_smul.smul = has_smul.smul) :
x = y
theorem has_smul.ext_iff {M : Type u_1} {α : Type u_2} (x y : has_smul M α) :
@[ext, class]
structure has_smul (M : Type u_1) (α : Type u_2) :
Type (max u_1 u_2)

Typeclass for types with a scalar multiplication operation, denoted (\bu)

Instances of this typeclass
Instances of other typeclasses for has_smul
  • has_smul.has_sizeof_inst
def left_mul {G : Type u_1} [has_mul G] :
G G G

left_mul g denotes left multiplication by g

Equations
def left_add {G : Type u_1} [has_add G] :
G G G

left_add g denotes left addition by g

Equations
def right_add {G : Type u_1} [has_add G] :
G G G

right_add g denotes right addition by g

Equations
def right_mul {G : Type u_1} [has_mul G] :
G G G

right_mul g denotes right multiplication by g

Equations
@[class]
structure is_left_cancel_mul (G : Type u) [has_mul G] :
Prop
  • mul_left_cancel : (a b c : G), a * b = a * c b = c

A mixin for left cancellative multiplication.

Instances of this typeclass
@[class]
structure is_right_cancel_mul (G : Type u) [has_mul G] :
Prop
  • mul_right_cancel : (a b c : G), a * b = c * b a = c

A mixin for right cancellative multiplication.

Instances of this typeclass
@[class]
structure is_cancel_mul (G : Type u) [has_mul G] :
Prop
  • mul_left_cancel : (a b c : G), a * b = a * c b = c
  • mul_right_cancel : (a b c : G), a * b = c * b a = c

A mixin for cancellative multiplication.

Instances of this typeclass
@[class]
structure is_left_cancel_add (G : Type u) [has_add G] :
Prop
  • add_left_cancel : (a b c : G), a + b = a + c b = c

A mixin for left cancellative addition.

Instances of this typeclass
@[class]
structure is_right_cancel_add (G : Type u) [has_add G] :
Prop
  • add_right_cancel : (a b c : G), a + b = c + b a = c

A mixin for right cancellative addition.

Instances of this typeclass
@[class]
structure is_cancel_add (G : Type u) [has_add G] :
Prop
  • add_left_cancel : (a b c : G), a + b = a + c b = c
  • add_right_cancel : (a b c : G), a + b = c + b a = c

A mixin for cancellative addition.

Instances of this typeclass
theorem mul_left_cancel {G : Type u_1} [has_mul G] [is_left_cancel_mul G] {a b c : G} :
a * b = a * c b = c
theorem add_left_cancel {G : Type u_1} [has_add G] [is_left_cancel_add G] {a b c : G} :
a + b = a + c b = c
theorem add_left_cancel_iff {G : Type u_1} [has_add G] [is_left_cancel_add G] {a b c : G} :
a + b = a + c b = c
theorem mul_left_cancel_iff {G : Type u_1} [has_mul G] [is_left_cancel_mul G] {a b c : G} :
a * b = a * c b = c
@[simp]
theorem mul_right_inj {G : Type u_1} [has_mul G] [is_left_cancel_mul G] (a : G) {b c : G} :
a * b = a * c b = c
@[simp]
theorem add_right_inj {G : Type u_1} [has_add G] [is_left_cancel_add G] (a : G) {b c : G} :
a + b = a + c b = c
theorem mul_ne_mul_right {G : Type u_1} [has_mul G] [is_left_cancel_mul G] (a : G) {b c : G} :
a * b a * c b c
theorem add_ne_add_right {G : Type u_1} [has_add G] [is_left_cancel_add G] (a : G) {b c : G} :
a + b a + c b c
theorem mul_right_cancel {G : Type u_1} [has_mul G] [is_right_cancel_mul G] {a b c : G} :
a * b = c * b a = c
theorem add_right_cancel {G : Type u_1} [has_add G] [is_right_cancel_add G] {a b c : G} :
a + b = c + b a = c
theorem mul_right_cancel_iff {G : Type u_1} [has_mul G] [is_right_cancel_mul G] {a b c : G} :
b * a = c * a b = c
theorem add_right_cancel_iff {G : Type u_1} [has_add G] [is_right_cancel_add G] {a b c : G} :
b + a = c + a b = c
theorem add_left_injective {G : Type u_1} [has_add G] [is_right_cancel_add G] (a : G) :
function.injective (λ (x : G), x + a)
theorem mul_left_injective {G : Type u_1} [has_mul G] [is_right_cancel_mul G] (a : G) :
function.injective (λ (x : G), x * a)
@[simp]
theorem add_left_inj {G : Type u_1} [has_add G] [is_right_cancel_add G] (a : G) {b c : G} :
b + a = c + a b = c
@[simp]
theorem mul_left_inj {G : Type u_1} [has_mul G] [is_right_cancel_mul G] (a : G) {b c : G} :
b * a = c * a b = c
theorem mul_ne_mul_left {G : Type u_1} [has_mul G] [is_right_cancel_mul G] (a : G) {b c : G} :
b * a c * a b c
theorem add_ne_add_left {G : Type u_1} [has_add G] [is_right_cancel_add G] (a : G) {b c : G} :
b + a c + a b c
theorem semigroup.ext {G : Type u} (x y : semigroup G) (h : semigroup.mul = semigroup.mul) :
x = y
@[instance]
def semigroup.to_has_mul (G : Type u) [self : semigroup G] :
@[instance]
def add_semigroup.to_has_add (G : Type u) [self : add_semigroup G] :
theorem add_assoc {G : Type u_1} [add_semigroup G] (a b c : G) :
a + b + c = a + (b + c)
theorem mul_assoc {G : Type u_1} [semigroup G] (a b c : G) :
a * b * c = a * (b * c)
@[protected, instance]
@[protected, instance]
@[instance]
theorem add_comm {G : Type u_1} [add_comm_semigroup G] (a b : G) :
a + b = b + a
theorem mul_comm {G : Type u_1} [comm_semigroup G] (a b : G) :
a * b = b * a
@[ext, class]
structure left_cancel_semigroup (G : Type u) :
  • mul : G G G
  • mul_assoc : (a b c : G), a * b * c = a * (b * c)
  • mul_left_cancel : (a b c : G), a * b = a * c b = c

A left_cancel_semigroup is a semigroup such that a * b = a * c implies b = c.

Instances of this typeclass
Instances of other typeclasses for left_cancel_semigroup
  • left_cancel_semigroup.has_sizeof_inst
@[ext, class]
structure right_cancel_semigroup (G : Type u) :
  • mul : G G G
  • mul_assoc : (a b c : G), a * b * c = a * (b * c)
  • mul_right_cancel : (a b c : G), a * b = c * b a = c

A right_cancel_semigroup is a semigroup such that a * b = c * b implies a = c.

Instances of this typeclass
Instances of other typeclasses for right_cancel_semigroup
  • right_cancel_semigroup.has_sizeof_inst
@[class]
structure mul_one_class (M : Type u) :
  • one : M
  • mul : M M M
  • one_mul : (a : M), 1 * a = a
  • mul_one : (a : M), a * 1 = a

Typeclass for expressing that a type M with multiplication and a one satisfies 1 * a = a and a * 1 = a for all a : M.

Instances of this typeclass
Instances of other typeclasses for mul_one_class
  • mul_one_class.has_sizeof_inst
@[instance]
def mul_one_class.to_has_one (M : Type u) [self : mul_one_class M] :
@[instance]
def mul_one_class.to_has_mul (M : Type u) [self : mul_one_class M] :
@[instance]
@[instance]
@[ext]
theorem mul_one_class.ext {M : Type u} ⦃m₁ m₂ : mul_one_class M⦄ :
@[ext]
theorem add_zero_class.ext {M : Type u} ⦃m₁ m₂ : add_zero_class M⦄ :
@[simp]
theorem one_mul {M : Type u} [mul_one_class M] (a : M) :
1 * a = a
@[simp]
theorem zero_add {M : Type u} [add_zero_class M] (a : M) :
0 + a = a
@[simp]
theorem add_zero {M : Type u} [add_zero_class M] (a : M) :
a + 0 = a
@[simp]
theorem mul_one {M : Type u} [mul_one_class M] (a : M) :
a * 1 = a
@[protected, instance]
@[protected, instance]
@[protected, instance]
@[protected, instance]
def npow_rec {M : Type u} [has_one M] [has_mul M] :
M M

The fundamental power operation in a monoid. npow_rec n a = a*a*...*a n times. Use instead a ^ n, which has better definitional behavior.

Equations
def nsmul_rec {M : Type u} [has_zero M] [has_add M] :
M M

The fundamental scalar multiplication in an additive monoid. nsmul_rec n a = a+a+...+a n times. Use instead n • a, which has better definitional behavior.

Equations

Suppose that one can put two mathematical structures on a type, a rich one R and a poor one P, and that one can deduce the poor structure from the rich structure through a map F (called a forgetful functor) (think R = metric_space and P = topological_space). A possible implementation would be to have a type class rich containing a field R, a type class poor containing a field P, and an instance from rich to poor. However, this creates diamond problems, and a better approach is to let rich extend poor and have a field saying that F R = P.

To illustrate this, consider the pair metric_space / topological_space. Consider the topology on a product of two metric spaces. With the first approach, it could be obtained by going first from each metric space to its topology, and then taking the product topology. But it could also be obtained by considering the product metric space (with its sup distance) and then the topology coming from this distance. These would be the same topology, but not definitionally, which means that from the point of view of Lean's kernel, there would be two different topological_space instances on the product. This is not compatible with the way instances are designed and used: there should be at most one instance of a kind on each type. This approach has created an instance diamond that does not commute definitionally.

The second approach solves this issue. Now, a metric space contains both a distance, a topology, and a proof that the topology coincides with the one coming from the distance. When one defines the product of two metric spaces, one uses the sup distance and the product topology, and one has to give the proof that the sup distance induces the product topology. Following both sides of the instance diamond then gives rise (definitionally) to the product topology on the product space.

Another approach would be to have the rich type class take the poor type class as an instance parameter. It would solve the diamond problem, but it would lead to a blow up of the number of type classes one would need to declare to work with complicated classes, say a real inner product space, and would create exponential complexity when working with products of such complicated spaces, that are avoided by bundling things carefully as above.

Note that this description of this specific case of the product of metric spaces is oversimplified compared to mathlib, as there is an intermediate typeclass between metric_space and topological_space called uniform_space. The above scheme is used at both levels, embedding a topology in the uniform space structure, and a uniform structure in the metric space structure.

Note also that, when P is a proposition, there is no such issue as any two proofs of P are definitionally equivalent in Lean.

To avoid boilerplate, there are some designs that can automatically fill the poor fields when creating a rich structure if one doesn't want to do something special about them. For instance, in the definition of metric spaces, default tactics fill the uniform space fields if they are not given explicitly. One can also have a helper function creating the rich structure from a structure with fewer fields, where the helper function fills the remaining fields. See for instance uniform_space.of_core or real_inner_product.of_core.

For more details on this question, called the forgetful inheritance pattern, see Competing inheritance paths in dependent type theory: a case study in functional analysis.

meta def try_refl_tac  :

try_refl_tac solves goals of the form ∀ a b, f a b = g a b, if they hold by definition.

Design note on add_monoid and monoid #

An add_monoid has a natural -action, defined by n • a = a + ... + a, that we want to declare as an instance as it makes it possible to use the language of linear algebra. However, there are often other natural -actions. For instance, for any semiring R, the space of polynomials R[X] has a natural R-action defined by multiplication on the coefficients. This means that ℕ[X] would have two natural -actions, which are equal but not defeq. The same goes for linear maps, tensor products, and so on (and even for itself).

To solve this issue, we embed an -action in the definition of an add_monoid (which is by default equal to the naive action a + ... + a, but can be adjusted when needed), and declare a has_smul ℕ α instance using this action. See Note [forgetful inheritance] for more explanations on this pattern.

For example, when we define R[X], then we declare the -action to be by multiplication on each coefficient (using the -action on R that comes from the fact that R is an add_monoid). In this way, the two natural has_smul ℕ ℕ[X] instances are defeq.

The tactic to_additive transfers definitions and results from multiplicative monoids to additive monoids. To work, it has to map fields to fields. This means that we should also add corresponding fields to the multiplicative structure monoid, which could solve defeq problems for powers if needed. These problems do not come up in practice, so most of the time we will not need to adjust the npow field when defining multiplicative objects.

A basic theory for the power function on monoids and the -action on additive monoids is built in the file algebra.group_power.basic. For now, we only register the most basic properties that we need right away.

In the definition, we use n.succ instead of n + 1 in the nsmul_succ' and npow_succ' fields to make sure that to_additive is not confused (otherwise, it would try to convert 1 : ℕ to 0 : ℕ).

@[instance]
@[instance]
@[instance]
def monoid.to_mul_one_class (M : Type u) [self : monoid M] :
@[instance]
def monoid.to_semigroup (M : Type u) [self : monoid M] :
@[protected, instance]
def monoid.has_pow {M : Type u_1} [monoid M] :
Equations
@[protected, instance]
Equations
@[simp]
theorem npow_eq_pow {M : Type u_2} [monoid M] (n : ) (x : M) :
monoid.npow n x = x ^ n
@[simp]
theorem nsmul_eq_smul {M : Type u_2} [add_monoid M] (n : ) (x : M) :
theorem zero_nsmul {M : Type u_2} [add_monoid M] (a : M) :
0 a = 0
@[simp]
theorem pow_zero {M : Type u_2} [monoid M] (a : M) :
a ^ 0 = 1
theorem succ_nsmul {M : Type u_2} [add_monoid M] (a : M) (n : ) :
(n + 1) a = a + n a
theorem pow_succ {M : Type u_2} [monoid M] (a : M) (n : ) :
a ^ (n + 1) = a * a ^ n
theorem left_inv_eq_right_inv {M : Type u} [monoid M] {a b c : M} (hba : b * a = 1) (hac : a * c = 1) :
b = c
theorem left_neg_eq_right_neg {M : Type u} [add_monoid M] {a b c : M} (hba : b + a = 0) (hac : a + c = 0) :
b = c
@[class]
structure add_comm_monoid (M : Type u) :

An additive commutative monoid is an additive monoid with commutative (+).

Instances of this typeclass
Instances of other typeclasses for add_comm_monoid
  • add_comm_monoid.has_sizeof_inst
@[instance]
@[class]
structure comm_monoid (M : Type u) :

A commutative monoid is a monoid with commutative (*).

Instances of this typeclass
Instances of other typeclasses for comm_monoid
  • comm_monoid.has_sizeof_inst
@[instance]
def comm_monoid.to_monoid (M : Type u) [self : comm_monoid M] :
Instances for comm_monoid.to_monoid
@[class]
structure add_left_cancel_monoid (M : Type u) :

An additive monoid in which addition is left-cancellative. Main examples are and groups. This is the right typeclass for many sum lemmas, as having a zero is useful to define the sum over the empty set, so add_left_cancel_semigroup is not enough.

Instances of this typeclass
Instances of other typeclasses for add_left_cancel_monoid
  • add_left_cancel_monoid.has_sizeof_inst
@[class]
structure left_cancel_monoid (M : Type u) :

A monoid in which multiplication is left-cancellative.

Instances of this typeclass
Instances of other typeclasses for left_cancel_monoid
  • left_cancel_monoid.has_sizeof_inst
@[instance]
@[class]
structure add_right_cancel_monoid (M : Type u) :

An additive monoid in which addition is right-cancellative. Main examples are and groups. This is the right typeclass for many sum lemmas, as having a zero is useful to define the sum over the empty set, so add_right_cancel_semigroup is not enough.

Instances of this typeclass
Instances of other typeclasses for add_right_cancel_monoid
  • add_right_cancel_monoid.has_sizeof_inst
@[instance]
@[class]
structure right_cancel_monoid (M : Type u) :

A monoid in which multiplication is right-cancellative.

Instances of this typeclass
Instances of other typeclasses for right_cancel_monoid
  • right_cancel_monoid.has_sizeof_inst
@[class]
structure add_cancel_monoid (M : Type u) :

An additive monoid in which addition is cancellative on both sides. Main examples are and groups. This is the right typeclass for many sum lemmas, as having a zero is useful to define the sum over the empty set, so add_right_cancel_semigroup is not enough.

Instances of this typeclass
Instances of other typeclasses for add_cancel_monoid
  • add_cancel_monoid.has_sizeof_inst
@[class]
structure cancel_monoid (M : Type u) :

A monoid in which multiplication is cancellative.

Instances of this typeclass
Instances of other typeclasses for cancel_monoid
  • cancel_monoid.has_sizeof_inst
@[class]
structure add_cancel_comm_monoid (M : Type u) :

Commutative version of add_cancel_monoid.

Instances of this typeclass
Instances of other typeclasses for add_cancel_comm_monoid
  • add_cancel_comm_monoid.has_sizeof_inst
@[class]
structure cancel_comm_monoid (M : Type u) :

Commutative version of cancel_monoid.

Instances of this typeclass
Instances of other typeclasses for cancel_comm_monoid
  • cancel_comm_monoid.has_sizeof_inst
@[protected, instance]

Any cancel_monoid M satisfies is_cancel_mul M.

@[protected, instance]

Any add_cancel_monoid M satisfies is_cancel_add M.

def zpow_rec {M : Type u_1} [has_one M] [has_mul M] [has_inv M] :
M M

The fundamental power operation in a group. zpow_rec n a = a*a*...*a n times, for integer n. Use instead a ^ n, which has better definitional behavior.

Equations
def zsmul_rec {M : Type u_1} [has_zero M] [has_add M] [has_neg M] :
M M

The fundamental scalar multiplication in an additive group. zsmul_rec n a = a+a+...+a n times, for integer n. Use instead n • a, which has better definitional behavior.

Equations
@[instance]
@[instance]
@[simp]
theorem inv_inv {G : Type u_1} [has_involutive_inv G] (a : G) :
@[simp]
theorem neg_neg {G : Type u_1} [has_involutive_neg G] (a : G) :
--a = a

Design note on div_inv_monoid/sub_neg_monoid and division_monoid/subtraction_monoid #

Those two pairs of made-up classes fulfill slightly different roles.

div_inv_monoid/sub_neg_monoid provides the minimum amount of information to define the action (zpow or zsmul). Further, it provides a div field, matching the forgetful inheritance pattern. This is useful to shorten extension clauses of stronger structures (group, group_with_zero, division_ring, field) and for a few structures with a rather weak pseudo-inverse (matrix).

division_monoid/subtraction_monoid is targeted at structures with stronger pseudo-inverses. It is an ad hoc collection of axioms that are mainly respected by three things:

It acts as a middle ground for structures with an inversion operator that plays well with multiplication, except for the fact that it might not be a true inverse (a / a ≠ 1 in general). The axioms are pretty arbitrary (many other combinations are equivalent to it), but they are independent:

As a consequence, a few natural structures do not fit in this framework. For example, ennreal respects everything except for the fact that (0 * ∞)⁻¹ = 0⁻¹ = ∞ while ∞⁻¹ * 0⁻¹ = 0 * ∞ = 0.

@[instance]
def div_inv_monoid.to_monoid (G : Type u) [self : div_inv_monoid G] :
Instances for div_inv_monoid.to_monoid
@[instance]
@[class]
structure div_inv_monoid (G : Type u) :

A div_inv_monoid is a monoid with operations / and ⁻¹ satisfying div_eq_mul_inv : ∀ a b, a / b = a * b⁻¹.

This deduplicates the name div_eq_mul_inv. The default for div is such that a / b = a * b⁻¹ holds by definition.

Adding div as a field rather than defining a / b := a * b⁻¹ allows us to avoid certain classes of unification failures, for example: Let foo X be a type with a ∀ X, has_div (foo X) instance but no ∀ X, has_inv (foo X), e.g. when foo X is a euclidean_domain. Suppose we also have an instance ∀ X [cromulent X], group_with_zero (foo X). Then the (/) coming from group_with_zero_has_div cannot be definitionally equal to the (/) coming from foo.has_div.

In the same way, adding a zpow field makes it possible to avoid definitional failures in diamonds. See the definition of monoid and Note [forgetful inheritance] for more explanations on this.

Instances of this typeclass
Instances of other typeclasses for div_inv_monoid
  • div_inv_monoid.has_sizeof_inst
@[instance]
@[instance]
@[instance]
Instances for sub_neg_monoid.to_add_monoid
@[class]
structure sub_neg_monoid (G : Type u) :

A sub_neg_monoid is an add_monoid with unary - and binary - operations satisfying sub_eq_add_neg : ∀ a b, a - b = a + -b.

The default for sub is such that a - b = a + -b holds by definition.

Adding sub as a field rather than defining a - b := a + -b allows us to avoid certain classes of unification failures, for example: Let foo X be a type with a ∀ X, has_sub (foo X) instance but no ∀ X, has_neg (foo X). Suppose we also have an instance ∀ X [cromulent X], add_group (foo X). Then the (-) coming from add_group.has_sub cannot be definitionally equal to the (-) coming from foo.has_sub.

In the same way, adding a zsmul field makes it possible to avoid definitional failures in diamonds. See the definition of add_monoid and Note [forgetful inheritance] for more explanations on this.

Instances of this typeclass
Instances of other typeclasses for sub_neg_monoid
  • sub_neg_monoid.has_sizeof_inst
@[instance]
@[protected, instance]
Equations
@[protected, instance]
Equations
@[simp]
theorem zsmul_eq_smul {G : Type u_1} [sub_neg_monoid G] (n : ) (x : G) :
@[simp]
theorem zpow_eq_pow {G : Type u_1} [div_inv_monoid G] (n : ) (x : G) :
@[simp]
theorem zero_zsmul {G : Type u_1} [sub_neg_monoid G] (a : G) :
0 a = 0
@[simp]
theorem zpow_zero {G : Type u_1} [div_inv_monoid G] (a : G) :
a ^ 0 = 1
@[simp, norm_cast]
theorem coe_nat_zsmul {G : Type u_1} [sub_neg_monoid G] (a : G) (n : ) :
n a = n a
@[simp, norm_cast]
theorem zpow_coe_nat {G : Type u_1} [div_inv_monoid G] (a : G) (n : ) :
a ^ n = a ^ n
theorem of_nat_zsmul {G : Type u_1} [sub_neg_monoid G] (a : G) (n : ) :
theorem zpow_of_nat {G : Type u_1} [div_inv_monoid G] (a : G) (n : ) :
a ^ int.of_nat n = a ^ n
@[simp]
theorem zsmul_neg_succ_of_nat {G : Type u_1} [sub_neg_monoid G] (a : G) (n : ) :
-[1+ n] a = -((n + 1) a)
@[simp]
theorem zpow_neg_succ_of_nat {G : Type u_1} [div_inv_monoid G] (a : G) (n : ) :
a ^ -[1+ n] = (a ^ (n + 1))⁻¹
theorem div_eq_mul_inv {G : Type u_1} [div_inv_monoid G] (a b : G) :
a / b = a * b⁻¹

Dividing by an element is the same as multiplying by its inverse.

This is a duplicate of div_inv_monoid.div_eq_mul_inv ensuring that the types unfold better.

theorem sub_eq_add_neg {G : Type u_1} [sub_neg_monoid G] (a b : G) :
a - b = a + -b

Subtracting an element is the same as adding by its negative.

This is a duplicate of sub_neg_monoid.sub_eq_mul_neg ensuring that the types unfold better.

theorem division_def {G : Type u_1} [div_inv_monoid G] (a b : G) :
a / b = a * b⁻¹

Alias of div_eq_mul_inv.

@[instance]
def neg_zero_class.to_has_zero (G : Type u_2) [self : neg_zero_class G] :
@[instance]
def neg_zero_class.to_has_neg (G : Type u_2) [self : neg_zero_class G] :
@[class]
structure neg_zero_class (G : Type u_2) :
Type u_2
  • zero : G
  • neg : G G
  • neg_zero : -0 = 0

Typeclass for expressing that -0 = 0.

Instances of this typeclass
Instances of other typeclasses for neg_zero_class
  • neg_zero_class.has_sizeof_inst
@[class]
structure sub_neg_zero_monoid (G : Type u_2) :
Type u_2

A sub_neg_monoid where -0 = 0.

Instances of this typeclass
Instances of other typeclasses for sub_neg_zero_monoid
  • sub_neg_zero_monoid.has_sizeof_inst
@[class]
structure inv_one_class (G : Type u_2) :
Type u_2

Typeclass for expressing that 1⁻¹ = 1.

Instances of this typeclass
Instances of other typeclasses for inv_one_class
  • inv_one_class.has_sizeof_inst
@[instance]
def inv_one_class.to_has_one (G : Type u_2) [self : inv_one_class G] :
@[instance]
def inv_one_class.to_has_inv (G : Type u_2) [self : inv_one_class G] :
@[class]
structure div_inv_one_monoid (G : Type u_2) :
Type u_2

A div_inv_monoid where 1⁻¹ = 1.

Instances of this typeclass
Instances of other typeclasses for div_inv_one_monoid
  • div_inv_one_monoid.has_sizeof_inst
@[simp]
theorem inv_one {G : Type u_1} [inv_one_class G] :
1⁻¹ = 1
@[simp]
theorem neg_zero {G : Type u_1} [neg_zero_class G] :
-0 = 0
@[class]
structure subtraction_monoid (G : Type u) :

A subtraction_monoid is a sub_neg_monoid with involutive negation and such that -(a + b) = -b + -a and a + b = 0 → -a = b.

Instances of this typeclass
Instances of other typeclasses for subtraction_monoid
  • subtraction_monoid.has_sizeof_inst
@[class]
structure division_monoid (G : Type u) :

A division_monoid is a div_inv_monoid with involutive inversion and such that (a * b)⁻¹ = b⁻¹ * a⁻¹ and a * b = 1 → a⁻¹ = b.

This is the immediate common ancestor of group and group_with_zero.

Instances of this typeclass
Instances of other typeclasses for division_monoid
  • division_monoid.has_sizeof_inst
@[simp]
theorem mul_inv_rev {G : Type u_1} [division_monoid G] (a b : G) :
(a * b)⁻¹ = b⁻¹ * a⁻¹
@[simp]
theorem neg_add_rev {G : Type u_1} [subtraction_monoid G] (a b : G) :
-(a + b) = -b + -a
theorem neg_eq_of_add_eq_zero_right {G : Type u_1} [subtraction_monoid G] {a b : G} :
a + b = 0 -a = b
theorem inv_eq_of_mul_eq_one_right {G : Type u_1} [division_monoid G] {a b : G} :
a * b = 1 a⁻¹ = b
@[class]
structure subtraction_comm_monoid (G : Type u) :

Commutative subtraction_monoid.

Instances of this typeclass
Instances of other typeclasses for subtraction_comm_monoid
  • subtraction_comm_monoid.has_sizeof_inst
@[class]
structure division_comm_monoid (G : Type u) :

Commutative division_monoid.

This is the immediate common ancestor of comm_group and comm_group_with_zero.

Instances of this typeclass
Instances of other typeclasses for division_comm_monoid
  • division_comm_monoid.has_sizeof_inst
@[class]
structure group (G : Type u) :

A group is a monoid with an operation ⁻¹ satisfying a⁻¹ * a = 1.

There is also a division operation / such that a / b = a * b⁻¹, with a default so that a / b = a * b⁻¹ holds by definition.

Instances of this typeclass
Instances of other typeclasses for group
  • group.has_sizeof_inst
@[instance]
def group.to_div_inv_monoid (G : Type u) [self : group G] :
@[class]
structure add_group (A : Type u) :

An add_group is an add_monoid with a unary - satisfying -a + a = 0.

There is also a binary operation - such that a - b = a + -b, with a default so that a - b = a + -b holds by definition.

Instances of this typeclass
Instances of other typeclasses for add_group
  • add_group.has_sizeof_inst
@[instance]
@[reducible]

Abbreviation for @sub_neg_monoid.to_add_monoid _ (@add_group.to_sub_neg_monoid _ _).

Useful because it corresponds to the fact that AddGroup is a subcategory of AddMon. Not an instance since it duplicates @sub_neg_monoid.to_add_monoid _ (@add_group.to_sub_neg_monoid _ _).

Equations
@[reducible]
def group.to_monoid (G : Type u) [group G] :

Abbreviation for @div_inv_monoid.to_monoid _ (@group.to_div_inv_monoid _ _).

Useful because it corresponds to the fact that Grp is a subcategory of Mon. Not an instance since it duplicates @div_inv_monoid.to_monoid _ (@group.to_div_inv_monoid _ _). See note [reducible non-instances].

Equations
@[simp]
theorem add_left_neg {G : Type u_1} [add_group G] (a : G) :
-a + a = 0
@[simp]
theorem mul_left_inv {G : Type u_1} [group G] (a : G) :
a⁻¹ * a = 1
theorem neg_add_self {G : Type u_1} [add_group G] (a : G) :
-a + a = 0
theorem inv_mul_self {G : Type u_1} [group G] (a : G) :
a⁻¹ * a = 1
@[simp]
theorem mul_right_inv {G : Type u_1} [group G] (a : G) :
a * a⁻¹ = 1
@[simp]
theorem add_right_neg {G : Type u_1} [add_group G] (a : G) :
a + -a = 0
theorem add_neg_self {G : Type u_1} [add_group G] (a : G) :
a + -a = 0
theorem mul_inv_self {G : Type u_1} [group G] (a : G) :
a * a⁻¹ = 1
@[simp]
theorem inv_mul_cancel_left {G : Type u_1} [group G] (a b : G) :
a⁻¹ * (a * b) = b
@[simp]
theorem neg_add_cancel_left {G : Type u_1} [add_group G] (a b : G) :
-a + (a + b) = b
@[simp]
theorem mul_inv_cancel_left {G : Type u_1} [group G] (a b : G) :
a * (a⁻¹ * b) = b
@[simp]
theorem add_neg_cancel_left {G : Type u_1} [add_group G] (a b : G) :
a + (-a + b) = b
@[simp]
theorem add_neg_cancel_right {G : Type u_1} [add_group G] (a b : G) :
a + b + -b = a
@[simp]
theorem mul_inv_cancel_right {G : Type u_1} [group G] (a b : G) :
a * b * b⁻¹ = a
@[simp]
theorem neg_add_cancel_right {G : Type u_1} [add_group G] (a b : G) :
a + -b + b = a
@[simp]
theorem inv_mul_cancel_right {G : Type u_1} [group G] (a b : G) :
a * b⁻¹ * b = a
@[protected, instance]
Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
@[instance]
def comm_group.to_group (G : Type u) [self : comm_group G] :
Instances for comm_group.to_group
@[class]
structure comm_group (G : Type u) :

A commutative group is a group with commutative (*).

Instances of this typeclass
Instances of other typeclasses for comm_group
  • comm_group.has_sizeof_inst
@[instance]
@[class]
structure add_comm_group (G : Type u) :

An additive commutative group is an additive group with commutative (+).

Instances of this typeclass
Instances of other typeclasses for add_comm_group
  • add_comm_group.has_sizeof_inst
@[protected, instance]
Equations
@[protected, instance]
Equations