成员结合递归
Member in combination with recursion
我在大学学习 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 不会将结果列表的尾部与空列表统一起来,尽管我认为成员谓词的使用是正确的。这是现在在不同练习中发生过几次的事情,很高兴知道我做错了什么......
问题出在子句中:
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).
我在大学学习 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 不会将结果列表的尾部与空列表统一起来,尽管我认为成员谓词的使用是正确的。这是现在在不同练习中发生过几次的事情,很高兴知道我做错了什么......
问题出在子句中:
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).