<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=Lean_theorem_prover%2FExplainers%2FThe_small_trusted_core</id>
	<title>Lean theorem prover/Explainers/The small trusted core - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=Lean_theorem_prover%2FExplainers%2FThe_small_trusted_core"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=Lean_theorem_prover/Explainers/The_small_trusted_core&amp;action=history"/>
	<updated>2026-10-21T12:02:34Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://invarians.org/index.php?title=Lean_theorem_prover/Explainers/The_small_trusted_core&amp;diff=6767&amp;oldid=prev</id>
		<title>PMA Publisher: Published from the Principia Machina source</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=Lean_theorem_prover/Explainers/The_small_trusted_core&amp;diff=6767&amp;oldid=prev"/>
		<updated>2026-10-15T19:34:37Z</updated>

		<summary type="html">&lt;p&gt;Published from the Principia Machina source&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:34, 15 October 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{DISPLAYTITLE:The small trusted core}}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{DISPLAYTITLE:The small trusted core}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Technical|Lean theorem prover/System/The Lean kernel}}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{Technical|Lean theorem prover/System/The Lean kernel}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{Lean theorem prover map}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Lean is a large program, and large programs have faults. Yet a proof Lean accepts can be&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Lean is a large program, and large programs have faults. Yet a proof Lean accepts can be&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>PMA Publisher</name></author>
	</entry>
	<entry>
		<id>https://invarians.org/index.php?title=Lean_theorem_prover/Explainers/The_small_trusted_core&amp;diff=6560&amp;oldid=prev</id>
		<title>PMA Publisher: Published from the Principia Machina source</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=Lean_theorem_prover/Explainers/The_small_trusted_core&amp;diff=6560&amp;oldid=prev"/>
		<updated>2026-10-14T18:00:53Z</updated>

		<summary type="html">&lt;p&gt;Published from the Principia Machina source&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{DISPLAYTITLE:The small trusted core}}&lt;br /&gt;
{{Technical|Lean theorem prover/System/The Lean kernel}}&lt;br /&gt;
&lt;br /&gt;
Lean is a large program, and large programs have faults. Yet a proof Lean accepts can be&lt;br /&gt;
believed without believing all of Lean. This page says why: one small part does the judging, and&lt;br /&gt;
everything else only proposes. It names the principle behind that design, the part of Lean that&lt;br /&gt;
does the judging, and what the rest of Lean is for.&lt;br /&gt;
&lt;br /&gt;
== A large program with a small judge ==&lt;br /&gt;
&lt;br /&gt;
A proof assistant has to do many things. It reads what a person types, fills in what the person&lt;br /&gt;
left out, runs automation that searches for proofs, shows the state of an unfinished proof,&lt;br /&gt;
reports errors and keeps track of thousands of definitions and theorems. Each of these is a&lt;br /&gt;
place where a mistake in the program could hide.&lt;br /&gt;
&lt;br /&gt;
If a proof were only as reliable as all of that machinery together, nobody could say how reliable&lt;br /&gt;
it was. The answer is to separate two jobs. Finding a proof is hard and needs cleverness, so it is&lt;br /&gt;
left to parts of the program that may be clever and may be wrong. Checking a proof that has been&lt;br /&gt;
written out in full is mechanical, so it is given to a part that is simple and is meant to be right.&lt;br /&gt;
&lt;br /&gt;
The second part is the only one whose mistakes would matter. If it is small, people can read it,&lt;br /&gt;
others can write it again independently, and its correctness can itself become a subject of proof.&lt;br /&gt;
&lt;br /&gt;
== De Bruijn&amp;#039;s criterion ==&lt;br /&gt;
&lt;br /&gt;
The idea is N. G. de Bruijn&amp;#039;s, whose Automath was the pioneer among computer systems for checking&lt;br /&gt;
mathematics (see [[Lean theorem prover/History/Automath|Automath]]). He stressed that checking&lt;br /&gt;
formal proofs by machine brings a real gain in reliability, because the program that checks them&lt;br /&gt;
can be small. Henk Barendregt and Freek Wiedijk, writing in 2005, state the principle under his&lt;br /&gt;
name: a proof assistant meets the &amp;#039;&amp;#039;&amp;#039;de Bruijn criterion&amp;#039;&amp;#039;&amp;#039; when its proofs can be checked&lt;br /&gt;
independently by a small program, one that a mathematician or logician can inspect in the usual&lt;br /&gt;
way.&amp;lt;ref name=&amp;quot;bw2005&amp;quot;&amp;gt;Henk Barendregt and Freek Wiedijk, &amp;quot;The challenge of computer mathematics&amp;quot;, &amp;#039;&amp;#039;Philosophical Transactions of the Royal Society A&amp;#039;&amp;#039; 363, no. 1835 (2005), pp. 2351–2375. [https://doi.org/10.1098/rsta.2005.1650 doi:10.1098/rsta.2005.1650]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The criterion rests on a difference between proving and checking. Whether a statement has a&lt;br /&gt;
proof at all cannot, in general, be settled by a machine. Whether a given text is a proof of a&lt;br /&gt;
given statement can be: the checker only has to confirm that each step follows one of a small&lt;br /&gt;
number of rules.&amp;lt;ref name=&amp;quot;bw2005&amp;quot; /&amp;gt; A proof may run to megabytes; the program that checks it&lt;br /&gt;
can still be short.&lt;br /&gt;
&lt;br /&gt;
Pollack made the same argument in 1998. A simple checker that only verifies explicit&lt;br /&gt;
derivations, with no search and no heuristics, is a formal object much smaller and easier to&lt;br /&gt;
understand than almost any substantial proof. To believe a proof it accepts, a reader has to&lt;br /&gt;
understand the checker, not the proof.&amp;lt;ref name=&amp;quot;pollack&amp;quot;&amp;gt;R. Pollack, &amp;quot;How to believe a machine-checked proof&amp;quot;, in Giovanni Sambin and Jan M. Smith (eds), &amp;#039;&amp;#039;Twenty Five Years of Constructive Type Theory&amp;#039;&amp;#039;, Oxford University Press, 1998, chapter 11 (from p. 205); first issued as BRICS Report RS-97-18, Aarhus University, 1997. [https://doi.org/10.7146/brics.v4i18.18945 doi:10.7146/brics.v4i18.18945]&amp;lt;/ref&amp;gt; He also recalls a remark of J Moore about&lt;br /&gt;
an earlier prover, NQTHM: until one long proof was checked with it, a reader who wanted to believe&lt;br /&gt;
everything it had checked would have done better to read all the proofs than its code, because&lt;br /&gt;
the code was longer than all of them.&amp;lt;ref name=&amp;quot;pollack&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Lean kernel ==&lt;br /&gt;
&lt;br /&gt;
In Lean the judge is the &amp;#039;&amp;#039;&amp;#039;Lean kernel&amp;#039;&amp;#039;&amp;#039;. Lean&amp;#039;s own reference describes it as &amp;quot;a small, robust&lt;br /&gt;
implementation of a type checker for the core type theory&amp;quot;, written in C++.&amp;lt;ref name=&amp;quot;refelab&amp;quot;&amp;gt;&amp;#039;&amp;#039;The Lean Language Reference&amp;#039;&amp;#039;, version for Lean 4.34.0, section &amp;quot;Elaboration and Compilation&amp;quot;. [https://lean-lang.org/doc/reference/4.34.0/Elaboration-and-Compilation/ lean-lang.org/doc/reference/4.34.0/Elaboration-and-Compilation], consulted 14 October 2026.&amp;lt;/ref&amp;gt;&lt;br /&gt;
Every new definition, theorem or inductive type has to pass it before it is added to Lean&amp;#039;s&lt;br /&gt;
environment, its table of definitions and theorems; the check is there to catch faults in the&lt;br /&gt;
parts of Lean that produced the definition.&amp;lt;ref name=&amp;quot;refelab&amp;quot; /&amp;gt; The paper that introduced&lt;br /&gt;
Lean 4 describes the same design: the trusted part of Lean is relatively small, and an interface&lt;br /&gt;
lets users export their work and write their own checkers.&amp;lt;ref name=&amp;quot;lean4&amp;quot;&amp;gt;Leonardo de Moura and Sebastian Ullrich, &amp;quot;The Lean 4 Theorem Prover and Programming Language (System Description)&amp;quot;, in &amp;#039;&amp;#039;Automated Deduction – CADE 28&amp;#039;&amp;#039;, Lecture Notes in Computer Science, Springer, 2021, pp. 625–635. [https://doi.org/10.1007/978-3-030-79876-5_37 doi:10.1007/978-3-030-79876-5_37]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Lean kernel is kept small partly by what it leaves to others. It does not search for proofs.&lt;br /&gt;
It does not work out missing pieces of a term; that is finished before a term reaches it. It does&lt;br /&gt;
not check that recursive functions finish: by the time a recursive definition reaches the Lean&lt;br /&gt;
kernel, it has been rewritten into a form built from basic recursion principles, which always&lt;br /&gt;
finish.&amp;lt;ref name=&amp;quot;refelab&amp;quot; /&amp;gt; (See [[Lean theorem prover/Explainers/Functions that always finish|functions that always finish]].)&lt;br /&gt;
&lt;br /&gt;
== The untrusted helpers ==&lt;br /&gt;
&lt;br /&gt;
Everything else in Lean is a helper. The &amp;#039;&amp;#039;&amp;#039;elaborator&amp;#039;&amp;#039;&amp;#039; turns what a person writes, with its&lt;br /&gt;
notation, its omitted arguments and its overloaded numerals, into a complete and explicit term.&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Tactics&amp;#039;&amp;#039;&amp;#039; are small programs that construct proof terms step by step, some of them doing a great&lt;br /&gt;
deal of search. Neither has to be trusted for the soundness of a proof, because neither has the&lt;br /&gt;
last word: their output goes to the Lean kernel, which accepts it or refuses it.&amp;lt;ref name=&amp;quot;tcl4&amp;quot;&amp;gt;&amp;#039;&amp;#039;Type Checking in Lean 4&amp;#039;&amp;#039;, online book, chapter &amp;quot;Trust&amp;quot;. [https://ammkrn.github.io/type_checking_in_lean4/trust/trust.html ammkrn.github.io/type_checking_in_lean4], consulted 14 October 2026.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference is visible. Here a tactic, &amp;lt;code&amp;gt;rw&amp;lt;/code&amp;gt;, proves that addition can be done in&lt;br /&gt;
either order, and &amp;lt;code&amp;gt;#print&amp;lt;/code&amp;gt; shows what was actually stored as the proof:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean&amp;quot; style=&amp;quot;background: #f8f9fa; border: 1px solid #c8ccd1; padding: 0.6em; margin: 0.3em 0; font-size: 0.85em; line-height: 1.35; overflow-x: auto; white-space: pre;&amp;quot;&amp;gt;&lt;br /&gt;
theorem swap (a b : Nat) : a + b = b + a := by&lt;br /&gt;
  rw [Nat.add_comm]&lt;br /&gt;
&lt;br /&gt;
#print swap&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lean 4.34.1 prints:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean-output&amp;quot; style=&amp;quot;background: #ffffff; border: 1px dashed #a2a9b1; padding: 0.6em; margin: 0.3em 0; font-size: 0.85em; line-height: 1.35; overflow-x: auto; white-space: pre;&amp;quot;&amp;gt;&lt;br /&gt;
theorem swap : ∀ (a b : Nat), a + b = b + a :=&lt;br /&gt;
fun a b =&amp;gt; Eq.mpr (id (congrArg (fun _a =&amp;gt; _a = b + a) (Nat.add_comm a b))) (Eq.refl (b + a))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;code&amp;gt;rw&amp;lt;/code&amp;gt; is gone. What remains is a term made of named facts and rules, and it&lt;br /&gt;
is that term the Lean kernel checked. If the tactic had a fault and produced a term that did not&lt;br /&gt;
prove the statement, the Lean kernel would refuse it, and the fault would show up as an error&lt;br /&gt;
rather than as a false theorem.&lt;br /&gt;
&lt;br /&gt;
== What a small core does not settle ==&lt;br /&gt;
&lt;br /&gt;
A small judge narrows the question of trust; it does not remove it. Three things stay outside.&lt;br /&gt;
The Lean kernel itself could have a fault, which is why independent re-checkers exist (see&lt;br /&gt;
[[Lean theorem prover/Explainers/Checking a proof again later|checking a proof again later]]).&lt;br /&gt;
Some features of Lean let results in without the Lean kernel computing them; they are listed on&lt;br /&gt;
[[Lean theorem prover/Explainers/What has to be trusted|what has to be trusted]]. And the Lean&lt;br /&gt;
kernel checks that a proof proves the statement as written, which may not be the statement that&lt;br /&gt;
was meant (see [[Lean theorem prover/Explainers/Stating the right thing|stating the right thing]]).&lt;br /&gt;
&lt;br /&gt;
Barendregt and Wiedijk noted one more tension. Systems in which some equations are settled by&lt;br /&gt;
computation rather than by written-out steps strain the criterion a little, since the checker&lt;br /&gt;
must then also compute; they judged this acceptable because the basic steps of&lt;br /&gt;
computation are themselves simple.&amp;lt;ref name=&amp;quot;bw2005&amp;quot; /&amp;gt; Lean is such a system (see&lt;br /&gt;
[[Lean theorem prover/Explainers/Computation inside proofs|computation inside proofs]]).&lt;br /&gt;
&lt;br /&gt;
== Next ==&lt;br /&gt;
&lt;br /&gt;
[[Lean theorem prover/Explainers/What has to be trusted|What has to be trusted]] lists everything&lt;br /&gt;
a reader of a Lean proof still relies on. The technical counterpart,&lt;br /&gt;
[[Lean theorem prover/System/The Lean kernel|the Lean kernel]], describes what it checks.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>PMA Publisher</name></author>
	</entry>
</feed>