Search code examples
prologtransitive-closure

Convert a list from findall predicate to a string prolog


I am struggling to identify a way to convert a list to string. This list is the output from a findall predicate.

see below my code.

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

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

allways(X, Y) :- findall(E, (route(X, Y, E), write(E), nl), _).
%allways(X, Y) :- findall(E, (route(X, Y, E), with_output_to(atom(_),maplist(write, E)), nl), _).
%allways(X, Y) :- findall(E, (route(X, Y, E), atomic_list_concat(E,'',A), nl), _),write(A).

my output

?- allways(a,e).
[b,c]
[b,c,d]
[c]
[c,d]

expected output

?- allways(a,e).
bc
bcd
c
cd

I tried different ways to convert the list to string using with_output_to predicate and atomic_list_concat predicate but nothing works.


Solution

  • When you say "string", what do you mean?

    There are many predicates for concatenating a list to an atom. In your case atomic_list_concat/2 sounds about right.

    Your problem however is in how you wrote the findall, you are capturing the wrong variable.

    ?- findall(Str, ( route(a, e, E), atomic_list_concat(E, Str) ), Strs),
       forall(member(Str, Strs), format("~w~n", [Str])).
    

    or, if you do not need the list at all, do not use findall at all.

    ?- forall(( route(a, e, E),
                atomic_list_concat(E, Str)
              ),
              format("~w~n", [Str])).