diff options
author | letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2008-03-15 23:43:05 +0000 |
---|---|---|
committer | letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2008-03-15 23:43:05 +0000 |
commit | 189770d9cf98db9ba08da66707002c52f092d73f (patch) | |
tree | 45e49e7e80b44e60a27e698b962e826be33196e2 /theories/FSets/FSetAVL.v | |
parent | ab8c213b7a4873265e325d0f8da0744bf31d96be (diff) |
Reorganisation of FSetAVL (consequences of remarks by B. Gregoire)
* FSetAVL is greatly lightened : modulo a minor change in bal, formal
proofs of avl invariant is not needed for building a functor
implementing FSetInterface.S (even if this invariant is still true)
* Non-structural functions (union, subset, compare, equal) are
transformed into efficient structural versions
* Both proofs of avl preservation and non-structural functions are
moved to a new file FSetFullAVL, that can be ignored by the average
user.
Same for FMapAVL (still work in progress...)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@10679 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'theories/FSets/FSetAVL.v')
-rw-r--r-- | theories/FSets/FSetAVL.v | 1840 |
1 files changed, 603 insertions, 1237 deletions
diff --git a/theories/FSets/FSetAVL.v b/theories/FSets/FSetAVL.v index 83dc3f1c4..5973b21ec 100644 --- a/theories/FSets/FSetAVL.v +++ b/theories/FSets/FSetAVL.v @@ -1,4 +1,3 @@ - (***********************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *) @@ -14,8 +13,29 @@ (* $Id$ *) +(** * FSetAVL *) + (** This module implements sets using AVL trees. - It follows the implementation from Ocaml's standard library. *) + It follows the implementation from Ocaml's standard library, + + All operations given here expect and produce well-balanced trees + (in the ocaml sense: heigths of subtrees shouldn't differ by more + than 2), and hence has low complexities (e.g. add is logarithmic + in the size of the set). But proving these balancing preservations + is in fact not necessary for ensuring correct operational behavior + and hence fulfilling the FSet interface. As a consequence, + balancing results are not part of this file anymore, they can + now be found in [FSetFullAVL]. + + Four operations ([union], [subset], [compare] and [equal]) have + been slightly adapted in order to have only structural recursive + calls. The precise ocaml versions of these operations have also + been formalized (thanks to Function+measure), see [ocaml_union], + [ocaml_subset], [ocaml_compare] and [ocaml_equal] in + [FSetFullAVL]. The structural variants compute faster in Coq, + whereas the other variants produce nicer and/or (slightly) faster + code after extraction. +*) Require Import Recdef FSetInterface FSetList ZArith Int. @@ -23,8 +43,7 @@ Set Implicit Arguments. Unset Strict Implicit. Module Raw (Import I:Int)(X:OrderedType). -Module Import II:=MoreInt(I). -Open Scope Int_scope. +Open Local Scope Int_scope. Module MX := OrderedTypeFacts X. Definition elt := X.t. @@ -87,35 +106,11 @@ Inductive bst : tree -> Prop := | BSNode : forall x l r h, bst l -> bst r -> lt_tree x l -> gt_tree x r -> bst (Node l x r h). -(** * AVL trees *) - -(** [avl s] : [s] is a properly balanced AVL tree, - i.e. for any node the heights of the two children - differ by at most 2 *) - -Inductive avl : tree -> Prop := - | RBLeaf : avl Leaf - | RBNode : forall x l r h, avl l -> avl r -> - -(2) <= height l - height r <= 2 -> - h = max (height l) (height r) + 1 -> - avl (Node l x r h). - - - (** * Automation and dedicated tactics *) -Hint Constructors In bst avl. +Hint Constructors In bst. Hint Unfold lt_tree gt_tree. -(** A tactic for cleaning hypothesis after use of functional induction. *) - -Ltac clearf := - match goal with - | H : (@Logic.eq (Compare _ _ _ _) _ _) |- _ => clear H; clearf - | H : (@Logic.eq (sumbool _ _) _ _) |- _ => clear H; clearf - | _ => idtac - end. - (** A tactic to repeat [inversion_clear] on all hyps of the form [(f (Node _ _ _ _))] *) @@ -128,14 +123,6 @@ Ltac inv f := | _ => idtac end. -(** Same, but with a backup of the original hypothesis. *) - -Ltac safe_inv f := match goal with - | H:f (Node _ _ _ _) |- _ => - generalize H; inversion_clear H; safe_inv f - | _ => intros - end. - Ltac intuition_in := repeat progress (intuition; inv In). (** Helper tactic concerning order of elements. *) @@ -146,39 +133,8 @@ Ltac order := match goal with | _ => MX.order end. -(** Tactics about [avl] *) - -Lemma height_non_negative : forall s : tree, avl s -> height s >= 0. -Proof. - induction s; simpl; intros; auto with zarith. - inv avl; intuition; omega_max. -Qed. -Implicit Arguments height_non_negative. - -(** When [H:avl r], typing [avl_nn H] or [avl_nn r] adds [height r>=0] *) -Ltac avl_nn_hyp H := - let nz := fresh "nz" in assert (nz := height_non_negative H). - -Ltac avl_nn h := - let t := type of h in - match type of t with - | Prop => avl_nn_hyp h - | _ => match goal with H : avl h |- _ => avl_nn_hyp H end - end. - -(* Repeat the previous tactic. - Drawback: need to clear the [avl _] hyps ... Thank you Ltac *) - -Ltac avl_nns := - match goal with - | H:avl _ |- _ => avl_nn_hyp H; clear H; avl_nns - | _ => idtac - end. - - - -(** * Basic results about [In], [lt_tree], [gt_tree], [avl], [height] *) +(** * Basic results about [In], [lt_tree], [gt_tree], [height] *) (** [In] is compatible with [X.eq] *) @@ -189,6 +145,13 @@ Proof. Qed. Hint Immediate In_1. +Lemma In_node_iff : + forall l x r h y, + In y (Node l x r h) <-> In y l \/ X.eq y x \/ In y r. +Proof. + intuition_in. +Qed. + (** Results about [lt_tree] and [gt_tree] *) Lemma lt_leaf : forall x : elt, lt_tree x Leaf. @@ -243,26 +206,6 @@ Qed. Hint Resolve lt_tree_not_in lt_tree_trans gt_tree_not_in gt_tree_trans. -(** Results about [avl] *) - -Lemma avl_node : - forall x l r, avl l -> avl r -> - -(2) <= height l - height r <= 2 -> - avl (Node l x r (max (height l) (height r) + 1)). -Proof. - intros; auto. -Qed. -Hint Resolve avl_node. - -(** Results about [height] *) - -Lemma height_0 : forall s, avl s -> height s = 0 -> s = Leaf. -Proof. - destruct 1; intuition; simpl in *. - avl_nns; simpl in *; elimtype False; omega_max. -Qed. - - (** * Some shortcuts. *) @@ -273,35 +216,21 @@ Definition For_all (P : elt -> Prop) s := forall x, In x s -> P x. Definition Exists (P : elt -> Prop) s := exists x, In x s /\ P x. - -(** trick for emulating [assert false] in Coq. *) - -Definition assert_false := Leaf. -Lemma assert_false_cardinal : cardinal assert_false = 0%nat. -Proof. simpl; auto. Qed. -Opaque assert_false. - - - (** * Empty set *) Definition empty := Leaf. -Lemma empty_bst : bst empty. +Lemma empty_1 : Empty empty. Proof. - auto. + intro; intro. + inversion H. Qed. -Lemma empty_avl : avl empty. -Proof. +Lemma empty_bst : bst empty. +Proof. auto. Qed. -Lemma empty_1 : Empty empty. -Proof. - intro; intro. - inversion H. -Qed. (** * Emptyness test *) @@ -337,7 +266,7 @@ Function mem (x:elt)(s:t) { struct s } : bool := Lemma mem_1 : forall s x, bst s -> In x s -> mem x s = true. Proof. - intros s x; functional induction mem x s; auto; intros; clearf; + intros s x; functional induction mem x s; auto; intros; try clear e0; inv bst; intuition_in; order. Qed. @@ -352,17 +281,6 @@ Qed. Definition singleton (x : elt) := Node Leaf x Leaf 1. -Lemma singleton_bst : forall x : elt, bst (singleton x). -Proof. - unfold singleton; auto. -Qed. - -Lemma singleton_avl : forall x : elt, avl (singleton x). -Proof. - unfold singleton; intro. - constructor; auto; try red; simpl; omega_max. -Qed. - Lemma singleton_1 : forall x y, In y (singleton x) -> X.eq x y. Proof. unfold singleton; intros; inv In; order. @@ -373,6 +291,11 @@ Proof. unfold singleton; auto. Qed. +Lemma singleton_bst : forall x : elt, bst (singleton x). +Proof. + unfold singleton; auto. +Qed. + (** * Helper functions *) @@ -383,6 +306,12 @@ Qed. Definition create l x r := Node l x r (max (height l) (height r) + 1). +Lemma create_in : + forall l x r y, In y (create l x r) <-> X.eq y x \/ In y l \/ In y r. +Proof. + unfold create; split; [ inversion_clear 1 | ]; intuition. +Qed. + Lemma create_bst : forall l x r, bst l -> bst r -> lt_tree x l -> gt_tree x r -> bst (create l x r). @@ -391,42 +320,24 @@ Proof. Qed. Hint Resolve create_bst. -Lemma create_avl : - forall l x r, avl l -> avl r -> -(2) <= height l - height r <= 2 -> - avl (create l x r). -Proof. - unfold create; auto. -Qed. - -Lemma create_height : - forall l x r, avl l -> avl r -> -(2) <= height l - height r <= 2 -> - height (create l x r) = max (height l) (height r) + 1. -Proof. - unfold create; intros; auto. -Qed. - -Lemma create_in : - forall l x r y, In y (create l x r) <-> X.eq y x \/ In y l \/ In y r. -Proof. - unfold create; split; [ inversion_clear 1 | ]; intuition. -Qed. - (** [bal l x r] acts as [create], but performs one step of rebalancing if necessary, i.e. assumes [|height l - height r| <= 3]. *) +Definition assert_false := create. + Function bal (l:t)(x:elt)(r:t) : t := let hl := height l in let hr := height r in if gt_le_dec hl (hr+2) then match l with - | Leaf => assert_false + | Leaf => assert_false l x r | Node ll lx lr _ => if ge_lt_dec (height ll) (height lr) then create ll lx (create lr x r) else match lr with - | Leaf => assert_false + | Leaf => assert_false l x r | Node lrl lrx lrr _ => create (create ll lx lrl) lrx (create lrr x r) end @@ -434,13 +345,13 @@ Function bal (l:t)(x:elt)(r:t) : t := else if gt_le_dec hr (hl+2) then match r with - | Leaf => assert_false + | Leaf => assert_false l x r | Node rl rx rr _ => if ge_lt_dec (height rr) (height rl) then create (create l x rl) rx rr else match rl with - | Leaf => assert_false + | Leaf => assert_false l x r | Node rll rlx rlr _ => create (create l x rll) rlx (create rlr rx rr) end @@ -448,6 +359,13 @@ Function bal (l:t)(x:elt)(r:t) : t := else create l x r. +Lemma bal_in : forall l x r y, + In y (bal l x r) <-> X.eq y x \/ In y l \/ In y r. +Proof. + intros l x r; functional induction bal l x r; intros; try clear e0; + rewrite !create_in; intuition_in. +Qed. + Lemma bal_bst : forall l x r, bst l -> bst r -> lt_tree x l -> gt_tree x r -> bst (bal l x r). Proof. @@ -456,51 +374,7 @@ Proof. (apply lt_tree_node || apply gt_tree_node); auto; (eapply lt_tree_trans || eapply gt_tree_trans); eauto. Qed. - -Lemma bal_avl : forall l x r, avl l -> avl r -> - -(3) <= height l - height r <= 3 -> avl (bal l x r). -Proof. - intros l x r; functional induction bal l x r; intros; clearf; - inv avl; repeat apply create_avl; simpl in *; auto; omega_max. -Qed. - -Lemma bal_height_1 : forall l x r, avl l -> avl r -> - -(3) <= height l - height r <= 3 -> - 0 <= height (bal l x r) - max (height l) (height r) <= 1. -Proof. - intros l x r; functional induction bal l x r; intros; clearf; - inv avl; avl_nns; simpl in *; omega_max. -Qed. - -Lemma bal_height_2 : - forall l x r, avl l -> avl r -> -(2) <= height l - height r <= 2 -> - height (bal l x r) == max (height l) (height r) +1. -Proof. - intros l x r; functional induction bal l x r; intros; clearf; - inv avl; simpl in *; omega_max. -Qed. - -Lemma bal_in : forall l x r y, avl l -> avl r -> - (In y (bal l x r) <-> X.eq y x \/ In y l \/ In y r). -Proof. - intros l x r; functional induction bal l x r; intros; clearf; - solve [repeat rewrite create_in; intuition_in - |inv avl; avl_nns; simpl in *; omega_max ]. -Qed. - -Lemma bal_cardinal : forall l x r, - (cardinal (bal l x r) <= S (cardinal l + cardinal r))%nat. -Proof. - intros l x r; functional induction bal l x r; intros; clearf; - simpl; auto with arith; romega with *. -Qed. - -Ltac omega_bal := match goal with - | H:avl ?l, H':avl ?r |- context [ bal ?l ?x ?r ] => - generalize (bal_height_1 x H H') (bal_height_2 x H H'); - omega_max - end. - +Hint Resolve bal_bst. (** * Insertion *) @@ -515,76 +389,33 @@ Function add (x:elt)(s:t) { struct s } : t := match s with end end. -Lemma add_avl_1 : forall s x, avl s -> - avl (add x s) /\ 0 <= height (add x s) - height s <= 1. -Proof. - intros s x; functional induction (add x s); subst;intros; inv avl; simpl in *. - intuition; try constructor; simpl; auto; try omega_max. - (* LT *) - destruct IHt; auto. - split. - apply bal_avl; auto; omega_max. - omega_bal. - (* EQ *) - intuition; omega_max. - (* GT *) - destruct IHt; auto. - split. - apply bal_avl; auto; omega_max. - omega_bal. -Qed. - -Lemma add_avl : forall s x, avl s -> avl (add x s). -Proof. - intros; destruct (@add_avl_1 s x H); auto. -Qed. -Hint Resolve add_avl. - -Lemma add_in : forall s x y, avl s -> - (In y (add x s) <-> X.eq y x \/ In y s). +Lemma add_in : forall s x y, + In y (add x s) <-> X.eq y x \/ In y s. Proof. - intros s x; functional induction (add x s); auto; intros. - intuition_in. - (* LT *) - inv avl. - rewrite bal_in; auto. - rewrite (IHt y0 H0); intuition_in. - (* EQ *) - inv avl. - intuition. + intros s x; functional induction (add x s); auto; intros; + try rewrite bal_in, IHt; intuition_in. eapply In_1; eauto. - (* GT *) - inv avl. - rewrite bal_in; auto. - rewrite (IHt y0 H1); intuition_in. Qed. -Lemma add_bst : forall s x, bst s -> avl s -> bst (add x s). +Lemma add_bst : forall s x, bst s -> bst (add x s). Proof. - intros s x; functional induction (add x s); auto; intros. - inv bst; inv avl; apply bal_bst; auto. + intros s x; functional induction (add x s); auto; intros; + inv bst; apply bal_bst; auto. (* lt_tree -> lt_tree (add ...) *) - red; red in H4. + red; red in H3. intros. - rewrite (add_in x y0 H) in H0. + rewrite add_in in H. intuition. eauto. - inv bst; inv avl; apply bal_bst; auto. + inv bst; auto using bal_bst. (* gt_tree -> gt_tree (add ...) *) - red; red in H4. + red; red in H3. intros. - rewrite (add_in x y0 H5) in H0. + rewrite add_in in H. intuition. apply MX.lt_eq with x; auto. Qed. - -Lemma add_cardinal : forall x s, - (cardinal (add x s) <= S (cardinal s))%nat. -Proof. - intros; functional induction add x s; simpl; auto with arith. - generalize (bal_cardinal (add x l) y r); romega with *. - generalize (bal_cardinal l y (add x r)); romega with *. -Qed. +Hint Resolve add_bst. @@ -607,7 +438,7 @@ Fixpoint join (l:t) : elt -> t -> t := end end. -(* XXX: Comment utiliser Function pour definit join et eviter join_tac ? *) +(* Function can't deal with internal fix. Let's do its job by hand: *) Ltac join_tac := intro l; induction l as [| ll _ lx lr Hlr lh]; @@ -624,128 +455,33 @@ Ltac join_tac := end | ] ] ] ]; intros. -Lemma join_avl_1 : forall l x r, avl l -> avl r -> avl (join l x r) /\ - 0<= height (join l x r) - max (height l) (height r) <= 1. -Proof. - join_tac. - - split; simpl; auto. - destruct (add_avl_1 x H0). - avl_nns; omega_max. - split; auto. - set (l:=Node ll lx lr lh) in *. - destruct (add_avl_1 x H). - simpl (height Leaf). - avl_nns; omega_max. - - inversion_clear H. - assert (height (Node rl rx rr rh) = rh); auto. - set (r := Node rl rx rr rh) in *; clearbody r. - destruct (Hlr x r H2 H0); clear Hrl Hlr. - set (j := join lr x r) in *; clearbody j. - simpl. - assert (-(3) <= height ll - height j <= 3) by omega_max. - split. - apply bal_avl; auto. - omega_bal. - - inversion_clear H0. - assert (height (Node ll lx lr lh) = lh); auto. - set (l := Node ll lx lr lh) in *; clearbody l. - destruct (Hrl H H1); clear Hrl Hlr. - set (j := join l x rl) in *; clearbody j. - simpl. - assert (-(3) <= height j - height rr <= 3) by omega_max. - split. - apply bal_avl; auto. - omega_bal. - - clear Hrl Hlr. - assert (height (Node ll lx lr lh) = lh); auto. - assert (height (Node rl rx rr rh) = rh); auto. - set (l := Node ll lx lr lh) in *; clearbody l. - set (r := Node rl rx rr rh) in *; clearbody r. - assert (-(2) <= height l - height r <= 2) by omega_max. - split. - apply create_avl; auto. - rewrite create_height; auto; omega_max. -Qed. - -Lemma join_avl : forall l x r, avl l -> avl r -> avl (join l x r). -Proof. - intros; destruct (@join_avl_1 l x r H H0); auto. -Qed. -Hint Resolve join_avl. - -Lemma join_in : forall l x r y, avl l -> avl r -> - (In y (join l x r) <-> X.eq y x \/ In y l \/ In y r). +Lemma join_in : forall l x r y, + In y (join l x r) <-> X.eq y x \/ In y l \/ In y r. Proof. join_tac. simpl. rewrite add_in; intuition_in. - rewrite add_in; intuition_in. - - inv avl. - rewrite bal_in; auto. - rewrite Hlr; clear Hlr Hrl; intuition_in. - - inv avl. - rewrite bal_in; auto. - rewrite Hrl; clear Hlr Hrl; intuition_in. - + rewrite bal_in, Hlr; clear Hlr Hrl; intuition_in. + rewrite bal_in, Hrl; clear Hlr Hrl; intuition_in. apply create_in. Qed. -Lemma join_bst : forall l x r, bst l -> avl l -> bst r -> avl r -> +Lemma join_bst : forall l x r, bst l -> bst r -> lt_tree x l -> gt_tree x r -> bst (join l x r). Proof. - join_tac. - apply add_bst; auto. - apply add_bst; auto. - - inv bst; safe_inv avl. - apply bal_bst; auto. - clear Hrl Hlr H13 H14 H16 H17 z; intro; intros. - set (r:=Node rl rx rr rh) in *; clearbody r. - rewrite (@join_in lr x r y) in H13; auto. - intuition. - apply MX.lt_eq with x; eauto. - eauto. - - inv bst; safe_inv avl. - apply bal_bst; auto. - clear Hrl Hlr H13 H14 H16 H17 z; intro; intros. - set (l:=Node ll lx lr lh) in *; clearbody l. - rewrite (@join_in l x rl y) in H13; auto. - intuition. - apply MX.eq_lt with x; eauto. - eauto. - - apply create_bst; auto. -Qed. - -Lemma join_cardinal : forall l x r, - (cardinal (join l x r) <= S (cardinal l + cardinal r))%nat. -Proof. - join_tac; simpl; auto with arith. - apply add_cardinal. - destruct X.compare; simpl; auto with arith. - generalize (bal_cardinal (add x ll) lx lr) (add_cardinal x ll); - romega with *. - generalize (bal_cardinal ll lx (add x lr)) (add_cardinal x lr); - romega with *. - generalize (bal_cardinal ll lx (join lr x (Node rl rx rr rh))) - (Hlr x (Node rl rx rr rh)); simpl; romega with *. - generalize (bal_cardinal (join (Node ll lx lr lh) x rl) rx rr). - simpl in *; romega with *. + join_tac; auto; inv bst; apply bal_bst; auto; + clear Hrl Hlr z; intro; intros; rewrite join_in in *. + intuition; [ apply MX.lt_eq with x | ]; eauto. + intuition; [ apply MX.eq_lt with x | ]; eauto. Qed. +Hint Resolve join_bst. (** * Extraction of minimum element - morally, [remove_min] is to be applied to a non-empty tree + Morally, [remove_min] is to be applied to a non-empty tree [t = Node l x r h]. Since we can't deal here with [assert false] for [t=Leaf], we pre-unpack [t] (and forget about [h]). *) @@ -757,75 +493,40 @@ Function remove_min (l:t)(x:elt)(r:t) { struct l } : t*elt := let (l',m) := remove_min ll lx lr in (bal l' x r, m) end. -Lemma remove_min_avl_1 : forall l x r h, avl (Node l x r h) -> - avl (remove_min l x r)#1 /\ - 0 <= height (Node l x r h) - height (remove_min l x r)#1 <= 1. -Proof. - intros l x r; functional induction (remove_min l x r); subst;simpl in *; intros. - inv avl; simpl in *; split; auto. - avl_nns; omega_max. - (* l = Node *) - inversion_clear H. - rewrite e0 in IHp;simpl in IHp;destruct (IHp lh); auto. - split; simpl in *. - apply bal_avl; auto; omega_max. - omega_bal. -Qed. - -Lemma remove_min_avl : forall l x r h, avl (Node l x r h) -> - avl (remove_min l x r)#1. -Proof. - intros; destruct (@remove_min_avl_1 l x r h H); auto. -Qed. - -Lemma remove_min_in : forall l x r h y, avl (Node l x r h) -> - (In y (Node l x r h) <-> - X.eq y (remove_min l x r)#2 \/ In y (remove_min l x r)#1). +Lemma remove_min_in : forall l x r h y, + In y (Node l x r h) <-> + X.eq y (remove_min l x r)#2 \/ In y (remove_min l x r)#1. Proof. intros l x r; functional induction (remove_min l x r); simpl in *; intros. intuition_in. - (* l = Node *) - inversion_clear H. - generalize (remove_min_avl H0). - rewrite e0; simpl; intros. - rewrite bal_in; auto. - rewrite e0 in IHp;generalize (IHp lh y H0). - intuition. - inversion_clear H7; intuition. + rewrite bal_in, In_node_iff, IHp, e0; simpl; intuition. Qed. Lemma remove_min_bst : forall l x r h, - bst (Node l x r h) -> avl (Node l x r h) -> bst (remove_min l x r)#1. + bst (Node l x r h) -> bst (remove_min l x r)#1. Proof. intros l x r; functional induction (remove_min l x r); subst;simpl in *; intros. inv bst; auto. - inversion_clear H; inversion_clear H0. - rewrite_all e0;simpl in *. + inversion_clear H. + specialize IHp with (1:=H0); rewrite e0 in IHp; auto. apply bal_bst; auto. - apply (IHp lh); auto. - intro; intros. - generalize (remove_min_in y H). - rewrite e0; simpl. - destruct 1. - apply H3; intuition. + intro y; specialize (H2 y). + rewrite remove_min_in, e0 in H2; simpl in H2; intuition. Qed. Lemma remove_min_gt_tree : forall l x r h, - bst (Node l x r h) -> avl (Node l x r h) -> + bst (Node l x r h) -> gt_tree (remove_min l x r)#2 (remove_min l x r)#1. Proof. intros l x r; functional induction (remove_min l x r); subst;simpl in *; intros. inv bst; auto. - inversion_clear H; inversion_clear H0. - intro; intro. - generalize (IHp lh H1 H); clear H6 H7 IHp. - generalize (remove_min_in m H)(remove_min_avl H). - rewrite e0; simpl; intros. - rewrite (bal_in x y H7 H5) in H0. - assert (In m (Node ll lx lr lh)) by (rewrite H6; auto); clear H6. - assert (X.lt m x) by order. - decompose [or] H0; order. + inversion_clear H. + specialize IHp with (1:=H0); rewrite e0 in IHp; simpl in IHp. + intro y; rewrite bal_in; intuition; + specialize (H2 m); rewrite remove_min_in, e0 in H2; simpl in H2; + [ apply MX.lt_eq with x | ]; eauto. Qed. +Hint Resolve remove_min_bst remove_min_gt_tree. @@ -843,56 +544,28 @@ Function merge (s1 s2 :t) : t:= match s1,s2 with let (s2',m) := remove_min l2 x2 r2 in bal s1 m s2' end. -Lemma merge_avl_1 : forall s1 s2, avl s1 -> avl s2 -> - -(2) <= height s1 - height s2 <= 2 -> - avl (merge s1 s2) /\ - 0<= height (merge s1 s2) - max (height s1) (height s2) <=1. +Lemma merge_in : forall s1 s2 y, + In y (merge s1 s2) <-> In y s1 \/ In y s2. Proof. - intros s1 s2; functional induction (merge s1 s2); subst;simpl in *; intros. - split; auto; avl_nns; omega_max. - split; auto; avl_nns; simpl in *; omega_max. - destruct s1;try contradiction;clear y. - generalize (remove_min_avl_1 H0). - rewrite e1; simpl; destruct 1. - split. - apply bal_avl; auto. - simpl; omega_max. - omega_bal. -Qed. - -Lemma merge_avl : forall s1 s2, avl s1 -> avl s2 -> - -(2) <= height s1 - height s2 <= 2 -> avl (merge s1 s2). -Proof. - intros; destruct (@merge_avl_1 s1 s2 H H0 H1); auto. -Qed. - -Lemma merge_in : forall s1 s2 y, bst s1 -> avl s1 -> bst s2 -> avl s2 -> - (In y (merge s1 s2) <-> In y s1 \/ In y s2). -Proof. intros s1 s2; functional induction (merge s1 s2); subst; simpl in *; intros. intuition_in. intuition_in. - destruct s1;try contradiction;clear y. - replace s2' with ((remove_min l2 x2 r2)#1); [|rewrite e1; auto]. - rewrite bal_in; auto. - generalize (remove_min_in y0 H2); rewrite e1; simpl; intro. - rewrite H3 ; intuition. - generalize (remove_min_avl H2); rewrite e1; simpl; auto. + rewrite bal_in, remove_min_in, e1; simpl; intuition. Qed. -Lemma merge_bst : forall s1 s2, bst s1 -> avl s1 -> bst s2 -> avl s2 -> +Lemma merge_bst : forall s1 s2, bst s1 -> bst s2 -> (forall y1 y2 : elt, In y1 s1 -> In y2 s2 -> X.lt y1 y2) -> - bst (merge s1 s2). + bst (merge s1 s2). Proof. - intros s1 s2; functional induction (merge s1 s2); subst;simpl in *; intros; auto. - destruct s1;try contradiction;clear y. + intros s1 s2; functional induction (merge s1 s2); subst; simpl in *; intros; auto; clear y. apply bal_bst; auto. - generalize (remove_min_bst H1 H2); rewrite e1; simpl in *; auto. - intro; intro. - apply H3; auto. - generalize (remove_min_in m H2); rewrite e1; simpl; intuition. - generalize (remove_min_gt_tree H1 H2); rewrite e1; simpl; auto. -Qed. + change s2' with ((s2',m)#1); rewrite <-e1; eauto. + intros y Hy. + apply H1; auto. + rewrite remove_min_in, e1; simpl; auto. + change (gt_tree (s2',m)#2 (s2',m)#1); rewrite <-e1; eauto. +Qed. +Hint Resolve merge_bst. @@ -908,76 +581,33 @@ Function remove (x:elt)(s:t) { struct s } : t := match s with end end. -Lemma remove_avl_1 : forall s x, avl s -> - avl (remove x s) /\ 0 <= height s - height (remove x s) <= 1. -Proof. - intros s x; functional induction (remove x s); subst;simpl; intros. - intuition; omega_max. - (* LT *) - inv avl. - destruct (IHt H0). - split. - apply bal_avl; auto. - omega_max. - omega_bal. - (* EQ *) - inv avl. - generalize (merge_avl_1 H0 H1 H2). - intuition omega_max. - (* GT *) - inv avl. - destruct (IHt H1). - split. - apply bal_avl; auto. - omega_max. - omega_bal. -Qed. - -Lemma remove_avl : forall s x, avl s -> avl (remove x s). -Proof. - intros; destruct (@remove_avl_1 s x H); auto. -Qed. -Hint Resolve remove_avl. - -Lemma remove_in : forall s x y, bst s -> avl s -> +Lemma remove_in : forall s x y, bst s -> (In y (remove x s) <-> ~ X.eq y x /\ In y s). Proof. - intros s x; functional induction (remove x s); subst;simpl; intros. + intros s x; functional induction (remove x s); subst; simpl; + intros; inv bst. intuition_in. - (* LT *) - inv avl; inv bst; clear e0. - rewrite bal_in; auto. - generalize (IHt y0 H0); intuition; [ order | order | intuition_in ]. - (* EQ *) - inv avl; inv bst; clear e0. - rewrite merge_in; intuition; [ order | order | intuition_in ]. - elim H9; eauto. - (* GT *) - inv avl; inv bst; clear e0. - rewrite bal_in; auto. - generalize (IHt y0 H5); intuition; [ order | order | intuition_in ]. + rewrite bal_in, IHt; clear e0 IHt; intuition; [order|order|intuition_in]. + rewrite merge_in; clear e0; intuition; [order|order|intuition_in]. + elim H4; eauto. + rewrite bal_in, IHt; clear e0 IHt; intuition; [order|order|intuition_in]. Qed. -Lemma remove_bst : forall s x, bst s -> avl s -> bst (remove x s). +Lemma remove_bst : forall s x, bst s -> bst (remove x s). Proof. - intros s x; functional induction (remove x s); simpl; intros. + intros s x; functional induction (remove x s); simpl; + intros; inv bst. auto. (* LT *) - inv avl; inv bst. apply bal_bst; auto. - intro; intro. - rewrite (remove_in x y0 H0) in H; auto. - destruct H; eauto. + intro z; rewrite remove_in; auto; destruct 1; eauto. (* EQ *) - inv avl; inv bst. - apply merge_bst; eauto. + eauto. (* GT *) - inv avl; inv bst. apply bal_bst; auto. - intro; intro. - rewrite (remove_in x y0 H5) in H; auto. - destruct H; eauto. + intro z; rewrite remove_in; auto; destruct 1; eauto. Qed. +Hint Resolve remove_bst. @@ -998,7 +628,7 @@ Proof. destruct l; auto. Qed. -Lemma min_elt_2 : forall s x y, bst s -> +Lemma min_elt_2 : forall s x y, bst s -> min_elt s = Some x -> In y s -> ~ X.lt y x. Proof. intro s; functional induction (min_elt s); subst;simpl. @@ -1088,11 +718,11 @@ Proof. exact min_elt_3. Qed. -Lemma choose_3 : forall s s', bst s -> avl s -> bst s' -> avl s' -> +Lemma choose_3 : forall s s', bst s -> bst s' -> forall x x', choose s = Some x -> choose s' = Some x' -> Equal s s' -> X.eq x x'. Proof. - unfold choose, Equal; intros s s' Hb Ha Hb' Ha' x x' Hx Hx' H. + unfold choose, Equal; intros s s' Hb Hb' x x' Hx Hx' H. assert (~X.lt x x'). apply min_elt_2 with s'; auto. rewrite <-H; auto using min_elt_1. @@ -1118,45 +748,28 @@ Function concat (s1 s2 : t) : t := join s1 m s2' end. -Lemma concat_avl : forall s1 s2, avl s1 -> avl s2 -> avl (concat s1 s2). +Lemma concat_in : forall s1 s2 y, + In y (concat s1 s2) <-> In y s1 \/ In y s2. Proof. - intros s1 s2; functional induction (concat s1 s2); subst;auto. - destruct s1;try contradiction;clear y. - intros; apply join_avl; auto. - generalize (remove_min_avl H0); rewrite e1; simpl; auto. + intros s1 s2; functional induction (concat s1 s2);subst;simpl;intros. + intuition_in. + intuition_in. + rewrite join_in, remove_min_in, e1; simpl; intuition. Qed. -Lemma concat_bst : forall s1 s2, bst s1 -> avl s1 -> bst s2 -> avl s2 -> +Lemma concat_bst : forall s1 s2, bst s1 -> bst s2 -> (forall y1 y2 : elt, In y1 s1 -> In y2 s2 -> X.lt y1 y2) -> bst (concat s1 s2). Proof. - intros s1 s2; functional induction (concat s1 s2); subst ;auto. - destruct s1;try contradiction;clear y. - intros; apply join_bst; auto. - generalize (remove_min_bst H1 H2); rewrite e1; simpl; auto. - generalize (remove_min_avl H2); rewrite e1; simpl; auto. - generalize (remove_min_in m H2); rewrite e1; simpl; auto. - destruct 1; intuition. - generalize (remove_min_gt_tree H1 H2); rewrite e1; simpl; auto. + intros s1 s2; functional induction (concat s1 s2); subst; auto; clear y. + intros; apply join_bst; auto. + change (bst (s2',m)#1); rewrite <-e1; eauto. + intros y Hy. + apply H1; auto. + rewrite remove_min_in, e1; simpl; auto. + change (gt_tree (s2',m)#2 (s2',m)#1); rewrite <-e1; eauto. Qed. - -Lemma concat_in : forall s1 s2 y, bst s1 -> avl s1 -> bst s2 -> avl s2 -> - (forall y1 y2 : elt, In y1 s1 -> In y2 s2 -> X.lt y1 y2) -> - (In y (concat s1 s2) <-> In y s1 \/ In y s2). -Proof. - intros s1 s2; functional induction (concat s1 s2);subst;simpl. - intuition. - inversion_clear H5. - destruct s1;try contradiction;clear y;intuition. - inversion_clear H5. - destruct s1;try contradiction;clear y; intros. - rewrite (@join_in _ m s2' y H0). - generalize (remove_min_in y H2); rewrite e1; simpl. - intro EQ; rewrite EQ; intuition. - generalize (remove_min_avl H2); rewrite e1; simpl; auto. -Qed. - -Hint Resolve concat_avl concat_bst. +Hint Resolve concat_bst. @@ -1182,118 +795,51 @@ Function split (x:elt)(s:t) { struct s } : t * (bool * t) := match s with end end. -Lemma split_avl : forall s x, avl s -> - avl (split x s)#1 /\ avl (split x s)#2#2. -Proof. - intros s x; functional induction (split x s);subst;simpl in *. - auto. - rewrite e1 in IHp;simpl in IHp;inversion_clear 1; intuition. - simpl; inversion_clear 1; auto. - rewrite e1 in IHp;simpl in IHp;inversion_clear 1; intuition. -Qed. - -Lemma split_in_1 : forall s x y, bst s -> avl s -> +Lemma split_in_1 : forall s x y, bst s -> (In y (split x s)#1 <-> In y s /\ X.lt y x). -Proof. - intros s x; functional induction (split x s);subst;simpl in *. - intuition; try inversion_clear H1. - (* LT *) - rewrite e1 in IHp;simpl in *; inversion_clear 1; inversion_clear 1; clear H7 H6. - rewrite (IHp y0 H0 H4); clear IHp e0. - intuition. - inversion_clear H6; auto; order. - (* EQ *) - simpl in *; inversion_clear 1; inversion_clear 1; clear H6 H5 e0. - intuition. - order. +Proof. + intros s x; functional induction (split x s); subst; simpl; intros; + inv bst; try clear e0. + intuition_in. + rewrite e1 in IHp; simpl in IHp; rewrite IHp; intuition_in; order. intuition_in; order. - (* GT *) - rewrite e1 in IHp;simpl in *; inversion_clear 1; inversion_clear 1; clear H7 H6. - rewrite join_in; auto. - rewrite (IHp y0 H1 H5); clear e1. - intuition; [ eauto | eauto | intuition_in ]. - generalize (split_avl x H5); rewrite e1; simpl; intuition. + rewrite join_in. + rewrite e1 in IHp; simpl in IHp; rewrite IHp; intuition_in; order. Qed. -Lemma split_in_2 : forall s x y, bst s -> avl s -> +Lemma split_in_2 : forall s x y, bst s -> (In y (split x s)#2#2 <-> In y s /\ X.lt x y). Proof. - intros s x; functional induction (split x s);subst;simpl in *. - intuition; try inversion_clear H1. - (* LT *) - rewrite e1 in IHp; simpl in *; inversion_clear 1; inversion_clear 1; clear H7 H6. - rewrite join_in; auto. - rewrite (IHp y0 H0 H4); clear IHp e0. - intuition; [ order | order | intuition_in ]. - generalize (split_avl x H4); rewrite e1; simpl; intuition. - (* EQ *) - simpl in *; inversion_clear 1; inversion_clear 1; clear H6 H5 e0. - intuition; [ order | intuition_in; order ]. - (* GT *) - rewrite e1 in IHp; simpl in *; inversion_clear 1; inversion_clear 1; clear H7 H6. - rewrite (IHp y0 H1 H5); clear IHp e0. - intuition; intuition_in; order. + intros s x; functional induction (split x s); subst; simpl; intros; + inv bst; try clear e0. + intuition_in. + rewrite join_in. + rewrite e1 in IHp; simpl in IHp; rewrite IHp; intuition_in; order. + intuition_in; order. + rewrite e1 in IHp; simpl in IHp; rewrite IHp; intuition_in; order. Qed. -Lemma split_in_3 : forall s x, bst s -> avl s -> +Lemma split_in_3 : forall s x, bst s -> ((split x s)#2#1 = true <-> In x s). Proof. - intros s x; functional induction (split x s);subst;simpl in *. - intuition; try inversion_clear H1. - (* LT *) - rewrite e1 in IHp; simpl in *; inversion_clear 1; inversion_clear 1; clear H7 H6. - rewrite IHp; auto. - intuition_in; absurd (X.lt x y); eauto. - (* EQ *) - simpl in *; inversion_clear 1; inversion_clear 1; intuition. - (* GT *) - rewrite e1 in IHp; simpl in *; inversion_clear 1; inversion_clear 1; clear H7 H6. - rewrite IHp; auto. - intuition_in; absurd (X.lt y x); eauto. + intros s x; functional induction (split x s); subst; simpl; intros; + inv bst; try clear e0. + intuition_in; try discriminate. + rewrite e1 in IHp; simpl in IHp; rewrite IHp; intuition_in; order. + intuition. + rewrite e1 in IHp; simpl in IHp; rewrite IHp; intuition_in; order. Qed. -Lemma split_bst : forall s x, bst s -> avl s -> +Lemma split_bst : forall s x, bst s -> bst (split x s)#1 /\ bst (split x s)#2#2. Proof. - intros s x; functional induction (split x s);subst;simpl in *. - intuition. - (* LT *) - rewrite e1 in IHp; simpl in *; inversion_clear 1; inversion_clear 1. - intuition. - apply join_bst; auto. - generalize (split_avl x H4); rewrite e1; simpl; intuition. - intro; intro. - generalize (split_in_2 x y0 H0 H4); rewrite e1; simpl; intuition. - (* EQ *) - simpl in *; inversion_clear 1; inversion_clear 1; intuition. - (* GT *) - rewrite e1 in IHp; simpl in *; inversion_clear 1; inversion_clear 1. - intuition. - apply join_bst; auto. - generalize (split_avl x H5); rewrite e1; simpl; intuition. - intro; intro. - generalize (split_in_1 x y0 H1 H5); rewrite e1; simpl; intuition. -Qed. - -Lemma split_cardinal_1 : forall x s, - (cardinal (split x s)#1 <= cardinal s)%nat. -Proof. - intros x s; functional induction split x s; simpl; auto. - rewrite e1 in IHp; simpl in *. - romega with *. - romega with *. - rewrite e1 in IHp; simpl in *. - generalize (@join_cardinal l y rl); romega with *. -Qed. - -Lemma split_cardinal_2 : forall x s, - (cardinal (split x s)#2#2 <= cardinal s)%nat. -Proof. - intros x s; functional induction split x s; simpl; auto. - rewrite e1 in IHp; simpl in *. - generalize (@join_cardinal rl y r); romega with *. - romega with *. - rewrite e1 in IHp; simpl in *; romega with *. + intros s x; functional induction (split x s); subst; simpl; intros; + inv bst; try clear e0; try rewrite e1 in *; simpl in *; intuition; + apply join_bst; auto. + intros y0. + generalize (split_in_2 x y0 H0); rewrite e1; simpl; intuition. + intros y0. + generalize (split_in_1 x y0 H1); rewrite e1; simpl; intuition. Qed. @@ -1310,57 +856,45 @@ Function inter (s1 s2 : t) { struct s1 } : t := match s1, s2 with end end. -Lemma inter_avl : forall s1 s2, avl s1 -> avl s2 -> avl (inter s1 s2). -Proof. - intros s1 s2; functional induction inter s1 s2; auto; intros A1 A2; - generalize (split_avl x1 A2); rewrite e1; simpl; destruct 1; - inv avl; auto. -Qed. -Hint Resolve inter_avl. - -Lemma inter_bst_in : forall s1 s2, bst s1 -> avl s1 -> bst s2 -> avl s2 -> +Lemma inter_bst_in : forall s1 s2, bst s1 -> bst s2 -> bst (inter s1 s2) /\ (forall y, In y (inter s1 s2) <-> In y s1 /\ In y s2). Proof. - intros s1 s2; functional induction inter s1 s2; intros B1 A1 B2 A2; + intros s1 s2; functional induction inter s1 s2; intros B1 B2; [intuition_in|intuition_in | | ]; set (r:=Node l2 x2 r2 h2) in *; - generalize (split_avl x1 A2)(split_bst x1 B2 A2); - rewrite e1; simpl; destruct 1; destruct 1; - inv avl; inv bst; + generalize (split_bst x1 B2); + rewrite e1; simpl; destruct 1; inv bst; destruct IHt as (IHb1,IHi1); auto; destruct IHt0 as (IHb2,IHi2); auto; - destruct (distr_pair e1); clear e1; - destruct (distr_pair H12); clear H12; split. + destruct (distr_pair e1); clear e1; + destruct (distr_pair H6); clear H6; split. (* bst join *) apply join_bst; auto; intro y; [rewrite IHi1|rewrite IHi2]; intuition. (* In join *) - intros; rewrite join_in; auto; rewrite IHi1; rewrite IHi2. - rewrite <- H11, <- H14, split_in_1; auto; rewrite split_in_2; auto. - rewrite split_in_3 in H13; intuition_in. + intros. + rewrite join_in, IHi1, IHi2, <- H5, <- H8, split_in_1, split_in_2; auto. + rewrite split_in_3 in H7; intuition_in. apply In_1 with x1; auto. (* bst concat *) apply concat_bst; auto; intros y1 y2; rewrite IHi1, IHi2; intuition; order. (* In concat *) - intros; rewrite concat_in; auto. - rewrite IHi1; rewrite IHi2. - rewrite <- H11, <- H14, split_in_1; auto; rewrite split_in_2; auto. - assert (~In x1 r) by (rewrite <- split_in_3; auto; rewrite H13; auto). + intros. + rewrite concat_in, IHi1, IHi2, <- H5, <- H8, split_in_1, split_in_2; auto. + assert (~In x1 r) by (rewrite <- split_in_3, H7; auto). intuition_in. - elim H12. + elim H6. apply In_1 with y; auto. - intros y1 y2; rewrite IHi1, IHi2; intuition; order. Qed. -Lemma inter_bst : forall s1 s2, bst s1 -> avl s1 -> bst s2 -> avl s2 -> - bst (inter s1 s2). +Lemma inter_in : forall s1 s2 y, bst s1 -> bst s2 -> + (In y (inter s1 s2) <-> In y s1 /\ In y s2). Proof. - intros s1 s2 B1 A1 B2 A2; destruct (inter_bst_in B1 A1 B2 A2); auto. + intros s1 s2 y B1 B2; destruct (inter_bst_in B1 B2); auto. Qed. -Lemma inter_in : forall s1 s2 y, bst s1 -> avl s1 -> bst s2 -> avl s2 -> - (In y (inter s1 s2) <-> In y s1 /\ In y s2). +Lemma inter_bst : forall s1 s2, bst s1 -> bst s2 -> bst (inter s1 s2). Proof. - intros s1 s2 y B1 A1 B2 A2; destruct (inter_bst_in B1 A1 B2 A2); auto. + intros s1 s2 B1 B2; destruct (inter_bst_in B1 B2); auto. Qed. @@ -1377,173 +911,95 @@ Function diff (s1 s2 : t) { struct s1 } : t := match s1, s2 with end end. -Lemma diff_avl : forall s1 s2, avl s1 -> avl s2 -> avl (diff s1 s2). -Proof. - intros s1 s2; functional induction diff s1 s2; auto; intros A1 A2; - generalize (split_avl x1 A2); rewrite e1; simpl; destruct 1; - inv avl; auto. -Qed. -Hint Resolve diff_avl. - -Lemma diff_bst_in : forall s1 s2, bst s1 -> avl s1 -> bst s2 -> avl s2 -> +Lemma diff_bst_in : forall s1 s2, bst s1 -> bst s2 -> bst (diff s1 s2) /\ (forall y, In y (diff s1 s2) <-> In y s1 /\ ~In y s2). Proof. - intros s1 s2; functional induction diff s1 s2; intros B1 A1 B2 A2; + intros s1 s2; functional induction diff s1 s2; intros B1 B2; [intuition_in|intuition_in | | ]; set (r:=Node l2 x2 r2 h2) in *; - generalize (split_avl x1 A2)(split_bst x1 B2 A2); - rewrite e1; simpl; destruct 1; destruct 1; + generalize (split_bst x1 B2); + rewrite e1; simpl; destruct 1; inv avl; inv bst; destruct IHt as (IHb1,IHi1); auto; destruct IHt0 as (IHb2,IHi2); auto; destruct (distr_pair e1); clear e1; - destruct (distr_pair H12); clear H12; split. + destruct (distr_pair H6); clear H6; split. (* bst concat *) apply concat_bst; auto; intros y1 y2; rewrite IHi1, IHi2; intuition; order. (* In concat *) - intros; rewrite concat_in; auto. - rewrite IHi1; rewrite IHi2. - rewrite <- H11, <- H14, split_in_1; auto; rewrite split_in_2; auto. - rewrite split_in_3 in H13; intuition_in. - elim H17. + intros. + rewrite concat_in, IHi1, IHi2, <-H5, <- H8, split_in_1, split_in_2; auto. + rewrite split_in_3 in H7; intuition_in. + elim H10. apply In_1 with x1; auto. - intros y1 y2; rewrite IHi1, IHi2; intuition; order. (* bst join *) apply join_bst; auto; intro y; [rewrite IHi1|rewrite IHi2]; intuition. (* In join *) - intros; rewrite join_in; auto; rewrite IHi1; rewrite IHi2. - rewrite <- H11, <- H14, split_in_1; auto; rewrite split_in_2; auto. - assert (~In x1 r) by (rewrite <- split_in_3; auto; rewrite H13; auto). + intros. + rewrite join_in, IHi1, IHi2, <-H5, <-H8, split_in_1, split_in_2; auto. + assert (~In x1 r) by (rewrite <- split_in_3, H7; auto). intuition_in. - elim H12. + elim H6. apply In_1 with y; auto. Qed. -Lemma diff_bst : forall s1 s2, bst s1 -> avl s1 -> bst s2 -> avl s2 -> - bst (diff s1 s2). +Lemma diff_in : forall s1 s2 y, bst s1 -> bst s2 -> + (In y (diff s1 s2) <-> In y s1 /\ ~In y s2). Proof. - intros s1 s2 B1 A1 B2 A2; destruct (diff_bst_in B1 A1 B2 A2); auto. + intros s1 s2 y B1 B2; destruct (diff_bst_in B1 B2); auto. Qed. -Lemma diff_in : forall s1 s2 y, bst s1 -> avl s1 -> bst s2 -> avl s2 -> - (In y (diff s1 s2) <-> In y s1 /\ ~In y s2). +Lemma diff_bst : forall s1 s2, bst s1 -> bst s2 -> bst (diff s1 s2). Proof. - intros s1 s2 y B1 A1 B2 A2; destruct (diff_bst_in B1 A1 B2 A2); auto. + intros s1 s2 B1 B2; destruct (diff_bst_in B1 B2); auto. Qed. (** * Union *) -Definition cardinal2 (s:t*t) := (cardinal s#1 + cardinal s#2)%nat. - -Ltac union_tac := - intros; unfold cardinal2; simpl fst in *; simpl snd in *; - match goal with H: split ?x ?s = _ |- _ => - generalize (split_cardinal_1 x s) (split_cardinal_2 x s); - rewrite H; simpl; romega with * - end. +(** In ocaml, heights of [s1] and [s2] are compared each time in order + to recursively perform the split on the smaller set. + Unfortunately, this leads to a non-structural algorithm. The + following code is a simplification of the ocaml version: no + comparison of heights. It might be slightly slower, but + experimentally all the tests I've made in ocaml have shown this + potential slowdown to be non-significant. Anyway, the exact code + of ocaml has also been formalized thanks to Function+measure, see + [ocaml_union] in [FSetFullAVL]. +*) -Function union (s : t * t) { measure cardinal2 s } : t := - match s with - | (Leaf, Leaf) => s#2 - | (Leaf, Node _ _ _ _) => s#2 - | (Node _ _ _ _, Leaf) => s#1 - | (Node l1 x1 r1 h1, Node l2 x2 r2 h2) => - if ge_lt_dec h1 h2 then - if eq_dec h2 1 then add x2 s#1 else - let (l2',r2') := split x1 s#2 in - join (union (l1,l2')) x1 (union (r1,r2'#2)) - else - if eq_dec h1 1 then add x1 s#2 else - let (l1',r1') := split x2 s#1 in - join (union (l1',l2)) x2 (union (r1'#2,r2)) +Function union (s1 s2 : t) { struct s1 } : t := + match s1, s2 with + | Leaf, _ => s2 + | Node _ _ _ _, Leaf => s1 + | Node l1 x1 r1 h1, Node l2 x2 r2 h2 => + let (l2',r2') := split x1 s2 in + join (union l1 l2') x1 (union r1 r2'#2) end. -Proof. -abstract union_tac. -abstract union_tac. -abstract union_tac. -abstract union_tac. -Defined. - -Lemma union_avl : forall s, - avl s#1 -> avl s#2 -> avl (union s). -Proof. - intros s; functional induction union s; - simpl fst in *; simpl snd in *; auto. - intros A1 A2; generalize (split_avl x1 A2); rewrite e2; simpl. - inv avl; destruct 1; auto. - intros A1 A2; generalize (split_avl x2 A1); rewrite e2; simpl. - inv avl; destruct 1; auto. -Qed. -Hint Resolve union_avl. -Lemma union_in : forall s y, - bst s#1 -> avl s#1 -> bst s#2 -> avl s#2 -> - (In y (union s) <-> In y s#1 \/ In y s#2). +Lemma union_in : forall s1 s2 y, bst s1 -> bst s2 -> + (In y (union s1 s2) <-> In y s1 \/ In y s2). Proof. - intros s; functional induction union s; intros y B1 A1 B2 A2; - simpl fst in *; simpl snd in *; try clear e0 e1. + intros s1 s2; functional induction union s1 s2; intros y B1 B2. intuition_in. intuition_in. - intuition_in. - (* add x2 s#1 *) - inv avl. - rewrite (height_0 H); [ | avl_nn l2; omega_max]. - rewrite (height_0 H0); [ | avl_nn r2; omega_max]. - rewrite add_in; auto; intuition_in. - (* join (union (l1,l2')) x1 (union (r1,r2'#2)) *) - generalize - (split_avl x1 A2) (split_bst x1 B2 A2) - (split_in_1 x1 y B2 A2) (split_in_2 x1 y B2 A2). - rewrite e2; simpl. - destruct 1; destruct 1; inv avl; inv bst. - rewrite join_in; auto. - rewrite IHt; auto. - rewrite IHt0; auto. + generalize (split_bst x1 B2) (split_in_1 x1 y B2) (split_in_2 x1 y B2). + rewrite e1; simpl. + destruct 1; inv bst. + rewrite join_in, IHt, IHt0; auto. do 2 (intro Eq; rewrite Eq; clear Eq). case (X.compare y x1); intuition_in. - (* add x1 s#2 *) - inv avl. - rewrite (height_0 H3); [ | avl_nn l1; omega_max]. - rewrite (height_0 H4); [ | avl_nn r1; omega_max]. - rewrite add_in; auto; intuition_in. - (* join (union (l1',l2)) x1 (union (r1'#2,r2)) *) - generalize - (split_avl x2 A1) (split_bst x2 B1 A1) - (split_in_1 x2 y B1 A1) (split_in_2 x2 y B1 A1). - rewrite e2; simpl. - destruct 1; destruct 1; inv avl; inv bst. - rewrite join_in; auto. - rewrite IHt; auto. - rewrite IHt0; auto. - do 2 (intro Eq; rewrite Eq; clear Eq). - case (X.compare y x2); intuition_in. Qed. -Lemma union_bst : forall s, - bst s#1 -> avl s#1 -> bst s#2 -> avl s#2 -> bst (union s). +Lemma union_bst : forall s1 s2, bst s1 -> bst s2 -> + bst (union s1 s2). Proof. - intros s; functional induction union s; intros B1 A1 B2 A2; - simpl fst in *; simpl snd in *; try clear e0 e1; - try apply add_bst; auto. - (* join (union (l1,l2')) x1 (union (r1,r2'#2)) *) - generalize (split_avl x1 A2) (split_bst x1 B2 A2). - rewrite e2; simpl. - destruct 1; destruct 1. - destruct (distr_pair e2) as (L,R); clear e2. - inv bst; inv avl. - apply join_bst; auto. - intro y; rewrite union_in; auto; simpl. - rewrite <- L, split_in_1; auto; intuition_in. - intro y; rewrite union_in; auto; simpl. - rewrite <- R, split_in_2; auto; intuition_in. - (* join (union (l1',l2)) x1 (union (r1'#2,r2)) *) - generalize (split_avl x2 A1) (split_bst x2 B1 A1). - rewrite e2; simpl. - destruct 1; destruct 1. - destruct (distr_pair e2) as (L,R); clear e2. - inv bst; inv avl. + intros s1 s2; functional induction union s1 s2; intros B1 B2; auto. + generalize (split_bst x1 B2) . + inv bst. + rewrite e1; simpl; destruct 1. + destruct (distr_pair e1) as (L,R); clear e1. apply join_bst; auto. intro y; rewrite union_in; auto; simpl. rewrite <- L, split_in_1; auto; intuition_in. @@ -1644,65 +1100,43 @@ Fixpoint filter_acc (acc:t)(s:t) { struct s } : t := match s with Definition filter := filter_acc Leaf. -Lemma filter_acc_avl : forall s acc, avl s -> avl acc -> - avl (filter_acc acc s). -Proof. - induction s; simpl; auto. - intros. - inv avl. - apply IHs2; auto. - apply IHs1; auto. - destruct (f t); auto. -Qed. -Hint Resolve filter_acc_avl. - -Lemma filter_acc_bst : forall s acc, bst s -> avl s -> bst acc -> avl acc -> - bst (filter_acc acc s). -Proof. - induction s; simpl; auto. - intros. - inv avl; inv bst. - destruct (f t); auto. - apply IHs2; auto. - apply IHs1; auto. - apply add_bst; auto. -Qed. - -Lemma filter_acc_in : forall s acc, avl s -> avl acc -> +Lemma filter_acc_in : forall s acc, compat_bool X.eq f -> forall x : elt, In x (filter_acc acc s) <-> In x acc \/ In x s /\ f x = true. Proof. induction s; simpl; intros. intuition_in. - inv bst; inv avl. - rewrite IHs2 by (destruct (f t); auto). - rewrite IHs1 by (destruct (f t); auto). + rewrite IHs2, IHs1 by (destruct (f t); auto). case_eq (f t); intros. rewrite (add_in); auto. intuition_in. - rewrite (H1 _ _ H8). + rewrite (H _ _ H2). intuition. intuition_in. - rewrite (H1 _ _ H8) in H9. - rewrite H in H9; discriminate. -Qed. - -Lemma filter_avl : forall s, avl s -> avl (filter s). -Proof. - unfold filter; intros; apply filter_acc_avl; auto. + rewrite (H _ _ H2) in H3. + rewrite H0 in H3; discriminate. Qed. -Lemma filter_bst : forall s, bst s -> avl s -> bst (filter s). +Lemma filter_acc_bst : forall s acc, bst s -> bst acc -> + bst (filter_acc acc s). Proof. - unfold filter; intros; apply filter_acc_bst; auto. + induction s; simpl; auto. + intros. + inv bst. + destruct (f t); auto. Qed. -Lemma filter_in : forall s, avl s -> +Lemma filter_in : forall s, compat_bool X.eq f -> forall x : elt, In x (filter s) <-> In x s /\ f x = true. Proof. unfold filter; intros; rewrite filter_acc_in; intuition_in. -Qed. +Qed. + +Lemma filter_bst : forall s, bst s -> bst (filter s). +Proof. + unfold filter; intros; apply filter_acc_bst; auto. +Qed. @@ -1720,62 +1154,7 @@ Fixpoint partition_acc (acc : t*t)(s : t) { struct s } : t*t := Definition partition := partition_acc (Leaf,Leaf). -Lemma partition_acc_avl_1 : forall s acc, avl s -> - avl acc#1 -> avl (partition_acc acc s)#1. -Proof. - induction s; simpl; auto. - destruct acc as [acct accf]; simpl in *. - intros. - inv avl. - apply IHs2; auto. - apply IHs1; auto. - destruct (f t); simpl; auto. -Qed. - -Lemma partition_acc_avl_2 : forall s acc, avl s -> - avl acc#2 -> avl (partition_acc acc s)#2. -Proof. - induction s; simpl; auto. - destruct acc as [acct accf]; simpl in *. - intros. - inv avl. - apply IHs2; auto. - apply IHs1; auto. - destruct (f t); simpl; auto. -Qed. -Hint Resolve partition_acc_avl_1 partition_acc_avl_2. - -Lemma partition_acc_bst_1 : forall s acc, bst s -> avl s -> - bst acc#1 -> avl acc#1 -> - bst (partition_acc acc s)#1. -Proof. - induction s; simpl; auto. - destruct acc as [acct accf]; simpl in *. - intros. - inv avl; inv bst. - destruct (f t); auto. - apply IHs2; simpl; auto. - apply IHs1; simpl; auto. - apply add_bst; auto. - apply partition_acc_avl_1; simpl; auto. -Qed. - -Lemma partition_acc_bst_2 : forall s acc, bst s -> avl s -> - bst acc#2 -> avl acc#2 -> - bst (partition_acc acc s)#2. -Proof. - induction s; simpl; auto. - destruct acc as [acct accf]; simpl in *. - intros. - inv avl; inv bst. - destruct (f t); auto. - apply IHs2; simpl; auto. - apply IHs1; simpl; auto. - apply add_bst; auto. - apply partition_acc_avl_2; simpl; auto. -Qed. - -Lemma partition_acc_in_1 : forall s acc, avl s -> avl acc#1 -> +Lemma partition_acc_in_1 : forall s acc, compat_bool X.eq f -> forall x : elt, In x (partition_acc acc s)#1 <-> In x acc#1 \/ In x s /\ f x = true. @@ -1783,21 +1162,20 @@ Proof. induction s; simpl; intros. intuition_in. destruct acc as [acct accf]; simpl in *. - inv bst; inv avl. rewrite IHs2 by (destruct (f t); auto; apply partition_acc_avl_1; simpl; auto). rewrite IHs1 by (destruct (f t); simpl; auto). case_eq (f t); simpl; intros. rewrite (add_in); auto. intuition_in. - rewrite (H1 _ _ H8). + rewrite (H _ _ H2). intuition. intuition_in. - rewrite (H1 _ _ H8) in H9. - rewrite H in H9; discriminate. + rewrite (H _ _ H2) in H3. + rewrite H0 in H3; discriminate. Qed. -Lemma partition_acc_in_2 : forall s acc, avl s -> avl acc#2 -> +Lemma partition_acc_in_2 : forall s acc, compat_bool X.eq f -> forall x : elt, In x (partition_acc acc s)#2 <-> In x acc#2 \/ In x s /\ f x = false. @@ -1805,44 +1183,21 @@ Proof. induction s; simpl; intros. intuition_in. destruct acc as [acct accf]; simpl in *. - inv bst; inv avl. rewrite IHs2 by (destruct (f t); auto; apply partition_acc_avl_2; simpl; auto). rewrite IHs1 by (destruct (f t); simpl; auto). case_eq (f t); simpl; intros. intuition. intuition_in. - rewrite (H1 _ _ H8) in H9. - rewrite H in H9; discriminate. + rewrite (H _ _ H2) in H3. + rewrite H0 in H3; discriminate. rewrite (add_in); auto. intuition_in. - rewrite (H1 _ _ H8). + rewrite (H _ _ H2). intuition. -Qed. - -Lemma partition_avl_1 : forall s, avl s -> avl (partition s)#1. -Proof. - unfold partition; intros; apply partition_acc_avl_1; auto. -Qed. - -Lemma partition_avl_2 : forall s, avl s -> avl (partition s)#2. -Proof. - unfold partition; intros; apply partition_acc_avl_2; auto. -Qed. - -Lemma partition_bst_1 : forall s, bst s -> avl s -> - bst (partition s)#1. -Proof. - unfold partition; intros; apply partition_acc_bst_1; auto. Qed. -Lemma partition_bst_2 : forall s, bst s -> avl s -> - bst (partition s)#2. -Proof. - unfold partition; intros; apply partition_acc_bst_2; auto. -Qed. - -Lemma partition_in_1 : forall s, avl s -> +Lemma partition_in_1 : forall s, compat_bool X.eq f -> forall x : elt, In x (partition s)#1 <-> In x s /\ f x = true. Proof. @@ -1850,7 +1205,7 @@ Proof. simpl in *; intuition_in. Qed. -Lemma partition_in_2 : forall s, avl s -> +Lemma partition_in_2 : forall s, compat_bool X.eq f -> forall x : elt, In x (partition s)#2 <-> In x s /\ f x = false. Proof. @@ -1858,6 +1213,40 @@ Proof. simpl in *; intuition_in. Qed. +Lemma partition_acc_bst_1 : forall s acc, bst s -> bst acc#1 -> + bst (partition_acc acc s)#1. +Proof. + induction s; simpl; auto. + destruct acc as [acct accf]; simpl in *. + intros. + inv bst. + destruct (f t); auto. + apply IHs2; simpl; auto. + apply IHs1; simpl; auto. +Qed. + +Lemma partition_acc_bst_2 : forall s acc, bst s -> bst acc#2 -> + bst (partition_acc acc s)#2. +Proof. + induction s; simpl; auto. + destruct acc as [acct accf]; simpl in *. + intros. + inv bst. + destruct (f t); auto. + apply IHs2; simpl; auto. + apply IHs1; simpl; auto. +Qed. + +Lemma partition_bst_1 : forall s, bst s -> bst (partition s)#1. +Proof. + unfold partition; intros; apply partition_acc_bst_1; auto. +Qed. + +Lemma partition_bst_2 : forall s, bst s -> bst (partition s)#2. +Proof. + unfold partition; intros; apply partition_acc_bst_2; auto. +Qed. + (** * [for_all] and [exists] *) @@ -1976,56 +1365,141 @@ Qed. (** * Subset *) -Function subset (s:t*t) { measure cardinal2 s } : bool := - match s with - | (Leaf, _) => true - | (Node _ _ _ _, Leaf) => false - | (Node l1 x1 r1 h1, Node l2 x2 r2 h2) => +(** In ocaml, recursive calls are made on "half-trees" such as + (Node l1 x1 Leaf _) and (Node Leaf x1 r1 _). Instead of these + non-structural calls, we propose here two specialized functions for + these situations. This version should be almost as efficient as + the one of ocaml (closures as arguments may slow things a bit), + it is simply less compact. The exact ocaml version has also been + formalized (thanks to Function+measure), see [ocaml_subset] in + [FSetFullAVL]. + *) + +Fixpoint subsetl (subset_l1:t->bool) x1 s2 : bool := + match s2 with + | Leaf => false + | Node l2 x2 r2 h2 => + match X.compare x1 x2 with + | EQ _ => subset_l1 l2 + | LT _ => subsetl subset_l1 x1 l2 + | GT _ => mem x1 r2 && subset_l1 s2 + end + end. + +Fixpoint subsetr (subset_r1:t->bool) x1 s2 : bool := + match s2 with + | Leaf => false + | Node l2 x2 r2 h2 => + match X.compare x1 x2 with + | EQ _ => subset_r1 r2 + | LT _ => mem x1 l2 && subset_r1 s2 + | GT _ => subsetr subset_r1 x1 r2 + end + end. + +Fixpoint subset s1 s2 : bool := match s1, s2 with + | Leaf, _ => true + | Node _ _ _ _, Leaf => false + | Node l1 x1 r1 h1, Node l2 x2 r2 h2 => match X.compare x1 x2 with - | EQ _ => subset (l1,l2) && subset (r1,r2) - | LT _ => subset (Node l1 x1 Leaf 0, l2) && subset (r1,s#2) - | GT _ => subset (Node Leaf x1 r1 0, r2) && subset (l1,s#2) + | EQ _ => subset l1 l2 && subset r1 r2 + | LT _ => subsetl (subset l1) x1 l2 && subset r1 s2 + | GT _ => subsetr (subset r1) x1 r2 && subset l1 s2 end end. +Lemma subsetl_12 : forall subset_l1 l1 x1 h1 s2, + bst (Node l1 x1 Leaf h1) -> bst s2 -> + (forall s, bst s -> (subset_l1 s = true <-> Subset l1 s)) -> + (subsetl subset_l1 x1 s2 = true <-> Subset (Node l1 x1 Leaf h1) s2 ). Proof. - intros; unfold cardinal2; simpl; abstract romega with *. - intros; unfold cardinal2; simpl; abstract romega with *. - intros; unfold cardinal2; simpl; abstract romega with *. - intros; unfold cardinal2; simpl; abstract romega with *. - intros; unfold cardinal2; simpl; abstract romega with *. - intros; unfold cardinal2; simpl; abstract romega with *. -Defined. + induction s2 as [|l2 IHl2 x2 r2 IHr2 h2]; simpl; intros. + unfold Subset; intuition; try discriminate. + assert (H': In x1 Leaf) by auto; inversion H'. + inversion_clear H0. + specialize (IHl2 H H2 H1). + specialize (IHr2 H H3 H1). + inv bst. clear H8. + destruct X.compare. + + rewrite IHl2; clear H1 IHl2 IHr2. + unfold Subset. intuition_in. + assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. + assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. -Lemma subset_12 : forall s, - bst s#1 -> bst s#2 -> - (Subset s#1 s#2 <-> subset s = true). + rewrite H1 by auto; clear H1 IHl2 IHr2. + unfold Subset. intuition_in. + assert (X.eq a x2) by order; intuition_in. + assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. + + rewrite andb_true_iff, H1 by auto; clear H1 IHl2 IHr2. + unfold Subset. intuition_in. + assert (H':=mem_2 H6); apply In_1 with x1; auto. + apply mem_1; auto. + assert (In x1 (Node l2 x2 r2 h2)) by auto; intuition_in; order. +Qed. + + +Lemma subsetr_12 : forall subset_r1 r1 x1 h1 s2, + bst (Node Leaf x1 r1 h1) -> bst s2 -> + (forall s, bst s -> (subset_r1 s = true <-> Subset r1 s)) -> + (subsetr subset_r1 x1 s2 = true <-> Subset (Node Leaf x1 r1 h1) s2). Proof. - intros s; functional induction subset s; simpl; - intros B1 B2; try clear e0. - intuition. - red; auto; inversion 1. - split; intros; try discriminate. - assert (H': In _x0 Leaf) by auto; inversion H'. - (**) - simpl in *; inv bst. - rewrite andb_true_iff. - rewrite <- IHb; auto; rewrite <- IHb0; auto; clear IHb IHb0. + induction s2 as [|l2 IHl2 x2 r2 IHr2 h2]; simpl; intros. + unfold Subset; intuition; try discriminate. + assert (H': In x1 Leaf) by auto; inversion H'. + inversion_clear H0. + specialize (IHl2 H H2 H1). + specialize (IHr2 H H3 H1). + inv bst. clear H7. + destruct X.compare. + + rewrite andb_true_iff, H1 by auto; clear H1 IHl2 IHr2. + unfold Subset. intuition_in. + assert (H':=mem_2 H1); apply In_1 with x1; auto. + apply mem_1; auto. + assert (In x1 (Node l2 x2 r2 h2)) by auto; intuition_in; order. + + rewrite H1 by auto; clear H1 IHl2 IHr2. + unfold Subset. intuition_in. + assert (X.eq a x2) by order; intuition_in. + assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. + + rewrite IHr2; clear H1 IHl2 IHr2. + unfold Subset. intuition_in. + assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. + assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. +Qed. + + +Lemma subset_12 : forall s1 s2, bst s1 -> bst s2 -> + (subset s1 s2 = true <-> Subset s1 s2). +Proof. + induction s1 as [|l1 IHl1 x1 r1 IHr1 h1]; simpl; intros. + unfold Subset; intuition_in. + destruct s2 as [|l2 x2 r2 h2]; simpl; intros. + unfold Subset; intuition_in; try discriminate. + assert (H': In x1 Leaf) by auto; inversion H'. + inv bst. + destruct X.compare. + + rewrite andb_true_iff, IHr1 by auto. + rewrite (@subsetl_12 (subset l1) l1 x1 h1) by auto. + clear IHl1 IHr1. unfold Subset; intuition_in. assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. - assert (X.eq a x2) by order; intuition_in. - (**) - simpl in *; inv bst. - rewrite andb_true_iff. - rewrite <- IHb; auto; rewrite <- IHb0; auto; clear IHb IHb0. + + rewrite andb_true_iff, IHl1, IHr1 by auto. + clear IHl1 IHr1. unfold Subset; intuition_in. + assert (X.eq a x2) by order; intuition_in. assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. - (**) - simpl in *; inv bst. - rewrite andb_true_iff. - rewrite <- IHb; auto; rewrite <- IHb0; auto; clear IHb IHb0. + + rewrite andb_true_iff, IHl1 by auto. + rewrite (@subsetr_12 (subset r1) r1 x1 h1) by auto. + clear IHl1 IHr1. unfold Subset; intuition_in. assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. assert (In a (Node l2 x2 r2 h2)) by auto; intuition_in; order. @@ -2037,8 +1511,6 @@ Qed. (** ** Relations [eq] and [lt] over trees *) -(* NB: Don't use name eq yet otherwise Function won't work *) - Lemma eq_refl : forall s : t, Equal s s. Proof. unfold Equal; intuition. @@ -2081,8 +1553,28 @@ Proof. apply L.lt_not_eq with (s := elements s) (s' := elements s'); auto. Qed. +Lemma L_eq_cons : + forall (l1 l2 : list elt) (x y : elt), + X.eq x y -> L.eq l1 l2 -> L.eq (x :: l1) (y :: l2). +Proof. + unfold L.eq, L.Equal in |- *; intuition. + inversion_clear H1; generalize (H0 a); clear H0; intuition. + apply InA_eqA with x; eauto. + inversion_clear H1; generalize (H0 a); clear H0; intuition. + apply InA_eqA with y; eauto. +Qed. +Hint Resolve L_eq_cons. + -(** * A new comparison algorithm suggested by Xavier Leroy *) +(** * A new comparison algorithm suggested by Xavier Leroy + + Transformation in C.P.S. suggested by Benjamin Grégoire. + The original ocaml code (with non-structural recursive calls) + has also been formalized (thanks to Function+measure), see + [ocaml_compare] in [FSetFullAVL]. The following code with + continuations computes dramatically faster in Coq, and + should be almost as efficient after extraction. +*) (** ** Enumeration of the elements of a tree *) @@ -2116,80 +1608,49 @@ Inductive sorted_e : enumeration -> Prop := | SortedEEnd : sorted_e End | SortedEMore : forall (x : elt) (s : tree) (e : enumeration), - bst s -> - (gt_tree x s) -> - sorted_e e -> - (forall y : elt, In_e y e -> X.lt x y) -> - (forall y : elt, - In y s -> forall z : elt, In_e z e -> X.lt y z) -> + bst s -> gt_tree x s -> sorted_e e -> + (forall y, In_e y e -> X.lt x y) -> + (forall y, In y s -> forall z, In_e z e -> X.lt y z) -> sorted_e (More x s e). Hint Constructors In_e sorted_e. Lemma elements_app : - forall (s : tree) (acc : list elt), elements_aux acc s = elements s ++ acc. + forall s acc, elements_aux acc s = elements s ++ acc. Proof. - simple induction s; simpl in |- *; intuition. - rewrite H0. - rewrite H. + induction s; simpl; intuition. + rewrite IHs1, IHs2. unfold elements; simpl. - do 2 rewrite H. - rewrite H0. - repeat rewrite <- app_nil_end. - repeat rewrite app_ass; auto. + rewrite 2 IHs1, IHs2, <- !app_nil_end, !app_ass; auto. Qed. Lemma compare_flatten_1 : - forall (t0 t2 : tree) (t1 : elt) (z : int) (l : list elt), - elements t0 ++ t1 :: elements t2 ++ l = - elements (Node t0 t1 t2 z) ++ l. + forall l x r h acc, + elements l ++ x :: elements r ++ acc = + elements (Node l x r h) ++ acc. Proof. - simpl in |- *; unfold elements in |- *; simpl in |- *; intuition. - repeat rewrite elements_app. - repeat rewrite <- app_nil_end. - repeat rewrite app_ass; auto. + unfold elements; simpl; intuition. + rewrite !elements_app, <- !app_nil_end, !app_ass; auto. Qed. (** key lemma for correctness *) Lemma flatten_e_elements : - forall (x : elt) (l r : tree) (z : int) (e : enumeration), - elements l ++ flatten_e (More x r e) = elements (Node l x r z) ++ flatten_e e. + forall l x r h e, + elements l ++ flatten_e (More x r e) = elements (Node l x r h) ++ flatten_e e. Proof. - intros; simpl. - apply compare_flatten_1. + intros; simpl; apply compare_flatten_1. Qed. -(** termination of [compare_aux] *) - -Open Scope nat_scope. - -Fixpoint measure_e_t (s : tree) : nat := match s with - | Leaf => 0 - | Node l _ r _ => 1 + measure_e_t l + measure_e_t r - end. - -Fixpoint measure_e (e : enumeration) : nat := match e with - | End => 0 - | More _ s r => 1 + measure_e_t s + measure_e r - end. - (** [cons t e] adds the elements of tree [t] on the head of enumeration [e]. *) -Fixpoint cons s e {struct s} : enumeration := +Fixpoint cons s e : enumeration := match s with | Leaf => e | Node l x r h => cons l (More x r e) end. -Lemma cons_measure_e : forall s e, - measure_e (cons s e) = measure_e_t s + measure_e e. -Proof. - induction s; simpl; intros; auto. - rewrite IHs1; simpl; rewrite <- plus_n_Sm; auto with arith. -Qed. - Lemma cons_1 : forall s e, bst s -> sorted_e e -> (forall (x y : elt), In x s -> In_e y e -> X.lt x y) -> @@ -2205,115 +1666,97 @@ Proof. apply flatten_e_elements. Qed. -Lemma l_eq_cons : - forall (l1 l2 : list elt) (x y : elt), - X.eq x y -> L.eq l1 l2 -> L.eq (x :: l1) (y :: l2). -Proof. - unfold L.eq, L.Equal in |- *; intuition. - inversion_clear H1; generalize (H0 a); clear H0; intuition. - apply InA_eqA with x; eauto. - inversion_clear H1; generalize (H0 a); clear H0; intuition. - apply InA_eqA with y; eauto. -Qed. +(** One step of comparison of elements *) -Definition measure2 e := measure_e e#1 + measure_e e#2. - -Function compare_aux - (e:enumeration*enumeration) { measure measure2 e } : comparison := - match e with - | (End,End) => Eq - | (End,More _ _ _) => Lt - | (More _ _ _, End) => Gt - | (More x1 r1 e1, More x2 r2 e2) => - match X.compare x1 x2 with - | EQ _ => compare_aux (cons r1 e1, cons r2 e2) - | LT _ => Lt - | GT _ => Gt - end +Definition compare_more x1 (cont:enumeration->comparison) e2 := + match e2 with + | End => Gt + | More x2 r2 e2 => + match X.compare x1 x2 with + | EQ _ => cont (cons r2 e2) + | LT _ => Lt + | GT _ => Gt + end end. -Proof. -intros; unfold measure2; simpl; -abstract (do 2 rewrite cons_measure_e; romega with *). -Defined. +(** Comparison of left tree, middle element, then right tree *) -Definition compare s1 s2 := compare_aux (cons s1 End, cons s2 End). +Fixpoint compare_cont s1 (cont:enumeration->comparison) e2 := + match s1 with + | Leaf => cont e2 + | Node l1 x1 r1 _ => + compare_cont l1 (compare_more x1 (compare_cont r1 cont)) e2 + end. -Lemma compare_aux_Eq : forall e, - sorted_e e#1 -> sorted_e e#2 -> - compare_aux e = Eq -> L.eq (flatten_e e#1) (flatten_e e#2). -Proof. - intros e; functional induction compare_aux e; simpl; intros; auto; - try discriminate. - apply L.eq_refl. - apply l_eq_cons; auto. - inversion H; subst; clear H. - inversion H0; subst; clear H0. - destruct (@cons_1 r1 e1); destruct (@cons_1 r2 e2); auto. - rewrite <- H0; rewrite <- H3; auto. -Qed. +(** Initial continuation *) -Lemma compare_aux_Lt : forall e, - sorted_e e#1 -> sorted_e e#2 -> - compare_aux e = Lt -> L.lt (flatten_e e#1) (flatten_e e#2). -Proof. - intros e; functional induction compare_aux e; simpl; intros; auto; - try discriminate. - apply L.lt_cons_eq; auto. - inversion H; subst; clear H. - inversion H0; subst; clear H0. - destruct (@cons_1 r1 e1); destruct (@cons_1 r2 e2); auto. - rewrite <- H0; rewrite <- H3; auto. -Qed. +Definition compare_end e2 := + match e2 with End => Eq | _ => Lt end. + +(** The complete comparison *) + +Definition compare s1 s2 := compare_cont s1 compare_end (cons s2 End). -Lemma compare_aux_Gt : forall e, - sorted_e e#1 -> sorted_e e#2 -> - compare_aux e = Gt -> L.lt (flatten_e e#2) (flatten_e e#1). +(** Correctness of this comparison *) + +Definition Cmp c := + match c with + | Eq => L.eq + | Lt => L.lt + | Gt => (fun l1 l2 => L.lt l2 l1) + end. + +Lemma cons_Cmp : forall c x1 x2 l1 l2, X.eq x1 x2 -> + Cmp c l1 l2 -> Cmp c (x1::l1) (x2::l2). Proof. - intros e; functional induction compare_aux e; simpl; intros; auto; - try discriminate. - apply L.lt_cons_eq; auto. - inversion H; subst; clear H. - inversion H0; subst; clear H0. - destruct (@cons_1 r1 e1); destruct (@cons_1 r2 e2); auto. - rewrite <- H0; rewrite <- H3; auto. + destruct c; simpl; auto. Qed. +Hint Resolve cons_Cmp. -Lemma compare_Eq : forall s1 s2, bst s1 -> bst s2 -> - compare s1 s2 = Eq -> Equal s1 s2. +Lemma compare_end_Cmp : + forall e2, Cmp (compare_end e2) nil (flatten_e e2). Proof. - unfold compare; intros. - destruct (@cons_1 s1 End) as (S1,E1); auto; try inversion 2. - destruct (@cons_1 s2 End) as (S2,E2); auto; try inversion 2. - simpl in *; rewrite <- app_nil_end in *. - apply L_eq_eq; rewrite <-E1, <-E2. - apply (@compare_aux_Eq (cons s1 End, cons s2 End)); simpl; auto. + destruct e2; simpl; auto. + apply L.eq_refl. Qed. -Lemma compare_Lt : forall s1 s2, bst s1 -> bst s2 -> - compare s1 s2 = Lt -> lt s1 s2. +Lemma compare_more_Cmp : forall x1 cont x2 r2 e2 l, + Cmp (cont (cons r2 e2)) l (elements r2 ++ flatten_e e2) -> + Cmp (compare_more x1 cont (More x2 r2 e2)) (x1::l) + (flatten_e (More x2 r2 e2)). Proof. - unfold compare; intros. - destruct (@cons_1 s1 End) as (S1,E1); auto; try inversion 2. - destruct (@cons_1 s2 End) as (S2,E2); auto; try inversion 2. - simpl in *; rewrite <- app_nil_end in *. - red; rewrite <- E1, <- E2. - apply (@compare_aux_Lt (cons s1 End, cons s2 End)); simpl; auto. + simpl; intros; destruct X.compare; simpl; auto. Qed. -Lemma compare_Gt : forall s1 s2, bst s1 -> bst s2 -> - compare s1 s2 = Gt -> lt s2 s1. +Lemma compare_cont_Cmp : forall s1 cont e2 l, + bst s1 -> sorted_e e2 -> + (forall e, sorted_e e -> Cmp (cont e) l (flatten_e e)) -> + Cmp (compare_cont s1 cont e2) (elements s1 ++ l) (flatten_e e2). Proof. - unfold compare; intros. - destruct (@cons_1 s1 End) as (S1,E1); auto; try inversion 2. - destruct (@cons_1 s2 End) as (S2,E2); auto; try inversion 2. - simpl in *; rewrite <- app_nil_end in *. - red; rewrite <- E1, <- E2. - apply (@compare_aux_Gt (cons s1 End, cons s2 End)); simpl; auto. + induction s1 as [|l1 Hl1 x1 r1 Hr1 h1]; simpl; intros; auto. + inv bst. + rewrite <- compare_flatten_1; simpl. + apply Hl1; auto. clear e2 H0. intros [|x2 r2 e2] He2. + simpl; auto. + apply compare_more_Cmp. + inversion_clear He2. + destruct (cons_1 H H6); auto. + rewrite <- H10; auto. +Qed. + +Lemma compare_Cmp : forall s1 s2, bst s1 -> bst s2 -> + Cmp (compare s1 s2) (elements s1) (elements s2). +Proof. + intros; unfold compare. + rewrite (app_nil_end (elements s1)), (app_nil_end (elements s2)). + destruct (@cons_1 s2 End); auto. + inversion 2. + simpl in H2. unfold elt in *; rewrite <- H2. + apply compare_cont_Cmp; auto. + intros. + apply compare_end_Cmp; auto. Qed. -Close Scope nat_scope. - (** * Equality test *) Definition equal s1 s2 : bool := @@ -2326,17 +1769,17 @@ Lemma equal_1 : forall s1 s2, bst s1 -> bst s2 -> Equal s1 s2 -> equal s1 s2 = true. Proof. unfold equal; intros s1 s2 B1 B2 E. -generalize (compare_Lt B1 B2)(compare_Gt B1 B2). -destruct (compare s1 s2); auto; intros. -elim (lt_not_eq B1 B2 (H (refl_equal Lt)) E); auto. -elim (lt_not_eq B2 B1 (H0 (refl_equal Gt)) (eq_sym E)); auto. +generalize (compare_Cmp B1 B2). +destruct (compare s1 s2); simpl in *; auto; intros. +elim (lt_not_eq B1 B2 H E); auto. +elim (lt_not_eq B2 B1 H (eq_sym E)); auto. Qed. Lemma equal_2 : forall s1 s2, bst s1 -> bst s2 -> equal s1 s2 = true -> Equal s1 s2. Proof. unfold equal; intros s1 s2 B1 B2 E. -generalize (compare_Eq B1 B2); +generalize (compare_Cmp B1 B2); destruct compare; auto; discriminate. Qed. @@ -2347,76 +1790,66 @@ End Raw. (** * Encapsulation Now, in order to really provide a functor implementing [S], we - need to encapsulate everything into a type of balanced binary search trees. *) + need to encapsulate everything into a type of binary search trees. + They also happen to be well-balanced, but this has no influence + on the correctness of operations, so we won't state this here, + see [FSetFullAVL] if you need more than just the FSet interface. +*) Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Module E := X. - Module Raw := Raw I X. + Module Raw := Raw I X. - Record bbst := Bbst {this :> Raw.t; is_bst : Raw.bst this; is_avl: Raw.avl this}. - Definition t := bbst. + Record bst := Bst {this :> Raw.t; is_bst : Raw.bst this}. + Definition t := bst. Definition elt := E.t. - Definition In (x : elt) (s : t) : Prop := Raw.In x s. - Definition Equal (s s':t) : Prop := forall a : elt, In a s <-> In a s'. - Definition Subset (s s':t) : Prop := forall a : elt, In a s -> In a s'. - Definition Empty (s:t) : Prop := forall a : elt, ~ In a s. - Definition For_all (P : elt -> Prop) (s:t) : Prop := forall x, In x s -> P x. - Definition Exists (P : elt -> Prop) (s:t) : Prop := exists x, In x s /\ P x. - + Definition In (x : elt) (s : t) := Raw.In x s. + Definition Equal (s s':t) := forall a : elt, In a s <-> In a s'. + Definition Subset (s s':t) := forall a : elt, In a s -> In a s'. + Definition Empty (s:t) := forall a : elt, ~ In a s. + Definition For_all (P : elt -> Prop) (s:t) := forall x, In x s -> P x. + Definition Exists (P : elt -> Prop) (s:t) := exists x, In x s /\ P x. + Lemma In_1 : forall (s:t)(x y:elt), E.eq x y -> In x s -> In y s. Proof. intro s; exact (@Raw.In_1 s). Qed. Definition mem (x:elt)(s:t) : bool := Raw.mem x s. - Definition empty : t := Bbst Raw.empty_bst Raw.empty_avl. + Definition empty : t := Bst Raw.empty_bst. Definition is_empty (s:t) : bool := Raw.is_empty s. - Definition singleton (x:elt) : t := Bbst (Raw.singleton_bst x) (Raw.singleton_avl x). - Definition add (x:elt)(s:t) : t := - Bbst (Raw.add_bst x (is_bst s) (is_avl s)) - (Raw.add_avl x (is_avl s)). - Definition remove (x:elt)(s:t) : t := - Bbst (Raw.remove_bst x (is_bst s) (is_avl s)) - (Raw.remove_avl x (is_avl s)). - Definition inter (s s':t) : t := - Bbst (Raw.inter_bst (is_bst s) (is_avl s) (is_bst s') (is_avl s')) - (Raw.inter_avl (is_avl s) (is_avl s')). - Definition union (s s':t) : t := - let (s,b,a) := s in let (s',b',a') := s' in - Bbst (@Raw.union_bst (s,s') b a b' a') - (@Raw.union_avl (s,s') a a'). - Definition diff (s s':t) : t := - Bbst (Raw.diff_bst (is_bst s) (is_avl s) (is_bst s') (is_avl s')) - (Raw.diff_avl (is_avl s) (is_avl s')). + Definition singleton (x:elt) : t := Bst (Raw.singleton_bst x). + Definition add (x:elt)(s:t) : t := Bst (Raw.add_bst x (is_bst s)). + Definition remove (x:elt)(s:t) : t := Bst (Raw.remove_bst x (is_bst s)). + Definition inter (s s':t) : t := Bst (Raw.inter_bst (is_bst s) (is_bst s')). + Definition union (s s':t) : t := Bst (Raw.union_bst (is_bst s) (is_bst s')). + Definition diff (s s':t) : t := Bst (Raw.diff_bst (is_bst s) (is_bst s')). Definition elements (s:t) : list elt := Raw.elements s. Definition min_elt (s:t) : option elt := Raw.min_elt s. Definition max_elt (s:t) : option elt := Raw.max_elt s. Definition choose (s:t) : option elt := Raw.choose s. - Definition fold (B : Type) (f : elt -> B -> B) (s:t) : B -> B := Raw.fold f s. + Definition fold (B : Type) (f : elt -> B -> B) (s:t) : B -> B := Raw.fold f s. Definition cardinal (s:t) : nat := Raw.cardinal s. Definition filter (f : elt -> bool) (s:t) : t := - Bbst (Raw.filter_bst f (is_bst s) (is_avl s)) - (Raw.filter_avl f (is_avl s)). + Bst (Raw.filter_bst f (is_bst s)). Definition for_all (f : elt -> bool) (s:t) : bool := Raw.for_all f s. Definition exists_ (f : elt -> bool) (s:t) : bool := Raw.exists_ f s. Definition partition (f : elt -> bool) (s:t) : t * t := let p := Raw.partition f s in - (@Bbst (fst p) (Raw.partition_bst_1 f (is_bst s) (is_avl s)) - (Raw.partition_avl_1 f (is_avl s)), - @Bbst (snd p) (Raw.partition_bst_2 f (is_bst s) (is_avl s)) - (Raw.partition_avl_2 f (is_avl s))). + (@Bst (fst p) (Raw.partition_bst_1 f (is_bst s)), + @Bst (snd p) (Raw.partition_bst_2 f (is_bst s))). Definition equal (s s':t) : bool := Raw.equal s s'. - Definition subset (s s':t) : bool := Raw.subset (s.(this),s'.(this)). + Definition subset (s s':t) : bool := Raw.subset s s'. Definition eq (s s':t) : Prop := Raw.Equal s s'. Definition lt (s s':t) : Prop := Raw.lt s s'. Definition compare (s s':t) : Compare lt eq s s'. - Proof. - intros (s,b,a) (s',b',a'). - generalize (Raw.compare_Eq b b') (Raw.compare_Lt b b') (Raw.compare_Gt b b'). + Proof. + intros (s,b) (s',b'). + generalize (Raw.compare_Cmp b b'). destruct Raw.compare; intros; [apply EQ|apply LT|apply GT]; red; auto. Defined. @@ -2425,7 +1858,7 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Variable s s' s'': t. Variable x y : elt. - Hint Resolve is_bst is_avl. + Hint Resolve is_bst. Lemma mem_1 : In x s -> mem x s = true. Proof. exact (Raw.mem_1 (is_bst s)). Qed. @@ -2437,15 +1870,12 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Lemma equal_2 : equal s s' = true -> Equal s s'. Proof. exact (Raw.equal_2 (is_bst s) (is_bst s')). Qed. - Lemma subset_1 : Subset s s' -> subset s s' = true. - Proof. - unfold subset; rewrite <- Raw.subset_12; simpl; auto. - Qed. + Ltac wrap t H := unfold t, In; simpl; rewrite H; auto; intuition. + Lemma subset_1 : Subset s s' -> subset s s' = true. + Proof. wrap subset Raw.subset_12. Qed. Lemma subset_2 : subset s s' = true -> Subset s s'. - Proof. - unfold subset; rewrite <- Raw.subset_12; simpl; auto. - Qed. + Proof. wrap subset Raw.subset_12. Qed. Lemma empty_1 : Empty empty. Proof. exact Raw.empty_1. Qed. @@ -2456,35 +1886,18 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Proof. exact (@Raw.is_empty_2 s). Qed. Lemma add_1 : E.eq x y -> In y (add x s). - Proof. - unfold add, In; simpl; rewrite Raw.add_in; auto. - Qed. - + Proof. wrap add Raw.add_in. Qed. Lemma add_2 : In y s -> In y (add x s). - Proof. - unfold add, In; simpl; rewrite Raw.add_in; auto. - Qed. - + Proof. wrap add Raw.add_in. Qed. Lemma add_3 : ~ E.eq x y -> In y (add x s) -> In y s. - Proof. - unfold add, In; simpl; rewrite Raw.add_in; intuition. - elim H; auto. - Qed. + Proof. wrap add Raw.add_in. elim H; auto. Qed. Lemma remove_1 : E.eq x y -> ~ In y (remove x s). - Proof. - unfold remove, In; simpl; rewrite Raw.remove_in; intuition. - Qed. - + Proof. wrap remove Raw.remove_in. Qed. Lemma remove_2 : ~ E.eq x y -> In y s -> In y (remove x s). - Proof. - unfold remove, In; simpl; rewrite Raw.remove_in; intuition. - Qed. - + Proof. wrap remove Raw.remove_in. Qed. Lemma remove_3 : In y (remove x s) -> In y s. - Proof. - unfold remove, In; simpl; rewrite Raw.remove_in; intuition. - Qed. + Proof. wrap remove Raw.remove_in. Qed. Lemma singleton_1 : In y (singleton x) -> E.eq x y. Proof. exact (@Raw.singleton_1 x y). Qed. @@ -2492,52 +1905,25 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Proof. exact (@Raw.singleton_2 x y). Qed. Lemma union_1 : In x (union s s') -> In x s \/ In x s'. - Proof. - unfold union, In; simpl. - destruct s; destruct s'; simpl; rewrite Raw.union_in; simpl; auto. - Qed. - + Proof. wrap union Raw.union_in. Qed. Lemma union_2 : In x s -> In x (union s s'). - Proof. - unfold union, In; simpl. - destruct s; destruct s'; simpl; rewrite Raw.union_in; simpl; auto. - Qed. - + Proof. wrap union Raw.union_in. Qed. Lemma union_3 : In x s' -> In x (union s s'). - Proof. - unfold union, In; simpl. - destruct s; destruct s'; simpl; rewrite Raw.union_in; simpl; auto. - Qed. + Proof. wrap union Raw.union_in. Qed. Lemma inter_1 : In x (inter s s') -> In x s. - Proof. - unfold inter, In; simpl; rewrite Raw.inter_in; intuition. - Qed. - + Proof. wrap inter Raw.inter_in. Qed. Lemma inter_2 : In x (inter s s') -> In x s'. - Proof. - unfold inter, In; simpl; rewrite Raw.inter_in; intuition. - Qed. - + Proof. wrap inter Raw.inter_in. Qed. Lemma inter_3 : In x s -> In x s' -> In x (inter s s'). - Proof. - unfold inter, In; simpl; rewrite Raw.inter_in; intuition. - Qed. + Proof. wrap inter Raw.inter_in. Qed. Lemma diff_1 : In x (diff s s') -> In x s. - Proof. - unfold diff, In; simpl; rewrite Raw.diff_in; intuition. - Qed. - + Proof. wrap diff Raw.diff_in. Qed. Lemma diff_2 : In x (diff s s') -> ~ In x s'. - Proof. - unfold diff, In; simpl; rewrite Raw.diff_in; intuition. - Qed. - + Proof. wrap diff Raw.diff_in. Qed. Lemma diff_3 : In x s -> ~ In x s' -> In x (diff s s'). - Proof. - unfold diff, In; simpl; rewrite Raw.diff_in; intuition. - Qed. + Proof. wrap diff Raw.diff_in. Qed. Lemma fold_1 : forall (A : Type) (i : A) (f : elt -> A -> A), fold f s i = fold_left (fun a e => f e a) (elements s) i. @@ -2554,19 +1940,11 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Variable f : elt -> bool. Lemma filter_1 : compat_bool E.eq f -> In x (filter f s) -> In x s. - Proof. - intro; unfold filter, In; simpl; rewrite Raw.filter_in; intuition. - Qed. - + Proof. intro. wrap filter Raw.filter_in. Qed. Lemma filter_2 : compat_bool E.eq f -> In x (filter f s) -> f x = true. - Proof. - intro; unfold filter, In; simpl; rewrite Raw.filter_in; intuition. - Qed. - + Proof. intro. wrap filter Raw.filter_in. Qed. Lemma filter_3 : compat_bool E.eq f -> In x s -> f x = true -> In x (filter f s). - Proof. - intro; unfold filter, In; simpl; rewrite Raw.filter_in; intuition. - Qed. + Proof. intro. wrap filter Raw.filter_in. Qed. Lemma for_all_1 : compat_bool E.eq f -> For_all (fun x => f x = true) s -> for_all f s = true. Proof. exact (@Raw.for_all_1 f s). Qed. @@ -2582,16 +1960,14 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Equal (fst (partition f s)) (filter f s). Proof. unfold partition, filter, Equal, In; simpl ;intros H a. - rewrite Raw.partition_in_1; auto. - rewrite Raw.filter_in; intuition. + rewrite Raw.partition_in_1, Raw.filter_in; intuition. Qed. Lemma partition_2 : compat_bool E.eq f -> Equal (snd (partition f s)) (filter (fun x => negb (f x)) s). Proof. unfold partition, filter, Equal, In; simpl ;intros H a. - rewrite Raw.partition_in_2; auto. - rewrite Raw.filter_in; intuition. + rewrite Raw.partition_in_2, Raw.filter_in; intuition. rewrite H2; auto. destruct (f a); auto. red; intros; f_equal. @@ -2601,18 +1977,11 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. End Filter. Lemma elements_1 : In x s -> InA E.eq x (elements s). - Proof. - unfold elements, In; rewrite Raw.elements_in; auto. - Qed. - + Proof. wrap elements Raw.elements_in. Qed. Lemma elements_2 : InA E.eq x (elements s) -> In x s. - Proof. - unfold elements, In; rewrite Raw.elements_in; auto. - Qed. - + Proof. wrap elements Raw.elements_in. Qed. Lemma elements_3 : sort E.lt (elements s). Proof. exact (Raw.elements_sort (is_bst s)). Qed. - Lemma elements_3w : NoDupA E.eq (elements s). Proof. exact (Raw.elements_nodup (is_bst s)). Qed. @@ -2636,9 +2005,7 @@ Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Proof. exact (@Raw.choose_2 s). Qed. Lemma choose_3 : choose s = Some x -> choose s' = Some y -> Equal s s' -> E.eq x y. - Proof. - exact (@Raw.choose_3 _ _ (is_bst s) (is_avl s) (is_bst s') (is_avl s') x y). - Qed. + Proof. exact (@Raw.choose_3 _ _ (is_bst s) (is_bst s') x y). Qed. Lemma eq_refl : eq s s. Proof. exact (Raw.eq_refl s). Qed. @@ -2660,4 +2027,3 @@ End IntMake. Module Make (X: OrderedType) <: S with Module E := X :=IntMake(Z_as_Int)(X). - |