Mercurial > hg > Papers > 2018 > nozomi-master
annotate paper/type.tex @ 78:897fda8e39c5
Reconstruct paper
author | atton <atton@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 08 Feb 2017 14:49:51 +0900 |
parents | 50c2d2f1a186 |
children | c0199291c58e |
rev | line source |
---|---|
28 | 1 \chapter{ラムダ計算と型システム} |
2 \label{chapter:type} | |
77 | 3 |
4 \ref{chapter:type} 章ではCbC の項の形式的な定義の一つとして、部分型を用いて CbC の CodeSegment と DataSegment を定義する。 | |
5 また、型システムの別の利用方法として命題が型で表現できる Curry-Howard 対応を利用した証明が存在するが、その利用方法については\ref{chapter:agda}章で述べる。 | |
6 | |
7 | |
28 | 8 しかし、さらに多くの要素を検証したり無限回の挿入を検証するには状態の抽象化や CbC 側に記号実行の機構を組み込んだり証明を行なう必要がある。 |
9 CbC は直接自身を証明する機構が存在しない。 | |
10 プログラムの性質を証明するには CbC の形式的な定義が必須となる。 | |
30
55f67e448dcc
Add type system description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
28
diff
changeset
|
11 |
55f67e448dcc
Add type system description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
28
diff
changeset
|
12 |
38 | 13 % {{{ 型無し算術式 |
34 | 14 \section{型無し算術式} |
15 まず、型システムやその性質について述べるためにプログラミング言語そのものの基本的な性質について述べる。 | |
40 | 16 プログラムの構文と意味論、推論について考えるために自然数とブール値のみで構成される小さな言語を扱いながら考察する。 |
34 | 17 この言語は二種類の値しか持たないが、項の帰納的定義や証明、評価、実行時エラーのモデル化を表現することができる。 |
18 | |
19 この言語はブール定数 $ true $ と $ false $ 、条件式、数値定数 0 、算術演算子 $ succ $ と $ pred $ 、判定演算子 $ iszero $ のみからなる。 | |
20 算術演算子 $ succ $ は与えられた数の次の数を返し、 $ pred $ はその前の数を返す。 | |
21 判定演算子$ iszero $ は与えられた項が 0 なら $ true $ を返し、それ以外は $ false $ を返す。 | |
22 これらを文法として定義すると以下のリスト\ref{src:expr-term}のようになる。 | |
23 | |
24 \lstinputlisting[label=src:expr-term, caption=算術式の項定義] {src/expr-term.txt} | |
25 | |
26 この定義では算術式の項 $ t $ を定義している。 | |
27 $ ::= $ は項の集合の定義を表であり、$ t $ は項の変数のようなものである。 | |
28 それに続くすべての行は、構文の選択肢である。 | |
29 構文の選択肢内に存在する記号 $ t $ は任意の項を代入できることを表現している。 | |
30 このように再帰的に定義することにより、 \verb/ if (ifzero (succ 0)) then true else (pred (succ 0)) / といった項もこの定義に含まれる。 | |
31 例において、 $ succ $ 、 $ pred $ 、 $ iszero $ に複合的な引数を渡す場合は読みやすさのために括弧でくくっている。 | |
32 括弧の定義は項の定義には含んでいない。 | |
33 コンパイラなど具体的な字句をパースする必要がある場合、曖昧な構文を排除するために括弧の定義は必須である。 | |
34 しかし、今回は型システムに言及するために曖昧な構文は明示的に括弧で指示することで排除し、抽象的な構文のみを取り扱うこととする。 | |
35 | |
36 現在、項と式という用語は同一である。 | |
37 型のような別の構文表現を持つ計算体系においては式はあらゆる種類の構文を表す。 | |
38 項は計算の構文的表現という意味である。 | |
39 | |
40 この言語におけるプログラムとは上述の文法で与えられた形からなる項である。 | |
41 評価の結果は常にブール定数か自然数のどちらかになる。 | |
42 これら項は値と呼ばれ、項の評価順序の形式化において区別が必要となる。 | |
43 | |
44 なお、この項の定義においては \verb/succ true/ といった怪しい項の形成を許してしまう。 | |
45 実際、これらのプログラムは無意味なものであり、このような項表現を排除するために型システムを利用する。 | |
46 | |
47 ある言語の構文を定義する際に、他の表現かいくつか存在する。 | |
48 先程の定義は次の帰納的な定義のためのコンパクトな記法である。 | |
49 | |
50 \begin{definition} | |
51 項の集合とは以下の条件を満たす最小の集合 $ T $ である。 | |
52 \begin{eqnarray*} | |
53 \label{eq:expr} | |
54 \{true , false , 0\} \subseteq T \\ | |
55 t_1 \in T ならば \{succ \; t_1 , pred \; t_1 , iszero \; t_1\} \subseteq T \\ | |
56 t_1 \in T かつ t_2 \in T かつ t_3 \in T ならば if \; t_1 \; then \; t_2 else \; t_3 \subseteq T | |
57 \end{eqnarray*} | |
58 \end{definition} | |
59 | |
60 まず1つめの条件は、$ T $ に属する3つの式を挙げている。 | |
61 2つめと3つめの条件は、ある種の複合的な式が $ T $ に属することを判断するための規則を表している。 | |
62 最後の「最小」という単語は $ T $ がこの3つの条件によって要求される要素以外の要素を持たないことを表している。 | |
63 | |
64 また、項の帰納的表現の略記法として、二次元の推論規則形式を用いる方法もある。 | |
65 これは論理体系を自然演繹スタイルで表現するためによく使われる。 | |
74 | 66 自然演繹による証明は\ref{chapter:agda}章内で触れるが、今回は項表現として導入する。 |
34 | 67 |
68 \begin{definition} | |
36 | 69 項の集合は次の規則によって定義される。 |
70 | |
71 \begin{prooftree} | |
72 \AxiomC{$ true \in T $} | |
73 \end{prooftree} | |
74 | |
75 \begin{prooftree} | |
76 \AxiomC{$ false \in T $} | |
77 \end{prooftree} | |
78 | |
79 \begin{prooftree} | |
80 \AxiomC{$ 0 \in T $} | |
81 \end{prooftree} | |
82 | |
83 \begin{prooftree} | |
84 \AxiomC{$ t_1 \in T $} | |
85 \UnaryInfC{$ succ \; t_1 \in T$} | |
86 \end{prooftree} | |
87 | |
88 \begin{prooftree} | |
89 \AxiomC{$ t_1 \in T $} | |
90 \UnaryInfC{$ pred \; t_1 \in T$} | |
91 \end{prooftree} | |
92 | |
93 \begin{prooftree} | |
94 \AxiomC{$ t_1 \in T $} | |
95 \UnaryInfC{$ iszero \; t_1 \in T$} | |
96 \end{prooftree} | |
97 | |
98 \begin{prooftree} | |
99 \AxiomC{$ t_1 \in T $} | |
100 \AxiomC{$ t_2 \in T $} | |
101 \AxiomC{$ t_3 \in T $} | |
102 \TrinaryInfC{$ if \; t_1 \; then \; t_2 \; else \; t_3 \in T$} | |
103 \end{prooftree} | |
104 | |
34 | 105 \end{definition} |
106 | |
36 | 107 最初の$ true, \; false, \; 0 $の3つ規則は再帰的定義の1つめの条件と同じである。 |
108 それ以外の4つの規則は再帰的定義の2つめと3つめの条件と同じである。 | |
109 それぞれの規則は「もし線の上に列挙して前提が成立するのならば、線の下の結論を導出できる」と読む。 | |
110 $ T $ がこれらの規則を満たす最小の集合である事実は明示的に述べられない。 | |
111 | |
112 言語の構文は定義できたので、次は項がどう評価されるかの意味論について触れていく。 | |
113 意味論の形式化には操作的意味論や表示的意味論、公理的意味論やゲーム意味論などがあるが、ここでは操作的意味論について述べる。 | |
114 操作的意味論とは、言語の抽象機械を定義することにより言語の振舞いを規程する。 | |
115 この抽象機械が示す抽象とは、扱う命令がプロセッサの命令セットなどの具体的なものでないことを表している。 | |
116 単純な言語の抽象機械における状態は単なる項であり、機械の振舞いは遷移関数で定義される。 | |
117 この関数は各状態において項の単純化ステップを実行して次の状態を与えるか、機械を停止させる。 | |
118 ここで項 $ t $ の意味は、$ t $ を初期状態として動き始めた機械が達する最終状態である。 | |
119 | |
120 なお、一つの言語に複数の操作的意味論を与えることもある。 | |
121 例えば、プログラマが扱う項に似た機械状態を持つ意味論の他に、コンパイラの内部表現やインタプリタが扱う意味論を定義する。 | |
122 これらの振舞いが同じプログラムを実行した時に何かしらの意味であれば、結果としてその言語の実装の正しさを証明することに繋がる。 | |
123 | |
124 まずはブール式のみの操作的意味論を定義する。 | |
125 | |
126 \begin{definition} | |
37 | 127 ブール値(B) |
36 | 128 |
38 | 129 項 |
36 | 130 \begin{align*} |
131 t ::= && \text{項} \\ | |
132 true && \text{定数真} \\ | |
133 false && \text{定数偽} \\ | |
134 if \; t \; then \; t \; else \; t && \text{条件式} | |
135 \end{align*} | |
136 | |
137 値 | |
138 \begin{align*} | |
139 v ::= && \text{値} \\ | |
140 true && \text{真} \\ | |
141 false && \text{偽} | |
142 \end{align*} | |
143 | |
144 評価 | |
145 \begin{align*} | |
146 if \; true \; then \; t_2 \; else t_3 \rightarrow t_2 && \text{(E-IFTRUE)} \\ | |
147 if \; false \; then \; t_2 \; else t_3 \rightarrow t_3 && \text{(E-IFFALSE)} \\ | |
148 \AxiomC{$ t_1 \rightarrow t_1'$} | |
149 \UnaryInfC{$ if \; t_1 \; then \; t_2 \; else \; t_3 \rightarrow if \; t_1' \; then t_2 \; else \;t_3 $} | |
150 \DisplayProof | |
151 && \text{(E-IF)} | |
152 \end{align*} | |
37 | 153 |
154 \end{definition} | |
155 | |
156 評価の最終結果になりえる項である値は定数 $ true $ と $ false $ のみである。 | |
157 評価の定義は評価関係の定義である。 | |
158 評価関係 $ t \rightarrow t' $ は「$ t $ が1ステップで $ t' $ に評価される」と読む。 | |
159 直感的には抽象機械の状態が $ t $ ならば $ t' $ が手に入るという意味である。 | |
160 | |
161 評価関係は3つあるが、2つは前提を持たないため、2つの公理と1つの規則から成る。 | |
162 1つめの規則 E-IFTRUE の意味は、評価の対象となる項の条件式が定数 $ true $ である時に、then 節にある $ t_2 $ を残して他の全ての項を捨てるという意味である。 | |
163 E-EIFFALSE も同様に条件式が $ false $ の時に $ t_3 $ のみを残す。 | |
164 3つ目の規則 E-IF は条件式の評価である。 | |
165 条件式 $ t $ が $ t'$ に評価されうるのならば then 節と else 節を変えずに条件部のみを評価する。 | |
166 | |
167 評価の定義から分かることの中に、if の中の then節 と else 節は条件部より先に評価されないことがある。 | |
168 よって、この言語は条件式の評価に対し条件部から評価が優先されるという評価戦略を持つことが分かる。 | |
169 | |
170 \begin{definition} | |
171 推論規則のインスタンスとは、規則の結論や前提に対し、一貫して同じ項による書き換えを行なったものである。 | |
172 \end{definition} | |
173 | |
174 例えば、 | |
47 | 175 $ if \; true \; then \; true \; else \; ( \;if \; false \; then \; false \; else \; false) $ |
176 は E-IFTRUE のインスタンスであり、 E-IFTRUEの $ t_2 $ が \verb/true/ かつ、 | |
177 $ t_3 $ が $ if \; false \; then \; false \; else \; false \;$ の時に相当する。 | |
37 | 178 |
179 \begin{definition} | |
180 1ステップ評価関係 $ \rightarrow $ とは、3つの評価の規則を満たす、項に関する最小の二項関係である。 | |
181 $ (t, \; t') $ がこの関係の元である時、「評価関係式 $ t \rightarrow t'$ は導出可能である」と言う。 | |
36 | 182 \end{definition} |
183 | |
37 | 184 ここで「最小」という言葉が表れるため、評価関係式 $ t \rightarrow t'$ が導出可能である時かつその時に限り、その関係式は規則によって正当化される。 |
185 すなわち評価関係式は公理 E-IFTRUE か E-IFFALSE 、前提が成り立つ時の E-IF のインスタンスとなる。 | |
186 与えられた評価関係式が導出可能であることを証明するには、葉が E-IFTRUE か E-IFFALSE であり、内部ノードのラベルが E-IF のインスタンスである導出木が示せれば良い。 | |
187 例えば以下の略記の元 $ if \; t \; then \; false \; then \; false \rightarrow if \; u \; then \; false \; else \; false $ の導出可能性は以下のような導出木によって示せる。 | |
36 | 188 |
37 | 189 \begin{itemize} |
190 \item $ s = if \; true \; then \; false \; else \; false $ | |
191 \item $ t = if \; s \; then \; true \; else \; true $ | |
192 \item $ u = if \; false \; then \; true \; else \; true $ | |
193 \end{itemize} | |
194 | |
195 | |
196 \begin{prooftree} | |
197 \AxiomC{} | |
198 \RightLabel{E-IFTRUE} | |
199 \UnaryInfC{ $ s \rightarrow true $ } | |
200 \RightLabel{E-IF} | |
201 \UnaryInfC{ $ t \rightarrow u $} | |
202 \RightLabel{E-IF} | |
203 \UnaryInfC{ $ if \; t \; then \; false \; then \; false/ \rightarrow if \; u \; then \; false \; else \; false $} | |
204 \end{prooftree} | |
205 | |
206 1ステップ評価関係は与えられた項に対して抽象機械の状態遷移を定義する。 | |
207 この時、機械がそれ以上ステップを進められない時にそれが最終結果となる。 | |
208 | |
209 \begin{definition} | |
210 正規形 | |
211 | |
212 項 $ t $ が正規形であるとは、$ t \rightarrow t'$となる評価規則が存在しないことである。 | |
213 \end{definition} | |
214 | |
215 この言語において $ true $ や $ false $ は正規形である。 | |
216 逆に言えば、構文的に正しい if が用いられている場合は評価することが可能なため正規形ではない。 | |
217 極端に言えばこの言語における全ての値は正規形なのである。 | |
218 しかし、他の言語における値は一般的に正規形ではない。 | |
219 実のところ、値でない正規形は実行時エラーとなって表れる。 | |
220 | |
40 | 221 実際にこの言語に自然数を導入し、値では無い正規形を確認していく。 |
34 | 222 |
223 | |
38 | 224 \begin{definition} |
225 算術式BN (B の拡張) の項 | |
226 \begin{align*} | |
227 t ::= && \text{項} \\ | |
228 true && \text{定数真} \\ | |
229 false && \text{定数偽} \\ | |
230 if \; t \; then \; t \; else \; t && \text{条件式} \\ | |
231 0 && \text{定数ゼロ} \\ | |
232 succ \; t && \text{後者値} \\ | |
233 pred \; t && \text{前者値} \\ | |
234 iszero \; t && \text{ゼロ判定} | |
235 \end{align*} | |
236 \end{definition} | |
237 | |
238 \begin{definition} | |
239 算術式BN の値 | |
240 \begin{align*} | |
241 v ::= && \text{値} \\ | |
242 true && \text{真} \\ | |
243 false && \text{偽} \\ | |
244 nv && \text{数値} \\ | |
245 \end{align*} | |
246 \end{definition} | |
247 | |
248 \begin{definition} | |
249 算術式BNの数値 | |
250 \begin{align*} | |
251 nv ::= && \text{数値} \\ | |
252 0 && \text{ゼロ} \\ | |
253 succ nv && \text{後者値} | |
254 \end{align*} | |
255 \end{definition} | |
256 | |
257 \begin{definition} | |
258 算術式BNの評価($ t \rightarrow t' $) | |
259 \begin{align*} | |
260 if \; true \; then \; t_2 \; else t_3 \rightarrow t_2 && \text{(E-IFTRUE)} \\ | |
261 if \; false \; then \; t_2 \; else t_3 \rightarrow t_3 && \text{(E-IFFALSE)} \\ | |
262 \AxiomC{$ t_1 \rightarrow t_1'$} | |
263 \UnaryInfC{$ if \; t_1 \; then \; t_2 \; else \; t_3 \rightarrow if \; t_1' \; then t_2 \; else \;t_3 $} | |
264 \DisplayProof && \text{(E-IF)} \\ | |
265 \AxiomC{$ pred \; 0 \rightarrow 0$} | |
266 \DisplayProof && \text{(E-PREDZERO)} \\ | |
267 \AxiomC{$ pred \; (succ \; nv_1) \rightarrow nv_1$} | |
268 \DisplayProof && \text{(E-PREDSUCC)} \\ | |
269 \AxiomC{$ t_1 \rightarrow t_1'$} | |
270 \UnaryInfC{$ pred \; t_1 \rightarrow pred \; t_1'$} | |
271 \DisplayProof && \text{(E-PRED)} \\ | |
272 \AxiomC{$ iszero \; 0 \rightarrow true$} | |
273 \DisplayProof && \text{(E-ISZEROZERO)} \\ | |
274 \AxiomC{$ iszero \; (succ \; nv_1) \rightarrow false$} | |
275 \DisplayProof && \text{(E-ISZEROSUCC)} \\ | |
276 \AxiomC{$ t_1 \rightarrow t_1'$} | |
277 \UnaryInfC{$ iszero \; t_1 \rightarrow iszero \; t_1'$} | |
278 \DisplayProof && \text{(E-ISZERO)} \\ | |
279 \end{align*} | |
280 \end{definition} | |
281 | |
282 今回値の定義に数値を表す構文要素が追加されている。 | |
283 数は0かある数に後者関数を適用したもののどちらかである。 | |
284 評価規則 E-PREDZERO、E-PREDSUCC、E-ISZEROZERO、E-ISZEROSUCC は演算 \verb/pred/ と \verb/iszero/ が数に適用された時にどう振る舞うかを定義している。 | |
285 E-SUCC 、 E-PRED 、 E-ISZERO の合同規則も E-IF のように部分項から先に評価することを示している。 | |
286 | |
287 数値の構文要素(nv)はこの定義によって重要な役割をはたす。 | |
288 例えば、 E-PREDSUCC 規則が適用できる項は任意の項 $ t $ ではなく数値 $nv_1$である。 | |
289 これは $ pred \; (succ \; (pred \; 0)) $ を $ pred 0 $ に評価できないことを意味する。 | |
290 なぜなら $ pred \; 0 $ は数値に含まれないからである。 | |
291 | |
292 ここで言語の操作的意味論について考える時、すべての項に関する振舞いを定義する必要がある。 | |
293 すべての項には $ pred \; 0 $ や $ succ false $ のような項も含まれる。 | |
294 しかし、 $ succ $ を $ false $ に適用する評価結果は定義されていないため、 $ succ \; false $ は正規形である。 | |
295 このような、正規形であるが値でない項は行き詰まり状態であるという。 | |
296 つまり、実行時エラーとは行き詰まり状態の項を指す。 | |
297 直感的な解釈としてはプログラムが無意味な状態になったこと示しておい、操作的意味論が次に何も行なえないことを特徴付けているのである。 | |
298 プログラング言語において実行時エラーはセグメンテーションフォールトや不正な命令などいくつかのものが挙げられるが、型システムを考える際にはこれらのエラーは行き詰まり状態という単一の概念で表す。 | |
299 | |
300 % }}} | |
34 | 301 |
41 | 302 % {{{ 単純型 |
303 | |
40 | 304 \section{単純型} |
305 先程定義した算術式には $ pred \; false $ のようなこれ以上評価できない行き詰まり状態が存在する。 | |
306 項を実際に評価する前に評価が行き詰まり状態にならないことを保証したい。 | |
307 そのために、自然数に評価される項とブール値に評価される項とを区別する必要がある。 | |
308 項を分類するために2つの型 Nat と Bool を定義する。 | |
309 | |
310 ここで、項$t$が型 $T$を持つ、という表現を用いた場合、$t$を評価した結果が明らかに適切な形の値になることを意味する。 | |
311 明らかに、という意味は項を実行することなく静的に分かるという意味である。 | |
312 例えば項 $ if \; true \; then \; false \; else \; true $ は Bool 型を持ち、$ pred \; (succ \; (succ \; 0)) $ はNat 型を持つ。 | |
313 しかし、項の型の分析は保守的であり、$ if \; true \; then \; 0 \; else \; false $ のような項は実際には行き詰まりにならないが型を持てない。 | |
314 | |
315 算術式のための型付け関係は $ t : T $ と書き、項に型を割り当てる推論規則の集合によって定義される。 | |
316 具体的な数値とブール値に関する拡張は以下である。 | |
317 | |
318 \begin{definition} | |
319 NB(型付き) の新しい構文形式 | |
320 \begin{align*} | |
321 T ::= && \text{型 :} \\ | |
322 Bool && \text{ブール型} \\ | |
323 Nat && \text{自然数型} \\ | |
324 \end{align*} | |
325 \end{definition} | |
326 | |
327 | |
328 \begin{definition} | |
329 NB(型付き)の型付け規則 | |
330 \begin{align*} | |
331 true : Bool && \text{T-TRUE} \\ | |
332 false : Bool && \text{T-FALSE} \\ | |
333 \AxiomC{$t_1 : Bool$} | |
334 \AxiomC{$t_2 : T$} | |
335 \AxiomC{$t_3 : T$} | |
336 \TrinaryInfC{$if \; t_1 \; then \; t_2 \; else \; t_3 : T$} | |
337 \DisplayProof && \text{T-IF} \\ | |
338 0 : Nat && \text{T-ZERO} \\ | |
339 \AxiomC{$t_1 : Nat$} | |
340 \UnaryInfC{$ succ \; t_1 : Nat $} | |
341 \DisplayProof && \text{T-SUCC} \\ | |
342 \AxiomC{$t_1 : Nat$} | |
343 \UnaryInfC{$ pred \; t_1 : Nat $} | |
344 \DisplayProof && \text{T-PRED} \\ | |
345 \AxiomC{$t_1 : Nat$} | |
346 \UnaryInfC{$ iszero \; t_1 : Bool $} | |
347 \DisplayProof && \text{T-BOOL} | |
348 \end{align*} | |
349 \end{definition} | |
350 | |
351 T-TRUE と T-FALSE はブール定数に Bool 型を割り当てている。 | |
352 T-IFは条件式の部分にBool型を、部分式に関しては同じ型を要求している。 | |
353 これは同じ変数 $ T $ を二回使用することで制約を表している。 | |
354 | |
355 また、数に関しては T-ZERO は Nat 型を $ 0 $ に割り当てている。 | |
356 T-SUCC と T-PRED は $ t_1 $ が Nat である時に限り Nat 型となる。 | |
357 同様に、 T-ISZERO は $ t_1 $ が Nat である時に Bool となる。 | |
358 | |
359 \begin{definition} | |
360 算術式のための型付け関係とは、NBにおける規則のすべてのインスタンスを満たす、項と型の二項関係である。 | |
361 項$ t $ に対してある型 $ T $ が存在して $ t : T $ である時、 $ t $ は型付け可能である(または正しく型付けされている)という。 | |
362 \end{definition} | |
363 | |
41 | 364 型推論をを行なう時、$succ t_1$という項が何らかの型を持つならばそれは Nat 型である、といった言及を行なう。 |
365 型付け関係を逆転させた補題を定義することで型推論の基本的なアルゴリズムを考えることができる。 | |
366 なお、逆転補題は型付け関係の定義により直ちに成り立つ。 | |
367 | |
368 \begin{lemma} | |
369 型付け関係の逆転 | |
370 \begin{enumerate} | |
371 \item $ true : R $ ならば $ R = Bool $ である | |
372 \item $ false : R $ ならば $ R = Bool $ である | |
373 \item $ if \; t_1 \; then \; t_2 \; else \; t_3 : R $ ならば $ t_1 : Bool $ かつ $ t_2 : R $ かつ $ t_3 : R $ である。 | |
374 \item $ 0 : R $ ならば $ R = Nat $ である | |
375 \item $ succ \; t_1 : R $ ならば $ R = Nat $ かつ $ t_1 : Nat $ である | |
376 \item $ pred \; t_1 : R $ ならば $ R = Nat $ かつ $ t_1 : Nat $ である | |
377 \item $ iszero \; t_1 : R $ ならば $ R = Bool $ かつ $ t_1 : Nat $ である | |
378 \end{enumerate} | |
379 \end{lemma} | |
380 | |
381 逆転補題は型付け関係のための生成補題と呼ばれることもある。 | |
382 なぜならば、与えられた型付け判断式に対してその証明がどのように生成されたかを示すからである。 | |
383 | |
40 | 384 型無し算術式の評価導出のように型付けも導出可能であり、それも規則のインスタンスの木である。 |
385 型付け関係に含まれる二つ組 $(t, \; T)$は $ t : T $ を結論とする型付け導出により正当化される。 | |
386 例えば $ if \; (iszero \; 0) \; then \; 0 \; else \; (pred \; 0) : Nat $ の型付け判断の導出木である。 | |
387 | |
388 \begin{prooftree} | |
389 \AxiomC{} | |
390 \RightLabel{T-ZERO} | |
391 \UnaryInfC{$ 0 : Nat$} | |
392 \RightLabel{T-ISZERO} | |
393 \UnaryInfC{$ iszero \; 0 : Bool$} | |
394 \AxiomC{} | |
395 \RightLabel{T-ZERO} | |
396 \UnaryInfC{$ 0 : Nat$} | |
397 \AxiomC{} | |
398 \RightLabel{T-ZERO} | |
399 \UnaryInfC{$ 0 : Nat$} | |
400 \RightLabel{T-PRED} | |
401 \UnaryInfC{$ pred \; 0 : Bool$} | |
402 \RightLabel{T-IF} | |
403 \TrinaryInfC{ if \; (iszero \; 0) \; then \; 0 \; else \; (pred \; 0) : Nat } | |
404 \end{prooftree} | |
405 | |
41 | 406 項その型付けの定義より、型システムが行き詰まり状態にならないことを示す。 |
407 その証明は指向定理と保存定理によって証明する。 | |
408 | |
409 \begin{itemize} | |
410 \item 進行とは、正しく型付けされた項は行き詰まり状態では無いことである | |
411 \item 保存とは、評価可能な正しく型付けされた項は評価後も正しく型付けされていることである。 | |
412 \end{itemize} | |
413 | |
414 型システムがこれらの性質を持つ時、正しく型付けされた項は行き詰まり状態になりえない。 | |
415 | |
416 進行定理の証明の為に Bool 型と Nat 型の標準形(それらの型を持つ正しく型付けされた値)を示す。 | |
417 | |
418 \begin{lemma} | |
419 標準形 | |
420 | |
421 \begin{enumerate} | |
422 \item $ v $ が $Bool$ 型の値ならば $v$ は $true$ または $false$ である。 | |
423 \item $v$ が $Nat$ 型の値ならば、$0$ もしくは $Nat$ に対して $succ$ を適用した値である。 | |
424 \end{enumerate} | |
425 \end{lemma} | |
426 | |
427 標準形の証明に関しては値における構造的帰納法を用いる。 | |
428 この言語における値とは $ true $ と $false $ と $ 0$ と $ succ \; nv$ のいずれかの形をしている。 | |
429 Bool型に関して注目した時、 $ true $ と $ false $ は定義によって正しい。 | |
430 $ 0 $ と $ succ \; nv $ に関しては逆転補題より Nat 型を持つため、Bool型を持つ値は $ true $ と $ false $ のどちらかとなる。 | |
431 Nat についても同様である。 | |
432 | |
433 \begin{theorem} | |
434 進行 | |
435 | |
436 $ t$ が正しく型付けされたと仮定すると、$ t$ は値であるか、またはある $t'$ が存在して$ t \rightarrow t' $ となる。 | |
437 \end{theorem} | |
438 | |
439 証明は $ t : T $ の導出に関する帰納法による。 | |
440 T-TRUE 、 T-FALSE 、 T-ZERO の場合は$t$が値であることより成立する。 | |
441 | |
442 T-IF の場合、帰納法の仮定により $ t1 $ は値であるか、$t_1'$ が存在して $ t_1 \rightarrow t_1'$ を満たす。 | |
443 $ t_1 $ が値ならば、標準形補題により $ true $ か $ false $ であり、その場合は E-IFTRUE か E-IFFALSE が適用可能である。 | |
444 一方 $ t_1 \rightarrow t_1' $ ならば E-IF が適用できる。 | |
445 | |
446 T-SUCC の場合も帰納法の仮定により $ t1 $ は値であるか、$t_1'$ が存在して $ t_1 \rightarrow t_1'$ を満たす。 | |
447 $ t_1 $ が値ならば標準形補題により数値でなければならず、その場合 $ t $ も数値であるため成り立つ。 | |
448 一方 $ t_1 \rightarrow t_1' $ ならば E-SUCC が適用できる。 | |
449 | |
450 T-SUCC の場合も同様で、 $ t_1 $ が値ならば標準形補題により数値でなければならず、その場合 E-PREDZERO か E-PREDSUCC が使える。 | |
451 $ t_1 \rightarrow t_1' $ ならば E-PRED が適用できる。 | |
452 | |
453 T-ISZERO の場合も値ならば標準形補題により $ t_1 $ は数値であり、どちらの場合でも E-ISZEROZERO と E-ISZEROSUCC が適用できる。 | |
454 $ t_1 \rightarrow t_1' $ ならば E-ISZERO が適用できる。 | |
455 | |
456 \begin{theorem} | |
457 保存 | |
458 | |
459 $ t : T $ かつ $ t \rightarrow t' $ ならば $ t' : T $ となる。 | |
460 \end{theorem} | |
461 | |
462 保存定理も $ t : T $ の導出に関する帰納法によって導ける。 | |
463 帰納法の各ステップにおいて全ての部分導出に関して所望の性質が成り立つと仮定し、導出の最後の規則についての場合分けで証明を行なう。 | |
464 | |
465 導入の最後の規則がT-TRUE の場合、その規則の形から $ t $ は定数 $ true $ でなければならず、 $ T $ は $ Bool$ となる。 | |
466 そして $ t $ は値であるためにどのような $ t' $ も存在せず、定理の要求は満たされる。 | |
467 T-FALSE と T-ZERO の場合も同様である。 | |
468 | |
469 導入の最後の規則 T-IF の場合は、$ t $ はある $ t_1, \; t_2 \; t_3 $ に対して $ if \; t_1 then t_2 else t_3 $ という形となる。 | |
470 さらに $ t_1 : Bool $ と $ t_2 : T $ と $ t_3 : T $ となる部分導出がある。 | |
471 ここで if を持つ評価規則において $ t \rightarrow t'$ を導入できる規則は E-IFTRUE と E-IFFALSE と E-IF のみである。 | |
472 それぞれの場合について別々に場合分けをして考える。 | |
473 | |
474 \begin{itemize} | |
475 \item E-IFTRUE の場合(E-IFFALSE も同様) | |
476 | |
477 $ t \rightarrow t' $ が E-IFTRUE を使った導出ならば、 $ t_1$ は $ true $ であり、結果の項 $ t' $ は $ t_2 $ となる。 | |
478 このことより $ t_2 : T $ であることが分かるため、条件を満たす。 | |
479 | |
480 \item E-IF の場合 | |
481 | |
482 場合分け T-IF の仮定より $ t_1 : Bool $が結論となる、部分導出が得られる。 | |
483 帰納法の仮定を部分導出に適用して $ t_1' : Bool $ とし、 $ t_2 : T $ と $ t_3 : T $ を合わせると規則 T-IF が適用できる。 | |
484 T-IF を適用すると $ if \; t_1' \; then \; t_2 \; else \; t_3$となり、$ t' : T $ が成り立つ。 | |
485 \end{itemize} | |
486 | |
487 T-SUCC が導入の最後であれば、 $ t \rightarrow t'$ を導くためには E-SUCC のみであり、この形から $ t_1 \rightarrow t_1'$が分かる。 | |
488 $ t_1 : Nat $ であることも分かるため、帰納法の仮定より $ t_1' : Nat $ が得られる。 | |
489 この時 T-SUCC が適用できるため $ succ \; t_1 : Nat$となって $ t' : T $ が成り立つ。 | |
490 T-PRED も同様である。 | |
491 | |
492 % }}} | |
40 | 493 |
32 | 494 % {{{ 型なしラムダ計算 |
30
55f67e448dcc
Add type system description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
28
diff
changeset
|
495 \section{型なしラムダ計算} |
38 | 496 計算とは何か、エラーとは何か、を算術式を定義することによって示してきた。 |
41 | 497 また、型を導入することにより行き詰まり状態を回避することも示した。 |
38 | 498 ここで、プログラミング言語における計算を形式的に定義していく。 |
74 | 499 プログラミング言語は複雑だが、その計算はある本質的な仕組みからの派生形式として定式化可能であることを Peter Ladin が示した~\cite{Landin64}。 |
38 | 500 この時 Landin が使った本質的な仕組みとしての核計算がラムダ計算であった。 |
74 | 501 ラムダ計算は Alonzo Church が発明した形式的体系の一つである~\cite{GlossarWiki:Church:1941}。 |
31 | 502 ラムダ計算では全ての計算が関数定義と関数適用の基本的な演算に帰着される。 |
503 ラムダ計算はプログラミング言語の機能の仕様記述や、言語設計と実装、型システムの研究に多く使われている。 | |
504 この計算体系の重要な点は、ラムダ計算内部で計算が記述できるプログラミング言語であると同時に、それ自身について厳格な証明が可能な数学的対象としてみなせる点にある。 | |
28 | 505 |
31 | 506 ラムダ計算はいろいろな方法で拡張できる。 |
507 数や組やレコードなどはラムダ計算そのもので模倣することができるが、記述が冗長になってしまう。 | |
508 それらの機能のための具体的な特殊構文を加えることは言語の利用者の視点で便利である。 | |
509 他にも書き換え可能な参照セルや非局所的な例外といった複雑な機能を表現することもできるが、膨大な変換を用いなければモデル化できない。 | |
74 | 510 それの機能を言語として備えた拡張に ML や Haskell~\cite{haskell-sigplan} といったものがある。 |
31 | 511 |
512 ラムダ計算(または $ \lambda $ 計算) とは、関数定義と関数適用を純粋な形で表現する。 | |
513 ラムダ計算においてはすべてが関数である。 | |
514 関数によって受け付ける引数も関数であり、関数が返す結果もまた関数である。 | |
515 | |
516 ラムダ計算の項は変数と抽象と適用の3種類の項からなり、以下の文法に要約される。 | |
517 変数 $ x $ は項であり、項 $ t_1 $ から変数 $ x $ を抽象化した $ \lambda x . t_1 $ も項であり、項 $ t_1 $ を他の項 $ t_2 $ に適用した $ t_1 t_2 $ も項である。 | |
518 | |
519 \begin{multline*} | |
520 t ::= \\ | |
521 x \\ | |
522 \lambda x . t \\ | |
523 t \, t \\ | |
524 \end{multline*} | |
525 | |
526 ラムダ計算において関数適用は左結合とする。 | |
527 つまり、 $ s \, t \, u $ は $ (s \, t) \, u $ となる。 | |
528 | |
529 また、抽象の本体はできる限り右側へと拡大する。 | |
47 | 530 例えば $ \lambda x . \; \lambda y . \; x \, y \, x $ は$ \lambda x . (\lambda . y ((x \, y) \, x)) $ となる。 |
31 | 531 |
532 ラムダ計算には変数のスコープが存在する。 | |
533 抽象 $ \lambda x . t $ の本体 $ t $ の中に変数 $ x $ がある時、 $ x $ の出現は束縛されていると言う。 | |
534 同様に、 $ \lambda x $ は $ t $ をスコープとする束縛子であると言う。 | |
535 なお、 $ x $ を囲む抽象によって束縛されていない場所の $ x $ の出現は自由であると言う。 | |
536 例えば $ x \; y $ や $ \lambda y . \; x \; y $ における $ x $ の出現は自由だが、 $ \lambda x . x $ や $ \lambda z . \lambda x . \lambda y . x (y \; z) $ における $ x $ の出現は束縛されている。 | |
537 $ (\lambda x . x) \;x $ においては、最初の $ x $ の出現は束縛されているが、2つ目の出現は自由である。 | |
538 | |
539 ラムダ計算において、計算とは引数に対する関数の適用である。 | |
540 抽象に対して項を適用した場合、抽象の本体に存在する束縛変数に適用する項を代入したもので書き換える。 | |
541 図式的には | |
542 | |
543 \begin{equation*} | |
544 (\lambda x . t_{12}) t_2 \rightarrow [ x \mapsto t_2] t_{12} | |
545 \end{equation*} | |
546 | |
547 と記述する。 | |
548 ここで $ [ x \mapsto t_2] t_{12} $ とは、$ t_12 $ 中の自由な $ x $ を全て $ t_2 $ で置換した項を意味する。 | |
549 例えば、 $ (\lambda x . x) \; y $ は $ y $ となり、項 $ (\lambda x . x (\lambda x . x)) (y \; z) $ は $ y \; z \; (\lambda x . x) $ となる。 | |
550 | |
551 なお、 $ (\lambda x . t_{12}) t_2 $ という形の項を簡約基(redex, reducible expression) と呼び、上記の規則で簡約基を置換する操作をベータ簡約と呼ぶ。 | |
552 ラムダ計算のための評価戦略には数種類の戦略がある。 | |
553 | |
554 \begin{itemize} | |
555 \item 完全ベータ簡約 | |
556 | |
557 任意の簡約基がいつでも簡約されうる。 | |
558 つまり項の中からどの順番で簡約しても良い。 | |
559 | |
560 \item 正規順序簡約 | |
561 | |
562 最も左で最も外側の簡約基が最初に簡約される。 | |
563 | |
564 \item 名前呼び | |
565 | |
566 正規順序の中でも抽象の内部での簡約を許さない。 | |
567 名前呼びの変種は Algol-60 や Haskell で利用されている。 | |
568 なお、Haskell においては必要呼びという最適化された変種を利用している。 | |
569 | |
570 \item 値呼び | |
571 | |
572 ほとんどの言語はこの戦略を用いている。 | |
573 基本的には最も左の簡約基をを簡約するが、右側が既に値(計算が終了してもう簡約できない閉じた項)になっている簡約基のみを簡約する。 | |
574 \end{itemize} | |
575 | |
576 値呼び戦略は関数の引数が本体で使われるかに関わらず評価され、これは正格と呼ばれる。 | |
577 名前呼びなどの非正格な戦略は引数が使われる時のみ評価され、これは遅延評価とも呼ばれる。 | |
578 | |
579 ラムダ計算において、複数の引数は、関数を返り値として返す高階関数として定義できる。 | |
32 | 580 項 $ s $ が二つの自由変数 $ x $ と $ y $ を含むとすれば、 $ \lambda x . \lambda y . s $ と書くことで二つの引数を持つ関数を表現できる。 |
581 これは $ x $ に $ v $ が与えられた時、$ y $ を受けとり、 $ s $ の抽象内の自由な $ x $ を $ v $ に置き換えた部分を置換する関数、を返す。 | |
582 例えば $ (\lambda x . \lambda y . s) \; v \; w $ は $ (\lambda y . [x \mapsto v] s) w $ に簡約され、 $ [y \mapsto w][x \mapsto v]s $ に簡約される。 | |
583 なお、複数の引数を取る関数を高階関数に変換することはカリー化と呼ばれる。 | |
584 | |
50
451c510825de
Add natural deduction and curry-howard isomorphism
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
48
diff
changeset
|
585 % TODO: ラムダの再帰とかペアとかの解説 直積直和 |
39 | 586 |
587 ラムダ計算の帰納的な項は以下のように定義される。 | |
588 | |
589 \begin{definition} | |
590 $ V $ を変数名の加算集合とする。項の集合は以下を満たす最小の集合 $ T $ である。 | |
591 | |
592 \begin{eqnarray*} | |
593 任意の x \in V について x \in T \\ | |
594 t_1 \in T かつ x in V ならば \lambda x . t \in T \\ | |
595 t_1 \in T かつ t_2 \in T ならば t_1 \; t_2 \in T | |
596 \end{eqnarray*} | |
597 \end{definition} | |
598 | |
599 また、形式的な自由変数の定義を与える。 | |
600 | |
601 \begin{definition} | |
602 項 $ t $ の自由変数の集合は $ FV(t)$と書き、以下のように定義される。 | |
603 | |
604 \begin{eqnarray*} | |
605 FV(x) = \{ x \} \\ | |
606 FV(\lambda . t_1 x) = FV(t_1) \setminus \{ x \} \\ | |
607 FV(t_1 \; t_2) = FV(t_1) \cup FV(t_2) | |
608 \end{eqnarray*} | |
609 \end{definition} | |
610 | |
611 記号 $ \setminus $ は集合に対する二項演算子であり、$ S \setminus T := {x \in S : x \notin T}$ である。 | |
612 つまり、$ t_1 $の内部の自由変数の集合から $ x $ を抜いた集合である。 | |
613 | |
614 最後に代入について定義する。 | |
32 | 615 代入の操作は直感的には置換であるが、変数の束縛に注意しなくてはならない。 |
616 例えば抽象への代入を以下のように定義する。 | |
617 | |
618 \begin{equation*} | |
619 [ x \mapsto s ] (\lambda y . t_1) = \lambda y . [ x \mapsto s] t_1 | |
620 \end{equation*} | |
621 | |
622 この場合、束縛変数の名前によっては定義が破綻してしまう。例えば以下のようになる。 | |
623 | |
624 \begin{equation*} | |
625 [x \mapsto y](\lambda x . x) = \lambda x . y | |
626 \end{equation*} | |
627 | |
628 $ \lambda $ よって束縛されているはずの $ x $ が書き変わっている。 | |
629 これはスコープとして振る舞っていないので誤っている。 | |
630 この問題は項 $ t $ 内の変数 $ x $ の自由な出現と束縛された出現を区別しなかったために出現した誤りである。 | |
631 | |
632 そこで、$ x $ を束縛する項に対しては置換行なわないように定義を変える。 | |
633 | |
634 \begin{itemize} | |
635 \item $ y = x $ の場合 | |
636 \begin{equation*} | |
637 [ x \mapsto s ] (\lambda y . t_1) = \lambda y . t_1 | |
638 \end{equation*} | |
639 | |
640 \item $ y \neq x $ の場合 | |
641 \begin{equation*} | |
642 [ x \mapsto s ] (\lambda y . t_1) = \lambda y . [ x \mapsto s] t_1 | |
643 \end{equation*} | |
644 \end{itemize} | |
645 | |
646 この場合は束縛された変数を上書きしないが、逆に自由変数を束縛するケースが発生する。 | |
647 具体的には以下である。 | |
648 | |
649 \begin{equation*} | |
650 [ x \mapsto z] (\lambda z . x) = \lambda z . z | |
651 \end{equation*} | |
652 | |
653 項 $ s $ 中の自由変数が項 $ t $ に代入されて束縛される現象は変数捕獲と呼ばれる。 | |
654 これを避けるためには $ t $ の束縛変数の名前が $ s $ の自由変数の名前と異なることを保証する必要がある。 | |
655 変数捕獲を回避した代入操作は捕獲回避代入と呼ばれる。 | |
33
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
656 代入における名前の衝突を回避するために項の束縛変数の名前を一貫して変更することで変数捕獲を回避する方法も存在する。 |
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
657 束縛変数の名前を一貫して変更することをアルファ変換と呼ばれる。 |
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
658 これは関数抽象に対する束縛変数は問わないという直感からくるもので、 $ \lambda x . x $ も $ \lambda y . y $ も振舞いとしては同じ関数であるとみなすものである。 |
32 | 659 捕獲回避の条件を追加した代入の定義は以下のような定義となる。 |
660 | |
661 \begin{itemize} | |
662 \item 変数への代入 | |
663 | |
664 \begin{equation*} | |
665 [ x \mapsto s ] x = s | |
666 \end{equation*} | |
667 | |
668 \item 存在しない変数への代入($ y \neq x $ の時) | |
669 | |
670 \begin{equation*} | |
671 [ x \mapsto s ] y = y | |
672 \end{equation*} | |
673 | |
674 \item 抽象内の項への代入($ y \neq x $ かつ $ y $ が $ s $ の自由変数でない) | |
675 | |
676 \begin{equation*} | |
677 [ x \mapsto s ] (\lambda y . t_1) = \lambda y . [ x \mapsto s] t_1 | |
678 \end{equation*} | |
679 | |
680 \item 適用への代入 | |
681 | |
682 \begin{equation*} | |
683 [x \mapsto s] (t_1 \; t_2) = (t_1[x\mapsto s])([x \mapsto s] t_2) | |
684 \end{equation*} | |
685 | |
686 \end{itemize} | |
687 | |
688 この定義は少なくとも代入が行なわれる際には正しく代入が行なえる。 | |
33
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
689 さらに、抽象が束縛している変数を名前では無く数字として扱う名無し表現も存在する。 |
74 | 690 これは De Brujin 表現~\cite{DEBRUIJN1972381}と呼ばれ、コンパイラ内部などでの項表現として用いられる。 |
32 | 691 |
39 | 692 最終的な型無しラムダ計算 $ \lambda $ の項の定義と評価の要約を示す。 |
693 | |
694 \begin{definition} | |
695 $ \rightarrow $ (型無し) | |
696 | |
697 項 | |
698 \begin{align*} | |
699 t ::= && \text{項} \\ | |
700 \lambda x . t && \text{ラムダ抽象} \\ | |
701 t \; t && \text{関数適用} | |
702 \end{align*} | |
703 | |
704 値 | |
705 \begin{align*} | |
706 v ::= && \text{値} \\ | |
707 \lambda x . t && \text{ラムダ抽象値} | |
708 \end{align*} | |
709 | |
710 評価( $ t \rightarrow t' $) | |
711 | |
712 \begin{align*} | |
713 \AxiomC{$ t_1 \rightarrow t_1'$} | |
714 \UnaryInfC{$t_1 \; t_2 \rightarrow t_1' t_2$} | |
715 \DisplayProof && \text{E-APP1} \\ | |
716 \AxiomC{$ t_2 \rightarrow t_2'$} | |
717 \UnaryInfC{$v_1 \; t_2 \rightarrow v_1 t_2'$} | |
718 \DisplayProof && \text{E-APP2} \\ | |
719 (\lambda x . t_{12}) \; v_2 \rightarrow [ x \mapsto v_2] t_{12} | |
720 && \text{E-APPABS} | |
721 \end{align*} | |
722 \end{definition} | |
32 | 723 |
33
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
724 項は変数かラムダ抽象か関数適用の3つにより構成される。 |
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
725 また、ラムダ抽象値は全て値である。 |
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
726 加えて評価は関数適用を行なう E-APPABS 計算規則と、適用の項を書き換える E-APP1 と E-APP2 合同規則により定義される。 |
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
727 |
39 | 728 この定義からも評価戦略と評価順序が分かる。 |
729 関数を適用する E-APPABS は左側が抽象であり、右側が値である $v_2$ の時にしか適用されない。 | |
730 逆に、規則 E-APP1 の$t_1$は任意の項にマッチするため関数部分が値でない関数適用に用いる。 | |
731 一方、E-APP2 は左辺が値であるようになるまで評価されない。 | |
732 よって、関数適用 $ t_1 \; t_2 $ の評価順は、まずE-APP1を用いて$t_1$が値となった後にE-APP2を用いて$t_2$を値とし、最後にE-APPABSで関数を適用を行なう。 | |
33
74a29a48575a
Update lambda description
atton <atton@cr.ie.u-ryukyu.ac.jp>
parents:
32
diff
changeset
|
733 |
32 | 734 |
735 % }}} | |
28 | 736 |
43 | 737 % {{{ 単純型付きラムダ計算 |
738 | |
28 | 739 \section{単純型付きラムダ計算} |
42 | 740 型無しラムダ計算に対して単純型を適用する場合、ラムダ抽象の型について考える必要がある。 |
741 ラムダ抽象は値を取って値を返すため、関数として考えることもできる。 | |
742 差し当たりBool型における関数の型を $ \lambda x . t : \rightarrow $ と定義する。 | |
743 この定義においては $ \lambda x . true $ についても $\lambda x . \lambda y . y $ のような型も同一の型を持つ。 | |
744 この二つの項は値を適用すると値を返すという点では同じであるが、前者は $ true $ を返し、後者は $ \lambda y . y $ を返す。 | |
745 これでは関数を適用した際に返す値の型は関数の型から予測できず、加えてどの値に対して適用可能かも分からない。 | |
746 そのために引数にどのような型を期待しているのか、正しい型の値を適用するとどの型の値を返すのかを型情報に追加する。 | |
747 具体的には以下のように $ \rightarrow $ を $ T_1 \rightarrow T_2 $ の形をした無限の型の族に置き換える。 | |
748 | |
749 \begin{definition} | |
750 型 Bool 上の単純型の集合は次の文法により生成される。 | |
751 | |
752 \begin{align*} | |
753 t ::= && 型 : \\ | |
754 T \rightarrow T && 関数の型 \\ | |
755 Bool && ブール値型 | |
756 \end{align*} | |
757 \end{definition} | |
758 | |
759 なお、型構築子 $ \rightarrow $ は右結合である。 | |
760 つまり $ T_1 \rightarrow T_2 \rightarrow T_3 $ は$ T_1 \rightarrow (T_2 \rightarrow T_3) $となる。 | |
761 | |
762 $ \lambda x . t $ に対して型を割り当てる時、明示的に型付けする方法と暗黙的に型付けする方法がある。 | |
763 明示的に型付けを行なう場合はプログラマが項に型の注釈を記述する。 | |
764 暗黙的に型付けを行なう場合は型検査器に情報を推論させ、型を再構築させる。 | |
765 型推論は $ \lambda $ 計算の文献内では型割り当て体系と呼ぶこともある。 | |
766 今回は明示的に型を指定する方法を取る。 | |
767 | |
768 $ \lambda $ 抽象の引数の型が分かれば、結果の型は本体 $ t_2 $となる。 | |
769 ここで、$ t_2 $内における $ x $ の出現は型 $ T_1 $ の項を表すと仮定する必要がある。 | |
770 これは引数に対して正しい型の値が渡されたにも関わらず抽象内で異なる型として振る舞うのを禁止するためである。 | |
771 この $ \lambda $ 抽象の型付けは以下の T-ABS によって定義される。 | |
772 | |
773 | |
774 \begin{align*} | |
775 \AxiomC{$x : T_1 \vdash t_2 : T_2$} | |
776 \UnaryInfC{$ \vdash \lambda x : T_1 . t_2 : T_1 \rightarrow T_2$} | |
777 \DisplayProof && \text{T-ABS} | |
778 \end{align*} | |
779 | |
780 項は抽象を入れ子で持つ可能性があるため、引数の仮定は複数持ちうる。 | |
781 このため型付け関係は二項関係 $ t : T $ から、三項関係 $ \Gamma \vdash t : T $ となる。 | |
782 ここで $ \Gamma $ とは $ t $ に表われる自由変数の型の仮定の集合である。 | |
783 $ \Gamma $ は型付け文脈や型環境と呼ばれ、$ \Gamma \vdash t : T $ は「型付け文脈 $ \Gamma $ において項 $ t$ は型$T$を持つ」と読む。 | |
784 空の文脈は $ \emptyset$ と書かえることもあるが、通常は省略して $ \vdash t : T $ と書く。 | |
785 また、型環境に対する $ , $ 演算子は $ \Gamma $ の右に新しい束縛を加えて拡張する。 | |
786 | |
787 新しい束縛と既に $ \Gamma $ に表われている束縛は混同しないように名前 $ x$は$\Gamma $に存在しない名前から選ばれるものとする。 | |
788 これはアルファ変換により$\lambda$抽象の束縛名は一貫して変更ができるため、常に満たせる。 | |
789 | |
790 ラムダ抽象に型を持たせる規則の一般的な形は | |
791 | |
792 \begin{align*} | |
793 \AxiomC{$ \Gamma, x : T_1 \vdash t_2 : T_2$} | |
794 \UnaryInfC{$ \Gamma \vdash \lambda x : T_1 . t_2 : T_1 \rightarrow T_2$} | |
795 \DisplayProof && \text{T-ABS} | |
796 \end{align*} | |
797 | |
798 であり、変数の型付け規則は | |
799 | |
800 \begin{align*} | |
801 \AxiomC{$ x : T \in \Gamma $} | |
802 \UnaryInfC{$ \Gamma \vdash x : T$} | |
803 \DisplayProof && \text{T-VAR} | |
804 \end{align*} | |
805 | |
806 である。 | |
807 $ x : T \in T $ は 、$ \Gamma$において $x$ に仮定された型は $ T $ である、と読む。 | |
808 | |
809 最後に関数適用の型付け規則を定義する。 | |
810 | |
811 \begin{align*} | |
812 \AxiomC{$ \Gamma \vdash t_1 : T_{11} \rightarrow T_{12}$} | |
43 | 813 \AxiomC{$ \Gamma \vdash t_2 : T_{11}$} |
42 | 814 \BinaryInfC{$ \Gamma \vdash t_1 \; t_2 : T_{12}$} |
815 \DisplayProof && \text{T-APP} | |
816 \end{align*} | |
817 | |
818 もし $t_1$ が$ T_{11}$の引数を $ T_{12}$の計算結果に移す関数へ評価され、$ t_2$が型$T_{11}$の計算結果にに評価されるのであれば、$t_1$ を $ t_2$に適用した計算結果は $ T_{12}$の型を持つ。 | |
819 ブール定数と条件式の型付け規則は型付き算術式と時と同様である。 | |
820 | |
43 | 821 最終的な純粋単純型付きラムダ計算の規則を示す。 |
822 純粋とは基本型を持たないという意味であり、純粋単純型付きラムダ計算にはブールのような型を持たない。 | |
823 この純粋単純型付きラムダ計算でブール値を扱う場合は型環境$\Gamma$を考慮してブール値の規則を追加すれば良い。 | |
42 | 824 |
825 \begin{definition} | |
43 | 826 $ \rightarrow $ (型付き)の構文 |
42 | 827 |
828 \begin{align*} | |
829 t ::= && \text{項} \\ | |
830 x && \text{変数} \\ | |
831 \lambda x : T . t && \text{ラムダ抽象} \\ | |
832 t \; t && \text{関数適用} \\ | |
833 \end{align*} | |
43 | 834 |
835 \begin{align*} | |
836 v ::= && \text{項} \\ | |
837 \lambda x : T . t && \text{ラムダ抽象値} \\ | |
838 \end{align*} | |
839 | |
840 \begin{align*} | |
841 T ::= && \text{型} \\ | |
842 T \rightarrow T && \text{関数型} \\ | |
843 \end{align*} | |
844 | |
845 \begin{align*} | |
846 \Gamma ::= && \text{文脈} \\ | |
847 \emptyset && \text{空の文脈} \\ | |
848 \Gamma , x : T && \text{項変数の束縛} \\ | |
849 \end{align*} | |
42 | 850 \end{definition} |
851 | |
43 | 852 \begin{definition} |
853 $ \rightarrow $ (型付き)の評価($ t \rightarrow t'$) | |
854 | |
855 \begin{align*} | |
856 \AxiomC{$t_1 \rightarrow t_1'$} | |
857 \UnaryInfC{$t_1 \; t_2 \rightarrow t_1' \; t_2$} | |
858 \DisplayProof && \text{E-APP1} \\ | |
859 \AxiomC{$t_2 \rightarrow t_2'$} | |
860 \UnaryInfC{$v_1 \; t_2 \rightarrow v_1 \; t_2'$} | |
861 \DisplayProof && \text{E-APP2} \\ | |
862 (\lambda x : T_{11} . t_{12}) v_2 \rightarrow [ x \mapsto v_2] t_{12} && | |
863 \text{E-APPABS} | |
864 \end{align*} | |
865 \end{definition} | |
866 | |
867 \begin{definition} | |
868 $ \rightarrow $ (型付き)の型付け($\Gamma \vdash t : T $) | |
869 | |
870 \begin{align*} | |
871 \AxiomC{$ x : T \in \Gamma$} | |
872 \UnaryInfC{$\Gamma \vdash x : T $} | |
873 \DisplayProof && \text{T-VAR} \\ | |
874 \AxiomC{$\Gamma , x : T_1 \vdash t_2 : T_2$} | |
875 \UnaryInfC{$\Gamma \vdash \lambda x : T_1 . t_2 : T_1 \rightarrow T_2$} | |
876 \DisplayProof && \text{E-ABS} \\ | |
877 \AxiomC{$ \Gamma \vdash t_1 : T_{11} \rightarrow T_{12}$} | |
878 \AxiomC{$ \Gamma \vdash t_2 : T_{11}$} | |
879 \BinaryInfC{$\Gamma \vdash t_1 \; t_2 : t_{12}$} | |
880 \DisplayProof && \text{T-APP} | |
881 \end{align*} | |
882 \end{definition} | |
883 | |
884 単純型付きラムダ計算の型付け規則のインスタンスも型付き算術式のように導出木をすることで示せる。 | |
885 例えば $ (\lambda x : Bool\; x) \; true $ が空の文脈において $ Bool$を持つことは以下の木で表せる。 | |
886 | |
887 \begin{prooftree} | |
888 \AxiomC{$ x : Bool \in x : Bool$} | |
889 \RightLabel{T-VAR} | |
890 \UnaryInfC{$x : Bool \vdash x : Bool$} | |
891 \RightLabel{T-ABS} | |
892 \UnaryInfC{$\vdash \lambda x : Bool . x : Bool \rightarrow Bool$} | |
893 \AxiomC{} | |
894 \RightLabel{T-TRUE} | |
895 \UnaryInfC{$\vdash true : Bool$} | |
896 \RightLabel{T-APP} | |
897 \BinaryInfC{$\vdash (\lambda x : Bool . x) \; true : Bool $} | |
898 \end{prooftree} | |
899 | |
47 | 900 純粋型付きラムダ計算の型システムにおいて、閉じた項に対して進行定理と保存定理は成り立つ\cite{Pierce:2002:TPL:509043}\cite{pierce2013型システム入門プログラミング言語と型の理論}。 % FIXME: 進行定理と保存定理の証明。 |
43 | 901 閉じた項、という制限が付いているのは $ f \; true $ といった自由変数が存在する項は正規形ではあるが値でないからである。 |
902 しかし、開いた項に関しては評価が行なえないために型システムの検査対象に含まれない。 | |
903 | |
904 % }}} | |
905 |