1

To preface, I'm a beginner at prolog.

I'm trying to print all possible paths between two nodes in an acyclic graph in one go, and my code can find all the possible paths, just that the format of the result is wrong for my specific task.

What I got so far is:

?- always(a,e).
bce
true ;
bcde
true ;
ce
true ;
cde
true ;

But I'd like to get in the the format of:

?- always(a,e).
bce
bcde
ce
cde
true ;

Without the need of pressing ; And i need this to be done in the code rather then add something in the query. My current code is

edge(a,b).
edge(a,c).
edge(b,c).
edge(c,d).
edge(c,e).
edge(d,e).
edge(f,g).
edge(g,h).

always(X,Y) :- always(X,Y,[]).
always(X,Y,Path) :- edge(X,Y), append(Path, [Y], Path2), always_writelist(Path2).
always(X,Y,Path) :- edge(X,Next), append(Path, [Next], Path2), always(Next,Y,Path2).
always_writelist(Path) :- length(Path,0).
always_writelist([Node|Path]) :- write(Node), always_writelist(Path).

Note that I can't use any built-in predicates except is, setof, write, nl, integer and !, in order to follow my instructions.

Any tips on what I can do?

I've tried printing out the whole list but then i just get

[b,c,e][c,e][e]
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

0

I am only answering because you are using write and append for absolutely no reason. Don't do it. If you know the path is acyclic, this is enough:

path(To, To, []).
path(From, To, [X|Path]) :-
    edge(From, X),
    path(X, To, Path).

That's it. Now you need setof to get all answers:

?- setof(P, path(a, e, P), Paths).
Paths = [[b, c, d, e], [b, c, e], [c, d, e], [c, e]].

If your path might have cycles in it this will loop (do you see why?). Here is the canonical "modern" solution to this: Definition of a path/trail/walk

This is "library code" so maybe the purpose is slightly obfuscated. The message is, you need to check the visited nodes to avoid loops.

TA_intern
  • 2,222
  • 4
  • 12