---
layout: default
title : "Setoid.Varieties.FreeAlgebras module (Agda Universal Algebra Library)"
date : "2021-06-29"
author: "agda-algebras development team"
---
#### Free setoid algebras
<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
open import Overture using (π ; π₯ ; Signature)
module Setoid.Varieties.FreeAlgebras {π : Signature π π₯} where
open import Agda.Primitive using () renaming ( Set to Type )
open import Data.Product using ( Ξ£-syntax ; _,_ )
open import Function using ( _β_ ; id ) renaming ( Func to _βΆ_ )
open import Level using ( Level ; _β_)
open import Relation.Binary using ( Setoid )
open import Relation.Unary using ( Pred ; _β_ ; _β_ )
open import Relation.Binary.PropositionalEquality as β‘ using (_β‘_)
import Relation.Binary.Reasoning.Setoid as SetoidReasoning
open import Overture using ( projβ ; projβ )
open import Overture.Terms {π = π} using ( β )
open import Setoid.Algebras {π = π} using ( Algebra ; ov ; Lift-Alg ; π»[_] )
open import Setoid.Functions using ( eq ; IsSurjective )
open import Setoid.Homomorphisms {π = π} using ( epi ; IsEpi ; IsHom ; hom
; epiβhom ; β-epi ; ToLift-epi )
open import Setoid.Relations using ( fkerPred )
open import Setoid.Terms {π = π} using ( π» ; _β_ ; module Environment
; free-lift ; free-lift-interp )
open import Setoid.Varieties.Closure {π = π} using ( V ; S )
open import Setoid.Varieties.Preservation {π = π} using ( classIds-β-VIds ; S-id1 )
open import Setoid.Varieties.SoundAndComplete {π = π} using ( Eq ; _β«_ ; β«-proof ; _βΜ_ ; _β’_βΉ_β_
; Th ; Mod ; module Soundness
; module FreeAlgebra )
open _βΆ_ using ( cong ) renaming ( to to _β¨$β©_ )
open Algebra using ( Domain )
```
-->
In the code below, `X` will play the role of an arbitrary collection of variables; it
would suffice to take `X` to be the cardinality of the largest algebra in π¦, but
since we don't know that cardinality, we leave `X` arbitrary for now.
Alternatively, we could let `X` be the product of all algebras in the class `π¦`, like so.
`π : Type oΞ±`
`π = Carrier ( Domain (β¨
(π{π¦ = S π¦})) )`
```agda
module FreeHom (Ο : Level){Ξ± Οα΅ β : Level}
{π¦ : Pred(Algebra Ξ± Οα΅) (Ξ± β Οα΅ β ov β)} where
private
ΞΉ : Level
ΞΉ = ov(Ο β Ξ± β Οα΅ β β)
open Eq
```
We now define the algebra `π½`, which plays the role of the relatively free algebra,
along with the natural epimorphism `epiπ½ : epi (π» π) π½` from `π» π` to `π½`.
The relatively free algebra (relative to `Th π¦`) is called `M` and is derived from
`TermSetoid π` and `TermInterp π` and imported from the EquationalLogic module.
```agda
β : Type ΞΉ
β = Ξ£[ eq β Eq{Ο} ] π¦ β« ((lhs eq) βΜ (rhs eq))
β° : β β Eq
β° (eqv , p) = eqv
β°β’[_]βΉThπ¦ : (X : Type Ο) β β{p q} β β° β’ X βΉ p β q β π¦ β« (p βΜ q)
β°β’[ X ]βΉThπ¦ x .β«-proof π¨ kA = sound (Ξ» i Ο β (projβ i) .β«-proof π¨ kA Ο) x
where open Soundness β° π¨
open FreeAlgebra {ΞΉ = ΞΉ}{I = β} β° using ( π½[_] )
```
Finally, we define an epimorphism from `π» X` onto the relatively free algebra
`π½[ X ]`. Of course, the kernel of this epimorphism will be the congruence of
`π» X` defined by identities modeled by (`S π¦`, hence) `π¦`.
```agda
epiπ½[_] : (X : Type Ο) β epi (π» X) π½[ X ]
epiπ½[ X ] = h , hepi
where
open Algebra π½[ X ] using() renaming ( Domain to F ; Interp to InterpF )
open Setoid F using() renaming ( _β_ to _βFβ_ ; refl to reflF )
open Algebra (π» X) using() renaming (Domain to TX)
open Setoid TX using() renaming ( _β_ to _βTβ_ ; refl to reflT )
open _β_ ; open IsEpi ; open IsHom
c : β {x y} β x βTβ y β x βFβ y
c (rfl {x}{y} β‘.refl) = reflF
c (gnl {f}{s}{t} x) = cong InterpF (β‘.refl , c β x)
h : TX βΆ F
h = record { to = id ; cong = c }
hepi : IsEpi (π» X) π½[ X ] h
compatible (isHom hepi) = cong h reflT
isSurjective hepi {y} = eq y reflF
homπ½[_] : (X : Type Ο) β hom (π» X) π½[ X ]
homπ½[ X ] = epiβhom (π» X) π½[ X ] epiπ½[ X ]
homπ½[_]-is-epic : (X : Type Ο) β IsSurjective (projβ (homπ½[ X ]))
homπ½[ X ]-is-epic = IsEpi.isSurjective (projβ (epiπ½[ X ]))
class-models-kernel : β{X p q} β (p , q) β fkerPred (projβ (homπ½[ X ])) β π¦ β« (p βΜ q)
class-models-kernel {X = X}{p}{q} pKq = β°β’[ X ]βΉThπ¦ pKq
kernel-in-theory : {X : Type Ο} β fkerPred (projβ (homπ½[ X ])) β Th (V β ΞΉ π¦)
kernel-in-theory {X = X} {p , q} pKq =
classIds-β-VIds {β = β} (class-models-kernel pKq)
module _ {X : Type Ο} {π¨ : Algebra Ξ± Οα΅}{sA : π¨ β S {Ξ² = Ξ±}{Οα΅} β π¦} where
open Environment π¨ using ( Equal )
kerπ½βEqual : β{p q} β (p , q) β fkerPred (projβ (homπ½[ X ])) β Equal p q
kerπ½βEqual{p = p}{q} x = S-id1{β = β} (β°β’[ X ]βΉThπ¦ x) .β«-proof π¨ sA
π¦β«ββ°β’ : {X : Type Ο} β β{p q} β π¦ β« p βΜ q β β° β’ X βΉ p β q
π¦β«ββ°β’ {p = p} {q} pKq = hyp (p βΜ q , pKq) where open _β’_βΉ_β_ using (hyp)
module _ {Ξ± Οα΅ β : Level} {π¦ : Pred(Algebra Ξ± Οα΅) (Ξ± β Οα΅ β ov β)} where
private ΞΉ = ov(Ξ± β Οα΅ β β)
open IsEpi ; open IsHom
module lower-universe-version {π¨ : Algebra Ξ± Οα΅} where
open FreeHom Ξ± {Ξ±}{Οα΅}{β}{π¦}
open FreeAlgebra {ΞΉ = ΞΉ}{I = β} β° using ( π½[_] )
open Algebra π¨ renaming (Domain to A) using( Interp )
open Setoid A renaming ( Carrier to β£Aβ£ ) using ( trans ; sym ; refl )
π½-ModTh-epi : π¨ β Mod (Th (V β ΞΉ π¦)) β epi π½[ β£Aβ£ ] π¨
π½-ModTh-epi AβModThK = Ο , isEpi
where
Ο : (Domain π½[ β£Aβ£ ]) βΆ A
Ο β¨$β© x = free-lift{π¨ = π¨} id x
Ο .cong {p} {q} pq =
trans (sym (free-lift-interp{π¨ = π¨} id p))
(trans (AβModThK{p = p}{q} (kernel-in-theory pq) id )
(free-lift-interp{π¨ = π¨} id q))
isEpi : IsEpi π½[ β£Aβ£ ] π¨ Ο
isEpi .isHom .compatible = cong Interp (β‘.refl , Ξ» _ β refl)
isEpi .isSurjective = eq (β _) refl
π½-ModTh-epi-lift :
π¨ β Mod (Th (V β ΞΉ π¦)) β epi π½[ β£Aβ£ ] (Lift-Alg π¨ (ov Ξ±) (ov Ξ±))
π½-ModTh-epi-lift AβModThK = β-epi (π½-ModTh-epi Ξ» {p q} β AβModThK{p = p}{q}) ToLift-epi
module _
{π¨ : Algebra (Ξ± β Οα΅ β β) (Ξ± β Οα΅ β β)}
where
open FreeHom (Ξ± β Οα΅ β β) {Ξ±}{Οα΅}{β}{π¦}
open FreeAlgebra {ΞΉ = ΞΉ}{I = β} β° using ( π½[_] )
open Algebra π¨ using( Interp ) renaming (Domain to A)
open Environment π¨ using ( β¦_β§ )
open Setoid A renaming ( Carrier to β£Aβ£ ) using ( trans ; sym ; refl ; _β_)
open SetoidReasoning A
π½-ModTh-epi : π¨ β Mod (Th (V β ΞΉ π¦)) β epi π½[ β£Aβ£ ] π¨
π½-ModTh-epi AβModThK = Ο , isEpi
where
Ο : π»[ π½[ β£Aβ£ ] ] βΆ A
Ο β¨$β© x = free-lift id x
Ο .cong {p} {q} pq = begin
free-lift id p βΛβ¨ free-lift-interp{π¨ = π¨} id p β©
β¦ p β§ β¨$β© id ββ¨ AβModThK{p = p}{q} (kernel-in-theory pq) id β©
β¦ q β§ β¨$β© id ββ¨ free-lift-interp{π¨ = π¨} id q β©
free-lift id q β
isEpi : IsEpi π½[ β£Aβ£ ] π¨ Ο
isEpi .isHom .compatible = cong Interp (β‘.refl , Ξ» _ β refl)
isEpi .isSurjective = eq (β _) refl
π½-ModTh-epi-lift : π¨ β Mod (Th (V β ΞΉ π¦)) β epi π½[ β£Aβ£ ] (Lift-Alg π¨ ΞΉ ΞΉ)
π½-ModTh-epi-lift AβModThK =
β-epi (π½-ModTh-epi (Ξ» {p q} β AβModThK{p = p}{q})) ToLift-epi
```