Ayberk Tosun, 11 September 2023

\begin{code}[hide]

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

open import MLTT.Spartan hiding (𝟚)
open import UF.PropTrunc
open import UF.FunExt
open import UF.Size

module Locales.Clopen (pt : propositional-truncations-exist)
                      (fe : Fun-Ext)
                      (sr : Set-Replacement pt) where

open import Locales.Compactness.Definition pt fe
open import Locales.Complements pt fe
open import Locales.Frame pt fe
open import Locales.WayBelowRelation.Definition pt fe
open import Locales.WellInside pt fe sr
open import MLTT.List hiding ([_])
open import Slice.Family
open import UF.Base using (from-Σ-=)
open import UF.Logic
open import UF.Subsingletons
open import UF.SubtypeClassifier

open AllCombinators pt fe
open PropositionalTruncation pt



open Locale

\end{code}

We define the notion of a clopen.

\begin{code}

is-clopenβ‚€ : (F : Frame 𝓀 π“₯ 𝓦) β†’ ⟨ F ⟩ β†’ 𝓀 Μ‡
is-clopenβ‚€ F U = Ξ£ W κž‰ ⟨ F ⟩ , is-boolean-complement-of F W U holds

is-clopenβ‚€-is-prop : (F : Frame 𝓀 π“₯ 𝓦) β†’ (U : ⟨ F ⟩) β†’ is-prop (is-clopenβ‚€ F U)
is-clopenβ‚€-is-prop F U (W₁ , p₁ , q₁) (Wβ‚‚ , pβ‚‚ , qβ‚‚) = to-subtype-= Ξ² Ξ³
 where
  P = poset-of F -- we refer to the underlying poset of F as P.

  Ξ² : (W : ⟨ F ⟩) β†’ is-prop ((U ∧[ F ] W = 𝟎[ F ]) Γ— (U ∨[ F ] W = 𝟏[ F ]))
  Ξ² W = Γ—-is-prop carrier-of-[ P ]-is-set carrier-of-[ P ]-is-set

  Ξ³ : W₁ = Wβ‚‚
  Ξ³ = W₁                                  =⟨ (𝟏-right-unit-of-∧ F W₁) ⁻¹       ⟩
      W₁ ∧[ F ] 𝟏[ F ]                    =⟨ ap (Ξ» - β†’ meet-of F W₁ -) (qβ‚‚ ⁻¹) ⟩
      W₁ ∧[ F ] (U ∨[ F ] Wβ‚‚)             =⟨ binary-distributivity F W₁ U Wβ‚‚   ⟩
      (W₁ ∧[ F ] U) ∨[ F ] (W₁ ∧[ F ] Wβ‚‚) =⟨ i                                 ⟩
      (U ∧[ F ] W₁) ∨[ F ] (W₁ ∧[ F ] Wβ‚‚) =⟨ ii                                ⟩
      𝟎[ F ] ∨[ F ] (W₁ ∧[ F ] Wβ‚‚)        =⟨ iii                               ⟩
      (U ∧[ F ] Wβ‚‚) ∨[ F ] (W₁ ∧[ F ] Wβ‚‚) =⟨ iv                                ⟩
      (Wβ‚‚ ∧[ F ] U) ∨[ F ] (W₁ ∧[ F ] Wβ‚‚) =⟨ v                                 ⟩
      (Wβ‚‚ ∧[ F ] U) ∨[ F ] (Wβ‚‚ ∧[ F ] W₁) =⟨ vi                                ⟩
      Wβ‚‚ ∧[ F ] (U ∨[ F ] W₁)             =⟨ vii                               ⟩
      Wβ‚‚ ∧[ F ] 𝟏[ F ]                    =⟨ viii                              ⟩
      Wβ‚‚                                  ∎
       where
        i    = ap (Ξ» - β†’ - ∨[ F ] (W₁ ∧[ F ] Wβ‚‚)) (∧[ F ]-is-commutative W₁ U)
        ii   = ap (Ξ» - β†’ - ∨[ F ] (W₁ ∧[ F ] Wβ‚‚)) p₁
        iii  = ap (Ξ» - β†’ - ∨[ F ] (W₁ ∧[ F ] Wβ‚‚)) (pβ‚‚ ⁻¹)
        iv   = ap (Ξ» - β†’ - ∨[ F ] (W₁ ∧[ F ] Wβ‚‚)) (∧[ F ]-is-commutative U Wβ‚‚)
        v    = ap (Ξ» - β†’ (Wβ‚‚ ∧[ F ] U) ∨[ F ] -) (∧[ F ]-is-commutative W₁ Wβ‚‚)
        vi   = binary-distributivity F Wβ‚‚ U W₁ ⁻¹
        vii  = ap (Ξ» - β†’ Wβ‚‚ ∧[ F ] -) q₁
        viii = 𝟏-right-unit-of-∧ F Wβ‚‚

\end{code}

The definition of the notion of clopen.

\begin{code}

is-clopen : (F : Frame 𝓀 π“₯ 𝓦) β†’ ⟨ F ⟩ β†’ Ξ© 𝓀
is-clopen F U = is-clopenβ‚€ F U , is-clopenβ‚€-is-prop F U

\end{code}

The type of clopens of a locale `X`.

\begin{code}

π’ž : Locale 𝓀 π“₯ 𝓦 β†’ 𝓀  Μ‡
π’ž X = Ξ£ C κž‰ ⟨ π’ͺ X ⟩ , is-clopen (π’ͺ X) C holds

\end{code}

The top element `𝟏` is always a clopen.

\begin{code}

𝟏-is-clopen : (L : Frame 𝓀 π“₯ 𝓦) β†’ is-clopen L 𝟏[ L ] holds
𝟏-is-clopen L = 𝟎[ L ] , † , ‑
 where
  † : 𝟏[ L ] ∧[ L ] 𝟎[ L ] = 𝟎[ L ]
  † = 𝟎-right-annihilator-for-∧ L 𝟏[ L ]

  ‑ : 𝟏[ L ] ∨[ L ] 𝟎[ L ] = 𝟏[ L ]
  ‑ = 𝟏-left-annihilator-for-∨ L 𝟎[ L ]

\end{code}

\begin{code}

consists-of-clopens : (F : Frame 𝓀 π“₯ 𝓦) β†’ Fam 𝓦 ⟨ F ⟩ β†’ Ξ© (𝓀 βŠ” 𝓦)
consists-of-clopens F S = β±― i κž‰ index S , is-clopen F (S [ i ])

\end{code}

\begin{code}

∧-complement : (F : Frame 𝓀 π“₯ 𝓦)
             β†’ {x y xβ€² yβ€² : ⟨ F ⟩}
             β†’ is-boolean-complement-of F x xβ€² holds
             β†’ is-boolean-complement-of F y yβ€² holds
             β†’ is-boolean-complement-of F (xβ€² ∨[ F ] yβ€²) (x ∧[ F ] y) holds
∧-complement F {x} {y} {xβ€²} {yβ€²} Ο† ψ = Ξ² , Ξ³
 where
  open PosetReasoning (poset-of F)

  _βŠ“_ = Ξ» x y β†’ x ∧[ F ] y

  Ο†β‚€ : x βŠ“ xβ€² = 𝟎[ F ]
  Ο†β‚€ = x βŠ“ xβ€² =⟨ ∧[ F ]-is-commutative x xβ€² ⟩ xβ€² βŠ“ x =⟨ pr₁ Ο† ⟩  𝟎[ F ] ∎

  Οˆβ‚€ : y βŠ“ yβ€² = 𝟎[ F ]
  Οˆβ‚€ = y βŠ“ yβ€² =⟨ ∧[ F ]-is-commutative y yβ€² ⟩ yβ€² βŠ“ y  =⟨ pr₁ ψ ⟩ 𝟎[ F ] ∎

  φ₁ : x ∨[ F ] xβ€² = 𝟏[ F ]
  φ₁ = x  ∨[ F ] xβ€² =⟨ ∨[ F ]-is-commutative x xβ€² ⟩
       xβ€² ∨[ F ] x  =⟨ prβ‚‚ Ο†                      ⟩
       𝟏[ F ]       ∎

  Ξ² : (x ∧[ F ] y) ∧[ F ] (xβ€² ∨[ F ] yβ€²) = 𝟎[ F ]
  Ξ² = (x βŠ“ y) βŠ“ (xβ€² ∨[ F ] yβ€²)                =⟨ β…  ⟩
      ((x βŠ“ y) βŠ“ xβ€²) ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)    =⟨ β…‘ ⟩
      ((y βŠ“ x) βŠ“ xβ€²) ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)    =⟨ β…’ ⟩
      (y βŠ“ (x βŠ“ xβ€²)) ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)    =⟨ β…£ ⟩
      (y βŠ“ 𝟎[ F ]) ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)      =⟨ β…€ ⟩
      𝟎[ F ] ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)            =⟨ β…₯ ⟩
      (x βŠ“ y) βŠ“ yβ€²                            =⟨ β…¦ ⟩
      x βŠ“ (y βŠ“ yβ€²)                            =⟨ β…§ ⟩
      x βŠ“ 𝟎[ F ]                              =⟨ β…¨ ⟩
      𝟎[ F ]                                  ∎
       where
        β…  = binary-distributivity F (x βŠ“ y) xβ€² yβ€²
        β…‘ = ap (Ξ» - β†’ (- βŠ“ xβ€²) ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)) (∧[ F ]-is-commutative x y)
        β…’ = ap (Ξ» - β†’ - ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)) (∧[ F ]-is-associative y x xβ€² ⁻¹)
        β…£ = ap (Ξ» - β†’ (y βŠ“ -) ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)) Ο†β‚€
        β…€ = ap (Ξ» - β†’ - ∨[ F ] ((x βŠ“ y) βŠ“ yβ€²)) (𝟎-right-annihilator-for-∧ F y)
        β…₯ = 𝟎-right-unit-of-∨ F ((x βŠ“ y) βŠ“ yβ€²)
        β…¦ = ∧[ F ]-is-associative x y yβ€² ⁻¹
        β…§ = ap (Ξ» - β†’ x βŠ“ -) Οˆβ‚€
        β…¨ = 𝟎-right-annihilator-for-∧ F x


  Ξ³ : (x βŠ“ y) ∨[ F ] (xβ€² ∨[ F ] yβ€²) = 𝟏[ F ]
  Ξ³ = (x βŠ“ y) ∨[ F ] (xβ€² ∨[ F ] yβ€²)                                =⟨ β…  ⟩
      (xβ€² ∨[ F ] yβ€²) ∨[ F ] (x βŠ“ y)                                =⟨ β…‘ ⟩
      ((xβ€² ∨[ F ] yβ€²) ∨[ F ] x) ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)   =⟨ β…’ ⟩
      ((yβ€² ∨[ F ] xβ€²) ∨[ F ] x) ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)   =⟨ β…£ ⟩
      (yβ€² ∨[ F ] (xβ€² ∨[ F ] x)) ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)   =⟨ β…€ ⟩
      (yβ€² ∨[ F ] 𝟏[ F ]) ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)          =⟨ β…₯ ⟩
      𝟏[ F ] ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)                      =⟨ β…¦ ⟩
      (xβ€² ∨[ F ] yβ€²) ∨[ F ] y                                      =⟨ β…§ ⟩
      xβ€² ∨[ F ] (yβ€² ∨[ F ] y)                                      =⟨ β…¨ ⟩
      xβ€² ∨[ F ] 𝟏[ F ]                                             =⟨ β…© ⟩
      𝟏[ F ]                                                       ∎
       where
        † = ∨[ F ]-is-commutative xβ€² yβ€²
        ‑ = 𝟏-right-annihilator-for-∨ F yβ€²
        β…  = ∨[ F ]-is-commutative (x βŠ“ y) (xβ€² ∨[ F ] yβ€²)
        β…‘ = binary-distributivity-op F (xβ€² ∨[ F ] yβ€²) x y
        β…’ = ap (Ξ» - β†’ (- ∨[ F ] x) ∧[ F ] ((_ ∨[ F ] _) ∨[ F ] y)) †
        β…£ = ap (Ξ» - β†’ - ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)) (∨[ F ]-assoc yβ€² xβ€² x)
        β…€ = ap (Ξ» - β†’ (yβ€² ∨[ F ] -) ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)) (prβ‚‚ Ο†)
        β…₯ = ap (Ξ» - β†’ - ∧[ F ] ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)) ‑
        β…¦ = 𝟏-left-unit-of-∧ F ((xβ€² ∨[ F ] yβ€²) ∨[ F ] y)
        β…§ = ∨[ F ]-assoc xβ€² yβ€² y
        β…¨ = ap (Ξ» - β†’ xβ€² ∨[ F ] -) (prβ‚‚ ψ)
        β…© = 𝟏-right-annihilator-for-∨ F xβ€²

\end{code}

\begin{code}

clopens-are-closed-under-∧ : (F : Frame 𝓀 π“₯ 𝓦) (x y : ⟨ F ⟩)
                           β†’ (is-clopen F x
                           β‡’  is-clopen F y
                           β‡’  is-clopen F (x ∧[ F ] y)) holds
clopens-are-closed-under-∧ F x y ΟŸβ‚@(xβ€² , φ₁ , Ο†β‚‚) ΟŸβ‚‚@(yβ€² , Οˆβ‚ , Οˆβ‚‚) =
 (xβ€² ∨[ F ] yβ€²) , †
  where
   ‑₁ : is-boolean-complement-of F x xβ€² holds
   ‑₁ = (xβ€² ∧[ F ] x =⟨ ∧[ F ]-is-commutative xβ€² x ⟩ x ∧[ F ] xβ€² =⟨ φ₁ ⟩ 𝟎[ F ] ∎)
      , (xβ€² ∨[ F ] x =⟨ ∨[ F ]-is-commutative xβ€² x ⟩ x ∨[ F ] xβ€² =⟨ Ο†β‚‚ ⟩ 𝟏[ F ] ∎)

   ‑₂ : is-boolean-complement-of F y yβ€² holds
   ‑₂ = (yβ€² ∧[ F ] y =⟨ ∧[ F ]-is-commutative yβ€² y ⟩ y ∧[ F ] yβ€² =⟨ Οˆβ‚ ⟩ 𝟎[ F ] ∎)
      , (yβ€² ∨[ F ] y =⟨ ∨[ F ]-is-commutative yβ€² y ⟩ y ∨[ F ] yβ€² =⟨ Οˆβ‚‚ ⟩ 𝟏[ F ] ∎)

   † : is-boolean-complement-of F (xβ€² ∨[ F ] yβ€²) (x ∧[ F ] y) holds
   † = ∧-complement F ‑₁ ‑₂

\end{code}

Given a family `S`, consisting of clopens, then `directify S` also consists of
clopens.

\begin{code}

clopens-are-closed-under-∨ : (F : Frame 𝓀 π“₯ 𝓦) (x y : ⟨ F ⟩)
                           β†’ (is-clopen F x
                           β‡’  is-clopen F y
                           β‡’  is-clopen F (x ∨[ F ] y)) holds
clopens-are-closed-under-∨ F x y (xβ€² , ϑ₁ , ΟŸβ‚) (yβ€² , Ο‘β‚‚ , ΟŸβ‚‚) =
 (xβ€² ∧[ F ] yβ€²) , † , ‑
  where
   open PosetReasoning (poset-of F)

   †₁ : (((x ∨[ F ] y) ∧[ F ] (xβ€² ∧[ F ] yβ€²)) ≀[ poset-of F ] 𝟎[ F ]) holds
   †₁ =
    (x ∨[ F ] y) ∧[ F ] (xβ€² ∧[ F ] yβ€²)                         =⟨ β…  βŸ©β‚š
    (x ∧[ F ] (xβ€² ∧[ F ] yβ€²)) ∨[ F ] (y ∧[ F ] (xβ€² ∧[ F ] yβ€²)) β‰€βŸ¨ β…‘ ⟩
    (x ∧[ F ] xβ€²) ∨[ F ] (y ∧[ F ] (xβ€² ∧[ F ] yβ€²))             β‰€βŸ¨ β…’ ⟩
    (x ∧[ F ] xβ€²) ∨[ F ] (y ∧[ F ] yβ€²)                         β‰€βŸ¨ β…£ ⟩
    𝟎[ F ] ∨[ F ] (y ∧[ F ] yβ€²)                                β‰€βŸ¨ β…€ ⟩
    𝟎[ F ] ∨[ F ] 𝟎[ F ]                                       =⟨ β…₯ βŸ©β‚š
    𝟎[ F ]                                                     β– 
     where
      β…  = binary-distributivity-right F
      β…‘ = ∨[ F ]-left-monotone  (∧[ F ]-right-monotone (∧[ F ]-lower₁ xβ€² yβ€²))
      β…’ = ∨[ F ]-right-monotone (∧[ F ]-right-monotone (∧[ F ]-lowerβ‚‚ xβ€² yβ€²))
      β…£ = ∨[ F ]-left-monotone  (reflexivity+ (poset-of F) ϑ₁)
      β…€ = ∨[ F ]-right-monotone (reflexivity+ (poset-of F) Ο‘β‚‚)
      β…₯ = ∨[ F ]-is-idempotent 𝟎[ F ] ⁻¹

   † : (x ∨[ F ] y) ∧[ F ] (xβ€² ∧[ F ] yβ€²) = 𝟎[ F ]
   † = only-𝟎-is-below-𝟎 F _ †₁

   ‑₁ : (𝟏[ F ] ≀[ poset-of F ] ((x ∨[ F ] y) ∨[ F ] (xβ€² ∧[ F ] yβ€²))) holds
   ‑₁ =
    𝟏[ F ]                                                      =⟨ β…  βŸ©β‚š
    𝟏[ F ] ∧[ F ] 𝟏[ F ]                                        β‰€βŸ¨ β…‘ ⟩
    (x ∨[ F ] xβ€²) ∧[ F ] 𝟏[ F ]                                 β‰€βŸ¨ β…’ ⟩
    (x ∨[ F ] xβ€²) ∧[ F ] (y ∨[ F ] yβ€²)                          β‰€βŸ¨ β…£ ⟩
    ((x ∨[ F ] y ) ∨[ F ] xβ€²)∧[ F ] (y ∨[ F ] yβ€²)               β‰€βŸ¨ β…€ ⟩
    ((x ∨[ F ] y ) ∨[ F ] xβ€²) ∧[ F ] ((x ∨[ F ] y ) ∨[ F ] yβ€²)  =⟨ β…₯ βŸ©β‚š
    (x ∨[ F ] y) ∨[ F ] (xβ€² ∧[ F ] yβ€²)                          β– 
     where
      β…  = ∧[ F ]-is-idempotent 𝟏[ F ]
      β…‘ = ∧[ F ]-left-monotone  (reflexivity+ (poset-of F) (ΟŸβ‚ ⁻¹))
      β…’ = ∧[ F ]-right-monotone (reflexivity+ (poset-of F) (ΟŸβ‚‚ ⁻¹))
      β…£ = ∧[ F ]-left-monotone (∨[ F ]-left-monotone (∨[ F ]-upper₁ x y))
      β…€ = ∧[ F ]-right-monotone (∨[ F ]-left-monotone (∨[ F ]-upperβ‚‚ x y))
      β…₯ = binary-distributivity-op F (x ∨[ F ] y) xβ€² yβ€² ⁻¹

   ‑ : (x ∨[ F ] y) ∨[ F ] (xβ€² ∧[ F ] yβ€²) = 𝟏[ F ]
   ‑ = only-𝟏-is-above-𝟏 F _ ‑₁

\end{code}

The bottom element is always clopen.

\begin{code}

𝟎-is-clopen : (F : Frame 𝓀 π“₯ 𝓦) β†’ is-clopenβ‚€ F 𝟎[ F ]
𝟎-is-clopen F = 𝟏[ F ] , β , γ
 where
  β : 𝟎[ F ] ∧[ F ] 𝟏[ F ] = 𝟎[ F ]
  β = 𝟎-left-annihilator-for-∧ F 𝟏[ F ]

  γ : 𝟎[ F ] ∨[ F ] 𝟏[ F ] = 𝟏[ F ]
  γ = 𝟏-right-annihilator-for-∨ F 𝟎[ F ]

\end{code}

\begin{code}

directification-preserves-clopenness : (F : Frame 𝓀 π“₯ 𝓦)
                                     β†’ (ℬ : Fam 𝓦 ⟨ F ⟩)
                                     β†’ (consists-of-clopens F ℬ
                                     β‡’ consists-of-clopens F (directify F ℬ))
                                       holds
directification-preserves-clopenness F ℬ ΞΎ []       = 𝟎-is-clopen F
directification-preserves-clopenness F ℬ ΞΎ (i ∷ is) =
 clopens-are-closed-under-∨ F (ℬ [ i ]) (directify F ℬ [ is ]) (ΞΎ i) ℐℋ
  where
   abstract
    ℐℋ : is-clopen F (directify F ℬ [ is ]) holds
    ℐℋ = directification-preserves-clopenness F ℬ ΞΎ is

\end{code}


\begin{code}

well-inside-itself-implies-clopen : (X : Locale 𝓀 π“₯ 𝓦)
                                  β†’ (U : ⟨ π’ͺ X ⟩)
                                  β†’ ((U β‹œ[ π’ͺ X ] U) β‡’ is-clopen (π’ͺ X) U) holds
well-inside-itself-implies-clopen X U =
 βˆ₯βˆ₯-rec (holds-is-prop (is-clopen (π’ͺ X) U)) id

\end{code}

\begin{code}

complements-are-unique : (F : Frame 𝓀 π“₯ 𝓦) (U V₁ Vβ‚‚ : ⟨ F ⟩)
                       β†’ is-boolean-complement-of F V₁ U holds
                       β†’ is-boolean-complement-of F Vβ‚‚ U holds
                       β†’ V₁ = Vβ‚‚
complements-are-unique F U V₁ Vβ‚‚ p q =
 pr₁ (from-Ξ£-= (is-clopenβ‚€-is-prop F U (V₁ , p) (Vβ‚‚ , q)))

\end{code}