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

MathGroup Archive 2006

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

Search the Archive

RE: Behavior of ReplaceAll with Computed Results from a Conditional Test

  • To: mathgroup at smc.vnet.net
  • Subject: [mg66770] RE: [mg66745] Behavior of ReplaceAll with Computed Results from a Conditional Test
  • From: "David Park" <djmp at earthlink.net>
  • Date: Mon, 29 May 2006 06:06:42 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

I received several replies, and thanks for them, that suggested using two
rules. In fact, that's what I did but I was still interested in the question
because I think it is quite reasonable to calculate quantities as part of
the test and have them available for the replacement code. It might not just
be choosing between two alternatives, where we could substitute two rules,
but might involve a complicated calculation as part of the test and we want
the results of the computation in the replacement routine.

With a little more investigation I have found that Mathematica does provide
a method for doing this. The trick is to put the test after the body of the
replacement Module. There is a note in the Module Help...

"You can use Module[{vars}, body /; cond] as the right-hand side of a
transformation rule with a condition attached."

That forces the replacement to be done immediately and the test can return
results that can be extracted.

Clear[transformf]
transformf[expr_] :=
  Module[{testQ},

    testQ[a_, b_, c_] :=
      Module[{replacea = False, test},
        test =
          Which[
            c === a, replacea = True; True,
            c === b, replacea = False; True,
            True, False];
        {test, replacea}];

    expr /. (f[a_, b_]c_) :>
        Module[{replacea, work},

          If[replacea, f[a^2, b], f[a, b^2]] /; (work = testQ[a, b, c];
              replacea = Last[work]; First[work])]
    ]

{f[a, b]a, f[a, b]b, f[a, b]c} // transformf
{f[a^2, b], f[a, b^2], c*f[a, b]}

David Park
djmp at earthlink.net
http://home.earthlink.net/~djmp/



From: David Park [mailto:djmp at earthlink.net]
To: mathgroup at smc.vnet.net

Dear MathGroup,

Here is a routine that mimics a more complicated routine I was working on. I
think it has strange behavior. The routine uses a conditional test on the
pattern variables that as a side effect computes a parameter used in the
replacement. When used on a list this doesn't work because Mathematica does
all of the tests first, leaving only the parameter from the last test, and
then does all of the replacements. Not what I want.

The sample routine looks at expressions of the form f[a,b]c. If c ===a it
returns f[a^2,b]. If c === b it returns f[a,b^2] and otherwise no
replacement is done. I've added two Print statements to clarify what is
happening.

transformf[expr_] :=
  Module[{testQ, replacea},

    testQ[a_, b_, c_] :=
      Module[{},
        Print["Testing ", f[a, b]c];
        Which[
          c === a, replacea = True; True,
          c === b, replacea = False; True,
          True, False]];

    expr /. (f[a_, b_]c_) /; testQ[a, b, c] :>
        Module[{},
          Print["Processing " , f[a, b]c];
          If[replacea, f[a^2, b], f[a, b^2]]]
    ]

If I Map this onto the following list it works as expected.

transformf /@ {f[a, b]a, f[a, b]b}
Testing a f[a, b]
Processing a f[a, b]
Testing b f[a, b]
Processing b f[a, b]
{f[a^2, b], f[a, b^2]}

However, if I use the routine on the entire list I obtain:

{f[a, b]a, f[a, b]b} // transformf
Testing a f[a, b]
Testing b f[a, b]
Processing a f[a, b]
Processing b f[a, b]
{f[a, b^2], f[a, b^2]}

which I regard as incorrect. The Help for ReplaceAll says...

"ReplaceAll looks at each part of expr, tries all the rules on it, and then
goes on to the next part of expr."

That seems to me to be a vague and inaccurate statement. One might think
that if the rule matched then the replacement would be done - or at least
calculated. Then ReplaceAll would go on to look at the next part of the
expression. Instead all the tests are done first, and all the matching
replacements are done afterwards. So in the above routine the replacea
parameter is set to the last test result and then used in all of the
replacements.

That hardly seems fair. Is there a way around this behavior.

David Park
djmp at earthlink.net
http://home.earthlink.net/~djmp/

Everyone should study mathematics - just so they will know what it is to be
wrong.










  • Prev by Date: Re: Behavior of ReplaceAll with Computed Results from a Conditional Test
  • Next by Date: Re: Closed Form solution too much to hope for?
  • Previous by thread: Re: Behavior of ReplaceAll with Computed Results from a Conditional Test
  • Next by thread: Re: RE: Behavior of ReplaceAll with Computed Results from a Conditional Test