1-- Distributive and modular lattices, cancellation, and unique complements2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Lattice.Distributive8import Complete910predicate IsDistributiveLattice (A r : Set) :=11 IsLattice(A, r) ∧12 (∀ x ∈ A, ∀ y ∈ A, ∀ z ∈ A,13 meet(A, r, x, join(A, r, y, z)) = join(A, r, meet(A, r, x, y), meet(A, r, x, z)))1415predicate IsModularLattice (A r : Set) :=16 IsLattice(A, r) ∧17 (∀ x ∈ A, ∀ y ∈ A, ∀ z ∈ A, relates(r, y, x) →18 meet(A, r, x, join(A, r, y, z)) = join(A, r, y, meet(A, r, x, z)))1920predicate BoundedDistributiveLattice (A r bot top : Set) :=21 IsDistributiveLattice(A, r) ∧ Least(A, r, A, bot) ∧ Greatest(A, r, A, top)2223theorem IsDistributiveLattice.lattice (A r : Set)24requires h : IsDistributiveLattice(A, r)25shows IsLattice(A, r)26proof27simp [IsDistributiveLattice]2829theorem IsDistributiveLattice.meet_join (A r x y z : Set)30requires h : IsDistributiveLattice(A, r)31requires hx : x ∈ A32requires hy : y ∈ A33requires hz : z ∈ A34shows35 meet(A, r, x, join(A, r, y, z)) = join(A, r, meet(A, r, x, y), meet(A, r, x, z))36proof37rcases h with⟨lattice, law⟩38exact law with x, hx, y, hy, z, hz3940theorem IsDistributiveLattice.meet_join_right (A r x y z : Set)41requires h : IsDistributiveLattice(A, r)42requires hx : x ∈ A43requires hy : y ∈ A44requires hz : z ∈ A45shows46 meet(A, r, join(A, r, x, y), z) = join(A, r, meet(A, r, x, z), meet(A, r, y, z))47proof48have lattice := IsDistributiveLattice.lattice with h49have xyA := join.member with lattice, hx, hy50have outer := meet.commutative with lattice, xyA, hz51have leftSwap := meet.commutative with lattice, hz, hx52have rightSwap := meet.commutative with lattice, hz, hy53have expand := IsDistributiveLattice.meet_join with h, hz, hx, hy54rw [outer, expand, leftSwap, rightSwap]55rfl5657-- The dual distributive law follows from the first.5859theorem IsDistributiveLattice.join_meet (A r x y z : Set)60requires h : IsDistributiveLattice(A, r)61requires hx : x ∈ A62requires hy : y ∈ A63requires hz : z ∈ A64shows65 join(A, r, x, meet(A, r, y, z)) = meet(A, r, join(A, r, x, y), join(A, r, x, z))66proof67have lattice := IsDistributiveLattice.lattice with h68have xyA := join.member with lattice, hx, hy69have zxA := meet.member with lattice, hz, hx70have zyA := meet.member with lattice, hz, hy71have expand := IsDistributiveLattice.meet_join with h, xyA, hx, hz72have absorbFirst : meet(A, r, join(A, r, x, y), x) = x73have swap := meet.commutative with lattice, xyA, hx74rw swap75exact meet.absorb with lattice, hx, hy76have swapSecond := meet.commutative with lattice, xyA, hz77have expandSecond := IsDistributiveLattice.meet_join with h, hz, hx, hy78have regroup := join.associative with lattice, hx, zxA, zyA79have absorbSecond := join.absorb_swap with lattice, hx, hz80have swapLast := meet.commutative with lattice, hz, hy81 symm82rw [expand, absorbFirst, swapSecond, expandSecond, ← regroup, absorbSecond,83 swapLast]84rfl8586theorem IsDistributiveLattice.of_join_meet (A r : Set)87requires lattice : IsLattice(A, r)88requires law : ∀ x ∈ A, ∀ y ∈ A, ∀ z ∈ A,89 join(A, r, x, meet(A, r, y, z)) = meet(A, r, join(A, r, x, y), join(A, r, x, z))90shows IsDistributiveLattice(A, r)91proof92constructor93 . exact lattice94 . intros x hx y hy z hz95have xyA := meet.member with lattice, hx, hy96have zxA := join.member with lattice, hz, hx97have zyA := join.member with lattice, hz, hy98have expand := law with meet(A, r, x, y), xyA, x, hx, z, hz99have absorbFirst : join(A, r, meet(A, r, x, y), x) = x100have swap := join.commutative with lattice, xyA, hx101rw swap102exact join.absorb with lattice, hx, hy103have swapSecond := join.commutative with lattice, xyA, hz104have expandSecond := law with z, hz, x, hx, y, hy105have regroup := meet.associative with lattice, hx, zxA, zyA106have absorbSecond := meet.absorb_swap with lattice, hx, hz107have swapLast := join.commutative with lattice, hz, hy108 symm109rw [expand, absorbFirst, swapSecond, expandSecond, ← regroup,110 absorbSecond, swapLast]111rfl112113theorem IsDistributiveLattice.join_meet_right (A r x y z : Set)114requires h : IsDistributiveLattice(A, r)115requires hx : x ∈ A116requires hy : y ∈ A117requires hz : z ∈ A118shows119 join(A, r, meet(A, r, x, y), z) = meet(A, r, join(A, r, x, z), join(A, r, y, z))120proof121have lattice := IsDistributiveLattice.lattice with h122have xyA := meet.member with lattice, hx, hy123have outer := join.commutative with lattice, xyA, hz124have leftSwap := join.commutative with lattice, hz, hx125have rightSwap := join.commutative with lattice, hz, hy126have expand := IsDistributiveLattice.join_meet with h, hz, hx, hy127rw [outer, expand, leftSwap, rightSwap]128rfl129130theorem IsDistributiveLattice.converse (A r : Set)131requires h : IsDistributiveLattice(A, r)132shows IsDistributiveLattice(A, converse(r, A, A))133proof134have lattice := IsDistributiveLattice.lattice with h135constructor136 . exact IsLattice.converse with lattice137 . intros x hx y hy z hz138have yzA := meet.member with lattice, hy, hz139have xyA := join.member with lattice, hx, hy140have xzA := join.member with lattice, hx, hz141have inner := join.converse with lattice, hy, hz142have outer := meet.converse with lattice, hx, yzA143have leftDual := meet.converse with lattice, hx, hy144have rightDual := meet.converse with lattice, hx, hz145have joined := join.converse with lattice, xyA, xzA146rw [inner, outer, leftDual, rightDual, joined]147exact IsDistributiveLattice.join_meet with h, hx, hy, hz148149-- Modularity150151theorem IsModularLattice.lattice (A r : Set)152requires h : IsModularLattice(A, r)153shows IsLattice(A, r)154proof155simp [IsModularLattice]156157theorem IsModularLattice.law (A r x y z : Set)158requires h : IsModularLattice(A, r)159requires hx : x ∈ A160requires hy : y ∈ A161requires hz : z ∈ A162requires hyx : relates(r, y, x)163shows meet(A, r, x, join(A, r, y, z)) = join(A, r, y, meet(A, r, x, z))164proof165rcases h with⟨lattice, law⟩166exact law with x, hx, y, hy, z, hz, hyx167168theorem IsDistributiveLattice.modular (A r : Set)169requires h : IsDistributiveLattice(A, r)170shows IsModularLattice(A, r)171proof172have lattice := IsDistributiveLattice.lattice with h173constructor174 . exact lattice175 . intros x hx y hy z hz hyx176have expand := IsDistributiveLattice.meet_join with h, hx, hy, hz177have below := meet.of_ge with lattice, hx, hy, hyx178rw [expand, below]179rfl180181-- Cancellation: in a distributive lattice an element is determined by its182-- meet and join with any fixed element.183184theorem IsDistributiveLattice.cancel (A r x y z : Set)185requires h : IsDistributiveLattice(A, r)186requires hx : x ∈ A187requires hy : y ∈ A188requires hz : z ∈ A189requires meets : meet(A, r, x, y) = meet(A, r, x, z)190requires joins : join(A, r, x, y) = join(A, r, x, z)191shows y = z192proof193have lattice := IsDistributiveLattice.lattice with h194have startAbsorb := meet.absorb_swap with lattice, hy, hx195have expand := IsDistributiveLattice.meet_join with h, hy, hx, hz196have swap := meet.commutative with lattice, hy, hx197have collect := IsDistributiveLattice.meet_join_right with h, hx, hy, hz198have endAbsorb := meet.absorb_swap with lattice, hz, hx199have xzA := join.member with lattice, hx, hz200have endSwap := meet.commutative with lattice, xzA, hz201 symm at startAbsorb202 symm at collect203calc204 y = meet(A, r, y, join(A, r, x, y)) := startAbsorb205 _ = meet(A, r, y, join(A, r, x, z)) :=bysimp [joins]206 _ = join(A, r, meet(A, r, y, x), meet(A, r, y, z)) := expand207 _ = join(A, r, meet(A, r, x, y), meet(A, r, y, z)) :=bysimp [swap]208 _ = join(A, r, meet(A, r, x, z), meet(A, r, y, z)) :=bysimp [meets]209 _ = meet(A, r, join(A, r, x, y), z) := collect210 _ = meet(A, r, join(A, r, x, z), z) :=bysimp [joins]211 _ = meet(A, r, z, join(A, r, x, z)) := endSwap212 _ = z := endAbsorb213214-- Bounded distributive lattices and the uniqueness of complements215216theorem BoundedDistributiveLattice.distributive (A r bot top : Set)217requires h : BoundedDistributiveLattice(A, r, bot, top)218shows IsDistributiveLattice(A, r)219proof220simp [BoundedDistributiveLattice]221222theorem BoundedDistributiveLattice.lattice (A r bot top : Set)223requires h : BoundedDistributiveLattice(A, r, bot, top)224shows IsLattice(A, r)225proof226exact IsDistributiveLattice.lattice with227 (BoundedDistributiveLattice.distributive with h)228229theorem BoundedDistributiveLattice.bounded (A r bot top : Set)230requires h : BoundedDistributiveLattice(A, r, bot, top)231shows IsBoundedLattice(A, r, bot, top)232proof233rcases h with⟨distributive, least, greatest⟩234have lattice := IsDistributiveLattice.lattice with distributive235exact IsBoundedLattice.of_bounds with lattice, least, greatest236237theorem BoundedDistributiveLattice.of_bounds (A r bot top : Set)238requires distributive : IsDistributiveLattice(A, r)239requires bounded : IsBoundedLattice(A, r, bot, top)240shows BoundedDistributiveLattice(A, r, bot, top)241proof242refine⟨distributive, IsBoundedLattice.least with bounded,243 IsBoundedLattice.greatest with bounded⟩244245theorem BoundedDistributiveLattice.converse (A r bot top : Set)246requires h : BoundedDistributiveLattice(A, r, bot, top)247shows BoundedDistributiveLattice(A, converse(r, A, A), top, bot)248proof249have distributive := BoundedDistributiveLattice.distributive with h250have bounded := BoundedDistributiveLattice.bounded with h251exact BoundedDistributiveLattice.of_bounds with252 (IsDistributiveLattice.converse with distributive), (IsBoundedLattice.converse with bounded)253254theorem Complementary.unique (A r bot top x y z : Set)255requires h : BoundedDistributiveLattice(A, r, bot, top)256requires hx : x ∈ A257requires hy : Complementary(A, r, bot, top, x, y)258requires hz : Complementary(A, r, bot, top, x, z)259shows y = z260proof261have distributive := BoundedDistributiveLattice.distributive with h262have yA := Complementary.member with hy263have zA := Complementary.member with hz264have meetY := Complementary.meet with hy265have meetZ := Complementary.meet with hz266have joinY := Complementary.join with hy267have joinZ := Complementary.join with hz268have meets : meet(A, r, x, y) = meet(A, r, x, z)269rw [meetY, meetZ]270rfl271have joins : join(A, r, x, y) = join(A, r, x, z)272rw [joinY, joinZ]273rfl274exact IsDistributiveLattice.cancel with distributive, hx, yA, zA, meets, joins275276-- The powerset lattice is distributive.277278theorem powersetOrder.distributive (X : Set)279shows IsDistributiveLattice(𝒫(X), powersetOrder(X))280proof281constructor282 . exact powersetOrder.lattice at X283 . intros B hB C hC D hD284have CX := powerset.membership_iff.forward with hC285have DX := powerset.membership_iff.forward with hD286have BX := powerset.membership_iff.forward with hB287have unionIn : C ∪ D ∈𝒫(X) :=288 powerset.membership_iff.backward with (union2.subset with CX, DX)289have leftIn : B ∩ C ∈𝒫(X) :=290 powerset.membership_iff.backward with (Subset.transitive with (intersection.subset_left at B, C), BX)291have rightIn : B ∩ D ∈𝒫(X) :=292 powerset.membership_iff.backward with (Subset.transitive with (intersection.subset_left at B, D), BX)293have innerJoin := powersetOrder.join with hC, hD294have outerMeet := powersetOrder.meet with hB, unionIn295have leftMeet := powersetOrder.meet with hB, hC296have rightMeet := powersetOrder.meet with hB, hD297have outerJoin := powersetOrder.join with leftIn, rightIn298rw [innerJoin, outerMeet, leftMeet, rightMeet, outerJoin]299exact intersection.union2_distrib at B, C, D300301theorem powersetOrder.bounded_distributive (X : Set)302shows BoundedDistributiveLattice(𝒫(X), powersetOrder(X), ∅, X)303proof304exact BoundedDistributiveLattice.of_bounds with305 (powersetOrder.distributive at X), (powersetOrder.bounded at X)306