Re: Question on pattern matching
- To: mathgroup at smc.vnet.net
- Subject: [mg47851] Re: Question on pattern matching
- From: ab_def at prontomail.com (Maxim)
- Date: Thu, 29 Apr 2004 00:35:08 -0400 (EDT)
- References: <c6l89b$is5$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Take a look at http://forums.wolfram.com/mathgroup/archive/2000/Jan/msg00296.html To sum it up, when Mathematica deals with patterns involving Flat or Orderless, it performs regrouping/reordering of arguments only if you explicitly have something like f[_, _] in the pattern. Blank[] as the head won't do: for a pattern such as h_[_, _] Mathematica is not smart enough to first match h_ to f and then to look at the attributes of f. BlankSequence or Repeated won't work in combination with Flat either (but will work with Orderless): In[1]:= Module[{f}, Attributes[f] = Flat; MatchQ[f[1, 2, 3], f[_f]] ] Module[{f}, Attributes[f] = Flat; MatchQ[f[1, 2, 3], f[__f]] ] Module[{f}, Attributes[f] = Flat; MatchQ[f[1, 2, 3], f[_f..]] ] Module[{f}, Attributes[f] = Flat; MatchQ[f[1, 2, 3], HoldPattern @ f[f[1], f[2, 3]]] ] Out[1]= True Out[2]= False Out[3]= False Out[4]= False This is very counter-intuitive, because if we have an expression matching f[_f] then it should also match f[__f] and f[_f..] -- the last two patterns are more general. It's even harder to explain what Mathematica didn't like in the following example: In[5]:= Module[{f}, Attributes[f] = Flat; MatchQ[f[1, 2, 3], f[x_, _] /; x === f[1]] ] Module[{f}, Attributes[f] = Flat; MatchQ[f[1, 2, 3], HoldPattern @ f[f[1], _]] ] Out[5]= True Out[6]= False And even more confusing in the case of Orderless: In[7]:= Module[{f}, Attributes[f] = Orderless; MatchQ[f[1, 2], HoldPattern[f][2, 1]] ] Module[{f}, Attributes[f] = Orderless; MatchQ[f[1, 2], HoldPattern @ f[2, 1]] ] Out[7]= True Out[8]= False What's more, this gives a nasty complication: what if we combine Flat and Orderless? In[9]:= Module[{f}, Attributes[f] = Orderless; MatchQ[f[1, 2, 3], f[s__, __] /; {s} === {2, 1}] ] Module[{f}, Attributes[f] = {Flat, Orderless}; MatchQ[f[1, 2, 3], f[s__, __] /; {s} === {2, 1}] ] Out[9]= True Out[10]= False When we add the Flat attribute, we only make the pattern more general, but suddenly there's no longer a match. Absolutely illogical and misleading. Maxim Rytin m.r at prontomail.com