prolog中对称关系上的传递闭包
我是一名prolog初学者,我想创建“兄弟”关系 关系应该是对称的,因为如果兄弟(alin,alex)为真,兄弟(alex,alin)也应该为真 它也应该是可传递的,因为如果兄弟(alin,alex)和兄弟(alex,claudiu)都是真的,兄弟(alin,claudiu)也应该是真的 结合to属性,如果兄弟(alex,alin)和兄弟(alex,claudiu)为真,兄弟(alin,claudiu)也应为真 这是我的密码: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
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])).