Ваш первый вопрос, почему ваша программа падает. Я не уверен, какую систему Prolog вы используете, но многие системы производят чистую «ошибку ресурса», которую можно обрабатывать из Prolog.
Ваша фактическая проблема в том, что ваша программа не заканчивается для запроса 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
доступен во многих системах Пролога как: SICStus, SWI, ПЕА, B, IF.
Из любопытства, что произойдет, если X \ = john предстанет перед подобными? – pedrofurla
Странно, если вы положите это перед телом, Prolog вернется: 'X = book; false.' Я понятия не имею, почему он останавливается сразу после «книги». –