Участник в сочетании с рекурсией
Я изучаю Пролог в университете и продолжаю спотыкаться о довольно странном во время домашних упражнений. Я написал следующие предложения Пролога, которые являются частью гораздо большей программы:
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).
Вы можете видеть шоссе как факт, который описывает два узла в первых двух аргументах и ребро в третьем. Все факты вместе образуют связный граф.
В предложении edgeList я хочу перечислить ребра для каждого узла, например
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 не объединит хвост списка результатов с пустым списком, несмотря на тот факт, что предикат-член используется правильно, я полагаю. Это то, что происходило несколько раз в разных упражнениях, и было бы хорошо узнать, что я сделал не так...
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).