;;;;
;;;; This is a set of routines for operating on intervals. It
;;;; implements a simple interval arithmetic package. Although SBCL
;;;;
;;;; This is a set of routines for operating on intervals. It
;;;; implements a simple interval arithmetic package. Although SBCL
;; bound is really unbounded, so drop the openness.
(let ((new-val (normalize-bound (first val))))
(when new-val
;; bound is really unbounded, so drop the openness.
(let ((new-val (normalize-bound (first val))))
(when new-val
-;;; Determine if two intervals X and Y intersect. Return T if so. If
-;;; CLOSED-INTERVALS-P is T, the treat the intervals as if they were
-;;; closed. Otherwise the intervals are treated as they are.
+;;; Determine whether two intervals X and Y intersect. Return T if so.
+;;; If CLOSED-INTERVALS-P is T, the treat the intervals as if they
+;;; were closed. Otherwise the intervals are treated as they are.
;;;
;;; Thus if X = [0, 1) and Y = (1, 2), then they do not intersect
;;; because no element in X is in Y. However, if CLOSED-INTERVALS-P
;;;
;;; Thus if X = [0, 1) and Y = (1, 2), then they do not intersect
;;; because no element in X is in Y. However, if CLOSED-INTERVALS-P
(cond ((and lo (= (bound-value p) (bound-value lo)))
(not (and (consp p) (numberp lo))))
((and hi (= (bound-value p) (bound-value hi)))
(cond ((and lo (= (bound-value p) (bound-value lo)))
(not (and (consp p) (numberp lo))))
((and hi (= (bound-value p) (bound-value hi)))
;;; true interval arithmetic here, but it's complicated because we
;;; have float and integer types and bounds can be open or closed.
;;; true interval arithmetic here, but it's complicated because we
;;; have float and integer types and bounds can be open or closed.
(defun interval-neg (x)
(declare (type interval x))
(make-interval :low (bound-func #'- (interval-high x))
:high (bound-func #'- (interval-low x))))
(defun interval-neg (x)
(declare (type interval x))
(make-interval :low (bound-func #'- (interval-high x))
:high (bound-func #'- (interval-low x))))
(defun interval-add (x y)
(declare (type interval x y))
(make-interval :low (bound-binop + (interval-low x) (interval-low y))
:high (bound-binop + (interval-high x) (interval-high y))))
(defun interval-add (x y)
(declare (type interval x y))
(make-interval :low (bound-binop + (interval-low x) (interval-low y))
:high (bound-binop + (interval-high x) (interval-high y))))
(defun interval-sub (x y)
(declare (type interval x y))
(make-interval :low (bound-binop - (interval-low x) (interval-high y))
:high (bound-binop - (interval-high x) (interval-low y))))
(defun interval-sub (x y)
(declare (type interval x y))
(make-interval :low (bound-binop - (interval-low x) (interval-high y))
:high (bound-binop - (interval-high x) (interval-low y))))
;;; a utility for defining derive-type methods of integer operations. If
;;; the types of both X and Y are integer types, then we compute a new
;;; a utility for defining derive-type methods of integer operations. If
;;; the types of both X and Y are integer types, then we compute a new
;; (float +0.0 +0.0) => (member 0.0)
;; (float -0.0 -0.0) => (member -0.0)
((and lo-float-zero-p hi-float-zero-p)
;; (float +0.0 +0.0) => (member 0.0)
;; (float -0.0 -0.0) => (member -0.0)
((and lo-float-zero-p hi-float-zero-p)
(if (= lo-float-zero-p hi-float-zero-p)
;; (float +0.0 +0.0) => (member 0.0)
;; (float -0.0 -0.0) => (member -0.0)
(if (= lo-float-zero-p hi-float-zero-p)
;; (float +0.0 +0.0) => (member 0.0)
;; (float -0.0 -0.0) => (member -0.0)
'integer
(numeric-type-class result-type))
:format (numeric-type-format result-type)
:low (interval-low result)
:high (interval-high result)))
'integer
(numeric-type-class result-type))
:format (numeric-type-format result-type)
:low (interval-low result)
:high (interval-high result)))