With the problem you describe, I don't see a straightforward way of doing it. One thing you could do to recast it to make it dramatically easier would be to redefine A
so its a function of the derivatives of F
and G
. If you have
A[{dFdx_,dFdy_}, {dGdx_,dGdy_}] := dFdx*dFdy
you'll be in a very good position to calculate the derivatives of F
that you need and then define AF
in a way that's generic with respect to A
, like so:
With[{ dFdx = D[F,x], dFdy = D[F,y] },
AF[G_] := A[{dFdx, dFdy}, {D[G, x], D[G, y]}]]
You can use With
to substitute evaluated pieces into the unevaluated right-hand side of a SetDelayed form (a definition using ":=") as shown. However, if you can't make that change, things are going to get hairy, and you'll have to make some assumptions about what A
is.
If A
is a symbol with DownValues defined for it, and has a simple definition, then you can do the partial evaluation you want by using a Hold
, doing rule substitutions, and then doing a ReleaseHold
, like so:
ReleaseHold[
Hold[AF[G_] := A[F, G]] /. DownValues[A] /.
HoldPattern[D[F, var_]] :> With[{eval = D[F, var]}, eval /; True]]
The With[...]
bit in the second rule is a trick for forcing the evaluation of something matching a pattern inside a Hold
called the "Trott-Strzebonski method", which is obscure but extremely useful for tasks like this. However, going this way really limits your interface, meaning that you can't, say, pass in a pure function for A
, and with a more complicated definition this trick probably won't work either. If you can possibly manage to specify that your differential form will be a function of the actual derivatives, I strongly recommend doing so.
EDIT: I thought of a more general and robust way of doing this.
The trick then is to temporarily suppress the definition of D
(the derivative operator) using Block
, so the derivatives in the definition of A
remain unevaluated, and then use rule-replacement to substitute in the values for the derivatives of F
while wrapping everything up in a pure function to get the name substitution right, like so:
With[{fRules =
{HoldPattern[D[F, x]] :> Evaluate[D[F, x]]}},
Block[{D},
With[{fn = Function[G, Evaluate[A[F, G] /. fRules]]},
AF[G_] := fn[G]]]]