CSC 330 Assignment 5
Simple Lisp Programming



ISSUED: Monday, 16 May 2005
DUE: 5PM Monday, 23 May 2005, via handin on falcon/hornet
POINTS POSSIBLE: 100
WEIGHT: 5% of total class grade
READING: Lecture Notes Week 8, Lisp Primer and other Lisp docs; book Ch 8

Overview


This assignment involves programming some simple Lisp functions. The purpose is to familiarize you with the fundamental concepts of functional programming, in particular the use of recursion and lists.

All of the functions you write for this assignment must be recursive, non- destructive, not use prog, and be less than fifteen lines each. Within the fifteen-line limit, it is OK to define more than on function for any problem, i.e., to write a solution that involves recursive "helper" functions.

Functions to Implement

  1. Implement Lisp's built-in length function using tail recursion. Name your function "xlength", so it does not override Lisp's version. Your xlength should have exactly the same behavior as Lisp's length, which returns the shallow count of the number of elements in a list, i.e,. the number of top-level elements.

  2. Implement a size function that computes the total number of atomic elements in a list, including elements of nested sublists. This is the structurally deep version of length. Here are examples of how size works (these are the official test cases for this function):
    Test Case Result
    (size '()) 0
    (size 'x) 0
    (size '(x)) 1
    (size '( () (((())) x) () (()()))) 1
    (size '(a b c)) 3
    (size '(((((a)))) (b (b (b c) d) e) (c d) () f)) 10

  3. Implement Lisp's union function that returns the set-based union of two lists, i.e, an order-irrelevant merge of two lists with only a single copy of duplicate elements. Name your function "xunion" to avoid conflict with Lisp's built-in. Assume that both inputs are sets, i.e., lists that do not contain duplicate elements. Like length, union should operate in a shallow fashion, merging only the top-level list elements without descending into sublists. The equality test for duplicateness should use equal as opposed to eq. Here are the test cases:
    Test Case Result
    (xunion '() '()) NIL
    (xunion '(a b c) '(a b c)) (A B C)
    (xunion '(b c a) '(a b c)) (A B C)
    (xunion '(a (a b c) b x z) '(a (a b c) x b y)) (Z A (A B C) X B Y)
    Note that a good solution for xunion uses the Lisp member function. However, the requirement that the duplicate equality test be equal as opposed to eq means that you'll have to invoke member in the following extended form:
    (member e l :test 'equal)
    
    This call tests if element e is a member of list l using the equal function instead of the default eq. See Section 15.2 of the online Lisp reference manual for further details.

  4. Write a function traverse that performs a depth-first, post-order traversal of the list representation of an n-ary tree. Recall from CSC 103 that a post-order tree traversal is one that visits all of the children of a subtree before visiting the root.

    Assume the input tree is represented in the form presented in Section 7.3.2 of the Lisp primer. That is, the general format of a Lisp tree representation is
    ( root subtree1 ... subtreen )
    where root must be an atom, and each subtree is an atom or list.

    The output of traverse is a list of tree nodes in traversal order. Here are (all of) the test cases:
    Test Case Result
    (traverse '()) NIL
    (traverse '(a)) (A)
    (traverse '(a b)) (B A)
    (traverse '(a b c)) (B C A)
    (traverse '(a b c d e)) (B C D E A)
    (traverse '(a (b (c d) e) (f g h i) j)) (D C E B G H I F J A)
    To help visualize the tree structure, here is a traditional picture of the Lisp tree
    (a (b (c d) e) (f g h i) j):





index | lectures | handouts | assignments | examples | doc | solutions | bin