关于循环事实的Prolog无限循环

关于循环事实的Prolog无限循环,prolog,transitive-closure,failure-slice,Prolog,Transitive Closure,Failure Slice,以下是我的事实循环部分(定义人与人之间的关系): 我想知道是否存在直接的或通过其他人使用递归的连接 在上述情况下,此代码会运行到无限循环中: connected(A, B) :- connection(A, B). connected(A, B) :- connection(A, C), connected(C, B). 我希望递归在遇到以前的搜索时停止。 例如: ?- connected(hermione, X). X = harry ; X = ron. 谢谢大家!

以下是我的事实循环部分(定义人与人之间的关系):

我想知道是否存在直接的或通过其他人使用递归的连接

在上述情况下,此代码会运行到无限循环中:

connected(A, B) :-
   connection(A, B).
connected(A, B) :- 
   connection(A, C),
   connected(C, B).
我希望递归在遇到以前的搜索时停止。 例如:

?- connected(hermione, X).
X = harry ;
X = ron.

谢谢大家!

Prolog的执行机制非常不直观。它将递归(正如您从其他语言中所知道的)与回溯相结合。但是有一个很好的出路。你可以考虑较小的程序而不是原来的程序。 为了更好地理解实际的循环,这里有一个称为a的最小程序片段,它是不终止的原因。其中有一些额外的错误:一些目标
false
。有了这些目标,推论的数量就会减少(或保持不变)。因此,当结果程序循环时,这也是原始程序循环的原因

connection(harry, ron). connection(ron, harry). connection(herminone, harry) :- false. connected(A, B) :- false, connection(A, B). connected(A, B) :- connection(A, C), connected(C, B), false. ?- connected(A, B). 要解决此问题,最简单的方法是这样使用:


你可以试着把它放在桌子上。许多Prolog系统都有table/1指令。您只需将其置于要制表的谓词之前

:- table connected/2.
connected(A, B) :-
   connection(A, B).
connected(A, B) :- 
   connection(A, C),
   connected(C, B).
如果然后运行查询,递归将自动停止。以下是使用SWI Prolog表格运行的示例:

Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.4)

?- connected(hermione, X).
X = harry ;
X = ron.

你真的很喜欢你的绰号,是吗?;-)我只学到了很多。不过这很有帮助。对于SWI序言:
:-使用_模块(库(表格))。:-表已连接/2,连接/2。
已经是一个表,因此您不需要将其设置为表。
connected(A, B) :-
   closure(connection, A, B).
:- table connected/2.
connected(A, B) :-
   connection(A, B).
connected(A, B) :- 
   connection(A, C),
   connected(C, B).
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.4)

?- connected(hermione, X).
X = harry ;
X = ron.