0

I want to rewrite a term, as a function in a sort of beta expansion (inverse of beta reduction).

So, for example in the term a + 1 = RHS I would like to replace it as (fun x => x + 1) a = RHS. Obviously, the two terms are equal by betta reduction, but I can't figure out how to automate it.

The tactic pattern comes very close to what I want, except it only applies to a full goal, and I can't see how I would use it in a term inside an equality.

Similarly, I thought I could use the context holes. Here is my best attempt

Ltac betaExpansion term a:=
  let T:= type of a in
  match term with
    context hole [a] =>
      idtac hole;
      let f:= fun x => context hole [x] in
      remember ( fun x:T => f x ) as f'
  end.

Goal forall a: nat, a + 1 = 0.
intros a.
  
  match goal with
    |- ?LHS = _ =>
      betaExpansion LHS a (*Error: Variable f should be bound to a term but is bound to a tacvalue.*)
  end.

This obviously fails, because f is a tacvalue when I really need a normal value. Can I somehow evaluate the expression to make it a value?

user2506946
  • 131
  • 9

2 Answers2

1

You should have a look at the pattern tactic. pattern t replaced all occurrences of t in the goal by a beta expanded variable.

  • This is almost what I want, except it only applies to the entire goal. If I could call 'pattern t in term' I would be so happy! – user2506946 Jan 26 '23 at 14:39
  • @user2506946 you *can* call `pattern t in term`, although perhaps it is not as strong as you want. It only seems to work if `term` is a named entity in the context, not if it's something that must be found on the goal such as `x + 1`. Anyway, if you want to recuperate the function emphasized by pattern you can do the following: `Goal forall a RHS, a + 1 = RHS. intros a RHS. set (t := _ + _). pattern a in t. let u := eval cbv delta [t] in t in match u with (fun z => @?h z) _ => set (f := h) end.` – Ana Borges Jan 26 '23 at 17:11
0

You may also use the change ... with ... at tactic.

Goal forall (a:nat) , a+1 = 2* (a+1) - (a+1).
intro x; change (x+1) with ((fun z => z) (x+1)) at 1 3.
(*
 x : nat
  ============================
  (fun z : nat => z) (x + 1) = 2 * (x + 1) - (fun z : nat => z) (x + 1)
*)

Or, more automatically

Ltac betaexp term i :=
  let x := fresh "x" in
  let T := type of term in 
   change term with ((fun x : T => x) term) at i.

Goal forall (a:nat) , a+1 = a+1 .
intro x; betaexp (x+1) ltac:(1). 
  • I'm trying to use this inside automation. Is there a way to builds the replacement term (i.e. The beta expanded term) tactically? – user2506946 Jan 26 '23 at 14:40
  • I managed to do it with an occurrence number. I think it should be possible to improve it with Tacic Notations ? I edit my last answer to include the definition. – Pierre Castéran Jan 26 '23 at 15:26