I need to generalize expression under the binder. For example, I have in my goal two expressions:
(fun a b => g a b c)
and
(fun a b => f (g a b c))
And I want to generalize g _ _ c
part:
One way to do is to rewrite them first into:
(fun a b => (fun x y => g x y c) a b)
and the second into:
(fun a b =>
f (
(fun x y => g x y c) a b
))
And then, to generalize (fun x y, g x y c)
as somefun
with type A -> A -> A
. This will turn my expressions into:
(fun a b => somefun a b)
and
(fun a b => f (somefun a b))
The difficulty here is that the expression I am trying to generalize is under the binder. I could not find either a tactic or LTAC expression to manipulate it. How can I do something like this?
There are two keys to this answer: the
change
tactic, which replaces one term with a convertible one, and generalizingc
so that you deal not withg _ _ c
butfun z => g _ _ z
; this second key allows you to deal withg
rather than withg
applied to its arguments. Here, I use thepose
tactic to control what function applications get β reduced:Here is an alternate version that uses
id
(the identity function) to blockcbv beta
, rather than usingpose
: