\begin{code}

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

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

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

open import Locales.Frame              pt fe
open import Locales.HeytingImplication pt fe
open import Locales.Complements        pt fe
open import Locales.Clopen             pt fe sr

open import UF.Logic
open AllCombinators pt fe

open Locale

module HeytingComplementationLemmas (X : Locale 𝓀 π“₯ π“₯)
                                    (𝒷 : has-basis (π’ͺ X) holds) where


  open HeytingImplicationConstruction X 𝒷

  complement-is-heyting-complement : (C Cβ€² : ⟨ π’ͺ X ⟩)
                                   β†’ is-boolean-complement-of (π’ͺ X) Cβ€² C holds
                                   β†’ Cβ€² = C ==> 𝟎[ π’ͺ X ]
  complement-is-heyting-complement C Cβ€² (p , q) =
   ≀-is-antisymmetric (poset-of (π’ͺ X)) † ‑
    where
     open PosetReasoning (poset-of (π’ͺ X))

     β€» : (((C ==> 𝟎[ π’ͺ X ]) ∧[ π’ͺ X ] (C ∨[ π’ͺ X ] Cβ€²)) ≀[ poset-of (π’ͺ X) ] Cβ€²) holds
     β€» =
      (C ==> 𝟎[ π’ͺ X ]) ∧[ π’ͺ X ] (C ∨[ π’ͺ X ] Cβ€²)                             =⟨ β…  βŸ©β‚š
      ((C ==> 𝟎[ π’ͺ X ]) ∧[ π’ͺ X ] C) ∨[ π’ͺ X ] ((C ==> 𝟎[ π’ͺ X ]) ∧[ π’ͺ X ] Cβ€²) β‰€βŸ¨ β…‘  ⟩
      Cβ€²                                                                    β– 
       where
        β…  = binary-distributivity (π’ͺ X) (C ==> 𝟎[ π’ͺ X ]) C Cβ€²
        β…‘ = ∨[ π’ͺ X ]-least
             ((C ==> 𝟎[ π’ͺ X ]) ∧[ π’ͺ X ] C    β‰€βŸ¨ mp-right C 𝟎[ π’ͺ X ]  ⟩
              𝟎[ π’ͺ X ]                       β‰€βŸ¨ 𝟎-is-bottom (π’ͺ X) Cβ€² ⟩
              Cβ€²                             β– )
             (∧[ π’ͺ X ]-lowerβ‚‚ (C ==> 𝟎[ π’ͺ X ]) Cβ€²)

     † : (Cβ€² ≀[ poset-of (π’ͺ X) ] (C ==> 𝟎[ π’ͺ X ])) holds
     † = heyting-implication₁ C 𝟎[ π’ͺ X ] Cβ€² †₁
      where
       †₁ : ((Cβ€² ∧[ π’ͺ X ] C) ≀[ poset-of (π’ͺ X) ] 𝟎[ π’ͺ X ]) holds
       †₁ = Cβ€² ∧[ π’ͺ X ] C   =⟨ ∧[ π’ͺ X ]-is-commutative Cβ€² C βŸ©β‚š
            C  ∧[ π’ͺ X ] Cβ€²  =⟨ p βŸ©β‚š
            𝟎[ π’ͺ X ]        β– 

     ‑ : (C ==> 𝟎[ π’ͺ X ] ≀[ poset-of (π’ͺ X) ] Cβ€²) holds
     ‑ = C ==> 𝟎[ π’ͺ X ]          β‰€βŸ¨ β…                 ⟩
         (C ∨[ π’ͺ X ] Cβ€²) ==> Cβ€²  =⟨ β…‘               βŸ©β‚š
         𝟏[ π’ͺ X ] ==> Cβ€²         =⟨ 𝟏-==>-law Cβ€² ⁻¹ βŸ©β‚š
         Cβ€²                      β– 
          where
           β…  = heyting-implication₁ (C ∨[ π’ͺ X ] Cβ€²) Cβ€² (C ==> 𝟎[ π’ͺ X ]) β€»
           β…‘ = ap (Ξ» - β†’ - ==> Cβ€²) q

  heyting-complement-is-complement : (C Cβ€² : ⟨ π’ͺ X ⟩)
                                   β†’ is-boolean-complement-of (π’ͺ X) Cβ€² C holds
                                   β†’ is-boolean-complement-of (π’ͺ X) (C ==> 𝟎[ π’ͺ X ]) C holds
  heyting-complement-is-complement C Cβ€² (p , q) = † , ‑
   where
    † : C ∧[ π’ͺ X ] (C ==> 𝟎[ π’ͺ X ]) = 𝟎[ π’ͺ X ]
    † = C ∧[ π’ͺ X ] (C ==> 𝟎[ π’ͺ X ])  =⟨ β€» ⟩
        C ∧[ π’ͺ X ] Cβ€²                =⟨ p ⟩
        𝟎[ π’ͺ X ]                     ∎
         where
          β€» = ap
               (Ξ» - β†’ C ∧[ π’ͺ X ] -)
               (complement-is-heyting-complement C Cβ€² (p , q) ⁻¹)


    ‑ : C ∨[ π’ͺ X ] (C ==> 𝟎[ π’ͺ X ]) = 𝟏[ π’ͺ X ]
    ‑ = C ∨[ π’ͺ X ] (C ==> 𝟎[ π’ͺ X ])  =⟨ β€» ⟩
        C ∨[ π’ͺ X ] Cβ€²                =⟨ q ⟩
        𝟏[ π’ͺ X ]                     ∎
         where
          β€» = ap
               (Ξ» - β†’ C ∨[ π’ͺ X ] -)
               (complement-is-heyting-complement C Cβ€² (p , q) ⁻¹)

  material-implication : (C U : ⟨ π’ͺ X ⟩)
                       β†’ is-clopenβ‚€ (π’ͺ X) C
                       β†’ (C ==> U) = (C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U
  material-implication C U (Cβ€² , p , q) = ≀-is-antisymmetric (poset-of (π’ͺ X)) † ‑
   where
    open PosetReasoning (poset-of (π’ͺ X))

    † : ((C ==> U) ≀[ poset-of (π’ͺ X) ] ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U)) holds
    † = (C ==> U)                                         β‰€βŸ¨ β…  ⟩
        (C ∨[ π’ͺ X ] Cβ€²) ==> ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U) =⟨ β…‘ βŸ©β‚š
        𝟏[ π’ͺ X ] ==> ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U)        =⟨ β…’ βŸ©β‚š
        (C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U                       β– 
         where
          β€» = (C ==> U) ∧[ π’ͺ X ] (C ∨[ π’ͺ X ] Cβ€²)                        =⟨ β…  βŸ©β‚š
              ((C ==> U) ∧[ π’ͺ X ] C) ∨[ π’ͺ X ] ((C ==> U) ∧[ π’ͺ X ] Cβ€²)   β‰€βŸ¨ β…‘  ⟩
              U ∨[ π’ͺ X ] ((C ==> U) ∧[ π’ͺ X ] Cβ€²)                        β‰€βŸ¨ β…’  ⟩
              U ∨[ π’ͺ X ] Cβ€²                                             =⟨ β…£ βŸ©β‚š
              Cβ€² ∨[ π’ͺ X ] U                                             =⟨ β…€ βŸ©β‚š
              (C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U                               β– 
               where
                β…  = binary-distributivity (π’ͺ X) (C ==> U) C Cβ€²
                β…‘ = ∨[ π’ͺ X ]-left-monotone (mp-right C U)
                β…’ = ∨[ π’ͺ X ]-right-monotone (∧[ π’ͺ X ]-lowerβ‚‚ (C ==> U) Cβ€²)
                β…£ = ∨[ π’ͺ X ]-is-commutative U Cβ€²
                β…€ = ap
                     (Ξ» - β†’ - ∨[ π’ͺ X ] U)
                     (complement-is-heyting-complement C Cβ€² (p , q))

          β…  = heyting-implication₁
               (C ∨[ π’ͺ X ] Cβ€²)
               ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U)
               (C ==> U)
               β€»
          β…‘ = ap (Ξ» - β†’ - ==> ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U)) q
          β…’ = 𝟏-==>-law ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U) ⁻¹

    ‑ : (((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U) ≀[ poset-of (π’ͺ X) ] (C ==> U)) holds
    ‑ = heyting-implication₁ C U ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U) ‑₁
     where
      ‑₁ : ((((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U) ∧[ π’ͺ X ] C)
             ≀[ poset-of (π’ͺ X) ]
            U) holds
      ‑₁ = ((C ==> 𝟎[ π’ͺ X ]) ∨[ π’ͺ X ] U) ∧[ π’ͺ X ] C               =⟨ β…  βŸ©β‚š
           ((C ==> 𝟎[ π’ͺ X ]) ∧[ π’ͺ X ] C) ∨[ π’ͺ X ] (U ∧[ π’ͺ X ] C)  β‰€βŸ¨ β…‘ ⟩
           U                                                      β– 
            where
             β€» = (C ==> 𝟎[ π’ͺ X ]) ∧[ π’ͺ X ] C    β‰€βŸ¨ mp-right C 𝟎[ π’ͺ X ] ⟩
                 𝟎[ π’ͺ X ]                       β‰€βŸ¨ 𝟎-is-bottom (π’ͺ X) U ⟩
                 U                              β– 

             β…  = binary-distributivity-right (π’ͺ X)
             β…‘ = ∨[ π’ͺ X ]-least β€» (∧[ π’ͺ X ]-lower₁ U C)

  double-negation-elimination : (C : ⟨ π’ͺ X ⟩)
                              β†’ is-clopenβ‚€ (π’ͺ X) C
                              β†’ (C ==> 𝟎[ π’ͺ X ]) ==> 𝟎[ π’ͺ X ] = C
  double-negation-elimination C (Cβ€² , p , q) =
   ≀-is-antisymmetric (poset-of (π’ͺ X)) † ‑
    where
     open PosetReasoning (poset-of (π’ͺ X))

     † : (((C ==> 𝟎[ π’ͺ X ]) ==> 𝟎[ π’ͺ X ]) ≀[ poset-of (π’ͺ X) ] C) holds
     † = (C ==> 𝟎[ π’ͺ X ]) ==> 𝟎[ π’ͺ X ]        =⟨ β…  βŸ©β‚š
         Cβ€² ==> 𝟎[ π’ͺ X ]                      =⟨ β…‘ βŸ©β‚š
         C                                    β– 
          where
           β…  = ap
                (Ξ» - β†’ - ==> 𝟎[ π’ͺ X ])
                (complement-is-heyting-complement C Cβ€² (p , q) ⁻¹)
           β…‘ = complement-is-heyting-complement Cβ€² C (⅑₁ , β…‘β‚‚) ⁻¹
                where
                 ⅑₁ = Cβ€² ∧[ π’ͺ X ] C     =⟨ ∧[ π’ͺ X ]-is-commutative Cβ€² C ⟩
                      C  ∧[ π’ͺ X ] Cβ€²    =⟨ p                            ⟩
                      𝟎[ π’ͺ X ]          ∎
                 β…‘β‚‚ = Cβ€² ∨[ π’ͺ X ] C     =⟨ ∨[ π’ͺ X ]-is-commutative Cβ€² C ⟩
                      C  ∨[ π’ͺ X ] Cβ€²    =⟨ q                            ⟩
                      𝟏[ π’ͺ X ]          ∎

     ‑ : (C ≀[ poset-of (π’ͺ X) ] (C ==> 𝟎[ π’ͺ X ]) ==> 𝟎[ π’ͺ X ]) holds
     ‑ = heyting-implication₁ (C ==> 𝟎[ π’ͺ X ]) 𝟎[ π’ͺ X ] C ‑₁
      where
       ‑₁ : ((C ∧[ π’ͺ X ] (C ==> 𝟎[ π’ͺ X ])) ≀[ poset-of (π’ͺ X) ] 𝟎[ π’ͺ X ]) holds
       ‑₁ = mp-left C 𝟎[ π’ͺ X ]

  negation-∨-lemma₁ : {U V W : ⟨ π’ͺ X ⟩}
                    β†’ is-clopenβ‚€ (π’ͺ X) V
                    β†’ (U ≀[ poset-of (π’ͺ X) ] (V ∨[ π’ͺ X ] W)) holds
                    β†’ ((U ∧[ π’ͺ X ] (V ==> 𝟎[ π’ͺ X ]))
                        ≀[ poset-of (π’ͺ X) ]
                       W) holds
  negation-∨-lemma₁ {U} {V} {W} (Vβ€² , p , q) Ο† =
   U ∧[ π’ͺ X ] (V ==> 𝟎[ π’ͺ X ])               =⟨ β…  βŸ©β‚š
   U ∧[ π’ͺ X ] Vβ€²                             β‰€βŸ¨ β…‘  ⟩
   (V ∨[ π’ͺ X ] W) ∧[ π’ͺ X ] Vβ€²                =⟨ β…’ βŸ©β‚š
   (V ∧[ π’ͺ X ] Vβ€²) ∨[ π’ͺ X ] (W ∧[ π’ͺ X ] Vβ€²)  =⟨ β…£ βŸ©β‚š
   𝟎[ π’ͺ X ] ∨[ π’ͺ X ] (W ∧[ π’ͺ X ] Vβ€²)         =⟨ β…€ βŸ©β‚š
   W ∧[ π’ͺ X ] Vβ€²                             β‰€βŸ¨  β…₯ ⟩
   W                                         β– 
    where
     open PosetReasoning (poset-of (π’ͺ X))

     β…  = ap
          (Ξ» - β†’ U ∧[ π’ͺ X ] -)
          (complement-is-heyting-complement V Vβ€² (p , q) ⁻¹)
     β…‘ = ∧[ π’ͺ X ]-left-monotone Ο†
     β…’ = binary-distributivity-right (π’ͺ X)
     β…£ = ap (Ξ» - β†’ - ∨[ π’ͺ X ] (W ∧[ π’ͺ X ] Vβ€²)) p
     β…€ = 𝟎-right-unit-of-∨ (π’ͺ X) (W ∧[ π’ͺ X ] Vβ€²)
     β…₯ = ∧[ π’ͺ X ]-lower₁ W Vβ€²

  negation-∨-lemmaβ‚‚ : {U V W : ⟨ π’ͺ X ⟩}
                 β†’ is-clopenβ‚€ (π’ͺ X) V
                  β†’ ((U ∧[ π’ͺ X ] (V ==> 𝟎[ π’ͺ X ]))
                      ≀[ poset-of (π’ͺ X) ]
                     W) holds
                  β†’ (U ≀[ poset-of (π’ͺ X) ] (V ∨[ π’ͺ X ] W)) holds
  negation-∨-lemmaβ‚‚ {U} {V} {W} (Vβ€² , p , q) Ο† =
   U                                                      =⟨ β…  βŸ©β‚š
   U ∧[ π’ͺ X ] 𝟏[ π’ͺ X ]                                    =⟨ β…‘ βŸ©β‚š
   U ∧[ π’ͺ X ] (V ∨[ π’ͺ X ] Vβ€²)                             =⟨ β…’ βŸ©β‚š
   (U ∧[ π’ͺ X ] V) ∨[ π’ͺ X ] (U ∧[ π’ͺ X ] Vβ€²)                =⟨ β…£ βŸ©β‚š
   (U ∧[ π’ͺ X ] V) ∨[ π’ͺ X ] (U ∧[ π’ͺ X ] (V ==> 𝟎[ π’ͺ X ]))  β‰€βŸ¨ β…€  ⟩
   (U ∧[ π’ͺ X ] V) ∨[ π’ͺ X ] W                              β‰€βŸ¨ β…₯  ⟩
   V ∨[ π’ͺ X ] W                                           β– 
    where
     open PosetReasoning (poset-of (π’ͺ X))

     β…  =  𝟏-right-unit-of-∧ (π’ͺ X) U ⁻¹
     β…‘ = ap (Ξ» - β†’ U ∧[ π’ͺ X ] -) (q ⁻¹)
     β…’ = binary-distributivity (π’ͺ X) U V Vβ€²
     β…£ = ap
          (Ξ» - β†’ (U ∧[ π’ͺ X ] V) ∨[ π’ͺ X ] (U ∧[ π’ͺ X ] -))
          (complement-is-heyting-complement V Vβ€² (p , q))
     β…€ = ∨[ π’ͺ X ]-right-monotone Ο†
     β…₯ = ∨[ π’ͺ X ]-left-monotone (∧[ π’ͺ X ]-lowerβ‚‚ U V)

\end{code}