8
$\begingroup$

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

$\endgroup$
7
  • $\begingroup$ I am really curious about what you are cooking here celtschk! :) $\endgroup$ Commented Apr 15, 2012 at 18:03
  • 2
    $\begingroup$ 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 Internal`ComparePatterns. For instance Internal`ComparePatterns[_Integer, _] gives "Specific", i.e. _Integer is a special case of _. $\endgroup$ Commented Apr 15, 2012 at 19:03
  • $\begingroup$ @OleksandrR.: Ah thanks, I was not aware of that. Is there any place where this function is described? $\endgroup$
    – celtschk
    Commented Apr 15, 2012 at 19:10
  • 1
    $\begingroup$ @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. $\endgroup$ Commented Apr 15, 2012 at 19:16
  • $\begingroup$ @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 Internal`ComparePatterns can actually address. $\endgroup$ Commented Apr 15, 2012 at 19:27

1 Answer 1

9
$\begingroup$

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.