{- Adjunction between suspension and loop space (Rongji Kang, Oct. 2021)

Main results:

- Ω∙ : ℕ → Pointed ℓ → Pointed ℓ
- ΣΩAdjunction : ((X , x₀) : Pointed ℓ) (Y : Pointed ℓ') → (∙Susp X →∙ Y) ≃ ((X , x₀) →∙ Ω∙ 1 Y)
-}
{-# OPTIONS --safe #-}
module Cubical.HITs.Susp.LoopAdjunction where

open import Cubical.Foundations.Prelude
open import Cubical.Foundations.GroupoidLaws
open import Cubical.Foundations.Equiv
open import Cubical.Foundations.Isomorphism

open import Cubical.Foundations.Pointed.Base
open import Cubical.Data.Nat.Base
open import Cubical.HITs.Susp.Base

private
  variable
     ℓ' : Level

Ω∙ :   Pointed   Pointed 
Ω∙ 0 X = X
Ω∙ 1 (X , x) = (x  x) , refl
Ω∙ (suc (suc n)) X = Ω∙ 1 (Ω∙ (suc n) X)

ΣX→∙YEquiv : ((X , x₀) : Pointed ) ((Y , y₀) : Pointed ℓ')
            (Susp∙ X →∙ (Y , y₀))  (Σ[ y  Y ] (X  (y₀  y)))
ΣX→∙YEquiv (X , x₀) (Y , y₀) =
  isoToEquiv (iso left→right right→left right→left→right left→right→left)
  where
    left→right : (Susp∙ X →∙ (Y , y₀))  Σ[ y  Y ] (X  (y₀  y))
    left→right (f , b) .fst = f south
    left→right (f , b) .snd x = sym b  cong f (merid x)

    right→left : (Σ[ y  Y ] (X  (y₀  y)))  (Susp∙ X →∙ (Y , y₀))
    right→left (y , g) .fst north = y₀
    right→left (y , g) .fst south = y
    right→left (y , g) .fst (merid x i) = g x i
    right→left (y , g) .snd = refl

    right→left→right : (g : Σ[ y  Y ] (X  (y₀  y)))  left→right (right→left g)  g
    right→left→right (y , g) i .fst = y
    right→left→right (y , g) i .snd x = lUnit (g x) (~ i)

    left→right→left : (f : Susp∙ X →∙ (Y , y₀))  right→left (left→right f)  f
    left→right→left (f , b) i .fst north = b (~ i)
    left→right→left (f , b) i .fst south = f south
    left→right→left (f , b) i .fst (merid x j) =
      hcomp  k  λ { (i = i0)  compPath-filler (sym b) (cong f (merid x)) k j
                     ; (i = i1)  f (merid x (j  k))
                     ; (j = i0)  b (~ i)
                     ; (j = i1)  f (merid x k) })
            (b (~ (i  j)))
    left→right→left (f , b) i .snd j = b (~ i  j)

X→∙ΩYEquiv : ((X , x₀) : Pointed )((Y , y₀) : Pointed ℓ')
            ((X , x₀) →∙ Ω∙ 1 (Y , y₀))  (Σ[ y  Y ] (X  (y₀  y)))
X→∙ΩYEquiv (X , x₀) (Y , y₀) =
  isoToEquiv (iso left→right right→left right→left→right left→right→left)
  where
    left→right : ((X , x₀) →∙ Ω∙ 1 (Y , y₀))  Σ[ y  Y ] (X  (y₀  y))
    left→right _ .fst = y₀
    left→right (f , b) .snd = f

    right→left : (Σ[ y  Y ] (X  (y₀  y)))  ((X , x₀) →∙ Ω∙ 1 (Y , y₀))
    right→left (y , g) .fst x = g x  sym (g x₀)
    right→left (y , g) .snd = rCancel (g x₀)

    right→left→right : (g : Σ[ y  Y ] (X  (y₀  y)))  left→right (right→left g)  g
    right→left→right (y , g) i .fst = g x₀ i
    right→left→right (y , g) i .snd x j =
      hcomp  k  λ { (i = i0)  compPath-filler (g x) (sym (g x₀)) k j
                     ; (i = i1)  g x j
                     ; (j = i0)  y₀
                     ; (j = i1)  g x₀ (i  ~ k) })
            (g x j)

    f-filler : ((X , x₀) →∙ Ω∙ 1 (Y , y₀))  X  (i j k : I)  Y
    f-filler (f , b) x i j k =
      hfill  k'  λ { (i = i0)  compPath-filler (f x) (sym (f x₀)) k' j
                      ; (i = i1)  f x j
                      ; (j = i0)  y₀
                      ; (j = i1)  b i (~ k') })
            (inS (f x j)) k

    bottom : ((X , x₀) →∙ Ω∙ 1 (Y , y₀))  (i j k : I)  Y
    bottom (f , b) i j k =
      hcomp  l  λ { (i = i0)  b (~ l) (k  ~ j)
                     ; (i = i1)  b (j  ~ l) k
                     ; (j = i0)  b (~ l) k
                     ; (j = i1)  y₀
                     ; (k = i0)  y₀
                     ; (k = i1)  b (~ l  i) (~ j) })
            y₀

    left→right→left : (f : (X , x₀) →∙ Ω∙ 1 (Y , y₀))  right→left (left→right f)  f
    left→right→left (f , b) i .fst x j =
      f-filler (f , b) x i j i1
    left→right→left (f , b) i .snd j k =
      hcomp  l  λ { (i = i0)  rCancel-filler (f x₀) l j k
                     ; (i = i1)  b j k
                     ; (j = i0)  f-filler (f , b) x₀ i k l
                     ; (j = i1)  y₀
                     ; (k = i0)  y₀
                     ; (k = i1)  b i (~ l  ~ j) })
            (bottom (f , b) i j k)

{- The Main Theorem -}
ΣΩAdjunction : ((X , x₀) : Pointed ) (Y : Pointed ℓ')  (Susp∙ X →∙ Y)  ((X , x₀) →∙ Ω∙ 1 Y)
ΣΩAdjunction X Y = compEquiv (ΣX→∙YEquiv X Y) (invEquiv (X→∙ΩYEquiv X Y))