Re: Rule and Module not working together

*To*: mathgroup at smc.vnet.net*Subject*: [mg77892] Re: Rule and Module not working together*From*: Szabolcs <szhorvat at gmail.com>*Date*: Tue, 19 Jun 2007 06:38:10 -0400 (EDT)*Organization*: University of Bergen*References*: <f55q32$k02$1@smc.vnet.net>

Steven Siew wrote: > On Mathematica 5.2, I tried to write a function which applies the rule > Log[A_] + Log[B_] -> Log[A * B] but somehow it does not work as I > expected. > > Instead of Log[f] + Log[g] becoming Log[f * g], I get the result of > Log[666 * f] even though I have marked both A and B as private > variables. > > Can anyone help? I'm sure I made a big mistake somewhere in my > understanding of Mathematica. > > > > In[1]:= AppendTo[$Echo,"stdout"] > Out[1]= {stdout} > > In[2]:= (* Write your mathematica code below *) > > In[3]:= If[Length[Names["Global`*"]] > 0, Remove["Global`*"]] > > In[4]:= Off[General::spell, General::spell1] > > In[5]:= myfunc[x_] := Module[{s, A, B}, > s = {Log[A_] + Log[B_] -> Log[A*B]}; Return[x /. s]] > > In[6]:= ? myfunc > Global`myfunc > > myfunc[x_] := Module[{s, A, B}, s = {Log[A_] + Log[B_] -> Log[A*B]}; > Return[x /. s]] > > In[7]:= B = 666; > > In[8]:= myfunc[Log[f] + Log[g]] > > Out[8]= Log[666 f] > > In[9]:= myfunc[Log[4] + Log[5]] > > Out[9]= Log[2664] > > In[10]:= (* End of mathematica code *) > > In[11]:= Quit[]; This looks like a bug. Here is a more concise example: In[1]:= Module[{a}, a_ -> 1] Out[1]= a_ -> 1 For some reason Module[] fails to rename the symbol a. In[2]:= Module[{a}, a_ -> a] Out[2]= a_ -> a Not even the 'a' on the right-hand-side of the Rule is renamed. In[3]:= Module[{a}, 1 -> a] Out[3]= 1 -> a$65 In[4]:= Module[{a}, a -> 1] Out[4]= a$71 -> 1 But if 'a' is not present on the left-hand-side in a Pattern, then it *is* renamed. This is very strange. I always thought that Rule and Pattern were nothing more than normal symbols which have certain attributes. But this example shows that this is not true. Mathematica treats Rule and Pattern specially because if they are replaced with other functions (that have the same attributes), the renaming _does_ take place. Here is another bug that I found in the MathGroup archives some time ago (unfortunately I don't have the link any more): In[1]:= With[{x = 1}, Function[{x}, x]] Out[1]= Function[{x}, x] In[2]:= With[{x = 1}, Function[{x}, x] -> 1] During evaluation of In[2]:= Function::flpar: Parameter specification \ {1} in Function[{1},1] should be a symbol or a list of symbols. >> Out[2]= Function[{1}, 1] -> 1 This again proves that Rule behaves specially, but here it seems to have the inverse effect. Or maybe it has the same effect: maybe both Module[] and Function[] mark their variables in the same way, and Rule somehow prevents this "marking", thus allowing With[] to replace x by 1. Actually here I was surprised by the first result too because I thought that With[] _always_ does a complete replacement on its second argument before it is evaluated, i.e. that With[] works like wth[{var_ = val_}, expr_] := expr /. var -> val for a single variable. But let's not wander too far from the original problem. What I do not understand is *why* Rule and Pattern need to be treated specially. Is there a special situation when pattern variables really need to be protected from renaming inside Module[]? a$123_ -> 2*a$123 should work just as well as a_ -> 2*a, shouldn't it? Szabolcs