Избегание использования вырезания в Prolog Absolute Value Predicate
-
24-10-2019 - |
Вопрос
Я реализовал следующую функцию в Prolog со следующим кодом:
abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.
Как я могу реализовать эту функцию без использования CUT ("!")?
Решение
В конструкции If-then-else из Prolog есть «скрытая» конструкция Prolog:
abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.
Это что-то вроде причуды, но Пролог не возвращается на субгол, который образует «предпосылку» конструкции if-then или if-then-else. Здесь, если x <0 сменит первую попытку, то выбор «затем предложений« по сравнению с другим »представлен (отсюда и описание такого поведения как« скрытого »разреза).
Есть больше роли для сокращения в первый пункт предиката ABS2/2 как написано в вопросе. Как отмечает Николас, сокращение в конце второго пункта не имеет никакого эффекта (нет никаких точек выбора, когда вы попадете туда). Но, как указывает Каарель, есть точка выбора, оставленную открытой, если первое предложение удастся.
Так что я бы написал, позволяя использовать разрез, это:
abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.
Комментарии Николаса также предлагают способы «арифметизировать» абсолютное значение (а не использовать логическое определение) и избежать «разрезания» таким образом.
Другие советы
Мой пролог немного ржавый, но зачем вам вообще нужен резак? Если вы правильно напишите предикат, отступление не может добиться успеха, поэтому вырез не нужен:
abs(X, Y) :- number(X) , X < 0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .