为什么这个Prolog Fibonacci函数会导致“instantiation_error”?

时间:2012-12-24 12:50:55

标签: prolog logic fibonacci declarative clpfd

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

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)

有谁知道为什么会这样?

3 个答案:

答案 0 :(得分:3)

在第二句中:

fib(N,A,B,F) :-
    N1 is N-1, Sum is A+B, fib(N1, B, Sum, F).

N是一个要递减的变量,并且在您的调用中:

fib(What, 6765).

尚未定义变量,因此您在N1 is N - 1上获得实例化错误。

在swipl中我甚至得到错误:

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

答案 1 :(得分:3)

现在你知道这是一个错误,你介意知道它是否真的可以回答你的问题?

你如何处理这个问题?你的功能还可以,不是吗?确切地说,因为它是函数,而不是 关系,所以你会收到错误。

解决它有点复杂,但CLP可以做到!

从CLP(FD)documentation(此处引用)

中查看这个引人入胜的例子
:- use_module(library(clpfd)).

n_factorial(0, 1).
n_factorial(N, F) :-
        N #> 0, N1 #= N - 1, F #= N * F1,
        n_factorial(N1, F1).

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

:- [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).

即。将is / 2替换为#= / 2,我们得到

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

?- fib(X,6765).
X = 20 ;
^C

请注意,在第一次响应后程序循环! 你有没有办法纠正它?或者另一个问题值得......

答案 2 :(得分:0)

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

//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