AVL tree
InductiveBinary trees with cached heights#✓fully proved
For a type \(\alpha\), a tree with cached heights over \(\alpha\) (the underlying type of AVL trees) is either empty, or a node made of a natural number \(h\) (its cached height), a left subtree, a key in \(\alpha\) and a right subtree.
The type does not require \(h\) to equal the actual height of the node.
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
Used by 73
DefinitionCached height of an AVL tree#✓fully proved
The cached height of the empty tree is \(0\), and the cached height of a node is the height value stored at that node, so it is read off the root in constant time.
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
Uses 1 · Used by 30
DefinitionAVL node with computed height#✓fully proved
Write \(h(T)\) for the cached height at the root of a tree \(T\), with \(h\) of the empty tree equal to \(0\). Given trees \(L\) and \(R\) and a key \(k\), this is the node with left subtree \(L\), key \(k\) and right subtree \(R\) whose cached height is \(\max(h(L), h(R)) + 1\).
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
Uses 2 · Used by 19
DefinitionCorrect cached heights#✓fully proved
The empty tree has correct cached heights. A node storing the height \(c\), with left subtree \(\ell\) and right subtree \(r\), has correct cached heights when \(\ell\) and \(r\) have correct cached heights and \(c = \max(h(\ell), h(r)) + 1\), where \(h\) denotes the height cached at the root of a tree (and \(0\) for the empty tree).
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
Uses 2 · Used by 22
DefinitionAVL balance invariant#✓fully proved
The empty tree is balanced. A node with left subtree \(\ell\) and right subtree \(r\) is balanced when \(\ell\) and \(r\) are balanced and \(h(\ell) \le h(r) + 1\) and \(h(r) \le h(\ell) + 1\), where \(h\) denotes the height cached at the root of a tree (and \(0\) for the empty tree). Equivalently, at every node the balance factor \(h(\ell) - h(r)\) lies in \(\{-1, 0, 1\}\).
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
Uses 2 · Used by 11
DefinitionErasing the cached heights of an AVL tree#✓fully proved
Let \(\alpha\) be a type. Erasing the cached heights sends a tree with cached heights over \(\alpha\) to a binary tree over \(\alpha\): the empty tree goes to the empty binary tree, and a node with height \(h\), left subtree \(L\), key \(k\) and right subtree \(R\) goes to the binary-tree node with key \(k\) whose left and right subtrees are the erasures of \(L\) and \(R\).
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
Uses 1 · Used by 27
DefinitionMembership in an AVL tree#✓fully proved
A key \(x\) belongs to a tree \(T\) when \(x\) belongs to the binary tree obtained from \(T\) by erasing the cached heights. Equivalently, no key belongs to the empty tree, and \(x\) belongs to a node with left subtree \(L\), key \(k\) and right subtree \(R\) exactly when \(x\) belongs to \(L\), \(x = k\), or \(x\) belongs to \(R\).
public def Mem (x : α) (tree : Tree α) : Prop :=
BinarySearchTree.Mem x (toBinaryTree tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Mem {α : Type u} (x : α) : BinaryTree α → Prop
| .nil => False
| .node key left right => Mem x left ∨ x = key ∨ Mem x right
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:33
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
Uses 3 · Used by 17
DefinitionEvery key of an AVL tree satisfies a predicate#✓fully proved
For a predicate \(p\) on keys and a tree \(t\) with cached heights, \(\mathrm{All}(p, t)\) holds when \(p\) holds at the key of every node of \(t\). It is defined as the corresponding predicate on the plain binary tree obtained from \(t\) by erasing its cached heights.
public def All (p : α → Prop) (tree : Tree α) : Prop :=
BinarySearchTree.All p (toBinaryTree tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def All {α : Type u} (p : α → Prop) : BinaryTree α → Prop
| .nil => True
| .node key left right => All p left ∧ p key ∧ All p right
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:83
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
Uses 3 · Used by 9
DefinitionOrdered AVL trees#✓fully proved
Let \(\alpha\) be a type with a relation \(<\). A tree with cached heights over \(\alpha\) is ordered when the binary tree obtained by erasing its cached heights is an ordered binary search tree: the empty tree is ordered, and a node with key \(k\) is ordered when its left and right subtrees are ordered, every key of the left subtree is less than \(k\), and every key of the right subtree is greater than \(k\).
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered {α : Type u} [LT α] : BinaryTree α → Prop
| .nil => True
| .node key left right =>
Ordered left ∧ Ordered right ∧ All (· < key) left ∧ All (key < ·) right
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:88
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
Uses 3 · Used by 16
DefinitionInorder traversal of an AVL tree onto a suffix#✓fully proved
Given a tree \(t\) and a list \(s\), this is the list of keys of \(t\) in inorder (left subtree, root key, right subtree, recursively) followed by \(s\). It is computed in linear time by the binary search tree traversal of \(t\) with its cached heights erased.
public def inorderAux (tree : Tree α) (suffix : List α) : List α :=
BinarySearchTree.inorderAux (toBinaryTree tree) suffix
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def inorderAux {α : Type u} : BinaryTree α → List α → List α
| .nil, suffix => suffix
| .node key left right, suffix =>
inorderAux left (key :: inorderAux right suffix)
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:50
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
DefinitionInorder traversal of an AVL tree#✓fully proved
The inorder traversal of a tree \(t\) lists its keys with the left subtree first, then the root key, then the right subtree, recursively. It is the binary search tree inorder traversal of \(t\) with its cached heights erased, computed in linear time.
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def inorder {α : Type u} (tree : BinaryTree α) : List α :=
inorderAux tree []
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:68
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
Uses 3 · Used by 10
TheoremAVL membership is membership in the underlying binary tree#✓fully proved
A key \(x\) lies in a tree \(T\) if and only if \(x\) lies in the binary tree obtained from \(T\) by erasing the cached heights.
This holds by definition.
public theorem mem_toBinaryTree {x : α} {tree : Tree α} :
x ∈ tree ↔ x ∈ toBinaryTree tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
TheoremThe all-keys predicate is unchanged by erasing height caches#✓fully proved
For a predicate \(p\) on keys and a tree \(t\) with cached heights, \(\mathrm{All}(p, t)\) holds if and only if \(p\) holds at every key of the plain binary tree obtained from \(t\) by erasing its cached heights. This holds by definition.
public theorem all_toBinaryTree {p : α → Prop} {tree : Tree α} :
All p tree ↔ BinarySearchTree.All p (toBinaryTree tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def All (p : α → Prop) (tree : Tree α) : Prop :=
BinarySearchTree.All p (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:127
public def All {α : Type u} (p : α → Prop) : BinaryTree α → Prop
| .nil => True
| .node key left right => All p left ∧ p key ∧ All p right
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:83
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
TheoremOrder of an AVL tree via its underlying binary tree#✓fully proved
Let \(\alpha\) be a type with a relation \(<\). A tree \(t\) with cached heights over \(\alpha\) is ordered if and only if the binary tree obtained from \(t\) by erasing the cached heights is an ordered binary search tree.
public theorem ordered_toBinaryTree [LT α] {tree : Tree α} :
Ordered tree ↔ BinarySearchTree.Ordered (toBinaryTree tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def Ordered {α : Type u} [LT α] : BinaryTree α → Prop
| .nil => True
| .node key left right =>
Ordered left ∧ Ordered right ∧ All (· < key) left ∧ All (key < ·) right
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:88
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
Uses 4
TheoremAVL inorder traversal agrees with the erased binary search tree#✓fully proved
For every AVL tree \(t\), the inorder traversal of \(t\) equals the binary search tree inorder traversal of the binary tree obtained from \(t\) by erasing its cached heights; this holds by definition.
public theorem inorder_toBinaryTree (tree : Tree α) :
inorder tree = BinarySearchTree.inorder (toBinaryTree tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
public def inorder {α : Type u} (tree : BinaryTree α) : List α :=
inorderAux tree []
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:68
public def toBinaryTree : Tree α → BinaryTree α
| .empty => .nil
| .node _ left key right => .node key (toBinaryTree left) (toBinaryTree right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:86
DefinitionMembership search in an AVL tree#✓fully proved
For a linearly ordered type \(\alpha\) and a key \(x\), the search for \(x\) returns false on the empty tree; at a node with key \(k\) it searches the left subtree if \(x < k\), searches the right subtree if \(k < x\), and returns true otherwise. The cached heights are ignored.
public def contains [LinearOrder α] (x : α) : Tree α → Bool
| .empty => false
| .node _ left key right =>
if x < key then contains x left
else if key < x then contains x right
else true
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
Uses 1 · Used by 1
DefinitionAVL rebalancing#✓fully proved
For trees \(l\), \(r\) with cached heights and a key \(x\), write \(h(T)\) for the cached height at the root of a tree \(T\) (zero for the empty tree) and \(N(A, y, B)\) for the node with left subtree \(A\), key \(y\), right subtree \(B\) and cached height \(\max(h(A), h(B)) + 1\). The node \(\mathrm{balance}(l, x, r)\) is defined by cases. If \(h(l) > h(r) + 1\) and \(l\) has left subtree \(A\), key \(y\) and right subtree \(B\), it is the single right rotation \(N(A, y, N(B, x, r))\) when \(h(B) \le h(A)\), and otherwise, when \(B\) has left subtree \(B_1\), key \(z\) and right subtree \(B_2\), the left-right double rotation \(N(N(A, y, B_1), z, N(B_2, x, r))\). Symmetrically, if \(h(l) \le h(r) + 1\), \(h(r) > h(l) + 1\) and \(r\) has left subtree \(A\), key \(y\) and right subtree \(B\), it is the single left rotation \(N(N(l, x, A), y, B)\) when \(h(A) \le h(B)\), and otherwise, when \(A\) has left subtree \(A_1\), key \(z\) and right subtree \(A_2\), the right-left double rotation \(N(N(l, x, A_1), z, N(A_2, y, B))\). In every other case it is \(N(l, x, r)\).
For balanced children with correct cached heights whose heights differ by at most two, the result is balanced again.
Cslib.Algorithms.Lean.AvlTree.balance · 26 lines
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
| .empty => mkNode left key right
else if height left + 1 < height right then
match right with
| .node _ rightLeft rightKey rightRight =>
if height rightLeft ≤ height rightRight then
mkNode (mkNode left key rightLeft) rightKey rightRight
else
match rightLeft with
| .node _ rightLeftLeft rightLeftKey rightLeftRight =>
mkNode (mkNode left key rightLeftLeft) rightLeftKey
(mkNode rightLeftRight rightKey rightRight)
| .empty => mkNode left key right
| .empty => mkNode left key right
else mkNode left key right
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 3 · Used by 37
DefinitionInsertion into an AVL tree#✓fully proved
Let the keys be linearly ordered, and write \(\mathrm{balance}(L, k, R)\) for the AVL rebalancing of the node with left subtree \(L\), key \(k\) and right subtree \(R\). Inserting \(x\) into the empty tree gives the node with key \(x\), two empty children and cached height \(1\). Inserting \(x\) into a node with left subtree \(L\), key \(k\) and right subtree \(R\) gives \(\mathrm{balance}(L', k, R)\), where \(L'\) is the result of inserting \(x\) into \(L\), when \(x < k\); it gives \(\mathrm{balance}(L, k, R')\), where \(R'\) is the result of inserting \(x\) into \(R\), when \(k < x\); and otherwise it returns the node unchanged.
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 3 · Used by 8
DefinitionBuilding an AVL tree from a list#✓fully proved
For a linearly ordered type \(\alpha\), the tree built from the empty list is the empty tree, and the tree built from a list with head \(x\) and tail \(xs\) is obtained by AVL insertion of \(x\) into the tree built from \(xs\). Thus the list is inserted from right to left, starting from the empty tree.
public def fromList [LinearOrder α] : List α → Tree α
| [] => .empty
| x :: xs => insert x (fromList xs)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:224
TheoremThe all-keys predicate in terms of membership (AVL trees)#✓fully proved
For a predicate \(p\) on keys and a tree \(t\) with cached heights, \(\mathrm{All}(p, t)\) holds if and only if \(p(x)\) holds for every \(x \in t\), where \(x \in t\) means that \(x\) is the key of some node of \(t\).
public theorem all_iff_forall_mem {p : α → Prop} {tree : Tree α} :
All p tree ↔ ∀ x, x ∈ tree → p x
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def All (p : α → Prop) (tree : Tree α) : Prop :=
BinarySearchTree.All p (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:127
Uses 5 · Used by 7
TheoremMembership in the inorder traversal of an AVL tree#✓fully proved
A key \(x\) occurs in the inorder traversal of a tree \(T\) if and only if \(x\) lies in \(T\).
public theorem mem_inorder {x : α} {tree : Tree α} :
x ∈ inorder tree ↔ x ∈ tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
Uses 5 · Used by 3
TheoremThe inorder traversal of an ordered AVL tree is strictly increasing#✓fully proved
Let \(\alpha\) be a linearly ordered type. If a tree \(t\) with cached heights over \(\alpha\) is ordered, then in the inorder traversal of \(t\) every key is less than every key that comes after it.
public theorem ordered_inorder [LinearOrder α] {tree : Tree α}
(hTree : Ordered tree) : List.Pairwise (· < ·) (inorder tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
TheoremThe inorder traversal of an ordered AVL tree has no duplicates#✓fully proved
For a linearly ordered type \(\alpha\), if an AVL tree is ordered, then its inorder traversal contains no key twice.
public theorem inorder_nodup [LinearOrder α] {tree : Tree α}
(hTree : Ordered tree) : (inorder tree).Nodup
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
TheoremThe AVL node constructor preserves cached heights#✓fully proved
If two AVL trees \(\ell\) and \(r\) have correct cached heights, then for every key \(k\) the node built from \(\ell\), \(k\) and \(r\) by the smart constructor, which stores the height \(\max(h(\ell), h(r)) + 1\) where \(h\) denotes the height cached at the root (and \(0\) for the empty tree), also has correct cached heights.
public theorem cacheCorrect_mkNode {key : α} {left right : Tree α}
(hLeft : CacheCorrect left) (hRight : CacheCorrect right) :
CacheCorrect (mkNode left key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 4 · Used by 2
TheoremThe AVL node constructor preserves balance#✓fully proved
Let \(\ell\) and \(r\) be AVL trees that satisfy the AVL balance invariant, and write \(h(\ell)\) and \(h(r)\) for the heights cached at their roots (with height \(0\) for the empty tree). If \(h(\ell) \le h(r) + 1\) and \(h(r) \le h(\ell) + 1\), then for every key \(k\) the node built from \(\ell\), \(k\) and \(r\) by the smart constructor, which stores the height \(\max(h(\ell), h(r)) + 1\), satisfies the AVL balance invariant.
public theorem balanced_mkNode {key : α} {left right : Tree α}
(hLeft : Balanced left) (hRight : Balanced right)
(hLeftRight : height left ≤ height right + 1)
(hRightLeft : height right ≤ height left + 1) :
Balanced (mkNode left key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 4 · Used by 2
TheoremRebalancing when the heights of the children differ by at most one#✓fully proved
Let \(l\) and \(r\) be trees with cached heights, let \(x\) be a key, and write \(h(T)\) for the cached height at the root of a tree \(T\) (zero for the empty tree). If \(h(l) \le h(r) + 1\) and \(h(r) \le h(l) + 1\), then \(\mathrm{balance}(l, x, r)\) is the node with left subtree \(l\), key \(x\), right subtree \(r\) and cached height \(\max(h(l), h(r)) + 1\); no rotation is performed.
public theorem balance_eq_mkNode_of_le {key : α} {left right : Tree α}
(hLeft : height left ≤ height right + 1) (hRight : height right ≤ height left + 1) :
balance left key right = mkNode left key right
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 4 · Used by 9
TheoremSingle right rotation in AVL rebalancing#✓fully proved
Write \(h(T)\) for the cached height at the root of a tree \(T\) (zero for the empty tree), \(\langle c; A, y, B \rangle\) for the node with cached height \(c\), left subtree \(A\), key \(y\) and right subtree \(B\), and \(N(A, y, B)\) for the node \(\langle \max(h(A), h(B)) + 1; A, y, B \rangle\). Let \(A\), \(B\), \(R\) be trees with cached heights, let \(x\), \(y\) be keys and let \(c\) be a natural number. If \(h(R) + 1 < c\) and \(h(B) \le h(A)\), then \(\mathrm{balance}(\langle c; A, y, B \rangle, x, R) = N(A, y, N(B, x, R))\).
public theorem balance_left_single {key leftKey : α} {cached : Nat}
{leftLeft leftRight right : Tree α}
(hTall : height right + 1 < cached) (hSingle : height leftRight ≤ height leftLeft) :
balance (.node cached leftLeft leftKey leftRight) key right =
mkNode leftLeft leftKey (mkNode leftRight key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 4 · Used by 6
TheoremLeft-right double rotation in AVL rebalancing#✓fully proved
Write \(h(T)\) for the cached height at the root of a tree \(T\) (zero for the empty tree), \(\langle c; A, y, B \rangle\) for the node with cached height \(c\), left subtree \(A\), key \(y\) and right subtree \(B\), and \(N(A, y, B)\) for the node \(\langle \max(h(A), h(B)) + 1; A, y, B \rangle\). Let \(A\), \(B\), \(C\), \(R\) be trees with cached heights, let \(x\), \(y\), \(z\) be keys and let \(c\), \(c'\) be natural numbers. If \(h(R) + 1 < c\) and \(h(A) < c'\), then \(\mathrm{balance}(\langle c; A, y, \langle c'; B, z, C \rangle \rangle, x, R) = N(N(A, y, B), z, N(C, x, R))\).
public theorem balance_left_double {key leftKey leftRightKey : α}
{cached cachedRight : Nat}
{leftLeft leftRightLeft leftRightRight right : Tree α}
(hTall : height right + 1 < cached) (hDouble : height leftLeft < cachedRight) :
balance (.node cached leftLeft leftKey
(.node cachedRight leftRightLeft leftRightKey leftRightRight)) key right =
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 4 · Used by 6
TheoremSingle left rotation in AVL rebalancing#✓fully proved
Write \(h(T)\) for the cached height at the root of a tree \(T\) (zero for the empty tree), \(\langle c; A, y, B \rangle\) for the node with cached height \(c\), left subtree \(A\), key \(y\) and right subtree \(B\), and \(N(A, y, B)\) for the node \(\langle \max(h(A), h(B)) + 1; A, y, B \rangle\). Let \(L\), \(A\), \(B\) be trees with cached heights, let \(x\), \(y\) be keys and let \(c\) be a natural number. If \(h(L) + 1 < c\) and \(h(A) \le h(B)\), then \(\mathrm{balance}(L, x, \langle c; A, y, B \rangle) = N(N(L, x, A), y, B)\).
public theorem balance_right_single {key rightKey : α} {cached : Nat}
{left rightLeft rightRight : Tree α}
(hTall : height left + 1 < cached)
(hSingle : height rightLeft ≤ height rightRight) :
balance left key (.node cached rightLeft rightKey rightRight) =
mkNode (mkNode left key rightLeft) rightKey rightRight
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 4 · Used by 6
TheoremRight-left double rotation in AVL rebalancing#✓fully proved
Write \(h(T)\) for the cached height at the root of a tree \(T\) (zero for the empty tree), \(\langle c; A, y, B \rangle\) for the node with cached height \(c\), left subtree \(A\), key \(y\) and right subtree \(B\), and \(N(A, y, B)\) for the node \(\langle \max(h(A), h(B)) + 1; A, y, B \rangle\). Let \(L\), \(A\), \(B\), \(C\) be trees with cached heights, let \(x\), \(y\), \(z\) be keys and let \(c\), \(c'\) be natural numbers. If \(h(L) + 1 < c\) and \(h(C) < c'\), then \(\mathrm{balance}(L, x, \langle c; \langle c'; A, z, B \rangle, y, C \rangle) = N(N(L, x, A), z, N(B, y, C))\).
public theorem balance_right_double {key rightKey rightLeftKey : α}
{cached cachedLeft : Nat}
{left rightLeftLeft rightLeftRight rightRight : Tree α}
(hTall : height left + 1 < cached)
(hDouble : height rightRight < cachedLeft) :
balance left key (.node cached
(.node cachedLeft rightLeftLeft rightLeftKey rightLeftRight) rightKey rightRight) =
mkNode (mkNode left key rightLeftLeft) rightLeftKey
(mkNode rightLeftRight rightKey rightRight)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
public def mkNode (left : Tree α) (key : α) (right : Tree α) : Tree α :=
.node (max (height left) (height right) + 1) left key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:56
Uses 4 · Used by 6
TheoremAVL rebalancing preserves cached heights#✓fully proved
If two AVL trees \(\ell\) and \(r\) have correct cached heights, then for every key \(k\) the tree produced by the rebalancing function from \(\ell\), \(k\) and \(r\) also has correct cached heights.
public theorem cacheCorrect_balance {key : α} {left right : Tree α}
(hLeft : CacheCorrect left) (hRight : CacheCorrect right) :
CacheCorrect (balance left key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 11 · Used by 3
TheoremUpper bound on height after AVL rebalancing#✓fully proved
Let \(l\) and \(r\) be trees whose cached heights are correct at every node, and write \(h\) for the cached height. Then for every key \(k\), the rebalanced node \(b\) built from \(l\), \(k\) and \(r\) satisfies \(h(b) \le \max(h(l), h(r)) + 1\).
public theorem height_balance_le {key : α} {left right : Tree α}
(hLeft : CacheCorrect left) (hRight : CacheCorrect right) :
height (balance left key right) ≤ max (height left) (height right) + 1
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 10 · Used by 3
TheoremRebalancing does not drop below the taller child#✓fully proved
Write \(h(T)\) for the cached height at the root of a tree \(T\), with \(h\) of the empty tree equal to \(0\), and write \(\mathrm{balance}(L, k, R)\) for the AVL rebalancing of the node with left subtree \(L\), key \(k\) and right subtree \(R\). If \(L\) and \(R\) are trees whose cached heights are correct at every node, then for every key \(k\) we have \(\max(h(L), h(R)) \le h(\mathrm{balance}(L, k, R))\).
public theorem le_height_balance {key : α} {left right : Tree α}
(hLeft : CacheCorrect left) (hRight : CacheCorrect right) :
max (height left) (height right) ≤ height (balance left key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 10 · Used by 3
TheoremAVL rebalancing yields a balanced tree#✓fully proved
Let \(l\) and \(r\) be trees whose cached heights are correct at every node and which are balanced (at every node the cached heights of the two subtrees differ by at most one), let \(x\) be a key, and write \(h(T)\) for the cached height at the root of a tree \(T\) (zero for the empty tree). If \(h(l) \le h(r) + 2\) and \(h(r) \le h(l) + 2\), then \(\mathrm{balance}(l, x, r)\) is balanced.
One insertion step maintains this precondition.
public theorem balanced_balance {key : α} {left right : Tree α}
(hCacheLeft : CacheCorrect left) (hCacheRight : CacheCorrect right)
(hBalLeft : Balanced left) (hBalRight : Balanced right)
(hDiffLeft : height left ≤ height right + 2)
(hDiffRight : height right ≤ height left + 2) :
Balanced (balance left key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 12 · Used by 3
TheoremAVL rebalancing preserves the inorder traversal#✓fully proved
For all trees \(l\) and \(r\) and every key \(k\), the inorder traversal of the rebalanced node built from \(l\), \(k\) and \(r\) is the inorder traversal of \(l\), followed by \(k\), followed by the inorder traversal of \(r\).
public theorem inorder_balance {key : α} {left right : Tree α} :
inorder (balance left key right) = inorder left ++ key :: inorder right
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 13 · Used by 3
TheoremMembership after AVL rebalancing#✓fully proved
Write \(\mathrm{balance}(L, k, R)\) for the AVL rebalancing of the node with left subtree \(L\), key \(k\) and right subtree \(R\). For trees \(L\) and \(R\) and keys \(k\) and \(x\), the key \(x\) lies in \(\mathrm{balance}(L, k, R)\) if and only if \(x\) lies in \(L\), \(x = k\), or \(x\) lies in \(R\).
public theorem mem_balance {x key : α} {left right : Tree α} :
x ∈ balance left key right ↔ x ∈ left ∨ x = key ∨ x ∈ right
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 6 · Used by 7
TheoremRebalancing an AVL node preserves the search-tree order#✓fully proved
Let \(\alpha\) be a linearly ordered type, let \(k \in \alpha\), and let \(L\) and \(R\) be ordered trees with cached heights over \(\alpha\) such that every key of \(L\) is less than \(k\) and every key of \(R\) is greater than \(k\). Then the tree that rebalancing produces from left subtree \(L\), key \(k\) and right subtree \(R\) is ordered.
public theorem ordered_balance [LinearOrder α] {key : α} {left right : Tree α}
(hOrdLeft : Ordered left) (hOrdRight : Ordered right)
(hAllLeft : All (· < key) left) (hAllRight : All (key < ·) right) :
Ordered (balance left key right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def All (p : α → Prop) (tree : Tree α) : Prop :=
BinarySearchTree.All p (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:127
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 16 · Used by 3
TheoremAVL insertion preserves cached heights#✓fully proved
Let \(\alpha\) be a linearly ordered type. If an AVL tree \(t\) over \(\alpha\) has correct cached heights, then for every \(x \in \alpha\) the tree obtained by inserting \(x\) into \(t\) also has correct cached heights.
public theorem cacheCorrect_insert [LinearOrder α] {x : α} {tree : Tree α}
(hTree : CacheCorrect tree) : CacheCorrect (insert x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:224
Uses 7 · Used by 4
TheoremUpper bound on height after AVL insertion#✓fully proved
For a linearly ordered type \(\alpha\), if a tree \(t\) has correct cached heights at every node, then for every key \(x\) the cached height of the tree obtained by inserting \(x\) into \(t\) is at most the cached height of \(t\) plus one.
public theorem height_insert_le [LinearOrder α] {x : α} {tree : Tree α}
(hTree : CacheCorrect tree) : height (insert x tree) ≤ height tree + 1
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:224
Uses 7 · Used by 1
TheoremInsertion does not lower the height#✓fully proved
Write \(h(T)\) for the cached height at the root of a tree \(T\), with \(h\) of the empty tree equal to \(0\). Let the keys be linearly ordered, and let \(T\) be a tree whose cached heights are correct at every node and which satisfies the AVL balance invariant at every node. Then for every key \(x\), if \(T'\) is the tree obtained by inserting \(x\) into \(T\), we have \(h(T) \le h(T')\).
public theorem le_height_insert [LinearOrder α] {x : α} {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
height tree ≤ height (insert x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:224
Uses 10 · Used by 1
TheoremAVL insertion preserves balance#✓fully proved
Let \(\alpha\) be a linearly ordered type, let \(t\) be an AVL tree over \(\alpha\) and let \(x \in \alpha\). If \(t\) has correct cached heights and satisfies the AVL balance invariant, then the tree obtained by inserting \(x\) into \(t\) also satisfies the AVL balance invariant.
public theorem balanced_insert [LinearOrder α] {x : α} {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
Balanced (insert x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:224
Uses 11 · Used by 1
TheoremMembership after insertion into an AVL tree#✓fully proved
Let the keys be linearly ordered. A key \(y\) lies in the tree obtained by inserting \(x\) into a tree \(T\) if and only if \(y = x\) or \(y\) lies in \(T\).
public theorem mem_insert [LinearOrder α] {x y : α} {tree : Tree α} :
y ∈ insert x tree ↔ y = x ∨ y ∈ tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:224
Uses 8 · Used by 2
TheoremAVL insertion preserves the search-tree order#✓fully proved
Let \(\alpha\) be a linearly ordered type. For every key \(x \in \alpha\) and every ordered tree \(t\) with cached heights over \(\alpha\), the tree obtained by inserting \(x\) into \(t\) is ordered.
public theorem ordered_insert [LinearOrder α] {x : α} {tree : Tree α}
(hTree : Ordered tree) : Ordered (insert x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def insert [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => mkNode .empty x .empty
| tree@(.node _ left key right) =>
if x < key then balance (insert x left) key right
else if key < x then balance left key (insert x right)
else tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:224
Uses 13 · Used by 1
TheoremCorrectness of AVL search#✓fully proved
Let \(\alpha\) be a linearly ordered type and let \(t\) be an ordered AVL tree over \(\alpha\). Then for every \(x \in \alpha\), searching for \(x\) in \(t\) by following comparisons from the root returns true if and only if \(x\) is a key of \(t\).
public theorem contains_eq_true_iff [LinearOrder α] {x : α} {tree : Tree α}
(hTree : Ordered tree) : contains x tree = true ↔ x ∈ tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def contains [LinearOrder α] (x : α) : Tree α → Bool
| .empty => false
| .node _ left key right =>
if x < key then contains x left
else if key < x then contains x right
else true
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:181
TheoremAVL trees built from a list have correct cached heights#✓fully proved
For every list \(L\) over a linearly ordered type, the AVL tree built from \(L\) by successive insertion has correct cached heights.
public theorem cacheCorrect_fromList [LinearOrder α] {xs : List α} :
CacheCorrect (fromList xs)
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def fromList [LinearOrder α] : List α → Tree α
| [] => .empty
| x :: xs => insert x (fromList xs)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:232
Uses 3 · Used by 1
TheoremAVL trees built from a list are balanced#✓fully proved
For every list \(L\) over a linearly ordered type, the AVL tree built from \(L\) by successive insertion satisfies the AVL balance invariant.
public theorem balanced_fromList [LinearOrder α] {xs : List α} :
Balanced (fromList xs)
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def fromList [LinearOrder α] : List α → Tree α
| [] => .empty
| x :: xs => insert x (fromList xs)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:232
Uses 4
TheoremAVL trees built from a list are ordered#✓fully proved
Let \(\alpha\) be a linearly ordered type. For every list \(xs\) of elements of \(\alpha\), the tree obtained from the empty tree by inserting the elements of \(xs\) one at a time, from the last element to the first, is ordered.
public theorem ordered_fromList [LinearOrder α] {xs : List α} :
Ordered (fromList xs)
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def fromList [LinearOrder α] : List α → Tree α
| [] => .empty
| x :: xs => insert x (fromList xs)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:232
Uses 3
TheoremMembership in an AVL tree built from a list#✓fully proved
Let the keys be linearly ordered. A key lies in the tree obtained by inserting the entries of a list one at a time, from last to first, into the empty tree exactly when it is in the list.
public theorem mem_fromList [LinearOrder α] {x : α} {xs : List α} :
x ∈ fromList xs ↔ x ∈ xs
public def fromList [LinearOrder α] : List α → Tree α
| [] => .empty
| x :: xs => insert x (fromList xs)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:232
Uses 5
DefinitionLeftmost key of a tree#✓fully proved
Given a default value \(d\) and a binary tree \(T\) with cached heights, the leftmost key of \(T\) with default \(d\) is \(d\) when \(T\) is empty; when \(T\) has left subtree \(L\) and root key \(k\), it is the leftmost key of \(L\) with default \(k\). Thus for a nonempty tree it is the key of the node reached from the root by following left children as far as possible, and it does not depend on \(d\).
public def minD : α → Tree α → α
| default, .empty => default
| _, .node _ left key _ => minD key left
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
Uses 1 · Used by 13
DefinitionRemoving the leftmost key of an AVL tree#✓fully proved
For a tree \(t\) with cached heights, the tree obtained by removing the leftmost key of \(t\) is defined by recursion on \(t\). The empty tree stays empty. A node whose left subtree is empty is replaced by its right subtree. A node with nonempty left subtree \(l\), key \(k\) and right subtree \(r\) is replaced by \(\mathrm{balance}(l', k, r)\), where \(l'\) is \(l\) with its leftmost key removed and \(\mathrm{balance}\) is the AVL rebalancing function.
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
Uses 2 · Used by 17
DefinitionMinimum deletion in an AVL tree#✓fully proved
Minimum deletion maps a binary tree with cached heights to the tree obtained by removing its leftmost key and rebalancing on the way back up. It is the operation of removing the minimum, under the name used for the successor step of deletion, where a deleted node with two children is replaced by the minimum of its right subtree.
public def deleteMin : Tree α → Tree α :=
eraseMin
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 2 · Used by 13
DefinitionAVL tree deletion#✓fully proved
Let \(\alpha\) be a linearly ordered type and \(x \in \alpha\). Deleting \(x\) from a tree with cached heights is defined by recursion on the tree, where \(\mathrm{balance}\) denotes the AVL rebalancing function. The empty tree stays empty. For a node with left subtree \(l\), key \(k\) and right subtree \(r\): if \(x < k\), the result is \(\mathrm{balance}(l', k, r)\), where \(l'\) is \(l\) with \(x\) deleted; if \(k < x\), the result is \(\mathrm{balance}(l, k, r')\), where \(r'\) is \(r\) with \(x\) deleted; if \(x = k\), the node is replaced by \(r\) when \(l\) is empty, by \(l\) when \(r\) is empty, and otherwise by \(\mathrm{balance}(l, m, r'')\), where \(m\) is the leftmost key of \(r\) and \(r''\) is \(r\) with its leftmost key removed.
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def balance (left : Tree α) (key : α) (right : Tree α) : Tree α :=
if height right + 1 < height left then
match left with
| .node _ leftLeft leftKey leftRight =>
if height leftRight ≤ height leftLeft then
mkNode leftLeft leftKey (mkNode leftRight key right)
else
match leftRight with
| .node _ leftRightLeft leftRightKey leftRightRight =>
mkNode (mkNode leftLeft leftKey leftRightLeft) leftRightKey
(mkNode leftRightRight key right)
| .empty => mkNode left key right
⋯
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:195
public def minD : α → Tree α → α
| default, .empty => default
| _, .node _ left key _ => minD key left
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:44
public def deleteMin : Tree α → Tree α :=
eraseMin
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:57
Uses 4 · Used by 10
DefinitionAVL tree deletion under its alternative name#✓fully proved
For a linearly ordered type \(\alpha\), a key \(x \in \alpha\) and a tree \(t\) with cached heights, \(\mathrm{delete}(x, t)\) is defined to be \(\mathrm{erase}(x, t)\), the AVL deletion of \(x\) from \(t\).
public def delete [LinearOrder α] (x : α) (tree : Tree α) : Tree α :=
erase x tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
TheoremThe leftmost key lies in the tree#✓fully proved
For every nonempty binary tree \(T\) with cached heights and every default value \(d\), the leftmost key of \(T\) computed with default \(d\) occurs in \(T\).
public theorem minD_mem {default : α} {tree : Tree α} (hTree : tree ≠ .empty) :
minD default tree ∈ tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def minD : α → Tree α → α
| default, .empty => default
| _, .node _ left key _ => minD key left
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:44
Uses 5 · Used by 4
TheoremRemoving the minimum keeps cached heights correct#✓fully proved
Let \(t\) be a binary tree with a cached height at each node whose cached heights are correct: each node stores one more than the larger of the cached heights of its two subtrees, the empty tree having height \(0\). Then the cached heights of the tree obtained from \(t\) by removing its leftmost key, rebalancing on the way back up, are again correct.
public theorem cacheCorrect_eraseMin {tree : Tree α} (hTree : CacheCorrect tree) :
CacheCorrect (eraseMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 6 · Used by 8
TheoremRemoving the leftmost key does not increase the height of an AVL tree#✓fully proved
If \(t\) is a tree whose cached heights are correct, then the cached height of the tree obtained from \(t\) by removing its leftmost key is at most the cached height of \(t\).
public theorem height_eraseMin_le {tree : Tree α} (hTree : CacheCorrect tree) :
height (eraseMin tree) ≤ height tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 7 · Used by 5
TheoremRemoving the leftmost key lowers the height of an AVL tree by at most one#✓fully proved
If \(t\) is a tree whose cached heights are correct and which is balanced, then the cached height of \(t\) is at most one more than the cached height of the tree obtained from \(t\) by removing its leftmost key.
public theorem le_height_eraseMin {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
height tree ≤ height (eraseMin tree) + 1
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 11 · Used by 3
TheoremRemoving the minimum preserves AVL balance#✓fully proved
Let \(t\) be a binary tree with a cached height at each node whose cached heights are correct, and which is balanced: at every node the cached heights of the two subtrees differ by at most one. Then the tree obtained from \(t\) by removing its leftmost key, rebalancing on the way back up, is again balanced.
public theorem balanced_eraseMin {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
Balanced (eraseMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 10 · Used by 2
TheoremRemoving the leftmost key preserves search-tree order#✓fully proved
Let \(T\) be a binary tree with cached heights over a linearly ordered type. If \(T\) is ordered as a search tree, then so is the tree obtained from \(T\) by removing its leftmost key and rebalancing on the way back up.
public theorem ordered_eraseMin [LinearOrder α] {tree : Tree α}
(hTree : Ordered tree) : Ordered (eraseMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 13 · Used by 2
TheoremKeys left after removing the minimum exceed it#✓fully proved
Let \(t\) be a binary tree with keys from a linearly ordered type and a cached height at each node, and suppose \(t\) is ordered: at every node, all keys in the left subtree are strictly smaller and all keys in the right subtree are strictly larger than the key at that node. Let \(m\) be the leftmost key of \(t\), or an arbitrary default value if \(t\) is empty. Then every key of the tree obtained from \(t\) by removing its leftmost key, rebalancing on the way back up, is strictly greater than \(m\).
public theorem all_minD_lt_eraseMin_of_ordered [LinearOrder α] {default : α} {tree : Tree α}
(hTree : Ordered tree) : All (minD default tree < ·) (eraseMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def All (p : α → Prop) (tree : Tree α) : Prop :=
BinarySearchTree.All p (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:127
public def minD : α → Tree α → α
| default, .empty => default
| _, .node _ left key _ => minD key left
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:44
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 13 · Used by 1
TheoremThe inorder traversal begins with the leftmost key#✓fully proved
Let \(t\) be a nonempty tree with cached heights and \(m\) its leftmost key. Then the inorder traversal of \(t\) is \(m\) followed by the inorder traversal of the tree obtained from \(t\) by removing its leftmost key.
The leftmost key is computed by a function that takes a default value for the empty tree; the identity holds for every choice of default.
public theorem inorder_eq_minD_cons_eraseMin {default : α} {tree : Tree α}
(hTree : tree ≠ .empty) :
inorder tree = minD default tree :: inorder (eraseMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
public def minD : α → Tree α → α
| default, .empty => default
| _, .node _ left key _ => minD key left
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:44
public def eraseMin : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
match left with
| .empty => right
| .node _ _ _ _ => balance (eraseMin left) key right
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:49
Uses 9 · Used by 2
TheoremDeletion keeps cached heights correct#✓fully proved
Let \(t\) be a binary tree with keys from a linearly ordered type and a cached height at each node whose cached heights are correct: each node stores one more than the larger of the cached heights of its two subtrees, the empty tree having height \(0\). Then for every key \(x\), the cached heights of the tree obtained from \(t\) by deleting \(x\), rebalancing along the search path, are again correct.
public theorem cacheCorrect_erase [LinearOrder α] {x : α} {tree : Tree α}
(hTree : CacheCorrect tree) : CacheCorrect (erase x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 10 · Used by 4
TheoremDeletion does not increase the height of an AVL tree#✓fully proved
Let \(\alpha\) be a linearly ordered type, \(x \in \alpha\), and \(t\) a tree whose cached heights are correct. Then the cached height of the tree obtained by deleting \(x\) from \(t\) is at most the cached height of \(t\).
public theorem height_erase_le [LinearOrder α] {x : α} {tree : Tree α}
(hTree : CacheCorrect tree) : height (erase x tree) ≤ height tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 12 · Used by 2
TheoremDeletion lowers the height of an AVL tree by at most one#✓fully proved
Let \(\alpha\) be a linearly ordered type, \(x \in \alpha\), and \(t\) a balanced tree whose cached heights are correct. Then the cached height of \(t\) is at most one more than the cached height of the tree obtained by deleting \(x\) from \(t\).
public theorem le_height_erase [LinearOrder α] {x : α} {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
height tree ≤ height (erase x tree) + 1
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def height : Tree α → Nat
| .empty => 0
| .node cached _ _ _ => cached
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:51
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 17 · Used by 1
TheoremDeletion preserves AVL balance#✓fully proved
Let \(t\) be a binary tree with keys from a linearly ordered type and a cached height at each node, whose cached heights are correct, and which is balanced: at every node the cached heights of the two subtrees differ by at most one. Then for every key \(x\), the tree obtained from \(t\) by deleting \(x\), rebalancing along the search path, is again balanced.
public theorem balanced_erase [LinearOrder α] {x : α} {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
Balanced (erase x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 17 · Used by 1
TheoremAVL deletion preserves search-tree order#✓fully proved
Let \(T\) be a binary tree with cached heights over a linearly ordered type, ordered as a search tree (every key in a left subtree is smaller, and every key in a right subtree is larger, than the key at the node). Then for every key \(x\), the tree obtained by deleting \(x\) from \(T\) with rebalancing is again ordered as a search tree.
public theorem ordered_erase [LinearOrder α] {x : α} {tree : Tree α}
(hTree : Ordered tree) : Ordered (erase x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 19 · Used by 1
TheoremInorder traversal after AVL deletion#✓fully proved
Let \(\alpha\) be a linearly ordered type, \(x \in \alpha\), and \(t\) an ordered tree. Then the inorder traversal of the tree obtained by deleting \(x\) from \(t\) is the inorder traversal of \(t\) with the first occurrence of \(x\) removed; if \(x\) does not occur, the traversal is unchanged.
public theorem inorder_erase [LinearOrder α] {x : α} {tree : Tree α}
(hTree : Ordered tree) : inorder (erase x tree) = (inorder tree).erase x
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 19 · Used by 1
TheoremAVL deletion keeps every other key#✓fully proved
Let \(T\) be a binary tree with cached heights whose keys come from a linearly ordered type, and let \(x\) and \(y\) be keys with \(y \ne x\). If \(y\) occurs in \(T\), then \(y\) occurs in the tree obtained by deleting \(x\) from \(T\). No search-tree ordering of \(T\) is assumed.
public theorem mem_erase_of_mem [LinearOrder α] {x y : α} {tree : Tree α}
(hy : y ∈ tree) (hxy : y ≠ x) : y ∈ erase x tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 13 · Used by 1
TheoremDeletion removes the deleted key from an ordered AVL tree#✓fully proved
Let \(T\) be a binary tree with cached heights over a linearly ordered type, ordered as a search tree. Then for every key \(x\), \(x\) does not occur in the tree obtained by deleting \(x\) from \(T\).
public theorem not_mem_erase_self [LinearOrder α] {x : α} {tree : Tree α}
(hTree : Ordered tree) : x ∉ erase x tree
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 16 · Used by 1
TheoremKeys of an ordered AVL tree after deletion#✓fully proved
Let \(T\) be a binary tree with cached heights over a linearly ordered type, ordered as a search tree (every key in a left subtree is smaller, and every key in a right subtree is larger, than the key at the node). Then for all keys \(x\) and \(y\), \(y\) occurs in the tree obtained by deleting \(x\) from \(T\) if and only if \(y\) occurs in \(T\) and \(y \ne x\).
public theorem mem_erase [LinearOrder α] {x y : α} {tree : Tree α}
(hTree : Ordered tree) : y ∈ erase x tree ↔ y ∈ tree ∧ y ≠ x
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def erase [LinearOrder α] (x : α) : Tree α → Tree α
| .empty => .empty
| .node _ left key right =>
if x < key then balance (erase x left) key right
else if key < x then balance left key (erase x right)
else
match left, right with
| .empty, _ => right
| _, .empty => left
| _, _ => balance left (minD key right) (deleteMin right)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:65
Uses 14
TheoremDeleting a key keeps cached heights correct#✓fully proved
Let \(t\) be a binary tree with keys from a linearly ordered type and a cached height at each node whose cached heights are correct: each node stores one more than the larger of the cached heights of its two subtrees, the empty tree having height \(0\). Then for every key \(x\), the cached heights of the tree obtained from \(t\) by deleting \(x\), rebalancing along the search path, are again correct.
public theorem cacheCorrect_delete [LinearOrder α] {x : α} {tree : Tree α}
(hTree : CacheCorrect tree) : CacheCorrect (delete x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def delete [LinearOrder α] (x : α) (tree : Tree α) : Tree α :=
erase x tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:77
Uses 4
TheoremDeleting a key preserves AVL balance#✓fully proved
Let \(t\) be a binary tree with keys from a linearly ordered type and a cached height at each node, whose cached heights are correct, and which is balanced: at every node the cached heights of the two subtrees differ by at most one. Then for every key \(x\), the tree obtained from \(t\) by deleting \(x\), rebalancing along the search path, is again balanced.
public theorem balanced_delete [LinearOrder α] {x : α} {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
Balanced (delete x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def delete [LinearOrder α] (x : α) (tree : Tree α) : Tree α :=
erase x tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:77
Uses 5
TheoremDeleting a key from an ordered AVL tree keeps it ordered#✓fully proved
Let \(T\) be a binary tree with cached heights over a linearly ordered type. If \(T\) is ordered as a search tree, then for every key \(x\) the tree obtained by deleting \(x\) from \(T\) with rebalancing is again ordered as a search tree.
public theorem ordered_delete [LinearOrder α] {x : α} {tree : Tree α}
(hTree : Ordered tree) : Ordered (delete x tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def delete [LinearOrder α] (x : α) (tree : Tree α) : Tree α :=
erase x tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:77
Uses 4
TheoremInorder traversal after AVL deletion, alternative name#✓fully proved
Let \(\alpha\) be a linearly ordered type, \(x \in \alpha\), and \(t\) an ordered tree. Then the inorder traversal of \(\mathrm{delete}(x, t)\), the AVL deletion of \(x\) from \(t\) under its alternative name, is the inorder traversal of \(t\) with the first occurrence of \(x\) removed; if \(x\) does not occur, the traversal is unchanged.
public theorem inorder_delete [LinearOrder α] {x : α} {tree : Tree α}
(hTree : Ordered tree) : inorder (delete x tree) = (inorder tree).erase x
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def inorder (tree : Tree α) : List α :=
BinarySearchTree.inorder (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:142
public def delete [LinearOrder α] (x : α) (tree : Tree α) : Tree α :=
erase x tree
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:77
Uses 5
TheoremMinimum deletion keeps cached heights correct#✓fully proved
Let \(t\) be a binary tree with a cached height at each node whose cached heights are correct: each node stores one more than the larger of the cached heights of its two subtrees, the empty tree having height \(0\). Then the cached heights of the tree obtained from \(t\) by minimum deletion (removing its leftmost key, rebalancing on the way back up) are again correct.
public theorem cacheCorrect_deleteMin {tree : Tree α} (hTree : CacheCorrect tree) :
CacheCorrect (deleteMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def deleteMin : Tree α → Tree α :=
eraseMin
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:57
Uses 4
TheoremMinimum deletion preserves AVL balance#✓fully proved
Let \(t\) be a binary tree with a cached height at each node whose cached heights are correct, and which is balanced: at every node the cached heights of the two subtrees differ by at most one. Then the tree obtained from \(t\) by minimum deletion (removing its leftmost key, rebalancing on the way back up) is again balanced.
public theorem balanced_deleteMin {tree : Tree α}
(hCache : CacheCorrect tree) (hBal : Balanced tree) :
Balanced (deleteMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def CacheCorrect : Tree α → Prop
| .empty => True
| .node cached left _ right =>
CacheCorrect left ∧ CacheCorrect right ∧
cached = max (height left) (height right) + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:71
public def Balanced : Tree α → Prop
| .empty => True
| .node _ left _ right =>
Balanced left ∧ Balanced right ∧ height left ≤ height right + 1 ∧
height right ≤ height left + 1
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:79
public def deleteMin : Tree α → Tree α :=
eraseMin
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:57
Uses 5
TheoremSuccessor-step minimum removal preserves search-tree order#✓fully proved
Let \(T\) be a binary tree with cached heights over a linearly ordered type. If \(T\) is ordered as a search tree, then so is the tree obtained by the minimum-removal step used for the successor in deletion, which removes the leftmost key of \(T\) and rebalances on the way back up.
public theorem ordered_deleteMin [LinearOrder α] {tree : Tree α}
(hTree : Ordered tree) : Ordered (deleteMin tree)
public inductive Tree (α : Type u) where
| empty : Tree α
| node (height : Nat) (left : Tree α) (key : α) (right : Tree α) : Tree α
deriving DecidableEq, Repr
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:43
public def Ordered [LT α] (tree : Tree α) : Prop :=
BinarySearchTree.Ordered (toBinaryTree tree)
CSLibExt/Algorithms/Lean/DataStructures/AvlTree.lean:132
public def deleteMin : Tree α → Tree α :=
eraseMin
CSLibExt/Algorithms/Lean/DataStructures/AvlTree/Delete.lean:57
Uses 4
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.