Swi-prolog Wyszukiwania wszystkich możliwych szkół podstawowych węzłów, które mogą przybyć na konkretny węzeł końcowy

0

Pytanie

Jestem początkujący w programowaniu logicznym. Próbuję napisać program, który może znaleźć wszystkie węzły, które mogą dotrzeć do określonego hosta.

Oto mój kod:

link(0, 1).  
link(3, 4). 
link(1, 2).  
link(2, 0). 
link(2, 1).  
link(3, 2).  
link(4, 3).

Więc pokaż wyżej na wykresie, to powinno wyglądać tak, jak pokazano poniżej:

Graph

Chcę zrobić coś takiego:

?- go(X,0).
X=1;
X=2;
X=3;
X=4;
....

Oznacza to, że ze wszystkich 1,2,3 i 4 może przejść do 0.

[1->2->0],[2->0],[3->2->0],[4->3->2->0]...

dlatego staram się

go(X,Y) :- link(X,Y).
go(X,Y) :- link(X,Z),go(Z,Y).

?- go(X,0).
X=2;
X=0;
X=0;
X=0;
X=0;
....

ale nie chcę, aby 0 był jednym z wyjściowych danych, nie ma sensu pokazywać, że mogę przejść do 0, gdy jestem już w 0. Poza tym, to ciągle się powtarza. Staram się rozwiązać ten problem za pomocą:

go(X,Y) :- link(X,Y).
go(X,Y) :- (X\==Y),link(X,Z),go(Z,Y).

?- go(X,0).
X = 2 ;
false.

Nie jestem pewien, dlaczego zatrzymuje się na X=2. Próbuję narysować drzewo wyszukiwania prologu, a ja wciąż nie wiem, dlaczego mój kod nie będzie nadal szukać innych faktów(link(3,4)). Wydaje się, że w pewnym momencie zatrzyma się i nie idź dalej do zielonej części poniżej:

Search Tree

Staram się go przetestować za pomocą go(1,0). iść(4,0). do przodu(1,0) i do przodu(2,0) sukces Ale go(3,0) i go(4,0) zwraca błąd: limit stosu. Odkryłem, że rekursja wszystko trwa i trwa między węzłami 3 i 4. Ale ja naprawdę nie wiem, jak to rozwiązać.

Teraz jestem tak zdezorientowany, proszę, powiedz mi, w czym mój błąd lub jak prawidłowo zaimplementować tę funkcję? Dziękuję.

logic-programming prolog
2021-11-23 11:09:32
1

Najlepsza odpowiedź

0

Problem w tym, że harmonogram jest cyklicznym, a nie ациклическим. Oznacza to, że od pewnego węzła Xmożna [w końcu] powrót do X.

Oznacza to, że (na początku), jeśli w jakiś sposób nie poradzi sobie z cyklami, zostaniesz zatrzymany w nieskończonym рекурсивном cyklu (dopóki nie skończy się miejsce na stosie).

W miarę postępów grafika trzeba zachować jakiś dodatkowy warunek (lista węzłów, które już odwiedziliśmy). Do tego w Prologu powszechną идиомой jest użycie pomocniczego predykatu o tej samej nazwie, ale dodatkowymi argumentami, które przekazują dodatkowe stan.

Więc spróbuj coś takiego:

% the public predicate. We seed the visited list here
% with our starting node.
%
% Not to worry if it is an unbound
% variable. It will become bound/unbound as necessary.
traverse(A,B) :- traverse(A,B,[A]).

traverse(A,B,V) :-    % We can get from A to B, if...
  link(A,B),          % - A and B are directly connected, and
  \+ member(B,V)      % - we haven't already visited B
  .                   % - easy!
traverse(A,B,V) :-    % Otherwise, we can get from A to B, if...
  link(A,X),          % - we can get to some intermediate node X,
  \+ member(X,V)      % - that we have not yet visited, and
  traverse(X,B,[X|V]) % - we can get from X to B (adding X to the visited list
  .
2021-11-24 04:50:58

W innych językach

Ta strona jest w innych językach

Русский
..................................................................................................................
Italiano
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................