【问题标题】:Problem with simple recursion task in PrologProlog中简单递归任务的问题
【发布时间】:2019-03-12 01:41:57
【问题描述】:

我目前正在解决 prolog 中的一些问题,但我似乎无法解决一个关于递归的问题,我收到了这张表: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的值应该是:

  • natalie_mcdonald,
  • 凯蒂贝尔,
  • parvati_patil,
  • lavender_brown,
  • neville_longbottom.

但Z只与值统一

  • natalie_mcdonald.

我相信我非常接近它,但我真的不知道该规则出了什么问题。我定义了它,所以 X 逐步等于 Y 的值,但是对于 Y 之前的值,它应该落在完美的情况下并停止移动,并统一它之前的其余元素。有什么想法吗?

【问题讨论】:

    标签: recursion prolog


    【解决方案1】:

    首先:你的基本情况(你称之为“完美情况”)说“如果XY的左边,而YX的右边,那么每个Z都在他们”,而不是“他们之间没有人”(条件也是多余的)。基本情况应该说明谓词何时成立(即,当某些Z 介于XY 之间时),而不是不成立时。另请参阅此答案:https://stackoverflow.com/a/3001941/9204

    第二:在非基本情况下,你有

    isAtLeft(X, X1),
    betweenTwo(X1, Y, Z1),
    Z = X1.
    

    当 Prolog 在isAtLeft(ron_weasley, X1) 中搜索X1 时,唯一的答案是natalie_mcdonald,后来Z = X1 强制Z 也是natalie_mcdonald

    所以这部分代码相当于

    isAtLeft(X, Z),
    betweenTwo(Z, Y, Z1).
    

    或者用文字“ZXY之间如果:X不等于YX直接在Z的左边,还有一些Z1介于ZY"之间,这没有意义。

    您也应该注意关于单例变量Z1 的警告。

    【讨论】:

    • 在您的更正之后,我进行了自己的检查,将基本情况更改为:betweenTwo(X,Y,Z):-isAtLeft(X, Z),isAtLeft(Z, Y).,将非基本情况更改为:betweenTwo(X,Y,Z):- X \= Y, isAtLeft(X, Z), betweenTwo(Z, Y, Z1). 我仍然只有natalie_mcdonald.我检查了回复你发送的,我真的没有完全正确......
    • 这修复了基础基础,但在非基础情况下,我的意思不是你应该改变这个,而是你的代码已经像这样工作了,你应该明白为什么它意味着它是错误的。提示:isAtLeft(X, Z)(或isAtLeft(X, X1), Z=X1)已经意味着你不能得到除natalie_mcdonald之外的任何Z,添加条件也只会使这个答案无效。
    • 我已经编辑了答案,因为它应该比评论更容易阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    相关资源
    最近更新 更多