Appearance
Basics
General Group
There is only one operator and one object (or set) in group, where the operator is abstracted as
One Class
lean
class One₁ (α : Type) where
/-- The element one -/
one : α
@[inherit_doc]
notation "𝟙" => One₁.one
example {α : Type} [One₁ α] : α := 𝟙
example {α : Type} [One₁ α] : (𝟙 : α) = 𝟙 := rflOne class, denoted as "𝟙", is used to show the existence of identity,
Dia Class
lean
class Dia₁ (α : Type) where
dia : α → α → α
infixl:70 " ⋄ " => Dia₁.diaDia class, denoted as diamond operator
Semigroup Class
lean
class Semigroup₁ (α : Type) extends toDia₁ : Dia₁ α where
/-- Diamond is associative -/
dia_assoc : ∀ a b c : α, a ⋄ b ⋄ c = a ⋄ (b ⋄ c)Semigroup class is used to define the associative property on operator
DiaOneClass Class
lean
class DiaOneClass₁ (α : Type) extends One₁ α, Dia₁ α where
/-- One is a left neutral element for diamond. -/
one_dia : ∀ a : α, 𝟙 ⋄ a = a
/-- One is a right neutral element for diamond -/
dia_one : ∀ a : α, a ⋄ 𝟙 = aDiaOneClass class is specially used to define binary operation properties of
Monoid Class
lean
class Monoid₁ (α : Type) extends Semigroup₁ α, DiaOneClass₁ αMonoid class is a combination of Semigroup and DiaOneClass, which has axioms:
- operation closure on operator
with type . - identity and its binary operations,
. - associative,
.
Inv Class
lean
class Inv₁ (α : Type) where
/-- The inversion function -/
inv : α → α
@[inherit_doc]
postfix:max "⁻¹" => Inv₁.invInv class, denoted as
Group
class Group₁ (G : Type) extends Monoid₁ G, Inv₁ G where
inv_dia : ∀ a : G, a⁻¹ ⋄ a =Group class defines the inverse property
Addition Group
Group with
AddSemigroup Class
class AddSemigroup₃ (α : Type) extends Add α where
/-- Addition is associative -/
add_assoc₃ : ∀ a b c : α, a + b + c = a + (b + c)Add is a concrete operator class of type Dia class in general Group structure. In this case, AddSemigroup is corresponded with Semigroup in general Group structure, in which the operator
Semigroup Class
lean
@[to_additive AddSemigroup₃]
class Semigroup₃ (α : Type) extends Mul α where
/-- Multiplication is associative -/
mul_assoc₃ : ∀ a b c : α, a * b * c = a * (b * c)In lean4, multipliation Semingroup is AddSemigroup.
AddMonoid Class
lean
class AddMonoid₃ (α : Type) extends AddSemigroup₃ α, AddZeroClass αSimilar with Monoid in general Group class structure, AddMonoid must extend AddSemigroup and AddZeroClass, where AddZeroClass corresponds with DiaOneClass specially for operator
AddCommSemigroup Class
lean
class AddCommSemigroup₃ (α : Type) extends AddSemigroup₃ α where
add_comm : ∀ a b : α, a + b = b + aAddCommSemigroup define the commutative property of AddSemigroup.
AddCommMonoid Class
lean
class AddCommMonoid₃ (α : Type) extends AddMonoid₃ α, AddCommSemigroup₃ αAddCommMonoid is a combination of AddMonoid and AddCommSemigroup.
AddGroup Class
lean
class AddGroup₃ (G : Type) extends AddMonoid₃ G, Neg G where
neg_add : ∀ a : G, -a + a = 0Similar with general Group class, Neg class is corresponded with Inv specially for operator inv_dia is replaced with neg_add.
Multiplicative Group
lean
@[to_additive AddGroup₃]
class Group₃ (G : Type) extends Monoid₃ G, Inv G where
inv_mul : ∀ a : G, a⁻¹ * a = 1In lean4, the default operator in group is @[to_...] to automatically generate code for AddGroup.
Additive Commutative Group
Additive commutative group is an additive group with commutative property.
lean
class AddCommGroup₃ (G : Type) extends AddGroup₃ G, AddCommMonoid₃ GIn this case, we need to inherit additive group property from AddGroup and commutative property from AddCommMonoid. Usually we have a beautiful name for AddCommGroup, that is Abelian Group. But in lean4
Ring
Ring is composed of two components, one is object, the other one is scalar, but both of them are defined by the same set
- the object is an
AddCommGroup(abelian group) with operator. But below we extend AddGroupinstead ofAddCommGroupas commutative property can be derived from the distributive property,. We can see that the add_commis derived in Additive Commutative Group. - the scalar is an (multiplicative)
Monoidwith operator. - operations on
with will be absorbed into . - mixed operations on
and satisfy distributive property.
lean
class Ring₃ (R : Type) extends AddGroup₃ R, Monoid₃ R, MulZeroClass R where
/-- Multiplication is left distributive over addition -/
left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c
/-- Multiplication is right distributive over addition -/
right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * cIn general, Ring does not have multiplicative commutative property.
Additive Commutative Group
Additive commutative group (also known as abelian group) is a additive group with commutative property.
class AddCommSemigroup₃ (α : Type) extends AddSemigroup₃ α where
add_comm : ∀ a b : α, a + b = b + a
@[to_additive AddCommSemigroup₃]
class CommSemigroup₃ (α : Type) extends Semigroup₃ α where
mul_comm : ∀ a b : α, a * b = b * a
class AddCommMonoid₃ (α : Type) extends AddMonoid₃ α, AddCommSemigroup₃ α
@[to_additive AddCommMonoid₃]
class CommMonoid₃ (α : Type) extends Monoid₃ α, CommSemigroup₃ α
class AddCommGroup₃ (G : Type) extends AddGroup₃ G, AddCommMonoid₃ GNote that, in general AddSemigroup does not have additive commutative property, so we need to add its definition manually in AddCommSemigroup. It is clear to see that AddSemigroup is also an abstract class, we need to instantiate it before using. We can see an instance of AddCommGroup with type Ring, and the commutative property will be instantiated by utilizing Ring's basic properties (additive association, distribution, etc...):
lean
instance {R : Type} [Ring₃ R] : AddCommGroup₃ R :=
{
add_comm := by
intro a b
have : a + (a + b + b) = a + (b + a + b) := calc
a + (a + b + b) = (a + a) + (b + b) := by simp [add_assoc₃, add_assoc₃]
_ = (1 * a + 1 * a) + (1 * b + 1 * b) := by simp
_ = (1 + 1) * a + (1 + 1) * b := by simp [Ring₃.right_distrib]
_ = (1 + 1) * (a + b) := by simp [Ring₃.left_distrib]
_ = 1 * (a + b) + 1 * (a + b) := by simp [Ring₃.right_distrib]
_ = (a + b) + (a + b) := by simp
_ = a + (b + a + b) := by simp [add_assoc₃]
exact add_right_cancel₃ (add_left_cancel₃ this)
}Module
Similar with Ring, Module also consists of two components, one is an object, the other one is a scalar. The difference is that they are defined on two different sets
- the object
is a AddCommGroup(or additive abelian group) with operator - the scalar
is a Ringwith two operators,and - operation between object and scalar is often abstracted as scalar-mul
SMulsymbolwith type . That is, any element from Ringis absorbed inAddCommGroup. A few operations of scalar-mulSMulare listed below :
lean
class SMul₃ (α : Type) (β : Type) where
/-- Scalar multiplication -/
smul : α → β → β
infixr:73 " • " => SMul₃.smul
class Module₁ (R : Type) [Ring₃ R] (M : Type) [AddCommGroup₃ M] extends SMul₃ R M where
zero_smul : ∀ m : M, (0 : R) • m = 0
one_smul : ∀ m : M, (1 : R) • m = m
mul_smul : ∀ (a b : R) (m : M), (a * b) • m = a • b • m
add_smul : ∀ (a b : R) (m : M), (a + b) • m = a • m + b • m
smul_add : ∀ (a : R) (m n : M), a • (m + n) = a • m + a • nNotice that Module class is also an abstract one, not instantiated yet, specially including a few operations of
SMuloperator, need to implement smulfunctionoperation, need to implement one_mulfunctionoperation, need to implement mul_onefunctionoperation, need to implement mul_smulfunctionoperation, need to implement add_smulfunctionoperation, need to implement smul_addfunction
Another typical example of Module is, Ring itself is a module over iteself, that is, Module class with :
SMuloperatorwith multiplication - object
of AddCommGroupinModuleis instantiated withRing, sinceRingextendsAddCommGroup. - scalar
of SemiringinModuleis instantiated withRingitself, even thoughRingdoes not inheritSemiringdirectly, but it has all properties ofSemiring.
So all relevent functions will be instantiated with:
smulis instantiated with one_mulis instantiated with mul_oneis instantiated with mul_smulis instantiated with add_mulis instantiated with mul_addis instantiated with
lean
instance selfModule (R : Type) [Ring₃ R] : Module₁ R R where
smul := fun r s ↦ r*s
zero_smul := zero_mul
one_smul := one_mul
mul_smul := mul_assoc₃
add_smul := Ring₃.right_distrib
smul_add := Ring₃.left_distribNotice that selfModule is not a fully instantiated instance of Module, since AddCommGroup Ring and Ring are still abstract classes. For example, Ring can be further instantiated with
Export
Similar with some other programming languages, by export Class (func1, func2, ...),
export DiaOneClass₁ (one_dia dia_one)
export Semigroup₁ (dia_assoc)
export Group₁ (inv_dia)we can directly us one_dia instead of DiaOneClass.one_dia, similarly for dia_one, dia_assoc, and inv_dia .
Mophism
Monoid Homomorphism
Homomorphism on Monoid which is operator-identity pair of
lean
@[ext]
structure MonoidHom₁ (G H : Type) [Monoid G] [Monoid H] where
toFun : G → H
map_one : toFun 1 = 1
map_mul : ∀ g g', toFun (g * g') = toFun g * toFun g'is defined with :
toFuncis one function ofmap_oneshows identity mapmap_mulshows operation preservation of map
Below shows homomorphism on AddMonoid with operator-identity pair of
lean
@[ext]
structure AddMonoidHom₁ (G H : Type) [AddMonoid G] [AddMonoid H] where
toFun : G → H
map_zero : toFun 0 = 0
map_add : ∀ g g', toFun (g + g') = toFun g + toFun g'Ring Homomorphism
lean
@[ext]
structure RingHom₁ (R S : Type) [Ring R] [Ring S] extends MonoidHom₁ R S, AddMonoidHom₁ R SRing has two operators RingHom can be easily obtained by extending MonoidHom and AddMonoidHom :
from MonoidHomfrom MonoidHomfrom AddMonoidHomfrom AddMonoidHom
Homomorphism Class
lean
class MonoidHomClass₁ (F : Type) (M N : Type) [Monoid M] [Monoid N] where
toFun : F → M → N
map_one : ∀ f : F, toFun f 1 = 1
map_mul : ∀ f g g', toFun f (g * g') = toFun f g * toFun f g'MonoidHomClass is a class (group) of MonoidHom with type
Another kind of definition of MonoidHomClass and RingHomClass :
lean
instance (M N : Type) [Monoid M] [Monoid N] : MonoidHomClass₂ (MonoidHom₁ M N) M N where
toFun := MonoidHom₁.toFun
map_one := fun f ↦ f.map_one
map_mul := fun f ↦ f.map_mul
instance (R S : Type) [Ring R] [Ring S] : MonoidHomClass₂ (RingHom₁ R S) R S where
toFun := fun f ↦ f.toMonoidHom₁.toFun
map_one := fun f ↦ f.toMonoidHom₁.map_one
map_mul := fun f ↦ f.toMonoidHom₁.map_mulSince already RingHom extends MonoidHom, we can directly use toMonoidHom to get the functionality of monoid homomorphism.
Order Preserve Homomorphism
Let's see an example of order preserve homomorphism on monoid,
lean
@[ext]
structure OrderPresHom (α β : Type) [LE α] [LE β] where
toFun : α → β
le_of_le : ∀ a a', a ≤ a' → toFun a ≤ toFun a'
@[ext]
structure OrderPresMonoidHom (M N : Type) [Monoid M] [LE M] [Monoid N] [LE N] extends
MonoidHom₁ M N, OrderPresHom M NOrderPresMonoidHom preserves order operation Monoid.
lean
class OrderPresHomClass (F : Type) (α β : outParam Type) [LE α] [LE β]
instance (α β : Type) [LE α] [LE β] : OrderPresHomClass (OrderPresHom α β) α β where
instance (α β : Type) [LE α] [Monoid α] [LE β] [Monoid β] :
OrderPresHomClass (OrderPresMonoidHom α β) α β where
instance (α β : Type) [LE α] [Monoid α] [LE β] [Monoid β] :
MonoidHomClass₃ (OrderPresMonoidHom α β) α β
where
coe := fun f ↦ f.toOrderPresHom.toFun
coe_injective' _ _ := OrderPresMonoidHom.ext
map_one := fun f ↦ f.toMonoidHom₁.map_one
map_mul := fun f ↦ f.toMonoidHom₁.map_mulOrderPresHomClass is the class (group) of order preserve homomorphism, and MonoidHomClass is the class (group) of order preseve homomorphism on Monoid.