5

This is my code:-

fib(0,0).
fib(1,1).
fib(F,N) :-
    N>1,
    N1 is N-1,
    N2 is N-2,
    F is F1+F2,
    fib(F1,N1),
    fib(F2,N2),
    write(F," ,").

On consulting in GNU Prolog, I am getting:

| ?- consult('C:/GNU-Prolog/bin/fib.pl').
compiling C:/GNU-Prolog/bin/fib.pl for byte code...
C:/GNU-Prolog/bin/fib.pl compiled, 3 lines read - 1253 bytes written, 15 ms

yes
| ?- fib(F,2).
uncaught exception: error(instantiation_error,(is)/2)
mat
  • 40,498
  • 3
  • 51
  • 78
user3341381
  • 53
  • 1
  • 1
  • 4

4 Answers4

8

Instantiation error is caused by the attempt to calculate F before the values of F1 and F2 have been determined. The simplest solution would to move F is F1+F2 after the recursive calls such that your program becomes

fib(0,0).
fib(1,1).
fib(F,N) :- 
    N>1,
    N1 is N-1,
    N2 is N-2,
    fib(F1,N1),
    fib(F2,N2),
    F is F1+F2,
    write(F," ,").

(thanks to @mbratch for reminding) write has only one argument, i.e., write(F," ,"). should be write(F), write(" ,").

You should be however careful with the output. The program above would print out the same value multiple times: e.g., to calculate fib(F,3) it will invoke fib(F1,2) and fib(F2,1) while fib(F1,2) will invoke fib(F11,1) and fib(F12,1) resulting in the following output 1, 1, 2, 1, 3. Is this really what you need?

Alexander Serebrenik
  • 3,567
  • 2
  • 16
  • 32
  • @Alexander You are right..it is displaying the same value multiple times. Is there any way in which I can display the complete series correctly? – user3341381 Apr 02 '14 at 23:09
  • @mbratch Thanks for the valuable information.Guess that was what was causing the error. And to add to the answer, the order of defining the argument matters as well. So the definition "N2 is N-2" should come just before "fib(F2,N2)". Having said that, is it possible to get the series in a single go in GNU Prolog? – user3341381 Apr 02 '14 at 23:10
  • @user3341381 what kind of output do you need? – Alexander Serebrenik Apr 03 '14 at 05:33
  • 1
    ?-fib(F,5) for e.g. should return F=11235 or even F=01123 or simply display the fibonacci series without assigning values to F like- ?-fib(F,5) 11235 @Alexander – user3341381 Apr 04 '14 at 06:56
2

You probably need F is F1+F2 after having instantiated F1 and F2. The following is an exact adaptation of your code to something that works. Now, I'm sure it's exactly what you want (besides, it fails for large values of N, large being impressively small here).

fib(0,0).
fib(1,1).
fib(F,N) :-
    N>1,
    N1 is N-1,
    N2 is N-2,
    fib(F1,N1),
    fib(F2,N2),
    F is F1+F2,
    format('~w, ',[F]).

I used format instead of write, I'm not sure that write/2 does what you expect.

gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
  • Thanks. But i'm really confused. What does write/2 mean and how is format different from it? – user3341381 Apr 02 '14 at 23:14
  • @user3341381 in Prolog, when referring to a predicate, you give the name and the arity (number of accepted arguments). `write/2` means the `write` predicate with two arguments. `write/1` and `write/2` are simple write predicates with no control over format. `format/2` lets you control the format of what you're writing. See the online manual for details. – lurker Apr 03 '14 at 00:16
  • @mbratch I get it..Thanks! :) The online manual is hard to comprehend . – user3341381 Apr 04 '14 at 07:03
1
fab1(1,1).
fab1(2,1).
fab1(N,T):-
    N>2,
    N1 is N-1,
    N2 is N-2,
    fab1(N1,T1),
    fab1(N2,T2),
    T is (T1+T2),
Floern
  • 33,559
  • 24
  • 104
  • 119
1

domains

N,N1,N2,Ans=integer

predicates

test(integer,integer)
findfibo(integer,integer)
go

clauses

go:-
    write("Enter number"),nl,
    readint(N),
    test(1,N).
go.
test(0,N).
test(X,N):-
    X<=N,
    findfibo(X,Ans),
    write(Ans," ,"),
    X1=X+1,
    test(X1,N).



findfibo(1,1).
findfibo(2,1).
findfibo(N,Ans):-
    N>1,
    N1=N-1,
    N2=N1-1,
    findfibo(N1,Ans1),
    findfibo(N2,Ans2),
    Ans=Ans1+Ans2.

sample output Goal: go Enter number 10 1 , 1, 2, 3, 5, 8, 13, 21, 34, 45, 55,Yes

h4k3r
  • 11
  • 3