Re: precedence for ReplaceAll?

*To*: mathgroup at smc.vnet.net*Subject*: [mg110555] Re: precedence for ReplaceAll?*From*: Matthias Fripp <mfripp at gmail.com>*Date*: Fri, 25 Jun 2010 07:27:44 -0400 (EDT)

Hi Leonid, Thanks -- your explanation is very helpful. The descriptions of the Trace, Unevaluated and HoldPattern functions are also very useful. It would have taken me a while to find them on my own! I'm surprised to see that Mathematica evaluates the main expression as far as possible before applying any replacement rules. It would seem more "natural" to me to apply the replacements first, then go to work on the expression. But I suppose there's a certain logic to this. At least now I know how to apply the rules before the expression is evaluated (which will be useful in other situations as well). I'm equally surprised that Mathematica applies the delayed assignment (a := A c) to the left hand side of the ReplaceAll rule (a -> x). But at least now I know what to watch out for and how to work around it! Thanks very much for your help. Matthias On Jun 24, 2010, at 12:59 PM, Leonid Shifrin wrote: > Hi Matthias, > > the problem is that in all rules you used, symbols <a> and <b> > evaluated to their respective values A*c and B*c before any rule > substitution took place, both in the rules and in the expressions to > which you apply the rules. This can be easily tracked by using Trace: > > In[1]:= > a:=A c > b:=B c > > In[3]:= Trace[a/.{a->x,b->y},ReplaceAll] > > Out[3]= {A c/.{A c->x,B c->y},x} > > In[4]:= Trace[b/.{a->x,b->y},ReplaceAll] > > Out[4]= {B c/.{A c->x,B c->y},y} > > In[5]:= Trace[a+b/.{a->x,b->y},ReplaceAll] > > Out[5]= {A c+B c/.{A c->x,B c->y},x+y} > > In[6]:= Trace[a*b/.{a->x,b->y},ReplaceAll] > > Out[6]= {A B c^2/.{A c->x,B c->y},A B c^2} > > So you see, the actual expressions used by ReplaceAll are not at > all those you started with, hence the results. Presumably, you > wanted to prevent evaluation of both expressions and rules, at least > until the rule applies. You can use Unevaluated and HoldPattern for > this purpose: > > In[7]:= > Unevaluated[a] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} > > Out[7]= x > > In[8]:= Unevaluated[b] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} > > Out[8]= y > > In[9]:= Unevaluated[a + b] /. {HoldPattern[a] -> x, > HoldPattern[b] -> y} > > Out[9]= x + y > > In[10]:= Unevaluated[a*b] /. {HoldPattern[a] -> x, HoldPattern[b] -> > y} > > Out[10]= x y > > You can use Trace as above to see that now the actual expressions > used in ReplaceAll are what you probably had in mind. However, if > you have a choice, I wouldn't make the assignments to <a> and <b> > in the first place, or make them local rules and apply after all > other rules have been applied. > > Hope this helps. > > Regards, > Leonid > > > > > > On Thu, Jun 24, 2010 at 1:27 AM, Matthias Fripp <mfripp at gmail.com> > wrote: > I am having trouble using ReplaceAll to replace symbols that already > have a delayed assignment. > > e.g., this input: > > In[287]:= > a := A c > b := B c > a /. {a -> x, b -> y} > b /. {a -> x, b -> y} > a + b /. {a -> x, b -> y} > a * b /. {a -> x, b -> y} > > gives this output: > > Out[289]= x > > Out[290]= y > > Out[291]= x + y > > Out[292]= A B c^2 > > All of this works as expected except for the final term. I would have > expected to get the result "x y". Is there any way to force > Mathematica to produce that result? > > If on the other hand the original assignment is a := A + c and b := B > + c, I get an unexpected output for the sum, but the expected output > (x y) for the product. If I insert d instead of one of the c's, I get > various other (unpredictable) kinds of result. > > My first guess is that Mathematica is doing a sort of "double > ReplaceAll", where it first tries the pattern given in the delayed > assignment, and any symbols matched by that are not tested against the > explicit ReplaceAll. But that doesn't explain why the sum works and > not the product. Am I thinking about this the wrong way? > > Thanks for any help you can give! > > Matthias Fripp > >