Infinite recursion in SWI-Prolog
我试图根据三个谓词来定义一个族树及其节点之间的关系:
我已经定义了祖先、后代、父亲、母亲、儿子、女儿、祖父、祖母、姑姑、叔叔和堂兄的概念。任何新的定义都不能基于"兄弟姐妹"的概念,而只能基于以前的概念。
这是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 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))). |
为了清晰起见,我通过图像表示了我遇到问题的那部分树:
。
当我写作时
1 2 3 | cousin(X, Y) :- ((uncle(Z, Y), parent_of(Z, X))); ((aunt(Z, Y), parent_of(Z, X))). |
号
而不是
1 2 3 | 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))). |
我得到
1 2 3 4 5 |
。
这是有效的结果。但是,当我介绍右边的递归定义时,如第一个(大)代码中所述,如果说y的表亲后代也是y的表亲,那么程序就会崩溃:
1 2 | ?- cousin(miguelin, daniel). ERROR: Out of local stack |
我不明白为什么。如果我看图像,那么递归定义(至少对我来说)是有意义的,并且
1 2 | ?- cousin(cristina, daniel), descendant(X, cristina). X = miguelin ; |
。
这个定义有什么问题?
1 2 3 4 | cousin(X, Y) :- (uncle(Z,Y), parent_of(Z,X)) ; (aunt(W,Y), parent_of(W,X)) ; (descendant(X,P), cousin(P,Y)). |
然后你会得到:
号