Я разрабатываю алгоритм поиска пути в Прологе, предоставляя все узлы, доступные по пути из начального узла. Чтобы избежать дублирования путей, посещенные узлы хранятся в списке.
Узлы и соседние узлы определены следующим образом:
node(a).
node(b).
node(c).
node(d).
node(e).
edge(a,b).
edge(b,c).
edge(c,d).
edge(b,d).
neighbor(X,Y) :- edge(X,Y).
neighbor(X,Y) :- edge(Y,X).
Исходный алгоритм, приведенный ниже, работает нормально:
path2(X,Y) :-
pathHelper(X,Y,[X]).
pathHelper(X,Y,L) :-
neighbor(X,Y),
\+ member(Y,L).
pathHelper(X,Y,H) :-
neighbor(X,Z),
\+ member(Z,H),
pathHelper(Z,Y,[Z|H]).
Это прекрасно работает
[debug] ?- path2(a,X).
X = b ;
X = c ;
X = d ;
X = d ;
X = c ;
false.
, однако, при изменении порядка двух предложений во втором определении, например, как показано ниже
pathHelper(X,Y,L) :-
\+ member(Y,L),
neighbor(X,Y).
При попытке выполнить то же самое здесь, swipl возвращает следующее:
[debug] ?- path2(a,X).
false.
Запрос больше не работает и возвращает только false
. Я пытался понять это с помощью команды trace
, но все еще не могу понять, что именно не так.
Другими словами, я не понимаю, почему порядок neighbor(X,Y)
и \+ member(Y,L)
имеет решающее значение здесь. Имеет смысл иметь neighbor(X,Y)
сначала с точки зрения эффективности, но не с точки зрения корректности для меня.