{-# OPTIONS --without-K #-}
module tower where
open import Data.Nat
open import Data.Maybe
open import Data.Sum
open import Data.Product
open import mctt
open import extract
data AllKinds : Cxt → Set where
AKε : AllKinds ε
AK,,k : {cxt : Cxt} → AllKinds cxt → (k : Kind cxt) → AllKinds (cxt ,, k)
data FirstTy : Cxt → Set where
FT,t₁ : {cxt : Cxt} → AllKinds cxt → (t : Ty cxt) → FirstTy (cxt , t)
FT,t₊ : {cxt : Cxt} → FirstTy cxt → (t : Ty cxt) → FirstTy (cxt , t)
FT,,k : {cxt : Cxt} → FirstTy cxt → (k : Kind cxt) → FirstTy (cxt ,, k)
AK⊎FT : (cxt : Cxt) → AllKinds cxt ⊎ FirstTy cxt
AK⊎FT ε = inj₁ AKε
AK⊎FT (cxt , t) = helper (AK⊎FT cxt) where
helper : AllKinds cxt ⊎ FirstTy cxt → AllKinds (cxt , t) ⊎ FirstTy (cxt , t)
helper (inj₁ ak) = inj₂ (FT,t₁ ak t)
helper (inj₂ ft) = inj₂ (FT,t₊ ft t)
AK⊎FT (cxt ,, k) = helper (AK⊎FT cxt) where
helper : AllKinds cxt ⊎ FirstTy cxt → AllKinds (cxt ,, k) ⊎ FirstTy (cxt ,, k)
helper (inj₁ ak) = inj₁ (AK,,k ak k)
helper (inj₂ ft) = inj₂ (FT,,k ft k)
tcxt : Cxt → Cxt
tcxt? : (cxt : Cxt) → AllKinds cxt ⊎ FirstTy cxt → Cxt
tcxt cxt = tcxt? cxt (AK⊎FT cxt)
tcxt-ak : (cxt : Cxt) → AllKinds cxt → Cxt
tnewty-ak : (cxt : Cxt) → (ak : AllKinds cxt) → Ty (tcxt-ak cxt ak)
tcxt-ft : (cxt : Cxt) → FirstTy cxt → Cxt
tcxt? cxt (inj₁ ak) = (tcxt-ak cxt ak , tnewty-ak cxt ak)
tcxt? cxt (inj₂ ft) = (tcxt-ft cxt ft)
tkind : {cxt : Cxt} → (k : Kind cxt) → Kind (tcxt cxt)
tkind? : {cxt : Cxt} → (akft : AllKinds cxt ⊎ FirstTy cxt) → (k : Kind cxt) → Kind (tcxt? cxt akft)
tkind {cxt} k = tkind? (AK⊎FT cxt) k
tty : {cxt : Cxt} → (t : Ty cxt) → Ty (tcxt cxt)
tty? : {cxt : Cxt} → (akft : AllKinds cxt ⊎ FirstTy cxt) → (t : Ty cxt) → Ty (tcxt? cxt akft)
tty {cxt} t = tty? (AK⊎FT cxt) t
tcxt-ak .ε AKε = (ε ,, U)
tcxt-ak .(cxt ,, k) (AK,,k {cxt} ak k) =
(tcxt-ak cxt ak ,, Π (tnewty-ak cxt ak) (tkind? (inj₁ ak) k))
tnewty-ak .ε AKε = (el (coe (U[] (kpop U)) ktop))
tnewty-ak .(cxt ,, k) (AK,,k {cxt} ak k) = tnewty-ak cxt ak [ kpop (Π (tnewty-ak cxt ak) (tkind? (inj₁ ak) k)) ]
tcxt-ft .(cxt , t) (FT,t₁ {cxt} ak t) =
((tcxt-ak cxt ak , tnewty-ak cxt ak) , tty? (inj₁ ak) t)
tcxt-ft .(cxt , t) (FT,t₊ {cxt} ft t) = (tcxt-ft cxt ft , tty? (inj₂ ft) t)
tcxt-ft .(cxt ,, k) (FT,,k {cxt} ft k) = (tcxt-ft cxt ft ,, tkind? (inj₂ ft) k)
tcxt-sub? : (cxt : Cxt) → (akft : AllKinds cxt ⊎ FirstTy cxt) → Sub (tcxt? cxt akft) cxt
tkind? {cxt} akft k = k [ tcxt-sub? cxt akft ]
tty? {cxt} akft t = t [ tcxt-sub? cxt akft ]
tcxt-sub? .ε (inj₁ AKε) = kpop U ∘ tpop (el (coe (U[] (kpop U)) ktop))
tcxt-sub? .(cxt ,, k) (inj₁ (AK,,k {cxt} ak k)) =
(tcxt-sub? cxt (inj₁ ak) ∘ (kpop (Π (tnewty-ak cxt ak) (tkind? (inj₁ ak) k)) <id (tnewty-ak cxt ak)))
≪ coe (k[∘] _ _ _)
(ap (coe (Π[] (tnewty-ak cxt ak) (tkind? (inj₁ ak) k) (kpop (Π (tnewty-ak cxt ak) (tkind? (inj₁ ak) k))))
ktop))
tcxt-sub? .(cxt , t) (inj₂ (FT,t₁ {cxt} ak t)) = tcxt-sub? cxt (inj₁ ak) <id t
tcxt-sub? .(cxt , t) (inj₂ (FT,t₊ {cxt} ft t)) = tcxt-sub? cxt (inj₂ ft) <id t
tcxt-sub? .(cxt ,, k) (inj₂ (FT,,k {cxt} ft k)) = tcxt-sub? cxt (inj₂ ft) ≪id k
tcxt-ak-ak : (cxt : Cxt) → (ak : AllKinds cxt) → AllKinds (tcxt-ak cxt ak)
tcxt-ak-ak .ε AKε = AK,,k AKε U
tcxt-ak-ak .(cxt ,, k) (AK,,k {cxt} ak k) = AK,,k (tcxt-ak-ak cxt ak) (Π (tnewty-ak cxt ak) (k [ tcxt-sub? cxt (inj₁ ak) ]))
tower : ℕ → Cxt
tower-ak : (n : ℕ) → AllKinds (tower n)
tower 0 = ε
tower (suc n) = tcxt-ak (tower n) (tower-ak n)
tower-ak 0 = AKε
tower-ak (suc n) = tcxt-ak-ak (tower n) (tower-ak n)