Function 检查第n个斐波那契数是否为第n个斐波那契数-算术错误失败

Function 检查第n个斐波那契数是否为第n个斐波那契数-算术错误失败,function,math,prolog,fibonacci,arithmetic-expressions,Function,Math,Prolog,Fibonacci,Arithmetic Expressions,这是我的谓词,它应该检查Fibonacci的Nth个数是否为NthFib 我得到的算术不是函数错误 K - current iteration N - Nth number Tmp - previous Fibonacci number Ans - current Fibonacci number 斐波那契序列:1、1、2、3、5、8、13、21等(前两个的总和=当前) fib(N,N个fib):- fib(1,N,1,0,NthFib)。 fib(K,N,Ans,Tmp,NthFib):-

这是我的谓词,它应该检查Fibonacci的
N
th个数是否为
NthFib

我得到的算术不是函数错误

K - current iteration
N - Nth number
Tmp - previous Fibonacci number
Ans - current Fibonacci number
斐波那契序列:1、1、2、3、5、8、13、21等(前两个的总和=当前)

fib(N,N个fib):-
fib(1,N,1,0,NthFib)。
fib(K,N,Ans,Tmp,NthFib):-
%如果Ans为NthFib,则为true,否则为false
(K>N->Ans是第N个fib
;K=fib(K+1,N,Ans+Tmp,Ans,NthFib)
).

如果
K
1
相统一,
K+1
1+1
相统一,而不是
2
我重写了一个算法,现在它更简单、更有效:

fib(0, 0).
fib(1, 1).
fib(N, F) :-
    N > 0,
    X is N - 2,
    Y is N - 1,
    fib(X, A),
    fib(Y, B),
    F is A + B.

首先,将原始代码重新编写为

fib(N, NthFib) :- fib(1, N, 1, 0, NthFib).

fib(K, N, Ans, Tmp, NthFib) :- 
  K > N -> Ans = NthFib;       % use = instead of is here
  K =< N -> fib((K+1), N, (Ans+Tmp), Ans, NthFib).
请参见,在Prolog中,数据是符号的,使用
is
将算术表达式强制转换为算术值(在假定表达式是有意义的算术表达式的情况下计算表达式)

要检查20是否是第7个斐波那契数,我们可以使用算术比较运算符来计算其参数

?- fib(7,X), X =:= 20.

No
这意味着您的代码只需要按照

fib(N, NthFib) :- fib(1, N, 1, 0, NthFib).

fib(K, N, Ans, Tmp, NthFib) :- 
  K > N -> NthFib is Ans ;       % exchange the order of operands
  K =< N -> fib((K+1), N, (Ans+Tmp), Ans, NthFib).
但它不能有效地工作,将所有这些长表达式作为符号数据携带。我们实际上只需要数字,所以正如其他答案中所示,
is
用于实现这一点。您拥有的每个符号子表达式,将其从封闭表达式中取出,并使用
is
而不是
=
对其命名


BTW21实际上是序列的第8个成员。更正代码。

你是否缺少家庭作业标签?这不是家庭作业,而是自我教育。现在你可以帮我了。K=K1是K+1,Ans1是Ans+Tmp,fib(K1,N,Ans1,Ans,NthFib)不,不,不!“更有效率”?不,您的原始代码是高效的-即线性-这是经典的树递归代码,计算第n个数需要大量时间,因为它在计算fib(Y)时重新计算fib(X)-而您的原始代码通过显式维护最后两个值来重复使用它。是的,这是一个指数复杂度算法。当
N
大于30左右时,您的计算机不会返回太多内容。你以前的算法——即使实现得很差——要好得多。见威尔·内斯的答案(+1)!
?- fib(7,X), X =:= 20.

No
fib(N, NthFib) :- fib(1, N, 1, 0, NthFib).

fib(K, N, Ans, Tmp, NthFib) :- 
  K > N -> NthFib is Ans ;       % exchange the order of operands
  K =< N -> fib((K+1), N, (Ans+Tmp), Ans, NthFib).
?- fib(7,21).

Yes
?- fib(7,20).

No