2009-12-10 66 views
0

我想写一个路由功能,但我似乎无法得到所需的结果。这是迄今为止的代码。 前身发现被挂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]

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

回答

2

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

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

在成员调用中,因为L是非圆的,所以实际上你要求prolog返回一个完全没有实例化列表的元素的表单项(A,A)。虽然这并没有使所有的东西,感觉有些时候做这样的事情是非常有用的,所以序言尽职尽责非接地的要求,并且将(在回溯)生成增加长度的名单(因为你没有指定长度的任何地方)在某个点有一个项目(A,A)的变量。即:

?- 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,然后将其也非接地。由于这个谓词是以递归的方式进行的,所以最终的列表永远都是非圆的。