Prolog中的简单图搜索

Prolog中的简单图搜索,prolog,Prolog,我试图用SWI Prolog编写一个简单的图形搜索代码。我想出了以下计划: adjacent(1,4). adjacent(4,2). adjacent(3,6). adjacent(6,4). adjacent(7,10). adjacent(4,9). adjacent(5,10). adjacent(7,10). adjacent(7,12). adjacent(6, 11). adjacent(13,11). adjacent(9,14). adjacent(14,12). adjace

我试图用SWI Prolog编写一个简单的图形搜索代码。我想出了以下计划:

adjacent(1,4). adjacent(4,2). adjacent(3,6).
adjacent(6,4). adjacent(7,10). adjacent(4,9).
adjacent(5,10). adjacent(7,10). adjacent(7,12).
adjacent(6, 11). adjacent(13,11). adjacent(9,14).
adjacent(14,12). adjacent(10,15). adjacent(9,12).

connected(X,Y) :- adjacent(X,Y); adjacent(Y,X).

path(A,B,[A|B]) :-
    connected(A,B).
path(A,B,[A|R]) :-
    \+member(R,A),
    connected(A,C),
    A \== C,
    path(C,B,R).

但是这个程序会导致堆栈溢出。我做错了什么?如何修复它?

这里的主要问题是成员测试:签名是
成员(元素,列表)
;你似乎认为论点是相反的

此外,您的第一个路径谓词旨在测试一个两元素列表,然而,B实际上与rest列表(它没有连接)相统一


如果您解决了这些问题,您会发现这只适用于完全实例化的变量,因为否定对未绑定的变量不起作用。

这里的主要问题是成员测试:签名是
成员(元素,列表)
;你似乎认为论点是相反的

此外,您的第一个路径谓词旨在测试一个两元素列表,然而,B实际上与rest列表(它没有连接)相统一


如果您修复了这些问题,您会发现这只适用于完全实例化的变量,因为对未绑定的变量进行否定并不有效。

您试图使用返回路径作为避免循环的检查。这在搜索路径时不起作用,因为该路径尚未在求反时实例化

最简单的解决方案是添加另一个输入参数,在其中收集已访问的节点并进行检查以避免重复

另外,我认为应该检查A\==B而不是A\==C。节点上没有循环,因此后者永远不会发生。案例A==B在第一个子句中处理,因此您不希望在第二个子句中再次处理

正如Martin所写的那样,您还得到了member的参数,需要修复第一个子句中的列表

避免无额外参数的无限循环的一种高级方法是在求反时使用freeze/2


还可以看看Prolog中调试是如何工作的,这可能会帮助您更好地理解事情。

您试图使用返回的路径作为避免循环的检查。这在搜索路径时不起作用,因为该路径尚未在求反时实例化

最简单的解决方案是添加另一个输入参数,在其中收集已访问的节点并进行检查以避免重复

另外,我认为应该检查A\==B而不是A\==C。节点上没有循环,因此后者永远不会发生。案例A==B在第一个子句中处理,因此您不希望在第二个子句中再次处理

正如Martin所写的那样,您还得到了member的参数,需要修复第一个子句中的列表

避免无额外参数的无限循环的一种高级方法是在求反时使用freeze/2


另外,看看Prolog中调试是如何工作的,这可能会帮助您更好地理解事情。

我的Prolog有点生疏,请您添加一些关于每个部分的意图的注释好吗?
path(a,B,path):-path(毗连,path,a,B)。
使用。我的Prolog有点生疏,能否请您添加一些关于每个部分意图的注释?
path(a,B,path):-path(相邻,path,a,B)。
使用。