(load library.lisp) ; associations, type assoc (define assoc-make (key value) ; : atom, s-exp -> assoc (list2 key value)) (define assoc-key (a) ; : assoc -> atom (car a)) (define assoc-value (a) ; : assoc -> s-exp (cadr a)) ; association lists, type alist (set the-empty-alist '()) ; : alist (define alist-empty? (al) ; : alist -> bool (null? al)) (define alist-first (al) ; : alist -> assoc ; requires: al is not empty (car al)) (define alist-tail (al) ; : alist -> alist ; requires: al is not empty (cdr al)) (define alist-assoc (key al) ; : alist -> s-exp (if (alist-empty? al) '() (if (= key (assoc-key (alist-first al))) (assoc-value (alist-first al)) (alist-assoc key (alist-tail al))))) (define alist-replace (a al) ; : assoc, alist -> alist ; requires: (assoc-key a) is defined ; by al's mapping (alist-replace-aux a al (assoc-key a))) (define alist-replace-aux (a al key) ; : assoc, alist, key -> alist ; requires: (assoc-key a) = key and ; key is defined by al's mapping (if (= key (assoc-key (alist-first al))) (cons a (alist-tail al)) (cons (alist-first al) (alist-replace-aux a (alist-tail al) key)))) (define alist-update (a al) ; : assoc, alist -> alist (if (alist-empty? al) (list1 a) (if (null? (alist-assoc (assoc-key a) al)) (cons a al) (alist-replace a al)))) (define alist-mkassoc (key value al) ; this is like mkassoc ; : atom, s-exp, alist -> alist (alist-update (assoc-make key value) al))