1

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

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] 

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

+0

Есть по существу бесконечное количество списков, для которых 'пользователь ((узел (Х), Ребра), OUTL)' верно, если 'OutL' является переменной. В приглашении Prolog посмотрите, что произойдет, если вы выполните 'member (a, L) .' и нажмите'; '(см. Следующий ответ) после каждого результата. Кроме того, ваш базовый регистр 'edgeList ([], _).' Неверен. '_' не означает * ничего *, но это означает * ничего *, поскольку' _' является анонимной переменной. Как выглядит список краев для '[]'? Конечно, это не '_' (что-то). – lurker

ответ

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). 
+0

Так что я не могу использовать участника вообще в этом случае? Почему я не могу объединить элемент с базовым регистром с двумя пустыми списками? – Programmer1994

+0

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

+0

Ну, до сих пор не понимаю, «когда использовать участника, а когда просто добавить голову», выходите навстречу, но ваш ответ работал нормально, спасибо! :) – Programmer1994

Смежные вопросы