不带列表的Prolog关系跟踪

不带列表的Prolog关系跟踪,prolog,relationship,backtracking,predicates,Prolog,Relationship,Backtracking,Predicates,我试图让谓词从一个事实关联到另一个事实,并一直运行到指定的停止点 比如说,, 假设我正在做一个物流记录,我想知道谁从谁那里得到了一个包裹,他们从哪里得到的,直到最后 序言代码 mailRoom(m). gotFrom(annie,brock). gotFrom(brock,cara). gotFrom(cara,daniel). gotFrom(daniel,m). gotFrom(X,Y) :- gotFrom(Y,_). 所以我试图用谓

我试图让谓词从一个事实关联到另一个事实,并一直运行到指定的停止点

比如说,, 假设我正在做一个物流记录,我想知道谁从谁那里得到了一个包裹,他们从哪里得到的,直到最后

序言代码

    mailRoom(m).

    gotFrom(annie,brock).
    gotFrom(brock,cara).
    gotFrom(cara,daniel).
    gotFrom(daniel,m).


    gotFrom(X,Y) :- gotFrom(Y,_).
所以我试图用谓词gotFrom做的是,它递归地从你开始的任何一个点(例如:gotFrom(brock,Who))沿着列表往下走,直到m指定的结尾,也就是邮件室

不幸的是,当我运行这个谓词时,它会读出

    Who = annie.
    Who = brock.
    Who = cara.
    etc.etc....
我试着一步一步地走过这整件事,但我不确定它从布洛克到安妮,到卡拉,一直走到哪里,直到它在真理中无限循环。我有一种感觉,它与函数中的通配符(\)有关,但我不确定如何表达函数的该部分,以便谓词在程序中搜索下一个事实,而不是跳到最后

我试着在我的程序中使用一个backcut(!),但它给了我同样的错误

非常感谢您的帮助。我不想要代码,我只想知道我做错了什么,这样我就可以学会如何做正确的事情


谢谢。

恐怕这条规则毫无意义:

gotFrom(X,Y) :- gotFrom(Y,_).
这里没有任何东西可以将X或Y约束到任何特定值。此外,存在单例变量
X
和匿名变量
\
意味着基本上任何东西都可以工作。试试看:

?- gotFrom([1,2,3], dogbert).
true ;
true ;
我认为你在这里试图建立的是某种传递属性。在这种情况下,您想要的可能更像这样:

gotFrom(X,Z) :- gotFrom(X, Y), gotFrom(Y, Z).
这产生了一个有趣的结果:

?- gotFrom(brock, Who).
Who = cara ;
Who = daniel ;
Who = m ;
ERROR: Out of local stack
这个问题的原因可能不是很明显。这是因为在该规则中有两次未经检查的递归。我们递归地统一
gotFrom/2
,然后再次递归地统一它。最好将其分成两个谓词,以便其中一个可以非递归地使用

got_directly_from(annie,brock).
got_directly_from(brock,cara).
got_directly_from(cara,daniel).
got_directly_from(daniel,m).

gotFrom(X,Y) :- got_directly_from(X, Y).
gotFrom(X,Z) :- got_directly_from(X, Y), gotFrom(Y, Z).
这为我们提供了所需的行为:

?- gotFrom(brock, Who).
Who = cara ;
Who = daniel ;
Who = m ;
false.
请注意,这一条对我攻击无意义数据具有弹性:

?- gotFrom([1,2,3], dogbert).
false.
一些一般性建议:

  • 永远不要忽略单例变量警告。它们几乎总是一只虫子
  • 当你不明白发生了什么事时,千万不要引入割伤。只有在您首先了解行为并且了解切割将如何影响行为的情况下,才应使用切割。理想情况下,你应该试着限制自己的绿色削减,只影响性能,没有明显的影响。如果您不明白Prolog在做什么,添加一个红色的切割只会使您的问题更加复杂

  • 我懂了。谢谢你,丹尼尔,我真的很感谢你的精彩表演。我对通配符运算符的想法犹豫不决,想都想不过去,但你的解释让我过去了。谢谢你。我会继续写我的序言来理解它。@user2020331太好了,不客气!我希望您喜欢使用Prolog并坚持使用它。这是一条艰难的路,但它是值得的!