Swi-ProLog Najít všechny možné počáteční uzly, které mohou přijít konkrétní koncový uzel

0

Otázka

Jsem nový na logické programování. Snažím se napsat program, který může najít všechny uzly, které mohou dosáhnout na konkrétní uzel.

Tady je můj kód:

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

Takže show nad tím, že graf by měl vypadat jako níže:

Graph

Chci udělat něco jako toto:

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

Což znamená, že ze všech 1,2,3 a 4, může jít na 0.

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

takže se snažím

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 nechci, 0 jako jeden z výstupů je nesmyslné, aby ukázal, že můžu jít na 0, když jsem již v 0. Také se to opakuje. Snažím se opravit tento problém tím, že:

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

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

Nejsem si jistý, proč se to zastaví v bodě X=2. Snažím se čerpat ProLog vyhledávací strom a já pořád nevím, proč je můj kód nebude nadále jít na další skutečnosti(odkaz(3,4)). Zdá se, že zastavit v určitém bodě a ne pokračovat na zelené části níže:

Search Tree

Snažím se vyzkoušet jej pomocí go(1,0). jít(4,0). (1,0) (2,0) úspěch Ale jít(3,0) a go(4,0) return Error: Stack limit. Zjistil jsem, že rekurze dál a dál mezi uzel 3 a 4. Ale já opravdu nevím, jak to vyřešit.

Jsem tak zmatený teď, prosím, řekněte mi, co je moje chyba, nebo jak implementovat tuto funkci správným způsobem? Děkuji.

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

Nejlepší odpověď

0

Problém je, že graf je cyklický, spíše než acyklický graf. To znamená, že od nějakého uzlu X[nakonec] bude návrat do X.

To znamená, že (pro začátek) pokud jste zvládnout cykly nějak, budete uvízl v nekonečné rekurzivní smyčka (dokud vám dojdou místa v zásobníku).

Jak budete procházet graf, je třeba zachovat některé další státní (seznam uzlů, které jste již navštívili). K tomu v jazyce Prolog, to je běžný idiom použít helper predikát, se stejným názvem, ale další argumenty, které nesou navíc státu.

Tak, zkusit něco jako tohle:

% 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

V jiných jazycích

Tato stránka je v jiných jazycích

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