MiniLean4
対話的定理証明器をゼロから実装する
Lean 4 風の証明カーネルをゼロから作る。5 種類の項と 8 つの型付け規則から始め、帰納型、タクティク言語、整合性を支える宇宙の階層へと進む。各要素に対応する Rust コードは短く、半日もあれば読み通せる。
証明はプログラムである。カーネルがそれを検査する。それ以外は何も信頼しない。
# 命題上の多相的な恒等関数: すべての P について P -> P。 goal forall (P : Sort 0), P -> P intro P intro p exact p qed
これは WebAssembly にコンパイルした本物のカーネルが、本書最初の定理を検査しているところである。スクリプトを書き換えて、もう一度実行してみてほしい。
本書とは
Lean、Coq、Agda といった対話的定理証明器の中核には、項が与えられた型を持つかを判定する小さなカーネル(kernel)がある。タクティクや記法、自動化などはカーネルに渡す項を作るものであり、カーネルが正しければ、ほかの部分にバグがあって定理の証明に失敗することはあっても、偽の定理を受理することはない。
MiniLean4 は、教育用の規模に縮めた証明支援系(proof assistant)のカーネルである。Lean 4、Coq、Agda が形式検証(formal verification)に使っているのと同じ種類の依存型理論を、数ファイルの Rust に収まるところまで削ぎ落としたものだ。Lean 4 が証明をどう検査するのか、Curry-Howard 対応が実際に何をもたらすのか、形式検証ツールの信頼がどこから来るのかを知りたいなら、その仕組みを何も隠さずに見せるのが本書である。
本書では、カーネルの仕組みを具体的に示す。各章で一つの概念を説明し、正確に定式化したうえで、それを実装する Rust コードを紹介する。カーネル、タクティク、パーサを合わせても実装は三千行に満たず、依存ライブラリもなく、本書はそのすべてを扱う。
本書だけで読み進められるように書いてあり、再帰関数と基本的な集合の記法が読めればよく、型理論や Lean の予備知識は必要ない。Lean を知っている読者には、見覚えのある話も多いだろう。
読み方
命題論理のためのカーネル
- 1命題は型である証明を検査することが、プログラムの型検査と同じ仕事である理由。
- 2項の言語5 種類の項と、それを表す Rust の enum。
- 3型付け規則文脈、判断、そして型の付く項を定める 8 つの規則。
- 4論理としての型付け規則自然演繹、論理式から型への翻訳、整合性の意味。
- 5型検査アルゴリズム規則を Infer と Check に変え、typecheck.rs と一行ずつ突き合わせる。
- 6実例で追う正しい証明、誤った証明、変換を検査器が処理する手順の追跡。
カーネルを育てる
- 7帰納型 I: 自然数定数、定義、そして再帰と帰納法の両方を与える再帰子。
- 8帰納型 II: 一般的な手順木、リスト、ベクトル、そして任意の再帰子を生成する手続き。
- 9等式も帰納型であるEq、輸送、定義的等価と命題的等価、そして 0 + n = n の証明。
- 10タクティク: 対話的に証明項を組み立てるゴール、ホール、そして intro、apply、induction、rw が項を作る方法。
内部のしくみ
- 11代入、捕獲、α 同値カーネルのバグが潜む操作と、substitution.rs がそれを避ける方法。
- 12簡約と変換β、δ、ι、データとしての計算規則、弱頭正規形。
基礎
- 13宇宙: なぜ Sort u なのかType : Type は矛盾する。非述語的な最下層をもつ階層は矛盾しない。
- 14体系の性質型の一意性、型保存性、強正規化、整合性。
付録
- A証明が項になることの証明翻訳定理の完全な証明。
- Bα 同値アルゴリズムの正しさどちらの定義も de Bruijn 形を計算している。
- CHurkens のパラドックスType : Type のもとでの False 型の閉項。
- D整合性の証明forall P, P を住まわせる閉項は存在しない。
- Eleanmini 言語スクリプト言語の構文、コマンド、タクティク。
- F記法と用語集本書で使うすべての記号と用語。
- 参考文献
第 I 部では依存型理論の型検査器を作り、それがある論理の証明検査器になっていることを示す。第 II 部では帰納型(自然数、木、リスト、ベクトル、等式)と、証明項を組み立てるタクティク言語を加える。第 III 部では第 I 部と第 II 部で詳しく扱わなかった代入、α 同値、簡約の内部を調べるが、カーネルのバグが潜みやすいのはここである。第 IV 部では宇宙の階層がこの形をとる理由を説明し、メタ理論を述べる。付録には完全な証明、宇宙の設計を正当化するパラドックス、そしてスクリプト言語のリファレンスを収めた。
本書を通じて、4 種類の対話的な要素が登場する。
- プレイグラウンドはカーネルを実行する。スクリプトを編集し、実行ボタンを押して、出力を読む。
- エクスプローラはカーネル自身から見た項の姿を示す。構文木、規則ごとの型付け導出、一歩ずつの簡約、各変数がどの束縛子に属するか、そしてタクティクを適用するたびの証明状態である。エクスプローラはすべてライブで動き、項を変えればカーネルが計算し直す。
- ステッパーはアルゴリズムを一歩ずつ進め、各ステップ後の状態を示す。
- 呼び出し木は、型検査器がある項に対して行う再帰呼び出しの正確な列を、各呼び出しが対応する型付け規則とともに示す。
コードではと記したコラムは、直前に定義したものを実装している Rust の関数を指し示す。演習には解答が付いており、必要になるまで折りたたまれている。
自分でコードを動かす
リポジトリには、カーネル、コマンドラインの実行器、本書で使う例題スクリプトが含まれている。
cargo run -- examples/identity.leanmini
cargo run -- examples/nat-reflexivity.leanmini
cargo run -- examples/zero-add.leanmini
cargo run -- examples/generic-list.leanmini
cargo run -- examples/generic-vec.leanmini
cargo test
引数なしで cargo run を実行すると対話セッションが始まり、同じコマンドを一行ずつ受け付ける。言語の説明は付録 E にある。
ソースは本書の流れに沿って構成してある。
| ファイル | 内容 | 章 |
|---|---|---|
src/term.rs |
項の表現 | 2 |
src/typecheck.rs |
型推論と型検査 | 5, 6 |
src/substitution.rs |
自由変数、代入、α 同値 | 11 |
src/reduction.rs |
弱頭正規形、正規化、定義的等価 | 12 |
src/declaration.rs |
シグネチャ: 定数、定義、帰納型のメタデータ | 7, 8 |
src/inductive/ |
帰納的宣言の検査と再帰子の生成 | 8 |
src/proof.rs |
ゴール、証明状態、タクティク | 10 |
src/syntax.rs |
スクリプト言語のパーサ | 付録 E |
src/main.rs |
コマンドラインの実行器 | 付録 E |