When working with bounded reals, some of the usual rules of arithmetic no longer hold. In particular, it is not always possible to determine whether one bounded real is larger, smaller, or the same as another. This is because, if the intervals overlap, it is not possible to know the relationship between the true values.

An example of this can be seen in Figure 9.2. If the
true value of X is X_{1}, then depending upon whether the
true value of Y is (say) Y_{1}, Y_{2} or
Y_{3}, we have X > Y, X =:= Y or X < Y,
respectively.

Different classes of predicate deal with the undecidable cases in different ways:

- Arithmetic comparison
- (</2, =:=/2, etc.)
If the comparison cannot be determined definitively, the comparison succeeds
but a delayed goal is left behind, indicating that the result of the
computation is contingent on the relationship actually being true.
Examples:
?- X = 0.2__0.3, Y = 0.0__0.1, X > Y. X = 0.2__0.3 Y = 0.0__0.1 Yes ?- X = 0.2__0.3, Y = 0.0__0.1, X < Y. No ?- X = 0.0__0.1, Y = 0.0__0.1, X < Y. X = 0.0__0.1 Y = 0.0__0.1 Delayed goals: 0.0__0.1 < 0.0__0.1 Yes ?- X = Y, X = 0.0__0.1, X < Y. No

- Term equality or comparison
- (=/2, ==/2, compare/3, @</2, etc.)
These predicates consider bounded reals from a purely syntactic point of
view: they determine how the bounded reals compare syntactically, without
taking into account their meaning. Two bounded reals are considered equal
if and only if their bounds are syntactically the same (note that the
floating point numbers 0.0 and -0.0 are considered to be syntactically
different). A unique ordering is also defined between bounded reals which
do not have identical bounds; see the documentation for compare/3 for
details. This is important as it means predicates such as sort/2 behave in
a sensible fashion when they encounter bounded reals (in particular, they do
not throw exceptions or leave behind large numbers of meaningless delayed
goals) — though one does need to be careful when comparing or sorting
things of different types.
Examples:
?- X = 0.2__0.3, Y = 0.0__0.1, X == Y. No ?- X = 0.0__0.1, Y = 0.0__0.1, X == Y. X = 0.0__0.1 Y = 0.0__0.1 Yes ?- X = 0.2__0.3, Y = 0.0__0.1, compare(R, X, Y). R = > X = 0.2__0.3 Y = 0.0__0.1 Yes ?- X = 0.1__3.0, Y = 0.2__0.3, compare(R, X, Y). R = < X = 0.1__3.0 Y = 0.2__0.3 Yes ?- X = 0.0__0.1, Y = 0.0__0.1, compare(R, X, Y). R = = X = 0.0__0.1 Y = 0.0__0.1 Yes ?- sort([-5.0, 1.0__1.0], Sorted). Sorted = [1.0__1.0, -5.0] % 1.0__1.0 > -5.0, but 1.0__1.0 @< -5.0 Yes

Note that the potential undecidability of arithmetic comparisons has implications when writing general code. For example, a common thing to do is test the value of a number, with different code being executed depending on whether or not it is above a certain threshold; e.g.

( X >= 0 -> % Code A ; % Code B ) |

When writing code such as the above, if X could be a bounded real, one ought to decide what should happen if X’s bounds span the threshold value. In the above example, if X = -0.1__0.1 then a delayed goal -0.1__0.1 >= 0 will be left behind and Code A executed. If one does not want the delayed goal, one can instead write:

( not X >= 0 -> % Code B ; % Code A ) |

The use of not ensures that any actions performed during the test (in particular the set up of any delayed goals) are backtracked, regardless of the outcome of the test.

Finally, if one wishes Code B to be executed instead of Code A in the case of an overlap, one can reverse the sense of the test:

( not X < 0 -> % Code A ; % Code B ) |