为什么这个Prolog Fibonacci函数会导致“a”;实例化错误;?

为什么这个Prolog Fibonacci函数会导致“a”;实例化错误;?,prolog,logic,fibonacci,declarative,clpfd,Prolog,Logic,Fibonacci,Declarative,Clpfd,我正在尝试使用以下函数计算: fib(0,A,_,A). fib(N,A,B,F) :- N1 is N-1, Sum is A+B, fib(N1, B, Sum, F). fib(N, F) :- fib(N, 0, 1, F). 其工作原理如下: | ?- fib(20,Result). Result = 6765 ? 但当我尝试这一点时,它会抱怨: | ?- fib(What,6765). uncaught exception: error(instantiation_e

我正在尝试使用以下函数计算:

fib(0,A,_,A).
fib(N,A,B,F) :-
    N1 is N-1, Sum is A+B, fib(N1, B, Sum, F).
fib(N, F) :- fib(N, 0, 1, F).
其工作原理如下:

| ?- fib(20,Result).

Result = 6765 ? 
但当我尝试这一点时,它会抱怨:

| ?- fib(What,6765).
uncaught exception: error(instantiation_error,(is)/2)
有人知道为什么会这样吗?

在第二条中:

fib(N,A,B,F) :-
    N1 is N-1, Sum is A+B, fib(N1, B, Sum, F).
N
是一个要递减的变量,在调用时:

fib(What, 6765).
变量尚未定义,因此您在
N1上得到的实例化错误为N-1

在swipl中,我甚至得到了错误:

?- fib(W, 6765).
ERROR: fib/4: Arguments are not sufficiently instantiated

既然你知道这是一个错误,你介意知道它是否真的可以回答你的问题吗

你将如何处理这个问题?你的功能没问题,不是吗?没错,因为它是一个函数,而不是一个关系,所以你得到了错误

解决这个问题有点复杂,但中电可以做到

请参阅CLP(FD)的这个迷人的例子(此处引用)

我们需要这样的东西,但对于斐波那契。 看看这有多容易:

:- [library(clpfd)].

fib(0,A,_,A).
fib(N,A,B,F) :-
    N #> 0,
    N1 #= N-1,
    Sum #= A+B,
    fib(N1, B, Sum, F).
fib(N, F) :- fib(N, 0, 1, F).
i、 e.用
#=
/2替换
is
/2,我们得到

?- fib(20,Result).
Result = 6765 .

?- fib(X,6765).
X = 20 ;
^C
注意,在第一次响应之后,程序将循环!
你有没有找到纠正的方法?或者另一个问题可能值得…

更清晰、更自然的谓词定义可能是:

//The two base steps
fib1(0,0). 
fib1(1,1).
//the recursive step
fib1(N,F) :- 
        N >= 0, M is N-2, O is N-1, fib1(M,A), fib1(O,B), F is A+B.
它也是一个只有一个谓词的定义:fib/2

//The two base steps
fib1(0,0). 
fib1(1,1).
//the recursive step
fib1(N,F) :- 
        N >= 0, M is N-2, O is N-1, fib1(M,A), fib1(O,B), F is A+B.