无法理解为什么prolog无限循环
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法理解为什么prolog无限循环相关的知识,希望对你有一定的参考价值。
从Bratko的书中,Prolog Programming for Artificial Intelligence (4th Edition) 我们有以下代码不起作用 -
anc4(X,Z):-
anc4(X,Y),
parent(Y,Z).
anc4(X,Z):-
parent(X,Z).
在本书的第55页,图2.15中,显示parent(Y,Z)
一直在调用,直到堆栈内存不足。
我不明白的是,prolog首先对anc4(X,Y)进行recursiv调用,而不是父对象(Y,Z)。为什么prolog不会反复到第一行,anc4(X,Y)
,而是转到第二行?
你能详细说明为什么parent(Y,Z)
这条线被称为?
谢谢。
你的“问题”(即目标顺序)的起源深深植根于语言的基础。
Prolog基于时间顺序回溯的简单而有效的策略,实现SLD resolution,并且像anc4/2
一样留下递归子句,导致无限递归。实际上,逗号运算符(,)/2
代表
仅当左表达式成立时才评估正确的表达式
因此,条款中的目标顺序实际上是该计划的重要部分。
对于你的具体案例,
... , parent(Y,Z).
如果不能被调用
anc4(X,Y),
不成立。
目标顺序的对应物是子句顺序。
也就是说,在交换子句之后,整个程序具有不同的语义:
anc4(X,Z):-
parent(X,Z).
anc4(X,Z):-
anc4(X,Y),
parent(Y,Z).
为了更好地理解这个问题,我认为也值得尝试这个定义。
没有表格机制,Prolog默认不能处理左递归。只有一些Prolog系统支持表格,通常你需要明确声明哪些谓词被列表。
如果你正在使用例如XSB,YAP或SWI-Prolog,尝试在包含anc4/2
谓词定义的源文件之上添加以下指令:
:- table(anc4/2).
并重试您的查询。 tabling机制检测查询何时调用自身的变量(*)并暂停执行该分支,直到找到查询答案并尝试替代分支(在第二个子句的情况下提供)。如果发生这种情况,则使用该答案恢复执行。
(*)这里的变量意味着在变量重命名时两个术语相等。
以上是关于无法理解为什么prolog无限循环的主要内容,如果未能解决你的问题,请参考以下文章