In this lecture, we explore basic algebraic stuctures. The group project will be conducted in that direction. If you prefer to work on a different topic, here are two suggestions:
For convenience, we call a curried function of signature M → M → M
an operation on M.
def Op (M : Type) : Type := M → M → M
M
and an operation μ : Op M
, such that μ
is associative.⟨M, μ, p⟩
where p
is a proof that μ
is associative, meaning that p
is a term of type∀ x y z : M, μ (μ x y) z = μ x (μ y z)
.μ
be a proposition is to guarantee that we can identify ⟨M, μ, p⟩
and ⟨M, μ, p'⟩
whenever p
and p'
are both proofs of the associativity property of μ
.We choose to define the proposition IsSemigroup M μ
as a structure (which, we recall, is essentially an inductive type with only one constructor). At this stage, it would also be possible to declare it as a Prop
-valued function instead (using the keyword def
).
structure IsSemigroup (M : Type) (μ : Op M) : Prop where
assoc : ∀ x y z : M, μ (μ x y) z = μ x (μ y z)
Technically, we are defining the type of semigroups as a
where Magma := (M : Type) × Op M
is itself a IsSemigroup
, not the type Semigroup
.
How do we show that Nat.add : Nat → Nat → Nat
. This is done as follows.
def isSemigroupNatAdd : IsSemigroup Nat (· + ·) where
assoc := Nat.add_assoc -- found by `exact?`
where
actually helps here (compared to using :=
).(· + ·)
as notation for Nat.add
, which is quite nice from the point of view of mathematical notation.Let us define monoids as semigroups that admit a neutral element. We can do that by extending the IsSemigroup
structure (this would not be possible if we had passed IsSemigroup
as a Prop
-valued function).
structure IsMonoid (M : Type) (μ : Op M) extends (IsSemigroup M μ : Prop) : Prop where
neutral : ∃ (e : M), ∀ x : M, (μ e x = x) ∧ (μ x e = x)
In the project, you will be asked to prove the following:
def isMonoidNatAdd : IsMonoid Nat (· + ·) where
assoc := by
sorry
neutral := by
sorry
From the IsSemigroup
structure, we get a projection map to the assoc
field of the structure.
#check @IsSemigroup.assoc -- @IsSemigroup.assoc : ∀ {M : Type} {μ : Op M},
IsSemigroup M μ → ∀ (x y z : M), μ (μ x y) z = μ x (μ y z)
#check isSemigroupNatAdd.assoc -- isSemigroupNatAdd.assoc : ∀ (x y z : Nat), x + y + z = x + (y + z)
Similarly, from the IsMonoid
structure, we get a projection IsMonoid.neutral
. But we also get a map to IsSemigroup
, which formalises the fact that (by definition) if ⟨M, μ⟩
is a monoid, then it is a semigroup.
#check IsMonoid.toIsSemigroup -- @IsMonoid.toIsSemigroup : ∀ {M : Type u_1} {μ : Op M},
IsMonoid M μ → IsSemigroup M μ
IsMonoid
on triples ⟨M, μ, e⟩
where M
is a type, μ
is an operation on M
and e
is an element M
. The advantage is that this gives access to the neutral element e
of M
.e : M
).IsMonoid M μ e
(otherwise it is not clear whether we can extract an explicit neutral element).e : M
with the property that ∀ x : M, (μ e x = x) ∧ (μ x e = x)
, then this element is unique...In the project file, you will be asked to:
⟨M, μ⟩
is a semigroup that admits a neutral element, then such an element is unique.⟨ℤ, (· + ·)⟩
is a group.⟨ℤ, (· + ·)⟩
is a commutative group.Before we start working on the project files, I would like to ask for 5 minutes of your time, to give feedback on the workshop if you have not done it yet:
Thanks!
Here are two project topics for you to work on:
2. Define a function that sends a monoid to its neutral element (difficult).