---
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][].
<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
open import Overture using (π ; π₯ ; Signature)
module Setoid.Congruences.Basic {π : Signature π π₯} where
open import Agda.Primitive using () renaming ( Set to Type )
open import Data.Product using ( _,_ ; Ξ£-syntax ; projβ ; 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 )
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.
Congruences should obviously contain the equality relation on the underlying
setoid. That is, they must be reflexive. Unfortunately this doesn't come for free
(e.g., as part of the definition of `IsEquivalence` on Setoid), so we must add the
field `reflexive` to the definition of `IsCongruence`. (In fact, we should
probably redefine equivalence relation on setoids to be reflexive with respect to
the underlying setoid equality (and not just with respect to _β‘_).)
```agda
module _ (π¨ : 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
IsCongruenceβCon : {π¨ : Algebra Ξ± Ο}(ΞΈ : BinaryRel π[ π¨ ] β) β IsCongruence π¨ ΞΈ β Con π¨ β
IsCongruenceβCon ΞΈ p = ΞΈ , p
ConβIsCongruence : {π¨ : Algebra Ξ± Ο}((ΞΈ , _) : 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.
```agda
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 π¨ β){u v : π[ π¨ ]}
β βͺ u β«{Eqv (projβ ΞΈ)} β βͺ v β«{Eqv (projβ ΞΈ)} β (projβ ΞΈ) 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 (cong (Interp π¨) (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 }
```