umber-tests cps) (flonum-test cps))
    (cond
     ((eqv? number-types &number)
      ;; Generic: no reduction.
      (with-cps cps #f))
     ((eqv? number-types &fixnum)
      (with-cps cps
        (build-term
          ($branch kf kt src 'fixnum? #f (arg)))))
     ((logtest type &fixnum)
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (letk kheap ($kargs () ()
                      ($branch kf ktest src 'heap-object? #f (arg))))
        (build-term
          ($branch kheap kt src 'fixnum? #f (arg)))))
     (else
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (build-term
          ($branch kf ktest src 'heap-object? #f (arg))))))))
(define-branch-reducer-aliases number? complex?)

(define-unary-branch-reducer (real? cps kf kt src arg type min max)
  (let ((real-types (logand type &real)))
    (when (or (zero? real-types) (eqv? type real-types))
      (error "should have folded!"))
    (define-syntax-rule (define-heap-number-test test &type pred next-test)
      (define (test cps)
        (if (logtest type &type)
            (with-cps cps
              (let$ kf (next-test))
              (letk k ($kargs () ()
                        ($branch kf kt src 'pred #f (arg))))
              k)
            (next-test cps))))
    (define (done cps) (with-cps cps kf))
    (define-heap-number-test fracnum-test &fraction fracnum? done)
    (define-heap-number-test bignum-test &bignum bignum? fracnum-test)
    (define-heap-number-test flonum-test &flonum flonum? bignum-test)
    (define (heap-number-tests cps) (flonum-test cps))
    (cond
     ((eqv? real-types &real)
      ;; Generic: no reduction.
      (with-cps cps #f))
     ((eqv? real-types &fixnum)
      (with-cps cps
        (build-term
          ($branch kf kt src 'fixnum? #f (arg)))))
     ((logtest type &fixnum)
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (letk kheap ($kargs () ()
                      ($branch kf ktest src 'heap-object? #f (arg))))
        (build-term
          ($branch kheap kt src 'fixnum? #f (arg)))))
     (else
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (build-term
          ($branch kf ktest src 'heap-object? #f (arg))))))))

(define-unary-branch-reducer (rational? cps kf kt src arg type min max)
  (let ((number-types (logand type &number)))
    (when (or (zero? number-types) (eqv? type (logand type &exact-number)))
      (error "should have folded!"))
    (define-syntax-rule (define-heap-number-test test &type pred next-test)
      (define (test cps)
        (if (logtest type &type)
            (with-cps cps
              (let$ kf (next-test))
              (letk k ($kargs () ()
                        ($branch kf kt src 'pred #f (arg))))
              k)
            (next-test cps))))
    (define (done cps) (with-cps cps kf))
    (define-heap-number-test fracnum-test &fraction fracnum? done)
    (define-heap-number-test bignum-test &bignum bignum? fracnum-test)
    (define (heap-number-tests cps) (bignum-test cps))
    (cond
     ((logtest type (logior &complex &flonum))
      ;; Too annoying to inline inf / nan tests.
      (with-cps cps #f))
     ((eqv? number-types &fixnum)
      (with-cps cps
        (build-term
          ($branch kf kt src 'fixnum? #f (arg)))))
     ((logtest type &fixnum)
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (letk kheap ($kargs () ()
                      ($branch kf ktest src 'heap-object? #f (arg))))
        (build-term
          ($branch kheap kt src 'fixnum? #f (arg)))))
     (else
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (build-term
          ($branch kf ktest src 'heap-object? #f (arg))))))))

(define-unary-branch-reducer (integer? cps kf kt src arg type min max)
  (define &integer-types (logior &fixnum &bignum &flonum &complex))
  (let ((integer-types (logand type &integer-types)))
    (when (or (zero? integer-types) (eqv? type (logand type &exact-integer)))
      (error "should have folded!"))
    (define-syntax-rule (define-heap-number-test test &type pred next-test)
      (define (test cps)
        (if (logtest type &type)
            (with-cps cps
              (let$ kf (next-test))
              (letk k ($kargs () ()
                        ($branch kf kt src 'pred #f (arg))))
              k)
            (next-test cps))))
    (define (done cps) (with-cps cps kf))
    (define-heap-number-test bignum-test &bignum bignum? done)
    (define (heap-number-tests cps) (bignum-test cps))
    (cond
     ((logtest type (logior &complex &flonum))
      ;; Too annoying to inline integer tests.
      (with-cps cps #f))
     ((eqv? integer-types &fixnum)
      (with-cps cps
        (build-term
          ($branch kf kt src 'fixnum? #f (arg)))))
     ((logtest type &fixnum)
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (letk kheap ($kargs () ()
                      ($branch kf ktest src 'heap-object? #f (arg))))
        (build-term
          ($branch kheap kt src 'fixnum? #f (arg)))))
     (else
      (with-cps cps
        (let$ ktest (heap-number-tests))
        (build-term
          ($branch kf ktest src 'heap-object? #f (arg))))))))

(define-unary-branch-reducer (exact-integer? cps kf kt src arg type min max)
  (let ((integer-types (logand type &exact-integer)))
    (when (or (zero? integer-types) (eqv? type integer-types))
      (error "should have folded!"))
    (cond
     ((eqv? integer-types &fixnum)
      (with-cps cps
        (build-term
          ($branch kf kt src 'fixnum? #f (arg)))))
     ((eqv? integer-types &bignum)
      (with-cps cps
        (letk kbig? ($kargs () ()
                      ($branch kf kt src 'bignum? #f (arg))))
        (build-term
          ($branch kf kbig? src 'heap-object? #f (arg)))))
     (else
      ;; No reduction.
      (with-cps cps #f)))))

(define-unary-branch-reducer (exact? cps kf kt src arg type min max)
  (let ((exact-types (logand type &exact-number)))
    (when (or (zero? exact-types) (eqv? type exact-types))
      (error "should have folded!"))
    ;; We have already passed a number? check, so we can assume either
    ;; fixnum or heap number.
    (define-syntax-rule (define-number-test test &type pred next-test)
      (define (test cps)
        (if (logtest type &type)
            (with-cps cps
              (let$ kf (next-test))
              (letk k ($kargs () ()
                        ($branch kf kt src 'pred #f (arg))))
              k)
            (next-test cps))))
    (define (done cps) (with-cps cps kf))
    (define-number-test fracnum-test &fraction fracnum? done)
    (define-number-test bignum-test &bignum bignum? fracnum-test)
    (define-number-test fixnum-test &fixnum fixnum? bignum-test)
    (define (number-tests cps) (fixnum-test cps))
    (cond
     ((eqv? exact-types &exact-number)
      ;; Generic: no reduction.
      (with-cps cps #f))
     (else
      (with-cps cps
        (let$ ktest (number-tests))
        (build-term
          ($continue ktest #f ($values ()))))))))

(define-unary-branch-reducer (inexact? cps kf kt src arg type min max)
  (define &inexact-number (logior &flonum &complex))
  (let ((inexact-types (logand type &inexact-number)))
    (when (or (zero? inexact-types) (eqv? type inexact-types))
      (error "should have folded!"))
    ;; We have already passed a number? check, so we can assume either
    ;; fixnum or heap number.
    (cond
     ((eqv? (logand type &exact-number) &fixnum)
      (with-cps cps
        (build-term
          ($branch kt kf src 'fixnum? #f (arg)))))
     ((logtest type &fixnum)
      (cond
       ((eqv? inexact-types &flonum)
        (with-cps cps
          (letk kflo ($kargs () ()
                       ($branch kf kt src 'flonum? #f (arg))))
          (build-term
            ($branch kflo kf src 'fixnum? #f (arg)))))
       ((eqv? inexact-types &complex)
        (with-cps cps
          (letk kcomp ($kargs () ()
                        ($branch kf kt src 'compnum? #f (arg))))
          (build-term
            ($branch kcomp kf src 'fixnum? #f (arg)))))
       (else
        ;; Generic: no reduction.
        (with-cps cps #f))))
     ((eqv? inexact-types &flonum)
      (with-cps cps
        (build-term
          ($branch kf kt src 'flonum? #f (arg)))))
     ((eqv? inexact-types &complex)
      (with-cps cps
        (build-term
          ($branch kf kt src 'compnum? #f (arg)))))
     (else
      ;; Still specialize, as we avoid heap-object?.
      (with-cps cps
        (letk kcomp ($kargs () ()
                      ($branch kf kt src 'compnum? #f (arg))))
        (build-term
          ($branch kcomp kt src 'flonum? #f (arg))))))))

(define-binary-branch-reducer (eq? cps kf kt src
                                   arg0 type0 min0 max0
                                   arg1 type1 min1 max1)
  (materialize-constant
   type0 min0 max0
   (lambda (const)
     (with-cps cps
       (build-term
         ($branch kf kt src 'eq-constant? const (arg1)))))
   (lambda ()
     (materialize-constant
      type1 min1 max1
      (lambda (const)
        (with-cps cps
          (build-term
            ($branch kf kt src 'eq-constant? const (arg0)))))
      (lambda () (with-cps cps #f))))))


