From a59a99c42dffec38be98f3c0449097c80bad40fe Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 11 Oct 2010 13:02:32 -0400 Subject: [PATCH] Changed the TR numeric tower to use the new flonums. --- .../racket/benchmarks/common/typed/fft.rktl | 2 +- .../benchmarks/shootout/typed/moments.rktl | 2 +- ...{inexact-complex.rkt => float-complex.rkt} | 0 .../typed-scheme/private/base-env-numeric.rkt | 43 +++++++++++++------ collects/typed-scheme/private/base-types.rkt | 6 ++- .../scribblings/optimization.scrbl | 15 ++++--- .../scribblings/ts-reference.scrbl | 7 ++- .../typed-scheme/typecheck/tc-expr-unit.rkt | 8 ++-- collects/typed-scheme/types/abbrev.rkt | 15 ++++--- collects/typed-scheme/types/subtype.rkt | 11 +++-- 10 files changed, 72 insertions(+), 37 deletions(-) rename collects/typed-scheme/optimizer/{inexact-complex.rkt => float-complex.rkt} (100%) diff --git a/collects/tests/racket/benchmarks/common/typed/fft.rktl b/collects/tests/racket/benchmarks/common/typed/fft.rktl index d66067825e..297581aed5 100644 --- a/collects/tests/racket/benchmarks/common/typed/fft.rktl +++ b/collects/tests/racket/benchmarks/common/typed/fft.rktl @@ -11,7 +11,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (: pi Float) -(define pi (assert (atan 0 -1) inexact-real?)) +(define pi (assert (atan 0 -1) flonum?)) ;;; FFT -- This is an FFT benchmark written by Harry Barrow. ;;; It tests a variety of floating point operations, diff --git a/collects/tests/racket/benchmarks/shootout/typed/moments.rktl b/collects/tests/racket/benchmarks/shootout/typed/moments.rktl index 9509b02f6e..af55c546b9 100644 --- a/collects/tests/racket/benchmarks/shootout/typed/moments.rktl +++ b/collects/tests/racket/benchmarks/shootout/typed/moments.rktl @@ -12,7 +12,7 @@ (numlist : (Listof Float) '()) (sum : Float 0.0)) (cond ((not (eof-object? line)) - (let ((num (assert (string->number line) inexact-real?))) + (let ((num (assert (string->number line) flonum?))) (loop (read-line) (cons num numlist) (+ num sum)))) (else (unless (null? numlist) diff --git a/collects/typed-scheme/optimizer/inexact-complex.rkt b/collects/typed-scheme/optimizer/float-complex.rkt similarity index 100% rename from collects/typed-scheme/optimizer/inexact-complex.rkt rename to collects/typed-scheme/optimizer/float-complex.rkt diff --git a/collects/typed-scheme/private/base-env-numeric.rkt b/collects/typed-scheme/private/base-env-numeric.rkt index 04806992f3..d40cccca1f 100644 --- a/collects/typed-scheme/private/base-env-numeric.rkt +++ b/collects/typed-scheme/private/base-env-numeric.rkt @@ -5,7 +5,7 @@ (for-template racket/flonum racket/fixnum racket/math racket/unsafe/ops racket/base) (only-in (types abbrev) [-Number N] [-Boolean B] [-Symbol Sym] [-Real R] [-ExactPositiveInteger -Pos])) - (define all-num-types (list -Pos -Nat -Integer -ExactRational -Flonum -Real N)) + (define all-num-types (list -Pos -Nat -Integer -ExactRational -Flonum -InexactReal -Real N)) (define binop (lambda (t [r t]) @@ -19,6 +19,7 @@ (-> -ExactRational -Integer) (-> -NonnegativeFlonum -NonnegativeFlonum) (-> -Flonum -Flonum) + (-> -InexactReal -InexactReal) (-> -Real -Real))) (define (unop t) (-> t t)) @@ -137,11 +138,12 @@ (-not-filter -Integer 0)))] [exact-integer? (make-pred-ty -Integer)] [real? (make-pred-ty -Real)] -[inexact-real? (make-pred-ty -Flonum)] +[flonum? (make-pred-ty -Flonum)] +[inexact-real? (make-pred-ty -InexactReal)] [complex? (make-pred-ty N)] [rational? (make-pred-ty -Real)] [exact? (asym-pred N B (-FS -top (-not-filter -ExactRational 0)))] -[inexact? (asym-pred N B (-FS -top (-not-filter (Un -Flonum -InexactComplex) 0)))] +[inexact? (asym-pred N B (-FS -top (-not-filter (Un -InexactReal -InexactComplex) 0)))] [fixnum? (make-pred-ty -Fixnum)] [positive? (cl->* (-> -Fixnum B : (-FS (-filter -PositiveFixnum 0) -top)) (-> -Integer B : (-FS (-filter -ExactPositiveInteger 0) -top)) @@ -228,6 +230,9 @@ (append (for/list ([t (list -Pos -Nat -Integer -ExactRational -NonnegativeFlonum -Flonum)]) (->* (list) t t)) (list (->* (list) (Un -Pos -NonnegativeFlonum) -NonnegativeFlonum)) (list (->* (list) (Un -Pos -Flonum) -Flonum)) + (list (->* (list -Flonum) (Un -InexactReal -Flonum) -Flonum)) + (list (->* (list -InexactReal -Flonum) (Un -InexactReal -Flonum) -Flonum)) + (list (->* (list) -InexactReal -InexactReal)) (list (->* (list) -Real -Real)) (list (->* (list) (Un -InexactComplex -Flonum) -InexactComplex)) (list (->* (list) N N))))] @@ -240,6 +245,7 @@ (list (->* (list) (Un -Nat -NonnegativeFlonum) -NonnegativeFlonum)) (list (->* (list -Flonum) -Real -Flonum)) (list (->* (list -Real -Flonum) -Real -Flonum)) + (list (->* (list) -InexactReal -InexactReal)) (list (->* (list) -Real -Real)) (list (->* (list) (Un -Real -InexactComplex) -InexactComplex)) (list (->* (list -InexactComplex) N -InexactComplex)) @@ -251,6 +257,7 @@ (->* (list t) t t)) (list (->* (list -Flonum) -Real -Flonum)) (list (->* (list -Real -Flonum) -Real -Flonum)) + (list (->* (list -InexactReal) -InexactReal -InexactReal)) (list (->* (list -Real) -Real -Real)) (list (->* (list) (Un -Real -InexactComplex) -InexactComplex)) (list (->* (list -InexactComplex) N -InexactComplex)) @@ -262,6 +269,8 @@ (->* (list t) t t)) ;; only exact 0 as first argument can cause the result of a division involving inexacts to be exact (list (->* (list -Flonum) -Real -Flonum)) + (list (->* (list -InexactReal -Flonum) -InexactReal -Flonum)) + (list (->* (list -InexactReal) -InexactReal -InexactReal)) (list (->* (list -Real) -Real -Real)) (list (->* (list (Un -Flonum -InexactComplex)) (Un -Real -InexactComplex) -InexactComplex)) (list (->* (list -InexactComplex) -InexactComplex -InexactComplex)) @@ -277,6 +286,7 @@ (->* (list -ExactRational) -ExactRational -ExactRational) (->* (list -NonnegativeFlonum) -Flonum -NonnegativeFlonum) (->* (list -Flonum) -Flonum -Flonum) + (->* (list -InexactReal) -InexactReal -InexactReal) (->* (list -Real) -Real -Real))] [min (cl->* (->* (list -PositiveFixnum) -PositiveFixnum -PositiveFixnum) (->* (list -NonnegativeFixnum) -NonnegativeFixnum -NonnegativeFixnum) @@ -289,6 +299,7 @@ (->* (list -ExactRational) -ExactRational -ExactRational) (->* (list -NonnegativeFlonum) -NonnegativeFlonum -NonnegativeFlonum) (->* (list -Flonum) -Flonum -Flonum) + (->* (list -InexactReal) -InexactReal -InexactReal) (->* (list -Real) -Real -Real))] @@ -298,6 +309,7 @@ (-> -ExactRational -ExactRational) (-> -NonnegativeFlonum -NonnegativeFlonum) (-> -Flonum -Flonum) + (-> -InexactReal -InexactReal) (-> -Real -Real) (-> -InexactComplex -InexactComplex) (-> N N))] @@ -306,6 +318,7 @@ (-> -Integer -Integer) (-> -ExactRational -ExactRational) (-> -Flonum -Flonum) + (-> -InexactReal -InexactReal) (-> -Real -Real) (-> -InexactComplex -InexactComplex) (-> N N))] @@ -353,10 +366,13 @@ (-Pos . -> . -Pos) (-Integer . -> . -Nat) (-Flonum . -> . -NonnegativeFlonum) + (-InexactReal . -> . -InexactReal) (-Real . -> . -Real))] ;; exactness -[exact->inexact (cl->* +[exact->inexact (cl->* + (-Flonum . -> . -Flonum) ; no conversion + (-InexactReal . -> . -InexactReal) ; no conversion (-Real . -> . -Flonum) (N . -> . -InexactComplex))] [inexact->exact (cl->* @@ -384,8 +400,9 @@ [denominator (cl->* (-ExactRational . -> . -Integer) (-Real . -> . -Real))] [rationalize (cl->* (-ExactRational -ExactRational . -> . -ExactRational) - (-Flonum . -> . -Flonum) - (-Real -Real . -> . N))] + (-Flonum -Flonum . -> . -Flonum) + (-InexactReal -InexactReal . -> . -InexactReal) + (-Real -Real . -> . -Real))] [expt (cl->* (-Nat -Nat . -> . -Nat) (-Integer -Nat . -> . -Integer) (-Integer -Integer . -> . -ExactRational) @@ -402,15 +419,16 @@ (-InexactComplex . -> . -InexactComplex) (N . -> . N))] [exp (cl->* (-Flonum . -> . -Flonum) + (-InexactReal . -> . -InexactReal) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] -[cos (cl->* (-Flonum . -> . -Flonum) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] -[sin (cl->* (-Flonum . -> . -Flonum) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] -[tan (cl->* (-Flonum . -> . -Flonum) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] -[acos (cl->* (-Flonum . -> . -Flonum) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] -[asin (cl->* (-Flonum . -> . -Flonum) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] -[atan (cl->* (-Flonum . -> . -Flonum) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N) (-Real -Real . -> . N))] +[cos (cl->* (-Flonum . -> . -Flonum) (-InexactReal . -> . -InexactReal) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] +[sin (cl->* (-Flonum . -> . -Flonum) (-InexactReal . -> . -InexactReal) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] +[tan (cl->* (-Flonum . -> . -Flonum) (-InexactReal . -> . -InexactReal) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] +[acos (cl->* (-Flonum . -> . -Flonum) (-InexactReal . -> . -InexactReal) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] +[asin (cl->* (-Flonum . -> . -Flonum) (-InexactReal . -> . -InexactReal) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N))] +[atan (cl->* (-Flonum . -> . -Flonum) (-InexactReal . -> . -InexactReal) (-Real . -> . -Real) (-InexactComplex . -> . -InexactComplex) (N . -> . N) (-Real -Real . -> . N))] [gcd (cl->* (null -Fixnum . ->* . -Fixnum) (null -Integer . ->* . -Integer))] [lcm (null -Integer . ->* . -Integer)] @@ -422,6 +440,7 @@ (-> -Integer -Nat) (-> -ExactRational -ExactRational) (-> -Flonum -NonnegativeFlonum) + (-> -InexactReal -InexactReal) (-> -Real -Real) (-> -InexactComplex -InexactComplex) (-> N N))] diff --git a/collects/typed-scheme/private/base-types.rkt b/collects/typed-scheme/private/base-types.rkt index 8249e11bb4..c2967cfb84 100644 --- a/collects/typed-scheme/private/base-types.rkt +++ b/collects/typed-scheme/private/base-types.rkt @@ -6,8 +6,10 @@ [Integer -Integer] [Real -Real] [Exact-Rational -ExactRational] -[Float -Flonum] -[Nonnegative-Float -NonnegativeFlonum] +[Float -Flonum] ;; these 2 are the default, 64-bit floats, can be optimized +[Nonnegative-Float -NonnegativeFlonum] ;; associated test is: flonum? +[Inexact-Real -InexactReal] ;; any inexact real. could be 32- or 64-bit float + ;; associated test is: inexact-real? [Exact-Positive-Integer -ExactPositiveInteger] [Exact-Nonnegative-Integer -ExactNonnegativeInteger] [Positive-Fixnum -PositiveFixnum] diff --git a/collects/typed-scheme/scribblings/optimization.scrbl b/collects/typed-scheme/scribblings/optimization.scrbl index f782c5c2a7..ac4f18cae8 100644 --- a/collects/typed-scheme/scribblings/optimization.scrbl +++ b/collects/typed-scheme/scribblings/optimization.scrbl @@ -39,18 +39,17 @@ For example, the following programs both typecheck: (f 3.5)] However, the second one uses more informative types: the -@racket[Float] type includes only -@tech[#:doc '(lib "scribblings/reference/reference.scrbl") #:key -"inexact numbers"]{inexact} -@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{real numbers} +@racket[Float] type includes only 64-bit floating-point numbers whereas the @racket[Real] type includes both exact and @tech[#:doc '(lib "scribblings/reference/reference.scrbl") #:key "inexact numbers"]{inexact} -@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{real numbers}. +@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{real numbers} +and the @racket[Inexact-Real] type includes both 32- and 64-bit +floating-point numbers. Typed Racket's optimizer can optimize the latter program to use @tech[#:doc '(lib "scribblings/reference/reference.scrbl") #:key -"inexact numbers"]{inexact} +"inexact numbers"]{float} -specific operations whereas it cannot do anything with the former program. @@ -65,7 +64,9 @@ instance, the result of @racket[(* 2.0 0)] is @racket[0] which is not a @racket[Float]. This can result in missed optimizations. To prevent this, when mixing floating-point numbers and exact reals, coerce exact reals to floating-point numbers using @racket[exact->inexact]. This is -not necessary when using @racket[+] or @racket[-]. +not necessary when using @racket[+] or @racket[-]. When mixing +floating-point numbers of different precisions, results use the +highest precision possible. On a similar note, the @racket[Inexact-Complex] type is preferable to the @racket[Complex] type for the same reason. Typed Racket can keep diff --git a/collects/typed-scheme/scribblings/ts-reference.scrbl b/collects/typed-scheme/scribblings/ts-reference.scrbl index 7ee9209107..d43e2773cb 100644 --- a/collects/typed-scheme/scribblings/ts-reference.scrbl +++ b/collects/typed-scheme/scribblings/ts-reference.scrbl @@ -39,6 +39,7 @@ any expression of this type will not evaluate to a value.} @defidform[Real] @defidform[Float] @defidform[Nonnegative-Float] +@defidform[Inexact-Real] @defidform[Exact-Rational] @defidform[Integer] @defidform[Natural] @@ -50,7 +51,11 @@ any expression of this type will not evaluate to a value.} @defidform[Zero] )]{These types represent the hierarchy of @rtech{numbers} of Racket. @racket[Integer] includes only @rtech{integers} that are @rtech{exact -numbers}, corresponding to the predicate @racket[exact-integer?]. +numbers}, corresponding to the predicate @racket[exact-integer?]. +@racket{Real} includes both exact and inexact reals. +An @racket{Inexact-Real} can be either 32- or 64-bit floating-point +numbers. @racket{Float} is restricted to 64-bit floats, which are the +default in Racket. @ex[ 7 diff --git a/collects/typed-scheme/typecheck/tc-expr-unit.rkt b/collects/typed-scheme/typecheck/tc-expr-unit.rkt index 6934dd2d10..2bd1285d8a 100644 --- a/collects/typed-scheme/typecheck/tc-expr-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-expr-unit.rkt @@ -41,15 +41,15 @@ [(~var i (3d exact-nonnegative-integer?)) -ExactNonnegativeInteger] [(~var i (3d exact-integer?)) -Integer] [(~var i (3d (conjoin number? exact? rational?))) -ExactRational] - [(~var i (3d (conjoin inexact-real? + [(~var i (3d (conjoin flonum? (lambda (x) (or (positive? x) (zero? x))) (lambda (x) (not (eq? x -0.0)))))) -NonnegativeFlonum] - [(~var i (3d inexact-real?)) -Flonum] + [(~var i (3d flonum?)) -Flonum] [(~var i (3d real?)) -Real] ;; a complex number can't have an inexact imaginary part and an exact real part - [(~var i (3d (conjoin number? (lambda (x) (and (inexact-real? (imag-part x)) - (inexact-real? (real-part x))))))) + [(~var i (3d (conjoin number? (lambda (x) (and (flonum? (imag-part x)) + (flonum? (real-part x))))))) -InexactComplex] [(~var i (3d number?)) -Number] [i:str -String] diff --git a/collects/typed-scheme/types/abbrev.rkt b/collects/typed-scheme/types/abbrev.rkt index 3255022f2a..6603b592b1 100644 --- a/collects/typed-scheme/types/abbrev.rkt +++ b/collects/typed-scheme/types/abbrev.rkt @@ -153,17 +153,20 @@ ;; Numeric hierarchy (define -Number (make-Base 'Number #'number?)) -(define -InexactComplex (make-Base 'InexactComplex +(define -InexactComplex (make-Base 'Inexact-Complex #'(and/c number? (lambda (x) - (and (inexact-real? (imag-part x)) - (inexact-real? (real-part x))))))) + (and (flonum? (imag-part x)) + (flonum? (real-part x))))))) -(define -Flonum (make-Base 'Flonum #'inexact-real?)) +;; default 64-bit floats +(define -Flonum (make-Base 'Flonum #'flonum?)) (define -NonnegativeFlonum (make-Base 'Nonnegative-Flonum - #'(and/c inexact-real? + #'(and/c flonum? (or/c positive? zero?) (lambda (x) (not (eq? x -0.0)))))) +;; could be 32- or 64-bit floats +(define -InexactReal (make-Base 'Inexact-Real #'inexact-real?)) (define -ExactRational (make-Base 'Exact-Rational #'(and/c number? rational? exact?))) @@ -177,7 +180,7 @@ (make-Base 'Negative-Fixnum #'(and/c number? fixnum? negative?))) (define -Zero (-val 0)) -(define -Real (*Un -Flonum -ExactRational)) +(define -Real (*Un -InexactReal -ExactRational)) (define -Fixnum (*Un -PositiveFixnum -NegativeFixnum -Zero)) (define -NonnegativeFixnum (*Un -PositiveFixnum -Zero)) (define -ExactNonnegativeInteger (*Un -ExactPositiveInteger -Zero)) diff --git a/collects/typed-scheme/types/subtype.rkt b/collects/typed-scheme/types/subtype.rkt index 33f0a82eee..16918d209f 100644 --- a/collects/typed-scheme/types/subtype.rkt +++ b/collects/typed-scheme/types/subtype.rkt @@ -233,9 +233,10 @@ ;; value types [((Value: v1) (Value: v2)) (=> unmatch) (if (equal? v1 v2) A0 (unmatch))] ;; now we encode the numeric hierarchy - bletch + [((Base: 'Integer _) (== -Real =t)) A0] [((Base: 'Integer _) (Base: 'Number _)) A0] + [((Base: 'Flonum _) (Base: 'Inexact-Real _)) A0] [((Base: 'Flonum _) (== -Real =t)) A0] - [((Base: 'Integer _) (== -Real =t)) A0] [((Base: 'Flonum _) (Base: 'Number _)) A0] [((Base: 'Exact-Rational _) (Base: 'Number _)) A0] [((Base: 'Integer _) (Base: 'Exact-Rational _)) A0] @@ -263,9 +264,13 @@ [((== -Fixnum =t) (Base: 'Integer _)) A0] [((Base: 'Nonnegative-Flonum _) (Base: 'Flonum _)) A0] + [((Base: 'Nonnegative-Flonum _) (Base: 'Inexact-Real _)) A0] [((Base: 'Nonnegative-Flonum _) (Base: 'Number _)) A0] - [((Base: 'InexactComplex _) (Base: 'Number _)) A0] + [((Base: 'Inexact-Real _) (== -Real =t)) A0] + [((Base: 'Inexact-Real _) (Base: 'Number _)) A0] + + [((Base: 'Inexact-Complex _) (Base: 'Number _)) A0] ;; values are subtypes of their "type" @@ -273,7 +278,7 @@ [((Value: (and n (? number?) (? exact?) (? rational?))) (Base: 'Exact-Rational _)) A0] [((Value: (? exact-nonnegative-integer? n)) (== -Nat =t)) A0] [((Value: (? exact-positive-integer? n)) (Base: 'Exact-Positive-Integer _)) A0] - [((Value: (? inexact-real? n)) (Base: 'Flonum _)) A0] + [((Value: (? flonum? n)) (Base: 'Flonum _)) A0] [((Value: (? real? n)) (== -Real =t)) A0] [((Value: (? number? n)) (Base: 'Number _)) A0]