I created a simple Prolog program to calculate the factorial of a number:
factorial(1,1).
factorial(Number, Factorial):-
Number>1,Number1 is Number-1,
factorial(Number1, Factorial1),
Factorial is Factorial1*Number.
It works correctly, but as you can notice, I have to store the one subtraction from Number
variable in a new one called Number1
before calling recursively to factorial predicate. The problem is that when I try to call the predicate without creating a new variable in the caller one, it always outputs false:
factorial(1,1).
factorial(Number, Factorial):-
Number>1,
factorial(Number-1, Factorial1),
Factorial is Factorial1*Number.
?- factorial(5,N).
false.
However, considering the above function is working with the right version, I made another function to calculate the binomial number of two N
and K
values like so:
binomial(N,K,R):-factorial(N,FN),factorial(K,FK),factorial(N-K,FNK),R is FN//(FK*FNK).
?- binomial(8,5,N).
N = 56 ;
false.
In this case, the N-K
calculation is directly inserted into the factorial predicate call without having to store the value in a variable, and it works correctly. So my question is; When and where can I assure Prolog will work without issues if I need to make a calculation that serves as input for another predicate?
When and where can I assure Prolog will work without issues if I need to make a calculation that serves as input for another predicate?
The short version is never, always calculate and store. The more detailed answer is: when you understand what's going on; trace your code and see N-K
is not doing any calculation:
>
is evaluating it once.
is
is evaluating it again.
If you try the binomial version on the factorial without is
, it fails.
In the plain version, factorial(1, 1).
never matches the term 4-1-1-1
, only once you have evaluated it and stored the result can it match 1
.