我要通过学习prolog网站试图学习一些序言,并试图进行2.3。我想每一次对word()的调用都会进入某种堆栈,这就解释了为什么它似乎会改变从结尾到开头的单词。但是,如果它改变其中一个单词,它又怎么会再次降低呢?
像:
一个罪犯吃了一个罪犯 一个罪犯吃了一个大kahuna汉堡犯罪分子每个 罪犯
犯罪分子吃每个 大kahuna汉堡
word(article,a).
word(article,every).
word(noun,criminal).
word(noun,'big kahuna burger').
word(verb,eats).
word(verb,likes).
sentence(Word1,Word2,Word3,Word4,Word5) :-
word(article,Word1),
word(noun,Word2),
word(verb,Word3),
word(article,Word4),
word(noun,Word5).
然后一个swi-prolog问题是否可以让它说是/否而不是真/假?
最好的问候安德斯·奥尔梅
答案 0 :(得分:3)
让我稍微介绍一下starblue说的话。
逻辑上,这个程序说如果第一件事是文章,第二件事是一个名词,第三件事是动词,第三件事是另一篇文章,第五件事是另一个名词。 Prolog的神奇之处在于你不必告诉它如何来获得答案,例如“为第一个单词尝试每篇文章,然后循环尝试第二个单词的每个名词,等等向前”;相反,你只是以声明方式陈述你的问题(第一个单词是一篇文章等),而Prolog会想出来。因此,只要您的问题在逻辑上陈述,您应该(最终)获得所有可能的有效答案。
因为Prolog在实际的计算机上运行,它必须有一个实际的策略来找到答案,并且该策略是深度优先搜索:它依次绑定每个变量,尝试各种可能性,直到它可以统一该变量,然后转移到下一个变量。当你要求下一个解决方案时,它会备份到具有其他可能性的最后一个统一,并尝试找到另一个满足谓词的统一。这就是为什么生成的句子按照它们的顺序出现的原因:单词5最后统一,所以当Prolog备份时,它会重试单词5.当它耗尽单词5的所有可能的统一时,它会备份到单词4然后移动再次转向第5个单词。因此,它最终会尝试所有五个单词的所有可能性。如果您不喜欢它尝试的顺序,您可以更改绑定变量的顺序。例如,如果您希望它重试第一个单词,然后是第二个单词,则可以将程序重写为:
sentence(Word1,Word2,Word3,Word4,Word5) :-
word(noun,Word5),
word(article,Word4),
word(verb,Word3),
word(noun,Word2),
word(article,Word1).
?- sentence(X,Y,Z,Q,A), write([X,Y,Z,Q,A]).
[a,criminal,eats,a,criminal] ;
[every,criminal,eats,a,criminal] ;
[a,big kahuna burger,eats,a,criminal]
符合您的期望,这是由堆栈内部管理。大多数现代Prolog都采用了WAM技术Warren Abstract Machine。 WAM与大多数其他编程语言虚拟机一样,有一个调用堆栈,但是还有一个名为 the trail 的第二个堆栈,它将变量推送到每个绑定上。然后回溯然后通过弹出最后一个变量离开路径并尝试统一它并从那里继续。如果此变量没有其他统一,它会从堆栈中弹出另一个变量并进一步备份。当Prolog用尽路径时,它只返回false,因为没有绑定是可能的。