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[5]]
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[5]]
Analysis of the evaluation gives the simpler form
Replace[Hold[2 + 3 + Hold[2 + 3]],
p_Plus :> RuleCondition[p], {0, Infinity}]
Hold[5 + Hold[5]]
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
> Trott, Adam Strzebonski idea.
>
>
> 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[5]]
>
> EvaluateAt[expr, 1]
>
> Hold[5 + Hold[2 + 3]]
>
> EvaluateAt[expr, {1, 3, 1}, #^2 &]
>
> Hold[2 + 3 + Hold[25]]
>
> 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[1]:=
> > 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[36]-Sqrt[16] evaluate to 6, 4, 9, 2
> > respectively since they each have the head Plus.
> >
> > In[2]:=
> >
> >
>
demo=HoldForm[(Erf[Infinity]+5)*Sin[Pi/(1+3)]*Sqrt[5+4]/(Sqrt[36]-Sqrt[16])]
> > ;
> > EvaluatePattern[demo,_Plus]
> >
> > Out[3]=
> > HoldForm[(6*Sin[Pi/4]*Sqrt[9])/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
> >
> >
> >
>
>
>
>
>