Prolog:2个数的递归乘法
Prolog: Recursive Multiplication of 2 Numbers
我不明白为什么这个乘法的递归定义有效。
我得到了添加部分,但是 "A" 在这种情况下的价值如何。
代码如下:
add(0,X,X).
add(s(X),Y,Z):-add(X,s(Y),Z).
mult(0,X,0).
mult(s(X),Y,Z):-mult(X,Y,A), add(Y,A,Z).
要理解谓词,请尝试 "read" 他们在说什么。
首先阅读 add/3
定义...
add(0,X,X).
Adding 0
to X
results in X
.
add(s(X),Y,Z):-add(X,s(Y),Z).
Adding s(X)
(the successor of X
) to Y
results in Z
if adding X
to s(Y)
(the successor of Y
) results in Z
.
如果我们将 successor 视为加 1,那么这就是说 (X + 1) + Y
导致 Z
如果 X + (Y + 1)
导致 Z
.这在逻辑上是显而易见的,但似乎没有任何意义。但是,我们会注意到此逻辑与 add(0,X,X)
的基本情况密切相关,因为递归情况将 减少 第一个参数,方法是每次迭代删除一个连续性,直到第一个参数变为 0
.
现在让我们试试mult/3
...
mult(0,X,0).
Multiplying 0
by X
results in 0
这似乎是显而易见的。
mult(s(X),Y,Z):-mult(X,Y,A), add(Y,A,Z).
Multiplying the successor of X
by Y
results in Z
if multiplying X
by Y
results in A
, and adding Y
to A
results in Z
.
如果你认为successor加1,那么这就是说(X+1)*Y
是Z
如果X*Y
是A
并且 A+Y
是 Z
。这是有道理的,因为 (X+1)*Y
是 (X*Y)+Y
也就是 A+Y
.
在此上下文中,A
是 (X-1) * Y
的值。您使用 mult
规则递归地找到此值,然后将其添加到 add
规则中的 Y
以获得最终结果。它将乘法写为 X * Y = (X - 1) * Y + Y
实际上最终发生的是它调用 add
X
次,并且每次都将 Y
添加到最终结果(从零开始)。这是利用乘法作为重复加法。这是手工跟踪:
mult(3, 2, Z)
初次通话
mult(2, 2, A_1), add(2, A_1, Z)
减去 1 帧 X
mult(1, 2, A_2), add(2, A_2, A_1)
再次.
mult(0, 2, A_3), add(2, A_3, A_2)
最后一次
mult(0, 2, A_3)
只有一种可能,因为零无法匹配 s(x)
。 A_3
设置为 0。
mult(0, 2, 0), add(2, 0, A_2)
第 4 步,但用 A_3
替换。我们现在知道 A_2
一定是 2.
mult(1, 2, 2), add(2, 2, A_1)
第 3 步,但用 A_2
替换。我们现在知道 A_1
必须是 4.
mult(2, 2, 4), add(2, 4, Z)
第 2 步,但用 A_1
替换。我们现在知道Z
一定是6,就是最后的结果。
对于第 2 步到第 4 步,您可以通过倒数来计算需要重复加法运算的次数。第 5 步是基本情况,最终结果从零开始。在步骤 6 到 8 中执行添加。这给出了 Z = 6 = 2 + 2 + 2
的结果
我不明白为什么这个乘法的递归定义有效。
我得到了添加部分,但是 "A" 在这种情况下的价值如何。
代码如下:
add(0,X,X).
add(s(X),Y,Z):-add(X,s(Y),Z).
mult(0,X,0).
mult(s(X),Y,Z):-mult(X,Y,A), add(Y,A,Z).
要理解谓词,请尝试 "read" 他们在说什么。
首先阅读 add/3
定义...
add(0,X,X).
Adding
0
toX
results inX
.
add(s(X),Y,Z):-add(X,s(Y),Z).
Adding
s(X)
(the successor ofX
) toY
results inZ
if addingX
tos(Y)
(the successor ofY
) results inZ
.
如果我们将 successor 视为加 1,那么这就是说 (X + 1) + Y
导致 Z
如果 X + (Y + 1)
导致 Z
.这在逻辑上是显而易见的,但似乎没有任何意义。但是,我们会注意到此逻辑与 add(0,X,X)
的基本情况密切相关,因为递归情况将 减少 第一个参数,方法是每次迭代删除一个连续性,直到第一个参数变为 0
.
现在让我们试试mult/3
...
mult(0,X,0).
Multiplying
0
byX
results in0
这似乎是显而易见的。
mult(s(X),Y,Z):-mult(X,Y,A), add(Y,A,Z).
Multiplying the successor of
X
byY
results inZ
if multiplyingX
byY
results inA
, and addingY
toA
results inZ
.
如果你认为successor加1,那么这就是说(X+1)*Y
是Z
如果X*Y
是A
并且 A+Y
是 Z
。这是有道理的,因为 (X+1)*Y
是 (X*Y)+Y
也就是 A+Y
.
在此上下文中,A
是 (X-1) * Y
的值。您使用 mult
规则递归地找到此值,然后将其添加到 add
规则中的 Y
以获得最终结果。它将乘法写为 X * Y = (X - 1) * Y + Y
实际上最终发生的是它调用 add
X
次,并且每次都将 Y
添加到最终结果(从零开始)。这是利用乘法作为重复加法。这是手工跟踪:
mult(3, 2, Z)
初次通话mult(2, 2, A_1), add(2, A_1, Z)
减去 1 帧X
mult(1, 2, A_2), add(2, A_2, A_1)
再次.mult(0, 2, A_3), add(2, A_3, A_2)
最后一次mult(0, 2, A_3)
只有一种可能,因为零无法匹配s(x)
。A_3
设置为 0。mult(0, 2, 0), add(2, 0, A_2)
第 4 步,但用A_3
替换。我们现在知道A_2
一定是 2.mult(1, 2, 2), add(2, 2, A_1)
第 3 步,但用A_2
替换。我们现在知道A_1
必须是 4.mult(2, 2, 4), add(2, 4, Z)
第 2 步,但用A_1
替换。我们现在知道Z
一定是6,就是最后的结果。
对于第 2 步到第 4 步,您可以通过倒数来计算需要重复加法运算的次数。第 5 步是基本情况,最终结果从零开始。在步骤 6 到 8 中执行添加。这给出了 Z = 6 = 2 + 2 + 2