1

我在大学学习 Prolog,并在家庭练习中不断发现一些相当奇怪的东西。我编写了以下 Prolog 子句,它们是更大程序的一部分:

edges(X,Edges):-
    findall(Edge,(highway(X,Y,Edge);highway(Y,X,Edge)),Edges).

edgesList([],_).
edgesList([node(X)|InL],OutL):-
    member((node(X),Edges),OutL),
    edges(X,Edges),
    edgesList(InL,OutL).

它使用以下事实:

highway(1,2,yellow). 
highway(2,3,blue). 
highway(1,3,yellow).

您可以将高速公路视为一个事实,它在前两个参数中描述了两个节点,在第三个参数中描述了一条边。所有事实一起形成一个连通图。

使用子句 edgesList,我想列出每个节点的边,例如

Result = [(node(1),[yellow,yellow]),(node(2),[blue,yellow]),(node(3),[blue,yellow])]

但是当我写我的查询时:

edgesList([node(1),node(2),node(3)],List).

我得到以下结果:

List = [(node(1),[yellow, yellow]), (node(2),[blue, yellow]), (node(3),[blue, yellow])|_G610]

出于某种原因,我认为,尽管成员谓词使用正确,Prolog 不会将结果列表的尾部与空列表统一起来。这是现在在不同的练习中发生过几次的事情,很高兴知道我做错了什么......

4

1 回答 1

1

问题出在条款中:

edgesList([],_).

因为最终它将用未实例化的尾部(|_G610)填充列表。

一种解决方案是:

edges(X,Edges):-
    findall(Edge,(highway(X,Y,Edge);highway(Y,X,Edge)),Edges).

edgesList([],[]).
edgesList([node(X)|InL],[(node(X),Edges)|T]):-
   edges(X,Edges),
   edgesList(InL,T).
于 2016-08-06T22:23:29.927 回答