--------------------------------------------------------------------------------
author:        Ayberk Tosun
date-started:  2022-03-01
dates-updated: [2024-05-06]
--------------------------------------------------------------------------------

Originally part of `ayberkt/formal-topology-in-UF`. Ported to TypeTopology on
2022-03-01.

\begin{code}

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

open import MLTT.Spartan
open import UF.FunExt
open import UF.PropTrunc

module Locales.AdjointFunctorTheoremForFrames
         (pt : propositional-truncations-exist)
         (fe : Fun-Ext)
         where

open import Locales.ContinuousMap.Definition pt fe
open import Locales.ContinuousMap.FrameHomomorphism-Properties pt fe
open import Locales.Frame pt fe
open import Locales.GaloisConnection pt fe
open import Slice.Family
open import UF.Logic

open AllCombinators pt fe
open PropositionalTruncation pt
open import UF.SubtypeClassifier

open Locale

\end{code}

\begin{code}

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

\end{code}

\begin{code}

 private
  π’ͺXβ‚š = poset-of (π’ͺ X)
  π’ͺYβ‚š = poset-of (π’ͺ Y)

 open GaloisConnectionBetween π’ͺYβ‚š π’ͺXβ‚š

 aft-forward : (f : π’ͺYβ‚š ─mβ†’ π’ͺXβ‚š)
             β†’ has-right-adjoint f
             β†’ is-join-preserving (π’ͺ Y) (π’ͺ X) (f .pr₁) holds
 aft-forward (f , ΞΌ) (β„Š@(g , _) , p) S =
  ⋁[ π’ͺ X ]-unique ⁅ f s ∣ s Ξ΅ S ⁆ (f (⋁[ π’ͺ Y ] S)) (Ξ² , Ξ³)
   where
    open Joins (Ξ» x y β†’ x ≀[ poset-of (π’ͺ X) ] y)
    open Joins (Ξ» x y β†’ x ≀[ poset-of (π’ͺ Y) ] y)
     using () renaming (_is-an-upper-bound-of_ to _is-a-ub-of_)

    Ξ² : (f (⋁[ π’ͺ Y ] S) is-an-upper-bound-of ⁅ f s ∣ s Ξ΅ S ⁆) holds
    Ξ² i = ΞΌ (S [ i ] , ⋁[ π’ͺ Y ] S) (⋁[ π’ͺ Y ]-upper S i)

    Ξ³ : (β±― (u , _) κž‰ upper-bound ⁅ f s ∣ s Ξ΅ S ⁆ , f (⋁[ π’ͺ Y ] S) ≀[ π’ͺXβ‚š ] u) holds
    Ξ³ (u , q) = prβ‚‚ (p (⋁[ π’ͺ Y ] S) u) (⋁[ π’ͺ Y ]-least S (g u , Ξ΄))
     where
      Ξ΄ : (g u is-a-ub-of S) holds
      Ξ΄ i = pr₁ (p (S [ i ]) u) (q i)

\end{code}

\begin{code}

 aft-backward : (𝒻 : π’ͺYβ‚š ─mβ†’ π’ͺXβ‚š)
              β†’ is-join-preserving (π’ͺ Y) (π’ͺ X) (𝒻 .pr₁) holds
              β†’ has-right-adjoint 𝒻
 aft-backward 𝒻@(f , ΞΌf) Ο† = βˆ₯βˆ₯-rec (has-right-adjoint-is-prop 𝒻) Ξ³ 𝒷
  where
   open Joins (Ξ» x y β†’ x ≀[ poset-of (π’ͺ Y) ] y)
   open Joins (Ξ» x y β†’ x ≀[ poset-of (π’ͺ X) ] y)
         using    ()
         renaming (_is-an-upper-bound-of_ to _is-an-ub-of_)

   Ξ³ : Ξ£ ℬ κž‰ Fam π“₯ ⟨ π’ͺ Y ⟩ , is-basis-for (π’ͺ Y) ℬ β†’ Ξ£ β„Š κž‰ π’ͺXβ‚š ─mβ†’ π’ͺYβ‚š , (𝒻 ⊣ β„Š) holds
   Ξ³ (ℬ , b) = (g , ΞΌβ€²) , Ξ²
    where
     𝒦 : ∣ π’ͺXβ‚š βˆ£β‚š β†’ π“₯ Μ‡
     𝒦 y = Ξ£ i κž‰ index ℬ , (f (ℬ [ i ]) ≀[ π’ͺXβ‚š ] y) holds

     g : ∣ π’ͺXβ‚š βˆ£β‚š β†’ ∣ π’ͺYβ‚š βˆ£β‚š
     g y = ⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 y ⁆

     ΞΌβ€² : is-monotonic π’ͺXβ‚š π’ͺYβ‚š g holds
     ΞΌβ€² (y₁ , yβ‚‚) p =
      ⋁[ π’ͺ Y ]-least ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 y₁ ⁆ (g yβ‚‚ , Ξ΅)
        where
         open PosetReasoning π’ͺXβ‚š

         Ξ΅ : (g yβ‚‚ is-an-upper-bound-of ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 y₁ ⁆) holds
         Ξ΅ 𝒾@(i , q) = ⋁[ π’ͺ Y ]-upper ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 yβ‚‚ ⁆ (i , †)
          where
           † : (f (ℬ [ i ]) ≀[ π’ͺXβ‚š ] yβ‚‚) holds
           † = f (ℬ [ i ]) β‰€βŸ¨ q ⟩ y₁ β‰€βŸ¨ p ⟩ yβ‚‚ β– 

     β„Š = g , ΞΌβ€²

     Ξ² : (𝒻 ⊣ β„Š) holds
     Ξ² U V = β₁ , Ξ²β‚‚
      where
       π’₯ : Fam π“₯ (index ℬ)
       π’₯ = pr₁ (b U)

       c : U = ⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆
       c = ⋁[ π’ͺ Y ]-unique ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆ U (prβ‚‚ (b U))

       β₁ : (f U ≀[ π’ͺXβ‚š ] V β‡’ U ≀[ π’ͺYβ‚š ] g V) holds
       β₁ p = U                             =⟨ c βŸ©β‚š
              ⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆  β‰€βŸ¨ † ⟩
              g V                           β– 
        where
         open PosetReasoning π’ͺYβ‚š
         open PosetReasoning π’ͺXβ‚š using () renaming (_β–  to _β– β‚—; _β‰€βŸ¨_⟩_ to _β‰€βŸ¨_βŸ©β‚—_)

         u = ⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 V ⁆

         ΞΆ : (u is-an-upper-bound-of ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆) holds
         ΞΆ j = ⋁[ π’ͺ Y ]-upper ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 V ⁆ (π’₯ [ j ] , Ξ·)
                where
                 ΞΈ : ((ℬ [ π’₯ [ j ] ]) ≀[ π’ͺYβ‚š ] U) holds
                 ΞΈ = ℬ [ π’₯ [ j ] ]                β‰€βŸ¨ ⋁[ π’ͺ Y ]-upper _ j ⟩
                     ⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆ =⟨ c ⁻¹             βŸ©β‚š
                     U β– 

                 Ξ· : (f (ℬ [ π’₯ [ j ] ]) ≀[ π’ͺXβ‚š ] V) holds
                 Ξ· = f (ℬ [ π’₯ [ j ] ])  β‰€βŸ¨ ΞΌf (ℬ [ π’₯ [ j ] ] , U) ΞΈ βŸ©β‚—
                     f U                β‰€βŸ¨ p βŸ©β‚—
                     V                  β– β‚—

         † : ((⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆) ≀[ poset-of (π’ͺ Y) ] g V) holds
         † = ⋁[ π’ͺ Y ]-least ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆ (g V , ‑)
              where
               ‑ : (g V is-an-upper-bound-of ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆) holds
               ‑ i = ℬ [ π’₯ [ i ] ]                         β‰€βŸ¨ 𝟏    ⟩
                     ⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆          β‰€βŸ¨ 𝟐    ⟩
                     ⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 V ⁆  =⟨ refl βŸ©β‚š
                     g V                                   β– 
                      where
                       𝟏 = ⋁[ π’ͺ Y ]-upper ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆ i
                       𝟐 = ⋁[ π’ͺ Y ]-least ⁅ ℬ [ i ] ∣ i Ξ΅ π’₯ ⁆ (u , ΞΆ)

       † : ((⋁[ π’ͺ X ] ⁅ f (ℬ [ i ]) ∣ (i , _) ∢ 𝒦 V ⁆) ≀[ poset-of (π’ͺ X) ] V) holds
       † = ⋁[ π’ͺ X ]-least ⁅ f (ℬ [ i ]) ∣ (i , _) ∢ 𝒦 V ⁆ (V , prβ‚‚)

       Ξ²β‚‚ : (U ≀[ π’ͺYβ‚š ] g V β‡’ f U ≀[ π’ͺXβ‚š ] V) holds
       Ξ²β‚‚ p =
        f U                                      β‰€βŸ¨ ΞΌf (U , g V) p                ⟩
        f (g V)                                  =⟨ refl                          βŸ©β‚š
        f (⋁[ π’ͺ Y ] ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 V ⁆) =⟨ Ο† ⁅ ℬ [ i ] ∣ (i , _) ∢ 𝒦 V ⁆ βŸ©β‚š
        ⋁[ π’ͺ X ] ⁅ f (ℬ [ i ]) ∣ (i , _) ∢ 𝒦 V ⁆ β‰€βŸ¨ †                             ⟩
        V                                        β– 
         where
          open PosetReasoning π’ͺXβ‚š

\end{code}

\begin{code}

 open ContinuousMaps
 open FrameHomomorphismProperties

 aft : (𝒻 : π’ͺYβ‚š ─mβ†’ π’ͺXβ‚š)
     β†’ has-right-adjoint 𝒻 ↔ is-join-preserving (π’ͺ Y) (π’ͺ X) (𝒻 .pr₁) holds
 aft 𝒻 = aft-forward 𝒻 , aft-backward 𝒻

 right-adjoint-of : (X ─cβ†’ Y) β†’ π’ͺXβ‚š ─mβ†’ π’ͺYβ‚š
 right-adjoint-of 𝒽@(h , Ο…@(_ , _ , jp)) = pr₁ (aft-backward hβ‚˜ Ξ³)
  where
   hβ‚˜ : π’ͺYβ‚š ─mβ†’ π’ͺXβ‚š
   hβ‚˜ = h , frame-morphisms-are-monotonic (π’ͺ Y) (π’ͺ X) h Ο…

   Ξ³ : is-join-preserving (π’ͺ Y) (π’ͺ X) h holds
   Ξ³ S = ⋁[ π’ͺ X ]-unique ⁅ h s ∣ s Ξ΅ S ⁆ (h (⋁[ π’ͺ Y ] S)) (jp S)

 infixl 9 _⁎·_

 _⁎·_ : (X ─cβ†’ Y) β†’ ⟨ π’ͺ X ⟩ β†’ ⟨ π’ͺ Y ⟩
 _⁎·_ f U = right-adjoint-of f .pr₁ U

 open ContinuousMapNotation X Y

 adjunction-inequality-forward : (𝒻@(f , _) : X ─cβ†’ Y)
                               β†’ (U : ⟨ π’ͺ X ⟩) (V : ⟨ π’ͺ Y ⟩)
                               β†’ ((𝒻 β‹†βˆ™ V) ≀[ poset-of (π’ͺ X) ] U) holds
                               β†’ (V ≀[ poset-of (π’ͺ Y) ] (𝒻 ⁎· U)) holds
 adjunction-inequality-forward 𝒻@(f , Ο‘@(_ , _ , p)) U V Ο† =
  pr₁ (prβ‚‚ (aft-backward π’»β‚˜ Ξ³) V U) Ο†
   where
    π’»β‚˜ : poset-of (π’ͺ Y) ─mβ†’ poset-of (π’ͺ X)
    π’»β‚˜ = f , frame-morphisms-are-monotonic (π’ͺ Y) (π’ͺ X) f Ο‘

    Ξ³ : is-join-preserving (π’ͺ Y) (π’ͺ X) (π’»β‚˜ .pr₁) holds
    Ξ³ S = ⋁[ π’ͺ X ]-unique ⁅ f V ∣ V Ξ΅ S ⁆ (f (⋁[ π’ͺ Y ] S)) (p S)

 adjunction-inequality-backward : (𝒻@(f , _) : X ─cβ†’ Y)
                                β†’ (U : ⟨ π’ͺ X ⟩) (V : ⟨ π’ͺ Y ⟩)
                                β†’ (V ≀[ poset-of (π’ͺ Y) ] (𝒻 ⁎· U)) holds
                                β†’ ((𝒻 β‹†βˆ™ V) ≀[ poset-of (π’ͺ X) ] U) holds
 adjunction-inequality-backward 𝒻@(f , Ο‘@(_ , _ , p)) U V Ο† =
  prβ‚‚ (prβ‚‚ (aft-backward π’»β‚˜ Ξ³) V U) Ο†
   where
    π’»β‚˜ : poset-of (π’ͺ Y) ─mβ†’ poset-of (π’ͺ X)
    π’»β‚˜ = f , frame-morphisms-are-monotonic (π’ͺ Y) (π’ͺ X) f Ο‘

    Ξ³ : is-join-preserving (π’ͺ Y) (π’ͺ X) (π’»β‚˜ .pr₁) holds
    Ξ³ S = ⋁[ π’ͺ X ]-unique ⁅ f V ∣ V Ξ΅ S ⁆ (f (⋁[ π’ͺ Y ] S)) (p S)

 fβ‚Š-is-right-adjoint-of-f⁺ : (𝒻@(f , _) : X ─cβ†’ Y)
                           β†’ let
                              π’»β‚˜ = monotone-map-of (π’ͺ Y) (π’ͺ X) 𝒻
                             in
                              (π’»β‚˜ ⊣ right-adjoint-of 𝒻) holds
 fβ‚Š-is-right-adjoint-of-f⁺ 𝒻 V U =
  adjunction-inequality-forward 𝒻 U V , adjunction-inequality-backward 𝒻 U V

 f⁺fβ‚Š-is-deflationary : (𝒻 : X ─cβ†’ Y)
                      β†’ let
                         π’»β‚Š = right-adjoint-of 𝒻 .pr₁
                        in
                         (U : ⟨ π’ͺ X ⟩)
                        β†’ (𝒻 .pr₁ (π’»β‚Š U) ≀[ poset-of (π’ͺ X) ] U) holds
 f⁺fβ‚Š-is-deflationary 𝒻 = counit π’»βΊβ‚˜ π’»β‚Šβ‚˜ (fβ‚Š-is-right-adjoint-of-f⁺ 𝒻)
  where
   π’»β‚Š   = right-adjoint-of 𝒻 .pr₁
   π’»β‚Šβ‚˜  = right-adjoint-of 𝒻
   π’»βΊβ‚˜  = monotone-map-of (π’ͺ Y) (π’ͺ X) 𝒻

 fβ‚Š-preserves-binary-meets : (𝒻@(f , _) : X ─cβ†’ Y)
                           β†’ (U V : ⟨ π’ͺ X ⟩)
                           β†’ let
                              π’»β‚Š = right-adjoint-of 𝒻 .pr₁
                             in
                              π’»β‚Š (U ∧[ π’ͺ X ] V) = π’»β‚Š U ∧[ π’ͺ Y ] π’»β‚Š V
 fβ‚Š-preserves-binary-meets 𝒻 U V = ∧[ π’ͺ Y ]-unique †
  where
   open Meets (Ξ» U V β†’ U ≀[ poset-of (π’ͺ Y) ] V)

   π’»β‚Š = right-adjoint-of 𝒻 .pr₁

   †₁ : (π’»β‚Š (U ∧[ π’ͺ X ] V) is-a-lower-bound-of (π’»β‚Š U , π’»β‚Š V)) holds
   †₁ = β₁ , Ξ²β‚‚
    where
     open PosetReasoning (poset-of (π’ͺ X))

     β…  = f⁺fβ‚Š-is-deflationary 𝒻 (U ∧[ π’ͺ X ] V)

     β₁ : (π’»β‚Š (U ∧[ π’ͺ X ] V) ≀[ poset-of (π’ͺ Y) ] (π’»β‚Š U)) holds
     β₁ = adjunction-inequality-forward 𝒻 U (π’»β‚Š (U ∧[ π’ͺ X ] V)) β€»
      where
       β€» : (𝒻 β‹†βˆ™ π’»β‚Š (U ∧[ π’ͺ X ] V) ≀[ poset-of (π’ͺ X) ] U) holds
       β€» = 𝒻 β‹†βˆ™ π’»β‚Š (U ∧[ π’ͺ X ] V)     β‰€βŸ¨ β…  ⟩
           U ∧[ π’ͺ X ] V               β‰€βŸ¨ β…‘ ⟩
           U                          β– 
            where
             β…‘ = ∧[ π’ͺ X ]-lower₁ U V

     Ξ²β‚‚ : (π’»β‚Š (U ∧[ π’ͺ X ] V) ≀[ poset-of (π’ͺ Y) ] (π’»β‚Š V)) holds
     Ξ²β‚‚ = adjunction-inequality-forward 𝒻 V (π’»β‚Š (U ∧[ π’ͺ X ] V)) β€»
      where
       β€» : (𝒻 β‹†βˆ™ π’»β‚Š (U ∧[ π’ͺ X ] V) ≀[ poset-of (π’ͺ X) ] V) holds
       β€» = 𝒻 β‹†βˆ™ π’»β‚Š (U ∧[ π’ͺ X ] V)     β‰€βŸ¨ β…  ⟩
           U ∧[ π’ͺ X ] V               β‰€βŸ¨ β…‘ ⟩
           V                          β– 
            where
             β…‘ = ∧[ π’ͺ X ]-lowerβ‚‚ U V

   †₂ : ((u , _) : lower-bound (π’»β‚Š U , π’»β‚Š V))
      β†’ (u ≀[ poset-of (π’ͺ Y) ] π’»β‚Š (U ∧[ π’ͺ X ] V)) holds
   †₂ (u , p , q) = adjunction-inequality-forward 𝒻 (U ∧[ π’ͺ X ] V) u β€»
    where
     ♣₁ : (𝒻 β‹†βˆ™ u ≀[ poset-of (π’ͺ X) ] U) holds
     ♣₁ = adjunction-inequality-backward 𝒻 U u p

     ♣₂ : (𝒻 β‹†βˆ™ u ≀[ poset-of (π’ͺ X) ] V) holds
     ♣₂ = adjunction-inequality-backward 𝒻 V u q

     β€» : (𝒻 β‹†βˆ™ u ≀[ poset-of (π’ͺ X) ]  (U ∧[ π’ͺ X ] V)) holds
     β€» = ∧[ π’ͺ X ]-greatest U V (𝒻 β‹†βˆ™ u) ♣₁ ♣₂

   † : (π’»β‚Š (U ∧[ π’ͺ X ] V) is-glb-of (π’»β‚Š U , π’»β‚Š V)) holds
   † = †₁ , †₂

\end{code}

Added on 2024-05-06.

Monotone equivalences are adjoints.

\begin{code}

 monotone-equivalences-are-adjoints
  : (sβ‚˜@(s , _) : poset-of (π’ͺ X) ─mβ†’ poset-of (π’ͺ Y))
  β†’ (rβ‚˜@(r , _) : poset-of (π’ͺ Y) ─mβ†’ poset-of (π’ͺ X))
  β†’ s ∘ r ∼ id
  β†’ r ∘ s ∼ id
  β†’ (rβ‚˜ ⊣ sβ‚˜) holds
 monotone-equivalences-are-adjoints (s , 𝓂₁) (r , 𝓂₂) Ο† ψ U V = † , ‑
  where
   open PosetReasoning π’ͺXβ‚š

   † : (r U ≀[ π’ͺXβ‚š ] V β‡’ U ≀[ π’ͺYβ‚š ] s V) holds
   † p =
    sections-are-order-embeddings (poset-of (π’ͺ Y)) (poset-of (π’ͺ X)) r s 𝓂₁ Ο† β€»
     where
      β€» : (r U ≀[ π’ͺXβ‚š ] r (s V)) holds
      β€» = r U β‰€βŸ¨ p ⟩ V =⟨ ψ V ⁻¹ βŸ©β‚š r (s V) β– 

   ‑ : (U ≀[ π’ͺYβ‚š ] s V β‡’ r U ≀[ π’ͺXβ‚š ] V) holds
   ‑ p = r U β‰€βŸ¨ 𝓂₂ (U , _) p ⟩ r (s V) =⟨ ψ V βŸ©β‚š V β– 

\end{code}