Zulip Chat Archive
Stream: new members
Topic: Universal vs existential quantifier proof computation
Plamen Dimitrov (Dec 14 2025 at 18:19):
Hi all, why is the computational structure for dependent function types preserved in Lean but the one for pairs isn't? If I have a proof h : ∀ x : α, P x I can apply it to data x to produce a proof of the proposition P xbut if I instead have a proof h : ∃ x : α, P xI need a noncomputable h.choose to extract the witness. Axiom of choice and classical reasoning aside, I assume the problem boils down to not allowing eliminating from the Prop universe into a Type universe which would differentiate the second from the first case? Because if one has already made the effort to construct the witness x and thus construct an existential proof h then why won't they be able to reuse their own constriction from within the proof term?
Aaron Liu (Dec 14 2025 at 18:21):
Because of definitional proof irrelevance, you can't be allowed to project data from proofs
Kevin Buzzard (Dec 14 2025 at 18:21):
Because it's unsound if you can use the witness. Any two proofs of a proposition are equal in lean so in particular different witnesses give the same proof
Aaron Liu (Dec 14 2025 at 18:24):
if the exists statement is the existence of a proof, then you can project it out, so if P is a proposition and h : ∃ x : P, Q x then h.1 : P and h.2 : Q h.1
Niels Voss (Dec 16 2025 at 04:41):
Please see https://leanprover-community.github.io/extras/pitfalls.html#trying-to-extract-data-from-proofs-of-propositions. I think what you might be confused about is why you can seemingly extract data from hf : ∀ x : α, P x, but not from he : ∃ x : α, P x, despite them both being proofs of propositions. The reason for this is that when you apply x to hf, you don't get data, you get a proof, which is perfectly fine. Likewise, you are actually allowed to extract an x from he without choice using Exists.elim provided that this x is only used to produce a proof of a proposition. The only thing that requires using choice is extracting an x from he and then using it to construct an element of some type in Type or above.
Plamen Dimitrov (Dec 16 2025 at 14:07):
First of all, thanks all for replying and the clarifications you added!
I think what you might be confused about is why you can seemingly extract data from
hf : ∀ x : α, P x, but not fromhe : ∃ x : α, P x, despite them both being proofs of propositions.
Exactly, it seemed strange they are treated differently at first.
Likewise, you are actually allowed to extract an
xfromhewithout choice usingExists.elimprovided that thisxis only used to produce a proof of a proposition.
Good clarification, it must explain why we can eliminate in proofs but not outside of them.
The only thing that requires using choice is extracting an
xfromheand then using it to construct an element of some type inTypeor above.
This matches with my suggested assumption above: "I assume the problem boils down to not allowing eliminating from the Prop universe into a Type universe which would differentiate the second from the first case."
Because it's unsound if you can use the witness. Any two proofs of a proposition are equal in lean so in particular different witnesses give the same proof.
I see, so in one sentence because of the design choice of proof irrelevance so that we cannot project two witnesses that might compute differently from the same proof. Or in a validated example:
def he1 : ∃ x, x = 0 := ⟨0, rfl⟩
def he2 : ∃ x, x = 0 := ⟨0 + 0, rfl⟩
def P : Prop := ∃ x, x = 0
def proof_irrelevance : ∀ (p q : P), p = q := sorry
def irrelevant_proofs : he1 = he2 := proof_irrelevance he1 he2
#check he1.1 = he2.1
/-
Invalid projection: Cannot project a value of non-propositional type
Nat
from the expression
he1
which has propositional type
∃ x, x = 0
-/
if the exists statement is the existence of a proof, then you can project it out, so if
Pis a proposition andh : ∃ x : P, Q xthenh.1 : Pandh.2 : Q h.1
Which makes the behavior consistent in allowing exploiting the computational structure of the two proofs as long as the result of this is a proof, i.e. remains in the Prop universe. Just to add a validated example for everyone else that might end up reading this:
def P: Prop := sorry
def Q (x: P): Prop := sorry
def h : ∃ x : P, Q x := sorry
#check h.1 -- : P
#check h.2 -- : Q h.1
Thanks all!
Last updated: Dec 20 2025 at 21:32 UTC