序言中的递归
我认为我不明白递归在序言中是如何工作的
以下代码(幂函数)
pow(_,0,1).
pow(X,Y,Z) :-
Y1 is Y - 1 ,
pow(X,Y1,Z1) ,
Z is Z1*X
.
创建以下跟踪:
[trace] ?- pow(2,2,X).
Call: (6) pow(2, 2, _G368) ? creep
Call: (7) _G444 is 2+ -1 ? creep
Exit: (7) 1 is 2+ -1 ? creep
Call: (7) pow(2, 1, _G443) ? creep
Call: (8) _G447 is 1+ -1 ? creep
Exit: (8) 0 is 1+ -1 ? creep
Call: (8) pow(2, 0, _G446) ? creep
Exit: (8) pow(2, 0, 1) ? creep
Call: (8) _G450 is 1*2 ? creep
Exit: (8) 2 is 1*2 ? creep
Exit: (7) pow(2, 1, 2) ? creep
Call: (7) _G368 is 2*2 ? creep
Exit: (7) 4 is 2*2 ? creep
Exit: (6) pow(2, 2, 4) ? creep
我不明白最后一个状态:“Z 是 Z1*X”是如何工作的。这个函数什么时候被调用?什么时候达到基本情况? 基本情况是如何被调用的?
谢谢
I dont think I understand how recursion works in prolog
The following code (a power function)
pow(_,0,1).
pow(X,Y,Z) :-
Y1 is Y - 1 ,
pow(X,Y1,Z1) ,
Z is Z1*X
.
Creates the following trace:
[trace] ?- pow(2,2,X).
Call: (6) pow(2, 2, _G368) ? creep
Call: (7) _G444 is 2+ -1 ? creep
Exit: (7) 1 is 2+ -1 ? creep
Call: (7) pow(2, 1, _G443) ? creep
Call: (8) _G447 is 1+ -1 ? creep
Exit: (8) 0 is 1+ -1 ? creep
Call: (8) pow(2, 0, _G446) ? creep
Exit: (8) pow(2, 0, 1) ? creep
Call: (8) _G450 is 1*2 ? creep
Exit: (8) 2 is 1*2 ? creep
Exit: (7) pow(2, 1, 2) ? creep
Call: (7) _G368 is 2*2 ? creep
Exit: (7) 4 is 2*2 ? creep
Exit: (6) pow(2, 2, 4) ? creep
I dont understand how the last state : 'Z is Z1*X' works. When is this function called? When the base case is reached?
How does the base case ever get called?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要点是
pow
不是一个函数。这是一个谓词。 Prolog 并不真正评估pow
,它尝试满足其条件。第一个条款什么时候达成?每次都这样尝试。但除非第二个参数为 0 并且第三个参数为 1(或者它们是可以与这些值统一的变量),否则它将失败。当第一个子句失败时,会尝试第二个子句。
The main point is that
pow
is not a function. It's a predicate. Prolog doesn't really evaluatepow
, it tries satisfy its conditions.And when is the first clause reached? It's tried every time. But unless the second argument is 0 and the third one is 1 (or they are variables that can be unified with those values), it fails. And when the first clause fails, the second one is tried.
您可以将
pow
视为一个函数,该函数分为两个处理不同参数值的子句。该函数是递归的,由第二个子句中的递归调用触发。但在这次调用之后,还有一些事情要做,Z is Z1*1
目标。这些“悬空”计算是在递归终止时完成的,并控制“气泡”再次向上,可以说是在返回的过程中。 (这种递归有一个名字,我不记得了)。看看这个评论跟踪:
You can think of
pow
as a function that is split in two clauses that deal with different parameter values. The function is recursive, which is triggered by the recursive call in the second clause. But after this call, there is still something to do, theZ is Z1*1
goal. These "dangling" computations are done when the recursion has terminated and control "bubbles" upward again, on the way back so to speak. (There is a name for this kind of recursion which I can't remember).Look at this commented trace:
跟踪中带有星号 (*) 的每一行都使用“Z is Z1 * X”规则。
该代码的工作原理是提供以下幂函数的递归定义:
Z、Z1 和 Y1 变量是 Prolog 的事实的产物需要一种引用中间结果的方法;您将 Y-1 称为 Y1,将 X^(Y-1) Z1 称为 X^(Y-1) Z1。
通过在递归的每个级别将指数 (Y) 减一(产生 Y1),直到 Y = 0 并且定义的第一种情况适用,即可得到基本情况。
Every line in the trace with the asterisk (*) is using the "Z is Z1 * X" rule.
This code works by providing the following recursive definition of the power function:
The Z, Z1 and Y1 variables are artifacts of the fact that Prolog needs a way to refer to intermediate results; you call Y-1 Y1 and you call X^(Y-1) Z1.
This gets to the base case by decreasing the exponent (Y) by one (yielding Y1) at each level of the recursion until Y = 0 and the first case of the definition applies.