Solutions to the fourth homework assignment
Exercise 3.6.1
An implementation of an abstract data type for finite functions, using
the "ribcage" representation described in section 3.6.3.
(define create-empty-ff
(lambda ()
(list 'empty-ff '())))
(define extended-ff*
(lambda (sym-list val-vector old-ff)
(list
'extended-ff
(list (list sym-list val-vector) old-ff))))
(define apply-ff
(lambda (ff symbol)
(form-case ff
(empty-ff (ff) (error
'apply-ff
"No association for ~a" symbol))
(extended-ff (ff)
(let ((assoc-list (car ff)))
(let ((sym-list (car assoc-list)))
(let ((val-vector (cadr assoc-list)))
(let ((val (ribassoc symbol sym-list val-vector
'*fail*)))
(if (eq? val '*fail*)
(apply-ff (cadr ff) symbol)
val))))))
(else (error 'apply-ff "Invalid finite function")))))
(define ribassoc
(lambda (s los v fail-value)
(letrec ((helper (lambda (los index)
(cond ((null? los) fail-value)
((eq? s (car los)) (vector-ref v index))
(else (helper (cdr los) (+ index 1)))))))
(helper los 0))))
Exerise 4.6.1
(define make-stack
(lambda (n)
(let ((stk (make-vector n))
(index -1))
(lambda (message)
(case message
((empty?) (lambda () (= index -1)))
((push!) (lambda (x)
(set! index (add1 index))
(if (> index n)
(error 'push! "Stack size exceeded!")
(vector-set! stk index x))))
((pop!) (lambda () (if (= index -1)
(error 'pop! "Stack empty!")
(let ((val (vector-ref stk index)))
(set! index (sub1 index))
val))))
((top) (lambda () (if (= index -1)
(error 'top! "Stack empty!")
(vector-ref stk index))))
(else (error
'make-stack
"Unknown message to stack ADT encountered!")))))))
Exercise 4-6-2
The finite function data representation is a list of pairs. To
extact the value, we use assoc. The extend
operation takes one symbol and one asociated value, and extends
the finite function.
(define make-ff
(lambda ()
(let ((ff '()))
(lambda (message)
(case message
((empty?) (lambda ()
(null? ff)))
((extend) (lambda (sym val)
(set! ff (cons (list sym val) ff))
"Finite function extended!")) ;hides representation
((apply) (lambda (sym)
(let ((val (assoc sym ff)))
(if val
(cadr val)
(error 'apply "No association for ~a"
sym)))))
(else (error 'make-ff "Unknown message encountered!")))))))
Vikram Subramaniam, 1995