Output is missing from these solutions, but they are otherwise complete. ;; 1.1 (define mmbr (lambda (obj lst) (if (null? lst) #f (or (eqv? obj (car lst)) (mmbr obj (cdr lst)))))) ;; 1.2 (define appnd (lambda (lst1 lst2) (if (null? lst1) lst2 (cons (car lst1) (appnd (cdr lst1) lst2))))) ;; 1.3 ; reverses by appending the reverse of the cdr of the list ; to the car of the list (define reverse (lambda (lst) (if (null? lst) '() (let ([first (car lst)] [reversed-rest (reverse (cdr lst))]) (append reversed-rest (list first)))))) ; another popular version was this one: ; reverses the list by moving the first element to another list ; in a stack like fashion. The other list is then returned. (define rev (lambda (L) (letrec ((dorev (lambda (from to) (if (null? from) to (dorev (cdr from) (cons (car from) to)))))) (dorev L '())))) ;; 1.4 (assuming that numbers are to be sorted) ; Sorts a list using insertion sort (define sort (lambda (lst) (if (null? lst) '() (let ([elem (car lst)] [sorted-rest (sort (cdr lst))]) (insert elem sorted-rest))))) (define insert (lambda (elem sorted-lst) (if (null? sorted-lst) (list elem) (let ([first (car sorted-lst)]) (if (<= elem first) (cons elem sorted-lst) (cons first (insert elem (cdr sorted-lst)))))))) ; Sorts a list using QuickSort (define sort (lambda (L) (letrec ((partition (lambda (pivot L left right) (cond ((null? L) (append (sort left) (cons pivot (sort right)))) ((< (car L) pivot) (partition pivot (cdr L) (cons (car L) left) right) (else (partition pivot (cdr L) left (cons (car L) right)))))))) (if (null? L) '() (partition (car L) (cdr L) '() '()))))) ;; 1.5 (define dot-product (lambda (lst1 lst2) (if (null? lst1) 0 (+ (* (car lst1) (car lst2)) (dot-product (cdr lst1) (cdr lst2)))))) ;; 2.1 ; Errors are handled by printing an error message and stopping. (define set-member (lambda (x S) (if (set-legal? S) (member x S) (error set-member "illegal set")))) ;; 2.2 (define set-union (lambda (s1 s2) (cond ((not (and (set-legal? s1) (set-legal? s2))) (error set-union "illegal sets")) ((null? s1) s2) (else (let ([elem (car s1)]) (if (set-member elem s2) (set-union (cdr s1) s2) (cons elem (set-union (cdr s1) s2)))))))) ; or equivalently (define set-union (lambda (s1 s2) (cond ((not (and (set-legal? s1) (set-legal? s2))) (error set-union "illegal sets")) (else (append (set-difference s1 s2) s2))))) ;; 2.3 (define set-intersect (lambda (s1 s2) (cond ((not (and (set-legal? s1) (set-legal? s2))) (error set-union "illegal sets")) ((null? s1) '()) (else (let ([elem (car s1)]) (if (set-member elem s2) (cons elem (set-intersect (cdr s1) s2)) (set-intersect (cdr s1) s2))))))) ;; 2.4 (define set-difference (lambda (s1 s2) (cond ((not (and (set-legal? s1) (set-legal? s2))) (error set-union "illegal sets")) ((null? s1) '()) (else (let ([elem (car s1)]) (if (not (set-member elem s2)) (cons elem (set-difference (cdr s1) s2)) (set-difference (cdr s1) s2))))))) ;; 2.5 (define set-legal? (lambda (s) (if (null? s) #t (let ([elem (car s)]) (if (member elem (cdr s)) #f (set-legal (cdr s))))))) ;; 3 ; Binary trees are defined as lists of three elements in the ; form (value left-child right-child) ; First some functions to make the code more readable: (define bset-empty '()) (define empty? null?) (define make-singleton (lambda (n) (list n '() '()))) (define node (lambda (val left right) (list val left right))) (define leftc cadr) (define rightc caddr) (define val car) ; a binary tree insert function (doesn't check for legal sets, ; since it can be used for general trees). (define bset-insert (lambda (n s) (if (empty? s) (make-singleton n) (if (= n (car s)) s (if (< n (car s)) (node (val s) (bset-insert n (leftc s)) (rightc s)) (node (val s) (leftc s) (bset-insert n (rightc s)))))))) ; the bset-legal? function assumes the input is a legal tree, and ; checks to see if is a legal set. (define bset-legal? (lambda (s) (if (empty? s) #t (if (or (bset-member (val s) (leftc s)) (bset-member (val s) (rightc s))) #f (and (bset-legal (leftc s)) (bset-legal (rightc s))))))) (define bset-member (lambda (x s) (cond ((not (bset-legal? s)) (error bset-member "illegal set")) ((empty? s) #f) ((= x (val s)) #t) ((< x (val s)) (bset-member x (leftc s))) (else (bset-member x (caddr s)))))) (define bset-union (lambda (s1 s2) (cond ((not (and (bset-legal? s1) (bset-legal? s2))) (error bset-union "illegal set")) ((empty? s1) s2) (else (bset-union (rightc s1) (bset-union (leftc s1) (bset-insert (val s1) s2)))))) (define bset-intersection (lambda (s1 s2) (cond ((not (and (bset-legal? s1) (bset-legal? s2))) (error bset-intersection "illegal set")) ((empty? s1) bset-empty) ((bset-member (val s1) s2) (bset-insert (val s1) (bset-intersection (bset-union (rightc s1) (leftc s1)) s2))) (else (bset-intersection (bset-union (rightc s1) (leftc s1)) s2))))) (define bset-difference (lambda (s1 s2) (cond ((not (and (bset-legal? s1) (bset-legal? s2))) (error bset-intersection "illegal set")) ((empty? s1) bset-empty) ((not (bset-member (val s1) s2)) (bset-insert (val s1) (bset-difference (bset-union (rightc s1) (leftc s1)) s2))) (else (bset-difference (bset-union (rightc s1) (leftc s1)) s2))))) ;; 4 (define kons (lambda (first second) (lambda (selector) (selector first second)))) (define kar (lambda (encoded-pair) (encoded-pair (lambda (first second) first)))) (define kdr (lambda (encoded-pair) (encoded-pair (lambda (first second) second)))) (define kappnd (lambda (lst1 lst2) (if (null? lst1) lst2 (kons (kar lst1) (kappnd (kdr lst1) lst2))))) ;; 5 ; First some functions to make the code more readable (define lambda? (lambda (expr) (and (list? expr) (= (length expr) 3) (eq? 'lambda (car expr))))) (define identifier? symbol?) (define let? (lambda (expr) (and (list? expr) (= (length expr) 3) (eq? 'let (car expr))))) ; The algorithm I use is (FV = free variables): ; ; FV( x ) = { x } ; FV((lambda x M)) = FV(M) - { x } ; FV((M N)) = FV(M) union FV(N) ; FV((let (x M) N)) = FV(M) union (FV(N) - {x}) ; I'm using the set functions from exercise 2. (define FV (lambda (exp) (cond [(identifier? exp) (list exp)] [(lambda? exp?) (let ([para (cadr exp)] ; you could also define functions [body (caddr exp)]) ; to extract these parts (set-difference (FV body) (list para)))] [(let? exp) (let* ([decl (cadr exp)] [body (caddr exp)] [para (car decl)] [rhs (cadr decl)]) (set-union (FV rhs) (set-difference (FV body) (list para))))] [else (set-union (FV (car exp)) (FV (cadr exp)))]))) (define isfree (lambda (x exp) (if (memv x (FV exp)) #t #f))) ; or (using the member from exercise 1) (define isfree (lambda (x exp) (mmbr x (FV exp))))