Вопросительный знак в SWI-Prolog - недетерминированный функтор

Я только что попытался реализовать абсолютную функцию в Прологе, и у меня странное поведение. Мой код был:

absval(X, RESULT) :- X >= 0, RESULT is X.
absval(X, RESULT) :- X < 0, RESULT is -X.

И когда я пробую в SWI-Prolog absval(-2,X). получаю

X = 2

yes

как и ожидалось. Но в противном случае, когда я вызываю absval(2,X), я получаю X = 2 ?, и мне нужно вставить другой ввод. После нажатия Enter у меня тоже yes.

Что значит второй результат? Что не так с моим решением?


person pt12lol    schedule 17.05.2014    source источник
comment
Поведение, с которым вы сталкиваетесь, можно объяснить тем фактом, что ваша программа не является детерминированной. Для absval/2 есть два правила. Итак, после того, как Prolog удовлетворяет absval(2,X), используя первое правило, он возвращается назад, чтобы повторно достичь цели. Первая подзадача (X < 0) второго правила не удастся, и вы не получите второго решения. Для детерминированного поведения добавьте оператор вырезания после X>=0, например: absval(X, RESULT) :- X >= 0, !, RESULT is X..   -  person Tudor Berariu    schedule 17.05.2014


Ответы (2)


то, о чем вы сообщаете, не соответствует поведению, которое я получаю здесь:

?- absval(2,X).
X = 2 ;
false.

это на самом деле то, что ожидается.

Если вам нужно сделать его детерминированным, используйте cut или, лучше, конструкцию if / then / else:

absval(X, RESULT) :- X >= 0 -> RESULT is X ; RESULT is -X.
person CapelliC    schedule 17.05.2014
comment
Хорошо, я вижу. и дополнительный вопрос: есть ли способ выразить это без использования if / then / else или сокращений? - person pt12lol; 17.05.2014
comment
AFAIK, нет. Ваш код уже правильный, недетерминизм неизбежен без сокращения ... - person CapelliC; 17.05.2014
comment
Нет нет нет! Вы должны видеть знаки! :-) - person Paulo Moura; 17.05.2014

Детерминированная версия с одним предложением без сокращений конструкций if-then-else:

absolute_value(Value, AbsoluteValue) :-
    AbsoluteValue is sign(Value) * Value.

Обратите внимание, что sign/1 - это стандартная встроенная арифметическая функция.

person Paulo Moura    schedule 17.05.2014
comment
abs тоже. Я пытаюсь выразить конструкцию if / else на процедурном языке, используя несколько функторов. - person pt12lol; 17.05.2014