;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; General intervals ;; This module defines arithmetic on general intervals, which are finite ;; unions of connected sets of reals. These connected sets can always be ;; represented by intervals whose endpoints are in the extended reals. ;; ;; The following procedures are defined ;; CONSTRUCTORS: ;; (s->i X) ;; (s->S X) ;; Pretty Printers: ;; (ppI X) ;; (ppS X) ;; ;; Interval Arithmetic Operators: ;; +S,-S,*S,/S,sqS,negateS, ;; Binary Set operations: ;; intersectS,unionS, ;; union0S -- returns smallest connected interval containing its two arguments ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PRIVATE procedures: ;; CONSTRUCTORS: ;; (s->i X) ;; (s->S X) ;; Pretty Printers: ;; (ppI X) ;; (ppS X) ;; ;; lb ub lc uc ;; (union0 X Y) ;; +I -I *I /I ;; (unionI L) ;; ;; This module uses the "ereal.scm" module which defines ;; CONSTRUCTOR: string->ereal conversion ;; (s->r S) -- parses a string into an extended real ;; CONSTANTS: infinite values, signed zeroes, signed units, and the NaN value ;; +inf -inf -zero zero one -one NaN ;; rounded arithmetic ;; +lo +hi -lo -hi *lo *hi /lo /hi ;; comparison operators: ;; r>0 r<0 r<=0 r>=0 i x) --> parse the string x into an interval (define (s->i x) (let ((LB (.indexOf x "[")) (RB (.indexOf x "]")) (LP (.indexOf x "(")) (RP (.indexOf x ")")) (CO (.indexOf x ","))) (if (and (= LB -1) (= LP -1)) (let ((a (s->r x))) (if (isInfinite a) EMPTY (interval a a #t #t))) (let ((a (s->r (.substring x (+ 1 (max LB LP)) CO))) (b (s->r (.substring x (+ 1 CO) (max RB RP))))) (interval a b (and (> LB -1) (not (equal? -inf a))) (and (> RB -1) (not (equal? +inf b)))))))) ;; (i x y) --> return the interval with bounds x and y (define (i x y X Y) (cond ((/<0,d> (newint b B c C a A -zero #f))) ;; / (((m m)) (union (interval -inf +inf #f #f))) (((p m)) (union (newint b B -zero #f a A c C) ;; / (newint a A d D b B zero #f))) ;; /<0,d> (((n p)) (union (newint a A c C b B d D))) (((m p)) (union (newint a A c C b B c C))) (((p p)) (union (newint a A d D b B c C))) (((z p)(z p1)(z m)(z n)(z n1)) (union (interval zero zero #t #t))) (((p1 z)(p z)(m z)(n1 z)(n z)(z z)) (union )) (else ERROR))))) (define (/I-optimized x y) (if (or (equal? x 'EMPTY) (equal? y EMPTY)) EMPTY (let ((a (lb x)) (A (lc x)) (b (ub x)) (B (uc x)) (c (lb y)) (C (lc y)) (d (ub y)) (D (uc y))) (case (list (iclass x) (iclass0 y)) (((n1 n)) (union (interval (/lo b c) (/hi a d) (and B C (eta/ b c)) (and A D (eta/ a d)))) ) (((n0 n)) (union (interval zero (/hi a d) B (and A D (eta/ a d)))) ) (((m n)) (union (interval (/lo b d) (/hi a d) (and B D (eta/ b d)) (and A D (eta/ a d)))) ) (((p0 n)) (union (interval (/lo b d) zero (and B D (eta/ b d)) A))) (((p1 n)) (union (interval (/lo b d) (/hi a c) (and B D (eta/ b d)) (and A C (eta/ a c)))) ) (((n1 m)) (union (interval -inf (/hi b d) #f (and B D (eta/ b d))) (interval (/lo b c) +inf (and B C (eta/ b c)) #f))) (((n0 m)) (union (interval -inf zero #f B) (interval zero +inf B #f))) (((m m)) (union (interval -inf +inf #f #f))) (((p0 m)) (union (interval -inf zero #f A) (interval zero +inf A #f))) (((p1 m)) (union (interval -inf (/hi a c) #f (and A C (eta/ a c))) (interval (/lo a d) +inf (and A D (eta/ a d)) #f))) (((n1 p)) (union (interval (/lo a c) (/hi b d) (and A C (eta/ a c)) (and B D (eta/ b d)))) ) (((n0 p)) (union (interval (/lo a c) zero (and A C (eta/ a c)) B))) (((m p)) (union (interval (/lo a c) (/hi b c) (and A C (eta/ a c)) (and B C (eta/ b c)))) ) (((p0 p)) (union (interval zero (/hi b c) A (and B C (eta/ b c)))) ) (((p1 p)) (union (interval (/lo a d) (/hi b c) (and A D (eta/ a d)) (and B C (eta/ b c)))) ) (((z p)(z p1)(z m)(z n)(z n1)) (union (interval zero zero #t #t))) (((p1 z)(p z)(m z)(n1 z)(n z)(z z)) (union )) (else ERROR))))) ;; pretty print an exact general interval (define (ppI x) (let ((a (lb x)) (A (lc x)) (b (ub x)) (B (uc x))) (string-append (if A "[" "(") (pp-r a) "," (pp-r b) (if B "]" ")") ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; arithmetic on sets of general intervals ;; this is a closed and total system ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; parse a set of general intervals:: ;; > (s->S "(-inf,-3] [10,11) [799/7,801/7)") ;; ((-Infinity (-3 1) #f #t) ((10 1) (11 1) #t #f) ((799 7) (801 7) #t #f)) (define (s->S S) (define (parse T) (if (not (.hasMoreTokens T)) () (cons (s->i (.nextToken T)) (parse T)))) (cons 'union (parse (java.util.StringTokenizer. S "{} " #f)))) ;; pretty print a set of exact general intervals (define (ppS S) (tryCatch (let ((S (union-elts S))) (if (equal? S ()) "{}" (string-append "{" (ppI (first S)) (apply string-append (map (lambda (x) (string-append " " (ppI x))) (rest S))) "}"))) (lambda(e) (.toString S)))) (define (unionS L) (unionI (apply append (map rest L)))) ;; form the union of the set L of exact general intervals ;; the result is a minimal ordered list of exact general intervals (define (unionI L) ;; union the interval x into the preprocessed union y of intervals (define (union x y) ; (display (list 'union x y)) (newline) (if (null? y) (list x) (if (isLeft (first y) x) (cons (first y) (union x (rest y))) (if (isLeft x (first y)) (cons x y) (union (union0 x (first y)) (rest y)))))) ;; true if interval x is entirely to the left of interval y (define (isLeft x y) (let ((a (lb x)) (A (lc x)) (b (ub x)) (B (uc x)) (c (lb y)) (C (lc y)) (d (ub y)) (D (uc y))) (or (