В чем разница между количеством /3 и /3 в прологе?
В чем разница между количеством /3 и /3 в прологе? а как использовать цикл for с декрементом -1 вроде (для (I, 9,0, -1))?
- например:
Dec = -2, Min_bound = 0, Max_bound = 9
Результат => 9,7,5,3,1
2 ответа
В чем разница между количеством /3 и /3 в Прологе (ECLiPSe/SICStus)?
Разница заключается в "режиме", то есть используется ли аргумент Max в качестве входных данных (+) или выходных (-).
Шаблон для (-I,+Min,+Max) используется для управления количеством итераций цикла. Значение Max должно быть известно во время запуска цикла, т. Е. Оно может быть числом
?- ( for(I,1,3) do writeln(I) ). 1 2 3
или это может быть выражение с созданными переменными
?- Next=4, ( for(I,1,Next-1) do writeln(I) ). 1 2 3
Условие завершения: I >= Макс.
Количество шаблонов (-I,+From,-To) используется для подсчета количества итераций. В то время, когда вы запускаете цикл, To обычно будет неопределенной переменной, которая в конце цикла объединяется с числом итераций цикла. В такой настройке количество итераций должно контролироваться чем-то другим, например, длиной списка, как в этом примере:
?- ( foreach(X,[a,b,c]),count(I,1,N) do writeln(I-X) ). 1 - a 2 - b 3 - c N = 3 Yes (0.01s cpu)
Поскольку Пролог, конечно, позволяет вам использовать значение вместо необоснованной переменной, вы можете использовать количество шаблонов (-I, + From, + To), но вы должны знать, что условие завершения - I = To, а не I >= К
Конструкция do-loop, к которой относятся итераторы for/3 и count/3, является попыткой обеспечить компактную запись для общего случая итеративной рекурсии и сделать это способом, напоминающим нотацию процедурного цикла. Уникальные свойства логических переменных и в целом двунаправленный характер Prolog приводят к некоторым интересным особенностям, например, используя итератор foreach/2, вы можете использовать один и тот же код цикла для обхода существующего списка или для создания нового списка. В данном случае итерации по числам эта симметрия, к сожалению, не достигается, поэтому вам нужны два разных итератора.
Как использовать цикл for с декрементацией
Ничего особенного, правда:
?- ( for(I,9,0,-2) do writeln(I) ).
9
7
5
3
1
Yes (0.00s cpu)
или, для сбора результатов в списке:
?- ( for(I,9,0,-2),foreach(I,Is) do true ).
Is = [9, 7, 5, 3, 1]
Yes (0.00s cpu)
Редактировать: было отмечено, что вышеупомянутое не работает в SICStus (4.3.2), потому что итератор for/4 не поддерживается. Вы все еще можете делать такие циклы, используя универсальный итератор fromto/4, но вы должны сделать некоторую арифметику самостоятельно, например
?- ( fromto(9,I,I1,-1) do I1 is I-2, writeln(I) ).
9
7
5
3
1
Yes (0.01s cpu)
В общем случае это немного сложно, так что вы можете получить более понятный код, используя рекурсивное решение...
Во-первых, ваш вопрос о do-loop, управляющей конструкции, которая встречается в некоторых системах. Текущая реализация в SICStus имеет довольно хаотичное поведение - особенно count
:
| ?- for(I,5,1), foreach(I,List) do true.
List = [] ? ;
no
| ?- count(I,5,1), foreach(I,List) do true.
**LOOPS**
В документации не ясно об этом цикле. Но из того, что я думаю, count
всегда будет считать вверх и ожидает, что Max
ценность законна; а если нет, то он зацикливается.
В любом случае, в do-циклах слишком много таких "функций", которые все еще не исправлены на протяжении многих лет, поэтому вам может понадобиться сначала изучить Prolog без do-циклов. В частности, рассмотрим конструкции высшего порядка, такие как maplist/2..
вместо.