2003-02-11 19:23:30 -05:00
|
|
|
; Copyright (c) 2003 RT Happe <rthappe at web de>
|
|
|
|
; See the file COPYING distributed with the Scheme Untergrund Library
|
|
|
|
|
|
|
|
;;; generic sequence procedures -- no explicit dispatch on sequence type
|
2003-03-13 13:38:28 -05:00
|
|
|
;;;
|
|
|
|
;;; The code should work with the names of the elementary sequence
|
2003-02-11 19:23:30 -05:00
|
|
|
;;; operations bound to the umbrella procedures that dispatch on the
|
|
|
|
;;; sequence type, or to the specific procedures of a particular type,
|
2003-03-13 13:38:28 -05:00
|
|
|
;;;
|
2003-02-11 19:23:30 -05:00
|
|
|
;;; sequence->list
|
2003-02-12 16:48:40 -05:00
|
|
|
;;; sequence-fill!
|
2003-03-20 14:09:05 -05:00
|
|
|
;;; sequence-tabulate!
|
2003-02-11 19:23:30 -05:00
|
|
|
;;; subsequence
|
2003-02-12 16:48:40 -05:00
|
|
|
;;; sequence-copy
|
2003-03-22 17:22:15 -05:00
|
|
|
;;; sequence-copy!
|
2003-02-12 16:48:40 -05:00
|
|
|
;;; sequence-append
|
2003-02-15 19:32:31 -05:00
|
|
|
;;; sequence-map sequences-map sequences-map/maker
|
2003-03-22 17:22:15 -05:00
|
|
|
;;; sequence-map-into! sequences-map-into!
|
2003-02-13 19:47:58 -05:00
|
|
|
;;; sequence-for-each sequences-for-each
|
|
|
|
;;; sequence-fold sequences-fold
|
|
|
|
;;; sequence-fold-right sequence-fold-right
|
2003-03-22 17:22:15 -05:00
|
|
|
;;; sequence-null?
|
2003-02-13 19:47:58 -05:00
|
|
|
;;; sequence-any sequences-any
|
|
|
|
;;; sequence-every sequences-every
|
2003-03-13 13:38:28 -05:00
|
|
|
;;; sequence= sequences=
|
2003-02-11 19:23:30 -05:00
|
|
|
|
2003-02-14 21:48:52 -05:00
|
|
|
(define (id x) x)
|
|
|
|
|
2003-02-15 19:32:31 -05:00
|
|
|
;; seqs : nonempty proper list of sequences
|
2003-03-20 14:09:05 -05:00
|
|
|
;; compute min sequence-length [ for internal use ]
|
2003-02-15 19:32:31 -05:00
|
|
|
(define (sequences-length seqs)
|
|
|
|
;; we got the time, we got the space ...
|
|
|
|
(apply min (map sequence-length seqs)))
|
|
|
|
|
|
|
|
|
2003-02-14 21:48:52 -05:00
|
|
|
(define (sequence->list s . opts)
|
|
|
|
(let-optionals opts ((start 0) (end (sequence-length s)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length s))
|
|
|
|
sequence->list)
|
2003-02-14 21:48:52 -05:00
|
|
|
(let loop ((i end) (xs '()))
|
|
|
|
(if (= i start) xs
|
|
|
|
(loop (- i 1) (cons (sequence-ref s (- i 1)) xs))))))
|
2003-02-11 19:23:30 -05:00
|
|
|
|
|
|
|
;; unspecified return value as usual
|
2003-02-14 21:48:52 -05:00
|
|
|
(define (sequence-fill! s x . opts)
|
|
|
|
(let-optionals opts ((start 0) (end (sequence-length s)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length s))
|
|
|
|
sequence-fill!)
|
2003-02-15 19:32:31 -05:00
|
|
|
(let loop ((i start))
|
2003-02-14 21:48:52 -05:00
|
|
|
(if (< i end)
|
2003-03-13 13:38:28 -05:00
|
|
|
(begin
|
2003-02-11 19:23:30 -05:00
|
|
|
(sequence-set! s i x)
|
|
|
|
(loop (+ i 1)))))))
|
2003-03-13 13:38:28 -05:00
|
|
|
|
2003-02-11 19:23:30 -05:00
|
|
|
|
2003-03-20 14:09:05 -05:00
|
|
|
(define (sequence-tabulate! s start proc len)
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start (+ start len) (sequence-length s))
|
2003-03-20 14:09:05 -05:00
|
|
|
sequence-tabulate!)
|
|
|
|
(do ((i 0 (+ i 1)))
|
|
|
|
((= i len) s)
|
|
|
|
(sequence-set! s (+ start i) (proc i))))
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-02-15 19:32:31 -05:00
|
|
|
(define (sequence-copy/maker maker s . opts)
|
|
|
|
(let-optionals opts ((start 0)
|
|
|
|
(end (sequence-length s)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length s))
|
|
|
|
sequence-copy/maker)
|
2003-02-15 19:32:31 -05:00
|
|
|
(let* ((len (- end start))
|
|
|
|
(ss (maker len)))
|
|
|
|
(do ((i 0 (+ i 1)))
|
|
|
|
((= i len) ss)
|
|
|
|
(sequence-set! ss i (sequence-ref s (+ start i)))))))
|
2003-02-11 19:23:30 -05:00
|
|
|
|
2003-02-12 16:48:40 -05:00
|
|
|
|
2003-02-14 21:48:52 -05:00
|
|
|
(define (sequence-copy s . opts)
|
2003-02-15 19:32:31 -05:00
|
|
|
(apply sequence-copy/maker
|
|
|
|
(lambda (n) (make-another-sequence s n))
|
|
|
|
s opts))
|
2003-03-13 13:38:28 -05:00
|
|
|
|
2003-02-15 19:32:31 -05:00
|
|
|
|
2003-03-22 17:22:15 -05:00
|
|
|
(define (sequence-copy! s1 start1 s0 . opts)
|
|
|
|
(let-optionals opts ((start0 0) (end0 (sequence-length s0)))
|
|
|
|
(assert (<= 0 start0 end0 (sequence-length s0))
|
|
|
|
sequence-copy!)
|
|
|
|
(assert (<= 0 start1 (+ start1 (- end0 start0)) (sequence-length s1))
|
|
|
|
sequence-copy!)
|
|
|
|
(do ((i0 start0 (+ i0 1))
|
|
|
|
(i1 start1 (+ i1 1)))
|
|
|
|
((= i0 end0) (unspecific))
|
|
|
|
(sequence-set! s1 i1 (sequence-ref s0 i0)))))
|
|
|
|
|
2003-02-15 19:32:31 -05:00
|
|
|
;; ...
|
|
|
|
(define (subsequence s start end)
|
|
|
|
(sequence-copy s start end))
|
2003-02-12 16:48:40 -05:00
|
|
|
|
|
|
|
|
2003-02-13 19:47:58 -05:00
|
|
|
(define (sequence-fold kons nil s . opts)
|
|
|
|
(let-optionals opts ((start 0)
|
|
|
|
(end (sequence-length s)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length s))
|
|
|
|
sequence-fold)
|
2003-02-13 19:47:58 -05:00
|
|
|
(let loop ((subtotal nil) (i start))
|
2003-02-12 16:48:40 -05:00
|
|
|
(if (= i end) subtotal
|
|
|
|
(loop (kons (sequence-ref s i) subtotal) (+ i 1))))))
|
|
|
|
|
|
|
|
|
2003-02-13 19:47:58 -05:00
|
|
|
(define (sequences-fold kons nil seq . seqs)
|
2003-02-12 16:48:40 -05:00
|
|
|
(if (null? seqs)
|
2003-02-13 19:47:58 -05:00
|
|
|
(sequence-fold kons nil seq)
|
2003-02-12 16:48:40 -05:00
|
|
|
(let* ((ss (cons seq seqs))
|
2003-02-13 19:47:58 -05:00
|
|
|
;; are we morally obliged to use FOLD here?
|
2003-02-15 19:32:31 -05:00
|
|
|
(end (sequences-length ss)))
|
2003-02-12 16:48:40 -05:00
|
|
|
(let loop ((subtotal nil) (i 0))
|
|
|
|
(if (= i end) subtotal
|
|
|
|
(loop (apply kons (append! (map (lambda (s)
|
|
|
|
(sequence-ref s i))
|
|
|
|
ss)
|
|
|
|
(list subtotal)))
|
|
|
|
(+ i 1)))))))
|
2003-03-13 13:38:28 -05:00
|
|
|
|
|
|
|
|
2003-02-13 19:47:58 -05:00
|
|
|
(define (sequence-fold-right kons nil s . opts)
|
|
|
|
(let-optionals opts ((start 0)
|
|
|
|
(end (sequence-length s)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length s))
|
|
|
|
sequence-fold-right)
|
2003-02-13 19:47:58 -05:00
|
|
|
(let loop ((subtotal nil) (i end))
|
|
|
|
(if (= i start) subtotal
|
|
|
|
(loop (kons (sequence-ref s (- i 1)) subtotal) (- i 1))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (sequences-fold-right kons nil seq . seqs)
|
|
|
|
(if (null? seqs)
|
|
|
|
(sequence-fold-right kons nil seq)
|
|
|
|
(let* ((ss (cons seq seqs))
|
|
|
|
;; are we morally obliged to use FOLD here?
|
2003-02-15 19:32:31 -05:00
|
|
|
(end (sequences-length ss)))
|
2003-02-13 19:47:58 -05:00
|
|
|
(let loop ((subtotal nil) (i (- end 1)))
|
|
|
|
(if (= i -1) subtotal
|
|
|
|
(loop (apply kons (append! (map (lambda (s)
|
|
|
|
(sequence-ref s i))
|
|
|
|
ss)
|
|
|
|
(list subtotal)))
|
|
|
|
(- i 1)))))))
|
|
|
|
|
|
|
|
|
2003-02-12 16:48:40 -05:00
|
|
|
(define (sequence-append . seqs)
|
|
|
|
(if (null? seqs) (vector)
|
|
|
|
(let* ((len (apply + (map sequence-length seqs)))
|
|
|
|
(res (make-another-sequence (car seqs) len)))
|
|
|
|
(let loop ((ss seqs) (start 0))
|
|
|
|
(if (null? ss) res
|
|
|
|
(let* ((s (car ss)) (end (sequence-length s)))
|
|
|
|
(do ((i 0 (+ i 1)))
|
|
|
|
((= i end) (loop (cdr ss) (+ start end)))
|
|
|
|
(sequence-set! res (+ start i)
|
|
|
|
(sequence-ref s i)))))))))
|
|
|
|
|
|
|
|
|
2003-02-13 19:47:58 -05:00
|
|
|
(define (sequence-for-each proc seq . opts)
|
|
|
|
(let-optionals opts ((start 0) (end (sequence-length seq)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length seq))
|
|
|
|
sequence-for-each)
|
2003-02-13 19:47:58 -05:00
|
|
|
(do ((i start (+ i 1)))
|
|
|
|
((= i end) (unspecific))
|
|
|
|
(proc (sequence-ref seq i)))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (sequences-for-each proc seq . seqs)
|
2003-02-12 16:48:40 -05:00
|
|
|
(let* ((ss (cons seq seqs))
|
2003-02-15 19:32:31 -05:00
|
|
|
(end (sequences-length ss)))
|
2003-02-12 16:48:40 -05:00
|
|
|
(do ((i 0 (+ i 1)))
|
|
|
|
((= i end) (unspecific))
|
|
|
|
(apply proc (map (lambda (s) (sequence-ref s i)) ss)))))
|
|
|
|
|
|
|
|
|
2003-02-15 19:32:31 -05:00
|
|
|
(define (sequence-map/maker maker proc seq . opts)
|
|
|
|
(let-optionals opts ((start 0)
|
|
|
|
(end (sequence-length seq)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length seq))
|
|
|
|
sequence-map/maker)
|
2003-02-15 19:32:31 -05:00
|
|
|
(let ((res (maker (- end start))))
|
2003-02-13 19:47:58 -05:00
|
|
|
(do ((i start (+ i 1)))
|
|
|
|
((= i end) res)
|
2003-02-15 19:32:31 -05:00
|
|
|
(sequence-set! res (- i start)
|
|
|
|
(proc (sequence-ref seq i)))))))
|
2003-02-13 19:47:58 -05:00
|
|
|
|
|
|
|
|
2003-02-15 19:32:31 -05:00
|
|
|
(define (sequence-map proc seq . opts)
|
2003-03-22 17:22:15 -05:00
|
|
|
(apply sequence-map/maker
|
2003-02-15 19:32:31 -05:00
|
|
|
(lambda (n) (make-another-sequence seq n))
|
|
|
|
seq opts))
|
|
|
|
|
|
|
|
|
|
|
|
(define (sequences-map/maker maker proc seq . seqs)
|
2003-02-12 16:48:40 -05:00
|
|
|
(let* ((ss (cons seq seqs))
|
2003-02-15 19:32:31 -05:00
|
|
|
(end (sequences-length ss))
|
|
|
|
(res (maker end)))
|
2003-02-12 16:48:40 -05:00
|
|
|
(do ((i 0 (+ i 1)))
|
|
|
|
((= i end) res)
|
|
|
|
(sequence-set! res i (apply proc (map (lambda (s) (sequence-ref s i))
|
|
|
|
ss))))))
|
|
|
|
|
2003-02-15 19:32:31 -05:00
|
|
|
|
|
|
|
(define (sequences-map proc seq . seqs)
|
|
|
|
(apply sequences-map/maker (lambda (n) (make-another-sequence seq n))
|
|
|
|
proc seq seqs))
|
|
|
|
|
|
|
|
|
2003-03-22 17:22:15 -05:00
|
|
|
(define (sequence-map-into! s1 proc s0 . opts)
|
|
|
|
(let-optionals opts ((start1 0)
|
|
|
|
(end1 (sequence-length s1))
|
|
|
|
(start0 0))
|
|
|
|
(assert (<= 0 start0 (sequence-length s0))
|
|
|
|
sequence-map-into!)
|
|
|
|
(assert (<= 0 start1 (sequence-length s1))
|
|
|
|
sequence-map-into!)
|
|
|
|
(assert (<= (- end1 start1) (- (sequence-length s0) start0))
|
|
|
|
sequence-map-into!)
|
|
|
|
(do ((i0 start0 (+ i0 1))
|
|
|
|
(i1 start1 (+ i1 1)))
|
|
|
|
((= i1 end1) s1)
|
|
|
|
(sequence-set! s1 i1 (proc (sequence-ref s0 i0))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (sequences-map-into! seq proc . seqs)
|
|
|
|
(let ((end (sequence-length seq)))
|
|
|
|
(do ((i 0 (+ i 1)))
|
|
|
|
((= i end) seq)
|
|
|
|
(sequence-set! seq i (apply proc
|
|
|
|
(map (lambda (s) (sequence-ref s i))
|
|
|
|
seqs))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (sequence-null? s)
|
|
|
|
(= (sequence-length s) 0))
|
|
|
|
|
|
|
|
|
2003-02-14 21:48:52 -05:00
|
|
|
(define (sequence-any foo? seq . opts)
|
2003-02-13 19:47:58 -05:00
|
|
|
(let-optionals opts ((start 0) (end (sequence-length seq)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length seq))
|
|
|
|
sequence-any)
|
2003-02-13 19:47:58 -05:00
|
|
|
(let loop ((i start))
|
|
|
|
(cond ((= i end) #f)
|
2003-02-14 21:48:52 -05:00
|
|
|
((foo? (sequence-ref seq i)) => id)
|
2003-02-13 19:47:58 -05:00
|
|
|
(else (loop (+ i 1)))))))
|
2003-02-12 16:48:40 -05:00
|
|
|
|
2003-02-13 19:47:58 -05:00
|
|
|
|
2003-03-13 13:38:28 -05:00
|
|
|
(define (sequences-any foo? . seqs)
|
2003-02-13 19:47:58 -05:00
|
|
|
(if (null? seqs) #f
|
2003-02-15 19:32:31 -05:00
|
|
|
(let ((end (sequences-length seqs)))
|
2003-02-12 16:48:40 -05:00
|
|
|
(let loop ((i 0))
|
2003-02-13 19:47:58 -05:00
|
|
|
(cond ((= i end) #f)
|
2003-02-14 21:48:52 -05:00
|
|
|
((apply foo? (map (lambda (seq) (sequence-ref seq i))
|
2003-02-12 16:48:40 -05:00
|
|
|
seqs))
|
2003-02-14 21:48:52 -05:00
|
|
|
=> id)
|
2003-02-13 19:47:58 -05:00
|
|
|
(else (loop (+ i 1))))))))
|
|
|
|
|
|
|
|
|
2003-02-14 21:48:52 -05:00
|
|
|
(define (sequence-every foo? seq . opts)
|
2003-02-13 19:47:58 -05:00
|
|
|
(let-optionals opts ((start 0) (end (sequence-length seq)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= 0 start end (sequence-length seq))
|
|
|
|
sequence-every)
|
2003-02-14 21:48:52 -05:00
|
|
|
(let loop ((i start) (res #t))
|
|
|
|
(cond ((= i end) res)
|
|
|
|
((foo? (sequence-ref seq i))
|
|
|
|
=> (lambda (r) (loop (+ i 1) r)))
|
2003-02-13 19:47:58 -05:00
|
|
|
(else #f)))))
|
2003-02-12 16:48:40 -05:00
|
|
|
|
|
|
|
|
2003-03-13 13:38:28 -05:00
|
|
|
(define (sequences-every foo? . seqs)
|
2003-02-12 16:48:40 -05:00
|
|
|
(if (null? seqs) #t
|
2003-02-15 19:32:31 -05:00
|
|
|
(let ((end (sequences-length seqs)))
|
2003-02-13 19:47:58 -05:00
|
|
|
(let loop ((i 0))
|
|
|
|
(cond ((= i end) #t)
|
2003-02-14 21:48:52 -05:00
|
|
|
((apply foo? (map (lambda (seq) (sequence-ref seq i))
|
2003-02-12 16:48:40 -05:00
|
|
|
seqs))
|
|
|
|
(loop (+ i 1)))
|
|
|
|
(else #f))))))
|
2003-02-11 19:23:30 -05:00
|
|
|
|
|
|
|
|
2003-03-13 13:38:28 -05:00
|
|
|
(define (sequence= elt= s0 s1 . opts)
|
|
|
|
(let-optionals opts ((start0 0) (end0 (sequence-length s0))
|
|
|
|
(start1 0) (end1 (sequence-length s1)))
|
2003-03-22 17:22:15 -05:00
|
|
|
(assert (<= start0 end0 (sequence-length s0)) sequence=)
|
|
|
|
(assert (<= start1 end1 (sequence-length s1)) sequence=)
|
2003-03-13 13:38:28 -05:00
|
|
|
(and (= (- end0 start0)
|
|
|
|
(- end1 start1))
|
|
|
|
(let loop ((i0 start0) (i1 start1))
|
|
|
|
(cond ((= i0 end0) #t)
|
|
|
|
((elt= (sequence-ref s0 i0)
|
|
|
|
(sequence-ref s1 i1))
|
|
|
|
(loop (+ i0 1) (+ i1 1)))
|
|
|
|
(else #f))))))
|
2003-02-11 19:23:30 -05:00
|
|
|
|
|
|
|
|
2003-03-13 13:38:28 -05:00
|
|
|
(define (sequences= elt= . seqs)
|
|
|
|
(if (null? seqs) #t
|
|
|
|
(let loop ((s (first seqs)) (ss (rest seqs)))
|
|
|
|
(cond ((null? ss) #t)
|
|
|
|
((sequence= elt= s (first ss))
|
|
|
|
(loop (first ss) (rest ss)))
|
|
|
|
(else #f)))))
|