Ian Ray, started: 2023-09-12 - updated: 2024-02-05.

A Sup Lattice L is a set with a partial order โ‰ค that has suprema of 'small'
types. We will use three universe parameters: ๐“ค for the carrier, ๐“ฆ for the
order values and ๐“ฅ for the families which have suprema.

\begin{code}

{-# OPTIONS --safe --without-K --exact-split #-}

open import MLTT.Spartan
open import UF.Equiv
open import UF.FunExt
open import UF.Hedberg
open import UF.Logic
open import UF.Powerset-MultiUniverse
open import UF.PropTrunc
open import UF.Retracts
open import UF.Sets
open import UF.SubtypeClassifier
open import UF.Size

module OrderedTypes.SupLattice
        (pt : propositional-truncations-exist)
        (fe : Fun-Ext)
       where

open import Locales.Frame pt fe hiding (โŸจ_โŸฉ ; join-of)
open import Slice.Family
open import UF.ImageAndSurjection pt

open AllCombinators pt fe
open PropositionalTruncation pt

\end{code}

We commence by defining sup lattices.

\begin{code}

module _ (๐“ค ๐“ฃ ๐“ฅ : Universe) where

 sup-lattice-data : ๐“ค  ฬ‡ โ†’ ๐“ค โŠ” ๐“ฃ โบ โŠ” ๐“ฅ โบ  ฬ‡
 sup-lattice-data A = (A โ†’ A โ†’ ฮฉ ๐“ฃ) ร— (Fam ๐“ฅ A โ†’ A)

 is-sup-lattice : {A : ๐“ค  ฬ‡} โ†’ sup-lattice-data A โ†’ ๐“ค โŠ” ๐“ฃ โŠ” ๐“ฅ โบ  ฬ‡
 is-sup-lattice {A} (_โ‰ค_ , โ‹_) = is-partial-order A _โ‰ค_ ร— suprema
  where
   open Joins _โ‰ค_
   suprema : ๐“ค โŠ” ๐“ฃ โŠ” ๐“ฅ โบ  ฬ‡
   suprema = (U : Fam ๐“ฅ A) โ†’ ((โ‹ U) is-lub-of U) holds

 sup-lattice-structure : ๐“ค ฬ‡ โ†’ ๐“ค โŠ” ๐“ฅ โบ โŠ” ๐“ฃ โบ ฬ‡
 sup-lattice-structure A = ฮฃ d ๊ž‰ (sup-lattice-data A) , is-sup-lattice d

 Sup-Lattice : (๐“ค โŠ” ๐“ฃ โŠ” ๐“ฅ) โบ  ฬ‡
 Sup-Lattice = ฮฃ A ๊ž‰ ๐“ค  ฬ‡ , sup-lattice-structure A

\end{code}

Now we give some naming conventions which will be useful.

\begin{code}

โŸจ_โŸฉ : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ โ†’ ๐“ค  ฬ‡
โŸจ A , rest โŸฉ = A

order-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ) โ†’ (โŸจ L โŸฉ โ†’ โŸจ L โŸฉ โ†’ ฮฉ ๐“ฃ)
order-of (A , (_โ‰ค_ , โ‹_) , rest) = _โ‰ค_

syntax order-of L x y = x โ‰คโŸจ L โŸฉ y

join-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ) โ†’ Fam ๐“ฅ โŸจ L โŸฉ โ†’ โŸจ L โŸฉ
join-of (A , (_โ‰ค_ , โ‹_) , rest) = โ‹_

syntax join-of L U = โ‹โŸจ L โŸฉ U

partial-orderedness-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
                       โ†’ is-partial-order โŸจ L โŸฉ (order-of L)
partial-orderedness-of (A , (_โ‰ค_ , โ‹_) , order , is-lub-of) = order

reflexivity-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ) โ†’ is-reflexive (order-of L) holds
reflexivity-of L = prโ‚ (prโ‚ (partial-orderedness-of L))

antisymmetry-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ) โ†’ is-antisymmetric (order-of L)
antisymmetry-of L = prโ‚‚ (partial-orderedness-of L)

transitivity-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ) โ†’ is-transitive (order-of L) holds
transitivity-of L = prโ‚‚ (prโ‚ (partial-orderedness-of L))

join-is-lub-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
               โ†’ (U : Fam ๐“ฅ โŸจ L โŸฉ)
               โ†’ ((order-of L) Joins.is-lub-of join-of L U) U holds
join-is-lub-of (A , (_โ‰ค_ , โ‹_) , order , suprema) = suprema

join-is-upper-bound-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
                       โ†’ (U : Fam ๐“ฅ โŸจ L โŸฉ)
                       โ†’ ((order-of L) Joins.is-an-upper-bound-of
                          join-of L U) U holds
join-is-upper-bound-of L U = prโ‚ (join-is-lub-of L U)

join-is-least-upper-bound-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
                             โ†’ (U : Fam ๐“ฅ โŸจ L โŸฉ)
                             โ†’ ((u' , _) : Joins.upper-bound (order-of L) U)
                             โ†’ (order-of L (join-of L U) u') holds
join-is-least-upper-bound-of L U = prโ‚‚ (join-is-lub-of L U)

sethood-of : (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ) โ†’ is-set โŸจ L โŸฉ
sethood-of L =
 type-with-prop-valued-refl-antisym-rel-is-set
  (ฮป x โ†’ ฮป y โ†’ order-of L x y holds)
  (ฮป x โ†’ ฮป y โ†’ holds-is-prop (order-of L x y))
  (ฮป x โ†’ reflexivity-of L x)
  (ฮป x โ†’ ฮป y โ†’ antisymmetry-of L)

\end{code}

We now define monotone endomaps on a sup-lattice and specify monotone endomaps
as a special case.

\begin{code}

module _ where

 is-monotone : {๐“ค ๐“ค' ๐“ฃ ๐“ฃ' ๐“ฅ ๐“ฅ' : Universe}
             โ†’ (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ) (M : Sup-Lattice ๐“ค' ๐“ฃ' ๐“ฅ')
             โ†’ (f : โŸจ L โŸฉ โ†’ โŸจ M โŸฉ)
             โ†’ ๐“ค โŠ” ๐“ฃ โŠ” ๐“ฃ'  ฬ‡
 is-monotone L M f = (x y : โŸจ L โŸฉ)
                   โ†’ (x โ‰คโŸจ L โŸฉ y) holds
                   โ†’ (f x โ‰คโŸจ M โŸฉ f y) holds

 is-monotone-endomap : {๐“ค ๐“ฃ ๐“ฅ : Universe}
                     โ†’ (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
                     โ†’ (f : โŸจ L โŸฉ โ†’ โŸจ L โŸฉ)
                     โ†’ ๐“ค โŠ” ๐“ฃ  ฬ‡
 is-monotone-endomap L f = is-monotone L L f

\end{code}

We now show that when one subset contains another the join of their total
spaces are ordered as expected.

\begin{code}

module _
        {๐“ค ๐“ฃ ๐“ฅ : Universe}
        (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
        {A : ๐“ฅ  ฬ‡}
        (m : A โ†’ โŸจ L โŸฉ)
       where

 open Joins (order-of L)

 joins-preserve-containment : {P : ๐“Ÿ {๐“ฅ} A} {Q : ๐“Ÿ {๐“ฅ} A}
                            โ†’ P โŠ† Q
                            โ†’ ((โ‹โŸจ L โŸฉ ใ€ m , P ใ€‘)
                             โ‰คโŸจ L โŸฉ (โ‹โŸจ L โŸฉ ใ€ m , Q ใ€‘)) holds
 joins-preserve-containment {P} {Q} C =
  (join-is-least-upper-bound-of L ใ€ m , P ใ€‘)
   (โ‹โŸจ L โŸฉ ใ€ m , Q ใ€‘ ,
    (ฮป (b , b-in-P) โ†’ (join-is-upper-bound-of L ใ€ m , Q ใ€‘)
                      (b , C b b-in-P)))

\end{code}

We now show if a type is small and has a map to the carrier then it has a join.

\begin{code}

module _
        {๐“ค ๐“ฃ ๐“ฅ ๐“ฆ : Universe}
        (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
        {T : ๐“ฆ  ฬ‡}
        (m : T โ†’ โŸจ L โŸฉ)
        (T-is-small : T is ๐“ฅ small)
       where
 private
  T' : ๐“ฅ  ฬ‡
  T' = (resized T) T-is-small

  T'-โ‰ƒ-T : T' โ‰ƒ T
  T'-โ‰ƒ-T = resizing-condition T-is-small

  T'-to-T : T' โ†’ T
  T'-to-T = โŒœ T'-โ‰ƒ-T โŒ

  T'-to-T-is-equiv : is-equiv T'-to-T
  T'-to-T-is-equiv = โŒœ T'-โ‰ƒ-T โŒ-is-equiv

  T-to-T' : T โ†’ T'
  T-to-T' =  โŒœ T'-โ‰ƒ-T โŒโปยน

  T'-to-T-has-section : has-section T'-to-T
  T'-to-T-has-section = equivs-have-sections T'-to-T T'-to-T-is-equiv

  T'-to-T-is-section : is-section T'-to-T
  T'-to-T-is-section = equivs-are-sections T'-to-T T'-to-T-is-equiv

  section-T'-to-T : T'-to-T โˆ˜ T-to-T' โˆผ id
  section-T'-to-T = section-equation T'-to-T T'-to-T-has-section

  retraction-T'-to-T : T-to-T' โˆ˜ T'-to-T โˆผ id
  retraction-T'-to-T = inverses-are-retractions' T'-โ‰ƒ-T

  T'-inclusion : T' โ†’ โŸจ L โŸฉ
  T'-inclusion = m โˆ˜ T'-to-T

  s : โŸจ L โŸฉ
  s = โ‹โŸจ L โŸฉ (T' , T'-inclusion)

 open Joins (order-of L)

 sup-of-small-fam-is-lub : (s is-lub-of (T , m)) holds
 sup-of-small-fam-is-lub = (I , III)
  where
   I : (s is-an-upper-bound-of (T , m)) holds
   I t = II
    where
     II : (m t โ‰คโŸจ L โŸฉ s) holds
     II = transport (ฮป - โ†’ (m - โ‰คโŸจ L โŸฉ s) holds)
                    (section-T'-to-T t)
                    (join-is-upper-bound-of L (T' , T'-inclusion) (T-to-T' t))
   III : ((u , _) : upper-bound (T , m)) โ†’ (s โ‰คโŸจ L โŸฉ u) holds
   III (u , is-upbnd-T) = IV
    where
     IV : (s โ‰คโŸจ L โŸฉ u) holds
     IV = join-is-least-upper-bound-of
            L (T' , T'-inclusion) (u , ฮป i โ†’ is-upbnd-T (T'-to-T i))

\end{code}

We now show that reindexing families along a surjection preserves the supremum.

\begin{code}

module _
        {๐“ค ๐“ฃ ๐“ฅ ๐“ฆ ๐“ฆ' : Universe}
        (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
        {T : ๐“ฆ  ฬ‡}
        {T' : ๐“ฆ'  ฬ‡}
        (e : T' โ†  T)
        (m : T โ†’ โŸจ L โŸฉ)
       where

 open Joins (order-of L)

 reindexing-along-surj-๏ผ-sup : (s s' : โŸจ L โŸฉ)
                              โ†’ (s is-lub-of (T , m)) holds
                              โ†’ (s' is-lub-of (T' , m โˆ˜ โŒž e โŒŸ)) holds
                              โ†’ s ๏ผ s'
 reindexing-along-surj-๏ผ-sup
  s s' (is-upbnd , is-least-upbnd) (is-upbnd' , is-least-upbnd') =
   antisymmetry-of L I IV
  where
   I : (s โ‰คโŸจ L โŸฉ s') holds
   I = is-least-upbnd (s' , ฮป t โ†’ III t (โŒžโŒŸ-is-surjection e t))
    where
     II : (t : T)
        โ†’ ฮฃ t' ๊ž‰ T' , โŒž e โŒŸ t' ๏ผ t
        โ†’ (m t โ‰คโŸจ L โŸฉ s') holds
     II t (t' , path) =
       transport (ฮป z โ†’ (m z โ‰คโŸจ L โŸฉ s') holds) path (is-upbnd' t')
     III : (t : T)
         โ†’ (ฦŽ t' ๊ž‰ T' , โŒž e โŒŸ t' ๏ผ t) holds
         โ†’ (m t โ‰คโŸจ L โŸฉ s') holds
     III t = โˆฅโˆฅ-rec (holds-is-prop (m t โ‰คโŸจ L โŸฉ s')) (II t)
   IV : (s' โ‰คโŸจ L โŸฉ s) holds
   IV = is-least-upbnd' (s , ฮป t' โ†’ is-upbnd (โŒž e โŒŸ t'))

\end{code}

We can also show that reindexing along an equivalence preserves the supremum.
This follows from the previous result as any equivalence can be demoted to a
surjection.

\begin{code}

module _
        {๐“ค ๐“ฃ ๐“ฅ ๐“ฆ ๐“ฆ' : Universe}
        (L : Sup-Lattice ๐“ค ๐“ฃ ๐“ฅ)
        {T : ๐“ฆ  ฬ‡}
        {T' : ๐“ฆ'  ฬ‡}
        (e : T' โ‰ƒ T)
        (m : T โ†’ โŸจ L โŸฉ)
       where

 open Joins (order-of L)

 reindexing-along-equiv-๏ผ-sup : (s s' : โŸจ L โŸฉ)
                               โ†’ (s is-lub-of (T , m)) holds
                               โ†’ (s' is-lub-of (T' , m โˆ˜ โŒœ e โŒ )) holds
                               โ†’ s ๏ผ s'
 reindexing-along-equiv-๏ผ-sup =
  reindexing-along-surj-๏ผ-sup
   L (โŒœ e โŒ , equivs-are-surjections โŒœ e โŒ-is-equiv) m

\end{code}