(* given a key and a search tree, we return either an associated value or the proof of its non-existence *)
Definition occ_dec_spec (k : key) (t : btree) :=
search_tree t -> {v : data | occ v k t} + {(forall v : data, ~ occ v k t)}.
Definition occ_dec : forall (k : key) (t : btree), occ_dec_spec k t.
intro p; simple induction t.
right.
auto with searchtrees.
intros n v t1 R1 t2 R2 H.
case (M.le_lt_dec p n).
intro H0; case (M.le_lt_eq_dec p n H0).
intro H1; case R1.
eauto with searchtrees.
simple destruct 1; intros v' H'.
left.
exists v'; eauto with searchtrees.
right.
intros v0 H3.
apply (n0 v0); eauto with searchtrees.
simple destruct 1; left.
exists v; eauto with searchtrees.
intro H2; case R2.
eauto with searchtrees.
simple destruct 1; intros v' H'.
left.
exists v'; eauto with searchtrees.
right.
intros v0 H3.
apply (n0 v0); eauto with searchtrees.
Defined.
(* t' is obtained by inserting (n,v) into t *)
Inductive INSERT (n : key) (v : data) (t t' : btree) : Prop :=
insert_intro :
(forall (p : key) (v' : data), occ v' p t -> p = n \/ occ v' p t') ->
occ v n t' ->
(forall (p : key) (v' : data),
occ v' p t' -> occ v' p t \/ n = p /\ v = v') ->
search_tree t' -> INSERT n v t t'.
Hint Resolve insert_intro: searchtrees.
Definition insert_spec (n : key) (v : data) (t : btree) : Set :=
search_tree t -> {t' : btree | INSERT n v t t'}.

(* Specifications: *)
Lemma insert_leaf :
forall (n : key) (v : data), INSERT n v leaf (bnode n v leaf leaf).