Message Boards Message Boards


Plus pattern matching quirkiness

Posted 10 years ago
2 Replies
3 Total Likes
What is it about Plus that accounts for this behavior (note the middle (non)match)?
 In[228]:= ClearAll[Bar];
           x = Plus[Bar[1, 2], Bar[3, 4]]; 
 In[230]:= MatchQ[x, Plus[_Bar, _]]
 Out[230]= True
 In[231]:= MatchQ[x, Plus[_Bar, _Bar]]
 Out[231]= False
 In[232]:= MatchQ[x, Plus[a_Bar, _Bar]]
Out[232]= True

I thought it might be something about the attributes:
In[233]:= Attributes[Plus]
Out[233]= {Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected}

especially having read the docs about Flat/OneIdentity. But with a dummy function of equivalent attributes:
 In[234]:= ClearAll[Foo];
           SetAttributes[Foo, Attributes[Plus]];
           x = Foo[Bar[1, 2], Bar[3, 4]];
 In[237]:= MatchQ[x, Foo[_Bar, _]]
 Out[237]= True
 In[238]:= MatchQ[x, Foo[_Bar, _Bar]]
 Out[238]= True

In[239]:= MatchQ[x, Foo[a_Bar, _Bar]]
Out[239]= True
POSTED BY: Buddy Ritchie
2 Replies
Posted 10 years ago
The reason is that before doing the pattern match,  Plus[_Bar, _Bar] is transformed to 2*_Bar. Therefore you must prevent the evaluation of Plus, with HoldPattern:
ClearAll[x, Bar];

x = Plus[Bar[1, 2], Bar[3, 4]];

MatchQ[x, HoldPattern[Plus[_Bar, _Bar]]]

Hope that helps
POSTED BY: Jose Gomez
Yes, indeed HoldPattern is very useful. A classic example from documentation which I personally use quite a bit

Cases[{a -> b, c -> d}, HoldPattern[a -> _]]
Out = {a -> b}

Cases[{a -> b, c -> d}, a -> _]
Out = {}
 the last one fails because Cases[e, patt->rhs] finds elements that match patt, and there is no patt (a) in the list.
POSTED BY: Vitaliy Kaurov
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract