Message Boards Message Boards

0
|
6482 Views
|
6 Replies
|
5 Total Likes
View groups...
Share
Share this post:

What's going wrong with this replacement rule?

a = v v a b /. a_ b_ -> a + b 2 v The expected answer is v + b

Maybe something about the global 'a' is interfering with the substitutions. Make 'a' and 'b' local variables in a module:

times2plus[expr_] := Module[{a, b},
  expr /. a_ b_ -> a + b
  ]

times2plus[a b]
2 v

Eliminate 'a', just go with 'v', but keep the global assignment a=v:

times2plus[v b]
2 v

Using TracePrint, it appears that the substitution is done twice, once correctly and then weirdly to produce 2v.

What is going on?

POSTED BY: Eric Johnstone
6 Replies

@Eric Johnstone please do not duplicate discussions, it is against the forum rules: http://wolfr.am/READ-1ST

POSTED BY: Moderation Team

Sorry, when I posted it the first time, I got a message that some further classification was needed, so I added another one and posted. But it looks like the first one when through anyway.

Eric

POSTED BY: Eric Johnstone

The disadvantage of Replace is that you can easily make complicated riddles like this one. Most experienced programmers don't solve these riddles - they just avoid them completely.

As convention, people often add a "$" to the front of variables that are "internal". So let's try that:

a = v;
a b /. $a_ $b_ -> $a + $b

This works. There's no confusion about what the "a" on the right hand side of the arrow means.

In general you want to avoid undescriptive variable names. That also avoids this problem.

Now to explain what happens. a = v; a b /. a_ b_ -> a + b

First a is replaced by v per its definition. So we effectively have:

 v b /. a_ b_ -> v + b

"Then the product is reordered alphabetically because "v b" is equal to "b v". So now we have "b v".

 b v /. a_ b_ -> v + b

By the substitution, we get b + b or 2b.

POSTED BY: Sean Clarke

The delayed rule is usually safer than the immediate rule, just like it is usually recommended to define function the delayed way f[x_]:= instead of the immediate way f[x_]=. There are some situation when the two rules behave in a dramatically different way, for example x:>RandomReal[] and x->RandomReal[], and you have to be careful.

POSTED BY: Gianluca Gorni

Thank you, Gianluca.

That has solved the problem. I have a long list of rules. Would it be better to always use delayed evaluation? This one is only that rule that seems to be problematic, but there might be other undiscovered gotchas hidden in the list.

Eric

ETA There were other problems. The delayed evaluation worked when applied to the complete list.

POSTED BY: Eric Johnstone

I think that we have to blame the reordering of the factors and immediate evaluation. When given this:

a*b /. a_ b_ -> a + b

a*b is first changed into v*b, and then reordered into b*v. The substitution with immediate evaluation becomes

b*v /. a_ b_ -> v + b

which means that b is associated with a and v is associated with b, which transforms b*v into v+v. Try delayed evaluation

a = v;
a b /. a_ b_ :> a + b
POSTED BY: Gianluca Gorni
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract