Section search_tree_basic_properties.
Variables (n : key) (v : data) (t1 t2 : btree).
Hypothesis se : search_tree (bnode n v t1 t2).
Hint Resolve search_tree_l: searchtrees.
Hint Resolve search_tree_r: searchtrees.
Hint Resolve maj_l: searchtrees.
Hint Resolve min_r: searchtrees.
Hint Resolve not_right: searchtrees.
Hint Resolve not_left: searchtrees.
End search_tree_basic_properties.
Hint Resolve go_left go_right not_left not_right search_tree_l search_tree_r
maj_l min_r: searchtrees.
(* each key occurs at most once *)
(* 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'}.
Hint Resolve insert_leaf: searchtrees.
(* Inserting in the left son *)
(* inserting in the right son *)
(* inserting at the root ; please notice that the most recent value is stored *)
Hint Resolve insert_l insert_r insert_eq: searchtrees.
Definition insert :
forall (n : key) (v : data) (t : btree), insert_spec n v t.
simple induction t.
exists (bnode n v leaf leaf).
auto with searchtrees.
unfold insert_spec at 3 in |- *; intros p b t1 H1 t2 H2 H0.
case (M.le_lt_dec n p).
intro H; case (M.le_lt_eq_dec n p H).
intro H'.
case (H1 (search_tree_l _ _ _ _ H0)).
intros t3; exists (bnode p b t3 t2).
auto with searchtrees.
intro e; rewrite e; exists (bnode p v t1 t2); auto with searchtrees.
case (H2 (search_tree_r _ _ _ _ H0)).
intros t3; exists (bnode p b t1 t3).
auto with searchtrees.
Defined.
(* realisation of the DICT  signature *)
(* dictionaries are represented as  certified binary search trees *)
Definition dict : Set := sig search_tree.
Definition empty : dict.
unfold dict in |- *; exists leaf.
left.
Defined.
Definition find (k : key) (d : dict) : option data :=
let (t, Ht) := d in
match occ_dec k t Ht with
| inleft s => let (v, _) := s in Some v
| inright _ => None (A:=data)
end.
Definition add : key -> data -> dict -> dict.
refine
(fun (k : key) (v : data) (d : dict) =>
let (t, Ht) := d in
let (x, Hx) := insert k v t Ht in exist search_tree x _).
case Hx; auto.
Defined.
(* Now, we've got to prove the axioms *)
Definition D_tree (d : dict) : btree := match d with
| exist t Ht => t
end.

Lemma not_find_occ_dec :
forall (k : key) (d : dict),
(forall v : data, ~ occ v k (D_tree d)) -> find k d = None.