Math in Prolog

Defining a mathematical function in Prolog means defining a relationship between the function and its return value. For example, here's the definition in C of a function that converts centigrade temperatures to Fahrenheit temperatures:

double c2f(double c) { return 9 * c / 5 + 32; }

Here's the equivalent definition in Prolog:

c2f(C, F) :- F is 9 * C / 5 + 32.

Basically, this definition says that if the input to c2f is C, then the output will be F.

Here's a sample session:

15 ?- c2f(100, X).
X = 212.

16 ?- c2f(0, X).
X = 32.

17 ?- c2f(37, X).
X = 98.6.

18 ?- c2f(-40, X).
X = -40.

19 ?- c2f(X, 70).
ERROR: is/2: Arguments are not sufficiently instantiated

 

Notice the error when we attempted to invert the function. This happens because "is" is a special one-way operation in Prolog that computes what is on its right and assigns it to what is on the left:

20 ?- X is 6 * 7.
X = 42.

21 ?- 6 * 7 is X.
ERROR: is/2: Arguments are not sufficiently instantiated

Of course we can define recursive relationships in Prolog. Here's the good old factorial function:

fact(0, 1).
fact(N, F) :- N > 0, N1 is N - 1, fact(N1, F1), F is N * F1.

The basic rule of thumb is never to write as the leftmost goal of the tail something that is identical (modulo variable names) with the goal given in the head. Rather, place such goals (which trigger recursive calls) as far as possible towards the right of the tail. That is, place them after the goals which test for the various (non-recursive) termination conditions.

For example, the following recursive definitions make sense logically, but lead to infinite loops:

fact(N, F) :- N > 0, N1 is N - 1, fact(N1, F1), F is N * F1.
fact(0, 1).

fact(0, 1).
fact(N, F) :- fact(N1, F1), N > 0, N1 is N - 1, F is N * F1.

Predefined Predicates

?- 3 < 4.
true.

?- 3 =< 3.
true.

?- 3 =:= 1 + 2.
true.
?- 3 \= 3.
false.

?- 3 >= 4.
false.

?- 3 > 4.
false.


Notice that expressions like 1 + 2 are computed.