Неожиданное поведение PatternTest в Mathematica - PullRequest
12 голосов
/ 12 декабря 2011

Я работаю над игрушечными проблемами, чтобы помочь мне усвоить идею сопоставления с образцом в 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. Однако это не так.

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

1 Ответ

14 голосов
/ 12 декабря 2011

Документация для PatternTest (он же ?) гласит:

В такой форме, как __?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}, {}}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...