#lang sicp
(define (make-interval a b) (cons a b))
(define (lower-bound int) (car int))
(define (upper-bound int) (cdr int))
(define (center i) (/ (+ (lower-bound i) (upper-bound i)) 2))
(define (width i) (/ (- (upper-bound i) (lower-bound i)) 2))
(define (percent i) (/ (width i) (center i)))
(define (make-percent-center x p)
    (make-interval (- x (* x p)) (+ x (* x p))))
(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 (contains? interval x)
  (and (<= (lower-bound interval) x) (<= x (upper-bound interval))))
(define (div-interval x y)
  (if (not (contains? y 0))
      (mul-interval x (make-interval (/ 1.0 (upper-bound y))
                                     (/ 1.0 (lower-bound y))))
      (error "div-interval called with interval containing zero")))
;; (define (disp-interval int)
;;   (display "[") (display (lower-bound int)) (display ", ") 
;;   (display (upper-bound int)) (display "]"))
(define (disp-interval int)
  (display (center int)) (display "(1 ± ") (display (percent int)) 
  (display ")"))
(define (disp-interval-op i1 i2 func character)
    (disp-interval i1) (display character) (disp-interval i2) (display " = ")
    (disp-interval (func i1 i2)) (newline))

(let ((A (make-percent-center 0.1 0.8))
      (B (make-percent-center 0.001 0.8))
      (C (make-percent-center 7.0 0.1))
      (one (make-percent-center 1.0 0)))
  (display "A = ") (disp-interval A) (newline)
  (display "B = ") (disp-interval B) (newline)
  (display "C = ") (disp-interval C) (newline)
  (display "Division of A/B+C/B:") (newline)
  (disp-interval (add-interval (div-interval A B) (div-interval C B)))
  (newline)
  (display "Division of (A+C)/B:") (newline)
  (disp-interval (div-interval (add-interval A C) B))
  (newline)
  (newline)
  (display "And, just to confirm the issue:") (newline)
  (display "Division of (AB)/(A+B):") (newline)
  (disp-interval (div-interval (mul-interval A B) (add-interval A B)))
  (newline)
  (display "Division of 1/(1/A+1/B):") (newline)
  (disp-interval (div-interval one (add-interval (div-interval one A) (div-interval one B)))))
