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