## CS 188, Fall 2005, Introduction to Artificial Intelligence Assignment 0, due 9/8, total value 1% of grade

To be done individually

People entering CS188 vary widely in their Lisp experience: this assignment should serve as a refresher and an opportunity to become more familiar with Common Lisp in particular.

Grading on this assignment is binary: if you make an honest effort at most of the questions you will get 100%, otherwise 0%. As with any programming assignment, include with each answer a transcript showing that the code works on a few different inputs. Submit your solution using the submit program from an instructional (named or class) account, as described here. The name for the assignment is a0 and your solution file should be called a0.lisp. Your file should be loadable into lisp and should include explanations and output traces (as needed) in portions commented with semicolons.

You may find the Notes on Lisp useful as well as the Tutorial on how to use Lisp, emacs, and the AIMA code.

1. Exponentiation
Write a recursive function (two-to-the x) which takes a single non-negative integer parameter x and returns 2x. (This can be done in logarithmic time.)

2. Write a LISP function (count-trees n) which returns the number of distinct strictly binary trees with n leaves. A strictly binary tree is one in which every node other than a leaf has exactly two children. A leaf has no children. There is 1 strictly binary tree with 1 leaf (just a single node tree), 1 strictly binary tree with 2 leaves, 2 distinct strictly binary trees with 3 leaves, and 5 distinct strictly binary trees with exactly 4 leaves. (count-trees n) can be implemented fairly easily using recursion. Test your program for n = 1 through 10. [Hint: Suppose a tree with n leaves has a leaves in its left subtree and b leaves in its right subtree, where a+b=n; how many such trees are there?]
Optional: measure the runtime as a function of n and find a way to speed it up by caching partial results.

3. Symbolic differentiation
One important AI application area is symbolic mathematics, particularly calculus. For this problem, you will construct a function deriv which differentiates simple, single-variable mathematical expressions. The function takes two arguments. The first is a mathematical expression in standard LISP syntax, containing numbers, atoms (representing constants and variables) and the functions +,-,*,/,expt. (Note that +, -, and * can be applied to any number of arguments. You need not handle * applied to more than two arguments unless you want brownie points.) The second is the name of the variable with respect to which to differentiate. Other symbols in the expression are treated as constants. The rules of differentiation are as follows (where u and v are arbitrary expressions):

u = constant implies du/dx = 0
dx/dx=1
d(u+v)/dx = du/dx + dv/dx; d(u-v)/dx = du/dx - dv/dx
d(uv)/dx = udv/dx + vdu/dx
d(u/v)/dx = (vdu/dx - udv/dx)/v
2
v = constant implies d(uv)/dx = (du/dx)vu(v-1)
d(eu)/dx = (du/dx)eu

Test your function on some interesting inputs. Add more rules (e.g., for trig functions) if you wish. For extra brownie points, you can write a simplifier to reduce the resulting expressions to their simplest form. For example, 0 * u simplifies to 0 and so on.

4. List recursion
Write the following functions:
(last-element l) returns the last element of l;
(all-but-last l) returns all but the last element;
(my-reverse l) returns the reversed list. (Should run in O(n) time.)
5. Powerset
A standard mathematical set function is powerset, which computes the set of all subsets of a set. For example,
```   >    (powerset '(a b))
(nil (a) (b) (a b))
```
Implement this as a recursive function. It may require other subsidiary functions.

6. Data types
(a) Write defstructss for points and line segments in two dimensions.
(b) Write a function (distance p1 p2) that returns the distance between two points.
(c) Write a function (midpoint l) that returns the midpoint of a line segment.
(d) Write a function (intersectp l1 l2) that decides if two line segments intersect. [Hint: the location of an arbitrary point on AB can be written as vA + (1-v)B; a point on CD is wC +(1-w)D; the lines cross where these are equal. This gives two equations (equating both x and y parts) for v and w. Solve these to find the intersection point, if any. Then you need to check that the intersection is actually on both segments - this can be determined by looking at the values of v and w.]
(e) A polygon can be defined by a list of points, where each point is assumed to be connected to the next. (You may wish to use the :type option to defstruct to make the structure itself be a list.) Define methods for calculating the area of a polygon. Begin with subtypes such as rectangle, square, triangle, regular polygon. Formulas for these can be found on the web. Optionally, you can provide a method that works for any polygon. You can assume that the list of points supplied to build any particular shape does in fact describe such a shape; for extra brownie points, include checks in the constructor functions.
(f) (Optional) A scene is a list of polygons. Write a method (visiblep scene p1 p2) that checks if one point is visible from another in a scene (that is, there is a straight line from one to the other not intersecting any polygon). Note that one vertex on a polygon should be visible from its immediate neighbors on the same polygon.
(g) (Optional) Create a scene full of polygons by instantiating your data types, using the coordinate data in here. Check to make sure that your visiblep predicate works.

7. Load the AIMA (textbook) code in ~cs188/code-2e-188 on the instructional machines (web-accessible here). Make sure it works by compiling the utilities and agents subsystems (do (aima-compile 'utilities) and (aima-compile 'agents)) and running (test 'utilities) and (test 'agents). If you want, you can try to write a better vacuum world agent. More information (somewhat outdated compared to the current version) on the AIMA code is available: see the overview and the instructions on how to use the code.