« Home

NOTE: Substitution Without Copy and Paste [tt-IHCF]

Substitution Without Copy and Paste

The copy-and-paste approach [ag-000M]

{-# OPTIONS --safe --without-K #-}
module ag-000M where

open import MLTT.Spartan

類型跟 context

data Ty : 𝓤₀ ̇ where
  base : Ty
  _⇒_ : Ty  Ty  Ty
infixl 50 _⇒_

data Con : 𝓤₀ ̇ where
   : Con
  _▷_ : Con  Ty  Con
infixl 40 _▷_
  1. 等一下用的變數
  2. de Bruijn variables
  3. terms
variable
  Γ Δ Ξ : Con
  A B C : Ty

data _∋_ : Con  Ty  𝓤₀ ̇ where
  here : Γ  A  A
  there : Γ  A  (B : Ty)
        ------------------
         Γ  B  A
infixl 30 _∋_

data _⊢_ : Con  Ty  𝓤₀ ̇ where
  -- embeds variables in λ-terms
  `_ : Γ  A  Γ  A
  -- application t · u
  _·_ : Γ  A  B  Γ  A  Γ  B
  ƛ_ : Γ  A  B  Γ  A  B
infixl 20 _⊢_
infixl 60 `_
infixl 50 _·_
infixl 40 ƛ_

substitution 定義成

data _⊩_ : Con  Con  𝓤₀ ̇ where
  ε : Γ  
  _,_ : Γ  Δ  Γ  A  Γ  Δ  A

現在要定義 substitution 在 terms 跟 variables 上的作用:

_v[_] : Δ  A  Γ  Δ  Γ  A
here v[ ts , t ] = t
there i B v[ ts , t ] = i v[ ts ]

data _⊩v_ : Con  Con  𝓤₀ ̇ where
  ε : Γ ⊩v 
  _,_ : Γ ⊩v Δ  Γ  A  Γ ⊩v Δ  A

_v[_]v : Γ  A  Δ ⊩v Γ  Δ  A
here v[ is , i ]v = i
there i B v[ is , j ]v = i v[ is ]v

_⁺v_ : Γ ⊩v Δ  (A : Ty)  Γ  A ⊩v Δ
ε ⁺v A = ε
(is , i) ⁺v A = (is ⁺v A) , there i A

_↑v_ : Γ ⊩v Δ  (A : Ty)  Γ  A ⊩v Δ  A
is ↑v A = (is ⁺v A) , here

_[_]v : Γ  A  Δ ⊩v Γ  Δ  A
(` i) [ is ]v = ` (i v[ is ]v)
(t · u) [ is ]v = (t [ is ]v) · (u [ is ]v)
(ƛ t) [ is ]v = ƛ (t [ is ↑v _ ]v)

idv : Γ ⊩v Γ
idv {Γ = } = ε
idv {Γ = Γ  A} = idv ↑v A

為了定義下面的 suc-tm,需要定義上面大量的類似結構 Γ ⊩v Δ

_⁺_ : Γ  Δ  (A : Ty)  Γ  A  Δ
ε  A = ε
(ts , t)  A = (ts  A) , suc-tm t A
  where
  suc-tm : Γ  B  (A : Ty)  Γ  A  B
  suc-tm t A = t [ idv ⁺v A ]v

_↑_ : Γ  Δ  (A : Ty)  Γ  A  Δ  A
ts  A = ts  A , ` here

_[_] : Γ  A  Δ  Γ  Δ  A
(` i) [ ts ] = i v[ ts ]
(t · u) [ ts ] = (t [ ts ]) · (u [ ts ])
(ƛ t) [ ts ] = ƛ (t [ ts  _ ])

所以為了避免這些重複,方法要改成:

Substituion without copy and paste 的提議 [ag-000N]

{-# OPTIONS --safe --without-K #-}
module ag-000N where

open import MLTT.Spartan hiding (_⊔_; id)
open import ag-000M using (Ty; _⇒_; Con; ; _▷_)

variable
  Γ Δ Ξ : Con
  A B C : Ty

引入 Sort 區分 variable 跟 term 的情況

mutual
  data Sort : 𝓤₀ ̇ where
    V : Sort
    T>V : (s : Sort)  IsV s  Sort
  data IsV : Sort  𝓤₀ ̇ where
    isV : IsV V

pattern T = T>V V isV

variable
  q r s : Sort

這樣就可以把 variables 跟 terms 定義到一起,用 s 區分 Γ ⊢[ s ] A 是 variable 還是 term

data _⊢[_]_ : Con  Sort  Ty  𝓤₀ ̇ where
  here : Γ  A ⊢[ V ] A
  there : Γ ⊢[ V ] A  (B : Ty)  Γ  B ⊢[ V ] A
  `_ : Γ ⊢[ V ] A  Γ ⊢[ T ] A
  _·_ : Γ ⊢[ T ] A  B  Γ ⊢[ T ] A  Γ ⊢[ T ] B
  ƛ_ : Γ  A ⊢[ T ] B  Γ ⊢[ T ] A  B

variable
  x y z : Γ ⊢[ q ] A

substitution 現在定義成

data _⊩[_]_ : Con  Sort  Con  𝓤₀ ̇ where
  ε : Γ ⊩[ q ] 
  _,_ : Γ ⊩[ q ] Δ  Γ ⊢[ q ] A  Γ ⊩[ q ] Δ  A

variable
  xs ys zs : Δ ⊩[ q ] Γ

現在需要考慮 sort 之間的關係,這些 lemma 有助於簡化後面的證明

data _⊑_ : Sort  Sort  Set where
  rfl : s  s
  v⊑t : V  T

_⊔_ : Sort  Sort  Sort
V  r = r
T  r = T

一些輔助用的 REWRITE [ag-000O]

{-# OPTIONS --without-K --rewriting #-}
module ag-000O where

open import MLTT.Spartan hiding (_⊔_; id)

open import ag-000M using (Ty; _⇒_; Con; ; _▷_)
open import ag-000N

{-# BUILTIN REWRITE _=_ #-}

這邊的定義很繁瑣但只是單純攤開 VT 就能證明,並不是很重要。重點在最後用 REWRITE 避免後續需要證明一些麻煩的情況

⊑t : s  T
⊑t {V} = v⊑t
⊑t {T} = rfl
v⊑ : V  s
v⊑ {V} = rfl
v⊑ {T} = v⊑t
⊑q⊔ : q  (q  r)
⊑q⊔ {V}{V} = rfl
⊑q⊔ {V}{T} = v⊑t
⊑q⊔ {T}{V} = rfl
⊑q⊔ {T}{T} = rfl
⊔⊔ : q  (r  s)  (q  r)  s
⊔⊔ {V}{V}{V} = refl
⊔⊔ {V}{V}{T} = refl
⊔⊔ {V}{T}{V} = refl
⊔⊔ {V}{T}{T} = refl
⊔⊔ {T}{V}{V} = refl
⊔⊔ {T}{V}{T} = refl
⊔⊔ {T}{T}{V} = refl
⊔⊔ {T}{T}{T} = refl
⊔v : q  V  q
⊔v {V} = refl
⊔v {T} = refl
⊔t : q  T  T
⊔t {V} = refl
⊔t {T} = refl
⊑⊔r : r  (q  r)
⊑⊔r {V}{V} = rfl
⊑⊔r {V}{T} = v⊑t
⊑⊔r {T}{V} = rfl
⊑⊔r {T}{T} = rfl

⊔-self : q  q  q
⊔-self {V} = refl
⊔-self {T} = refl

{-# REWRITE ⊔⊔ ⊔v ⊔t ⊔-self #-}

substitution 的組合 [ag-000P]

{-# OPTIONS --without-K --rewriting #-}
module ag-000P where

open import MLTT.Spartan hiding (_⊔_; id)

open import ag-000M using (Ty; _⇒_; Con; ; _▷_)
open import ag-000N
open import ag-000O

這裡的目的是定義 relation 對 term 的影響,以及定義 substitution 的結合

tm⊑ : q  s  Γ ⊢[ q ] A  Γ ⊢[ s ] A
tm⊑ rfl x = x
tm⊑ v⊑t i = ` i

here[_] : (q : Sort)  Γ  A ⊢[ q ] A
here[ V ] = here
here[ T ] = ` here

mutual
  _[_] : Γ ⊢[ q ] A  Δ ⊩[ r ] Γ  Δ ⊢[ q  r ] A
  here [ xs , x ] = x
  there i _ [ xs , x ] = i [ xs ]
  (` i) [ xs ] = tm⊑ ⊑t (i [ xs ])
  (t · u) [ xs ] = (t [ xs ]) · (u [ xs ])
  (ƛ t) [ xs ] = ƛ (t [ xs  _ ])

  id-poly : (q : Sort)  Γ ⊩[ q ] Γ
  id-poly {Γ = } q = ε
  id-poly {Γ = Γ  A} q = id-poly q  A
  id : Γ ⊩[ V ] Γ
  id = id-poly V
  {-# INLINE id #-}

  there[_] : (q : Sort)  Γ ⊢[ q ] B  (A : Ty)  Γ  A ⊢[ q ] B
  there[ V ] i A = there i A
  there[ T ] t A = t [ id  A ]

  _⁺_ : Γ ⊩[ q ] Δ  (A : Ty)  Γ  A ⊩[ q ] Δ
  ε  A = ε
  (ts , t)  A = (ts  A) , there[ _ ] t A

  _↑_ : Γ ⊩[ q ] Δ  (A : Ty)  Γ  A ⊩[ q ] Δ  A
  ts  A = ts  A , here[ _ ]
infixl 70 _⁺_

_◦_ : Γ ⊩[ q ] Ξ  Δ ⊩[ r ] Γ  Δ ⊩[ q  r ] Ξ
ε  ys = ε
(xs , x)  ys = (xs  ys) , x [ ys ]

Proposition. The right identity law [ag-000Q]

{-# OPTIONS --without-K --rewriting #-}
module ag-000Q where

open import MLTT.Spartan hiding (_⊔_; id)

open import ag-000M using (Ty; _⇒_; Con; ; _▷_)
open import ag-000N
open import ag-000O
open import ag-000P
⁺-nat[]v : (i : Γ ⊢[ V ] A)  (xs : Δ ⊩[ q ] Γ)  i [ xs  B ]  there[ q ] (i [ xs ]) B
⁺-nat[]v here (xs , x) = refl
⁺-nat[]v (there j _) (xs , x) = ⁺-nat[]v j xs

[id] : x [ id ]  x
[id] {x = here} = refl
[id] {x = there i B} =
  (i [ id  B ]) =⟨ ⁺-nat[]v {q = V} i id 
  there (i [ id ]) B =⟨ ap  -  there - B) [id] 
  there i B 
[id] {x = ` i} = ap `_ [id]
[id] {x = t · u} =
  ((t [ id ]) · (u [ id ])) =⟨ ap (t [ id ] ·_) [id] 
  ((t [ id ]) · u) =⟨ ap ( u) [id] 
  (t · u) 
[id] {x = ƛ t} = ap ƛ_ [id]

◦id : xs  id  xs
◦id {xs = ε} = refl
◦id {xs = xs , x} =
  (xs  id) , (x [ id ]) =⟨ ap ((xs  id) ,_) [id] 
  (xs  id) , x          =⟨ ap (_, x) ◦id 
  xs , x 

Proposition. Left identity law 與 Associative law [ag-000R]

{-# OPTIONS --allow-unsolved-metas --without-K --rewriting #-}
module ag-000R where

open import MLTT.Spartan hiding (_⊔_; id)

open import ag-000M using (Ty; _⇒_; Con; ; _▷_)
open import ag-000N
open import ag-000O
open import ag-000P
open import ag-000Q

這兩個是 mutual 定義的,而且有一些 goals 我也看不出怎麼解了,暫時就先這樣 xd

tm[] : tm⊑ ⊑t (x [ xs ])  (tm⊑ ⊑t x) [ xs ]
tm[] {x = here} = refl
tm[] {x = there x B} = refl
tm[] {x = ` x} = tm[] {x = x}
tm[] {x = x · x₁} = refl
tm[] {x = ƛ x} = refl

zero[] : {q : Sort} {r : Sort} {Γ : Con} {Δ : Con} {A : Ty} {xs : Δ ⊩[ r ] Γ} {x : Δ ⊢[ r ] A}  here[ q ] [ xs , x ]  tm⊑ (⊑⊔r {q = q}) x
zero[] {q = V} {r = V} = refl
zero[] {q = V} {r = T} = refl
zero[] {q = T} {r = V} = refl
zero[] {q = T} {r = T} = refl

tm⊑zero : (q⊑r : q  r)  here[ r ]  tm⊑ q⊑r here[ q ]
tm⊑zero rfl = refl
tm⊑zero v⊑t = refl

{-# TERMINATING #-}
mutual
  suc[] : (there[ s ] x _) [ ys , y ]  x [ ys ]
  suc[] {s = V} = refl
  suc[] {s = T} {x = x} {ys = ys} {y = y} =
    there[ T ] x _ [ ys , y ] =⟨ refl 
    x [ id  _ ] [ ys , y ]   =⟨ [◦] {x = x} ⁻¹ 
    x [ (id  _)  (ys , y) ] =⟨ ap (x [_]) ⁺◦ 
    x [ id  ys ] =⟨ ap (x [_]) id◦ 
    x [ ys ] 

  ⁺◦ : xs  A  (ys , x)  xs  ys
  ⁺◦ {xs = ε} = refl
  ⁺◦ {xs = ts , t} {A = A} {ys = ys} {x = x} =
    ((ts  A)  (ys , x)) , (there[ _ ] t A [ ys , x ]) =⟨ ap (((ts  A)  (ys , x)) ,_) (suc[] {x = t}) 
    ((ts  A)  (ys , x)) , (t [ ys ]) =⟨ ap (_, (t [ ys ])) ⁺◦ 
    (ts  ys) , (t [ ys ]) 

  ⁺−nat◦ : {xs : Δ ⊩[ q ] Γ}  {ys : Ξ ⊩[ r ] Δ}  {A : Ty} 
            xs  (ys  A)  (xs  ys)  A
  ⁺−nat◦ {xs = ε} = refl
  ⁺−nat◦ {q = q} {r = r} {xs = xs , x} {ys = ys} {A = A} =
    (xs  (ys  A)) , (x [ ys  A ]) =⟨ ap ((xs  (ys  A)) ,_) (⁺-nat[] {q = q} {B = A} {x = x} {xs = ys}) 
    (xs  (ys  A)) , there[ _ ] (x [ ys ]) A =⟨ ap (_, there[ _ ] (x [ ys ]) A) ⁺−nat◦ 
    ((xs  ys)  A) , there[ _ ] (x [ ys ]) A 

  ⁺-nat[] : {q r : Sort}  {A B : Ty}  {x : Γ ⊢[ q ] A}  {xs : Δ ⊩[ r ] Γ}  x [ xs  B ]  there[ q  r ] (x [ xs ]) B
  ⁺-nat[] {q = V} {x = i} {xs = xs} = ⁺-nat[]v i xs
  ⁺-nat[] {q = T} {B = B} {x = x} {xs = xs} =
    x [ xs  B ]        =⟨ ap  -  x [ -  B ]) (◦id {xs = xs} ⁻¹) 
    x [ (xs  id)  B ] =⟨ ap (x [_]) (⁺−nat◦ ⁻¹) 
    x [ xs  (id  B) ] =⟨ [◦] {x = x} 
    x [ xs ] [ id  B ] =⟨ refl 
    there[ T ] (x [ xs ]) B 

  ↑◦ : {r s : Sort}  {xs : Δ ⊩[ r ] Ξ}  {ys : Γ ⊩[ s ] Δ}  {A : Ty}  (xs  ys)  A  (xs  A)  (ys  A)
  ↑◦ {r = r} {s = s} {xs = xs} {ys = ys} {A = A} =
    (xs  ys)  A                                  =⟨ refl 
    (xs  ys)  A , here[ r  s ]                  =⟨ ap  -  - , here[ _ ]) (⁺−nat◦ ⁻¹) 
    xs  (ys  A) , here[ r  s ]                  =⟨ ap (xs  (ys  A) ,_) (tm⊑zero (⊑⊔r {r = s} {q = r})) 
    xs  (ys  A) , tm⊑ (⊑⊔r {q = r}) here[ s ]    =⟨ ap (xs  (ys  A) ,_) (zero[] {q = r} {r = s} {A = A} {xs = ys  A} {x = here[ s ]} ⁻¹) 
    xs  (ys  A) , (here[ r ] [ ys  A ])         =⟨ ap (_, (here[ r ] [ ys  A ])) (⁺◦ {xs = xs} {A = A} {ys = ys  A} {x = here[ s ]}  ⁻¹) 
    ((xs  A)  (ys  A , here[ s ])) , (here[ r ] [ ys  A ]) =⟨ refl 
    (xs  A)  (ys  A)

  [◦] : x [ xs  ys ]  x [ xs ] [ ys ]
  [◦] {x = here} {xs = xs , x} = refl
  [◦] {x = there i B} {xs = xs , x} = [◦] {x = i}
  [◦] {x = ` x} {xs = xs} {ys = ys} =
    tm⊑ ⊑t (x [ xs  ys ])   =⟨ ap  -  tm⊑ ⊑t -) ([◦] {x = x}) 
    tm⊑ ⊑t (x [ xs ] [ ys ]) =⟨ tm[] {x = x [ xs ]} 
    (tm⊑ ⊑t (x [ xs ]) [ ys ]) 
  [◦] {x = t · u} {xs = xs} {ys = ys} =
    (t [ xs  ys ]) · (u [ xs  ys ])   =⟨ ap ( (u [ xs  ys ])) ([◦] {x = t}) 
    (t [ xs ] [ ys ]) · (u [ xs  ys ]) =⟨ ap ((t [ xs ] [ ys ]) ·_) ([◦] {x = u}) 
    ((t [ xs ]) [ ys ]) · ((u [ xs ]) [ ys ]) 
  [◦] {x = ƛ t} {xs = xs} {ys = ys} = ap ƛ_
    (t [ (xs  ys)  _ ]       =⟨ ap (t [_]) (↑◦ {xs = xs}) 
     t [ (xs  _)  (ys  _) ] =⟨ [◦] {x = t} 
     (t [ xs  _ ]) [ ys  _ ] )

  id◦' : Sort  id  xs  xs
  id◦' {xs = ε} q = refl
  id◦' {xs = xs , x} q = ap (_, x)
    (((id  _)  (xs , x)) =⟨ ⁺◦ 
     id  xs               =⟨ id◦ 
     xs )

  id◦ : id  xs  xs
  id◦ = id◦' V
  {-# INLINE id◦ #-}

到這裡已經證明了 contexts 與 substitutions 真的是一個範疇,而且這個範疇有 terminal object。第五節是把這邊的工作放進去 CwF-simple(constant presheaves 可以讓 CwF 適用於 simply typed calculus)裡,那個我暫時沒什麼興趣。