Подтвердить что ты не робот

Неожиданное поведение PatternTest в Mathematica

Я работаю над игрушечными проблемами, чтобы помочь мне усвоить идею сопоставления шаблонов в Mathematica. Следующий код не ведет себя так, как я ожидал, и я не мог понять, что не так с моим пониманием PatternTest.

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

Я ожидал, что этот фрагмент кода проверяет, можно ли записать список {2,1,2,5} в виде двух последовательных (непустых) последовательностей, так что целое число, которое мы получаем из первой последовательности, больше 3. Так как {Sequence[2,1],Sequence[2,5]} является одним чтобы переписать список таким образом, что FromDigits[{2,1}] > 3 выполняется, я ожидал, что код вернет значение True. Однако это не так.

Что не так с моей интерпретацией кода?

4b9b3361

Ответ 1

Документация для PatternTest (aka ?) говорит

В форме, такой как __?test, каждый элемент в последовательности, согласованной с __должен давать True при применении теста.

Таким образом, ваш код не будет работать так, как вы надеялись.

Хорошим способом увидеть, как работает шаблон, является использование ReplaceList. Что-то близко к вашему коду

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

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

Однако, если вы используете Условие (/;) вместо теста шаблона, вы можете получить поведение, которое вы искали

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}, {}}}