TAPLを読んでから 約2年が経過しました。
忘れた頃にやる勉強が一番良いらしいので、型のリハビリをしていこうと思います。単純な自作の言語を定義し、その上に型システムを導入し、もろもろの性質を証明していきます。
これ以降は、説明なしに型理論の記法がいろいろ登場します。ごめんなさい。必要に応じてTAPLを参照していただければと思います。
抽象構文
今回作成する言語は以下のような感じです。
t ::= 項:
x 変数
λx:T. t ラムダ抽象
t t 適用
0 ゼロ
succ t 後者値
let x = t in t let束縛
v ::= 値:
λx:T. t ラムダ抽象
nv 数値
nv ::= 数値:
0 ゼロ
succ nv 後者値
T ::= 型:
T→T 関数型
Nat 自然数型
Γ ::= 文脈:
∅ 空の文脈
Γ,x:T 束縛
典型的なラムダ計算 + αです。ラムダ計算は、関数だけでいろいろ計算できちゃうというのがかっこいいです。かっこいいですよね?(確認)
数値は、最終的な計算結果を表すために導入しました。計算結果を表示するPrinterには、succ (succ (... (succ 0) ...))
を数字に変換する機能をつけようと思います。
let束縛は便利なので入れました。
評価
評価規則を定義することで、言語に意味を与えます。
t 1 ⟶ t 1 ′ t 1 t 2 ⟶ t 1 ′ t 2 (E-App1) \dfrac
{
t_1
\longrightarrow
t'_1
}
{
t_1 ~ t_2
\longrightarrow
t'_1 ~ t_2
}
\quad\text{(E-App1)} t 1 t 2 ⟶ t 1 ′ t 2 t 1 ⟶ t 1 ′ (E-App1)
t 2 ⟶ t 2 ′ v 1 t 2 ⟶ v 1 t 2 ′ (E-App2) \dfrac
{
t_2 \longrightarrow t'_2
}
{
v_1 ~ t_2 \longrightarrow v_1 ~ t'_2
}
\quad\text{(E-App2)} v 1 t 2 ⟶ v 1 t 2 ′ t 2 ⟶ t 2 ′ (E-App2)
( λ x : T 11 . t 12 ) v 2 ⟶ [ x ↦ v 2 ] t 12 (E-AppAbs) (\lambda x : T_{11} . ~ t_{12}) ~ v_2
\longrightarrow
[x \mapsto v_2]t_{12}
\quad\text{(E-AppAbs)} ( λ x : T 11 . t 12 ) v 2 ⟶ [ x ↦ v 2 ] t 12 (E-AppAbs)
t 1 ⟶ t 1 ′ succ t 1 ⟶ succ t 1 ′ (E-Succ) \dfrac
{
t_1
\longrightarrow
t'_1
}
{
\text{succ} ~ t_1
\longrightarrow
\text{succ} ~ t'_1
}
\quad\text{(E-Succ)} succ t 1 ⟶ succ t 1 ′ t 1 ⟶ t 1 ′ (E-Succ)
t 1 ⟶ t 1 ′ let x = t 1 in t 2 ⟶ let x = t 1 ′ in t 2 (E-Let) \dfrac
{
t_1
\longrightarrow
t'_1
}
{
\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2
\longrightarrow
\text{let} ~ x ~ \text{=} ~ t'_1 ~ \text{in} ~ t_2
}
\quad\text{(E-Let)} let x = t 1 in t 2 ⟶ let x = t 1 ′ in t 2 t 1 ⟶ t 1 ′ (E-Let)
let x = v 1 in t 2 ⟶ [ x ↦ v 1 ] t 2 (E-LetV) \text{let} ~ x ~ \text{=} ~ v_1 ~ \text{in} ~ t_2
\longrightarrow
[x \mapsto v_1]t_{2}
\quad\text{(E-LetV)} let x = v 1 in t 2 ⟶ [ x ↦ v 1 ] t 2 (E-LetV)
定義:代入
[ x ↦ s ] x = s [ x ↦ s ] y = y ( if y ≠ x ) [ x ↦ s ] ( λ y . t ) = λ y . [ x ↦ s ] t ( if y ≠ x and y ∉ F V ( s ) ) [ x ↦ s ] ( t 1 t 2 ) = [ x ↦ s ] t 1 [ x ↦ s ] t 2 [ x ↦ s ] 0 = 0 [ x ↦ s ] ( succ t ) = succ [ x ↦ s ] ( t ) [ x ↦ s ] ( let y = t 1 in t 2 ) = ( let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 ) ( if y ≠ x and y ∉ F V ( s ) ) \begin{aligned}
[x \mapsto s]x
&=
s \\
[x \mapsto s]y
&=
y \quad (\text{if} ~ y \ne x) \\
[x \mapsto s](\lambda y . ~ t)
&=
\lambda y . ~ [x \mapsto s] t
\quad (\text{if} ~ y \ne x ~ \text{and} ~ y \notin FV(s)) \\
[x \mapsto s](t_1 ~ t_2)
&=
[x \mapsto s]t_1 ~ [x \mapsto s]t_2 \\
[x \mapsto s]0
&=
0 \\
[x \mapsto s](\text{succ} ~ t)
&=
\text{succ} ~ [x \mapsto s](t) \\
[x \mapsto s](\text{let} ~ y ~ = ~ t_1 ~ \text{in} ~ t_2)
&=
(\text{let} ~ y ~ = ~ [x \mapsto s]t_1 ~ \text{in} ~ [x \mapsto s]t_2)
\quad (\text{if} ~ y \ne x ~ \text{and} ~ y \notin FV(s)) \\
\end{aligned} [ x ↦ s ] x [ x ↦ s ] y [ x ↦ s ] ( λ y . t ) [ x ↦ s ] ( t 1 t 2 ) [ x ↦ s ] 0 [ x ↦ s ] ( succ t ) [ x ↦ s ] ( let y = t 1 in t 2 ) = s = y ( if y = x ) = λ y . [ x ↦ s ] t ( if y = x and y ∈ / F V ( s )) = [ x ↦ s ] t 1 [ x ↦ s ] t 2 = 0 = succ [ x ↦ s ] ( t ) = ( let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 ) ( if y = x and y ∈ / F V ( s ))
まぁそうなるよね、という感じです。
型付け
型を付けていきます。
x : T ∈ Γ Γ ⊢ x : T (T-Var) \dfrac
{
x : T \in \Gamma
}
{
\Gamma \vdash
x :
T
}
\quad\text{(T-Var)} Γ ⊢ x : T x : T ∈ Γ (T-Var)
Γ , x : T 1 ⊢ t 2 : T 2 Γ ⊢ λ x : T 1 . t 2 : T 1 → T 2 (T-Abs) \dfrac
{
\Gamma , x : T_1 \vdash
t_2 :
T_2
}
{
\Gamma \vdash
\lambda x: T_1 . ~ t_2 :
T_1 \rightarrow T_2
}
\quad\text{(T-Abs)} Γ ⊢ λ x : T 1 . t 2 : T 1 → T 2 Γ , x : T 1 ⊢ t 2 : T 2 (T-Abs)
Γ ⊢ t 1 : T 11 → T 12 Γ ⊢ t 2 : T 11 Γ ⊢ t 1 t 2 : T 12 (T-App) \dfrac
{
\Gamma \vdash
t_1 :
T_{11} \rightarrow T_{12}
\qquad
\Gamma \vdash
t_2 :
T_{11}
}
{
\Gamma \vdash
t_1 ~ t_2 :
T_{12}
}
\quad\text{(T-App)} Γ ⊢ t 1 t 2 : T 12 Γ ⊢ t 1 : T 11 → T 12 Γ ⊢ t 2 : T 11 (T-App)
Γ ⊢ 0 : Nat (T-Zero) \Gamma \vdash
0 :
\text{Nat}
\quad\text{(T-Zero)} Γ ⊢ 0 : Nat (T-Zero)
Γ ⊢ t 1 : Nat Γ ⊢ succ t 1 : Nat (T-Succ) \dfrac
{
\Gamma \vdash
t_1 :
\text{Nat}
}
{
\Gamma \vdash
\text{succ} ~ t_1 :
\text{Nat}
}
\quad\text{(T-Succ)} Γ ⊢ succ t 1 : Nat Γ ⊢ t 1 : Nat (T-Succ)
Γ ⊢ t 1 : T 1 Γ , x : T 1 ⊢ t 2 : T 2 Γ ⊢ let x = t 1 in t 2 : T 2 (T-Let) \dfrac
{
\Gamma \vdash
t_1 :
T_1
\qquad
\Gamma , x : T_1 \vdash
t_2 :
T_2
}
{
\Gamma \vdash
\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 :
T_2
}
\quad\text{(T-Let)} Γ ⊢ let x = t 1 in t 2 : T 2 Γ ⊢ t 1 : T 1 Γ , x : T 1 ⊢ t 2 : T 2 (T-Let)
文脈に関する暗黙の仮定
文脈に束縛を追加するとき、すでに束縛している名前とは別のものを追加する。
文脈のすべての束縛は別々の変数名を持つ。
1について、文脈に束縛を追加するのはT-Absだけである。ラムダ抽象の変数を束縛するときに、必要に応じてフレッシュな変数を用いてα-変換することで、名前の衝突を避けられる。
2について、1の性質より成り立つ
ふむり。
進行
おまたせしました、リハビリタイムです。さきほど定義した言語が、安全であることを証明します。
証明の大きな流れはTAPLを参考にしていますが、各議論や式変形は、僕でもわかるようにできるだけ細かく書くようにします。なのでめっちゃ長いです。読み飛ばしましょう。
安全性は、進行と保存によって示します。
まず、以下のように進行定理を示します。そのために、逆転補題と標準形補題という基本的な性質を示します。
補題:逆転
Γ ⊢ x : R \Gamma \vdash x : R Γ ⊢ x : R ならば、 x : R ∈ Γ x : R \in \Gamma x : R ∈ Γ である。
Γ ⊢ λ x : T 1 . t 2 : R \Gamma \vdash \lambda x : T_1 . ~ t_2 : R Γ ⊢ λ x : T 1 . t 2 : R ならば、Γ , x : T 1 ⊢ t 2 : R 2 \Gamma , x : T_1 \vdash t_2 : R_2 Γ , x : T 1 ⊢ t 2 : R 2 を満たす R 2 R_2 R 2 が存在し、 R = T 1 → R 2 R = T_1 \rightarrow R_2 R = T 1 → R 2 である。
Γ ⊢ t 1 t 2 : R \Gamma \vdash t_1 ~ t_2 : R Γ ⊢ t 1 t 2 : R ならば、 Γ ⊢ t 1 : T 11 → R \Gamma \vdash t_1 : T_{11} \rightarrow R Γ ⊢ t 1 : T 11 → R と Γ ⊢ t 2 : T 11 \Gamma \vdash t_2 : T_{11} Γ ⊢ t 2 : T 11 を満たす T 11 T_{11} T 11 が存在する。
Γ ⊢ 0 : R \Gamma \vdash 0 : R Γ ⊢ 0 : R ならば、 R = Nat R = \text{Nat} R = Nat である。
Γ ⊢ succ t 1 : R \Gamma \vdash \text{succ} ~ t_1 : R Γ ⊢ succ t 1 : R ならば、 R = Nat R = \text{Nat} R = Nat かつ Γ ⊢ t 1 : Nat \Gamma \vdash t_1 : \text{Nat} Γ ⊢ t 1 : Nat である。
Γ ⊢ let x = t 1 in t 2 : R \Gamma \vdash \text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 : R Γ ⊢ let x = t 1 in t 2 : R ならば、 Γ ⊢ t 1 : T 1 \Gamma \vdash t_1 : T_1 Γ ⊢ t 1 : T 1 と Γ , x : T 1 ⊢ t 2 : R \Gamma , x : T_1 \vdash t_2 : R Γ , x : T 1 ⊢ t 2 : R を満たす T 1 T_1 T 1 が存在する。
概要:ある項にある型が付いているとき、項の形から型の形をいえる補題。
証明:
型付け規則の定義より自明。
補題:標準形
v v v が T 1 → T 2 T_1 \rightarrow T_2 T 1 → T 2 型の値ならば、 v = λ x : T 1 . t 2 v = \lambda x : T_1 . ~ t_2 v = λ x : T 1 . t 2 である。
v v v が Nat \text{Nat} Nat 型の値ならば、 v v v は抽象構文にしたがった数値である。
概要:ある値にある型が付いているとき、型の形から値の形をいえる補題。
証明:
抽象構文の定義によれば、値である v v v は
λ x : T 1 . t λx:T_1. t λ x : T 1 . t
0 0 0
succ nv \text{succ} ~ \text{nv} succ nv
のいずれかの形。
補題のそれぞれの節について、 v v v をこれら3つのパターンに分けて検証すれば十分である。
1について、
v v v が λ x : T 1 . t λx:T_1. t λ x : T 1 . t 型の場合、逆転補題2より T 1 → R 2 T_1 \rightarrow R_2 T 1 → R 2 型が付く。そのため前提を満たし、結論も満たす。
v v v が 0 0 0 の場合、逆転補題4より関数型が付かないため前提を満たさない。
v v v が succ nv \text{succ} ~ \text{nv} succ nv の場合、逆転補題5より関数型が付かないため前提を満たさない。
2について、
v v v が λ x : T 1 . t λx:T_1. t λ x : T 1 . t 型の場合、逆転補題2より Nat \text{Nat} Nat 型が付かないため前提を満たさない。
v v v が 0 0 0 の場合、逆転補題4より Nat \text{Nat} Nat 型が付くため前提を満たす。抽象構文の定義によれば0は数値であるため、結論も満たす。
v v v が succ nv \text{succ} ~ \text{nv} succ nv の場合、逆転補題5より Nat \text{Nat} Nat 型が付くため前提を満たす。抽象構文の定義によれば succ nv \text{succ} ~ \text{nv} succ nv は数値であるため、結論も満たす。
で、これらを使って進行を示します。
定理:進行
⊢ t : T \vdash t : T ⊢ t : T ならば t t t は値であるか、ある t ′ t' t ′ が存在して t ⟶ t ′ t \longrightarrow t' t ⟶ t ′ である。
概要:空の文脈で型が付いた項は値であるか、別の形に評価できる。
証明:
⊢ t : T \vdash t : T ⊢ t : T の導出に関する構造的帰納法によって示す。
構造的帰納法のしくみ
ここでは、すべての型付け規則について、(必要であれば)前提(線の上)が所望の性質を満たすと仮定して、結論(線の下)もまた性質を満たすことを示します。
これでなぜ証明になるのかというと、例えば ⊢ t : T \vdash t : T ⊢ t : T に対応する導出木が以下のような形であるとします。
⋮ A (T-Y) ⋮ B (T-Z) ⊢ t : T (T-X) \dfrac
{
\dfrac
{\vdots}
{A}
\quad\text{\small(T-Y)}
\qquad
\dfrac
{\vdots}
{B}
\quad\text{\small(T-Z)}
}
{
\vdash t : T
}
\quad\text{\small(T-X)} ⊢ t : T A ⋮ (T-Y) B ⋮ (T-Z) (T-X)
ここで、導出木の一番下で使われた規則T-Xに着目します。T-Xがどの型付け規則であっても、その前提であるAとBが所望の性質を満たすと仮定すると、 ⊢ t : T \vdash t : T ⊢ t : T でも性質を満たしていると言えて、証明が完了します。さきほど、これをすべての型付け規則について示したからです。
ではAやBが性質を満たすのはどう示すのかというと、同じようにT-YやT-Zについて、それらの前提で性質を仮定すれば示せます。このように、木の葉に向かって性質を示していけます。数学的帰納法の感覚に似ていますね。
というわけで、性質を「 ⊢ t : T \vdash t : T ⊢ t : T ならば t t t は値であるか、ある t ′ t' t ′ が存在して t ⟶ t ′ t \longrightarrow t' t ⟶ t ′ である 」として、それぞれの型付け規則について、前提での性質を仮定し、結論もまた性質を満たすことを示します。
T-Varの場合、
定理とT-Varの結論を以下のように対応付ける(左辺が定理、右辺がT-Varの結論。名前が違う意味で衝突するときは、右辺の名前を優先して変える)
∅ = Γ \varnothing = \Gamma ∅ = Γ
空の文脈でT-Verに型は付けられないため、定理の前提は成立せず、所望の結論は自明に満たされる。
メモ:T-Varの前提は空の文脈では成立しない。導出木の一番下は ⊢ t : T \vdash t : T ⊢ t : T であり、文脈は空である。型付け規則を下から上に読むと、T-Absのみが文脈に束縛を追加する。そのため、導出木でT-Varが使われているとしたら、それはT-Absより上にある。しかしT-Absでは、前提で性質を仮定せず、結論のみで性質を満たせる。したがって、T-Varの場合を示す必要はない。
T-Absの場合、
定理とT-Absの結論を以下のように対応付ける。
t = λ x : T 1 . t 2 t = \lambda x: T_1 . ~ t_2 t = λ x : T 1 . t 2
t t t は値であるため性質を満たす。
T-Appの場合、
定理とT-Appの結論を以下のように対応付ける。
∅ = Γ \varnothing = \Gamma ∅ = Γ
t = t 1 t 2 t = t_1 ~ t_2 t = t 1 t 2
T-Appの前提より、
⊢ t 1 : T 11 → T 12 \vdash t_1 : T_{11} \rightarrow T_{12} ⊢ t 1 : T 11 → T 12
帰納法の仮定より、
t 1 t_1 t 1 は値であるか、ある t 1 ′ t'_1 t 1 ′ が存在して t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′
t 2 t_2 t 2 は値であるか、ある t 2 ′ t'_2 t 2 ′ が存在して t 2 ⟶ t 2 ′ t_2 \longrightarrow t'_2 t 2 ⟶ t 2 ′
t 1 t_1 t 1 が値の場合、
t 2 t_2 t 2 が値の場合、
t 1 t_1 t 1 が T 11 → T 12 T_{11} \rightarrow T_{12} T 11 → T 12 型の値であるため、標準形補題より t 1 = λ x : T 11 . t 12 t_1 = \lambda x : T_{11} . ~ t_{12} t 1 = λ x : T 11 . t 12 である。
E-AppAbsにより t = ( λ x : T 11 . t 12 ) t 2 ⟶ [ x ↦ t 2 ] t 12 = t ′ t = (\lambda x : T_{11} . ~ t_{12}) ~ t_2 \longrightarrow [x \mapsto t_2]t_{12} = t' t = ( λ x : T 11 . t 12 ) t 2 ⟶ [ x ↦ t 2 ] t 12 = t ′ と評価できる。
ある t 2 ′ t'_2 t 2 ′ が存在して t 2 ⟶ t 2 ′ t_2 \longrightarrow t'_2 t 2 ⟶ t 2 ′ である場合、E-App2により t = t 1 t 2 ⟶ t 1 t 2 ′ = t ′ t = t_1 ~ t_2 \longrightarrow t_1 ~ t'_2 = t' t = t 1 t 2 ⟶ t 1 t 2 ′ = t ′ と評価できる。
ある t 1 ′ t'_1 t 1 ′ が存在して t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′ である場合、E-App1により t = t 1 t 2 ⟶ t 1 ′ t 2 = t ′ t = t_1 ~ t_2 \longrightarrow t'_1 ~ t_2 = t' t = t 1 t 2 ⟶ t 1 ′ t 2 = t ′ と評価できる。
T-Zeroの場合、
定理とT-Zeroの結論を以下のように対応付ける。
t t t は値であるため性質を満たす。
T-Succの場合、
定理とT-Succの結論を以下のように対応付ける。
t = succ t 1 t = \text{succ} ~ t_1 t = succ t 1
T-Succの前提より、
⊢ t 1 : Nat \vdash t_1 : \text{Nat} ⊢ t 1 : Nat
帰納法の仮定より、
t 1 t_1 t 1 は値であるか、ある t 1 ′ t'_1 t 1 ′ が存在して t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′
t 1 t_1 t 1 が値の場合、 t 1 t_1 t 1 は Nat \text{Nat} Nat 型の値であるから、標準形補題より t 1 t_1 t 1 は抽象構文にしたがった数値である。抽象構文の定義より t = succ t 1 t = \text{succ} ~ t_1 t = succ t 1 もまた数値であり、数値は値であるから性質を満たす。
ある t 1 ′ t'_1 t 1 ′ が存在して t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′ である場合、E-Succにより t = succ t 1 ⟶ succ t 1 ′ = t ′ t = \text{succ} ~ t_1 \longrightarrow \text{succ} ~ t'_1 = t' t = succ t 1 ⟶ succ t 1 ′ = t ′ と評価できる。
T-Letの場合、
定理とT-Letの結論を以下のように対応付ける。
t = ( let x = t 1 in t 2 ) t = (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) t = ( let x = t 1 in t 2 )
帰納法の仮定より、
t 1 t_1 t 1 は値であるか、ある t 1 ′ t'_1 t 1 ′ が存在して t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′
t 1 t_1 t 1 が値の場合、E-LetVにより t = ( let x = t 1 in t 2 ) ⟶ [ x ↦ t 1 ] t 2 = t ′ t = (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) \longrightarrow [x \mapsto t_1]t_{2} = t' t = ( let x = t 1 in t 2 ) ⟶ [ x ↦ t 1 ] t 2 = t ′ と評価できる。
ある t 1 ′ t'_1 t 1 ′ が存在して t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′ である場合、E-Letにより t = ( let x = t 1 in t 2 ) ⟶ ( let x = t 1 ′ in t 2 ) = t ′ t = (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) \longrightarrow (\text{let} ~ x ~ \text{=} ~ t'_1 ~ \text{in} ~ t_2) = t' t = ( let x = t 1 in t 2 ) ⟶ ( let x = t 1 ′ in t 2 ) = t ′ と評価できる。
よーし。
保存
次に保存定理を示します。これは進行よりも難しいです。
特に代入補題と呼ばれるやつはTAPLで最も重要と言って良い とのことで、この補題を示すためにさらに補題が2つ必要です。
がんばるぞ。
補題:並べ替え
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T かつ、 Δ \Delta Δ が Γ \Gamma Γ の並べ替えならば、 Δ ⊢ t : T \Delta \vdash t : T Δ ⊢ t : T である。さらに、前者と後者の導出の深さ(導出木の高さ)は同じ。
概要:文脈の要素を並べ替えても、その文脈のもとで型付けができる。
証明:
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T の導出に関するごく簡単な構造的帰納法によって示す。
T-Varの場合、
文脈に関する暗黙の仮定より、変数名がそれぞれ異なる文脈を並べ替えたとしても x : T ∈ Δ x : T \in \Delta x : T ∈ Δ が成り立つため、 T-Varより Δ ⊢ x : T \Delta \vdash x : T Δ ⊢ x : T もまた成り立つ。
並び替え前後で導出の深さは変化していない。
T-Absの場合、
帰納法の仮定より、 Δ , x : T 1 ⊢ t 2 : T 2 \Delta , x : T_1 \vdash t_2 : T_2 Δ , x : T 1 ⊢ t 2 : T 2 であるため、T-Absより Δ ⊢ λ x : T 1 . t 2 : T 1 → T 2 \Delta \vdash \lambda x: T_1 . ~ t_2 : T_1 \rightarrow T_2 Δ ⊢ λ x : T 1 . t 2 : T 1 → T 2 が成り立ち、これは所望の結論である。
以降、同様の形式の議論について「帰納法の仮定とT-Xから、所望の結論が成り立つ」と表現する。
並び替え前後で導出の深さは変化していない。
T-Appの場合、
帰納法の仮定とT-Appから、所望の結論が成り立つ
並び替え前後で導出の深さは変化していない。
T-Zeroの場合、
前提がないため、T-Zeroにより即座に Δ ⊢ 0 : Nat \Delta \vdash 0 : \text{Nat} Δ ⊢ 0 : Nat が成り立つ。
並び替え前後で導出の深さは変化していない。
T-Succの場合、
帰納法の仮定とT-Succから、所望の結論が成り立つ
並び替え前後で導出の深さは変化していない。
T-Letの場合、
帰納法の仮定とT-Letから、所望の結論が成り立つ
並び替え前後で導出の深さは変化していない。
補題:弱化
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T かつ、 x ∉ d o m ( Γ ) x \notin dom(\Gamma) x ∈ / d o m ( Γ ) ならば、 Γ , x : S ⊢ t : T \Gamma , x : S \vdash t : T Γ , x : S ⊢ t : T である。さらに、前者と後者で導出の深さ(導出木の高さ)は同じ。
概要:文脈に現れない変数の束縛を追加しても、その文脈のもとで型付けができる。
証明:
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T の導出に関するごく簡単な構造的帰納法によって示す。
T-Varの場合、
x ′ ∉ d o m ( Γ ) x' \notin dom(\Gamma) x ′ ∈ / d o m ( Γ ) である x ′ : S x' : S x ′ : S を Γ \Gamma Γ に追加したとしても、 x : T ∈ Γ , x ′ : S x : T \in \Gamma , x' : S x : T ∈ Γ , x ′ : S であることは変わらないため、 T-Varより Γ , x ′ : S ⊢ x : T \Gamma , x' : S \vdash x : T Γ , x ′ : S ⊢ x : T が成り立つ。
束縛の追加前後で導出の深さは変化していない。
T-Absの場合、
帰納法の仮定より、x ′ ∉ d o m ( Γ ) x' \notin dom(\Gamma) x ′ ∈ / d o m ( Γ ) である x ′ : S x' : S x ′ : S について、 Γ , x : T 1 , x ′ : S ⊢ t 2 : T 2 \Gamma , x : T_1 , x' : S \vdash t_2 : T_2 Γ , x : T 1 , x ′ : S ⊢ t 2 : T 2 である。T-Absより、 Γ , x ′ : S ⊢ λ x : T 1 . t 2 : T 1 → T 2 \Gamma , x' : S \vdash \lambda x: T_1 . ~ t_2 : T_1 \rightarrow T_2 Γ , x ′ : S ⊢ λ x : T 1 . t 2 : T 1 → T 2 が成り立ち、これは所望の結論である。
以降、同様の議論について「帰納法の仮定とT-Xから、所望の結論が成り立つ」と表現する。
束縛の追加前後で導出の深さは変化していない。
T-Appの場合、
帰納法の仮定とT-Appから、所望の結論が成り立つ。
束縛の追加前後で導出の深さは変化していない。
T-Zeroの場合、
前提がないため、 x ′ ∉ d o m ( Γ ) x' \notin dom(\Gamma) x ′ ∈ / d o m ( Γ ) である x ′ : S x' : S x ′ : S について、T-Zeroにより即座に Γ , x ′ : S ⊢ 0 : Nat \Gamma , x' : S \vdash 0 : \text{Nat} Γ , x ′ : S ⊢ 0 : Nat が成り立つ。
束縛の追加前後で導出の深さは変化していない。
T-Succの場合、
帰納法の仮定とT-Succから、所望の結論が成り立つ。
束縛の追加前後で導出の深さは変化していない。
T-Letの場合、
帰納法の仮定とT-Letから、所望の結論が成り立つ。
束縛の追加前後で導出の深さは変化していない。
これらを使って代入を示します。
補題:代入
Γ , x : S ⊢ t : T \Gamma , x : S \vdash t : T Γ , x : S ⊢ t : T かつ、 Γ ⊢ s : S \Gamma \vdash s : S Γ ⊢ s : S ならば、 Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T である。
概要:型付けされた項 t t t について、文脈中の任意の束縛 x : S x : S x : S を取り出して、その束縛なしに S S S 型が付く項 s s s があるなら、[ x ↦ s ] t [x \mapsto s]t [ x ↦ s ] t にも型が付く。
証明:
Γ , x : S ⊢ t : T \Gamma , x : S \vdash t : T Γ , x : S ⊢ t : T の導出に関する構造的帰納法によって示す。
T-Varの場合、
補題とT-Varの結論を以下のように対応付ける。
補題の1つ目の前提より
Γ , x : S ⊢ t : T \Gamma , x : S \vdash t : T Γ , x : S ⊢ t : T
Γ , x : S ⊢ y : T \Gamma , x : S \vdash y : T Γ , x : S ⊢ y : T
逆転補題1によって、
y : T ∈ Γ , x : S y : T \in \Gamma , x : S y : T ∈ Γ , x : S
補題のもう1つの前提より
Γ ⊢ s : S \Gamma \vdash s : S Γ ⊢ s : S
所望の結論は、 Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T である。代入の定義より、 x = y x = y x = y と x ≠ y x \ne y x = y の場合を検証すれば十分である。
x = y x = y x = y の場合、
y : T ∈ Γ , x : S y : T \in \Gamma , x : S y : T ∈ Γ , x : S から T = S T = S T = S である。
所望の結論は
Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T
Γ ⊢ [ x ↦ s ] y : T \Gamma \vdash [x \mapsto s]y : T Γ ⊢ [ x ↦ s ] y : T
Γ ⊢ s : T \Gamma \vdash s : T Γ ⊢ s : T
Γ ⊢ s : S \Gamma \vdash s : S Γ ⊢ s : S
であり、これは補題の前提に含まれるため所望の性質を満たす。
x ≠ y x \ne y x = y の場合、
y : T ∈ Γ , x : S y : T \in \Gamma , x : S y : T ∈ Γ , x : S について、 x : S x : S x : S は y y y と無関係の束縛のため、 y : T ∈ Γ y : T \in \Gamma y : T ∈ Γ である。
所望の結論は
Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T
Γ ⊢ [ x ↦ s ] y : T \Gamma \vdash [x \mapsto s]y : T Γ ⊢ [ x ↦ s ] y : T
Γ ⊢ y : T \Gamma \vdash y : T Γ ⊢ y : T
であり、これは y : T ∈ Γ y : T \in \Gamma y : T ∈ Γ と T-Varより成り立つ。
T-Absの場合、
補題とT-Absの結論を以下のように対応付ける。
Γ , x : S = Δ \Gamma , x : S = \Delta Γ , x : S = Δ
t = λ y : T 1 . t 2 t = \lambda y: T_1 . ~ t_2 t = λ y : T 1 . t 2
ただし、 y ≠ x y \ne x y = x かつ y ∉ F V ( s ) y \notin FV(s) y ∈ / F V ( s ) かつ y ∉ d o m ( Γ ) y \notin dom(\Gamma) y ∈ / d o m ( Γ ) を仮定する (仮定1)
フレッシュな変数を選び、もとのラムダ抽象をα-変換することでこの仮定はいつでも満たせる。
T = T 1 → T 2 T = T_1 \rightarrow T_2 T = T 1 → T 2
T-Absの前提は
Δ , y : T 1 ⊢ t s : T 2 \Delta , y : T_1 \vdash t_s : T_2 Δ , y : T 1 ⊢ t s : T 2
Γ , x : S , y : T 1 ⊢ t 2 : T 2 \Gamma , x : S , y : T_1 \vdash t_2 : T_2 Γ , x : S , y : T 1 ⊢ t 2 : T 2
並び替え補題より
Γ , y : T 1 , x : S ⊢ t 2 : T 2 \Gamma , y : T_1 , x : S \vdash t_2 : T_2 Γ , y : T 1 , x : S ⊢ t 2 : T 2 (1)
補題の前提より、
Γ ⊢ s : S \Gamma \vdash s : S Γ ⊢ s : S
弱化補題と仮定1より
Γ , y : T 1 ⊢ s : S \Gamma , y : T_1 \vdash s : S Γ , y : T 1 ⊢ s : S (2)
帰納法の仮定より、1と2に補題を適用して
Γ , y : T 1 ⊢ [ x ↦ s ] t 2 : T 2 \Gamma , y : T_1 \vdash [x \mapsto s]t_2 : T_2 Γ , y : T 1 ⊢ [ x ↦ s ] t 2 : T 2
T-Absより
Γ ⊢ λ y : T 1 . [ x ↦ s ] t 2 : T 1 → T 2 \Gamma \vdash \lambda y : T_1 . ~ [x \mapsto s]t_2 : T_1 \rightarrow T_2 Γ ⊢ λ y : T 1 . [ x ↦ s ] t 2 : T 1 → T 2
Γ ⊢ λ y : T 1 . [ x ↦ s ] t 2 : T \Gamma \vdash \lambda y : T_1 . ~ [x \mapsto s]t_2 : T Γ ⊢ λ y : T 1 . [ x ↦ s ] t 2 : T (3)
所望の結論は
Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T
Γ ⊢ [ x ↦ s ] ( λ y : T 1 . t 2 ) : T \Gamma \vdash [x \mapsto s](\lambda y: T_1 . ~ t_2) : T Γ ⊢ [ x ↦ s ] ( λ y : T 1 . t 2 ) : T
代入の定義と仮定1より
Γ ⊢ λ y : T 1 . [ x ↦ s ] t 2 : T \Gamma \vdash \lambda y : T_1 . ~ [x \mapsto s]t_2 : T Γ ⊢ λ y : T 1 . [ x ↦ s ] t 2 : T (3)
3は型付けの前提、補題の前提および帰納法の仮定のみから得られるため、所望の結論は満たされる。
T-Appの場合、
補題とT-Appの結論を以下のように対応付ける。
Γ , x : S = Δ \Gamma , x : S = \Delta Γ , x : S = Δ
t = t 1 t 2 t = t_1 ~ t_2 t = t 1 t 2
T = T 12 T = T_{12} T = T 12
T-Appの前提は
Γ , x : S ⊢ t 1 : T 11 → T 12 \Gamma , x : S \vdash t_1 : T_{11} \rightarrow T_{12} Γ , x : S ⊢ t 1 : T 11 → T 12 (1)
Γ , x : S ⊢ t 2 : T 11 \Gamma , x : S \vdash t_2 : T_{11} Γ , x : S ⊢ t 2 : T 11 (2)
補題の前提より
Γ ⊢ s : S \Gamma \vdash s : S Γ ⊢ s : S (3)
帰納法の仮定より、補題を1と3に適用して
Γ ⊢ [ x ↦ s ] t 1 : T 11 → T 12 \Gamma \vdash [x \mapsto s]t_1 : T_{11} \rightarrow T_{12} Γ ⊢ [ x ↦ s ] t 1 : T 11 → T 12 (4)
帰納法の仮定より、補題を2と3に適用して
Γ ⊢ [ x ↦ s ] t 2 : T 11 \Gamma \vdash [x \mapsto s]t_2 : T_{11} Γ ⊢ [ x ↦ s ] t 2 : T 11 (5)
4、5とT-Appより
Γ ⊢ [ x ↦ s ] t 1 [ x ↦ s ] t 2 : T 12 \Gamma \vdash [x \mapsto s]t_1 ~ [x \mapsto s]t_2 : T_{12} Γ ⊢ [ x ↦ s ] t 1 [ x ↦ s ] t 2 : T 12
Γ ⊢ [ x ↦ s ] t 1 [ x ↦ s ] t 2 : T \Gamma \vdash [x \mapsto s]t_1 ~ [x \mapsto s]t_2 : T Γ ⊢ [ x ↦ s ] t 1 [ x ↦ s ] t 2 : T
Γ ⊢ [ x ↦ s ] ( t 1 t 2 ) : T \Gamma \vdash [x \mapsto s](t_1 ~ t_2) : T Γ ⊢ [ x ↦ s ] ( t 1 t 2 ) : T
Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T
となるため、所望の結論が成り立つ。
T-Zeroの場合、
補題とT-Zeroの結論を以下のように対応付ける。
Γ , x : S = Δ \Gamma , x : S = \Delta Γ , x : S = Δ
t = 0 t = 0 t = 0
T = Nat T = \text{Nat} T = Nat
所望の結論は
Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T
Γ ⊢ [ x ↦ s ] 0 : Nat \Gamma \vdash [x \mapsto s]0 : \text{Nat} Γ ⊢ [ x ↦ s ] 0 : Nat
Γ ⊢ 0 : Nat \Gamma \vdash 0 : \text{Nat} Γ ⊢ 0 : Nat
となり、T-Zeroより即座に成り立つ。
T-Succの場合、
補題とT-Succの結論を以下のように対応付ける。
Γ , x : S = Δ \Gamma , x : S = \Delta Γ , x : S = Δ
t = succ t 1 t = \text{succ} ~ t_1 t = succ t 1
T = Nat T = \text{Nat} T = Nat
T-Succの前提は
Δ ⊢ t 1 : Nat \Delta \vdash t_1 : \text{Nat} Δ ⊢ t 1 : Nat
Γ , x : S ⊢ t 1 : Nat \Gamma , x : S \vdash t_1 : \text{Nat} Γ , x : S ⊢ t 1 : Nat (1)
補題の前提より
Γ ⊢ s : S \Gamma \vdash s : S Γ ⊢ s : S (2)
帰納法の仮定より、1と2に補題を適用して
Γ ⊢ [ x ↦ S ] t 1 : Nat \Gamma \vdash [x \mapsto S]t_1 : \text{Nat} Γ ⊢ [ x ↦ S ] t 1 : Nat
T-Succより
Γ ⊢ succ [ x ↦ S ] t 1 : Nat \Gamma \vdash \text{succ} ~ [x \mapsto S]t_1 : \text{Nat} Γ ⊢ succ [ x ↦ S ] t 1 : Nat
Γ ⊢ [ x ↦ S ] ( succ t 1 ) : Nat \Gamma \vdash [x \mapsto S](\text{succ} ~ t_1) : \text{Nat} Γ ⊢ [ x ↦ S ] ( succ t 1 ) : Nat
Γ ⊢ [ x ↦ S ] t : Nat \Gamma \vdash [x \mapsto S]t : \text{Nat} Γ ⊢ [ x ↦ S ] t : Nat
Γ ⊢ [ x ↦ S ] t : T \Gamma \vdash [x \mapsto S]t : T Γ ⊢ [ x ↦ S ] t : T
となるため、所望の結論が成り立つ。
T-Letの場合、
補題とT-Letの結論を以下のように対応付ける。
Γ , x : S = Δ \Gamma , x : S = \Delta Γ , x : S = Δ
t = ( let y = t 1 in t 2 : T 2 ) t = (\text{let} ~ y ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 : T_2) t = ( let y = t 1 in t 2 : T 2 )
ただし、 y ≠ x y \ne x y = x かつ y ∉ F V ( s ) y \notin FV(s) y ∈ / F V ( s ) かつ y ∉ d o m ( Γ ) y \notin dom(\Gamma) y ∈ / d o m ( Γ ) を仮定する (仮定1)
フレッシュな変数を選び、 t 2 t_2 t 2 内のもとの変数を置き換えることでこの仮定はいつでも満たせる。
T = T 2 T = T_2 T = T 2
T-Letの前提は
Γ , x : S ⊢ t 1 : T 1 \Gamma , x : S \vdash t_1 : T_1 Γ , x : S ⊢ t 1 : T 1 (1)
Γ , x : S , y : T 1 ⊢ t 2 : T 2 \Gamma , x : S , y : T_1 \vdash t_2 : T_2 Γ , x : S , y : T 1 ⊢ t 2 : T 2 (2)
補題の前提より
Γ ⊢ s : S \Gamma \vdash s : S Γ ⊢ s : S (3)
弱化補題と仮定1より
Γ , y : T 1 ⊢ s : S \Gamma , y : T_1 \vdash s : S Γ , y : T 1 ⊢ s : S (4)
帰納法の仮定より、1と3に補題を適用して
Γ ⊢ [ x ↦ s ] t 1 : T 1 \Gamma \vdash [x \mapsto s]t_1 : T_1 Γ ⊢ [ x ↦ s ] t 1 : T 1 (5)
2に並べ替え補題を適用して
Γ , y : T 1 , x : S ⊢ t 2 : T 2 \Gamma , y : T_1 , x : S \vdash t_2 : T_2 Γ , y : T 1 , x : S ⊢ t 2 : T 2
帰納法の仮定より、4と補題を適用して
Γ , y : T 1 ⊢ [ x ↦ s ] t 2 : T 2 \Gamma , y : T_1 \vdash [x \mapsto s]t_2 : T_2 Γ , y : T 1 ⊢ [ x ↦ s ] t 2 : T 2 (6)
5、6、T-Letより
Γ ⊢ let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 : T 2 \Gamma \vdash \text{let} ~ y ~ \text{=} ~ [x \mapsto s]t_1 ~ \text{in} ~ [x \mapsto s]t_2 : T_2 Γ ⊢ let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 : T 2
Γ ⊢ let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 : T \Gamma \vdash \text{let} ~ y ~ \text{=} ~ [x \mapsto s]t_1 ~ \text{in} ~ [x \mapsto s]t_2 : T Γ ⊢ let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 : T (7)
所望の結論は
Γ ⊢ [ x ↦ s ] t : T \Gamma \vdash [x \mapsto s]t : T Γ ⊢ [ x ↦ s ] t : T
Γ ⊢ [ x ↦ s ] ( let y = t 1 in t 2 : T 2 ) : T \Gamma \vdash [x \mapsto s](\text{let} ~ y ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 : T_2) : T Γ ⊢ [ x ↦ s ] ( let y = t 1 in t 2 : T 2 ) : T
代入の定義と仮定1より
Γ ⊢ let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 : T 2 : T \Gamma \vdash \text{let} ~ y ~ \text{=} ~ [x \mapsto s]t_1 ~ \text{in} ~ [x \mapsto s]t_2 : T_2 : T Γ ⊢ let y = [ x ↦ s ] t 1 in [ x ↦ s ] t 2 : T 2 : T (7)
7は型付けの前提、補題の前提および帰納法の仮定のみから得られるため、所望の結論は満たされる。
で、代入を使って保存を示します。
定理:保存
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T かつ t ⟶ t ′ t \longrightarrow t' t ⟶ t ′ ならば Γ ⊢ t ′ : T \Gamma \vdash t' : T Γ ⊢ t ′ : T
概要:項を評価しても同じ型が付く。
証明:
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T の導出に関する構造的帰納法によって示す。
T-Varの場合、
定理とT-Varの結論を以下のように対応付ける。
t t t は変数であり、変数は評価できないため定理の前提を満たさない。したがって所望の結論は自明に満たされる。
T-Absの場合、
定理とT-Absの結論を以下のように対応付ける。
t = λ x : T 1 . t 2 t = \lambda x: T_1 . ~ t_2 t = λ x : T 1 . t 2
t t t はラムダ抽象であり、ラムダ抽象は評価できないため定理の前提を満たさない。したがって所望の結論は自明に満たされる。
T-Appの場合、
定理とT-Appの結論を以下のように対応付ける。
t = t 1 t 2 t = t_1 ~ t_2 t = t 1 t 2
T = T 12 T = T_{12} T = T 12
T-Appの前提より
Γ ⊢ t 1 : T 11 → T 12 \Gamma \vdash t_1 : T_{11} \rightarrow T_{12} Γ ⊢ t 1 : T 11 → T 12 (1)
Γ ⊢ t 2 : T 11 \Gamma \vdash t_2 : T_{11} Γ ⊢ t 2 : T 11 (2)
帰納法の仮定と1、2より
t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′
Γ ⊢ t 1 ′ : T 11 → T 12 \Gamma \vdash t'_1 : T_{11} \rightarrow T_{12} Γ ⊢ t 1 ′ : T 11 → T 12 (3)
t 2 ⟶ t 2 ′ t_2 \longrightarrow t'_2 t 2 ⟶ t 2 ′
Γ ⊢ t 2 ′ : T 11 \Gamma \vdash t'_2 : T_{11} Γ ⊢ t 2 ′ : T 11 (4)
定理の前提より
t ⟶ t ′ t \longrightarrow t' t ⟶ t ′ (5)
t t t に適用されうる評価規則はE-App1、E-App2、E-AppAbsであるため、それぞれのケースを検証すれば十分である。
E-App1の場合、
5とE-App1の結論を対応付けると
t ′ = t 1 ′ t 2 t' = t'_1 ~ t_2 t ′ = t 1 ′ t 2
3と2、T-Appより
Γ ⊢ t 1 ′ t 2 : T 12 \Gamma \vdash t'_1 ~ t_2 : T_{12} Γ ⊢ t 1 ′ t 2 : T 12
Γ ⊢ t 1 ′ t 2 : T \Gamma \vdash t'_1 ~ t_2 : T Γ ⊢ t 1 ′ t 2 : T
Γ ⊢ t ′ : T \Gamma \vdash t' : T Γ ⊢ t ′ : T
となるため、所望の結論を満たす。
E-App2の場合、
5とE-App2の結論を対応付けると
t ′ = t 1 t 2 ′ t' = t_1 ~ t'_2 t ′ = t 1 t 2 ′
1と4、T-Appより
Γ ⊢ t 1 t 2 ′ : T 12 \Gamma \vdash t_1 ~ t'_2 : T_{12} Γ ⊢ t 1 t 2 ′ : T 12
Γ ⊢ t 1 t 2 ′ : T \Gamma \vdash t_1 ~ t'_2 : T Γ ⊢ t 1 t 2 ′ : T
Γ ⊢ t ′ : T \Gamma \vdash t' : T Γ ⊢ t ′ : T
となるため、所望の結論を満たす。
E-AppAbsの場合、
5とE-AppApsの結論を対応付けると
t 1 = λ x : T 11 . t 12 t_1 = \lambda x : T_{11} . ~ t_{12} t 1 = λ x : T 11 . t 12 (6)
t ′ = [ x ↦ t 2 ] t 12 t' = [x \mapsto t_2]t_{12} t ′ = [ x ↦ t 2 ] t 12
1より
Γ ⊢ t 1 : T 11 → T 12 \Gamma \vdash t_1 : T_{11} \rightarrow T_{12} Γ ⊢ t 1 : T 11 → T 12
6より
Γ ⊢ λ x : T 11 . t 12 : T 11 → T 12 \Gamma \vdash \lambda x : T_{11} . ~ t_{12} : T_{11} \rightarrow T_{12} Γ ⊢ λ x : T 11 . t 12 : T 11 → T 12
逆転補題2より
Γ , x : T 11 ⊢ t 12 : T 12 \Gamma , x : T_{11} \vdash t_{12} : T_{12} Γ , x : T 11 ⊢ t 12 : T 12
2と代入補題より
Γ ⊢ [ x ↦ t 2 ] t 12 : T 12 \Gamma \vdash [x \mapsto t_2]t_{12} : T_{12} Γ ⊢ [ x ↦ t 2 ] t 12 : T 12
Γ ⊢ t ′ : T 12 \Gamma \vdash t' : T_{12} Γ ⊢ t ′ : T 12
Γ ⊢ t ′ : T \Gamma \vdash t' : T Γ ⊢ t ′ : T
となるため、所望の結論を満たす。
T-Zeroの場合、
定理とT-Zeroの結論を以下のように対応付ける。
t t t は0であり、0は評価できないため定理の前提を満たさない。したがって所望の結論は自明に満たされる。
T-Succの場合、
定理とT-Succの結論を以下のように対応付ける。
t = succ t 1 t = \text{succ} ~ t_1 t = succ t 1
T = Nat T = \text{Nat} T = Nat
T-Succの前提より
Γ ⊢ t 1 : Nat \Gamma \vdash t_1 : \text{Nat} Γ ⊢ t 1 : Nat (1)
帰納法の仮定と1より
t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′
Γ ⊢ t 1 ′ : Nat \Gamma \vdash t'_1 : \text{Nat} Γ ⊢ t 1 ′ : Nat (2)
定理の前提より
t ⟶ t ′ t \longrightarrow t' t ⟶ t ′ (3)
t t t に適用されうる評価規則はE-Succだけであるため、
t ′ = succ t 1 ′ t' = \text{succ} ~ t'_1 t ′ = succ t 1 ′
2とT-Succより
Γ ⊢ succ t 1 ′ : Nat \Gamma \vdash \text{succ} ~ t'_1 : \text{Nat} Γ ⊢ succ t 1 ′ : Nat
Γ ⊢ t ′ : Nat \Gamma \vdash t' : \text{Nat} Γ ⊢ t ′ : Nat
Γ ⊢ t ′ : T \Gamma \vdash t' : T Γ ⊢ t ′ : T
となるため、所望の結論を満たす。
T-Letの場合、
定理とT-Succの結論を以下のように対応付ける。
t = ( let x = t 1 in t 2 ) t = (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) t = ( let x = t 1 in t 2 )
T = T 2 T = T_2 T = T 2
T−Letの前提より
Γ ⊢ t 1 : T 1 \Gamma \vdash t_1 : T_1 Γ ⊢ t 1 : T 1 (1)
Γ , x : T 1 ⊢ t 2 : T 2 \Gamma , x : T_1 \vdash t_2 : T_2 Γ , x : T 1 ⊢ t 2 : T 2 (2)
帰納法の仮定と1、2より
t 1 ⟶ t 1 ′ t_1 \longrightarrow t'_1 t 1 ⟶ t 1 ′
Γ ⊢ t 1 ′ : T 1 \Gamma \vdash t'_1 : T_1 Γ ⊢ t 1 ′ : T 1 (3)
t 2 ⟶ t 2 ′ t_2 \longrightarrow t'_2 t 2 ⟶ t 2 ′
Γ , x : T 1 ⊢ t 2 ′ : T 2 \Gamma , x : T_1 \vdash t'_2 : T_2 Γ , x : T 1 ⊢ t 2 ′ : T 2 (4)
定理の前提より
t ⟶ t ′ t \longrightarrow t' t ⟶ t ′ (5)
t t t に適用されうる評価規則はE-Let、E-LetVであるため、それぞれのケースを検証すれば十分である。
E-Letの場合、
5とE-Letの結論を対応付けると
t ′ = ( let x = t 1 ′ in t 2 ) t' = (\text{let} ~ x ~ \text{=} ~ t'_1 ~ \text{in} ~ t_2) t ′ = ( let x = t 1 ′ in t 2 )
3と2、T-Letより
Γ ⊢ let x = t 1 ′ in t 2 : T 2 \Gamma \vdash \text{let} ~ x ~ \text{=} ~ t'_1 ~ \text{in} ~ t_2 : T_2 Γ ⊢ let x = t 1 ′ in t 2 : T 2
Γ ⊢ t ′ : T 2 \Gamma \vdash t' : T_2 Γ ⊢ t ′ : T 2
Γ ⊢ t ′ : T \Gamma \vdash t' : T Γ ⊢ t ′ : T
となるため、所望の結論を満たす。
E-LetVの場合、
5とE-LetVの結論を対応付けると
t ′ = [ x ↦ t 1 ] t 2 t' = [x \mapsto t_1]t_2 t ′ = [ x ↦ t 1 ] t 2
2より
Γ , x : T 1 ⊢ t 2 : T 2 \Gamma , x : T_1 \vdash t_2 : T_2 Γ , x : T 1 ⊢ t 2 : T 2
1と代入補題より
Γ ⊢ [ x ↦ t 1 ] t 2 : T 2 \Gamma \vdash [x \mapsto t_1]t_2 : T_2 Γ ⊢ [ x ↦ t 1 ] t 2 : T 2
Γ ⊢ t ′ : T 2 \Gamma \vdash t' : T_2 Γ ⊢ t ′ : T 2
Γ ⊢ t ′ : T \Gamma \vdash t' : T Γ ⊢ t ′ : T
となるため、所望の結論を満たす。
うーし。
型安全性
ここまで来れば勝利確定です。進行定理と保存定理により安全性を示します。
定理:安全性
⊢ t : T \vdash t : T ⊢ t : T かつ t ⟶ ∗ t ′ ↛ t \longrightarrow^\ast t' \nrightarrow t ⟶ ∗ t ′ ↛ ならば t ′ t' t ′ は値である。
概要:空の文脈で型が付いた t t t を評価していって停止するなら、それは値である。
証明:
t ⟶ ∗ t ′ t \longrightarrow^\ast t' t ⟶ ∗ t ′ の評価の長さ n n n による数学的帰納法によって示す。
n = 0 n = 0 n = 0 の場合、
定理の1つ目の前提より
これと進行定理より
t t t は値であるか、ある t ′ t' t ′ が存在して t ⟶ t ′ t \longrightarrow t' t ⟶ t ′
しかし、定理のもう1つの前提より
t ⟶ 0 t ′ ↛ t \longrightarrow^0 t' \nrightarrow t ⟶ 0 t ′ ↛
つまり
t ↛ t \nrightarrow t ↛
したがって t t t は値であり、所望の結論を満たす。
任意の n n n について定理を仮定し、 n + 1 n + 1 n + 1 について示す。
定理の前提より
⊢ t : T \vdash t : T ⊢ t : T (1)
t ⟶ n + 1 t ′ ↛ t \longrightarrow^{n + 1} t' \nrightarrow t ⟶ n + 1 t ′ ↛ (2)
t t t の1ステップ評価結果を u u u とおくと
t ⟶ u t \longrightarrow u t ⟶ u (3)
u ⟶ n t ′ ↛ u \longrightarrow^n t' \nrightarrow u ⟶ n t ′ ↛ (4)
保存定理を1と3に適用して
帰納法の仮定より、定理を5と4に適用すると、 t ′ t' t ′ は値であり、所望の結論を満たす。
よっしゃよっしゃよっしゃ
型推論
プログラムにいちいち型を書くのは面倒なので、型推論を実装したいと思います。
型推論は、制約型付けによって制約集合を生成することと、それを単一化アルゴリズムによって解くことで実現できます。
制約型付け
制約型付け規則を定義します。これは先程までの型付け規則に似ていますが、導出の過程で型に関する制約の集合を生成します。
x : T ∈ Γ Γ ⊢ F x : T ∣ F { } (CT-Var) \dfrac
{
x : T \in \Gamma
}
{
\Gamma \vdash_F
x :
T ~
|_F ~
\{\}
}
\quad\text{(CT-Var)} Γ ⊢ F x : T ∣ F { } x : T ∈ Γ (CT-Var)
Γ , x : T 1 ⊢ F t 2 : T 2 ∣ F ′ C Γ ⊢ F λ x : T 1 . t 2 : T 1 → T 2 ∣ F ′ C (CT-Abs) \dfrac
{
\Gamma , x : T_1 \vdash_F
t_2 :
T_2 ~
|_{F'} ~
C
}
{
\Gamma \vdash_F
\lambda x : T_1 . ~ t_2 :
T_1 \rightarrow T_2 ~
|_{F'} ~
C
}
\quad\text{(CT-Abs)} Γ ⊢ F λ x : T 1 . t 2 : T 1 → T 2 ∣ F ′ C Γ , x : T 1 ⊢ F t 2 : T 2 ∣ F ′ C (CT-Abs)
Γ ⊢ F t 1 : T 1 ∣ F ′ C 1 Γ ⊢ F ′ t 2 : T 2 ∣ F ′ ′ C 2 F ′ ′ = X , F ′ ′ ′ Γ ⊢ F t 1 t 2 : X ∣ F ′ ′ ′ C 1 ∪ C 2 ∪ { T 1 = T 2 → X } (CT-App) \dfrac
{
\begin{aligned}
&
\Gamma \vdash_F
t_1 :
T_1 ~
|_{F'} ~
C_1
\\ &
\Gamma \vdash_{F'}
t_2 :
T_2 ~
|_{F''} ~
C_2
\\ &
F'' = X , F'''
\end{aligned}
}
{
\Gamma \vdash_F
t_1 ~ t_2 :
X ~
|_{F'''} ~
C_1 \cup C_2 \cup \{T_1 = T_2 \rightarrow X \}
}
\quad\text{(CT-App)} Γ ⊢ F t 1 t 2 : X ∣ F ′′′ C 1 ∪ C 2 ∪ { T 1 = T 2 → X } Γ ⊢ F t 1 : T 1 ∣ F ′ C 1 Γ ⊢ F ′ t 2 : T 2 ∣ F ′′ C 2 F ′′ = X , F ′′′ (CT-App)
Γ ⊢ F 0 : Nat ∣ F { } (CT-Zero) \Gamma \vdash_F
0 :
\text{Nat} ~
|_F ~
\{\}
\quad\text{(CT-Zero)} Γ ⊢ F 0 : Nat ∣ F { } (CT-Zero)
Γ ⊢ F t 1 : T ∣ F ′ C Γ ⊢ F succ t 1 : Nat ∣ F ′ C ∪ { T = Nat } (CT-Succ) \dfrac
{
\Gamma \vdash_F
t_1 :
T ~
|_{F'} ~
C
}
{
\Gamma \vdash_F
\text{succ} ~ t_1 :
\text{Nat} ~
|_{F'} ~
C \cup \{ T = \text{Nat} \}
}
\quad\text{(CT-Succ)} Γ ⊢ F succ t 1 : Nat ∣ F ′ C ∪ { T = Nat } Γ ⊢ F t 1 : T ∣ F ′ C (CT-Succ)
Γ ⊢ F t 1 : T 1 ∣ F ′ C 1 Γ , x : X ⊢ F ′ t 2 : T 2 ∣ F ′ ′ C 2 F ′ ′ = X , F ′ ′ ′ Γ ⊢ F let x = t 1 in t 2 : T 2 ∣ F ′ ′ ′ C 1 ∪ C 2 ∪ { T 1 = X } (CT-Let) \dfrac
{
\begin{aligned}
&
\Gamma \vdash_F
t_1 :
T_1 ~
|_{F'} ~
C_1
\\ &
\Gamma , x : X \vdash_{F'}
t_2 :
T_2 ~
|_{F''} ~
C_2
\\ &
F'' = X, F'''
\end{aligned}
}
{
\Gamma \vdash_F
\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 :
T_2 ~
|_{F'''} ~
C_1 \cup C_2 \cup \{T_1 = X\}
}
\quad\text{(CT-Let)} Γ ⊢ F let x = t 1 in t 2 : T 2 ∣ F ′′′ C 1 ∪ C 2 ∪ { T 1 = X } Γ ⊢ F t 1 : T 1 ∣ F ′ C 1 Γ , x : X ⊢ F ′ t 2 : T 2 ∣ F ′′ C 2 F ′′ = X , F ′′′ (CT-Let)
以降は、これらの制約型付けが、通常の型付けと対応することを示していきます。
定義:( Γ , t ) (\Gamma, t) ( Γ , t ) の解とは、σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T を満たす ( σ , T ) (\sigma, T) ( σ , T ) である。
定義:( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解とは、Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C であり、σ \sigma σ が C C C を単一化し、σ S = T \sigma S = T σ S = T となる ( σ , T ) (\sigma, T) ( σ , T ) である。
定理:型代入の下での型付けの保存
任意の型代入 σ \sigma σ について、Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T ならば σ Γ ⊢ σ t : σ T \sigma \Gamma \vdash \sigma t : \sigma T σ Γ ⊢ σ t : σ T である。
概要:型代入を適用しても型付けは保存される
証明:
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T の導出に関する構造的帰納法による。
T-Varの場合、
定理とT-Varの結論を以下のように対応付ける。
定理の前提より
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T
1より
Γ ⊢ x : T \Gamma \vdash x : T Γ ⊢ x : T
逆転補題1より
x : T ∈ Γ x : T \in \Gamma x : T ∈ Γ
文脈に対する型代入の定義より
x : σ T ∈ σ Γ x : \sigma T \in \sigma \Gamma x : σ T ∈ σ Γ
T-Varより
σ Γ ⊢ x : σ T \sigma \Gamma \vdash x : \sigma T σ Γ ⊢ x : σ T
変数に対する型代入の定義より
σ Γ ⊢ σ x : σ T \sigma \Gamma \vdash \sigma x : \sigma T σ Γ ⊢ σ x : σ T
1より
σ Γ ⊢ σ t : σ T \sigma \Gamma \vdash \sigma t : \sigma T σ Γ ⊢ σ t : σ T
したがって、所望の性質を満たす。
T-Absの場合、
定理とT-Absの結論を以下のように対応付ける。
t = λ x : T 1 . t 2 t = \lambda x : T_1 . ~ t_2 t = λ x : T 1 . t 2 (1)
T = T 1 → T 2 T = T_1 \rightarrow T_2 T = T 1 → T 2 (2)
定理の前提より
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T
1と2より
Γ ⊢ λ x : T 1 . t 2 : T 1 → T 2 \Gamma \vdash \lambda x : T_1 . ~ t_2 : T_1 \rightarrow T_2 Γ ⊢ λ x : T 1 . t 2 : T 1 → T 2
逆転補題2より
Γ , x : T 1 ⊢ t 2 : T 2 \Gamma , x : T_1 \vdash t_2 : T_2 Γ , x : T 1 ⊢ t 2 : T 2
帰納法の仮定より
σ ( Γ , x : T 1 ) ⊢ σ t 2 : σ T 2 \sigma (\Gamma , x : T_1) \vdash \sigma t_2 : \sigma T_2 σ ( Γ , x : T 1 ) ⊢ σ t 2 : σ T 2
σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2 \sigma \Gamma , x : \sigma T_1 \vdash \sigma t_2 : \sigma T_2 σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2
T-Absより
σ Γ ⊢ λ x : σ T 1 . σ t 2 : σ T 1 → σ T 2 \sigma \Gamma \vdash \lambda x : \sigma T_1 . ~ \sigma t_2 : \sigma T_1 \rightarrow \sigma T_2 σ Γ ⊢ λ x : σ T 1 . σ t 2 : σ T 1 → σ T 2
σ Γ ⊢ σ ( λ x : T 1 . t 2 ) : σ T 1 → σ T 2 \sigma \Gamma \vdash \sigma (\lambda x : T_1 . ~ t_2) : \sigma T_1 \rightarrow \sigma T_2 σ Γ ⊢ σ ( λ x : T 1 . t 2 ) : σ T 1 → σ T 2
2より
σ Γ ⊢ σ t : σ T 1 → σ T 2 \sigma \Gamma \vdash \sigma t : \sigma T_1 \rightarrow \sigma T_2 σ Γ ⊢ σ t : σ T 1 → σ T 2
σ Γ ⊢ σ t : σ ( T 1 → T 2 ) \sigma \Gamma \vdash \sigma t : \sigma (T_1 \rightarrow T_2) σ Γ ⊢ σ t : σ ( T 1 → T 2 )
1より
σ Γ ⊢ σ t : σ T \sigma \Gamma \vdash \sigma t : \sigma T σ Γ ⊢ σ t : σ T
したがって、所望の性質を満たす。
T-Appの場合、
定理とT-Appの結論を以下のように対応付ける。
t = t 1 t 2 t = t_1 ~ t_2 t = t 1 t 2 (1)
T = T 12 T = T_{12} T = T 12 (2)
定理の前提より
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T
1と2より
Γ ⊢ t 1 t 2 : T 12 \Gamma \vdash t_1 ~ t_2 : T_{12} Γ ⊢ t 1 t 2 : T 12 (3)
3と逆転補題3より
Γ ⊢ t 1 : T 11 → T 12 \Gamma \vdash t_1 : T_{11} \rightarrow T_{12} Γ ⊢ t 1 : T 11 → T 12
帰納法の仮定より
σ Γ ⊢ σ t 1 : σ ( T 11 → T 12 ) \sigma \Gamma \vdash \sigma t_1 : \sigma (T_{11} \rightarrow T_{12}) σ Γ ⊢ σ t 1 : σ ( T 11 → T 12 )
σ Γ ⊢ σ t 1 : σ T 11 → σ T 12 \sigma \Gamma \vdash \sigma t_1 : \sigma T_{11} \rightarrow \sigma T_{12} σ Γ ⊢ σ t 1 : σ T 11 → σ T 12 (4)
3と逆転補題3より
Γ ⊢ t 2 : T 11 \Gamma \vdash t_2 : T_{11} Γ ⊢ t 2 : T 11
帰納法の仮定より
σ Γ ⊢ σ t 2 : σ T 11 \sigma \Gamma \vdash \sigma t_2 : \sigma T_{11} σ Γ ⊢ σ t 2 : σ T 11 (5)
4、5とT-Appより
σ Γ ⊢ σ t 1 σ t 2 : σ T 12 \sigma \Gamma \vdash \sigma t_1 ~ \sigma t_2 : \sigma T_{12} σ Γ ⊢ σ t 1 σ t 2 : σ T 12
σ Γ ⊢ σ ( t 1 t 2 ) : σ T 12 \sigma \Gamma \vdash \sigma (t_1 ~ t_2) : \sigma T_{12} σ Γ ⊢ σ ( t 1 t 2 ) : σ T 12
1より
σ Γ ⊢ σ t : σ T 12 \sigma \Gamma \vdash \sigma t : \sigma T_{12} σ Γ ⊢ σ t : σ T 12
2より
σ Γ ⊢ σ t : σ T \sigma \Gamma \vdash \sigma t : \sigma T σ Γ ⊢ σ t : σ T
したがって、所望の性質を満たす。
T-Zeroの場合、
定理とT-Appの結論を以下のように対応付ける。
t = 0 t = 0 t = 0 (1)
T = Nat T = \text{Nat} T = Nat (2)
T-Zeroより
σ Γ ⊢ 0 : Nat \sigma \Gamma \vdash 0 : \text{Nat} σ Γ ⊢ 0 : Nat
0 0 0 に対する型代入の定義より
σ Γ ⊢ σ 0 : Nat \sigma \Gamma \vdash \sigma 0 : \text{Nat} σ Γ ⊢ σ 0 : Nat
Nat \text{Nat} Nat に対する型代入の定義より
σ Γ ⊢ σ 0 : σ Nat \sigma \Gamma \vdash \sigma 0 : \sigma \text{Nat} σ Γ ⊢ σ 0 : σ Nat
1と2より
σ Γ ⊢ σ t : σ T \sigma \Gamma \vdash \sigma t : \sigma T σ Γ ⊢ σ t : σ T
したがって、所望の性質を満たす。
T-Succの場合、
定理とT-Succの結論を以下のように対応付ける。
t = succ t 1 t = \text{succ} ~ t_1 t = succ t 1 (1)
T = Nat T = \text{Nat} T = Nat (2)
定理の前提より
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T
1と2より
Γ ⊢ succ t 1 : Nat \Gamma \vdash \text{succ} ~ t_1 : \text{Nat} Γ ⊢ succ t 1 : Nat
逆転補題5より
Γ ⊢ t 1 : Nat \Gamma \vdash t_1 : \text{Nat} Γ ⊢ t 1 : Nat
帰納法の仮定より
σ Γ ⊢ σ t 1 : σ Nat \sigma \Gamma \vdash \sigma t_1 : \sigma \text{Nat} σ Γ ⊢ σ t 1 : σ Nat
T-Succより
σ Γ ⊢ succ ( σ t 1 ) : σ Nat \sigma \Gamma \vdash \text{succ} ~ (\sigma t_1) : \sigma \text{Nat} σ Γ ⊢ succ ( σ t 1 ) : σ Nat
σ Γ ⊢ σ ( succ t 1 ) : σ Nat \sigma \Gamma \vdash \sigma (\text{succ} ~ t_1) : \sigma \text{Nat} σ Γ ⊢ σ ( succ t 1 ) : σ Nat
1より
σ Γ ⊢ σ t : σ Nat \sigma \Gamma \vdash \sigma t : \sigma \text{Nat} σ Γ ⊢ σ t : σ Nat
2より
σ Γ ⊢ σ t : σ T \sigma \Gamma \vdash \sigma t : \sigma T σ Γ ⊢ σ t : σ T
したがって、所望の性質を満たす。
T-Letの場合、
定理とT-Letの結論を以下のように対応付ける。
t = ( let x = t 1 in t 2 ) t = (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) t = ( let x = t 1 in t 2 ) (1)
T = T 2 T = T_2 T = T 2 (2)
定理の前提より
Γ ⊢ t : T \Gamma \vdash t : T Γ ⊢ t : T
1と2より
Γ ⊢ let x = t 1 in t 2 : T 2 \Gamma \vdash \text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 : T_2 Γ ⊢ let x = t 1 in t 2 : T 2 (3)
3と逆転補題6より
Γ ⊢ t 1 : T 1 \Gamma \vdash t_1 : T_1 Γ ⊢ t 1 : T 1
帰納法の仮定より
σ Γ ⊢ σ t 1 : σ T 1 \sigma \Gamma \vdash \sigma t_1 : \sigma T_1 σ Γ ⊢ σ t 1 : σ T 1 (4)
3と逆転補題6より
Γ , x : T 1 ⊢ t 2 : T 2 \Gamma , x : T_1 \vdash t_2 : T_2 Γ , x : T 1 ⊢ t 2 : T 2
帰納法の仮定より
σ ( Γ , x : T 1 ) ⊢ σ t 2 : σ T 2 \sigma (\Gamma , x : T_1) \vdash \sigma t_2 : \sigma T_2 σ ( Γ , x : T 1 ) ⊢ σ t 2 : σ T 2
σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2 \sigma \Gamma , x : \sigma T_1 \vdash \sigma t_2 : \sigma T_2 σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2 (5)
4、5とT-Letより
σ Γ ⊢ let x = σ t 1 in σ t 2 : σ T 2 \sigma \Gamma \vdash \text{let} ~ x ~ \text{=} ~ \sigma t_1 ~ \text{in} ~ \sigma t_2 : \sigma T_2 σ Γ ⊢ let x = σ t 1 in σ t 2 : σ T 2
σ Γ ⊢ σ ( let x = t 1 in t 2 ) : σ T 2 \sigma \Gamma \vdash \sigma (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) : \sigma T_2 σ Γ ⊢ σ ( let x = t 1 in t 2 ) : σ T 2
1より
σ Γ ⊢ σ t : σ T 2 \sigma \Gamma \vdash \sigma t : \sigma T_2 σ Γ ⊢ σ t : σ T 2
2より
σ Γ ⊢ σ t : σ T \sigma \Gamma \vdash \sigma t : \sigma T σ Γ ⊢ σ t : σ T
したがって、所望の性質を満たす。
定理:制約型付けの健全性
( σ , T ) (\sigma, T) ( σ , T ) が ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解ならば、( Γ , t ) (\Gamma, t) ( Γ , t ) の解でもある。
概要:制約型付けの解は型付けの解でもある
証明:
定理の前提における導出 Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C に関する構造的帰納法によって示す。
CT-Varの場合、
定理の前提における導出とCT-Varの結論を以下のように対応付ける。
定理の前提より、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解であるため
定理の前提およびCT-Varの前提より
x : S ∈ Γ x : S \in \Gamma x : S ∈ Γ
文脈に対する型代入の定義より
x : σ S ∈ σ Γ x : \sigma S \in \sigma \Gamma x : σ S ∈ σ Γ
T-Varより
σ Γ ⊢ x : σ S \sigma \Gamma \vdash x : \sigma S σ Γ ⊢ x : σ S
2より
σ Γ ⊢ x : T \sigma \Gamma \vdash x : T σ Γ ⊢ x : T
変数に対する型代入の定義より
σ Γ ⊢ σ x : T \sigma \Gamma \vdash \sigma x : T σ Γ ⊢ σ x : T
1より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
したがって、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t ) (\Gamma, t) ( Γ , t ) の解でもあるため、所望の結論を満たす。
CT-Absの場合、
定理の前提における導出とCT-Absの結論を以下のように対応付ける。
t = λ x : T 1 . t 2 t = \lambda x : T_1 . ~ t_2 t = λ x : T 1 . t 2 (1)
S = T 1 → T 2 S = T_1 \rightarrow T_2 S = T 1 → T 2 (2)
定理の前提より、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解であるため
σ \sigma σ は C C C を単一化する(3)
σ S = T \sigma S = T σ S = T
2より
σ ( T 1 → T 2 ) = T \sigma (T_1 \rightarrow T_2) = T σ ( T 1 → T 2 ) = T
σ T 1 → σ T 2 = T \sigma T_1 \rightarrow \sigma T_2 = T σ T 1 → σ T 2 = T (4)
定理の前提およびCT-Absの前提より
Γ , x : T 1 ⊢ t 2 : T 2 ∣ C \Gamma , x : T_1 \vdash t_2 : T_2 ~ | ~ C Γ , x : T 1 ⊢ t 2 : T 2 ∣ C
3より
( σ , σ T 2 ) (\sigma, \sigma T_2) ( σ , σ T 2 ) は ( ( Γ , x : T 1 ) , t 2 , T 2 , C ) ((\Gamma , x : T_1), t_2, T_2, C) (( Γ , x : T 1 ) , t 2 , T 2 , C ) の解である
帰納法の仮定より
( σ , σ T 2 ) (\sigma, \sigma T_2) ( σ , σ T 2 ) は ( ( Γ , x : T 1 ) , t 2 ) ((\Gamma , x : T_1), t_2) (( Γ , x : T 1 ) , t 2 ) の解である
解の定義より
σ ( Γ , x : T 1 ) ⊢ σ t 2 : σ T 2 \sigma (\Gamma , x : T_1) \vdash \sigma t_2 : \sigma T_2 σ ( Γ , x : T 1 ) ⊢ σ t 2 : σ T 2
σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2 \sigma \Gamma , x : \sigma T_1 \vdash \sigma t_2 : \sigma T_2 σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2
T-Absより
σ Γ ⊢ λ x : σ T 1 . σ t 2 : σ T 1 → σ T 2 \sigma \Gamma \vdash \lambda x : \sigma T_1 . ~ \sigma t_2 : \sigma T_1 \rightarrow \sigma T_2 σ Γ ⊢ λ x : σ T 1 . σ t 2 : σ T 1 → σ T 2
4より
σ Γ ⊢ λ x : σ T 1 . σ t 2 : T \sigma \Gamma \vdash \lambda x : \sigma T_1 . ~ \sigma t_2 : T σ Γ ⊢ λ x : σ T 1 . σ t 2 : T
σ Γ ⊢ σ ( λ x : T 1 . t 2 ) : T \sigma \Gamma \vdash \sigma (\lambda x : T_1 . ~ t_2) : T σ Γ ⊢ σ ( λ x : T 1 . t 2 ) : T
1より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
したがって、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t ) (\Gamma, t) ( Γ , t ) の解でもあるため、所望の結論を満たす。
CT-Appの場合、
定理の前提における導出とCT-Appの結論を以下のように対応付ける。
t = t 1 t 2 t = t_1 ~ t_2 t = t 1 t 2 (1)
S = X S = X S = X (2)
C = C 1 ∪ C 2 ∪ { T 1 = T 2 → X } C = C_1 \cup C_2 \cup \{T_1 = T_2 \rightarrow X\} C = C 1 ∪ C 2 ∪ { T 1 = T 2 → X } (3)
定理の前提より、( σ , T ) (\sigma, T) ( σ , T ) が ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解であるため
σ \sigma σ は C C C を単一化する。3より
σ \sigma σ は C 1 C_1 C 1 を単一化する(4)
σ \sigma σ は C 2 C_2 C 2 を単一化する(5)
σ \sigma σ は { T 1 = T 2 → X } \{T_1 = T_2 \rightarrow X\} { T 1 = T 2 → X } を単一化する
σ T 1 = σ ( T 2 → X ) \sigma T_1 = \sigma (T_2 \rightarrow X) σ T 1 = σ ( T 2 → X )
σ T 1 = σ T 2 → σ X \sigma T_1 = \sigma T_2 \rightarrow \sigma X σ T 1 = σ T 2 → σ X (6)
σ S = T \sigma S = T σ S = T
2より
σ X = T \sigma X = T σ X = T (7)
定理の前提およびCT-Appの前提より
Γ ⊢ t 1 : T 1 ∣ C 1 \Gamma \vdash t_1 : T_1 ~ | ~ C_1 Γ ⊢ t 1 : T 1 ∣ C 1
4より
( σ , σ T 1 ) (\sigma, \sigma T_1) ( σ , σ T 1 ) は ( Γ , t 1 , T 1 , C 1 ) (\Gamma, t_1, T_1, C_1) ( Γ , t 1 , T 1 , C 1 ) の解である
帰納法の仮定より
( σ , σ T 1 ) (\sigma, \sigma T_1) ( σ , σ T 1 ) は ( Γ , t 1 ) (\Gamma, t_1) ( Γ , t 1 ) の解である
解の定義より
σ Γ ⊢ σ t 1 : σ T 1 \sigma \Gamma \vdash \sigma t_1 : \sigma T_1 σ Γ ⊢ σ t 1 : σ T 1
6より
σ Γ ⊢ σ t 1 : σ T 2 → σ X \sigma \Gamma \vdash \sigma t_1 : \sigma T_2 \rightarrow \sigma X σ Γ ⊢ σ t 1 : σ T 2 → σ X (8)
定理の前提およびCT-Appの前提より
Γ ⊢ t 2 : T 2 ∣ C 2 \Gamma \vdash t_2 : T_2 ~ | ~ C_2 Γ ⊢ t 2 : T 2 ∣ C 2
5より
( σ , σ T 2 ) (\sigma, \sigma T_2) ( σ , σ T 2 ) は ( Γ , t 2 , T 2 , C 2 ) (\Gamma, t_2, T_2, C_2) ( Γ , t 2 , T 2 , C 2 ) の解である
帰納法の仮定より
( σ , σ T 2 ) (\sigma, \sigma T_2) ( σ , σ T 2 ) は ( Γ , t 2 ) (\Gamma, t_2) ( Γ , t 2 ) の解である
解の定義より
σ Γ ⊢ σ t 2 : σ T 2 \sigma \Gamma \vdash \sigma t_2 : \sigma T_2 σ Γ ⊢ σ t 2 : σ T 2 (9)
8、9、T-Appより
σ Γ ⊢ σ t 1 σ t 2 : σ X \sigma \Gamma \vdash \sigma t_1 ~ \sigma t_2 : \sigma X σ Γ ⊢ σ t 1 σ t 2 : σ X
7より
σ Γ ⊢ σ t 1 σ t 2 : T \sigma \Gamma \vdash \sigma t_1 ~ \sigma t_2 : T σ Γ ⊢ σ t 1 σ t 2 : T
σ Γ ⊢ σ ( t 1 t 2 ) : T \sigma \Gamma \vdash \sigma (t_1 ~ t_2) : T σ Γ ⊢ σ ( t 1 t 2 ) : T
1より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
したがって、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t ) (\Gamma, t) ( Γ , t ) の解でもあるため、所望の結論を満たす。
CT-Zeroの場合、
定理の前提における導出とCT-Zeroの結論を以下のように対応付ける。
t = 0 t = 0 t = 0 (1)
S = Nat S = \text{Nat} S = Nat (2)
定理の前提より
T-Zeroより
Γ ⊢ 0 : Nat \Gamma \vdash 0 : \text{Nat} Γ ⊢ 0 : Nat
1より
Γ ⊢ t : Nat \Gamma \vdash t : \text{Nat} Γ ⊢ t : Nat
2より
Γ ⊢ t : S \Gamma \vdash t : S Γ ⊢ t : S
型代入の下での型付けの保存定理より
σ Γ ⊢ σ t : σ S \sigma \Gamma \vdash \sigma t : \sigma S σ Γ ⊢ σ t : σ S
3より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
したがって、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t ) (\Gamma, t) ( Γ , t ) の解でもあるため、所望の結論を満たす。
CT-Succの場合、
定理の前提における導出とCT-Succの結論を以下のように対応付ける。
t = succ t 1 t = \text{succ} ~ t_1 t = succ t 1 (1)
S = Nat S = \text{Nat} S = Nat (2)
C = C ′ ∪ { T ′ = Nat } C = C' \cup \{T' = \text{Nat}\} C = C ′ ∪ { T ′ = Nat } (3)
定理の前提より、( σ , T ) (\sigma, T) ( σ , T ) が ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解であるため
σ \sigma σ は C C C を単一化する。3より
σ \sigma σ は C ′ C' C ′ を単一化する(4)
σ \sigma σ は { T ′ = Nat } \{T' = \text{Nat}\} { T ′ = Nat } を単一化する
σ T ′ = σ Nat \sigma T' = \sigma \text{Nat} σ T ′ = σ Nat
σ T ′ = Nat \sigma T' = \text{Nat} σ T ′ = Nat (5)
σ S = T \sigma S = T σ S = T
2より
σ Nat = T \sigma \text{Nat} = T σ Nat = T
Nat = T \text{Nat} = T Nat = T (6)
定理の前提およびCT-Succの前提より
Γ ⊢ t 1 : T ′ ∣ C ′ \Gamma \vdash t_1 : T' ~ | ~ C' Γ ⊢ t 1 : T ′ ∣ C ′
4より
( σ , σ T ′ ) (\sigma, \sigma T') ( σ , σ T ′ ) は ( Γ , t 1 , T ′ , C ′ ) (\Gamma, t_1, T', C') ( Γ , t 1 , T ′ , C ′ ) の解である
帰納法の仮定より
( σ , σ T ′ ) (\sigma, \sigma T') ( σ , σ T ′ ) は ( Γ , t 1 ) (\Gamma, t_1) ( Γ , t 1 ) の解である
解の定義より
σ Γ ⊢ σ t 1 : σ T ′ \sigma \Gamma \vdash \sigma t_1 : \sigma T' σ Γ ⊢ σ t 1 : σ T ′
5より
σ Γ ⊢ σ t 1 : Nat \sigma \Gamma \vdash \sigma t_1 : \text{Nat} σ Γ ⊢ σ t 1 : Nat
T-Succより
σ Γ ⊢ succ ( σ t 1 ) : Nat \sigma \Gamma \vdash \text{succ} ~ (\sigma t_1) : \text{Nat} σ Γ ⊢ succ ( σ t 1 ) : Nat
σ Γ ⊢ σ ( succ t 1 ) : Nat \sigma \Gamma \vdash \sigma (\text{succ} ~ t_1) : \text{Nat} σ Γ ⊢ σ ( succ t 1 ) : Nat
1より
σ Γ ⊢ σ t : Nat \sigma \Gamma \vdash \sigma t : \text{Nat} σ Γ ⊢ σ t : Nat
6より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
したがって、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t ) (\Gamma, t) ( Γ , t ) の解でもあるため、所望の結論を満たす。
CT-Letの場合、
定理の前提における導出とCT-Letの結論を以下のように対応付ける。
t = ( let x = t 1 in t 2 ) t = (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) t = ( let x = t 1 in t 2 ) (1)
S = T 2 S = T_2 S = T 2 (2)
C = C 1 ∪ C 2 ∪ { T 1 = X } C = C_1 \cup C_2 \cup \{T_1 = X\} C = C 1 ∪ C 2 ∪ { T 1 = X } (3)
定理の前提より、( σ , T ) (\sigma, T) ( σ , T ) が ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解であるため
σ \sigma σ は C C C を単一化する。3より
σ \sigma σ は C 1 C_1 C 1 を単一化する (4)
σ \sigma σ は C 2 C_2 C 2 を単一化する (5)
σ \sigma σ は { T 1 = X } \{T_1 = X\} { T 1 = X } を単一化する
σ T 1 = σ X \sigma T_1 = \sigma X σ T 1 = σ X (6)
σ S = T \sigma S = T σ S = T
2より
σ T 2 = T \sigma T_2 = T σ T 2 = T (7)
定理の前提およびCT-Letの前提より
Γ ⊢ t 1 : T 1 ∣ C 1 \Gamma \vdash t_1 : T_1 ~ | ~ C_1 Γ ⊢ t 1 : T 1 ∣ C 1
4より
( σ , σ T 1 ) (\sigma, \sigma T_1) ( σ , σ T 1 ) は ( Γ , t 1 , T 1 , C 1 ) (\Gamma, t_1, T_1, C_1) ( Γ , t 1 , T 1 , C 1 ) の解である
帰納法の仮定より
( σ , σ T 1 ) (\sigma, \sigma T_1) ( σ , σ T 1 ) は ( Γ , t 1 ) (\Gamma, t_1) ( Γ , t 1 ) の解である
解の定義より
σ Γ ⊢ σ t 1 : σ T 1 \sigma \Gamma \vdash \sigma t_1 : \sigma T_1 σ Γ ⊢ σ t 1 : σ T 1 (8)
定理の前提およびCT-Letの前提より
Γ , x : X ⊢ t 2 : T 2 ∣ C 2 \Gamma , x : X \vdash t_2 : T_2 ~ | ~ C_2 Γ , x : X ⊢ t 2 : T 2 ∣ C 2
5より
( σ , σ T 2 ) (\sigma, \sigma T_2) ( σ , σ T 2 ) は ( ( Γ , x : X ) , t 2 , T 2 , C 2 ) ((\Gamma , x : X), t_2, T_2, C_2) (( Γ , x : X ) , t 2 , T 2 , C 2 ) の解である
帰納法の仮定より
( σ , σ T 2 ) (\sigma, \sigma T_2) ( σ , σ T 2 ) は ( ( Γ , x : X ) , t 2 ) ((\Gamma , x : X), t_2) (( Γ , x : X ) , t 2 ) の解である
解の定義より
σ ( Γ , x : X ) ⊢ σ t 2 : σ T 2 \sigma (\Gamma , x : X) \vdash \sigma t_2 : \sigma T_2 σ ( Γ , x : X ) ⊢ σ t 2 : σ T 2
σ Γ , x : σ X ⊢ σ t 2 : σ T 2 \sigma \Gamma , x : \sigma X \vdash \sigma t_2 : \sigma T_2 σ Γ , x : σ X ⊢ σ t 2 : σ T 2
6より
σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2 \sigma \Gamma , x : \sigma T_1 \vdash \sigma t_2 : \sigma T_2 σ Γ , x : σ T 1 ⊢ σ t 2 : σ T 2 (9)
8、9とT-Letより
σ Γ ⊢ let x = σ t 1 in σ t 2 : σ T 2 \sigma \Gamma \vdash \text{let} ~ x ~ \text{=} ~ \sigma t_1 ~ \text{in} ~ \sigma t_2 : \sigma T_2 σ Γ ⊢ let x = σ t 1 in σ t 2 : σ T 2
σ Γ ⊢ σ ( let x = t 1 in t 2 ) : σ T 2 \sigma \Gamma \vdash \sigma (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) : \sigma T_2 σ Γ ⊢ σ ( let x = t 1 in t 2 ) : σ T 2
1より
σ Γ ⊢ σ t : σ T 2 \sigma \Gamma \vdash \sigma t : \sigma T_2 σ Γ ⊢ σ t : σ T 2
7より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
したがって、( σ , T ) (\sigma, T) ( σ , T ) は ( Γ , t ) (\Gamma, t) ( Γ , t ) の解でもあるため、所望の結論を満たす。
定義:σ \sigma σ のそれぞれの組 X ↦ T X \mapsto T X ↦ T について、X ∈ χ X \in \chi X ∈ χ である組を除いた型代入を σ \ χ \sigma \backslash \chi σ \ χ と書く。
定理:制約型付けの完全性
( σ , T ) (\sigma, T) ( σ , T ) が ( Γ , t ) (\Gamma, t) ( Γ , t ) の解かつ、d o m ( σ ) ∩ χ = ∅ dom(\sigma) \cap \chi = \varnothing d o m ( σ ) ∩ χ = ∅ ならば、σ ′ \ χ = σ \sigma' \backslash \chi = \sigma σ ′ \ χ = σ となるような ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解 ( σ ′ , T ) (\sigma', T) ( σ ′ , T ) が存在する。
ここで、χ \chi χ は制約型付けによって導入される型変数の集合。また、σ \sigma σ は単一化アルゴリズム(後述)によって生成された型代入。
概要:型付けの解は、その型代入に「制約型付けによって導入される型変数に具体的な型を割り当てる組」を追加することで、制約型付けの解にできる。
証明:
定理の前提における導出 σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T に関する構造的帰納法による。
T-Varの場合、
定理の前提における導出とT-Varの結論を以下のように対応付ける
σ t = x \sigma t = x σ t = x
型代入は項の形に影響しない。したがって、型代入を適用して変数 x x x となるのはそれ自身だけであるため
t = x t = x t = x (1)
S S S を以下のように定義する
x : S ∈ Γ x : S \in \Gamma x : S ∈ Γ (2)
x : σ S ∈ σ Γ x : \sigma S \in \sigma \Gamma x : σ S ∈ σ Γ (3)
2とCT-Varより
Γ ⊢ x : S ∣ { } \Gamma \vdash x : S ~ | ~ \{\} Γ ⊢ x : S ∣ { }
CT-Varは型変数を導入しないため χ = { } \chi = \{\} χ = { } である。σ ′ \sigma' σ ′ 、C C C を以下のように定義する
σ ′ \ χ = σ \sigma' \backslash \chi = \sigma σ ′ \ χ = σ (4)
χ \chi χ は空であるため
σ ′ = σ \sigma' = \sigma σ ′ = σ (5)
C = { } C = \{\} C = { }
C C C が空であるため、σ ′ \sigma' σ ′ は C C C を単一化する (6)
Γ ⊢ x : S ∣ C \Gamma \vdash x : S ~ | ~ C Γ ⊢ x : S ∣ C
1より
Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C (7)
定理の前提における導出より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
1より
σ Γ ⊢ σ x : T \sigma \Gamma \vdash \sigma x : T σ Γ ⊢ σ x : T
σ Γ ⊢ x : T \sigma \Gamma \vdash x : T σ Γ ⊢ x : T
逆転補題1より
x : T ∈ σ Γ x : T \in \sigma \Gamma x : T ∈ σ Γ
3と型の部分を比較して
σ S = T \sigma S = T σ S = T
5より
σ ′ S = T \sigma' S = T σ ′ S = T (8)
7、6、8、4より、所望の結論を満たす。
T-Absの場合、
定理の前提における導出とT-Absの結論を以下のように対応付ける
σ t = λ x : T 1 . t 2 \sigma t = \lambda x : T_1 . ~ t_2 σ t = λ x : T 1 . t 2 (1)
T 1 ′ T'_1 T 1 ′ 、t 2 ′ t'_2 t 2 ′ を以下のように定義すると
σ T 1 ′ = T 1 \sigma T'_1 = T_1 σ T 1 ′ = T 1 (2)
σ t 2 ′ = t 2 \sigma t'_2 = t_2 σ t 2 ′ = t 2 (3)
t = λ x : T 1 ′ . t 2 ′ t = \lambda x : T'_1 . ~ t'_2 t = λ x : T 1 ′ . t 2 ′ (4)
T = T 1 → T 2 T = T_1 \rightarrow T_2 T = T 1 → T 2 (5)
定理の前提における導出より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
1より
σ Γ ⊢ λ x : T 1 . t 2 : T \sigma \Gamma \vdash \lambda x : T_1 . ~ t_2 : T σ Γ ⊢ λ x : T 1 . t 2 : T
5と逆転補題2より
σ Γ , x : T 1 ⊢ t 2 : T 2 \sigma \Gamma , x : T_1 \vdash t_2 : T_2 σ Γ , x : T 1 ⊢ t 2 : T 2
2、3より
σ Γ , x : σ T 1 ′ ⊢ σ t 2 ′ : T 2 \sigma \Gamma , x : \sigma T'_1 \vdash \sigma t'_2 : T_2 σ Γ , x : σ T 1 ′ ⊢ σ t 2 ′ : T 2
σ ( Γ , x : T 1 ′ ) ⊢ σ t 2 ′ : T 2 \sigma (\Gamma , x : T'_1) \vdash \sigma t'_2 : T_2 σ ( Γ , x : T 1 ′ ) ⊢ σ t 2 ′ : T 2
( σ , T 2 ) (\sigma, T_2) ( σ , T 2 ) は ( ( Γ , x : T 1 ′ ) , t 2 ′ ) ((\Gamma , x : T'_1), t'_2) (( Γ , x : T 1 ′ ) , t 2 ′ ) の解である
帰納法の仮定より、ある σ 1 \sigma_1 σ 1 、S 2 S_2 S 2 、C 1 C_1 C 1 、χ 1 \chi_1 χ 1 について以下を満たす。ただし、χ 1 \chi_1 χ 1 の要素はいずれもフレッシュに選ばれるものと仮定する
メモ:χ 1 \chi_1 χ 1 がフレッシュに選ばれるため、帰納法の仮定を適用するための d o m ( σ ) ∩ χ 1 = ∅ dom(\sigma) \cap \chi_1 = \varnothing d o m ( σ ) ∩ χ 1 = ∅ はいつでも満たせる。
σ 1 \ χ 1 = σ \sigma_1 \backslash \chi_1 = \sigma σ 1 \ χ 1 = σ (6)
( σ 1 , T 2 ) (\sigma_1, T_2) ( σ 1 , T 2 ) は ( ( Γ , x : T 1 ′ ) , t 2 ′ , S 2 , C 1 ) ((\Gamma , x : T'_1), t'_2, S_2, C_1) (( Γ , x : T 1 ′ ) , t 2 ′ , S 2 , C 1 ) の解である
解の定義より
Γ , x : T 1 ′ ⊢ t 2 ′ : S 2 ∣ C 1 \Gamma , x : T'_1 \vdash t'_2 : S_2 ~ | ~ C_1 Γ , x : T 1 ′ ⊢ t 2 ′ : S 2 ∣ C 1 (7)
σ 1 S 2 = T 2 \sigma_1 S_2 = T_2 σ 1 S 2 = T 2 (8)
σ 1 \sigma_1 σ 1 は C 1 C_1 C 1 を単一化する (9)
7より
Γ , x : T 1 ′ ⊢ t 2 ′ : S 2 ∣ C 1 \Gamma , x : T'_1 \vdash t'_2 : S_2 ~ | ~ C_1 Γ , x : T 1 ′ ⊢ t 2 ′ : S 2 ∣ C 1
CT-Absより
Γ ⊢ λ x : T 1 ′ . t 2 ′ : T 1 ′ → S 2 ∣ C 1 \Gamma \vdash \lambda x : T'_1 . ~ t'_2 : T'_1 \rightarrow S_2 ~ | ~ C_1 Γ ⊢ λ x : T 1 ′ . t 2 ′ : T 1 ′ → S 2 ∣ C 1
4より
Γ ⊢ t : T 1 ′ → S 2 ∣ C 1 \Gamma \vdash t : T'_1 \rightarrow S_2 ~ | ~ C_1 Γ ⊢ t : T 1 ′ → S 2 ∣ C 1
S S S 、C C C を以下のように定義する
S = T 1 ′ → S 2 S = T'_1 \rightarrow S_2 S = T 1 ′ → S 2 (10)
C = C 1 C = C_1 C = C 1 (11)
Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C (12)
χ \chi χ 、σ ′ \sigma' σ ′ を以下のように定義する
χ = χ 1 \chi = \chi_1 χ = χ 1 (13)
σ ′ = σ 1 \sigma' = \sigma_1 σ ′ = σ 1 (14)
10より
S = T 1 ′ → S 2 S = T'_1 \rightarrow S_2 S = T 1 ′ → S 2
σ 1 S = σ 1 ( T 1 ′ → S 2 ) \sigma_1 S = \sigma_1 (T'_1 \rightarrow S_2) σ 1 S = σ 1 ( T 1 ′ → S 2 )
σ 1 S = σ 1 T 1 ′ → σ 1 S 2 \sigma_1 S = \sigma_1 T'_1 \rightarrow \sigma_1 S_2 σ 1 S = σ 1 T 1 ′ → σ 1 S 2
8より
σ 1 S = σ 1 T 1 ′ → T 2 \sigma_1 S = \sigma_1 T'_1 \rightarrow T_2 σ 1 S = σ 1 T 1 ′ → T 2
6と以下の議論より
σ 1 \ χ 1 = σ \sigma_1 \backslash \chi_1 = \sigma σ 1 \ χ 1 = σ
σ 1 \ χ 1 ( T 1 ′ ) = σ T 1 ′ \sigma_1 \backslash \chi_1 (T'_1) = \sigma T'_1 σ 1 \ χ 1 ( T 1 ′ ) = σ T 1 ′
χ 1 \chi_1 χ 1 の要素はフレッシュに選ばれているため、T 1 ′ T'_1 T 1 ′ 内の型変数は χ 1 \chi_1 χ 1 に含まれないことから
σ 1 T 1 ′ = σ T 1 ′ \sigma_1 T'_1 = \sigma T'_1 σ 1 T 1 ′ = σ T 1 ′
σ 1 S = σ T 1 ′ → T 2 \sigma_1 S = \sigma T'_1 \rightarrow T_2 σ 1 S = σ T 1 ′ → T 2
2より
σ 1 S = T 1 → T 2 \sigma_1 S = T_1 \rightarrow T_2 σ 1 S = T 1 → T 2
5より
σ 1 S = T \sigma_1 S = T σ 1 S = T
14より
σ ′ S = T \sigma' S = T σ ′ S = T (15)
6、13、14より
σ ′ \ χ = σ \sigma' \backslash \chi = \sigma σ ′ \ χ = σ (16)
9、14、11より
σ ′ \sigma' σ ′ は C C C を単一化する (17)
16、12、15、17より、所望の結論を満たす。
T-Appの場合、
定理の前提における導出とT-Appの結論を以下のように対応付ける
σ t = t 1 t 2 \sigma t = t_1 ~ t_2 σ t = t 1 t 2 (1)
t 1 ′ t'_1 t 1 ′ 、t 2 ′ t'_2 t 2 ′ を以下のように定義すると
σ t 1 ′ = t 1 \sigma t'_1 = t_1 σ t 1 ′ = t 1 (2)
σ t 2 ′ = t 2 \sigma t'_2 = t_2 σ t 2 ′ = t 2 (3)
t = t 1 ′ t 2 ′ t = t'_1 ~ t'_2 t = t 1 ′ t 2 ′ (4)
T = T 12 T = T_{12} T = T 12 (5)
定理の前提における導出より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
1より
σ Γ ⊢ t 1 t 2 : T \sigma \Gamma \vdash t_1 ~ t_2 : T σ Γ ⊢ t 1 t 2 : T
2、3より
σ Γ ⊢ σ t 1 ′ σ t 2 ′ : T \sigma \Gamma \vdash \sigma t'_1 ~ \sigma t'_2 : T σ Γ ⊢ σ t 1 ′ σ t 2 ′ : T
5より
σ Γ ⊢ σ t 1 ′ σ t 2 ′ : T 12 \sigma \Gamma \vdash \sigma t'_1 ~ \sigma t'_2 : T_{12} σ Γ ⊢ σ t 1 ′ σ t 2 ′ : T 12
逆転補題3より、以下を満たす T 11 T_{11} T 11 が存在する
σ Γ ⊢ σ t 1 ′ : T 11 → T 12 \sigma \Gamma \vdash \sigma t'_1 : T_{11} \rightarrow T_{12} σ Γ ⊢ σ t 1 ′ : T 11 → T 12 (6)
σ Γ ⊢ σ t 2 ′ : T 11 \sigma \Gamma \vdash \sigma t'_2 : T_{11} σ Γ ⊢ σ t 2 ′ : T 11 (7)
6より
( σ , T 11 → T 12 ) (\sigma, T_{11} \rightarrow T_{12}) ( σ , T 11 → T 12 ) は ( Γ , t 1 ′ ) (\Gamma, t'_1) ( Γ , t 1 ′ ) の解である
帰納法の仮定より、ある σ 1 \sigma_1 σ 1 、S 1 S_1 S 1 、C 1 C_1 C 1 、χ 1 \chi_1 χ 1 について以下を満たす。ただし、χ 1 \chi_1 χ 1 の要素はいずれもフレッシュに選ばれるものと仮定する
σ 1 \ χ 1 = σ \sigma_1 \backslash \chi_1 = \sigma σ 1 \ χ 1 = σ (8)
( σ 1 , T 11 → T 12 ) (\sigma_1, T_{11} \rightarrow T_{12}) ( σ 1 , T 11 → T 12 ) は ( Γ , t 1 ′ , S 1 , C 1 ) (\Gamma, t'_1, S_1, C_1) ( Γ , t 1 ′ , S 1 , C 1 ) の解である
解の定義より
Γ ⊢ t 1 ′ : S 1 ∣ C 1 \Gamma \vdash t'_1 : S_1 ~ | ~ C_1 Γ ⊢ t 1 ′ : S 1 ∣ C 1 (9)
σ 1 S 1 = T 11 → T 12 \sigma_1 S_1 = T_{11} \rightarrow T_{12} σ 1 S 1 = T 11 → T 12 (10)
σ 1 \sigma_1 σ 1 は C 1 C_1 C 1 を単一化する (11)
7より
( σ , T 11 ) (\sigma, T_{11}) ( σ , T 11 ) は ( Γ , t 2 ′ ) (\Gamma, t'_2) ( Γ , t 2 ′ ) の解である
帰納法の仮定より、ある σ 2 \sigma_2 σ 2 、S 2 S_2 S 2 、C 2 C_2 C 2 、χ 2 \chi_2 χ 2 について以下を満たす。ただし、χ 2 \chi_2 χ 2 の要素はいずれもフレッシュに選ばれるものと仮定する
σ 2 \ χ 2 = σ \sigma_2 \backslash \chi_2 = \sigma σ 2 \ χ 2 = σ
( σ 1 , T 11 ) (\sigma_1, T_{11}) ( σ 1 , T 11 ) は ( Γ , t 2 ′ , S 2 , C 2 ) (\Gamma, t'_2, S_2, C_2) ( Γ , t 2 ′ , S 2 , C 2 ) の解である
解の定義より
Γ ⊢ t 2 ′ : S 2 ∣ C 2 \Gamma \vdash t'_2 : S_2 ~ | ~ C_2 Γ ⊢ t 2 ′ : S 2 ∣ C 2 (12)
σ 2 S 2 = T 11 \sigma_2 S_2 = T_{11} σ 2 S 2 = T 11 (13)
σ 2 \sigma_2 σ 2 は C 2 C_2 C 2 を単一化する
9、12、フレッシュな型変数 X X X およびCT-Appにより
Γ ⊢ t 1 ′ t 2 ′ : X ∣ C 1 ∪ C 2 ∪ { S 1 = S 2 → X } \Gamma \vdash t'_1 ~ t'_2 : X ~ | ~ C_1 \cup C_2 \cup \{S_1 = S_2 \rightarrow X\} Γ ⊢ t 1 ′ t 2 ′ : X ∣ C 1 ∪ C 2 ∪ { S 1 = S 2 → X }
4より
Γ ⊢ t : X ∣ C 1 ∪ C 2 ∪ { S 1 = S 2 → X } \Gamma \vdash t : X ~ | ~ C_1 \cup C_2 \cup \{S_1 = S_2 \rightarrow X\} Γ ⊢ t : X ∣ C 1 ∪ C 2 ∪ { S 1 = S 2 → X }
S S S と C C C を以下のように定義する
S = X S = X S = X (14)
C = C 1 ∪ C 2 ∪ { S 1 = S 2 → X } C = C_1 \cup C_2 \cup \{S_1 = S_2 \rightarrow X\} C = C 1 ∪ C 2 ∪ { S 1 = S 2 → X }
Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C (15)
χ \chi χ を以下のように定義する
χ = χ 1 ∪ χ 2 ∪ { X } \chi = \chi_1 \cup \chi_2 \cup \{X\} χ = χ 1 ∪ χ 2 ∪ { X } (16)
σ ′ \sigma' σ ′ を以下のように定義する
X ↦ T X \mapsto T X ↦ T (17)
Y ↦ U Y \mapsto U Y ↦ U 、ただし Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 かつ ( Y ↦ U ) ∈ σ 1 (Y \mapsto U) \in \sigma_1 ( Y ↦ U ) ∈ σ 1 の場合 (18)
Y ↦ U Y \mapsto U Y ↦ U 、ただし Y ∈ χ 2 Y \in \chi_2 Y ∈ χ 2 かつ ( Y ↦ U ) ∈ σ 2 (Y \mapsto U) \in \sigma_2 ( Y ↦ U ) ∈ σ 2 の場合
Y ↦ U Y \mapsto U Y ↦ U 、ただし Y ∉ χ Y \notin \chi Y ∈ / χ かつ ( Y ↦ U ) ∈ σ (Y \mapsto U) \in \sigma ( Y ↦ U ) ∈ σ の場合 (19)
14より
S = X S = X S = X
σ ′ S = σ ′ X \sigma' S = \sigma' X σ ′ S = σ ′ X
17より
σ ′ S = T \sigma' S = T σ ′ S = T (20)
以下の議論より、σ ′ \ χ = σ \sigma' \backslash \chi = \sigma σ ′ \ χ = σ である (21)
σ ′ \sigma' σ ′ の定義より、σ ′ \ χ \sigma' \backslash \chi σ ′ \ χ に含まれる組は、19で定義されるものだけである
そのような組は、 σ \sigma σ に含まれる、かつそのときに限り σ ′ \sigma' σ ′ にも含まれる
以下の議論より、σ ′ \sigma' σ ′ は C C C を単一化する (22)
σ ′ \sigma' σ ′ は C 1 C_1 C 1 を単一化する
χ 2 \chi_2 χ 2 の要素および X X X は、9の導出とは独立に、フレッシュに選ばれているため、C 1 C_1 C 1 の単一化に関与しない
したがって、C 1 C_1 C 1 の単一化に関与する組 Y ↦ U Y \mapsto U Y ↦ U は、18または19で定義される、Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 または Y ∉ χ Y \notin \chi Y ∈ / χ であるものだけである
Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 である組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ にも含まれる
これは、Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 という前提条件が、σ ′ \sigma' σ ′ の定義の4つの節のうち、18以外の条件を満たさないことからわかる
Y ∉ χ Y \notin \chi Y ∈ / χ である組は、σ \sigma σ に含まれる、かつそのときに限り σ ′ \sigma' σ ′ にも含まれる
ここで、16より Y ∉ χ 1 Y \notin \chi_1 Y ∈ / χ 1 である
その場合、8より σ 1 = σ \sigma_1 = \sigma σ 1 = σ である
したがって、Y ∉ χ Y \notin \chi Y ∈ / χ である組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ にも含まれる
したがって、C 1 C_1 C 1 の単一化に関わる組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ にも含まれる
11より、σ 1 \sigma_1 σ 1 は C 1 C_1 C 1 を単一化するため、σ ′ \sigma' σ ′ もまた C 1 C_1 C 1 を単一化する
C 1 C_1 C 1 と同様の議論より、σ ′ \sigma' σ ′ は C 2 C_2 C 2 を単一化する
σ ′ \sigma' σ ′ は { S 1 = S 2 → X } \{S_1 = S_2 \rightarrow X\} { S 1 = S 2 → X } を単一化する
σ ′ { S 1 = S 2 → X } \sigma' \{S_1 = S_2 \rightarrow X\} σ ′ { S 1 = S 2 → X }
{ σ ′ S 1 = σ ′ ( S 2 → X ) } \{\sigma' S_1 = \sigma' (S_2 \rightarrow X)\} { σ ′ S 1 = σ ′ ( S 2 → X )}
σ ′ S 1 = σ ′ ( S 2 → X ) \sigma' S_1 = \sigma' (S_2 \rightarrow X) σ ′ S 1 = σ ′ ( S 2 → X )
σ ′ S 1 = σ ′ S 2 → σ ′ X \sigma' S_1 = \sigma' S_2 \rightarrow \sigma' X σ ′ S 1 = σ ′ S 2 → σ ′ X
以下の議論より σ ′ S 1 = σ 1 S 1 \sigma' S_1 = \sigma_1 S_1 σ ′ S 1 = σ 1 S 1 であるため
χ 2 \chi_2 χ 2 の要素および X X X はフレッシュに選ばれているため、これらの型変数は S 1 S_1 S 1 に現れない
したがって、S 1 S_1 S 1 に適用されうる組は、18または19で定義される、Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 または Y ∉ χ Y \notin \chi Y ∈ / χ であるものだけである
C 1 C_1 C 1 と同様の議論より、S 1 S_1 S 1 に適用されうる組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ にも含まれる
したがって、σ ′ S 1 = σ 1 S 1 \sigma' S_1 = \sigma_1 S_1 σ ′ S 1 = σ 1 S 1
σ 1 S 1 = σ ′ S 2 → σ ′ X \sigma_1 S_1 = \sigma' S_2 \rightarrow \sigma' X σ 1 S 1 = σ ′ S 2 → σ ′ X
σ 1 \sigma_1 σ 1 と同様の議論により
σ 1 S 1 = σ 2 S 2 → σ ′ X \sigma_1 S_1 = \sigma_2 S_2 \rightarrow \sigma' X σ 1 S 1 = σ 2 S 2 → σ ′ X
10、13、17より
T 11 → T 12 = T 11 → T T_{11} \rightarrow T_{12} = T_{11} \rightarrow T T 11 → T 12 = T 11 → T
5より
T 11 → T 12 = T 11 → T 12 T_{11} \rightarrow T_{12} = T_{11} \rightarrow T_{12} T 11 → T 12 = T 11 → T 12
したがって、σ ′ \sigma' σ ′ は { S 1 = S 2 → X } \{S_1 = S_2 \rightarrow X\} { S 1 = S 2 → X } を単一化する
21、15、20、22より、所望の結論を満たす。
T-Zeroの場合、
定理の前提における導出とT-Appの結論を以下のように対応付ける
σ t = 0 \sigma t = 0 σ t = 0
型代入は項の形に影響しないため、代入を適用して 0 0 0 になる項はそれ自身しか無いため
t = 0 t = 0 t = 0 (1)
T = Nat T = \text{Nat} T = Nat (2)
CT-Zeroより
Γ ⊢ 0 : Nat ∣ { } \Gamma \vdash 0 : \text{Nat} ~ | ~ \{\} Γ ⊢ 0 : Nat ∣ { }
1より
Γ ⊢ t : Nat ∣ { } \Gamma \vdash t : \text{Nat} ~ | ~ \{\} Γ ⊢ t : Nat ∣ { }
CT-Zeroは型変数を導入しないため χ = { } \chi = \{\} χ = { } である。σ ′ \sigma' σ ′ 、S S S 、C C C を以下のように定義する
σ ′ \ χ = σ \sigma' \backslash \chi = \sigma σ ′ \ χ = σ (3)
S = Nat S = \text{Nat} S = Nat (4)
C = { } C = \{\} C = { }
C C C は空であるため、σ ′ \sigma' σ ′ は C C C を単一化する (5)
Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C (6)
4より
S = Nat S = \text{Nat} S = Nat
σ ′ S = σ ′ Nat \sigma' S = \sigma' \text{Nat} σ ′ S = σ ′ Nat
σ ′ S = Nat \sigma' S = \text{Nat} σ ′ S = Nat
2より
σ ′ S = T \sigma' S = T σ ′ S = T (7)
3、6、5、7より、所望の結論を満たす。
T-Succの場合、
定理の前提における導出とT-Succの結論を以下のように対応付ける
σ t = succ t 1 \sigma t = \text{succ} ~ t_1 σ t = succ t 1 (1)
t 1 ′ t'_1 t 1 ′ を以下のように定義すると
σ t 1 ′ = t 1 \sigma t'_1 = t_1 σ t 1 ′ = t 1 (2)
t = succ t 1 ′ t = \text{succ} ~ t'_1 t = succ t 1 ′ (3)
T = Nat T = \text{Nat} T = Nat (4)
定理の前提における導出より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
1より
σ Γ ⊢ succ t 1 : T \sigma \Gamma \vdash \text{succ} ~ t_1 : T σ Γ ⊢ succ t 1 : T
逆転補題5より
σ Γ ⊢ t 1 : Nat \sigma \Gamma \vdash t_1 : \text{Nat} σ Γ ⊢ t 1 : Nat
2より
σ Γ ⊢ σ t 1 ′ : Nat \sigma \Gamma \vdash \sigma t'_1 : \text{Nat} σ Γ ⊢ σ t 1 ′ : Nat
( σ , Nat ) (\sigma, \text{Nat}) ( σ , Nat ) は ( Γ , t 1 ′ ) (\Gamma, t'_1) ( Γ , t 1 ′ ) の解である
帰納法の仮定より、ある σ 1 \sigma_1 σ 1 、S 1 S_1 S 1 、C 1 C_1 C 1 、χ 1 \chi_1 χ 1 について以下を満たす。ただし、χ 1 \chi_1 χ 1 の要素はいずれもフレッシュに選ばれるものと仮定する
σ 1 \ χ 1 = σ \sigma_1 \backslash \chi_1 = \sigma σ 1 \ χ 1 = σ (5)
( σ 1 , Nat ) (\sigma_1, \text{Nat}) ( σ 1 , Nat ) は ( Γ , t 1 ′ , S 1 , C 1 ) (\Gamma, t'_1, S_1, C_1) ( Γ , t 1 ′ , S 1 , C 1 ) の解である
解の定義より
Γ ⊢ t 1 ′ : S 1 ∣ C 1 \Gamma \vdash t'_1 : S_1 ~ | ~ C_1 Γ ⊢ t 1 ′ : S 1 ∣ C 1 (6)
σ 1 S 1 = Nat \sigma_1 S_1 = \text{Nat} σ 1 S 1 = Nat (7)
σ 1 \sigma_1 σ 1 は C 1 C_1 C 1 を単一化する (8)
6とCT-Succより
Γ ⊢ succ t 1 ′ : Nat ∣ C 1 ∪ { S 1 = Nat } \Gamma \vdash \text{succ} ~ t'_1 : \text{Nat} ~ | ~ C_1 \cup \{ S_1 = \text{Nat} \} Γ ⊢ succ t 1 ′ : Nat ∣ C 1 ∪ { S 1 = Nat }
3より
Γ ⊢ t : Nat ∣ C 1 ∪ { S 1 = Nat } \Gamma \vdash t : \text{Nat} ~ | ~ C_1 \cup \{ S_1 = \text{Nat} \} Γ ⊢ t : Nat ∣ C 1 ∪ { S 1 = Nat }
S S S と C C C を以下のように定義する
S = Nat S = \text{Nat} S = Nat (9)
C = C 1 ∪ { S 1 = Nat } C = C_1 \cup \{ S_1 = \text{Nat} \} C = C 1 ∪ { S 1 = Nat }
Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C (10)
χ \chi χ を以下のように定義する
χ = χ 1 \chi = \chi_1 χ = χ 1 (11)
σ ′ \sigma' σ ′ を以下のように定義する
σ ′ = σ 1 \sigma' = \sigma_1 σ ′ = σ 1 (12)
5より
σ 1 \ χ 1 = σ \sigma_1 \backslash \chi_1 = \sigma σ 1 \ χ 1 = σ
12より
σ ′ \ χ 1 = σ \sigma' \backslash \chi_1 = \sigma σ ′ \ χ 1 = σ
11より
σ ′ \ χ = σ \sigma' \backslash \chi = \sigma σ ′ \ χ = σ (13)
以下の議論より、σ ′ \sigma' σ ′ は C C C を単一化する (14)
σ ′ \sigma' σ ′ は C 1 C_1 C 1 を単一化する
8より
σ 1 \sigma_1 σ 1 は C 1 C_1 C 1 を単一化する
12より
σ ′ \sigma' σ ′ は C 1 C_1 C 1 を単一化する
σ ′ \sigma' σ ′ は { S 1 = Nat } \{ S_1 = \text{Nat} \} { S 1 = Nat } を単一化する
σ ′ { S 1 = Nat } \sigma' \{ S_1 = \text{Nat} \} σ ′ { S 1 = Nat }
12より
σ 1 { S 1 = Nat } \sigma_1 \{ S_1 = \text{Nat} \} σ 1 { S 1 = Nat }
{ σ 1 S 1 = σ 1 Nat } \{ \sigma_1 S_1 = \sigma_1 \text{Nat} \} { σ 1 S 1 = σ 1 Nat }
σ 1 S 1 = σ 1 Nat \sigma_1 S_1 = \sigma_1 \text{Nat} σ 1 S 1 = σ 1 Nat
7より
Nat = Nat \text{Nat} = \text{Nat} Nat = Nat
9より
S = Nat S = \text{Nat} S = Nat
σ ′ S = σ ′ Nat \sigma' S = \sigma' \text{Nat} σ ′ S = σ ′ Nat
σ ′ S = Nat \sigma' S = \text{Nat} σ ′ S = Nat
4より
σ ′ S = T \sigma' S = T σ ′ S = T (15)
13、10、14、15より、所望の結論を満たす
T-Letの場合、
定理の前提における導出とT-Letの結論を以下のように対応付ける
σ t = ( let x = t 1 in t 2 ) \sigma t = (\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2) σ t = ( let x = t 1 in t 2 ) (1)
t 1 ′ t'_1 t 1 ′ 、t 2 ′ t'_2 t 2 ′ を以下のように定義すると
σ t 1 ′ = t 1 \sigma t'_1 = t_1 σ t 1 ′ = t 1 (2)
σ t 2 ′ = t 2 \sigma t'_2 = t_2 σ t 2 ′ = t 2 (3)
t = ( let x = t 1 ′ in t 2 ′ ) t = (\text{let} ~ x ~ \text{=} ~ t'_1 ~ \text{in} ~ t'_2) t = ( let x = t 1 ′ in t 2 ′ ) (4)
T = T 2 T = T_2 T = T 2 (5)
定理の前提における導出より
σ Γ ⊢ σ t : T \sigma \Gamma \vdash \sigma t : T σ Γ ⊢ σ t : T
1より
σ Γ ⊢ let x = t 1 in t 2 : T \sigma \Gamma \vdash \text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 : T σ Γ ⊢ let x = t 1 in t 2 : T
5より
σ Γ ⊢ let x = t 1 in t 2 : T 2 \sigma \Gamma \vdash \text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 : T_2 σ Γ ⊢ let x = t 1 in t 2 : T 2
逆転補題6より、ある T 1 = σ T 1 ′ T_1 = \sigma T_1' T 1 = σ T 1 ′ が存在して
σ Γ ⊢ t 1 : T 1 \sigma \Gamma \vdash t_1 : T_1 σ Γ ⊢ t 1 : T 1
2より
σ Γ ⊢ σ t 1 ′ : T 1 \sigma \Gamma \vdash \sigma t'_1 : T_1 σ Γ ⊢ σ t 1 ′ : T 1
( σ , T 1 ) (\sigma, T_1) ( σ , T 1 ) は ( Γ , t 1 ′ ) (\Gamma, t'_1) ( Γ , t 1 ′ ) の解である
帰納法の仮定より、ある σ 1 \sigma_1 σ 1 、S 1 S_1 S 1 、C 1 C_1 C 1 、χ 1 \chi_1 χ 1 が存在して以下が成り立つ。ただし、χ 1 \chi_1 χ 1 の各要素はフレッシュに選ばれると仮定する。
σ 1 \ χ 1 = σ \sigma_1 \backslash \chi_1 = \sigma σ 1 \ χ 1 = σ (6)
( σ 1 , T 1 ) (\sigma_1, T_1) ( σ 1 , T 1 ) は ( Γ , t 1 ′ , S 1 , C 1 ) (\Gamma, t'_1, S_1, C_1) ( Γ , t 1 ′ , S 1 , C 1 ) の解である
解の定義より
Γ ⊢ t 1 ′ : S 1 ∣ C 1 \Gamma \vdash t'_1 : S_1 ~ | ~ C_1 Γ ⊢ t 1 ′ : S 1 ∣ C 1 (7)
σ 1 S 1 = T 1 \sigma_1 S_1 = T_1 σ 1 S 1 = T 1 (8)
σ 1 \sigma_1 σ 1 は C 1 C_1 C 1 を単一化する (9)
σ Γ , x : σ T 1 ′ ⊢ t 2 : T 2 \sigma \Gamma , x : \sigma T_1' \vdash t_2 : T_2 σ Γ , x : σ T 1 ′ ⊢ t 2 : T 2
ここで、σ \sigma σ は単一化アルゴリズムによって生成された型代入である。この型代入は、一部の型変数を削除する(例えば、X X X という型変数が右辺に現れた場合は、左辺に自身が現れないことを確認した上で、型の中のすべての X X X を左辺に置き換える。これは実質的に X X X を削除していることになる)。つまり、この型代入を複数回適用しても、すでに削除された変数に対しては効果がないため、結果の型は変化しない。したがって、σ T 1 ′ = σ σ T 1 ′ \sigma T_1' = \sigma \sigma T_1' σ T 1 ′ = σσ T 1 ′ とできるため
σ Γ , x : σ σ T 1 ′ ⊢ t 2 : T 2 \sigma \Gamma , x : \sigma \sigma T_1' \vdash t_2 : T_2 σ Γ , x : σσ T 1 ′ ⊢ t 2 : T 2
σ Γ , x : σ T 1 ⊢ t 2 : T 2 \sigma \Gamma , x : \sigma T_1 \vdash t_2 : T_2 σ Γ , x : σ T 1 ⊢ t 2 : T 2
σ ( Γ , x : T 1 ) ⊢ t 2 : T 2 \sigma (\Gamma , x : T_1) \vdash t_2 : T_2 σ ( Γ , x : T 1 ) ⊢ t 2 : T 2
3より
σ ( Γ , x : T 1 ) ⊢ σ t 2 ′ : T 2 \sigma (\Gamma , x : T_1) \vdash \sigma t'_2 : T_2 σ ( Γ , x : T 1 ) ⊢ σ t 2 ′ : T 2
σ X \sigma_X σ X を以下のように定義する。型代入の下での型付けの保存定理によって
σ X = [ X ↦ T 1 ] \sigma_X = [X \mapsto T_1] σ X = [ X ↦ T 1 ]
σ X ∘ σ ( Γ , x : X ) ⊢ σ X ∘ σ t 2 ′ : σ X T 2 \sigma_X \circ \sigma (\Gamma , x : X) \vdash \sigma_X \circ \sigma t'_2 : \sigma_X T_2 σ X ∘ σ ( Γ , x : X ) ⊢ σ X ∘ σ t 2 ′ : σ X T 2
X X X はフレッシュに選ばれており、T 2 T_2 T 2 に現れないため
σ X ∘ σ ( Γ , x : X ) ⊢ σ X ∘ σ t 2 ′ : T 2 \sigma_X \circ \sigma (\Gamma , x : X) \vdash \sigma_X \circ \sigma t'_2 : T_2 σ X ∘ σ ( Γ , x : X ) ⊢ σ X ∘ σ t 2 ′ : T 2
( σ X ∘ σ , T 2 ) (\sigma_X \circ \sigma, T_2) ( σ X ∘ σ , T 2 ) は ( ( Γ , x : X ) , t 2 ′ ) ((\Gamma , x : X), t'_2) (( Γ , x : X ) , t 2 ′ ) の解である
帰納法の仮定より、ある σ 2 \sigma_2 σ 2 、S 2 S_2 S 2 、C 2 C_2 C 2 、χ 2 \chi_2 χ 2 が存在して以下が成り立つ。ただし、χ 2 \chi_2 χ 2 の各要素はフレッシュに選ばれると仮定する。
σ 2 \ χ 2 = σ X ∘ σ \sigma_2 \backslash \chi_2 = \sigma_X \circ \sigma σ 2 \ χ 2 = σ X ∘ σ (10)
( σ 2 , T 2 ) (\sigma_2, T_2) ( σ 2 , T 2 ) は ( ( Γ , x : X ) , t 2 ′ , S 2 , C 2 ) ((\Gamma , x : X), t'_2, S_2, C_2) (( Γ , x : X ) , t 2 ′ , S 2 , C 2 ) の解である
解の定義より
Γ , x : X ⊢ t 2 ′ : S 2 ∣ C 2 \Gamma , x : X \vdash t'_2 : S_2 ~ | ~ C_2 Γ , x : X ⊢ t 2 ′ : S 2 ∣ C 2 (11)
σ 2 S 2 = T 2 \sigma_2 S_2 = T_2 σ 2 S 2 = T 2 (12)
σ 2 \sigma_2 σ 2 は C 2 C_2 C 2 を単一化する (13)
7、11、フレッシュな型変数 X X X とCT-Letより
Γ ⊢ let x = t 1 ′ in t 2 ′ : S 2 ∣ C 1 ∪ C 2 ∪ { S 1 = X } \Gamma \vdash \text{let} ~ x ~ \text{=} ~ t'_1 ~ \text{in} ~ t'_2 : S_2 ~ | ~ C_1 \cup C_2 \cup \{S_1 = X\} Γ ⊢ let x = t 1 ′ in t 2 ′ : S 2 ∣ C 1 ∪ C 2 ∪ { S 1 = X }
4より
Γ ⊢ t : S 2 ∣ C 1 ∪ C 2 ∪ { S 1 = X } \Gamma \vdash t : S_2 ~ | ~ C_1 \cup C_2 \cup \{S_1 = X\} Γ ⊢ t : S 2 ∣ C 1 ∪ C 2 ∪ { S 1 = X }
S S S 、C C C を以下のように定義する
S = S 2 S = S_2 S = S 2 (14)
C = C 1 ∪ C 2 ∪ { S 1 = X } C = C_1 \cup C_2 \cup \{S_1 = X\} C = C 1 ∪ C 2 ∪ { S 1 = X } (15)
Γ ⊢ t : S ∣ C \Gamma \vdash t : S ~ | ~ C Γ ⊢ t : S ∣ C (16)
χ \chi χ を以下のように定義する
χ = χ 1 ∪ χ 2 ∪ { X } \chi = \chi_1 \cup \chi_2 \cup \{X\} χ = χ 1 ∪ χ 2 ∪ { X }
σ ′ \sigma' σ ′ を以下のように定義する (17)
X ↦ T 1 X \mapsto T_1 X ↦ T 1
Y ↦ U Y \mapsto U Y ↦ U 、ただし Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 かつ ( Y ↦ U ) ∈ σ 1 (Y \mapsto U) \in \sigma_1 ( Y ↦ U ) ∈ σ 1 の場合
Y ↦ U Y \mapsto U Y ↦ U 、ただし Y ∈ χ 2 Y \in \chi_2 Y ∈ χ 2 かつ ( Y ↦ U ) ∈ σ 2 (Y \mapsto U) \in \sigma_2 ( Y ↦ U ) ∈ σ 2 の場合
Y ↦ U Y \mapsto U Y ↦ U 、ただし Y ∉ χ Y \notin \chi Y ∈ / χ かつ ( Y ↦ U ) ∈ σ (Y \mapsto U) \in \sigma ( Y ↦ U ) ∈ σ の場合
以下の議論より、σ ′ \ χ = σ \sigma' \backslash \chi = \sigma σ ′ \ χ = σ (18)
17より、σ ′ \ χ \sigma' \backslash \chi σ ′ \ χ に含まれる組 Y ↦ U Y \mapsto U Y ↦ U は、Y ∉ χ Y \notin \chi Y ∈ / χ であるため、最後の節でのみ定義される
そのような組は、 σ \sigma σ に含まれる、かつそのときに限り σ ′ \sigma' σ ′ にも含まれる
σ ′ \sigma' σ ′ の組 Y ↦ U Y \mapsto U Y ↦ U について、以下が成り立つ (19)
組 X ↦ T 1 X \mapsto T_1 X ↦ T 1 は、σ 2 \sigma_2 σ 2 と σ ′ \sigma' σ ′ に含まれる
σ ′ \sigma' σ ′ に含まれるのは定義より明らかである。
σ 2 \sigma_2 σ 2 に含まれることを確認する。10より σ 2 \ χ 2 = σ X ∘ σ \sigma_2 \backslash \chi_2 = \sigma_X \circ \sigma σ 2 \ χ 2 = σ X ∘ σ である。σ X \sigma_X σ X の定義より、組は右辺に含まれる。したがって左辺の σ 2 \ χ 2 \sigma_2 \backslash \chi_2 σ 2 \ χ 2 にも含まれ、σ 2 \sigma_2 σ 2 にも含まれる
Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 である組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
Y ∈ χ 2 Y \in \chi_2 Y ∈ χ 2 である組は、σ 2 \sigma_2 σ 2 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
Y ∉ χ Y \notin \chi Y ∈ / χ である組は、σ \sigma σ に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
ここで、Y ∉ χ 1 Y \notin \chi_1 Y ∈ / χ 1 かつ Y ∉ χ 2 Y \notin \chi_2 Y ∈ / χ 2 かつ Y ≠ X Y \neq X Y = X である。
そのため、そのような組に着目すれば
6より σ 1 = σ \sigma_1 = \sigma σ 1 = σ である
10より σ 2 = σ \sigma_2 = \sigma σ 2 = σ である
したがって、当該の組は σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ 2 \sigma_2 σ 2 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
以下の議論より、σ ′ S = T \sigma' S = T σ ′ S = T (20)
12より
σ 2 S 2 = T 2 \sigma_2 S_2 = T_2 σ 2 S 2 = T 2
以下の議論より
σ ′ \sigma' σ ′ の組 Y ↦ U Y \mapsto U Y ↦ U について、19と以下の議論より
組 X ↦ T 1 X \mapsto T_1 X ↦ T 1 は、σ 2 \sigma_2 σ 2 と σ ′ \sigma' σ ′ に含まれる
Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 である組は、S 2 S_2 S 2 に適用されない
χ 1 \chi_1 χ 1 の要素が11の導出とは独立に、フレッシュに選ばれているため
Y ∈ χ 2 Y \in \chi_2 Y ∈ χ 2 である組は、定義より σ 2 \sigma_2 σ 2 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
Y ∉ χ Y \notin \chi Y ∈ / χ である組は、σ 2 \sigma_2 σ 2 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
したがって、σ 2 S 2 = σ ′ S 2 \sigma_2 S_2 = \sigma' S_2 σ 2 S 2 = σ ′ S 2 である
σ ′ S 2 = T 2 \sigma' S_2 = T_2 σ ′ S 2 = T 2
14、5より
σ ′ S = T \sigma' S = T σ ′ S = T
以下の議論より、σ ′ \sigma' σ ′ は C C C を単一化する (21)
σ ′ \sigma' σ ′ は C 1 C_1 C 1 を単一化する
9より
σ 1 \sigma_1 σ 1 は C 1 C_1 C 1 を単一化する
σ ′ \sigma' σ ′ の組 Y ↦ U Y \mapsto U Y ↦ U について、19と以下の議論より
組 X ↦ T 1 X \mapsto T_1 X ↦ T 1 は、C 1 C_1 C 1 の単一化に関与しない
X X X は7の導出とは独立にフレッシュに選ばれたため
Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 である組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
Y ∈ χ 2 Y \in \chi_2 Y ∈ χ 2 である組は、C 1 C_1 C 1 の単一化に関与しない
χ 2 \chi_2 χ 2 の各要素は7の導出とは独立にフレッシュに選ばれたため
Y ∉ χ Y \notin \chi Y ∈ / χ である組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
σ ′ \sigma' σ ′ は C 1 C_1 C 1 を単一化する
σ ′ \sigma' σ ′ は C 2 C_2 C 2 を単一化する
13より
σ 2 \sigma_2 σ 2 は C 2 C_2 C 2 を単一化する
σ ′ \sigma' σ ′ の組 Y ↦ U Y \mapsto U Y ↦ U について、19と以下の議論より
組 X ↦ T 1 X \mapsto T_1 X ↦ T 1 は、σ 2 \sigma_2 σ 2 と σ ′ \sigma' σ ′ に含まれる
Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 である組は、C 2 C_2 C 2 の単一化に関与しない
Y ∈ χ 2 Y \in \chi_2 Y ∈ χ 2 である組は、σ 2 \sigma_2 σ 2 と σ ′ \sigma' σ ′ に含まれる
Y ∉ χ Y \notin \chi Y ∈ / χ である組は、σ 2 \sigma_2 σ 2 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
σ ′ \sigma' σ ′ は C 2 C_2 C 2 を単一化する
σ ′ \sigma' σ ′ は { S 1 = X } \{S_1 = X\} { S 1 = X } を単一化する
σ ′ { S 1 = X } \sigma' \{S_1 = X\} σ ′ { S 1 = X }
{ σ ′ S 1 = σ ′ X } \{\sigma' S_1 = \sigma' X\} { σ ′ S 1 = σ ′ X }
σ ′ S 1 = σ ′ X \sigma' S_1 = \sigma' X σ ′ S 1 = σ ′ X
17より
σ ′ S 1 = T 1 \sigma' S_1 = T_1 σ ′ S 1 = T 1
σ ′ \sigma' σ ′ の組 Y ↦ U Y \mapsto U Y ↦ U について、19と以下の議論より
組 X ↦ T 1 X \mapsto T_1 X ↦ T 1 は、S 1 S_1 S 1 に適用されない
Y ∈ χ 1 Y \in \chi_1 Y ∈ χ 1 である組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
Y ∈ χ 2 Y \in \chi_2 Y ∈ χ 2 である組は、S 1 S_1 S 1 に適用されない
Y ∉ χ Y \notin \chi Y ∈ / χ である組は、σ 1 \sigma_1 σ 1 に含まれる、かつそのときに限り σ ′ \sigma' σ ′ に含まれる
σ 1 S 1 = T 1 \sigma_1 S_1 = T_1 σ 1 S 1 = T 1
8より
T 1 = T 1 T_1 = T_1 T 1 = T 1
18、16、20、21より、所望の結論を見たす
というわけで、
定理:型付けと制約型付けの対応
(単一化アルゴリズムによって生成された) ( Γ , t ) (\Gamma, t) ( Γ , t ) の解が存在する、かつそのときに限り ( Γ , t , S , C ) (\Gamma, t, S, C) ( Γ , t , S , C ) の解が存在する。
証明:
制約型付けの健全性、完全性定理より成り立つ。
となります。
単一化
制約型付けで得られた制約集合を単一化する型代入を見つけるために、以下の単一化アルゴリズム unifyを使用します。
定義:unify
unify( C C C ) =
if ( C C C = { } \{\} { } )
else
let { S = T } ∪ C ′ = C \{S = T\} \cup C' = C { S = T } ∪ C ′ = C in
if ( S S S == T T T )
else if ( S S S == X X X && X ∉ F V ( T ) X \notin FV(T) X ∈ / F V ( T ) )
return unify( [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ ) ∘ \circ ∘ [ X ↦ T ] [X \mapsto T] [ X ↦ T ]
else if ( T T T == X X X && X ∉ F V ( S ) X \notin FV(S) X ∈ / F V ( S ) )
return unify( [ X ↦ S ] C ′ [X \mapsto S] C' [ X ↦ S ] C ′ ) ∘ \circ ∘ [ X ↦ S ] [X \mapsto S] [ X ↦ S ]
else if ( S S S == ( S 1 → S 2 ) (S_1 \rightarrow S_2) ( S 1 → S 2 ) && T T T == ( T 1 → T 2 ) (T_1 \rightarrow T_2) ( T 1 → T 2 ) )
return unify( C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } )
else
以降は、unifyの性質について示していきます。
定理:停止性
ある C C C について、unifyは失敗するか、型代入を返すことで停止する。
証明:
C C C の次数 ( m , n ) (m, n) ( m , n ) を定義する。
m m m は C C C に含まれる異なる型変数の数である。例えば、{ X = A → A , A = Nat } \{X = A \rightarrow A, A = \text{Nat}\} { X = A → A , A = Nat } に含まれる異なる型変数は X X X と A A A であるため、m m m は2である。
n n n は C C C の等式の空白を除いた文字数である。例えば、{ X = A → A , A = Nat } \{X = A \rightarrow A, A = \text{Nat}\} { X = A → A , A = Nat } の n n n は、X=A→AA=Nat
の文字数を数えて10である。
以下の議論によって、unifyの各節は即座に停止するか C C C の次数を辞書的に減らす。次数の辞書的順序は整礎であるため、これが停止尺度となる。
unify( C C C ) =
if ( C C C = { } \{\} { } )
else
let { S = T } ∪ C ′ = C \{S = T\} \cup C' = C { S = T } ∪ C ′ = C in
if ( S S S == T T T )
return unify( C ′ C' C ′ )
S S S と T T T が型変数であり、それが C ′ C' C ′ に現れない場合、次数の m m m が減少する
それ以外の場合、次数の m m m は変化しないが、n n n が減少する
else if ( S S S == X X X && X ∉ F V ( T ) X \notin FV(T) X ∈ / F V ( T ) )
return unify( [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ ) ∘ \circ ∘ [ X ↦ T ] [X \mapsto T] [ X ↦ T ]
X ∉ F V ( T ) X \notin FV(T) X ∈ / F V ( T ) かつ [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ であることから、X X X が制約集合から消えるため、次数の m m m が減少する
else if ( T T T == X X X && X ∉ F V ( S ) X \notin FV(S) X ∈ / F V ( S ) )
return unify( [ X ↦ S ] C ′ [X \mapsto S] C' [ X ↦ S ] C ′ ) ∘ \circ ∘ [ X ↦ S ] [X \mapsto S] [ X ↦ S ]
上記と同様
else if ( S S S == ( S 1 → S 2 ) (S_1 \rightarrow S_2) ( S 1 → S 2 ) && T T T == ( T 1 → T 2 ) (T_1 \rightarrow T_2) ( T 1 → T 2 ) )
return unify( C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } )
C C C から取り出された等式Aと C ′ C' C ′ へ新たに追加される等式Bを以下のように比較すると、次数の n n n が減少するとわかる
等式A:S 1 → S 2 = T 1 → T 2 S_1 \rightarrow S_2 = T_1 \rightarrow T_2 S 1 → S 2 = T 1 → T 2
等式B:S 1 = T 1 S 2 = T 2 S_1 = T_1 S_2 = T_2 S 1 = T 1 S 2 = T 2
else
定理:単一化
unify ( C C C ) = σ = \sigma = σ ならば、σ \sigma σ は C C C を単一化する。
証明:
unifyの再起呼び出し回数に関する数学的帰納法による。n n n 回の再帰呼出しを行うunifyを unify n \text{unify}_n unify n と書く。
n = 0 n = 0 n = 0 の場合、
u n i f y 0 {unify_0} u ni f y 0 ( C C C ) =
if ( C C C = { } \{\} { } )
return [ ] [] [ ]
C C C は空であるため、空の型代入 [ ] [] [ ] は C C C を単一化し、所望の結論を満たす
else
let { S = T } ∪ C ′ = C \{S = T\} \cup C' = C { S = T } ∪ C ′ = C in
if ( S S S == T T T )
再帰呼出しを行うため、n = 0 n = 0 n = 0 である前提を満たさず、所望の結論は自明に満たされる
else if ( S S S == X X X && X ∉ F V ( T ) X \notin FV(T) X ∈ / F V ( T ) )
else if ( T T T == X X X && X ∉ F V ( S ) X \notin FV(S) X ∈ / F V ( S ) )
else if ( S S S == ( S 1 → S 2 ) (S_1 \rightarrow S_2) ( S 1 → S 2 ) && T T T == ( T 1 → T 2 ) (T_1 \rightarrow T_2) ( T 1 → T 2 ) )
else
任意の n n n について定理を仮定し、n + 1 n + 1 n + 1 の場合を示す
unify n + 1 \text{unify}_{n + 1} unify n + 1 ( C C C ) =
if ( C C C = { } \{\} { } )
return [ ] [] [ ]
再帰呼出しを行わないため、n + 1 n + 1 n + 1 回の再帰呼出しを行う前提を満たさない
else
let { S = T } ∪ C ′ = C \{S = T\} \cup C' = C { S = T } ∪ C ′ = C in
if ( S S S == T T T )
return unify n \text{unify}_n unify n ( C ′ C' C ′ )
定理の前提、および帰納法の仮定より、unify n \text{unify}_n unify n ( C ′ C' C ′ ) = σ ′ = \sigma' = σ ′ かつ σ ′ \sigma' σ ′ は C ′ C' C ′ を単一化する
S S S と T T T が等しいため、σ = σ ′ \sigma = \sigma' σ = σ ′ とおくと、σ \sigma σ は C C C を単一化し、所望の結論を満たす
else if ( S S S == X X X && X ∉ F V ( T ) X \notin FV(T) X ∈ / F V ( T ) )
return unify n \text{unify}_n unify n ( [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ ) ∘ \circ ∘ [ X ↦ T ] [X \mapsto T] [ X ↦ T ]
定理の前提、および帰納法の仮定より、unify n \text{unify}_n unify n ( [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ ) = σ ′ = \sigma' = σ ′ かつ σ ′ \sigma' σ ′ は [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ を単一化する
σ = σ ′ ∘ [ X ↦ T ] \sigma = \sigma' \circ [X \mapsto T] σ = σ ′ ∘ [ X ↦ T ] とおくと、σ \sigma σ は { X = T } ∪ C ′ \{X = T\} \cup C' { X = T } ∪ C ′ 、つまり C C C を単一化し、所望の結論を満たす
else if ( T T T == X X X && X ∉ F V ( S ) X \notin FV(S) X ∈ / F V ( S ) )
return unify n \text{unify}_n unify n ( [ X ↦ S ] C ′ [X \mapsto S] C' [ X ↦ S ] C ′ ) ∘ \circ ∘ [ X ↦ S ] [X \mapsto S] [ X ↦ S ]
上記と同様
else if ( S S S == ( S 1 → S 2 ) (S_1 \rightarrow S_2) ( S 1 → S 2 ) && T T T == ( T 1 → T 2 ) (T_1 \rightarrow T_2) ( T 1 → T 2 ) )
return unify n \text{unify}_n unify n ( C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } )
定理の前提、および帰納法の仮定より、unify n \text{unify}_n unify n ( C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } ) = σ ′ = \sigma' = σ ′ かつ σ ′ \sigma' σ ′ は C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } を単一化する
σ = σ ′ \sigma = \sigma' σ = σ ′ とおく
σ \sigma σ は { S 1 = T 1 , S 2 = T 2 } \{S_1 = T_1, S_2 = T_2\} { S 1 = T 1 , S 2 = T 2 } を単一化するため、{ S 1 → S 2 = T 1 → T 2 } \{S_1 \rightarrow S_2 = T_1 \rightarrow T_2\} { S 1 → S 2 = T 1 → T 2 } も単一化する
したがって、σ \sigma σ は C ′ ∪ { S 1 → S 2 = T 1 → T 2 } C' \cup \{S_1 \rightarrow S_2 = T_1 \rightarrow T_2\} C ′ ∪ { S 1 → S 2 = T 1 → T 2 } 、つまり C C C も単一化するため、所望の結論を満たす
else
定義:型代入 σ \sigma σ 、σ ′ \sigma' σ ′ について、σ ′ = σ ′ ′ ∘ σ \sigma' = \sigma'' \circ \sigma σ ′ = σ ′′ ∘ σ となるような σ ′ ′ \sigma'' σ ′′ が存在する場合、σ \sigma σ は σ ′ \sigma' σ ′ よりも限定的でないといい、σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′ と書く。
定理:主要単一化
σ ′ \sigma' σ ′ が C C C を単一化するならば、unify ( C C C ) = σ = \sigma = σ かつ σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′ である。
証明:
unifyの再起呼び出し回数に関する数学的帰納法による。n n n 回の再帰呼出しを行うunifyを unify n \text{unify}_n unify n と書く。
n = 0 n = 0 n = 0 の場合、
unify 1 \text{unify}_1 unify 1 ( C C C ) =
if ( C C C = { } \{\} { } )
return [ ] [] [ ]
以下のようになる
C = { } C = \{\} C = { }
unify ( C C C ) = σ = [ ] = \sigma = [] = σ = [ ]
σ ′ \sigma' σ ′ を任意の型代入と定義する。
C C C は空であるため、σ ′ \sigma' σ ′ は C C C を単一化する (1)
以下の議論より、σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′ (2)
σ ′ = σ ′ \sigma' = \sigma' σ ′ = σ ′
σ ′ = σ ′ ∘ [ ] \sigma' = \sigma' \circ [] σ ′ = σ ′ ∘ [ ]
σ ′ = σ ′ ∘ σ \sigma' = \sigma' \circ \sigma σ ′ = σ ′ ∘ σ
σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′
1、2より所望の結論を満たす
else
let { S = T } ∪ C ′ = C \{S = T\} \cup C' = C { S = T } ∪ C ′ = C in
if ( S S S == T T T )
else if ( S S S == X X X && X ∉ F V ( T ) X \notin FV(T) X ∈ / F V ( T ) )
else if ( T T T == X X X && X ∉ F V ( S ) X \notin FV(S) X ∈ / F V ( S ) )
else if ( S S S == ( S 1 → S 2 ) (S_1 \rightarrow S_2) ( S 1 → S 2 ) && T T T == ( T 1 → T 2 ) (T_1 \rightarrow T_2) ( T 1 → T 2 ) )
else
以下の議論により、所望の結論は自明に満たされる
S = X S = X S = X の場合
前節のelse ifの条件により、X ∈ F V ( T ) X \in FV(T) X ∈ F V ( T )
S ∈ F V ( T ) S \in FV(T) S ∈ F V ( T )
前節のelse ifの条件により、S ≠ T S \neq T S = T
以上より、T T T は S S S を含む、より複合的な型である
この場合、型代入によって S S S をどのような型に写像しても、T T T は S S S 以上に複合的な型になる
したがって、S = T S = T S = T は単一化できないため、定理の前提を満たさない
S = Nat S = \text{Nat} S = Nat の場合
T = X T = X T = X の場合
T = Nat T = \text{Nat} T = Nat の場合
T = T 1 → T 2 T = T_1 \rightarrow T_2 T = T 1 → T 2 の場合
そのような等式は単一化できないため、定理の前提を満たさない
S = S 1 → S 2 S = S_1 \rightarrow S_2 S = S 1 → S 2 の場合
T = X T = X T = X の場合
S = X S = X S = X の場合の議論と同様に、定理の前提を満たさない
T = Nat T = \text{Nat} T = Nat の場合
そのような等式は単一化できないため、定理の前提を満たさない
T = T 1 → T 2 T = T_1 \rightarrow T_2 T = T 1 → T 2 の場合
任意の n n n について定理を仮定し、n + 1 n + 1 n + 1 の場合を示す
unify n + 1 \text{unify}_{n + 1} unify n + 1 ( C C C ) =
if ( C C C = { } \{\} { } )
else
let { S = T } ∪ C ′ = C \{S = T\} \cup C' = C { S = T } ∪ C ′ = C in
if ( S S S == T T T )
return unify n \text{unify}_n unify n ( C ′ C' C ′ )
σ ′ \sigma' σ ′ が C ′ C' C ′ を単一化することと、帰納法の仮定より、ある σ n \sigma_n σ n について
unify n \text{unify}_n unify n ( C ′ C' C ′ ) = σ n = \sigma_n = σ n
unify n + 1 \text{unify}_{n + 1} unify n + 1 ( C C C ) = σ n = \sigma_n = σ n (1)
σ n ⊑ σ ′ \sigma_n \sqsubseteq \sigma' σ n ⊑ σ ′ (2)
σ = σ n \sigma = \sigma_n σ = σ n とおくと、1、2より
unify n + 1 \text{unify}_{n + 1} unify n + 1 ( C C C ) = σ = \sigma = σ (3)
σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′ (4)
3、4より、所望の結論を満たす
else if ( S S S == X X X && X ∉ F V ( T ) X \notin FV(T) X ∈ / F V ( T ) )
return unify n \text{unify}_n unify n ( [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ ) ∘ \circ ∘ [ X ↦ T ] [X \mapsto T] [ X ↦ T ]
定理の前提より
σ ′ \sigma' σ ′ は C C C を単一化する
S = T S = T S = T は C C C の部分であるため
σ ′ \sigma' σ ′ は S = T S = T S = T を単一化する
単一化の定義より
σ ′ S = σ ′ T \sigma' S = \sigma' T σ ′ S = σ ′ T
ifの前提より
σ ′ X = σ ′ T \sigma' X = \sigma' T σ ′ X = σ ′ T (1)
定理の前提より
σ ′ \sigma' σ ′ は C C C を単一化する
C ′ C' C ′ は C C C の部分であるため
σ ′ \sigma' σ ′ は C ′ C' C ′ を単一化する
単一化の定義より、U 1 = U 2 ∈ C ′ U_1 = U_2 \in C' U 1 = U 2 ∈ C ′ とすると
σ ′ U 1 = σ ′ U 2 \sigma' U_1 = \sigma' U_2 σ ′ U 1 = σ ′ U 2
1より
σ ′ ( [ X ↦ T ] U 1 ) = σ ′ ( [ X ↦ T ] U 2 ) \sigma' ([X \mapsto T] U_1) = \sigma' ([X \mapsto T] U_2) σ ′ ([ X ↦ T ] U 1 ) = σ ′ ([ X ↦ T ] U 2 )
単一化の定義より
σ ′ \sigma' σ ′ は [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ を単一化する (2)
2と帰納法の仮定より、ある σ n \sigma_n σ n について
unify n \text{unify}_n unify n ( [ X ↦ T ] C ′ [X \mapsto T] C' [ X ↦ T ] C ′ ) = σ n = \sigma_n = σ n (3)
σ n ⊑ σ ′ \sigma_n \sqsubseteq \sigma' σ n ⊑ σ ′
また、ある σ n ′ ′ \sigma_n'' σ n ′′ について
σ ′ = σ n ′ ′ ∘ σ n \sigma' = \sigma_n'' \circ \sigma_n σ ′ = σ n ′′ ∘ σ n (4)
3とunifyの定義より
unify n + 1 \text{unify}_{n + 1} unify n + 1 ( C C C ) = σ = \sigma = σ (5)
σ = σ n ∘ [ X ↦ T ] \sigma = \sigma_n \circ [X \mapsto T] σ = σ n ∘ [ X ↦ T ] (6)
以下の議論より σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′ である (7)
ある型変数 Y Y Y について
Y = X Y = X Y = X の場合
4より
σ ′ = σ n ′ ′ ∘ σ n \sigma' = \sigma_n'' \circ \sigma_n σ ′ = σ n ′′ ∘ σ n
σ ′ T = ( σ n ′ ′ ∘ σ n ) T \sigma' T = (\sigma_n'' \circ \sigma_n) T σ ′ T = ( σ n ′′ ∘ σ n ) T
1より
σ ′ X = ( σ n ′ ′ ∘ σ n ) T \sigma' X = (\sigma_n'' \circ \sigma_n) T σ ′ X = ( σ n ′′ ∘ σ n ) T
σ ′ X = ( σ n ′ ′ ∘ σ n ) ( [ X ↦ T ] X ) \sigma' X = (\sigma_n'' \circ \sigma_n) ([X \mapsto T] X) σ ′ X = ( σ n ′′ ∘ σ n ) ([ X ↦ T ] X )
σ ′ X = ( σ n ′ ′ ∘ ( σ n ∘ [ X ↦ T ] ) ) X \sigma' X = (\sigma_n'' \circ (\sigma_n \circ [X \mapsto T])) X σ ′ X = ( σ n ′′ ∘ ( σ n ∘ [ X ↦ T ])) X
6より
σ ′ X = ( σ n ′ ′ ∘ σ ) X \sigma' X = (\sigma_n'' \circ \sigma) X σ ′ X = ( σ n ′′ ∘ σ ) X
σ ′ Y = ( σ n ′ ′ ∘ σ ) Y \sigma' Y = (\sigma_n'' \circ \sigma) Y σ ′ Y = ( σ n ′′ ∘ σ ) Y
Y ≠ X Y \neq X Y = X の場合
4より
σ ′ = σ n ′ ′ ∘ σ n \sigma' = \sigma_n'' \circ \sigma_n σ ′ = σ n ′′ ∘ σ n
σ ′ Y = ( σ n ′ ′ ∘ σ n ) Y \sigma' Y = (\sigma_n'' \circ \sigma_n) Y σ ′ Y = ( σ n ′′ ∘ σ n ) Y
σ ′ Y = ( σ n ′ ′ ∘ σ n ) ( [ X ↦ T ] Y ) \sigma' Y = (\sigma_n'' \circ \sigma_n) ([X \mapsto T] Y) σ ′ Y = ( σ n ′′ ∘ σ n ) ([ X ↦ T ] Y )
σ ′ Y = ( σ n ′ ′ ∘ ( σ n ∘ [ X ↦ T ] ) ) Y \sigma' Y = (\sigma_n'' \circ (\sigma_n \circ [X \mapsto T])) Y σ ′ Y = ( σ n ′′ ∘ ( σ n ∘ [ X ↦ T ])) Y
6より
σ ′ Y = ( σ n ′ ′ ∘ σ ) Y \sigma' Y = (\sigma_n'' \circ \sigma) Y σ ′ Y = ( σ n ′′ ∘ σ ) Y
したがって、σ ′ \sigma' σ ′ が作用する任意の Y Y Y について
σ ′ Y = ( σ n ′ ′ ∘ σ ) Y \sigma' Y = (\sigma_n'' \circ \sigma) Y σ ′ Y = ( σ n ′′ ∘ σ ) Y
σ ′ = σ n ′ ′ ∘ σ \sigma' = \sigma_n'' \circ \sigma σ ′ = σ n ′′ ∘ σ
σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′
5、7より、所望の結論を満たす
else if ( T T T == X X X && X ∉ F V ( S ) X \notin FV(S) X ∈ / F V ( S ) )
return unify n \text{unify}_n unify n ( [ X ↦ S ] C ′ [X \mapsto S] C' [ X ↦ S ] C ′ ) ∘ \circ ∘ [ X ↦ S ] [X \mapsto S] [ X ↦ S ]
上記と同様
else if ( S S S == ( S 1 → S 2 ) (S_1 \rightarrow S_2) ( S 1 → S 2 ) && T T T == ( T 1 → T 2 ) (T_1 \rightarrow T_2) ( T 1 → T 2 ) )
return unify n \text{unify}_n unify n ( C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } )
定理の前提より
σ ′ \sigma' σ ′ は C C C を単一化する
C ′ C' C ′ は C C C の部分であるため
σ ′ \sigma' σ ′ は C ′ C' C ′ を単一化する (1)
S 1 → S 2 = T 1 → T 2 S_1 \rightarrow S_2 = T_1 \rightarrow T_2 S 1 → S 2 = T 1 → T 2 は C C C の部分であるため
σ ′ \sigma' σ ′ は S 1 → S 2 = T 1 → T 2 S_1 \rightarrow S_2 = T_1 \rightarrow T_2 S 1 → S 2 = T 1 → T 2 を単一化する
単一化の定義より
σ ′ ( S 1 → S 2 ) = σ ′ ( T 1 → T 2 ) \sigma' (S_1 \rightarrow S_2) = \sigma' (T_1 \rightarrow T_2) σ ′ ( S 1 → S 2 ) = σ ′ ( T 1 → T 2 )
σ ′ S 1 → σ ′ S 2 = σ ′ T 1 → σ ′ T 2 \sigma' S_1 \rightarrow \sigma' S_2 = \sigma' T_1 \rightarrow \sigma' T_2 σ ′ S 1 → σ ′ S 2 = σ ′ T 1 → σ ′ T 2
両辺を比較すると
σ ′ S 1 = σ ′ T 1 \sigma' S_1 = \sigma' T_1 σ ′ S 1 = σ ′ T 1
σ ′ \sigma' σ ′ は S 1 = T 1 S_1 = T_1 S 1 = T 1 を単一化する (2)
σ ′ S 2 = σ ′ T 2 \sigma' S_2 = \sigma' T_2 σ ′ S 2 = σ ′ T 2
σ ′ \sigma' σ ′ は S 2 = T 2 S_2 = T_2 S 2 = T 2 を単一化する (3)
1、2、3より
σ ′ \sigma' σ ′ は C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } を単一化する (4)
4と帰納法の仮定より、ある σ n \sigma_n σ n について
unify n \text{unify}_n unify n ( C ′ ∪ { S 1 = T 1 , S 2 = T 2 } C' \cup \{S_1 = T_1, S_2 = T_2\} C ′ ∪ { S 1 = T 1 , S 2 = T 2 } ) = σ n = \sigma_n = σ n (5)
σ n ⊑ σ ′ \sigma_n \sqsubseteq \sigma' σ n ⊑ σ ′ (6)
5とunifyの定義より
unify n + 1 \text{unify}_{n + 1} unify n + 1 ( C C C ) = σ = \sigma = σ (7)
σ = σ n \sigma = \sigma_n σ = σ n (8)
6、8より
σ ⊑ σ ′ \sigma \sqsubseteq \sigma' σ ⊑ σ ′ (9)
7、9より、所望の結論を満たす
else
n = 0 n = 0 n = 0 の場合の議論と同様に、所望の結論は自明に満たされる
というわけで、unifyは C C C を充足する型代入を計算してくれます。しかも、その代入は最も限定的でないもので、アルゴリズムは必ず停止するという良い性質を備えています。やったね
練習
型推論がどのように行われるかを手計算で実感してみます。
TAPLの演習22.3.3を解いてみます。以下の項の型を推論します。
λ x : X . λ y : Y . λ z : Z . ( x z ) ( y z ) \lambda x : X . ~
\lambda y : Y . ~
\lambda z : Z . ~
(x ~ z) ~ (y ~ z) λ x : X . λ y : Y . λ z : Z . ( x z ) ( y z )
制約型付け導出は以下のようになります。
x : X ∈ x : X , y : Y , z : Z x : X , y : Y , z : Z ⊢ { A , B , C } x : X ∣ { A , B , C } { } (CT-Var) z : Z ∈ x : X , y : Y , z : Z x : X , y : Y , z : Z ⊢ { A , B , C } z : Z ∣ { A , B , C } { } (CT-Var) x : X , y : Y , z : Z ⊢ { A , B , C } ( x z ) : A ∣ { B , C } { X = Z → A } (CT-App) y : Y ∈ x : X , y : Y , z : Z x : X , y : Y , z : Z ⊢ { B , C } y : Y ∣ { B , C } { } (CT-Var) z : Z ∈ x : X , y : Y , z : Z x : X , y : Y , z : Z ⊢ { B , C } z : Z ∣ { B , C } { } (CT-Var) x : X , y : Y , z : Z ⊢ { B , C } ( y z ) : B ∣ { C } { Y = Z → B } (CT-App) x : X , y : Y , z : Z ⊢ { A , B , C } ( x z ) ( y z ) : C ∣ { } { X = Z → A , Y = Z → B , A = B → C } (CT-App) x : X , y : Y ⊢ { A , B , C } λ z : Z . ( x z ) ( y z ) : Z → C ∣ { } { X = Z → A , Y = Z → B , A = B → C } (CT-Abs) x : X ⊢ { A , B , C } λ y : Y . λ z : Z . ( x z ) ( y z ) : Y → ( Z → C ) ∣ { } { X = Z → A , Y = Z → B , A = B → C } (CT-Abs) ⊢ { A , B , C } λ x : X . λ y : Y . λ z : Z . ( x z ) ( y z ) : X → ( Y → ( Z → C ) ) ∣ { } { X = Z → A , Y = Z → B , A = B → C } (CT-Abs) \dfrac
{
\dfrac
{
\dfrac
{
\dfrac
{
\dfrac
{
\dfrac
{
x : X \in x : X , y : Y , z : Z
}
{
x : X , y : Y , z : Z \vdash_{\{A , B , C\}}
x :
X ~
|_{\{A , B , C\}} ~
\{\}
}
\quad\text{(CT-Var)}
\qquad
\dfrac
{
z : Z \in x : X , y : Y , z : Z
}
{
x : X , y : Y , z : Z \vdash_{\{A , B , C\}}
z :
Z ~
|_{\{A , B , C\}} ~
\{\}
}
\quad\text{(CT-Var)}
}
{
x : X , y : Y , z : Z \vdash_{\{A , B , C\}}
(x ~ z) :
A ~
|_{\{B , C\}} ~
\{ X = Z \rightarrow A \}
}
\quad\text{(CT-App)}
\qquad
\dfrac
{
\dfrac
{
y : Y \in x : X , y : Y , z : Z
}
{
x : X , y : Y , z : Z \vdash_{\{B , C\}}
y :
Y ~
|_{\{B , C\}} ~
\{\}
}
\quad\text{(CT-Var)}
\qquad
\dfrac
{
z : Z \in x : X , y : Y , z : Z
}
{
x : X , y : Y , z : Z \vdash_{\{B , C\}}
z :
Z ~
|_{\{B , C\}} ~
\{\}
}
\quad\text{(CT-Var)}
}
{
x : X , y : Y , z : Z \vdash_{\{B , C\}}
(y ~ z) :
B ~
|_{\{C\}} ~
\{ Y = Z \rightarrow B \}
}
\quad\text{(CT-App)}
}
{
x : X , y : Y , z : Z \vdash_{\{A, B, C\}}
(x ~ z) ~ (y ~ z) :
C ~
|_{\{\}} ~
\{ X = Z \rightarrow A , Y = Z \rightarrow B , A = B \rightarrow C \}
}
\quad\text{(CT-App)}
}
{
x : X , y : Y \vdash_{\{A, B, C\}}
\lambda z : Z . ~
(x ~ z) ~ (y ~ z) :
Z \rightarrow C ~
|_{\{\}} ~
\{ X = Z \rightarrow A , Y = Z \rightarrow B , A = B \rightarrow C \}
}
\quad\text{(CT-Abs)}
}
{
x : X \vdash_{\{A, B, C\}}
\lambda y : Y . ~
\lambda z : Z . ~
(x ~ z) ~ (y ~ z) :
Y \rightarrow (Z \rightarrow C) ~
|_{\{\}} ~
\{ X = Z \rightarrow A , Y = Z \rightarrow B , A = B \rightarrow C \}
}
\quad\text{(CT-Abs)}
}
{
\vdash_{\{A, B, C\}}
\lambda x : X . ~
\lambda y : Y . ~
\lambda z : Z . ~
(x ~ z) ~ (y ~ z) :
X \rightarrow (Y \rightarrow (Z \rightarrow C)) ~
|_{\{\}} ~
\{ X = Z \rightarrow A , Y = Z \rightarrow B , A = B \rightarrow C \}
}
\quad\text{(CT-Abs)} ⊢ { A , B , C } λ x : X . λ y : Y . λ z : Z . ( x z ) ( y z ) : X → ( Y → ( Z → C )) ∣ { } { X = Z → A , Y = Z → B , A = B → C } x : X ⊢ { A , B , C } λ y : Y . λ z : Z . ( x z ) ( y z ) : Y → ( Z → C ) ∣ { } { X = Z → A , Y = Z → B , A = B → C } x : X , y : Y ⊢ { A , B , C } λ z : Z . ( x z ) ( y z ) : Z → C ∣ { } { X = Z → A , Y = Z → B , A = B → C } x : X , y : Y , z : Z ⊢ { A , B , C } ( x z ) ( y z ) : C ∣ { } { X = Z → A , Y = Z → B , A = B → C } x : X , y : Y , z : Z ⊢ { A , B , C } ( x z ) : A ∣ { B , C } { X = Z → A } x : X , y : Y , z : Z ⊢ { A , B , C } x : X ∣ { A , B , C } { } x : X ∈ x : X , y : Y , z : Z (CT-Var) x : X , y : Y , z : Z ⊢ { A , B , C } z : Z ∣ { A , B , C } { } z : Z ∈ x : X , y : Y , z : Z (CT-Var) (CT-App) x : X , y : Y , z : Z ⊢ { B , C } ( y z ) : B ∣ { C } { Y = Z → B } x : X , y : Y , z : Z ⊢ { B , C } y : Y ∣ { B , C } { } y : Y ∈ x : X , y : Y , z : Z (CT-Var) x : X , y : Y , z : Z ⊢ { B , C } z : Z ∣ { B , C } { } z : Z ∈ x : X , y : Y , z : Z (CT-Var) (CT-App) (CT-App) (CT-Abs) (CT-Abs) (CT-Abs)
めっちゃ横に長いです。幅の広い画面で見ている方は、
ブログの幅を一時的に最大にするボタン
が役に立つかもしれません。リロードするともとに戻ります。
制約型付けで得られた制約を単一化アルゴリズムで解きます。
unify ( { X = Z → A , Y = Z → B , A = B → C } ) = unify ( [ X ↦ Z → A ] { Y = Z → B , A = B → C } ) ∘ [ X ↦ Z → A ] = unify ( { Y = Z → B , A = B → C } ) ∘ [ X ↦ Z → A ] = unify ( [ Y ↦ Z → B ] { A = B → C } ) ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = unify ( { A = B → C } ) ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = unify ( [ A ↦ B → C ] { } ) ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = unify ( { } ) ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = [ ] ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] \begin{aligned}
&
\text{unify}
(
\{
X = Z \rightarrow A ,
Y = Z \rightarrow B ,
A = B \rightarrow C
\}
)
\\
&=
\text{unify}
(
[X \mapsto Z \rightarrow A]
\{
Y = Z \rightarrow B ,
A = B \rightarrow C
\}
)
\circ
[X \mapsto Z \rightarrow A]
\\
&=
\text{unify}
(
\{
Y = Z \rightarrow B ,
A = B \rightarrow C
\}
)
\circ
[X \mapsto Z \rightarrow A]
\\
&=
\text{unify}
(
[Y \mapsto Z \rightarrow B]
\{
A = B \rightarrow C
\}
)
\circ
[Y \mapsto Z \rightarrow B]
\circ
[X \mapsto Z \rightarrow A]
\\
&=
\text{unify}
(
\{
A = B \rightarrow C
\}
)
\circ
[Y \mapsto Z \rightarrow B]
\circ
[X \mapsto Z \rightarrow A]
\\
&=
\text{unify}
(
[A \mapsto B \rightarrow C]
\{\}
)
\circ
[A \mapsto B \rightarrow C]
\circ
[Y \mapsto Z \rightarrow B]
\circ
[X \mapsto Z \rightarrow A]
\\
&=
\text{unify}
(
\{\}
)
\circ
[A \mapsto B \rightarrow C]
\circ
[Y \mapsto Z \rightarrow B]
\circ
[X \mapsto Z \rightarrow A]
\\
&=
[]
\circ
[A \mapsto B \rightarrow C]
\circ
[Y \mapsto Z \rightarrow B]
\circ
[X \mapsto Z \rightarrow A]
\\
\end{aligned} unify ({ X = Z → A , Y = Z → B , A = B → C }) = unify ([ X ↦ Z → A ] { Y = Z → B , A = B → C }) ∘ [ X ↦ Z → A ] = unify ({ Y = Z → B , A = B → C }) ∘ [ X ↦ Z → A ] = unify ([ Y ↦ Z → B ] { A = B → C }) ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = unify ({ A = B → C }) ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = unify ([ A ↦ B → C ] { }) ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = unify ({ }) ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] = [ ] ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ]
主要型は以下のとおりです。
[ ] ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] ( X → ( Y → ( Z → C ) ) ) = [ ] ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ( ( Z → A ) → ( Y → ( Z → C ) ) ) = [ ] ∘ [ A ↦ B → C ] ( ( Z → A ) → ( ( Z → B ) → ( Z → C ) ) ) = [ ] ( ( Z → ( B → C ) ) → ( ( Z → B ) → ( Z → C ) ) ) = ( Z → ( B → C ) ) → ( ( Z → B ) → ( Z → C ) ) \begin{aligned}
&
[]
\circ
[A \mapsto B \rightarrow C]
\circ
[Y \mapsto Z \rightarrow B]
\circ
[X \mapsto Z \rightarrow A]
(X \rightarrow (Y \rightarrow (Z \rightarrow C)))
\\
&=
[]
\circ
[A \mapsto B \rightarrow C]
\circ
[Y \mapsto Z \rightarrow B]
((Z \rightarrow A) \rightarrow (Y \rightarrow (Z \rightarrow C)))
\\
&=
[]
\circ
[A \mapsto B \rightarrow C]
((Z \rightarrow A) \rightarrow ((Z \rightarrow B) \rightarrow (Z \rightarrow C)))
\\
&=
[]
((Z \rightarrow (B \rightarrow C)) \rightarrow ((Z \rightarrow B) \rightarrow (Z \rightarrow C)))
\\
&=
(Z \rightarrow (B \rightarrow C)) \rightarrow ((Z \rightarrow B) \rightarrow (Z \rightarrow C))
\\
\end{aligned} [ ] ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] ∘ [ X ↦ Z → A ] ( X → ( Y → ( Z → C ))) = [ ] ∘ [ A ↦ B → C ] ∘ [ Y ↦ Z → B ] (( Z → A ) → ( Y → ( Z → C ))) = [ ] ∘ [ A ↦ B → C ] (( Z → A ) → (( Z → B ) → ( Z → C ))) = [ ] (( Z → ( B → C )) → (( Z → B ) → ( Z → C ))) = ( Z → ( B → C )) → (( Z → B ) → ( Z → C ))
これは以下のもともとの項に整合しているとわかります。
λ x : X . λ y : Y . λ z : Z . ( x z ) ( y z ) \lambda x : X . ~
\lambda y : Y . ~
\lambda z : Z . ~
(x ~ z) ~ (y ~ z) λ x : X . λ y : Y . λ z : Z . ( x z ) ( y z )
SICPの思い出
単一化アルゴリズムはSICPでも登場してました。あっちでは論理プログラミングにおける変数束縛で使われてましたね。パターンには値と変数がどちらも現れうるので、値と値の等式、値と変数の等式、変数と変数の等式の制約集合を解くために必要でした。
TAPLによれば、
実はこのアルゴリズムのどの部分も、単一化の対象が型式であることには依存していない。同じアルゴリズムを用いて、他の任意の種類の式(ただし一階のもの)に関する等式制約を解ける。
出典:定義22.4.4、型システム入門 プログラミング言語と型の理論
とあります。なーるほど。
実装
証明が終わったのでさっそく実装していきましょう。
構文解析
まず、どのようにプログラムを書くかという、具象構文を定義します。
Term ::=
Identifier
λIdentifier. Term
Term Term
0
Succ Term
let Identifier = Term in Term
(Term)
Identifier ::=
/[a-zA-Z0-9]+/
抽象構文に似ていますが、カッコの規則などが追加されています。
証明などの形式的な議論では明示的には不要でしたが、実際にプログラムを書く際には必要です。例えば、適用の優先順位を指定する際などに使います。
字句解析
勘で実装しました。
例えば、λhoge.
という文字列の入力に対しては、
ラムダ記号
hoge
というIdentifier
ドット記号
というトークンの列を出力します。
また、スペースの連続や改行、コメントの除去などもここで処理してくれます。
構文解析:LR法
前から興味があったLR法 を実装してみました。
特にLR構文解析の原理 という論文が最高なので人類の皆さんにおすすめです。
LR法に関する他の資料も参照したのですが、「アクション表やShift、Reduceを使ってそれが実行されるのはわかるけど、それでなぜ構文解析ができるのかがいまいち納得できない」という感じでした。
しかし上記の論文では、LR法が非決定性有限オートマトン を繰り返し使用することで実装できること、そして部分集合構成法 を使用することで、非決定性有限オートマトンを決定性有限オートマトン に変換し、実行できることが順序良く示されていてわかりやすかったです。
あまりに良いので、日本ソフトウェア科学会の解説論文賞を受賞してたりするそうです。
大堀先生、ありがとうございました。
構文の実装
LR法のおかげで、構文を実装するのはとても楽になります。
例えば以下は適用の構文規則 Term ::= Term Term
の実装です。
[
{
symbol : "Term" ,
expression: [ "Term" , "Spaces" , "Term" ] ,
callback: ( symbols) : Result< ASTApply> => {
const operator = symbols[ 0 ] ;
const operand = symbols[ 2 ] ;
if ( ! isAST ( operator) ) return error ( ) ;
if ( ! isAST ( operand) ) return error ( ) ;
return ok ( { kind: "ast" , type: "Apply" , operator, operand } ) ;
} ,
} ,
] ;
symbol: "Term"
が ::=
の左辺、 expression: ["Term", "Spaces", "Term"]
が右辺に直接対応しています。
callback
は、この規則がマッチしたときに呼ばれる関数で、 ["Term", "Spaces", "Term"]
のトークン列から適用のASTノードを返します。
syntax.ts にはこのような規則が配列として列挙してあります。
パーサーはこの規則をもとにオートマトンを構築して、トークン列からASTを構築してくれます。便利ですね。
実際、見通しが甘くて文法の改修を何度か行ったのですが、とても短時間で済んでしまい驚きました。
評価器、型検査器
評価規則と制約型付けを愚直に実装しました。マジでそれだけです。
完成!
言語の名前はpico-lambda としました。
型無しラムダ計算
とりあえず型検査はオフにして、まずは簡単な計算から
let ToNumber = λn. (n (λx. (succ x)) 0) in
let One = λs. λz. (s z) in
let Two = λs. λz. (s (s z)) in
let Three = λs. λz. (s (s (s z))) in
let Four = λs. λz. (s (s (s (s z)))) in
// see: https://en.wikipedia.org/wiki/Church_encoding
let Succ = λn. λf. λx. (f (n f x)) in
let Plus = λm. λn. (m Succ n) in
let Mult = λm. λn. λf. (m (n f)) in
let Exp = λm. λn. (n m) in
let Pred = λn. λf. λx. (n (λg. λh. (h (g f))) (λu. x) (λu. u)) in
(ToNumber
// ((1 + 2) * 3)^(4 - 1) = 729
(Exp
(Mult (Plus One Two) Three)
(Pred Four)
)
)
$ ./main.ts examples/arithmetics.lambda --skip-tc
729
おー、計算できてます!
729
というのは、本当は succ (succ (... (succ 0) ...))
という値で、Printerがよしなに数字として表示しているだけです。
続いて、前回の記事 でも触れたZコンビネータを使った階乗の計算
let ToNumber = λn. (n (λx. (succ x)) 0) in
let Zero = λs. λz. z in
let One = λs. λz. (s z) in
let Five = λs. λz. (s (s (s (s (s z))))) in
let Succ = λn. λs. λz. (s (n s z)) in
let Mul = λn1. λn2. λs. λz. (n2 (λz. (n1 s z)) z) in
let MakePair = λfirstValue. λsecondValue. λselector. (selector firstValue secondValue) in
let First = λpair. (pair (λfirstValue. λsecondValue. firstValue)) in
let Second = λpair. (pair (λfirstValue. λsecondValue. secondValue)) in
let Pred = λn. (
(Second
(n
// s
λpair. (
(MakePair
(Succ (First pair))
(First pair)
)
)
// z
(MakePair Zero Zero)
)
)
) in
let Force = λthunk. (thunk 0) in
let If = λbool. λdelayedTrueValue. λdelayedFalseValue. (bool delayedTrueValue delayedFalseValue) in
let True = λdelayedTrueValue. λdelayedFalseValue. (Force delayedTrueValue) in
let False = λdelayedTrueValue. λdelayedFalseValue. (Force delayedFalseValue) in
let IsZero = λn. (n (λz. False) True) in
let Fix = (
λg. (
λh. (
g (λarg. (h h arg))
)
λh. (
g (λarg. (h h arg))
)
)
) in
// main
let Fact = (
Fix
λfact. λn. (
(If
(IsZero n)
λx. One
λx. (
Mul
n
(fact (Pred n))
)
)
)
) in
(ToNumber (Fact Five))
$ ./main.ts examples/fact.lambda --skip-tc
120
いいですね!
次は発散コンビネータ(omegaとも)、関数だけで無限ループするやつ
$ ./main.ts examples/omega.lambda --skip-tc
ちゃんと動いてますねー
型付きラムダ計算
それでは、--skip-tc
を外し、型検査を有効にして動かしてみます。
まず、先程の簡単な計算は以下のようになります。
$ ./main.ts examples/arithmetics.lambda
tc passed: Nat
729
型検査をパスして、推論の結果が Nat
型であると表示されています。検査をパスしたので、実際に実行してみたら 729
という値だったというわけです。このことは、これまでに示した一連の定理によって保証されています。
無限ループである発散コンビネータはどうなるでしょうか。
$ ./main.ts examples/omega.lambda
type checking failed
{
msg: 'inferType: unification failed' ,
error: { .. . }
}
型検査に失敗したので、そもそも実行されませんでした。無限ループはいつまでも値にならないので、それに型は付かなさそうだというのは感覚的に納得できると思います。
全ての無限ループを生まれる前に消し去りたい ってやつです
実際、停止しないならば項に型は付かない(項に型が付くならば停止する)と言うには、正規化可能性(または停止性)という性質を証明する必要があるそうです。型付きラムダ計算では正規化可能性が成り立つと知られています。
ところで、同じような理由でZコンビネータにも型が付かないので、先程の階乗の計算もまた実行できません。
$ ./main.ts examples/fact.lambda
type checking failed
.. .
さすがにループが書けないのは実用上厳しいです。
この能力を取り戻すために、高度な型システムを組み込んだり、特殊な評価規則を追加したりすることによって、制限を緩める方法があるようです。
単相性
今回作った型システムは単相的です。以下のプログラムは型エラーになります。
let id = λx. x in
(
id // 1
id // 2
)
2の id
を考えると A → A A \rightarrow A A → A 型が付きそうですが、 1の id
を考えると ( A → A ) → ( A → A ) (A \rightarrow A) \rightarrow (A \rightarrow A) ( A → A ) → ( A → A ) 型でないとダメそうです。
CT-Letは、
Γ ⊢ F t 1 : T 1 ∣ F ′ C 1 Γ , x : X ⊢ F ′ t 2 : T 2 ∣ F ′ ′ C 2 F ′ ′ = X , F ′ ′ ′ Γ ⊢ F let x = t 1 in t 2 : T 2 ∣ F ′ ′ ′ C 1 ∪ C 2 ∪ { T 1 = X } (CT-Let) \dfrac
{
\begin{aligned}
&
\Gamma \vdash_F
t_1 :
T_1 ~
|_{F'} ~
C_1
\\ &
\Gamma , x : X \vdash_{F'}
t_2 :
T_2 ~
|_{F''} ~
C_2
\\ &
F'' = X, F'''
\end{aligned}
}
{
\Gamma \vdash_F
\text{let} ~ x ~ \text{=} ~ t_1 ~ \text{in} ~ t_2 :
T_2 ~
|_{F'''} ~
C_1 \cup C_2 \cup \{T_1 = X\}
}
\quad\text{(CT-Let)} Γ ⊢ F let x = t 1 in t 2 : T 2 ∣ F ′′′ C 1 ∪ C 2 ∪ { T 1 = X } Γ ⊢ F t 1 : T 1 ∣ F ′ C 1 Γ , x : X ⊢ F ′ t 2 : T 2 ∣ F ′′ C 2 F ′′ = X , F ′′′ (CT-Let)
としていました。
ここで、x = i d x = id x = i d なので、文脈を Γ , i d : X \Gamma , id : X Γ , i d : X として t 2 = ( i d i d ) t_2 = (id ~ id) t 2 = ( i d i d ) の型を推論するのですが、どちらの i d id i d も同一の X X X とみなして制約を生成するので、最終的に単一化でエラーというわけです。
こうならないためには、例えば以下のように書けば良いのですが、
let id1 = λx. x in
let id2 = λx. x in
(id1 id2)
型の都合でプログラムが汚れているのでだいぶ嫌です。
うまい解消方法はいろいろあるようで、おそらく最も有名なのがLet多相です。気が向いたら組み込んでみたいですね。
まとめ
型のリハビリをしました。構文解析では、前から気になっていたLR法を実装しました。
型初心者なので、間違っている箇所がありそうです。見つけたら教えていただけると助かります。
それでは!
参考資料