<?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%2FSystem%2FDecision_procedures</id>
	<title>Lean theorem prover/System/Decision procedures - 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%2FSystem%2FDecision_procedures"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=Lean_theorem_prover/System/Decision_procedures&amp;action=history"/>
	<updated>2026-10-21T16:00:29Z</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/System/Decision_procedures&amp;diff=6791&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/System/Decision_procedures&amp;diff=6791&amp;oldid=prev"/>
		<updated>2026-10-15T19:35:12Z</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:35, 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: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;{{DISPLAYTITLE:Decision procedures}}&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;{{Plebeian|Lean theorem prover/Explainers/Automation and its limits|Lean theorem prover/Explainers/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;{{Plebeian|Lean theorem prover/Explainers/Automation and its limits|Lean theorem prover/Explainers/Computation inside proofs}}&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;A &amp;#039;&amp;#039;&amp;#039;decision procedure&amp;#039;&amp;#039;&amp;#039; is an algorithm that settles every question in a fixed class, answering yes or no. In Lean such an algorithm is useful only when its yes comes with evidence that the Lean kernel accepts. This page treats five tactics that automate whole classes of goals in Lean 4.34.1: &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;simp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt;. For each it says what the tactic covers, what evidence it hands to the Lean kernel, and what a reader must trust beyond 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;A &amp;#039;&amp;#039;&amp;#039;decision procedure&amp;#039;&amp;#039;&amp;#039; is an algorithm that settles every question in a fixed class, answering yes or no. In Lean such an algorithm is useful only when its yes comes with evidence that the Lean kernel accepts. This page treats five tactics that automate whole classes of goals in Lean 4.34.1: &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;simp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt;. For each it says what the tactic covers, what evidence it hands to the Lean kernel, and what a reader must trust beyond the Lean kernel.&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/System/Decision_procedures&amp;diff=6584&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/System/Decision_procedures&amp;diff=6584&amp;oldid=prev"/>
		<updated>2026-10-14T18:01:07Z</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:Decision procedures}}&lt;br /&gt;
{{Plebeian|Lean theorem prover/Explainers/Automation and its limits|Lean theorem prover/Explainers/Computation inside proofs}}&lt;br /&gt;
&lt;br /&gt;
A &amp;#039;&amp;#039;&amp;#039;decision procedure&amp;#039;&amp;#039;&amp;#039; is an algorithm that settles every question in a fixed class, answering yes or no. In Lean such an algorithm is useful only when its yes comes with evidence that the Lean kernel accepts. This page treats five tactics that automate whole classes of goals in Lean 4.34.1: &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;simp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt;. For each it says what the tactic covers, what evidence it hands to the Lean kernel, and what a reader must trust beyond the Lean kernel.&lt;br /&gt;
&lt;br /&gt;
== Three kinds of evidence ==&lt;br /&gt;
&lt;br /&gt;
Every tactic ends by assigning a term to the goal&amp;#039;s metavariable, as described on [[Lean theorem prover/System/The tactic framework|the tactic framework]], and the Lean kernel checks that term when the theorem is added. The procedures below differ in the shape of the term.&lt;br /&gt;
&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;An ordinary proof term.&amp;#039;&amp;#039;&amp;#039; The tactic searches, then assembles a proof from library lemmas. &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;simp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; work this way. The search is untrusted; only its output is checked.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Proof by reflection.&amp;#039;&amp;#039;&amp;#039; A Boolean function is written in Lean and proved correct once. The tactic reduces the goal to the claim that this function returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; on some input, and the Lean kernel confirms the claim by evaluating the function during its definitional equality check. &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt; works this way.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;An asserted evaluation.&amp;#039;&amp;#039;&amp;#039; As in reflection, but the function is run by compiled code and its result is added to Lean&amp;#039;s environment, its table of definitions and theorems, as a new axiom. &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt; works this way. The Lean compiler then joins the trusted base.&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;code&amp;gt;#print axioms&amp;lt;/code&amp;gt; tells the three apart: the first two leave only Lean&amp;#039;s standard axioms (described on [[Lean theorem prover/Foundations/The three axioms|the three axioms]]), the third leaves an extra one.&lt;br /&gt;
&lt;br /&gt;
== decide ==&lt;br /&gt;
&lt;br /&gt;
A proposition &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; is decidable when there is an instance of the class &amp;lt;code&amp;gt;Decidable p&amp;lt;/code&amp;gt;. The class is an inductive type with two constructors, one carrying a proof of &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; and one a proof of its negation:&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;
#print Decidable&lt;br /&gt;
#synth Decidable (∀ x : Fin 4, x.val * x.val &amp;amp;lt; 10)&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;
inductive Decidable : Prop → Type&lt;br /&gt;
number of parameters: 1&lt;br /&gt;
constructors:&lt;br /&gt;
Decidable.isFalse : {p : Prop} → ¬p → Decidable p&lt;br /&gt;
Decidable.isTrue : {p : Prop} → p → Decidable p&lt;br /&gt;
Nat.decidableForallFin fun x =&amp;gt; ↑x * ↑x &amp;amp;lt; 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instances compose: a bounded quantifier over &amp;lt;code&amp;gt;Fin 4&amp;lt;/code&amp;gt; is decidable because each instance of its body is, and instance resolution (see [[Lean theorem prover/System/Type classes and instance resolution|type classes and instance resolution]]) assembles the instance. The tactic &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt; synthesises such an instance for the goal and reduces it; if it reaches &amp;lt;code&amp;gt;isTrue h&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; proves the goal.&amp;lt;ref name=&amp;quot;src-tactics&amp;quot;&amp;gt;Lean 4 source code, version 4.34.1 (2026), file &amp;lt;code&amp;gt;src/Init/Tactics.lean&amp;lt;/code&amp;gt;: the documentation strings of the tactics &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt;. Apache License 2.0. https://github.com/leanprover/lean4/blob/v4.34.1/src/Init/Tactics.lean&amp;lt;/ref&amp;gt;&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 small : 2 ^ 10 = 1024 ∧ 3 &amp;amp;lt; 5 := by decide&lt;br /&gt;
#print small&lt;br /&gt;
#print axioms small&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 small : 2 ^ 10 = 1024 ∧ 3 &amp;amp;lt; 5 :=&lt;br /&gt;
of_decide_eq_true (id (Eq.refl true))&lt;br /&gt;
&amp;#039;small&amp;#039; does not depend on any axioms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The proof term is short because the work is moved into checking it. For &amp;lt;code&amp;gt;Eq.refl true&amp;lt;/code&amp;gt; to have type &amp;lt;code&amp;gt;decide p = true&amp;lt;/code&amp;gt;, the Lean kernel must reduce &amp;lt;code&amp;gt;decide p&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, which is the computation itself. This is [[Lean theorem prover/Foundations/Definitional equality|definitional equality]] put to use. On a false proposition the same evaluation yields a refutation, and the tactic reports it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean 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;
example : ∀ x : Fin 5, x.val * x.val &amp;amp;lt; 10 := by decide&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
error: Tactic `decide` proved that the proposition&lt;br /&gt;
  ∀ (x : Fin 5), ↑x * ↑x &amp;amp;lt; 10&lt;br /&gt;
is false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The limits follow from the method. The goal may contain no local variables or metavariables; on &amp;lt;code&amp;gt;n + 0 = n&amp;lt;/code&amp;gt; for a variable &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, Lean says &amp;lt;code&amp;gt;Expected type must not contain free variables&amp;lt;/code&amp;gt; and suggests the option &amp;lt;code&amp;gt;+revert&amp;lt;/code&amp;gt;, which first moves such variables into the goal as universally quantified ones. Instances defined by well-founded recursion may not reduce, and reduction can get stuck on instances built with rewriting tactics. The option &amp;lt;code&amp;gt;decide +kernel&amp;lt;/code&amp;gt; hands the reduction to the Lean kernel directly, and &amp;lt;code&amp;gt;decide +native&amp;lt;/code&amp;gt; runs compiled code and admits the result through an axiom. Its documentation says this can be significantly more efficient, but comes &amp;quot;at the cost of increasing the size of the trusted code base&amp;quot;.&amp;lt;ref name=&amp;quot;src-tactics&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== omega ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt; proves goals in linear arithmetic over &amp;lt;code&amp;gt;Int&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Nat&amp;lt;/code&amp;gt;. It accepts hypotheses of the forms &amp;lt;code&amp;gt;x = y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;x &amp;amp;lt; y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;x ≤ y&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;k ∣ x&amp;lt;/code&amp;gt; for a literal &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;, with their negations; it splits both sides into linear combinations of atoms, and for &amp;lt;code&amp;gt;x / k&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;x % k&amp;lt;/code&amp;gt; with a literal &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; it introduces a new variable together with the two inequalities that bound it.&amp;lt;ref name=&amp;quot;src-tactics&amp;quot; /&amp;gt;&amp;lt;ref name=&amp;quot;src-omega&amp;quot; /&amp;gt;&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 bound (x y : Nat) (h₁ : x + 2 * y ≤ 10) (h₂ : 3 &amp;amp;lt; x) : y ≤ 3 := by&lt;br /&gt;
  omega&lt;br /&gt;
&lt;br /&gt;
example (a b : Int) (h : 2 * a + 1 = 2 * b) : False := by&lt;br /&gt;
  omega&lt;br /&gt;
&lt;br /&gt;
example (n : Nat) : n / 2 + n % 2 ≤ n := by&lt;br /&gt;
  omega&lt;br /&gt;
&lt;br /&gt;
#print axioms bound&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last line prints &amp;lt;code&amp;gt;&amp;#039;bound&amp;#039; depends on axioms: [propext, Quot.sound]&amp;lt;/code&amp;gt;: the proof is an ordinary term. The method is William Pugh&amp;#039;s omega test of 1991, an extension of Fourier–Motzkin variable elimination from the reals to the integers.&amp;lt;ref name=&amp;quot;pugh&amp;quot;&amp;gt;William Pugh, &amp;quot;The Omega test: a fast and practical integer programming algorithm for dependence analysis&amp;quot;, &amp;#039;&amp;#039;Proceedings of the 1991 ACM/IEEE Conference on Supercomputing (Supercomputing &amp;#039;91)&amp;#039;&amp;#039;, ACM, 1991, pp. 4–13. doi:10.1145/125826.125848. Read in an expanded version whose first page states that it appeared in &amp;#039;&amp;#039;Communications of the ACM&amp;#039;&amp;#039; in August 1992, there titled &amp;quot;A practical algorithm for exact array dependence analysis&amp;quot;, 35(8), pp. 102–114, doi:10.1145/135226.135233.&amp;lt;/ref&amp;gt; Eliminating a variable from a set of integer inequalities yields Pugh&amp;#039;s &amp;#039;&amp;#039;&amp;#039;real shadow&amp;#039;&amp;#039;&amp;#039;, which may have integer points that lift to no integer solution, and his &amp;#039;&amp;#039;&amp;#039;dark shadow&amp;#039;&amp;#039;&amp;#039;, whose integer points always lift; when the two coincide the elimination is exact.&amp;lt;ref name=&amp;quot;pugh&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lean&amp;#039;s implementation states its own limits. Its notes say that it follows Pugh&amp;#039;s paper closely but leaves out the dark and grey shadows, so when the real shadow is satisfiable it fails rather than deciding. It prefers to eliminate a variable for which elimination is exact: all upper bounds, or all lower bounds, with unit coefficient. The notes record that failures from the missing shadows appear to be rare in practice.&amp;lt;ref name=&amp;quot;src-omega&amp;quot;&amp;gt;Lean 4 source code, version 4.34.1 (2026), file &amp;lt;code&amp;gt;src/Lean/Elab/Tactic/Omega.lean&amp;lt;/code&amp;gt;: implementation notes of the &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt; tactic. Apache License 2.0. https://github.com/leanprover/lean4/blob/v4.34.1/src/Lean/Elab/Tactic/Omega.lean&amp;lt;/ref&amp;gt; The tactic&amp;#039;s documentation accordingly calls it &amp;quot;not yet a full decision procedure&amp;quot;.&amp;lt;ref name=&amp;quot;src-tactics&amp;quot; /&amp;gt; Each derived constraint carries a record of how it was obtained, and when a contradiction appears that record is turned into the proof term.&amp;lt;ref name=&amp;quot;src-omega&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Products of variables are outside the fragment. &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt; treats &amp;lt;code&amp;gt;x * y&amp;lt;/code&amp;gt; as an atom, an unknown like any other,&amp;lt;ref name=&amp;quot;src-omega&amp;quot; /&amp;gt; and, on failure, prints constraints that a counterexample might satisfy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean 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;
example (x y : Nat) (h : x * y = 6) : x ≤ 6 := by&lt;br /&gt;
  omega&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
error: omega could not prove the goal:&lt;br /&gt;
a possible counterexample may satisfy the constraints&lt;br /&gt;
  a ≥ 7&lt;br /&gt;
where&lt;br /&gt;
 a := ↑x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== simp ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;simp&amp;lt;/code&amp;gt; is not a decision procedure. It is a rewriting engine: the reference manual describes it as performing inside-out rewriting of terms from a database of simplification rules.&amp;lt;ref name=&amp;quot;manual-simp&amp;quot;&amp;gt;Lean Developers, &amp;#039;&amp;#039;The Lean Language Reference&amp;#039;&amp;#039;, version 4.34.0, chapter &amp;quot;The Simplifier&amp;quot;. https://lean-lang.org/doc/reference/4.34.0/The-Simplifier/&amp;lt;/ref&amp;gt; The database is the &amp;#039;&amp;#039;&amp;#039;simp set&amp;#039;&amp;#039;&amp;#039;: every theorem marked &amp;lt;code&amp;gt;@[simp]&amp;lt;/code&amp;gt;, read as an equation to be used from left to right, together with any lemmas named in the call.&amp;lt;ref name=&amp;quot;lean4-paper&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 12699, Springer, 2021, pp. 625–635. doi:10.1007/978-3-030-79876-5_37&amp;lt;/ref&amp;gt; A goal is closed when it rewrites to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;. The option &amp;lt;code&amp;gt;trace.Meta.Tactic.simp.rewrite&amp;lt;/code&amp;gt; shows each step:&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 rev : List α → List α&lt;br /&gt;
  | [] =&amp;gt; []&lt;br /&gt;
  | a :: as =&amp;gt; rev as ++ [a]&lt;br /&gt;
&lt;br /&gt;
@[simp] theorem rev_nil : rev ([] : List α) = [] := rfl&lt;br /&gt;
@[simp] theorem rev_cons (a : α) (as : List α) :&lt;br /&gt;
    rev (a :: as) = rev as ++ [a] := rfl&lt;br /&gt;
&lt;br /&gt;
set_option trace.Meta.Tactic.simp.rewrite true in&lt;br /&gt;
example (a b : Nat) : rev [a, b] = [b, a] := by&lt;br /&gt;
  simp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
[Meta.Tactic.simp.rewrite] rev_cons:1000:&lt;br /&gt;
      rev [a, b]&lt;br /&gt;
    ==&amp;gt;&lt;br /&gt;
      rev [b] ++ [a]&lt;br /&gt;
[Meta.Tactic.simp.rewrite] rev_cons:1000:&lt;br /&gt;
      rev [b]&lt;br /&gt;
    ==&amp;gt;&lt;br /&gt;
      rev [] ++ [b]&lt;br /&gt;
[Meta.Tactic.simp.rewrite] rev_nil:1000:&lt;br /&gt;
      rev []&lt;br /&gt;
    ==&amp;gt;&lt;br /&gt;
      []&lt;br /&gt;
[Meta.Tactic.simp.rewrite] List.nil_append:1000:&lt;br /&gt;
      [] ++ [b]&lt;br /&gt;
    ==&amp;gt;&lt;br /&gt;
      [b]&lt;br /&gt;
[Meta.Tactic.simp.rewrite] List.cons_append:1000:&lt;br /&gt;
      [b] ++ [a]&lt;br /&gt;
    ==&amp;gt;&lt;br /&gt;
      b :: ([] ++ [a])&lt;br /&gt;
[Meta.Tactic.simp.rewrite] List.nil_append:1000:&lt;br /&gt;
      [] ++ [a]&lt;br /&gt;
    ==&amp;gt;&lt;br /&gt;
      [a]&lt;br /&gt;
[Meta.Tactic.simp.rewrite] eq_self:1000:&lt;br /&gt;
      [b, a] = [b, a]&lt;br /&gt;
    ==&amp;gt;&lt;br /&gt;
      True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The number after each lemma name is its priority. Two of the lemmas come from this page, the rest from Lean&amp;#039;s library. The variant &amp;lt;code&amp;gt;simp?&amp;lt;/code&amp;gt; reports a &amp;lt;code&amp;gt;simp only [...]&amp;lt;/code&amp;gt; call naming just the lemmas used; pasted in its place, it makes the proof independent of later changes to the library&amp;#039;s simp set. Whether &amp;lt;code&amp;gt;simp&amp;lt;/code&amp;gt; succeeds depends on the simp set as much as on the goal: it answers no question by itself. Its proof is assembled from the lemmas it used and is checked by the Lean kernel like any other term.&lt;br /&gt;
&lt;br /&gt;
== grind ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; is part of core Lean in version 4.34.1 and needs no import. Its documentation calls it inspired by modern SMT solvers. It keeps one shared collection of facts, groups terms known to be equal by &amp;#039;&amp;#039;&amp;#039;congruence closure&amp;#039;&amp;#039;&amp;#039;, instantiates theorems by &amp;#039;&amp;#039;&amp;#039;E-matching&amp;#039;&amp;#039;&amp;#039; (matching a theorem&amp;#039;s pattern modulo the equalities known so far), splits cases, and passes facts to specialised solvers for linear integer arithmetic, for commutative rings and fields, and for linear arithmetic (its &amp;lt;code&amp;gt;linarith&amp;lt;/code&amp;gt; component).&amp;lt;ref name=&amp;quot;src-grind&amp;quot;&amp;gt;Lean 4 source code, version 4.34.1 (2026), file &amp;lt;code&amp;gt;src/Init/Grind/Tactics.lean&amp;lt;/code&amp;gt;: the documentation string of the &amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; tactic. Apache License 2.0. https://github.com/leanprover/lean4/blob/v4.34.1/src/Init/Grind/Tactics.lean&amp;lt;/ref&amp;gt; The reference manual states that it &amp;quot;produces ordinary Lean proof terms for every fact it adds&amp;quot;.&amp;lt;ref name=&amp;quot;manual-grind&amp;quot;&amp;gt;Lean Developers, &amp;#039;&amp;#039;The Lean Language Reference&amp;#039;&amp;#039;, version 4.34.0, chapter &amp;quot;The grind tactic&amp;quot;. https://lean-lang.org/doc/reference/4.34.0/The--grind--tactic/&amp;lt;/ref&amp;gt;&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 f (a : Nat) : Nat := a + 1&lt;br /&gt;
def g (a : Nat) : Nat := a - 1&lt;br /&gt;
&lt;br /&gt;
@[grind =] theorem g_f (x : Nat) : g (f x) = x := by&lt;br /&gt;
  simp [f, g]&lt;br /&gt;
&lt;br /&gt;
theorem grind_demo {a b : Nat} (h : f b = a) : g a = b := by&lt;br /&gt;
  grind&lt;br /&gt;
&lt;br /&gt;
example {x y : Int} : 2 * x + 4 * y ≠ 5 := by&lt;br /&gt;
  grind&lt;br /&gt;
&lt;br /&gt;
#print axioms grind_demo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute &amp;lt;code&amp;gt;@[grind =]&amp;lt;/code&amp;gt; makes the left side &amp;lt;code&amp;gt;g (f x)&amp;lt;/code&amp;gt; a pattern. The goal mentions &amp;lt;code&amp;gt;g a&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;g (f b)&amp;lt;/code&amp;gt;; but &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; puts &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;f b&amp;lt;/code&amp;gt; in one equality class, so the pattern matches modulo that equality and congruence closure finishes the proof. The second example, taken from the tactic&amp;#039;s documentation, is linear integer arithmetic: &amp;lt;code&amp;gt;2 * x + 4 * y&amp;lt;/code&amp;gt; is even and 5 is not. The last line prints &amp;lt;code&amp;gt;&amp;#039;grind_demo&amp;#039; depends on axioms: [propext, Classical.choice, Quot.sound]&amp;lt;/code&amp;gt;, the standard three and nothing more. Its documentation warns that &amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; is not designed for problems whose search space explodes combinatorially, and points to &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt; for bit-level and combinatorial problems.&amp;lt;ref name=&amp;quot;src-grind&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== bv_decide ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt; closes goals about fixed-width bit vectors (&amp;lt;code&amp;gt;BitVec n&amp;lt;/code&amp;gt;) and &amp;lt;code&amp;gt;Bool&amp;lt;/code&amp;gt;: the Lean counterpart of the SMT-LIB logic QF_BV. It needs &amp;lt;code&amp;gt;import Std.Tactic.BVDecide&amp;lt;/code&amp;gt;, and on failure it prints a counterexample.&amp;lt;ref name=&amp;quot;src-tactics&amp;quot; /&amp;gt; Its implementation notes give the steps. It starts a proof by contradiction, normalises the hypotheses with a simp set, and represents the problem as a Lean value of a syntax-tree type. A verified bit-blaster turns that value into an and-inverter graph and then into a formula in conjunctive normal form. The SAT solver CaDiCaL, which is shipped beside the &amp;lt;code&amp;gt;lean&amp;lt;/code&amp;gt; executable, is asked for an LRAT proof that the formula is unsatisfiable. That proof is checked by an LRAT checker with a soundness proof in Lean, and the proofs so far are chained back to the goal.&amp;lt;ref name=&amp;quot;src-bvdecide&amp;quot;&amp;gt;Lean 4 source code, version 4.34.1 (2026), file &amp;lt;code&amp;gt;src/Lean/Elab/Tactic/BVDecide.lean&amp;lt;/code&amp;gt;: the overview of &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt;, sections &amp;quot;Architecture&amp;quot; and &amp;quot;Axioms&amp;quot;. Apache License 2.0. https://github.com/leanprover/lean4/blob/v4.34.1/src/Lean/Elab/Tactic/BVDecide.lean&amp;lt;/ref&amp;gt;&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;
import Std.Tactic.BVDecide&lt;br /&gt;
&lt;br /&gt;
theorem add_as_xor (x y : BitVec 8) :&lt;br /&gt;
    x + y = (x ^^^ y) + ((x &amp;amp;amp;&amp;amp;amp;&amp;amp;amp; y) &amp;amp;lt;&amp;amp;lt;&amp;amp;lt; 1) := by&lt;br /&gt;
  bv_decide&lt;br /&gt;
&lt;br /&gt;
#print axioms add_as_xor&lt;br /&gt;
#print add_as_xor._native.bv_decide.ax_1_5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;add_as_xor&amp;#039; depends on axioms: [propext, Classical.choice, Quot.sound, add_as_xor._native.bv_decide.ax_1_5]&lt;br /&gt;
axiom add_as_xor._native.bv_decide.ax_1_5 : Std.Tactic.BVDecide.Reflect.verifyBVExpr add_as_xor._expr_def_1_1&lt;br /&gt;
    add_as_xor._cert_def_1_1 =&lt;br /&gt;
  true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output states the trust story exactly. The fourth axiom says that one Boolean function, &amp;lt;code&amp;gt;verifyBVExpr&amp;lt;/code&amp;gt;, returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; on the encoded problem and on the certificate string the solver produced. In Lean&amp;#039;s library, &amp;lt;code&amp;gt;verifyBVExpr&amp;lt;/code&amp;gt; bit-blasts the problem and checks the certificate against the resulting formula, and the theorem &amp;lt;code&amp;gt;unsat_of_verifyBVExpr_eq_true&amp;lt;/code&amp;gt; proves that a &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; result means the problem is unsatisfiable.&amp;lt;ref name=&amp;quot;src-reflect&amp;quot;&amp;gt;Lean 4 source code, version 4.34.1 (2026), file &amp;lt;code&amp;gt;src/Std/Tactic/BVDecide/Reflect.lean&amp;lt;/code&amp;gt;: the definition &amp;lt;code&amp;gt;verifyBVExpr&amp;lt;/code&amp;gt; and the theorem &amp;lt;code&amp;gt;unsat_of_verifyBVExpr_eq_true&amp;lt;/code&amp;gt;. Apache License 2.0. https://github.com/leanprover/lean4/blob/v4.34.1/src/Std/Tactic/BVDecide/Reflect.lean&amp;lt;/ref&amp;gt; So the result relies on three things: the Lean kernel, which checks the soundness theorems and the chain of reasoning around the axiom; the compiled evaluation of &amp;lt;code&amp;gt;verifyBVExpr&amp;lt;/code&amp;gt;, which is what the axiom asserts; and therefore the Lean compiler that produced that code, together with any definition whose compiled form is replaced by another implementation through &amp;lt;code&amp;gt;@[implemented_by]&amp;lt;/code&amp;gt;, a dependency the documentation of &amp;lt;code&amp;gt;decide +native&amp;lt;/code&amp;gt; spells out for the same mechanism.&amp;lt;ref name=&amp;quot;src-tactics&amp;quot; /&amp;gt; The implementation notes say so: the result of the compiled check is added as an axiom, &amp;quot;thus adding the Lean compiler to the trusted code base&amp;quot;.&amp;lt;ref name=&amp;quot;src-bvdecide&amp;quot; /&amp;gt; The SAT solver is not trusted. A wrong certificate makes the check return &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; and the tactic fails. The Lean kernel does not repeat the bit-level computation itself.&lt;br /&gt;
&lt;br /&gt;
The reference manual&amp;#039;s page on validating proofs records that up to version 4.28.0 every such use showed up in &amp;lt;code&amp;gt;#print axioms&amp;lt;/code&amp;gt; as one shared axiom, &amp;lt;code&amp;gt;Lean.trustCompiler&amp;lt;/code&amp;gt;, and that since 4.29.0 these tactics instead introduce one dedicated axiom for each computation, as above.&amp;lt;ref name=&amp;quot;manual-validating&amp;quot;&amp;gt;Lean Developers, &amp;#039;&amp;#039;The Lean Language Reference&amp;#039;&amp;#039;, version 4.34.0, &amp;quot;Validating a Lean Proof&amp;quot;. https://lean-lang.org/doc/reference/4.34.0/ValidatingProofs/&amp;lt;/ref&amp;gt; In 4.34.1 the older primitive &amp;lt;code&amp;gt;Lean.ofReduceBool&amp;lt;/code&amp;gt; still exists; &amp;lt;code&amp;gt;#check @Lean.ofReduceBool&amp;lt;/code&amp;gt; answers with the warning that native reduction inside the Lean kernel is deprecated. For the older mechanism the manual states that external checkers cannot check such proofs, having no access to the Lean compiler, and that proofs needing that level of checking must avoid native evaluation.&amp;lt;ref name=&amp;quot;manual-validating&amp;quot; /&amp;gt; Under the newer one a checker sees, in the list of axioms, exactly which computation it is asked to take on trust. [[Lean theorem prover/System/Proof export and independent checkers|Proof export and independent checkers]] takes this up.&lt;br /&gt;
&lt;br /&gt;
A false bit-vector claim is refuted with values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lean 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;
import Std.Tactic.BVDecide&lt;br /&gt;
&lt;br /&gt;
example (x y : BitVec 4) : x * y = x + y := by&lt;br /&gt;
  bv_decide&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
error: The prover found a counterexample, consider the following assignment:&lt;br /&gt;
x = 15#4&lt;br /&gt;
y = 15#4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Indeed 15 × 15 = 225, which is 1 modulo 16, while 15 + 15 = 30, which is 14.&lt;br /&gt;
&lt;br /&gt;
== Side by side ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tactic !! Covers !! Evidence !! Trusted beyond the Lean kernel&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;decide&amp;lt;/code&amp;gt; || propositions with a &amp;lt;code&amp;gt;Decidable&amp;lt;/code&amp;gt; instance that reduces || reflection, evaluated by the Lean kernel || nothing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;omega&amp;lt;/code&amp;gt; || linear arithmetic over &amp;lt;code&amp;gt;Int&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Nat&amp;lt;/code&amp;gt; (incomplete) || ordinary proof term || nothing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;simp&amp;lt;/code&amp;gt; || whatever the simp set rewrites to &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; || ordinary proof term || nothing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;grind&amp;lt;/code&amp;gt; || equalities, theorem instances, case splits, arithmetic || ordinary proof term || nothing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;bv_decide&amp;lt;/code&amp;gt; || fixed-width bit vectors and &amp;lt;code&amp;gt;Bool&amp;lt;/code&amp;gt; || asserted evaluation of a verified checker || the Lean compiler and the compiled code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In every row the search can be wrong without harm: a mistaken search produces a term the Lean kernel rejects, or no term. Only the last row moves part of the checking out of the Lean kernel.&lt;br /&gt;
&lt;br /&gt;
== Next ==&lt;br /&gt;
&lt;br /&gt;
[[Lean theorem prover/System/Syntax extension and hygienic macros|Syntax extension and hygienic macros]] shows how new notation, and new tactics, are added to the language.&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>