【发布时间】:2016-08-06 21:57:33
【问题描述】:
我在大学学习 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).
您可以将高速公路视为一个事实,它在前两个参数中描述了两个节点,在第三个参数中描述了一条边。所有事实共同构成一个连通图。
使用边列表,我想列出每个节点的边,例如
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 不会将结果列表的尾部与空列表统一起来,尽管我认为成员谓词使用正确。这种事情现在在不同的练习中发生了几次,很高兴知道我做错了什么......
【问题讨论】:
-
如果
OutL是一个变量,则基本上有无限数量的列表member((node(X),Edges),OutL)为真。在 Prolog 提示符下,看看如果您执行member(a, L).并在每个结果后按;(请参阅下一个答案)会发生什么。此外,您的基本情况edgesList([],_).不正确。_并不意味着 nothing,而是意味着 anything,因为_是一个匿名变量。[]的边缘列表是什么样的?当然不是_(任何东西)。
标签: prolog computer-science unification declarative-programming