为什么都在内核中?
Why is it all in the kernel?

原始链接: https://lawrencecpaulson.github.io//2026/07/30/Collatz.html

最近关于通过 Lean 反驳考拉兹猜想(Collatz conjecture)的传闻——尽管经过了独立工具的检查,却未能通过验证——凸显了现代证明辅助工具的一个关键缺陷。作者认为,行业对“证明对象”(proof objects)的依赖适得其反。这些本应作为正确性独立证明的“对象”,带来了巨大的内存负担,并往往迫使开发者将递归和归纳类型等复杂特性直接置入“内核”之中。 这种用假设复杂特性来取代推导过程的做法——即罗素所说的“窃取比诚实劳动更具优势”——增加了系统出现可靠性漏洞的风险。相比之下,以 HOL 为代表的系统所推崇的“诚实劳动”方法,通过最少公理集来推导复杂结构(如递归函数和归纳类型)。由于这些构造存在于内核之外,它们无法破坏系统的基本完整性。作者总结称,社区应当优先考虑更简单的内核,而非依赖证明对象这一存在缺陷的承诺,并指出像 Isabelle/HOL 或 HOL Light 这类系统通过将复杂逻辑安全地移出核心,提供了远高于前者的可靠性。

这篇 Hacker News 的讨论探讨了证明辅助工具中“内核”(kernel)的概念——即负责验证数学证明的小型可信核心。正如操作系统领域一样,关于是应保持内核精简以减小攻击面,还是应加入更多功能以提升性能和实用性,一直存在争议。 该讨论强调了不同架构哲学之间的张力: * **极简主义方法:** 如 HOL Light 等系统维持一个微小的内核,以简化人工验证,并将复杂的逻辑推送到不可信的“用户空间”工具中。 * **功能丰富的方法:** 如 Lean 和 Rocq 等系统将递归函数和归纳定义等复杂特性直接集成到内核中,以支持高级证明对象和可执行代码。 批评者认为,将更多逻辑移入内核会增加可靠性漏洞的风险,即系统可能因缺陷而“证明”错误的陈述。支持者则认为,这是现代验证需求中必要的务实权衡。归根结底,这场辩论反映了在优先考虑形式化安全性还是计算实用性方面的更广泛分歧,参与者常将这些证明辅助工具的内核与操作系统设计中经典的微内核与宏内核之争进行类比。
相关文章

原文

30 Jul 2026

[ general  Lean  Isabelle  HOL system  philosophy  memories  ]

Sensational news! The Collatz conjecture has just been refuted. Ramana Kumar has proved its negation. The proof has been checked in Lean and double‑checked using the independent Nanoda type checker. Unfortunately, the proof is wrong. It exploited a bug in the Lean kernel. Somehow, Nanoda didn’t detect the error either. Now I am not writing to gloat about this. Soundness bugs have been discovered in Isabelle, among many other proof assistants; for all I know, a new and monstrous bug will be discovered tomorrow. Nevertheless, there are some lessons here, so let’s go!

The Collatz conjecture

This famous conjecture has been around for nearly a century, attracting the attention of serious mathematicians and cranks alike. It concerns the following procedure. Start with a number N. Now repeat this step: if N is even then divide it by two; if odd, set N to 3N+1. Collatz conjectured that this procedure is guaranteed to reach 1 no matter what value of N we start with. Extensive testing has failed to find a single counterexample. Recent work shows language models to be quite good at finding counterexamples to conjectures, so why not Collatz? Resolving it really would cause a sensation.

The dead weight of proof objects

As we have known for half a century, proof objects are unnecessary. Robin Milner designed the ML language for the specific purpose of supporting proof assistants. Through the notion of an abstract type, the proof kernel could be made secure from the rest of the program. The rules of inference, confined to the abstract type, would be an API for creating theorems.

Nevertheless, much of our community has doubled down on storing proof objects. In particular, they noted that a proof object was a certificate that could be checked independently. But I am not aware of a single instance where an independent proof checker detected a soundness error that had passed through the kernel of a proof assistant. For Collatz, as we have seen, Nanoda was also fooled. When we consider the memory burden that proof objects represent, this is analogous to driving everywhere pulling a spare car on a trailer behind you in case of a breakdown. And your car does break down, but lo and behold, the spare car doesn’t work either. And the exact reason your car broke down was the burden of pulling the spare car. Because it is only the proof calculi that have proof objects that seemingly need to put everything into the kernel.

Theft versus honest toil

For most of the 20th century, logicians assumed the fewest axioms they could, from them deriving the rest of mathematics. Possibly they were worried about Russell’s and other paradoxes; possibly they were just parsimonious. This point of view was perhaps best put by Russell himself:

The method of ‘postulating’ what we want has many advantages; they are the same as the advantages of theft over honest toil. Let us leave them to others and proceed with our honest toil. (Russell, 1919)

So it’s notable that – so rumor has it – the bug in Lean was caused by nested inductive types in the kernel. A number of soundness bugs in Rocq were caused by pattern matching involving recursive functions in the kernel. I’m not precisely sure why dependent type theories are not expressive enough to express things like recursion from a more basic calculus. The reason is probably technical. But let’s be clear: in set theory and in simple type theory, you have to assume very little. Set theory gives you a few principles for introducing sets: unions, separation, pairing, replacement. Simple type theory gives you a little bit of logic and a bit of λ-calculus, which gives you a typed set theory where the sets are Boolean-valued functions. Then, with honest toil, you can obtain inductive definitions, records, recursive data structures and recursive functions in quite general settings, including pattern matching and partial functions. You can perform numerical calculations using symbolic binary arithmetic. Because all these things are defined in terms of the primitive axioms, rather than being postulated, they lie outside the kernel and cannot lead to contradictions.

Back in the 1980s, when I was working with Martin‑Löf type theory, a question arose about expressing recursive functions. The theory only recognized forms of primitive recursion. But the theory also admitted higher types, giving the possibility of more powerful forms of recursion. Having learned mathematics in the tradition of honest toil, I worked (and it really was laborious) to define a system of combinators within Martin‑Löf type theory that could express a vast space of terminating recursive functions. But I hadn’t understood how this game was played. The correct answer to the question was to extend MLTT with a general notion of recursion, and I must admit, it could be done simply and elegantly. I’m not sure anyone ever understood what I did. Years later, I saw the paper cited with the comment, “Paulson extended MLTT with recursion”: they couldn’t imagine someone obtaining recursion through honest toil.

What does the honest toil look like?

I can see why the implementers of a proof assistant take the option of theft, because the honest toil really is like breaking rocks. The easiest of the many objectives is recursive data structures. An inductive definition can be transformed into a monotone operator on sets. The least fixed point gives you an inductive definition, and if you prefer a co-inductive definition, you take the greatest fixed point. In Isabelle, we seldom bother to link these constructions to types, but recursive data types are an important special case, now handled in a general and sophisticated way through bounded natural functors.

The construction of recursive functions from first principles is particularly tedious. You begin with a well‑founded relation and prove the existence of the desired recursive function by well‑founded induction. The work I did on recursion in MLTT was somewhat helpful in this, so it was not entirely wasted. Isabelle/HOL now supports recursive function definitions in great generality, including pattern matching and termination checking. And all of these things lie safely outside the kernel.

There’s an irony that proof objects are sometimes touted as leading to greater soundness guarantees. The opposite is clearly true. If soundness is your main concern, you should go for HOL Light or HOL4. Isabelle has had more bugs than those, but few, and definitely far fewer than certain other systems.

联系我们 contact @ memedata.com