module Order.Semilattice.Join.NAry where

n-Ary joinsπŸ”—

Let be a join semilattice, and let be a finite family of elements of We can compute joins of in via induction on the size of the family.

  ⋃ᢠ : βˆ€ {n} (f : Fin n β†’ Ob) β†’ Ob
  ⋃ᢠ {0}           f = bot
  ⋃ᢠ {1}           f = f fzero
  ⋃ᢠ {suc (suc n)} f = f fzero βˆͺ ⋃ᢠ (Ξ» i β†’ f (fsuc i))

  ⋃ᢠ-inj : βˆ€ {n} {f : Fin n β†’ Ob} β†’ (i : Fin n) β†’ f i ≀ ⋃ᢠ f
  ⋃ᢠ-inj {1}           fzero    = ≀-refl
  ⋃ᢠ-inj {suc (suc n)} fzero    = l≀βˆͺ
  ⋃ᢠ-inj {suc (suc n)} (fsuc i) = ≀-trans (⋃ᢠ-inj i) r≀βˆͺ

  ⋃ᢠ-universal
    : βˆ€ {n} {f : Fin n β†’ Ob} (x : Ob)
    β†’ (βˆ€ i β†’ f i ≀ x) β†’ ⋃ᢠ f ≀ x
  ⋃ᢠ-universal {0} x p = Β‘
  ⋃ᢠ-universal {1} x p = p fzero
  ⋃ᢠ-universal {suc (suc n)} x p =
    βˆͺ-universal _ (p fzero) (⋃ᢠ-universal x (p βŠ™ fsuc))

  Finite-lubs : βˆ€ {n} (f : Fin n β†’ Ob) β†’ Lub P f
  Finite-lubs f .lub              = ⋃ᢠ f
  Finite-lubs f .has-lub .fam≀lub = ⋃ᢠ-inj
  Finite-lubs f .has-lub .least   = ⋃ᢠ-universal

Furthermore, must also have joins of finitely indexed sets. Let be a finitely indexed set with enumeration and let be an family in is a finite family in so it must have a least upper bound. Furthermore, is surjective, so it must reflect the least upper bound.

  opaque
    Finitely-indexed-lubs
      : βˆ€ {β„“α΅’} {I : Type β„“α΅’}
      β†’ is-finitely-indexed I
      β†’ (f : I β†’ Ob)
      β†’ Lub P f
    Finitely-indexed-lubs {I = I} fin-indexed f = case fin-indexed of Ξ» cov β†’
      cover-reflects-lub (cov .is-cover) (Finite-lubs (f βŠ™ cov .cover))
      where open Finite-cover

Join semilattice homomorphisms must also preserve finite joins. This follows from another induction on the size of the family we are taking a join over.

module
  _ {o β„“ o' β„“'} {P : Poset o β„“} {Q : Poset o' β„“'} {f : Monotone P Q} {Pl Ql}
    (hom : is-join-slat-hom f Pl Ql) where abstract

  private
    module Pβ‚— = is-join-semilattice Pl
    module Qβ‚— = is-join-semilattice Ql

  open is-join-slat-hom hom

  pres-⋃ᢠ : βˆ€ {n} (k : Fin n β†’ ⌞ P ⌟) β†’ f # (⋃ᢠ Pl k) ≑ ⋃ᢠ Ql (apply f βŠ™ k)
  pres-⋃ᢠ {n = 0} k = pres-bot
  pres-⋃ᢠ {n = 1} k = refl
  pres-⋃ᢠ {n = suc (suc n)} k =
    f # (k fzero Pβ‚—.βˆͺ ⋃ᢠ Pl (k βŠ™ fsuc))       β‰‘βŸ¨ pres-βˆͺ _ _ βŸ©β‰‘
    f # (k fzero) Qβ‚—.βˆͺ f # (⋃ᢠ Pl (k βŠ™ fsuc)) β‰‘βŸ¨ apβ‚‚ Qβ‚—._βˆͺ_ refl (pres-⋃ᢠ (k βŠ™ fsuc)) βŸ©β‰‘
    ⋃ᢠ Ql (apply f βŠ™ k)                       ∎

  pres-fin-lub
    : βˆ€ {n} (k : Fin n β†’ ⌞ P ⌟) (x : ⌞ P ⌟)
    β†’ is-lub P k x
    β†’ is-lub Q (Ξ» x β†’ f # (k x)) (f # x)
  pres-fin-lub k x lub = done where
    rem₁ : x ≑ ⋃ᢠ Pl k
    rem₁ = lub-unique lub (Finite-lubs Pl k .has-lub)

    remβ‚‚ : f # x ≑ ⋃ᢠ Ql (apply f βŠ™ k)
    remβ‚‚ = ap (apply f) rem₁ βˆ™ pres-⋃ᢠ k

    done : is-lub Q (Ξ» x β†’ f # k x) (f # x)
    done = subst (is-lub Q (apply f βŠ™ k)) (sym remβ‚‚) (Finite-lubs Ql _ .has-lub)

  pres-finite-lub
    : βˆ€ {β„“α΅’} {I : Type β„“α΅’}
    β†’ Finite I
    β†’ (k : I β†’ ⌞ P ⌟)
    β†’ (x : ⌞ P ⌟)
    β†’ is-lub P k x
    β†’ is-lub Q (Ξ» x β†’ f # (k x)) (f # x)
  pres-finite-lub I-finite k x P-lub = case I-finite .enumeration of Ξ» enum β†’
    cast-is-lub (enum e⁻¹) (Ξ» _ β†’ refl) $
    pres-fin-lub (k βŠ™ Equiv.from enum) x $
    cast-is-lub enum (Ξ» x β†’ sym (ap k (Equiv.Ξ· enum x))) P-lub

As a corollary, join semilattice homomorphisms must also preserve joins of finitely-indexed sets.

  pres-finitely-indexed-lub
    : βˆ€ {β„“α΅’} {I : Type β„“α΅’}
    β†’ is-finitely-indexed I
    β†’ (k : I β†’ ⌞ P ⌟)
    β†’ (x : ⌞ P ⌟)
    β†’ is-lub P k x
    β†’ is-lub Q (Ξ» x β†’ f # (k x)) (f # x)
  pres-finitely-indexed-lub I-fin-indexed k x P-lub = case I-fin-indexed of Ξ» cov β†’
    cover-reflects-is-lub (Finite-cover.is-cover cov) $
    pres-fin-lub (k βŠ™ Finite-cover.cover cov) x $
    cover-preserves-is-lub (Finite-cover.is-cover cov) P-lub