---
layout: default
title : "Setoid.Homomorphisms.Kernels module (Agda Universal Algebra Library)"
date : "2021-09-13"
author: "agda-algebras development team"
---

#### Kernels of Homomorphisms

This is the [Setoid.Homomorphisms.Kernels][] module of the [Agda Universal Algebra Library][].

<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}

module Setoid.Homomorphisms.Kernels where

-- Imports from Agda and the Agda Standard Library ------------------------------------------
open  import Data.Product                           using ( _,_ ;  proj₁ ; projβ‚‚ )
open  import Function   renaming ( Func to _⟢_ )    using ( _∘_ ; id )
open  import Level                                  using ( Level )
open  import Relation.Binary                        using ( Setoid )
open  import Relation.Binary.PropositionalEquality  using (refl)

-- Imports from the Agda Universal Algebra Library ------------------------------------------
open  import Overture                    using ( kerRel ; kerRelOfEquiv ; π“ž ; π“₯ ; Signature)
open  import Setoid.Functions            using ( Image_βˆ‹_ )
open  import Setoid.Algebras             using ( Algebra ; _^_ ; 𝔻[_] )
open  import Setoid.Congruences          using ( _βˆ£β‰ˆ_ ; Con ; mkcon ; _β•±_ ; IsCongruence )
open  import Setoid.Homomorphisms.Basic  using ( hom ; IsHom ; epi ; IsEpi ; epiβ†’hom ; 𝒾𝒹 )

private variable  Ξ± Ξ² ρᡃ ρᡇ β„“ : Level

open _⟢_ using ( cong ) renaming ( to to _⟨$⟩_ )
```
-->

```agda
module _ {𝑆 : Signature π“ž π“₯} {𝑨 : Algebra {𝑆 = 𝑆} Ξ± ρᡃ}{𝑩 : Algebra Ξ² ρᡇ} ((hmap , hhom) : hom 𝑨 𝑩) where
  open Algebra 𝑩   using ( Interp ) renaming ( Domain to B )
  open Setoid B    using ( _β‰ˆ_ ; sym ; trans ; isEquivalence )
  private h = _⟨$⟩_ hmap
```

`HomKerComp` asserts that the kernel of a homomorphism is compatible with the basic operations.
That is, if each `(u i, v i)` belongs to the kernel, then so does the pair `((f ^ 𝑨) u , (f ^ 𝑨) v)`.

```agda
  HomKerComp : 𝑨 βˆ£β‰ˆ kerRel _β‰ˆ_ h
  HomKerComp f {u}{v} kuv = Goal
    where
    fhuv : (f ^ 𝑩)(h ∘ u) β‰ˆ (f ^ 𝑩)(h ∘ v)
    fhuv = cong Interp (refl , kuv)

    lem1 : h ((f ^ 𝑨) u) β‰ˆ (f ^ 𝑩)(h ∘ u)
    lem1 = IsHom.compatible hhom

    lem2 : (f ^ 𝑩) (h ∘ v) β‰ˆ h ((f ^ 𝑨) v)
    lem2 = sym (IsHom.compatible hhom)

    Goal : h ((f ^ 𝑨) u) β‰ˆ h ((f ^ 𝑨) v)
    Goal = trans lem1 (trans fhuv lem2)
```

The kernel of a homomorphism is a congruence of the domain, which we construct as follows.

```agda
  kercon : Con 𝑨 ρᡇ
  kercon =  kerRel _β‰ˆ_ h ,
            mkcon (Ξ» x β†’ cong hmap x)(kerRelOfEquiv isEquivalence h)(HomKerComp)
```

Now that we have a congruence, we can construct the quotient relative to the kernel.

```agda
  kerquo : Algebra Ξ± ρᡇ
  kerquo = 𝑨 β•± kercon

ker[_β‡’_]_ :  {𝑆 : Signature π“ž π“₯} (𝑨 : Algebra {𝑆 = 𝑆} Ξ± ρᡃ) (𝑩 : Algebra Ξ² ρᡇ) β†’ hom 𝑨 𝑩 β†’ Algebra _ _
ker[ 𝑨 β‡’ 𝑩 ] h = kerquo h
```


#### The canonical projection

Given an algebra `𝑨` and a congruence `ΞΈ`, the *canonical projection* is a map from `𝑨` onto `𝑨 β•± ΞΈ` that is constructed, and proved epimorphic, as follows.

```agda
module _ {𝑆 : Signature π“ž π“₯} {𝑨 : Algebra {𝑆 = 𝑆} Ξ± ρᡃ}{𝑩 : Algebra Ξ² ρᡇ} (h : hom 𝑨 𝑩) where
  open IsCongruence

  Ο€epi : (ΞΈ : Con 𝑨 β„“) β†’ epi 𝑨 (𝑨 β•± ΞΈ)
  Ο€epi ΞΈ = p , pepi
    where

    open Setoid 𝔻[ 𝑨 β•± ΞΈ ]    using () renaming ( sym to β‰ˆsym ; refl to β‰ˆrefl )
    open IsHom {𝑨 = (𝑨 β•± ΞΈ)}  using ( compatible )
    open IsEpi

    p : 𝔻[ 𝑨 ] ⟢ 𝔻[ 𝑨 β•± ΞΈ ]
    p ⟨$⟩ x = x
    p .cong = reflexive (ΞΈ .projβ‚‚)

    pepi : IsEpi 𝑨 (𝑨 β•± ΞΈ) p
    pepi .isHom .compatible = β‰ˆsym (𝒾𝒹 .projβ‚‚ .compatible)
    pepi .isSurjective {y} = Image_βˆ‹_.eq y β‰ˆrefl
```

In may happen that we don't care about the surjectivity of `Ο€epi`, in which
case would might prefer to work with the *homomorphic reduct* of `Ο€epi`.
This is obtained by applying `epi-to-hom`, like so.

```agda
  Ο€hom : (ΞΈ : Con 𝑨 β„“) β†’ hom 𝑨 (𝑨 β•± ΞΈ)
  Ο€hom ΞΈ = epiβ†’hom 𝑨 (𝑨 β•± ΞΈ) (Ο€epi ΞΈ)
```

We combine the foregoing to define a function that takes 𝑆-algebras `𝑨` and `𝑩`,
and a homomorphism `h : hom 𝑨 𝑩` and returns the canonical epimorphism from `𝑨`
onto `𝑨 [ 𝑩 ]/ker h`. (Recall, the latter is the special notation we defined
above for the quotient of `𝑨` modulo the kernel of `h`.)

```agda
  Ο€ker : epi 𝑨 (ker[ 𝑨 β‡’ 𝑩 ] h)
  Ο€ker = Ο€epi (kercon h)
```

The kernel of the canonical projection of `𝑨` onto `𝑨 / ΞΈ` is equal to `ΞΈ`,
but since equality of inhabitants of certain types (like `Congruence` or `Rel`)
can be a tricky business, we settle for proving the containment `𝑨 / ΞΈ βŠ† ΞΈ`.
Of the two containments, this is the easier one to prove; luckily it is also
the one we need later.

```agda
  ker-in-con : {ΞΈ : Con 𝑨 β„“} β†’ βˆ€ {x}{y} β†’ kercon (Ο€hom ΞΈ) .proj₁ x y β†’  ΞΈ .proj₁ x y
  ker-in-con = id
```