I have problems extending a replacement rule.

Schematically, this is the situation: I have an expression and a rule, and they work perfectly together.

In[1] =  result = expr /.rule
Out[1] = ...

Now I want to extend the rule to let it cope with extra multiplication factors. It should be such that

In[2] =  5 result - (5 expr /. ruleex)
Out[2] = 0


In[3] =  5 w result - (5 w expr /. ruleex)
Out[3] = 0

These are the expression and the rule I am working with:

In[4]:=  rule = Times[f[x__][y__], z__] -> Times[-1, q, y, f[x][z]]
In[5]:=  expr = f[-a][s[c, -b]]*f[a][s[-c, b]]
In[6]:=  result = expr /. rule
Out[4]:= -s[c, -b] f[-a][f[a][s[-c, b]]]

To make the rule cope with an arbitrary number of multiplicative factors on the left, I guess adding a BlankNullSequence would do.

In[7]:=   ruleex = Times[q___, f[x__][y__], z__] -> Times[-1, q, y, f[x][z]];
In[8]:=   expr /.rulex
In[9]:=   5 expr /. ruleex
In[10]:=  5 w expr /. ruleex
Out[5]:=  -s[c, -b] f[-a][f[a][s[-c, b]]]
Out[6]:=  -s[c, -b] f[-a][5, f[a][s[-c, b]]]
Out[7]:=  -s[c, -b] f[-a][5, w, f[a][s[-c, b]]]

Out[5] is as expected. The extra factor 5 ends up not at the front of the expression, but somewhere in the in f[a][...]. In Out[7] something similar occurs.

Why does this not work? How can I extend the rule to act in the way I described?


2 Answers 2


The reason why your rule doesn't work is that Times is orderless so that the two multiplicative factors at the beginning and end of the expression 5 expr are not considered distinct.

Your goal seems to be to treat factors that occur to the left of the product of f differently from factors occurring to the right.

This can be done symbolically, but only if you use a different symbol instead of Times to describe your non-commutative multiplication. Fortunately, there is a function pre-defined for that, it's NonCommutativeMultiply:

How to use this depends a little on the details of your problem, but the idea is that you have to start with all your expressions written in this non-commutative way:

expr = f[-a][s[c, -b]] ** f[a][s[-c, b]]

The ** replaces normal multiplication here. Now you can manipulate this using a rule of the exact form that you wanted, except for the change from Times to **:

ruleex = NonCommutativeMultiply[q___, f[x__][y__], z__] -> 
   NonCommutativeMultiply[-1, q, y, f[x][z]];

This yields the following:

5 expr /. ruleex

(* ==> 5 (-1) ** s[c, -b] ** f[-a][f[a][s[-c, b]]] *)

So the output looks more complicated now, but it has the advantage that you can then work on it further under the assumption of non-commutativity. E.g., you can apply the rule repeatedly using //..

But if you're done with the replacements that depend on the order of factors and want to have a result that has only Times, you can end by doing this:

5 expr /. ruleex /. NonCommutativeMultiply -> Times

(* ==> -5 s[c, -b] f[-a][f[a][s[-c, b]]] *)

Everything Jens wrote is valid, but perhaps you merely want to restrict your z pattern a bit.


ruleex = Times[q___, f[x__][y__], z : f[__][___] ..] :> Times[-1, q, y, f[x][z]];

expr = f[-a][s[c, -b]]*f[a][s[-c, b]];

5 w expr /. ruleex
-5 w s[c, -b] f[-a][f[a][s[-c, b]]]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.