编写一个适用于循环图的谓词,使用prolog检查两个节点之间是否存在路径

编写一个适用于循环图的谓词,使用prolog检查两个节点之间是否存在路径,prolog,predicate,cyclic-graph,Prolog,Predicate,Cyclic Graph,我试图编写一个谓词isway(a,B),它应该适用于循环图。我试图得到的预期结果是,两个节点之间是否存在路径。示例:如果我问isway(a,f),期望它回答yes或no。下面是我的代码,但它从不工作,总是给我false作为输出 %given facts edge(a,b). edge(a,c). edge(b,c). edge(c,d). edge(c,e). edge(d,e). edge(f,g). edge(g,h). edge2(d,a). edge2(h,f). edge2(X,Y

我试图编写一个谓词isway(a,B),它应该适用于循环图。我试图得到的预期结果是,两个节点之间是否存在路径。示例:如果我问isway(a,f),期望它回答yes或no。下面是我的代码,但它从不工作,总是给我false作为输出

%given facts

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

edge2(d,a).
edge2(h,f).
edge2(X,Y) :- edge(X,Y).

%my implementation
isway(A,B) :- edge2(A,B,[]).

edge2(A,B,V) :- edge(A,X), not(member(X,V)), (B = X ; edge2(X,B,[A|V])).

%my output
?- isway(b,a). %I expect true for this one
false

?- isway(a,f). %False for this is ok but I am not confident about my logic
false.


可用于计算边关系的传递闭包:

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

edge(d,a). % acyclic
edge(h,f). % acyclic

:- table path/2.
path(X, Y) :- edge(X, Y).
path(X, Y) :- path(X, Z), path(Z, Y).
然后,查询将按预期工作:

?- path(a, f).
false.

?- path(b, a).
true.

如果edge/2是无向的,那么您需要一个类似于
edge(From,To):-edge(To,From)的谓词。
但是这会打开一个新的蠕虫,您必须解决它。是的。我补充说,但它似乎给了我类似的结果。变化不大。
isway(A,B):-closure(edge,A,B)。
请参阅。