PrologEZ
Data & computation ยท Lesson 15 of 43

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 + 2

To 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 ** 200

Comparison

Arithmetic comparison evaluates both sides:

goalmeaning
A =:= Bequal as numbers
A =\= Bnot equal as numbers
A < B, A > Bless / greater
A =< B, A >= Bless-or-equal / greater-or-equal (note: =<, not <=)
?- 3 + 4 =:= 2 * 3 + 1
?- 1 =:= 1.0
?- 1 == 1.0
?- 5 =< 5

The 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 + 1

That'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:

  1. is_even(N): true when the integer N is even.
  2. max_of(X, Y, Max): Max is the larger of X and Y (don't use the built-in max). There must be exactly one answer, even when X and Y are equal.