{-# OPTIONS --prop --rewriting  #-}

module strictifyPMP where

open import lib
open import model

-- In this file, we define a strictified model using Pédrot's strict presheaves

module str (C : CwF {lzero}{lzero}{lzero}{lzero}) (M : Model C) where

  import strictifyCat C M as strictifyCat

  Cₛ = strictifyCat.Cₛ
  Mₛ = strictifyCat.Mₛ

  private module Cₛ = CwF Cₛ
  private module Ct = CwF-tools Cₛ
  private module Mₛ = Model Mₛ

  variable i j k l : Level

  Ob  = Cₛ.Con -- named x,y,z
  Hom = Cₛ.Sub -- named f,g,h

  -- sections of a strict presheaf on C/x
  record Y
    (x : Ob)
    (A :  {y}  Hom y x  Set i)
    (A-rel :  {y} (f : Hom y x)  (∀ {z} (g : Hom z y)  A (f Cₛ.∘ g))  Prop i)
    : Set i
    where
    constructor mkY
    field
      a   :  {y}  (f : Hom y x)  A f
      rel :  {y}  (f : Hom y x)  A-rel f  g  a (f Cₛ.∘ g))
  open Y public renaming (a to ∣_∣)

  record Con (i : Level) : Set (lsuc i) where
    constructor mkCon
    field
      Γ   : Ob  Set i
      rel :  {x}  (∀ {y : Ob}  Hom y x  Γ y)  Prop i
  open Con public renaming (Γ to ∣_∣)

  -- converting Γ to ordinary presheaf
  Yᶜ : Con i  Ob  Set i
  Yᶜ Γ x = Y x  {y} _   Γ  y)  _  Γ .rel)

  Yᶜ~ :  {Γ : Con i} {x₀ x₁} (xₑ : x₀ ~ x₁) {γ₀ : Yᶜ Γ x₀} {γ₁ : Yᶜ Γ x₁}   {x}   γ₀  {x}) ~  {x}   γ₁  {x})  γ₀ ~ γ₁
  Yᶜ~ xₑ γₑ = ~congₚₛ (cong₂  x  mkY {x = x}) xₑ γₑ)

  Yᶜ≡ :  {Γ : Con i} {x}  {γ₀ γ₁ : Yᶜ Γ x}   {x}   γ₀  {x}) ~  {x}   γ₁  {x})  γ₀ ~ γ₁
  Yᶜ≡ e = ~congₚₛ (cong mkY e)

  infixl 9 _|ᶜ_
  _|ᶜ_ :  {Γ : Con i} {x}  Yᶜ Γ x   {y}  Hom y x  Yᶜ Γ y
   γ |ᶜ f  g =  γ  (f Cₛ.∘ g)
  (γ |ᶜ f) .rel g = γ .rel (f Cₛ.∘ g)

  record Sub (Δ : Con i) (Γ : Con j) : Set (i  j) where
    constructor mkSub
    field
      γ   :  {x}  (δ : Yᶜ Δ x)   Γ  x
      rel :  {x}  (δ : Yᶜ Δ x)  Γ .rel  f  γ (δ |ᶜ f))
  open Sub public renaming (γ to ∣_∣)

  Sub≡ :  {Γ : Con i} {Δ : Con j}
    {γ₀ γ₁ : Sub Δ Γ}   {x}   γ₀  {x}) ~  {x}   γ₁  {x})  γ₀ ~ γ₁
  Sub≡ e = ~congₚₛ (cong mkSub e)

  -- converting a Sub into a natural transformation
   :  {Γ : Con i} {Δ : Con j} (σ : Sub Δ Γ)   {x}  Yᶜ Δ x  Yᶜ Γ x
    σ δ  f =   σ  (δ |ᶜ f)
   σ δ .rel f =  σ .rel (δ |ᶜ f)

  infixl 9 _∘_
  _∘_ :  {Γ : Con i} {Δ : Con j} {Θ : Con k}  Sub Δ Γ  Sub Θ Δ  Sub Θ Γ
   σ  τ  θ =  σ  ( τ θ)
  (σ  τ) .rel θ = σ .rel ( τ θ)

  comp :  (Γ : Con i) {Δ : Con i}  Sub Δ Γ  ∀{Θ : Con i}  Sub Θ Δ  Sub Θ Γ
  comp Γ σ τ = _∘_ {Γ = Γ} σ τ
  syntax comp Γ σ τ = σ ∘[ Γ ] τ

  assoc :  {Γ : Con i} {Δ : Con j} {Θ : Con k} {Ξ : Con l} (σ : Sub Δ Γ) (τ : Sub Θ Δ) (υ : Sub Ξ Θ)  σ  (τ  υ) ~ (σ  τ)  υ
  assoc σ τ υ = ~refl

  id :  {Γ : Con i}  Sub Γ Γ
   id  γ =  γ  Cₛ.id
  id .rel γ = γ .rel Cₛ.id

  idr :  {Γ : Con i} {Δ : Con j} (σ : Sub Δ Γ)  σ  id ~ σ
  idr σ = ~refl

  idl :  {Γ : Con i} {Δ : Con j} (σ : Sub Δ Γ)  id  σ ~ σ
  idl σ = ~refl

  -- CwF structure on strict presheaves
  module Ĉ where
    record Ty (Γ : Con i) (j : Level) : Set (i  lsuc j) where
      field
        A   :  {x}  (γ : Yᶜ Γ x)  Set j
        rel :  {x}  (γ : Yᶜ Γ x)  (∀ {y} (f : Hom y x)  A (γ |ᶜ f))  Prop j
    open Ty public renaming (A to ∣_∣)

    Yᵀ :  {Γ : Con i}  Ty Γ j   {x}  Yᶜ Γ x  Set j
    Yᵀ A {x = x} γ = Y x  f   A  (γ |ᶜ f))  f  A .rel (γ |ᶜ f))

    Yᵀ≡ :  {Γ : Con i} (A : Ty Γ j) {x₀ x₁} (xₑ : x₀ ~ x₁) {γ₀ : Yᶜ Γ x₀} {γ₁ : Yᶜ Γ x₁} (γₑ : γ₀ ~ γ₁)
            {a₀ : Yᵀ A {x₀} γ₀} {a₁ : Yᵀ A {x₁} γ₁}   {x}   a₀  {x}) ~  {x}   a₁  {x})  a₀ ~ a₁
    Yᵀ≡ A xₑ γₑ aₑ = ~congₚₛ (cong₃  x γ  mkY {x = x} {A = λ f   A  (γ |ᶜ f)} {A-rel = λ f  A .rel (γ |ᶜ f)}) xₑ γₑ aₑ)

    infixl 9 ⟨_,_⟩_|ᵀ_
    ⟨_,_⟩_|ᵀ_ :  {Γ : Con i} (A : Ty Γ j) {x} (γ : Yᶜ Γ x)  Yᵀ A γ   {y} (f : Hom y x)  Yᵀ A (γ |ᶜ f)
      A , γ  a |ᵀ f  g =  a  (f Cₛ.∘ g)
    ( A , γ  a |ᵀ f) .rel g = a .rel (f Cₛ.∘ g)

    infixl 9 _[_]T
    _[_]T :  {Γ : Con i} {Δ : Con j}  Ty Γ k  Sub Δ Γ  Ty Δ k
     A [ σ ]T  δ =  A  ( σ δ)
    (A [ σ ]T) .rel δ = A .rel ( σ δ)

    [∘]T :  {Γ : Con i} {Δ : Con j} {Θ : Con k}
             (A : Ty Γ l) (σ : Sub Δ Γ) (τ : Sub Θ Δ)  A [ σ  τ ]T ~ A [ σ ]T [ τ ]T
    [∘]T A γ δ = ~refl

    [id]T :  {Γ : Con i} (A : Ty Γ j)  A [ id ]T ~ A
    [id]T A = ~refl

    record Tm (Γ : Con i) (A : Ty Γ j) : Set (i  j) where
      constructor mkTm
      field
        a   :  {x} (γ : Yᶜ Γ x)   A  γ
        rel :  {x} (γ : Yᶜ Γ x)  A .rel γ  f  a (γ |ᶜ f))
    open Tm public renaming (a to ∣_∣)

    Tm≡ :  {Γ : Con i} {A : Ty Γ j} {a₀ a₁ : Tm Γ A}   {x}   a₀  {x}) ~  {x}   a₁  {x})  a₀ ~ a₁
    Tm≡ e = ~congₚₛ (cong mkTm e)

    Yᵗ :  {Γ : Con i} {A : Ty Γ j}  Tm Γ A   {x} (γ : Yᶜ Γ x)  Yᵀ A γ
     Yᵗ a γ  f =  a  (γ |ᶜ f)
    Yᵗ a γ .rel f = a .rel (γ |ᶜ f)

    infixl 9 _[_]t
    _[_]t :  {Γ : Con i} {Δ : Con j} {A : Ty Γ k}  Tm Γ A  (σ : Sub Δ Γ)  Tm Δ (A [ σ ]T)
     a [ σ ]t  δ =  a  ( σ δ)
    (a [ σ ]t) .rel δ = a .rel ( σ δ)

    [∘]t :  {Γ : Con i} {Δ : Con j} {Θ : Con k} {A : Ty Γ l}
      (a : Tm Γ A) (σ : Sub Δ Γ) (τ : Sub Θ Δ)  a [ σ  τ ]t ~ a [ σ ]t [ τ ]t
    [∘]t a σ τ = ~refl

    [id]t :  {Γ : Con i} {A : Ty Γ j} (a : Tm Γ A)  a [ id ]t ~ a
    [id]t a = ~refl

    record ∣▹∣ (Γ : Con i) (A : Ty Γ j) (x : Ob) : Set (i  j) where
      constructor mk▹
      field
        con : Yᶜ Γ x
        ty :  A  con
    open ∣▹∣ public

    record ▹-rel
      {Γ : Con i} {A : Ty Γ j} {x : Ob} (γa :  {y}  Hom y x  ∣▹∣ Γ A y) : Prop (i  j)
      where
      constructor mk▹rel
      field
        con :  {y} (f : Hom y x) {z} (g : Hom z y)   γa f .con  g ~  γa (f Cₛ.∘ g) .con  Cₛ.id
        ty :
          A .rel
            record
              { a = λ f   γa f .∣▹∣.con  Cₛ.id
              ; rel = λ f  coeₚ (cong (Γ .rel) (funextHᵢᵣ λ g  con f g)) (γa f .∣▹∣.con .rel Cₛ.id) }
             f  coe (cong  A  (Yᶜ≡ (funextHᵢᵣ λ g  con f g))) (γa f .ty))
    open ▹-rel public

    infixl 2 _▹_
    _▹_ : (Γ : Con i)  Ty Γ j  Con (i  j)
     Γ  A  = ∣▹∣ Γ A
    (Γ  A) .rel = ▹-rel

    Y▹ : {Γ : Con i} {A : Ty Γ j} {x : Ob} (γ : Yᶜ Γ x)  Yᵀ A γ  Yᶜ (Γ  A) x
     Y▹ γ a  f .con = γ |ᶜ f
     Y▹ γ a  f .ty =  a  f
    Y▹ γ a .rel f .con = λ _ _  ~refl
    Y▹ γ a .rel f .ty = a .rel f

    p : {Γ : Con i} {A : Ty Γ j}  Sub (Γ  A) Γ
     p  γa =   γa  Cₛ.id .con  Cₛ.id
    p {Γ = Γ} .rel γa =
      let e = funextHᵢᵣ λ f  γa .rel Cₛ.id .con Cₛ.id f in
      coeₚ (cong (Γ .rel) e) ( γa  Cₛ.id .con .rel Cₛ.id)

    q : {Γ : Con i} {A : Ty Γ j}  Tm (Γ  A) (A [ p ]T)
     q {A = A}  γa =
      let e = Yᶜ≡ (funextHᵢᵣ λ f  γa .rel Cₛ.id .con Cₛ.id f) in
      coe (cong  A  e) ( γa  Cₛ.id .ty)
    q .rel γa = γa .rel Cₛ.id .ty

    infixl 4 _,_
    _,_ : {Γ : Con i} {Δ : Con j} {A : Ty Γ k} (σ : Sub Δ Γ)  Tm Δ (A [ σ ]T)  Sub Δ (Γ  A)
     σ , a  δ .con =  σ δ
     σ , a  δ .ty =  a  δ
    (σ , a) .rel δ .con = λ _ _  ~refl
    (_,_ {A = A} σ a) .rel δ .ty = a .rel δ

    infixl 4 _,⟨_⟩_
    _,⟨_⟩_ : {Γ : Con i} {Δ : Con j} (γ : Sub Δ Γ) (A : Ty Γ k)  Tm Δ (A [ γ ]T)  Sub Δ (Γ  A)
    γ ,⟨ A  a = γ , a

    _,[_]_ : ∀{Γ : Con i}{Δ : Con j}(γ : Sub Δ Γ) {A : Ty Γ k} {A' : Ty Δ k}  A [ γ ]T ~ A'  Tm Δ A'  Sub Δ (Γ  A)
     _,[_]_ {Γ}{Δ = Δ} γ {A}{A'} e a  δ .con =  γ δ
     _,[_]_ {Γ}{Δ = Δ} γ {A}{A'} e a  δ .ty = coe ((cong  (A : Ty Δ _)   A  δ) e) ⁻¹) ( a  δ)
    _,[_]_ {Γ = Γ}{Δ = Δ} γ {A}{A'} e a .rel δ .con = λ _ _  ~refl
    _,[_]_ {Γ = Γ}{Δ = Δ} γ {A}{A'} e a .rel {x = x} δ .ty =
      let e = ~cong (cong  (A : Ty Δ _)  A .rel δ) (e ⁻¹))
                    (funextᵢ λ xₑ 
                      funext λ {γ₀} {γ₁} γₑ 
                        cong₂  y (γ : Hom y x)   a  (δ |ᶜ γ)) xₑ γₑ  coe≡-eq _ ( a  (δ |ᶜ γ₁)))
      in coeₚ e (a .rel δ)

    ,∘ : {Γ : Con i} {Δ : Con j} {Θ : Con k} {A : Ty Γ l}
      (σ : Sub Δ Γ) (a : Tm Δ (A [ σ ]T)) (τ : Sub Θ Δ) 
      (σ ,⟨ A  a)  τ ~ (σ  τ , a [ τ ]t)
    ,∘ σ a τ = ~refl

    ▹β₁ : {Γ : Con i} {Δ : Con j} {A : Ty Γ k} (σ : Sub Δ Γ) (a : Tm Δ (A [ σ ]T))  p  (σ ,⟨ A  a) ~ σ
    ▹β₁ σ a = ~refl

    ▹β₂ : {Γ : Con i} {Δ : Con j} {A : Ty Γ k} (σ : Sub Δ Γ) (a : Tm Δ (A [ σ ]T))  q [ σ ,⟨ A  a ]t ~ a
    ▹β₂ γ a = ~refl

    ▹η : {Γ : Con i} {A : Ty Γ j}  (p {A = A} ,⟨ A  q) ~ id {Γ = Γ  A}
    ▹η {Γ = Γ} {A = A} =
      Sub≡ (funextᵢ λ {x} {x'} ex 
            funext λ {γa} {γa'} eγa 
              cong₃  x  mk▹ {Γ = Γ} {A = A} {x}) ex
                ((cong₂  z   p {z}) ex eγa)  (Yᶜ≡ (funextHᵢᵣ  f  γa' .rel Cₛ.id .con Cₛ.id f) ⁻¹)))
                ((coe≡-eq _ ( γa  Cₛ.id .ty)) ⁻¹  (cong₂  x (γ : Yᶜ (Γ  A) x)   γ  Cₛ.id .ty) ex eγa)))

     : {Γ : Con i} {Δ : Con j} {A : Ty Γ k} (σ : Sub Δ Γ)  Sub (Δ  A [ σ ]T) (Γ  A)
     σ = σ  p , q

    sg : {Γ : Con i} {A : Ty Γ j} (a : Tm Γ A)  Sub Γ (Γ  A)
    sg a = id , a

     : Con lzero
       x = 
     .rel γ = ⊤ₚ

    ε : {Γ : Con i}  Sub Γ 
     ε  γ = _
    ε .rel γ = ttₚ

    ε∘ : {Γ : Con i} {Δ : Con j} (σ : Sub Δ Γ)  ε  σ ~ ε
    ε∘ γ = ~refl

    ◇η : (ε {Γ = }) ~ (id {Γ = })
    ◇η = ~refl

    -- Now we build a universe hierarchy for the CwF of strict presheaves
    -- These universes come from the external universes Set i, not from the CwF structure on M
    {-
    record ∣U∣ (i : Level) (x : Ob) : Set (lsuc i) where
      field
        t : ∀ {y} → Hom y x → Set i   -- this is simpler than just Ty (yoneda x)
        rel : (∀ {y} (f : Hom y x) → t f) → Prop i
    open ∣U∣ public renaming (t to ∣_∣)

    U : (i : Level) → {Γ : Con j} → Ty Γ (lsuc i)
    ∣ U i ∣ {x} γ = ∣U∣ i x
    U i .rel {x} γ A =
      (λ {y} (f : Hom y x) {z} (g : Hom z y) → ∣ A f ∣ g) ~
      (λ {y} (f : Hom y x) {z} (g : Hom z y) → ∣ A (f Cₛ.∘ g) ∣ Cₛ.id)

    U-[] : (i : Level) {Γ : Con j} {Δ : Con k} (γ : Sub Δ Γ) → U i [ γ ]ᵀ ~ U i
    U-[] i γ = ~refl

    El : {Γ : Con j} → Tm Γ (U i) → Ty Γ i
    ∣ El A ∣ γ = ∣ ∣ A ∣ γ ∣ Cₛ.id
    El A .rel γ a =
      ∣ A ∣ γ .rel λ f → let e = (~congᵢᵣ (~congᵢᵣ ((A .rel γ) ⁻¹) ~refl (~refl {a = Cₛ.id})) ~refl (~refl {a = f})) in
                             coe (~to≡ e) (a f)

    El-[] : {Γ : Con j} {Δ : Con k} (A : Tm Γ (U i)) (γ : Sub Δ Γ) → El A [ γ ]ᵀ ~ El (A [ γ ]ᵗ)
    El-[] A γ = ~refl

    c : {Γ : Con j} → Ty Γ i → Tm Γ (U i)
    ∣ ∣ c A ∣ γ ∣ f = ∣ A ∣ (γ |ᶜ f)
    ∣ c A ∣ γ .rel a = A .rel γ a
    c A .rel γ = ~refl

    c-[] : {Γ : Con j} {Δ : Con k} (A : Ty Γ i) (γ : Sub Δ Γ) → c A [ γ ]ᵗ ~ c (A [ γ ]ᵀ)
    c-[] A γ = ~refl

    U-β : {Γ : Con j} (A : Ty Γ i) → El (c A) ~ A
    U-β A = ~refl

    {-
    U-η : (A : Tm Γ (U i)) → c (El A) ≡ A
    U-η A = Tm-≡ (funextᵢ (funext λ γ → sym (∣U∣-≡ (ap (λ a → a Cₛ.id) (A .rel γ)) {!refl!})))
    -}

    -- Then we equip the CwF of strict presheaves with dependent products

    Π : {Γ : Con i} (A : Ty Γ j) → Ty (Γ ▹ A) k → Ty Γ (j ⊔ k)
    ∣ Π A B ∣ γ = (a : Yᵀ A γ) → ∣ B ∣ (Y▹ γ a)
    Π A B .rel γ t = (a : Yᵀ A γ) → B .rel (Y▹ γ a) λ f → t f (⟨ A , γ ⟩ a |ᵀ f)

    Π-[] : {Γ : Con i} {Δ : Con j}
      (A : Ty Γ k) (B : Ty (Γ ▹ A) l) (γ : Sub Δ Γ) →
      Π A B [ γ ]ᵀ ~ Π (A [ γ ]ᵀ) (B [ γ ↑ ]ᵀ)
    Π-[] A B γ = ~refl

    app : {Γ : Con i}
      {A : Ty Γ j} (B : Ty (Γ ▹ A) k) →
      Tm Γ (Π A B) → (a : Tm Γ A) → Tm Γ (B [ id , a ]ᵀ)
    ∣ app B t a ∣ γ = ∣ t ∣ γ (Yᵗ a γ)
    app B t a .rel γ = t .rel γ (Yᵗ a γ)

    app-[] : {Γ : Con i} {Δ : Con j}
      {A : Ty Γ k} (B : Ty (Γ ▹ A) l) →
      (t : Tm Γ (Π A B)) (a : Tm Γ A) (γ : Sub Δ Γ) →
      app B t a [ γ ]ᵗ ~
      app (B [ γ ↑ ]ᵀ) (t [ γ ]ᵗ) (a [ γ ]ᵗ)
    app-[] B t a γ = ~refl

    lam : {Γ : Con i} {A : Ty Γ j} {B : Ty (Γ ▹ A) k} → Tm (Γ ▹ A) B → Tm Γ (Π A B)
    ∣ lam b ∣ γ a = ∣ b ∣ (Y▹ γ a)
    lam b .rel γ a = b .rel (Y▹ γ a)

    lam-[] : {Γ : Con i} {Δ : Con j} {A : Ty Γ k} {B : Ty (Γ ▹ A) l}
             (b : Tm (Γ ▹ A) B) (γ : Sub Δ Γ) → lam b [ γ ]ᵗ ~ lam (b [ γ ↑ ]ᵗ)
    lam-[] b γ = ~refl

    Π-β : {Γ : Con i}
      {A : Ty Γ j} (B : Ty (Γ ▹ A) k) (b : Tm (Γ ▹ A) B) (a : Tm Γ A) →
      app B (lam b) a ~ b [ id , a ]ᵗ
    Π-β B b a = ~refl

    Π-η :
      {Γ : Con i} {A : Ty Γ j} (B : Ty (Γ ▹ A) k) (t : Tm Γ (Π A B)) →
      lam (app (B [ p ↑ ]ᵀ) (t [ p ]ᵗ) (q {A = A})) ~ t
    Π-η B t = ~refl

    -- This concludes the definition of the CwF of strict presheaves on Cₛ.
    -- Now we define the higher-order model in the CwF of strict presheaves by internalising the CwF structure on Cₛ.
    -}

  -- reorganising Cₛ.Ty as a strict presheaf
  CTy : Con lzero
  CTy =
    record {
      Γ = Cₛ.Ty ;
      rel = λ {x} γ  ∀{y}(f : Hom y x)  (γ Cₛ.id Cₛ.[ f ]T) ~ γ f
    }

  -- reorganising Cₛ.Tm as a dependent strict presheaf
  CTm : Ĉ.Ty CTy lzero
  CTm = record { A = λ {x} γ  Cₛ.Tm x ( γ  Cₛ.id)
               ; rel = λ {x} γ α  ∀{y}(f : Hom y x)  (α Cₛ.id Cₛ.[ f ]t) ~ α f }

  -- the new sort of types in our final model
  Ty : Con i  Set i
  Ty Γ = Sub Γ CTy

  _[_]T : ∀{Γ : Con i}  Ty Γ  ∀{Δ : Con i}  Sub Δ Γ  Ty Δ
  A [ σ ]T = A  σ

  [∘]T : ∀{Γ : Con i}{A : Ty Γ}{Δ : Con i}{σ : Sub Δ Γ}{Θ : Con i}{τ : Sub Θ Δ}
         A [ σ  τ ]T ~ A [ σ ]T [ τ ]T
  [∘]T = ~refl

  [id]T : ∀{Γ : Con i}{A : Ty Γ}  A [ id ]T ~ A
  [id]T = ~refl

  -- the new sort of terms in our final model
  Tm : (Γ : Con i)  Ty Γ  Set i
  Tm Γ A = Ĉ.Tm Γ (CTm Ĉ.[ A ]T)

  _[_]t : ∀{Γ : Con i}{A : Ty Γ}  Tm Γ A  ∀{Δ : Con i}(γ : Sub Δ Γ)  Tm Δ (A [ γ ]T)
  a [ γ ]t = a Ĉ.[ γ ]t

  [∘]t : ∀{Γ : Con i}{A : Ty Γ}{a : Tm Γ A}{Δ : Con i}{σ : Sub Δ Γ}{Θ : Con i}{τ : Sub Θ Δ}
         _[_]t {A = A} a (σ ∘[ Γ ] τ) ~ _[_]t {A = A [ σ ]T} (_[_]t {A = A} a σ) τ
  [∘]t = ~refl

  [id]t : ∀{Γ : Con i}{A : Ty Γ}{a : Tm Γ A}
          _[_]t {A = A} a id ~ a
  [id]t = ~refl

  _▹_ : (Γ : Con i)(A : Ty Γ)  Con i
  Γ  A = Γ Ĉ.▹ (CTm Ĉ.[ A ]T)

  infixl 4 _,_
  _,_ : ∀{Γ Δ : Con i}(σ : Sub Δ Γ){A : Ty Γ}  Tm Δ (A [ σ ]T)  Sub Δ (Γ  A)
  _,_ σ {A} a = Ĉ._,_ {A = CTm Ĉ.[ A ]T} σ a

  p : ∀{Γ : Con i}{A : Ty Γ}  Sub (Γ  A) Γ
  p {A = A} = Ĉ.p {A = CTm Ĉ.[ A ]T}

  q : ∀{Γ : Con i}{A : Ty Γ}  Tm (Γ  A) (A [ p {A = A} ]T)
  q {A = A} = Ĉ.q {A = CTm Ĉ.[ A ]T}

  ▹β₁ : ∀{Γ Δ : Con i}{γ : Sub Δ Γ}{A : Ty Γ}{a : Tm Δ (A [ γ ]T)}
        p {A = A} ∘[ Γ ] (_,_ γ {A = A} a) ~ γ
  ▹β₁ = ~refl

  ▹β₂ : ∀{Γ Δ : Con i}{γ : Sub Δ Γ}{A : Ty Γ}{a : Tm Δ (A [ γ ]T)}
        _[_]t {A = A [ p {A = A} ]T} (q {A = A}) (_,_ γ {A = A} a) ~ a
  ▹β₂ = ~refl

  ▹η : ∀{Γ : Con i}{Δ : Con i}{A : Ty Γ}{γa : Sub Δ (Γ  A)}
         (Ĉ._,[_]_ (p {A = A}  γa) {A = CTm Ĉ.[ A ]T} {A' = CTm Ĉ.[ A  (p {A = A})  γa ]T} ~refl
                  (_[_]t {A = A [ p {A = A} ]T} (q {A = A}) γa))
          ~ γa
  ▹η {Γ = Γ}{Δ = Δ}{A = A}{γa = γa} = cong  (x : Sub (Γ  A) (Γ  A))  x  γa) Ĉ.▹η

  mutual
    data Tel : Set where
      ◇ₜ : Tel
      _▹ₜ_ : (Γ : Tel)  Ty (El Γ)  Tel

    El : Tel  Con lzero
    El ◇ₜ = Ĉ.◇
    El (Γ ▹ₜ A) = (El Γ)  A

  Cₛₛ : CwF {lzero}{lzero}{lzero}{lzero}
  Cₛₛ = record
         { Con = Tel
         ; Sub = λ Γ Δ  Sub (El Γ) (El Δ)
         ; _∘_ = λ {_} {_} γ {_} δ  γ  δ
         ; ass = ~refl
         ; id = id
         ; idl = ~refl
         ; idr = ~refl
         ;  = ◇ₜ
         ; ε = Ĉ.ε
         ; ◇η = ~refl
         ; Ty = λ Γ  Ty (El Γ)
         ; _[_]T = λ {_} A {_} γ  A [ γ ]T
         ; [∘]T = ~refl
         ; [id]T = ~refl
         ; Tm = λ Γ A  Tm (El Γ) A
         ; _[_]t = λ {_}{A} a {_} γ  _[_]t {A = A} a γ
         ; [∘]t = ~refl
         ; [id]t = ~refl
         ; _▹_ = λ Γ A  Γ ▹ₜ A
         ; _,[_]_ = λ {_}{Δ} γ {A}{A'} e a  γ Ĉ.,[ cong  (γ : Ty (El Δ))  CTm Ĉ.[ γ ]T) e ] a
         ; p = λ {_}{A}  p {A = A}
         ; q = λ {_}{A}  q {A = A}
         ; ▹β₁ = ~refl
         ; ▹β₂ = ~refl
         ; ▹η = λ {_}{_}{A}{_}  ▹η {A = A} -- not reflexivity!
         }

  open CwF-tools Cₛₛ

  -- Counterparts of p, q, ↑ in the language of presheaves
  Cp : {Γ : Con i}(A : Ty Γ){x : Ob}(γ : Yᶜ Γ x)  Yᶜ Γ (x Cₛ.▹  A  γ)
  Cp A γ = γ |ᶜ Cₛ.p

  Cq : {Γ : Con i}(A : Ty Γ){x : Ob}(γ : Yᶜ Γ x)  Ĉ.Yᵀ (CTm Ĉ.[ A ]T) (Cp A γ)
  Cq {Γ} A {x} γ =
    mkY
       {y} f  coe (cong (Cₛ.Tm y) (Cₛ.[∘]T {γ = Cₛ.p} {δ = f} ⁻¹  A .rel γ (Cₛ.p Cₛ.∘ f))) (Cₛ.q Cₛ.[ f ]t))
       {y} f {z} g  cong₂  A a  Cₛ._[_]t {A = A} a g) (A .rel γ (Cₛ.p Cₛ.∘ f) ⁻¹  Cₛ.[∘]T {γ = Cₛ.p} {δ = f}) (coe≡-eq _ (Cₛ.q Cₛ.[ f ]t) ⁻¹)
                        Cₛ.[∘]t {γ = f} {δ = g} ⁻¹  coe≡-eq _ (Cₛ.q Cₛ.[ f Cₛ.∘ g ]t))

  C↑ : {Γ : Con i}(A : Ty Γ){x : Ob}(γ : Yᶜ Γ x)  Yᶜ (Γ  A) (x Cₛ.▹  A  γ)
  C↑ {Γ} A {x} γ = Ĉ.Y▹ (γ |ᶜ Cₛ.p) (Cq A γ)

  -- Some equations for Cp, Cq, C↑
  Cp-↑ : {Γ : Con i}(A : Ty Γ){x : Ob}(γ : Yᶜ Γ x){y : Ob}(f : Hom y x)
        (Cp A γ) |ᶜ (Ct.↑ f) ~ Cp A (γ |ᶜ f)
  Cp-↑ {Γ} A {x} γ {y} f = cong₂  y (f : Hom y x)  γ |ᶜ f) (cong (Cₛ._▹_ y) (A .rel γ f))
                                 (Ct.▹β₁-EX {e = Cₛ.[∘]T {γ = f} {δ = Cₛ.p}}  cong  A  f Cₛ.∘ Cₛ.p {A = A}) (A .rel γ f))

  Cq-↑ : {Γ : Con i}(A : Ty Γ){x : Ob}(γ : Yᶜ Γ x){y : Ob}(f : Hom y x)
        Ĉ.⟨ CTm Ĉ.[ A ]T , Cp A γ  (Cq A γ) |ᵀ (Ct.↑ f) ~ Cq A (γ |ᶜ f)
  Cq-↑ {Γ} A {x} γ {y} f =
    Ĉ.Yᵀ≡ (CTm Ĉ.[ A ]T) (cong (Cₛ._▹_ y) (A .rel γ f)) (Cp-↑ A γ f)
          (funexthᵢ λ {z}  funext λ {g₀} {g₁} gₑ 
            coe≡-eq _ (Cₛ.q Cₛ.[ Ct.↑ f Cₛ.∘ g₀ ]t) ⁻¹  Cₛ.[∘]t {γ = Ct.↑ f} {δ = g₀}
             cong₄  x A a f  Cₛ._[_]t {x} {A} a f) (cong (Cₛ._▹_ y) (A .rel γ f)) e₂ e₁ gₑ  coe≡-eq _ (Cₛ.q Cₛ.[ g₁ ]t))
    where
      e₁ : Cₛ.q {A =  A  γ} Cₛ.[ Ct.↑ f ]t ~ Cₛ.q {A =  A  (γ |ᶜ f)}
      e₁ = Ct.▹β₂-EX {γ = f Cₛ.∘ Cₛ.p} {e = Cₛ.[∘]T {γ = f} {δ = Cₛ.p}}  cong  A  Cₛ.q {A = A}) (A .rel γ f)

      e₂ :  A  γ Cₛ.[ Cₛ.p ]T Cₛ.[ Ct.↑ f ]T ~  A  (γ |ᶜ f) Cₛ.[ Cₛ.p ]T
      e₂ = Cₛ.[∘]T {γ = Cₛ.p} {δ = Ct.↑ f} ⁻¹  A .rel γ (Cₛ.p Cₛ.∘ (Ct.↑ f))
            cong₂  x   A  {x}) (cong (Cₛ._▹_ y) (A .rel γ f)) (Cp-↑ A γ f)  A .rel (γ |ᶜ f) Cₛ.p ⁻¹

  C↑-↑ : {Γ : Con i}(A : Ty Γ){x : Ob}(γ : Yᶜ Γ x){y : Ob}(f : Hom y x)
        (C↑ A γ) |ᶜ (Ct.↑ f) ~ C↑ A (γ |ᶜ f)
  C↑-↑ {Γ} A {x} γ {y} f = cong₃  x  Ĉ.Y▹ {A = CTm Ĉ.[ A ]T} {x = x}) (cong (Cₛ._▹_ y) (A .rel γ f)) (Cp-↑ A γ f) (Cq-↑ A γ f)

  Cp-sg : {Γ : Con i}(A : Ty Γ)(a : Tm Γ A){x : Ob}(γ : Yᶜ Γ x)
        (Cp A γ) |ᶜ (Ct.sg (Ĉ.∣ a  γ)) ~ γ
  Cp-sg {Γ = Γ} A a {x} γ = cong  (f : Hom x x)  γ |ᶜ f) (Ct.▹β₁-EX {γ = Cₛ.id} {e = Cₛ.[id]T})

  Cq-sg : {Γ : Con i}(A : Ty Γ)(a : Tm Γ A){x : Ob}(γ : Yᶜ Γ x)
         Ĉ.⟨ CTm Ĉ.[ A ]T , Cp A γ  (Cq A γ) |ᵀ (Ct.sg (Ĉ.∣ a  γ)) ~ Ĉ.Yᵗ a γ
  Cq-sg {Γ = Γ} A a {x} γ =
    Ĉ.Yᵀ≡ (CTm Ĉ.[ A ]T) ~refl (Cp-sg A a γ)
          (funexthᵢᵣ λ {y} f  coe≡-eq _ (Cₛ.q Cₛ.[ Ct.sg (Ĉ.∣ a  γ) Cₛ.∘ f ]t) ⁻¹  Cₛ.[∘]t {γ = Ct.sg (Ĉ.∣ a  γ)} {δ = f}
                                cong₂  A a  Cₛ._[_]t {A = A} a f) e (Ct.▹β₂-EX {γ = Cₛ.id} {e = Cₛ.[id]T})  a .Ĉ.rel γ f)
    where
      e :  A  γ Cₛ.[ Cₛ.p ]T Cₛ.[ Ct.sg (Ĉ.∣ a  γ) ]T ~  A  γ
      e = Cₛ.[∘]T {γ = Cₛ.p} {δ = Ct.sg (Ĉ.∣ a  γ)} ⁻¹  A .rel γ (Cₛ.p Cₛ.∘ Ct.sg (Ĉ.∣ a  γ))  cong  A  (Cp-sg A a γ)

  C↑-sg : {Γ : Con i}(A : Ty Γ)(a : Tm Γ A){x : Ob}(γ : Yᶜ Γ x)
          (C↑ A γ) |ᶜ (Ct.sg (Ĉ.∣ a  γ)) ~ Ĉ.Y▹ {A = CTm Ĉ.[ A ]T} γ (Ĉ.Yᵗ a γ)
  C↑-sg {Γ = Γ} A a {x} γ = cong₂ (Ĉ.Y▹ {A = CTm Ĉ.[ A ]T}) (Cp-sg A a γ) (Cq-sg A a γ)

  Cp-subExt : {Γ : Con i}(A : Ty Γ)(a : Tm Γ A){x : Ob}(γ : Yᶜ Γ x){y : Ob}(f : Hom y x)
             (Cp A γ) |ᶜ (f Cₛ.,[ ~refl ] (Ĉ.∣ a  γ Cₛ.[ f ]t)) ~ γ |ᶜ f
  Cp-subExt {Γ} A a {x} γ {y} f = cong  f  γ |ᶜ f) (Cₛ.▹β₁ {γ = f} {a = Ĉ.∣ a  γ Cₛ.[ f ]t})

  -- Substituting equations in types and terms
  C↑-[↑]T : {Γ : Con i}(A : Ty Γ)(B : Ty (Γ  A)){x : Ob}(γ : Yᶜ Γ x){y : Ob}(f : Hom y x)
           B  (C↑ A γ) Cₛ.[ Ct.↑ f ]T ~  B  (C↑ A (γ |ᶜ f))
  C↑-[↑]T A B γ {y} f = B .rel (C↑ A γ) (Ct.↑ f)  cong₂  x   B  {x}) (cong (Cₛ._▹_ y) (A .rel γ f)) (C↑-↑ A γ f)

  C↑-[↑]t : {Γ : Con i}(A : Ty Γ)(B : Ty (Γ  A))(t : Tm (Γ  A) B){x : Ob}(γ : Yᶜ Γ x){y : Ob}(f : Hom y x)
          Ĉ.∣ t  (C↑ A γ) Cₛ.[ Ct.↑ f ]t ~ Ĉ.∣ t  (C↑ A (γ |ᶜ f))
  C↑-[↑]t A B t γ {y} f = t .Ĉ.rel (C↑ A γ) (Ct.↑ f)  cong₂  x  Ĉ.∣ t  {x}) (cong (Cₛ._▹_ y) (A .rel γ f)) (C↑-↑ A γ f)

  C↑-[sg]T : {Γ : Con i}(A : Ty Γ)(a : Tm Γ A)(B : Ty (Γ  A)){x : Ob}(γ : Yᶜ Γ x)
             B  (C↑ A γ) Cₛ.[ Ct.sg (Ĉ.∣ a  γ) ]T ~  B [ Ĉ.sg a ]T  γ
  C↑-[sg]T A a B γ = B .rel (C↑ A γ) (Ct.sg (Ĉ.∣ a  γ))  cong  B  (C↑-sg A a γ)

  C↑-[sg]t : {Γ : Con i}(A : Ty Γ)(a : Tm Γ A)(B : Ty (Γ  A))(t : Tm (Γ  A) B){x : Ob}(γ : Yᶜ Γ x)
            Ĉ.∣ t  (C↑ A γ) Cₛ.[ Ct.sg (Ĉ.∣ a  γ) ]t ~ Ĉ.∣ _[_]t {A = B} t (Ĉ.sg a)  γ
  C↑-[sg]t A a B t γ = t .Ĉ.rel (C↑ A γ) (Ct.sg (Ĉ.∣ a  γ))  cong Ĉ.∣ t  (C↑-sg A a γ)

  -- Dependent products
  Π : ∀{Γ : Con i}(A : Ty Γ)  Ty (Γ  A)  Ty Γ
  Π {Γ = Γ} A B =
    mkSub
       {x} γ  Mₛ.Π ( A  γ) ( B  (C↑ A γ)))
       {x} γ {y} f  Mₛ.Π[] {γ = f}  cong₂ Mₛ.Π (A .rel γ f) (C↑-[↑]T A B γ f))

  lam : ∀{Γ : Con i}(A : Ty Γ){B : Ty (Γ  A)}(t : Tm (Γ  A) B)  Tm Γ (Π A B)
  lam {Γ = Γ} A {B} t =
    Ĉ.mkTm
       {x} γ  Mₛ.lam ( A  γ) { B  (C↑ A γ)} (Ĉ.∣ t  (C↑ A γ)))
       {x} γ {y} f  Mₛ.lam[] {γ = f}  cong₃  A B  Mₛ.lam A {B}) (A .rel γ f) (C↑-[↑]T A B γ f) (C↑-[↑]t A B t γ f))

  app : ∀{Γ : Con i}{A : Ty Γ}{B : Ty (Γ  A)}(t : Tm Γ (Π A B))(u : Tm Γ A)  Tm Γ (B [ Ĉ.sg u ]T)
  app {Γ = Γ}{A}{B} t u =
    Ĉ.mkTm
       {x} γ  coe (cong (Cₛ.Tm x) (C↑-[sg]T A u B γ))
                     (Mₛ.app {A =  A  γ}{B =  B  (C↑ A γ)} (Ĉ.∣ t  γ) (Ĉ.∣ u  γ)))
       {x} γ {y} f  Ct.coe[]t (C↑-[sg]T A u B γ) (Mₛ.app (Ĉ.∣ t  γ) (Ĉ.∣ u  γ)) f
                         coe≡-eq _ (Mₛ.app (Ĉ.∣ t  γ) (Ĉ.∣ u  γ) Cₛ.[ f ]t) ⁻¹
                         Mₛ.app[] {γ = f}
                         cong₄  A B  Mₛ.app {A = A} {B = B}) (A .rel γ f) (C↑-[↑]T A B γ f)
                                (coe≡-eq _ (Ĉ.∣ t  γ Cₛ.[ f ]t) ⁻¹  t .Ĉ.rel γ f) (u .Ĉ.rel γ f)
                         coe≡-eq _ (Mₛ.app (Ĉ.∣ t  (γ |ᶜ f)) (Ĉ.∣ u  (γ |ᶜ f))))

  Πβ : ∀{Γ : Con i}{A : Ty Γ}{B : Ty (Γ  A)}{t : Tm (Γ  A) B}{a : Tm Γ A}
      app {A = A}{B = B} (lam A {B} t) a ~ _[_]t {A = B} t (Ĉ.sg a)
  Πβ {Γ = Γ}{A}{B}{t}{a} = Ĉ.Tm≡ (funextHᵢᵣ λ {x} γ 
    coe≡-eq _ (Mₛ.app (Mₛ.lam ( A  γ) (Ĉ.∣ t  (C↑ A γ))) (Ĉ.∣ a  γ)) ⁻¹  Mₛ.Πβ  C↑-[sg]t A a B t γ)

  Πη : ∀{Γ : Con i}{A : Ty Γ}{B : Ty (Γ  A)}{t : Tm Γ (Π A B)}
      t ~ lam A {B = B [ Ĉ.↑ (p {A = A}) ]T [ Ĉ.sg (q {A = A}) ]T}
                 (app {A = A [ p {A = A} ]T} {B = B [ Ĉ.↑ (p {A = A}) ]T} (_[_]t {A = Π A B} t (p {A = A})) (q {A = A}))
  Πη {Γ = Γ}{A}{B}{t} = Ĉ.Tm≡ (funextHᵢᵣ λ {x} γ 
    Mₛ.Πη  cong₂  B  Mₛ.lam ( A  γ){B = B}) (e₁ γ) (e₂ γ))
    where
      e₁ : {x : Ob} (γ : Yᶜ Γ x)   B  (C↑ A γ) Cₛ.[ Ct.↑ Cₛ.p ]T Cₛ.[ Ct.sg Cₛ.q ]T ~  B  (C↑ A γ)
      e₁ γ = Cₛ.[∘]T {γ = Ct.↑ Cₛ.p} {δ = Ct.sg Cₛ.q} ⁻¹  cong  f   B  (C↑ A γ) Cₛ.[ f ]T) Ct.↑p-sgq  Cₛ.[id]T

      e₂ : {x : Ob} (γ : Yᶜ Γ x)  Mₛ.app (coe (cong (Cₛ.Tm (x Cₛ.▹  A  γ)) (Mₛ.Π[] {γ = Cₛ.p})) (Ĉ.∣ t  γ Cₛ.[ Cₛ.p ]t)) Cₛ.q
                  ~ Ĉ.∣ app {A = A [ p {A = A} ]T} {B = B [ Ĉ.↑ (p {A = A}) ]T} (_[_]t {A = Π A B} t (p {A = A})) (q {A = A})  (C↑ A γ)
      e₂ γ = cong₄  A B  Mₛ.app {A = A} {B = B}) (A .rel γ Cₛ.p) (C↑-[↑]T A B γ Cₛ.p)
                   (coe≡-eq _ (Ĉ.∣ t  γ Cₛ.[ Cₛ.p {A =  A  γ} ]t) ⁻¹  t .Ĉ.rel γ Cₛ.p)
                   (Cₛ.[id]t ⁻¹  coe≡-eq _ (Cₛ.q {A =  A  γ} Cₛ.[ Cₛ.id ]t))
              coe≡-eq _ (Mₛ.app (Ĉ.∣ (_[_]t {A = Π A B} t (p {A = A}))  (C↑ A γ)) (Ĉ.∣ (q {A = A})  (C↑ A γ)))

  -- Booleans with large elimination
  𝔹 : Ty Ĉ.◇
  𝔹 = mkSub
     _  Mₛ.𝔹 Cₛ.[ Cₛ.ε ]T)
     f g  Ct.ε[]T {γ = g})

  𝕥 : Tm Ĉ.◇ 𝔹
  𝕥 = Ĉ.mkTm
     _  Mₛ.𝕥 Cₛ.[ Cₛ.ε ]t)
     f g  Ct.ε[]t {γ = g})

  𝕗 : Tm Ĉ.◇ 𝔹
  𝕗 = Ĉ.mkTm
     _  Mₛ.𝕗 Cₛ.[ Cₛ.ε ]t)
     f g  Ct.ε[]t {γ = g})

  ifᵀ : ∀{Γ}  Tm Γ (𝔹 [ Ĉ.ε ]T)  Ty Γ  Ty Γ  Ty Γ
  ifᵀ b A𝕥 A𝕗 =
    mkSub
       γ  Mₛ.ifᵀ (Ĉ.∣ b  γ) ( A𝕥  γ) ( A𝕗  γ))
       γ f  Mₛ.ifᵀ[] {γ = f}
                cong₃ Mₛ.ifᵀ (coe≡-eq _ (Ĉ.∣ b  γ Cₛ.[ f ]t) ⁻¹  b .Ĉ.rel γ f) (A𝕥 .rel γ f) (A𝕗 .rel γ f))

  ifᵀ[] : ∀{Γ}{b : Tm (El Γ) (𝔹 [ Ĉ.ε ]T)}{A B : Ty (El Γ)}{Δ}{γ : Sub (El Δ) (El Γ)}
         (ifᵀ b A B) [ γ ]T ~ ifᵀ (coe (cong (Tm (El Δ)) ((ε[]T {𝔹}{Γ}{Δ}{γ}))) (_[_]t {A = 𝔹 [ Ĉ.ε ]T} b γ)) (A [ γ ]T) (B [ γ ]T)
  ifᵀ[] = ~refl

  ifᵀβ₁ : ∀{Γ}{A B : Ty Γ}  ifᵀ (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) A B ~ A
  ifᵀβ₁ {Γ}{A}{B} = Sub≡ (funextHᵢᵣ λ {x} γ  Mₛ.ifᵀβ₁)

  ifᵀβ₂ : ∀{Γ}{A B : Ty Γ}  ifᵀ (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) A B ~ B
  ifᵀβ₂ {Γ}{A}{B} = Sub≡ (funextHᵢᵣ λ {x} γ  Mₛ.ifᵀβ₂)

  ifᵗ : ∀{Γ} (P : Ty (Γ  (𝔹 [ Ĉ.ε ]T))) (P𝕥 : Tm Γ (P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) ]T))
             (P𝕗 : Tm Γ (P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) ]T)) (b : Tm Γ (𝔹 [ Ĉ.ε ]T))  Tm Γ (P [ Ĉ.sg b ]T)
  ifᵗ {Γ = Γ} P P𝕥 P𝕗 b =
    Ĉ.mkTm
       {x} γ  coe (cong (Cₛ.Tm x) (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) b P γ))
        (Mₛ.ifᵗ ( P  (C↑ (𝔹 [ Ĉ.ε ]T) γ)) (coe (e𝕥 γ Cₛ.id) (Ĉ.∣ P𝕥  γ)) (coe (e𝕗 γ Cₛ.id) (Ĉ.∣ P𝕗  γ)) (Ĉ.∣ b  γ)))
       {x} γ {y} f  Ct.coe[]t (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) b P γ) _ f
         coe≡-eq _ (Mₛ.ifᵗ ( P  (C↑ (𝔹 [ Ĉ.ε ]T) γ)) (coe (e𝕥 γ Cₛ.id) (Ĉ.∣ P𝕥  γ)) (coe (e𝕗 γ Cₛ.id) (Ĉ.∣ P𝕗  γ)) (Ĉ.∣ b  γ) Cₛ.[ f ]t) ⁻¹
         Mₛ.ifᵗ[] {γ = f}
         cong₄ Mₛ.ifᵗ
                (cong₂  y (f : Hom y _)   P  (C↑ (𝔹 [ Ĉ.ε ]T) γ) Cₛ.[ f ]T) (cong (Cₛ._▹_ y) (Ct.ε[]T {γ = f} ⁻¹)) (Ct.↑ε≡↑ f)
                   C↑-[↑]T (𝔹 [ Ĉ.ε ]T) P γ f)
                (coe≡-eq _ (coe (e𝕥 γ Cₛ.id) (Ĉ.∣ P𝕥  γ) Cₛ.[ f ]t) ⁻¹
                   Ct.coe[]t (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) P γ ⁻¹) (Ĉ.∣ P𝕥  γ) f
                   coe≡-eq _ (Ĉ.∣ P𝕥  γ Cₛ.[ f ]t) ⁻¹  P𝕥 .Ĉ.rel γ f  coe≡-eq _ (Ĉ.∣ P𝕥  (γ |ᶜ f)))
                (coe≡-eq _ (coe (e𝕗 γ Cₛ.id) (Ĉ.∣ P𝕗  γ) Cₛ.[ f ]t) ⁻¹
                   Ct.coe[]t (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) P γ ⁻¹) (Ĉ.∣ P𝕗  γ) f
                   coe≡-eq _ (Ĉ.∣ P𝕗  γ Cₛ.[ f ]t) ⁻¹  P𝕗 .Ĉ.rel γ f  coe≡-eq _ (Ĉ.∣ P𝕗  (γ |ᶜ f)))
                (coe≡-eq _ (Ĉ.∣ b  γ Cₛ.[ f ]t) ⁻¹  b .Ĉ.rel γ f)
         coe≡-eq _ (Mₛ.ifᵗ ( P  (C↑ (𝔹 [ Ĉ.ε ]T) (γ |ᶜ f))) (coe (e𝕥 γ f) (Ĉ.∣ P𝕥  (γ |ᶜ f)))
                           (coe (e𝕗 γ f) (Ĉ.∣ P𝕗  (γ |ᶜ f))) (Ĉ.∣ b  (γ |ᶜ f))))
    where
      e𝕥 : {x : Ob} (γ : Yᶜ Γ x) {y : Ob} (f : Hom y x)
          Cₛ.Tm y ( P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) ]T  (γ |ᶜ f))
           ~ Cₛ.Tm y ( P  (C↑ (𝔹 [ Ĉ.ε ]T) (γ |ᶜ f)) Cₛ.[ Ct.sg (Cₛ._[_]t {A = Mₛ.𝔹} Mₛ.𝕥 Cₛ.ε) ]T)
      e𝕥 {x} γ {y} f = cong (Cₛ.Tm y) (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) P (γ |ᶜ f) ⁻¹)

      e𝕗 : {x : Ob} (γ : Yᶜ Γ x) {y : Ob} (f : Hom y x)
          Cₛ.Tm y ( P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) ]T  (γ |ᶜ f))
           ~ Cₛ.Tm y ( P  (C↑ (𝔹 [ Ĉ.ε ]T) (γ |ᶜ f)) Cₛ.[ Ct.sg (Cₛ._[_]t {A = Mₛ.𝔹} Mₛ.𝕗 Cₛ.ε) ]T)
      e𝕗 {x} γ {y} f = cong (Cₛ.Tm y) (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) P (γ |ᶜ f) ⁻¹)

  ifᵗβ₁ : ∀{Γ} {P : Ty (Γ  (𝔹 [ Ĉ.ε ]T))} {P𝕥 : Tm Γ (P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) ]T)} {P𝕗 : Tm Γ (P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) ]T)}
         ifᵗ P P𝕥 P𝕗 (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) ~ P𝕥
  ifᵗβ₁ {Γ = Γ}{P}{P𝕥}{P𝕗} = Ĉ.Tm≡ (funextHᵢᵣ λ {x} γ 
    coe≡-eq _ (Mₛ.ifᵗ ( P  (C↑ (𝔹 [ Ĉ.ε ]T) γ))
                     (coe (cong (Cₛ.Tm x) (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) P γ ⁻¹)) (Ĉ.∣ P𝕥  γ))
                     (coe (cong (Cₛ.Tm x) (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) P γ ⁻¹)) (Ĉ.∣ P𝕗  γ))
                     (Ĉ.∣ _[_]t {A = 𝔹} 𝕥 Ĉ.ε  γ)) ⁻¹
     Mₛ.ifᵗβ₁  coe≡-eq _ (Ĉ.∣ P𝕥  γ) ⁻¹)

  ifᵗβ₂ : ∀{Γ} {P : Ty (Γ  (𝔹 [ Ĉ.ε ]T))} {P𝕥 : Tm Γ (P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) ]T)} {P𝕗 : Tm Γ (P [ Ĉ.sg (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) ]T)}
         ifᵗ P P𝕥 P𝕗 (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) ~ P𝕗
  ifᵗβ₂ {Γ = Γ}{P}{P𝕥}{P𝕗} = Ĉ.Tm≡ (funextHᵢᵣ λ {x} γ 
    coe≡-eq _ (Mₛ.ifᵗ ( P  (C↑ (𝔹 [ Ĉ.ε ]T) γ))
                     (coe (cong (Cₛ.Tm x) (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕥 Ĉ.ε) P γ ⁻¹)) (Ĉ.∣ P𝕥  γ))
                     (coe (cong (Cₛ.Tm x) (C↑-[sg]T (𝔹 [ Ĉ.ε ]T) (_[_]t {A = 𝔹} 𝕗 Ĉ.ε) P γ ⁻¹)) (Ĉ.∣ P𝕗  γ))
                     (Ĉ.∣ _[_]t {A = 𝔹} 𝕗 Ĉ.ε  γ)) ⁻¹
     Mₛ.ifᵗβ₂  coe≡-eq _ (Ĉ.∣ P𝕗  γ) ⁻¹)

  Mₛₛ : Model Cₛₛ
  Mₛₛ = record
         { Π = Π
         ; Π[] = ~refl
         ; lam = lam
         ; lam[] = ~refl
         ; app = λ {Γ}{A}{B} t u  app {A = A}{B = B} t u
         ; app[] = ~refl
         ; Πβ = λ {Γ}{A}{B}{t}{a}  Πβ {A = A}{B = B}{t = t}{a = a}
         ; Πη = λ {Γ}{A}{B}{t}  Πη {A = A}{B = B}{t = t}
         ; 𝔹 = 𝔹
         ; 𝕥 = 𝕥
         ; 𝕗 = 𝕗
         ; ifᵀ = ifᵀ
         ; ifᵀ[] = ~refl
         ; ifᵀβ₁ = λ {Γ}{A}{B}  ifᵀβ₁ {A = A}{B = B}
         ; ifᵀβ₂ = λ {Γ}{A}{B}  ifᵀβ₂ {A = A}{B = B}
         ; ifᵗ = ifᵗ
         ; ifᵗ[] = ~refl
         ; ifᵗβ₁ = λ {Γ}{P}{P𝕥}{P𝕗}  ifᵗβ₁ {P = P}{P𝕥}{P𝕗}
         ; ifᵗβ₂ = λ {Γ}{P}{P𝕥}{P𝕗}  ifᵗβ₂ {P = P}{P𝕥}{P𝕗}
         }