15-212-X : Homework Assignment 3

**Due Wed Oct 8, 2:00pm (electronically); papers at recitation.
**

Maximum Points: 100 (+20 extra credit)

- Strive for elegance in your code! Not every program which runs deserves full credit. Make sure to state invariants in comments which are sometimes implicit in the informal presentation of an exercise. If auxiliary functions are required, describe concisely what they implement. Do not reinvent wheels and try to make your functions small and easy to understand. Use tasteful layout and avoid longwinded and contorted code. None of the problems requires more than a few lines of SML code.
- Make sure that your file compiles and runs. A program which doesn't run will not get full credit and is likely to incur a heavy penalty.
- Homeworks must be all your own work.
- Late homeworks will be accepted
**only**until start lecture on Thursday, with a 25% penalty. - If you have any questions about the assignment, contact Frank Pfenning
at
`fp@andrew.cmu.edu`or use`cmu.andrew.academic.15-212-X.discuss`.

Please include needed auxiliary declarations from the ML files in

signature DICT = sig type key = int * int type 'a entry = key * 'a type 'a dict val empty : 'a dict val lookup : 'a dict -> key -> 'a option val insert : 'a dict * 'a entry -> 'a dict val delete : 'a dict * key -> 'a dict val map : 'a dict -> ('a -> 'b) -> 'b dict val fold : 'a dict -> ('a * 'b * 'b -> 'b) -> 'b -> b' val exists : 'a dict -> ('a entry -> bool) -> bool end; (* signature DICT *)There is a partial implemenation of a structure

`BinarySearchTree`

with this
signature in the file `map `*d* *f*

should go through the
whole dictionary
`map`

.
`fold `*d* *f* *init*

should go through the binary tree `d`

and return
`init`

if it encounters a leaf. For every other node in the tree
it should return *f*(*datum*,*vLeft*,*vRight*)

where
`fold`

on the left subtree,
`fold`

on the right
subtree. Write the function
`fold`

.
`exists `*d* *p*

should return
`true`

if there is an entry in the database satisfying the
predicate `false`

otherwise. Write the function `exists`

.
`delete (`*d*, *k*)

should return a
dictionary Another company is interested in purchasing CMU's dictionary package: GAMESoft intends to implement the PEG solitaire game. The PEG solitaire game is best described as follows: A PEG board contains 15 holes, shaped in form of a triangle. Every hole can be addressed by a pair of coordinates.

Initially 14 of the holes are filled with pegs . That means there is one empty hole somewhere on the
board. In our example it is `(1,2)`

, which is the standard
initial board.

During the game it is possible to take a peg, jump over a peg into an empty hole. The peg that was jumped over is then removed from the board. It is important that

- the jumping peg jumps 2 fields,
- the destination is an empty hole,
- and there is a peg inbetween.

The goal of the peg solitaire game is to jump pegs in such a way that only one peg remains on the board eventually.

Initially GAMESoft was only interested in purchasing CMU's dictionary
package. But because of its nice implementation, GAMESoft decided to ask
you for programming help. Here is what the company has already done using
the signature `DICT`

from above:

structure Dict :> DICT = BinarySearchTree; datatype square = Peg | Hole; type board = square Dict.dict; structure Dir = struct datatype direction = East | NorthEast | NorthWest | West | SouthWest | SouthEast fun increment (East) = (1,0) | increment (NorthEast) = (0,1) | increment (NorthWest) = (~1,1) | increment (West) = (~1,0) | increment (SouthWest) = (0,~1) | increment (SouthEast) = (1,~1) fun exists p = p East orelse p NorthEast orelse p NorthWest orelse p West orelse p SouthWest orelse p SouthEast end; fun initialize (i,j) b = next (i,j) (Dict.insert (b,((i,j),Peg))) and next (0,0) b = b | next (i,0) b = initialize (i-1,5-i) b | next (i,j) b = initialize (i,j-1) b; val fullBoard = initialize (4,0) (Dict.empty);See the file

`solve : int -> board -> bool`

, where
`solve `*n* *b*

returns `true`

if there is a
possibility to make `false`

.
That means if `solve 13`

applied to the initial
board returns `true`

then there is a way
to remove all but one peg. Is your implementation efficient enough
to determine that there cannot be 14 consecutive moves?
`solution`

containing enough information
so that a sequence of moves can easily be replayed from it.
Generalize the function from Question 2.1 to a function
findSolution : int -> board -> solution optionwhich returns the first found solution or

`NONE`

for the
given number of moves `findSolution 13`

on the standard initial board.
`R`

:
- Characters
**a** - Concatentation
*r*_{1}r_{2} - The empty string
`One`

- Alternative
*r*+_{1}*r*_{2} - Empty set
`Zero`

- Repetition
*r*^{*}

datatype regexp = Char of char | Times of regexp * regexp | One | Plus of regexp * regexp | Zero | Star of regexp;From time to time it is helpful to have some more constructs available to form regular expressions, such as

- A wildcard symbol
**_**which accepts any characterL(

**_**) = {**a**|**a**is a character in the alphabet}`Underscore`

. - Intersection
which accepts a string only if it is contained in*r*_{1}&*r*_{2}*r*and simultaneously in_{1}*r*._{2}L(

*r*_{1}&*r*_{2}) = {*s*|*s*in L(*r*_{1}) and*s*in L(*r*_{2})}`And`

. - A wildcard
**T**which matches any string.L(

**T**) = {*s*|*s*is a string over the alphabet}`Top`

. - Negation
**~**which contains every string which is not contained in*r**r*.L(~

*r*) = {*s*|*s*not in*r*}`Not`

.

`accept`

is available in the
file `acc`

function and make sure your new
cases fit this specification. You should also generate some test data
to validate your implementation.
Note that for the purposes of our implementation, the alphabet is simply
any ML value of type `char`

.
- Put your SML code into a single file named
`ass3.sml`in your ass3 directory. All of your definitions should be in this one file. Please keep a backup for your records. Your handin directory for this assignment is`/afs/andrew/scs/cs/15-212-X/studentdir/<your andrew id>/ass3/`