Ваш первый вопрос был о том, почему ваша программа дает сбой. Я не уверен, какую систему Пролога вы используете, но многие системы выдают чистую "ошибку ресурса", которую можно обработать из Пролога.
Ваша фактическая проблема заключается в том, что ваша программа не завершается для запроса likes(john, X)
. Он дает вам ожидаемые ответы и только потом зацикливается.
?- likes(john,X).
X = book ;
X = mary ;
X = tom ;
ERROR: Out of local stack
Вам очень повезло, что вы так быстро обнаружили эту проблему. Представьте себе больше ответов, и не было бы так очевидно, что у вас хватит терпения просмотреть все ответы. Но для этого есть ярлык. Вместо этого спросите:
?- likes(john, X), false.
Эта false
цель никогда не бывает верной. Так что это легко предотвращает любой ответ. В лучшем случае запрос с false
в конце завершается. В настоящее время это не так. Причину этого незавершения лучше всего видно при рассмотрении следующих failure-slice (подробнее см. другие ответы):
?- likes(john,X), false.
likes(tom,jerry) :- false.
likes(mary,john) :- false.
likes(mary,mary) :- false.
likes(tom,mouse) :- false.
likes(jerry,jerry) :- false.
likes(jerry,cheese) :- false.
likes(mary,fruit) :- false.
likes(john,book) :- false.
likes(mary,book) :- false.
likes(tom,john) :- false.
likes(john,X) :-
likes(X,john), false,
X\=john.
Так что именно эта крошечная часть вашей программы отвечает за переполнение стека. Чтобы решить проблему, мы должны что-то сделать в этой крошечной части. Вот один из них: добавьте цель dif(X, john)
так, чтобы правило читалось так:
likes(john,X) :-
dif(X, john),
likes(X,john).
dif/2
доступен во многих системах Prolog, таких как: SICStus, SWI, YAP, B, IF.
person
false
schedule
14.11.2012
X = book ; false.
Я понятия не имею, почему он останавливается сразу послеbook
. - person Yukio Fukuzawa   schedule 28.04.2012