{-# OPTIONS --without-K #-}
module Trunc.TypeConstructors where
open import lib.Basics
open import lib.NType2
open import lib.Equivalences2
open import lib.types.Unit
open import lib.types.Nat hiding (_+_)
open import lib.types.Pi
open import lib.types.Sigma
open import lib.types.Paths
open import Preliminaries
open import Pointed
open import UniverseOfNTypes
open import Trunc.Universal
open import Trunc.Basics
open trunc-ty
open trunc-props
module trunc-self {i} {n : ℕ₋₂} (A : n -Type i) where
trunc : ∀ {j} → trunc-ty n ⟦ A ⟧ j
trunc = record
{ type = A
; cons = idf _
; univ = λ _ → snd (ide _) }
module trunc-⊤ {n : ℕ₋₂} = trunc-self {n = n} ⊤-≤
module trunc-Σ {ia ib j} {n : ℕ₋₂} {A : Type ia}
(TrA : trunc-ty n A (ia ⊔ ib ⊔ j))
{B : ⟦ type TrA ⟧ → Type ib}
(TrB : (ta : ⟦ type TrA ⟧) → trunc-ty n (B ta) (ib ⊔ j)) where
trunc : trunc-ty n (Σ A (B ∘ cons TrA)) (ib ⊔ j)
trunc = record
{ type = Σ-≤ (type TrA) (type ∘ TrB)
; cons = λ {(a , b) → (cons TrA a , cons (TrB (cons TrA a)) b)}
; univ = snd ∘ e } where
e : (U : n -Type _) → _
e U =
(⟦ Σ-≤ (type TrA) (type ∘ TrB) ⟧ → ⟦ U ⟧) ≃⟨ curry-equiv ⟩
((ta : ⟦ type TrA ⟧) → ⟦ type (TrB ta) ⟧ → ⟦ U ⟧) ≃⟨ equiv-Π-r eb ⟩
((ta : ⟦ type TrA ⟧) → B ta → ⟦ U ⟧) ≃⟨ ea ⟩
((a : A) → B (cons TrA a) → ⟦ U ⟧) ≃⟨ curry-equiv ⁻¹ ⟩
(Σ A (B ∘ cons TrA) → ⟦ U ⟧) ≃∎ where
ea = dup {j = ib ⊔ j} TrA (λ ta → B ta →-≤ U)
eb = λ ta → up {j = ib ⊔ j} (TrB ta) U
module trunc-× {ia ib j} {n : ℕ₋₂} {A : Type ia} {B : Type ib}
(TrA : trunc-ty n A (ia ⊔ ib ⊔ j))
(TrB : trunc-ty n B (ib ⊔ j)) =
trunc-Σ {j = j} TrA (λ _ → TrB)
module trunc-path {i j} {n : ℕ₋₂} {A : Type i} (TrA : trunc-ty (S n) A (lsucc (i ⊔ j))) where
private
l : ULevel
l = i ⊔ j
TrAA : trunc-ty (S n) (A × A) (lsucc l)
TrAA = trunc-×.trunc {j = lsucc l} TrA TrA
module MA = trunc-props {j = lsucc l} {k = l} TrA
module MAA = trunc-props {j = lsucc l} {k = l} TrAA
module code (U : n -Type l) where
abstract
code : ⟦ type TrAA ⟧ → n -Type l
code = rec {j = lsucc l} TrAA (n -Type-≤ l)
(λ {(a₀ , a₁) → (a₀ == a₁ → ⟦ U ⟧) →-≤ U})
code-β : {a₀ a₁ : A} → ⟦ code (cons TrAA (a₀ , a₁)) ⟧
≃ ((a₀ == a₁ → ⟦ U ⟧) → ⟦ U ⟧)
code-β = coe-equiv (ap ⟦_⟧ (rec-β TrAA _))
encode : {ta₀ ta₁ : ⟦ type TrA ⟧} → ta₀ == ta₁ → ⟦ code (ta₀ , ta₁) ⟧
encode idp = MA.elim (λ ta → raise (code (ta , ta)))
(λ _ → <– code-β (λ f → f idp)) _
encode-β : {a₀ a₁ : A} (p : a₀ == a₁) (f : a₀ == a₁ → ⟦ U ⟧)
→ –> code-β (encode (ap (cons TrA) p)) f == f p
encode-β idp = app= (ap (–> code-β) (MA.elim-β _) ∙ <–-inv-r code-β _)
decode : {ta₀ ta₁ : ⟦ type TrA ⟧}
→ ⟦ code (ta₀ , ta₁) ⟧ → (ta₀ == ta₁ → ⟦ U ⟧) → ⟦ U ⟧
decode = MAA.elim
(λ {(ta₀ , ta₁) → _ →-≤ (ta₀ == ta₁ → ⟦ U ⟧) →-≤ raise U})
(λ _ c g → –> code-β c (g ∘ ap (cons TrA))) _ where
decode-β : {a₀ a₁ : A} (c : ⟦ code (cons TrAA (a₀ , a₁)) ⟧)
(g : cons TrA a₀ == cons TrA a₁ → ⟦ U ⟧)
→ decode c g == –> code-β c (g ∘ ap (cons TrA))
decode-β = app= ∘ app= (MAA.elim-β _)
decode-encode : {ta₀ ta₁ : ⟦ type TrA ⟧} (q : ta₀ == ta₁)
(g : ta₀ == ta₁ → ⟦ U ⟧) → decode (encode q) g == g q
decode-encode idp = MA.elim
(λ ta → Π-≤ (ta == ta → ⟦ U ⟧)
(λ g → Path-≤ (raise U) (decode (encode idp) g) (g idp)))
(λ _ g → decode-β (encode idp) g ∙ encode-β idp (g ∘ ap (cons TrA))) _
trunc : (a₀ a₁ : A) → trunc-ty n (a₀ == a₁) l
trunc a₀ a₁ = record
{ type = Path-< (type TrA) (cons TrA a₀) (cons TrA a₁)
; cons = ap (cons TrA)
; univ = snd ∘ e } where
e : (U : _) → (cons TrA a₀ == cons TrA a₁ → ⟦ U ⟧) ≃ (a₀ == a₁ → ⟦ U ⟧)
e U = equiv u v u-v v-u where
open code U
u : (cons TrA a₀ == cons TrA a₁ → ⟦ U ⟧) → a₀ == a₁ → ⟦ U ⟧
u g = g ∘ ap (cons TrA)
v : (a₀ == a₁ → ⟦ U ⟧) → cons TrA a₀ == cons TrA a₁ → ⟦ U ⟧
v f q = –> code-β (encode q) f
u-v : (f : a₀ == a₁ → ⟦ U ⟧) → u (v f) == f
u-v f = λ= (λ p → encode-β p f)
v-u : (g : cons TrA a₀ == cons TrA a₁ → ⟦ U ⟧) → v (u g) == g
v-u g = λ= (λ q → ! (decode-β (encode q) g) ∙ decode-encode q g)