Избегание использования вырезания в Prolog Absolute Value Predicate

StackOverflow https://stackoverflow.com/questions/4809319

  •  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 .

Не нужно использовать !

Просто напишите:

abs2(X,Y) :- Y is abs(X).
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top