Factorial in Prolog
Create a new project with UI Strategy “Console” and replace contents of files
main.pro with given code.
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.
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*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).