Prolog-分支警告中的单例变量

Prolog- singleton variable in branch warning

你好,这是我在 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).

当我尝试 运行 check(a,b) 时,它没有 运行。我收到消息

Singleton variable in branch: Xs

当我不使用切题时,我没有收到任何错误。如果能指出我的错误并指出修复方法,我将不胜感激。

TL;DR: Prolog 是正确的。而且您真的在认真对待这些消息。

您正在以非常规的方式使用 if-then-else。出于这个原因,弄清楚正在发生的事情并不是那么简单。当我说 listing(check) 时,我得到以下信息:

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

所以 Prolog 对您的缩进风格印象不深,相反,它只是在寻找运算符。事实上,C(这是您原来的 Xs)出现在与 else 部分无关的 if 部分中。您可能想要的是:

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

不管手头的具体问题如何,我都非常怀疑你的代码是否有意义:Xs 是一个连接节点的列表,但你真的需要这个在这种情况下?我不这么认为。

为什么不使用closure0/3来确定连通性:​​

?- closure0(arc, A, B).

顺便说一句,不清楚你考虑的是有向图还是无向图。以上仅适用于有向图,对于无向图则使用:

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

如果您也对路径感兴趣,请使用 path/4:

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