Prolog:递减参数中的变量
我是 Prolog 新手,任务是处理斐波那契谓词 fib( N, F),其中 N 是序列中的数字,F 是值。我想出的方法不起作用,但我找到的解决方案对我来说似乎相同......我无法理解其中的区别。
我的版本:
/* MY VERSION, DOES NOT WORK */
fib( 0, 0).
fib( 1, 1).
fib(N,F) :-
N > 1,
fib(N-1,F1),
fib(N-2,F2),
plus(F1,F2,F).
工作版本:
/* FOUND SOLUTION, DOES WORK */
fib( 0, 0).
fib( 1, 1).
fib(N,F) :-
N > 1,
N1 is N-1,
N2 is N-2,
fib(N1,F1),
fib(N2,F2),
plus(F1,F2,F).
显然,问题与我使用“N-1”和“N-2”作为参数而不是首先将这些值分配给新变量有关。但我不明白......因为在其他递归 Prolog 代码中,我已经成功地做到了这一点(在参数槽中减少了一个变量)。这有道理吗?
谢谢!
下面是“N-1”起作用的示例。
line( N, _, _) :-
N =:= 0.
line( N, M, Char) :-
N > 0,
N mod M =\= 1,
write( Char), write( ' '),
line( N-1, M, Char).
line( N, M, Char) :-
N > 0,
N mod M =:= 1,
write( Char), write( '\n'),
line( N-1, M, Char).
square( N, Char) :-
N > 0,
line( N*N, N, Char).
新版本的 fib/2 也可以使用!
/* NEW VERSION, CHANGED TRIVIAL CASES TO EVALUATE N */
fib( N, 0) :-
N =:= 0.
fib( N, 1).
N =:= 1.
fib(N,F) :-
N > 1,
fib(N-1,F1),
fib(N-2,F2),
plus(F1,F2,F).
I am new to Prolog and was tasked with a Fibonnaci predicate fib( N, F) where N is the number in sequence, and F is the value. What I came up with does not work, but the solution I found seems identical to me... I cannot understand the difference.
My version:
/* MY VERSION, DOES NOT WORK */
fib( 0, 0).
fib( 1, 1).
fib(N,F) :-
N > 1,
fib(N-1,F1),
fib(N-2,F2),
plus(F1,F2,F).
The working version:
/* FOUND SOLUTION, DOES WORK */
fib( 0, 0).
fib( 1, 1).
fib(N,F) :-
N > 1,
N1 is N-1,
N2 is N-2,
fib(N1,F1),
fib(N2,F2),
plus(F1,F2,F).
Obviously the problem has something to do with me using "N-1" and "N-2" as arguments rather than assigning those values to new variables first. But I don't get it... because in other recursive Prolog codes, I have successfully done just that (decremented a variable right in the argument slot). Does this make sense?
Thanks!
Below is an example where the "N-1" did work.
line( N, _, _) :-
N =:= 0.
line( N, M, Char) :-
N > 0,
N mod M =\= 1,
write( Char), write( ' '),
line( N-1, M, Char).
line( N, M, Char) :-
N > 0,
N mod M =:= 1,
write( Char), write( '\n'),
line( N-1, M, Char).
square( N, Char) :-
N > 0,
line( N*N, N, Char).
A new version of fib/2 which also works!
/* NEW VERSION, CHANGED TRIVIAL CASES TO EVALUATE N */
fib( N, 0) :-
N =:= 0.
fib( N, 1).
N =:= 1.
fib(N,F) :-
N > 1,
fib(N-1,F1),
fib(N-2,F2),
plus(F1,F2,F).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在序言中,
实际上并没有做任何算术(我知道,对吧?),它创建了一个结构:
is
是一个评估该结构的谓词:Will unify X with
-1< /代码>。
显然也
<
和>
(以及类似的) 就像is
因为他们评估表达式。因此,这意味着
fib
谓词和line
谓词之间的区别在于使用统一,即测试术语本身是否相等:
而像
这样的测试>=:=
测试数值相等:In prolog,
Doesn't actually do any arithmetic (I know, right?), it creates a structure:
And
is
is a predicate that evaluates that structure:Will unify X with
-1
.Also apparently
<
and>
(and those like it) are likeis
in that they evaluate expressions.So that means that the difference between your
fib
predicate and yourline
predicate is thatis using unification, ie, testing whether the terms themselves are equal:
Whereas a test like
=:=
tests for numerical equality:我可能会编写如下所示的谓词。
fib/2
是外部“公共”接口。N
是序列中的位置(零相对)。F
与该位置的斐波那契数列值统一。fibonacci/5 是完成这项工作的内部“核心”。
核心中的每个子句的工作原理如下:
这是代码:
I'd probably write the predicate somthing like the following.
fib/2
is the outer 'public' interface.N
is the position in the sequence (zero-relative).F
gets unified with the value of the Fibonacci sequence at that position.fibonacci/5
is the inner 'core' that does the work.Each clause in the core works as follows:
Here's the code: