This module implements sets using AVL trees. It follows the implementation from Ocaml's standard library. |
Require
FSetInterface.
Require
FSetList.
Require
ZArith.
Import
Z_scope.
Open Scope Z_scope.
Notation
"[]" := (nil ?) (at level 1).
Notation
"a :: l" := (cons a l) (at level 1, l at next level).
Set Ground Depth 3.
Module
Make [X : OrderedType] <: Sdep with Module E := X.
Module
E := X.
Module
ME := MoreOrderedType X.
Trees |
Inductive
tree : Set :=
| Leaf : tree
| Node : tree -> X.t -> tree -> Z -> tree.
The fourth field of Node is the height of the tree
|
Occurrence in a tree |
Inductive
In_tree [x:elt] : tree -> Prop :=
| IsRoot : (l,r:tree)(h:Z)(y:elt)
(X.eq x y) -> (In_tree x (Node l y r h))
| InLeft : (l,r:tree)(h:Z)(y:elt)
(In_tree x l) -> (In_tree x (Node l y r h))
| InRight : (l,r:tree)(h:Z)(y:elt)
(In_tree x r) -> (In_tree x (Node l y r h)).
Hint
In_tree := Constructors In_tree.
In_tree is compatible with X.eq
|
Lemma
eq_In_tree: (s:tree)(x,y:elt)(E.eq x y) -> (In_tree x s) -> (In_tree y s).
In_tree is height-insensitive
|
Lemma
In_height : (h,h':Z)(x,y:elt)(l,r:tree)
(In_tree y (Node l x r h)) -> (In_tree y (Node l x r h')).
Hints
Resolve In_height.
Binary search trees |
lt_tree x s : all elements in s are smaller than x
(resp. greater for gt_tree )
|
Definition
lt_tree [x:elt; s:tree] := (y:elt)(In_tree y s) -> (X.lt y x).
Definition
gt_tree [x:elt; s:tree] := (y:elt)(In_tree y s) -> (X.lt x y).
Hints
Unfold lt_tree gt_tree.
Results about lt_tree and gt_tree
|
Lemma
lt_leaf : (x:elt)(lt_tree x Leaf).
Lemma
gt_leaf : (x:elt)(gt_tree x Leaf).
Lemma
lt_tree_node : (x,y:elt)(l,r:tree)(h:Z)
(lt_tree x l) -> (lt_tree x r) -> (X.lt y x) ->
(lt_tree x (Node l y r h)).
Lemma
gt_tree_node : (x,y:elt)(l,r:tree)(h:Z)
(gt_tree x l) -> (gt_tree x r) -> (E.lt x y) ->
(gt_tree x (Node l y r h)).
Hints
Resolve lt_leaf gt_leaf lt_tree_node gt_tree_node.
Lemma
lt_node_lt : (x,y:elt)(l,r:tree)(h:Z)
(lt_tree x (Node l y r h)) -> (E.lt y x).
Lemma
gt_node_gt : (x,y:elt)(l,r:tree)(h:Z)
(gt_tree x (Node l y r h)) -> (E.lt x y).
Lemma
lt_left : (x,y:elt)(l,r:tree)(h:Z)
(lt_tree x (Node l y r h)) -> (lt_tree x l).
Lemma
lt_right : (x,y:elt)(l,r:tree)(h:Z)
(lt_tree x (Node l y r h)) -> (lt_tree x r).
Lemma
gt_left : (x,y:elt)(l,r:tree)(h:Z)
(gt_tree x (Node l y r h)) -> (gt_tree x l).
Lemma
gt_right : (x,y:elt)(l,r:tree)(h:Z)
(gt_tree x (Node l y r h)) -> (gt_tree x r).
Hints
Resolve lt_node_lt gt_node_gt
lt_left lt_right gt_left gt_right.
Lemma
lt_tree_not_in :
(x:elt)(t:tree)(lt_tree x t) -> ~(In_tree x t).
Lemma
lt_tree_trans :
(x,y:elt)(X.lt x y) -> (t:tree)(lt_tree x t) -> (lt_tree y t).
Lemma
gt_tree_not_in :
(x:elt)(t:tree)(gt_tree x t) -> ~(In_tree x t).
Lemma
gt_tree_trans :
(x,y:elt)(X.lt y x) -> (t:tree)(gt_tree x t) -> (gt_tree y t).
Hints
Resolve lt_tree_not_in lt_tree_trans
gt_tree_not_in gt_tree_trans.
bst t : t is a binary search tree
|
Inductive
bst : tree -> Prop :=
| BSLeaf :
(bst Leaf)
| BSNode : (x:elt)(l,r:tree)(h:Z)
(bst l) -> (bst r) ->
(lt_tree x l) -> (gt_tree x r) ->
(bst (Node l x r h)).
Hint
bst := Constructors bst.
Results about bst
|
Lemma
bst_left : (x:elt)(l,r:tree)(h:Z)
(bst (Node l x r h)) -> (bst l).
Lemma
bst_right : (x:elt)(l,r:tree)(h:Z)
(bst (Node l x r h)) -> (bst r).
Implicits
bst_left. Implicits
bst_right.
Hints
Resolve bst_left bst_right.
Lemma
bst_height : (h,h':Z)(x:elt)(l,r:tree)
(bst (Node l x r h)) -> (bst (Node l x r h')).
Hints
Resolve bst_height.
Key fact about binary search trees: rotations preserve the
bst property
|
Lemma
rotate_left : (x,y:elt)(a,b,c:tree)(h1,h2,h3,h4:Z)
(bst (Node a x (Node b y c h2) h1)) ->
(bst (Node (Node a x b h4) y c h3)).
Lemma
rotate_right : (x,y:elt)(a,b,c:tree)(h1,h2,h3,h4:Z)
(bst (Node (Node a x b h4) y c h3)) ->
(bst (Node a x (Node b y c h2) h1)).
Hints
Resolve rotate_left rotate_right.
AVL trees |
avl s : s is a properly balanced AVL tree,
i.e. for any node the heights of the two children
differ by at most 2
|
Definition
height : tree -> Z :=
[s:tree]Cases s of
| Leaf => 0
| (Node _ _ _ h) => h end.
Definition
max [x,y:Z] : Z :=
if (Z_lt_ge_dec x y) then [_]y else [_]x.
Instead of writing h = 1 + (max (height l) (height r)) we prefer
the following relation height_of_node l r h to ease the use of
Omega
|
Definition
height_of_node [l,r:tree; h:Z] :=
((height l) >= (height r) /\ h = (height l) + 1) \/
((height r) >= (height l) /\ h = (height r) + 1).
Inductive
avl : tree -> Prop :=
| RBLeaf :
(avl Leaf)
| RBNode : (x:elt)(l,r:tree)(h:Z)
(avl l) -> (avl r) ->
`-2 <= (height l) - (height r) <= 2` ->
(height_of_node l r h) ->
(avl (Node l x r h)).
Hint
avl := Constructors avl.
Results about avl
|
Lemma
avl_left :
(x:elt)(l,r:tree)(h:Z)
(avl (Node l x r h)) -> (avl l).
Lemma
avl_right :
(x:elt)(l,r:tree)(h:Z)
(avl (Node l x r h)) -> (avl l).
Implicits
avl_left. Implicits
avl_right.
Hints
Resolve avl_left avl_right.
Tactic
Definition
MaxCase x y :=
Unfold max; Case (Z_lt_ge_dec x y); Simpl.
Lemma
avl_node: (x:elt)(l,r:tree)
(avl l) -> (avl r) ->
`-2 <= (height l) - (height r) <= 2` ->
(avl (Node l x r ((max (height l) (height r)) + 1))).
Hints
Resolve avl_node.
The AVL tactic
|
Lemma
height_non_negative :
(s:tree)(avl s) -> (height s) >= 0.
Lemma
height_equation :
(l,r:tree)(x:elt)(h:Z)
(avl (Node l x r h)) ->
`-2 <= (height l) - (height r) <= 2` /\
(((height l) >= (height r) /\ h = (height l) + 1) \/
((height r) >= (height l) /\ h = (height r) + 1)).
Implicits
height_non_negative.
Implicits
height_equation.
If h is a proof of avl (Node l x r h) , then tactic
AVL h is adding all information about h to the context
|
Tactic
Definition
AVL h :=
(Generalize (height_non_negative h); Try Simpl);
(Try Generalize (height_equation h)); Intros.
Sets as AVL trees |
A set is implement as a record t , containing a tree,
a proof that it is a binary search tree and a proof that it is
a properly balanced AVL tree
|
Record
t_ : Set := t_intro {
the_tree :> tree;
is_bst : (bst the_tree);
is_avl : (avl the_tree) }.
Definition
t := t_.
Projections |
Lemma
t_is_bst : (s:t)(bst s).
Hints
Resolve t_is_bst.
Lemma
t_is_avl : (s:t)(avl s).
Hints
Resolve t_is_avl.
Logical appartness |
Definition
In : elt -> t -> Prop := [x:elt][s:t](In_tree x s).
Definition
Equal := [s,s'](a:elt)(In a s)<->(In a s').
Definition
Subset := [s,s'](a:elt)(In a s)->(In a s').
Definition
Add
:= [x:elt;s,s':t](y:elt)(In y s') <-> ((E.eq y x)\/(In y s)).
Definition
Empty := [s](a:elt)~(In a s).
Definition
For_all := [P:elt->Prop; s:t](x:elt)(In x s)->(P x).
Definition
Exists := [P:elt->Prop; s:t](EX x:elt | (In x s)/\(P x)).
Lemma
eq_In: (s:t)(x,y:elt)(E.eq x y) -> (In x s) -> (In y s).
Hints
Resolve eq_In.
Empty set |
Definition
empty : { s:t | (x:elt)~(In x s) }.
Emptyness test |
Definition
is_empty : (s:t){ Empty s }+{ ~(Empty s) }.
Appartness |
The mem function is deciding appartness. It exploits the bst property
to achieve logarithmic complexity.
|
Definition
mem : (x:elt) (s:t) { (In x s) } + { ~(In x s) }.
Singleton set |
Definition
singleton_tree [x:elt] := (Node Leaf x Leaf 1).
Lemma
singleton_bst : (x:elt)(bst (singleton_tree x)).
Lemma
singleton_avl : (x:elt)(avl (singleton_tree x)).
Definition
singleton : (x:elt){ s:t | (y:elt)(In y s) <-> (E.eq x y)}.
Helper functions |
create l x r creates a node, assuming l and r
to be balanced and |height l - height r| <= 2 .
|
Definition
create :
(l:tree)(x:elt)(r:tree)
(bst l) -> (avl l) -> (bst r) -> (avl r) ->
(lt_tree x l) -> (gt_tree x r) ->
`-2 <= (height l) - (height r) <= 2` ->
{ s:tree |
(bst s) /\
(avl s) /\
(height_of_node l r (height s)) /\
(y:elt)(In_tree y s) <->
((X.eq y x) \/ (In_tree y l) \/ (In_tree y 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
bal :
(l:tree)(x:elt)(r:tree)
(bst l) -> (avl l) -> (bst r) -> (avl r) ->
(lt_tree x l) -> (gt_tree x r) ->
`-3 <= (height l) - (height r) <= 3` ->
{ s:tree |
(bst s) /\ (avl s) /\
(((height_of_node l r (height s)) \/
(height_of_node l r ((height s) + 1))) /\
(`-2 <= (height l) - (height r) <= 2` ->
(height_of_node l r (height s)))) /\
(y:elt)(In_tree y s) <->
((X.eq y x) \/ (In_tree y l) \/ (In_tree y r)) }.
Insertion |
Definition
add_tree :
(x:elt)(s:tree)(bst s) -> (avl s) ->
{ s':tree | (bst s') /\ (avl s') /\
0 <= (height s')-(height s) <= 1 /\
((y:elt)(In_tree y s') <-> ((E.eq y x)\/(In_tree y s))) }.
Definition
add : (x:elt) (s:t) { s':t | (Add
x s s') }.
Definition
join :
(l:tree)(x:elt)(r:tree)
(bst l) -> (avl l) -> (bst r) -> (avl r) ->
(lt_tree x l) -> (gt_tree x r) ->
{ s:tree | (bst s) /\ (avl s) /\
((height_of_node l r (height s)) \/
(height_of_node l r ((height s)+1))) /\
((y:elt)(In_tree y s) <->
((X.eq y x) \/ (In_tree y l) \/ (In_tree y r))) }.
Extraction of minimum and maximum element |
Definition
remove_min :
(s:tree)(bst s) -> (avl s) -> ~s=Leaf ->
{ r : tree * elt |
let (s',m) = r in
(bst s') /\ (avl s') /\
((height s') = (height s) \/ (height s')=(height s)-1) /\
((y:elt)(In_tree y s') -> (E.lt m y)) /\
((y:elt)(In_tree y s) <-> (E.eq y m) \/ (In_tree y s')) }.
Definition
remove_max :
(s:tree)(bst s) -> (avl s) -> ~s=Leaf ->
{ r : tree * elt |
let (s',m) = r in
(bst s') /\ (avl s') /\
((height s') = (height s) \/ (height s')=(height s)-1) /\
((y:elt)(In_tree y s') -> (E.lt y m)) /\
((y:elt)(In_tree y s) <-> (E.eq y m) \/ (In_tree y s')) }.
Definition
merge :
(s1,s2:tree)(bst s1) -> (avl s1) -> (bst s2) -> (avl s2) ->
((y1,y2:elt)(In_tree y1 s1) -> (In_tree y2 s2) -> (X.lt y1 y2)) ->
`-2 <= (height s1) - (height s2) <= 2` ->
{ s:tree | (bst s) /\ (avl s) /\
((height_of_node s1 s2 (height s)) \/
(height_of_node s1 s2 ((height s)+1))) /\
((y:elt)(In_tree y s) <->
((In_tree y s1) \/ (In_tree y s2))) }.
Variant where we remove from the biggest subtree |
Definition
merge_bis :
(s1,s2:tree)(bst s1) -> (avl s1) -> (bst s2) -> (avl s2) ->
((y1,y2:elt)(In_tree y1 s1) -> (In_tree y2 s2) -> (X.lt y1 y2)) ->
`-2 <= (height s1) - (height s2) <= 2` ->
{ s:tree | (bst s) /\ (avl s) /\
((height_of_node s1 s2 (height s)) \/
(height_of_node s1 s2 ((height s)+1))) /\
((y:elt)(In_tree y s) <->
((In_tree y s1) \/ (In_tree y s2))) }.
Deletion |
Definition
remove_tree :
(x:elt)(s:tree)(bst s) -> (avl s) ->
{ s':tree | (bst s') /\ (avl s') /\
((height s') = (height s) \/ (height s') = (height s) - 1) /\
((y:elt)(In_tree y s') <-> (~(E.eq y x) /\ (In_tree y s))) }.
Definition
remove : (x:elt)(s:t)
{ s':t | (y:elt)(In y s') <-> (~(E.eq y x) /\ (In y s))}.
Minimum element |
Definition
min_elt :
(s:t){ x:elt | (In x s) /\ (For_all [y]~(E.lt y x) s) } + { Empty s }.
Maximum element |
Definition
max_elt :
(s:t){ x:elt | (In x s) /\ (For_all [y]~(E.lt x y) s) } + { Empty s }.
Any element |
Definition
choose : (s:t) { x:elt | (In x s)} + { Empty s }.
Definition
concat :
(s1,s2:tree)(bst s1) -> (avl s1) -> (bst s2) -> (avl s2) ->
((y1,y2:elt)(In_tree y1 s1) -> (In_tree y2 s2) -> (X.lt y1 y2)) ->
{ s:tree | (bst s) /\ (avl s) /\
((y:elt)(In_tree y s) <->
((In_tree y s1) \/ (In_tree y s2))) }.
Definition
split :
(x:elt)(s:tree)(bst s) -> (avl s) ->
{ res:tree*bool*tree |
let (l,res') = res in
let (b,r) = res' in
(bst l) /\ (avl l) /\ (bst r) /\ (avl r) /\
((y:elt)(In_tree y l) <-> ((In_tree y s) /\ (X.lt y x))) /\
((y:elt)(In_tree y r) <-> ((In_tree y s) /\ (X.lt x y))) /\
(b=true <-> (In_tree x s)) }.
Definition
inter :
(s1,s2:t)
{ s':t | (x:elt)(In x s') <-> ((In x s1)/\(In x s2))}.
Definition
diff :
(s1,s2:t)
{ s':t | (x:elt)(In x s') <-> ((In x s1) /\ ~(In x s2))}.
Elements |
elements_tree_aux acc t catenates the elements of t in infix
order to the list acc
|
Fixpoint
elements_tree_aux [acc:(list X.t); t:tree] : (list X.t) :=
Cases t of
| Leaf =>
acc
| (Node l x r _) =>
(elements_tree_aux (x :: (elements_tree_aux acc r)) l)
end.
then elements_tree is an instanciation with an empty acc
|
Definition
elements_tree := (elements_tree_aux []).
Lemma
elements_tree_aux_acc_1 :
(s:tree)(acc:(list elt))
(x:elt)(InList E.eq x acc)->(InList E.eq x (elements_tree_aux acc s)).
Hints
Resolve elements_tree_aux_acc_1.
Lemma
elements_tree_aux_1 :
(s:tree)(acc:(list elt))
(x:elt)(In_tree x s)->(InList E.eq x (elements_tree_aux acc s)).
Lemma
elements_tree_1 :
(s:tree)
(x:elt)(In_tree x s)->(InList E.eq x (elements_tree s)).
Hints
Resolve elements_tree_1.
Lemma
elements_tree_aux_acc_2 :
(s:tree)(acc:(list elt))
(x:elt)(InList E.eq x (elements_tree_aux acc s)) ->
(InList E.eq x acc) \/ (In_tree x s).
Hints
Resolve elements_tree_aux_acc_2.
Lemma
elements_tree_2 :
(s:tree)
(x:elt)(InList E.eq x (elements_tree s)) -> (In_tree x s).
Hints
Resolve elements_tree_2.
Lemma
elements_tree_aux_sort :
(s:tree)(bst s) -> (acc:(list elt))
(sort E.lt acc) ->
((x:elt)(InList E.eq x acc) -> (y:elt)(In_tree y s) -> (E.lt y x)) ->
(sort E.lt (elements_tree_aux acc s)).
Lemma
elements_tree_sort :
(s:tree)(bst s) -> (sort E.lt (elements_tree s)).
Hints
Resolve elements_tree_sort.
Definition
elements :
(s:t){ l:(list elt) | (sort E.lt l) /\ (x:elt)(In x s)<->(InList E.eq x l)}.
Cardinal |
Fixpoint
cardinal_tree [s:tree] : nat := Cases s of
| Leaf => O
| (Node l _ r _) => (S (plus (cardinal_tree l) (cardinal_tree r))) end.
Lemma
cardinal_elements_1 :
(s:tree)(acc:(list X.t))
(plus (length acc) (cardinal_tree s)) =
(length (elements_tree_aux acc s)).
Lemma
cardinal_elements_2 :
(s:tree)(cardinal_tree s)=(length (elements_tree s)).
Definition
cardinal :
(s:t) { r : nat | (EX l:(list elt) |
(Unique E.eq l) /\
((x:elt)(In x s)<->(InList E.eq x l)) /\
r = (length l)) }.
Induction over cardinals |
Lemma
sorted_subset_cardinal :
(l',l:(list X.t))(sort X.lt l) -> (sort X.lt l') ->
((x:elt)(InList X.eq x l) -> (InList X.eq x l')) ->
(le (length l) (length l')).
Lemma
cardinal_subset :
(a,b:tree)(bst a) -> (bst b) ->
((y:elt)(In_tree y a) -> (In_tree y b)) ->
(le (cardinal_tree a) (cardinal_tree b)).
Lemma
cardinal_left :
(l,r:tree)(x:elt)(h:Z)
(lt (cardinal_tree l) (cardinal_tree (Node l x r h))).
Lemma
cardinal_right :
(l,r:tree)(x:elt)(h:Z)
(lt (cardinal_tree r) (cardinal_tree (Node l x r h))).
Lemma
cardinal_rec2 :
(P:tree->tree->Set)
((x,x':tree)
((y,y':tree)(lt (plus (cardinal_tree y) (cardinal_tree y'))
(plus (cardinal_tree x) (cardinal_tree x'))) ->(P y y'))
-> (P x x')) ->
(x,x':tree)(P x x').
Lemma
height_0 : (s:tree)(avl s) -> (height s)=0 -> (x:elt)~(In_tree x s).
Implicits
height_0.
Definition
union : (s1,s2:t)
{ s':t | (x:elt)(In x s') <-> ((In x s1)\/(In x s2))}.
Filterlet filter p s = let rec filt accu = function | Empty -> accu | Node(l, v, r, _) -> filt (filt (if p v then add v accu else accu) l) r in filt Empty s
|
Definition
filter_acc :
(P:elt->Prop)(Pdec:(x:elt){P x}+{~(P x)})
(s,acc:tree)(bst s) -> (avl s) -> (bst acc) -> (avl acc) ->
{ s':tree |
(bst s') /\ (avl s') /\
((compat_P E.eq P) ->
(x:elt)(In_tree x s') <->
((In_tree x acc) \/ ((In_tree x s)/\(P x)))) }.
Definition
filter : (P:elt->Prop)(Pdec:(x:elt){P x}+{~(P x)})(s:t)
{ s':t | (compat_P E.eq P) -> (x:elt)(In x s') <-> ((In x s)/\(P x)) }.
Partitionlet partition p s = let rec part (t, f as accu) = function | Empty -> accu | Node(l, v, r, _) -> part (part (if p v then (add v t, f) else (t, add v f)) l) r in part (Empty, Empty) s
|
Definition
partition_acc :
(P:elt->Prop)(Pdec:(x:elt){P x}+{~(P x)})
(s,acct,accf:tree)
(bst s) -> (avl s) ->
(bst acct) -> (avl acct) -> (bst accf) -> (avl accf) ->
{ partition : tree*tree |
let (s1,s2) = partition in
(bst s1) /\ (avl s1) /\ (bst s2) /\ (avl s2) /\
((compat_P E.eq P) ->
(x:elt)(((In_tree x s1) <->
((In_tree x acct) \/ ((In_tree x s) /\ (P x)))) /\
(((In_tree x s2) <->
((In_tree x accf) \/ ((In_tree x s) /\ ~(P x))))))) }.
Definition
partition :
(P:elt->Prop)(Pdec:(x:elt){P x}+{~(P x)})(s:t)
{ partition : t*t |
let (s1,s2) = partition in
(compat_P E.eq P) ->
((For_all P s1) /\
(For_all ([x]~(P x)) s2) /\
(x:elt)(In x s)<->((In x s1)\/(In x s2))) }.
Definition
subset :
(s1,s2:t){ Subset s1 s2 } + { ~(Subset s1 s2) }.
for_all and exists
|
Definition
for_all : (P:elt->Prop)(Pdec:(x:elt){P x}+{~(P x)})(s:t)
{ (compat_P E.eq P) -> (For_all P s) } +
{ (compat_P E.eq P) -> ~(For_all P s) }.
Definition
exists : (P:elt->Prop)(Pdec:(x:elt){P x}+{~(P x)})(s:t)
{ (compat_P E.eq P) -> (Exists P s) } +
{ (compat_P E.eq P) -> ~(Exists P s) }.
Fold |
Fixpoint
fold_tree [A:Set; f:elt->A->A; s:tree] : A -> A :=
Cases s of
| Leaf => [a]a
| (Node l x r _) => [a](fold_tree A f l (f x (fold_tree A f r a)))
end.
Implicits
fold_tree [1].
Definition
fold_tree' :=
[A:Set; f:elt->A->A; s:tree] (L.fold f (elements_tree s)).
Implicits
fold_tree' [1].
Lemma
fold_tree_equiv_aux :
(A:Set)(s:tree)(f:elt->A->A)(a:A; acc : (list elt))
(L.fold f (elements_tree_aux acc s) a)
= (fold_tree f s (L.fold f acc a)).
Lemma
fold_tree_equiv :
(A:Set)(s:tree)(f:elt->A->A; a:A)
(fold_tree f s a)=(fold_tree' f s a).
Definition
fold :
(A:Set)(f:elt->A->A)(s:t)(i:A)
{ r : A | (EX l:(list elt) |
(Unique E.eq l) /\
((x:elt)(In x s)<->(InList E.eq x l)) /\
r = (fold_right f i l)) }.
Comparison |
Relations
|
Definition
eq : t -> t -> Prop := Equal.
Lemma
eq_sym: (s,s':t)(eq s s') -> (eq s' s).
Lemma
eq_trans: (s,s',s'':t)(eq s s') -> (eq s' s'') -> (eq s s'').
Lemma
eq_L_eq : (s,s':t)
(eq s s') -> (L.eq (elements_tree s) (elements_tree s')).
Lemma
L_eq_eq : (s,s':t)
(L.eq (elements_tree s) (elements_tree s')) -> (eq s s').
Hints
Resolve eq_L_eq L_eq_eq.
Definition
lt : t -> t -> Prop :=
[s1,s2:t](L.lt (elements_tree s1) (elements_tree s2)).
Definition
lt_trans : (s,s',s'':t)(lt s s') -> (lt s' s'') -> (lt s s'')
:= [s,s',s'':t][h][h'](L.lt_trans h h').
Lemma
lt_not_eq : (s,s':t)(lt s s') -> ~(eq s s').
Lists of trees |
flatten l returns the list of elements of l i.e. the list
of elements actually compared
|
Fixpoint
flatten [l:(list tree)] : (list elt) :=
Cases l of
| nil => []
| (cons t r) => (app (elements_tree t) (flatten r)) end.
sorted_l l expresses that elements in the trees of l are
sorted, and that all trees in l are binary search trees.
|
Inductive
In_tree_l : elt -> (list tree) -> Prop :=
| InHd : (x:elt)(s:tree)(l:(list tree))(In_tree x s) ->
(In_tree_l x (cons s l))
| InTl : (x:elt)(s:tree)(l:(list tree))(In_tree_l x l) ->
(In_tree_l x (cons s l)).
Hint
In_tree_l := Constructors In_tree_l.
Inductive
sorted_l : (list tree) -> Prop :=
| SortedLNil :
(sorted_l [])
| SortedLCons :
(s:tree)(l:(list tree))
(bst s) -> (sorted_l l) ->
((x:elt)(In_tree x s) -> (y:elt)(In_tree_l y l) -> (X.lt x y)) ->
(sorted_l (cons s l)).
Hint
sorted_l := Constructors sorted_l.
Lemma
sort_app :
(l1,l2:(list elt))(sort E.lt l1) -> (sort E.lt l2) ->
((x,y:elt)(InList E.eq x l1) -> (InList E.eq y l2) -> (X.lt x y)) ->
(sort E.lt (app l1 l2)).
Lemma
in_app :
(x:elt)(l1,l2:(list elt))
(InList E.eq x (app l1 l2)) ->
((InList E.eq x l1) \/ (InList E.eq x l2)).
Lemma
in_flatten :
(x:elt)(l:(list tree))
(InList E.eq x (flatten l)) -> (In_tree_l x l).
Lemma
sorted_flatten :
(l:(list tree))(sorted_l l) -> (sort E.lt (flatten l)).
Termination of
|
Fixpoint
measure_t [s:tree] : Z :=
Cases s of Leaf => 1
| (Node l _ r _) => 1+3*(measure_t l)+(measure_t r) end.
Fixpoint
measure_l [l:(list tree)] : Z :=
Cases l of nil => 0
| (cons s l) => (measure_t s)+(measure_l l) end.
Tactic
Definition
Measure_t := Unfold measure_t; Fold measure_t.
Tactic
Definition
Measure_l := Unfold measure_l; Fold measure_l.
Lemma
measure_t_1 : (s:tree)(measure_t s) >= 1.
Tactic
Definition
Measure_t_1 s := Generalize (measure_t_1 s); Intro.
Lemma
measure_t_3 : (l,r:tree)(x:elt)(z:Z)
(measure_t (Node l x r z)) >= 3.
Tactic
Definition
Measure_t_3 l x r z := Generalize (measure_t_3 l x r z); Intro.
Lemma
measure_l_0 : (l:(list tree))(measure_l l)>=0.
Tactic
Definition
Measure_l_0 l := Generalize (measure_l_0 l); Intro.
Induction principle over the sum of the measures for two lists |
Definition
compare_rec2 :
(P:(list tree)->(list tree)->Set)
((x,x':(list tree))
((y,y':(list tree))
(measure_l y)+(measure_l y') < (measure_l x)+(measure_l x')
->(P y y'))
-> (P x x')) ->
(x,x':(list tree))(P x x').
Lemmas for the correctness of
|
Lemma
lt_nil_elements_tree_Node :
(l,r:tree)(x:elt)(z:Z)(L.lt [] (elements_tree (Node l x r z))).
Lemma
lt_app : (l1,l2,l3:(list elt))
(L.lt l1 l2) -> (L.lt l1 (app l2 l3)).
Lemma
lt_app_eq : (l1,l2,l3:(list elt))
(L.lt l2 l3) -> (L.lt (app l1 l2) (app l1 l3)).
Lemma
lt_eq_1 : (l1,l2,l3:(list elt))
l1=l2 -> (L.lt l1 l3) -> (L.lt l2 l3).
Lemma
lt_eq_2 : (l1,l2,l3:(list elt))
l2=l3 -> (L.lt l1 l2) -> (L.lt l1 l3).
Lemma
eq_eq_1 : (l1,l2,l3:(list elt))
l1=l2 -> (L.eq l1 l3) -> (L.eq l2 l3).
Lemma
eq_eq_2 : (l1,l2,l3:(list elt))
l2=l3 -> (L.eq l1 l2) -> (L.eq l1 l3).
Lemma
l_eq_cons : (l1,l2:(list elt))(x,y:elt)
(X.eq x y) -> (L.eq l1 l2) -> (L.eq (x :: l1) (y :: l2)).
Hints
Resolve lt_nil_elements_tree_Node lt_app lt_app_eq
lt_eq_1 lt_eq_2 eq_eq_1 eq_eq_2 l_eq_cons.
Lemma
elements_app : (s:tree)(acc:(list elt))
(elements_tree_aux acc s) = (app (elements_tree s) acc).
main lemma for correctness of compare
|
Lemma
compare_flatten :
(l,r:tree)(x:elt)(z:Z)(tl:(list tree))
(flatten ((Node l x r z) :: tl))
= (flatten (l :: ((Node Leaf x r z) :: tl))).
Hints
Resolve compare_flatten.
same lemma, expressed differently |
Lemma
compare_flatten_1 :
(t0,t2:tree)(t1:elt)(z:Z)(l:(list elt))
(app (elements_tree t0) (t1 :: (app (elements_tree t2) l)))
= (app (elements_tree (Node t0 t1 t2 z)) l).
Hints
Resolve compare_flatten_1.
invariant for compare l1 l2 : Leaf may only occur on head
of l1 and l2 , and only when the other list is non-empty
|
Fixpoint
no_leaf [l:(list tree)] : Prop := Cases l of
| nil => True
| (cons Leaf _) => False
| (cons _ r) => (no_leaf r) end.
Inductive
leaf_invariant : (list tree) -> (list tree) -> Prop :=
| LI_nil_l : (l:(list tree)) (no_leaf l) -> (leaf_invariant [] l)
| LI_l_nil : (l:(list tree)) (no_leaf l) -> (leaf_invariant l [])
| LI_leaf_leaf : (l1,l2:(list tree))(no_leaf l1) -> (no_leaf l2) ->
(leaf_invariant (Leaf :: l1) (Leaf :: l2))
| LI_leaf_l : (l1,l2:(list tree))(no_leaf l1) -> (no_leaf l2) ->
~l2=[] -> (leaf_invariant (Leaf :: l1) l2)
| LI_l_leaf : (l1,l2:(list tree))(no_leaf l1) -> (no_leaf l2) ->
~l1=[] -> (leaf_invariant l1 (Leaf :: l2))
| LI_l_l : (l1,l2:(list tree))(no_leaf l1) -> (no_leaf l2) ->
~l1=[] -> ~l2=[] -> (leaf_invariant l1 l2).
Hint
leaf_invariant := Constructors leaf_invariant.
Lemma
no_leaf_invariant : (l1,l2:(list tree))
(no_leaf l1) -> (no_leaf l2) -> (leaf_invariant l1 l2).
Hints
Resolve no_leaf_invariant.
|
Definition
compare_aux :
(l1,l2:(list tree))(sorted_l l1) -> (sorted_l l2) ->
(leaf_invariant l1 l2) ->
(Compare L.lt L.eq (flatten l1) (flatten l2)).
Lemma
flatten_elements :
(s:tree)(flatten (s::[])) = (elements_tree s).
Definition
compare : (s1,s2:t)(Compare lt eq s1 s2).
Equality test |
Definition
equal : (s,s':t){ Equal s s' } + { ~(Equal s s') }.
Write State toto.
End
Make.