MathGroup Archive 1998

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

Search the Archive

An operator called-- LocalRule

  • To: mathgroup at smc.vnet.net
  • Subject: [mg13812] An operator called-- LocalRule
  • From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
  • Date: Fri, 28 Aug 1998 04:18:31 -0400
  • Sender: owner-wri-mathgroup at wolfram.com

The result at Out[1] is probably not what was intended.  To get the
right result one can use lhs:>rhs as with In[2].

In[1]:=
x=3;
Log[a b c]/.Log[x_ y_]->Log[x]+Log[y]

Out[1]=
Log[3]+Log[b c]


In[2]:=
Log[a b c]/.Log[x_ y_]:>Log[x]+Log[y]

Out[2]=
Log[a]+Log[b c]


Now suppose you want to define a rule where the right side of the rule
takes a while to evaluate, and you need to use it many times.  Use of
lhs->rhs is tempting (for efficiency) but you have to worry about the
problem seen in Out[1].  Some extra effort is needed to get a rule that
evaluates the right side without using global values for x or y.

In[3]:=
rule1=f[x_,y_]->Expand[(x+y)^5]

Out[3]=
f[x_,y_]->243+405 y+270 y^2+90 y^3+15 y^4+y^5


To address this problem, I made a new function called RightArrow which
evaluates both of it's arguments, but variables that are used for
patterns are evaluated in a local environment.  By default RightArrow
is an infix operator using the character 
\[RightArrow].   If you wish you can use the FullForm 
LocalRule[lhs,rhs]. All the necessary definitions are given below.


In[4]:=
LocalRule=RightArrow;
SetAttributes[RightArrow,HoldRest];
 
RightArrow[lhs_,rhs_]:=Module[{q},(
  q=Cases[lhs,_Pattern,{0,Infinity}];
  If[q==={},(lhs:>Evaluate at rhs),(
     q=Extract[#,1,Hold]&  /@q;
     q=Thread[q,Hold];
     q=Hold@@{Join[q,Hold[lhs:>Evaluate at rhs] ]};
     ReleaseHold at ReplacePart[q,Block,{1,0}]   )
   ]
)]

___________________

In[5]:=
x

Out[5]=
3

In the line above we see (x) still has the global value (3). Below
RightArrow and LocalRule give the desired results.


In[6]:=
Log[a b c]/.Log[x_  y_] \[RightArrow] Log[x]+Log[y]

Out[6]=
Log[a]+Log[b c]


In[7]:=
rule1=f[x_,y_] \[RightArrow] Expand[(x+y)^5]

Out[7]=
f[x_,y_] :> x^5+5 x^4 y+10 x^3 y^2+10x^2 y^2+5 x y^4+y^5


In[8]:=
rule1=LocalRule[f[x_,y_],Expand[(x+y)^5]]


Out[9]=
f[x_,y_] :> x^5+5 x^4 y+10 x^3 y^2+10x^2 y^2+5 x y^4+y^5


Notice at In[10]  (x) is used as a pattern, so the global value isn't
used. At In[11] (x) isn't used as a pattern, so in this case the global
value is used.


In[10]:=
rule2=LocalRule[x_, a+x^2]

Out[11]=
x_ :>a+x^2


In[11]:=
rule2=LocalRule[expr,a+ x^2]

Out[11]=
expr :>9+a

______________________
I also wrote a function called LocalSet to address the same problem with
Set.
I am looking forward to some feedback on this subject.

Ted Ersek



  • Prev by Date: Re: Matrix Multiplication
  • Next by Date: Re: Disappearing variables
  • Previous by thread: Re: Matrix Multiplication
  • Next by thread: RE: An operator called-- LocalRule