(** The question is, why did we not need the representation invariant in the proof of [lookup_relate]?  The answer is that our particular Abs relation is much more clever than necessary:  *)
Print Abs.
(* Inductive Abs : tree -> total_map V -> Prop := Abs_E : Abs E (t_empty default) | Abs_T : forall (a b: total_map V) (l: tree) (k: key) (v: V) (r: tree), Abs l a -> Abs r b -> Abs (T l k v r) (t_update (combine k a b) (Id k) v) *)
(** Because the [combine] function is chosen very carefully, it turns out that this abstraction relation even works on bogus trees! *)
Remark abstraction_of_bogus_tree:
forall v2 v3,
Abs (T (T E 3 v3 E) 2 v2 E) (t_update (t_empty default) 2 v2).
(** Step through the proof to [LOOK HERE], and notice what's going on. Just when it seems that [(T (T E 3 v3 E) 2 v2 E)] is about to produce [v3] while [(t_update (t_empty default) (Id 2) v2)] is about to produce [default], [omega] finds a contradiction.  What's happening is that [combine 2] is careful to ignore any keys >= 2 in the left-hand subtree.  For that reason, [Abs] matches the _actual_ behavior of [lookup], even on bogus trees.  But that's a really strong condition!  We should not have to care about the behavior of [lookup] (and [insert]) on bogus trees.  We should not need to prove anything about it, either.  Sure, it's convenient in this case that the abstraction relation is able to cope with ill-formed trees.  But in general, when proving correctness of abstract-data-type (ADT) implementations, it may be a lot of extra effort to make the abstraction relation as heavy-duty as that. It's often much easier for the abstraction relation to assume that the representation is well formed.  Thus, the general statement of our correctness theorems will be more like [lookup_relate'] than like [lookup_relate].  *)
(* ################################################################# *)
(** * Every Well-Formed Tree Does Actually Relate to an Abstraction *)
(** We're not quite done yet.  We would like to know that _every tree that satisfies the representation invariant, means something_.  So as a general sanity check, we need the following theorem: *)

(* Specifications: *)
(** **** Exercise: 2 stars (can_relate)  *)
Lemma can_relate:
forall t,  SearchTree t -> exists cts, Abs t cts.