Factorial in Prolog

Example for versions Visual Prolog 7.2

Create a new project with UI Strategy “Console” and replace contents of files main.cl and main.pro with given code.

In main.cl the only added line factorial : (integer N, integer F) procedure (i,o). specifies that factorial is a predicate of arity 2, with known first and unknown second argument. Keyword procedure describes the behavior of predicate, indicating that is will always succeed with only one solution, so no backtracking is required.

In main.pro the actual description of newly specified predicate takes place. There are two possible matches for each call of factorial — with zero or arbitrary first argument. Visual Prolog searches the clauses for matching call in the order of their appearance in the code, so if first argument is zero, it starts with first clause factorial(0,F). The first rule in this clause is !, a so-called cut, which prevents backtracking to second clause factorial(N,F) and thus ensures that there is only one solution to the call. After this the return variable F is set to 0! = 1 and the result of the clause is printed. The second clause factorial(N,F) recursively calculates F1 as factorial of N-1, assigns N*F1 to return variable F and prints the result. Finally, stdio::nl prints a new line.

When the main program runs, factorial is called exactly once, for N=12. With each call of recursion N is decremented until it reaches 0. After this factorials are returned and printed in increasing order of N. This program can process only factorials up to 12!, since trying to calculate 13! causes an integer overflow.

% main.cl
class main
    open core

    classInfo : core::classInfo.
    factorial : (integer N, integer F) procedure (i,o).
    run : core::runnable.

end class main

% main.pro
implement main
    open core

    className = "main".
    classVersion = "".

    classInfo(className, classVersion).
    factorial(0,F) :- 
        F = 1, 
        stdio::write("0! = 1"),
    factorial(N,F) :-
        F = N*F1,
        stdio::write(N, "! = ", F),
end implement main