Arithmetic
Why `X = 1 + 2` is not 3, and how `is` fixes it.
Prolog terms are just structures, 1 + 2 is the term +(1, 2), not the number 3. Unification won't compute it:
?- X = 1 + 2To evaluate arithmetic you use is/2. The right-hand side is evaluated; the result is unified with the left-hand side.
?- X is 1 + 2?- X is 7 / 2?- X is 8 / 2?- X is 7 // 2, Y is 7 mod 2, Z is -7 // 2?- X is 2 ** 10, Y is 2 ^ 100?- X is max(3, 9) + abs(-4) * 2?- X is sqrt(16), Y is pi, Z is truncate(3.99), W is round(2.5)Big integers for free
SWI-Prolog integers are unbounded. Overflow isn't a thing:
?- X is 2 ** 200Comparison
Arithmetic comparison evaluates both sides:
| goal | meaning |
|---|---|
A =:= B | equal as numbers |
A =\= B | not equal as numbers |
A < B, A > B | less / greater |
A =< B, A >= B | less-or-equal / greater-or-equal (note: =<, not <=) |
?- 3 + 4 =:= 2 * 3 + 1?- 1 =:= 1.0?- 1 == 1.0?- 5 =< 5The classic mistake
is needs its right side fully known. Using an unbound variable is an error, not a failed query, an error:
?- X is Y + 1?- Y = 4, X is Y + 1That's why Prolog arithmetic is not "reversible" like most relations: X is 3 + 4 works, but 7 is X + 4 does not. (Constraint logic programming, a later lesson, fixes this.)
Counting and ranges
between(Low, High, X) generates integers; succ(A, B) relates consecutive integers; numlist/3 builds a list.
?- between(1, 5, X)?- findall(S, (between(1, 5, X), S is X * X), Squares)?- succ(X, 5)?- numlist(1, 5, L), sum_list(L, S)Arithmetic in your own predicates
Put is in the body, after the variables it needs have been bound:
area(circle(R), A) :- A is pi * R * R.
area(rect(W, H), A) :- A is W * H.
% Fahrenheit from Celsius
fahrenheit(C, F) :- F is C * 9 / 5 + 32.?- area(rect(3, 4), A)?- area(circle(1), A)?- fahrenheit(100, F)Exercise: Even numbers and the larger of two
Define two predicates:
is_even(N): true when the integerNis even.max_of(X, Y, Max):Maxis the larger ofXandY(don't use the built-inmax). There must be exactly one answer, even whenXandYare equal.