Name: __________________________________________________________________

Start time: _______________________________________________________________

End time: ________________________________________________________________

Honor code pledge:

________________________________________________________________________

Scores (to be completed by course staff)
Problem   Extra credit
1 2 3 4 5 Total 6 7 Total
Score
Possible 20 10 15 15 30 90 10 10 20

This is a take-home exam. It is due Wednesday December 14, 5pm. Turn it in to Dr. Taha's office, DH 3103.

You are allowed 5 contiguous hours to work on the exam.

You may use your textbook, notes, and any material provided as part of this course, whether printed or online. You may use any Scheme syntax and functions that have been introduced in class, lab, or the sections of textbook covered so far.

You may not use the rest of the Web, other people, or any other materials. You may not use DrScheme while taking the exam.

Read all instructions and problems carefully. You need only present the parts of the design recipe that are specifically asked for. If you have any questions about what a question is asking, make reasonable assumptions and document them.

Print this exam out, do your work in the space provided, and turn this in. If you need additional space, use the backs of the exam pages or additional paper.

1. (20 points total)
1. (10 points) Develop a function
```lastpos : [number] -> number or false
```
that returns the last positive number before the first zero. If there is no such number, return `false`. Do follow all steps of the design recipe that are relevant for defining such a function. Do not reverse the list or use side-effects, i.e., do not use `set!` or `set-…!`.

2. (5 points) Hand-evaluate the expression
```(lastpos (list 8 -1 2 -5 0 3 0))
```
You need only show the recursive calls and final result.

3. (5 points) Given a list of n numbers, what is the maximum number of recursive calls to `lastpos` that may be needed to compute a result?

2. (10 points total) The following function models a looping construct common to many programming languages.
```; for : number number number (number -> X) -> void
; Evaluates (body low)
;           (body (+ low incr))
;           (body (+ low incr incr))
;           …
; in that order, for each value of low+n*incr that is
; less than or equal to high.
; (define (for low high incr body) …)
```
1. (5 points) Write `for` without using any side-effects.

2. (5 points) Write `for` with side-effects, i.e., changing a local variable to successively take on the values `low`, `(+ low incr)`, …

3. (15 points) In the land of Nincompoopia, there is a castle with a magic dungeon and some strange jailers. For any given n you choose, the dungeon will have that many jail cells, each with a prisoner. Of course, all the cells are locked.

For the holidays, the jailers go through a strange ritual. First, they toggle every other cell lock, (counting from zero, the 0th, 2nd, 4th, …). I.e., if it's locked, they unlock it. If it's unlocked, they lock it. Next, they toggle every third cell lock (0th, 3rd, 6th, …). They continue in this fashion until they finally toggle every nth cell lock (just the 0th). After all that effort, the jailers go home for the holidays.

Write a function
```nincompoopia : natural -> natural
```
that simulates a dungeon of n jail cells. At the end, return the number of prisoner who get to escape because they're cells are unlocked at the end. Use `for` from the previous problem and vectors.

4. (15 points total) The purely functional lists that we have used for most of the course are sometimes described as singly-linked lists by imperative programmers. In particular, we can think of each ``` cons ``` struct as having a single "link" to the next struct via the ` rest ` field. In this problem, we will consider doubly-linked lists, where struct has a link to both the next AND the previous structs. For simplicitly, we will assume that the elements can only be 'Zero or 'One. We can use the following type definition to implement this idea:
```(define-struct (cons+ left value right))

; A doubly-linked list (dll) is one of
; - empty, or
; - (make-cons+ left value right),
;   where value is either 'Zero or 'One
;   and   left,right are doubly-linked lists.
```
A value `a-dll` of this type should maintain the following invariants:
• If it is empty, nothing more is required.
• If the `left` field is empty, nothing is required. But if the `left` field is not, then `(cons+-right (cons+-left a-dll))` should be exactly the same as `a-dll`.
• A similar condition holds for the `right` field.
With a singly-linked list, we need to know the first cell of the list. With a doubly-linked list, it's enough to have access to any cell, because we can move left and right along the list.

The goal of this exercise is to develop a mutable doubly-linked list that we can extend on the right (so we can always make it longer) and where we can change the value in the cell that we are currently at.
1. (5 points) Give code creating a doubly-linked list with one cell with value 'Zero. Give code creating a doubly-linked list with two cells, one with 'Zero, and one with 'One.

2. (5 points) Assume that `a-dll` is a globally-defined doubly-linked list. Write a function
```; write! : ('Zero or 'One) -> void
; Changes the value of the current cell of a-dll.
```

3. (5 points) Assume that `a-dll` is a globally-defined doubly-linked list. Write a function
```; move-right! : void -> void
; Changes the global list a-dll to be one element
; to the "right".  If there is no cell to the right,
; one is added with value `'Zero`.
```

For the rest of the exam, you can assume that you are given a `move-left!` function that moves left (if it can, and stays in place otherwise).
5. (30 points) One of the simplest and most widely used models of computation is called a finite-state machine (FSM). We can think of an FSM as a function with memory: At any point in time, it can take one input (for simplicity, we'll say the input can only be 'Zero or 'One), and change state based on its input and the current state. An FSM can only have a finite number of different states. We can assume that each state has a unique name in the form of a symbol. At any time, the machine is said to be "in" one of these states. Whenever the machine is given one input, the machine can change from one state to another. Such a change in state is called a transition. Transition rules have the form "If you see the input n and you are in state Current, then go to state Next". If there is no transition defined, then the machine is considered to have stopped and terminated all its work.

A simple example of an FSM is the traffic light, which has states named `'Red`, `'Yellow`, and `'Green`. As we said above, we will assume the only input it accepts are 'Zero and 'One. Then we need six rules that determine the next state based on the input and the current state. Note that we will also need the six rules to make sure the traffic light never stops!

Other examples of FSMs include the controllers for the dishwasher, soft-drink machine, your digital alarm clock, and, in fact, most appliances that we use everyday. This problem will give you practice with this concept that you'll see everywhere from now on.

In this problem we will implement an FSM using the same ideas that we used to implement graphs with sharing. We will use the following type definitions:
```; A machine is a list of states and a mutable global variable
; "current" which points to the current state.
;
; A state is
; - (make-state name ifZero ifOne)
;   where name is a symbol, and ifZero and ifOne are either states or false.
```
1. (10 points) Using exactly one `make-state` for each state, define a global variable `traffic-light` of type `machine`, which contains the three states discussed above. Note that you will model the transition rules by picking the value for `ifZero` and `ifOne` in each state. If the input is 'Zero, the light should go to red, independent of the current state. If the input is 'One, the light should move to the next color in the normal cycle (red, green, yellow, red, etc.).

2. (5 points) Define a function
```init_light : void -> void
```
that initializes the global variable `current` to the safest initial state.

3. (5 points) Write a function
```step : ('Zero or 'One) -> void
```
which takes the next input and makes one transition. This function should use only the global variable `current` and the current input. It should also work for any machine that we define, not just the traffic light.

4. (5 points) Define a function
```easy-machine : [symbol] -> [state]
```
that takes a list of symbols and creates an FSM where each given symbol names a state. All transitions in this machine are false. You should change the global variable `current` to be the initial state -- the first state in the list.

5. (5 points) Define a function
```any-machine : [symbol] [[symbol]] -> [state]
```
that takes takes a list of state names and a list of 3-element-lists and creates a FSM. Each 3-element list is a transition. The first element is a name for a state that should be in the machine, the second element is the name of an input (either 'Zero or 'One), and the third element is the name of the next state. For example, your function should be able to automatically produce the same result as you did by hand if you give it the list `(list 'Red 'Yellow 'Green)` and the following transitions:
```(list (list 'Red    'Zero 'Red)
(list 'Red    'One  'Green)
(list 'Yellow 'Zero 'Red)
(list 'Yellow 'One  'Red)
(list 'Green  'Zero 'Red)
(list 'Green  'One  'Yellow))
```
Make sure that the resulting machine will work properly with the `step` function from part (c).

6. (10 points -- extra credit) An extended finite state machine (EFSM) is an FSM with a notion of "action". An action is a value (make-action move output) where move is either `'Left` or `'Right` and output can be either `'Zero` or `'One`. Now, each transition also produces an action and an output.
1. (1 point) Write a revised definition of the type `machine`, and write a revised function
```step : ('Zero or 'One) -> action
```
which returns the action associated with the transition.

2. (1 point) Write a function
```step-from-dll : void -> action or false
```
which reads the input from `a-dll` and steps the EFSM using this input. The function returns false if there is no transition from the current state with the current input.

3. (1 point) Write a function
```step-with-dll : void -> bool
```
which reads the input from the `a-dll` and steps the EFSM using this input. It should return true if and only if the machine was able to make a move. If the resulting move is `'Left`, the move the `a-dll` left. Similarly for `'Right`. The output should be written to `a-dll` before the move is made.

4. (7 points) Write the code for building an EFSM that achieves the following task: If we start with `a-dll` containin a series of `'One`s, we end with a dll that has been extended with one `'Zero` and the same number of `'One`s. For example, if we start with `'One 'One 'One` on the dll, we can keep steping the machine until it stops. When it stops, we should have ```'One 'One 'One 'Zero 'One 'One 'One``` on `a-dll`. Your machine should use no more than ten states, but must still work for any series of `'Ones` of any length. The machine must stop after it has finished this task.
7. (10 points -- extra credit) Throughout the course, we used compound values and self-reference to model intersting structures, starting from natural numbers and lists and going to complicated mutable data structures. As it turns out, with a little bit of work, the lambda-calculus (consisting of only application, variables, and `lambda`) is enough to encode a lot of the types that we know. For example, Alonzo Church noticed that we can encode each natural number N with a function:
```c_N : (X->X) -> (X->X)

c_0 = (lambda (f) (lambda (x) x)
c_1 = (lambda (f) (lambda (x) (f x))
c_2 = (lambda (f) (lambda (x) (f (f x)))
…
```
1. (1 point) Let the type `ChNu = (X->X)->(X->X)`. Define the function
```add : ChNu ChNu -> ChNu
```
which takes encodings of m and n and returns an encoding of m+n.

2. (1 point) Define a similar function for multiplication.

3. (1 point) Define a similar function for exponentiation.

4. (7 points) Suggest a type `ChLiNu` for representing a list of numbers, and show how it can be used to define the `map` function on lists.