Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An unexpected behavior of PatternTest in Mathematica

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?

like image 373
Michael Wijaya Avatar asked Dec 11 '11 22:12

Michael Wijaya


1 Answers

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}, {}}}
like image 139
Simon Avatar answered Sep 30 '22 17:09

Simon