#lang sicp
(define (make-interval a b) (cons a b))
(define (lower-bound int) (car int))
(define (upper-bound int) (cdr int))
(define (add-interval x y)
  (make-interval (+ (lower-bound x) (lower-bound y))
                 (+ (upper-bound x) (upper-bound y))))
(define (sub-interval A B)
  (make-interval (- (lower-bound A) (upper-bound B))
                 (- (upper-bound A) (lower-bound B))))
(define (mul-interval x y)
  (let ((p1 (* (lower-bound x)
               (lower-bound y)))
        (p2 (* (lower-bound x)
               (upper-bound y)))
        (p3 (* (upper-bound x)
               (lower-bound y)))
        (p4 (* (upper-bound x)
               (upper-bound y))))
    (make-interval (min p1 p2 p3 p4)
                   (max p1 p2 p3 p4))))
(define (div-interval x y)
  (mul-interval x 
                (make-interval 
                 (/ 1.0 (upper-bound y)) 
                 (/ 1.0 (lower-bound y)))))
(define (width-interval int)
  (- (upper-bound int) (lower-bound int)))
(define (disp-interval int)
  (display "[") (display (lower-bound int)) (display ", ") 
  (display (upper-bound int)) (display "]"))
(define (disp-interval-op a b c d func character)
  (let ((i1 (make-interval a b))
        (i2 (make-interval c d)))
    (disp-interval i1) (display character) (disp-interval i2) (display " = ")
    (disp-interval (func i1 i2)) (newline)))

(display "Multiplication of two width 2 intervals result in a width 3 interval:") (newline)
(disp-interval-op -0.5 1.5 -1.5 0.5 mul-interval " * ")

(display "Multiplication of two width 2 intervals result in a width 4 interval:") (newline)
(disp-interval-op 0 2 0 2 mul-interval " * ")

(display "Division of two width 1 intervals creates a tiny interval:") (newline)
(disp-interval-op 2 3 10 11 div-interval " / ")

(display "Division of two width 1 intervals creates a huge interval:") (newline)
(disp-interval-op 2 3 0.1 1.1 div-interval " / ")
