---
layout: default
title : "Setoid.Homomorphisms.Basic module (Agda Universal Algebra Library)"
date : "2021-09-13"
author: "agda-algebras development team"
---
#### Homomorphisms of Algebras over Setoids
This is the [Setoid.Homomorphisms.Basic][] module of the [Agda Universal Algebra Library][].
A **homomorphism** from `π¨` to `π©` is a setoid function `h : π»[ π¨ ] βΆ π»[ π© ]`
between the domains of the two algebras that is *compatible* with every basic
operation: for each operation symbol `f` and each tuple `a` of arguments,
`h β¨$β© (f ^ π¨) a` and `(f ^ π©) Ξ» x β h β¨$β© a x` are related by the equality of `π©`.
Two things distinguish this from an ordinary type-based definition, where
compatibility is an identification `h ((f ^ π¨) a) β‘ (f ^ π©) (h β a)`.
1. The map is a setoid function, so it carries its own congruence proof and
cannot fail to send equal arguments to equal results.
2. Compatibility is asserted up to the equality *of the codomain*, not up to
propositional equality; that is what lets `π©` be a quotient algebra (the same
carrier under a coarser equivalence) with no special quotient type and no
appeal to extensionality.
This module defines the compatibility predicates, the homomorphism type
`hom`{.AgdaFunction} and its predicate form `IsHom`{.AgdaRecord}, the injective
and surjective variants (monomorphisms and epimorphisms) in both of those forms,
the translations between them, and the identity homomorphism `πΎπΉ`{.AgdaFunction}.
Everything else the library proves about homomorphisms is built on these,
including the following:
+ **composition**, `β-hom`{.AgdaFunction}, and the homomorphisms that witness
**universe lifting** in [Setoid.Homomorphisms.Properties][];
+ **the kernel** of a homomorphism as a congruence, and the **quotient** it
determines in [Setoid.Homomorphisms.Kernels][];
+ **isomorphism**, `_β
_`{.AgdaRecord}, given by a pair of mutually inverse
homomorphisms in [Setoid.Homomorphisms.Isomorphisms][];
+ **the first homomorphism theorem** in [Setoid.Homomorphisms.Noether][];
+ **factoring** one homomorphism through another in
[Setoid.Homomorphisms.Factor][].
<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
module Setoid.Homomorphisms.Basic where
open import Agda.Primitive using () renaming ( Set to Type )
open import Data.Product using ( _,_ ; Ξ£ ; Ξ£-syntax ; projβ ; projβ )
open import Function.Bundles using () renaming ( Func to _βΆ_ )
open import Level using ( Level ; _β_ )
open import Relation.Binary using ( Setoid )
open import Relation.Binary.PropositionalEquality using ( refl )
open import Overture using ( OperationSymbolsOf ; π ; π₯ ; Signature )
open import Setoid.Functions using ( IsInjective ; IsSurjective ; ππ )
open import Setoid.Algebras using ( Algebra ; _^_ ; π»[_])
private variable
Ξ± Ξ² Οα΅ Οα΅ : Level
```
-->
The homomorphism type is built in four steps. `compatible-map-op`{.AgdaFunction}
says that a setoid function `h` commutes with *one* operation symbol `f`;
`compatible-map`{.AgdaFunction} quantifies that over all operation symbols;
`IsHom`{.AgdaRecord} packages the resulting property as a record with the single
field `compatible`{.AgdaField} and the constructor
`mkIsHom`{.AgdaInductiveConstructor}; and `hom`{.AgdaFunction} is the type of
homomorphisms proper. An inhabitant of `hom π¨ π©` is therefore a pair `(h , p)`: a
setoid function `h` from the domain of `π¨` to that of `π©`, together with a proof
that `h` is compatible.
`mkhom`{.AgdaFunction} is the smart constructor for that pair, so a caller who has
`h` and a `compatible-map`{.AgdaFunction} proof never has to write the `Ξ£`-pair
and the `IsHom`{.AgdaRecord} record by hand.
```agda
module _ {π : Signature π π₯} (π¨ : Algebra {π = π} Ξ± Οα΅)(π© : Algebra Ξ² Οα΅) where
open _βΆ_ {a = Ξ±}{Οα΅}{Ξ²}{Οα΅}{From = π»[ π¨ ]}{To = π»[ π© ]} renaming (to to _β¨$β©_ )
compatible-map-op : (π»[ π¨ ] βΆ π»[ π© ]) β OperationSymbolsOf π β Type (π₯ β Ξ± β Οα΅)
compatible-map-op h f = β {a} β h β¨$β© (f ^ π¨) a ββ (f ^ π©) Ξ» x β h β¨$β© a x
where open Setoid π»[ π© ] using() renaming ( _β_ to _ββ_ )
compatible-map : (π»[ π¨ ] βΆ π»[ π© ]) β Type (π β π₯ β Ξ± β Οα΅)
compatible-map h = β {f} β compatible-map-op h f
record IsHom (h : π»[ π¨ ] βΆ π»[ π© ]) : Type (π β π₯ β Ξ± β Οα΅ β Οα΅) where
constructor mkIsHom
field compatible : compatible-map h
hom : Type (π β π₯ β Ξ± β Οα΅ β Ξ² β Οα΅)
hom = Ξ£ (π»[ π¨ ] βΆ π»[ π© ]) IsHom
mkhom : (h : π»[ π¨ ] βΆ π»[ π© ]) β compatible-map h β hom
mkhom h c = h , mkIsHom c
```
#### Monomorphisms and epimorphisms
A **monomorphism** is an injective homomorphism and an **epimorphism** is a
surjective one. Each comes in the two forms `hom`{.AgdaFunction} does:
+ the predicates `IsMon`{.AgdaRecord} and `IsEpi`{.AgdaRecord}, whose fields pair
the homomorphism property with `IsInjective`{.AgdaFunction} or
`IsSurjective`{.AgdaFunction};
+ the bundled types `mon`{.AgdaFunction} and `epi`{.AgdaFunction}, which pair a
setoid function with such a proof.
Both predicates export a `HomReduct`{.AgdaFunction} that forgets the extra
condition, and `monβhom`{.AgdaFunction} and `epiβhom`{.AgdaFunction} apply it to
the bundled forms.
`monβintohom`{.AgdaFunction} and `epiβontohom`{.AgdaFunction} regroup the same
data the other way, as a `hom`{.AgdaFunction} paired with the injectivity or the
surjectivity of its underlying map. That regrouping earns a name because the two
resulting types are, by definition, `_IsSubalgebraOf_`{.AgdaFunction} of
[Setoid.Subalgebras.Basic][] and `_IsHomImageOf_`{.AgdaFunction} of
[Setoid.Homomorphisms.HomomorphicImages][]; so these are the functions that turn a
monomorphism into a subalgebra and an epimorphism into a homomorphic image.
```agda
record IsMon (h : π»[ π¨ ] βΆ π»[ π© ]) : Type (π β π₯ β Ξ± β Οα΅ β Ξ² β Οα΅) where
field
isHom : IsHom h
isInjective : IsInjective h
HomReduct : hom
HomReduct = h , isHom
mon : Type (π β π₯ β Ξ± β Οα΅ β Ξ² β Οα΅)
mon = Ξ£ (π»[ π¨ ] βΆ π»[ π© ]) IsMon
monβhom : mon β hom
monβhom h = IsMon.HomReduct (projβ h)
record IsEpi (h : π»[ π¨ ] βΆ π»[ π© ]) : Type (π β π₯ β Ξ± β Οα΅ β Ξ² β Οα΅) where
field
isHom : IsHom h
isSurjective : IsSurjective h
HomReduct : hom
HomReduct = h , isHom
epi : Type (π β π₯ β Ξ± β Οα΅ β Ξ² β Οα΅)
epi = Ξ£ (π»[ π¨ ] βΆ π»[ π© ]) IsEpi
epiβhom : epi β hom
epiβhom h = IsEpi.HomReduct (projβ h)
module _ {π : Signature π π₯} (π¨ : Algebra {π = π} Ξ± Οα΅)(π© : Algebra Ξ² Οα΅) where
open IsEpi
open IsMon
monβintohom : mon π¨ π© β Ξ£[ h β hom π¨ π© ] IsInjective (projβ h)
monβintohom (hh , hhM) = (hh , isHom hhM) , isInjective hhM
epiβontohom : epi π¨ π© β Ξ£[ h β hom π¨ π© ] IsSurjective (projβ h)
epiβontohom (hh , hhE) = (hh , isHom hhE) , isSurjective hhE
```
Finally, we define the identity homomorphism for setoid algebras.
```agda
module _ {π : Signature π π₯} {π¨ : Algebra {π = π} Ξ± Οα΅} where
open Setoid π»[ π¨ ] using ( reflexive )
πΎπΉ : hom π¨ π¨
πΎπΉ = ππ , mkIsHom (reflexive refl)
```