15-212-X : Homework Assignment 3
Due Wed Oct 9, 10:00 am (electronically); papers at recitation.
Maximum Points: 100 (+20 extra credit)
Guidelines
- While we acknowledge that beauty is in the eye of the beholder, you
should nonetheless 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 Carsten
Schuermann at carsten@cs.cmu.edu or use
cmu.andrew.academic.15-212-X.discuss.
Problem 1: Dictionaries (35 points)
The company DataSoft decided recently to purchase CMU's dictionary
package promising fast and easy access to their client records. The
contract requires CMU to extend the signature of their dictionary
package by a delete function, and a few other functions.
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 partial implemenation of this structure as a
BinarySearchTree
. Plese extend this structure according to
the following questions.
Question 1.1 (5 points)
The function map d f
should go through the whole dictionary
d
and apply the function f
to every entry,
creating a new dictonary. Write the function map
.
Question 1.2 (10 points)
The function fold d f init
should go through the
binary tree d
, return
init
if it encounters a leaf, for every other node in the tree
it should return f(datum,v_left,v_right)
where
datum
is the datum of the node, and v_left
is the result
of summarizing the left subtree, v_right
is the result of summarizing
the right subtree. Write the function fold
.
Question 1.3 (5 points)
Implement the function exists
. exists d f
must return
true
if there is an entry in the database satisfying f
,
false
otherwise.
Question 1.4 (15 points)
For the implementation of the delete
function, here is the
what DataSoft and CMU agreed on:
- If the node to be removed has no children, just remove the node.
- If the node to be removed has one child, remove it and connect the
child to the parent.
- If the node to be removed has two children, look for the
successor remove the successor, and update the entry in the node
to be removed by the successor node entry. Here, the
successor to a node n is the node whose key is
greater than the key of n, but smaller than any other
node greater than n.
- If the node to be removed cannot be found in the tree (even if it
is empty), the result of the
delete operation should
be the tree itself.
Implement the delete
function. Why is it always
possible to delete the successor node in the third case?
Problem 2: The PEG game (35 points)
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 clearly (1,2)
.
During the game it is possible to take a peg, jump over a peg into an
empty hole. It is important that
- the jumping peg jumps 2 fields,
- the destination is an empty hole,
- and there is a peg inbetween.
It should be clear that pegs might jump into six different directions.
While jumping over a peg the jumped peg is removed. 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 initialBoard = initialize (4,0) (Dict.empty);
The source code is also available.
Question 2.1 (35 points)
Write a function play: int -> board -> bool
, where
play n b
returns true
if there is a
possibility to make n
consecutive moves otherwise false.
That means if play 13
applied to the initial
board returns true then there is a way
to remove all but one peg.
GAMESoft is very grateful for your support.
Problem 3: Regular expressions (30 points +20 extra credit)
In class five different operatores have been introduced to describe
regular expressions R
:
- Characters
c
- Concatentation
R1.R2
- Epsilon, the empty string
e
- Alternative
R1+R2
- Empty set
Empty
- Repetition
R*
This has been implemented as datatype -- as presented in class.
datatype regExp
= Char of char
| Times of regExp * regExp
| Epsilon
| Plus of regExp * regExp
| Empty
| Star of regExp
From time to time it is helpful to have some more constructs available
to form regular expressions, such as
- Don't care symbol
_
which accepts any
character
[[_]] = {c | c is a character}
The constructor must be called Underscore
.
- Intersection
R1 & R2
which
accepts a string only if it is contained in R1
and simultanieously in R2
.
[[R1 & R2]] = [[R1]] Intersection [[R2]]
The constructor must be called And
.
- Wildcard for strings
T
which accepts arbitrary many
characters (even 0)
[[T]] = {s | s is a string in the language}
The constructor must be called Top
.
- Negation
~ R
which contains every string which is
not contained in R
.
[[~R]] = {s | s is not in [[R]]}
The constructor must be called Not
.
The acceptor accept is available and
should be extended to deal with these new constructors
Question 3.1 (10 points)
Implement the cases for don't care symbols and intersection.
Question 3.2 (10 points)
Implement the case for Top.
Question 3.3 (10 points)
Explain in detail why your implementation of the
acceptor function terminates (consider also the given cases in your
explanation).
Question 3.4 (Extra credit 20 points)
Implement the case for Negation.
For some test data click here .
Handin instructions
- Put your SML code into a file named ass3.sml in your ass3 directory. All
of your definitions should be in this one file. Your handin directory is
/afs/andrew/scs/cs/15-212-X/studentdir/<your andrew id>/ass<number>