Homework Assignment 7 Interactive Computer Theorem Proving CS294-9, Fall 2006 UC Berkeley |
Require
Import
List.
Set Implicit
Arguments.
This assignment involves producing two strongly-specified implementations of
the same abstract data type. We'll use Coq's module system to express this
idea. I don't think you need to be an expert on ML-style module systems to do
this assignment, since I've filled in all of the module-related parts in the
template, but the curious can consult
the
OCaml manual's tutorial.
Feel free to copy some of the infrastructure for programming with specifications from the Lecture 8 code; you might want to add some of your own code in that spirit, too. Template source file |
Signatures |
First, we define what it means to implement the dictionary ADT. |
Module Type
DICTIONARY.
We have some Set that forms the keys of dictionaries.
|
Parameter
domain : Set.
We have the type of dictionaries, indexed by the type of data being stored. |
Parameter
dict : Set -> Set.
Look up the data associated with a given key. |
Parameter
lookup : forall (range : Set), dict range -> domain -> option range.
The empty dictionary |
Parameter
empty : forall (range : Set),
{D : dict range | forall (d : domain), lookup D d = None}.
Adding a mapping |
Parameter
add : forall (range : Set) (D : dict range) (d : domain) (r : range),
{D' : dict range | lookup D' d = Some r
/\ forall (d' : domain), d <> d' -> lookup D' d' = lookup D d'}.
End
DICTIONARY.
This signature defines what we will require from clients who want to build dictionaries for particular key types. |
Module Type
DICTIONARY_PARAM.
Parameter
domain : Set.
Parameter
domain_eq_dec : forall (x y : domain), {x = y} + {x <> y}.
...so all that we require is that equality on the key type is decidable. |
End
DICTIONARY_PARAM.
Naive dictionaries using functions |
We'll implement the dictionary ADT using the most obvious (and quite inefficient!) representation: dictionaries will be the lookup functions themselves. |
Module
FuncDictionary (Param : DICTIONARY_PARAM) : DICTIONARY
with Definition
domain := Param.domain.
Import
Param.
Section
dict.
Variable
range : Set.
Defined as promised, dictionaries are lookup functions. |
Definition
dict := domain -> option range.
That makes lookup very convenient to write. :-)
|
Definition
lookup : dict -> domain -> option range := fun D => D.
Fill in a definition for empty .
|
Definition
empty : {D : dict | forall (d : domain), lookup D d = None}.
Admitted.
Fill in a definition for add .
|
Definition
add : forall (D : dict) (d : domain) (r : range),
{D' : dict | lookup D' d = Some r
/\ forall (d' : domain), d <> d' -> lookup D' d' = lookup D d'}.
Admitted.
End
dict.
Definition
domain := domain.
End
FuncDictionary.
Of course, it's always fun to see the OCaml version of your implementation. |
Extraction FuncDictionary.
Dictionaries using unsorted lists |
Now we'll implement dictionaries using the more efficient representation of unsorted association lists with no duplicates. |
Module
ListDictionary (Param : DICTIONARY_PARAM) : DICTIONARY
with Definition
domain := Param.domain.
Import
Param.
Section
dict.
Variable
range : Set.
We start by defining an auxiliary dependent, list-like type.
The list parameter to dict' expresses the keys that have "already been
used" and so may not appear again.
|
Inductive
dict' : list domain -> Set :=
| Nil : forall ls,
dict' ls
| Cons : forall ls d,
~In d ls
-> range
-> dict' (d :: ls)
-> dict' ls.
A dictionary is just a dict' where no keys have already been used.
|
Definition
dict := dict' nil.
The obvious lookup function |
Fixpoint
lookup' (ls : list domain) (D : dict' ls) (d : domain) {struct D}
: option range :=
match D with
| Nil _ => None
| Cons _ d' _ r D' =>
if domain_eq_dec d d'
then Some r
else lookup' D' d
end.
Definition
lookup := lookup' (ls:= nil).
Fill in a definition for empty .
|
Definition
empty : {D : dict | forall (d : domain), lookup D d = None}.
Admitted.
Fill in a definition for add . You'll probably want some auxiliary
definitions for this one.
|
Definition
add : forall (D : dict) (d : domain) (r : range),
{D' : dict | lookup D' d = Some r
/\ forall (d' : domain), d <> d' -> lookup D' d' = lookup D d'}.
Admitted.
End
dict.
Definition
domain := domain.
End
ListDictionary.
Extraction ListDictionary.