Martin Escardo, May 2020

We now consider σ-frames. A σ-frame is a poset with countable joins
and finite meets such that binary meets distribute over countable
joins. Countable joins are exhausted by finitely indexed joins and
ℕ-indexed joins. But, apart from the empty join, all finite joins can
be expressed as ℕ-indexed joins (of eventually constant sequences) and
hence it is enough to consider the empty join (a bottom element) and
ℕ-indexed joins, which is the approach we take here.

We denote the empty meet (a top element) by ⊤, the binary meet by ∧,
the empty join (a bottom element) by ⊥, and the ℕ-indexed join by
⋁. These are unary, binary and ℕ-ary operations.

TODO. Currently the order is derived from the binary meet. However,
for size reasons, it would be good to add the other as a separate
relation coinciding with the binary meet order, similarly to what we
did with σ-sup-lattices. Perhaps it would be better to define a
σ-frame as a σ-sup-lattice equipped with a binary meet.

\begin{code}

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

open import UF.FunExt

module OrderedTypes.sigma-frame (fe : Fun-Ext) where

open import MLTT.Spartan
open import UF.Equiv hiding (_≅_)
open import UF.SIP
open import UF.SIP-Examples
open import UF.Sets
open import UF.Sets-Properties
open import UF.Subsingletons
open import UF.Subsingletons-FunExt
open import UF.Univalence

σ-frame-structure : 𝓤 ̇  𝓤 ̇
σ-frame-structure X = X × (X  X  X) × X × ((  X)  X)

σ-frame-axioms : (X : 𝓤 ̇ )  σ-frame-structure X  𝓤 ̇
σ-frame-axioms {𝓤} X ( , _∧_ ,  , ) = I × II × III × IV × V × VI × VII × VIII × IX
 where
  _≤_ : X  X  𝓤 ̇
  x  y = x  y  x

  I    = is-set X
  II   = (x : X)  x  x  x
  III  = (x y : X)  x  y  y  x
  IV   = (x y z : X)  x  (y  z)  (x  y)  z
  V    = (x : X)    x
  VI   = (x : X)  x  
  VII  = (x : X) (y :   X)  x  ( y)   (n  (x  y n))
  VIII = (x :   X) (n : )  x n   x
  IX   = (x :   X) (u : X)  ((n : )  x n  u)   x  u
\end{code}

Axioms I-IV say that (X , ⊤ , ∧) is a bounded semilattice, axiom VII
says that ⋁ gives least upper bounds w.r.t. the induced partial order,
and axiom VI says that binary meets distribute over countable joins.

\begin{code}

σ-frame-axioms-is-prop : (X : 𝓤 ̇ ) (s : σ-frame-structure X)
                        is-prop (σ-frame-axioms X s)
σ-frame-axioms-is-prop X ( , _∧_ ,  , ) = prop-criterion δ
 where
  δ : σ-frame-axioms X ( , _∧_ ,  , )  is-prop (σ-frame-axioms X ( , _∧_ ,  , ))
  δ (i , ii-ix) =
    ×-is-prop (being-set-is-prop fe)
   (×-is-prop (Π-is-prop fe  x   i {x  x} {x}))
   (×-is-prop (Π-is-prop fe  x 
               Π-is-prop fe  y   i {x  y} {y  x})))
   (×-is-prop (Π-is-prop fe  x 
               Π-is-prop fe  y 
               Π-is-prop fe  z   i {x  (y  z)} {(x  y)  z}))))
   (×-is-prop (Π-is-prop fe  x   i {  x} {}))
   (×-is-prop (Π-is-prop fe  x   i {x  } {x}))
   (×-is-prop (Π-is-prop fe  x 
               Π-is-prop fe  y   i {x   y} { (n  x  y n)})))
   (×-is-prop (Π-is-prop fe  x 
               Π-is-prop fe  n  i {x n   x} {x n})))
              (Π-is-prop fe  x 
               Π-is-prop fe  u 
               Π-is-prop fe  _   i { x  u} { x})))))))))))

σ-Frame : (𝓤 : Universe)  𝓤  ̇
σ-Frame 𝓤 = Σ A  𝓤 ̇ , Σ s  σ-frame-structure A , σ-frame-axioms A s

⟨_⟩ : σ-Frame 𝓤  𝓤 ̇
 A , _  = A

is-σ-frame-homomorphism : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
                         ( 𝓐    𝓑 )  𝓤  𝓥 ̇
is-σ-frame-homomorphism  (_ , ( , _∧_ ,  , ) , _) (_ , (⊤' , _∧'_ , ⊥' , ⋁') , _) f =
    (f   ⊤')
  × ((λ a b  f (a  b))   a b  f a ∧' f b))
  × (f   ⊥')
  × ((λ 𝕒  f ( 𝕒))   𝕒  ⋁' (n  f (𝕒 n))))

_≅[σ-Frame]_ : σ-Frame 𝓤  σ-Frame 𝓤  𝓤 ̇
𝓐 ≅[σ-Frame] 𝓑 = Σ f  ( 𝓐    𝓑 ), is-equiv f × is-σ-frame-homomorphism 𝓐 𝓑 f

characterization-of-σ-Frame-= : is-univalent 𝓤
                               (A B : σ-Frame 𝓤)
                               (A  B)  (A ≅[σ-Frame] B)
characterization-of-σ-Frame-= ua =
  sip.characterization-of-= ua
   (sip-with-axioms.add-axioms
      σ-frame-axioms
      σ-frame-axioms-is-prop
     (sip-join.join
       pointed-type.sns-data
     (sip-join.join
       ∞-magma.sns-data
       (sip-join.join
        pointed-type.sns-data
        (∞-bigmagma.sns-data )))))

\end{code}

We name the projections (we wouldn't need to do this if we had used a
record, but we need Σ for our approach to SIP):

\begin{code}

⊤⟨_⟩ : (𝓐 : σ-Frame 𝓤)   𝓐 
⊤⟨ A , ( , _∧_ ,  , ) , _  = 

meet : (𝓐 : σ-Frame 𝓤)   𝓐    𝓐    𝓐 
meet (A , ( , _∧_ ,  , ) , _) = _∧_

syntax meet 𝓐 x y = x ∧⟨ 𝓐  y

⊥⟨_⟩ : (𝓐 : σ-Frame 𝓤)   𝓐 
⊥⟨ A , ( , _∧_ ,  , ) , _  = 

⋁⟨_⟩ : (𝓐 : σ-Frame 𝓤)  (   𝓐 )   𝓐 
⋁⟨ A , ( , _∧_ ,  , ) , _  = 

⟨_⟩-is-set : (𝓐 : σ-Frame 𝓤)  is-set  𝓐 
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-is-set = i

⟨_⟩-idempotency : (𝓐 : σ-Frame 𝓤) (a :  𝓐 )
                 a ∧⟨ 𝓐  a  a
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-idempotency = ii

⟨_⟩-commutativity : (𝓐 : σ-Frame 𝓤) (a b :  𝓐 )
                   a ∧⟨ 𝓐  b  b ∧⟨ 𝓐  a
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-commutativity = iii

⟨_⟩-associativity : (𝓐 : σ-Frame 𝓤) (a b c :  𝓐 )
                   a ∧⟨ 𝓐  (b ∧⟨ 𝓐  c)  (a ∧⟨ 𝓐  b) ∧⟨ 𝓐  c
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-associativity = iv

order : (𝓐 : σ-Frame 𝓤)
     𝓐    𝓐   𝓤 ̇
order 𝓐 a b = a ∧⟨ 𝓐  b  a

syntax order 𝓐 x y = x ≤⟨ 𝓐  y

⟨_⟩-⊥-minimum : (𝓐 : σ-Frame 𝓤) (a :  𝓐 )
               ⊥⟨ 𝓐  ≤⟨ 𝓐  a
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-⊥-minimum = v

⟨_⟩-⊤-maximum : (𝓐 : σ-Frame 𝓤) (a :  𝓐 )
               a ≤⟨ 𝓐  ⊤⟨ 𝓐 
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-⊤-maximum = vi

⟨_⟩-distributivity : (𝓐 : σ-Frame 𝓤) (a :  𝓐 ) (b :    𝓐 )
                    a ∧⟨ 𝓐  (⋁⟨ 𝓐  b)  ⋁⟨ 𝓐  (n  (a ∧⟨ 𝓐  b n))
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-distributivity = vii

⟨_⟩-⋁-is-ub : (𝓐 : σ-Frame 𝓤) (a :    𝓐 ) (n : )
             a n ≤⟨ 𝓐  ⋁⟨ 𝓐  a
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-⋁-is-ub = viii

⟨_⟩-⋁-is-lb-of-ubs : (𝓐 : σ-Frame 𝓤) (a :    𝓐 ) (u :  𝓐 )
                    ((n : )  a n ≤⟨ 𝓐  u)  ⋁⟨ 𝓐  a ≤⟨ 𝓐  u
 A , _ , (i , ii , iii , iv , v , vi , vii , viii , ix) ⟩-⋁-is-lb-of-ubs = ix

⟨_⟩-refl : (𝓐 : σ-Frame 𝓤) (a :  𝓐 )  a ≤⟨ 𝓐  a
⟨_⟩-refl 𝓐 a =  𝓐 ⟩-idempotency a

⟨_⟩-trans : (𝓐 : σ-Frame 𝓤) (a b c :  𝓐 )  a ≤⟨ 𝓐  b  b ≤⟨ 𝓐  c  a ≤⟨ 𝓐  c
⟨_⟩-trans 𝓐 a b c l m = (a ∧⟨ 𝓐  c)             =⟨ ap  -  - ∧⟨ 𝓐  c) (l ⁻¹) 
                         ((a ∧⟨ 𝓐  b) ∧⟨ 𝓐  c) =⟨ ( 𝓐 ⟩-associativity a b c)⁻¹ 
                         (a ∧⟨ 𝓐  (b ∧⟨ 𝓐  c)) =⟨ ap  -  a ∧⟨ 𝓐  -) m 
                         (a ∧⟨ 𝓐  b)             =⟨ l 
                         a                         

⟨_⟩-antisym : (𝓐 : σ-Frame 𝓤) (a b :  𝓐 )  a ≤⟨ 𝓐  b  b ≤⟨ 𝓐  a  a  b
⟨_⟩-antisym 𝓐 a b l m = a            =⟨ l ⁻¹ 
                        (a ∧⟨ 𝓐  b) =⟨  𝓐 ⟩-commutativity a b 
                        (b ∧⟨ 𝓐  a) =⟨ m 
                        b             


being-σ-frame-homomorphism-is-prop : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
                                    (f :  𝓐    𝓑 )
                                    is-prop (is-σ-frame-homomorphism 𝓐 𝓑 f)
being-σ-frame-homomorphism-is-prop (_ , _ ,  _) (_ , _ , (i' , _)) f =
  ×-is-prop i'
 (×-is-prop (Π-is-set fe  a 
             Π-is-set fe  b  i')))
 (×-is-prop i' (Π-is-set fe  𝕒  i'))))

∘-σ-frame-homomorphism : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥) (𝓒 : σ-Frame 𝓦)
                         (f :  𝓐    𝓑 ) (g :  𝓑    𝓒 )
                        is-σ-frame-homomorphism 𝓐 𝓑 f
                        is-σ-frame-homomorphism 𝓑 𝓒 g
                        is-σ-frame-homomorphism 𝓐 𝓒 (g  f)
∘-σ-frame-homomorphism 𝓐 𝓑 𝓒 f g (p₀ , q₀ , r₀ , s₀) (p₁ , q₁ , r₁ , s₁) = (p₂ , q₂ , r₂ , s₂)
 where
  p₂ = g (f ⊤⟨ 𝓐 ) =⟨ ap g p₀ 
       g ⊤⟨ 𝓑      =⟨ p₁ 
       ⊤⟨ 𝓒        

  q₂ =  a b  g (f (a ∧⟨ 𝓐  b)))     =⟨ dfunext fe  a  dfunext fe  b  ap  -  g (- a b)) q₀)) 
        a b  g (f a ∧⟨ 𝓑  f b))     =⟨ dfunext fe  a  dfunext fe  b  ap  -  - (f a) (f b)) q₁)) 
        a b  g (f a) ∧⟨ 𝓒  g (f b)) 

  r₂ = g (f ⊥⟨ 𝓐 ) =⟨ ap g r₀ 
       g ⊥⟨ 𝓑      =⟨ r₁ 
       ⊥⟨ 𝓒        

  s₂ =  𝕒  g (f (⋁⟨ 𝓐  𝕒)))           =⟨ dfunext fe  𝕒  ap  -  g (- 𝕒)) s₀) 
        𝕒  g (⋁⟨ 𝓑   n  f (𝕒 n)))) =⟨ dfunext fe  𝕒  ap  -  -  n  f (𝕒 n))) s₁) 
        𝕒  ⋁⟨ 𝓒   n  g (f (𝕒 n)))) 

\end{code}

I think I prefer to work with pointwise homomorphisms:

\begin{code}
is-σ-frame-hom : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
                ( 𝓐    𝓑 )  𝓤  𝓥 ̇
is-σ-frame-hom  (_ , ( , _∧_ ,  , ) , _) (_ , (⊤' , _∧'_ , ⊥' , ⋁') , _) f =
    (f   ⊤')
  × (∀ a b  f (a  b)  f a ∧' f b)
  × (f   ⊥')
  × (∀ 𝕒  f ( 𝕒)  ⋁' (n  f (𝕒 n)))

σ-frame-hom-⊤ : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
               (f :  𝓐    𝓑 )
               is-σ-frame-hom 𝓐 𝓑 f
               f ⊤⟨ 𝓐   ⊤⟨ 𝓑 
σ-frame-hom-⊤ 𝓐 𝓑 f (i , ii , iii , vi) = i

σ-frame-hom-∧ : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
               (f :  𝓐    𝓑 )
               is-σ-frame-hom 𝓐 𝓑 f
                a b  f (a ∧⟨ 𝓐  b)  f a ∧⟨ 𝓑  f b
σ-frame-hom-∧ 𝓐 𝓑 f (i , ii , iii , vi) = ii

σ-frame-hom-⊥ : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
               (f :  𝓐    𝓑 )
               is-σ-frame-hom 𝓐 𝓑 f
               f ⊥⟨ 𝓐   ⊥⟨ 𝓑 
σ-frame-hom-⊥ 𝓐 𝓑 f (i , ii , iii , vi) = iii

σ-frame-hom-⋁ : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
               (f :  𝓐    𝓑 )
               is-σ-frame-hom 𝓐 𝓑 f
                𝕒  f (⋁⟨ 𝓐  𝕒)  ⋁⟨ 𝓑  (n  f (𝕒 n))
σ-frame-hom-⋁ 𝓐 𝓑 f (i , ii , iii , vi) = vi

being-σ-frame-hom-is-prop : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥)
                           (f :  𝓐    𝓑 )
                           is-prop (is-σ-frame-hom 𝓐 𝓑 f)
being-σ-frame-hom-is-prop (_ , _ ,  _) (_ , _ , (i' , _)) f =

   ×₄-is-prop i' (Π₂-is-prop fe  a b  i')) i' (Π-is-prop fe  𝕒  i'))

id-is-σ-frame-hom : (𝓐 : σ-Frame 𝓤)  is-σ-frame-hom 𝓐 𝓐 id
id-is-σ-frame-hom 𝓐 = refl ,  a b  refl) , refl ,  𝕒  refl)

∘-σ-frame-hom : (𝓐 : σ-Frame 𝓤) (𝓑 : σ-Frame 𝓥) (𝓒 : σ-Frame 𝓦)
                (f :  𝓐    𝓑 ) (g :  𝓑    𝓒 )
               is-σ-frame-hom 𝓐 𝓑 f
               is-σ-frame-hom 𝓑 𝓒 g
               is-σ-frame-hom 𝓐 𝓒 (g  f)
∘-σ-frame-hom 𝓐 𝓑 𝓒 f g (p₀ , q₀ , r₀ , s₀) (p₁ , q₁ , r₁ , s₁) = (p₂ , q₂ , r₂ , s₂)
 where
  p₂ = g (f ⊤⟨ 𝓐 ) =⟨ ap g p₀ 
       g ⊤⟨ 𝓑      =⟨ p₁ 
       ⊤⟨ 𝓒        

  q₂ = λ a b  g (f (a ∧⟨ 𝓐  b))     =⟨ ap g (q₀ a b) 
               g (f a ∧⟨ 𝓑  f b)     =⟨ q₁ (f a) (f b) 
               g (f a) ∧⟨ 𝓒  g (f b) 

  r₂ = g (f ⊥⟨ 𝓐 ) =⟨ ap g r₀ 
       g ⊥⟨ 𝓑      =⟨ r₁ 
       ⊥⟨ 𝓒        

  s₂ = λ 𝕒  g (f (⋁⟨ 𝓐  𝕒))           =⟨ ap g (s₀ 𝕒) 
             g (⋁⟨ 𝓑   n  f (𝕒 n))) =⟨ s₁  n  f (𝕒 n)) 
             ⋁⟨ 𝓒   n  g (f (𝕒 n))) 

import OrderedTypes.sigma-sup-lattice

private σ-SupLat = OrderedTypes.sigma-sup-lattice.σ-SupLat fe

σ-frames-are-σ-suplats : σ-Frame 𝓤  σ-SupLat 𝓤 𝓤
σ-frames-are-σ-suplats 𝓑  =  𝓑  ,
                            (⊥⟨ 𝓑  , ⋁⟨ 𝓑 ) ,
                             x y  x ∧⟨ 𝓑  y  x) ,
                             x y   𝓑 ⟩-is-set) ,
                            ( 𝓑 ⟩-refl) ,
                             𝓑 ⟩-trans ,
                             𝓑 ⟩-antisym ,
                             𝓑 ⟩-⊥-minimum ,
                             𝓑 ⟩-⋁-is-ub ,
                             𝓑 ⟩-⋁-is-lb-of-ubs

open import OrderedTypes.Frame fe

frames-are-sigma-frames : Frame 𝓤 𝓤₀  σ-Frame 𝓤
frames-are-sigma-frames (X , ( , _∧_ , ) , i , ii , iii , iv , v , vi , vii , viii) =
                        (X , ( , _∧_ ,  unique-from-𝟘 ,  {}) , i , ii , iii , iv ,
                         x  viii unique-from-𝟘 x  (n : 𝟘)  𝟘-elim n)) ,
                        v ,  x y  vi x {} y) , vii {} , viii {})

open import UF.PropTrunc

module _ (pe : Prop-Ext)
         (pt  : propositional-truncations-exist)
       where

 Ω-qua-σ-frame : σ-Frame (𝓤 )
 Ω-qua-σ-frame {𝓤} = frames-are-sigma-frames (Ω-qua-frame pe pt 𝓤₀ 𝓤)

 Ω-qua-σ-suplat : σ-SupLat (𝓤 ) (𝓤 )
 Ω-qua-σ-suplat {𝓤} = σ-frames-are-σ-suplats (Ω-qua-σ-frame {𝓤})

\end{code}