# Homework 3

## Working with semantics

This homework is written in literate Haskell; you can download the raw source to fill in yourself. You’re welcome to submit literate Haskell yourself, or to start fresh in a new file, literate or not.

Please submit homeworks via the DCI submission page.

For the rest of this course, you’re free to use any functions from the Prelude or standard libraries that come with the Haskell platform, e.g., `Data.Map`

and `Data.Set`

. That said—don’t use anything you don’t understand! If you can’t explain your solution to a homework problem, I don’t care whether or not it works—you’ll get a zero.

```
module Hw03 where
import Prelude
```

Okay—let’s start actually studying programming languages.

**Problem 1: compiling expressions to a stack machine**

The `eval`

function from the last homework is an *interpreter*: it takes in an abstract syntax tree (AST) and runs it immediately to produce a result. The `translate`

function you defined last week, from `ArithExp'`

to `ArithExp`

, is a miniature compiler. Let’s write a marginally less minimal compiler: we’ll translate arithmetic expressions to run on a tiny stack machine.

Our stack machine’s assembly language will have four instructions.

```
data Instruction =
IPush Int
| IPlus
| ITimes
| INeg
deriving Show
type Stack = [Int]
```

*(a) 10 points*

Implement a function that runs a single instruction. Here is the reduction relation:

Command | Input stack | Output stack | |
---|---|---|---|

IPush n | s | –> | n:s |

IPlus | n1:n2:s | –> | n1 + n2:s |

ITimes | n1:n2:s | –> | n1 * n2:s |

INeg | n:s | –> | (0-n):s |

Before you write this code, try to explain to yourself why the return type is `Maybe Stack`

.

```
instruction :: Instruction -> Stack -> Maybe Stack
instruction = undefined
```

Were you right?

*(b) (10 points)*

Explain what can go wrong when `instruction`

runs. What kind of errors can happen, and when? Why can `instruction`

run into errors but not the `eval`

function from last week?

*(c) (5 points)*

The `instruction`

function lets you run an individual step of our stack machine. Finish the function `program`

that runs multiple steps of the stack machine, where a program is just a list of instructions interpreted from front to back. (This is just like taking the reflexive, transitive closure of the `instruction`

function.)

For example, `program [IPush 21,IPush 21,IPlus] []`

should evaluate to `Just [42]`

.

```
type Program = [Instruction]
program :: Program -> Stack -> Maybe Stack
program p s = undefined
```

*(d) (10 points)*

Write a function `depth`

which can predict the depth of the output stack given a program and the depth of its input stack. Return `Nothing`

if the program will raise an error.

```
depth :: Program -> Int -> Maybe Int
depth = undefined
```

*(e) (10 points)*

Write a compiler from our original `ArithExp`

language (redefined here) to `Program`

s. You can use the function `runAndCompile`

below to test your code.

```
data ArithExp =
Num Int
| Plus ArithExp ArithExp
| Times ArithExp ArithExp
| Neg ArithExp
deriving (Eq,Show)
```

```
compile :: ArithExp -> Program
compile = undefined
```

```
runAndCompile :: ArithExp -> Int
runAndCompile e =
case program (compile e) [] of
Just [x] -> x
_ -> error "Your compiler is buggy!"
```

**Problem 2: lambda calculus reduction**

Please do problem 4.3 from Mitchell, page 83.

**Problem 3: symbolic reduction**

Please do problem 4.4 from Mitchell, page 83.

**Problem 4: Church numerals**

In class we defined Church numerals and booleans, and showed how to define more complex functions in the pure lambda calculus. Please show how to define the following functions in the pure lambda calculus. (You may use the functions defined in class in defining these new functions.)

Do these questions on paper, not in Haskell.

*(a) (5 points)*

Define a function `minus`

such that `minus m n`

reduces to `m - n`

if `m`

> `n`

and 0 otherwise. Do not use recursion, but instead define it directly. You may assume that you are given the function `pred`

defined in class that computes the predecessor of a number (where the predecessor of 0 is 0, predecessor of 1 is 0, 2 is 1, etc.). That is, your answer may include the term `pred`

without providing a definition of it.

```
minus m n =
fill in here
```

*(b) (5 points)*

Define a function `lessThan`

such that `lessThan m n`

reduces to `true`

iff `m`

< `n`

.

```
lessThan m n =
fill in here
```

*(c) (5 points)*

Define the recursive Fibonacci function `fib`

such that `fib 0`

reduces to 1, `fib 1`

reduces to 1, and `fib n`

reduces to `fib (n-1) + fib (n-2)`

for `n`

> 1. This is tricky as you are not allowed to name the function and use the name in the definition. You *must* use the Y combinator and emulate what we did in class defining `factorial`

.

You can just write `Y`

for the combinator.

` fill in here`

*(d) (5 points)*

Use your definition of fib from above to calculate fib 2. Do it step by step, showing all of your work. You may assume that `fib 1`

and `fib 0`

both reduce to 1, that `pred 2`

reduces to 1, and that `plus 1 1`

reduces to 2 without showing all of the reduction steps. All other steps in the reduction should be shown. You can write Church numerals as actual numbers, i.e., 0 to mean `\s z. z`

and 1 to `\s z. s z`

.

Note that I just want the steps—you don’t need to write derivations for every step taken!

```
fib 2 =
(your definition of fib) 2 -->
... fill in the steps ...
```