:- module(_,_).

% Comparing Peano arithmetic and ISO-Prolog is/2 built-in 
% for computing factorial

% a) Using Peano arithmetic: 

peano_factorial(0,s(0)).
peano_factorial(s(N),F) :-
    peano_factorial(N,F1),
    peano_times(s(N),F1,F).

peano_times(0,_,0).
peano_times(s(X),Y,Z) :-
    peano_times(X,Y,W),
    peano_plus(W,Y,Z).

peano_plus(0,Y,Y) :-
    nat(Y).
peano_plus(s(X),Y,s(Z)) :-
    peano_plus(X,Y,Z).

nat(0).
nat(s(X)) :- nat(X).

% Try: 
% ?- peano_factorial(s(s(s(s(s(0))))),F).
% ?- peano_factorial(s(s(s(s(s(0))))),_).
% ?- peano_factorial(s(s(s(s(s(s(0)))))),_).
% ?- peano_factorial(s(s(s(s(s(s(s(0))))))),_).
% Takes long...

% b) Using ISO-Prolog is/2 and >/2:

factorial(0,1). 
factorial(N,F) :-
    N > 0,
    N1 is N-1,
    factorial(N1,F1),
    F is F1*N.

% Try:
% ?- factorial(7,F).
% ?- factorial(1000,F).
% ?- factorial(100000,_).
% But: 
% ?- factorial(N,6).
% Error!

wrong_factorial(0,1). 
wrong_factorial(N,F) :-
    N > 0,
    N1 is N-1,
    F is F1*N,
    wrong_factorial(N1,F1).

% Try: 
% ?- wrong_factorial(3,F).
% Error!
