Associativity of upvalue

how can I ensure the following definition to be associative?

Unprotect[Times];
a_ f[x_] + b_ f[y_] ^:= f[a x + b y]
Protect[Times];


gives me

a f[x] + b f[y] + c f[z]


f[a x + b y] + c f[z]

I'd like it to be

f[a x + b y + c z]

• You probably need to set default values for the patterns a_ and b_ like a_. and b_., otherwise $ScriptCapitalN][a x + b y] does not match the pattern of multiplier_ \[ScriptCapitalN][a x + b y] Commented Sep 11, 2018 at 8:58 • My previous comment about Times vs. Plus was of course wrong. Commented Sep 11, 2018 at 8:59 • Well it works with the default value. But I don't really understand why I need it. Commented Sep 11, 2018 at 9:01 • And if c=1 it does not work anymore. Commented Sep 11, 2018 at 9:07 • @LLlAMnYP That's easy to achieve. Just go to thw NinjaKot script and add ['\\\\\\[ScriptCapitalN\$', 'f'], on line 599 =D Commented Sep 11, 2018 at 9:43

f[a x + b y] + c f[z]


is not the same as

1 * f[a x + b y] + c f[z]


so the pattern

a_ f[x] + b_ f[y]


does not match it. But if you use a_. then it's replaced with the default value (1, for Times) if the multiplier is omitted. So then it will match.

However, you observe that if c == 1, then it doesn't work again. This is understandable, since if c == 1, the expression

f[a x + b y] + f[z]


does not contain Times at level 1 anymore. I suggest using more granular rules:

a_ f[x_] ^:= f[a x]

f[x_] + f[y_] ^:= f[x + y]


This achieves two things: the upvalue is attached to f and not to system symbols, and it solves the problem you mentioned in the comments.

• Thank you for the explanation. But isn't the case c==1 a variant of the first case, now with the two multipliers omitted? And shouldn't then the two multipliers be replaced with their default values? Or did I get it completely wrong what you tried to point out? Edit Or can only be one default value be replaced at a time? Commented Sep 11, 2018 at 9:28
• The UpValue in your attempt is associated with Times. I replace scriptcapitalN with just N for brevity: N[x] + b N[y] is Plus[N[x], Times[b, N[y]]]. Times is present at level 1 of the expression, so MMA checks UpValues for the symbol Times. However, N[x] + N[y] is Plus[N[x], N[y]], so MMA has no waying of realizing that it has to apply the UpValue defined for Times. So it doesn't even get round to doing that and attempting to substitute default values in the process. Commented Sep 11, 2018 at 9:33
• Thank you, makes perfectly sense. Commented Sep 11, 2018 at 9:47