I’m working my way through a book, and have been reading about the way Prolog does arithmetic. He explained how `=`

doesn’t cause evaluation, so `1+2=2+1`

will be false, whereas `1+2=:=2+1`

would be true.

Along the way, he said that `<`

would evaluate its arguments.

One of the samples that followed involved writing a predicate to work out the greatest common divisor of two integers. The formula is simple enough…

- if X and Y are equal, then D is X
- if X < Y then D is the GCD of X and Y-X
- if Y < X, do as in 2) but with X and Y reversed

This led me to the following code…

```
gcd(X, X, X).
gcd(X, Y, D) :-
X < Y,
gcd(X, Y-X, D).
gcd(X, Y, D) :-
Y < X,
gcd(Y, X-Y, D).
```

However, this always failed.

Using `trace/0`

(which I’m now beginning to understand), I could see that when it got to the lines with `<`

, it didn’t evaluate the subtraction…

```
[trace] 19 ?- gcd(2, 4, D).
Call: (10) gcd(2, 4, _214) ? creep
Call: (11) 2<4 ? creep
Exit: (11) 2<4 ? creep
Call: (11) gcd(2, 4-2, _214) ? creep
Call: (12) 2<4-2 ? creep
Fail: (12) 2<4-2 ? creep
Redo: (11) gcd(2, 4-2, _214) ? creep
Call: (12) 4-2<2 ? creep
Fail: (12) 4-2<2 ? creep
Fail: (11) gcd(2, 4-2, _214) ? creep
Redo: (10) gcd(2, 4, _214) ? creep
Call: (11) 4<2 ? creep
Fail: (11) 4<2 ? creep
Fail: (10) gcd(2, 4, _214) ? creep
false.
```

If I understand this correctly, then on the 6th line (the first `fail`

), it’s comparing `2`

with `4-2`

, which are not the same thing (when not evaluated) and so the comparison fails.

Why doesn’t `<`

evaluate `4-2`

?

Thanks for any help you can give.

P.S. Rewriting the code solved the problem…

```
gcd(X, X, X).
gcd(X, Y, D) :-
X < Y,
Z is Y-X,
gcd(X, Z, D).
gcd(X, Y, D) :-
Y < X,
Z is X-Y,
gcd(Y, Z, D).
```

…but I would like to understand why the evaluation wasn’t done, when my book says it should be.

Thanks