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
changetactic, which replaces one term with a convertible one, and generalizingcso that you deal not withg _ _ cbutfun z => g _ _ z; this second key allows you to deal withgrather than withgapplied to its arguments. Here, I use theposetactic to control what function applications get β reduced:Here is an alternate version that uses
id(the identity function) to blockcbv beta, rather than usingpose: