module Order.Lattice where
Lattices🔗
A lattice is a poset which is a semilattice in two compatible, dual ways. We have a “meet” semilattice , and a “join” semilattice — and we take the order on induced by, for definiteness, the semilattice. The question is then: how do we write, algebraically, a condition on and which guarantees that provides with joins?
The answer is yes! Of course, since if it were not, this page would not be being written. A lattice structure on is a pair of semilattices and , such that the and operations satisfy the two absorption laws with respect to eachother:
field
: is-semilattice ⊤ _∩_
has-meets : is-semilattice ⊥ _∪_
has-joins
: ∀ {x y} → x ∩ (x ∪ y) ≡ x
∩-absorbs-∪ : ∀ {x y} → x ∪ (x ∩ y) ≡ x ∪-absorbs-∩
As usual, a lattice structure on a set is a record packaging together the operations and a proof that they are actually an instance of the algebraic structure we’re talking about.
record Lattice-on {ℓ} (A : Type ℓ) : Type ℓ where
no-eta-equality
field
: A
top : A
bot _∩_ : A → A → A
_∪_ : A → A → A
: is-lattice top _∩_ bot _∪_
has-is-lattice
open is-lattice has-is-lattice public
: Semilattice-on A
meets = record { has-is-semilattice = has-meets }
meets
: Semilattice-on A
joins = record { has-is-semilattice = has-joins }
joins
open Semilattice-on meets using (⋂) public
private module x = Semilattice-on joins renaming (⋂ to ⋃)
open x using (⋃) public
The question then becomes: what is the point of the absorption laws? I’ll tell you! Since we have two semilattice structures on the set, we can imagine defining two orders on it: one is given by iff , and the other is given by . As an exercise, try to work out that these are the same thing in the lattice of subsets of a fixed .
Really, there are four orderings we could imagine defining on a semilattice: iff. , , , and . The absorption laws serve to cut these possibilities in half, because using them we can show that is the same as (and, respectively, is the same as ).
: ∀ {x y} → y ≡ x ∪ y → x ≡ x ∩ y
∪-order→∩-order {x} {y} y=x∪y =
∪-order→∩-order
x ≡˘⟨ ∩-absorbs-∪ ⟩
x ∩ ⌜ x ∪ y ⌝ ≡˘⟨ ap¡ y=x∪y ⟩
x ∩ y ∎
: ∀ {x y} → x ≡ x ∩ y → y ≡ x ∪ y
∩-order→∪-order {x} {y} p =
∩-order→∪-order
y ≡⟨ sym ∪-absorbs-∩ ⟩
y ∪ ⌜ y ∩ x ⌝ ≡⟨ ap! ∩-commutative ⟩
y ∪ ⌜ x ∩ y ⌝ ≡˘⟨ ap¡ p ⟩
y ∪ x ≡⟨ ∪-commutative ⟩ x ∪ y ∎
Using the “cup ordering”, we can establish that cups provide a join of two elements. Since the cup ordering and the “cap ordering” agree, we can prove that cups give a join in that case, too!
: ∀ {x y} → is-join Lattice→poset x y (x ∪ y)
∪-is-join .is-join.l≤join = sym ∩-absorbs-∪
∪-is-join {x} {y} .is-join.r≤join =
∪-is-join
y ≡˘⟨ ∩-absorbs-∪ ⟩
y ∩ ⌜ y ∪ x ⌝ ≡⟨ ap! ∪-commutative ⟩(x ∪ y) ∎
y ∩ {x} {y} .is-join.least ub' x=x∩ub' y=y∩ub' = ∪-order→∩-order $ sym $
∪-is-join (x ∪ y) ∪ ub' ≡˘⟨ ∪-associative ⟩
(∩-order→∪-order y=y∩ub') ⟩
x ∪ ⌜ y ∪ ub' ⌝ ≡˘⟨ ap¡
x ∪ ub' ≡˘⟨ ∩-order→∪-order x=x∩ub' ⟩
ub' ∎
: ∀ {x} → bot P.≤ x
⊥-is-bottom = ∪-order→∩-order (sym ∪-idl) ⊥-is-bottom
Category of lattices🔗
A lattice homomorphism is a function which is, at the same time, a homomorphism for both of the semilattice monoid structures: A function sending bottom to bottom, top to top, joins to joins, and meets to meets. Put more concisely, a function which preserves finite meets and finite joins.
record
is-lattice-hom{ℓ ℓ'} {A : Type ℓ} {B : Type ℓ'}
(f : A → B)
(S : Lattice-on A) (T : Lattice-on B)
: Type (ℓ ⊔ ℓ')
where
private
module S = Lattice-on S
module T = Lattice-on T
field
: f S.top ≡ T.top
pres-⊤ : f S.bot ≡ T.bot
pres-⊥ : ∀ {x y} → f (x S.∩ y) ≡ f x T.∩ f y
pres-∩ : ∀ {x y} → f (x S.∪ y) ≡ f x T.∪ f y pres-∪
Standard equational nonsense implies that (a) lattices and lattice homomorphisms form a precategory; and (b) this is a univalent category.
: ∀ ℓ → Thin-structure ℓ Lattice-on
Lattice-structure
.is-hom f S T .∣_∣ = is-lattice-hom f S T
Lattice-structure ℓ .is-hom f S T .is-tr = hlevel!
Lattice-structure ℓ
.id-is-hom .pres-⊤ = refl
Lattice-structure ℓ .id-is-hom .pres-⊥ = refl
Lattice-structure ℓ .id-is-hom .pres-∩ = refl
Lattice-structure ℓ .id-is-hom .pres-∪ = refl
Lattice-structure ℓ
.∘-is-hom f g α β .pres-⊤ = ap f (β .pres-⊤) ∙ α .pres-⊤
Lattice-structure ℓ .∘-is-hom f g α β .pres-⊥ = ap f (β .pres-⊥) ∙ α .pres-⊥
Lattice-structure ℓ .∘-is-hom f g α β .pres-∩ = ap f (β .pres-∩) ∙ α .pres-∩
Lattice-structure ℓ .∘-is-hom f g α β .pres-∪ = ap f (β .pres-∪) ∙ α .pres-∪ Lattice-structure ℓ
Univalence follows from the special case of considering the identity as a lattice homomorphism — preservation of the operations guarantees that we get (for each operation; , and ), which eventually gives .
.id-hom-unique {s = s} {t = t} α _ = p where
Lattice-structure ℓ open Lattice-on
: s ≡ t
p .top = α .pres-⊤ i
p i .bot = α .pres-⊥ i
p i ._∩_ x y = α .pres-∩ {x} {y} i
p i ._∪_ x y = α .pres-∪ {x} {y} i
p i .has-is-lattice =
p i
is-prop→pathp(λ i → hlevel {T = is-lattice (α .pres-⊤ i) (λ x y → α .pres-∩ i)
(α .pres-⊥ i) (λ x y → α .pres-∪ i)}
1)
(s .has-is-lattice) (t .has-is-lattice) i
: ∀ ℓ → Precategory (lsuc ℓ) ℓ
Lattices = Structured-objects (Lattice-structure ℓ) Lattices ℓ