Prolog- singleton variable in branch warning

1.8k views Asked by At

Hello here is my code in Prolog:

arc(a,h).
arc(b,c).

related_to(X, Ys) :-
   setof(Y, arc(X, Y), Ys).

cut([H|T],Y) :- 
    check(H,Y),

    T = [] ->   cut(T,Y).

check(X,Y) :-
    related_to(X,Xs),
    member(Y,Xs) ->  write('There is a road');
    cut(Xs,Y).

When I am trying to run check(a,b) it doesn't run. I get the message

Singleton variable in branch: Xs

When I am not using cut question, I don't get any error. I would be grateful for pointing me where I made a mistake and showing way to repair it.

1

There are 1 answers

5
false On BEST ANSWER

TL;DR: Prolog is right. And you really are doing the best taking the messages seriously.

You are using if-then-else in an unconventional manner. For this reason it is not that simple to figure out what is happening. When I say listing(check) I get the following:

check(A, B) :-
        (   related_to(A, C),
            member(B, C)
        ->  write('There is a road')
        ;   cut(C, B)
        ).

So Prolog was not very impressed by your indentation style, instead, it just looked for operators. In fact, the C (which is your original Xs) occurs in the if-part which is unrelated to the else-part. What you probably wanted is:

check(X,Y) :-
    related_to(X,Xs),
    (  member(Y,Xs)
    -> write('There is a road')
    ;  cut(Xs,Y)
    ).

Regardless of the concrete problem at hand, I very much doubt that your code makes sense: Xs is a list of connected nodes, but do you really need this in this context? I do not think so.

Why not use closure0/3 to determine connectedness:

?- closure0(arc, A, B).

BTW, it is not clear whether you consider a directed graph or an undirected one. Above works only for directed graphs, for undirected graphs rather use:

comm(P_2, A,B) :-
   (  call(P_2, A,B)
   ;  call(P_2, B,A)
   ).
?- closure0(comm(arc), A, B).

If you are interested in the path as well, use path/4:

?- path(comm(arc), Path, A, B).