Free Algebras
Given a commutative semiring R
, and a type X
, we construct the free R
-algebra on X
.
Notation
free_algebra R X
is the free algebra itself. It is endowed with anR
-algebra structure.free_algebra.ι R
is the functionX → free_algebra R X
.- Given a function
f : X → A
to an R-algebraA
,lift R f
is the lift off
to anR
-algebra morphismfree_algebra R X → A
.
Theorems
ι_comp_lift
states that the composition(lift R f) ∘ (ι R)
is identical tof
.lift_unique
states that whenever an R-algebra morphismg : free_algebra R X → A
is given whose composition withι R
isf
, then one hasg = lift R f
.hom_ext
is a variant oflift_unique
in the form of an extensionality theorem.lift_comp_ι
is a combination ofι_comp_lift
andlift_unique
. It states that the lift of the composition of an algebra morphism withι
is the algebra morphism itself.equiv_monoid_algebra_free_monoid : free_algebra R X ≃ₐ[R] monoid_algebra R (free_monoid X)
Implementation details
We construct the free algebra on X
as a quotient of an inductive type free_algebra.pre
by an inductively defined relation free_algebra.rel
.
Explicitly, the construction involves three steps:
- We construct an inductive type
free_algebra.pre R X
, the terms of which should be thought of as representatives for the elements offree_algebra R X
. It is the free type with maps fromR
andX
, and with two binary operationsadd
andmul
. - We construct an inductive relation
free_algebra.rel R X
onfree_algebra.pre R X
. This is the smallest relation for which the quotient is anR
-algebra where addition resp. multiplication are induced byadd
resp.mul
from 1., and for which the map fromR
is the structure map for the algebra. - The free algebra
free_algebra R X
is the quotient offree_algebra.pre R X
by the relationfree_algebra.rel R X
.
- of : Π (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2), X → free_algebra.pre R X
- of_scalar : Π (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2), R → free_algebra.pre R X
- add : Π (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2), free_algebra.pre R X → free_algebra.pre R X → free_algebra.pre R X
- mul : Π (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2), free_algebra.pre R X → free_algebra.pre R X → free_algebra.pre R X
This inductive type is used to express representatives of the free algebra.
Equations
Coercion from X
to pre R X
. Note: Used for notation only.
Equations
Coercion from R
to pre R X
. Note: Used for notation only.
Equations
Multiplication in pre R X
defined as pre.mul
. Note: Used for notation only.
Equations
- free_algebra.pre.has_mul R X = {mul := free_algebra.pre.mul X}
Addition in pre R X
defined as pre.add
. Note: Used for notation only.
Equations
- free_algebra.pre.has_add R X = {add := free_algebra.pre.add X}
Zero in pre R X
defined as the image of 0
from R
. Note: Used for notation only.
Equations
One in pre R X
defined as the image of 1
from R
. Note: Used for notation only.
Equations
Scalar multiplication defined as multiplication by the image of elements from R
.
Note: Used for notation only.
Equations
- free_algebra.pre.has_scalar R X = {smul := λ (r : R) (m : free_algebra.pre R X), (free_algebra.pre.of_scalar r).mul m}
Given a function from X
to an R
-algebra A
, lift_fun
provides a lift of f
to a function
from pre R X
to A
. This is mainly used in the construction of free_algebra.lift
.
Equations
- free_algebra.lift_fun R X f = λ (t : free_algebra.pre R X), t.rec_on f ⇑(algebra_map R A) (λ (_x _x : free_algebra.pre R X), has_add.add) (λ (_x _x : free_algebra.pre R X), has_mul.mul)
- add_scalar : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {r s : R}, free_algebra.rel R X ↑(r + s) (↑r + ↑s)
- mul_scalar : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {r s : R}, free_algebra.rel R X (↑r * s) ((↑r) * ↑s)
- central_scalar : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {r : R} {a : free_algebra.pre R X}, free_algebra.rel R X ((↑r) * a) (a * ↑r)
- add_assoc : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X (a + b + c) (a + (b + c))
- add_comm : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b : free_algebra.pre R X}, free_algebra.rel R X (a + b) (b + a)
- zero_add : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a : free_algebra.pre R X}, free_algebra.rel R X (0 + a) a
- mul_assoc : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X ((a * b) * c) (a * b * c)
- one_mul : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a : free_algebra.pre R X}, free_algebra.rel R X (1 * a) a
- mul_one : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a : free_algebra.pre R X}, free_algebra.rel R X (a * 1) a
- left_distrib : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X (a * (b + c)) (a * b + a * c)
- right_distrib : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X ((a + b) * c) (a * c + b * c)
- zero_mul : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a : free_algebra.pre R X}, free_algebra.rel R X (0 * a) 0
- mul_zero : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a : free_algebra.pre R X}, free_algebra.rel R X (a * 0) 0
- add_compat_left : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X a b → free_algebra.rel R X (a + c) (b + c)
- add_compat_right : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X a b → free_algebra.rel R X (c + a) (c + b)
- mul_compat_left : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X a b → free_algebra.rel R X (a * c) (b * c)
- mul_compat_right : ∀ (R : Type u_1) [_inst_1 : comm_semiring R] (X : Type u_2) {a b c : free_algebra.pre R X}, free_algebra.rel R X a b → free_algebra.rel R X (c * a) (c * b)
An inductively defined relation on pre R X
used to force the initial algebra structure on
the associated quotient.
The free algebra for the type X
over the commutative semiring R
.
Equations
- free_algebra R X = quot (free_algebra.rel R X)
Equations
- free_algebra.semiring R X = {add := quot.map₂ has_add.add _ _, add_assoc := _, zero := quot.mk (free_algebra.rel R X) 0, zero_add := _, add_zero := _, add_comm := _, mul := quot.map₂ has_mul.mul _ _, mul_assoc := _, one := quot.mk (free_algebra.rel R X) 1, one_mul := _, mul_one := _, zero_mul := _, mul_zero := _, left_distrib := _, right_distrib := _}
Equations
- free_algebra.inhabited R X = {default := 0}
Equations
- free_algebra.has_scalar R X = {smul := λ (r : R) (a : free_algebra R X), quot.lift_on a (λ (x : free_algebra.pre R X), quot.mk (free_algebra.rel R X) ((↑r) * x)) _}
Equations
- free_algebra.algebra R X = {to_has_scalar := free_algebra.has_scalar R X, to_ring_hom := {to_fun := λ (r : R), quot.mk (free_algebra.rel R X) ↑r, map_one' := _, map_mul' := _, map_zero' := _, map_add' := _}, commutes' := _, smul_def' := _}
The canonical function X → free_algebra R X
.
Equations
- free_algebra.ι R = λ (m : X), quot.mk (free_algebra.rel R X) ↑m
Given a function f : X → A
where A
is an R
-algebra, lift R f
is the unique lift
of f
to a morphism of R
-algebras free_algebra R X → A
.
Equations
- free_algebra.lift R f = {to_fun := λ (a : free_algebra R X), quot.lift_on a (free_algebra.lift_fun R X f) _, map_one' := _, map_mul' := _, map_zero' := _, map_add' := _, commutes' := _}
At this stage we set the basic definitions as @[irreducible]
, so from this point onwards one should only use the universal properties of the free algebra, and consider the actual implementation as a quotient of an inductive type as completely hidden.
Of course, one still has the option to locally make these definitions semireducible
if so desired, and Lean is still willing in some circumstances to do unification based on the underlying definition.
The free algebra on X
is "just" the monoid algebra on the free monoid on X
.
This would be useful when constructing linear maps out of a free algebra, for example.
Equations
- free_algebra.equiv_monoid_algebra_free_monoid = alg_equiv.of_alg_hom (free_algebra.lift R (λ (x : X), ⇑(monoid_algebra.of R (free_monoid X)) (free_monoid.of x))) (⇑(monoid_algebra.lift R (free_monoid X) (free_algebra R X)) (⇑free_monoid.lift (free_algebra.ι R))) free_algebra.equiv_monoid_algebra_free_monoid._proof_1 free_algebra.equiv_monoid_algebra_free_monoid._proof_2