Is there a way to change the path predicate to not only get the "best" path, but to get all the paths that lead to that node/location in order?
The given code is rather specialized to the Dijkstra algorithm and for finding shortest paths only. I don't see a simple way to modify it to give what you ask. (Initially I thought it might suffice to just remove some cuts, but I haven't had success with that. Comments welcome!)
If you want all paths between two nodes, you don't need the complexity of the Dijkstra algorithm. Here is a mostly reasonable answer defining a predicate that enumerates all paths: https://stackoverflow.com/a/27194523/4391743 ("Mostly" reasonable because the formatting isn't pretty, and because the unvisited/2
predicate would better be expressed using a generic non_member/2
predicate such as the one given here: https://stackoverflow.com/a/10322639/4391743)
There are many other Prolog path-finding questions here, but I haven't yet found one that has the best beginner-friendly answer.
Edit: Forgot to add that the predicate given above computes all paths, but does not yield them "in order". Enumerating all paths ordered by length isn't very easy. Here the best way might be to enumerate all paths and their lengths, use findall/3
to compute a single list of all these paths, and to sort that list by length.
How can I make the path predicate more "user friendly" and just insert the two locations I want to calculate, e.g. path(london, manchester)
If your predicate has too many arguments, just define another one that hides some of them:
path(Start, End) :-
path(Start, End, _Path, _Distance).
This will simply succeed or fail but not tell you anything more:
?- path(london, manchester).
true.
In Prolog it is normal to overload predicate names with different arities like this, which is why references to predicates often include the arity. In the definition above, we define path/2
in terms of path/4
.