# Manipulate mapping on lists

For some function f, consider the following expression:

 f f - f f f - f f f + f f f f - f f f + f f f f + f f f f - f f f f f


f[2,5] - f[1,2,5] - f[2,3,5] + f[1,2,3,5] - f[2,4,5] + f[1,2,4,5] + f[2,3,4,5] - f[1,2,3,4,5]


I.e. the function is now implemented on a list of the individual arguments. I've had a go at trying Map to achieve this but with no luck.

EDIT TO QUESTION

To make this more meaningful for functions, how can the above string be passed as a single vector. Specifically, how can we obtain the output

f[{2,5}] - f[{1,2,5}] - f[{2,3,5}] + f[{1,2,3,5}] - f[{2,4,5}] + f[{1,2,4,5}] + f[{2,3,4,5}] - f[{1,2,3,4,5}],


this form can then be applied to a predefined function f[u] that operates on the list u. The function should also be able to take additional arguments.

Try using upvalues:

Times[f[x__], f[y__]] ^:= f[x, y]


and then evaluating the expression f f - f f f - ... again.

You could also do it without modifying f and using ReplaceRepeated (//.):

expr //. Times[f[x__], f[y__]] :> f[x, y]

• This works great. Sometimes, it doesn't apply the same ordering. I.e. f f f //. Times[f[x__], f[y__]] :> f[x, y] gives f[5, 2, 3] not f[2, 3,5]. Is there a simple fix for this? – Sid Mar 19 at 0:12
• @Sid - Once you have defined UpValues for f you do not need to use /. or //. If you want the arguments ordered use ClearAll[f]; Times[f[x__], f[y__]] ^:= f @@ Sort[{x, y}] Then just evaluate f f f and the result will be f[2, 3, 5] – Bob Hanlon Mar 19 at 0:56
• @Sid Another way: you can evaluate SetAttributes[f, Orderless], and f will thereafter always automatically put its arguments in canonical order (the same ordering Times uses). – thorimur Mar 19 at 4:03
• @Sid expr //. Times[f[x__], f[y__]] :> f[x, y] /. f[x__] :> f[{x}] – wuyudi Mar 19 at 15:26
• @Sid Or expr //. Times[f[x__], f[y__]] :> f[x, y] /. f :> (f@*List) – wuyudi Mar 19 at 15:27