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.
Please try to comment your code and use, meaningful variable names.
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.)
- Write a LISP function (count-trees n)
which returns the number of distinct strictly binary trees with
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.
- 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
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)/v2
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.
- 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.)
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.
- 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
(c) Write a function (midpoint
l) that returns the midpoint of a line
(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
Check to make sure that your visiblep
- Load the AIMA (textbook) code in ~cs188/code-2e-188
on the instructional machines (web-accessible
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
on how to use the code.