       Re: A function to evaluate only parts matching a pattern

• To: mathgroup at smc.vnet.net
• Subject: [mg25762] Re: A function to evaluate only parts matching a pattern
• From: "Allan Hayes" <hay at haystack.demon.co.uk>
• Date: Sat, 21 Oct 2000 14:43:15 -0400 (EDT)
• References: <8se9n3\$6ps@smc.vnet.net> <8sjhpt\$fpm@smc.vnet.net>
• Sender: owner-wri-mathgroup at wolfram.com

```In my previous posting in this thread I noted, essentially, the following

Hold[2 + 3 + Hold[2 + 3]] /. p_Plus :> With[{eval = p}, eval /; True]

Hold[5 + Hold[2 + 3]]

When we wanted to get Hold[5 + Hold]

It turns out that Replace provides a way out:

Replace[Hold[2 + 3 + Hold[2 + 3]],
p_Plus :> With[{eval = p}, eval /; True], {0, Infinity}]

Hold[5 + Hold]

Analysis of the evaluation gives the simpler form

Replace[Hold[2 + 3 + Hold[2 + 3]],
p_Plus :> RuleCondition[p], {0, Infinity}]

Hold[5 + Hold]

There are two generally applicable techniques here.
1) RuleCondition[p] (or With[{eval=p},eval/;True]) causes instances of p to
be evaluated before replacement takes place. We can control the evaluation
by using RuleCondition[p, test].
2) Replace turns out to be vey flexible -- the following examples illustrate
its evaluation

? Replacements are from deepest level up; and no evaluation is done between
replacements.

Consider

rls = {a + z -> c, a + q -> b, z -> q};
x = a; h[b] = B;
h[a + q] = R;

We get

Replace[h[x + z], rls, {1, 2}]

B

Here are the main steps in the evaluation

h[x+ z]

Initial evaluation uses x=a.
h[a+ z]

Replacements in held expression
h[a+ q] (replace at level 2)
(the rule h[a+q] =R is not used)
h[b]  (replace at level 1)

Final evaluation uses h[b] = B
B

? ReplaceAll is not equivalent to  Replace[ expr, rules, {0, Infinity}]

h[x + z] //. rls

h[c]

Replace[h[x + z], rls, {0, Infinity}]

B

? We can include or exclude heads

Replace[a[a], a -> p, {1}]

a[p]

Replace[a[a], a -> p, {1}, Heads -> True]

p[p]

--
Allan
---------------------
Allan Hayes
Mathematica Training and Consulting
Leicester UK
www.haystack.demon.co.uk
hay at haystack.demon.co.uk
Voice: +44 (0)116 271 4198
Fax: +44 (0)870 164 0565

"Allan Hayes" <hay at haystack.demon.co.uk> wrote in message
news:8sjhpt\$fpm at smc.vnet.net...
> Ted,
> ReplaceAll, /., causes a problem with
>
> EvaluatePattern[expr_,pattn_]:= expr/.Pattern[p,pattn] :> With[{eval =p},
> eval /; True]
>
> Thus:
>
> EvaluatePattern[Hold[2 + 3 + Hold[2 + 3]], _Plus]
>
>         Hold[5 + Hold[2 + 3]]
>
> We can't solve this by using ReplaceRepeated,  insead of  ReplaceAll :
>
> EvaluatePattern2[expr_, pattn_] :=
>   expr //. Pattern[p, pattn] :> With[{eval = p}, eval /; True]
>
> EvaluatePattern2[Hold[2 + 3 + Hold[2 + 3]], _Plus]
>
>         Hold[5 + Hold[2 + 3]]
>
> because the second use of ReplaceAll sees 5+Hold[2+3] and does not move on
> to 2+3.
>
> Here is a different approach to the problem of evaluating in place, based
on
> position rather than pattern. This will appear in Mathematica in Education
> and Research 9.1 together with an analysis and variations on the Micheal
>
>
> EvaluateAt[expr_, pos_, f_:Identity] :=
>   Module[{pos1},(*normalize pos*)
>     pos1 = Switch[pos, _Integer, {{pos}}, {__Integer}, {pos}, _, pos];
>     Fold[ReplacePart[#1, Extract[#1, #2, f], #2] &, expr,
>       Reverse[Sort[pos1]]]
>     ]
>
> EvaluateAt[expr, Position[expr, _Plus]]
>
>         Hold[5 + Hold]
>
> EvaluateAt[expr, 1]
>
>         Hold[5 + Hold[2 + 3]]
>
> EvaluateAt[expr, {1, 3, 1}, #^2 &]
>
>         Hold[2 + 3 + Hold]
>
> Programming note
>
> 1. Reverse is used in Reverse[Sort[pos]] to arrange the position lists in
> decreasing length so that the later positions still refer to the same part
> of the modified expression
> 2. Fold is used so that later replacements replace with parts of the
> previously modified expression, not parts of the original expression.
>
> --
> Allan
> ---------------------
> Allan Hayes
> Mathematica Training and Consulting
> Leicester UK
> www.haystack.demon.co.uk
> hay at haystack.demon.co.uk
> Voice: +44 (0)116 271 4198
> Fax: +44 (0)870 164 0565
>
> "Ersek, Ted R" <ErsekTR at navair.navy.mil> wrote in message
> news:8se9n3\$6ps at smc.vnet.net...
> > The function below evaluates all parts of a held expression that match a
> > certain pattern. This is based on some code Robby Villegas of Wolfram
> > Research discussed at the 1999 Developer Conference. There Micheal Trott
> and
> > Adam Strzebonski of Wolfram Research are mentioned as the inventors of
> this
> > trick discussed by Robby Villegas.
> >
> > In:=
> >   EvaluatePattern[expr_,pattn_]:=
> >    expr/.Pattern[p,pattn] :> With[{eval =p}, eval /; True]
> >
> >
> > I made it into a function and added (Pattern[p,pattn]). The nice part
> > is that there is no need to use Module[{p}, _]
> >
> > -----------
> > The next cell creates a held expression and evaluates all sub
expressions
> > with the Head Plus but nothing else evaluates. In this example
> > Erf[Infinity]+5, 1+3, 5+4, Sqrt-Sqrt evaluate to 6, 4, 9, 2
> > respectively since they each have the head Plus.
> >
> > In:=
> >
> >
>
demo=HoldForm[(Erf[Infinity]+5)*Sin[Pi/(1+3)]*Sqrt[5+4]/(Sqrt-Sqrt)]
> > ;
> >   EvaluatePattern[demo,_Plus]
> >
> > Out=
> >   HoldForm[(6*Sin[Pi/4]*Sqrt)/2]
> >
> >
> > Isn't that slick!  Now this function doesn't work if any of the
> definitions
> > below are used. Why is the definition above the only one that works?
> >
> >
> >  EvaluatePattern[expr_,pattn_]:=
> >   expr/.Pattern[p,pattn]:>(p/;True)
> >
> >  EvaluatePattern[expr_,pattn_]:=
> >   expr/.Pattern[p,pattn]:>With[{eval=p},eval]
> >
> >  EvaluatePattern[expr_,pattn_]:=
> >   expr/.Pattern[p,pattn]->p
> >
> >
> > --------------------
> > Regards,
> > Ted Ersek
> >
> > Down load Mathematica tips, tricks from
> > http://www.verbeia.com/mathematica/tips/Tricks.html
> >
> >
> >
>
>
>
>
>

```

• Prev by Date: ImplicitSolve
• Next by Date: Regressions!
• Previous by thread: Re: A function to evaluate only parts matching a pattern
• Next by thread: Graphics Directives Lost In Certain Cases