:- ensure_loaded(typeops).

% fibonacci implementation

 
%+++++++++++++++++++++++++++++ type definitions +++++++++++++++++++++++ 

:- import_pred(prolog_arith, is/2).
:- import_type(prolog_types, num).
:- import_type(prolog_types, numexpr).
:- import_type(prolog_types, float).
:- import_type(prolog_types, int).
:- import_type(prolog_types, negint).

:- type nat.

:- subtype posint < nat.
:- subtype zero < nat.
:- type zero --> 0.
:- type posint --> {X^(integer(X),X>0)}.

 
%+++++++++++++++++++++++++++++ predicates  +++++++++++++++++++++++ 

:- pred fibonacci(nat, nat).
fibonacci(0, 1).
fibonacci(1, 1).
fibonacci(X, Y) :- fibonacci(X-1,Y1), fibonacci(X-2,Y2),     % ill-typed
	           Y is Y1 + Y2.
fibonacci(X, Y) :- X1 is X - 1, X2 is X - 2, 
	           fibonacci(X1, Y1), fibonacci(X2, Y2),
		   Y is Y1 + Y2.
