2

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?

Carl Patenaude Poulin
  • 6,238
  • 5
  • 24
  • 46

1 Answers1

5

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.
Arthur Azevedo De Amorim
  • 23,012
  • 3
  • 33
  • 39