Пролог возвращает список дубликатов

Я получаю дублированный список, когда пытаюсь найти все/3 возможных пути на графике? Есть идеи, что не так с кодом? Схема дублирования: S:6 дублируется с S:13, S:7 с S:14, S:8 с S:15 и так далее.

 co(X,Y) :- hen(X,Y) ; hen(Y,X).

 pan(A, B, _, [A,B]) :- co(A, B).
 pan(A, B, Vix, [A | Len]) :-
     co(A, C),
     C \== B,
     \+ member(C, Vix),
     pan(C, B, [C | Vix], Len).

 long_p(A, B):-
     findall(Len, pan(A,B,[A],Len), Z),
     printT(Z,0).

 printT([],_).
 printT([H|T],V) :-
     V1 is V + 1,
     write('S: '), write(V1), nl,
     write(H), nl,
     nl,
     printT(T,V1).

Будет ли Prolog findall/3 возвращать отличный результат?


person user236501    schedule 19.10.2011    source источник


Ответы (2)


Я собираюсь угадать.

printT/2 печатает S:(length-of-path). Почему не должно быть нескольких путей из А в Б одинаковой длины?

Я предполагаю, что ваша проблема в том, что long_p/2 успешно выполняется дважды для одного и того же пути. Я не вижу причин для этого в pan/4. Если я не ошибаюсь, причина в co/2 и/или hen/2. Например, если в вашей базе данных есть hen(a,b) и hen(b,a), co(a,b) будет успешным дважды. Это можно исправить с помощью

co(X,Y) :- hen(X,Y).
co(X,Y) :- hen(Y,X), \+ hen(X,Y).
person chs    schedule 19.10.2011

findall(Len, pan(A,B,[A],Len), Z)

создаст список Z с всеми Len , так что pan(A,B,[A],Len) будет успешным. Таким образом, выполняется возврат pan(A,B,[A],Len) и все решения Len помещаются в список Z.

В вашем графе есть маршрут длиной 6 между двумя конкретными узлами A и B. Но есть еще путь из A в B через какой-то C длиной 13. findall находит эти два пути и т.д.

person Jiri Kriz    schedule 19.10.2011