Участник в сочетании с рекурсией

Я изучаю Пролог в университете и продолжаю спотыкаться о довольно странном во время домашних упражнений. Я написал следующие предложения Пролога, которые являются частью гораздо большей программы:

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).
Другие вопросы по тегам