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))