2026年7月、Lean の周辺では少し奇妙な事件が続いた。AI 支援で作られたというコラッツ予想の「反証」が公開され、しかもその証明は sorry なしの Lean 形式化として見える形で現れた。ところが後からたどると、それは数学の新発見というより、証明チェッカー側の抜け穴を踏んだ結果だった。証明の中身そのものを見て安心するだけでは足りない。最後にそれを裁くカーネルが、きちんと拒否できるかどうかが本丸になる。
Lean の開発者が 2026-08-01 に公開した事後報告では、この問題の中心にあったのがカーネルの soundness bug #14576 だと説明されている。発覚のきっかけは、7 月 25 日に公開されたコラッツ反証リポジトリだった。7 月 28 日には、それを小さな False の証明まで縮めた報告が issue として上がり、約 1 時間後に修正が入った。つまり、外から見ると「AI が難問を解いたのかもしれない」と見えたものが、実際には証明基盤のほころびを突いただけだったわけだ。
反証が“見えてしまう”とき
この手の事故で厄介なのは、前段のチェックを全部すり抜ける必要はない、という点にある。Lean のフロントエンドは普通、入力された項を型検査する。だが今回の不具合は、より内側の、カーネルが直接受け取る経路にあった。事後報告によれば、ネストした帰納型の扱いで、あるパラメータが「幽霊」のように消えてしまい、生成された補助型の型検査から逃げられる状況が生まれた。そこで不正な引数を滑り込ませると、カーネルが False の証明を受け入れてしまう。
ここで重要なのは、これは理論の破綻ではなく実装バグだということだ。Lean のメタ理論そのものに穴が空いた、という話ではない。しかも到達経路はメタプログラミング経由に限られる。フロントエンドは弾けるが、カーネル単体に直接食わせると抜けてしまう。証明支援系では、この「外側は信用せず、内側で必ず再検査する」分離が生命線になる。
さらに面白いのは、独立実装の外部チェッカー nanoda も、この一件では別の不具合を抱えていたことだ。元のコラッツ系リポジトリは week-old の nanoda でも通っていたが、nanoda はその箇所を別の理由で見落としていた。Lean 本体のバグと nanoda のバグは無関係で、たまたま同じ証明が両方の穴をまたいだ。独立したチェッカーを使えば安心、という単純な話ではないことがはっきりした瞬間だった。
一つの抜け穴を、二重三重に塞ぐ発想
この事件の後、Lean 側は「外部カーネルで再チェックする」仕組みを本格化させる。2026-10-15 の開発者ブログでは、Lean v4.35.0 に lake check が入り、開発成果を sandbox 内で再検査できるようになったと案内された。しかも --paranoid を付けると、公式カーネルだけでなく、nanoda、lean4lean、con-leche、con-ron の四つの外部カーネルでも検査できる。さらに公式カーネルの変種も、ハード化したメモリアロケータ付きで走る。メモリ破損が静かに誤答になるのではなく、checked abort に変わるようにするためだ。
この構図が示しているのは、単一の番人では足りない、という現実だ。1 個のカーネルが正しいかどうかを疑うのではなく、異なる設計の番人を複数並べ、同じ証明をそれぞれに通す。もし一つが見逃しても、別の一つが止める。事後報告でも、con-leche と con-ron を両方通すことで、Lean の compiler や runtime 側に潜む不具合まで含めて、かなり強い防御になると説明されている。理由は単純で、同じ実装ミスが Lean 側と Rust 側の両方に同時にある可能性は低いからだ。
Lean が自分の番人を Lean で証明するということ
ここで出てくるのが con-leche だ。これは Lean で書かれた外部チェッカーで、しかも「False の証明を受け入れない」ことが Lean の中で証明されている。README には、checker の実装に少し余計な仕事、つまり soundness を壊さない範囲の型比較を許すことで、証明を通しやすくしているとある。設計としては、Lean の Expr に依存しない独自の項表現を使い、既存の未検証 C++ ルーチンに頼らない。しかも nested や mutual を含む帰納型を一様な方針で扱う。
proof idea の文書を読むと、この証明はかなり筋が通っている。チェッカーが受理した環境には、集合論的なモデルが必ず存在する、という形で consistency を示す。False は空集合、Eq は集合の等号として解釈されるので、False の証明を含む環境はモデルを持てない。要するに、受理と真理を結ぶ橋を、型理論の内部ではなくモデル論で架けている。
しかも con-leche は「遅いから安心」ではない。開発者ブログによれば、full Mathlib export に対して公式カーネルの 0.69 倍の命令数で走り、8 スレッドで約 100 秒で全体を検査できるという。守りを厚くすると遅くなる、という常識をそのままは受け入れていない。そこからさらに Rust 版の con-ron が作られ、Lean で証明した結果を Rust に移して、別の実行系で再確認する。ここまで来ると、もはや「カーネルを信じる」話ではない。カーネルを複数の方法で疑い尽くす設計になっている。
それでも、まだ終わっていない
面白いのは、Lean の開発者がこの段階でも満足していないことだ。lake check をもっと使いやすくしたい、好きな外部カーネルを差し込めるようにしたい、さらに将来的にはコンパイラの一部まで検証したい、と書かれている。理由ははっきりしている。Mathlib は 2.5M LoC、Anthropic の FLT は 13M LoC 超、Tau Ceti は 3M LoC 超、さらに 1B LoC 級の数学ライブラリ構想まで出ている。今の外部カーネル連携は、このサイズでは持たない。二重化だけでは足りず、バイナリ形式のエクスポートや増分チェックまで必要になる。
だから今回の本質は、「AI が難問を解いたように見えた」ことではない。その後ろで、証明支援系が自分の足場をどこまで自力で強くできるかが試されたことにある。Lean は今、公式カーネルを守るだけでなく、自分の番人を自分で証明し、さらに別実装で裏取りする段階に入った。では、その verified kernels の中で、con-leche と con-ron はそれぞれ何をどこまで保証し、どこにまだ穴が残るのか。そこが次の焦点になる。
👉 続き(核心はここから)は PaPoo で読めます: https://papoo.work/doc/121e566cb2a3c858