我试图定义一个家族树及其节点之间的关系,它们的定义基于三个谓词: male/1
, female/1
和 parent_of/2
.
我已经定义了上升,后代,父亲,母亲,儿子,女儿,祖父,祖母,阿姨,叔叔和堂兄的概念 . 任何新的定义都不能基于“兄弟/姐妹”的概念,而只能基于以前的定义 .
这是代码:
male(daniel).
male(miguelangel).
male(mario).
male(mahmoud).
male(esteban).
male(enrique).
male(javier).
male(miguelin).
female(diana).
female(hengameh).
female(vicenta).
female(mahvash).
female(angeles).
female(mexicana).
female(eloina).
female(esmeralda).
female(cristina).
female(otilia).
parent_of(miguelangel, daniel).
parent_of(miguelangel, diana).
parent_of(hengameh, daniel).
parent_of(hengameh, diana).
parent_of(mario, miguelangel).
parent_of(mario, esteban).
parent_of(mario, eloina).
parent_of(mario, angeles).
parent_of(mario, otilia).
parent_of(vicenta, miguel).
parent_of(vicenta, esteban).
parent_of(vicenta, eloina).
parent_of(vicenta, angeles).
parent_of(vicenta, otilia).
parent_of(mahmoud, hengameh).
parent_of(mahvash, hengameh).
parent_of(enrique, javier).
parent_of(angeles, javier).
parent_of(cristina, miguelin).
parent_of(otilia, cristina).
parent_of(eloina, esmeralda).
% Rules
ancestor(X, Y) :-
parent_of(X, Y);
parent_of(X, Z),
ancestor(Z, Y).
descendant(X, Y) :-
ancestor(Y, X).
father(X, Y) :-
parent_of(X, Y),
male(X).
mother(X, Y) :-
parent_of(X, Y),
female(X).
son(X, Y) :-
parent_of(Y, X),
male(X).
daughter(X, Y) :-
parent_of(Y, X),
female(X).
grandfather(X, Y) :-
parent_of(X, Z),
parent_of(Z, Y),
male(X).
grandmother(X, Y) :-
parent_of(X, Z),
parent_of(Z, Y),
female(X).
aunt(X, Y) :-
(grandfather(Z, Y) ; grandmother(Z, Y)),
(father(Z, X) ; mother(Z, X)),
not(parent_of(X, Y)),
female(X).
uncle(X, Y) :-
(grandfather(Z, Y) ; grandmother(Z, Y)),
(father(Z, X) ; mother(Z, X)),
not(parent_of(X, Y)),
male(X).
cousin(X, Y) :-
((uncle(Z, Y), parent_of(Z, X)) ; (cousin(P, Y), descendant(X, P)));
((aunt(Z, Y), parent_of(Z, X)) ; (cousin(P, Y), descendant(X, P))).
为了清楚起见,我通过图像表示了我遇到问题的树的一部分:
当我写作
cousin(X, Y) :-
((uncle(Z, Y), parent_of(Z, X)));
((aunt(Z, Y), parent_of(Z, X))).
代替
cousin(X, Y) :-
((uncle(Z, Y), parent_of(Z, X)) ; (cousin(P, Y), descendant(X, P)));
((aunt(Z, Y), parent_of(Z, X)) ; (cousin(P, Y), descendant(X, P))).
我明白了
?- cousin(miguelin, daniel).
false.
?- cousin(cristina, daniel).
true .
这是有效的结果 . 但是当我在右边引入递归定义时,如第一个(大)代码所述,为了说Y的堂兄弟的后代也是Y的表兄弟,程序崩溃了:
?- cousin(miguelin, daniel).
ERROR: Out of local stack
我不明白为什么 . 如果我看一下图像,那么递归定义是有意义的(至少对我而言), miguelin
现在应该是 daniel
的堂兄(因为他是 daniel
的另一个堂兄的后代,这是 cristina
) . 我也测试了它"manually",我得到了正确的结果:
?- cousin(cristina, daniel), descendant(X, cristina).
X = miguelin ;
定义有什么问题?
1 回答
cousin/2
谓词的一个问题是递归在您解析descendant/2
之前发生,并且cousin/2
在此上下文中具有无限递归问题 . 作为解决这个问题的简单方法,您可以更换它们 . 此外,您有一个冗余递归子句 . 所以修改后的cousin/2
谓词将是:然后你得到: