# 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

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

end class main

% main.pro
implement main
open core

constants
className = "main".
classVersion = "".

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

clauses
run():-
console::init(),
factorial(12,F),
programControl::sleep(1000),
succeed().
end implement main

goal
mainExe::run(main::run).
``````