2.11|

$ cd ~

SICP Exercise 2.11

The table for the min and max for each combination is as folows:

\(L_x\) \(U_x\) \(L_y\) \(U_y\) \(L_x L_y\) \(L_x U_y\) \(U_x L_y\) \(U_x U_y\) min max
+ + + + + + + + \(L_x L_y\) \(U_x U_y\)
+ + - + - + + + \(U_x L_y\) \(U_x U_y\)
+ + - - - - - - \(U_x L_y\) \(L_x U_y\)
- + + + - - + + \(L_x U_y\) \(U_x U_y\)
- + + - + - - + \(min(L_xU_y, U_x L_y)\) \(max (L_x L_y, U_x U_y)\)
- + - - + + - - \(U_x L_y\) \(L_x L_y\)
- - + + - - - - \(L_x U_y\) \(U_x L_y\)
- - - + + - + - \(L_x L_y\) \(L_x U_y\)
- - - - + + + + \(U_x U_y\) \(L_x L_y\)

So our procedure now becomes:

(define (mul-interval x y)
  (define not-negative?
           (lambda (x) (not (negative? x))))
  (let ((lx (lower-bound x))
        (ux (upper-bound x))
        (ly (lower-bound y))
        (uy (upper-bound y)))
    (cond ((and (not-negative? lx)
                (not-negative? ux)
                (not-negative? ly)
                (not-negative? uy)))
          (make-interval (* lx ly)
                         (* ux uy)))
    (cond ((and (not-negative? lx)
                (not-negative? ux)
                (negative? ly)
                (not-negative? uy)))
          (make-interval (* ux ly)
                         (* ux uy)))
    (cond ((and (not-negative? lx)
                (not-negative? ux)
                (negative? ly)
                (negative? uy)))
          (make-interval (* ux ly)
                         (* lx uy)))
    (cond ((and (negative? lx)
                (not-negative? ux)
                (not-negative? ly)
                (not-negative? uy)))
          (make-interval (* lx uy)
                         (* ux uy)))
    (cond ((and (negative? lx)
                (not-negative? ux)
                (not-negative? ly)
                (negative? uy)))
          (make-interval (min (* lx uy) (* ux ly))
                         (max (* lx ly) (* ux uy)))
    (cond ((and (negative? lx)
                (not-negative? ux)
                (negative? ly)
                (negative? uy)))
          (make-interval (* ux ly)
                         (* lx ly)))
    (cond ((and (negative? lx)
                (negative? ux)
                (not-negative? ly)
                (not-negative? uy)))
          (make-interval (* lx uy)
                         (* ux ly)))
    (cond ((and (negative? lx)
                (negative? ux)
                (negative? ly)
                (not-negative? uy)))
          (make-interval (* lx ly)
                         (* lx uy)))
    (cond ((and (negative? lx)
                (negative? ux)
                (negative? ly)
                (negative? uy)))
          (make-interval (* ux uy)
                         (* lx ly))))))