我是Prolog的初学者,我想创建“兄弟”关系。
这个关系应该是对称的,例如如果brother(alin,alex)是正确的,brother(alex,alin)也应该是正确的。
它还应该是可传递的,例如如果brother(alin,alex)和brother(alex,claudiu)是正确的,brother(alin,claudiu)也应该是正确的。
结合这两个特性,如果brother(alex,alin)和brother(alex,claudiu)都成立,则brother(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.
我查看了追踪记录,理解了问题所在,但是不知道如何解决。
alin 不应该是一个可能的答案,其他答案应该只出现一次。
(AlternativeA;AlternativeB)
。要么L2
是下一个兄弟节点L3
,要么我们通过递归调用 t_brother 找到一个L2
。也许你把它和(Condition -> Then ; Else)
语句混淆了,后者意味着一个本地剪枝? - danielp