Search code examples
coqcoq-tacticltac

Equivalent of `remember (f x) as y eqn:H; clear H; clear x`?


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?


Solution

  • 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.