我目前正在解决序言中的一些问题,但似乎无法解决关于递归的一个问题,因此向我介绍了此表:Gryffindor Table。
鉴于这些信息,我用以下内容制作了自己的知识库:
/*
This order represents how they are sit from left to right
parvati_patil is left to lavender_brown,
lavender_brown is left to neville_longbottom
and so on, until we reach parvati again at the end.
*/
seatedTogether(parvati_patil, lavender_brown).
seatedTogether(lavender_brown, neville_longbottom).
seatedTogether(neville_longbottom, alicia_spinnet).
seatedTogether(alicia_spinnet, fred_weasley).
seatedTogether(fred_weasley, george_weasley).
seatedTogether(george_weasley, lee_jordan).
seatedTogether(lee_jordan, dennis_creevey).
seatedTogether(dennis_creevey, dean_thomas).
seatedTogether(dean_thomas, ginny_weasley).
seatedTogether(ginny_weasley, angelina_johnson).
seatedTogether(angelina_johnson, seamus_finnigan).
seatedTogether(seamus_finnigan, colin_creevey).
seatedTogether(colin_creevey, harry_potter).
seatedTogether(harry_potter, hermione_granger).
seatedTogether(hermione_granger, ron_weasley).
seatedTogether(ron_weasley, natalie_mcdonald).
seatedTogether(natalie_mcdonald, katie_bell).
seatedTogether(katie_bell, parvati_patil).
% X is left to Y if they are seatedTogether(X,Y)
isAtLeft(X,Y):-seatedTogether(X,Y).
% X is right to Y if they are seatedTogether(Y,X)
isAtRight(X,Y):-seatedTogether(Y,X).
/*
This rule just tells us who X is two places away from Y,
X is two places away from Y if
X is seatedTogether(X,Z)
and that Z is seatedTogether(Z,Y).
*/
twoPlacesAway(X,Y):-seatedTogether(X, Z), seatedTogether(Z,Y).
/*
This rule just tells us whos sitting @ the table
by just unifying X with the values of seatedTogether(X,Y)
without regarding Y.
*/
atTable(X):-seatedTogether(X,_).
/*
Between two:
Its supposed to tell us whos Z is between X and Y
The perfect case (for me) would be that X and Y are sitting
together, so they have no one in the middle.
The other way around would be that
X is not equal to Y
X1 is sitting left to X,
and then we call it again with
X1, Y and Z1 as args,
after each call, we equal
Z to X1 value.
*/
betweenTwo(X,Y,Z):-isAtLeft(X,Y),isAtRight(Y,X).
betweenTwo(X,Y,Z):-
X \= Y,
isAtLeft(X, X1),
betweenTwo(X1, Y, Z1),
Z = X1.
问题出在最后一个规则定义上,如果我这样称呼它:
betweenTwo(ron_weasley, alicia_spinnet, Z).
Z的值应为:
但是Z仅与
的值统一我相信我已经非常接近它了,但是我真的迷失了那个规则出了什么问题。我将其定义为使X逐步等于Y的值,但在Y之前的值应处于理想情况并停止移动,并统一之前的其余元素。有什么想法吗?
答案 0 :(得分:0)
首先:您的基本案例(您称之为“完美案例”)说:“如果X
位于Y
的左侧,而Y
位于X
的右侧,则每个Z
都在它们之间”,而不是“在它们之间没有人”(条件也是多余的)。基本情况应说明谓词成立的时间(即,某些Z
在X
和Y
之间),而不是当谓词不成立时。另请参见以下答案:https://stackoverflow.com/a/3001941/9204
第二:在非基础情况下,您有
isAtLeft(X, X1),
betweenTwo(X1, Y, Z1),
Z = X1.
当Prolog在X1
中搜索isAtLeft(ron_weasley, X1)
时,唯一的答案是natalie_mcdonald
,随后的Z = X1
也迫使Z
也成为natalie_mcdonald
所以这部分代码等同于
isAtLeft(X, Z),
betweenTwo(Z, Y, Z1).
或用词“ Z
在X
和Y
之间,如果:X
不等于Y
,X
直接等于Z
的左侧,并且某些Z1
在Z
和Y
“之间,这是没有道理的。
您还应该注意有关单例变量Z1
的警告。