Recursion Prolog超出本地堆栈空间/无限递归

Recursion Prolog超出本地堆栈空间/无限递归,recursion,prolog,infinite-loop,transitive-closure,failure-slice,Recursion,Prolog,Infinite Loop,Transitive Closure,Failure Slice,我在这个网站上读过其他类似的问题和答案,但似乎找不到我特定问题的答案。我试图用Prolog对迷宫进行编码。 从区域0可以自由移动到区域1或区域3。从区域3,您可以自由移动到区域0、区域4或区域5等。我想找到从开始到结束(从0到14)长度为7的所有路径。我在SWI Prolog中以以下方式对问题进行了编码: region(0). region(1). region(2). region(3). region(4). region(5). re

我在这个网站上读过其他类似的问题和答案,但似乎找不到我特定问题的答案。我试图用Prolog对迷宫进行编码。 从区域0可以自由移动到区域1或区域3。从区域3,您可以自由移动到区域0、区域4或区域5等。我想找到从开始到结束(从0到14)长度为7的所有路径。我在SWI Prolog中以以下方式对问题进行了编码:

    region(0).
    region(1).
    region(2).
    region(3).
    region(4).
    region(5).
    region(6).
    region(7).
    region(8).
    region(9).
    region(10).
    region(11).
    region(12).
    region(13).
    region(14).
    region(15).

    connection(0,1).                %connection exists between these two regions
    connection(0,3).        
    connection(1,2).
    connection(1,8).
    connection(1,7).
    connection(3,4).
    connection(3,5).
    connection(7,9).
    connection(7,5).
    connection(7,8).
    connection(5,6).
    connection(8,10).
    connection(8,11).
    connection(11,12).
    connection(11,13).
    connection(13,15).
    connection(13,14).

    double_link(X,Y) :-
       region(X),
       region(Y),
       ( connection(X,Y) | connection(Y,X) ). %can go from region X to region Y, and vice versa

    path(X,Y) :-
       double_link(X,Y).
    path(X,Y) :-
       double_link(X,Z),
       path(Z,Y).

当我执行路径(14,0)时。我得到
true
。但是,当我执行路径(0,14)时,我耗尽了本地堆栈空间。我不知道怎么会这样。谢谢你的帮助

问题的出现是因为你可以在迷宫中转圈。例如,在你的迷宫中,你有连接
0-1-7-5-3-0
。您尚未采取任何措施确保搜索不会盲目跟随这些圈子

通常的方法是向包含已访问区域(最初为空)的路径谓词添加参数。然后,你必须确保当你去一个新的地点时,
X
不在该列表中(例如,
非成员(X,已访问)
)。

你说:

当我执行路径(14,0)时。我得到
true

这是事实的一半!哦,比那还要少!事实上,你得到的不是一次而是很多次

?- path(14,0).
true ;
true ;
true ;
true ;
true ;
true ...
有一种简单的方法可以避免打字;或者说一直都是空间。只需使用目标
false

?- path(14,0), false **LOOPS**
所以在剩下的部分中,循环必须被解决。现在它应该是不言自明的了,不是吗?

你有没有试着做一个
跟踪
,看看它在哪里循环?我没有,但我刚刚意识到,它可能在试图回溯到死胡同时循环? region(0) :- false. % ... region(12) :- false. region(13). region(14). region(15) :- false. connection(0,1) :- false. % ... connection(13,15) :- false. connection(13,14). double_link(X,Y) :- region(X), region(Y), ( connection(X,Y) ; connection(Y,X) ). path(X,Y) :- false, double_link(X,Y). path(X,Y) :- double_link(X,Z), path(Z,Y), false.