Lattices.Free.Canonical.Joinands¶
Canonical joinands¶
This is the Lattices.Free.Canonical.Joinands module of the agda-lattices library.
Let w be an element of the free lattice. If the canonical form of w is a join
t₁ ∨ ⋯ ∨ tₙ, the elements the tᵢ represent are the canonical joinands of
w; otherwise (w is join irreducible) its only canonical joinand is w itself
(Freese, Ježek, and Nation (1995), Section I.3). The canonical meetands are
dual. Theorem 1.19 says that the canonical joinands refine every join
representation of w: if w = u₁ ∨ ⋯ ∨ uₘ, then every canonical joinand of w
lies below some uⱼ. In this sense the canonical join representation is the
best way to write w as a join, and the theorem is the form in which canonical
forms are used: semidistributivity of free lattices is a short consequence, and
so are the later arithmetic of free lattices and the theory of their
sublattices.
Here canonicalJoinands w is the list of the lattice terms
embedded from the joinands of the canonical form computed by
Lattices.Free.Canonical.Algorithm, and Theorem 1.19
(canonicalJoinands-refine) is Lemma 1.16 of
Lattices.Free.Canonical.Uniqueness read for that list. The module closes
with Theorem 1.17 read through the same lists: equal elements have the same
canonical joinands, up to order and equality in the free lattice
(canonicalJoinands-≈ˡ), so that "u is a canonical joinand
of w", read up to equality, depends only on the elements u and w
(canonicalJoinand-resp).
Refinement for a canonical term¶
Theorem 1.19 is first proved for an arbitrary canonical term C and a join
representation of the element it represents (joinands-refine),
by cases on the shape of C. The joinand of a generator is the generator, which
is join prime. The joinands of a canonical join are covered by Lemma 1.16. The
joinand of a canonical meet ⋀ⱼ tⱼ is the meet itself: by Whitman's condition it
lies below some uⱼ, or some meetand tⱼ lies below the join of the uⱼ,
which is the meet itself, hence below every meetand; and no member of an
antichain of two or more lies below all the others. meetands-refine
is the dual.
module _ {X : Type χ} where open Antichains {A = CJand X} (λ u v → ⌊ u ⌋ᴶ ≤ʷ ⌊ v ⌋ᴶ) ≤ʷ-trans using () renaming ( antichain-no-max to no-maxᴶ ) open Antichains {A = CMand X} (λ u v → ⌊ u ⌋ᴹ ≤ʷ ⌊ v ⌋ᴹ) ≤ʷ-trans using () renaming ( antichain-no-min to no-minᴹ ) joinands-refine : (C : CTerm X) → IsCanonical C → {u : LatTerm X} {us : List (LatTerm X)} → ⌊ C ⌋ ≈ʷ ⋁⁺ u us → ∀ {a} → a ∈ asListJ (joinandsOf C) → Any (⌊ a ⌋ᴶ ≤ʷ_) (u ∷ us) joinands-refine (genᶜ _) _ (p , _) (here refl) = gen-⋁⁺-prime p joinands-refine (joinᶜ _ _) (cjoin _ _ _ c4) e a∈ = ⋁ᴶ-refines c4 e a∈ joinands-refine (meetᶜ _ _) (cmeet ne _ ac _) (p , q) (here refl) with W-list-ᴹ⁺ p ... | inj₁ r = let (_ , m∈ , m≤) = find r in ⊥-elim (no-minᴹ ac ne m∈ (λ v∈ → ≤ʷ-trans m≤ (≤ʷ-trans q (⋀ᴹ-lower v∈)))) ... | inj₂ r = r meetands-refine : (C : CTerm X) → IsCanonical C → {u : LatTerm X} {us : List (LatTerm X)} → ⌊ C ⌋ ≈ʷ ⋀⁺ u us → ∀ {a} → a ∈ asListM (meetandsOf C) → Any (_≤ʷ ⌊ a ⌋ᴹ) (u ∷ us) meetands-refine (genᶜ _) _ (_ , q) (here refl) = ⋀⁺-gen-below q meetands-refine (meetᶜ _ _) (cmeet _ _ _ c4) e a∈ = ⋀ᴹ-refines c4 e a∈ meetands-refine (joinᶜ _ _) (cjoin ne _ ac _) (p , q) (here refl) with W-list-⁺ᴶ q ... | inj₁ r = r ... | inj₂ r = let (_ , j∈ , ≤j) = find r in ⊥-elim (no-maxᴶ ac ne j∈ (λ v∈ → ≤ʷ-trans (⋁ᴶ-upper v∈) (≤ʷ-trans p ≤j)))
Theorem 1.19¶
canonicalJoinands w and canonicalMeetands w are the
lattice terms of the joinands and meetands of the canonical form of w. Each
canonical joinand lies below w (canonicalJoinands-upper), and
w lies below every common upper bound of them
(canonicalJoinands-least), so w is their join; dually for the
canonical meetands. Theorem 1.19 (canonicalJoinands-refine) and
its dual (canonicalMeetands-refine) are the refinement lemmas
above, applied to the canonical form of w, which is canonical and represents w.
module _ {X : Type χ} (_≟_ : DecidableEquality X) where open Canonicalization _≟_ using ( canonical ; canonical-sound ; canonical-isCanonical ) canonicalJoinands : LatTerm X → List (LatTerm X) canonicalJoinands w = map ⌊_⌋ᴶ (asListJ (joinandsOf (canonical w))) canonicalMeetands : LatTerm X → List (LatTerm X) canonicalMeetands w = map ⌊_⌋ᴹ (asListM (meetandsOf (canonical w))) canonicalJoinands-upper : {w c : LatTerm X} → c ∈ canonicalJoinands w → c ≤ʷ w canonicalJoinands-upper {w} c∈ with ∈-map⁻ ⌊_⌋ᴶ c∈ ... | _ , a∈ , refl = ≤ʷ-trans (⋁ᴶ-upper a∈) (subst (_≤ʷ w) (sym (joinandsOf-sound (canonical w))) (proj₁ (canonical-sound w))) canonicalJoinands-least : {w z : LatTerm X} → (∀ {c} → c ∈ canonicalJoinands w → c ≤ʷ z) → w ≤ʷ z canonicalJoinands-least {w} f = ≤ʷ-trans (proj₂ (canonical-sound w)) (subst (_≤ʷ _) (joinandsOf-sound (canonical w)) (⋁ᴶ-least λ a∈ → f (∈-map⁺ ⌊_⌋ᴶ a∈))) canonicalMeetands-lower : {w c : LatTerm X} → c ∈ canonicalMeetands w → w ≤ʷ c canonicalMeetands-lower {w} c∈ with ∈-map⁻ ⌊_⌋ᴹ c∈ ... | _ , a∈ , refl = ≤ʷ-trans (proj₂ (canonical-sound w)) (subst (_≤ʷ _) (meetandsOf-sound (canonical w)) (⋀ᴹ-lower a∈)) canonicalMeetands-greatest : {w z : LatTerm X} → (∀ {c} → c ∈ canonicalMeetands w → z ≤ʷ c) → z ≤ʷ w canonicalMeetands-greatest {w} f = ≤ʷ-trans (subst (_ ≤ʷ_) (meetandsOf-sound (canonical w)) (⋀ᴹ-greatest λ a∈ → f (∈-map⁺ ⌊_⌋ᴹ a∈))) (proj₁ (canonical-sound w)) canonicalJoinands-refine : {w u : LatTerm X} {us : List (LatTerm X)} → w ≈ʷ ⋁⁺ u us → ∀ {c} → c ∈ canonicalJoinands w → Any (c ≤ʷ_) (u ∷ us) canonicalJoinands-refine {w} e c∈ with ∈-map⁻ ⌊_⌋ᴶ c∈ ... | _ , a∈ , refl = joinands-refine (canonical w) (canonical-isCanonical w) (≈ʷ-trans (canonical-sound w) e) a∈ canonicalMeetands-refine : {w u : LatTerm X} {us : List (LatTerm X)} → w ≈ʷ ⋀⁺ u us → ∀ {c} → c ∈ canonicalMeetands w → Any (_≤ʷ c) (u ∷ us) canonicalMeetands-refine {w} e c∈ with ∈-map⁻ ⌊_⌋ᴹ c∈ ... | _ , a∈ , refl = meetands-refine (canonical w) (canonical-isCanonical w) (≈ʷ-trans (canonical-sound w) e) a∈
Theorem 1.17, read through the lists¶
Theorem 1.17 (≈ʷ⇒≈ᶜ of Lattices.Free.Canonical.Uniqueness)
says that two canonical terms of one element differ only in the order of
children, at every level. Read for the lists of canonical joinands, it says
that two equal elements have the same canonical joinands up to order and
equality in the free lattice. The relation is _≈ˡ_, built as
_≈ᶜ_ is: some permutation (_↭_) of the first
list is pointwise equal (Pointwise _≈ʷ_) to the second. It
is an equivalence (≈ˡ-refl, ≈ˡ-sym,
≈ˡ-trans), the symmetry and transitivity moving a permutation
across a pointwise relation with PW-↭.
-- Two lists of lattice terms that agree up to order and equality in the free lattice. infix 4 _≈ˡ_ _≈ˡ_ : {X : Type χ} → List (LatTerm X) → List (LatTerm X) → Type χ us ≈ˡ vs = Σ[ zs ∈ List _ ] us ↭ zs × Pointwise _≈ʷ_ zs vs module _ {X : Type χ} where private PW-≈ʷ-refl : (us : List (LatTerm X)) → Pointwise _≈ʷ_ us us PW-≈ʷ-refl [] = [] PW-≈ʷ-refl (_ ∷ us) = ≈ʷ-refl ∷ PW-≈ʷ-refl us -- The relation is an equivalence. ≈ˡ-refl : {us : List (LatTerm X)} → us ≈ˡ us ≈ˡ-refl {us} = us , ↭-refl , PW-≈ʷ-refl us ≈ˡ-sym : {us vs : List (LatTerm X)} → us ≈ˡ vs → vs ≈ˡ us ≈ˡ-sym (_ , p , q) = PW-↭ (Pointwise.symmetric ≈ʷ-sym q) (↭-sym p) ≈ˡ-trans : {us vs ws : List (LatTerm X)} → us ≈ˡ vs → vs ≈ˡ ws → us ≈ˡ ws ≈ˡ-trans (_ , p , q) (_ , p' , q') = let (ys , p'' , q'') = PW-↭ q p' in ys , ↭-trans p p'' , Pointwise.transitive ≈ʷ-trans q'' q'
Membership up to equality is invariant under the relation
(Any-resp-≈ˡ): a witness moves along the permutation, and then
across the pointwise equality.
-- A member up to equality of one list is a member up to equality of the other. Any-resp-≈ˡ : {u : LatTerm X} {us vs : List (LatTerm X)} → us ≈ˡ vs → Any (u ≈ʷ_) us → Any (u ≈ʷ_) vs Any-resp-≈ˡ (_ , p , q) i = across q (Any-resp-↭ p i) where across : {u : LatTerm X} {zs vs : List (LatTerm X)} → Pointwise _≈ʷ_ zs vs → Any (u ≈ʷ_) zs → Any (u ≈ʷ_) vs across (r ∷ _) (here e) = here (≈ʷ-trans e r) across (_ ∷ q) (there i) = there (across q i)
Two canonical terms related by _≈ᶜ_ have related lists of
joinands (≈ᶜ⇒joinands-≈ˡ), by cases on the relation: two
generators are equal; two joins have permuted, pointwise related children, and
≈ᶜᴶs⇒≈ʷ turns the pointwise relation into pointwise equality
of the embedded children; and two meets are each their own only joinand, equal
by ≈ᶜ⇒≈ʷ. Meetands are dual
(≈ᶜ⇒meetands-≈ˡ).
-- Related canonical terms have related joinands, and related meetands. ≈ᶜ⇒joinands-≈ˡ : {C D : CTerm X} → C ≈ᶜ D → map ⌊_⌋ᴶ (asListJ (joinandsOf C)) ≈ˡ map ⌊_⌋ᴶ (asListJ (joinandsOf D)) ≈ᶜ⇒joinands-≈ˡ (gen≈ refl) = ≈ˡ-refl ≈ᶜ⇒joinands-≈ˡ (join≈ p q) = _ , ↭-map⁺ ⌊_⌋ᴶ p , Pointwise.map⁺ ⌊_⌋ᴶ ⌊_⌋ᴶ (≈ᶜᴶs⇒≈ʷ q) ≈ᶜ⇒joinands-≈ˡ e@(meet≈ _ _) = _ , ↭-refl , ≈ᶜ⇒≈ʷ e ∷ [] ≈ᶜ⇒meetands-≈ˡ : {C D : CTerm X} → C ≈ᶜ D → map ⌊_⌋ᴹ (asListM (meetandsOf C)) ≈ˡ map ⌊_⌋ᴹ (asListM (meetandsOf D)) ≈ᶜ⇒meetands-≈ˡ (gen≈ refl) = ≈ˡ-refl ≈ᶜ⇒meetands-≈ˡ e@(join≈ _ _) = _ , ↭-refl , ≈ᶜ⇒≈ʷ e ∷ [] ≈ᶜ⇒meetands-≈ˡ (meet≈ p q) = _ , ↭-map⁺ ⌊_⌋ᴹ p , Pointwise.map⁺ ⌊_⌋ᴹ ⌊_⌋ᴹ (≈ᶜᴹs⇒≈ʷ q)
So the joinands of any canonical term of w are the canonical joinands of w
up to order and equality (joinands-≈ˡ), by Theorem 1.17 applied
to that term and the computed canonical form. This is the list form of
Theorem 1.17: if w ≈ʷ w', then canonicalJoinands w ≈ˡ canonicalJoinands w'
(canonicalJoinands-≈ˡ), and dually for meetands
(canonicalMeetands-≈ˡ). Its corollary
(canonicalJoinand-resp, canonicalMeetand-resp)
is the reading of "u is a canonical joinand of w" that the rest of the
development uses, Any (u ≈ʷ_) (canonicalJoinands w): it holds of w exactly
when it holds of any element equal to w.
module _ {X : Type χ} (_≟_ : DecidableEquality X) where open Canonicalization _≟_ using ( canonical ; canonical-sound ; canonical-isCanonical ) -- The joinands of any canonical term of w are the canonical joinands of w. joinands-≈ˡ : (C : CTerm X) → IsCanonical C → {w : LatTerm X} → ⌊ C ⌋ ≈ʷ w → map ⌊_⌋ᴶ (asListJ (joinandsOf C)) ≈ˡ canonicalJoinands _≟_ w joinands-≈ˡ C cC {w} e = ≈ᶜ⇒joinands-≈ˡ (≈ʷ⇒≈ᶜ C (canonical w) cC (canonical-isCanonical w) (≈ʷ-trans e (≈ʷ-sym (canonical-sound w)))) meetands-≈ˡ : (C : CTerm X) → IsCanonical C → {w : LatTerm X} → ⌊ C ⌋ ≈ʷ w → map ⌊_⌋ᴹ (asListM (meetandsOf C)) ≈ˡ canonicalMeetands _≟_ w meetands-≈ˡ C cC {w} e = ≈ᶜ⇒meetands-≈ˡ (≈ʷ⇒≈ᶜ C (canonical w) cC (canonical-isCanonical w) (≈ʷ-trans e (≈ʷ-sym (canonical-sound w)))) -- Theorem 1.17, list form: equal elements have the same canonical joinands. canonicalJoinands-≈ˡ : {w w' : LatTerm X} → w ≈ʷ w' → canonicalJoinands _≟_ w ≈ˡ canonicalJoinands _≟_ w' canonicalJoinands-≈ˡ {w} e = joinands-≈ˡ (canonical w) (canonical-isCanonical w) (≈ʷ-trans (canonical-sound w) e) canonicalMeetands-≈ˡ : {w w' : LatTerm X} → w ≈ʷ w' → canonicalMeetands _≟_ w ≈ˡ canonicalMeetands _≟_ w' canonicalMeetands-≈ˡ {w} e = meetands-≈ˡ (canonical w) (canonical-isCanonical w) (≈ʷ-trans (canonical-sound w) e) -- Being a canonical joinand, up to equality, depends only on the element. canonicalJoinand-resp : {w w' u : LatTerm X} → w ≈ʷ w' → Any (u ≈ʷ_) (canonicalJoinands _≟_ w) → Any (u ≈ʷ_) (canonicalJoinands _≟_ w') canonicalJoinand-resp e = Any-resp-≈ˡ (canonicalJoinands-≈ˡ e) canonicalMeetand-resp : {w w' u : LatTerm X} → w ≈ʷ w' → Any (u ≈ʷ_) (canonicalMeetands _≟_ w) → Any (u ≈ʷ_) (canonicalMeetands _≟_ w') canonicalMeetand-resp e = Any-resp-≈ˡ (canonicalMeetands-≈ˡ e)