Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding the same answer multiple times in prolog

Tags:

prolog

So I have this undirected graph to traverse, and I should find all the verticies those are connected to a given vertex.

edge(a, b).
edge(b, c).
edge(c, d).
edge(d, e).
edge(e, f).
edge(f, d).
edge(d, g).
edge(g, f).
edge(g, h).
edge(h, i).
edge(i, j).
edge(j, d).
edge(d, k).
edge(l, m).
edge(m, n).

undirectedEdge(X, Y) :- edge(X, Y).
undirectedEdge(X, Y) :- edge(Y, X).

connected(X, Y) :- undirectedEdge(X, Y).
connected(X, Y) :- connected(X, Z), connected(Z, Y), X \= Y.

And once I type connected(a, X). it goes into an infinite loop. I understand why I have it, but I have no idea how to avoid it, maybe I can find some help here?

like image 696
Question Avatar asked Dec 22 '25 02:12

Question


2 Answers

Using closure0/3 and setof/3 we get:

connected(A,B) :-
   setof(t, closure0(undirectedEdge, A, B), _).
like image 93
false Avatar answered Dec 24 '25 10:12

false


And once I type connected(a, X). it goes into an infinite loop.

The reason this happens is because it is checking a path of the form a → b → a → b → a → b → …. So it keeps "hopping" between two nodes.

You can maintain a list of nodes that the algorithm already visisted, to prevent that like:

connected(X, Y) :-
    connected(X, Y, [X]).

connected(X, X, _).
connected(X, Z, L) :-
    undirectedEdge(X, Y),
    \+ member(Y, L),
    connected(Y, Z, [Y|L]).

You can make use of the distinct/1 predicate [swi-doc] to generate distinct answers:

?- distinct(connected(a, X)).
X = a ;
X = b ;
X = c ;
X = d ;
X = e ;
X = f ;
X = g ;
X = h ;
X = i ;
X = j ;
X = k ;
false.
like image 22
Willem Van Onsem Avatar answered Dec 24 '25 12:12

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!