As an alternative, you can try the interpeter
`~cs152/bin/mllisp`, which has the following features:

- The highly useful
`use`primitive, which lets you type, e.g.,(use '~cs152/kamin/code.lsp)

to read in and evaluate all the code in that file. It's something like`#include`

in C. - This interpreter is written in ML, so it is guaranteed not to dump core without an explanation.
- There are no limits on the length of anything.

. In particular, it handles quoting differently.`mllisp`is not an exact match for the Kamin Lisp interpreter- The implementation in Moscow ML is itself interpreted, so programs
run about 20 times slower than in the C version.
You can try compiled code by using
`~cs152/bin/mllispx`; it may start slower but will run large programs faster. It also may be less helpful in case of an error.

We recommend that you use `mllisp`, `qlisp`, or `mllispx`
for development but that you
test your work on the C `lisp` before turning it in.
Remember *not* to include `quit` in your solutions!

There are two regular problems and one extra-credit problem for this assignment:

*Assocation lists*. It is possible to use an association list to represent a directed graph. Write a LISP function to topologically sort such a graph. The function`(tsort alist)`should return a list that gives the keys in association list`alist`in topological order. The pairs of symbols in`alist`specify precedence constraints, e.g.,`'(a b)`indicates that`a`must precede`b`in the output list. As an example,`(tsort '((a b) (a c) (c b) (d b)))`can return either`'(a d c b)`or`'(a c d b)`. For details on topological sorting, see Sedgewick, chapter 32 or Knuth vol 1, section 2.2.3.Note that you will do best if you implement several small ``helper'' functions. Your documentation/explanation for this assignment should be sure to explain those functions.

For extra credit, have

`tsort`print out a cycle if the graph has a cycle.My functional solution to this problem, with comments, is 104 lines of code. My imperative solution is 88 lines.

*The metacircular evaluator*. Do exercise 6 on page 61 of Kamin, which extends the LISP metacircular evaluator by adding`begin`,`set`,`print`, and local variables. We have extracted the lisp code you need to get started (for`eval`,`r-e-p-loop`, and related functions) from`~cs152/kamin/code.lsp`.The crucial part of this assignment is handling mutation, especially setting of local variables. When you did this in C, you could simply change bindings in place. In pure LISP, you can't mutate the environment; instead, you have to create a new environment with new bindings. You must be sure to return that new environment from

`eval`, so that the new environment is used in the future. But`eval`also has to return a value! Obviously you have to figure out a way to return*both*, so you can evaluate expressions both for their results and for their side effects. The hard part is figuring out what to do with the environment after you return it. You can't just throw it on the floor; you*have*to make sure it gets seen in subsequent evaluations.Here's a high-stress test case to help you with this problem.

(define rough () (x) (begin (begin (set x 1)) x))

A call to`(rough)`

should return 1.*Good functional style*. The function(define f-imperative (y) (begin (set x e) (while (p x y) (set x (g x y))) (h x y)))

is in a typical imperative style, with assignment and looping. Write an equivalent function`f-functional`that doesn't use the imperative features`begin`(sequencing),`while`(goto), and`set`(assignment). You may use as many ``helper functions'' as you like.*Hint #1:*If you have trouble getting started, rewrite`while`to use`if`and`goto`. Now, what is like a`goto`?*Hint #2:*`(set x e)`

creates a binding of`e`to the name`x`. What other ways do you know of creating a binding of`e`to the name`x`?Don't be confused about the purpose of this exercise. The exercise is a ``thought experiment.'' We don't want you to write and run code for some particular choice of

`g`,`h`,`p`,`e`,`x`, and`y`. Instead, we want you write a function that works the same as`f-imperative`given*any*choice of`g`,`h`,`p`,`e`,`x`, and`y`. So for example, if`f-imperative`would loop forever on some inputs, your`f-functional`should also loop forever on exactly the same inputs.Once you get your mind twisted in the right way, this exercise should be easy. The point of the exercise is not only to show that you can program without imperative features, but help you develop a technique for eliminating such features. You'll use this technique again later on.

*Extra credit---programs as data*. Consider the class of well-formed arithmetic computations using the numeral 5. These are expressions formed by taking the integer literal 5, the four arithmetic operators +, -, *, and /, and properly placed parentheses. Such expressions correspond to binary trees in which the internal nodes are operators and every leaf is a 5. Write a LISP program to answer one or more of the following questions:- What is the smallest positive integer than cannot be computed by an expression involving exactly five 5's?
- What is the largest prime number that can computed by an expression involving exactly five 5's?
- Exhibit an expression that evaluates to that prime number.

- Explain how you would change your implementation to use
*exact*division instead of integer division.

*Hints:*- You can build S-expressions that represent the arithmetic expressions in the problem,
and you can just call
`eval`to find out what they evaluate to. - This problem involves an exhaustive search (for all numbers that can be computed with 5's), so good techniques are important. This is an excellent problem for dynamic programming.
- It will help you debug if you write a 'set of integer' implementation that keeps elements in order.
- You may want to speed up the search by writing a specialized version of eval.
- You may have to do something special to avoid division by zero. This is something of a pain in LISP, but you can cheat by specializing eval.
- Rational arithmetic is a good way to implement exact division.

~cs152/bin/submit README solution[123]In the

Files that do not compile will not be graded; your first two solutions should pass the test

qlisp < solutionwithout any diagnostics.x

If you do the extra credit, please submit `solution4` and
include an explanation in your README file.