Я знаю, что в Прологе технически нет «возврата», но я не знал, как иначе сформулировать вопрос.
Я нашел пример кода алгоритма поиска маршрутов между станциями метро. Он работает хорошо, однако предполагается, что он просто печатает результат, поэтому его трудно расширить или, например, выполнить findall/3
.
% direct routes
findRoute(X,Y,Lines,Output) :-
line(Line,Stations),
\+ member(Line,Lines),
member(X,Stations),
member(Y,Stations),
append(Output,[[X,Line,Y]],NewOutput),
print(NewOutput).
% needs intermediate stop
findRoute(X,Y,Lines,Output) :-
line(Line,Stations),
\+ member(Line,Lines),
member(X,Stations),
member(Intermediate,Stations),
X\=Intermediate,Intermediate\=Y,
append(Output,[[X,Line,Intermediate]],NewOutput),
findRoute(Intermediate,Y,[Line|Lines],NewOutput).
line
— это предикат с атомом и списком станций.
Например: line(s1, [first_stop, second_stop, third_stop])
Итак, что я пытаюсь сделать, так это избавиться от этого print
в строке 11 и добавить дополнительную переменную в мое правило, чтобы сохранить результат для последующего использования. Однако я с треском провалился, потому что независимо от того, что я пытаюсь, он либо входит в бесконечный цикл, либо возвращает false.
Сейчас:
?- findRoute(first_stop, third_stop, [], []).
% prints [[first_stop,s1,third_stop]]
Хочу:
?- findRoute(first_stop, third_stop, [], R).
% [[first_stop,s1,third_stop]] is stored in R
findRoute/4
и избавиться отprint(NewOutput)
. Очевидно, выберите имя для нового аргумента, которое еще не используется в предикате. - person lurker   schedule 25.03.2016