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