Type Renaming and Substitution
module Type.RenamingSubstitution where
Imports
open import Type open import Function using (id; _∘_) open import Relation.Binary.PropositionalEquality renaming (subst to substEq) using (_≡_; refl; cong; cong₂; trans; sym)
Type renaming
A type renaming is a mapping of type variables to type variables.
Ren : Ctx⋆ → Ctx⋆ → Set Ren Φ Ψ = ∀ {J} → Φ ∋⋆ J → Ψ ∋⋆ J
Let ρ
range of renamings.
variable ρ ρ' : Ren Φ Ψ
Extending a type renaming — used when going under a binder.
ext : Ren Φ Ψ ----------------------------- → ∀ {K} → Ren (Φ ,⋆ K) (Ψ ,⋆ K) ext ρ Z = Z ext ρ (S α) = S (ρ α)
Apply a type renaming to a type.
ren : Ren Φ Ψ ----------------------- → ∀ {J} → Φ ⊢⋆ J → Ψ ⊢⋆ J ren ρ (` α) = ` (ρ α) ren ρ (Π B) = Π (ren (ext ρ) B) ren ρ (A ⇒ B) = ren ρ A ⇒ ren ρ B ren ρ (ƛ B) = ƛ (ren (ext ρ) B) ren ρ (A · B) = ren ρ A · ren ρ B ren ρ (μ A B) = μ (ren ρ A) (ren ρ B) ren ρ (con tcn) = con tcn
Weakening is a special case of renaming.
weaken : Φ ⊢⋆ J ----------- → Φ ,⋆ K ⊢⋆ J weaken = ren S
Renaming proofs
First functor law for ext
ext-id : (α : Φ ,⋆ K ∋⋆ J) ----------------- → ext id α ≡ α ext-id Z = refl ext-id (S α) = refl
This congruence lemma and analogous ones for exts
, ren
, and
sub
avoids the use of extensionality when reasoning about equal
renamings/substitutions as we only need a pointwise version of
equality. If we used the standard library’s cong
we would need to
postulate extensionality and our equality proofs wouldn’t compute. I
learnt this from Conor McBride.
ext-cong : (∀ {J}(α : Φ ∋⋆ J) → ρ α ≡ ρ' α) → ∀{J K}(α : Φ ,⋆ J ∋⋆ K) -------------------------------- → ext ρ α ≡ ext ρ' α ext-cong p Z = refl ext-cong p (S α) = cong S (p α)
Congruence lemma for ren
ren-cong : (∀ {J}(α : Φ ∋⋆ J) → ρ α ≡ ρ' α) → ∀{K}(A : Φ ⊢⋆ K) -------------------------------- → ren ρ A ≡ ren ρ' A ren-cong p (` α) = cong ` (p α) ren-cong p (Π A) = cong Π (ren-cong (ext-cong p) A) ren-cong p (A ⇒ B) = cong₂ _⇒_ (ren-cong p A) (ren-cong p B) ren-cong p (ƛ A) = cong ƛ (ren-cong (ext-cong p) A) ren-cong p (A · B) = cong₂ _·_ (ren-cong p A) (ren-cong p B) ren-cong p (μ A B) = cong₂ μ (ren-cong p A) (ren-cong p B) ren-cong p (con c) = refl
First functor law for ren
ren-id : (t : Φ ⊢⋆ J) ------------ → ren id t ≡ t ren-id (` α) = refl ren-id (Π A) = cong Π (trans (ren-cong ext-id A) (ren-id A)) ren-id (A ⇒ B) = cong₂ _⇒_(ren-id A) (ren-id B) ren-id (ƛ A) = cong ƛ (trans (ren-cong ext-id A) (ren-id A)) ren-id (A · B) = cong₂ _·_ (ren-id A) (ren-id B) ren-id (μ A B) = cong₂ μ (ren-id A) (ren-id B) ren-id (con tcn) = refl
Second functor law for ext
ext-comp : ∀{J K}(x : Φ ,⋆ K ∋⋆ J) --------------------------------- → ext (ρ ∘ ρ') x ≡ ext ρ (ext ρ' x) ext-comp Z = refl ext-comp (S x) = refl
Second functor law for ren
ren-comp : ∀{J}(A : Φ ⊢⋆ J) --------------------------------- → ren (ρ ∘ ρ') A ≡ ren ρ (ren ρ' A) ren-comp (` x) = refl ren-comp (Π A) = cong Π (trans (ren-cong ext-comp A) (ren-comp A)) ren-comp (A ⇒ B) = cong₂ _⇒_ (ren-comp A) (ren-comp B) ren-comp (ƛ A) = cong ƛ (trans (ren-cong ext-comp A) (ren-comp A)) ren-comp (A · B) = cong₂ _·_ (ren-comp A) (ren-comp B) ren-comp (μ A B) = cong₂ μ (ren-comp A) (ren-comp B) ren-comp (con tcn) = refl
Type substitution
A type substitution is a mapping of type variables to types.
Sub : Ctx⋆ → Ctx⋆ → Set Sub Φ Ψ = ∀ {J} → Φ ∋⋆ J → Ψ ⊢⋆ J
Let σ
range over substitutions:
variable σ σ' : Sub Φ Ψ
Extending a type substitution — used when going under a binder.
exts : Sub Φ Ψ ----------------------------- → ∀ {K} → Sub (Φ ,⋆ K) (Ψ ,⋆ K) exts σ Z = ` Z exts σ (S α) = weaken (σ α)
Apply a type substitution to a type.
sub : Sub Φ Ψ ----------------------- → ∀ {J} → Φ ⊢⋆ J → Ψ ⊢⋆ J sub σ (` α) = σ α sub σ (Π B) = Π (sub (exts σ) B) sub σ (A ⇒ B) = sub σ A ⇒ sub σ B sub σ (ƛ B) = ƛ (sub (exts σ) B) sub σ (A · B) = sub σ A · sub σ B sub σ (μ A B) = μ (sub σ A) (sub σ B) sub σ (con tcn) = con tcn
Extend a substitution with an additional type (analogous to cons
for
backward lists)
sub-cons : Sub Φ Ψ → ∀{J}(A : Ψ ⊢⋆ J) ---------------- → Sub (Φ ,⋆ J) Ψ sub-cons f A Z = A sub-cons f A (S x) = f x
A special case is substitution a type for the outermost free variable:
_[_] : Φ ,⋆ K ⊢⋆ J → Φ ⊢⋆ K ----------- → Φ ⊢⋆ J B [ A ] = sub (sub-cons ` A) B
Type Substitution Proofs
Extending the identity substitution yields the identity substitution
exts-id : (α : Φ ,⋆ K ∋⋆ J) ----------------- → exts ` α ≡ ` α exts-id Z = refl exts-id (S α) = refl
Congruence lemma for exts
exts-cong : (∀ {J}(α : Φ ∋⋆ J) → σ α ≡ σ' α) → ∀{J K}(α : Φ ,⋆ K ∋⋆ J) -------------------------------- → exts σ α ≡ exts σ' α exts-cong p Z = refl exts-cong p (S α) = cong (ren S) (p α)
Congruence lemma for sub
sub-cong : (∀ {J}(α : Φ ∋⋆ J) → σ α ≡ σ' α) → ∀{K}(A : Φ ⊢⋆ K) -------------------------------- → sub σ A ≡ sub σ' A sub-cong p (` α) = p α sub-cong p (Π A) = cong Π (sub-cong (exts-cong p) A) sub-cong p (A ⇒ B) = cong₂ _⇒_ (sub-cong p A) (sub-cong p B) sub-cong p (ƛ A) = cong ƛ (sub-cong (exts-cong p) A) sub-cong p (A · B) = cong₂ _·_ (sub-cong p A) (sub-cong p B) sub-cong p (μ A B) = cong₂ μ (sub-cong p A) (sub-cong p B) sub-cong p (con tcn) = refl
First relative monad law
for sub
sub-id : (t : Φ ⊢⋆ J) ------------ → sub ` t ≡ t sub-id (` α) = refl sub-id (Π A) = cong Π (trans (sub-cong exts-id A) (sub-id A)) sub-id (A ⇒ B) = cong₂ _⇒_ (sub-id A) (sub-id B) sub-id (ƛ A) = cong ƛ (trans (sub-cong exts-id A) (sub-id A)) sub-id (A · B) = cong₂ _·_ (sub-id A) (sub-id B) sub-id (μ A B) = cong₂ μ (sub-id A) (sub-id B) sub-id (con tcn) = refl
Fusion of exts
and ext
exts-ext : ∀{J K}(α : Φ ,⋆ K ∋⋆ J) --------------------------------- → exts (σ ∘ ρ) α ≡ exts σ (ext ρ α) exts-ext Z = refl exts-ext (S α) = refl
Fusion for sub
and ren
sub-ren : ∀{J}(A : Φ ⊢⋆ J) ------------------------------- → sub (σ ∘ ρ) A ≡ sub σ (ren ρ A) sub-ren (` α) = refl sub-ren (Π A) = cong Π (trans (sub-cong exts-ext A) (sub-ren A)) sub-ren (A ⇒ B) = cong₂ _⇒_ (sub-ren A) (sub-ren B) sub-ren (ƛ A) = cong ƛ (trans (sub-cong exts-ext A) (sub-ren A)) sub-ren (A · B) = cong₂ _·_ (sub-ren A) (sub-ren B) sub-ren (μ A B) = cong₂ μ (sub-ren A) (sub-ren B) sub-ren (con tcn) = refl
Fusion for exts
and ext
ren-ext-exts : ∀{J K}(α : Φ ,⋆ K ∋⋆ J) ------------------------------------------- → exts (ren ρ ∘ σ) α ≡ ren (ext ρ) (exts σ α) ren-ext-exts Z = refl ren-ext-exts (S α) = trans (sym (ren-comp _)) (ren-comp _)
Fusion for ren
and sub
ren-sub : ∀{J}(A : Φ ⊢⋆ J) ----------------------------------- → sub (ren ρ ∘ σ) A ≡ ren ρ (sub σ A) ren-sub (` α) = refl ren-sub (Π A) = cong Π (trans (sub-cong ren-ext-exts A) (ren-sub A)) ren-sub (A ⇒ B) = cong₂ _⇒_ (ren-sub A) (ren-sub B) ren-sub (ƛ A) = cong ƛ (trans (sub-cong ren-ext-exts A) (ren-sub A)) ren-sub (A · B) = cong₂ _·_ (ren-sub A) (ren-sub B) ren-sub (μ A B) = cong₂ μ (ren-sub A) (ren-sub B) ren-sub (con tcn) = refl
Fusion of two exts
extscomp : ∀{J K}(α : Φ ,⋆ K ∋⋆ J) ---------------------------------------------- → exts (sub σ ∘ σ') α ≡ sub (exts σ) (exts σ' α) extscomp Z = refl extscomp {σ' = σ'} (S α) = trans (sym (ren-sub (σ' α))) (sub-ren (σ' α))
Fusion of substitutions/third relative monad law for sub
sub-comp : ∀{J}(A : Φ ⊢⋆ J) ------------------------------------- → sub (sub σ ∘ σ') A ≡ sub σ (sub σ' A) sub-comp (` x) = refl sub-comp (Π A) = cong Π (trans (sub-cong extscomp A) (sub-comp A)) sub-comp (A ⇒ B) = cong₂ _⇒_ (sub-comp A) (sub-comp B) sub-comp (ƛ A) = cong ƛ (trans (sub-cong extscomp A) (sub-comp A)) sub-comp (A · B) = cong₂ _·_ (sub-comp A) (sub-comp B) sub-comp (μ A B) = cong₂ μ (sub-comp A) (sub-comp B) sub-comp (con tcn) = refl
Commuting sub-cons
and ren
ren-sub-cons : (ρ : Ren Φ Ψ) → (A : Φ ⊢⋆ K) → (α : Φ ,⋆ K ∋⋆ J) ------------------------------------------------------- → sub-cons ` (ren ρ A) (ext ρ α) ≡ ren ρ (sub-cons ` A α) ren-sub-cons ρ A Z = refl ren-sub-cons ρ A (S α) = refl
Commuting sub-cons
and sub
sub-sub-cons : (σ : Sub Φ Ψ) → (M : Φ ⊢⋆ K) → (α : Φ ,⋆ K ∋⋆ J) -------------------------------------------------------------- → sub (sub-cons ` (sub σ M)) (exts σ α) ≡ sub σ (sub-cons ` M α) sub-sub-cons σ M Z = refl sub-sub-cons σ M (S α) = trans (sym (sub-ren (σ α))) (sub-id (σ α))
A useful lemma for fixing up the types when renaming a wrap
or unwrap
ren-μ : (ρ⋆ : Ren Φ Ψ) → (A : Φ ⊢⋆ _) → (B : Φ ⊢⋆ K) → ----------------------------------------------------- ren ρ⋆ (A · ƛ (μ (weaken A) (` Z)) · B) ≡ ren ρ⋆ A · ƛ (μ (weaken (ren ρ⋆ A)) (` Z)) · ren ρ⋆ B ren-μ ρ⋆ A B = cong (λ X → ren ρ⋆ A · ƛ (μ X (` Z)) · ren ρ⋆ B) (trans (sym (ren-comp A)) (ren-comp A))
A useful lemma for fixing up the types when renaming a type application
ren-Π : ∀(A : Φ ⊢⋆ K)(B : Φ ,⋆ K ⊢⋆ J)(ρ : Ren Φ Ψ) → ren (ext ρ) B [ ren ρ A ] ≡ ren ρ (B [ A ]) ren-Π A B ρ = trans (sym (sub-ren B)) (trans (sub-cong (ren-sub-cons ρ A) B) (ren-sub B))
A useful lemma for fixing up the types when substituting into a wrap
or unwrap
sub-μ : (σ⋆ : Sub Φ Ψ) → (A : Φ ⊢⋆ _) → (B : Φ ⊢⋆ K) ----------------------------------------------------- → sub σ⋆ (A · ƛ (μ (weaken A) (` Z)) · B) ≡ sub σ⋆ A · ƛ (μ (weaken (sub σ⋆ A)) (` Z)) · sub σ⋆ B sub-μ σ⋆ A B = cong (λ X → sub σ⋆ A · ƛ (μ X (` Z)) · sub σ⋆ B) (trans (sym (sub-ren A)) (ren-sub A))
A useful lemma when substituting into a type application
sub-Π : ∀(A : Φ ⊢⋆ K)(B : Φ ,⋆ K ⊢⋆ J)(σ : Sub Φ Ψ) → sub (exts σ) B [ sub σ A ] ≡ sub σ (B [ A ]) sub-Π A B σ = trans (sym (sub-comp B)) (trans (sub-cong (sub-sub-cons σ A) B) (sub-comp B))