-- "Weakening": transporting terms to larger contexts
module Term.Weakening where
open import Prelude
open import Term
private
variable
a b : Ty
Γ Δ Φ : Context
-- ρ : Wk Γ Δ transports a term living in context Δ to a larger context Γ.
-- The relative order of assumptions in Δ is preserved in Γ;
-- Γ is Δ with additional assumptions inserted anywhere.
--
-- In other words, Δ can be obtained by deleting some assumptions from Γ.
-- This perspective is taken by the constructor names, describing how Δ
-- is stepwise constructed from Γ, by either keeping or skipping assumptions.
data Wk : (Γ Δ : Context) → Set where
done : Wk [] []
skip : (ρ : Wk Γ Δ) → Wk (a ∷ Γ) Δ
keep : (ρ : Wk Γ Δ) → Wk (a ∷ Γ) (a ∷ Δ)
-- If Wk Γ Δ, then any assumption a ∈ Δ is also in Γ.
-- lookup (ρ : Wk Γ Δ) transport de Bruijn indices a ∈ Δ to those a ∈ Γ.
-- In particular, "skip" increases a de Bruijn index.
lookup : Wk Γ Δ → a ∈ Δ → a ∈ Γ
lookup (keep ρ) zero = zero
lookup (keep ρ) (suc x) = suc (lookup ρ x)
lookup (skip ρ) x = suc (lookup ρ x)
-- wk (ρ : Wk Γ Δ) transports a term from context Δ to larger context Γ
-- by updating the de Bruijn indices.
-- In particular, it maps a term t : Term Δ a to a term wk ρ t : Term Γ a.
wk : Wk Γ Δ → Term Δ a → Term Γ a
wk ρ (var x) = var (lookup ρ x)
wk ρ (abs t) = abs (wk (keep ρ) t)
wk ρ (app t u) = app (wk ρ t) (wk ρ u)
-- Weakening compose, so they form a category with identity idW.
idW : Wk Γ Γ
idW {Γ = []} = done
idW {Γ = x ∷ Γ} = keep idW
-- We write composition in the diagrammatic order, so that
-- wk (compWW ρ ρ') = wk ρ ∘ wk ρ'.
compWW : Wk Γ Δ → Wk Δ Φ → Wk Γ Φ
compWW done ρ' = ρ'
compWW (skip ρ) ρ' = skip (compWW ρ ρ')
compWW (keep ρ) (skip ρ') = skip (compWW ρ ρ')
compWW (keep ρ) (keep ρ') = keep (compWW ρ ρ')
-- Some shorthands for common weakenings and weakening operations.
skip1 : Wk (a ∷ Γ) Γ
skip1 = skip idW
skips : Wk Γ Δ → Wk (Φ ++ Γ) Δ
skips {Φ = []} ρ = ρ
skips {Φ = a ∷ Φ} ρ = skip (skips ρ)
wk1 : Term Γ b → Term (a ∷ Γ) b
wk1 = wk skip1