Interval arithmetic (just a few functions)

Dear list,

I have seen this nice package for interval arithmetic:

:- use_module(library(clpBNR)).

example :-
    X = 1,
    Y::real(-0.1, 0.1),
    {Z == X + Y},
    writeln(sum: Z).

What I am wondering is (I apologize if the question is trivial): The package clpBNR implements the arithmetic as a constraint solver, which is nice, but way to much for me (and maybe too slow, I don’t know). Is there a simpler, “functional” alternative, basically one that would just duplicate is/2. In my use case, the LHS of ==/2 is always a variable, and everything on the RHS is instantiated.

Best regards,

Matthias

1 Like

No, not a trivial question. You are correct that clpBNR implements real relational arithmetic over intervals. I think what you’re looking for is extending the current functional arithmetic system with a new interval numeric type, similar to bounded reals in Eclipse.

I’m not aware of any packages implementing bounded reals for SWI-Prolog but, now that rounding modes are supported, this could implemented in Prolog as a new isi predicate (with operator def.) which evaluates the RHS expression (containing bounded real values) and unifies the result with LHS. You would have to define the structure of a bounded real, e.g., (L,H), and write the code to perform the evaluation over expressions of mixed numeric types. (You could use the clpBNR primitives as a guide but they implement relational semantics rather than functional so not an exact fit; functional semantics would actually be simpler.) The complexity of this job depends on the set arithmetic functions you want to support.

1 Like

Thanks. In fact, the subset of arithmetic functions is rather small, not more than highschool mathematics. I want to use it to deal with the rounding errors of my students, example:

t-ratio in statistics, T = (D - Mu) / (S / sqrt(N)), but the D is already from a previous task, and whenever you see “dec2”, I suspect that my students truncate or round the result to maybe 2 digits.

writeln(tratio),
interval(5.7 ... 5.8, D),
interval(4.0 ... 4.0, Mu),
interval(3.8 ... 3.8, S),
interval(24.0 ... 24.0, N),
interval(dec2(frac(D - Mu, dec2(S / dec2(sqrt(N))))), T),
writeln(t --> T).

resulting in a “range” of 2.17 to 2.34 for the accepted solution.

When I am done, I’ll make a “pack” out of the intervals, and, of course, I would much appreciate if you could have a short glance at it.

If the functions you’re interested in are monotonic, the implementation is fairly straight forward. There may be the odd special case, e.g., division by an interval containing 0, but that should be manageable. There’s a fair amount of published material on interval arithmetic if you need the details.

One of clpBNR's primary concerns is correctness over the reals in the face of floating point rounding errors, i.e., whether any result is guaranteed to contain the real value of the expression. This determines whether rounding modes need to be controlled.

1 Like

I’ve seen the literature. 25 cases to distinguish for division :slight_smile:

1 Like

Another option (since you seem to only care about a few decimal places) you could use, library(clpfd) and use integer arithmetic (dividing the results by a suitable number at the end).

You may have to implement some approximation of sqrt(N), since I don’t think clpfd provides that.

Thanks for the link; I wasn’t aware of this work on ball arithmetic (a variant of interval arithmetic). From what I understand, it provides the (more than) necessary machinery to do sound arithmetic over real numbers. It appears the actual C library is only (?) 2-3 MB (Setup — Arb 2.23.0 documentation) so not too bad.

If one were considering a new Prolog arithmetic type (i.e., reals), this would be a good candidate library (analogous to GMP for unbounded integers and rationals).

I was assuming the O.P. was looking for a SWI-Prolog “pack”, not a C library. And If he only needed “a few functions”, this would be overkill IMO.

Not quite sure which problems you’re referring to. Many of the relevant global flags support the requirement to support both ISO arithmetic and IEEE 754 semantics within SWI-Prolog, a problem ARB doesn’t have. (The flags were also chosen to provide Eclipse compatibility.) Rounding control is stateless when using the roundtoward/1 arithmetic function. But, in general, I agree with the objective (stateless arithmetic libraries).