---
title: SIP for distributive lattices
author: Ayberk Tosun
date-started: 2024-05-16
---
\begin{code}[hide]
{-# OPTIONS --safe --without-K #-}
open import MLTT.Spartan hiding (𝟚; ₀; ₁)
open import UF.FunExt
open import UF.PropTrunc
open import UF.Size
open import UF.Subsingletons
open import UF.UA-FunExt
open import UF.Univalence
module Locales.SIP.DistributiveLatticeSIP
(ua : Univalence)
(pt : propositional-truncations-exist)
(sr : Set-Replacement pt)
where
private
fe : Fun-Ext
fe {𝓤} {𝓥} = univalence-gives-funext' 𝓤 𝓥 (ua 𝓤) (ua (𝓤 ⊔ 𝓥))
pe : Prop-Ext
pe {𝓤} = univalence-gives-propext (ua 𝓤)
open import Locales.DistributiveLattice.Definition fe pt
open import Locales.DistributiveLattice.Definition-SigmaBased fe pt
open import Locales.DistributiveLattice.Homomorphism fe pt
open import Locales.DistributiveLattice.Isomorphism fe pt
open import Locales.Frame pt fe
open import UF.Base
open import UF.Equiv
open import UF.Logic
open import UF.SIP
open import UF.SubtypeClassifier
open AllCombinators pt fe
open sip hiding (⟨_⟩)
\end{code}
We work in a module parameterized by two distributive lattice structures that
we call `str₁` and `str₂`.
\begin{code}
module SIP-For-Distributive-Lattices
{A : 𝓤 ̇ }
(str₁ str₂ : Distributive-Lattice-Structure A)
where
\end{code}
We denote by `K` and `L` the distributive lattices `(A , str₁)` and `(B , str₂)`.
\begin{code}
K : Distributive-Lattice₀ 𝓤
K = A , str₁
L : Distributive-Lattice₀ 𝓤
L = A , str₂
\end{code}
To avoid using projections, we also define the record-based versions of these
two distributive lattices.
\begin{code}
private
Kᵣ : DistributiveLattice 𝓤
Kᵣ = to-distributive-lattice 𝓤 K
Lᵣ : DistributiveLattice 𝓤
Lᵣ = to-distributive-lattice 𝓤 L
\end{code}
We define a bunch of other abbreviations that we will use throughout this
module.
\begin{code}
lattice-data-of-K : Distributive-Lattice-Data A
lattice-data-of-K = pr₁ str₁
lattice-data-of-L : Distributive-Lattice-Data A
lattice-data-of-L = pr₁ str₂
_≤₁_ : A → A → Ω 𝓤
_≤₁_ = λ x y → x ≤[ poset-ofᵈ Kᵣ ] y
_≤₂_ : A → A → Ω 𝓤
_≤₂_ = λ x y → x ≤[ poset-ofᵈ Lᵣ ] y
𝟏₁ : A
𝟏₁ = DistributiveLattice.𝟏 Kᵣ
𝟏₂ : A
𝟏₂ = DistributiveLattice.𝟏 Lᵣ
𝟎₁ : A
𝟎₁ = DistributiveLattice.𝟎 Kᵣ
𝟎₂ : A
𝟎₂ = DistributiveLattice.𝟎 Lᵣ
_∧₁_ : A → A → A
_∧₁_ = λ x y → x ∧∙ y
where
open DistributiveLattice Kᵣ renaming (_∧_ to _∧∙_)
_∧₂_ : A → A → A
_∧₂_ = λ x y → x ∧∙ y
where
open DistributiveLattice Lᵣ renaming (_∧_ to _∧∙_)
_∨₁_ : A → A → A
_∨₁_ = λ x y → x ∨∙ y
where
open DistributiveLattice Kᵣ renaming (_∨_ to _∨∙_)
_∨₂_ : A → A → A
_∨₂_ = λ x y → x ∨∙ y
where
open DistributiveLattice Lᵣ renaming (_∨_ to _∨∙_)
open HomomorphicEquivalences Kᵣ Lᵣ
homomorphic-identity-equivalence-gives-order-agreement
: is-homomorphic (≃-refl ∣ Lᵣ ∣ᵈ) holds
→ _≤₁_ = _≤₂_
homomorphic-identity-equivalence-gives-order-agreement (𝓂₁ , 𝓂₂) =
dfunext fe λ x → dfunext fe λ y → † x y
where
† : (x y : ∣ Kᵣ ∣ᵈ) → x ≤₁ y = x ≤₂ y
† x y = ⇔-gives-= pe (x ≤₁ y) (x ≤₂ y) ‡
where
‡ : (x ≤₁ y) ⇔ (x ≤₂ y) = ⊤
‡ = holds-gives-equal-⊤ pe fe ((x ≤₁ y) ⇔ (x ≤₂ y)) (β , γ)
where
β : (x ≤₁ y ⇒ x ≤₂ y) holds
β = 𝓂₁ (x , y)
γ : (x ≤₂ y ⇒ x ≤₁ y) holds
γ = 𝓂₂ (x , y)
\end{code}
The identity equivalence being homomorphic gives the equality of top elements.
\begin{code}
open DistributiveLatticeIsomorphisms Kᵣ Lᵣ
homomorphic-identity-equivalence-gives-top-agreement
: is-homomorphic (≃-refl ∣ Lᵣ ∣ᵈ) holds
→ 𝟏₁ = 𝟏₂
homomorphic-identity-equivalence-gives-top-agreement 𝒽 = †
where
iso : DistributiveLatticeIsomorphisms.Isomorphismᵈᵣ Kᵣ Lᵣ
iso = to-isomorphismᵈᵣ (≃-refl A , 𝒽)
† : preserves-𝟏 Kᵣ Lᵣ id holds
† = Homomorphismᵈᵣ.h-preserves-𝟏 (Isomorphismᵈᵣ.𝓈 iso)
\end{code}
The identity function being homomorphic gives the equality of bottom elements.
\begin{code}
homomorphic-identity-equivalence-gives-bottom-agreement
: is-homomorphic (≃-refl ∣ Lᵣ ∣ᵈ) holds
→ 𝟎₁ = 𝟎₂
homomorphic-identity-equivalence-gives-bottom-agreement 𝒽 = †
where
iso : DistributiveLatticeIsomorphisms.Isomorphismᵈᵣ Kᵣ Lᵣ
iso = to-isomorphismᵈᵣ (≃-refl A , 𝒽)
† : preserves-𝟎 Kᵣ Lᵣ id holds
† = Homomorphismᵈᵣ.h-preserves-𝟎 (Isomorphismᵈᵣ.𝓈 iso)
\end{code}
The identity function being homomorphic gives the equality of meets.
\begin{code}
homomorphic-identity-equivalence-gives-meet-agreement
: is-homomorphic (≃-refl ∣ Lᵣ ∣ᵈ) holds
→ _∧₁_ = _∧₂_
homomorphic-identity-equivalence-gives-meet-agreement 𝒽 =
dfunext fe λ x → dfunext fe λ y → φ x y
where
iso : Isomorphismᵈᵣ
iso = to-isomorphismᵈᵣ (≃-refl A , 𝒽)
φ : preserves-∧ Kᵣ Lᵣ id holds
φ = Homomorphismᵈᵣ.h-preserves-∧ (Isomorphismᵈᵣ.𝓈 iso)
\end{code}
The identity function being homomorphic gives join agreement.
\begin{code}
homomorphic-identity-equivalence-gives-join-agreement
: is-homomorphic (≃-refl ∣ Lᵣ ∣ᵈ) holds
→ _∨₁_ = _∨₂_
homomorphic-identity-equivalence-gives-join-agreement 𝒽 =
dfunext fe λ x → dfunext fe λ y → φ x y
where
iso : Isomorphismᵈᵣ
iso = to-isomorphismᵈᵣ (≃-refl A , 𝒽)
φ : preserves-∨ Kᵣ Lᵣ id holds
φ = Homomorphismᵈᵣ.h-preserves-∨ (Isomorphismᵈᵣ.𝓈 iso)
\end{code}
If the identity equivalence is homomorphic, then the two distributive lattice
structures must be equal.
\begin{code}
abstract
homomorphic-equivalence-gives-distributive-lattice-data-agreement
: is-homomorphic (≃-refl A) holds
→ distributive-lattice-data-of A str₁ = distributive-lattice-data-of A str₂
homomorphic-equivalence-gives-distributive-lattice-data-agreement 𝒽 = β
where
ϵ : _∨₁_ = _∨₂_
ϵ = homomorphic-identity-equivalence-gives-join-agreement 𝒽
δ : _∧₁_ , _∨₁_ = _∧₂_ , _∨₂_
δ = transport
(λ - → _∧₁_ , _∨₁_ = - , _∨₂_)
(homomorphic-identity-equivalence-gives-meet-agreement 𝒽)
(to-Σ-=' ϵ)
γ : 𝟏₁ , _∧₁_ , _∨₁_ = 𝟏₂ , _∧₂_ , _∨₂_
γ = transport
(λ - → 𝟏₁ , _∧₁_ , _∨₁_ = - , _∧₂_ , _∨₂_)
(homomorphic-identity-equivalence-gives-top-agreement 𝒽)
(to-Σ-=' δ)
β : 𝟎₁ , 𝟏₁ , _∧₁_ , _∨₁_ = 𝟎₂ , 𝟏₂ , _∧₂_ , _∨₂_
β = transport
(λ - → 𝟎₁ , 𝟏₁ , _∧₁_ , _∨₁_ = - , 𝟏₂ , _∧₂_ , _∨₂_)
(homomorphic-identity-equivalence-gives-bottom-agreement 𝒽)
(to-Σ-=' γ)
abstract
homomorphic-equivalence-gives-structural-equality
: is-homomorphic (≃-refl A) holds
→ str₁ = str₂
homomorphic-equivalence-gives-structural-equality 𝒽 =
to-subtype-=
satisfying-distributive-lattice-laws-is-prop
(homomorphic-equivalence-gives-distributive-lattice-data-agreement 𝒽)
\end{code}
The distributive lattice structure is a standard notion of structure.
\begin{code}
distributive-lattice-sns-data : SNS Distributive-Lattice-Structure 𝓤
distributive-lattice-sns-data {𝓤} = ι , ρ , θ
where
ι : (K′ L′ : Distributive-Lattice₀ 𝓤) → sip.⟨ K′ ⟩ ≃ sip.⟨ L′ ⟩ → 𝓤 ̇
ι K′ L′ e = is-homomorphic e holds
where
K′ᵣ = to-distributive-lattice 𝓤 K′
L′ᵣ = to-distributive-lattice 𝓤 L′
open HomomorphicEquivalences K′ᵣ L′ᵣ
ρ : (L : Distributive-Lattice₀ 𝓤) → ι L L (≃-refl sip.⟨ L ⟩)
ρ L = (λ _ → id) , (λ _ → id)
θ : {X : 𝓤 ̇ }
→ (str₁ str₂ : Distributive-Lattice-Structure X)
→ is-equiv (canonical-map ι ρ str₁ str₂)
θ {X} str₁ str₂ = (homomorphic-equivalence-gives-structural-equality , †)
, (homomorphic-equivalence-gives-structural-equality , ‡)
where
open SIP-For-Distributive-Lattices str₁ str₂
open HomomorphicEquivalences
Kᵣ = to-distributive-lattice 𝓤 (X , str₁)
Lᵣ = to-distributive-lattice 𝓤 (X , str₂)
† : (h : is-homomorphic Kᵣ Lᵣ (≃-refl X) holds)
→ let
p = homomorphic-equivalence-gives-structural-equality h
in
canonical-map ι ρ str₁ str₂ p = h
† h = holds-is-prop
(is-homomorphic Kᵣ Lᵣ (≃-refl X))
(canonical-map ι ρ str₁ str₂ (homomorphic-equivalence-gives-structural-equality h))
h
‡ : (p : str₁ = str₂)
→ homomorphic-equivalence-gives-structural-equality (canonical-map ι ρ str₁ str₂ p) = p
‡ p = distributive-lattice-structure-is-set
X
pe
(homomorphic-equivalence-gives-structural-equality (canonical-map ι ρ str₁ str₂ p))
p
\end{code}
We abbreviate this proof by `snsᵈ`.
\begin{code}
private
snsᵈ = distributive-lattice-sns-data
\end{code}
The notion of isomorphism given by `snsᵈ` is trivially equivalent to the type
`Isomorphismᵈ₀`.
\begin{code}
open HomomorphicEquivalences
isomorphism₀-equivalent-to-sns-isomorphism
: (K L : Distributive-Lattice₀ 𝓤)
→ let
Kᵣ = to-distributive-lattice 𝓤 K
Lᵣ = to-distributive-lattice 𝓤 L
in
(K ≃[ snsᵈ ] L) ≃ (Isomorphism₀ Kᵣ Lᵣ)
isomorphism₀-equivalent-to-sns-isomorphism {𝓤} K L = 𝔰 , qinvs-are-equivs 𝔰 †
where
Kᵣ = to-distributive-lattice 𝓤 K
Lᵣ = to-distributive-lattice 𝓤 L
𝔰 : K ≃[ snsᵈ ] L → Isomorphism₀ Kᵣ Lᵣ
𝔰 (f , (e , φ)) = (f , e) , φ
𝔯 : Isomorphism₀ Kᵣ Lᵣ → K ≃[ snsᵈ ] L
𝔯 ((f , e) , φ) = f , (e , φ)
† : qinv 𝔰
† = 𝔯 , (λ _ → refl) , (λ _ → refl)
\end{code}
From this, we get the characterization of equality for distributive lattices.
\begin{code}
characterization-of-distributive-lattice₀-= : (K L : Distributive-Lattice₀ 𝓤)
→ (K = L) ≃ (K ≃[ snsᵈ ] L)
characterization-of-distributive-lattice₀-= {𝓤} K L =
characterization-of-= (ua 𝓤) snsᵈ K L
characterization-of-distributive-lattice-= : (K L : DistributiveLattice 𝓤)
→ (K = L) ≃ (K ≅d≅ L)
characterization-of-distributive-lattice-= {𝓤} K L =
let
K₀ = to-distributive-lattice₀ 𝓤 K
L₀ = to-distributive-lattice₀ 𝓤 L
Ⅱ = characterization-of-distributive-lattice₀-= K₀ L₀
Ⅲ = isomorphism₀-equivalent-to-sns-isomorphism K₀ L₀
Ⅳ = isomorphismᵈᵣ-is-equivalent-to-isomorphism₀ K L
𝔰 : K = L → K₀ = L₀
𝔰 = λ { refl → refl}
𝔯 : K₀ = L₀ → K = L
𝔯 = λ { refl → refl}
† : (𝔯 ∘ 𝔰) ∼ id
† = (λ { refl → refl})
‡ : (𝔰 ∘ 𝔯) ∼ id
‡ = (λ { refl → refl})
goal : (K = L) ≃ (K₀ = L₀)
goal = 𝔰 , qinvs-are-equivs 𝔰 (𝔯 , † , ‡)
in
(K = L) ≃⟨ goal ⟩
(K₀ = L₀) ≃⟨ Ⅱ ⟩
(K₀ ≃[ snsᵈ ] L₀) ≃⟨ Ⅲ ⟩
(Isomorphism₀ K L) ≃⟨ Ⅳ ⟩
(K ≅d≅ L) ■
\end{code}
Finally, we record the fact that isomorphic distributive lattices are _equal_.
\begin{code}
isomorphic-distributive-lattices-are-equal
: (K L : DistributiveLattice 𝓤)
→ K ≅d≅ L
→ K = L
isomorphic-distributive-lattices-are-equal K L =
⌜ ≃-sym (characterization-of-distributive-lattice-= K L) ⌝
\end{code}