Sometimes I have a proof that is best done by projecting into a different space. At the moment I do the following:
remember (f x) as y eqn:H; clear H; clear x.
I tried to automate this with Ltac:
Ltac project x y :=
let z := fresh in
remember x as y eqn:z; clear z; clear x.
But I get the following error:
Error: Ltac variable x is bound to f x which cannot be coerced to a variable.
What's the issue here?
I assume you are trying to call your tactic like this:
project (f x) y.
If you unfold the definition you gave, you will see that this call ends with
clear (f x).
This call is the culprit: you can only clear variables, not arbitrary expressions. Here is a possible fix.
Ltac project x y :=
match x with
| ?f ?x' =>
let z := fresh in
remember x as y eqn:z; clear z; clear x'
end.
Since you are generating an equation that you never use, it is better to replace remember
with generalize
:
Ltac project x y :=
match x with
| ?f ?x' => generalize x; clear x'; intros y
end.
You might also consider using the ssreflect proof language, which considerably simplifies this kind of context manipulation. Instead of calling project (f x) y
, we could just use
move: (f x)=> {x} y.
This is much more flexible. For instance, if you wanted to do something similar with an expression with two free variables, you would only have to write
move: (f x1 x2)=> {x1 x2} y.