spook

A "game" for the 2023 Autumn Lisp Game Jam. Won first place! (from the bottom...)
git clone https://kaka.farm/~git/spook
Log | Files | Refs | LICENSE

srfi-25.scm (42123B)


      1 ;;;; srfi-25.scm - Jussi Piitulainen's array library
      2 
      3 
      4 (define array:array-tag (list 'array))
      5 
      6 (define (array:make vec ind shp) (vector array:array-tag vec ind shp))
      7 (define (array:array? x) (and (vector? x) (eq? (vector-ref x 0) array:array-tag)))
      8 (define (array:vector a) (vector-ref a 1))
      9 (define (array:index a) (vector-ref a 2))
     10 (define (array:shape a) (vector-ref a 3))
     11 
     12 
     13 ;;; array
     14 ;;; 1997 - 2001 Jussi Piitulainen
     15 
     16 
     17 ;;; --- Intro ---
     18 
     19 ;;; This interface to arrays is based on Alan Bawden's array.scm of
     20 ;;; 1993 (earlier version in the Internet Repository and another
     21 ;;; version in SLIB). This is a complete rewrite, to be consistent
     22 ;;; with the rest of Scheme and to make arrays independent of lists.
     23 
     24 ;;; Some modifications are due to discussion in srfi-25 mailing list.
     25 
     26 ;;; (array? obj)
     27 ;;; (make-array shape [obj])             changed arguments
     28 ;;; (shape bound ...)                    new
     29 ;;; (array shape obj ...)                new
     30 ;;; (array-rank array)                   changed name back
     31 ;;; (array-start array dimension)        new
     32 ;;; (array-end array dimension)          new
     33 ;;; (array-ref array k ...)
     34 ;;; (array-ref array index)              new variant
     35 ;;; (array-set! array k ... obj)         changed argument order
     36 ;;; (array-set! array index obj)         new variant
     37 ;;; (share-array array shape proc)       changed arguments
     38 
     39 ;;; All other variables in this file have names in "array:".
     40 
     41 ;;; Should there be a way to make arrays with initial values mapped
     42 ;;; from indices? Sure. The current "initial object" is lame.
     43 ;;;
     44 ;;; Removed (array-shape array) from here. There is a new version
     45 ;;; in arlib though.
     46 
     47 ;;; --- Representation type dependencies ---
     48 
     49 ;;; The mapping from array indices to the index to the underlying vector
     50 ;;; is whatever array:optimize returns. The file "opt" provides three
     51 ;;; representations:
     52 ;;; 
     53 ;;; mbda) mapping is a procedure that allows an optional argument
     54 ;;; tter) mapping is two procedures that takes exactly the indices
     55 ;;; ctor) mapping is a vector of a constant term and coefficients
     56 ;;;
     57 ;;; Choose one in "opt" to make the optimizer. Then choose the matching
     58 ;;; implementation of array-ref and array-set!.
     59 ;;;
     60 ;;; These should be made macros to inline them. Or have a good compiler
     61 ;;; and plant the package as a module.
     62 
     63 ;;; 1. Pick an optimizer.
     64 ;;; 2. Pick matching index representation.
     65 ;;; 3. Pick a record implementation; as-procedure is generic; syntax inlines.
     66 ;;; 3. This file is otherwise portable.
     67 
     68 ;;; --- Portable R5RS (R4RS and multiple values) ---
     69 
     70 ;;; (array? obj)
     71 ;;; returns #t if `obj' is an array and #t or #f otherwise.
     72 
     73 (define (array? obj)
     74    (array:array? obj))
     75 
     76 (define-syntax check-array
     77   (syntax-rules ()
     78     ((_ x loc)
     79      (let ((var x))
     80        (or (##core#check (array:array? var))
     81 	   (##sys#signal-hook #:type-error loc (##core#immutable '"bad argument type - not an array") var) ) ) ) ) )
     82 
     83 ;;; (make-array shape)
     84 ;;; (make-array shape obj)
     85 ;;; makes array of `shape' with each cell containing `obj' initially.
     86 
     87 (define (make-array shape . rest)
     88   (or (##core#check (array:good-shape? shape))
     89       (##sys#signal-hook #:type-error 'make-array "bad argument type - not a valid shape" shape))
     90   (apply array:make-array shape rest))
     91 
     92 (define (array:make-array shape . rest)
     93   (let ((size (array:size shape)))
     94     (array:make
     95      (if (pair? rest)
     96          (apply (lambda (o) (make-vector size o)) rest)
     97          (make-vector size))
     98      (if (= size 0)
     99          (array:optimize-empty
    100           (vector-ref (array:shape shape) 1))
    101          (array:optimize
    102           (array:make-index shape)
    103           (vector-ref (array:shape shape) 1)))
    104      (array:shape->vector shape))))
    105 
    106 ;;; (shape bound ...)
    107 ;;; makes a shape. Bounds must be an even number of exact, pairwise
    108 ;;; non-decreasing integers. Note that any such array can be a shape.
    109 
    110 (define (shape . bounds)
    111   (let ((v (list->vector bounds)))
    112     (or (##core#check (even? (vector-length v)))
    113         (##sys#error 'shape "uneven number of bounds" bounds) )
    114     (let ((shp (array:make
    115                 v
    116                 (if (pair? bounds)
    117                     (array:shape-index)
    118                     (array:empty-shape-index))
    119                 (vector 0 (quotient (vector-length v) 2)
    120                         0 2))))
    121       (or (##core#check (array:good-shape? shp))
    122           (##sys#signal-hook #:type-error 'shape "bounds are not pairwise non-decreasing exact integers" bounds) )
    123       shp)))
    124 
    125 ;;; (array shape obj ...)
    126 ;;; is analogous to `vector'.
    127 
    128 (define (array shape . elts)
    129   (or (##core#check (array:good-shape? shape))
    130       (##sys#signal-hook #:type-error 'array "bad argument type - not a valid shape" shape) )
    131   (let ((size (array:size shape)))
    132     (let ((vector (list->vector elts)))
    133       (or (##core#check (= (vector-length vector) size))
    134           (##sys#error 'array "bad number of elements" shape elts) )
    135       (array:make
    136        vector
    137        (if (= size 0)
    138            (array:optimize-empty
    139             (vector-ref (array:shape shape) 1))
    140            (array:optimize
    141             (array:make-index shape)
    142             (vector-ref (array:shape shape) 1)))
    143        (array:shape->vector shape)))))
    144 
    145 ;;; (array-rank array)
    146 ;;; returns the number of dimensions of `array'.
    147 
    148 (define (array-rank array)
    149   (check-array array 'array-rank)
    150   (quotient (vector-length (array:shape array)) 2))
    151 
    152 ;;; (array-start array k)
    153 ;;; returns the lower bound index of array along dimension k. This is
    154 ;;; the least valid index along that dimension if the dimension is not
    155 ;;; empty.
    156 
    157 (define (array-start array d)
    158   (check-array array 'array-start)
    159   (vector-ref (array:shape array) (+ d d)))
    160 
    161 ;;; (array-end array k)
    162 ;;; returns the upper bound index of array along dimension k. This is
    163 ;;; not a valid index. If the dimension is empty, this is the same as
    164 ;;; the lower bound along it.
    165 
    166 (define (array-end array d)
    167   (check-array array 'array-end)
    168   (vector-ref (array:shape array) (+ d d 1)))
    169 
    170 ;;; (share-array array shape proc)
    171 ;;; makes an array that shares elements of `array' at shape `shape'.
    172 ;;; The arguments to `proc' are indices of the result.  The values of
    173 ;;; `proc' are indices of `array'.
    174 
    175 ;;; Todo: in the error message, should recognise the mapping and show it.
    176 
    177 (define (share-array array subshape f)
    178   (check-array array 'share-array)
    179   (or (##core#check (array:good-shape? subshape))
    180       (##sys#signal-hook #:type-error 'share-array "not a shape" subshape) )
    181   (let ((subsize (array:size subshape)))
    182     (or (##core#check (array:good-share? subshape subsize f (array:shape array)))
    183         (##sys#error 'share-array "subshape does not map into supershape" subshape shape) )
    184     (let ((g (array:index array)))
    185       (array:make
    186        (array:vector array)
    187        (if (= subsize 0)
    188            (array:optimize-empty
    189             (vector-ref (array:shape subshape) 1))
    190            (array:optimize
    191             (lambda ks
    192               (call-with-values
    193                (lambda () (apply f ks))
    194                (lambda ks (array:vector-index g ks))))
    195             (vector-ref (array:shape subshape) 1)))
    196        (array:shape->vector subshape)))))
    197 
    198 ;;; --- Hrmph ---
    199 
    200 ;;; (array:share/index! ...)
    201 ;;; reuses a user supplied index object when recognising the
    202 ;;; mapping. The mind balks at the very nasty side effect that
    203 ;;; exposes the implementation. So this is not in the spec.
    204 ;;; But letting index objects in at all creates a pressure
    205 ;;; to go the whole hog. Arf.
    206 
    207 ;;; Use array:optimize-empty for an empty array to get a
    208 ;;; clearly invalid vector index.
    209 
    210 ;;; Surely it's perverse to use an actor for index here? But
    211 ;;; the possibility is provided for completeness.
    212 
    213 (define (array:share/index! array subshape proc index)
    214   (array:make
    215    (array:vector array)
    216    (if (= (array:size subshape) 0)
    217        (array:optimize-empty
    218         (quotient (vector-length (array:shape array)) 2))
    219        ((if (vector? index)
    220             array:optimize/vector
    221             array:optimize/actor)
    222         (lambda (subindex)
    223           (let ((superindex (proc subindex)))
    224             (if (vector? superindex)
    225                 (array:index/vector
    226                  (quotient (vector-length (array:shape array)) 2)
    227                  (array:index array)
    228                  superindex)
    229                 (array:index/array
    230                  (quotient (vector-length (array:shape array)) 2)
    231                  (array:index array)
    232                  (array:vector superindex)
    233                  (array:index superindex)))))
    234         index))
    235    (array:shape->vector subshape)))
    236 
    237 (define (array:optimize/vector f v)
    238   (let ((r (vector-length v)))
    239     (do ((k 0 (+ k 1)))
    240       ((= k r))
    241       (vector-set! v k 0))
    242     (let ((n0 (f v))
    243           (cs (make-vector (+ r 1)))
    244           (apply (array:applier-to-vector (+ r 1))))
    245       (vector-set! cs 0 n0)
    246       (let wok ((k 0))
    247         (if (< k r)
    248             (let ((k1 (+ k 1)))
    249               (vector-set! v k 1)
    250               (let ((nk (- (f v) n0)))
    251                 (vector-set! v k 0)
    252                 (vector-set! cs k1 nk)
    253                 (wok k1)))))
    254       (apply (array:maker r) cs))))
    255 
    256 (define (array:optimize/actor f a)
    257   (let ((r (array-end a 0))
    258         (v (array:vector a))
    259         (i (array:index a)))
    260     (do ((k 0 (+ k 1)))
    261       ((= k r))
    262       (vector-set! v (array:actor-index i k) 0))
    263     (let ((n0 (f a))
    264           (cs (make-vector (+ r 1)))
    265           (apply (array:applier-to-vector (+ r 1))))
    266       (vector-set! cs 0 n0)
    267       (let wok ((k 0))
    268         (if (< k r)
    269             (let ((k1 (+ k 1))
    270                   (t (array:actor-index i k)))
    271               (vector-set! v t 1)
    272               (let ((nk (- (f a) n0)))
    273                 (vector-set! v t 0)
    274                 (vector-set! cs k1 nk)
    275                 (wok k1)))))
    276       (apply (array:maker r) cs))))
    277 
    278 ;;; --- Internals ---
    279 
    280 (define (array:shape->vector shape)
    281   (let ((idx (array:index shape))
    282         (shv (array:vector shape))
    283         (rnk (vector-ref (array:shape shape) 1)))
    284     (let ((vec (make-vector (* rnk 2))))
    285       (do ((k 0 (+ k 1)))
    286         ((= k rnk)
    287          vec)
    288         (vector-set! vec (+ k k)
    289                      (vector-ref shv (array:shape-vector-index idx k 0)))
    290         (vector-set! vec (+ k k 1)
    291                      (vector-ref shv (array:shape-vector-index idx k 1)))))))
    292 
    293 ;;; (array:size shape)
    294 ;;; returns the number of elements in arrays of shape `shape'.
    295 
    296 (define (array:size shape)
    297    (let ((idx (array:index shape))
    298          (shv (array:vector shape))
    299          (rnk (vector-ref (array:shape shape) 1)))
    300      (do   ((k 0 (+ k 1))
    301             (s 1 (* s
    302                     (- (vector-ref shv (array:shape-vector-index idx k 1))
    303                        (vector-ref shv (array:shape-vector-index idx k 0))))))
    304        ((= k rnk) s))))
    305 
    306 ;;; (array:make-index shape)
    307 ;;; returns an index function for arrays of shape `shape'. This is a
    308 ;;; runtime composition of several variable arity procedures, to be
    309 ;;; passed to array:optimize for recognition as an affine function of
    310 ;;; as many variables as there are dimensions in arrays of this shape.
    311 
    312 (define (array:make-index shape)
    313    (let ((idx (array:index shape))
    314          (shv (array:vector shape))
    315          (rnk (vector-ref (array:shape shape) 1)))
    316      (do ((f (lambda () 0)
    317              (lambda (k . ks)
    318                (+ (* s (- k (vector-ref
    319                              shv
    320                              (array:shape-vector-index idx (- j 1) 0))))
    321                   (apply f ks))))
    322           (s 1 (* s (- (vector-ref
    323                         shv
    324                         (array:shape-vector-index idx (- j 1) 1))
    325                        (vector-ref
    326                         shv
    327                         (array:shape-vector-index idx (- j 1) 0)))))
    328           (j rnk (- j 1)))
    329        ((= j 0)
    330         f))))
    331 
    332 
    333 ;;; --- Error checking ---
    334 
    335 ;;; (array:good-shape? shape)
    336 ;;; returns true if `shape' is an array of the right shape and its
    337 ;;; elements are exact integers that pairwise bound intervals `[lo..hi)´.
    338 
    339 (define (array:good-shape? shape)
    340   (and (array:array? shape)
    341        (let ((u (array:shape shape))
    342              (v (array:vector shape))
    343              (x (array:index shape)))
    344          (and (= (vector-length u) 4)
    345               (= (vector-ref u 0) 0)
    346               (= (vector-ref u 2) 0)
    347               (= (vector-ref u 3) 2))
    348          (let ((p (vector-ref u 1)))
    349            (do ((k 0 (+ k 1))
    350                 (true #t (let ((lo (vector-ref
    351                                     v
    352                                     (array:shape-vector-index x k 0)))
    353                                (hi (vector-ref
    354                                     v
    355                                     (array:shape-vector-index x k 1))))
    356                            (and true
    357                                 (integer? lo)
    358                                 (exact? lo)
    359                                 (integer? hi)
    360                                 (exact? hi)
    361                                 (<= lo hi)))))
    362              ((= k p) true))))))
    363 
    364 ;;; (array:good-share? subv subsize mapping superv)
    365 ;;; returns true if the extreme indices in the subshape vector map
    366 ;;; into the bounds in the supershape vector.
    367 
    368 ;;; If some interval in `subv' is empty, then `subv' is empty and its
    369 ;;; image under `f' is empty and it is trivially alright.  One must
    370 ;;; not call `f', though.
    371 
    372 (define (array:good-share? subshape subsize f super)
    373   (or (zero? subsize)
    374       (letrec
    375           ((sub (array:vector subshape))
    376            (dex (array:index subshape))
    377            (ck (lambda (k ks)
    378 		 (if (zero? k)
    379                      (call-with-values
    380                       (lambda () (apply f ks))
    381                       (lambda qs (array:good-indices? qs super)))
    382                      (and (ck (- k 1)
    383                               (cons (vector-ref
    384                                      sub
    385                                      (array:shape-vector-index
    386                                       dex
    387                                       (- k 1)
    388                                       0))
    389                                     ks))
    390                           (ck (- k 1)
    391                               (cons (- (vector-ref
    392                                         sub
    393                                         (array:shape-vector-index
    394                                          dex
    395                                          (- k 1)
    396                                          1))
    397                                        1)
    398                                     ks)))))))
    399         (let ((rnk (vector-ref (array:shape subshape) 1)))
    400           (or (array:unchecked-share-depth? rnk)
    401               (ck rnk '()))))))
    402 
    403 ;;; Check good-share on 10 dimensions at most. The trouble is,
    404 ;;; the cost of this check is exponential in the number of dimensions.
    405 
    406 (define (array:unchecked-share-depth? rank)
    407   (if (> rank 10)
    408       (begin
    409         (display `(warning: unchecked depth in share:
    410                             ,rank subdimensions))
    411         (newline)
    412         #t)
    413       #f))
    414 
    415 ;;; (array:check-indices caller indices shape-vector)
    416 ;;; (array:check-indices.o caller indices shape-vector)
    417 ;;; (array:check-index-vector caller index-vector shape-vector)
    418 ;;; return if the index is in bounds, else signal error.
    419 ;;;
    420 ;;; Shape-vector is the internal representation, with
    421 ;;; b and e for dimension k at 2k and 2k + 1.
    422 
    423 (define (array:check-indices who ks shv)
    424   (or (array:good-indices? ks shv)
    425       (##sys#signal-hook #:bounds-error (array:not-in who ks shv))))
    426 
    427 (define (array:check-indices.o who ks shv)
    428   (or (array:good-indices.o? ks shv)
    429       (##sys#signal-hook #:bounds-error (array:not-in who (reverse (cdr (reverse ks))) shv))))
    430 
    431 (define (array:check-index-vector who ks shv)
    432   (or (array:good-index-vector? ks shv)
    433       (##sys#signal-hook #:bounds-error (array:not-in who (vector->list ks) shv))))
    434 
    435 (define (array:check-index-actor who ks shv)
    436   (let ((shape (array:shape ks)))
    437     (or (and (= (vector-length shape) 2)
    438              (= (vector-ref shape 0) 0))
    439         (##sys#signal-hook #:type-error "not an actor"))
    440     (or (array:good-index-actor?
    441          (vector-ref shape 1)
    442          (array:vector ks)
    443          (array:index ks)
    444          shv)
    445         (array:not-in who (do ((k (vector-ref shape 1) (- k 1))
    446                                (m '() (cons (vector-ref
    447                                              (array:vector ks)
    448                                              (array:actor-index
    449                                               (array:index ks)
    450                                               (- k 1)))
    451                                             m)))
    452                             ((= k 0) m))
    453                       shv))))
    454 
    455 (define (array:good-indices? ks shv)
    456    (let ((d2 (vector-length shv)))
    457       (do ((kp ks (if (pair? kp)
    458                       (cdr kp)))
    459            (k 0 (+ k 2))
    460            (true #t (and true (pair? kp)
    461                          (array:good-index? (car kp) shv k))))
    462         ((= k d2)
    463          (and true (null? kp))))))
    464 
    465 (define (array:good-indices.o? ks.o shv)
    466    (let ((d2 (vector-length shv)))
    467      (do   ((kp ks.o (if (pair? kp)
    468                          (cdr kp)))
    469             (k 0 (+ k 2))
    470             (true #t (and true (pair? kp)
    471                           (array:good-index? (car kp) shv k))))
    472        ((= k d2)
    473         (and true (pair? kp) (null? (cdr kp)))))))
    474 
    475 (define (array:good-index-vector? ks shv)
    476   (let ((r2 (vector-length shv)))
    477     (and (= (* 2 (vector-length ks)) r2)
    478          (do ((j 0 (+ j 1))
    479               (k 0 (+ k 2))
    480               (true #t (and true
    481                             (array:good-index? (vector-ref ks j) shv k))))
    482            ((= k r2) true)))))
    483 
    484 (define (array:good-index-actor? r v i shv)
    485   (and (= (* 2 r) (vector-length shv))
    486        (do ((j 0 (+ j 1))
    487             (k 0 (+ k 2))
    488             (true #t (and true
    489                           (array:good-index? (vector-ref
    490                                               v
    491                                               (array:actor-index i j))
    492                                              shv
    493                                              k))))
    494          ((= j r) true))))
    495 
    496 ;;; (array:good-index? index shape-vector 2d)
    497 ;;; returns true if index is within bounds for dimension 2d/2.
    498 
    499 (define (array:good-index? w shv k)
    500   (and (integer? w)
    501        (exact? w)
    502        (<= (vector-ref shv k) w)
    503        (< w (vector-ref shv (+ k 1)))))
    504 
    505 (define (array:not-in who ks shv)
    506   (##sys#signal-hook #:bounds-error (string-append who ": index not in bounds") ks shv) )
    507 
    508 
    509 (begin
    510   (define (array:coefficients f n0 vs vp)
    511     (case vp
    512       ((()) '())
    513       (else
    514        (set-car! vp 1)
    515        (let ((n (- (apply f vs) n0)))
    516          (set-car! vp 0)
    517          (cons n (array:coefficients f n0 vs (cdr vp)))))))
    518   (define (array:vector-index x ks)
    519     (do ((sum 0 (+ sum (* (vector-ref x k) (car ks))))
    520          (ks ks (cdr ks))
    521          (k 0 (+ k 1)))
    522         ((null? ks) (+ sum (vector-ref x k)))))
    523   (define (array:shape-index) '#(2 1 0))
    524   (define (array:empty-shape-index) '#(0 0 -1))
    525   (define (array:shape-vector-index x r k)
    526     (+
    527      (* (vector-ref x 0) r)
    528      (* (vector-ref x 1) k)
    529      (vector-ref x 2)))
    530   (define (array:actor-index x k)
    531     (+ (* (vector-ref x 0) k) (vector-ref x 1)))
    532   (define (array:0 n0) (vector n0))
    533   (define (array:1 n0 n1) (vector n1 n0))
    534   (define (array:2 n0 n1 n2) (vector n1 n2 n0))
    535   (define (array:3 n0 n1 n2 n3) (vector n1 n2 n3 n0))
    536   (define (array:n n0 n1 n2 n3 n4 . ns)
    537     (apply vector n1 n2 n3 n4 (append ns (list n0))))
    538   (define (array:maker r)
    539     (case r
    540       ((0) array:0)
    541       ((1) array:1)
    542       ((2) array:2)
    543       ((3) array:3)
    544       (else array:n)))
    545   (define array:indexer/vector
    546     (let ((em
    547            (vector
    548 	    (lambda (x i) (+ (vector-ref x 0)))
    549 	    (lambda (x i)
    550 	      (+
    551 	       (* (vector-ref x 0) (vector-ref i 0))
    552 	       (vector-ref x 1)))
    553 	    (lambda (x i)
    554 	      (+
    555 	       (* (vector-ref x 0) (vector-ref i 0))
    556 	       (* (vector-ref x 1) (vector-ref i 1))
    557 	       (vector-ref x 2)))
    558 	    (lambda (x i)
    559 	      (+
    560 	       (* (vector-ref x 0) (vector-ref i 0))
    561 	       (* (vector-ref x 1) (vector-ref i 1))
    562 	       (* (vector-ref x 2) (vector-ref i 2))
    563 	       (vector-ref x 3)))
    564 	    (lambda (x i)
    565 	      (+
    566 	       (* (vector-ref x 0) (vector-ref i 0))
    567 	       (* (vector-ref x 1) (vector-ref i 1))
    568 	       (* (vector-ref x 2) (vector-ref i 2))
    569 	       (* (vector-ref x 3) (vector-ref i 3))
    570 	       (vector-ref x 4)))
    571 	    (lambda (x i)
    572 	      (+
    573 	       (* (vector-ref x 0) (vector-ref i 0))
    574 	       (* (vector-ref x 1) (vector-ref i 1))
    575 	       (* (vector-ref x 2) (vector-ref i 2))
    576 	       (* (vector-ref x 3) (vector-ref i 3))
    577 	       (* (vector-ref x 4) (vector-ref i 4))
    578 	       (vector-ref x 5)))
    579 	    (lambda (x i)
    580 	      (+
    581 	       (* (vector-ref x 0) (vector-ref i 0))
    582 	       (* (vector-ref x 1) (vector-ref i 1))
    583 	       (* (vector-ref x 2) (vector-ref i 2))
    584 	       (* (vector-ref x 3) (vector-ref i 3))
    585 	       (* (vector-ref x 4) (vector-ref i 4))
    586 	       (* (vector-ref x 5) (vector-ref i 5))
    587 	       (vector-ref x 6)))
    588 	    (lambda (x i)
    589 	      (+
    590 	       (* (vector-ref x 0) (vector-ref i 0))
    591 	       (* (vector-ref x 1) (vector-ref i 1))
    592 	       (* (vector-ref x 2) (vector-ref i 2))
    593 	       (* (vector-ref x 3) (vector-ref i 3))
    594 	       (* (vector-ref x 4) (vector-ref i 4))
    595 	       (* (vector-ref x 5) (vector-ref i 5))
    596 	       (* (vector-ref x 6) (vector-ref i 6))
    597 	       (vector-ref x 7)))
    598 	    (lambda (x i)
    599 	      (+
    600 	       (* (vector-ref x 0) (vector-ref i 0))
    601 	       (* (vector-ref x 1) (vector-ref i 1))
    602 	       (* (vector-ref x 2) (vector-ref i 2))
    603 	       (* (vector-ref x 3) (vector-ref i 3))
    604 	       (* (vector-ref x 4) (vector-ref i 4))
    605 	       (* (vector-ref x 5) (vector-ref i 5))
    606 	       (* (vector-ref x 6) (vector-ref i 6))
    607 	       (* (vector-ref x 7) (vector-ref i 7))
    608 	       (vector-ref x 8)))
    609 	    (lambda (x i)
    610 	      (+
    611 	       (* (vector-ref x 0) (vector-ref i 0))
    612 	       (* (vector-ref x 1) (vector-ref i 1))
    613 	       (* (vector-ref x 2) (vector-ref i 2))
    614 	       (* (vector-ref x 3) (vector-ref i 3))
    615 	       (* (vector-ref x 4) (vector-ref i 4))
    616 	       (* (vector-ref x 5) (vector-ref i 5))
    617 	       (* (vector-ref x 6) (vector-ref i 6))
    618 	       (* (vector-ref x 7) (vector-ref i 7))
    619 	       (* (vector-ref x 8) (vector-ref i 8))
    620 	       (vector-ref x 9)))))
    621           (it
    622            (lambda (w)
    623              (lambda (x i)
    624                (+
    625                 (* (vector-ref x 0) (vector-ref i 0))
    626                 (* (vector-ref x 1) (vector-ref i 1))
    627                 (* (vector-ref x 2) (vector-ref i 2))
    628                 (* (vector-ref x 3) (vector-ref i 3))
    629                 (* (vector-ref x 4) (vector-ref i 4))
    630                 (* (vector-ref x 5) (vector-ref i 5))
    631                 (* (vector-ref x 6) (vector-ref i 6))
    632                 (* (vector-ref x 7) (vector-ref i 7))
    633                 (* (vector-ref x 8) (vector-ref i 8))
    634                 (* (vector-ref x 9) (vector-ref i 9))
    635                 (do ((xi
    636                       0
    637                       (+
    638                        (* (vector-ref x u) (vector-ref i u))
    639                        xi))
    640                      (u (- w 1) (- u 1)))
    641                     ((< u 10) xi))
    642                 (vector-ref x w))))))
    643       (lambda (r) (if (< r 10) (vector-ref em r) (it r)))))
    644   (define array:indexer/array
    645     (let ((em
    646            (vector
    647 	    (lambda (x v i) (+ (vector-ref x 0)))
    648 	    (lambda (x v i)
    649 	      (+
    650 	       (*
    651 		(vector-ref x 0)
    652 		(vector-ref v (array:actor-index i 0)))
    653 	       (vector-ref x 1)))
    654 	    (lambda (x v i)
    655 	      (+
    656 	       (*
    657 		(vector-ref x 0)
    658 		(vector-ref v (array:actor-index i 0)))
    659 	       (*
    660 		(vector-ref x 1)
    661 		(vector-ref v (array:actor-index i 1)))
    662 	       (vector-ref x 2)))
    663 	    (lambda (x v i)
    664 	      (+
    665 	       (*
    666 		(vector-ref x 0)
    667 		(vector-ref v (array:actor-index i 0)))
    668 	       (*
    669 		(vector-ref x 1)
    670 		(vector-ref v (array:actor-index i 1)))
    671 	       (*
    672 		(vector-ref x 2)
    673 		(vector-ref v (array:actor-index i 2)))
    674 	       (vector-ref x 3)))
    675 	    (lambda (x v i)
    676 	      (+
    677 	       (*
    678 		(vector-ref x 0)
    679 		(vector-ref v (array:actor-index i 0)))
    680 	       (*
    681 		(vector-ref x 1)
    682 		(vector-ref v (array:actor-index i 1)))
    683 	       (*
    684 		(vector-ref x 2)
    685 		(vector-ref v (array:actor-index i 2)))
    686 	       (*
    687 		(vector-ref x 3)
    688 		(vector-ref v (array:actor-index i 3)))
    689 	       (vector-ref x 4)))
    690 	    (lambda (x v i)
    691 	      (+
    692 	       (*
    693 		(vector-ref x 0)
    694 		(vector-ref v (array:actor-index i 0)))
    695 	       (*
    696 		(vector-ref x 1)
    697 		(vector-ref v (array:actor-index i 1)))
    698 	       (*
    699 		(vector-ref x 2)
    700 		(vector-ref v (array:actor-index i 2)))
    701 	       (*
    702 		(vector-ref x 3)
    703 		(vector-ref v (array:actor-index i 3)))
    704 	       (*
    705 		(vector-ref x 4)
    706 		(vector-ref v (array:actor-index i 4)))
    707 	       (vector-ref x 5)))
    708 	    (lambda (x v i)
    709 	      (+
    710 	       (*
    711 		(vector-ref x 0)
    712 		(vector-ref v (array:actor-index i 0)))
    713 	       (*
    714 		(vector-ref x 1)
    715 		(vector-ref v (array:actor-index i 1)))
    716 	       (*
    717 		(vector-ref x 2)
    718 		(vector-ref v (array:actor-index i 2)))
    719 	       (*
    720 		(vector-ref x 3)
    721 		(vector-ref v (array:actor-index i 3)))
    722 	       (*
    723 		(vector-ref x 4)
    724 		(vector-ref v (array:actor-index i 4)))
    725 	       (*
    726 		(vector-ref x 5)
    727 		(vector-ref v (array:actor-index i 5)))
    728 	       (vector-ref x 6)))
    729 	    (lambda (x v i)
    730 	      (+
    731 	       (*
    732 		(vector-ref x 0)
    733 		(vector-ref v (array:actor-index i 0)))
    734 	       (*
    735 		(vector-ref x 1)
    736 		(vector-ref v (array:actor-index i 1)))
    737 	       (*
    738 		(vector-ref x 2)
    739 		(vector-ref v (array:actor-index i 2)))
    740 	       (*
    741 		(vector-ref x 3)
    742 		(vector-ref v (array:actor-index i 3)))
    743 	       (*
    744 		(vector-ref x 4)
    745 		(vector-ref v (array:actor-index i 4)))
    746 	       (*
    747 		(vector-ref x 5)
    748 		(vector-ref v (array:actor-index i 5)))
    749 	       (*
    750 		(vector-ref x 6)
    751 		(vector-ref v (array:actor-index i 6)))
    752 	       (vector-ref x 7)))
    753 	    (lambda (x v i)
    754 	      (+
    755 	       (*
    756 		(vector-ref x 0)
    757 		(vector-ref v (array:actor-index i 0)))
    758 	       (*
    759 		(vector-ref x 1)
    760 		(vector-ref v (array:actor-index i 1)))
    761 	       (*
    762 		(vector-ref x 2)
    763 		(vector-ref v (array:actor-index i 2)))
    764 	       (*
    765 		(vector-ref x 3)
    766 		(vector-ref v (array:actor-index i 3)))
    767 	       (*
    768 		(vector-ref x 4)
    769 		(vector-ref v (array:actor-index i 4)))
    770 	       (*
    771 		(vector-ref x 5)
    772 		(vector-ref v (array:actor-index i 5)))
    773 	       (*
    774 		(vector-ref x 6)
    775 		(vector-ref v (array:actor-index i 6)))
    776 	       (*
    777 		(vector-ref x 7)
    778 		(vector-ref v (array:actor-index i 7)))
    779 	       (vector-ref x 8)))
    780 	    (lambda (x v i)
    781 	      (+
    782 	       (*
    783 		(vector-ref x 0)
    784 		(vector-ref v (array:actor-index i 0)))
    785 	       (*
    786 		(vector-ref x 1)
    787 		(vector-ref v (array:actor-index i 1)))
    788 	       (*
    789 		(vector-ref x 2)
    790 		(vector-ref v (array:actor-index i 2)))
    791 	       (*
    792 		(vector-ref x 3)
    793 		(vector-ref v (array:actor-index i 3)))
    794 	       (*
    795 		(vector-ref x 4)
    796 		(vector-ref v (array:actor-index i 4)))
    797 	       (*
    798 		(vector-ref x 5)
    799 		(vector-ref v (array:actor-index i 5)))
    800 	       (*
    801 		(vector-ref x 6)
    802 		(vector-ref v (array:actor-index i 6)))
    803 	       (*
    804 		(vector-ref x 7)
    805 		(vector-ref v (array:actor-index i 7)))
    806 	       (*
    807 		(vector-ref x 8)
    808 		(vector-ref v (array:actor-index i 8)))
    809 	       (vector-ref x 9)))))
    810           (it
    811            (lambda (w)
    812              (lambda (x v i)
    813                (+
    814                 (*
    815                  (vector-ref x 0)
    816                  (vector-ref v (array:actor-index i 0)))
    817                 (*
    818                  (vector-ref x 1)
    819                  (vector-ref v (array:actor-index i 1)))
    820                 (*
    821                  (vector-ref x 2)
    822                  (vector-ref v (array:actor-index i 2)))
    823                 (*
    824                  (vector-ref x 3)
    825                  (vector-ref v (array:actor-index i 3)))
    826                 (*
    827                  (vector-ref x 4)
    828                  (vector-ref v (array:actor-index i 4)))
    829                 (*
    830                  (vector-ref x 5)
    831                  (vector-ref v (array:actor-index i 5)))
    832                 (*
    833                  (vector-ref x 6)
    834                  (vector-ref v (array:actor-index i 6)))
    835                 (*
    836                  (vector-ref x 7)
    837                  (vector-ref v (array:actor-index i 7)))
    838                 (*
    839                  (vector-ref x 8)
    840                  (vector-ref v (array:actor-index i 8)))
    841                 (*
    842                  (vector-ref x 9)
    843                  (vector-ref v (array:actor-index i 9)))
    844                 (do ((xi
    845                       0
    846                       (+
    847                        (*
    848                         (vector-ref x u)
    849                         (vector-ref
    850 			 v
    851 			 (array:actor-index i u)))
    852                        xi))
    853                      (u (- w 1) (- u 1)))
    854                     ((< u 10) xi))
    855                 (vector-ref x w))))))
    856       (lambda (r) (if (< r 10) (vector-ref em r) (it r)))))
    857   (define array:applier-to-vector
    858     (let ((em
    859            (vector
    860 	    (lambda (p v) (p))
    861 	    (lambda (p v) (p (vector-ref v 0)))
    862 	    (lambda (p v)
    863 	      (p (vector-ref v 0) (vector-ref v 1)))
    864 	    (lambda (p v)
    865 	      (p
    866 	       (vector-ref v 0)
    867 	       (vector-ref v 1)
    868 	       (vector-ref v 2)))
    869 	    (lambda (p v)
    870 	      (p
    871 	       (vector-ref v 0)
    872 	       (vector-ref v 1)
    873 	       (vector-ref v 2)
    874 	       (vector-ref v 3)))
    875 	    (lambda (p v)
    876 	      (p
    877 	       (vector-ref v 0)
    878 	       (vector-ref v 1)
    879 	       (vector-ref v 2)
    880 	       (vector-ref v 3)
    881 	       (vector-ref v 4)))
    882 	    (lambda (p v)
    883 	      (p
    884 	       (vector-ref v 0)
    885 	       (vector-ref v 1)
    886 	       (vector-ref v 2)
    887 	       (vector-ref v 3)
    888 	       (vector-ref v 4)
    889 	       (vector-ref v 5)))
    890 	    (lambda (p v)
    891 	      (p
    892 	       (vector-ref v 0)
    893 	       (vector-ref v 1)
    894 	       (vector-ref v 2)
    895 	       (vector-ref v 3)
    896 	       (vector-ref v 4)
    897 	       (vector-ref v 5)
    898 	       (vector-ref v 6)))
    899 	    (lambda (p v)
    900 	      (p
    901 	       (vector-ref v 0)
    902 	       (vector-ref v 1)
    903 	       (vector-ref v 2)
    904 	       (vector-ref v 3)
    905 	       (vector-ref v 4)
    906 	       (vector-ref v 5)
    907 	       (vector-ref v 6)
    908 	       (vector-ref v 7)))
    909 	    (lambda (p v)
    910 	      (p
    911 	       (vector-ref v 0)
    912 	       (vector-ref v 1)
    913 	       (vector-ref v 2)
    914 	       (vector-ref v 3)
    915 	       (vector-ref v 4)
    916 	       (vector-ref v 5)
    917 	       (vector-ref v 6)
    918 	       (vector-ref v 7)
    919 	       (vector-ref v 8)))))
    920           (it
    921            (lambda (r)
    922              (lambda (p v)
    923                (apply
    924                 p
    925                 (vector-ref v 0)
    926                 (vector-ref v 1)
    927                 (vector-ref v 2)
    928                 (vector-ref v 3)
    929                 (vector-ref v 4)
    930                 (vector-ref v 5)
    931                 (vector-ref v 6)
    932                 (vector-ref v 7)
    933                 (vector-ref v 8)
    934                 (vector-ref v 9)
    935                 (do ((k r (- k 1))
    936                      (r
    937                       '()
    938                       (cons (vector-ref v (- k 1)) r)))
    939                     ((= k 10) r)))))))
    940       (lambda (r) (if (< r 10) (vector-ref em r) (it r)))))
    941   (define array:applier-to-actor
    942     (let ((em
    943            (vector
    944 	    (lambda (p a) (p))
    945 	    (lambda (p a) (p (array-ref a 0)))
    946 	    (lambda (p a)
    947 	      (p (array-ref a 0) (array-ref a 1)))
    948 	    (lambda (p a)
    949 	      (p
    950 	       (array-ref a 0)
    951 	       (array-ref a 1)
    952 	       (array-ref a 2)))
    953 	    (lambda (p a)
    954 	      (p
    955 	       (array-ref a 0)
    956 	       (array-ref a 1)
    957 	       (array-ref a 2)
    958 	       (array-ref a 3)))
    959 	    (lambda (p a)
    960 	      (p
    961 	       (array-ref a 0)
    962 	       (array-ref a 1)
    963 	       (array-ref a 2)
    964 	       (array-ref a 3)
    965 	       (array-ref a 4)))
    966 	    (lambda (p a)
    967 	      (p
    968 	       (array-ref a 0)
    969 	       (array-ref a 1)
    970 	       (array-ref a 2)
    971 	       (array-ref a 3)
    972 	       (array-ref a 4)
    973 	       (array-ref a 5)))
    974 	    (lambda (p a)
    975 	      (p
    976 	       (array-ref a 0)
    977 	       (array-ref a 1)
    978 	       (array-ref a 2)
    979 	       (array-ref a 3)
    980 	       (array-ref a 4)
    981 	       (array-ref a 5)
    982 	       (array-ref a 6)))
    983 	    (lambda (p a)
    984 	      (p
    985 	       (array-ref a 0)
    986 	       (array-ref a 1)
    987 	       (array-ref a 2)
    988 	       (array-ref a 3)
    989 	       (array-ref a 4)
    990 	       (array-ref a 5)
    991 	       (array-ref a 6)
    992 	       (array-ref a 7)))
    993 	    (lambda (p a)
    994 	      (p
    995 	       (array-ref a 0)
    996 	       (array-ref a 1)
    997 	       (array-ref a 2)
    998 	       (array-ref a 3)
    999 	       (array-ref a 4)
   1000 	       (array-ref a 5)
   1001 	       (array-ref a 6)
   1002 	       (array-ref a 7)
   1003 	       (array-ref a 8)))))
   1004           (it
   1005            (lambda (r)
   1006              (lambda (p a)
   1007                (apply
   1008                 a
   1009                 (array-ref a 0)
   1010                 (array-ref a 1)
   1011                 (array-ref a 2)
   1012                 (array-ref a 3)
   1013                 (array-ref a 4)
   1014                 (array-ref a 5)
   1015                 (array-ref a 6)
   1016                 (array-ref a 7)
   1017                 (array-ref a 8)
   1018                 (array-ref a 9)
   1019                 (do ((k r (- k 1))
   1020                      (r '() (cons (array-ref a (- k 1)) r)))
   1021                     ((= k 10) r)))))))
   1022       (lambda (r)
   1023         "These are high level, hiding implementation at call site."
   1024         (if (< r 10) (vector-ref em r) (it r)))))
   1025   (define array:applier-to-backing-vector
   1026     (let ((em
   1027            (vector
   1028 	    (lambda (p ai av) (p))
   1029 	    (lambda (p ai av)
   1030 	      (p (vector-ref av (array:actor-index ai 0))))
   1031 	    (lambda (p ai av)
   1032 	      (p
   1033 	       (vector-ref av (array:actor-index ai 0))
   1034 	       (vector-ref av (array:actor-index ai 1))))
   1035 	    (lambda (p ai av)
   1036 	      (p
   1037 	       (vector-ref av (array:actor-index ai 0))
   1038 	       (vector-ref av (array:actor-index ai 1))
   1039 	       (vector-ref av (array:actor-index ai 2))))
   1040 	    (lambda (p ai av)
   1041 	      (p
   1042 	       (vector-ref av (array:actor-index ai 0))
   1043 	       (vector-ref av (array:actor-index ai 1))
   1044 	       (vector-ref av (array:actor-index ai 2))
   1045 	       (vector-ref av (array:actor-index ai 3))))
   1046 	    (lambda (p ai av)
   1047 	      (p
   1048 	       (vector-ref av (array:actor-index ai 0))
   1049 	       (vector-ref av (array:actor-index ai 1))
   1050 	       (vector-ref av (array:actor-index ai 2))
   1051 	       (vector-ref av (array:actor-index ai 3))
   1052 	       (vector-ref av (array:actor-index ai 4))))
   1053 	    (lambda (p ai av)
   1054 	      (p
   1055 	       (vector-ref av (array:actor-index ai 0))
   1056 	       (vector-ref av (array:actor-index ai 1))
   1057 	       (vector-ref av (array:actor-index ai 2))
   1058 	       (vector-ref av (array:actor-index ai 3))
   1059 	       (vector-ref av (array:actor-index ai 4))
   1060 	       (vector-ref av (array:actor-index ai 5))))
   1061 	    (lambda (p ai av)
   1062 	      (p
   1063 	       (vector-ref av (array:actor-index ai 0))
   1064 	       (vector-ref av (array:actor-index ai 1))
   1065 	       (vector-ref av (array:actor-index ai 2))
   1066 	       (vector-ref av (array:actor-index ai 3))
   1067 	       (vector-ref av (array:actor-index ai 4))
   1068 	       (vector-ref av (array:actor-index ai 5))
   1069 	       (vector-ref av (array:actor-index ai 6))))
   1070 	    (lambda (p ai av)
   1071 	      (p
   1072 	       (vector-ref av (array:actor-index ai 0))
   1073 	       (vector-ref av (array:actor-index ai 1))
   1074 	       (vector-ref av (array:actor-index ai 2))
   1075 	       (vector-ref av (array:actor-index ai 3))
   1076 	       (vector-ref av (array:actor-index ai 4))
   1077 	       (vector-ref av (array:actor-index ai 5))
   1078 	       (vector-ref av (array:actor-index ai 6))
   1079 	       (vector-ref av (array:actor-index ai 7))))
   1080 	    (lambda (p ai av)
   1081 	      (p
   1082 	       (vector-ref av (array:actor-index ai 0))
   1083 	       (vector-ref av (array:actor-index ai 1))
   1084 	       (vector-ref av (array:actor-index ai 2))
   1085 	       (vector-ref av (array:actor-index ai 3))
   1086 	       (vector-ref av (array:actor-index ai 4))
   1087 	       (vector-ref av (array:actor-index ai 5))
   1088 	       (vector-ref av (array:actor-index ai 6))
   1089 	       (vector-ref av (array:actor-index ai 7))
   1090 	       (vector-ref av (array:actor-index ai 8))))))
   1091           (it
   1092            (lambda (r)
   1093              (lambda (p ai av)
   1094                (apply
   1095                 p
   1096                 (vector-ref av (array:actor-index ai 0))
   1097                 (vector-ref av (array:actor-index ai 1))
   1098                 (vector-ref av (array:actor-index ai 2))
   1099                 (vector-ref av (array:actor-index ai 3))
   1100                 (vector-ref av (array:actor-index ai 4))
   1101                 (vector-ref av (array:actor-index ai 5))
   1102                 (vector-ref av (array:actor-index ai 6))
   1103                 (vector-ref av (array:actor-index ai 7))
   1104                 (vector-ref av (array:actor-index ai 8))
   1105                 (vector-ref av (array:actor-index ai 9))
   1106                 (do ((k r (- k 1))
   1107                      (r
   1108                       '()
   1109                       (cons
   1110                        (vector-ref
   1111 			av
   1112 			(array:actor-index ai (- k 1)))
   1113                        r)))
   1114                     ((= k 10) r)))))))
   1115       (lambda (r)
   1116         "These are low level, exposing implementation at call site."
   1117         (if (< r 10) (vector-ref em r) (it r)))))
   1118   (define (array:index/vector r x v)
   1119     ((array:indexer/vector r) x v))
   1120   (define (array:index/array r x av ai)
   1121     ((array:indexer/array r) x av ai))
   1122   (define (array:apply-to-actor r p a)
   1123     ((array:applier-to-actor r) p a))
   1124   (define (array:apply-to-vector r p v)
   1125     ((array:applier-to-vector r) p v))
   1126   (define (array:optimize f r)
   1127     (case r
   1128       ((0) (let ((n0 (f))) (array:0 n0)))
   1129       ((1) (let ((n0 (f 0))) (array:1 n0 (- (f 1) n0))))
   1130       ((2)
   1131        (let ((n0 (f 0 0)))
   1132 	 (array:2 n0 (- (f 1 0) n0) (- (f 0 1) n0))))
   1133       ((3)
   1134        (let ((n0 (f 0 0 0)))
   1135          (array:3
   1136            n0
   1137            (- (f 1 0 0) n0)
   1138            (- (f 0 1 0) n0)
   1139            (- (f 0 0 1) n0))))
   1140       (else
   1141        (let ((v
   1142 	      (do ((k 0 (+ k 1)) (v '() (cons 0 v)))
   1143 		  ((= k r) v))))
   1144 	 (let ((n0 (apply f v)))
   1145 	   (apply
   1146 	    array:n
   1147 	    n0
   1148 	    (array:coefficients f n0 v v)))))))
   1149   (define (array:optimize-empty r)
   1150     (let ((x (make-vector (+ r 1) 0)))
   1151       (vector-set! x r -1)
   1152       x)))
   1153 
   1154 
   1155 (define (array-ref a . xs)
   1156   (or (##core#check (array:array? a))
   1157       (##sys#signal-hook #:type-error 'array-ref "not an array" a))
   1158   (let ((shape (array:shape a)))
   1159     (##core#check
   1160      (if (null? xs)
   1161 	 (array:check-indices "array-ref" xs shape)
   1162 	 (let ((x (car xs)))
   1163 	   (if (vector? x)
   1164               (array:check-index-vector "array-ref" x shape)
   1165               (if (integer? x)
   1166                   (array:check-indices "array-ref" xs shape)
   1167                   (if (array:array? x)
   1168                       (array:check-index-actor "array-ref" x shape)
   1169                       (##sys#signal-hook #:type-error 'array-ref "not an index object" x)))))))
   1170     (vector-ref
   1171      (array:vector a)
   1172      (if (null? xs)
   1173          (vector-ref (array:index a) 0)
   1174          (let ((x (car xs)))
   1175            (if (vector? x)
   1176                (array:index/vector
   1177                 (quotient (vector-length shape) 2)
   1178                 (array:index a)
   1179                 x)
   1180                (if (integer? x)
   1181                    (array:vector-index (array:index a) xs)
   1182                    (if (##core#check (array:array? x))
   1183                        (array:index/array
   1184                         (quotient (vector-length shape) 2)
   1185                         (array:index a)
   1186                         (array:vector x)
   1187                         (array:index x))
   1188                        (##sys#signal-hook #:type-error 'array-ref "bad index object" x)))))))))
   1189 
   1190 (define (array-set! a x . xs)
   1191   (or (##core#check (array:array? a))
   1192       (##sys#signal-hook #:type-error 'array-set! "not an array" a))
   1193   (let ((shape (array:shape a)))
   1194     (##core#check
   1195      (if (null? xs)
   1196 	 (array:check-indices "array-set!" '() shape)
   1197 	 (if (vector? x)
   1198             (array:check-index-vector "array-set!" x shape)
   1199             (if (integer? x)
   1200                 (array:check-indices.o "array-set!" (cons x xs) shape)
   1201                 (if (array:array? x)
   1202                     (array:check-index-actor "array-set!" x shape)
   1203                     (##sys#signal-hook #:type-error 'array-set! "not an index object" x))))))
   1204     (if (null? xs)
   1205         (vector-set! (array:vector a) (vector-ref (array:index a) 0) x)
   1206         (if (vector? x)
   1207             (vector-set! (array:vector a)
   1208                          (array:index/vector
   1209                           (quotient (vector-length shape) 2)
   1210                           (array:index a)
   1211                           x)
   1212                          (car xs))
   1213             (if (integer? x)
   1214                 (let ((v (array:vector a))
   1215                       (i (array:index a))
   1216                       (r (quotient (vector-length shape) 2)))
   1217                   (do ((sum (* (vector-ref i 0) x)
   1218                             (+ sum (* (vector-ref i k) (car ks))))
   1219                        (ks xs (cdr ks))
   1220                        (k 1 (+ k 1)))
   1221                     ((= k r)
   1222                      (vector-set! v (+ sum (vector-ref i k)) (car ks)))))
   1223                 (if (##core#check (array:array? x))
   1224                     (vector-set! (array:vector a)
   1225                                  (array:index/array
   1226                                   (quotient (vector-length shape) 2)
   1227                                   (array:index a)
   1228                                   (array:vector x)
   1229                                   (array:index x))
   1230                                  (car xs))
   1231                     (##sys#signal-hook
   1232 		     #:type-error 'array-set!
   1233 		     "bad index object: "
   1234 		     x)))))))
   1235 
   1236 (define (array:make-locative a x weak?)
   1237   (or (##core#check (array:array? a))
   1238       (##sys#signal-hook #:type-error 'array:make-locative "not an array"))
   1239   (let ((shape (array:shape a)))
   1240     (##core#check
   1241      (if (vector? x)
   1242 	 (array:check-index-vector "array:make-locative" x shape)
   1243 	 (if (integer? x)
   1244 	     (array:check-indices.o "array:make-locative" (list x) shape)
   1245 	     (if (array:array? x)
   1246 		 (array:check-index-actor "array:make-locative" x shape)
   1247 		 (##sys#signal-hook #:type-error 'array:make-locative "not an index object" x)))))
   1248     (if (vector? x)
   1249 	(##core#inline_allocate
   1250 	 ("C_a_i_make_locative" 5)
   1251 	 0
   1252 	 (array:vector a)
   1253 	 (array:index/vector
   1254 	  (quotient (vector-length shape) 2)
   1255 	  (array:index a)
   1256 	  x) 
   1257 	 weak?)
   1258 	(if (##core#check (array:array? x))
   1259 	    (##core#inline_allocate
   1260 	     ("C_a_i_make_locative" 5)
   1261 	     0
   1262 	     (array:vector a)
   1263 	     (array:index/array
   1264 	      (quotient (vector-length shape) 2)
   1265 	      (array:index a)
   1266 	      (array:vector x)
   1267 	      (array:index x)) 
   1268 	     weak?)
   1269 	    (##sys#signal-hook #:type-error 'array:make-locative "bad index object: " x)))))