Предикат Prolog определен как логический ИЛИ из 2 целей?

#prolog

#prolog

Вопрос:

Мне интересно, как создать предикат в Prolog, который оценивается как «true», если любая из его целей доказуема.

У меня есть эта программа:

 adjacent(place1, place2).
distance(X, Y, 1) :-
    adjacent(X, Y) ; adjacent(Y, X).
  

После просмотра его в Prolog, если я наберу:

 > distance(place1, place2, 1)
  

Я получаю этот вывод:

 true;
false.
  

Мне интересно, есть ли способ создать предикат distance, который просто возвращает единственный ответ «true», если любой из смежных (X, Y) или смежных (Y, X) доказуем.

Простите меня, если что-то в этом сообщении сбивает с толку, я не очень хорошо разбираюсь в Prolog, но, надеюсь, этот вопрос понятен. Спасибо.

Ответ №1:

Вы можете использовать once/1 предикат, чтобы убедиться, что возврата нет.

Оператор дизъюнкции ; вводит возможность возврата, поэтому Prolog будет ждать, пока вы сообщите ему, чтобы изучить любые дальнейшие возможные решения.

once определяется в терминах «cut» ( ! ), который отбрасывает любые предыдущие «точки выбора», которые могли бы быть. Возможно, стоит прочитать о cut.

Ответ №2:

кстати, предикат оценивается как true. следующий ответ заключается в том, что вы запрашиваете у prolog альтернативные ответы (разные способы получения результата и т.д.), А prolog ofc говорит, что false, других способов нет.

в принципе, вам действительно не нужно беспокоиться об этом, если вы специально не хотите иметь только один ответ (интерфейс).

в этом случае вам следует использовать cut/once .

Ответ №3:

Объяснение того, почему once/1 можно проверить, верны ли какие-либо цели. Чтобы расширить ответ Ника.

Как показано ниже, once обнаруживает факт, который вычисляется как true, независимо от того, где он находится, и немедленно останавливается.

 % undesired behaviour
?- false;true;true.
true ;
true.
% desired behaviour
?- once(false;true;true).
true.
  

Давайте посмотрим на реализацию Prolog once

 once(Goal) :-
    call(Goal),
    !.
  

Вау, это было просто. Что ! делает?

Отбросьте все точки выбора, созданные с момента ввода предиката, в котором появляется разрез. Другими словами, зафиксируйте предложение, в котором появляется сокращение, и отбросьте точки выбора, которые были созданы целями слева от сокращения в текущем предложении. Согласно документации SWI-Prolog

Проще говоря ! , предотвращает возврат к успеху. Когда Prolog видит первое значение false, он выполняет обратный поиск, чтобы проверить, можно ли найти true, когда он нашел первое значение true, он удовлетворен и останавливается из-за ! .