I've written code in prolog which will return a list using the depth-first search method.
s(a, b).
s(a, f).
s(b, c).
s(b, d).
s(b, e).
s(f, g).
s(f, i).
s(i, j).
s(i, k).
goal(i).
searching(Path, Paths, RestOfPaths):-
Rest = [Start|],
Start == Path,
findall( X,( arc(X, Start, ), s(X, Rest) ),[T|Extend]),
maplist( consed(Rest), [T|Extend], VisitedExtended).
How can I change my code to produce
X = [a, f, i]
.
CodePudding user response:
Assuming s/2 is defined by:
s(A, B):- arc(A, B).
s(A, B):- arc(B, A).
you can reverse the list after obtaining your path:
solve2(Node, Solution):-
depthfirst2([], Node, SolutionR),
reverse(SolutionR, Solution).
Test run:
?- solve2(a, X).
X = [a, f, i] ;
false.
You may also build the list in order by traversing the list where you will keep the solution, unifying step by step with each visited node:
solve2(Node, [Node|Solution]) :-
depthfirst2([], Solution, Node).
depthfirst2(_, [], Node) :-
goal(Node).
depthfirst2(Path, [Node1|Solution], Node) :-
s(Node, Node1),
not(member(Node1, Path)),
depthfirst2([Node|Path], Solution, Node1).
CodePudding user response:
Put the reverse/2
as part of the public (wrapper) predicate.
This is how I would do it:
arc( a , b ).
arc( a , f ).
arc( b , c ).
arc( b , d ).
arc( b , e ).
arc( f , g ).
arc( f , i ).
arc( i , j ).
arc( i , k ).
% --- traverse/3 -----------------------
%
% Traverses a directed graph
%
% traverse( Origin, Destination, Path ).
%---------------------------------------
traverse(A,Z,P) :-
traverse(A,Z,[],Vs),
reverse(Vs,P).
% --- traverse/4 --------------------------------------------
%
% private helper for traverse/3
%
% traverse( Origin, Destination, Visited, Path).
%
% Note that Path is returned in most recently visited order.
%
%------------------------------------------------------------
traverse(A,Z,Vs,[Z,A|Vs]) :- % we can get from A to Z
arc(A,Z). % - if A and Z are directly connected
traverse(A,Z,Vs,P) :- % otherwise, we can get from A to Z, if...
arc(A,B), % - A is connected to some B
\ member(B,Vs), % - that we have not yet visited
traverse(B,Z,[A|Vs],P). % - and we can get from B to Z (recording that A has been visited).
And if you run this (See the Swish at https://swish.swi-prolog.org/p/MhhEiKal.pl) by invoking:
traverse(a,i,P).
You get
P = [a,f,i]