0

我正在尝试编写路由功能,但似乎无法获得所需的结果。这是到目前为止的代码。Predecessor 找到链接到 N 的节点并将其作为 P 返回。

traceroute(_,L) :- member((A,A),L).
traceroute(N,L) :-
   predecessor(N,P),
   append(N,L,L1),
   traceroute(P,L1).

当我运行traceroute(placeA, Y).它时,它会返回此数据.. Y = [ (_G575, _G575)|_G579] .

基本上对于 traceroute 的第一行,如果任何成员是其自身的前身,我将尝试终止递归。第二部分应该遍历所有节点并将它们添加到列表(L)中。

节点存储为 [(placeA,placeB),(placeB,placeC)],列表应存储为 [placeA,placeB,placeC]

我不明白为什么我会得到这些结果。

4

1 回答 1

2

看起来像这样的解决方案(当它不正确时)通常意味着您没有在您应该拥有的某个地方接地(即实例化)一个术语。

我不完全确定您的代码是如何工作的,但看起来您的主要问题是您为 traceroute 的第二个参数传递了一个非地面变量。

在成员调用中,由于 L 是非接地的,因此您实际上是在要求 prolog 返回一个 (A,A) 形式的项目,它是一个完全未实例化的列表的元素。虽然这没有多大意义,但有时做这种事情很有用,所以 prolog 尽职尽责地遵守并将(在回溯时)生成非地面的长度增加的列表(因为你没有在任何地方指定长度)在某个点具有项 (A,A) 的变量。IE:

?- traceroute(placeA, Y).
Y = [ (_G271, _G271)|_G275] ;
Y = [_G274, (_G271, _G271)|_G278] ;
Y = [_G274, _G277, (_G271, _G271)|_G281] ;
Y = [_G274, _G277, _G280, (_G271, _G271)|_G284] ;

您需要传递一个接地的 Y 值,或者进一步限制它在谓词中采用的值,甚至可能两者兼而有之。

此外,即使第二个子句实际上没有执行,你也会遇到类似的问题:再次是非地面的 L 被附加到 N 以产生 L1 ,它也是非地面的。由于该谓词递归地执行此操作,因此最终列表始终是非基础的。

于 2009-12-10T23:57:15.000 回答