# Why does Mathematica choose the second function definition?

While working on a solution to this question I've come across a case where I simply don't understand Mathematica's behaviour.

I've got the following definitions:

PatternImplies[(x:(Verbatim[Blank]
|Verbatim[BlankSequence]
|Verbatim[BlankNullSequence]))[h_],x[]]:=True

(*CatchAll rule*)
PatternImplies[_,_]:=Maybe;


Now I try this:

PatternImplies[_Integer,_]
(*
==> Maybe
*)


I would have expected True. My first thought was that I probably got the pattern wrong, so I tested:

MatchQ[PatternImplies[_Integer,_],
PatternImplies[(x:(Verbatim[Blank]
|Verbatim[BlankSequence]
|Verbatim[BlankNullSequence]))[h_],x[]]]
(*
==> True
*)


In other words, the pattern matches. Moreover, looking at Downvalues I see that the special rule is indeed stored before the catch-all rule.

So why does Mathematica chose the second definition (and more importantly, what can I do about it?)

• I am really curious about what you are cooking here celtschk! :) Apr 15, 2012 at 18:03
• Just thought I'd better make you (and @István) aware, if you're not already, that what this implements seems quite similar to the undocumented function InternalComparePatterns. For instance InternalComparePatterns[_Integer, _] gives "Specific", i.e. _Integer is a special case of _. Apr 15, 2012 at 19:03
• @OleksandrR.: Ah thanks, I was not aware of that. Is there any place where this function is described? Apr 15, 2012 at 19:10
• @OleksandrR. would you care to post your findings as an answer to my question here? It would be nice to gather related stuff there, and it might nudge others knowing more to share information about ComparePatterns. So far it seems that this amazing function handles all my example cases posted there. Apr 15, 2012 at 19:16
• @István I haven't looked into this function in great detail so far; I just know that it exists and, in general terms, what it does. I think I'll research it further and then post an answer to your question mentioning it. I hadn't done so previously as what you ask for covers a much broader scope than InternalComparePatterns can actually address. Apr 15, 2012 at 19:27

As far as I can tell, it should match the catch all rule. That's because _ isn't of the form x[]

Now, when you test the MatchQ expression, both arguments are first evaluated. So, you're actually doing MatchQ[maybe, maybe] which of course returns True.

You can do the checking as you intended to by first holding the arguments

MatchQ[Hold@PatternImplies[_Integer, _],
Hold@PatternImplies[(x : (Verbatim[Blank] | Verbatim[BlankSequence] |
Verbatim[BlankNullSequence]))[h_], x[]]]

False


EDIT:

I now see what you intended with x[]. You could do x_[] instead. That would mean "any no-argument expression whose head coincides with the previous pattern labelled x. If you write x[] it matches literally

• Thank you. So I got fooled by MatchQ — next time I'll know to use Unevaluated. With the x_[]` now it works great. Apr 15, 2012 at 18:19