考虑以下逻辑程序:
p(b) :- p(b).
p(X) :- r(b).
p(a) :- p(a).
r(Y).
对目标 p(t) 的评估在哪些术语 t 中终止,哪些不终止?
考虑以下逻辑程序:
p(b) :- p(b).
p(X) :- r(b).
p(a) :- p(a).
r(Y).
对目标 p(t) 的评估在哪些术语 t 中终止,哪些不终止?
您想要的是确定所有不会终止的查询。我假设你的意思是普遍终止。也就是说,我们不仅查看第一个答案,而且查看所有答案。
如果您的程序是纯粹的、单调的,那么对此有一个非常快速的答案:只需采用最一般的查询即可。也就是说,如果任何术语有可能T
不p(T)
终止,那么p(X)
也将是不终止的。
如果我们想知道更多,我们必须仔细观察。使用故障切片,我们可以缩小未终止的实际原因。通过将目标插入false
到您的程序中,我们正在减少可能用于查询的推理数量。但是如果剩下的程序仍然允许无限多的推理,我们就找到了一个循环。在这种情况下:
p(b) :-错误,p(b)。p(X) :-假,r(b)。 p(a) :- p(a),假。r(Y) :-假的。
是一个最小故障片。也就是说,p(a)
不会终止。但是请注意,简单地查询p(a)
(在您的原始程序中)会成功,您需要坚持查看进一步的答案:
?- p(a)。 真的 ; % 有一个答案 ** LOOP ** % 循环“回溯”
为了节省您寻求进一步答案的劳力,只需使用p(a), false
。
还有另一个最小的故障片:
p(b) :- p(b),假。p(X) :-假,r(b)。p(a) :- false, p(a)。r(Y) :-假的。
有关更多示例,请参见故障切片。