# Pattern matching involving a sum of wildcards

I am trying to implement the following substitution to an expression in Mathematica:

ti den[a-ti] -> -1 + a den[a-ti]


where ti can be t1, t2, ..., and den is an undefined function. The variable ti can also be a sum of t1, t2, .... The expression is part of a larger expression.

Now, it works when one variable is involved:

t1 den[s1 + s2 - t1] /. t_ den[q_ - t_] -> (-1 + q den[q - t])


returns

-1 + (s1 + s2) den[s1 + s2 - t1]


However, if ti is a sum of multiple terms, e.g. (t1-t2), the replacement breaks down. I've tried to implement a rule with the combination of ReplaceRepeated.

rule = {t_ den[q_ - t_] :> (-1 + q den[q - t])}
(t1 - t2) den[s1 - s12 + s2 - t1 + t2] //. rule


but that doesn't seem to work, because it just returns

(t1 - t2) den[s1 - s12 + s2 - t1 + t2]


My guess is that Mathematica cannot recognize den[s1 - s12 + s2 - t1 + t2] as den[s1 - s12 + s2 - (t1 - t2)] and that my substitution rule is wrongly formulated.

Does anybody know how to fix this?

• try Unevaluated[(t1 - t2) den[s1 - s12 + s2 - (t1 - t2)]] /. rule? – kglr Sep 21 '20 at 14:46
• or Defer[(t1 - t2) den[s1 - s12 + s2 - (t1 - t2)]] /. rule or HoldForm[(t1 - t2) den[s1 - s12 + s2 - (t1 - t2)]] /. rule? – kglr Sep 21 '20 at 14:47
• Thanks for the suggestion, but that only works under the assumption that Mathematica recognizes den[s1 - s12 + s2 - t1 + t2] as den[s1 - s12 + s2 - (t1 - t2)], for arbitrary combinations of t, but it does not.. – absharma Sep 21 '20 at 15:03

## 3 Answers

As m_goldberg explained above, because of the internal representation of expressions, "(a-b)" and "-(a-b" are not simple matched by "t_" and "-t_". What you can do, is to put the arithmetic of "-(..)" into a condition. E.g. Match "(t1-t2)" and "-(t1-t2)" by 2 different symbols and use a condition to ensure that one is the inverse of the other:

rule= rule = p1_ den[q_ + p2_] /; (p1 == -p2) -> (-1 + q den[q - p1]);


This works now for any number of terms in (t1-t2+t3..):

t1 den[s1 - s12 + s2 - t1] //. rule
(t1 - t2) den[s1 - s12 + s2 - t1 + t2] //. rule
(t1 - t2 + t3) den[s1 - s12 + s2 - t1 + t2 - t3] //. rule

• thanks, this works. Could you explain where the syntax rule=rule=.. comes from or point to a reference about it? – absharma Sep 22 '20 at 7:31
• Please excuse , that is simply a cut and paste typo.wo "rule=" are equivalent to one. – Daniel Huber Sep 22 '20 at 8:19
• A related question: I'm trying to implement this for arbitrary powers of den as rule = p1_ den[q_ + p2_]^(p3_) /; (p1 == -p2) -> (-1 + q den[q - p1]) (den[q - p1]^(p3 - 1)); but this only seems to work for p3 not equal to 1. How could I also make it work for p3=1? @DanielHuber – absharma Sep 22 '20 at 8:39
• Additionally, right now I use a separate rule for p3=1 and apply both rules as //.{rule1,rule2}, where rule1 works for all p3 except at 1 and rule2 works only at p3=1, but this feels cumbersome. – absharma Sep 22 '20 at 8:48

This is not an answer. I just want to acquaint you with some difficulties you may not be aware of, and my remarks aren't suited to a comment.

Be aware that the Mathematica evauator sees

(t1 - t2) den[s1 - s12 + s2 - t1 + t2]


as

Times[Plus[t1, Times[-1, t2]], den[Plus[s1, Times[-1, s12], s2, Times[-1, t1], t2]]]


and this internal form is the form your pattern matching code has to deal with. And it is clear that there is nothing in the argument of den that is going to match Plus[t1, Times[-1, t2]] and this is one of the sources of your troubles.

You can observe the internal form yourself by evaluating:

(t1 - t2) den[s1 - s12 + s2 - t1 + t2] // FullForm


More trouble arises because your pattern cannot distinguish the $$s_i$$ from the forms $$t_i$$. And, indeed, there is no way to make the distinction with Mathematica's symbolic pattern matcher.

To make it work for higher powers of "den" you simply specify a default value of p3 by p3_:1. Here some examples:

rule = p1_ den[q_ + p2_]^(p3_ : 1) /; (p1 == -p2) -> (-1 +
q den[q - p1]) (den[q - p1]^(p3 - 1));
(t1 - t2 + t3) den[s1 - s12 + s2 - t1 + t2 - t3] /. rule
(t1 - t2 + t3) den[s1 - s12 + s2 - t1 + t2 - t3]^2 /. rule
(t1 - t2 + t3) den[s1 - s12 + s2 - t1 + t2 - t3]^3 /. rule

• Question regarding the default value, I'm trying to convert all negative powers of den[..] to positive powers of a new function num[..]. Inspired by your answer, I tried rule2 = den[a_]^-(p3_ : 1) -> (num[a])^(p3), but this now only seems to work for p3=1. For instance 1/den[s1 - t1]^2//.rule2` doesn't work. Again, the terms are part of a larger expression, any suggestions? @DanielHuber – absharma Sep 22 '20 at 12:13
• This should do the trick: e.g.: den[x]^(-3) /. den[x]^p_ /; (p < 0) :> ma[x]^(-p) – Daniel Huber Sep 22 '20 at 13:21