<?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%2FComputation_inside_proofs</id>
	<title>Lean theorem prover/Explainers/Computation inside proofs - 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%2FComputation_inside_proofs"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=Lean_theorem_prover/Explainers/Computation_inside_proofs&amp;action=history"/>
	<updated>2026-10-21T08:23:27Z</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/Computation_inside_proofs&amp;diff=6766&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/Computation_inside_proofs&amp;diff=6766&amp;oldid=prev"/>
		<updated>2026-10-15T19:34:36Z</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:Computation inside proofs}}&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:Computation inside proofs}}&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/Foundations/Definitional equality|Lean theorem prover/System/Decision procedures}}&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/Foundations/Definitional equality|Lean theorem prover/System/Decision procedures}}&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;Some statements are proved by calculating. That 2 + 2 is 4, or that 97 is prime, 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;Some statements are proved by calculating. That 2 + 2 is 4, or that 97 is prime, can be&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key pma_cutover_20261020t051351z-soft_:diff:1.41:old-6559:rev-6766:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>PMA Publisher</name></author>
	</entry>
	<entry>
		<id>https://invarians.org/index.php?title=Lean_theorem_prover/Explainers/Computation_inside_proofs&amp;diff=6559&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/Computation_inside_proofs&amp;diff=6559&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:Computation inside proofs}}&lt;br /&gt;
{{Technical|Lean theorem prover/Foundations/Definitional equality|Lean theorem prover/System/Decision procedures}}&lt;br /&gt;
&lt;br /&gt;
Some statements are proved by calculating. That 2 + 2 is 4, or that 97 is prime, can be&lt;br /&gt;
settled by working the sum or by trying every divisor. Lean accepts such calculations as&lt;br /&gt;
proofs. This page shows how, what has to be trusted when it does, and what the calculation&lt;br /&gt;
costs.&lt;br /&gt;
&lt;br /&gt;
== A sum as a 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;
example : 2 + 2 = 4 := rfl&lt;br /&gt;
&lt;br /&gt;
example : 2 ^ 100 = 1267650600228229401496703205376 := rfl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The proof &amp;lt;code&amp;gt;rfl&amp;lt;/code&amp;gt; says that the two sides are the same thing. To accept it, Lean&lt;br /&gt;
works out both sides and compares the results. Two expressions that compute to the same value&lt;br /&gt;
are, in Lean&amp;#039;s terms, &amp;#039;&amp;#039;&amp;#039;definitionally equal&amp;#039;&amp;#039;&amp;#039;, and for them &amp;lt;code&amp;gt;rfl&amp;lt;/code&amp;gt; is a complete&lt;br /&gt;
proof (see [[Lean theorem prover/Explainers/Two kinds of equality|two kinds of&lt;br /&gt;
equality]]).&lt;br /&gt;
&lt;br /&gt;
The second line raises 2 to the power 100 and is accepted at once. In the logic a natural&lt;br /&gt;
number is zero followed by a chain of successors, and a chain of that length could never be&lt;br /&gt;
written out. The Lean kernel does not try. It stores number literals in a fast library for&lt;br /&gt;
arithmetic on large numbers, usually GMP, and replaces addition, multiplication and the other&lt;br /&gt;
basic operations with routines from that library. The Lean Language Reference adds the&lt;br /&gt;
condition that comes with the speed: these routines are part of the Lean kernel, so if they&lt;br /&gt;
did not agree with the definitions they stand in for, soundness could suffer.&amp;lt;ref name=&amp;quot;ref-nat&amp;quot;&amp;gt;&amp;#039;&amp;#039;The&lt;br /&gt;
Lean Language Reference&amp;#039;&amp;#039;, version for Lean 4.34.0 (lean-lang.org, 2026), section 20.1,&lt;br /&gt;
&amp;quot;Natural Numbers&amp;quot;, with section 20.1.2, &amp;quot;Run-Time Representation&amp;quot;.&lt;br /&gt;
https://lean-lang.org/doc/reference/4.34.0/Basic-Types/Natural-Numbers/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Deciding a finite question ==&lt;br /&gt;
&lt;br /&gt;
A finite question can be answered by a program, and the run of the program can be a proof.&lt;br /&gt;
Here is a test for primality by trial division, applied to 97:&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;
def isPrime (n : Nat) : Bool :=&lt;br /&gt;
  n ≥ 2 &amp;amp;amp;&amp;amp;amp; (List.range (n - 2)).all (fun k =&amp;gt; n % (k + 2) != 0)&lt;br /&gt;
&lt;br /&gt;
#eval isPrime 97&lt;br /&gt;
&lt;br /&gt;
theorem prime97 : isPrime 97 = true := by decide&lt;br /&gt;
&lt;br /&gt;
#print axioms prime97&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function checks that n is at least 2 and that no number from 2 to n − 1 divides it.&lt;br /&gt;
&amp;lt;code&amp;gt;#eval&amp;lt;/code&amp;gt; runs it and prints &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. That is a program&amp;#039;s answer, not yet&lt;br /&gt;
a proof. The theorem turns it into one. The tactic &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt; finds a procedure that&lt;br /&gt;
decides the statement and evaluates it inside the logic; when the result is &amp;quot;true&amp;quot;, that&lt;br /&gt;
evaluation is the proof, and the Lean kernel repeats it when it checks the&lt;br /&gt;
theorem.&amp;lt;ref name=&amp;quot;ref-tacref&amp;quot;&amp;gt;&amp;#039;&amp;#039;The Lean Language Reference&amp;#039;&amp;#039;, version for Lean 4.34.0&lt;br /&gt;
(lean-lang.org, 2026), section 14.5, &amp;quot;Tactic Reference&amp;quot;: entries for &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt; and&lt;br /&gt;
&amp;lt;code&amp;gt;native_decide&amp;lt;/code&amp;gt;.&lt;br /&gt;
https://lean-lang.org/doc/reference/4.34.0/Tactic-Proofs/Tactic-Reference/&amp;lt;/ref&amp;gt; The last&lt;br /&gt;
line confirms that nothing extra was assumed: &amp;lt;code&amp;gt;&amp;#039;prime97&amp;#039; does not depend on any&lt;br /&gt;
axioms&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running the program instead: native_decide ==&lt;br /&gt;
&lt;br /&gt;
The same question can be answered faster by running the program as a program and accepting&lt;br /&gt;
its answer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean lean-cont&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 prime97_native : isPrime 97 = true := by native_decide&lt;br /&gt;
&lt;br /&gt;
#print axioms prime97_native&lt;br /&gt;
#print prime97_native._native.native_decide.ax_1_1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lean 4.34.1 answers:&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;
&amp;#039;prime97_native&amp;#039; depends on axioms: [prime97_native._native.native_decide.ax_1_1]&lt;br /&gt;
axiom prime97_native._native.native_decide.ax_1_1 : decide (isPrime 97 = true) = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The theorem now rests on an axiom made for the occasion. &amp;lt;code&amp;gt;native_decide&amp;lt;/code&amp;gt; evaluated&lt;br /&gt;
the question the way &amp;lt;code&amp;gt;#eval&amp;lt;/code&amp;gt; does, and then added an axiom stating the answer. The&lt;br /&gt;
Lean kernel asks for no proof of an axiom; it accepts it. So the theorem is only as sound as the&lt;br /&gt;
evaluation behind the axiom, which means the Lean compiler and every function that has been&lt;br /&gt;
given a faster implementation for running. The reference manual says that this adds the&lt;br /&gt;
entire Lean compiler to the trusted part of the system, and that a new axiom will show up in&lt;br /&gt;
&amp;lt;code&amp;gt;#print axioms&amp;lt;/code&amp;gt; for the theorem and for anything that depends on&lt;br /&gt;
it.&amp;lt;ref name=&amp;quot;ref-tacref&amp;quot; /&amp;gt; In versions of Lean up to 4.28, such theorems were marked&lt;br /&gt;
instead by one shared axiom, &amp;lt;code&amp;gt;Lean.trustCompiler&amp;lt;/code&amp;gt;.&amp;lt;ref name=&amp;quot;ref-validating&amp;quot;&amp;gt;&amp;#039;&amp;#039;The&lt;br /&gt;
Lean Language Reference&amp;#039;&amp;#039;, version for Lean 4.34.0 (lean-lang.org, 2026), &amp;quot;Validating a Lean&lt;br /&gt;
Proof&amp;quot;, with the note &amp;quot;On Lean.trustCompiler (up to Lean 4.28.0)&amp;quot;.&lt;br /&gt;
https://lean-lang.org/doc/reference/4.34.0/ValidatingProofs/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is a widening of what must be trusted, not a mistake in the answer. The prime is still&lt;br /&gt;
prime. But a reader who wants to rely on the theorem must now trust a much larger body of&lt;br /&gt;
code than the Lean kernel. The project this wiki records forbids&lt;br /&gt;
&amp;lt;code&amp;gt;native_decide&amp;lt;/code&amp;gt; in its own sources, as its proof gate states (see&lt;br /&gt;
[[Principia Machina/Lean transition|the transition page]]). Nothing is hidden either way: the&lt;br /&gt;
axiom&amp;#039;s name appears in the list, as on&lt;br /&gt;
[[Lean theorem prover/Explainers/What has to be trusted|what has to be trusted]].&lt;br /&gt;
&lt;br /&gt;
== What the calculation costs ==&lt;br /&gt;
&lt;br /&gt;
Evaluation inside the logic is slow. It proceeds step by step through the definitions, with&lt;br /&gt;
few of the shortcuts of a compiled program, and it has limits on how deep it may go. Asking&lt;br /&gt;
the same question about 1009 shows the difference:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean lean-cont lean-fails&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;
#eval isPrime 1009&lt;br /&gt;
&lt;br /&gt;
example : isPrime 1009 = true := by decide&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#eval&amp;lt;/code&amp;gt; prints &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; at once, but &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt; stops with&lt;br /&gt;
&amp;lt;code&amp;gt;maximum recursion depth has been reached&amp;lt;/code&amp;gt;. The option &amp;lt;code&amp;gt;decide +kernel&amp;lt;/code&amp;gt;&lt;br /&gt;
hands the evaluation directly to the Lean kernel, which evaluates the procedure once instead&lt;br /&gt;
of twice:&amp;lt;ref name=&amp;quot;ref-tacref&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean lean-cont&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 prime1009 : isPrime 1009 = true := by decide +kernel&lt;br /&gt;
&lt;br /&gt;
#print axioms prime1009&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This succeeds, and &amp;lt;code&amp;gt;&amp;#039;prime1009&amp;#039; does not depend on any axioms&amp;lt;/code&amp;gt;. The cost grows with&lt;br /&gt;
the size of the question. In one measurement made for this page, on one computer, checking&lt;br /&gt;
the same theorem for the six-digit prime 100003 with &amp;lt;code&amp;gt;decide +kernel&amp;lt;/code&amp;gt; took about&lt;br /&gt;
fifteen seconds, while running the program with &amp;lt;code&amp;gt;#eval&amp;lt;/code&amp;gt; took well under a second.&lt;br /&gt;
Other computers will give other times.&lt;br /&gt;
&lt;br /&gt;
Some procedures cannot be evaluated inside the logic at all. A decision procedure defined by&lt;br /&gt;
well-founded recursion may get stuck, because evaluating it would require working through&lt;br /&gt;
proofs as well as data.&amp;lt;ref name=&amp;quot;ref-tacref&amp;quot; /&amp;gt; The page on&lt;br /&gt;
[[Lean theorem prover/Explainers/Functions that always finish|functions that always finish]]&lt;br /&gt;
explains where such definitions come from.&lt;br /&gt;
&lt;br /&gt;
== The choice ==&lt;br /&gt;
&lt;br /&gt;
Computing inside a proof is a trade between speed and trust. Evaluation by the Lean kernel is&lt;br /&gt;
slow and bounded, but it adds nothing to what must be trusted. Evaluation by the compiler is&lt;br /&gt;
fast, but it adds the compiler, and an axiom, to the foundation of the theorem. When a&lt;br /&gt;
calculation is too large for the first, the alternatives include proving a general&lt;br /&gt;
theorem that makes the calculation unnecessary, and accepting the larger trust and recording it.&lt;br /&gt;
Lean makes the choice visible, so that a reader can see which was taken.&lt;br /&gt;
&lt;br /&gt;
== Next ==&lt;br /&gt;
&lt;br /&gt;
* [[Lean theorem prover/Explainers/The small trusted core|The small trusted core]]: what the Lean kernel is, and why it is kept small.&lt;br /&gt;
* [[Lean theorem prover/Foundations/Definitional equality|Definitional equality]]: the technical treatment of computation in the logic.&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>