これは型 Advent Calendar 2019 15日目の記事です. 交差型についてのよく知られた事実——交差型を持つ単純型付きλ計算において,強正規化する項は型付け可能であることを解説します.
はじめに
交差型とは,読んで字のごとく型と型の共通部分を表す型です.すなわち,型を持つ項e(つまり )とは,型を持ち(),なおかつ型も持つ項()を指します.交差型のある体系では,SMLの+
のようなアドホックな多相性1をのように表現できる嬉しさが知られています.しかし,真にヤバい点と言えば後述する性質でしょう.
交差型を含むある種の言語——交差型を持つ単純型付きλ計算——において,任意の項の型付け可能性と強正規化性は一致することが知られています.確かに左の性質から右の性質は導けそうです.単純型付きλ計算,System F,CoC等々,多くの言語において,型付けできる項は強正規化する2ことが知られています.しかし右——ある項が強正規化すること——から左——その項が型付け可能であること——も導けるとはどういう事でしょう?もうそれを聞いただけでヤバそうです.与えられた項が型付け可能かどうか判定するプログラムが存在すれば停止性問題が解けてしまうので,無制限に交差型を入れてしまうと型推論が決定不能になってしまいます.3
この記事ではその右から左への性質,すなわち交差型を持つ単純型付きλ計算において,強正規化する項は型付け可能であることをふわっと解説します.左から右への性質,型付け可能な項は強正規化する事については,論理関係(logical relation)を使えば単純型付きλ計算の時と同じノリで証明できるので割愛します.
性質が成り立つ直感
この性質が成り立つ直感を得るには,この論文による証明を追うのが良いでしょう.この論文では,肝心の定理は大きく分けて以下の二つの性質から証明しています.
- 正規形が型付け可能であること
- 主部展開定理(subject expansion)
正規形が型付け可能であること
交差型を持つ単純型付きλ計算においては,全ての正規形——これ以上簡約できない項——は適当な型環境を持って来れば型を付けられます.
これは明らかに単純型付きλ計算では成り立たなかった性質です.例えば,正規形に型を付けられるかどうか考えてみましょう.この項に型を付けようと思うと,引数の型は,型の値を受け取って適当な型の値を返す関数の型と一致しなくてはなりません.を満たす型なんて単純型では表現できないので,に型は付けられません.
一方で,交差型を認めればに型を付けられるようになります.これは,型の値としても使えるし,型の値としても使える値の型を,として表現できるためです.型注釈を補ってやればみたいな感じですね.
主部展開定理
主部展開定理(subject expansion)とは,簡約後の項が型付け可能ならば簡約前の項も型付け可能になる性質です.良く知られた主部簡約定理(subject reduction)4の逆ですね.
単純型付きλ計算ではもちろん,主部展開定理は成り立ちません.説明のために,,二つ組とかがあると仮定して,項に型を付けられるかどうか考えてみましょう.この項に型を付けるためには,がを受け取る関数であり,なおかつを受け取る関数でもあると表現できなくてはなりません.単純型ではそのような多相性を表現できないので,簡約結果に型が付くにもかかわらず,簡約前の項には型が付きません.
一方,交差型があれば簡約前の項にも型を付けられます.これは,がを受け取る関数であり,を受け取る関数でもあることをのように表現できるためです.
つまるところ,評価結果に型が付く5なら評価前のにも型が付く主な理由は,交差型がアドホックな多相性を表現できるからに他なりません.に型が付くなら,項の変数の出現に代入されたそれぞれに適当な型が付いているはずなので,その型付けを集めてみたいな感じに交差型で結んでやる感じです.
厳密に言うとにが出現しない場合,に型が付いたからと言ってに型が付くとは限らないので,論文で扱う主部展開定理のステートメントではに少なくとも何かしらの型が付くことを仮定しています.,とか明らかにアウトですもんね.
主定理の証明
以上二つの性質を用いると,直感的には以下の手順で強正規化する項は型付け可能であることを示せます.
- 正規形まで簡約し,正規形が型付け可能であることを用いる
- 簡約を遡りながら主部展開定理を用い,簡約後の項が型付け可能であることから簡約前の項型付け可能であることを示していく
論文では,強正規化する項の考えうる簡約列の長さの和についての完全帰納法で証明しています. 論文で用いている主部展開定理はに型が付くことに加えてに型が付くことも仮定していますが, これも帰納法の仮定から手に入ります.
-
SMLの四則演算ってクッソアドホックにオーバーロードされていて,文脈によって勝手に
int
上の二項演算になったりreal
上の二項演算になったりするんですよね.マイナー言語で例えてしまったので,この辺りは各自お好きな言語で脳内補完して下さい…↩ -
どう計算を進めたところで必ず評価が停止する,みたいな性質.とりあえず計算が停止するかどうかみたいに思っておけばよろしい.↩
-
流石にそれでは実用上不便なので,実際には初期の篩型(refinement types)みたいに,制限された形の交差型が使われがち.今の篩型って依存型っぽい雰囲気出してるけど,最初は制限された交差型だったんすよ↩
-
TaPLで言うところの型保存(preservation)↩
-
後述するように,厳密にはに型が付くことも必要↩