(* V:        INSERTION 
**********************************
**********************************


V.1   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 : nat) (t t' : nat_tree) : Prop :=
    insert_intro :
      (forall p : nat, occ t p -> occ t' p) ->
      occ t' n ->
      (forall p : nat, occ t' p -> occ t p \/ n = p) ->
      search t' -> INSERT n t t'.(* V:        INSERTION 
**********************************
**********************************


V.1   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 : nat) (t t' : nat_tree) : Prop :=
    insert_intro :
      (forall p : nat, occ t p -> occ t' p) ->
      occ t' n ->
      (forall p : nat, occ t' p -> occ t p \/ n = p) ->
      search t' -> INSERT n t t'.(* ZZZZ ! insert_rec is defined ! yep ! *)


(* the specification of an insertion algorithm *)

Definition INSERT_SPEC (n : nat) (t : nat_tree) :=
  {t' : nat_tree | INSERT n t t'}.

(* Specifications: *)
Lemma insert_nil : forall n : nat, INSERT n NIL (bin n NIL NIL).
Lemma insert_l : forall (n p : nat) (t1 t'1 t2 : nat_tree), n < p -> search (bin p t1 t2) -> INSERT n t1 t'1 -> INSERT n (bin p t1 t2) (bin p t'1 t2).
Lemma insert_r : forall (n p : nat) (t1 t2 t'2 : nat_tree), p < n -> search (bin p t1 t2) -> INSERT n t2 t'2 -> INSERT n (bin p t1 t2) (bin p t1 t'2).
Lemma insert_eq : forall (n : nat) (t1 t2 : nat_tree), search (bin n t1 t2) -> INSERT n (bin n t1 t2) (bin n t1 t2).
Lemma insert : forall (n : nat) (t : nat_tree), search t -> INSERT_SPEC n t.