This is my code:
% A The first link as a predicate
link(1,2).
link(2,3).
link(3,4).
link(3,6).
link(6,7).
link(6,5).
So what we did with the path predicate is check from a given starting point check if there exists a path from that point to the goal (which is defined at the top). This gives the correct outcome for all possible values.
What I need to do now is, I know there is a valid path from 1 to the goal, my path() predicate told me so, now i need to return a list of nodes that shows the that path to the goal, so with using path(L), path([2,3,6,5]) is true.
If I understand your problem statement, you
link(From,To).This is a pretty straightforward problem that doesn't require
assert/1orretract/1.A common pattern in Prolog programming is the use of helper predicates that carry extra arguments that track the persistent state required to accomplish the task at hand.
Graph traversal, as an algorithm, is pretty easy (and nicely recursive):
The trick here is that you need to track what nodes you've visited (and their order), and you'd want to do that anyway, so that you can detect cycles in the graph. Trying to traverse a cyclic graph like this::
a→b→c→bleads to infinite recursion unless you check to see whether or not you've already visited node
b.That leads pretty direction to an implementation like this:
traverse/3predicate,traverse(Origin, Destination,Path), and,traverse/4helper predicate,traverse(Origin,Destination,Visited,Path).You can fiddle with it at https://swish.swi-prolog.org/p/oZUomEcK.pl
Once you have that, invoking
traverse/3with all arguments unboundresults in finding all paths in the graph via backtracking.
If you want to know all the paths in the graph, beginning at a specific origin node, invoke it with the origin argument bound:
And if you want to know if two specific nodes are connected, invoke it with both origin and destination bound:
Note: because we're building the list of visited nodes by prepending them to the list of visited nodes, the path thus build is in reverse (destination-first) order. If you want the path in proper (origin-first) order, just use
reverse/2in the main predicate: