Prolog 序言:a(b,c)和a(X,Y):-a(Y,X),查询a(c,b)返回无穷多true?

Prolog 序言:a(b,c)和a(X,Y):-a(Y,X),查询a(c,b)返回无穷多true?,prolog,Prolog,以下是我的知识库: a(b,c). a(X,Y):-a(Y,X). 这是我的问题:a(c,b)。 我正在使用SWI Prolog。我以为这个查询会导致程序打印“true”。但是,它会打印“true”,如果我点击分号,它会继续打印true。。。直到永远 为什么不停下来 我的想法是:首先,X与b绑定,Y与c绑定。然后,Prolog测试a(b,c)并发现这是正确的。因此,a(c,b)也是真的,SWI Prolog应该打印一次真的。然而,由于只要我不断地点击分号,它就会永远打印为真,这让我想到递归

以下是我的知识库:

a(b,c). 
a(X,Y):-a(Y,X). 
这是我的问题:
a(c,b)。

我正在使用SWI Prolog。我以为这个查询会导致程序打印“true”。但是,它会打印“true”,如果我点击分号,它会继续打印true。。。直到永远

为什么不停下来

我的想法是:首先,X与b绑定,Y与c绑定。然后,Prolog测试a(b,c)并发现这是正确的。因此,a(c,b)也是真的,SWI Prolog应该打印一次真的。然而,由于只要我不断地点击分号,它就会永远打印为真,这让我想到递归正在发生。这在哪里发生?救命啊


编辑:更具体地说,我的问题是,为什么程序在每次“true”之后都会暂停,并等待我按分号或其他键,而不是仅仅完成?如果我有两个谓词:人(苏格拉底)和凡人(X):-人(X),那么对凡人(苏格拉底)问题的回答将是一个“真”。(对不起,如果我没有在上面说清楚的话。)

Prolog首先通过第二条规则和第一条规则来证明
a(c,b)
。然后,它通过三次调用第二个规则和第一个规则来证明
a(c,b)
。然后,通过五次调用第二条规则等,Prolog的推理算法是一种没有封闭集的深度优先搜索,也就是说,它不跟踪已经证明的内容,而是愉快地再次证明

如果您不希望出现这种行为,您应该将规则改写为,例如

a_fact(b, c).
a(X, Y) :- a_fact(X, Y).
a(Y, X) :- a_fact(X, Y).

。。。或者用某种方法。不过,我认为SWI Prolog不支持列表。

…或者只使用
a(b,c):-
以获得所需的结果。@duri:当存在多个基本情况时,这将失败。等等-它首先证明a(c,b),然后再次证明a(c,b)?为什么在第一次证明A(c,b)之后它不停止?@杜里:考虑<代码> A(b,b)< /代码>。它应该会失败,但按照您的建议,它会再次循环。@NullPointer:当第一次证明
a(b,c)
时,Prolog注意到
a/2
还有一个子句可能与
a(b,c)
匹配,因此它做出了一个选择点。然后,当您请求下一个解决方案时,它进入该子句,替换
X=b,Y=c
,并进入递归调用。尝试发出
跟踪。a(b,c)。
在序言提示下(查看SWI手册了解
跟踪的工作原理)。