前言,点与点之间的段落数



我在Prolog有一个任务要做。这似乎很容易,但我对这种语言真的是新手,我不能习惯它。

我必须写一个函数path_L(a,z,N),其中a,z是一条"路"的边,N是我要找的变量。因此,有许多边定义单向方向:edge(a,b), edge(b,c), edge(b,d), edge(e,f)等。path_L函数的目标是给出一个结果,即(a,z)之间的节数以N=result的形式表示。例如:

path_L(a,b,N). -> N=1
path_L(a,c,N). -> N=2

我已经定义了另一个函数来定义(X,Y)之间的路径是否存在:

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

假设,如@lurker所说,您的意思是用于查找路径的谓词是:

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

并且给定一些子句来说明边的存在性,如:

edge(a,b).
edge(b,c).
edge(c,d).

你得到了正确的想法,path_L应该有一个额外的参数节点之间的边的"计数"。下面是您想要的简单版本(有一些注意事项):

path_L(X,Y,1):- edge(X,Y).
path_L(X,Y,R):- edge(X,Z), path_L(Z,Y,N), R is N+1. 

请注意,第一种情况是如何简单地将第三个参数与"1"统一起来的,所以像path_L(a,b,2)("a和b之间的距离是2")这样的客观子句正确地失败了,而path_L(a,b,R)(注意R是一个变量)成功地将R与1统一起来。范式的一个简洁特点是,相同的定义对"两种方式"都有好处。

另一个例子是目标path_L(a,B,2)(注意B是一个变量),它成功地将B与c统一-因为c是与a距离为2的节点。

最后,假设给出如下图:

edge(a,b).
edge(b,c).
edge(c,d).
edge(d,x).
edge(a,x).

path_L(a,x,R)这样的目标子句应该首先在R = 1时成功,然后,如果请求(在终端上按下;),则使用R = 4。这是因为从ax两个有效路径(长度为1和4)。谓词的顺序很重要—如果您这样定义path_L:

path_L(X,Y,R):- edge(X,A), path_L(A,Y,N), R is N+1. 
path_L(X,Y,1):- edge(X,Y).

同样的查询将首先在R=4中得到,然后在R=1中得到。这是因为定义谓词的顺序与有关。事实上,Prolog选择测试哪些谓语以及如何选择子句来"解决问题"的机制是明确的;如果你学逻辑编程的话,你一定要查一下。

希望对你有帮助。

注::关于这些警告-例如,以上都不允许从节点到自身的路径长度为零。这取决于你想要什么,可能是这样,也可能是错误的。

最新更新