home *** CD-ROM | disk | FTP | other *** search
- ;;;-*- Base: 10; Mode: Scheme; Syntax: MIT Scheme; Package: USER -*-
- ;;
- ;; ARRAY-DISPLACED.SCM
- ;;
- ;; July 1, 1991
- ;; Minghsun Liu
- ;;
- ;; This file contains procedures written in MIT Scheme that implement
- ;; a data type that is anologous to the arrays found in CommonLisp.
- ;; The main idea is to use vectors whose elements are also vectors to
- ;; implement the multi-dimensionality of arrays.
- ;;
- ;; July 19, 1991
- ;; Major Overhawl: All the codes are re-written using message passing.
- ;;
- ;; July 26, 1991
- ;; Yet Another Major Overhawl: the requirement of :displaced-to suggests
- ;; that a flattened internal representation of the array is the ideal
- ;; implementation.
- ;;
- ;;
- ;; August 5, 1991
- ;; This file contains the original implementation of the array data
- ;; type with supports for :displaced-to keyword. The implementation
- ;; is still buggy for it has not undergone any extensive tests. USE
- ;; WITH CAUTION!
- ;
- ;; The following(s) are(is) defined:
- ;;
- ;; :INITIAL-CONTENTS
- ;; :INITIAL-ELEMENT
- ;; (MAKE-ARRAY DIMENSIONS . OPTIONS)
- ;; (ARRAY-REF ARRAY . SUBSCRIPTS)
- ;; (ARRAY-RANK ARRAY)
- ;; (ARRAY-DIMENSION ARRAY AXIS-NUMBER)
- ;; (ARRAY? ARRAY)
- ;; (ARRAY-SET! ARRAY OBJ . SUBSCRIPTS)
- ;; (JUST-THE-ARRAY-MAAM ARRAY)
- ;; (CHANGE-MYSELF ARRAY NEW-DATA)
- ;;
- (declare (usual-integrations))
-
-
- ;;
- ;; :INITIAL-CONTENTS
- ;; :INITIAL-ELEMENT
- ;;
- ;; are constants whose values should not be changed.
- ;;
- (define :initial-contents (cons ':initial-contents 'keyword-constant))
- (define :initial-element (cons ':initial-element 'keyword-constant))
- (define :displaced-to (cons ':displaced-to 'keyword-constant))
-
-
- ;;
- ;; (MAKE-ARRAY DIMENSIONS #!REST OPTIONS)
- ;;
- ;; creates a array with its dimensions specified by DIMENSIONS which
- ;; should be a list of non-negative integers with the length of the
- ;; list being the rank of the array.
- ;;
- (define (make-array dimensions #!rest options)
- (let ((initialize-array? #f)
- (initial-element? #t)
- (cur-array '())
- (initial-object '()))
- (define (flatten a-list) ;; ahhh....a-list been run over by a truck
- (cond ((null? a-list)
- '())
- ((pair? (car a-list))
- (append (flatten (car a-list))
- (flatten (cdr a-list))))
- (else
- (cons (car a-list)
- (flatten (cdr a-list))))))
- (define (list->array dims flat-list)
- (if (and (= (length flat-list) dims)
- (not (list-transform-positive flat-list pair?)))
- (list->vector flat-list)
- (error "MAKE-ARRAY: displaced -> something is WRONG!!" flat-list dims)))
- (define (check-options options-left)
- (cond ((null? options-left)
- 'done)
- ((equal? (car options-left) :initial-contents)
- (set! initial-element? #f)
- (set! initialize-array? #t)
- (set! initial-object (cadr options-left))
- (check-options (cddr options-left)))
- ((equal? (car options-left) :initial-element)
- (set! initialize-array? #t)
- (set! initial-object (cadr options-left))
- (check-options (cddr options-left)))
- ((equal? (car options-left) :displaced-to)
- (set! displaced-to? #t)
- (set! destin-array (cadr options-left))
- (check-options (cddr options-left)))
- (else (error "MAKE-ARRAY: unknown keyword" options-left))))
- (define (translate subscripts) ;; collapse the world down to 1D
- (define (trans-aux subs dims)
- (if (null? (cddr subs))
- (+ (* (cadr subs) (car dims)) (car subs))
- (trans-aux (cons (+ (* (cadr subs) (car dims)) (car subs))
- (cddr subs))
- (cons (* (car dims) (cadr dims)) (cddr dims)))))
- (let ((trans-index
- (if (= (length subscripts) (length dimensions))
- (if (= (length subscripts) 1)
- (car subscripts)
- (trans-aux (reverse subscripts) (reverse dimensions)))
- (error "ARRAY: invalid index" subscripts dimeensions))))
- (if (>= trans-index (vector-length cur-array))
- (error "TRANSLATE-ARRAY: bad index" subscripts trans-index)
- trans-index)))
- (define (m-array-ref subscripts)
- (cond ((and (null? subscripts) (null? dimensions))
- cur-array)
- ((list? subscripts)
- (vector-ref cur-array (translate subscripts)))
- (else
- (error "AREF: array corrupt or bad index" cur-array subscripts dimensions))))
- (define (m-array-rank)
- (length dimensions))
- (define (m-array-dimension axis-number)
- (list-ref axis-number dimensions))
- (define (m-array-dimensions)
- (if (null? dimensions)
- '()
- dimensions))
- (define (m-array-set! arguements)
- (let ((obj (car arguements))
- (ind (if (null? (cdr arguements))
- '()
- (translate (cdr arguements)))))
- (define (array-set-aux!)
- (vector-set! cur-array ind obj)
- obj)
- (define (array-set-aux-2!)
- (set! cur-array obj)
- obj)
- (define (propagate-obj)
- (desin-array 'fast-array-set! obj ind))
- (if (and (null? ind) (null? dimensions))
- (if displaced-to?
- (begin
- (array-set-aux-2!)
- (propagate-obj))
- (array-set-aux-2!))
- (if (and (not (null? ind)) (not (null? dimensions)))
- (if displaced-to?
- (begin
- (array-set-aux!)
- (propagate-obj))
- (array-set-aux!))
- (error "ARRAY-SET: bad index" arguements)))))
- (define (copy-array)
- (let ((to-be-copied (destin-array 'just-the-array-maam))
- (destin-dim (destin-array 'array-dimensions)))
- (cond ((and (null? dimensions) (null? destin-dim))
- to-be-copied)
- ((and (not (null? dimensions)) (null? destin-dim))
- (subvector (vector to-be-copied) 0 (max 1 (if (number? dimensions)
- dimensions
- (apply * dimensions)))))
- ((and (null? dimensions) (not (null? destin-dim)))
- (vector-ref to-be-copied 0))
- (else
- (if (number? dimensions)
- (subvector to-be-copied 0 (min dimensions
- (if (number? destin-dim)
- destin-dim
- (apply * destin-dim))))
- (subvector to-be-copied 0 (min (if (number? destin-dim)
- destin-dim
- (apply * destin-dim))
- (apply * dimensions))))))))
- (define (array-type msg #!rest args)
- (case msg
- ((dispaced)
- (set! displaced-to? #t)
- (set! destin-array (car args))
- (car args))
- ((fast-array-set!)
- (if (and (null? dimensions)
- (or (null? (cdr args))
- (> 1 (cadr args))))
- (set! cur-array (car args))
- (if (null? (cdr args))
- (vector-set! cur-array 0 (car args))
- (vector-set! cur-array (cadr args) (car args)))))
- ((array-ref)
- (if displaced-to?
- (set! cur-array (copy-array)))
- (m-array-ref args))
- ((array-rank) (m-array-rank))
- ((array-dimension) (m-array-dimension (car args)))
- ((array?) #t)
- ((array-dimensions) (m-array-dimensions))
- ((array-set!) (m-array-set! args))
- ((just-the-array-maam)
- (if displaced-to?
- (set! cur-array (copy-array)))
- cur-array)
- ((change-myself)
- (set! cur-array (car args)) ;; change yourself, i.e.
- ;; destructive.
- (destin-array 'change-my-self (car args)))
- (else (error "ARRAY: not a valid method" msg))))
- (check-options options)
- (set! cur-array
- (if displaced-to?
- (copy-array)
- (if (or (number? dimensions) (= 1 (length dimensions)) (null? dimensions))
- (if (number? dimensions)
- (if initialize-array?
- (if initial-element?
- (make-vector dimensions initial-object)
- (if (= (length initial-object) dimensions)
- (list->vector initial-object)
- (error "MAKE-ARRAY: array is not of correct size"
- dimensions initial-object)))
- (make-vector dimensions))
- (if (null? dimensions)
- (if initialize-array?
- initial-object
- 0)
- (if initialize-array?
- (if initial-element?
- (make-vector (car dimensions) initial-object)
- (if (= (length initial-object) (car dimensions))
- (list->vector initial-object)
- (error "MAKE-ARRAY: array is not of correct size"
- (car dimensions) initial-object)))
- (make-vector (car dimensions)))))
- (if (and initialize-array? (not initial-element?))
- (list->array (apply * dimensions) (flatten initial-object))
- (if initial-element?
- (make-vector (apply * dimensions) initial-object)
- (make-vector (apply * dimensions)))))))
- (if displaced-to?
- (destin-array 'displaced array-type)
- array-type)))
-
-
- ;;
- ;; (AREF ARRAY . SUBSCRIPTS)
- ;;
- ;; access and returns the element of array specified by the SUBSCRIPTS
- ;; whose number must equal the rank of the array.
- ;;
- (define (aref array #!rest subscripts)
- (apply array 'array-ref subscripts))
-
-
- ;;
- ;; (ARRAY-RANK ARRAY)
- ;;
- ;; returns the number of dimensions of ARRAY. One limitation of
- ;; current implementation is that the elements in the array can't
- ;; be vectors.
- ;;
- (define (array-rank array)
- (array 'array-rank))
-
-
- ;;
- ;; (ARRAY-DIMENSION ARRAY AXIS-NUMBER)
- ;;
- ;; returns the length of dimension number AXIS-NUMBER of ARRAY.
- ;;
- (define (array-dimensions array axis-number)
- (array 'array-dimensions axis-number))
-
-
- ;;
- ;; (ARRAY-DIMENSIONS ARRAY)
- ;;
- ;; get the dimensions of ARRAY.
- ;;
- (define (array-dimensions array)
- (array 'array-dimensions))
-
-
- ;;
- ;; (ARRAY? OBJECT)
- ;;
- ;; tests if object is an array.
- ;;
- (define (array? object)
- (if (procedure? object)
- (object 'array?)
- #f))
-
-
- ;;
- ;; (ARRAY-SET! ARRAY OBJ . SUBSCRIPTS)
- ;;
- ;; destructively replace an array element of index SUBSCRIPTS with the
- ;; value OBJ.
- ;;
- (define (array-set! array obj #!rest subscripts)
- (apply array 'array-set! obj subscripts))
-
-
- ;;
- ;; (JUST-THE-ARRAY-MAAM ARRAY)
- ;;
- ;; like the name says: a wicked way to get the multidimensional array
- ;; only, instead of the whole procedural object.
- ;;
- (define (just-the-array-maam array)
- (array 'just-the-array-maam))
-
-
- ;;
- ;; (CHANGE-MYSELF ARRAY NEW-DATA)
- ;;
- ;; coupled with the above procedure, JUST-THE-ARRAY-MAAM, provide the
- ;; facilities to write operations on arrays as independent procedures,
- ;; instead of a new method in the ARRAY object. This method, however,
- ;; does not check the consistency of NEW-DATA with the characteristics
- ;; of the array. (e.g. If the array is a 2 by 2 array, it is assumed
- ;; that NEW-DATA is a vector that contains at least 4 elements.)
- ;;
- (define (change-myself array new-data)
- (array 'change-myself new-data))
-
-
-
-
-