(** * Maps: Total and Partial Maps *)
(** Maps (or dictionaries) are ubiquitous data structures both generally and in the theory of programming languages in particular; we're going to need them in many places in the coming chapters.  They also make a nice case study using ideas we've seen in previous chapters, including building data structures out of higher-order functions (from [Basics] and [Poly]) and the use of reflection to streamline proofs (from [IndProp]).  We'll define two flavors of maps: _total_ maps, which include a "default" element to be returned when a key being looked up doesn't exist, and _partial_ maps, which return an [option] to indicate success or failure.  The latter is defined in terms of the former, using [None] as the default element. *)
(* ################################################################# *)
(** * The Coq Standard Library *)
(** One small digression before we get to maps.  Unlike the chapters we have seen so far, this one does not [Require Import] the chapter before it (and, transitively, all the earlier chapters).  Instead, in this chapter and from now, on we're going to import the definitions and theorems we need directly from Coq's standard library stuff.  You should not notice much difference, though, because we've been careful to name our own definitions and theorems the same as their counterparts in the standard library, wherever they overlap. *)
(** Documentation for the standard library can be found at http://coq.inria.fr/library/.  The [Search] command is a good way to look for theorems involving objects of specific types.  Take a minute now to experiment with it. *)
(* ################################################################# *)
(** * Identifiers *)
(** First, we need a type for the keys that we use to index into our maps.  For this purpose, we again use the type [id] from the [Lists] chapter.  To make this chapter self contained, we repeat its definition here, together with the equality comparison function for [id]s and its fundamental property. *)
Inductive id : Type :=
| Id : string -> id.
Definition beq_id x y :=
match x,y with
| Id n1, Id n2 => if string_dec n1 n2 then true else false
end.
(** (The function [string_dec] comes from Coq's string library. If you check its result type, you'll see that it does not actually return a [bool], but rather a type that looks like [{x = y} + {x <> y}], called a [sumbool], which can be thought of as an "evidence-carrying boolean."  Formally, an element of [sumbool] is either a proof that two things are equal or a proof that they are unequal, together with a tag indicating which.  But for present purposes you can think of it as just a fancy [bool].) *)

(* Specifications: *)
Theorem beq_id_refl : forall id, true = beq_id id id.
(** The following useful property of [beq_id] follows from an analogous lemma about strings: *)
Theorem beq_id_true_iff : forall x y : id,
beq_id x y = true <-> x = y.