Zulip Chat Archive
Stream: mathlib4
Topic: Proofs that end with Exists.choose_spec
Robert Maxton (Apr 24 2025 at 06:22):
I seem to keep writing proofs relying on Exists.choose
, whose final line turn out to be essentially Exists.choose_spec
, except that the existential hypothesis has either been transformed into something ugly, or I've simply lost the original name. Currently, I handle this with
...
simp
generalize_proofs h
exact h.choose_spec
or the like; but this is of course a non-terminal simp. Is there a systematically better way to handle this I don't know about?
Robert Maxton (Apr 24 2025 at 06:23):
(The main issue here, I believe, is that there's no nice way to address the existential hypothesis; I've tried simpa using Exists.choose_spec _
, for example, but unless it's simple enough that I can just fill in the name myself that doesn't seem to work.)
Robert Maxton (Apr 24 2025 at 06:24):
I could use generalize_proofs
before the simp
, but then I end up with many proofs I would have to separately combine, probably with another simp
anyway.
Ruben Van de Velde (Apr 24 2025 at 06:41):
It surprises me that you end up in this situation. Would it not be easier to do obtain \<x, hx\> := h_exists
rather than let x := Exists.choose h_exists
?
Sébastien Gouëzel (Apr 24 2025 at 06:41):
Instead of using Exists.choose
, can you use the choose
tactic, which is much more user-friendly?
Robert Maxton (Apr 24 2025 at 06:42):
Ruben Van de Velde said:
It surprises me that you end up in this situation. Would it not be easier to do
obtain \<x, hx\> := h_exists
rather thanlet x := Exists.choose h_exists
?
I usually don't do either, actually; I just have e.g. hom | ⟨x, hx⟩ => (hx (𝟙 _)).choose
Robert Maxton (Apr 24 2025 at 06:42):
Sébastien Gouëzel said:
Instead of using
Exists.choose
, can you use thechoose
tactic, which is much more user-friendly?
Hm. Let's find out.
Robert Maxton (Apr 24 2025 at 06:45):
Nope; or, well, certainly I can write hom | ⟨x, hx⟩ => by choose y hy using hx (𝟙 _); exact y
instead, but when I then have to interact with that definition later simpa using (Classical.choose_spec _)
doesn't work
Ruben Van de Velde (Apr 24 2025 at 06:46):
I see
Robert Maxton (Apr 24 2025 at 06:46):
... I suppose I should probably have been more specific: the issue is with defining data at one point in a definition with Exists.choose
, where later I need to access that data with Exists.choose_spec
Robert Maxton (Apr 24 2025 at 06:47):
... I could use Classical.indefiniteDescription
everywhere instead; that would be ugly but might be more compatible with automation...
Ruben Van de Velde (Apr 24 2025 at 06:47):
In that case it might be easier to create an auxiliary def
with the result of Exists.choose
and add a specialized lemma about that def
with Exists.choose_spec
Ruben Van de Velde (Apr 24 2025 at 06:47):
I'm reasonably sure Classical.indefiniteDescription
would be more painful
Robert Maxton (Apr 24 2025 at 06:49):
Well, it'd mean that the last line of my data generation is Subtype.val _
, which sometimes simp
seems to be able to exploit automatically via Subtype.coe_prop
.
Robert Maxton (Apr 24 2025 at 06:49):
Ruben Van de Velde said:
In that case it might be easier to create an auxiliary
def
with the result ofExists.choose
and add a specialized lemma about thatdef
withExists.choose_spec
Mm. That would be somewhat unpleasant as this is occurring in a rather deeply nested series of definitions, but that itself probably isn't great practice... I'll think about it.
Sébastien Gouëzel (Apr 24 2025 at 06:57):
Do you have a #mwe?
Yury G. Kudryashov (Apr 24 2025 at 14:32):
BTW, I think that we should have an attribute version of the choose
tactic. It should take a lemma claiming \forall a b, \ex x, p x \and q x
and output def
with lemmas.
Yury G. Kudryashov (Apr 24 2025 at 14:32):
(both choose
and choose!
versions can be useful)
Kyle Miller (Apr 24 2025 at 15:26):
Maybe @[split]
could in general destruct the target type and make new declarations, using some list of types that we'd normally split (curry) if they were arguments to a function or lemma. What come to mind: and, exists, sigma, subtype, maybe prod.
Ah, maybe the syntax is @[split ⟨thm1, ⟨thm2, thm3⟩, thm4⟩]
and there does not need to be a list of "blessed" types. There would be an implicit intro
for this destruct syntax, so for example the ⟨thm2, thm3⟩
could be parameterized by more arguments if it's a forall there.
Kyle Miller (Apr 24 2025 at 15:29):
(Somewhat related: the discussion about mutual induction. This link is to joint theorem definitions.)
Yury G. Kudryashov (Apr 24 2025 at 16:24):
Should it be a superset of alias
?
Last updated: May 02 2025 at 03:31 UTC