module A201801.LPTTDerivations where open import A201801.Prelude open import A201801.Category open import A201801.Fin open import A201801.Vec open import A201801.VecLemmas open import A201801.AllVec open import A201801.S4TTTerms open import A201801.S4TTTermsLemmas open import A201801.LPTTTypes open import A201801.LPTTTypesLemmas open import A201801.LPTTAsserts -------------------------------------------------------------------------------- infix 3 _⊢_⦂_valid[_] data _⊢_⦂_valid[_] : ∀ {d g} → Asserts d → Term d g → Type d → Types d g → Set where var : ∀ {d g I A} → {Δ : Asserts d} {Γ : Types d g} → Γ ∋⟨ I ⟩ A → Δ ⊢ VAR I ⦂ A valid[ Γ ] lam : ∀ {d g M A B} → {Δ : Asserts d} {Γ : Types d g} → Δ ⊢ M ⦂ B valid[ Γ , A ] → Δ ⊢ LAM M ⦂ A ⊃ B valid[ Γ ] app : ∀ {d g M N A B} → {Δ : Asserts d} {Γ : Types d g} → Δ ⊢ M ⦂ A ⊃ B valid[ Γ ] → Δ ⊢ N ⦂ A valid[ Γ ] → Δ ⊢ APP M N ⦂ B valid[ Γ ] mvar : ∀ {d g I M A} → {Δ : Asserts d} {Γ : Types d g} → Δ ∋◆⟨ I ⟩ ⟪⊫ M ⦂ A ⟫ -- NOTE: This is more than Artemov-Bonelli → Δ ⊢ MVAR I ⦂ A valid[ Γ ] box : ∀ {d g M A} → {Δ : Asserts d} {Γ : Types d g} → Δ ⊢ M ⦂ A valid[ ∙ ] → Δ ⊢ BOX M ⦂ [ M ] A valid[ Γ ] letbox : ∀ {d g M N Q A B} → {Δ : Asserts d} {Γ : Types d g} {B′ : Type d} {{p : TMCUT Q B ≡ B′}} → Δ ⊢ M ⦂ [ Q ] A valid[ Γ ] → Δ , ⟪⊫ Q ⦂ A ⟫ ⊢ N ⦂ B valid[ TMWKS Γ ] -- NOTE → Δ ⊢ LETBOX M N ⦂ B′ valid[ Γ ] infix 3 _⊢_⦂_allvalid[_] _⊢_⦂_allvalid[_] : ∀ {d g n} → Asserts d → Terms d g n → Types d n → Types d g → Set Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] = All (\ { (M , A) → Δ ⊢ M ⦂ A valid[ Γ ] }) (zip τ Ξ) -------------------------------------------------------------------------------- -- ren : ∀ {d g g′ e M A} → {Δ : Asserts d} {Γ : Types g} {Γ′ : Types g′} -- → Γ′ ⊇⟨ e ⟩ Γ → Δ ⊢ M ⦂ A valid[ Γ ] -- → Δ ⊢ REN e M ⦂ A valid[ Γ′ ] -- ren η (var i) = var (ren∋ η i) -- ren η (lam 𝒟) = lam (ren (keep η) 𝒟) -- ren η (app 𝒟 ℰ) = app (ren η 𝒟) (ren η ℰ) -- ren η (mvar i) = mvar i -- ren η (box 𝒟) = box 𝒟 -- ren η (letbox 𝒟 ℰ) = letbox (ren η 𝒟) (ren η ℰ) -- rens : ∀ {d g g′ e n} → {Δ : Asserts d} {Γ : Types g} {Γ′ : Types g′} -- {τ : Terms d g n} {Ξ : Types n} -- → Γ′ ⊇⟨ e ⟩ Γ → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] -- → Δ ⊢ RENS e τ ⦂ Ξ allvalid[ Γ′ ] -- rens {τ = ∙} {∙} η ∙ = ∙ -- rens {τ = τ , M} {Ξ , A} η (ξ , 𝒟) = rens η ξ , ren η 𝒟 -- -------------------------------------------------------------------------------- -- mren : ∀ {d d′ g e M A} → {Δ : Asserts d} {Δ′ : Asserts d′} {Γ : Types g} -- → Δ′ ⊇⟨ e ⟩ Δ → Δ ⊢ M ⦂ A valid[ Γ ] -- → Δ′ ⊢ MREN e M ⦂ A valid[ Γ ] -- mren η (var i) = var i -- mren η (lam 𝒟) = lam (mren η 𝒟) -- mren η (app 𝒟 ℰ) = app (mren η 𝒟) (mren η ℰ) -- mren η (mvar i) = mvar (ren∋ η i) -- mren η (box 𝒟) = box (mren η 𝒟) -- mren η (letbox 𝒟 ℰ) = letbox (mren η 𝒟) (mren (keep η) ℰ) -- mrens : ∀ {d d′ g e n} → {Δ : Asserts d} {Δ′ : Asserts d′} {Γ : Types g} -- {τ : Terms d g n} {Ξ : Types n} -- → Δ′ ⊇⟨ e ⟩ Δ → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] -- → Δ′ ⊢ MRENS e τ ⦂ Ξ allvalid[ Γ ] -- mrens {τ = ∙} {∙} η ∙ = ∙ -- mrens {τ = τ , M} {Ξ , A} η (ξ , 𝒟) = mrens η ξ , mren η 𝒟 -- mrens* : ∀ {d d′ e n} → {Δ : Asserts d} {Δ′ : Asserts d′} -- {τ : Terms* d n} {Ξ : Asserts n} -- → Δ′ ⊇⟨ e ⟩ Δ → Δ ⊢ τ ⦂ Ξ allvalid* -- → Δ′ ⊢ MRENS* e τ ⦂ Ξ allvalid* -- mrens* {τ = ∙} {∙} η ∙ = ∙ -- mrens* {τ = τ , M} {Ξ , A} η (ξ , 𝒟) = mrens* η ξ , mren η 𝒟 -- -------------------------------------------------------------------------------- -- wk : ∀ {B d g M A} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ A valid[ Γ ] -- → Δ ⊢ WK M ⦂ A valid[ Γ , B ] -- wk 𝒟 = ren (drop id⊇) 𝒟 -- wks : ∀ {A d g n} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms d g n} {Ξ : Types n} -- → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] -- → Δ ⊢ WKS τ ⦂ Ξ allvalid[ Γ , A ] -- wks ξ = rens (drop id⊇) ξ -- vz : ∀ {d g A} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ VZ ⦂ A valid[ Γ , A ] -- vz = var zero -- lifts : ∀ {A d g n} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms d g n} {Ξ : Types n} -- → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] -- → Δ ⊢ LIFTS τ ⦂ Ξ , A allvalid[ Γ , A ] -- lifts ξ = wks ξ , vz -- vars : ∀ {d g g′ e} → {Δ : Asserts d} {Γ : Types g} {Γ′ : Types g′} -- → Γ′ ⊇⟨ e ⟩ Γ -- → Δ ⊢ VARS e ⦂ Γ allvalid[ Γ′ ] -- vars done = ∙ -- vars (drop η) = wks (vars η) -- vars (keep η) = lifts (vars η) -- ids : ∀ {d g} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ IDS ⦂ Γ allvalid[ Γ ] -- ids = vars id⊇ -- -------------------------------------------------------------------------------- -- mwk : ∀ {B d g M A} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ A valid[ Γ ] -- → Δ , ⟪⊫ B ⟫ ⊢ MWK M ⦂ A valid[ Γ ] -- mwk 𝒟 = mren (drop id⊇) 𝒟 -- mwks : ∀ {A d g n} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms d g n} {Ξ : Types n} -- → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] -- → Δ , ⟪⊫ A ⟫ ⊢ MWKS τ ⦂ Ξ allvalid[ Γ ] -- mwks ξ = mrens (drop id⊇) ξ -- mwks* : ∀ {A d n} → {Δ : Asserts d} -- {τ : Terms* d n} {Ξ : Asserts n} -- → Δ ⊢ τ ⦂ Ξ allvalid* -- → Δ , ⟪⊫ A ⟫ ⊢ MWKS* τ ⦂ Ξ allvalid* -- mwks* ξ = mrens* (drop id⊇) ξ -- mvz : ∀ {d g A} → {Δ : Asserts d} {Γ : Types g} -- → Δ , ⟪⊫ A ⟫ ⊢ MVZ ⦂ A valid[ Γ ] -- mvz = mvar zero -- mlifts* : ∀ {A d n} → {Δ : Asserts d} -- {τ : Terms* d n} {Ξ : Asserts n} -- → Δ ⊢ τ ⦂ Ξ allvalid* -- → Δ , ⟪⊫ A ⟫ ⊢ MLIFTS* τ ⦂ Ξ , ⟪⊫ A ⟫ allvalid* -- mlifts* ξ = mwks* ξ , mvz -- mvars* : ∀ {d d′ e} → {Δ : Asserts d} {Δ′ : Asserts d′} -- → Δ′ ⊇⟨ e ⟩ Δ -- → Δ′ ⊢ MVARS* e ⦂ Δ allvalid* -- mvars* done = ∙ -- mvars* (drop η) = mwks* (mvars* η) -- mvars* (keep η) = mlifts* (mvars* η) -- mids* : ∀ {d} → {Δ : Asserts d} -- → Δ ⊢ MIDS* ⦂ Δ allvalid* -- mids* = mvars* id⊇ -- -------------------------------------------------------------------------------- -- sub : ∀ {d g n M A} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms d g n} {Ξ : Types n} -- → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] → Δ ⊢ M ⦂ A valid[ Ξ ] -- → Δ ⊢ SUB τ M ⦂ A valid[ Γ ] -- sub ξ (var i) = get ξ (zip∋₂ i) -- sub ξ (lam 𝒟) = lam (sub (lifts ξ) 𝒟) -- sub ξ (app 𝒟 ℰ) = app (sub ξ 𝒟) (sub ξ ℰ) -- sub ξ (mvar i) = mvar i -- sub ξ (box 𝒟) = box 𝒟 -- sub ξ (letbox 𝒟 ℰ) = letbox (sub ξ 𝒟) (sub (mwks ξ) ℰ) -- subs : ∀ {d g n m} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms d g n} {Ξ : Types n} -- {υ : Terms d n m} {Ψ : Types m} -- → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] → Δ ⊢ υ ⦂ Ψ allvalid[ Ξ ] -- → Δ ⊢ SUBS τ υ ⦂ Ψ allvalid[ Γ ] -- subs {υ = ∙} {∙} ξ ∙ = ∙ -- subs {υ = υ , M} {Ψ , A} ξ (ψ , 𝒟) = subs ξ ψ , sub ξ 𝒟 -- -------------------------------------------------------------------------------- -- msub : ∀ {d g n M A} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms* d n} {Ξ : Asserts n} -- → Δ ⊢ τ ⦂ Ξ allvalid* → Ξ ⊢ M ⦂ A valid[ Γ ] -- → Δ ⊢ MSUB τ M ⦂ A valid[ Γ ] -- msub ξ (var i) = var i -- msub ξ (lam 𝒟) = lam (msub ξ 𝒟) -- msub ξ (app 𝒟 ℰ) = app (msub ξ 𝒟) (msub ξ ℰ) -- msub ξ (mvar i) = sub ∙ (get ξ (zip∋₂ i)) -- msub ξ (box 𝒟) = box (msub ξ 𝒟) -- msub ξ (letbox 𝒟 ℰ) = letbox (msub ξ 𝒟) (msub (mlifts* ξ) ℰ) -- msubs : ∀ {d g n m} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms* d n} {Ξ : Asserts n} -- {υ : Terms n g m} {Ψ : Types m} -- → Δ ⊢ τ ⦂ Ξ allvalid* → Ξ ⊢ υ ⦂ Ψ allvalid[ Γ ] -- → Δ ⊢ MSUBS τ υ ⦂ Ψ allvalid[ Γ ] -- msubs {υ = ∙} {∙} ξ ∙ = ∙ -- msubs {υ = υ , M} {Ψ , A} ξ (ψ , 𝒟) = msubs ξ ψ , msub ξ 𝒟 -- msubs* : ∀ {d n m} → {Δ : Asserts d} -- {τ : Terms* d n} {Ξ : Asserts n} -- {υ : Terms* n m} {Ψ : Asserts m} -- → Δ ⊢ τ ⦂ Ξ allvalid* → Ξ ⊢ υ ⦂ Ψ allvalid* -- → Δ ⊢ MSUBS* τ υ ⦂ Ψ allvalid* -- msubs* {υ = ∙} {∙} ξ ∙ = ∙ -- msubs* {υ = υ , M} {Ψ , ⟪⊫ A ⟫} ξ (ψ , 𝒟) = msubs* ξ ψ , msub ξ 𝒟 -- -------------------------------------------------------------------------------- -- unlam : ∀ {d g M A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ A ⊃ B valid[ Γ ] -- → Δ ⊢ UNLAM M ⦂ B valid[ Γ , A ] -- unlam 𝒟 = app (wk 𝒟) vz -- cut : ∀ {d g M N A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ A valid[ Γ ] → Δ ⊢ N ⦂ B valid[ Γ , A ] -- → Δ ⊢ CUT M N ⦂ B valid[ Γ ] -- cut 𝒟 ℰ = sub (ids , 𝒟) ℰ -- pseudocut : ∀ {d g M N A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ A valid[ Γ ] → Δ ⊢ N ⦂ B valid[ Γ , A ] -- → Δ ⊢ PSEUDOCUT M N ⦂ B valid[ Γ ] -- pseudocut 𝒟 ℰ = app (lam ℰ) 𝒟 -- pseudosub : ∀ {d g n M A} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms d g n} {Ξ : Types n} -- → Δ ⊢ τ ⦂ Ξ allvalid[ Γ ] → Δ ⊢ M ⦂ A valid[ Ξ ] -- → Δ ⊢ PSEUDOSUB τ M ⦂ A valid[ Γ ] -- pseudosub {τ = ∙} {∙} ∙ 𝒟 = ren bot⊇ 𝒟 -- pseudosub {τ = τ , M} {Ξ , B} (ξ , 𝒞) 𝒟 = app (pseudosub ξ (lam 𝒟)) 𝒞 -- exch : ∀ {d g M A B C} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ C valid[ Γ , A , B ] -- → Δ ⊢ EXCH M ⦂ C valid[ Γ , B , A ] -- exch 𝒟 = app (app (wk (wk (lam (lam 𝒟)))) vz) (wk vz) -- -------------------------------------------------------------------------------- -- vau : ∀ {d g M A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ , ⟪⊫ A ⟫ ⊢ M ⦂ B valid[ Γ ] -- → Δ ⊢ VAU M ⦂ B valid[ Γ , □ A ] -- vau 𝒟 = letbox vz (wk 𝒟) -- unvau : ∀ {d g M A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ B valid[ Γ , □ A ] -- → Δ , ⟪⊫ A ⟫ ⊢ UNVAU M ⦂ B valid[ Γ ] -- unvau 𝒟 = app (lam (mwk 𝒟)) (box mvz) -- boxapp : ∀ {d g M N A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ □ (A ⊃ B) valid[ Γ ] → Δ ⊢ N ⦂ □ A valid[ Γ ] -- → Δ ⊢ BOXAPP M N ⦂ □ B valid[ Γ ] -- boxapp 𝒟 ℰ = letbox 𝒟 (letbox (mwk ℰ) (box (app (mwk mvz) mvz))) -- unbox : ∀ {d g M A} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ □ A valid[ Γ ] -- → Δ ⊢ UNBOX M ⦂ A valid[ Γ ] -- unbox 𝒟 = letbox 𝒟 mvz -- -- NOTE: Local completeness of □ -- rebox : ∀ {d g M A} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ □ A valid[ Γ ] -- → Δ ⊢ REBOX M ⦂ □ A valid[ Γ ] -- rebox 𝒟 = letbox 𝒟 (box mvz) -- dupbox : ∀ {d g M A} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ □ A valid[ Γ ] -- → Δ ⊢ DUPBOX M ⦂ □ □ A valid[ Γ ] -- dupbox 𝒟 = letbox 𝒟 (box (box mvz)) -- mcut : ∀ {d g M N A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ A valid[ ∙ ] → Δ , ⟪⊫ A ⟫ ⊢ N ⦂ B valid[ Γ ] -- → Δ ⊢ MCUT M N ⦂ B valid[ Γ ] -- mcut 𝒟 ℰ = msub (mids* , 𝒟) ℰ -- -- NOTE: Local soundness of □ -- pseudomcut : ∀ {d g M N A B} → {Δ : Asserts d} {Γ : Types g} -- → Δ ⊢ M ⦂ A valid[ ∙ ] → Δ , ⟪⊫ A ⟫ ⊢ N ⦂ B valid[ Γ ] -- → Δ ⊢ PSEUDOMCUT M N ⦂ B valid[ Γ ] -- pseudomcut 𝒟 ℰ = letbox (box 𝒟) ℰ -- pseudomsub : ∀ {d g n M A} → {Δ : Asserts d} {Γ : Types g} -- {τ : Terms* d n} {Ξ : Asserts n} -- → Δ ⊢ τ ⦂ Ξ allvalid* → Ξ ⊢ M ⦂ A valid[ Γ ] -- → Δ ⊢ PSEUDOMSUB τ M ⦂ A valid[ Γ ] -- pseudomsub {τ = ∙} {∙} ∙ 𝒟 = mren bot⊇ 𝒟 -- pseudomsub {τ = τ , M} {Ξ , ⟪⊫ A ⟫} (ξ , 𝒞) 𝒟 = app (pseudomsub ξ (lam (vau 𝒟))) (box 𝒞) -- mexch : ∀ {d g M A B C} → {Δ : Asserts d} {Γ : Types g} -- → Δ , ⟪⊫ A ⟫ , ⟪⊫ B ⟫ ⊢ M ⦂ C valid[ Γ ] -- → Δ , ⟪⊫ B ⟫ , ⟪⊫ A ⟫ ⊢ MEXCH M ⦂ C valid[ Γ ] -- mexch 𝒟 = unvau (unvau (exch (vau (vau 𝒟)))) -- --------------------------------------------------------------------------------