Why do you want a non-recursive version? Recursion is a natural thing in Visual Prolog.
Here is a recursive is a plain forward recursive version:
Code: Select all
class predicates
factorial : (integer N) -> integer FacN.
clauses
factorial(N) = if N <= 1 then 1 else N * factorial(N - 1) end if.
If anybody worries: It is not tail call optimized because the multiplication takes place after the recursive call. However it will give integral overflow for N = 13. A stack depth that should not cause any problems.
Even if you switch to
reals it will overflow at N = 171, still not really a stack depth that need worry.
Anyways, a tail call optimized version can be made like this:
Code: Select all
class predicates
factorial_tailOpt : (integer N) -> integer FacN.
clauses
factorial_tailOpt(N) = factorial_tailOpt2(N, 1).
class predicates
factorial_tailOpt2 : (integer N, integer Acc) -> integer FacN.
clauses
factorial_tailOpt2(N, Acc) = if N <= 1 then Acc else factorial_tailOpt2(N - 1, N * Acc) end if.
A test could look like this:
Code: Select all
clauses
run() :-
foreach I = std::cIterate(11) do
stdio::writef("%2! = %7 = %7\n", I, factorial(I), factorial_tailOpt(I))
end foreach.