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.(*
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'.(*
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'.Definition insert_spec (n : Z) (t : Z_btree) :=
  search t -> {t' : Z_btree | INSERT n t t'}.

(* Specifications: *)
Lemma insert_leaf : forall n : Z, INSERT n Z_leaf (Z_bnode n Z_leaf Z_leaf).
Lemma insert_l : forall (n p : Z) (t1 t'1 t2 : Z_btree), (n < p)%Z -> search (Z_bnode p t1 t2) -> INSERT n t1 t'1 -> INSERT n (Z_bnode p t1 t2) (Z_bnode p t'1 t2).
Lemma insert_r : forall (n p : Z) (t1 t2 t'2 : Z_btree), (n > p)%Z -> search (Z_bnode p t1 t2) -> INSERT n t2 t'2 -> INSERT n (Z_bnode p t1 t2) (Z_bnode p t1 t'2).
Lemma insert_eq : forall (n : Z) (t1 t2 : Z_btree), search (Z_bnode n t1 t2) -> INSERT n (Z_bnode n t1 t2) (Z_bnode n t1 t2).
Lemma insert : forall (n : Z) (t : Z_btree), insert_spec n t.