here's a sketch of a working (but incomplete) interval evaluator.
More stuff is needed from my generic arithmetic package, on my web page..
#| a Maxima interpreter for intervals |#
(in-package :ri) ; real intervals
(defun maxima::$IEVAL(expr)(ieval (meval expr)))
(defun ieval(e)
(cond ((realp e) (widen-ri e e)) ;3.0 -> [3-eps,3+eps]
((atom e)
(error "IEVAL cannot handle ~s" e))
(t (case
(caar e)
(maxima::MPLUS
(cond ((null (cdr e)) 0)
((null (cddr e))(ieval (cadr e)))
(t (+ (ieval (cadr e)) ;this + is a real-interval +
(ieval (cons (car e) (cddr e)))))))
(maxima::MTIMES
(cond ((null (cdr e)) 0)
((null (cddr e))(ieval (cadr e)))
(t (* (ieval (cadr e)) ; this * is a real-interval *
(ieval (cons (car e) (cddr e)))))))
(maxima:: MLIST
;; make a real interval, a structure of type ri
;; check it is a list of 2 items
;; both numbers, in order,
(let ((a (second e))(b (third e)))
(if (and (realp a)
(realp b) ;; optional? (<= a b)
(null(cdddr e)))
(widen-ri (cadr e)(caddr e))
(error "can't convert ~s to interval")))
(otherwise
;; look on property list of (car e)
;; to see if it has an ieval property. eg.
(if (setf fn (get (caar e)
'ieval))
(apply fn (mapcar #'ieval (cdr e)))
(error "IEVAL cannot handle ~s" e)))))))
(setf (get '$includes 'ieval) #'include-ri)
(setf (get '$intersects 'ieval) #'intersect-ri)
(setf (get '$min 'ieval) #'(lambda(x)(ri-lo x)))
(setf (get '$max 'ieval) #'(lambda(x)(ri-hi x)))
(setf (get '$sin 'ieval) #'intsin) ;; etc etc
(defun maxima::$RealInterval(a b )(ri a b))
;; etc