Re: Re: Weird localization bug!

*To*: mathgroup at smc.vnet.net*Subject*: [mg106079] Re: [mg106060] Re: [mg106009] Weird localization bug!*From*: danl at wolfram.com*Date*: Fri, 1 Jan 2010 05:32:47 -0500 (EST)*References*: <200912300913.EAA17160@smc.vnet.net>

> Hi Derek, > > This indeed looks like a bug to me. Tracing the execution allows to reveal > some details: > > In[1]:= makerule[5]//Trace > > > Out[1]= {makerule[5],(5/.a$_Integer:>2 a)->5,{{a$_Integer:>2 > a,a$_Integer:>2 > a},5/.a$_Integer:>2 a,2 a},2 a->5,2 a->5} > [...] I asked about odd behavior this in-house yesterday. Either someone will give a plausible explanation, or it will get filed as a bug report. Daniel Lichtblau Wolfram Research > The real problem is that <input> is present in the definition *and* > the both sides of the rule <(input /. a_Integer :> 2 a) -> input>. It is > well-known that Mathematica does aggressive dummy (pattern) variable > renaming whenever it suspects a name collision in nesting lexical scoping > constructs. Both Rule and RuleDelayed are scoping constructs, therefore > placing rule within a rule where some of the pattern names are present in > both external and internal rules (<input> in this case) is an invitation > for > the Mathematica variable-renaming mechanism. In this case, however, the > renaming was obviously inconsistent - <a> was renamed to <$a> only on the > left-hand side of the delayed rule. > > My guess would be that the binding in the internal RuleDelayed is > performed > at an earlier stage, since in nesting the scoping constructs the usual > Mathematica convention is that inner scopes are favored in name collisions > (but again, Rule and RuleDelayed do not always obey this convention). Then > <a> gets replaced by <$a> indeed everywhere, but then the just mentioned > internal binding sets the r.h.s. back to <a>. Regardless of whether or not > this is indeed what happens, the final result is IMO not what it should > have > been. > > It is easy to see that the problem shows up "dynamically" during the rule > application rather than when the definition is given: > > In[2]:= Hold[makerule[5]] /. DownValues[makerule] > > Out[2]= Hold[(5 /. a$_Integer :> 2 a) -> 5] > > > Why the same did not happen in the second case is beyond me. Perhaps > wrapping your numbers in <myrule> means for RuleDelayed that there is no > nesting of scoping, since <myrule> is not a scoping construct (while Rule > is > a scoping construct and thus there is direct nesting), and therefore > renaming is not attempted. > > In the last case you seem to have blinded the renaming mechanism by using > Block (the latter being a dynamic scoping construct). > > In any case, this looks like a bug. > > Regards, > Leonid > > > On Wed, Dec 30, 2009 at 1:13 AM, Derek Yates <yatesd at mac.com> wrote: > >> I can't figure this out, and think it is a bug. I'm using Mathematica >> 7.0.0 and get the same behaviour on both Mac OS X (10.5.8) and on >> Windows XP. >> >> I want a function which creates a rule. The rule is of the form >> "manipulated input" -> "input". Here is my first attempt (I have >> simplified from what I really want to do, in order to illustrate the >> bug): >> >> (1) makerule[input_] :=(input /. a_Integer :> 2 a) -> input >> In: makerule[5] >> Out: 2a->5 >> >> (I expect to get 10->5) >> >> (2) makerule2[input_] := (input /. a_Integer :> 2 a)~myrule~input >> In: makerule2[5] >> Out: myrule[10,5] >> >> as expected >> >> Forcing an extra layer of localization seems to squash the bug: >> >> (3) makerule3[input_] :=Block[{inputcopy = input},(input /. >> a_Integer :> 2 a) -> inputcopy] >> In: makerule[5] >> Out: 10->5 >> >> Is it a bug, or have I misunderstood how the localization is meant to >> work? >>