0

This is my code given below:

edge(a,b).
edge(b,d).
edge(a,c).
edge(c,e).

path(X,Y):-edge(X,Y),write(X),write(Y).
path(X,Y):-edge(X,Z),path(Z,Y),write(X),write(Z),write(Y).

Output:
?- path(a,e).
ceace
true 

But I want only print which path I want. My graph Initial state "a" and Goal State "e". But here I got ceace but I want ace or eca.

  • If you watn paths without cycles, try [`this`](https://stackoverflow.com/q/30328433/772868). Thus `?- path(edge, Path, a, e).` Your desired answer will now be given in `Path = [a,c,c,e]`. – false Aug 21 '19 at 05:37

2 Answers2

0

An Idea would be using iterative depth search by using an adjacency relation, it would look like this for your given example:

% adjacency relation
adj(X,Y) :- adj0(X,Y); adj0(Y,X).
%graph nodes
adj0(X,Y) :- member((X,Y), [(a,b), (b,d), (a,c), (c,e)]).

%goal node
goal(e).

%depthsearch which saves already visited nodes
dfs(Node, Path, ReturnPath) :-
    goal(Node), reverse(Path, ReturnPath);
    adj(Node,NewNeighbor), not(member(NewNeighbor,Path)),
    dfs(NewNeighbor, [NewNeighbor|Path], ReturnPath).

call the predicate by using:

dfs(a, [a], X)

result will be:

X = [a, c, e]

For sure you could tweak what you have wrote to make it work, but with a search alogrithm you are better to go, it has almost no complexity and is easy and efficent to use.

A.A.
  • 145
  • 13
0

Your output, ceace is printed by two different clauses.

First when your search reaches the base case, it prints ce as it found edge(c, e):

path(X,Y) :- edge(X,Y),write(X),write(Y).
% i.e. path(c, e) :- edge(c, e), write(c), write(e).

Then your program returns to the recursive clause and prints ace, which is your X, Z, and Y:

path(X,Y) :- edge(X,Z),path(Z,Y),write(X),write(Z),write(Y).
% i.e. path(a, e) :- edge(a, c), path(c, e), write(a), write(c), write(e).

Your best option is to separate your search from the printing. Here I just add an argument to your search method to build the path.

path(X, Y, [X, Y]) :- edge(X, Y).
path(X, Y, [X|T]) :- edge(X, Z), path(Z, Y, T).

write_path(X, Y) :-
     path(X, Y, Path),
     maplist(write, Path).

This means you can print out any length of path and use that path data elsewhere, such as in finding the length of a path. As other solutions note, your search method will only work with finite tree structures.

Paul Brown
  • 2,235
  • 12
  • 18
  • Thanks for your opinion but I didn't get my desired answer. Because when I run this code, I cannot find the path to my graph. I get only true. – Washim Akram Aug 22 '19 at 04:23
  • When you query `write_path/2` it will print the path and return true. If you query `path/3` with the third argument as a variable it will be unified with the path, and printed as a list at the prompt. How did you query it? – Paul Brown Aug 22 '19 at 09:25
  • Thanks for the help I got my answer. – Washim Akram Aug 22 '19 at 19:54