您的第一个问题是为什么程序崩溃。我不确定您使用的是什么类型的Prolog系统,但许多系统会产生一个干净的“资源错误”,可以从Prolog内部处理。
您实际遇到的问题是,对于查询
likes(john, X)
,您的程序没有终止。它给出了预期的答案,然后才进入循环。
?- likes(john,X).
X = book
; X = mary
; X = tom
; resource_error(local_stack). % 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).
因此,你的程序的这个小部分是导致堆栈溢出的原因。要解决问题,我们必须在这个小部分做一些修改。这里有一个方法:添加一个目标dif(X, john)
,使规则现在变成:
likes(john,X) :-
dif(X, john),
likes(X,john).
“likes(john,X)”表示“约翰喜欢X”,“dif(X, john)”表示“X不等于约翰”,“likes(X,john)”表示“X喜欢约翰”。所以整个句子的意思是“如果X不等于约翰并且X喜欢约翰,那么约翰也喜欢X”。
X = book ; false.
我不知道为什么它停在了book
后面。 - Max