Solution to SICP Exercise 2.11

Structure and Interpretation of Computer Programs

One solution to Exercise 2.11:

(define (mul-interval x y)
(let* ((lx (lower-bound x))
(ux (upper-bound x))
(ly (lower-bound y))
(uy (upper-bound y))
(pos-lx? (positive? lx))
(pos-ux? (positive? ux))
(pos-ly? (positive? ly))
(pos-uy? (positive? uy)))
(cond
; lx ux ly uy example
; ----------------------------------
; + - + + invalid interval
; + - + - invalid interval
; + - - + invalid interval
; + - - - invalid interval
((and pos-lx? (not pos-ux?))
(error "invalid interval" x))

; + + + - invalid interval
; - + + - invalid interval
; - - + - invalid interval
((and pos-ly? (not pos-uy?))
(error "invalid interval" y))

; + + + + (1.2)(2.3) = (2.6)
((and pos-lx? pos-ux? pos-ly? pos-uy?)
(make-interval (* lx ly) (* ux uy)))

; + + - + (1.2)(-2.3) = (-4.6)
((and pos-lx? pos-ux? (not pos-ly?) pos-uy?)
(make-interval (* ux ly) (* ux uy)))

; + + - - (1.2)(-2.-1) = (-4.-1)
((and pos-lx? pos-ux? (not pos-ly?) (not pos-uy?))
(make-interval (* ux ly) (* lx uy)))

; - + + + (-1.2)(2.3) = (-3.6)
((and (not pos-lx?) pos-ux? pos-ly? pos-uy?)
(make-interval (* lx uy) (* ux uy)))

; - + - + (-1.2)(-2.3) = (-4.6) *
((and (not pos-lx?) pos-ux? (not pos-ly?) pos-uy?)
(make-interval (min (* lx uy) (* ux ly))
(* ux uy)))

; - + - - (-1.2)(-2.-1) = (-4.2)
((and (not pos-lx?) pos-ux? (not pos-ly?) (not pos-uy?))
(make-interval (* ux ly) (* lx ly)))

; - - + + (-2.-1)(2.3) = (-6.-2)
((and (not pos-lx?) (not pos-ux?) pos-ly? pos-uy?)
(make-interval (* lx uy) (* ux ly)))

; - - - + (-2.-1)(-2.3) = (-6, 4)
((and (not pos-lx?) (not pos-ux?) (not pos-ly?) pos-uy?)
(make-interval (* lx uy) (* lx ly)))

; - - - - (-2.-1)(-2.-1) = (1.4)
((and (not pos-lx?) (not pos-ux?) (not pos-ly?) (not pos-uy?))
(make-interval (* ux uy) (* lx ly))))))
Advertisements