<?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%2FFoundations%2FClassical_logic_from_choice</id>
	<title>Lean theorem prover/Foundations/Classical logic from choice - 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%2FFoundations%2FClassical_logic_from_choice"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=Lean_theorem_prover/Foundations/Classical_logic_from_choice&amp;action=history"/>
	<updated>2026-10-21T06:37:22Z</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/Foundations/Classical_logic_from_choice&amp;diff=6783&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/Foundations/Classical_logic_from_choice&amp;diff=6783&amp;oldid=prev"/>
		<updated>2026-10-15T19:34:59Z</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:Classical logic from choice}}&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:Classical logic from choice}}&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/What the axioms are}}&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/What the axioms are}}&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;The rules of Lean&amp;#039;s type theory, taken alone, are constructive: to assert &amp;lt;code&amp;gt;p ∨ ¬p&amp;lt;/code&amp;gt;&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;The rules of Lean&amp;#039;s type theory, taken alone, are constructive: to assert &amp;lt;code&amp;gt;p ∨ ¬p&amp;lt;/code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key pma_cutover_20261020t051351z-soft_:diff:1.41:old-6576:rev-6783: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/Foundations/Classical_logic_from_choice&amp;diff=6576&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/Foundations/Classical_logic_from_choice&amp;diff=6576&amp;oldid=prev"/>
		<updated>2026-10-14T18:01:02Z</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:Classical logic from choice}}&lt;br /&gt;
{{Plebeian|Lean theorem prover/Explainers/What the axioms are}}&lt;br /&gt;
&lt;br /&gt;
The rules of Lean&amp;#039;s type theory, taken alone, are constructive: to assert &amp;lt;code&amp;gt;p ∨ ¬p&amp;lt;/code&amp;gt;&lt;br /&gt;
is to know which of the two disjuncts holds, and for an arbitrary &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; that is not&lt;br /&gt;
known.&amp;lt;ref name=&amp;quot;tpil-logic&amp;quot;&amp;gt;Jeremy Avigad, Leonardo de Moura, Soonho Kong and Sebastian Ullrich, &amp;#039;&amp;#039;Theorem Proving in Lean 4&amp;#039;&amp;#039;, chapter 3 &amp;quot;Propositions and Proofs&amp;quot;, §3.5 &amp;quot;Classical Logic&amp;quot;. https://lean-lang.org/theorem_proving_in_lean4/Propositions-and-Proofs/&amp;lt;/ref&amp;gt; Lean does not add excluded middle as an axiom. It proves it, as the theorem&lt;br /&gt;
&amp;lt;code&amp;gt;Classical.em&amp;lt;/code&amp;gt;, from the axiom of choice together with propositional and function&lt;br /&gt;
extensionality. The argument is known as &amp;#039;&amp;#039;&amp;#039;Diaconescu&amp;#039;s theorem&amp;#039;&amp;#039;&amp;#039;. This page follows the&lt;br /&gt;
proof as Lean&amp;#039;s core library carries it, then the decidability of every proposition that&lt;br /&gt;
follows from it, the &amp;lt;code&amp;gt;noncomputable&amp;lt;/code&amp;gt; marker, and what is lost computationally.&lt;br /&gt;
&lt;br /&gt;
== The statement ==&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;
#check @Classical.em&lt;br /&gt;
#print axioms Classical.em&lt;br /&gt;
&amp;lt;/pre&amp;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;
Classical.em : ∀ (p : Prop), p ∨ ¬p&lt;br /&gt;
&amp;#039;Classical.em&amp;#039; depends on axioms: [propext, Classical.choice, Quot.sound]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three axioms of [[Lean theorem prover/Foundations/The three axioms|the three axioms]]&lt;br /&gt;
appear. &amp;lt;code&amp;gt;Quot.sound&amp;lt;/code&amp;gt; enters through &amp;lt;code&amp;gt;funext&amp;lt;/code&amp;gt;, which Lean proves from&lt;br /&gt;
quotients.&lt;br /&gt;
&lt;br /&gt;
== The argument ==&lt;br /&gt;
&lt;br /&gt;
Fix a proposition &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. Define two predicates on propositions:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U(x) \;:\equiv\; (x = \mathrm{True}) \lor p \qquad\qquad V(x) \;:\equiv\; (x = \mathrm{False}) \lor p&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each is inhabited: &amp;lt;math&amp;gt;U(\mathrm{True})&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;V(\mathrm{False})&amp;lt;/math&amp;gt; hold by&lt;br /&gt;
their left disjuncts. Choice therefore yields a proposition &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; with&lt;br /&gt;
&amp;lt;math&amp;gt;U(u)&amp;lt;/math&amp;gt; and a proposition &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;V(v)&amp;lt;/math&amp;gt;. Two facts follow.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;First, either &amp;lt;math&amp;gt;u \neq v&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&amp;#039;&amp;#039;&amp;#039; Each of &amp;lt;math&amp;gt;U(u)&amp;lt;/math&amp;gt; and&lt;br /&gt;
&amp;lt;math&amp;gt;V(v)&amp;lt;/math&amp;gt; is a disjunction, giving four cases. If either right disjunct holds,&lt;br /&gt;
&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; holds. In the remaining case &amp;lt;math&amp;gt;u = \mathrm{True}&amp;lt;/math&amp;gt; and&lt;br /&gt;
&amp;lt;math&amp;gt;v = \mathrm{False}&amp;lt;/math&amp;gt;, and since &amp;lt;math&amp;gt;\mathrm{True} \neq \mathrm{False}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;u \neq v&amp;lt;/math&amp;gt;. This step is a case analysis on proofs of disjunctions, and it&lt;br /&gt;
produces a proposition, so it is permitted.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Second, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; implies &amp;lt;math&amp;gt;u = v&amp;lt;/math&amp;gt;.&amp;#039;&amp;#039;&amp;#039; If &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; holds, both&lt;br /&gt;
predicates are true of every &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, so &amp;lt;math&amp;gt;U(x)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;V(x)&amp;lt;/math&amp;gt; are&lt;br /&gt;
equivalent for each &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;. Propositional extensionality makes them equal for each&lt;br /&gt;
&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, and function extensionality makes &amp;lt;math&amp;gt;U = V&amp;lt;/math&amp;gt;. The choice function&lt;br /&gt;
applied to equal predicates gives equal results, so &amp;lt;math&amp;gt;u = v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Combining the two: if &amp;lt;math&amp;gt;u \neq v&amp;lt;/math&amp;gt;, the second fact gives &amp;lt;math&amp;gt;\neg p&amp;lt;/math&amp;gt;;&lt;br /&gt;
otherwise &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. Either way &amp;lt;math&amp;gt;p \lor \neg p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The core library&amp;#039;s proof, in &amp;lt;code&amp;gt;Init/Classical.lean&amp;lt;/code&amp;gt;, follows exactly these&lt;br /&gt;
steps.&amp;lt;ref name=&amp;quot;classical&amp;quot;&amp;gt;Lean 4 source, file &amp;lt;code&amp;gt;src/Init/Classical.lean&amp;lt;/code&amp;gt;, version 4.34.1: &amp;lt;code&amp;gt;Classical.em&amp;lt;/code&amp;gt; (&amp;quot;Diaconescu&amp;#039;s theorem&amp;quot;), &amp;lt;code&amp;gt;Classical.choose&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Classical.propDecidable&amp;lt;/code&amp;gt;. Apache License 2.0. https://github.com/leanprover/lean4/blob/v4.34.1/src/Init/Classical.lean&amp;lt;/ref&amp;gt; Below is a copy, lightly condensed, in which one case is closed&lt;br /&gt;
by an explicit term where the original calls &amp;lt;code&amp;gt;simp&amp;lt;/code&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;
open Classical in&lt;br /&gt;
theorem em&amp;#039; (p : Prop) : p ∨ ¬p :=&lt;br /&gt;
  let U (x : Prop) : Prop := x = True ∨ p&lt;br /&gt;
  let V (x : Prop) : Prop := x = False ∨ p&lt;br /&gt;
  have exU : ∃ x, U x := ⟨True, Or.inl rfl⟩&lt;br /&gt;
  have exV : ∃ x, V x := ⟨False, Or.inl rfl⟩&lt;br /&gt;
  let u : Prop := choose exU&lt;br /&gt;
  let v : Prop := choose exV&lt;br /&gt;
  have u_def : U u := choose_spec exU&lt;br /&gt;
  have v_def : V v := choose_spec exV&lt;br /&gt;
  have not_uv_or_p : u ≠ v ∨ p :=&lt;br /&gt;
    match u_def, v_def with&lt;br /&gt;
    | Or.inr h, _ =&amp;gt; Or.inr h&lt;br /&gt;
    | _, Or.inr h =&amp;gt; Or.inr h&lt;br /&gt;
    | Or.inl hut, Or.inl hvf =&amp;gt;&lt;br /&gt;
      Or.inl fun huv =&amp;gt; true_ne_false (hut.symm.trans (huv.trans hvf))&lt;br /&gt;
  have p_implies_uv : p → u = v := fun hp =&amp;gt;&lt;br /&gt;
    have hpred : U = V :=&lt;br /&gt;
      funext fun _ =&amp;gt; propext ⟨fun _ =&amp;gt; Or.inr hp, fun _ =&amp;gt; Or.inr hp⟩&lt;br /&gt;
    have h₀ : ∀ exU exV, @choose _ U exU = @choose _ V exV := by&lt;br /&gt;
      rw [hpred]; intros; rfl&lt;br /&gt;
    h₀ _ _&lt;br /&gt;
  match not_uv_or_p with&lt;br /&gt;
  | Or.inl hne =&amp;gt; Or.inr (mt p_implies_uv hne)&lt;br /&gt;
  | Or.inr h =&amp;gt; Or.inl h&lt;br /&gt;
&lt;br /&gt;
#print axioms em&amp;#039;&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;em&amp;#039;&amp;#039; depends on axioms: [propext, Classical.choice, Quot.sound]&amp;lt;/code&amp;gt;.&lt;br /&gt;
The step &amp;lt;code&amp;gt;h₀&amp;lt;/code&amp;gt; is where the choice function is shown to respect equality of&lt;br /&gt;
predicates. After rewriting &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt;, the two sides are&lt;br /&gt;
&amp;lt;code&amp;gt;choose&amp;lt;/code&amp;gt; applied to the same predicate and to two proofs of the same&lt;br /&gt;
proposition, and &amp;lt;code&amp;gt;rfl&amp;lt;/code&amp;gt; closes the goal because those proofs are definitionally&lt;br /&gt;
equal.&lt;br /&gt;
&lt;br /&gt;
== Where the strength comes from ==&lt;br /&gt;
&lt;br /&gt;
The essential ingredient is not choice alone but choice combined with extensionality.&lt;br /&gt;
Constructive systems such as Bishop&amp;#039;s constructive analysis and Martin-Löf&amp;#039;s type theory&lt;br /&gt;
affirm a form of the axiom of choice, the statement that&lt;br /&gt;
&amp;lt;math&amp;gt;\forall x\, \exists y\, \phi(x,y)&amp;lt;/math&amp;gt; gives a function &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; with&lt;br /&gt;
&amp;lt;math&amp;gt;\forall x\, \phi(x, f(x))&amp;lt;/math&amp;gt;, without affirming excluded middle. Bell&amp;#039;s survey&lt;br /&gt;
explains why there is no conflict. On a constructive reading that choice principle follows&lt;br /&gt;
from what existence means. The derivation of excluded middle needs more: besides choice, it&lt;br /&gt;
uses a comprehension principle and the extensionality of functions on predicates, so a&lt;br /&gt;
constructive system that affirms choice but not excluded middle must give up one of the two;&lt;br /&gt;
Bell finds a constructive justification for comprehension but none for extensionality.&amp;lt;ref name=&amp;quot;sep&amp;quot;&amp;gt;John L. Bell, &amp;quot;The Axiom of Choice&amp;quot;, &amp;#039;&amp;#039;Stanford Encyclopedia of Philosophy&amp;#039;&amp;#039;, substantive revision of 10 December 2021, §5 &amp;quot;The Axiom of Choice and Logic&amp;quot; and note 15. https://plato.stanford.edu/entries/axiom-choice/&amp;lt;/ref&amp;gt; Lean asserts both. Its &amp;lt;code&amp;gt;Classical.choice&amp;lt;/code&amp;gt; is a single&lt;br /&gt;
global choice function on all inhabited types, and &amp;lt;code&amp;gt;propext&amp;lt;/code&amp;gt; with&lt;br /&gt;
&amp;lt;code&amp;gt;funext&amp;lt;/code&amp;gt; makes it extensional. Once a choice function must give equal answers on&lt;br /&gt;
equivalent predicates, it can be made to decide &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diaconescu first derived excluded middle from the axiom of choice, in 1975, in a&lt;br /&gt;
category-theoretic setting.&amp;lt;ref name=&amp;quot;diaconescu&amp;quot;&amp;gt;Radu Diaconescu, &amp;quot;Axiom of choice and complementation&amp;quot;, &amp;#039;&amp;#039;Proceedings of the American Mathematical Society&amp;#039;&amp;#039; 51 (1975), 176–178. https://doi.org/10.1090/S0002-9939-1975-0373893-X&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;sep&amp;quot; /&amp;gt; Goodman and Myhill&amp;#039;s&lt;br /&gt;
note of 1978 is titled &amp;quot;Choice implies excluded middle&amp;quot;.&amp;lt;ref name=&amp;quot;goodman-myhill&amp;quot;&amp;gt;Nicolas D. Goodman and John Myhill, &amp;quot;Choice implies excluded middle&amp;quot;, &amp;#039;&amp;#039;Zeitschrift für mathematische Logik und Grundlagen der Mathematik&amp;#039;&amp;#039; 24 (1978), 461. https://doi.org/10.1002/malq.19780242514&amp;lt;/ref&amp;gt; Bell&lt;br /&gt;
traces the idea of the proof presented above, with two predicates and an extensional choice function,&lt;br /&gt;
to Goodman and Myhill, whose note built on Diaconescu&amp;#039;s result.&amp;lt;ref name=&amp;quot;sep&amp;quot; /&amp;gt; Lean&amp;#039;s documentation names the theorem after&lt;br /&gt;
Diaconescu.&amp;lt;ref name=&amp;quot;classical&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Decidable and propDecidable ==&lt;br /&gt;
&lt;br /&gt;
The disjunction &amp;lt;code&amp;gt;p ∨ ¬p&amp;lt;/code&amp;gt; is a proposition, and an inductive proposition with two&lt;br /&gt;
constructors can be eliminated only into propositions. A program therefore cannot branch on it. For&lt;br /&gt;
branching Lean uses a different type, &amp;lt;code&amp;gt;Decidable p&amp;lt;/code&amp;gt;, whose two constructors carry&lt;br /&gt;
the same information as the two disjuncts but which lives in &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;:&amp;lt;ref name=&amp;quot;tpil&amp;quot;&amp;gt;Jeremy Avigad, Leonardo de Moura, Soonho Kong and Sebastian Ullrich, &amp;#039;&amp;#039;Theorem Proving in Lean 4&amp;#039;&amp;#039;, chapter 12 &amp;quot;Axioms and Computation&amp;quot;, the introduction, §12.5 &amp;quot;Choice&amp;quot; and §12.6 &amp;quot;The Law of the Excluded Middle&amp;quot;. https://lean-lang.org/theorem_proving_in_lean4/Axioms-and-Computation/&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;
#print Decidable&lt;br /&gt;
#check @Classical.propDecidable&lt;br /&gt;
#eval decide (2 &amp;amp;lt; 3)&lt;br /&gt;
example : decide (2 &amp;amp;lt; 3) = true := rfl&lt;br /&gt;
&amp;lt;/pre&amp;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;
Classical.propDecidable : (a : Prop) → Decidable a&lt;br /&gt;
true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt; expression asks for a &amp;lt;code&amp;gt;Decidable&amp;lt;/code&amp;gt; instance of its condition.&lt;br /&gt;
For &amp;lt;code&amp;gt;2 &amp;amp;lt; 3&amp;lt;/code&amp;gt; the instance is an algorithm on natural numbers, so&lt;br /&gt;
&amp;lt;code&amp;gt;decide (2 &amp;amp;lt; 3)&amp;lt;/code&amp;gt; evaluates to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, both in compiled code and by&lt;br /&gt;
&amp;lt;code&amp;gt;rfl&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;Classical.propDecidable&amp;lt;/code&amp;gt; supplies an instance for every&lt;br /&gt;
proposition. It is defined by applying &amp;lt;code&amp;gt;Classical.choice&amp;lt;/code&amp;gt; to the fact, given by&lt;br /&gt;
&amp;lt;code&amp;gt;Classical.em&amp;lt;/code&amp;gt;, that &amp;lt;code&amp;gt;Decidable a&amp;lt;/code&amp;gt; is inhabited. It is a scoped&lt;br /&gt;
instance of low priority, active only after &amp;lt;code&amp;gt;open Classical&amp;lt;/code&amp;gt;, so that where an&lt;br /&gt;
ordinary instance also applies, the ordinary one is tried first.&amp;lt;ref name=&amp;quot;classical&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Noncomputable definitions ==&lt;br /&gt;
&lt;br /&gt;
A definition that uses the classical instance to produce data cannot be compiled, and Lean&lt;br /&gt;
requires it to say so:&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;
open Classical in&lt;br /&gt;
noncomputable def classify (p : Prop) : Bool := if p then true else false&lt;br /&gt;
&lt;br /&gt;
theorem classify_true : classify True = true := by&lt;br /&gt;
  simp [classify]&lt;br /&gt;
&lt;br /&gt;
#print axioms classify&lt;br /&gt;
#print axioms classify_true&lt;br /&gt;
#reduce classify True&lt;br /&gt;
&amp;lt;/pre&amp;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;classify&amp;#039; depends on axioms: [propext, Classical.choice, Quot.sound]&lt;br /&gt;
&amp;#039;classify_true&amp;#039; depends on axioms: [propext, Classical.choice, Quot.sound]&lt;br /&gt;
Decidable.rec (fun h =&amp;gt; false) (fun h =&amp;gt; true) (Classical.choice ⋯)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Without the marker the same definition is refused:&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;
open Classical in&lt;br /&gt;
def classify&amp;#039; (p : Prop) : Bool := if p then true else false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lean reports: &amp;lt;code&amp;gt;failed to compile definition, consider marking it as &amp;#039;noncomputable&amp;#039;&lt;br /&gt;
because it depends on &amp;#039;propDecidable&amp;#039;, which is &amp;#039;noncomputable&amp;#039;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== What is lost ==&lt;br /&gt;
&lt;br /&gt;
Three things are lost when data is obtained from choice, and one is kept.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Evaluation.&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;#reduce classify True&amp;lt;/code&amp;gt; stops at&lt;br /&gt;
&amp;lt;code&amp;gt;Classical.choice&amp;lt;/code&amp;gt;, an axiom with nothing to unfold. The term is a closed&lt;br /&gt;
&amp;lt;code&amp;gt;Bool&amp;lt;/code&amp;gt; that is neither &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; nor &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; by computation,&lt;br /&gt;
although &amp;lt;code&amp;gt;classify_true&amp;lt;/code&amp;gt; proves that it equals &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. &amp;#039;&amp;#039;Theorem Proving in Lean 4&amp;#039;&amp;#039; describes a&lt;br /&gt;
&amp;quot;computationally pure&amp;quot; fragment of Lean in which every closed term of type&lt;br /&gt;
&amp;lt;code&amp;gt;Nat&amp;lt;/code&amp;gt; reduces to a numeral; a definition that uses choice for data lies outside&lt;br /&gt;
it.&amp;lt;ref name=&amp;quot;tpil&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Compilation.&amp;#039;&amp;#039;&amp;#039; There is no code to generate for an axiom, so such a definition cannot&lt;br /&gt;
be run, as the refusal above shows.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Information.&amp;#039;&amp;#039;&amp;#039; A classical existence proof does not say how to find the object, and a&lt;br /&gt;
function defined with &amp;lt;code&amp;gt;Classical.choose&amp;lt;/code&amp;gt; does not say which object it picked.&lt;br /&gt;
&amp;#039;&amp;#039;Theorem Proving in Lean 4&amp;#039;&amp;#039; illustrates this with a left inverse of an injective function:&lt;br /&gt;
a function from a classical point of view, unacceptable from a constructive one, since&lt;br /&gt;
there is in general no way to implement it.&amp;lt;ref name=&amp;quot;tpil&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What is kept&amp;#039;&amp;#039;&amp;#039; is classical reasoning in proofs. Proofs are erased when Lean compiles a&lt;br /&gt;
definition, so excluded middle, proof by contradiction and the other classical principles&lt;br /&gt;
may be used freely to establish properties of programs that themselves compute.&lt;br /&gt;
&amp;#039;&amp;#039;Theorem Proving in Lean 4&amp;#039;&amp;#039; puts the line exactly there: classical principles are&lt;br /&gt;
compatible with code generation so long as they are not used to manufacture data.&amp;lt;ref name=&amp;quot;tpil&amp;quot; /&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;noncomputable&amp;lt;/code&amp;gt; marker, not the axiom list, shows on which side of the line a&lt;br /&gt;
definition falls: a theorem proved with excluded middle lists &amp;lt;code&amp;gt;Classical.choice&amp;lt;/code&amp;gt;&lt;br /&gt;
among its axioms, yet the programs it is about still run.&lt;br /&gt;
&lt;br /&gt;
== Next ==&lt;br /&gt;
&lt;br /&gt;
[[Lean theorem prover/Foundations/Proof irrelevance and subsingleton elimination|Proof irrelevance and subsingleton elimination]]&lt;br /&gt;
explains why a proof of &amp;lt;code&amp;gt;p ∨ ¬p&amp;lt;/code&amp;gt; cannot be used to branch, while a proof of an&lt;br /&gt;
equation can be used to cast.&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>