(** Before we prove that [elements] is correct, let's consider a simpler version. *)
Fixpoint slow_elements (s: tree) : list (key * V) :=
match s with
| E => nil
| T a k v b => slow_elements a ++ [(k,v)] ++ slow_elements b
end.
(** This one is easier to understand than the [elements] function, because it doesn't carry the [base] list around in its recursion. Unfortunately, its running time is quadratic, because at each of the [T] nodes it does a linear-time list-concatentation.  The original [elements] function takes linear time overall; that's much more efficient.  To prove correctness of [elements], it's actually easier to first prove that it's equivalent to [slow_elements], then prove the correctness of [slow_elements].  We don't care that [slow_elements] is quadratic, because we're never going to really run it; it's just there to support the proof. *)

(* Specifications: *)
(** **** Exercise: 3 stars, optional (elements_slow_elements)  *)
Theorem elements_slow_elements: elements = slow_elements.
Lemma list2map_app_left:
forall (al bl: list (key*V)) (i: key) v,
In (i,v) al -> list2map (al++bl) i = list2map al i.
Lemma list2map_app_right:
forall (al bl: list (key*V)) (i: key),
~(exists v, In (i,v) al) -> list2map (al++bl) i = list2map bl i.
Lemma list2map_not_in_default:
forall (al: list (key*V)) (i: key),
~(exists v, In (i,v) al) -> list2map al i = default.
(** **** Exercise: 3 stars, optional (elements_relate)  *)
Theorem elements_relate:
forall t cts,
SearchTree t ->
Abs t cts ->
list2map (elements t) = cts.
(** **** Exercise: 3 stars (insert_SearchTree)  *)
Theorem insert_SearchTree:
forall k v t,
SearchTree t -> SearchTree (insert k v t).
Theorem insert_relate':
forall k v t cts,
SearchTree t ->
Abs t cts ->
Abs (insert k v t) (t_update cts k v).