MathGroup Archive 1997

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Confused about replacement rules

  • To: mathgroup at
  • Subject: [mg7194] Re: Confused about replacement rules
  • From: villegas (Robert Villegas)
  • Date: Wed, 14 May 1997 01:11:30 -0400 (EDT)
  • Organization: Wolfram Research, Inc.
  • Sender: owner-wri-mathgroup at

This is a common point of confusion when ReplaceAll (as opposed to
Replace) is used to apply two or more rules.  In

   expr /. {rule1, ..., rulen}

it is NOT the case that rule1 is tried on all subexpressions, then rule2,
and so on.  Instead, it is the parts of the expression (from the top
down, in lexicographic order by position) that are the first
dimension of the ReplaceAll operation, and the rules that are the second

The pattern-matcher starts at level 0 (i.e the entire expression)
and tries all the rules in order on it.  The pattern-matcher applies the
first rule that matches and then ceases.

If no rule applies to the whole, the pattern-matcher moves on to level
1 (head and then elements in order), trying all rules on each given
target before moving on to the next target.  Again, once a rewrite
is performed on a part, the pattern-matcher never visits it or its
subexpressions again.

After visiting level 1, the pattern-matcher moves on to level 2
(the elements of any parts it did not rewrite during its visit to
level 1).

And so on through the bottom-most level, the atoms.

The confusing point is that after a part is transformed, it and its
subexpressions aren't visited any more, even though they might
contain plenty of matches of the rules.  This is especially confusing
when a rule applies to a part but ends up not changing it, which happened
to the entire expression (level 0 -- the pattern-matcher's first stop)
in your case.  One way around this is to do cumulative ReplaceAll
operations instead of a single one, effectively changing the first dimension  
of the operation to the rules and the second dimension to the parts of the  

  Fold[ReplaceAll, expr, {rule1, ..., rulen}]

You can use ReplaceRepeated if the rewrites might themselves contain
things that can be transformed:

  Fold[ReplaceRepeated, expr, {rule1, ..., rulen}]

(and maybe even do a FixedPoint of the Fold operation if one rule might
introduce more matches of the previous rules).

A useful debugging technique to use when your rules go awry is to print the
value that matched the pattern.  For instance, 

In[15]:= rules = {x_^2 :> (Print["x = ", x]; a), expr_ :> (Print["expr = ",  
expr]; Expand[expr])}

Out[15]= {(x_)  :> (Print[x = , x]; a), 
    expr_ :> (Print[expr = , expr]; Expand[expr])}

In[16]:= x (b + x) /. rules
expr = x (b + x)

Out[16]= b x + x

In[17]:= % /. rules
expr = b x + x

Out[17]= b x + x

As you can now see, the second rule fired on the entire expression in
In[17] but did not change it.  After applying a rule to the whole expression,
ReplaceAll stopped applying rules.  

If you have several rules intended to transform subexpressions, it is
usually wise to avoid an all-encompassing pattern such as expr_ but instead  
to use specific patterns.  Or if you can't avoid this then you
might have to Map your replacement operation onto the elements of the
expression, as you discovered.  

Robby Villegas

  • Prev by Date: Re: ordered pairs
  • Next by Date: Re: Re: GUI for Mma
  • Previous by thread: Re: Confused about replacement rules
  • Next by thread: New "User's Guide for Macintosh" for 3.0?