; Answers are below... ; ---------------------------------------------------- ; constructor to create a part with no subparts. ; called as (simple-part n) where n is the ; name of the part. (define simple-part (lambda (s) (list 'simple-part s))) ; constructor to create a part with subparts ; called as (complex-part n l) where n is the ; name of the part and l is the list of its ; subparts. (define complex-part (lambda (s l) (list 'complex-part s l))) ; test to determine whether a part has no subparts. (define is-simple? (lambda (s) (eq? (car s) 'simple-part))) ; test to determine whether a part has subparts. (define is-complex? (lambda (s) (eq? (car s) 'complex-part))) ; accessor function that returns the name of a part. (define name-of (lambda (s) (car (cdr s)))) ; accessor function that returns the list of all ; the subparts of a part. if the part is simple, ; this returns the empty list. (define parts-of (lambda (s) (if (is-simple? s) '() (car (cdr (cdr s)))))) ; here is a simple example of how to use the constructors ; to create a representation of a whole that is made up ; of parts. (define basic-doric-form (complex-part 'doric-form (list (simple-part 'entablature) (simple-part 'column) (simple-part 'pedestal)))) ; here is a complex example of how to use the constructors ; to create a representation of a whole that is made up of ; parts. (define full-doric-form (complex-part 'doric-form (list (complex-part 'entablature (list (simple-part 'cornice) (simple-part 'frieze) (simple-part 'architrave))) (complex-part 'column (list (complex-part 'capital (list (complex-part 'abacus (list (simple-part 'fillet) (simple-part 'cymation) (simple-part 'plinth))) (complex-part 'necking (list (simple-part 'fillets) (simple-part 'astragal) (simple-part 'cincture))))) (simple-part 'shaft) (simple-part 'column-base))) (complex-part 'pedestal (list (simple-part 'cap) (simple-part 'dado) (simple-part 'base)))))) ; --------------------- ; Answers to program 1 ; -- 3a ; determine if a list of structures (part-list) contains an element ; called name (define has-part-helper? (lambda (part-list name) (cond ((null? part-list) #f) (else (or (eq? (name-of (car part-list)) name) (has-part-helper? (cdr part-list) name)))))) ; determine if a structure has a part called name (define has-part? (lambda (structure name) (has-part-helper? (parts-of structure) name))) ; -- 3b ; returns the element of the list of structures (part-list) called name ; or false if doesn't exist (define get-part-helper (lambda (part-list name) (cond ((null? part-list) #f) ((eq? (name-of (car part-list)) name) (car part-list)) (else (get-part-helper (cdr part-list) name))))) ; returns the part of structure called name, or false if doesn't exist (define get-part (lambda (structure name) (get-part-helper (parts-of structure) name))) ;-- 4a ; determine if a list of structures contains a part anywhere inside it ; --- ; if the (car part-list) is called name --> true ; if any part inside (car part-list) is called name -> true ; if (cdr part-list) has any part inside it called name -> true ; else --> false (define has-subpart-helper? (lambda (part-list name) (cond ((null? part-list) #f) (else (or (eq? (name-of (car part-list)) name) (has-subpart-helper? (parts-of (car part-list)) name) (has-subpart-helper? (cdr part-list) name)))))) ; determine if a structure contains a part anywhere inside it, ; including itself (define has-subpart? (lambda (structure name) (has-subpart-helper? (list structure) name))) ;-- 4a, a different way: has-subpart2? ; this way uses "mutual recursion" where has-subpart-helper2? calls ; has-subpart2? In this case, the eq? is in has-subpart? ; determine if a list of structures contains a part anywhere inside it (define has-subpart2-helper? (lambda (part-list name) (cond ((null? part-list) #f) (else (or (has-subpart2? (car part-list) name) (has-subpart2-helper? (cdr part-list) name)))))) ; determine if a structure contains a part anywhere inside it ; including itself (define has-subpart2? (lambda (structure name) (or (eq? (name-of structure) name) (has-subpart2-helper? (parts-of structure) name)))) ;-- 4b (define get-subpart-helper (lambda (part-list name) (cond ((null? part-list) #f) ((eq? (name-of (car part-list)) name) (car part-list)) ((not (eq? (get-subpart-helper (parts-of (car part-list)) name) #f)) (get-subpart-helper (parts-of (car part-list)) name)) (else (get-subpart-helper (cdr part-list) name))))) ; return the part called name located anywhere inside structure, or ; false if it is not present (define get-subpart (lambda (structure name) (get-subpart-helper (list structure) name))) ; -- 4b, another way ; Here is another way of writing get-subpart-helper, that takes advantage ; of how the value of (or ...) is the first non-false value given. ; It also uses mutual recursion, putting the eq? in get-subpart2 (define get-subpart2-helper (lambda (part-list name) (cond ((null? part-list) #f) (else (or (get-subpart2 (car part-list) name) (get-subpart2-helper (cdr part-list) name)))))) (define get-subpart2 (lambda (structure name) (if (eq? (name-of structure) name) structure (get-subpart2-helper (parts-of structure) name))))