Now we will look at some example programs without considering the details of their execution. The first example is a program expressing the relation fib(N, X) where X is the Nth Fibonacci number.
fib(0, 1).
fib(1, 1).
fib(N, X1 + X2) :-
N > 1,
fib(N - 1, X1),
fib(N - 2, X2).
To compute the 10th Fibonacci number, we can use the goal
?- fib(10, Z).
while to find out which Fibonacci number is 89, we can use the goal
?- fib(X, 89).
The next program describes the relationship between two complex numbers and their product. We will represent the complex number X + iY as the term c(X, Y).
zmul(c(R1, I1), c(R2, I2), c(R3, I3)) :-
R3 = R1 * R2 - I1 * I2 ,
I3 = R1 * I2 + R2 * I1 .
Any of the following goals will return a unique answer. The first goal asks for the product of two complex numbers, while the other two ask for the result when one complex number is divided by another.
?- zmul(c(1, 1), c(2, 2), Z).
?- zmul(c(1, 1), Y, c(0, 4)).
?- zmul(X, c(2, 2), c(0, 4)).
Notice how both operations are described using the definition of complex multiplication, rather than writing a separate rule that divides complex numbers by first realizing the divisor and then multiplying. This declarative aspect will be an important feature of many of the programs we look at. Also notice that both of the programs we have seen so far have been invertible in the sense that it did not matter which terms in the goals were ground and which were not. This is a property that we will try to obtain as often as possible when we define programs or parts of programs. As a further example, the special pow function can be used to compute powers, roots and logarithms of an arbitrary base. The rules below for square root,
sqroot(X, pow(X, 0.5)):-
X >= 0.
sqroot(X, -pow(X, 0.5)) :-
X >= 0.
state that a non-negative number has a positive and negative square root. Finally consider the following program, which relates the key parameters in a mortgage.
mortgage(P, Time, IntRate, Bal, MP) :-
Time > 0, Time <= 1,
Bal = P * (1 + Time * IntRate/1200) - Time * MP.
mortgage(P, Time, IntRate, Bal, MP) :-
Time > 1,
mortgage(P*(1 + IntRate/1200) - MP, Time-1, IntRate, Bal, MP).
The parameters above are principal, life of the mortgage (in months), annual interest rate (%) which is compounded monthly, the monthly payment, and finally, the outstanding balance. The goal
?- mortgage(100000, 180, 12, 0, MP).
asks the straightforward query as to how much it would cost to finance a $100,000 mortgage at 12 percent for 15 years, and the answer obtained is MP = 1200.17. We can ask the question backwards:
?- mortgage(P, 180, 12, 0, 1200.17).
to obtain the expected answer P = 100000, or ask for how long a mortgage is needed:
?- mortgage(100000, Time, 12, Bal, 1300).
Here we get the answer Time = 147.365. The main point of this example, however, is that we can ask, not for the values of, but for the relationship between P, MP and Bal. For example,
?- mortgage(P, 180, 12, Bal, MP).
gives the answer
P = 0.166783 * Bal + 83.3217 * MP
This particular example illustrates how answer constraints may be viewed as a partial evaluation of the program. In this case, the equation above is the result of partially evaluating the program with respect to Time = 180 and I = 12.