proposal for object-oriented dispatch on sign



Proposal: Modify sign (not $sign) to use object-oriented dispatch. 
The function associated with %asin extends the current sign function, I think:

(%i1) assume(-1 < x, x < 0);
(%o1) [x > - 1, x < 0]

(%i2) sign(asin(x));
(%o2) neg

The code (the frob macro is based on similar code in trigi): Comments? 

(defvar *sign-function* (make-hash-table :size 32)
   "Hash table mapping a maxima function identifier to a CL function that determines the 
    sign of an expression.")

(macrolet ((frob (fun sign-fun) `(setf (gethash ',fun *sign-function*) ,sign-fun)))
  (frob mtimes 'sign-mtimes)
  (frob mplus 'sign-mplus)
  (frob mexpt 'sign-mexpt)
  (frob %log 'sign-log)
  (frob mabs 'sign-mabs)
  (frob $min #'(lambda (x) (sign-minmax (caar x) (cdr x))))
  (frob $max #'(lambda (x) (sign-minmax (caar x) (cdr x))))
  (frob %csc #'(lambda (x) (sign (inv* (cons (ncons (zl-get (caar x) 'recip)) (cdr x))))))
  (frob %csch #'(lambda (x) (sign (inv* (cons (ncons (zl-get (caar x) 'recip)) (cdr x))))))
  (frob %asin #'(lambda (x) (if (and (eq t (mgrp (cadr x) -1)) (eq t (mgrp 1 (cadr x)))) (sign (cadr x)) (sign-any x))))
  (frob %signum #'(lambda (x) (sign (cadr x))))
  (frob %erf #'(lambda (x) (sign (cadr x)))))
  		 
(defmfun sign (x)
  (cond ((mnump x) (setq sign (rgrp x 0) minus nil odds nil evens nil))
	((and *complexsign* (atom x) (eq x '$%i))
	 ;; In Complex Mode the sign of %i is $imaginary.
	 (setq sign '$imaginary))
	((atom x) (if (eq x '$%i) (imag-err x)) (sign-any x))
	((gethash (mop x) *sign-function*) (funcall (gethash (mop x) *sign-function*) x))
	((specrepp x) (sign (specdisrep x)))
	((kindp (caar x) '$posfun) (sign-posfun x))
	((and (kindp (caar x) '$oddfun) (kindp (caar x) '$increasing)) (sign-oddinc x))
	(t (sign-any x))))

--Barton