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