12

I am working on toy problems to help me assimilate the idea of pattern matching in Mathematica. The following code does not behave as I expected, and I could not figure out what is wrong with my understanding of PatternTest.

MatchQ[{2, 1, 2, 5}, {x__?(FromDigits[{#}] > 3 &), y__}]

I expected this piece of code to check if the list {2,1,2,5} can be written as two consecutive (non-empty) sequences such that the integer we get from the first sequence is greater than 3. Since {Sequence[2,1],Sequence[2,5]} is one way to rewrite the list such that FromDigits[{2,1}] > 3 holds, I expected that code to return the value True. However, that is not the case.

What is wrong with my interpretation of the code?

Michael Wijaya
  • 377
  • 2
  • 9

1 Answers1

14

The documentation for PatternTest (aka ?) says

In a form such as __?test every element in the sequence matched by __ must yield True when test is applied.

Thus your code will not work as you hoped.

A good way to see how a pattern is working is to use ReplaceList. Something close to your code is

In[1]:= ReplaceList[{3, 4, 2, 1}, 
          {___, x__?(FromDigits[{##}] > 3 &), y___} :> {{x}, {y}}]

Out[1]= {{{4}, {2, 1}}}

However, if you use Condition (/;) instead of pattern test, then you can get the behaviour that you were looking for

In[2]:= ReplaceList[{3, 4, 2, 1}, 
          {___, x__, y___} :> {{x}, {y}} /; FromDigits[{x}] > 3]

Out[2]= {{{3, 4}, {2, 1}}, {{3, 4, 2}, {1}}, {{3, 4, 2, 1}, {}}, 
         {{4}, {2, 1}}, {{4, 2}, {1}}, {{4, 2, 1}, {}}, {{2, 1}, {}}}
Simon
  • 14,631
  • 4
  • 41
  • 101
  • @Leonid: The power of procrastination knows no bounds! – Simon Dec 11 '11 at 22:59
  • I think that response was written faster than I put together a comment, roughly at the same time. – Daniel Lichtblau Dec 11 '11 at 23:02
  • 1
    @Simon Thank you very much! I got a bunch of tips from your reply: ## instead of #, ReplaceList to test pattern, and difference between /; and __?test. – Michael Wijaya Dec 11 '11 at 23:33
  • +1: Hope this comment is ok, but you guys are way too fast answering MMA questions! The few questions I know a good answer for are already answered by the time I notice that someone asked a question under the tag :(. (This is both good and bad, bad that I'm having a real hard time trying to participate on SO, good for all the question askers!) – nixeagle Dec 12 '11 at 00:50
  • @nixeagle: You're not the first one to complain about this! Harder questions or ones with multiple approaches are easier to get a word in. For the easier questions, you've either got to get lucky and check the site just as a question gets posted (which is my method, since the rss feed is too slow). Other people take [more extreme measures](http://stackoverflow.com/q/6505675/421225). – Simon Dec 12 '11 at 01:08
  • @Simon Neat question/answers you linked to. Amazing what MMA can do sometimes :o. I'm not *that* desperate... at least not yet! I'll just satisfy myself with reading older questions and answers and upvoting the ones I find helpful and or new to me. :) – nixeagle Dec 12 '11 at 01:12
  • @nixeagle, occasionally you'll find an "easy" question that no one has touched for 20 mins, like [this one](http://stackoverflow.com/a/8278915/198315), and then you need to pounce. – rcollyer Dec 12 '11 at 04:27
  • @nixeagle or you use this tool: http://stackoverflow.com/questions/6505675/watching-for-new-mathematica-questions-using-mathematica-and-the-stackoverflow-a – Sjoerd C. de Vries Dec 12 '11 at 22:06
  • @Sjoerd you apparently missed Simon's comment above... :-) – Mr.Wizard Dec 13 '11 at 03:32