New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
notations/syndefs with parameters applied to holes result in tac-in-term not being executed #8190
Comments
@maximedenes this is my problem... |
A related issue: Require Import ssreflect.
Notation foo := _.
Goal True.
have := foo. produces a goal shown as |
And by the way, the same problem goes for rewrite: Require Import ssreflect.
Notation lt := (ltac: (exact tt)).
Definition f (u' u : unit) : u = u' :=
match u, u' with tt, tt => eq_refl end.
Notation flt u := (f lt u).
Lemma test (u : unit) : u = tt.
Fail have := flt _.
(* The command has indeed failed with message: *)
(* Ltac call to "have (ssrhavefwdwbinders)" failed. *)
(* Cannot infer an internal placeholder of type "Type" in environment: *)
(* u : unit *)
have := f lt _.
Fail rewrite [u](flt _). (* same error *)
rewrite [u](f lt _).
done.
Qed. |
I think the notation is not affecting have...
|
Notations are affecting tactic in terms, the bug has nothing to do with ssr:
|
have
with ltac:
in a notation
The behavior is the following:
To me there are two bugs here:
|
@CohenCyril could you update the first message of this PR with a pointer down here? |
My bet is that notations are stores as fully developed. Indeed the second notation emits a warning that it cannot be used for printing, since it contains some ltac code. It does not, but uses another notation that does. Maybe this inlining breaks the ltac-annotated |
The bug is affected by the presence of parameters in the notations, because this works: Notation zero := (ltac: (exact 0)).
Definition f (m n : nat) : nat := m.
Notation fzero := (f zero).
Lemma test : False.
eassert (H : fzero = fun _ =>3). |
Actually, my bug happens ONLY with parameters, and when they are applied to holes when using the notation, cf third example in original post. |
One can reproduce the bug using |
The minimal example is Notation zero := (ltac: (exact 0)).
Notation foo x := (x + zero).
(* Let's use foo, the offending notation with a parameter *)
Check foo 1.
Fail Check foo _. (* here I pass _ for the parameter *)
(* Now I get rid of `foo` and do the unfolding by hand *)
Check (1 + zero).
Check (_ + zero). |
Hi, the problem seems to be a bit tricky. The notation (roughly) generates the following Ltac code: Check ltac:(let x := (eval cbn in _) in exact 0). which indeed fails. (Note: it should be an identity conversion rather than Ideally, one should generate instead the code Check ltac:(let a := open_constr:(_) in exact a). internally using a |
I must confess I do not understand your message at all, and I don't have time to learn this part of the system I've never looked at. Please just confirm I've assigned the bug to the right persons. |
Sorry for not having been clear. When there is an This code was initially written by @ppedrot but I'm also knowledgeable to fix it. So, it basically depends on the urgency for a fix. I must confess that I don't have time to work on it today, which means basically that it shall get tomorrow a level of priority comparable to a lot of pending things I have to do, and this is why I was asking whether you would be interested to look at it, first to get it fixed quickly, second thinking that you may have been interested in getting more expertise in notations, since getting more expertise in notations shall never be useless. In any case, the assignees are indeed appropriate persons. |
Hi @herbelin, it seems to me that in the example |
@CohenCyril: What matters in the example is the argument to
I've seen examples where collecting ltac variables which effectively occur could be useful. So, both directions (i.e. moving the constr's passed to ltac to open_constr's and avoiding passing the arguments which do not occur) are indeed worth. |
@herbelin oh ok, I think I understand now! Thanks |
@herbelin I played a little bit to understand where the let c = ConstrMayEval (ConstrTerm c) in [...] and not something like let cbn = Cbn {rBeta = true; rMatch = true; rFix = true; rCofix = true;
rZeta = true; rDelta = true; rConst = []} in
let c = ConstrMayEval (ConstrEval (cbn, c)) in [...] |
Great. The code you mention uses
Yes, there is no So, yes, this is the line, and I suspect it could be replaced by a |
@herbelin the exact code you gave fixed my problem. I still do not understand what the identity conversion ( |
This is a very good question. Using Doing this change would have a bigger impact than just in
works, while, currently, it fails with |
Where is (However, I believe that The Correct thing to do, given the current scope of notations, is interpret binders as |
- code by Hugo @herbelin and @JasonGross - Notations expanding to expressions containing calls to `ltac:(tac)` now accept that their arguments contain unresolved existential variables. - fixes coq#8190, coq#3278 and coq#4728 - adding a test-suite file for the bug
@CohenCyril did you have some code that fixed this issue? Was it ever submitted as a PR? |
There is code at #8200 It stalled for lack of a good option. In particular:
I think the ideal design is using uconstr (or preterm in Ltac2?), and having automatic coercions from uconstr to constr, but this is probably too invasive a change to make for Ltac1, and goes in the wrong direction for Ltac2. |
IIRC in Ltac2 the problem is already solved since you get a |
Function cbv_norm_flags now needs to know if the reduction is expected to be weak or strong. We set it to strong:true preserving the previous semantics.
Function cbv_norm_flags now needs to know if the reduction is expected to be weak or strong. We set it to strong:true preserving the previous semantics.
Version
The Coq Proof Assistant, version 8.8.1 (July 2018)
compiled on Jul 25 2018 17:35:15 with OCaml 4.06.0
Operating system
Linux 4.16.0-1-amd64 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux
Description of the problem
I do not understand why the following two uses of
have
do not give the same result...(I expect both to succeed, like the second one, by generalizing over left evars)
(updated code)
(updated code)
The same problem happens when expanding the first notation inside the second:
EDIT: however, if the notation is fully instanciated, there is no problem:
@gares do you understand this?
The text was updated successfully, but these errors were encountered: