prologarithmetic-expressionsunification

When can I safely avoid storing temporary calculations in Prolog?


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?


Solution

  • 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:

    8-1-1-1-1

    > 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.