End search_tree_basic_properties.
Hint Resolve go_left go_right not_left not_right search_l search_r maj_l
min_r: searchtrees.
Definition sch_spec (p : Z) (t : Z_btree) :=
search t -> {occ p t} + {~ occ p t}.
Definition sch : forall (p : Z) (t : Z_btree), sch_spec p t.
refine
(fix sch (p : Z) (t : Z_btree) {struct t} : sch_spec p t :=
match t as x return (sch_spec p x) with
| Z_leaf => fun h => right _ _
| Z_bnode n t1 t2 =>
fun h =>
match Z_le_gt_dec p n with
| left h1 =>
match Z_le_lt_eq_dec p n h1 with
| left h'1 =>
match sch p t1 _ with
| left h''1 => left _ _
| right h''2 => right _ _
end
| right h'2 => left _ _
end
| right h2 =>
match sch p t2 _ with
| left h''1 => left _ _
| right h''2 => right _ _
end
end
end); eauto with searchtrees.
rewrite h'2; auto with searchtrees.
Defined.
Extraction sch.
(* let rec sch p t x = match t with Z_leaf -> right | Z_bnode (n, t1, t2) -> (match Z_le_gt_dec p n with left -> (match match Zcompare p n with EGAL -> right | INFERIEUR -> left | SUPERIEUR -> assert false  with left -> sch p t1 prop | right -> left) | right -> sch p t2 prop) *)
(* Definition of an INSERT predicate (a la  Prolog) ***************************************************  We begin with the definition of a predicate:  (INSERT n t t') if t' is a binary search tree containing exactly n and the elements of t *)
Inductive INSERT (n : Z) (t t' : Z_btree) : Prop :=
insert_intro :
(forall p : Z, occ p t -> occ p t') ->
occ n t' ->
(forall p : Z, occ p t' -> occ p t \/ n = p) ->
search t' -> INSERT n t t'.
Hint Resolve insert_intro: searchtrees.
Definition insert_spec (n : Z) (t : Z_btree) :=
search t -> {t' : Z_btree | INSERT n t t'}.

Lemma insert_leaf : forall n : Z, INSERT n Z_leaf (Z_bnode n Z_leaf Z_leaf).