I would like to proof
Goal forall (T : eqType) (s1 s2 : seq T) P, all P (undup (s1 ++ s2)) -> all P s1 && all P s2.
move/allP.
T : eqType
P : pred T
s1, s2 : seq T
============================
{in undup (s1 ++ s2), forall x : T, P x} -> all P s1 && all P s2
Questions.
{in }
is kind of notation for forall x, x \in s1 ->...
)Locate
about this {in}
? Locate "{in _, _}"
and Locate "{in _}"
didnt help.You probably need to Locate "{ in _ }"
(with a space)
I would look for a lemma linking all
and cat
to operate on the conclusion, but I did not try.
Try Search {in _, _}.
@Enrico Tassi , thanks for the point , Locate "{ in _ , _ }".
worked right. all_cat
worked great too, thanks for the idea!
@Christian Doczkal , thanks for pointing to Search, I didnt try, it just works. Great!
Andrey Klaus has marked this topic as resolved.
Sometimes it's more convenient to reason about all
using it's own lemmas rather than using the view for Prop. Try:
under eq_all_r => x do rewrite mem_undup //.
by rewrite all_cat.
@Enrico Tassi , Why do I need to add the //, shouldn't over
close the goal?
CC @Erik Martin-Dorel
@Christian Doczkal , great example, it is just what I wanted to find already a couple days! Lucky day :) Thank you.
Thanks @Enrico Tassi for the ping,
Regarding @Christian Doczkal's question:
under eq_all_r => x do tac.
is essentially equivalent to:
(under eq_all_r) => [x | ]; [ tac; over | cbv beta iota ].
and over is defined by:
Ltac over := by [ apply: under_rel_done | rewrite over ]
But, if you only use the interactive mode (without the "do") on this example, I've noticed we get:
Goal forall (T : eqType) (s1 s2 : seq T) P, all P (undup (s1 ++ s2)) -> all P s1 && all P s2.
move=> T s1 s2 P.
under eq_all_r.
↓
- T : eqType
- s1, s2 : seq T
- P : pred T
============================
forall x : T, (x \in undup (s1 ++ s2)) = (x \in ?Goal)
subgoal 2 (ID 7724) is:
all P ?Goal -> all P s1 && all P s2
i.e. there is no 'Under[ _ ]
notation for capturing the evar (and enabling the proper feature of over).
On the other hand, look at what we'd get with this script:
Lemma ex_map l : head 0 (map (fun m => m - m) l) = 0.
under eq_map.
↓
- l : seq nat
============================
forall x : nat, 'Under[ x - x ]
subgoal 2 (ID 7703) is:
head 0 [seq ?Goal i | i <- l] = 0
So I guess there's a small bug here (or at least some room for improvement), certainly due to the specific form of the extensionality lemma eq_all_r
.
I don't have the time to dive into this right now, but you might want to file an issue in the Coq bug tracker.
@Erik Martin-Dorel , indeed I hadn't spotted that the 'Under [ _ ]
notation was missing. I'll try to do a (plain) Coq example tomorrow and put it in the bug tracker.
I'm just circling around to this and I'm starting to think that this is not a bug, in the sense that there is no obvious (safe) way in which things should work. My understanding is that for under _ => x
to work reliably, the (hidden) RHS must be of the form ?Goal x
. In the case of eq_all_r
it is of a more specific shape and, indeed, one can easily do rewrites on the LHS that make unification fail (e.g. mem_cat
). But it is interesting to know that one can temporarily violate the shape restriction and do things like this:
Goal forall (T : eqType) (s1 s2 : seq T) P,
all P (undup (s1 ++ s2)) -> all P s1 && all P s2.
move=> T s1 s2 P.
under eq_all_r => x.
by rewrite mem_undup mem_cat orbC -mem_cat.
Whether this is code that I would like to see in the mathcomp libraries is an entirely different matter. ^^
Hi @Christian Doczkal, yes I agree that this is not a bug.
This is indeed related to the fact under
's automatic extensional-side-conditions-detector only handles =1
like quantified equalities, of kind forall x, f x = ?Goal x
.
So e.g. under eq_all => x.
is supported for now.
Anyway, even if we don't see an obvious generalization of all quantified side-conditions that are involved here,
I believe it should be at least possible to extend the tactic so that =i
is supported as well. So feel free to open a feature request if you agree :)
Regarding your last remark, I don't have a strong opinion, but one could either say:
under
now with =i
side-conditions (that are not "protected" with the 'Under[ _ ]
goals, and discharged without over) is not recommended.Last updated: Jan 29 2023 at 19:02 UTC