Prolog 序言,点之间的节数

Prolog 序言,点之间的节数,prolog,Prolog,我在Prolog中有一个任务要做。这似乎很容易,但我对这类语言真的是新手,我无法习惯 我必须编写一个函数path_L(a,z,N),其中a,z-一条“路”的边,N是我要寻找的变量。因此,有许多边定义单向方向:edge(a,b),edge(b,c),edge(b,d),edge(e,f),等等。path\u L函数的目标是以N=result的形式给出一个结果,即(a,z)之间的节数。例如,如果: path_L(a,b,N). -> N=1 path_L(a,c,N). -> N=2

我在Prolog中有一个任务要做。这似乎很容易,但我对这类语言真的是新手,我无法习惯

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

path_L(a,b,N). -> N=1
path_L(a,c,N). -> N=2
我已经定义了另一个函数,用于定义(X,Y)之间是否存在路径:


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

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\u 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统一起来。同样的定义对“两种方式”都有好处,这是该范式的一个简洁特征

另一个例子是目标
路径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时成功。这是因为从
a
x
有两条有效路径(长度为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选择测试哪些谓词以及如何选择子句来“解决问题”的机制已经得到了很好的定义;如果你学的是逻辑编程,你肯定应该学

希望这有帮助


注意:关于这些注意事项-例如,上述任何一项都不允许从节点到自身的路径长度为零。根据您的需要,可能是这样,也可能是错误。

您是否已经完成了基本的Prolog教程或正在使用的Prolog教科书?你的尝试有一些基本的语法错误。实际上,我只听了一节课:)你说的错误是什么?
=
是为了统一。要定义一个谓词(prolog没有函数),你可以使用
:-
。谢谢,我已经更正了:)非常感谢,这是一个很棒的答案,我现在明白了:)顺便问一下,如果出现你提到的情况,我能做些什么很容易得到N=0吗?@PawełPoręba,
路径L(X,X,0)。
嗨,我刚刚注意到,当我添加
路径L(X,X,0)
时,它会使分数加倍。我的意思是,例如路径L(a,c)的结果是:N=2,N=2。
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).