Пролог возвращает true вместо yes

Мой код Пролога должен возвращать да (или нет) после ввода запроса, но вместо этого возвращает «true?» и требуя, чтобы я нажал клавишу ввода, чтобы получить «да».

Проблема с русскими куклами, порядок кукол от внешнего к внутреннему: катрина-> ольга-> наташа-> ирина. DirectlyIn(X,Y) имеет значение true, если X находится непосредственно внутри Y, и содержит значение true, если X содержит Y.

directlyIn('irina', 'natasha').
directlyIn('natasha', 'olga').
directlyIn('olga', 'katrina').

///

contains(X, Y) :- directlyIn(Y, X).
contains(X, Y) :- directlyIn(Z, X), contains(Z, Y).

Из запроса ?- contains(katrina, irina). я ожидал, что результат будет просто «да», но вместо этого он выводит «true ?» пока я не нажму ввод, а затем он выводит «да».


person Rhys Duncan    schedule 13.08.2019    source источник


Ответы (2)


Это связано с тем, что ваша программа откатывается. Обратите внимание, что каждый раз, когда от интерпретатора Пролога требуется доказать предикат contains/2, он может выбирать между первым или вторым правилом, поскольку оба они производят совпадение, и он отмечает этот факт, который может быть использован позже, если пользователь захочет произвести другое доказательство. Когда он достигает листа в дереве доказательств, он выводит это (путем печати true в вашем случае и ожидает вашего ввода, если он должен продолжить поиск доказательства. Если вы нажмете Enter, он начнет этот поиск и вернется, но он не может найти дальше доказательство, в результате чего на экран выводится false Вы можете заставить Пролог забыть о точках ветвления, введя разрез в дереве доказательства:

directlyIn('irina', 'natasha').
directlyIn('natasha', 'olga').
directlyIn('olga', 'katrina').

contains(X, Y) :- directlyIn(Z, X), contains(Z, Y), !.
contains(X, Y) :- directlyIn(Y, X).

Это вынуждает интерпретатор Пролога «забыть» тот факт, что у него были другие альтернативы на выбор при проверке тела первого правила.

person Paweł    schedule 13.08.2019

Если вам необходимо вывести yes или no, вы можете сгенерировать ответ следующим образом. Cut! используется для запрета ответа no всякий раз, когда выводится yes.

directlyIn(irina, natasha).
directlyIn(natasha, olga).
directlyIn(olga, katrina).

contains(X, Y, yes) :- directlyIn(Y, X).
contains(X, Y, yes) :- directlyIn(Z, X), contains(Z, Y, yes), !.
contains(_, _, no).

Запрос contains(katrina, irina, Answer). дает:

Answer = yes

Запрос contains(irina, katrina, Answer). дает:

Answer = no
person RobertBaron    schedule 13.08.2019
comment
@Rhys Duncan - это ответило на твой вопрос? - person RobertBaron; 15.08.2019