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.