Splay Tree
Tobias Nipkow
April 17, 2016
Abstract
Splay trees are self-adjusting binary search trees which were invented by Sleator and Tarjan [1]. This entry provides executable and
verified functional splay trees.
The amortized complexity of splay trees is analyzed in the AFP
entry Amortized Complexity.
Contents
1 Splay Tree
1.1 Function splay . .
1.2 Is-in Test . . . . .
1.3 Function insert . .
1.4 Function splay-max
1.5 Function delete . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
3
3
4
5
theory Splay-Tree
imports ∼∼ /src/HOL/Library/Tree
begin
1
Splay Tree
Splay trees were invented by Sleator and Tarjan [1].
This compensates for an incompleteness of the partial order prover:
hMLi
1.1
Function splay
function splay :: 0a::linorder ⇒ 0a tree ⇒ 0a tree where
splay a Leaf = Leaf |
splay a (Node l a r ) = Node l a r |
a<b =⇒ splay a (Node (Node la a ra) b rb) = Node la a (Node ra b rb) |
a<b =⇒ splay a (Node Leaf b r ) = Node Leaf b r |
x <a =⇒ x <b =⇒ splay x (Node (Node Leaf a ra) b rb) = Node Leaf a (Node ra
b rb) |
1
x <a =⇒ x <b =⇒ la 6= Leaf =⇒
splay x (Node (Node la a lr ) b rb) =
(case splay x la of Node lc c rc ⇒ Node lc c (Node rc a (Node lr b rb))) |
x <b =⇒ a<x =⇒ splay x (Node (Node la a Leaf ) b rb) = Node la a (Node Leaf
b rb) |
x <b =⇒ a<x =⇒ ra 6= Leaf =⇒
splay x (Node (Node la a ra) b rb) =
(case splay x ra of Node lc c rc ⇒ Node (Node la a lc) c (Node rc b rb)) |
b<a =⇒ splay a (Node lb b (Node la a ra)) = Node (Node lb b la) a ra |
a<x =⇒ splay x (Node l a Leaf ) = Node l a Leaf |
a<x =⇒ x <b =⇒ lb 6= Leaf =⇒
splay x (Node la a (Node lb b rb)) =
(case splay x lb of Node lc c rc ⇒ Node (Node la a lc) c (Node rc b rb)) |
a<x =⇒ x <b =⇒ splay x (Node la a (Node Leaf b rb)) = Node (Node la a Leaf )
b rb |
a<x =⇒ b<x =⇒ splay x (Node la a (Node lb b Leaf )) = Node (Node la a lb) b
Leaf |
a<x =⇒ b<x =⇒ rb 6= Leaf =⇒
splay x (Node la a (Node lb b rb)) =
(case splay x rb of Node lc c rc ⇒ Node (Node (Node la a lb) b lc) c rc)
hproof i
termination splay
hproof i
lemma splay-code: splay x (Node la a ra) =
(if x =a
then Node la a ra
else if x < a
then case la of
Leaf ⇒ Node la a ra |
Node lb b rb ⇒
(if x =b then Node lb x (Node rb a ra)
else if x < b
then if lb = Leaf then Node lb b (Node rb a ra)
else case splay x lb of
Node lc c rc ⇒ Node lc c (Node rc b (Node rb a ra))
else if rb = Leaf then Node lb b (Node rb a ra)
else case splay x rb of
Node lc c rc ⇒ Node (Node lb b lc) c (Node rc a ra))
else case ra of
Leaf ⇒ Node la a ra |
Node lb b rb ⇒
(if x =b then Node (Node la a lb) x rb
else if x < b
then if lb = Leaf then Node (Node la a lb) b rb
else case splay x lb of
Node lc c rc ⇒ Node (Node la a lc) c (Node rc b rb)
else if rb=Leaf then Node (Node la a lb) b rb
2
else case splay x rb of
Node lc c rc ⇒ Node (Node (Node la a lb) b lc) c rc))
hproof i
lemma splay-Leaf-iff [simp]: (splay a t = Leaf ) = (t = Leaf )
hproof i
lemma size-splay[simp]: size (splay a t) = size t
hproof i
lemma size-if-splay: splay a t = Node l u r =⇒ size t = size l + size r + 1
hproof i
lemma splay-not-Leaf : t 6= Leaf =⇒ ∃ l x r . splay a t = Node l x r
hproof i
lemma set-splay: set-tree(splay a t) = set-tree t
hproof i
lemma splay-bstL: bst t =⇒ splay a t = Node l e r =⇒ x ∈ set-tree l =⇒ x < a
hproof i
lemma splay-bstR: bst t =⇒ splay a t = Node l e r =⇒ x ∈ set-tree r =⇒ a < x
hproof i
lemma bst-splay: bst t =⇒ bst(splay a t)
hproof i
lemma splay-to-root: [[ bst t; splay a t = t 0 ]] =⇒
a ∈ set-tree t ←→ (∃ l r . t 0 = Node l a r )
hproof i
1.2
Is-in Test
To test if an element a is in t, first perform splay a t, then check if the root
is a. One could put this into one function that returns both a new tree and
the test result.
definition is-root :: 0a ⇒ 0a tree ⇒ bool where
is-root a t = (case t of Leaf ⇒ False | Node - x - ⇒ x = a)
lemma is-root-splay: bst t =⇒ is-root a (splay a t) ←→ a ∈ set-tree t
hproof i
1.3
Function insert
context
begin
qualified fun insert :: 0a::linorder ⇒ 0a tree ⇒ 0a tree where
3
insert x t = (if t = Leaf then Node Leaf x Leaf
else case splay x t of
Node l a r ⇒ if x =a then Node l a r
else if x <a then Node l x (Node Leaf a r ) else Node (Node l a Leaf ) x r )
end
lemma set-insert: set-tree(Splay-Tree.insert a t) = insert a (set-tree t)
hproof i
lemma bst-insert: bst t =⇒ bst(Splay-Tree.insert a t)
hproof i
1.4
Function splay-max
fun splay-max :: 0a::linorder tree ⇒ 0a tree where
splay-max Leaf = Leaf |
splay-max (Node la a Leaf ) = Node la a Leaf |
splay-max (Node la a (Node lb b rb)) =
(if rb = Leaf then Node (Node la a lb) b Leaf
else case splay-max rb of
Node lc c rc ⇒ Node (Node (Node la a lb) b lc) c rc)
lemma splay-max-Leaf-iff [simp]: (splay-max t = Leaf ) = (t = Leaf )
hproof i
lemma splay-max-code: splay-max t = (case t of
Leaf ⇒ t |
Node la a ra ⇒ (case ra of
Leaf ⇒ t |
Node lb b rb ⇒
(if rb=Leaf then Node (Node la a lb) b rb
else case splay-max rb of
Node lc c rc ⇒ Node (Node (Node la a lb) b lc) c rc)))
hproof i
lemma size-splay-max : size(splay-max t) = size t
hproof i
lemma size-if-splay-max : splay-max t = Node l u r =⇒ size t = size l + size r +
1
hproof i
lemma set-splay-max : set-tree(splay-max t) = set-tree t
hproof i
lemma bst-splay-max : bst t =⇒ bst (splay-max t)
hproof i
4
lemma splay-max-Leaf : splay-max t = Node l a r =⇒ r = Leaf
hproof i
For sanity purposes only:
lemma splay-max-eq-splay:
bst t =⇒ ∀ x ∈ set-tree t. x ≤ a =⇒ splay-max t = splay a t
hproof i
lemma splay-max-eq-splay-ex : assumes bst t shows ∃ a. splay-max t = splay a t
hproof i
1.5
Function delete
context
begin
qualified definition delete :: 0a::linorder ⇒ 0a tree ⇒ 0a tree where
delete x t = (if t=Leaf then Leaf
else case splay x t of Node l a r ⇒
if x =a
then if l = Leaf then r else case splay-max l of Node l 0 m r 0 ⇒ Node l 0 m r
else Node l a r )
lemma set-delete: assumes bst t
shows set-tree (delete a t) = set-tree t − {a}
hproof i
lemma bst-delete: assumes bst t shows bst (delete a t)
hproof i
end
end
References
[1] D. D. Sleator and R. E. Tarjan. Self-adjusting binary search trees. J.
ACM, 32(3):652–686, 1985.
5
© Copyright 2026 Paperzz