Prolog 谓词无终止
我有一些关于黑白顶点图的程序:Prolog 谓词无终止,prolog,failure-slice,transitive-closure,Prolog,Failure Slice,Transitive Closure,我有一些关于黑白顶点图的程序: black(root). black(v1). black(v3). black(v4). edge(root,root). edge(v1,root). edge(v2,v1). edge(v3,v1). edge(v4,v3). edge(v5,v2). edge(v5,v4). edge(v6,v5). vertex(X) :- edge(X,_). vertex(X) :- edge(_,X). white(X) :- vertex(X),
black(root).
black(v1).
black(v3).
black(v4).
edge(root,root).
edge(v1,root).
edge(v2,v1).
edge(v3,v1).
edge(v4,v3).
edge(v5,v2).
edge(v5,v4).
edge(v6,v5).
vertex(X) :- edge(X,_).
vertex(X) :- edge(_,X).
white(X) :-
vertex(X),
not(black(X)).
foo(root).
foo(X) :-
edge(X,Y),
black(Y),
foo(Y).
当我运行目标foo(X)
时,我遇到了一个问题:
如果我删除事实边(根,根)
程序会找到一些解决方案(6种不同的解决方案)。否则,我得到无限解,所有解都是X=root
。
为什么会发生这种情况?首先是一个快速的答案,它向您展示了Prolog程序员是如何看待您的程序的,下面是对它的解释。您的程序不会终止,因为以下情况不会终止: black(root).
foo(X)
确实产生了答案,实际上只有X=root
。所以,也许你只是迫不及待地等待序言的结束?通过询问查询foo(X),false
,我们摆脱了这些恼人的、让人目不转睛的答案,我们将等待得到false
作为回答
我们仍然不能确定程序的非终止属性。但是我们可以通过插入目标false
(以及(=)/2
)来缩小实际原因。在上面的故障片中,我插入了最大值。如果您刚刚开始,只需添加一个false,然后重新加载程序并重试查询。有了一些经验,您将很快能够快速识别此类零件。所以现在我们只需要理解
foo(root) :-
edge(root,root), % always true
black(root), % always true
foo(root), false.
foo(root):-
边(根,根),%始终为真
黑色(根),%始终为真
foo(root),false。
甚至更短
foo(root) :-
foo(root).
foo(root):-
foo(根)。
Prolog非常简单但高效的执行机制不会检测到这样的循环。基本上有几种解决方法:
这个答案确实需要投票表决。 foo(root) :- foo(root).