Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

And

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?

share|improve this question

2 Answers 2

up vote 10 down vote accepted

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]]] *)
share|improve this answer

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

Consider:

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]]]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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