prolog - 序言中对称关系的传递闭包

标签 prolog transitive-closure

我是 prolog 初学者,我想创建“兄弟”关系。

关系应该是对称的,就像 兄弟(阿林,亚历克斯)是真的,兄弟(亚历克斯,阿林)也应该如此。

它也应该是可传递的,就像 兄弟(阿林,亚历克斯)兄弟(亚历克斯,克劳迪乌)是真的,兄弟(alin, claudiu) 也应该如此。

组合 to 属性,如果 兄弟(亚历克斯,阿林)兄弟(亚历克斯,克劳迪乌)是真的,兄弟(alin, claudiu) 也应该是真的。

这是我的代码:

r_brother(alin, alex).
r_brother(alin, ciprian).
r_brother(alex, claudiu).

s_brother(X, Y) :- r_brother(X, Y).
s_brother(X, Y) :- r_brother(Y, X).

brother(L1, L2) :-
    t_brother(L1, L2, []).

t_brother(L1, L2, _) :-
    s_brother(L1, L2).

t_brother(L1, L2, IntermediateNodes) :-
    s_brother(L1, L3),
    \+ member(L3, IntermediateNodes),
    t_brother(L3, L2, [L3 | IntermediateNodes]).

r_brother - 是基本关系

s_brother - 是对称兄弟关系( 这很有效 )

t_brother - 这应该是传递和对称关系,我保留中间节点所以我没有得到一个循环

问题是以下问题的答案:
?- brother(X, alin).

是:
X = alex ;
X = ciprian ;
X = alin ;
X = alin ;
X = alin ;
X = alin ;
X = alex ;
X = alex ;
X = alex ;
X = alex ;
X = ciprian ;
X = ciprian ;
X = claudiu ;
X = claudiu ;
false.

我查看了跟踪,我知道问题是什么,但我不知道如何解决它。

阿林不应该是一个可能的答案,其他人应该出现一次。

最佳答案

我认为基本问题是您没有检查是否已在 t_brother/3 的第一个子句中找到 L2。并且应该将初始 L1 添加到兄弟/2 中的列表中:

brother(L1, L2) :-
  t_brother(L1, L2, [L1]).                   % <-- [L1] instead of []

t_brother(L1, L2, IntermediateNodes) :-
  s_brother(L1, L2),
  \+ member(L2, IntermediateNodes).          % <-- added this check

t_brother(L1, L2, IntermediateNodes) :-      % <-- this clause is unchanged
  s_brother(L1, L3),
  \+ member(L3, IntermediateNodes),
  t_brother(L3, L2, [L3 | IntermediateNodes]).

您仍然可以通过使用析取来缩短解决方案:
t_brother(L1, L2, IntermediateNodes) :-
  s_brother(L1, L3),
  \+ member(L3, IntermediateNodes),
  ( L2=L3
  ; t_brother(L3, L2, [L3 | IntermediateNodes])).

关于prolog - 序言中对称关系的传递闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23539327/

相关文章:

minizinc - MiniZinc : Y/N? 中关系的预计算传递闭包

list - prolog 中列表的所有元素的所有子集

list - SWI-Prolog : Sum-List

prolog - 在 Warren 的抽象机中,参数变量是在哪里创建的?

algorithm - 计算邻接表中每个顶点的可达性

prolog - 确定图形是否在序言中连接

awk - 计算传递闭包

debugging - gprolog : Getting a stacktrace after an exception

prolog - 自动定理证明