1

我是遵循“LearnPrologNow!”的 Prolog 初学者。一套教程。我正在尽我所能掌握概念和词汇。当遇到这个问题时,我已经能够理解所有内容,直到第 3 章递归定义:

numeral(0).
numeral(succ(X))  :-  numeral(X). 

给定查询

numeral(X).

现在,我了解到该程序的想法是 Prolog 将开始在该系统中按以下顺序计数数字

X=0
X=succ(0)
X=succ(succ(0))

但我不明白是什么导致它每次“缩减”并上升。我理解统一的原则是程序试图统一X的查询,但是它应该只遵循递归规则一次,然后返回零吗?是什么允许它在查询周围添加一个 succ() ?那不是在相反的方向遍历递归规则吗?

4

2 回答 2

3

请以声明的方式思考:

规则

numeral(succ(X))  :-  numeral(X).

方法:

如果 X是一个数字,那么 succ(X)是一个数字。

:-就像在逻辑含义中使用的箭头(它看起来类似于<==)。

看到您成功推导0出数字(第一个答案),因此这succ(0)是另一种解决方案也就不足为奇了。

我建议您考虑这种关系,而不是试图追踪实际的控制流。

请注意,succ/1它不是“围绕查询”添加的,而是实际答案的一部分。该术语succ(0)只是一个普通的 Prolog 术语,带有 functorsucc和 argument 0

于 2015-03-12T13:14:58.910 回答
2

已经给出的答案很好,我会添加更多:

Prolog 使用指称语法(或声明性语法)来定义术语之间的逻辑关系/“方程式”

术语是由变量/函数/占位符等组成的对象。

统一是检查两个表达式(或两个项)对于给定关系/方程是否相等的过程。

numeral(succ(X))  :-  numeral(X)

是这样一个关系/方程,它表示变量项X属于numeral type(或类)的事实,意味着后继泛函succ也属于同一类型。所以这里的Prolog可以统一表达式(也就是解方程)和替换Xsucc(X)等等,直到X覆盖了的域。所以这个统一意味着X被替换succ(X),然后可以重新应用统一。

于 2015-03-12T13:46:26.620 回答