Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(* -*- coding: utf-8 -*- *)
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
This module implements finite sets using AVL trees.
It follows the implementation from Ocaml's standard library,
All operations given here expect and produce well-balanced trees
(in the ocaml sense: heights 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 MSet interface. As a consequence,
balancing results are not part of this file anymore, they can
now be found in MSetFullAVL.
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
MSetFullAVL. The structural variants compute faster in Coq,
whereas the other variants produce nicer and/or (slightly) faster
code after extraction.
Require Import FunInd MSetInterface MSetGenTree BinInt Int. Set Implicit Arguments. Unset Strict Implicit. (* for nicer extraction, we create inductive principles only when needed *) Local Unset Elimination Schemes.
Module Ops (Import I:Int)(X:OrderedType) <: MSetInterface.Ops X. Local Open Scope Int_scope. Notation int := I.t.
We reuse a generic definition of trees where the information
parameter is a Int.t. Functions like mem or fold are also
provided by this generic functor.
Include MSetGenTree.Ops X I. Definition t := tree.
Definition height (s : t) : int :=
match s with
| Leaf => 0
| Node h _ _ _ => h
end.
Definition singleton x := Node 1 Leaf x Leaf.
create l x r creates a node, assuming l and r
to be balanced and |height l - height r| ≤ 2.
Definition create l x r :=
Node (max (height l) (height r) + 1) l x r.
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. Definition bal l x r := let hl := height l in let hr := height r in if (hr+2) <? hl then match l with | Leaf => assert_false l x r | Node _ ll lx lr => if (height lr) <=? (height ll) then create ll lx (create lr x r) else match lr with | Leaf => assert_false l x r | Node _ lrl lrx lrr => create (create ll lx lrl) lrx (create lrr x r) end end else if (hl+2) <? hr then match r with | Leaf => assert_false l x r | Node _ rl rx rr => if (height rl) <=? (height rr) then create (create l x rl) rx rr else match rl with | Leaf => assert_false l x r | Node _ rll rlx rlr => create (create l x rll) rlx (create rlr rx rr) end end else create l x r.
Fixpoint add x s := match s with
| Leaf => Node 1 Leaf x Leaf
| Node h l y r =>
match X.compare x y with
| Lt => bal (add x l) y r
| Eq => Node h l y r
| Gt => bal l y (add x r)
end
end.
Fixpoint join l : elt -> t -> t :=
match l with
| Leaf => add
| Node lh ll lx lr => fun x =>
fix join_aux (r:t) : t := match r with
| Leaf => add x l
| Node rh rl rx rr =>
if (rh+2) <? lh then bal ll lx (join lr x r)
else if (lh+2) <? rh then bal (join_aux rl) rx rr
else create l x r
end
end.
Extraction of minimum element
Fixpoint remove_min l x r : t*elt :=
match l with
| Leaf => (r,x)
| Node lh ll lx lr =>
let (l',m) := remove_min ll lx lr in (bal l' x r, m)
end.
Merging two trees
Definition merge s1 s2 := match s1,s2 with
| Leaf, _ => s2
| _, Leaf => s1
| _, Node _ l2 x2 r2 =>
let (s2',m) := remove_min l2 x2 r2 in bal s1 m s2'
end.
Fixpoint remove x s := match s with
| Leaf => Leaf
| Node _ l y r =>
match X.compare x y with
| Lt => bal (remove x l) y r
| Eq => merge l r
| Gt => bal l y (remove x r)
end
end.
Definition concat s1 s2 :=
match s1, s2 with
| Leaf, _ => s2
| _, Leaf => s1
| _, Node _ l2 x2 r2 =>
let (s2',m) := remove_min l2 x2 r2 in
join s1 m s2'
end.
Splitting
- l is the set of elements of s that are < x
- r is the set of elements of s that are > x
- present is true if and only if s contains x.
Record triple := mktriple { t_left:t; t_in:bool; t_right:t }. Notation "<< l , b , r >>" := (mktriple l b r) (at level 9). Fixpoint split x s : triple := match s with | Leaf => << Leaf, false, Leaf >> | Node _ l y r => match X.compare x y with | Lt => let (ll,b,rl) := split x l in << ll, b, join rl y r >> | Eq => << l, true, r >> | Gt => let (rl,b,rr) := split x r in << join l y rl, b, rr >> end end.
Fixpoint inter s1 s2 := match s1, s2 with
| Leaf, _ => Leaf
| _, Leaf => Leaf
| Node _ l1 x1 r1, _ =>
let (l2',pres,r2') := split x1 s2 in
if pres then join (inter l1 l2') x1 (inter r1 r2')
else concat (inter l1 l2') (inter r1 r2')
end.
Fixpoint diff s1 s2 := match s1, s2 with
| Leaf, _ => Leaf
| _, Leaf => s1
| Node _ l1 x1 r1, _ =>
let (l2',pres,r2') := split x1 s2 in
if pres then concat (diff l1 l2') (diff r1 r2')
else join (diff l1 l2') x1 (diff r1 r2')
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 MSetFullAVL.
Fixpoint union s1 s2 :=
match s1, s2 with
| Leaf, _ => s2
| _, Leaf => s1
| Node _ l1 x1 r1, _ =>
let (l2',_,r2') := split x1 s2 in
join (union l1 l2') x1 (union r1 r2')
end.
Fixpoint filter (f:elt->bool) s := match s with
| Leaf => Leaf
| Node _ l x r =>
let l' := filter f l in
let r' := filter f r in
if f x then join l' x r' else concat l' r'
end.
Fixpoint partition (f:elt->bool)(s : t) : t*t := match s with | Leaf => (Leaf, Leaf) | Node _ l x r => let (l1,l2) := partition f l in let (r1,r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2) end. End Ops.
Module MakeRaw (Import I:Int)(X:OrderedType) <: RawSets X. Include Ops I X.
Generic definition of binary-search-trees and proofs of
specifications for generic functions such as mem or fold.
Include MSetGenTree.Props X I.
Automation and dedicated tactics
Local Hint Immediate MX.eq_sym : core. Local Hint Unfold In lt_tree gt_tree Ok : core. Local Hint Constructors InT bst : core. Local Hint Resolve MX.eq_refl MX.eq_trans MX.lt_trans ok : core. Local Hint Resolve lt_leaf gt_leaf lt_tree_node gt_tree_node : core. Local Hint Resolve lt_tree_not_in lt_tree_trans gt_tree_not_in gt_tree_trans : core. Local Hint Resolve elements_spec2 : core. (* Sometimes functional induction will expose too much of a tree structure. The following tactic allows factoring back a Node whose internal parts occurs nowhere else. *) (* TODO: why Ltac instead of Tactic Notation don't work ? why clear ? *) Tactic Notation "factornode" ident(s) := try clear s; match goal with | |- context [Node ?l ?x ?r ?h] => set (s:=Node l x r h) in *; clearbody s; clear l x r h | _ : context [Node ?l ?x ?r ?h] |- _ => set (s:=Node l x r h) in *; clearbody s; clear l x r h end.
Inductions principles for some of the set operators
Functional Scheme bal_ind := Induction for bal Sort Prop. Functional Scheme remove_min_ind := Induction for remove_min Sort Prop. Functional Scheme merge_ind := Induction for merge Sort Prop. Functional Scheme concat_ind := Induction for concat Sort Prop. Functional Scheme inter_ind := Induction for inter Sort Prop. Functional Scheme diff_ind := Induction for diff Sort Prop. Functional Scheme union_ind := Induction for union Sort Prop.
Notations and helper lemma about pairs and triples
Declare Scope pair_scope. Notation "s #1" := (fst s) (at level 9, format "s '#1'") : pair_scope. Notation "s #2" := (snd s) (at level 9, format "s '#2'") : pair_scope. Notation "t #l" := (t_left t) (at level 9, format "t '#l'") : pair_scope. Notation "t #b" := (t_in t) (at level 9, format "t '#b'") : pair_scope. Notation "t #r" := (t_right t) (at level 9, format "t '#r'") : pair_scope. Local Open Scope pair_scope.
forall (x : X.t) (y : elt), InT y (singleton x) <-> X.eq y xunfold singleton; intuition_in. Qed.forall (x : X.t) (y : elt), InT y (singleton x) <-> X.eq y xx:X.tOk (singleton x)unfold singleton; auto. Qed.x:X.tOk (singleton x)
forall (l : t) (x : X.t) (r : t) (y : elt), InT y (create l x r) <-> X.eq y x \/ InT y l \/ InT y runfold create; split; [ inversion_clear 1 | ]; intuition. Qed.forall (l : t) (x : X.t) (r : t) (y : elt), InT y (create l x r) <-> X.eq y x \/ InT y l \/ InT y rl:treex:X.tr:treeH:Ok lH0:Ok rlt_tree0:lt_tree x lgt_tree0:gt_tree x rOk (create l x r)unfold create; auto. Qed.l:treex:X.tr:treeH:Ok lH0:Ok rlt_tree0:lt_tree x lgt_tree0:gt_tree x rOk (create l x r)forall (l : t) (x : X.t) (r : t) (y : elt), InT y (bal l x r) <-> X.eq y x \/ InT y l \/ InT y rintros l x r; functional induction bal l x r; intros; try clear e0; rewrite !create_spec; intuition_in. Qed.forall (l : t) (x : X.t) (r : t) (y : elt), InT y (bal l x r) <-> X.eq y x \/ InT y l \/ InT y rl:treex:X.tr:treeH:Ok lH0:Ok rlt_tree0:lt_tree x lgt_tree0:gt_tree x rOk (bal l x r)functional induction bal l x r; intros; inv; repeat apply create_ok; auto; unfold create; (apply lt_tree_node || apply gt_tree_node); auto; (eapply lt_tree_trans || eapply gt_tree_trans); eauto. Qed.l:treex:X.tr:treeH:Ok lH0:Ok rlt_tree0:lt_tree x lgt_tree0:gt_tree x rOk (bal l x r)
forall (s : tree) (x : X.t) (y : elt), InT y (add x s) <-> X.eq y x \/ InT y sforall (s : tree) (x : X.t) (y : elt), InT y (add x s) <-> X.eq y x \/ InT y ssetoid_replace y with x'; eauto. Qed.i:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), InT y0 (add x0 l) <-> X.eq y0 x0 \/ InT y0 lIHr:forall (x0 : X.t) (y0 : elt), InT y0 (add x0 r) <-> X.eq y0 x0 \/ InT y0 rx:X.ty:eltH:X.eq x x'H1:X.eq y xInT y (Node i l x' r)forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (add x s) <-> X.eq y x \/ InT y sintros; apply add_spec'. Qed.forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (add x s) <-> X.eq y x \/ InT y ss:treex:X.tH:Ok sOk (add x s)induct s x; auto; apply bal_ok; auto; intros y; rewrite add_spec'; intuition; order. Qed. Local Open Scope Int_scope.s:treex:X.tH:Ok sOk (add x s)
Function/Functional Scheme can't deal with internal fix.
Let's do its job by hand:
Ltac join_tac := let l := fresh "l" in intro l; induction l as [| lh ll _ lx lr Hlr]; [ | intros x r; induction r as [| rh rl Hrl rx rr _]; unfold join; [ | destruct ((rh+2) <? lh) eqn:LT; [ match goal with |- context b [ bal ?a ?b ?c] => replace (bal a b c) with (bal ll lx (join lr x (Node rh rl rx rr))); [ | auto] end | destruct ((lh+2) <? rh) eqn:LT'; [ match goal with |- context b [ bal ?a ?b ?c] => replace (bal a b c) with (bal (join (Node lh ll lx lr) x rl) rx rr); [ | auto] end | ] ] ] ]; intros.forall (l : tree) (x : elt) (r : t) (y : elt), InT y (join l x r) <-> X.eq y x \/ InT y l \/ InT y rforall (l : tree) (x : elt) (r : t) (y : elt), InT y (join l x r) <-> X.eq y x \/ InT y l \/ InT y rx:eltr:ty:eltInT y (join Leaf x r) <-> X.eq y x \/ InT y Leaf \/ InT y rlh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx, y:eltInT y (add x (Node lh ll lx lr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y Leaflh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = truey:eltInT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = truey:eltInT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = falsey:eltInT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)x:eltr:ty:eltInT y (add x r) <-> X.eq y x \/ InT y Leaf \/ InT y rlh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx, y:eltInT y (add x (Node lh ll lx lr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y Leaflh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = truey:eltInT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = truey:eltInT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = falsey:eltInT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx, y:eltInT y (add x (Node lh ll lx lr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y Leaflh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = truey:eltInT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = truey:eltInT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = falsey:eltInT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = truey:eltInT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = truey:eltInT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = falsey:eltInT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = truey:eltInT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = falsey:eltInT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)apply create_spec. Qed.lh:I.tll:treelx:X.tlr:treeHlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 rx:eltrh:I.trl:treerx:X.trr:treeHrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rlLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = falsey:eltInT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)forall (l : tree) (x : X.t) (r : tree), Ok l -> Ok r -> lt_tree x l -> gt_tree x r -> Ok (join l x r)forall (l : tree) (x : X.t) (r : tree), Ok l -> Ok r -> lt_tree x l -> gt_tree x r -> Ok (join l x r)lh:I.tll:treelx:X.tlr:treex:X.trh:I.trl:treerx:X.trr:treeLT:(rh + 2 <? lh) = truelt_tree0:lt_tree x (Node lh ll lx lr)gt_tree0:gt_tree x (Node rh rl rx rr)H5:Ok rlH6:Ok rrH7:lt_tree rx rlH8:gt_tree rx rrH4:Ok llH9:Ok lrH10:lt_tree lx llH11:gt_tree lx lry:eltH:X.eq y x \/ InT y lr \/ InT y (Node rh rl rx rr)X.lt lx ylh:I.tll:treelx:X.tlr:treex:X.trh:I.trl:treerx:X.trr:treeLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = truelt_tree0:lt_tree x (Node lh ll lx lr)gt_tree0:gt_tree x (Node rh rl rx rr)H5:Ok rlH6:Ok rrH7:lt_tree rx rlH8:gt_tree rx rrH4:Ok llH9:Ok lrH10:lt_tree lx llH11:gt_tree lx lry:eltH:X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y rlX.lt y rxintuition; [ setoid_replace y with x | ]; eauto. Qed.lh:I.tll:treelx:X.tlr:treex:X.trh:I.trl:treerx:X.trr:treeLT:(rh + 2 <? lh) = falseLT':(lh + 2 <? rh) = truelt_tree0:lt_tree x (Node lh ll lx lr)gt_tree0:gt_tree x (Node rh rl rx rr)H5:Ok rlH6:Ok rrH7:lt_tree rx rlH8:gt_tree rx rrH4:Ok llH9:Ok lrH10:lt_tree lx llH11:gt_tree lx lry:eltH:X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y rlX.lt y rx
forall (l : tree) (x : X.t) (r : tree) (y : elt) (h : I.t), InT y (Node h l x r) <-> X.eq y (remove_min l x r)#2 \/ InT y (remove_min l x r)#1forall (l : tree) (x : X.t) (r : tree) (y : elt) (h : I.t), InT y (Node h l x r) <-> X.eq y (remove_min l x r)#2 \/ InT y (remove_min l x r)#1x:eltr:ty:elth:I.tInT y (Node h Leaf x r) <-> X.eq y x \/ InT y rx:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall (y0 : elt) (h0 : I.t), InT y0 (Node h0 ll lx lr) <-> X.eq y0 (remove_min ll lx lr)#2 \/ InT y0 (remove_min ll lx lr)#1y:elth:I.tInT y (Node h (Node _x ll lx lr) x r) <-> X.eq y m \/ InT y (bal l' x r)rewrite bal_spec, In_node_iff, IHp, e0; simpl; intuition. Qed.x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall (y0 : elt) (h0 : I.t), InT y0 (Node h0 ll lx lr) <-> X.eq y0 (remove_min ll lx lr)#2 \/ InT y0 (remove_min ll lx lr)#1y:elth:I.tInT y (Node h (Node _x ll lx lr) x r) <-> X.eq y m \/ InT y (bal l' x r)l:treex:X.tr:treeforall h : I.t, Ok (Node h l x r) -> Ok (remove_min l x r)#1l:treex:X.tr:treeforall h : I.t, Ok (Node h l x r) -> Ok (remove_min l x r)#1x:eltr:th:I.tH:Ok (Node h Leaf x r)Ok rx:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)Ok (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)Ok (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)Ok (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)Ok (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)Ok (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)Ok rx:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)lt_tree x l'x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)gt_tree x rx:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)lt_tree x l'x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)gt_tree x rx:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)y:eltL:InT y (Node _x ll lx lr) -> X.lt y xInT y l' -> X.lt y xx:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)gt_tree x rinv; auto. Qed.x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:Ok l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)gt_tree x rforall (l : tree) (x : X.t) (r : tree) (h : I.t), Ok (Node h l x r) -> gt_tree (remove_min l x r)#2 (remove_min l x r)#1forall (l : tree) (x : X.t) (r : tree) (h : I.t), Ok (Node h l x r) -> gt_tree (remove_min l x r)#2 (remove_min l x r)#1x:eltr:th:I.tH:Ok (Node h Leaf x r)gt_tree x rx:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)gt_tree m (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)gt_tree m (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)gt_tree m (bal l' x r)x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)gt_tree m (bal l' x r)intro y; rewrite bal_spec; intuition; specialize (L m); rewrite remove_min_spec, e0 in L; simpl in L; [setoid_replace y with x|inv]; eauto. Qed. Local Hint Resolve remove_min_gt_tree : core.x:eltr:t_x:I.tll:treelx:X.tlr:treel':tm:elte0:remove_min ll lx lr = (l', m)IHp:gt_tree m l'h:I.tH:Ok (Node h (Node _x ll lx lr) x r)O:Ok (Node _x ll lx lr)L:lt_tree x (Node _x ll lx lr)gt_tree m (bal l' x r)
forall (s1 s2 : tree) (y : elt), InT y (merge s1 s2) <-> InT y s1 \/ InT y s2forall (s1 s2 : tree) (y : elt), InT y (merge s1 s2) <-> InT y s1 \/ InT y s2s2:treey:eltInT y s2 <-> InT y Leaf \/ InT y s2y:elts1:treeInT y s1 <-> InT y s1 \/ InT y Leaf_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)y:elts1:treeInT y (bal s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)y:elts1:treeInT y s1 <-> InT y s1 \/ InT y Leaf_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)y:elts1:treeInT y (bal s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)rewrite bal_spec, remove_min_spec, e1; simpl; intuition. Qed._x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)y:elts1:treeInT y (bal s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)s1, s2:treeOk s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (merge s1 s2)s1, s2:treeOk s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (merge s1 s2)_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2Ok (bal s1 m s2')_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2Ok s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2lt_tree m s1_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2lt_tree m s1_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2y:eltHy:InT y s1X.lt y m_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2y:eltHy:InT y s1InT m (Node _x3 l2 x2 r2)_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'change (gt_tree (s2',m)#2 (s2',m)#1); rewrite <-e1; eauto. Qed._x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'
forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (remove x s) <-> InT y s /\ ~ X.eq y xforall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (remove x s) <-> InT y s /\ ~ X.eq y xx:X.ty:eltH:Ok LeafInT y Leaf <-> InT y Leaf /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (merge l r) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (merge l r) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ (X.eq y0 x0 -> False)IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ (X.eq y0 x0 -> False)x:X.ty:eltH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rH2:X.eq y x -> FalseH3:X.eq y x'InT y l \/ InT y ri:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y xrewrite bal_spec, IHr; clear IHl IHr; intuition; [order|order|intuition_in]. Qed.i:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y xs:treex:X.tH:Ok sOk (remove x s)s:treex:X.tH:Ok sOk (remove x s)x:X.tH:Ok LeafOk Leafi:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (merge l r)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal (remove x l) x' r)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal l x' (remove x r))(* EQ *)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (merge l r)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal (remove x l) x' r)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal l x' (remove x r))(* LT *)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal (remove x l) x' r)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal l x' (remove x r))i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rlt_tree x' (remove x l)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal l x' (remove x r))(* GT *)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (bal l x' (remove x r))intro z; rewrite remove_spec; auto; destruct 1; eauto. Qed.i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (remove x l)IHr:Ok r -> Ok (remove x r)H0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rgt_tree x' (remove x r)
forall (s1 s2 : tree) (y : elt), InT y (concat s1 s2) <-> InT y s1 \/ InT y s2forall (s1 s2 : tree) (y : elt), InT y (concat s1 s2) <-> InT y s1 \/ InT y s2s2:treey:eltInT y s2 <-> InT y Leaf \/ InT y s2y:elts1:treeInT y s1 <-> InT y s1 \/ InT y Leaf_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)y:elts1:treeInT y (join s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)y:elts1:treeInT y s1 <-> InT y s1 \/ InT y Leaf_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)y:elts1:treeInT y (join s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)rewrite join_spec, remove_min_spec, e1; simpl; intuition. Qed._x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)y:elts1:treeInT y (join s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)s1, s2:treeOk s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (concat s1 s2)s1, s2:treeOk s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (concat s1 s2)_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2Ok (join s1 m s2')_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2Ok s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2lt_tree m s1_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2lt_tree m s1_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2y:eltHy:InT y s1X.lt y m_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2y:eltHy:InT y s1InT m (Node _x3 l2 x2 r2)_x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'change (gt_tree (s2',m)#2 (s2',m)#1); rewrite <-e1; eauto. Qed._x3:I.tl2:treex2:X.tr2:trees2':tm:elte1:remove_min l2 x2 r2 = (s2', m)s1:treeH:Ok s1H0:Ok (Node _x3 l2 x2 r2)H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2gt_tree m s2'
forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#l <-> InT y s /\ X.lt y xforall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#l <-> InT y s /\ X.lt y xx:X.ty:eltH:Ok LeafInT y Leaf <-> InT y Leaf /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (<< l, true, r >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (<< l, true, r >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treex:X.ty:eltIHl:Ok l -> InT y (split x l)#l <-> InT y l /\ X.lt y xIHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treex:X.ty:eltt_left0:tt_in0:boolt_right0:tIHl:Ok l -> InT y t_left0 <-> InT y l /\ X.lt y xIHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y t_left0 <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y xi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0x:X.ty:eltIHr:Ok r -> InT y (split x r)#l <-> InT y r /\ X.lt y xH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y xrewrite join_spec, IHr; intuition_in; order. Qed.i:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0x:X.ty:eltt_left0:tt_in0:boolt_right0:tIHr:Ok r -> InT y t_left0 <-> InT y r /\ X.lt y xH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (join l x' t_left0) <-> InT y (Node i l x' r) /\ X.lt y xforall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#r <-> InT y s /\ X.lt x yforall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#r <-> InT y s /\ X.lt x yx:X.ty:eltH:Ok LeafInT y Leaf <-> InT y Leaf /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (<< l, true, r >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (<< l, true, r >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treex:X.ty:eltIHl:Ok l -> InT y (split x l)#r <-> InT y l /\ X.lt x yIHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treex:X.ty:eltt_left0:tt_in0:boolt_right0:tIHl:Ok l -> InT y t_right0 <-> InT y l /\ X.lt x yIHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0H0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (join t_right0 x' r) <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0x:X.ty:eltH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x yi:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0x:X.ty:eltIHr:Ok r -> InT y (split x r)#r <-> InT y r /\ X.lt x yH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x yrewrite IHr; intuition_in; order. Qed.i:I.tl:treex':X.tr:treeIHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0x:X.ty:eltt_left0:tt_in0:boolt_right0:tIHr:Ok r -> InT y t_right0 <-> InT y r /\ X.lt x yH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rInT y t_right0 <-> InT y (Node i l x' r) /\ X.lt x yforall (s : tree) (x : X.t), Ok s -> (split x s)#b = true <-> InT x sforall (s : tree) (x : X.t), Ok s -> (split x s)#b = true <-> InT x sx:X.tH:Ok Leaffalse = true <-> InT x Leafi:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(<< l, true, r >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.eq x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(<< l, true, r >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> (split x l)#b = true <-> InT x lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treex:X.tt_left0:tt_in0:boolt_right0:tIHl:Ok l -> t_in0 = true <-> InT x lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rt_in0 = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lIHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lx:X.tIHr:Ok r -> (split x r)#b = true <-> InT x rH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)rewrite IHr; intuition_in; order. Qed.i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 lx:X.tt_left0:tt_in0:boolt_right0:tIHr:Ok r -> t_in0 = true <-> InT x rH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rt_in0 = true <-> InT x (Node i l x' r)forall (s : tree) (x : X.t), Ok s -> Ok (split x s)#l /\ Ok (split x s)#rforall (s : tree) (x : X.t), Ok s -> Ok (split x s)#l /\ Ok (split x s)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rx:X.tH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l /\ Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (split x l)#l /\ Ok (split x l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l /\ Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treex:X.tIHl:Ok l -> Ok (split x l)#l /\ Ok (split x l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(forall y : elt, InT y (split x l)#r <-> InT y l /\ X.lt x y) -> Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l /\ Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treex:X.tt_left0:tt_in0:boolt_right0:tIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rH:forall y : elt, InT y t_right0 <-> InT y l /\ X.lt x yH2:Ok t_left0H3:Ok t_right0Ok (join t_right0 x' r)i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treex:X.tt_left0:tt_in0:boolt_right0:tIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rH0:X.lt x x'H5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rH:forall y : elt, InT y t_right0 <-> InT y l /\ X.lt x yH2:Ok t_left0H3:Ok t_right0lt_tree x' t_right0i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rIHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#rx:X.tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rx:X.tIHr:Ok r -> Ok (split x r)#l /\ Ok (split x r)#rH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rOk (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rx:X.tIHr:Ok r -> Ok (split x r)#l /\ Ok (split x r)#rH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' r(forall y : elt, InT y (split x r)#l <-> InT y r /\ X.lt y x) -> Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#ri:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rx:X.tt_left0:tt_in0:boolt_right0:tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rH:forall y : elt, InT y t_left0 <-> InT y r /\ X.lt y xH2:Ok t_left0H3:Ok t_right0Ok (join l x' t_left0)intros y; rewrite H; intuition. Qed.i:I.tl:treex':X.tr:treeIHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#rx:X.tt_left0:tt_in0:boolt_right0:tH0:X.lt x' xH5:Ok lH6:Ok rH7:lt_tree x' lH8:gt_tree x' rH:forall y : elt, InT y t_left0 <-> InT y r /\ X.lt y xH2:Ok t_left0H3:Ok t_right0gt_tree x' t_left0s:treex:X.tH:Ok sOk (split x s)#lintros; destruct (@split_ok s x); auto. Qed.s:treex:X.tH:Ok sOk (split x s)#ls:treex:X.tH:Ok sOk (split x s)#rintros; destruct (@split_ok s x); auto. Qed.s:treex:X.tH:Ok sOk (split x s)#r
Ltac destruct_split := match goal with | H : split ?x ?s = << ?u, ?v, ?w >> |- _ => assert ((split x s)#l = u) by (rewrite H; auto); assert ((split x s)#b = v) by (rewrite H; auto); assert ((split x s)#r = w) by (rewrite H; auto); clear H; subst u w end.forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (inter s1 s2) /\ (forall y : elt, InT y (inter s1 s2) <-> InT y s1 /\ InT y s2)forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (inter s1 s2) /\ (forall y : elt, InT y (inter s1 s2) <-> InT y s1 /\ InT y s2)_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#rOk (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltInT y (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#rOk (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltInT y (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2apply join_ok; auto with *; intro y; rewrite ?IHi1, ?IHi2; intuition._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#rOk (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltInT y (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltH1:X.eq y x1InT y s2rewrite <- split_spec3; auto._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltH1:X.eq y x1InT x1 s2apply concat_ok; auto with *; intros y1 y2; rewrite IHi1, IHi2; intuition; order._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#rOk (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltInT y (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltInT y l1 /\ InT y s2 /\ X.lt y x1 \/ InT y r1 /\ InT y s2 /\ X.lt x1 y <-> InT y (Node _x l1 x1 r1) /\ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltH2:InT y s2H3:X.eq y x1InT y l1 /\ InT y s2 /\ X.lt y x1 \/ InT y r1 /\ InT y s2 /\ X.lt x1 y_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltH2:InT y s2H3:X.eq y x1~ InT x1 s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltH2:InT y s2H3:X.eq y x1InT x1 s2setoid_replace x1 with y; auto. Qed._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHo1:Ok (inter l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#lIHo2:Ok (inter r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#ry:eltH2:InT y s2H3:X.eq y x1InT x1 s2forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (inter s1 s2) <-> InT y s1 /\ InT y s2intros; destruct (@inter_spec_ok s1 s2); auto. Qed.forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (inter s1 s2) <-> InT y s1 /\ InT y s2s1, s2:treeH:Ok s1H0:Ok s2Ok (inter s1 s2)intros; destruct (@inter_spec_ok s1 s2); auto. Qed.s1, s2:treeH:Ok s1H0:Ok s2Ok (inter s1 s2)
forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (diff s1 s2) /\ (forall y : elt, InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2)forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (diff s1 s2) /\ (forall y : elt, InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2)_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#rOk (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#ry:eltInT y (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#rOk (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#ry:eltInT y (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2apply concat_ok; auto; intros y1 y2; rewrite IHi1, IHi2; intuition; order._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#rOk (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#ry:eltInT y (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH2:InT y s2 -> FalseH3:X.eq y x1InT y l1 /\ (InT y s2 /\ X.lt y x1 -> False) \/ InT y r1 /\ (InT y s2 /\ X.lt x1 y -> False)_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH2:InT y s2 -> FalseH3:X.eq y x1~ InT x1 s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH2:InT y s2 -> FalseH3:X.eq y x1InT x1 s2setoid_replace x1 with y; auto._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH2:InT y s2 -> FalseH3:X.eq y x1~ InT x1 s2rewrite <- split_spec3; auto; congruence._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = trueH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH2:InT y s2 -> FalseH3:X.eq y x1InT x1 s2apply join_ok; auto; intro y; rewrite ?IHi1, ?IHi2; intuition._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#rOk (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#ry:eltInT y (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#lIHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#ry:eltX.eq y x1 \/ InT y l1 /\ ~ (InT y s2 /\ X.lt y x1) \/ InT y r1 /\ ~ (InT y s2 /\ X.lt x1 y) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH1:X.eq y x1H:InT y s2False_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH1:X.eq y x1H:InT y s2~ InT x1 s2_x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH1:X.eq y x1H:InT y s2InT x1 s2rewrite <- split_spec3; auto; congruence._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH1:X.eq y x1H:InT y s2~ InT x1 s2setoid_replace x1 with y; auto. Qed._x:I.tl1:treex1:X.tr1, s2:treeB2:Ok s2H0:(split x1 s2)#b = falseH4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1IHb1:Ok (diff l1 (split x1 s2)#l)IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)IHb2:Ok (diff r1 (split x1 s2)#r)IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)y:eltH1:X.eq y x1H:InT y s2InT x1 s2forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2intros; destruct (@diff_spec_ok s1 s2); auto. Qed.forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2s1, s2:treeH:Ok s1H0:Ok s2Ok (diff s1 s2)intros; destruct (@diff_spec_ok s1 s2); auto. Qed.s1, s2:treeH:Ok s1H0:Ok s2Ok (diff s1 s2)
forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (union s1 s2) <-> InT y s1 \/ InT y s2forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (union s1 s2) <-> InT y s1 \/ InT y s2s2:treey:eltB1:Ok LeafB2:Ok s2InT y s2 <-> InT y Leaf \/ InT y s2_x:I.tl1:treex1:X.tr1:treey:eltB1:Ok (Node _x l1 x1 r1)B2:Ok LeafInT y (Node _x l1 x1 r1) <-> InT y (Node _x l1 x1 r1) \/ InT y Leaf_x:I.tl1:treex1:X.tr1:tree_x0:I.t_x1:tree_x2:X.t_x3:treel2':t_x4:boolr2':te1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>IHt0:forall y0 : elt, Ok l1 -> Ok l2' -> InT y0 (union l1 l2') <-> InT y0 l1 \/ InT y0 l2'IHt1:forall y0 : elt, Ok r1 -> Ok r2' -> InT y0 (union r1 r2') <-> InT y0 r1 \/ InT y0 r2'y:eltB1:Ok (Node _x l1 x1 r1)B2:Ok (Node _x0 _x1 _x2 _x3)InT y (join (union l1 l2') x1 (union r1 r2')) <-> InT y (Node _x l1 x1 r1) \/ InT y (Node _x0 _x1 _x2 _x3)_x:I.tl1:treex1:X.tr1:treey:eltB1:Ok (Node _x l1 x1 r1)B2:Ok LeafInT y (Node _x l1 x1 r1) <-> InT y (Node _x l1 x1 r1) \/ InT y Leaf_x:I.tl1:treex1:X.tr1:tree_x0:I.t_x1:tree_x2:X.t_x3:treel2':t_x4:boolr2':te1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>IHt0:forall y0 : elt, Ok l1 -> Ok l2' -> InT y0 (union l1 l2') <-> InT y0 l1 \/ InT y0 l2'IHt1:forall y0 : elt, Ok r1 -> Ok r2' -> InT y0 (union r1 r2') <-> InT y0 r1 \/ InT y0 r2'y:eltB1:Ok (Node _x l1 x1 r1)B2:Ok (Node _x0 _x1 _x2 _x3)InT y (join (union l1 l2') x1 (union r1 r2')) <-> InT y (Node _x l1 x1 r1) \/ InT y (Node _x0 _x1 _x2 _x3)_x:I.tl1:treex1:X.tr1:tree_x0:I.t_x1:tree_x2:X.t_x3:treel2':t_x4:boolr2':te1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>IHt0:forall y0 : elt, Ok l1 -> Ok l2' -> InT y0 (union l1 l2') <-> InT y0 l1 \/ InT y0 l2'IHt1:forall y0 : elt, Ok r1 -> Ok r2' -> InT y0 (union r1 r2') <-> InT y0 r1 \/ InT y0 r2'y:eltB1:Ok (Node _x l1 x1 r1)B2:Ok (Node _x0 _x1 _x2 _x3)InT y (join (union l1 l2') x1 (union r1 r2')) <-> InT y (Node _x l1 x1 r1) \/ InT y (Node _x0 _x1 _x2 _x3)_x:I.tl1:treex1:X.tr1, s2:treeIHt0:forall y0 : elt, Ok l1 -> Ok (split x1 s2)#l -> InT y0 (union l1 (split x1 s2)#l) <-> InT y0 l1 \/ InT y0 (split x1 s2)#lIHt1:forall y0 : elt, Ok r1 -> Ok (split x1 s2)#r -> InT y0 (union r1 (split x1 s2)#r) <-> InT y0 r1 \/ InT y0 (split x1 s2)#ry:eltB2:Ok s2H4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1InT y (join (union l1 (split x1 s2)#l) x1 (union r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) \/ InT y s2destruct (X.compare_spec y x1); intuition_in. Qed._x:I.tl1:treex1:X.tr1, s2:treeIHt0:forall y0 : elt, Ok l1 -> Ok (split x1 s2)#l -> InT y0 (union l1 (split x1 s2)#l) <-> InT y0 l1 \/ InT y0 (split x1 s2)#lIHt1:forall y0 : elt, Ok r1 -> Ok (split x1 s2)#r -> InT y0 (union r1 (split x1 s2)#r) <-> InT y0 r1 \/ InT y0 (split x1 s2)#ry:eltB2:Ok s2H4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1X.eq y x1 \/ (InT y l1 \/ InT y s2 /\ X.lt y x1) \/ InT y r1 \/ InT y s2 /\ X.lt x1 y <-> InT y (Node _x l1 x1 r1) \/ InT y s2s1, s2:treeOk s1 -> Ok s2 -> Ok (union s1 s2)s1, s2:treeOk s1 -> Ok s2 -> Ok (union s1 s2)_x:I.tl1:treex1:X.tr1:tree_x0:I.t_x1:tree_x2:X.t_x3:treel2':t_x4:boolr2':te1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>IHt0:Ok l1 -> Ok l2' -> Ok (union l1 l2')IHt1:Ok r1 -> Ok r2' -> Ok (union r1 r2')B1:Ok (Node _x l1 x1 r1)B2:Ok (Node _x0 _x1 _x2 _x3)Ok (join (union l1 l2') x1 (union r1 r2'))_x:I.tl1:treex1:X.tr1, s2:treeIHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)B2:Ok s2H4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1Ok (join (union l1 (split x1 s2)#l) x1 (union r1 (split x1 s2)#r))_x:I.tl1:treex1:X.tr1, s2:treeIHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)B2:Ok s2H4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1lt_tree x1 (union l1 (split x1 s2)#l)_x:I.tl1:treex1:X.tr1, s2:treeIHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)B2:Ok s2H4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1gt_tree x1 (union r1 (split x1 s2)#r)intro y; rewrite union_spec, split_spec2; intuition_in. Qed._x:I.tl1:treex1:X.tr1, s2:treeIHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)B2:Ok s2H4:Ok l1H5:Ok r1H6:lt_tree x1 l1H7:gt_tree x1 r1gt_tree x1 (union r1 (split x1 s2)#r)
forall (s : tree) (x : elt) (f : X.t -> bool), Proper (X.eq ==> Logic.eq) f -> InT x (filter f s) <-> InT x s /\ f x = trueforall (s : tree) (x : elt) (f : X.t -> bool), Proper (X.eq ==> Logic.eq) f -> InT x (filter f s) <-> InT x s /\ f x = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fInT x Leaf <-> InT x Leaf /\ f x = trueh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fInT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = trueintuition_in.x:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fInT x Leaf <-> InT x Leaf /\ f x = trueh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fInT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = trueh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fHx0:f x0 = trueInT x (join (filter f l) x0 (filter f r)) <-> InT x (Node h l x0 r) /\ f x = trueh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fHx0:f x0 = falseInT x (concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = trueh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fHx0:f x0 = trueInT x (join (filter f l) x0 (filter f r)) <-> InT x (Node h l x0 r) /\ f x = truenow setoid_replace x with x0.h:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fHx0:f x0 = trueH0:X.eq x x0f x = trueh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fHx0:f x0 = falseInT x (concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = trueh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fHx0:f x0 = falseH1:f x = trueH2:X.eq x x0InT x l /\ f x = true \/ InT x r /\ f x = truecongruence. Qed.h:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = trueHr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = truex:eltf:X.t -> boolHf:Proper (X.eq ==> Logic.eq) fHx0:f x0 = falseH1:f x = trueH2:X.eq x x0H:f x = f x0InT x l /\ f x = true \/ InT x r /\ f x = trueforall (s : tree) (x : elt) (f : elt -> bool), InT x (filter f s) -> InT x sforall (s : tree) (x : elt) (f : elt -> bool), InT x (filter f s) -> InT x sx:eltf:elt -> boolInT x Leaf -> InT x Leafh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 lHr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 rx:eltf:elt -> boolInT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)trivial.x:eltf:elt -> boolInT x Leaf -> InT x Leafh:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 lHr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 rx:eltf:elt -> boolInT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)h:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 lHr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 rx:eltf:elt -> boolInT x (join (filter f l) x0 (filter f r)) -> InT x (Node h l x0 r)h:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 lHr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 rx:eltf:elt -> boolInT x (concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)rewrite join_spec; intuition_in; eauto.h:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 lHr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 rx:eltf:elt -> boolInT x (join (filter f l) x0 (filter f r)) -> InT x (Node h l x0 r)rewrite concat_spec; intuition_in; eauto. Qed.h:I.tl:treex0:X.tr:treeHl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 lHr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 rx:eltf:elt -> boolInT x (concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)s:treef:elt -> boolH:Ok sOk (filter f s)s:treef:elt -> boolH:Ok sOk (filter f s)f:elt -> boolOk (filter f Leaf)f:elt -> boolh:I.tx:X.tl, r:treeHl:bst lHr:bst rHlt:lt_tree x lHgt:gt_tree x rHfl:Ok (filter f l)Hfr:Ok (filter f r)Ok (filter f (Node h l x r))constructor.f:elt -> boolOk (filter f Leaf)f:elt -> boolh:I.tx:X.tl, r:treeHl:bst lHr:bst rHlt:lt_tree x lHgt:gt_tree x rHfl:Ok (filter f l)Hfr:Ok (filter f r)Ok (filter f (Node h l x r))f:elt -> boolh:I.tx:X.tl, r:treeHl:bst lHr:bst rHlt:lt_tree x lHgt:gt_tree x rHfl:Ok (filter f l)Hfr:Ok (filter f r)Ok (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))f:elt -> boolh:I.tx:X.tl, r:treeHl:bst lHr:bst rHlt:lt_tree x lHgt:gt_tree x rHfl:Ok (filter f l)Hfr:Ok (filter f r)H:lt_tree x (filter f l)Ok (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))destruct (f x); eauto using concat_ok, join_ok. Qed.f:elt -> boolh:I.tx:X.tl, r:treeHl:bst lHr:bst rHlt:lt_tree x lHgt:gt_tree x rHfl:Ok (filter f l)Hfr:Ok (filter f r)H:lt_tree x (filter f l)H0:gt_tree x (filter f r)Ok (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))
s:tf:elt -> bool(partition f s)#1 = filter f ss:tf:elt -> bool(partition f s)#1 = filter f sf:elt -> boolLeaf = Leafh:I.tl:treex:X.tr:treef:elt -> boolHl:(partition f l)#1 = filter f lHr:(partition f r)#1 = filter f r(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#1 = (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))trivial.f:elt -> boolLeaf = Leafh:I.tl:treex:X.tr:treef:elt -> boolHl:(partition f l)#1 = filter f lHr:(partition f r)#1 = filter f r(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#1 = (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))now destruct (partition f l), (partition f r), (f x). Qed.h:I.tl:treex:X.tr:treef:elt -> boolHl:(partition f l)#1 = filter f lHr:(partition f r)#1 = filter f r(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#1 = (if f x then join (partition f l)#1 x (partition f r)#1 else concat (partition f l)#1 (partition f r)#1)s:tf:elt -> bool(partition f s)#2 = filter (fun x : elt => negb (f x)) ss:tf:elt -> bool(partition f s)#2 = filter (fun x : elt => negb (f x)) sf:elt -> boolLeaf = Leafh:I.tl:treex:X.tr:treef:elt -> boolHl:(partition f l)#2 = filter (fun x0 : elt => negb (f x0)) lHr:(partition f r)#2 = filter (fun x0 : elt => negb (f x0)) r(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#2 = (if negb (f x) then join (filter (fun x0 : elt => negb (f x0)) l) x (filter (fun x0 : elt => negb (f x0)) r) else concat (filter (fun x0 : elt => negb (f x0)) l) (filter (fun x0 : elt => negb (f x0)) r))trivial.f:elt -> boolLeaf = Leafh:I.tl:treex:X.tr:treef:elt -> boolHl:(partition f l)#2 = filter (fun x0 : elt => negb (f x0)) lHr:(partition f r)#2 = filter (fun x0 : elt => negb (f x0)) r(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#2 = (if negb (f x) then join (filter (fun x0 : elt => negb (f x0)) l) x (filter (fun x0 : elt => negb (f x0)) r) else concat (filter (fun x0 : elt => negb (f x0)) l) (filter (fun x0 : elt => negb (f x0)) r))now destruct (partition f l), (partition f r), (f x). Qed.h:I.tl:treex:X.tr:treef:elt -> boolHl:(partition f l)#2 = filter (fun x0 : elt => negb (f x0)) lHr:(partition f r)#2 = filter (fun x0 : elt => negb (f x0)) r(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#2 = (if negb (f x) then join (partition f l)#2 x (partition f r)#2 else concat (partition f l)#2 (partition f r)#2)s:tf:X.t -> boolProper (X.eq ==> Logic.eq) f -> Equal (partition f s)#1 (filter f s)now rewrite partition_spec1'. Qed.s:tf:X.t -> boolProper (X.eq ==> Logic.eq) f -> Equal (partition f s)#1 (filter f s)s:tf:X.t -> boolProper (X.eq ==> Logic.eq) f -> Equal (partition f s)#2 (filter (fun x : elt => negb (f x)) s)now rewrite partition_spec2'. Qed.s:tf:X.t -> boolProper (X.eq ==> Logic.eq) f -> Equal (partition f s)#2 (filter (fun x : elt => negb (f x)) s)s:treef:elt -> boolH:Ok sOk (partition f s)#1rewrite partition_spec1'; now apply filter_ok. Qed.s:treef:elt -> boolH:Ok sOk (partition f s)#1s:treef:elt -> boolH:Ok sOk (partition f s)#2rewrite partition_spec2'; now apply filter_ok. Qed. End MakeRaw.s:treef:elt -> boolH:Ok sOk (partition f s)#2
Encapsulation
Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X. Module Raw := MakeRaw I X. Include Raw2Sets X Raw. End IntMake. (* For concrete use inside Coq, we propose an instantiation of [Int] by [Z]. *) Module Make (X: OrderedType) <: S with Module E := X :=IntMake(Z_as_Int)(X).