更好地理解prolog

更好地理解prolog,prolog,transitive-closure,failure-slice,Prolog,Transitive Closure,Failure Slice,我试图理解Prolog以及它使用的解析算法。我发现了一个例子: hates(1, 2). hates(2, 3). hates(3, 4). jealous(A, B) :- jealous(A, C), jealous(C,B). jealous(A,B) :- hates(A,B). 但是当我试着说嫉妒(1,4)的时候,它总是满溢,永远不会给出真的,这很奇怪,好像1恨2,2恨3,3恨4,那么1也应该恨4 但是我试着把它改成这样: hates(1, 2). hates(2, 3). hate

我试图理解Prolog以及它使用的解析算法。我发现了一个例子:

hates(1, 2).
hates(2, 3).
hates(3, 4).
jealous(A, B) :- jealous(A, C), jealous(C,B).
jealous(A,B) :- hates(A,B).
但是当我试着说嫉妒(1,4)的时候,它总是满溢,永远不会给出真的,这很奇怪,好像1恨2,2恨3,3恨4,那么1也应该恨4

但是我试着把它改成这样:

hates(1, 2).
hates(2, 3).
hates(3, 4).
jealous(A,B) :- hates(A,B).
jealous(A, B) :- jealous(A, C), jealous(C,B).

然后当我说嫉妒(1,4)

时,它就会起作用。如果您使用的是SWI Prolog或XSB Prolog,您可以尝试添加以下内容:

:- table jealous/2.
它应该可以工作(我还没有尝试过这个,但这里有一个类似的例子:)

您的问题是Prolog默认的执行策略,即从左到右的深度优先。可以通过将最后一个子句更改为:

jealous(A, B) :- hates(A, C), jealous(C,B).
(Prolog教科书中有许多类似的例子)

当我说嫉妒(1,4)

不,没有。或者,嗯,有点。只需键入空格,即可看到它再次循环。那么嫉妒(4,1)哪个循环会立即循环呢

要理解这一点,只需看看程序的一小部分,即:

jealous(A,B) :- false, hates(A,B). jealous(A, B) :- jealous(A, C), false, jealous(C,B). 但是一旦你在
haves/2
中有了循环,这就不再有效了。然后,考虑:

嫉妒(A,B):- 关闭(A、B、A)。 另一种方法是使用表格。但请注意,tabling解决了这一问题,但不再适用于约束环境(您迟早会遇到约束)


1) 假设你有一个纯单调的程序