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

Theorem insert_relate':
forall k v t cts,
SearchTree t ->
Abs t cts ->
Abs (insert k v t) (t_update cts k v).