open import 1Lab.Prelude open import Algebra.Semilattice open import Cat.Functor.Equivalence open import Cat.Functor.Base open import Cat.Prelude open import Cat.Thin module Algebra.Lattice where
Latticesš
A lattice is a pair of semilattices and which āfit togetherā with equations specifying that and are duals, called absorption laws.
record is-lattice (_ā§_ : A ā A ā A) (_āØ_ : A ā A ā A) : Type (level-of A) where field has-meets : is-semilattice _ā§_ has-joins : is-semilattice _āØ_
We rename the fields of has-meets and has-joins so they refer to the operator in their name, and hide anything extra from the hierarchy.
open is-semilattice has-meets public renaming ( associative to ā§-associative ; commutative to ā§-commutative ; idempotent to ā§-idempotent ) hiding ( has-is-magma ; has-is-semigroup ) open is-semilattice has-joins public renaming ( associative to āØ-associative ; commutative to āØ-commutative ; idempotent to āØ-idempotent ) hiding ( underlying-set ; has-is-magma ; has-is-set ; magma-hlevel )
field ā§-absorbs-āØ : ā {x y} ā (x ā§ (x āØ y)) ā” x āØ-absorbs-ā§ : ā {x y} ā (x āØ (x ā§ y)) ā” x
A lattice structure equips a type with two binary operators, the meet and join , such that is a lattice. Since being a semilattice includes being a set, this means that being a lattice is a property of :
private unquoteDecl eqv = declare-record-iso eqv (quote is-lattice) instance H-Level-is-lattice : ā {M J : A ā A ā A} {n} ā H-Level (is-lattice M J) (suc n) H-Level-is-lattice = prop-instance Ī» x ā let open is-lattice x in is-hlevelā 1 (IsoāEquiv eqv eā»Ā¹) (hlevel 1) x record Lattice-on (A : Type ā) : Type ā where field _Lā§_ : A ā A ā A _LāØ_ : A ā A ā A infixr 40 _Lā§_ infixr 30 _LāØ_ field has-is-lattice : is-lattice _Lā§_ _LāØ_ open is-lattice has-is-lattice public Lattice-onāis-meet-semi : is-semilattice _Lā§_ Lattice-onāis-meet-semi = has-meets Lattice-onāis-join-semi : is-semilattice _LāØ_ Lattice-onāis-join-semi = has-joins open Lattice-on using (Lattice-onāis-meet-semi ; Lattice-onāis-join-semi) public Lattice : ā ā ā Type (lsuc ā) Lattice ā = Ī£ (Lattice-on {ā = ā})
Since the absorption laws are property, not structure, a lattice homomorphism turns out to be a function which is homomorphic for both semilattice structures, i.e.Ā one that independently preserves meets and joins.
record Latticeā (A B : Lattice ā) (f : A .fst ā B .fst) : Type ā where private module A = Lattice-on (A .snd) module B = Lattice-on (B .snd) field pres-ā§ : ā x y ā f (x A.Lā§ y) ā” f x B.Lā§ f y pres-āØ : ā x y ā f (x A.LāØ y) ā” f x B.LāØ f y Latticeā : (A B : Lattice ā) (f : A .fst ā B .fst) ā Type ā Latticeā A B = Latticeā A B ā fst
Using the automated machinery for deriving is-univalent proofs, we get that identification of lattices is the same thing as lattice isomorphism.
Lattice-univalent : ā {ā} ā is-univalent (HomTāStr (Latticeā {ā = ā})) Lattice-univalent {ā = ā} = Derive-univalent-record (record-desc (Lattice-on {ā = ā}) Latticeā (record: field[ Lattice-on._Lā§_ by Latticeā.pres-ā§ ] field[ Lattice-on._LāØ_ by Latticeā.pres-āØ ] axiom[ Lattice-on.has-is-lattice by (Ī» _ ā hlevel 1) ]))
Order-theoreticallyš
We already know that a given semilattice structure can induce one of two posets, depending on whether the semilattice operator is being considered as equipping the poset with meets or joins. Weād then expect that a lattice, having two semi-lattices, would have four poset structures. However, there are only two, which we call the ācovariantā and ācontravariantā orderings.
Latticeācovariant-on : Lattice-on A ā Poset (level-of A) (level-of A) Latticeācovariant-on lat = Semilattice-onāMeet-on (Lattice-onāis-meet-semi lat) Latticeācontravariant-on : Lattice-on A ā Poset (level-of A) (level-of A) Latticeācontravariant-on lat = Semilattice-onāJoin-on (Lattice-onāis-meet-semi lat)
Above, the ācovariant orderā is obtaining by considering the semilattice as inducing meets on the poset (hence the operator being called ). It can also be obtained in a dual way, by considering that induces joins on the poset. By the absorption laws, these constructions give rise to the same poset; We start by defining a monotone map (that is, a Functor) between the two possibilities:
covariant-order-map : (l : Lattice-on A) ā Monotone-map (Semilattice-onāMeet-on (Lattice-onāis-meet-semi l)) (Semilattice-onāJoin-on (Lattice-onāis-join-semi l)) covariant-order-map {A = A} l = F where open Lattice-on l hiding (Lattice-onāis-join-semi ; Lattice-onāis-meet-semi) F : Monotone-map (Semilattice-onāMeet-on (Lattice-onāis-meet-semi l)) (Semilattice-onāJoin-on (Lattice-onāis-join-semi l)) F .Fā = id F .Fā {x} {y} p = q where abstract q : y ā” x LāØ y q = y ā”āØ sym āØ-absorbs-ā§ ā©ā” y LāØ (y Lā§ x) ā”āØ apā _LāØ_ refl ā§-commutative ā©ā” y LāØ (x Lā§ y) ā”āØ apā _LāØ_ refl (sym p) ā©ā” y LāØ x ā”āØ āØ-commutative ā©ā” x LāØ y ā F .F-id = has-is-set _ _ _ _ F .F-ā _ _ = has-is-set _ _ _ _
We now show that this functor is an equivalence: It is fully faithful and split essentially surjective.
covariant-order-map-is-equivalence : (l : Lattice-on A) ā is-equivalence (covariant-order-map l) covariant-order-map-is-equivalence l = ff+split-esoāis-equivalence ff eso where open Lattice-on l hiding (Lattice-onāis-join-semi) import Cat.Reasoning (Semilattice-onāJoin-on (Lattice-onāis-join-semi l) .Poset.underlying) as D
A tiny calculation shows that this functor is fully faithful, and essential surjectivity is immediate:
ff : is-fully-faithful (covariant-order-map l) ff {x} {y} .is-eqv p .centre .fst = x ā”āØ sym ā§-absorbs-āØ ā©ā” x Lā§ (x LāØ y) ā”āØ apā _Lā§_ refl (sym p) ā©ā” x Lā§ y ā ff .is-eqv y .centre .snd = has-is-set _ _ _ _ ff .is-eqv y .paths x = Ī£-path (has-is-set _ _ _ _) (is-propāis-set (has-is-set _ _) _ _ _ _) eso : is-split-eso (covariant-order-map l) eso y .fst = y eso y .snd = D.make-iso (sym āØ-idempotent) (sym āØ-idempotent) (has-is-set _ _ _ _) (has-is-set _ _ _ _)