Library HW7

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.

Index
This page has been generated by coqdoc