(** 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. *)

(** **** Exercise: 3 stars (insert_SearchTree)  *)
Theorem insert_SearchTree:
forall k v t,
SearchTree t -> SearchTree (insert k v t).