Zulip Chat Archive
Stream: general
Topic: sufficesI
Yaël Dillies (May 08 2022 at 19:19):
Could we have an "instance version" of tactic#suffices? This would complete the have
, haveI
, suffices
square.
Reid Barton (May 08 2022 at 19:21):
Do you have a practical use in mind for it?
Yaël Dillies (May 08 2022 at 19:22):
It has the same applications as haveI
. For example I have this proof
haveI : is_empty {a // b a = k},
{ refine subtype.is_empty_of_false _,
rintro a rfl,
exact hbk (finset.mem_image_of_mem _ $ finset.mem_univ _) },
exact det_is_empty,
This would read slightly better as
sufficesI : is_empty {a // b a = k},
{ exact det_is_empty },
refine subtype.is_empty_of_false _,
rintro a rfl,
exact hbk (finset.mem_image_of_mem _ $ finset.mem_univ _),
Reid Barton (May 08 2022 at 19:31):
Ideally is_empty
would not be a class in the first place, and you could just write apply det_is_empty
and then the rest.
Yaël Dillies (May 08 2022 at 19:32):
Sure, but
- It should be a class
- My specific problem has little to do with the tactic gap that I just uncovered
Reid Barton (May 08 2022 at 19:35):
But I think this is really a representative example--my biggest problem with type class abuse is precisely that it makes these kinds of proofs more awkward. In the best case you make I
duplicates of a bunch of tactics but it's still worse than just proving stuff normally; here you had to spell out the exact is_empty
statement you need.
Reid Barton (May 08 2022 at 19:36):
I think what would make the situation more tolerable is something like an apply
tactic that turns failed instance searches into new goals
Yaël Dillies (May 08 2022 at 19:37):
We should either have both haveI
and sufficesI
or none of them, because they fulfill the exact same role. Is your solution to delete haveI
?
Reid Barton (May 08 2022 at 19:38):
??
Yaël Dillies (May 08 2022 at 19:38):
There's a mismatch between have
and suffices
. This mismatch shouldn't exist. What is your solution to it?
Reid Barton (May 08 2022 at 19:39):
Why do I need a solution?
Reid Barton (May 08 2022 at 19:39):
I think adding sufficesI
is okay; but it doesn't address the real issue
Yaël Dillies (May 08 2022 at 19:40):
Sure, we can also add applyI
which does what you say. I think this would be ideal.
Adam Topaz (May 08 2022 at 19:40):
We have apply_with
Adam Topaz (May 08 2022 at 19:40):
And you can just use suffices : foo, { resetI, bar }
.
Yaël Dillies (May 08 2022 at 19:41):
How does one use apply_with
?
Adam Topaz (May 08 2022 at 19:42):
apply_with ... { instances := ff }
Reid Barton (May 08 2022 at 19:45):
Does that mean all instance arguments will become new goals? That's probably not ideal either
Adam Topaz (May 08 2022 at 19:48):
Yeah, that's what it does. When I do it I usually have to do any_goal { apply_instance }
right after
Damiano Testa (May 08 2022 at 20:33):
It might be that adding a tactic.swap
at the end of the haveI
tactic would generate the sufficesI
tactic.
I'm not at a computer, so cannot check now, though.
Kyle Miller (May 08 2022 at 20:54):
You could use tactic#exactI here:
suffices : is_empty {a // b a = k},
{ exactI det_is_empty },
refine subtype.is_empty_of_false _,
rintro a rfl,
exact hbk (finset.mem_image_of_mem _ $ finset.mem_univ _),
Or there's
suffices : is_empty {a // b a = k},
unfreezingI { exact det_is_empty },
refine subtype.is_empty_of_false _,
rintro a rfl,
exact hbk (finset.mem_image_of_mem _ $ finset.mem_univ _),
but tactic#unfreezingI doesn't focus the goal.
Kyle Miller (May 08 2022 at 20:58):
For longer proofs inside the first suffices
goal, you can put tactic#resetI at the beginning. I think the value-add of haveI
is that you don't have to do have : foo, { ...}, resetI, ...
with the resetI
potentially far away from the have
.
Last updated: Dec 20 2023 at 11:08 UTC