---
layout: default
title : "Setoid.Congruences.Lattice module (The Agda Universal Algebra Library)"
date : "2026-06-01"
author: "agda-algebras development team"
---
#### The Congruence Lattice of a Setoid Algebra
This is the [Setoid.Congruences.Lattice][] module of the [Agda Universal Algebra Library][].
The congruences of an algebra `π¨`, ordered by containment, form a complete lattice.
This module begins the formalization of that fact by promoting `Con π¨` to a
first-class ordered object: it defines the containment order `_β_`, the induced
equivalence `_β_` of mutual containment, and the **meet** `ΞΈ β§ Ο`, which is the
relational intersection `ΞΈ β© Ο`. The intersection of two congruences is again a
congruence, and it is the greatest lower bound of the two arguments. Thus we have a
partially ordered set which, with the meet operation, forms a semilattice.
<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
open import Overture using (π ; π₯ ; Signature)
module Setoid.Congruences.Lattice {π : Signature π π₯} where
open import Agda.Primitive using () renaming ( Set to Type )
open import Data.Product using ( _Γ_ ; _,_ ; projβ ; projβ ; swap )
open import Data.Unit.Base using ( tt )
open import Level using ( Level ; _β_ ; lift ; lower )
open import Relation.Binary using ( Setoid ; IsEquivalence ; IsPartialOrder ; _β_ )
renaming ( Rel to BinaryRel )
open import Relation.Binary.Bundles using ( Poset )
open import Relation.Binary.Lattice using ( Infimum ; IsMeetSemilattice ; MeetSemilattice )
open import Setoid.Algebras.Basic {π = π} using ( ov ; Algebra ; π[_] ; π»[_] )
open import Setoid.Congruences.Basic {π = π} using ( Con ; mkcon ; _β£β_ ; reflexive
; is-equivalence ; is-compatible
; π[_] ; π[_] )
private variable Ξ± Ο β : Level
```
-->
#### The containment order on congruences
For congruences `ΞΈ Ο : Con π¨` we write `ΞΈ β Ο` when the underlying relation of `ΞΈ`
is **contained** in that of `Ο` ("contained" is with respect to subset inclusion on
`β(A Γ A)`). Classically this is the familiar (lattice) partial order on equivalence
relations, and it remains a partial order here β `_β_` is antisymmetric
**with respect to `_β_`**, the equivalence of *mutual set containment*. The only
subtlety is which equality counts as **equal congruences**.
The underlying relation of a congruence inhabits the `BinaryRel` type
(`BinaryRel A β = A β A β Type β`), so mutual containment yields back-and-forth maps
between the proof-types `projβ ΞΈ x y` and `projβ Ο x y` rather than a proof that the
packaged congruences are *propositionally* equal.
Upgrading `_β_` to propositional equality would need function extensionality with
propositional extensionality/univalence (and proof-irrelevance for the `IsCongruence`
witness), and that's simply not available under `--safe --cubical-compatible`; so we
take `_β_` as the equality of congruences, exactly as the `Setoid/` discipline
dictates. Classically `_β_` collapses to propositional equality via propositional
extensionality.
```agda
module _ {π¨ : Algebra Ξ± Ο} where
_β_ : Con π¨ β β Con π¨ β β Type (Ξ± β β)
ΞΈ β Ο = projβ ΞΈ β projβ Ο
infix 4 _β_
_β_ : Con π¨ β β Con π¨ β β Type (Ξ± β β)
ΞΈ β Ο = ΞΈ β Ο Γ Ο β ΞΈ
infix 4 _β_
```
The order is reflexive and transitive, and `_β_` collapses it to a partial order.
```agda
β-refl : {ΞΈ : Con π¨ β} β ΞΈ β ΞΈ
β-refl p = p
β-trans : {ΞΈ Ο Ο : Con π¨ β} β ΞΈ β Ο β Ο β Ο β ΞΈ β Ο
β-trans ΞΈβΟ ΟβΟ p = ΟβΟ (ΞΈβΟ p)
β-reflexive : {ΞΈ Ο : Con π¨ β} β ΞΈ β Ο β ΞΈ β Ο
β-reflexive = projβ
β-antisym : {ΞΈ Ο : Con π¨ β} β ΞΈ β Ο β Ο β ΞΈ β ΞΈ β Ο
β-antisym ΞΈβΟ ΟβΞΈ = ΞΈβΟ , ΟβΞΈ
β-refl : {ΞΈ : Con π¨ β} β ΞΈ β ΞΈ
β-refl = (Ξ» z β z) , (Ξ» z β z)
β-sym : {ΞΈ Ο : Con π¨ β} β ΞΈ β Ο β Ο β ΞΈ
β-sym = swap
β-trans : {ΞΈ Ο Ο : Con π¨ β} β ΞΈ β Ο β Ο β Ο β ΞΈ β Ο
β-trans (ΞΈβΟ , ΟβΞΈ) (ΟβΟ , ΟβΟ) = (Ξ» p β ΟβΟ (ΞΈβΟ p)) , (Ξ» p β ΟβΞΈ (ΟβΟ p))
β-isEquivalence : IsEquivalence (_β_ {β})
β-isEquivalence {β} = record
{ refl = Ξ» {ΞΈ} β β-refl {β} {ΞΈ}
; sym = Ξ» {ΞΈ} {Ο} β β-sym {β} {ΞΈ} {Ο}
; trans = Ξ» {ΞΈ} {Ο} {Ο} β β-trans {β} {ΞΈ} {Ο} {Ο}
}
β-isPartialOrder : IsPartialOrder (_β_ {β}) _β_
β-isPartialOrder {β} = record
{ isPreorder = record { isEquivalence = β-isEquivalence {β}
; reflexive = Ξ» {ΞΈ} {Ο} β β-reflexive {β} {ΞΈ} {Ο}
; trans = Ξ» {ΞΈ} {Ο} {Ο} β β-trans {β} {ΞΈ} {Ο} {Ο}
}
; antisym = Ξ» {ΞΈ} {Ο} β β-antisym {β} {ΞΈ} {Ο}
}
```
#### The bottom and top of the order
The diagonal congruence `π[ π¨ ]` (defined in [Setoid.Congruences.Basic][]) is the
*least* congruence: it is contained in every congruence, because a congruence is
reflexive over `β` and `π[ π¨ ]` relates only `β`-equal pairs. The total congruence
`π[ π¨ ]` is the *greatest*: every congruence is contained in it, since it relates
everything. These are the `β₯` and `β€` of the congruence lattice.
```agda
π-min : {β : Level}(ΞΈ : Con π¨ (Ο β β)) β π[ π¨ ] {β} β ΞΈ
π-min ΞΈ p = reflexive (projβ ΞΈ) (lower p)
π-max : {β : Level}(ΞΈ : Con π¨ β) β ΞΈ β π[ π¨ ] {β}
π-max ΞΈ _ = lift tt
```
#### Meet: the intersection of two congruences
The intersection `ΞΈ β© Ο` holds at `(x , y)` exactly when both `ΞΈ` and `Ο` do. It
is again a congruence: it contains the setoid equality (reflexivity), it is an
equivalence relation (componentwise), and it is compatible with every basic
operation (componentwise, using the compatibility of `ΞΈ` and of `Ο`). We define
the underlying relation first, then bundle the `IsCongruence` proof.
```agda
meetRel : Con π¨ β β Con π¨ β β BinaryRel π[ π¨ ] β
meetRel ΞΈ Ο x y = projβ ΞΈ x y Γ projβ Ο x y
_β§_ : Con π¨ β β Con π¨ β β Con π¨ β
ΞΈ β§ Ο = meetRel ΞΈ Ο , mkcon m-reflexive m-isEquivalence m-compatible
where
ΞΈc = projβ ΞΈ
Οc = projβ Ο
ΞΈe = is-equivalence ΞΈc
Οe = is-equivalence Οc
open Setoid π»[ π¨ ] using ( _β_ )
m-reflexive : β {aβ aβ} β aβ β aβ β meetRel ΞΈ Ο aβ aβ
m-reflexive e = reflexive ΞΈc e , reflexive Οc e
open IsEquivalence using (refl ; sym ; trans )
m-isEquivalence : IsEquivalence (meetRel ΞΈ Ο)
m-isEquivalence .refl = ΞΈe .refl , Οe .refl
m-isEquivalence .sym = Ξ» (p , q) β ΞΈe .sym p , Οe .sym q
m-isEquivalence .trans = Ξ» (p , q) (pβ² , qβ²) β ΞΈe .trans p pβ² , Οe .trans q qβ²
m-compatible : π¨ β£β meetRel ΞΈ Ο
m-compatible π uv = is-compatible ΞΈc π (Ξ» i β projβ (uv i))
, is-compatible Οc π (Ξ» i β projβ (uv i))
infixr 7 _β§_
```
The meet is the *greatest lower bound* of its two arguments: it is below each of
them, and it is above any common lower bound. These three facts are exactly the
`Infimum` of `_β_` at `_β§_`.
```agda
β§-lowerΛ‘ : {ΞΈ Ο : Con π¨ β} β ΞΈ β§ Ο β ΞΈ
β§-lowerΛ‘ = projβ
β§-lowerΚ³ : {ΞΈ Ο : Con π¨ β} β ΞΈ β§ Ο β Ο
β§-lowerΚ³ = projβ
β§-greatest : {ΞΈ Ο Ο : Con π¨ β} β Ο β ΞΈ β Ο β Ο β Ο β ΞΈ β§ Ο
β§-greatest ΟβΞΈ ΟβΟ p = ΟβΞΈ p , ΟβΟ p
β§-infimum : Infimum (_β_ {β}) _β§_
β§-infimum ΞΈ Ο = projβ , projβ , Ξ» Ο ΟβΞΈ ΟβΟ p β ΟβΞΈ p , ΟβΟ p
open IsMeetSemilattice
β§-isMeetSemilattice : IsMeetSemilattice (_β_ {β}) _β_ _β§_
β§-isMeetSemilattice .isPartialOrder = β-isPartialOrder
β§-isMeetSemilattice .infimum = β§-infimum
```
#### The poset and meet-semilattice of congruences
Finally we assemble the standard-library bundles. At a fixed relation level `β`,
`Con-Poset π¨` is the poset `(Con π¨, β, β)` and `Con-MeetSemilattice π¨` equips it
with the meet `_β§_`. (The full lattice and complete lattice, with the join and
the bounds `β₯`/`β€`, are built in the subsequent steps of #271.)
```agda
module _ (π¨ : Algebra Ξ± Ο) {β : Level} where
Con-Poset : Poset (Ξ± β Ο β ov β) (Ξ± β β) (Ξ± β β)
Con-Poset = record { Carrier = Con π¨ β ; _β_ = _β_ ; _β€_ = _β_
; isPartialOrder = β-isPartialOrder }
Con-MeetSemilattice : MeetSemilattice (Ξ± β Ο β ov β) (Ξ± β β) (Ξ± β β)
Con-MeetSemilattice = record { Carrier = Con π¨ β
; _β_ = _β_
; _β€_ = _β_
; _β§_ = _β§_
; isMeetSemilattice = β§-isMeetSemilattice
}
```