{-# OPTIONS --without-K #-} module Model.Exponential where open import Cats.Category open import Model.RGraph as RG using (RGraph) open import Model.Type.Core open import Model.Product open import Util.HoTT.HLevel open import Util.Prelude hiding (_×_ ; id ; _∘_) open RGraph open RG._⇒_ private variable Δ : RGraph infixr 9 _↝_ Ap : ⟦Type⟧ Δ → Δ .Obj → RGraph Ap {Δ} T δ = record { ObjHSet = T .ObjHSet δ ; eqHProp = eqHProp T (Δ .eq-refl _) ; eq-refl = λ x → T .eq-refl x } _↝_ : (T U : ⟦Type⟧ Δ) → ⟦Type⟧ Δ _↝_ T U = record { ObjHSet = λ γ → HLevel⁺ (Ap T γ RG.⇒ Ap U γ) (RG.⇒-IsSet {Ap T γ} {Ap U γ}) ; eqHProp = λ γ≈γ′ f g → ∀∙-HProp λ x → ∀∙-HProp λ y → T .eqHProp γ≈γ′ x y →-HProp′ U .eqHProp γ≈γ′ (f .RG.fobj x) (g .RG.fobj y) ; eq-refl = λ f → f .RG.feq } curry : (T U V : ⟦Type⟧ Δ) → T × U ⇒ V → T ⇒ U ↝ V curry {Δ} T U V f = record { fobj = λ {δ} t → record { fobj = λ u → f .fobj (t , u) ; feq = λ x≈y → f .feq (Δ .eq-refl δ) (T .eq-refl t , x≈y) } ; feq = λ γ≈γ′ x≈y v≈w → f .feq γ≈γ′ (x≈y , v≈w) } eval : (T U : ⟦Type⟧ Δ) → (T ↝ U) × T ⇒ U eval T U = record { fobj = λ { (f , x) → f .RG.fobj x } ; feq = λ { γ≈γ′ (f≈g , x≈y) → f≈g x≈y } } eval∘curry : (T U V : ⟦Type⟧ Δ) {f : T × U ⇒ V} → eval U V ∘ ⟨_×_⟩ {B = U} (curry T U V f) id ≈ f eval∘curry T U V = ≈⁺ λ γ x → refl instance hasExponentials : ∀ {Δ} → HasExponentials (⟦Types⟧ Δ) hasExponentials .HasExponentials.hasBinaryProducts = hasBinaryProducts hasExponentials .HasExponentials._↝′_ T U = record { Cᴮ = T ↝ U ; eval = eval T U ; curry′ = λ {A} f → record { arr = curry A T U f ; prop = eval∘curry A T U ; unique = λ {g} g-prop → ≈⁺ λ γ h → RG.≈→≡ (RG.≈⁺ λ x → sym (g-prop .≈⁻ γ (h , x))) } } module ⟦Types⟧↝ {Δ} = HasExponentials (hasExponentials {Δ}) ↝-resp-≈⟦Type⟧ : ∀ {Δ} (T T′ U U′ : ⟦Type⟧ Δ) → T ≈⟦Type⟧ T′ → U ≈⟦Type⟧ U′ → T ↝ U ≈⟦Type⟧ T′ ↝ U′ ↝-resp-≈⟦Type⟧ {Δ} T T′ U U′ T≈T′ U≈U′ = ⟦Types⟧↝.↝-resp-≅ {Δ} {T} {T′} {U} {U′} T≈T′ U≈U′ subT-↝ : ∀ {Γ Δ} (f : Γ RG.⇒ Δ) → (T U : ⟦Type⟧ Δ) → subT f T ↝ subT f U ≈⟦Type⟧ subT f (T ↝ U) subT-↝ {Γ} {Δ} f T U = record { forth = record { fobj = λ g → record { fobj = g .fobj ; feq = λ {x y} x≈y → transportEq U (g .feq (transportEq T x≈y)) } ; feq = λ γ≈γ′ f≈g x≈y → f≈g x≈y } ; back = record { fobj = λ g → record { fobj = g .fobj ; feq = λ {x y} x≈y → transportEq U (g .feq (transportEq T x≈y)) } ; feq = λ γ≈γ′ f≈g x≈y → f≈g x≈y } ; back-forth = ≈⁺ λ γ x → RG.≈→≡ (RG.≈⁺ λ y → refl) ; forth-back = ≈⁺ λ γ x → RG.≈→≡ (RG.≈⁺ λ y → refl) }