2

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.

false
  • 10,264
  • 13
  • 101
  • 209
Dago
  • 788
  • 2
  • 9
  • 24
  • In the code you show, I don't see a singleton variable issue. And `check(a,b)` runs forever (doesn't terminate). Is the code you are showing what you actually ran? Did you try doing a `trace` to see what's happening? – lurker Jun 12 '15 at 12:11
  • Also, be wary of operator precedence. `,` has higher precedence than `;`. In your `check` code, it is equivalent to `check(X,Y) :- (related_to(X,Xs), member(Y,Xs) -> write('There is a road')) ; cut(Xs, Y).` So if `related_to(X,Xs)` fails, then it will call `cut(Xs,Y)` with `Xs` unbound. – lurker Jun 12 '15 at 12:17

1 Answers1

3

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).
Community
  • 1
  • 1
false
  • 10,264
  • 13
  • 101
  • 209