我的数据库中有以下事实和规则。
above(b, a).
above(c, b).
above(d, c).
above(X,Y):-above(X,Z),above(Z,Y).
below(X,Y):- above(Y,X).
这可以满足实际情况,因此如果我查询
above(c,a).
返回值为True。但是,当我尝试以下期望为False的查询时,
above(a,c).
我收到了消息,
Stack sizes: local: 0.2Gb, global: 16Kb, trail: 3Kb
Stack depth: 2,839,964, last-call: 0%, Choice points: 12
Probable infinite recursion (cycle):
[2,839,964] above(a, _1394)
[2,839,963] above(a, _1420)
我的理解是,由于没有与above(a,X).
关联的原子X,并且实际上此查询返回了False,所以我的规则的第一个条件将不满足,并且足以断定该查询为False 。事实并非如此。我该如何设置规则,以使其在仍按预期情况工作时仍返回False?
答案 0 :(得分:1)
由于above(a, X)
与前三个子句(事实)不匹配,因此输入了第四个子句above(X, Y) :- ...
。之后要做的第一件事是above(X, Z)
,即above(a, Z)
。然后,它尝试失败的前三个子句,然后再次进入above(X, Y)
。这是无限递归的来源。
解决方案是通过重命名其中之一来将您的规则与事实分开,例如:
is_above(b, a).
is_above(c, b).
is_above(d, c).
above(X,Y):- is_above(X,Z), above(Z,Y).
below(X,Y):- above(Y,X).
这样,您就没有无限的递归了,above
在递归之前必须取得一定的进步。