| 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))}.
Filter
let 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)) }.
Partition
let 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.