Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2007
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2007

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

Search the Archive

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


  • Prev by Date: Re: Manipulate a complex expression
  • Next by Date: Re: is there a better way to iterate this?
  • Previous by thread: Re: Rule and Module not working together
  • Next by thread: Re: Rule and Module not working together