正本:FormalLab/TypeTheory/PureTypeSystems.lean
第33章:純粋型システム・ラムダ・キューブ・構成計算#
単純型、依存型、パラメトリック多相、型演算子は、互いに無関係な機能なのでしょうか。 それとも「何が何に依存できるか」という少数の規則から統一的に分類できるのでしょうか。
この章は名称の暗記から始めません。まず単純型付きラムダ計算の判断 に、型自身を分類する判断 を加えます。次に、Π型の束縛変数と 本体がどの階層に属するかを三つの軸として読みます。八体系の名前は、その組合せに 後から付く座標名です。最後に全三軸を持つCoCを位置づけ、帰納型・宇宙・商などを備える Lean 4やCICと同一視できない理由を明確にします。
sort公理とΠ形成規則から型理論を指定する#
PTSは三つ組 で指定されます。 はsortの集合、 はsort公理、 はΠ形成規則です。 項・型・kindは別々の文法カテゴリではなく、判断 の中で担う役割によって区別されます。 下のLeanコードはこの考え方の構文と ラムダ・キューブの座標をモデル化するもので、完全なPTS型検査器ではありません。
namespace FormalLab.TypeTheory.PureTypeSystems項・型・kindを一つの構文で表す#
純粋型システム(pure type system; PTS)では、項と型に別々の文法を用意しません。 変数・適用・ラムダ抽象・依存積・sortを、同じ式の文法で表します。ある式が項・型・ kindのどれとして働くかは、構文の形だけでなく型判断によって決まります。
次の Expression はその共通構文の骨格です。lam domain body は
λ (x : domain). body、pi domain codomain は Π (x : domain), codomain を表します。
de Bruijn添字 0 は最も近い束縛子を参照します。
ラムダ・キューブを記述する二つのsort。
inductive PTSSort where
| star
| boxsort集合を型 SortType で表したPTS仕様。公理関係とΠ形成関係だけを保持する。
structure PTSSpec (SortType : Type) where
sortAxiom : SortType → SortType → Prop
productRule : SortType → SortType → SortType → PropPTSの共通構文の骨格。型もkindも同じ構文の式として表す。
inductive Expression where
| sort : PTSSort → Expression
| var : Nat → Expression
| app : Expression → Expression → Expression
| lam : Expression → Expression → Expression
| pi : Expression → Expression → Expression注釈付き恒等関数 λ (x : A). x の構文。
def annotatedIdentity (A : Expression) : Expression :=
.lam A (.var 0)*(star)は項を分類する型のsort、□(box)は型を分類するkindのsortとして読みます。
ラムダ・キューブの標準的なPTS表示では公理 を置き、 自身の型はこの二sort
体系の内部では与えません。ここでの * と □ はLeanの Type と Sort の別名では
ありません。Leanの可算な宇宙階層を、二sortへ潰して理解してはいけません。
三つ組のうち集合 はLeanの型引数 SortType に、公理関係 は
PTSSpec.sortAxiom に、形成関係 は PTSSpec.productRule に対応します。この構造体は規則の
許可範囲だけを記録します。
項の導出、文脈の整形式性、簡約関係はまだ含みません。
Π形成規則を座標にする#
PTSの積形成規則はsortの三つ組 で指定されます。 であるとき、次の形成規則を使えます。
ラムダ・キューブでは、単純関数に必要な (*, *, *) を全頂点が持ち、残る三規則を
加えるか否かで座標を作ります。
ラムダ・キューブで区別する四種類のΠ形成規則。
inductive ProductRule where(*, *, *):項から項への通常の関数。
| termToTerm(□, *, *):型を束縛して項を作る多相。
| typeToTerm(*, □, □):項を束縛して型構成子を作る依存型。
| termToType(□, □, □):型を束縛して型構成子を作る型演算子。
| typeToType規則名をPTSのsort三つ組へ戻す。
def productRuleSorts : ProductRule → PTSSort × PTSSort × PTSSort
| .termToTerm => (.star, .star, .star)
| .typeToTerm => (.box, .star, .star)
| .termToType => (.star, .box, .box)
| .typeToType => (.box, .box, .box)(*, □, □) が「型が項に依存する」軸なのは、型族そのものが
λ (x : A). B という型レベルの関数だからです。その型 Π (x : A), * はkindに属します。
一方、個々の依存積 Π (x : A), B x の形成だけを見て三軸を推測すると向きを取り違えます。
三つの独立な追加機能#
CubeFeatures の三つの真偽値は次を表します。
dependentTypes:型が項に依存できる。polymorphism:項が型に依存できる。typeOperators:型が型に依存できる。
項が項に依存する通常の関数は全頂点に共通なので、座標には含めません。
ラムダ・キューブの頂点を決める三つの独立な機能。
structure CubeFeatures where
dependentTypes : Bool
polymorphism : Bool
typeOperators : Boolある頂点で積形成規則が許されるか。通常の関数規則は常に許す。
def CubeFeatures.allows (features : CubeFeatures) : ProductRule → Bool
| .termToTerm => true
| .typeToTerm => features.polymorphism
| .termToType => features.dependentTypes
| .typeToType => features.typeOperators三軸の指定から二sortのPTS仕様を作る。
def lambdaCubeSpec (features : CubeFeatures) : PTSSpec PTSSort where
sortAxiom s₁ s₂ := s₁ = .star ∧ s₂ = .box
productRule s₁ s₂ s₃ :=
∃ rule, productRuleSorts rule = (s₁, s₂, s₃) ∧ features.allows rule = true形成だけでは項を型付けできない#
の要素 は、空の文脈でsortを導入します。
変数を文脈へ加えるには、その型自身がsortを持つことを先に確かめます。文脈 が整形式で、 なら、 を導けます。弱化は、既存の判断を新しい未使用変数の下へ 持ち上げます。形成済みのΠ型に対するラムダ抽象と適用は次の形です。
右下の は、 に現れる自由な を で捕獲を避けて置換した式です。値域 が を
含まなければ通常の関数型 に戻ります。さらに型がβ変換で一致するときの変換規則が、計算と型付けを
結びます。したがって PTSSpec の二関係は体系の可変部分を指定しますが、型付け関係そのものではありません。
三軸を代表項から見分ける#
三つの追加規則は、すべて「型を引数に取る」という一語では区別できません。外側の束縛子と本体のsortを調べます。
- は、型 を束縛して項を作ります。多相恒等関数の型は です。
- は、項 を束縛して型族を作ります。例えば は というkindを持ちます。
- は、型 を束縛して型演算子を作ります。例えば のkindは です。
多相恒等関数と型演算子は、どちらも型変数 を束縛します。前者の本体は項でありsort に分類され、後者の 本体は型でありkindの側に分類されます。この値域のsortが、項の多相と高階の型演算を分けます。
八頂点#
三つの独立な真偽値には 通りあります。文献では次の名称が標準的です。 と は下線の有無が意味を持つため、プレーンテキストでは機能の列も 必ず併記します。
| 体系 | 型←項 | 項←型 | 型←型 | 通称・役割 |
|---|---|---|---|---|
λ→ |
× | × | × | 単純型付きラムダ計算 |
λP |
○ | × | × | 依存型 |
λ2 |
× | ○ | × | System F、二階多相 |
| × | × | ○ | 型演算子だけを加えた体系 | |
λP2 |
○ | ○ | × | 依存型+多相 |
λPω |
○ | × | ○ | 依存型+型演算子 |
| × | ○ | ○ | System Fω | |
λC |
○ | ○ | ○ | 構成計算(CoC) |
矢印 型←項 は「左のものが右のものに依存する」と読みます。関数の入出力方向では
ありません。
λ→:三機能を追加しない基点。
def lambdaArrow : CubeFeatures := ⟨false, false, false⟩λP:型が項に依存する。
def lambdaP : CubeFeatures := ⟨true, false, false⟩λ2(System F):項が型に依存する。
def lambda2 : CubeFeatures := ⟨false, true, false⟩λ\underline{ω}:型が型に依存する。
def lambdaOmegaUnderlined : CubeFeatures := ⟨false, false, true⟩λP2:依存型と多相を組み合わせる。
def lambdaP2 : CubeFeatures := ⟨true, true, false⟩λPω:依存型と型演算子を組み合わせる。
def lambdaPOmega : CubeFeatures := ⟨true, false, true⟩λω(System Fω):多相と型演算子を組み合わせる。
def lambdaOmega : CubeFeatures := ⟨false, true, true⟩λC(CoC):三機能を全て組み合わせる。
def lambdaC : CubeFeatures := ⟨true, true, true⟩
theorem lambdaArrow_has_only_term_functions :
lambdaArrow.allows .termToTerm = true ∧
lambdaArrow.allows .typeToTerm = false ∧
lambdaArrow.allows .termToType = false ∧
lambdaArrow.allows .typeToType = false :=
⟨rfl, rfl, rfl, rfl⟩
theorem lambdaC_has_all_product_rules (rule : ProductRule) :
lambdaC.allows rule = true := by
cases rule <;> rfl
theorem lambdaCube_has_star_box_axiom (features : CubeFeatures) :
(lambdaCubeSpec features).sortAxiom .star .box :=
⟨rfl, rfl⟩
theorem lambdaC_spec_contains_every_cube_product (rule : ProductRule) :
(lambdaCubeSpec lambdaC).productRule
(productRuleSorts rule).1
(productRuleSorts rule).2.1
(productRuleSorts rule).2.2 := by
exact ⟨rule, rfl, lambdaC_has_all_product_rules rule⟩構成計算(CoC)#
CoCはキューブの対角頂点 λC です。単純型付きラムダ計算を基点にすると、次を同時に
許します。
- 依存型:型族が項を引数に取る。
- パラメトリック多相:項が型を引数に取る。
- 高階の型演算子:型構成子が型を引数に取る。
ただし規則一覧だけでは型理論は完成しません。PTSの型判断には、sort公理と変数規則が必要です。 さらに弱化、Π形成、ラムダ抽象、適用、β変換による変換規則を備えます。 文脈の整形式性と代入補題も必要です。型保存、合流性、強正規化などは、体系について証明する メタ定理です。「表現力が高い」ことから無矛盾性や停止性は自動では出ません。
命題=型対応の下では、型は命題、項は証明、β簡約は証明の正規化として読めます。 CoCが「構成」と「計算」を同じ言語で扱う要点はここにあります。
キューブの分類表をLeanで検査する範囲#
ProductRule と CubePoint はラムダ・キューブの三軸と八頂点を有限データとして検査するための
Lean上の表現です。これはPTSの構文・文脈・型判断・β変換・メタ理論を全て実装したものでは
ありません。rfl で閉じる各定理は表の定義展開を検査しており、CoCの正規化や無矛盾性を
証明しているわけではありません。
CoC、CIC、Lean 4を同一視しない#
古典的なラムダ・キューブのCoCは二sort * : □ と四種類のΠ形成規則を持つ小さな核です。
Lean 4はこれに似た依存ラムダ計算を核としますが、実際には可算な非累積宇宙、
非可述的かつ証明無関係な Prop、帰納族、商などを備えます。したがってLeanを単に
「キューブの λC」と呼ぶだけでは、kernelの重要な規則を落とします。CoCは設計の座標軸、
Leanはその発展形の一つとして理解します [LEAN-DTT]。
また、帰納構成計算(Calculus of Inductive Constructions; CIC)は、CoCへ帰納的定義を 組み込む系統の名称です。LeanとRocq(旧Coq)はCIC系の発想を共有しますが、宇宙の累積性、 証明無関係性、商、再帰のkernel上の扱いなどに差があります [LEAN-FAQ]。
要点#
- PTSは項・型・kindを同じ構文で書き、sort公理とΠ形成規則で役割を判定する。
- ラムダ・キューブの三軸は、項による型への依存、型による項への依存、型による型への依存である。
- 八頂点は三機能の有無による分類で、発明順や強弱だけを表す年代図ではない。
- CoCは三軸をすべて持つが、帰納型などを備えるCICやLean 4そのものではない。
- 形成規則、型判断、計算規則、メタ定理がそれぞれ何を定めるかを混同しない。
研究史と文献案内#
CoquandとHuetは1988年の論文でCoCの基本理論を提示しました [CH88]。Barendregtは1991年、 型付きラムダ計算群を一般化型システムとして統一し、CoCを八体系の標準的な立方体として 細分しました [BAR91]。ラムダ・キューブはCoCの発明順をそのまま描く年代図ではなく、 許される依存規則による包含関係の分類です。
CoC原論文 [CH88] とBarendregtのPTSによる再編 [BAR91] は役割が異なります。CoC・System F・ 正規化をproof theoryから読むには [GLT89] を参照してください。LeanとCIC系の差は [LEAN-DTT; LEAN-FAQ; LEAN-REF] が扱います。
問題#
PTSの規則から依存の許可範囲を読む#
純粋型システムのsort、公理、Π形成規則をそれぞれ定義せよ。形成規則に現れる三つのsortについて、 定義域、値域、形成されるΠ型の分類を順に説明する。同じ構文範疇に項・型・kindを置けても、型判断における 役割まで同じになるわけではないことを具体的な判断で示す。
[CH88] のCoCと [BAR91] のPTSによる整理を対照し、原体系の記法と後世の一般化を混同しない表を 作れ。表には原典が与える規則、一般化でパラメータ化された部分、本章のLean上のモデルを含める。
ラムダ・キューブを暗記せず復元する#
ラムダ・キューブの三軸を「何が何に依存するか」という文で表し、各軸を追加したときに初めて
書ける代表的な型を一つずつ挙げよ。その記述から λP2、λPω、λω の機能を表を見ずに復元し、
八頂点を包含関係に従って配置する。
ポリモーフィック恒等関数と、型構成子を引数に取る高階演算を別々の軸へ分類せよ。両者を単に 「ジェネリック」と呼ぶと失われる区別を、束縛変数のsortから説明すること。
体系の規則とメタ定理を切り分ける#
型形成規則を列挙することと、その体系について保存、合流性、強正規化を証明することを区別せよ。 各メタ定理が何を量化し、どの簡約関係に依存するかを書き、ある規則集合から自動的に全てが従う わけではない理由を述べる。
CoC、CIC、Lean 4の差を比較する。少なくとも帰納型、宇宙、計算・再帰の扱いを比較項目に含める。LeanがCoCの 系譜にあるという歴史的説明を、LeanのkernelがCoCそのものであるという同一視へ強めてはならない。