Предотвращение использования сокращения в предикате абсолютных значений Пролога - PullRequest
6 голосов
/ 26 января 2011

Я реализовал следующую функцию в прологе со следующим кодом:

abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.

Как я могу реализовать эту функцию без использования cut ("!")?

Ответы [ 3 ]

9 голосов
/ 27 января 2011

В конструкции Пролога if-then-else есть «скрытый» разрез:

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.

Это что-то странное, но Пролог не отступает от подцели, которая формирует "предпосылку" конструкции if-then или if-then-else. Здесь, если X <0 завершается успешно с первой попытки, тогда выбирается предложение «then» над предложением «else» (отсюда и описание этого поведения как «скрытого» сокращения). </p>

В предложении first предиката abs2 / 2 , как написано в вопросе, больше важна роль сокращения. Как указывает Николас, разрез в конце второго предложения не имеет никакого эффекта (у вас не останется точек выбора, когда вы туда попадете). Но, как указывает Каарел, в первом случае остается открытым пункт выбора.

Итак, что бы я написал, разрешив использование разреза, это:

abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.

Комментарии Николая также предлагают способы «арифметизировать» абсолютное значение (а не использовать логическое определение) и избегать «разрезания» таким образом.

6 голосов
/ 26 января 2011

Мой пролог немного ржавый, но зачем вам нужен разрез?Если вы правильно написали предикат, возврат не может быть успешным, поэтому сокращение не требуется:

abs(X, Y) :- number(X) , X <  0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .
3 голосов
/ 26 мая 2015

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

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

abs2(X,Y) :- Y is abs(X).
...