2013 Lean 誕生案:de Moura 打造人人可用的證明器#
報案人:SMT 求解器 Z3 之父 Leonardo de Moura。案情:Coq 太難,Isabelle 太老,新人不敢入行。 偵探:de Moura 本人。兇器:C++ 核心 + 依賴型別 + 元程式設計。
案發現場#
2013 年,互動式定理證明界陷入一種尷尬。Coq 與 Isabelle 戰功彪炳,卻各有難解的沉痾:
- Coq 的 tactic 語言 Ltac 難以擴展,大型函式庫舉步維艱,IDE 體驗停留在上世紀。
- Isabelle 的 ML 生態封閉,依賴型別支持不足,年輕的程式設計師望而卻步。
- Z3 等 SMT 求解器在工業界大殺四方,但在數學證明中只能當配角,無法構造可檢查的證明項。
時任微軟研究院研究員的 Leonardo de Moura 剛與 Nikolaj Bjørner 打完 Z3 這場勝仗,心中卻有更大的疑惑:能不能把 SMT 的自動化、程式語言的現代感、依賴型別的表達力,裝進同一個證明器?
2013 年,他在微軟啟動了 Lean 計畫。名字取得謙遜,野心卻極大:Lean,要讓證明變得輕盈。第一版的設計文件開宗明義:效能、可擴展性、美觀的語法,一個都不能少。
同案的背景還有 HoTT 的衝擊:新基礎需要新工具,老證明器對同倫型別論支持有限。Lean 從一開始就把宇宙多態、商型別、擴展性公理納入考量,立意要做「下一個十年的證明器」。
偵查過程#
線索一:C++ 核心與依賴型別的雙刀流#
Lean 的內核是一個用 C++ 撰寫的小型可信核心,負責檢查依賴型別演算(Calculus of Inductive Constructions 的變體)的每一步推理。
其型別系統的核心判斷是:
表示在上下文 \(\Gamma\) 中,項 \(e\) 具有型別 \(\alpha\) 。而依賴函數型別 \(\Pi (x : A), B(x)\) 允許值域 \(B\) 依賴於參數 \(x\) ,從而把命題、謂詞、證明全部統一為項。
Lean 的宇宙階層設計為:
其中 \(Prop\) 是特殊的不可分宇宙,專門容納命題,以兼顧古典推理與構造性。商型別、選擇公理、函數外延性被作為內建或相容公理引入,務求讓古典數學家也能無痛遷入。
與 Coq 的 OCaml 核心相比,C++ 核心帶來了更快的 elaborator(精製器)與統一器,讓 Lean 在處理大規模代數結構時不再氣喘吁吁。
線索二:元程式設計——偵探可以改造警局#
Lean 最大的破案手法是元程式設計(metaprogramming)。在 Lean 中,tactic 本身就是用 Lean 寫的 Lean 程式,可以直接操作語法樹與證明狀態。
一個最小的 tactic 框架例子如下:
meta def my_intro : tactic unit := do
t ← target,
match t with
| `(%%a → %%b) := intro `h >> skip
| _ := fail "目標不是蘊含式"
end
這段程式的意思是:讀取當前目標 \(t\) ,若它形如 \(a → b\) ,則自動引入假設 \(h\) 。其中 \(tactic\) 是一個單子(monad),封裝了證明狀態的讀寫。
更進一步,Lean 允許自訂語法:
syntax "my_have " ident " : " term " := " term : tactic
這種「語言可長大」的特性,讓後來的 mathlib 貢獻者可以發明無數領域專用 tactic,而不必等待核心開發者施恩。這正是 SSReflect 精神在 Lean 世界的轉世。
下表比較了三代證明器的辦案風格:
| 證明器 | 核心語言 | tactic 擴展 | 自動化 |
|---|---|---|---|
| Coq | OCaml | Ltac,較難維護 | 有限 |
| Isabelle | Standard ML | Eisbach,框架封閉 | Sledgehammer 強大 |
| Lean | C++,後改 Lean 自舉 | Lean 即 tactic,可自訂語法 | SMT 風格 +simp +omega |
線索三:從 Lean 3 到 Lean 4 的長征#
Lean 的歷史可分為三個階段:
- Lean 1 至 Lean 2(2013 至 2016):驗證概念,吸引 HoTT 社群試用,但函式庫尚小。
- Lean 3(2017 至 2020):mathlib 萌芽。Jeremy Avigad、Mario Carneiro 等人發起數學函式庫計畫,採用單一 monorepo、嚴格審查、快速迭代的開源模式。短短數年就累積了數十萬行形式化數學,成為最活躍的證明社群。
- Lean 4(2021 至今):de Moura 決定重寫整個系統。新核心不再只是證明器,還是一個通用程式語言與編譯器,支援高效的 C 編譯、FFI、Lake 建構系統。Lean 4 甚至可以自己編譯自己,元程式可以直接編成原生碼執行。關鍵的轉折公式是:證明助理 = 函數式語言 + 驗證核心,Lean 4 把等號右邊的第一項做到了工業級,讓寫 tactic 的體驗與寫 Rust 或 Haskell 一樣愉快。
mathlib 的增長曲線本身就是證據:從 2017 年的數千行,到 2023 年突破百萬行,涵蓋代數、拓樸、分析、數論,成為 AI 訓練的最佳語料,也為 2024 年的 AlphaProof 埋下伏筆。
結案報告#
Lean 並沒有在 2013 年就結案,它真正的結案報告要到 2021 年 Lean 4 發布才算寫完第一章:
- 降低門檻:VS Code 插件、即時顯示、友善錯誤訊息,讓大學生也能在幾小時內寫出第一個形式化證明。
- mathlib 生態:證明了「大教堂式」的集中協作可以在形式化數學中成功,改寫了 Coq 與 Isabelle 各自為政的局面。
- 工業與學術通吃:既有乾淨的依賴型別理論,又有 SMT 式的自動化,成為連接 2008 年 Z3 革命與 2024 年 AI 證明的橋樑。
- 未竟之業:古典與構造的張力、宇宙管理的複雜性、大規模搜尋的效能,留給了下一代的 AI 偵探去操心。
用探案的話說:de Moura 沒有破完所有案子,但他蓋了一間設備最新、燈光最亮的警局,讓所有後輩都想來辦案。
證據與工具#
證據一:Lean 的經典開場白
theorem and_swap (p q : Prop) : p ∧ q → q ∧ p := by
intro h
cases h with
| intro hp hq => exact ⟨hq, hp⟩
其中 \(p ∧ q\) 是合取引入, \(cases\) 是消去策略, \(⟨hq, hp⟩\) 是匿名構造子。這短短四行展示了 tactic 塊 \(by\) 的工作方式。
證據二:tactic 狀態變遷表
| 步驟 | 證明狀態 |
|---|---|
| 初始目標 | \(⊢ p ∧ q → q ∧ p\) |
| 執行 \(intro\) 後 | \(h : p ∧ q ⊢ q ∧ p\) |
| 執行 \(cases\) 後 | \(hp : p, hq : q ⊢ q ∧ p\) |
| 執行 \(exact\) 後 | 無剩餘目標,結案 |
證據三:偵探工具箱
| 工具 | 作用 |
|---|---|
| Lean 核心 | C++ 高速檢查器,後改 Lean 自舉 |
| mathlib | 最大最活躍的形式化數學函式庫 |
| Lake + VS Code | 建構系統與互動式審訊室 |
| Mathport | 把 Lean 3 證據自動搬運到 Lean 4 的時光機 |
延伸閱讀:de Moura et al., "The Lean Theorem Prover (System Description)"(CADE 2015);《Theorem Proving in Lean》;mathlib 官方文件。