Path: utzoo!mnetor!uunet!lll-winken!lll-tis!mordor!sri-spam!sri-unix!quintus!ok From: ok@quintus.UUCP (Richard A. O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: Arithmetic problems with Quintus Prolog Message-ID: <869@cresswell.quintus.UUCP> Date: 12 Apr 88 07:20:13 GMT References: <11111@shemp.CS.UCLA.EDU> Organization: Quintus Computer Systems, Mountain View, CA Lines: 99 In article <11111@shemp.CS.UCLA.EDU>, arman@CS.UCLA.EDU writes: > Please don't take this message as a flame against Quintus. I'd like to > discuss some problems that I think Qprolog should address. Overall, Good sir, why not send your messages to Quintus before sending them to the world? We would have been delighted to discuss these topics with you. Most Prolog vendors have some sort of contact address for customers who have problems: we certainly have, and if I remember correctly AAIS, ALS, and Arity have. It is almost always a good idea to take your problems to your vendor first: you may have already paid for the privilege, and the chances are that they have heard the question before. > Firstly, Qprolog seems to maintain both 0 and -0. Here's what I mean: > | ?- X is 0.0, Y is -X, X=Y. > no > This is a bug! Have you read the IEEE 754 standard lately? -0.0 and 0.0 compare equal, so | ?- X is 0.0, Y is -X, X =:= Y. succeeds, but they do *NOT* behave identically in IEEE 754 or IEEE 854 arithmetic! Things which do not behave identically should not unify. Actually, the floating-point arithmetic you get is machine-dependent: if you try your example on an IBM 370 you'll get the result you were expecting, but that's because IBM 370s antedate the IEEE standard. > Also, the Qprolog lexical analyzer seems to be somewhat brain-damaged. > | ?- X is 1000000000. > X = -73741824 > > I think that in this case the system should have either trapped with > an arithmetic overflow, or it should have unified X with "Infinity" as > C-Prolog does it. Granted "Infinity" is not a great solution, but it's > better than random answers. (1) Section 10.1 of the "System-Dependent Features Manual" says: Integers must be in the range -268435456 (-2^28) to 268435455 (2^28-1) inclusive. At the present time, there is no range checking. (Integer arithmetic that yields numbers outside the above range can be interpreted as modulo 2^29 in this range.) This applies to input as well as to computation. (2) Using "Infinity" here (not an originally intended feature of C Prolog, by the way. C Prolog was originally written for VAXen, and it was years before it was ported to an IEEE754 machine) would be a serious mistake: "Infinity" is a floating-point number but 1000000000 is an integer. (3) We do, however, intend to report out-of-range numbers as syntax errors in some future release. (4) Have you complained to Sun yet about the way their scanf("%d") will silently truncate? Same problem, same reason. > Here is a misfeature that really bugged me. > | ?- Op=..[+,2,2], X is Op. > [ERROR: variable is not bound to a number: 2+2 (error 303)] > [ERROR: invalid arithmetic expression: 2+2 (error 302)] > no > The Qprolog manual mentions this misfeature. The problem is that > is/2 will not accept expressions that contain variables not bound to > numbers. This is bad. It means that if I want a C-Prolog like is/2, > I'll have to write my own! No, you do not have to write your own. All you have to do is | ?- Op =.. [+,2,2], call(X is Op). This has been explained in the Quintus Prolog Newsletter, and there is an example in the library. (People have been doing this in DEC-10 Prolog since 1979 at least.) There are two reasons for this behaviour: first, DEC-10 Prolog compatibility, and second, speed. The fact that you sometimes have to wrap call/1 around the thing when you want to evaluate an arbitrary expression didn't seem too high a price to pay: the "variable is not bound to a number" error message usually indicates a genuine error. > I should also note that floating point numbers are not automatically > coerced into integers. For example: > | ?- 0 is 0.0. > no > > This is a matter of taste I guess. I personally prefer the way that > C-Prolog does it (i.e. when a floating point number fits in an > integer, it is automatically converted) This can become a big > performance issue if one is trying to do number crunching. This is indeed a big performance issue: that automatic conversion is one of the things which makes arithmetic in C Prolog excruciatingly slow. An experimental version of C Prolog with integer arithmetic operations ran length/2 twice as fast. (This means that the way C Prolog handled coalesced integer/float arithmetic cost as much -- on a VAX-11/750 -- as an _interpreted_ procedure call.) The conversion was also a source of error: the round-off error on floating-point numbers which happen to be close to integers is dramatically higher in C Prolog than the round-off error on other floating-point number. (This is not to say that the round-off error on any floating point number is good in C Prolog.) I don't think you will find any numerical analyst prepared to defend that conversion. (Oh yes, this conversion would eliminate the IEEE-mandated distinction between 0.0 and -0.0 as well. That turns out to be an important distinction.) Summary: 0.0 -vs- -0.0 -- mandated by IEEE overflow -- an admitted but documented blemish call(Var is Expr) -- you can get the behaviour you want 1 \== 1.0 -- implicitly mandated by IEEE, required for numerical programming.