prolog中对称关系上的传递闭包

prolog中对称关系上的传递闭包,prolog,transitive-closure,Prolog,Transitive Closure,我是一名prolog初学者,我想创建“兄弟”关系 关系应该是对称的,因为如果兄弟(alin,alex)为真,兄弟(alex,alin)也应该为真 它也应该是可传递的,因为如果兄弟(alin,alex)和兄弟(alex,claudiu)都是真的,兄弟(alin,claudiu)也应该是真的 结合to属性,如果兄弟(alex,alin)和兄弟(alex,claudiu)为真,兄弟(alin,claudiu)也应为真 这是我的密码: r_brother(alin, alex). r_brother(a

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

关系应该是对称的,因为如果兄弟(alin,alex)为真,兄弟(alex,alin)也应该为真

它也应该是可传递的,因为如果兄弟(alin,alex)兄弟(alex,claudiu)都是真的,兄弟(alin,claudiu)也应该是真的

结合to属性,如果兄弟(alex,alin)兄弟(alex,claudiu)为真,兄弟(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\u brother-是基本关系

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

t_brother-这应该是传递的对称关系,我保留中间节点,所以不会得到循环

问题在于,答案是:

?- brother(X, alin).
是:

我通过追踪了解了问题所在,但不知道如何解决


alin不应该是一个可能的答案,其他的应该只出现一次。

你可以这样写兄弟关系(与及物性定义完全相同)

也就是说,如果X是一个对称的兄弟,或者他们有一个共同的兄弟,那么X就是Y的兄弟,加上他们是不同的条件


尝试将X\=Y添加到代码中,以摆脱“alin”作为解决方案。

我认为基本问题是,您没有检查t\u brother/3的第一个子句中是否已经找到L2。初始L1应添加到brother/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]).

谢谢,这要短得多:),但这里的问题是,如果你加上另一个事实,比如r_brother(claudiu,jack)。你不会得到“杰克”的回答。这必须是递归的才能工作。正如我所理解的,在“(L2=L3;t_brother(L3,L2,[L3 | IntermediateNodes])”-这是否意味着如果第一个条件(L2=L3)为真,则不需要验证第二个条件?不,这是一个简单的析取
(AlternativeA;AlternativeB)
。要么
L2
是下一个兄弟
L3
,要么我们通过递归调用t_兄弟来找到
L2
。也许你把它和
(Condition->Then;Else)
语句混淆了,这意味着局部切割?
s_brother(X, Y) :- r_brother(X, Y);r_brother(Y, X).

brother(X,Y) :- s_brother(X, Y).
brother(X,Y) :- s_brother(X, Z),s_brother(Z, Y),X\=Y.
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])).