Коммутативность дизъюнкции в прологе
Я только начал изучать Пролог и столкнулся с проблемой, которую не понимаю. Когда я спрашиваю:
?- fail; true.
Пролог отвечает:
true
Что-то, чего я ожидал. Но если я спрошу:
?- true; fail.
Пролог отвечает:
true ;
false.
..и я не понимаю почему. Оператор дизъюнкции должен быть коммутативным. Почему эти два ответа Пролога разные?
3 ответа
Это просто деталь взаимодействия на высшем уровне, тогда вы можете наблюдать различное поведение в зависимости от используемого интерпретатора Prolog.
SWI-Prolog во вводной документации дает некоторую информацию:
2.1.2 Выполнение запроса
После загрузки программы можно задавать запросы Пролога о программе. Приведенный ниже запрос спрашивает у Пролога, что любит еда `sam'. Система отвечает X =, если она может доказать цель для определенного X. Пользователь может ввести точку с запятой (;) или пробел6, если он хочет другое решение. Используйте клавишу возврата, если вы не хотите видеть больше ответов. Prolog завершает вывод с полной остановкой (.), Если пользователь использует клавишу возврата или Prolog знает, что больше нет ответов. Если Пролог не может найти (больше) ответов, он пишет false.
Также обратите внимание, что оператор дизологизации Пролог, (;)/2
не является коммутативной в целом. Например:
?- !; write(else).
true.
?- write(then); !.
then
true ;
true.
Правая ветвь дизъюнкции пробуется только при возврате, если неявная точка выбора не обрезается при выполнении левой ветви. Обратите внимание, что такой пункт, как:
foo :- (!; write(else)).
эквивалентно:
foo :- !.
foo :- write(else).
Таким образом, порезы и (другие) побочные эффекты приводят к (;)/2
не ведя себя как логическое разделение.
Путаница в том, как пролог отображает результаты. Когда вы делаете запрос в прологе, он попытается найти все возможные ответы. Это означает, что он начнется с первого факта или предложения, последовательно пройдется по ним и, когда сможет окончательно выполнить запрос, отобразит ответ. Если в процессе поиска последнего решения была точка выбора, пролог предлагает пользователю искать более возможные успешные решения.
В случае:
?- false ; true.
Этот запрос начинается с рассмотрения предложения false
, который терпит неудачу, а затем, так как есть дизъюнкция ;
, проверяет положение после ;
который true
, Это успешно, и пролог отображает:
true
Обратите внимание, что когда он нашел это решение, вариантов больше не было, поэтому нет никаких подсказок для дальнейших решений.
Теперь давайте посмотрим на второй пример:
?- true ; false.
Пролог смотрит на первый пункт, true
, и успешно и говорит пользователю:
true
Но в этом случае он не исчерпал все возможные решения, поскольку существует ;
это создало другой выбор. Поэтому, когда вы вводите ;
по подсказке:
true ;
Вы говорите прологу, чтобы найти больше решений. Пролог возвращается и проверяет предложение после дизъюнкции и встреч false
, Это не удается, и нет других решений. Таким образом, ваш запрос на дальнейшие решения терпит неудачу и пролог выводит false
:
true ;
false
Первый true
значит, это удалось. false
означает, что он не нашел больше решений и потерпел неудачу со второй попытки.
Поведение Пролога состоит в том, чтобы последовательно искать решения через соответствующие пункты и представлять их, пока вы их просите, пока не произойдет сбой. Когда это наконец терпит неудачу, вы получаете false
, Вывод некоторых прологов no
, Поведение выше не является проблемой коммутативности.