Our current model of family trees makes it easy to find someone's parents, but hard to find someone's children. Assume we reversed the arrows on the family tree from the last lecture. What sort of data definition would you propose? A parent is a structure (make-parent n y e loc) where n and e are symbols, y is a num, and loc is a list-of-children. (define-struct parent (name year eye-color children)) Notice however, that we don't have a data definition for list-of-children. What should we use? A list-of-children is either - empty, or - (cons p loc) where p is a parent and loc is a list-of-children Notice that this data definition refers to the definition of parent. If you were to draw the arrows, you'd see that these two data definitions are mutually dependent. In this case, the data definitions are called mutually recursive. What's an example of a family tree using this data definition? (make-parent 'Tom 1930 'blue (cons (make-parent 'Ann 1952 'green (cons (make-parent 'Mary 1975 'green empty) empty)) (cons (make-parent 'Mike 1955 'blue empty) empty))) What does a template look like over this pair of data definitions? (define (p-func a-parent) (parent-name a-parent) ... (parent-year a-parent) ... (parent-eye-color a-parent) ... (loc-func (parent-children a-parent)) ... ) (define (loc-func a-loc) (cond [(empty? a-loc) ...] [(cons? a-loc) ... (p-func (first a-loc)) ... (loc-func (rest a-loc)) ... ])) Notice that the template for a mutually recursive data definition contains one template for each constituent data definition. Furthermore, if there is a template for the datum returned by a selector, we add a call to the template for that datum. In this way, the calls in the template follow the arrows in the data definition, just as we've done for recursive functions. Write the program count-members, which consumes a parent and returns a number. The returned number indicates how many people are in the family tree starting at parent. ;; count-members : parent -> num ;; compute how many people in family tree rooted at parent (define (count-members a-parent) (+ 1 (count-children (parent-children a-parent)))) ;; count-children : list-of-children -> num ;; compute how many people in family trees rooted at children (define (count-children a-loc) (cond [(empty? a-loc) 0] [(cons? a-loc) (+ (count-members (first a-loc)) (count-children (rest a-loc)))])) Write a program at-least-two-children which consumes a parent and returns a list of names of all parents with at least two children. ;; at-least-two-children : parent -> list-of-symbol ;; returns a list of all people in tree with at least two children (define (at-least-two-children a-parent) (cond [(> (num-children (parent-children a-parent)) 2) (cons (parent-name a-parent) (children-with-two-children (parent-children a-parent)))] [else (children-with-two-children (parent-children a-parent))])) ;; children-with-two-children : list-of-children -> list-of-symbol ;; returns a list of all children with at least two children (define (children-with-two-children a-loc) (cond [(empty? a-loc) empty] [(cons? a-loc) (append (at-least-two-children (first a-loc)) (children-with-two-children (rest a-loc)))])) ;; num-children : list-of-children -> num ;; counts how many children are in the list (define (num-children a-loc) (cond [(empty? a-loc) 0] [else (+ 1 (num-children (rest a-loc)))]))