这是我的知识库:
a(b,c).
a(X,Y):-a(Y,X).
以下是我的问题:a(c,b).
我正在使用SWI-Prolog。我认为这个查询会导致程序打印“true”。但是,相反它打印“true”并继续打印true如果我按分号...直到FOREVER。
为什么不停止?
我的想法:首先,X绑定到b,Y绑定到c。然后,Prolog测试a(b,c)并发现这是真的。因此,a(c,b)也是正确的,并且SWI-Prolog应该打印一次真实。但是,因为只要我一直打到分号,它就永远打印出来,这让我觉得递归的东西正在发生。这发生在哪里?救命!
编辑:更具体地说,我的问题是为什么程序在每个“真实”之后暂停并等待我按分号或其他键而不是仅仅完成?如果我有两个谓词人(苏格拉底)和凡人(X): - 人(X),对查询凡人(苏格拉底)的回应将是单一的“真实”。 (对不起,如果我上面没有说清楚。)
答案 0 :(得分:2)
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).
...或者使用某种tabling execution。不过,我认为SWI-Prolog不支持制表。