你好,这是我在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
当我不使用剪切问题时,我不会收到任何错误。我很高兴能指出我在哪里犯了错误并且想方设法修复它。
答案 0 :(得分:2)
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).