:- module(_,[fact/2],[regtypes,assertions,nativeprops]).

% adapted from the `Factorial` example of the Interproc analyzer
%   http://pop-art.inrialpes.fr/interproc/interprocweb.cgi
%
% /* Direct Multiplication.
%    Changing the order of the arguments changes the result */
% proc fact3 (a:int) returns (b:int)
% var c:int;
% begin
%   if (a<=1) then
%     b = 1;
%   else
%     c = a - 1;
%     c = fact3(c);
%     b = c*a;
%   endif
%   ;
% end
%
% var
% y:int,z:int;
%
% begin
% y = 1;
% while true do
%   z = fact1(y);
%   z = fact2(y);
%   z = fact3(y);
%   y = y+1;
% done;
% end

% ----------------------------------------------------------------------
:- entry fact(A,B) : constraint([A >= 0]).
:- pred fact(A,B) : constraint([A >= 0]) => constraint([B >=0, B >= A]).

fact(A,B) :- A =< 1, B = 1.
fact(A,B) :-
        A > 1,
        C0 is A - 1,
        fact(C0,C),
        B is C * A.
