---
layout: default
title : "Setoid.Congruences.Basic module (The Agda Universal Algebra Library)"
date : "2021-09-15"
author: "agda-algebras development team"
---
#### Congruences of Setoid Algebras
This is the [Setoid.Congruences.Basic][] module of the [Agda Universal Algebra Library][].
A **congruence** of an algebra `π¨` is a binary relation on the carrier of `π¨` that
is an equivalence relation, contains the setoid equality of `π¨`, and is *compatible*
with the basic operations: applying an operation to argument tuples that are
related coordinatewise gives related results.
The compatibility half is `_β£β_`{.AgdaFunction}; `IsCongruence`{.AgdaRecord} adds
the other two conditions, and `Con`{.AgdaFunction} is the bundled Ξ£-form that the
rest of the library passes around, with `IsCongruenceβCon`{.AgdaFunction} and
`ConβIsCongruence`{.AgdaFunction} converting between them.
The reason to require containment of the setoid equality is that a congruence has
to be an equivalence relation on the *setoid*, not merely on the carrier: a
quotient by a relation that split an equality class would not be well defined.
With the congruence in hand `_β±_`{.AgdaFunction} forms the quotient algebra, which
is the same carrier under the coarser equivalence, needing neither a quotient type
nor extensionality. Kernels of homomorphisms are the primary source of congruences;
see [Setoid.Homomorphisms.Kernels][].
<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
module Setoid.Congruences.Basic where
open import Agda.Primitive using () renaming ( Set to Type )
open import Data.Product using ( _,_ ; Ξ£-syntax ; projβ )
open import Data.Unit.Base using ( β€ ; tt )
open import Function using ( Func )
open import Level using ( Level ; _β_ ; Lift ; lift ; lower )
open import Relation.Binary using ( Setoid ; IsEquivalence )
renaming ( Rel to BinaryRel )
open import Relation.Binary.PropositionalEquality using ( refl )
open import Overture using ( _|:_ ; Equivalence ; π ; π₯ ; Signature ; π )
open import Setoid.Relations using ( βͺ_β« ; _/_ ; βͺ_βΌ_β«-elim )
open import Setoid.Algebras.Basic using ( ov ; Algebra ; π»[_] ; π[_] ; _^_ )
private variable Ξ± Ο β : Level
```
-->
We now define the predicate `_β£β_` so that, if `π¨` denotes an algebra and `R` a
binary relation, then `π¨ β£β R` will represent the assertion that `R` is
*compatible* with all basic operations of `π¨`. The formal definition is immediate
since all the work is done by the relation `|:`, which we defined above (see
[Setoid.Relations.Discrete][]).
```agda
_β£β_ : (π¨ : Algebra {π = π} Ξ± Ο) β BinaryRel π[ π¨ ] β β Type _
π¨ β£β R = β π β (π ^ π¨) |: R
```
A *congruence relation* of an algebra `π¨` is defined to be an equivalence relation
that is compatible with the basic operations of `π¨`. This concept can be
represented in a number of alternative but equivalent ways. Formally, we define a
record type (`IsCongruence`) to represent the property of being a congruence, and
we define a Sigma type (`Con`) to represent the type of congruences of a given
algebra.
As mentioned above, congruences should contain the equality relation on the
underlying setoid. That is, they must be *reflexive*; hence, the `reflexive`
field in the definition of `IsCongruence`.
```agda
module _ {π : Signature π π₯} (π¨ : Algebra {π = π} Ξ± Ο) where
open Setoid π»[ π¨ ] using ( _β_ )
record IsCongruence (ΞΈ : BinaryRel π[ π¨ ] β) : Type (π β π₯ β Ο β β β Ξ±) where
constructor mkcon
field
reflexive : β {aβ aβ} β aβ β aβ β ΞΈ aβ aβ
is-equivalence : IsEquivalence ΞΈ
is-compatible : π¨ β£β ΞΈ
Eqv : Equivalence π[ π¨ ] {β}
Eqv = ΞΈ , is-equivalence
open IsCongruence public
Con : (β : Level) β Type (Ξ± β Ο β ov {π = π} β)
Con β = Ξ£[ ΞΈ β BinaryRel π[ π¨ ] β ] IsCongruence ΞΈ
```
Each of these types captures what it means to be a congruence and they are
equivalent in the sense that each implies the other. One implication is the
"uncurry" operation and the other is the second projection.
```agda
module _ {π : Signature π π₯} {π¨ : Algebra {π = π} Ξ± Ο} where
IsCongruenceβCon : (ΞΈ : BinaryRel π[ π¨ ] β) β IsCongruence π¨ ΞΈ β Con π¨ β
IsCongruenceβCon ΞΈ p = ΞΈ , p
ConβIsCongruence : ((ΞΈ , _) : Con π¨ β) β IsCongruence π¨ ΞΈ
ConβIsCongruence (_ , p) = p
```
#### Quotient algebras
In many areas of abstract mathematics the *quotient* of an algebra `π¨` with
respect to a congruence relation `ΞΈ` of `π¨` plays an important role. This quotient
is typically denoted by `π¨ / ΞΈ` and Agda allows us to define and express quotients
using this standard notation.
(Note that the forward-slash we use to denote the quotient is produced by typing
`\---` (in the Agda input method); it is a unicode character, and it is not the
ascii forward-slash that appears in the preceding paragraph.)
```agda
module _ {π : Signature π π₯} where
open Algebra using ( Domain ; Interp )
open Func using ( cong ) renaming ( to to _β¨$β©_ )
_β±_ : (π¨ : Algebra {π = π} Ξ± Ο) β Con π¨ β β Algebra Ξ± β
(π¨ β± ΞΈ) .Domain = π[ π¨ ] / (Eqv (projβ ΞΈ))
(π¨ β± ΞΈ) .Interp β¨$β© (f , a) = (f ^ π¨) a
(π¨ β± ΞΈ) .Interp .cong {f , u} {.f , v} (refl , a) = is-compatible (projβ ΞΈ) f a
module _ (π¨ : Algebra Ξ± Ο) where
open Setoid π»[ π¨ ] using ( _β_ )
_/β_ : π[ π¨ ] β (ΞΈ : Con π¨ β) β π[ π¨ β± ΞΈ ]
a /β ΞΈ = a
/-β‘ : ((_ΞΈ_ , ΞΈcon) : Con π¨ β){u v : π[ π¨ ]}
β βͺ u β«{Eqv ΞΈcon} β βͺ v β«{Eqv ΞΈcon} β u ΞΈ v
/-β‘ ΞΈ uv = reflexive (ConβIsCongruence ΞΈ) uv
```
#### The least and greatest congruences
Every algebra has a *least* and a *greatest* congruence. The least is the
**diagonal** (identity) congruence `π[ π¨ ]`, which relates exactly the
`β`-equal elements β it is the setoid equality, viewed as a congruence. The
greatest is the **total** congruence `π[ π¨ ]`, which relates everything. These
are the bottom and top of the congruence lattice (their order properties β that
they really are least and greatest β are recorded in
[Setoid.Congruences.Lattice][], where the containment order `_β_` is available).
Both are level-polymorphic via `Lift`, so they can be taken at whatever relation
level the surrounding context dictates (e.g. the absorbing level at which the
congruence lattice is assembled in [Setoid.Congruences.CompleteLattice][]); the
diagonal's result lives at `Ο β β`, the total's at `β`.
The only non-trivial obligation is **compatibility with the operations**. For the
diagonal this is *exactly* the statement that the operations of `π¨` respect its
setoid equality β i.e. the `cong` field of `Interp π¨` β which is why the diagonal
congruence cannot live in `Overture` (which has no algebra to appeal to) and
belongs here. For the total congruence compatibility is trivial, since every two
elements are related.
```agda
π[_] : (π¨ : Algebra {π = π} Ξ± Ο){β : Level} β Con π¨ (Ο β β)
π[ π¨ ] {β} = (Ξ» x y β Lift β (x β y)) , mkcon (Ξ» e β lift e) π-isEquiv π-compatible
where
open Setoid π»[ π¨ ] using ( _β_ )
renaming ( refl to βrefl ; sym to βsym ; trans to βtrans )
π-isEquiv : IsEquivalence (Ξ» x y β Lift β (x β y))
π-isEquiv = record { refl = lift βrefl
; sym = Ξ» p β lift (βsym (lower p))
; trans = Ξ» p q β lift (βtrans (lower p) (lower q)) }
π-compatible : π¨ β£β Ξ» x y β Lift β (x β y)
π-compatible f h = lift (π¨ .Interp .cong (refl , Ξ» i β lower (h i)))
π[_] : (π¨ : Algebra {π = π} Ξ± Ο){β : Level} β Con π¨ β
π[ π¨ ] {β} = (Ξ» _ _ β Lift β β€) , mkcon (Ξ» _ β lift tt) π-isEquiv (Ξ» _ _ β lift tt)
where
π-isEquiv : IsEquivalence (Ξ» (_ _ : π[ π¨ ]) β Lift β β€)
π-isEquiv = record { refl = lift tt ; sym = Ξ» _ β lift tt ; trans = Ξ» _ _ β lift tt }
```