MathGroup Archive 2000

[Date Index] [Thread Index] [Author Index]

Search the Archive

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



  • Prev by Date: Re: Functional Expression Meaning (was:A Functional Expression Trick)
  • Next by Date: Re: Pattern Matching
  • Previous by thread: Re: Pattern Matching
  • Next by thread: Re: Pattern Matching