Re: Pattern Matching

*To*: mathgroup at smc.vnet.net*Subject*: [mg23907] Re: Pattern Matching*From*: Hartmut Wolf <hwolf at debis.com>*Date*: Fri, 16 Jun 2000 00:56:48 -0400 (EDT)*Organization*: debis Systemhaus*References*: <8hsu3g$dh4@smc.vnet.net> <8i1suj$jls@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

My comments below at >>>>>>>> Allan Hayes schrieb: > > Johannes, > > Re your first question. > > We get > > x[1] b[1] + x[2] b[2] /. > Plus[Times[x[_], b[_]] ..] -> z > > b[1] x[1] + b[2] x[2] > > possibly because, before the matching and replacement, the left side of the > rule is evaluated thus: > > Plus[Times[x[_], b[_]] ..] > > b[_] x[_] .. > > So we end up with > > x[1] b[1] + x[2] b[2] /. (*1*) > (x[_] b[_]) .. -> z > > b[1] x[1] + b[2] x[2] > > We can avoid this by using HoldPattern: > > x[1] b[1] + x[2] b[2] /. > HoldPattern[Plus[Times[x[_], b[_]] ..]] -> z > > z > > However it does seem odd that, in spite of (*1*), we get > > x * b[1] + x* b[2] /. > (x* b[_]) .. -> z > > 2 z > > -- > 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 > >>>>>>>> Dear Allan, as so often you come up with the right questions. You observed (example simplified) In[35]:= h[x, x] /. x .. -> z (*2*) Out[35]= h[z, z] whereas (*1*) doesn't substitute. Before coming back to that, why isn't Out[35] == h[z]? Time to go back to the Book. Although I didn't find it stated, and although we wouldn't get an error message, all examples given in the book indicate that the use of Repeated in (*1*) and (*2*) isn't legal. Since Repeat[...] is equivalent to a Sequence the matched object must be enclosed in a head anyways, so In[38]:= h[x, x] /. head_[x ..] -> head[z] Out[38]= h[z] works right, as well as does In[26]:= h[x[1] b[1], x[2] b[2]] /. head_[x[_] b[_] ..] -> head[z] Out[26]= h[z] (And of course the HoldPattern version suggested by you and Andrzej corresponds to this syntax.) However this doesn't yet solve the problem as to replace only for equal indices. In[47]:= x[1] b[1] + x[2] b[2] /. HoldPattern[Plus[Times[x[n_], b[n_]] ..]] -> z Out[47]= z + b[2] x[2] gives only one substitution. I would have liked to restrict the scope of the pattern variable n_ only to Times[x[n_], b[n_]] and not to the whole sequence, but I found no way to do that. David Park, and similarily Wagner Truppel, proposed In[80]:= Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. b[n_]x[n_] -> z /. n_Integer z -> z Out[80]= z + b[2] x[1] + b[1] x[2] using iterated replacement (which is fine!). But let's try to do that within one stroke. Since it is easy to simply remove all elements x[n_] b[n_] In[88]:= Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. p : b[n_]x[n_] :> Sequence[] Out[88]= b[2] x[1] + b[1] x[2] we may try just to not remove the first occurance: In[125]:= Module[{virgo = True}, Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. b[n_]x[n_] :> RuleCondition[ If[virgo, virgo = False; z, Unevaluated[Sequence[]]] ]] Out[125]= z + b[2] x[1] + b[1] x[2] RuleCondition is not striktly neccessary in this case, but would give a more pleasing result if the lhs in ReplaceAll is held: then the rhs of RuleDelayed will be evaluated *after* pattern matching and before substitution (the Trott-Strzebonski-Hayes method; else the rhsides will be evaluated later when the result of ReplaceAll is evaluated as the final step, which of course will not occur if held). A less obfuscated method to do the same would be In[127]:= Module[{virgo = True}, Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. {b[n_]x[n_] /; First[{virgo, virgo = False}] -> z, b[n_] x[n_] -> Sequence[]}] Out[127]= z + b[2] x[1] + b[1] x[2] where the condition is evaluated at the lhs (of Rule). Finally a remark addressed to Johannes: I certainly would not try to program that way; it is much easier (and clearer) just to seperate "diagonal" and "off-diagonal" elements of your sum In[90]:= Plus[x[1] b[1], x[1]b[2], x[2] b[1], x[2] b[2]] /. {{b[n_]x[n_] -> Sequence[]}, {b[n_]x[m_] /; n =!= m -> Sequence[]}} Out[90]= {b[2] x[1] + b[1] x[2], b[1] x[1] + b[2] x[2]} and then proceed with the parts as you like. Kind regards to everyone, Hartmut Wolf > "Johannes Ludsteck" <ludsteck at zew.de> wrote in message > news:8hsu3g$dh4 at smc.vnet.net... > > Dear Group Members, > > I would like to "find" and replace expressions with the simple > > structure x[1] b[1]+x[2] b2]+...+x[n] b[n] > > I tried to use the following replacement rule > > In[27]:= x[1] b[1] + x[2] b[2] /. Plus[Times[x[_], b[_]] ..] -> z > > > > Out[27]= b[1] x[1] + b[2] x[2] + b[3] x[3] > > Which didn't work (Out[27] should be z). > > Why? > > The following FullForm seems to give exactly the structure I used > > in my replacement rule. > > > > In[17]:= > > FullForm[x[1] b[1] + x[2] b[2] + x[3] b[3]] > > Out[17]//FullForm= > > Plus[Times[b[1], x[1]], Times[b[2], x[2]], Times[b[3], x[3]]] > > > > Even if this worked, my pattern wouldn't account for equal indices, > > i.e. it would match x[1] b[500]+x[12] b[3], even if it shouldn't. > > > > Any suggestions? > > Thanks, > > Johannes Ludsteck > > > > > > Johannes Ludsteck > > Centre for European Economic Research (ZEW) > > Department of Labour Economics, > > Human Resources and Social Policy > > Phone (+49)(0)621/1235-157 > > Fax (+49)(0)621/1235-225 > > > > P.O.Box 103443 > > D-68034 Mannheim > > GERMANY > > > > Email: ludsteck at zew.de > >