?add(0.0,1/10) is wrong



Today, I had a problem with a subtle effect.

We know that Maxima preserves the type in numerical addition:

(%i1) 0.0 + 1/10;
(%o1) 0.1

(%i2) 1/10 + 0.0;
(%o2) 0.1

But when I use the macro add in Lisp code I get the following. The type
is not preserved, if the floating point number is the first argument:

(%i3) ?add(0.0,1/10);
(%o3) 1/10

(%i4) ?add(1/10,0.0);
(%o4) 0.1

I call this a bug and it is a very subtle one.

This is the responsible code in opers.lisp:

(defmfun add2 (x y)
  (cond ((numberp x)
         (cond ((numberp y) (+ x y))
               ((zerop x) y)
               (t (simplifya `((mplus) ,x ,y) t))))
        ((eql y 0) x)
        (t (simplifya `((mplus) ,x ,y) t))))

A possible correction is to specialize the first test for a zero
argument:

(defmfun add2 (x y)
  (cond ((numberp x)
         (cond ((numberp y) (+ x y))
               ((eql x 0) y)
               (t (simplifya `((mplus) ,x ,y) t))))
        ((eql y 0) x)
        (t (simplifya `((mplus) ,x ,y) t))))

Or we can use the test function =0:

(defmfun add2 (x y)
  (cond ((numberp x)
         (cond ((numberp y) (+ x y))
               ((=0 x) y)
               (t (simplifya `((mplus) ,x ,y) t))))
        ((=0 y) x)
        (t (simplifya `((mplus) ,x ,y) t))))

A more drastic solution would be not to bypass the simplifier at all:

(defmfun add2 (x y)
  (simplifya `((mplus) ,x ,y) t)))

We do not have the problem with other routines of the file opers.lisp.
All other routines have code which bypasses the simplifier too, but
these routines do a test with =0 or =1.

Dieter Kaiser