;-*- Mode: Lisp -*- ;;;; Author: Paul Dietz ;;;; Created: Sun Aug 18 14:08:57 2002 ;;;; Contains: Tests for function REDUCE (in-package :cl-test) (deftest reduce-list.1 (reduce #'cons '(a b c d e f)) (((((a . b) . c) . d) . e) . f)) (deftest reduce-list.2 (reduce #'cons '(a b c d e f) :from-end t) (a b c d e . f)) (deftest reduce-list.3 (reduce #'cons '(a b c d e f) :initial-value 'z) ((((((z . a) . b) . c) . d) . e) . f)) (deftest reduce-list.4 (reduce #'cons '(a b c d e f) :from-end t :initial-value 'g) (a b c d e f . g)) (deftest reduce-list.5 (reduce #'cons '(a b c d e f) :from-end nil) (((((a . b) . c) . d) . e) . f)) (deftest reduce-list.6 (reduce #'cons '(a b c d e f) :from-end 17) (a b c d e . f)) (deftest reduce-list.7 (reduce #'cons '(a b c d e f) :end nil) (((((a . b) . c) . d) . e) . f)) (deftest reduce-list.8 (reduce #'cons '(a b c d e f) :end 3) ((a . b) . c)) (deftest reduce-list.9 (reduce #'cons '(a b c d e f) :start 1 :end 4) ((b . c) . d)) (deftest reduce-list.10 (reduce #'cons '(a b c d e f) :start 1 :end 4 :from-end t) (b c . d)) (deftest reduce-list.11 (reduce #'cons '(a b c d e f) :start 1 :end 4 :from-end t :initial-value nil) (b c d)) (deftest reduce-list.12 (reduce 'cons '(a b c d e f)) (((((a . b) . c) . d) . e) . f)) (deftest reduce-list.13 (reduce #'+ nil) 0) (deftest reduce-list.14 (reduce #'+ '(1 2 3) :start 0 :end 0) 0) (deftest reduce-list.15 (reduce #'+ '(1 2 3) :key '1+) 9) (deftest reduce-list.16 (reduce #'cons '(1 2 3) :key '1+ :from-end t :initial-value nil) (2 3 4)) (deftest reduce-list.17 (reduce #'+ '(1 2 3 4 5 6 7) :key '1+ :start 2 :end 6) 22) ;;;;;;; (deftest reduce-array.1 (reduce #'cons #(a b c d e f)) (((((a . b) . c) . d) . e) . f)) (deftest reduce-array.2 (reduce #'cons #(a b c d e f) :from-end t) (a b c d e . f)) (deftest reduce-array.3 (reduce #'cons #(a b c d e f) :initial-value 'z) ((((((z . a) . b) . c) . d) . e) . f)) (deftest reduce-array.4 (reduce #'cons #(a b c d e f) :from-end t :initial-value 'g) (a b c d e f . g)) (deftest reduce-array.5 (reduce #'cons #(a b c d e f) :from-end nil) (((((a . b) . c) . d) . e) . f)) (deftest reduce-array.6 (reduce #'cons #(a b c d e f) :from-end 17) (a b c d e . f)) (deftest reduce-array.7 (reduce #'cons #(a b c d e f) :end nil) (((((a . b) . c) . d) . e) . f)) (deftest reduce-array.8 (reduce #'cons #(a b c d e f) :end 3) ((a . b) . c)) (deftest reduce-array.9 (reduce #'cons #(a b c d e f) :start 1 :end 4) ((b . c) . d)) (deftest reduce-array.10 (reduce #'cons #(a b c d e f) :start 1 :end 4 :from-end t) (b c . d)) (deftest reduce-array.11 (reduce #'cons #(a b c d e f) :start 1 :end 4 :from-end t :initial-value nil) (b c d)) (deftest reduce-array.12 (reduce 'cons #(a b c d e f)) (((((a . b) . c) . d) . e) . f)) (deftest reduce-array.13 (reduce #'+ #(1 2 3) :start 0 :end 0) 0) (deftest reduce-array.14 (let ((a (make-array '(8) :initial-contents '(1 2 3 4 5 6 7 8) :fill-pointer 4))) (reduce #'+ a)) 10) (deftest reduce-array.15 (let ((a (make-array '(8) :initial-contents '(1 2 3 4 5 6 7 8) :fill-pointer 4))) (reduce #'+ a :end nil)) 10) (deftest reduce-array.16 (let ((a (make-array '(8) :initial-contents '(1 2 3 4 5 6 7 8) :fill-pointer 4))) (reduce #'+ a :from-end t)) 10) (deftest reduce-array.17 (let ((a (make-array '(8) :initial-contents '(1 2 3 4 5 6 7 8) :fill-pointer 4))) (reduce #'+ a :initial-value 1)) 11) (deftest reduce-array.18 (let ((a (make-array '(8) :initial-contents '(1 2 3 4 5 6 7 8) :fill-pointer 4))) (reduce #'+ a :initial-value 1 :start 2)) 8) (deftest reduce-array.19 (let ((a (make-array '(8) :initial-contents '(1 2 3 4 5 6 7 8) :fill-pointer 4))) (reduce #'+ a :end 3)) 6) ;;; Specialized vectors (deftest reduce-array.20 (do-special-integer-vectors (v #(1 0 0 1 1 0) nil) (assert (eql (reduce #'+ v) 3))) nil) (deftest reduce-array.21 (do-special-integer-vectors (v #(1 0 0 1 1 0) nil) (assert (equal (reduce #'cons v :from-end t :initial-value nil) '(1 0 0 1 1 0)))) nil) (deftest reduce-array.22 (do-special-integer-vectors (v #(1 2 3 4 5 6 7) nil) (assert (eql (reduce #'+ v) 28)) (assert (eql (reduce #'+ v :from-end t) 28)) (assert (eql (reduce #'+ v :start 1) 27)) (assert (eql (reduce #'+ v :initial-value 10) 38)) (assert (eql (reduce #'+ v :end 6) 21))) nil) (deftest reduce-array.23 (let* ((len 10) (expected (* 1/2 (1+ len) len))) (loop for etype in '(short-float single-float double-float long-float) for vals = (loop for i from 1 to len collect (coerce i etype)) for vec = (make-array len :initial-contents vals :element-type etype) for result = (reduce #'+ vec) unless (= result (coerce expected etype)) collect (list etype vals vec result))) nil) (deftest reduce-array.24 (let* ((len 10) (expected (* 1/2 (1+ len) len))) (loop for cetype in '(short-float single-float double-float long-float) for etype = `(complex ,cetype) for vals = (loop for i from 1 to len collect (complex (coerce i cetype) (coerce (- i) cetype))) for vec = (make-array len :initial-contents vals :element-type etype) for result = (reduce #'+ vec) unless (= result (complex (coerce expected cetype) (coerce (- expected) cetype))) collect (list etype vals vec result))) nil) (deftest reduce-array.25 (do-special-integer-vectors (v (vector 0 most-positive-fixnum 0 most-positive-fixnum 0) nil) (assert (eql (reduce #'+ v) (* 2 most-positive-fixnum)))) nil) ;;;;;;;; (deftest reduce.error.1 (check-type-error #'(lambda (x) (reduce 'cons x)) #'sequencep) nil) (deftest reduce.error.2 (signals-error (reduce) program-error) t) (deftest reduce.error.3 (signals-error (reduce #'list nil :start) program-error) t) (deftest reduce.error.4 (signals-error (reduce #'list nil 'bad t) program-error) t) (deftest reduce.error.5 (signals-error (reduce #'list nil 'bad t :allow-other-keys nil) program-error) t) (deftest reduce.error.6 (signals-error (reduce #'list nil 1 2) program-error) t) (deftest reduce.error.7 (signals-error (locally (reduce 'cons 'a) t) type-error) t) (deftest reduce.error.8 (signals-error (reduce #'identity '(a b c)) program-error) t) (deftest reduce.error.9 (signals-error (reduce #'cons '(a b c) :key #'cons) program-error) t) (deftest reduce.error.10 (signals-error (reduce #'cons '(a b c) :key #'car) type-error) t) ;;;;;;;; (deftest reduce-string.1 (reduce #'cons "abcdef") (((((#\a . #\b) . #\c) . #\d) . #\e) . #\f)) (deftest reduce-string.2 (reduce #'cons "abcdef" :from-end t) (#\a #\b #\c #\d #\e . #\f)) (deftest reduce-string.3 (reduce #'cons "abcdef" :initial-value 'z) ((((((z . #\a) . #\b) . #\c) . #\d) . #\e) . #\f)) (deftest reduce-string.4 (reduce #'cons "abcdef" :from-end t :initial-value 'g) (#\a #\b #\c #\d #\e #\f . g)) (deftest reduce-string.5 (reduce #'cons "abcdef" :from-end nil) (((((#\a . #\b) . #\c) . #\d) . #\e) . #\f)) (deftest reduce-string.6 (reduce #'cons "abcdef" :from-end 17) (#\a #\b #\c #\d #\e . #\f)) (deftest reduce-string.7 (reduce #'cons "abcdef" :end nil) (((((#\a . #\b) . #\c) . #\d) . #\e) . #\f)) (deftest reduce-string.8 (reduce #'cons "abcdef" :end 3) ((#\a . #\b) . #\c)) (deftest reduce-string.9 (reduce #'cons "abcdef" :start 1 :end 4) ((#\b . #\c) . #\d)) (deftest reduce-string.10 (reduce #'cons "abcdef" :start 1 :end 4 :from-end t) (#\b #\c . #\d)) (deftest reduce-string.11 (reduce #'cons "abcdef" :start 1 :end 4 :from-end t :initial-value nil) (#\b #\c #\d)) (deftest reduce-string.12 (reduce 'cons "abcdef") (((((#\a . #\b) . #\c) . #\d) . #\e) . #\f)) (deftest reduce-string.13 (reduce #'+ "abc" :start 0 :end 0) 0) (deftest reduce-string.14 (let ((s (make-array '(8) :initial-contents "abcdefgh" :fill-pointer 6 :element-type 'character))) (coerce (reduce #'(lambda (x y) (cons y x)) s :initial-value nil) 'string)) "fedcba") (deftest reduce-string.15 (let ((s (make-array '(8) :initial-contents "abcdefgh" :fill-pointer 6 :element-type 'character))) (coerce (reduce #'(lambda (x y) (cons y x)) s :initial-value nil :start 1) 'string)) "fedcb") (deftest reduce-string.16 (let ((s (make-array '(8) :initial-contents "abcdefgh" :fill-pointer 6 :element-type 'character))) (coerce (reduce #'(lambda (x y) (cons y x)) s :end nil :initial-value nil) 'string)) "fedcba") (deftest reduce-string.17 (let ((s (make-array '(8) :initial-contents "abcdefgh" :fill-pointer 6 :element-type 'character))) (coerce (reduce #'(lambda (x y) (cons y x)) s :end 4 :initial-value nil) 'string)) "dcba") (deftest reduce-string.18 (do-special-strings (s "12345" nil) (let ((x (reduce #'(lambda (x y) (cons y x)) s))) (assert (equal x '(#\5 #\4 #\3 #\2 . #\1))))) nil) (deftest reduce-string.19 (do-special-strings (s "54321" nil) (let ((x (reduce #'cons s :from-end t))) (assert (equal x '(#\5 #\4 #\3 #\2 . #\1))))) nil) (deftest reduce-string.20 (do-special-strings (s "12345" nil) (let ((x (reduce #'(lambda (x y) (cons y x)) s :initial-value nil))) (assert (equal x '(#\5 #\4 #\3 #\2 #\1))))) nil) ;;;;;;;; (deftest reduce-bitstring.1 (reduce #'cons #*001101) (((((0 . 0) . 1) . 1) . 0) . 1)) (deftest reduce-bitstring.2 (reduce #'cons #*001101 :from-end t) (0 0 1 1 0 . 1)) (deftest reduce-bitstring.3 (reduce #'cons #*001101 :initial-value 'z) ((((((z . 0) . 0) . 1) . 1) . 0) . 1)) (deftest reduce-bitstring.4 (reduce #'cons #*001101 :from-end t :initial-value 'g) (0 0 1 1 0 1 . g)) (deftest reduce-bitstring.5 (reduce #'cons #*001101 :from-end nil) (((((0 . 0) . 1) . 1) . 0) . 1)) (deftest reduce-bitstring.6 (reduce #'cons #*001101 :from-end 17) (0 0 1 1 0 . 1)) (deftest reduce-bitstring.7 (reduce #'cons #*001101 :end nil) (((((0 . 0) . 1) . 1) . 0) . 1)) (deftest reduce-bitstring.8 (reduce #'cons #*001101 :end 3) ((0 . 0) . 1)) (deftest reduce-bitstring.9 (reduce #'cons #*001101 :start 1 :end 4) ((0 . 1) . 1)) (deftest reduce-bitstring.10 (reduce #'cons #*001101 :start 1 :end 4 :from-end t) (0 1 . 1)) (deftest reduce-bitstring.11 (reduce #'cons #*001101 :start 1 :end 4 :from-end t :initial-value nil) (0 1 1)) (deftest reduce-bitstring.12 (reduce 'cons #*001101) (((((0 . 0) . 1) . 1) . 0) . 1)) (deftest reduce-bitstring.13 (reduce #'+ #(1 1 1) :start 0 :end 0) 0) (deftest reduce-bitstring.14 (let ((s (make-array '(8) :initial-contents '(0 0 1 0 1 1 0 1) :fill-pointer 6 :element-type 'bit))) (reduce #'+ s)) 3) (deftest reduce-bitstring.15 (let ((s (make-array '(8) :initial-contents '(0 0 1 0 1 1 0 1) :fill-pointer 6 :element-type 'bit))) (reduce #'+ s :start 3)) 2) (deftest reduce-bitstring.16 (let ((s (make-array '(8) :initial-contents '(0 0 1 0 1 1 0 1) :fill-pointer 6 :element-type 'bit))) (reduce #'+ s :start 3 :initial-value 10)) 12) (deftest reduce-bitstring.17 (let ((s (make-array '(8) :initial-contents '(0 0 1 0 1 1 0 1) :fill-pointer 6 :element-type 'bit))) (reduce #'+ s :end nil)) 3) (deftest reduce-bitstring.18 (let ((s (make-array '(8) :initial-contents '(1 1 1 1 1 1 1 1) :fill-pointer 6 :element-type 'bit))) (reduce #'+ s :start 2 :end 4)) 2) ;;; Order of evaluation tests (deftest reduce.order.1 (let ((i 0) x y) (values (reduce (progn (setf x (incf i)) #'cons) (progn (setf y (incf i)) '(a b c))) i x y)) ((a . b) . c) 2 1 2) (deftest reduce.order.2 (let ((i 0) a b c d e f g) (values (reduce (progn (setf a (incf i)) #'cons) (progn (setf b (incf i)) '(a b c d e f)) :from-end (progn (setf c (incf i)) t) :initial-value (progn (setf d (incf i)) 'nil) :start (progn (setf e (incf i)) 1) :end (progn (setf f (incf i)) 4) :key (progn (setf g (incf i)) #'identity) ) i a b c d e f g)) (b c d) 7 1 2 3 4 5 6 7) (deftest reduce.order.3 (let ((i 0) a b c d e f g) (values (reduce (progn (setf a (incf i)) #'cons) (progn (setf b (incf i)) '(a b c d e f)) :key (progn (setf c (incf i)) #'identity) :end (progn (setf d (incf i)) 4) :start (progn (setf e (incf i)) 1) :initial-value (progn (setf f (incf i)) 'nil) :from-end (progn (setf g (incf i)) t) ) i a b c d e f g)) (b c d) 7 1 2 3 4 5 6 7) ;;; Keyword tests (deftest reduce.allow-other-keys.1 (reduce #'+ '(1 2 3) :allow-other-keys t) 6) (deftest reduce.allow-other-keys.2 (reduce #'+ '(1 2 3) :allow-other-keys nil) 6) (deftest reduce.allow-other-keys.3 (reduce #'+ '(1 2 3) :bad t :allow-other-keys t) 6) (deftest reduce.allow-other-keys.4 (reduce #'+ '(1 2 3) :allow-other-keys t :bad t) 6) (deftest reduce.allow-other-keys.5 (reduce #'+ '(1 2 3) :allow-other-keys t :allow-other-keys nil :bad t) 6) (deftest reduce.allow-other-keys.6 (reduce #'+ '(1 2 3) :allow-other-keys t :bad t :allow-other-keys nil) 6) (deftest reduce.allow-other-keys.7 (reduce #'+ '(1 2 3) :bad t :allow-other-keys t :allow-other-keys nil) 6) (deftest reduce.allow-other-keys.8 (reduce #'cons '(1 2 3) :allow-other-keys t :from-end t :bad t :initial-value nil) (1 2 3)) (deftest reduce.keywords.9 (reduce #'cons '(1 2 3) :from-end t :from-end nil :initial-value nil :initial-value 'a) (1 2 3))