Przechodniość w zadaniach z Prolog'a

0

Cześć,
otrzymałem ostatnio takie zadanie: Napisz predykat, który sprawdza czy dana osoba jest w stanie skontaktować się z drugą, nie znając bezpośrednio jej numeru.

Tutaj jest mój kod:

szukaj(Kto,DoKogo,Trasa) :- telefon(_,DoKogo), go(Kto,DoKogo,[],Trasa).

go(X,X,T,R):- reverse(T,R).
go(X,Y,T,R):- telefon(X,Z),\+member(Z,T), go(Z,Y,[Z|T],R).
go(X,Y,T,R):- telefon(Z,X), \+member(Z,T), go(Z,Y,[Z|T],R).



telefon(adam,ania).
telefon(ania,karol).
telefon(karol,basia).
telefon(basia,adam).
telefon(karol,dominik).

chciałbym, aby poza sprawdzeniem czy dane połączenie istnieje program także wypisał trasę, która pozwala na dotarcie do danej osoby.
Jednak zapytanie:

?- szukaj(adam,dominik,Trasa).

Nie dość, że w wyniku pomija pierwszą osobę, to jeszcze niektóre trasy wypisuje niepoprawnie tzn, osoba początkowa zostaje wypisana na drugim miejscu trasy.
Poniżej kod wyniku zapytania dla jasności:

?- szukaj(adam,dominik,Trasa).
Trasa = [ania, karol, dominik] ;
Trasa = [ania, adam, basia, karol, dominik] ;
Trasa = [basia, adam, ania, karol, dominik] ;
Trasa = [basia, karol, dominik] ;
false.

Proszę o pomoc, gdzie robię błędy i jak mogę rozwiązać mój problem

1

Moje podejście wzorując się na podejściu stąd:

phone(adam, ania).
phone(ania, karol).
phone(karol, basia).
phone(basia, adam).
phone(karol, dominik).

know(X, Y) :- phone(X, Y); phone(Y, X).

lookup(X, Y, Route) :- lookup(X, Y, [X], Route).

lookup(X, X, Visited, Route) :- reverse(Visited, Route).
lookup(From, To, Visited, Route) :-
    know(From, Through),
    \+member(Through, Visited),
    lookup(Through, To, [Through | Visited], Route).

Z istotnych rzeczy, zamiast kopiować predykat stworzyłemnowy know/2 który zwraca czy dane dwie osoby się znają. Błąd był głównie w tym miejscu, bo ze względu na to jak ty to zapisałeś, to Prolog testował najpierw ścieżkę z X do Y a potem (używając drugiego predykatu), Y do X. Z racji, że żaden nie występował w danym momencie na liście, to oba były akcepowane jako rozwiązania jeśli był podany jakiś cykl, w tym przypadku:

  • wybieramy tylko 1 rozwiązanie z dostępnych
  • dopisujemy punkt początkowy jako odwiedzony już na samym początku, przez co cykle zaczynające się w punkcie początkowym nie wpłyną na rozwiązania.
0

O super, teraz rozumiem gdzie był błąd. Dziękuję bardzo za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1