---
layout: default
file: "src/Examples/Setoid/CongruenceLattice.lagda.md"
title: "Examples.Setoid.CongruenceLattice module"
date: "2026-06-02"
author: "the agda-algebras development team"
---
### Worked example: the congruence lattice of a two-element algebra {#examples-setoid-congruencelattice}
This is the [Examples.Setoid.CongruenceLattice][] module of the [Agda Universal Algebra Library][].
We exercise [Setoid.Congruences.CompleteLattice][] on the smallest
nontrivial example: the two-element algebra `π` in the *empty* signature (no
operations), whose carrier is `Bool` under propositional equality. Because there are
no operations, every equivalence relation on `Bool` is automatically a congruence, so
`Con π` is just the lattice of equivalence relations on a two-element set β the
two-element chain `β₯ < β€`, where `β₯` is the diagonal (`β‘`) and `β€` is the all-relation.
We instantiate the `Lattice`, `BoundedLattice`, and `CompleteLattice` bundles for
`π`, and verify the lattice is genuinely nontrivial by proving `β€ β¬ β₯`.
<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
module Examples.Setoid.CongruenceLattice where
open import Data.Bool.Base using ( Bool ; true ; false )
open import Data.Empty using ( β₯ )
open import Data.Product using ( _,_ )
open import Function using ( Func )
open import Level using ( 0β ; lift )
open import Relation.Binary using ( Setoid )
open import Relation.Binary.PropositionalEquality as β‘ using ( _β‘_ )
open import Relation.Nullary using ( Β¬_ )
open import Overture using ( Signature )
open Func renaming ( to to _β¨$β©_ )
```
-->
#### The empty signature and the two-element algebra `π` {#the-algebra}
The empty signature has no operation symbols (`β₯`), hence no arities.
```agda
πβ : Signature 0β 0β
πβ = β₯ , Ξ» ()
open import Setoid.Algebras {π = πβ} using ( Algebra )
open import Setoid.Congruences {π = πβ} using ( Con ; mkcon )
open import Setoid.Signatures using ( β¨_β© )
π : Algebra 0β 0β
π = record { Domain = β‘.setoid Bool ; Interp = interp }
where
interp : Func (β¨ πβ β© (β‘.setoid Bool)) (β‘.setoid Bool)
interp β¨$β© (() , _)
cong interp {() , _}
```
#### The Diagonal Congruence
Propositional equality `_β‘_` is a congruence of `π`: it is reflexive over the
setoid equality (which *is* `_β‘_` here), an equivalence relation, and β since `πβ`
has no operations β compatibility is vacuous.
```agda
Ξ : Con π 0β
Ξ = _β‘_ , mkcon (Ξ» e β e)
(record { refl = β‘.refl ; sym = β‘.sym ; trans = β‘.trans })
(Ξ» ())
```
#### Instantiating the bundles
With the base level `ββ = 0β` the absorbing level `L` is `0β`, so the congruence
lattice of `π` is the chain on `Con π {0β}`. All three bundles type-check.
```agda
open import Setoid.Congruences.Lattice {π = πβ} using ( _β_ )
open import Setoid.Congruences.CompleteLattice {π = πβ}
using ( Con-Lattice ; Con-BoundedLattice ; Con-CompleteLattice ; 1ᴬ ; 0ᴬ ; 0ᴬ-minimum )
Conπ-Lattice = Con-Lattice π 0β
Conπ-BoundedLattice = Con-BoundedLattice π 0β
Conπ-CompleteLattice = Con-CompleteLattice π 0β
```
#### Nontriviality: `β€ β¬ β₯` {#nontriviality}
The top and bottom congruences are distinct. If we had `β€ β€ β₯`, then composing with
`0 β€ Ξ` (the bottom is the least congruence, so it is below `Ξ`) would give `β€ β€ Ξ`;
but `β€` relates `true` and `false` while `Ξ` (namely `_β‘_`) does not, so `true β‘ false`
β a contradiction.
```agda
Conπ-nontrivial : Β¬ ( (1ᴬ π 0β) β (0ᴬ π 0β) )
Conπ-nontrivial β€β€β₯ with 0ᴬ-minimum π 0β Ξ (β€β€β₯ {true} {false} (lift _))
... | ()
```