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