{-# OPTIONS --without-K --safe #-}
module Definition.Typed.Weakening where
open import Definition.Untyped as U hiding (wk)
open import Definition.Untyped.Properties
open import Definition.Typed
open import Tools.Nat
open import Tools.Product
import Tools.PropositionalEquality as PE
data _∷_⊆_ : Wk → Con Term → Con Term → Set where
id : ∀ {Γ} → id ∷ Γ ⊆ Γ
step : ∀ {Γ Δ A ρ} → ρ ∷ Δ ⊆ Γ → step ρ ∷ Δ ∙ A ⊆ Γ
lift : ∀ {Γ Δ A ρ} → ρ ∷ Δ ⊆ Γ → lift ρ ∷ Δ ∙ U.wk ρ A ⊆ Γ ∙ A
_•ₜ_ : ∀ {ρ ρ′ Γ Δ Δ′} → ρ ∷ Γ ⊆ Δ → ρ′ ∷ Δ ⊆ Δ′ → ρ • ρ′ ∷ Γ ⊆ Δ′
id •ₜ η′ = η′
step η •ₜ η′ = step (η •ₜ η′)
lift η •ₜ id = lift η
lift η •ₜ step η′ = step (η •ₜ η′)
_•ₜ_ {lift ρ} {lift ρ′} {Δ′ = Δ′ ∙ A} (lift η) (lift η′) =
PE.subst (λ x → lift (ρ • ρ′) ∷ x ⊆ Δ′ ∙ A)
(PE.cong₂ _∙_ PE.refl (PE.sym (wk-comp ρ ρ′ A)))
(lift (η •ₜ η′))
wkIndex : ∀ {Γ Δ n A ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρn = wkVar ρ n
in ⊢ Δ → n ∷ A ∈ Γ → ρn ∷ ρA ∈ Δ
wkIndex id ⊢Δ i = PE.subst (λ x → _ ∷ x ∈ _) (PE.sym (wk-id _)) i
wkIndex (step ρ) (⊢Δ ∙ A) i = PE.subst (λ x → _ ∷ x ∈ _)
(wk1-wk _ _)
(there (wkIndex ρ ⊢Δ i))
wkIndex (lift ρ) (⊢Δ ∙ A) (there i) = PE.subst (λ x → _ ∷ x ∈ _)
(wk1-wk≡lift-wk1 _ _)
(there (wkIndex ρ ⊢Δ i))
wkIndex (lift ρ) ⊢Δ here =
let G = _
n = _
in PE.subst (λ x → n ∷ x ∈ G)
(wk1-wk≡lift-wk1 _ _)
here
mutual
wk : ∀ {Γ Δ A ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
in ⊢ Δ → Γ ⊢ A → Δ ⊢ ρA
wk ρ ⊢Δ (ℕ ⊢Γ) = ℕ ⊢Δ
wk ρ ⊢Δ (U ⊢Γ) = U ⊢Δ
wk ρ ⊢Δ (Π F ▹ G) = let ρF = wk ρ ⊢Δ F
in Π ρF ▹ (wk (lift ρ) (⊢Δ ∙ ρF) G)
wk ρ ⊢Δ (univ A) = univ (wkTerm ρ ⊢Δ A)
wkTerm : ∀ {Γ Δ A t ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρt = U.wk ρ t
in ⊢ Δ → Γ ⊢ t ∷ A → Δ ⊢ ρt ∷ ρA
wkTerm ρ ⊢Δ (ℕ ⊢Γ) = ℕ ⊢Δ
wkTerm ρ ⊢Δ (Π F ▹ G) = let ρF = wkTerm ρ ⊢Δ F
in Π ρF ▹ (wkTerm (lift ρ) (⊢Δ ∙ univ ρF) G)
wkTerm ρ ⊢Δ (var ⊢Γ x) = var ⊢Δ (wkIndex ρ ⊢Δ x)
wkTerm ρ ⊢Δ (lam F t) = let ρF = wk ρ ⊢Δ F
in lam ρF (wkTerm (lift ρ) (⊢Δ ∙ ρF) t)
wkTerm ρ ⊢Δ (_∘_ {G = G} g a) = PE.subst (λ x → _ ⊢ _ ∷ x)
(PE.sym (wk-β G))
(wkTerm ρ ⊢Δ g ∘ wkTerm ρ ⊢Δ a)
wkTerm ρ ⊢Δ (zero ⊢Γ) = zero ⊢Δ
wkTerm ρ ⊢Δ (suc n) = suc (wkTerm ρ ⊢Δ n)
wkTerm {Δ = Δ} {ρ = ρ} [ρ] ⊢Δ (natrec {G = G} {s = s} ⊢G ⊢z ⊢s ⊢n) =
PE.subst (λ x → _ ⊢ natrec _ _ _ _ ∷ x) (PE.sym (wk-β G))
(natrec (wk (lift [ρ]) (⊢Δ ∙ ℕ ⊢Δ) ⊢G)
(PE.subst (λ x → _ ⊢ _ ∷ x) (wk-β G) (wkTerm [ρ] ⊢Δ ⊢z))
(PE.subst (λ x → Δ ⊢ U.wk ρ s ∷ x)
(wk-β-natrec ρ G)
(wkTerm [ρ] ⊢Δ ⊢s))
(wkTerm [ρ] ⊢Δ ⊢n))
wkTerm ρ ⊢Δ (conv t A≡B) = conv (wkTerm ρ ⊢Δ t) (wkEq ρ ⊢Δ A≡B)
wkEq : ∀ {Γ Δ A B ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρB = U.wk ρ B
in ⊢ Δ → Γ ⊢ A ≡ B → Δ ⊢ ρA ≡ ρB
wkEq ρ ⊢Δ (univ A≡B) = univ (wkEqTerm ρ ⊢Δ A≡B)
wkEq ρ ⊢Δ (refl A) = refl (wk ρ ⊢Δ A)
wkEq ρ ⊢Δ (sym A≡B) = sym (wkEq ρ ⊢Δ A≡B)
wkEq ρ ⊢Δ (trans A≡B B≡C) = trans (wkEq ρ ⊢Δ A≡B) (wkEq ρ ⊢Δ B≡C)
wkEq ρ ⊢Δ (Π-cong F F≡H G≡E) = let ρF = wk ρ ⊢Δ F
in Π-cong ρF (wkEq ρ ⊢Δ F≡H)
(wkEq (lift ρ) (⊢Δ ∙ ρF) G≡E)
wkEqTerm : ∀ {Γ Δ A t u ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρt = U.wk ρ t
ρu = U.wk ρ u
in ⊢ Δ → Γ ⊢ t ≡ u ∷ A → Δ ⊢ ρt ≡ ρu ∷ ρA
wkEqTerm ρ ⊢Δ (refl t) = refl (wkTerm ρ ⊢Δ t)
wkEqTerm ρ ⊢Δ (sym t≡u) = sym (wkEqTerm ρ ⊢Δ t≡u)
wkEqTerm ρ ⊢Δ (trans t≡u u≡r) = trans (wkEqTerm ρ ⊢Δ t≡u) (wkEqTerm ρ ⊢Δ u≡r)
wkEqTerm ρ ⊢Δ (conv t≡u A≡B) = conv (wkEqTerm ρ ⊢Δ t≡u) (wkEq ρ ⊢Δ A≡B)
wkEqTerm ρ ⊢Δ (Π-cong F F≡H G≡E) =
let ρF = wk ρ ⊢Δ F
in Π-cong ρF (wkEqTerm ρ ⊢Δ F≡H)
(wkEqTerm (lift ρ) (⊢Δ ∙ ρF) G≡E)
wkEqTerm ρ ⊢Δ (app-cong {G = G} f≡g a≡b) =
PE.subst (λ x → _ ⊢ _ ≡ _ ∷ x)
(PE.sym (wk-β G))
(app-cong (wkEqTerm ρ ⊢Δ f≡g) (wkEqTerm ρ ⊢Δ a≡b))
wkEqTerm ρ ⊢Δ (β-red {a = a} {t = t} {G = G} F ⊢t ⊢a) =
let ρF = wk ρ ⊢Δ F
in PE.subst (λ x → _ ⊢ _ ≡ _ ∷ x)
(PE.sym (wk-β G))
(PE.subst (λ x → _ ⊢ U.wk _ ((lam t) ∘ a) ≡ x ∷ _)
(PE.sym (wk-β t))
(β-red ρF (wkTerm (lift ρ) (⊢Δ ∙ ρF) ⊢t)
(wkTerm ρ ⊢Δ ⊢a)))
wkEqTerm ρ ⊢Δ (η-eq F f g f0≡g0) =
let ρF = wk ρ ⊢Δ F
in η-eq ρF (wkTerm ρ ⊢Δ f)
(wkTerm ρ ⊢Δ g)
(PE.subst (λ t → _ ⊢ t ∘ _ ≡ _ ∷ _)
(PE.sym (wk1-wk≡lift-wk1 _ _))
(PE.subst (λ t → _ ⊢ _ ≡ t ∘ _ ∷ _)
(PE.sym (wk1-wk≡lift-wk1 _ _))
(wkEqTerm (lift ρ) (⊢Δ ∙ ρF) f0≡g0)))
wkEqTerm ρ ⊢Δ (suc-cong m≡n) = suc-cong (wkEqTerm ρ ⊢Δ m≡n)
wkEqTerm {Δ = Δ} {ρ = ρ} [ρ] ⊢Δ (natrec-cong {s = s} {s′ = s′} {F = F}
F≡F′ z≡z′ s≡s′ n≡n′) =
PE.subst (λ x → Δ ⊢ natrec _ _ _ _ ≡ _ ∷ x) (PE.sym (wk-β F))
(natrec-cong (wkEq (lift [ρ]) (⊢Δ ∙ ℕ ⊢Δ) F≡F′)
(PE.subst (λ x → Δ ⊢ _ ≡ _ ∷ x) (wk-β F)
(wkEqTerm [ρ] ⊢Δ z≡z′))
(PE.subst (λ x → Δ ⊢ U.wk ρ s
≡ U.wk ρ s′ ∷ x)
(wk-β-natrec _ F)
(wkEqTerm [ρ] ⊢Δ s≡s′))
(wkEqTerm [ρ] ⊢Δ n≡n′))
wkEqTerm {Δ = Δ} {ρ = ρ} [ρ] ⊢Δ (natrec-zero {z} {s} {F} ⊢F ⊢z ⊢s) =
PE.subst (λ x → Δ ⊢ natrec (U.wk (lift _) F) _ _ _ ≡ _ ∷ x)
(PE.sym (wk-β F))
(natrec-zero (wk (lift [ρ]) (⊢Δ ∙ ℕ ⊢Δ) ⊢F)
(PE.subst (λ x → Δ ⊢ U.wk ρ z ∷ x)
(wk-β F)
(wkTerm [ρ] ⊢Δ ⊢z))
(PE.subst (λ x → Δ ⊢ U.wk ρ s ∷ x)
(wk-β-natrec _ F)
(wkTerm [ρ] ⊢Δ ⊢s)))
wkEqTerm {Δ = Δ} {ρ = ρ} [ρ] ⊢Δ (natrec-suc {n} {z} {s} {F} ⊢n ⊢F ⊢z ⊢s) =
PE.subst (λ x → Δ ⊢ natrec (U.wk (lift _) F) _ _ _
≡ _ ∘ (natrec _ _ _ _) ∷ x)
(PE.sym (wk-β F))
(natrec-suc (wkTerm [ρ] ⊢Δ ⊢n)
(wk (lift [ρ]) (⊢Δ ∙ ℕ ⊢Δ) ⊢F)
(PE.subst (λ x → Δ ⊢ U.wk ρ z ∷ x)
(wk-β F)
(wkTerm [ρ] ⊢Δ ⊢z))
(PE.subst (λ x → Δ ⊢ U.wk ρ s ∷ x)
(wk-β-natrec _ F)
(wkTerm [ρ] ⊢Δ ⊢s)))
mutual
wkRed : ∀ {Γ Δ A B ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρB = U.wk ρ B
in ⊢ Δ → Γ ⊢ A ⇒ B → Δ ⊢ ρA ⇒ ρB
wkRed ρ ⊢Δ (univ A⇒B) = univ (wkRedTerm ρ ⊢Δ A⇒B)
wkRedTerm : ∀ {Γ Δ A t u ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρt = U.wk ρ t
ρu = U.wk ρ u
in ⊢ Δ → Γ ⊢ t ⇒ u ∷ A → Δ ⊢ ρt ⇒ ρu ∷ ρA
wkRedTerm ρ ⊢Δ (conv t⇒u A≡B) = conv (wkRedTerm ρ ⊢Δ t⇒u) (wkEq ρ ⊢Δ A≡B)
wkRedTerm ρ ⊢Δ (app-subst {B = B} t⇒u a) =
PE.subst (λ x → _ ⊢ _ ⇒ _ ∷ x) (PE.sym (wk-β B))
(app-subst (wkRedTerm ρ ⊢Δ t⇒u) (wkTerm ρ ⊢Δ a))
wkRedTerm ρ ⊢Δ (β-red {A} {B} {a} {t} ⊢A ⊢t ⊢a) =
let ⊢ρA = wk ρ ⊢Δ ⊢A
in PE.subst (λ x → _ ⊢ _ ⇒ _ ∷ x) (PE.sym (wk-β B))
(PE.subst (λ x → _ ⊢ U.wk _ ((lam t) ∘ a) ⇒ x ∷ _)
(PE.sym (wk-β t))
(β-red ⊢ρA (wkTerm (lift ρ) (⊢Δ ∙ ⊢ρA) ⊢t)
(wkTerm ρ ⊢Δ ⊢a)))
wkRedTerm {Δ = Δ} {ρ = ρ} [ρ] ⊢Δ (natrec-subst {s = s} {F = F} ⊢F ⊢z ⊢s n⇒n′) =
PE.subst (λ x → _ ⊢ natrec _ _ _ _ ⇒ _ ∷ x) (PE.sym (wk-β F))
(natrec-subst (wk (lift [ρ]) (⊢Δ ∙ ℕ ⊢Δ) ⊢F)
(PE.subst (λ x → _ ⊢ _ ∷ x) (wk-β F)
(wkTerm [ρ] ⊢Δ ⊢z))
(PE.subst (λ x → Δ ⊢ U.wk ρ s ∷ x)
(wk-β-natrec _ F)
(wkTerm [ρ] ⊢Δ ⊢s))
(wkRedTerm [ρ] ⊢Δ n⇒n′))
wkRedTerm {Δ = Δ} {ρ = ρ} [ρ] ⊢Δ (natrec-zero {s = s} {F = F} ⊢F ⊢z ⊢s) =
PE.subst (λ x → _ ⊢ natrec (U.wk (lift ρ) F) _ _ _ ⇒ _ ∷ x)
(PE.sym (wk-β F))
(natrec-zero (wk (lift [ρ]) (⊢Δ ∙ ℕ ⊢Δ) ⊢F)
(PE.subst (λ x → _ ⊢ _ ∷ x)
(wk-β F)
(wkTerm [ρ] ⊢Δ ⊢z))
(PE.subst (λ x → Δ ⊢ U.wk ρ s ∷ x)
(wk-β-natrec ρ F)
(wkTerm [ρ] ⊢Δ ⊢s)))
wkRedTerm {Δ = Δ} {ρ = ρ} [ρ] ⊢Δ (natrec-suc {s = s} {F = F} ⊢n ⊢F ⊢z ⊢s) =
PE.subst (λ x → _ ⊢ natrec _ _ _ _ ⇒ _ ∘ natrec _ _ _ _ ∷ x)
(PE.sym (wk-β F))
(natrec-suc (wkTerm [ρ] ⊢Δ ⊢n)
(wk (lift [ρ]) (⊢Δ ∙ ℕ ⊢Δ) ⊢F)
(PE.subst (λ x → _ ⊢ _ ∷ x)
(wk-β F)
(wkTerm [ρ] ⊢Δ ⊢z))
(PE.subst (λ x → Δ ⊢ U.wk ρ s ∷ x)
(wk-β-natrec ρ F)
(wkTerm [ρ] ⊢Δ ⊢s)))
wkRed* : ∀ {Γ Δ A B ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρB = U.wk ρ B
in ⊢ Δ → Γ ⊢ A ⇒* B → Δ ⊢ ρA ⇒* ρB
wkRed* ρ ⊢Δ (id A) = id (wk ρ ⊢Δ A)
wkRed* ρ ⊢Δ (A⇒A′ ⇨ A′⇒*B) = wkRed ρ ⊢Δ A⇒A′ ⇨ wkRed* ρ ⊢Δ A′⇒*B
wkRed*Term : ∀ {Γ Δ A t u ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρt = U.wk ρ t
ρu = U.wk ρ u
in ⊢ Δ → Γ ⊢ t ⇒* u ∷ A → Δ ⊢ ρt ⇒* ρu ∷ ρA
wkRed*Term ρ ⊢Δ (id t) = id (wkTerm ρ ⊢Δ t)
wkRed*Term ρ ⊢Δ (t⇒t′ ⇨ t′⇒*u) = wkRedTerm ρ ⊢Δ t⇒t′ ⇨ wkRed*Term ρ ⊢Δ t′⇒*u
wkRed:*: : ∀ {Γ Δ A B ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρB = U.wk ρ B
in ⊢ Δ → Γ ⊢ A :⇒*: B → Δ ⊢ ρA :⇒*: ρB
wkRed:*: ρ ⊢Δ [ ⊢A , ⊢B , D ] = [ wk ρ ⊢Δ ⊢A , wk ρ ⊢Δ ⊢B , wkRed* ρ ⊢Δ D ]
wkRed:*:Term : ∀ {Γ Δ A t u ρ} → ρ ∷ Δ ⊆ Γ →
let ρA = U.wk ρ A
ρt = U.wk ρ t
ρu = U.wk ρ u
in ⊢ Δ → Γ ⊢ t :⇒*: u ∷ A → Δ ⊢ ρt :⇒*: ρu ∷ ρA
wkRed:*:Term ρ ⊢Δ [ ⊢t , ⊢u , d ] =
[ wkTerm ρ ⊢Δ ⊢t , wkTerm ρ ⊢Δ ⊢u , wkRed*Term ρ ⊢Δ d ]