I am new to logic programming. I am trying to write a program which can find all nodes which can reach to an specific node.
Here is my code:
link(0, 1).
link(3, 4).
link(1, 2).
link(2, 0).
link(2, 1).
link(3, 2).
link(4, 3).
So show above by graph, it should look like below:
I want to do something like this:
?- go(X,0).
X=1;
X=2;
X=3;
X=4;
....
Which mean that from all 1,2,3 and 4 can go to 0.
[1->2->0],[2->0],[3->2->0],[4->3->2->0]...
so I try
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;
....
but i don't want 0 as one of the output, it is meaningless to show I can go to 0 when I am already in 0. Also, it keeps repeating. I try to fix this problem by:
go(X,Y) :- link(X,Y).
go(X,Y) :- (X\==Y),link(X,Z),go(Z,Y).
?- go(X,0).
X = 2 ;
false.
I'm not sure why it will stop at X=2. I try to draw the ProLog search tree and i still don't know why my code wont continue go for other facts(link(3,4)). Seem it stop at some point and no keep going for the green part below:
I try to test it using go(1,0). to go(4,0). go(1,0) and go(2,0) success But go(3,0) and go(4,0) return Error: Stack limit. I found that the recursion keep going and going between node 3 and 4. But I don't really know how to solve it.
I am so confused now, please tell me what is my mistake, or how to implement this function in a correct way? Thank you.


The problem is that your graph is a cyclic, rather than acyclic graph. That means that starting from some node
X, you [eventually] will return toX.That means that (for starters) unless you handle the cycles somehow, you will be stuck in an endless recursive loop (until you run out of stack space).
As you traverse the graph, you need to maintain some extra state (a list of nodes that you have already visited). To do this in Prolog, it is a common idiom to use a helper predicate, with the same name but additional arguments that carry the extra state.
So, try something like this: