The other answers do not explain why your rule doesn't work. They also don't capture the spirit of your question, in my opinion. I will use arbitrary functions so as not to be distracted by incidentals.
Why doesn't the "obvious" rule work?
First, let's explain why f[c[x] + d[x] + e[x]] //. f[a_[x] + b_[x]] -> f[a[x]] + exp[b[x]]
doesn't do what you want it to. You are wanting to use the Flat
attribute of the Plus
function to "break" f
over addition, because you reason that since Plus[b, c, d]===Plus[b, Plus[c, d]]
, then f[Plus[b[x], c[x], d[x]]]/.f[p_[x] + q_[x]] -> f[b[x]]+f[c[x]+d[x]]
. In fact, you may have noticed that it does work without the functions:
a+b+c/.x_+y_->{{x},{y}}
{{a}, {b + c}}
The Blank
pattern—and only the Blank
pattern—is treated in a special way when used on Flat
functions like Plus
, because Blank
is given a special meaning within Flat
functions in the sense that it can match like f[__]
(if it’s able to). In particular, a Blank
pattern can match any sequence of arguments of f[a, b, c, ...]
when f
is flat. To drive home the point, we can use ReplaceList
to list all of the different possible ways to match the pattern:
SetAttributes[f, Flat];
ReplaceList[f[b, c, d], f[x_, y_] -> {{x}, {y}}]
{{{f[b]},{f[c,d]}}, {{f[b,c]},{f[d]}}, {{b},{f[c,d]}}, {{f[b,c]},{d}}}
However, p_[x]
, or any other pattern, is not endowed with this same special meaning within Flat
functions, and so f[p_[x], q_[x], ...]
has the effect of annihilating p_
’s special abilities within Flat
functions.
Here's the rule for non-Blank
patterns (as of v11.3): If a pattern has to unflatten a flat function in order to match, then the pattern will not match. On the other hand, if a Blank
pattern needs to unflatten a flat function in order to match, it will.
How can we make a rule that works?
The general case
Here's the general case: Suppose g
is any function and f
is Flat
. We are interested in transforming g[f[c[x], d[x], e[x]]]
into f[g[c[x]], g[f[d[x], e[x]]]
in a single step. Thus,
SetAttributes[f, Flat];
g[f[c[x], d[x], e[x]]] //. g[f[a_[x], b_]] :> f[g[a[x]], g[f[b]]]
f[g[c[x]], g[d[x]], g[f[e[x]]]]
Notice that the final result has an inner f
, because we have no rule for when g
has only a single argument. In other words, it did exactly what we asked it, but not more.
The specific case of Plus
There is nothing special about Plus
. Again, for any function g
, we want to transform g[c[x] + d[x] + e[x]]
into g[c[x]] + g[d[x] + e[x]]
in one step. Thus,
g[c[x] + d[x] + e[x]] //. g[a_[x] + b_] :> g[a[x]] + g[b]
g[c[x]] + g[d[x]] + g[e[x]]
Exp[c[x]]+Exp[d[x]+Exp[e[x]]
orExp[c[x]]*Exp[d[x]*Exp[e[x]]
? If byexp
you really meanExp
, then the former is not the proper expansion while the latter is. $\endgroup$exp[c[x]]+exp[d[x]]+exp[e[x]]
.exp
was supposed to mean "expected value" for some random distribution. Initially I used\[DoubleStruckE]
for that function, but converted it to lower-caseexp
to post my question here. $\endgroup$