C311 Fall96. Assignment 7 (solution)

;;
;; C311 Assignment 7
;; CPS transformation
;; Due F 11/01/96 @ 5:00pm
;;


; 1. list index

(define list-index
  (lambda (a ls)
    (list-index-cps a ls (make-final-valcont))))

(define list-index-cps
  (lambda (a ls k)
    (cond
      [(null? ls) (apply-k k -1)]
      [(eq? (car ls) a) (apply-k k 0)]
      [else (list-index-cps a (cdr ls) (make-listindex-k k))])))

(define make-listindex-k
  (lambda (k)
    (lambda (v)
      (let ([answ v])
	(if (= answ -1)
	    (apply-k k -1)
	    (apply-k k (add1 answ)))))))


; 2. intersection

(define intersection
  (lambda (s0 s1)
    (intersection-cps s0 s1 (make-final-valcont))))

(define intersection-cps
  (lambda (s0 s1 k)
    (cond
      [(null? s0) (apply-k k '())]
      [(memq (car s0) s1)
       (intersection-cps (cdr s0) s1
	 (make-intersection-k s0 k))]
      [else
	(intersection-cps (cdr s0) s1 k)])))

(define make-intersection-k
  (lambda (s0 k)
    (list 'intersection-k s0 k)))

; 3 count-parens

(define count-parens
  (lambda (ls)
    (count-parens-cps ls (make-final-valcont))))

(define count-parens-cps
  (lambda (ls k)
    (cond
      [(null? ls) (apply-k k 2)]
      [(list? (car ls))
       (count-parens-cps (car ls) (make-countparens-k ls k))]
      [else
	(count-parens-cps (cdr ls) k)])))

(define make-countparens-k
  (lambda (ls k)
    (lambda (v-car)
      (count-parens-cps (cdr ls) (make-countparens2-k v-car k)))))

(define make-countparens2-k
  (lambda (v-car k)
    (lambda (v-cdr)
      (apply-k k (+ v-car v-cdr)))))

; 4 depth

(define depth
  (lambda (ls)
    (depth-cps ls (make-final-valcont))))

(define depth-cps
  (lambda (ls k)
    (cond
      [(null? ls) (apply-k k 1)]
      [(pair? ls) (depth-cps (car ls) (make-depth-k ls k))]
      [else (apply-k k 0)])))

(define make-depth-k
  (lambda (ls k)
    (list 'depth-k ls k)))

(define make-depth2-k
  (lambda (v-car k)
    (list 'depth2-k v-car k)))

; vector-index

(define vector-index
  (lambda (a v)
    (vector-index-cps a v (make-final-valcont))))

(define vector-index-cps
  (lambda (a v k)
    (let ([vlen (vector-length v)])
      (letrec ([vindex-hlp-cps
		 (lambda (n k)
		   (cond
		     [(= vlen n)	(apply-k k -1)]
		     [(eq? (vector-ref v n) a) (apply-k k n)]
		     [else (vindex-hlp-cps (add1 n) k)]))])
	(vindex-hlp-cps 0 k)))))

;;
;;
;; apply-k

(define apply-k
  (lambda (k v)
    (if (procedure? k)
	(k v)
	(record-case k
	  (intersection-k (s0 k)
	    (let ([v v])
	      (apply-k k (cons (car s0) v))))
	  (depth-k (ls k)
	    (let ([v-car v])
	      (depth-cps (cdr ls) (make-depth2-k v-car k))))
	  (depth2-k (v-car k)
	    (let ([v-cdr v])
	      (apply-k k (max (add1 v-car) v-cdr))))
	  (else (error 'apply-k "invalid continuation ~s" k))))))

(define make-final-valcont
  (lambda ()
    (lambda (v)
      v)))


Last modified on Tue Oct 29 01:11:06 1996