Re: Pattern Matching
- To: mathgroup at smc.vnet.net
- Subject: [mg23927] Re: Pattern Matching
- From: "Allan Hayes" <hay at haystack.demon.co.uk>
- Date: Fri, 16 Jun 2000 00:57:06 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Andrzej, We can modify David's solution to behave in the alternative way: Module[{u}, x[1] b[1] + x[1]b[2] + x[2] b[1] + x[2] b[2] + 3z /. b[n_]x[n_] -> u /. n_Integer u -> z] 4 z + b[2] x[1] + b[1] x[2] or x[1] b[1] + x[1]b[2] + x[2] b[1] + x[2] b[2] + 3z /. b[n_]x[n_] -> # /. n_Integer # -> z &[Unique[u]] 4 z + b[2] x[1] + b[1] x[2] ( x[1]b[1] + x[2]b[2] )y + (x[3]b[3] + x[4]b[4])v /. b[n_]x[n_] -> # /. n_Integer # -> z &[Unique[u]] v z + y 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 ----- Original Message ----- From: "Andrzej Kozlowski" <andrzej at tuins.ac.jp> To: mathgroup at smc.vnet.net <hay at haystack.demon.co.uk>; "David Park" <djmp at earthlink.net>; "Johannes Ludsteck" <ludsteck at zew.de>; "Wagner Truppel" <wtruppel at uci.edu> Subject: [mg23927] Re: Pattern Matching > Dear Hartmut > > One problem with questions of this kind is that the author often does not > give us a really precise idea of what he wants. The result is that a number > of potential solutions suggest themselves, which may work in some but not in > other situations. For example, take the solution proposed by David Park, and > Wagner Truppel: > > In[4]:= > 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[4]= > z + b[2] x[1] + b[1] x[2] > > is fine, if that is all what Johannes wanted but; > > In[5]:= > x[1] b[1] + x[1]b[2] + x[2] b[1] + x[2] b[2] + 3z /. b[n_]x[n_] -> z /. > n_Integer z -> z > > Out[5]= > z + b[2] x[1] + b[1] x[2] > > may not be quite what he had in mind. > > Similarly, with your solution > > In[6]:= > 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[6]= > z + b[2] x[1] + b[1] x[2] > > is fine but > > > In[7]:= > Module[{virgo = True}, > ( x[1]b[1] + x[2]b[2] )y + (x[3]b[3] + x[4]b[4])v /. > b[n_]x[n_] :> > RuleCondition[ If[virgo, virgo = False; z, Unevaluated[Sequence[]]] ]] > > Out[7]= > y z > > while it would seem to me that the answer: > > v z + y z > > would be more reasonable. > In both of these cases my "global function" solution: > > funct[expr_Plus] := expr /. HoldPattern[Plus[Times[x[_], b[_]] ..] ] :> z; > funct[(x[i_]*b[j_] /; i != j) + c_] := x[i]*b[j] + funct[c]; > funct[x_] := x > > > seems preferable, since in the above examples it gives: > > In[15]:= > MapAll[funct, ( x[1]b[1] + x[2]b[2] )y + (x[3]b[3] + x[4]b[4])v] > > Out[15]= > v z + y z > > In[16]:= > MapAll[funct, x[1] b[1] + x[1]b[2] + x[2] b[1] + x[2] b[2] + 3z] > > Out[16]= > 4 z + b[2] x[1] + b[1] x[2] > > But of course, as I wrote, Johannes did not really make completely clear > exactly which matches were to be allowed and which not. > > Andrzej Kozlowski > > -- > Andrzej Kozlowski > Toyama International University, JAPAN > > For Mathematica related links and resources try: > <http://www.sstreams.com/Mathematica/> > > > > > on 00.6.15 5:27 PM, Hartmut Wolf at hwolf at debis.com wrote: > > > 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 > >>> > >