检测路径的Prolog定义

时间:2013-07-03 21:09:30

标签: graph prolog transitive-closure

上下文,首先。我有以下双向图表。

Graph

在Prolog中代表:

relation(a,c).
relation(b,d).
relation(c,d).
relation(d,e).
relation(e,f).

connection(X,Y) :- relation(X,Y).
connection(X,Y) :- relation(Y,X).

所以我有节点之间的关系,然后我之前说过,两个方向上的节点之间的连接。

我希望做的是一个prolog定义path(X,Y)能够判断两个节点之间是否存在路径(如果至少存在一条路径,则为true两个节点,如果两个节点之间没有现有路径,则为false)。

因此,此模型中的目标输出应如下所示:

?- path(a,d).
true.

?- path(b,a).
true. 

?- path(f,b).
true

?  path(a,g).  % The node g doesn't exist
false.

我知道这涉及到使用访问列表,我看过这个例子but giving all the posible paths between two nodes。但是,这不是我想要的。我正在寻找是一个定义,它检测两个节点之间是否存在路径,而不是给出两个节点之间的所有可用路径

编辑:感谢@mbratch,我现在可以将建议的问题调整为解决方案:

relation(a,c).
relation(b,d).
relation(c,d).
relation(d,e).
relation(e,f).

connection(X,Y) :- relation(X,Y).
connection(X,Y) :- relation(Y,X).

path_exists(X,Y) :- path(X,Y,_), !.

path(A,B,Path) :-
       travel(A,B,[A],Q), 
       reverse(Q,Path).

travel(A,B,P,[B|P]) :- 
       connection(A,B).
travel(A,B,Visited,Path) :-
       connection(A,C),           
       C \== B,
       \+member(C,Visited),
       travel(C,B,[C|Visited],Path).  

1 个答案:

答案 0 :(得分:2)

您想要获得的内容通常被称为" transitive closure 二元关系"。

我们可以使用 这样获得connection/2的{​​{1}}:

% Q: Which `To` can be reached via `connection` starting at `From`?
?- closure(connection,From,To).

首先,让我们运行OP给出的查询:

?- closure(connection,a,d).
  true                                % OK: succeeds non-deterministically
; false.                      

?- closure(connection,b,a).
  true                                % OK: succeeds non-deterministically
; false.

?- closure(connection,f,b).
  true                                % OK: succeeds non-deterministically
; false.

?- closure(connection,a,g).
false.                                % OK: finitely fails

让我们问最常见的问题!

?- closure(connection,X,Y).
  X = a, Y = c
; X = a, Y = d
; X = a, Y = e
; X = a, Y = f
; X = a, Y = b
; X = b, Y = d
; X = b, Y = e
; X = b, Y = f
; X = b, Y = c
; X = b, Y = a
; X = c, Y = d
; X = c, Y = e
; X = c, Y = f
; X = c, Y = b
; X = d, Y = e
; X = d, Y = f
; X = e, Y = f
; X = c, Y = a
; X = d, Y = b
; X = d, Y = c
; X = d, Y = a
; X = e, Y = d
; X = e, Y = b
; X = e, Y = c
; X = e, Y = a
; X = f, Y = e
; X = f, Y = d
; X = f, Y = b
; X = f, Y = c
; X = f, Y = a
false.