I am a complete newbie in Prolog. I am trying to figure out a problem where I need to check if path is present between edges. I am done with acyclic graph code for cyclic my code is going to infinite loop.
path(Start, End) :- edge(Start, End).
path(Start, End) :- edge(Start, Z), path(Z, End).
I need to handle this case by defining a new predicate: new_path(Start,End,path) which should eliminate infinite loop. Please let me know how to proceed with it.
false
Nicholas Carey
You need to keep track of what nodes you've visited as you go, using a prolog list as a LIFO stack. Something along these lines:
path( A , Z , P ) :- % to find a path from A to Z
traverse( A , Z , [] , P ) , % take a walk, visiting A to see if we can get to Z, seeding the visited list with the empty string.
reverse(P,Path) % once we find a path, let's reverse it, since it's in LIFO order.
. % That's all there is to it, really.
traverse( Z , Z , V , [Z|V] ) % if current node is the destination node, we've arrived.
. % - just push the destination vertice onto the visited list and unify that with the path
traverse( A , Z , V , P ) :- % Otherwise...
edge( A , Z ) , % - if the current node is directly connected to the destination node,
traverse( Z , Z , [A|V] , P) % - go visit the destination, marking the current node as visited
. %
traverse( A, Z , V , P ) :- % Otherwise...
A \= Z,
edge( A , B ) , % - if the current node is connected to a node
B \= Z , % - that is not the destination node, and
unvisited([A|V],B) , % - we have not yet visited that node,
traverse( B , Z , [A|V] , P ) % - go visit the intermediate node, marking the current node as visited.
. % Easy!
unvisited( [] , _ ) . % We succeed if the visited list is empty.
unvisited( [A|_] , A ) :- ! , fail . % We fail deterministically if we find the node in the visited list.
unvisited( [_|L] , A ) :- unvisited(L,A) . % otherwise, we keep looking.
来源:https://stackoverflow.com/questions/27180060/prolog-graph-path-search-with-cyclic-path