(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
Global Set Asymmetric Patterns.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Standard Proposition Elimination Names.
Require Extraction.
Require Export ZArith_base.
Inductive Z_btree : Set :=
| Z_leaf : Z_btree
| Z_bnode : Z -> Z_btree -> Z_btree -> Z_btree.
Inductive Binp : Z_btree -> Prop :=
Binp_intro : forall (n : Z) (t1 t2 : Z_btree), Binp (Z_bnode n t1 t2).
Hint Resolve Binp_intro: searchtrees.
Inductive occ (n : Z) : Z_btree -> Prop :=
| occ_root : forall t1 t2 : Z_btree, occ n (Z_bnode n t1 t2)
| occ_l :
forall (p : Z) (t1 t2 : Z_btree), occ n t1 -> occ n (Z_bnode p t1 t2)
| occ_r :
forall (p : Z) (t1 t2 : Z_btree), occ n t2 -> occ n (Z_bnode p t1 t2).
Hint Resolve occ_root occ_l occ_r: searchtrees.
Derive Inversion_clear OCC_INV with
(forall (z z' : Z) (t1 t2 : Z_btree), occ z' (Z_bnode z t1 t2)).
Hint Resolve occ_inv: searchtrees.
Hint Resolve not_occ_Leaf: searchtrees.
Definition naive_sch : forall (n : Z) (t : Z_btree), {occ n t} + {~ occ n t}.
simple induction t.
right; auto with searchtrees.
intros z t0 H0 t1 H1.
case (Z.eq_dec n z).
simple induction 1; left; auto with searchtrees.
case H0; case H1; intros; auto with searchtrees.
right; intro H; elim (occ_inv H); auto with searchtrees.
tauto.
Defined.
Extraction naive_sch.
(* let rec naive_sch n = function Z_leaf -> right | Z_bnode (z1, z0, z) -> (match Z_eq_dec n z1 with left -> left | right -> (match naive_sch n z0 with left -> left | right -> naive_sch n z)) *)
Inductive min (z : Z) (t : Z_btree) : Prop :=
min_intro : (forall z' : Z, occ z' t -> (z < z')%Z) -> min z t.
Hint Resolve min_intro: searchtrees.
(* p is greater than every member of t *)
Inductive maj (z : Z) (t : Z_btree) : Prop :=
maj_intro : (forall z' : Z, occ z' t -> (z' < z)%Z) -> maj z t.
Hint Resolve maj_intro: searchtrees.
Inductive search : Z_btree -> Prop :=
| leaf_search : search Z_leaf
| bnode_search :
forall (z : Z) (t1 t2 : Z_btree),
search t1 ->
search t2 -> maj z t1 -> min z t2 -> search (Z_bnode z t1 t2).
Hint Resolve leaf_search bnode_search: searchtrees.
Hint Resolve min_leaf: searchtrees.
Hint Resolve maj_leaf: searchtrees.

Lemma maj_not_occ : forall (z : Z) (t : Z_btree), maj z t -> ~ occ z t.