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