module Untyped.RenamingSubstitution where
open import Function using (id;_∘_) open import Data.List using (List;_∷_;[]) open import Relation.Binary.PropositionalEquality using (_≡_;refl;sym;trans;cong;cong₂) open import Utils using (Maybe;nothing;just) open import Untyped using (_⊢) open _⊢
Ren : Set → Set → Set
Ren X Y = X → Y
lift : {X Y : Set} → Ren X Y → Ren (Maybe X) (Maybe Y)
lift ρ nothing = nothing
lift ρ (just x) = just (ρ x)
renList : {X Y : Set} → Ren X Y → List (X ⊢) → List (Y ⊢)
ren : {X Y : Set} → Ren X Y → X ⊢ → Y ⊢
ren ρ (` x) = ` (ρ x)
ren ρ (ƛ t) = ƛ (ren (lift ρ) t)
ren ρ (t · u) = ren ρ t · ren ρ u
ren ρ (force t) = force (ren ρ t)
ren ρ (delay t) = delay (ren ρ t)
ren ρ (con tcn) = con tcn
ren ρ (builtin b) = builtin b
ren ρ error = error
ren ρ (constr i xs) = constr i (renList ρ xs)
ren ρ (case x ts) = case (ren ρ x) (renList ρ ts)
renList ρ [] = []
renList ρ (x ∷ xs) = ren ρ x ∷ renList ρ xs
weaken : {X : Set} → X ⊢ → Maybe X ⊢
weaken t = ren just t
Proofs that renaming forms a functor
lift-cong : ∀{X Y}
{ρ ρ' : Ren X Y}
→ (∀ x → ρ x ≡ ρ' x)
→ (x : Maybe X)
--------------------
→ lift ρ x ≡ lift ρ' x
lift-cong p nothing = refl
lift-cong p (just x) = cong just (p x)
renList-cong : ∀{X Y}
{ρ ρ' : Ren X Y}
→ (∀ x → ρ x ≡ ρ' x)
→ (t : List (X ⊢))
→ renList ρ t ≡ renList ρ' t
ren-cong : ∀{X Y}
{ρ ρ' : Ren X Y}
→ (∀ x → ρ x ≡ ρ' x)
→ (t : X ⊢)
→ ren ρ t ≡ ren ρ' t
ren-cong p (` x) = cong ` (p x)
ren-cong p (ƛ t) = cong ƛ (ren-cong (lift-cong p) t)
ren-cong p (t · u) = cong₂ _·_ (ren-cong p t) (ren-cong p u)
ren-cong p (force t) = cong force (ren-cong p t)
ren-cong p (delay t) = cong delay (ren-cong p t)
ren-cong p (con c) = refl
ren-cong p (builtin b) = refl
ren-cong p error = refl
ren-cong p (constr i xs) = cong (constr i) (renList-cong p xs)
ren-cong p (case t ts) = cong₂ case (ren-cong p t) (renList-cong p ts)
renList-cong p [] = refl
renList-cong p (x ∷ xs) = cong₂ _∷_ (ren-cong p x) (renList-cong p xs)
lift-id : ∀{X}(x : Maybe X) → id x ≡ lift id x
lift-id nothing = refl
lift-id (just x) = refl
lift-comp : ∀{X Y Z}(g : Ren X Y)(f : Ren Y Z)(x : Maybe X)
→ lift (f ∘ g) x ≡ lift f (lift g x)
lift-comp g f nothing = refl
lift-comp g f (just x) = refl
renList-id : ∀{X}(ts : List (X ⊢)) → ts ≡ renList id ts
ren-id : ∀{X}(t : X ⊢) → t ≡ ren id t
ren-id (` x) = refl
ren-id (ƛ t) = cong ƛ (trans (ren-id t) (ren-cong lift-id t))
ren-id (t · u) = cong₂ _·_ (ren-id t) (ren-id u)
ren-id (force t) = cong force (ren-id t)
ren-id (delay t) = cong delay (ren-id t)
ren-id (con c) = refl
ren-id (builtin b) = refl
ren-id error = refl
ren-id (constr i xs) = cong (constr i) (renList-id xs)
ren-id (case t ts) = cong₂ case (ren-id t) (renList-id ts)
renList-id [] = refl
renList-id (x ∷ ts) = cong₂ _∷_ (ren-id x) (renList-id ts)
renList-comp : ∀{X Y Z}(g : Ren X Y)(f : Ren Y Z)(t : List (X ⊢))
→ renList (f ∘ g) t ≡ renList f (renList g t)
ren-comp : ∀{X Y Z}(g : Ren X Y)(f : Ren Y Z)(t : X ⊢)
→ ren (f ∘ g) t ≡ ren f (ren g t)
ren-comp ρ ρ' (` x) = refl
ren-comp ρ ρ' (ƛ t) = cong ƛ (trans
(ren-cong (lift-comp ρ ρ') t)
(ren-comp (lift ρ) (lift ρ') t))
ren-comp ρ ρ' (t · u) = cong₂ _·_ (ren-comp ρ ρ' t) (ren-comp ρ ρ' u)
ren-comp ρ ρ' (force t) = cong force (ren-comp ρ ρ' t)
ren-comp ρ ρ' (delay t) = cong delay (ren-comp ρ ρ' t)
ren-comp ρ ρ' (con c) = refl
ren-comp ρ ρ' (builtin b) = refl
ren-comp ρ ρ' error = refl
ren-comp ρ ρ' (constr i xs) = cong (constr i) (renList-comp ρ ρ' xs)
ren-comp ρ ρ' (case t ts) = cong₂ case (ren-comp ρ ρ' t) (renList-comp ρ ρ' ts)
renList-comp ρ ρ' [] = refl
renList-comp ρ ρ' (x ∷ xs) = cong₂ _∷_ (ren-comp ρ ρ' x) (renList-comp ρ ρ' xs)
Sub : Set → Set → Set
Sub X Y = X → Y ⊢
lifts : {X Y : Set} → Sub X Y → Sub (Maybe X) (Maybe Y)
lifts ρ nothing = ` nothing
lifts ρ (just x) = ren just (ρ x)
subList : {X Y : Set} → Sub X Y → List (X ⊢) → List (Y ⊢)
sub : {X Y : Set} → Sub X Y → X ⊢ → Y ⊢
sub σ (` x) = σ x
sub σ (ƛ t) = ƛ (sub (lifts σ) t)
sub σ (t · u) = sub σ t · sub σ u
sub σ (force t) = force (sub σ t)
sub σ (delay t) = delay (sub σ t)
sub σ (con tcn) = con tcn
sub σ (builtin b) = builtin b
sub σ error = error
sub σ (constr i xs) = constr i (subList σ xs)
sub σ (case x ts) = case (sub σ x) (subList σ ts)
subList σ [] = []
subList σ (x ∷ xs) = sub σ x ∷ subList σ xs
extend : ∀{X Y} → Sub X Y → Y ⊢ → Sub (Maybe X) Y
extend σ t nothing = t
extend σ t (just x) = σ x
_[_] : ∀{X} → Maybe X ⊢ → X ⊢ → X ⊢
t [ u ] = sub (extend ` u) t
Proofs that substitution forms a monad
lifts-cong : ∀{X Y}{σ σ' : Sub X Y}
→ (∀ x → σ x ≡ σ' x)
→ (x : Maybe X)
→ lifts σ x ≡ lifts σ' x
lifts-cong p nothing = refl
lifts-cong p (just x) = cong (ren just) (p x)
subList-cong : ∀{X Y}{σ σ' : Sub X Y}
→ (∀ x → σ x ≡ σ' x)
→ (ts : List (X ⊢))
→ subList σ ts ≡ subList σ' ts
sub-cong : ∀{X Y}{σ σ' : Sub X Y}
→ (∀ x → σ x ≡ σ' x)
→ (t : X ⊢)
→ sub σ t ≡ sub σ' t
sub-cong p (` x) = p x
sub-cong p (ƛ t) = cong ƛ (sub-cong (lifts-cong p) t)
sub-cong p (t · u) = cong₂ _·_ (sub-cong p t) (sub-cong p u)
sub-cong p (force t) = cong force (sub-cong p t)
sub-cong p (delay t) = cong delay (sub-cong p t)
sub-cong p (con c) = refl
sub-cong p (builtin b) = refl
sub-cong p error = refl
sub-cong p (constr i xs) = cong (constr i) (subList-cong p xs)
sub-cong p (case t ts) = cong₂ case (sub-cong p t) (subList-cong p ts)
subList-cong p [] = refl
subList-cong p (x ∷ xs) = cong₂ _∷_ (sub-cong p x) (subList-cong p xs)
lifts-id : ∀{X}(x : Maybe X) → ` x ≡ lifts ` x
lifts-id nothing = refl
lifts-id (just x) = refl
subList-id : ∀{X}(ts : List (X ⊢)) → ts ≡ subList ` ts
sub-id : ∀{X}(t : X ⊢) → t ≡ sub ` t
sub-id (` x) = refl
sub-id (ƛ t) = cong ƛ (trans (sub-id t) (sub-cong lifts-id t))
sub-id (t · u) = cong₂ _·_ (sub-id t) (sub-id u)
sub-id (force t) = cong force (sub-id t)
sub-id (delay t) = cong delay (sub-id t)
sub-id (con c) = refl
sub-id (builtin b) = refl
sub-id error = refl
sub-id (constr i xs) = cong (constr i) (subList-id xs)
sub-id (case t ts) = cong₂ case (sub-id t) (subList-id ts)
subList-id [] = refl
subList-id (x ∷ xs) = cong₂ _∷_ (sub-id x) (subList-id xs)
lifts-lift : ∀{X Y Z}(g : Ren X Y)(f : Sub Y Z)(x : Maybe X)
→ lifts (f ∘ g) x ≡ lifts f (lift g x)
lifts-lift g f nothing = refl
lifts-lift g f (just x) = refl
subList-ren : ∀{X Y Z}(ρ : Ren X Y)(σ : Sub Y Z)(xs : List (X ⊢))
→ subList (σ ∘ ρ) xs ≡ subList σ (renList ρ xs)
sub-ren : ∀{X Y Z}(ρ : Ren X Y)(σ : Sub Y Z)(t : X ⊢)
→ sub (σ ∘ ρ) t ≡ sub σ (ren ρ t)
sub-ren ρ σ (` x) = refl
sub-ren ρ σ (ƛ t) = cong ƛ (trans
(sub-cong (lifts-lift ρ σ) t)
(sub-ren (lift ρ) (lifts σ) t))
sub-ren ρ σ (t · u) = cong₂ _·_ (sub-ren ρ σ t) (sub-ren ρ σ u)
sub-ren ρ σ (force t) = cong force (sub-ren ρ σ t)
sub-ren ρ σ (delay t) = cong delay (sub-ren ρ σ t)
sub-ren ρ σ (con c) = refl
sub-ren ρ σ (builtin b) = refl
sub-ren ρ σ error = refl
sub-ren ρ σ (constr i xs) = cong (constr i) (subList-ren ρ σ xs)
sub-ren ρ σ (case t ts) = cong₂ case (sub-ren ρ σ t) (subList-ren ρ σ ts)
subList-ren ρ σ [] = refl
subList-ren ρ σ (x ∷ xs) = cong₂ _∷_ (sub-ren ρ σ x) (subList-ren ρ σ xs)
ren-lift-lifts : ∀{X Y Z}(g : Sub X Y)(f : Ren Y Z)(x : Maybe X)
→ lifts (ren f ∘ g) x ≡ ren (lift f) (lifts g x)
ren-lift-lifts g f nothing = refl
ren-lift-lifts g f (just x) = trans
(sym (ren-comp f just (g x)))
(ren-comp just (lift f) (g x))
renList-sub : ∀{X Y Z}(σ : Sub X Y)(ρ : Ren Y Z)(xs : List (X ⊢))
→ subList (ren ρ ∘ σ) xs ≡ renList ρ (subList σ xs)
ren-sub : ∀{X Y Z}(σ : Sub X Y)(ρ : Ren Y Z)(t : X ⊢)
→ sub (ren ρ ∘ σ) t ≡ ren ρ (sub σ t)
ren-sub σ ρ (` x) = refl
ren-sub σ ρ (ƛ t) = cong ƛ (trans
(sub-cong (ren-lift-lifts σ ρ) t)
(ren-sub (lifts σ) (lift ρ) t))
ren-sub σ ρ (t · u) = cong₂ _·_ (ren-sub σ ρ t) (ren-sub σ ρ u)
ren-sub σ ρ (force t) = cong force (ren-sub σ ρ t)
ren-sub σ ρ (delay t) = cong delay (ren-sub σ ρ t)
ren-sub σ ρ (con c) = refl
ren-sub σ ρ (builtin b) = refl
ren-sub σ ρ error = refl
ren-sub σ ρ (constr i xs) = cong (constr i) (renList-sub σ ρ xs)
ren-sub σ ρ (case t ts) = cong₂ case (ren-sub σ ρ t) (renList-sub σ ρ ts)
renList-sub σ ρ [] = refl
renList-sub σ ρ (x ∷ xs) = cong₂ _∷_ (ren-sub σ ρ x) (renList-sub σ ρ xs)
lifts-comp : ∀{X Y Z}(g : Sub X Y)(f : Sub Y Z)(x : Maybe X)
→ lifts (sub f ∘ g) x ≡ sub (lifts f) (lifts g x)
lifts-comp g f nothing = refl
lifts-comp g f (just x) = trans
(sym (ren-sub f just (g x)))
(sub-ren just (lifts f) (g x))
subList-comp : ∀{X Y Z}(g : Sub X Y)(f : Sub Y Z)(xs : List (X ⊢))
→ subList (sub f ∘ g) xs ≡ subList f (subList g xs)
sub-comp : ∀{X Y Z}(g : Sub X Y)(f : Sub Y Z)(t : X ⊢)
→ sub (sub f ∘ g) t ≡ sub f (sub g t)
sub-comp g f (` x) = refl
sub-comp g f (ƛ t) =
cong ƛ (trans (sub-cong (lifts-comp g f) t) (sub-comp (lifts g) (lifts f) t))
sub-comp g f (t · u) = cong₂ _·_ (sub-comp g f t) (sub-comp g f u)
sub-comp g f (force t) = cong force (sub-comp g f t)
sub-comp g f (delay t) = cong delay (sub-comp g f t)
sub-comp g f (con c) = refl
sub-comp g f (builtin b) = refl
sub-comp g f error = refl
sub-comp g f (constr i xs) = cong (constr i) (subList-comp g f xs)
sub-comp g f (case t ts) = cong₂ case (sub-comp g f t) (subList-comp g f ts)
subList-comp g f [] = refl
subList-comp g f (x ∷ xs) = cong₂ _∷_ (sub-comp g f x) (subList-comp g f xs)