MathGroup Archive 2009

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

Search the Archive

Re: Weird localization bug!

  • To: mathgroup at smc.vnet.net
  • Subject: [mg106060] Re: [mg106009] Weird localization bug!
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Thu, 31 Dec 2009 03:18:29 -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}


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?
>
>


  • Prev by Date: Re: Re: bug in RandomChoice if weight is zero?
  • Next by Date: Re: More /.{I->-1} craziness
  • Previous by thread: Weird localization bug!
  • Next by thread: Re: Weird localization bug!