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