Red-black trees #
Note: users are recommended to use Std.TreeMap
instead of Batteries.RBMap
.
Std.TreeMap
is a mostly drop-in replacement (notably, there is no ToStream
instance yet),
and has more complete and consistent API. This implementation will eventually be deprecated.
This module implements a type RBMap α β cmp
which is a functional data structure for
storing a key-value store in a binary search tree.
It is built on the simpler RBSet α cmp
type, which stores a set of values of type α
using the function cmp : α → α → Ordering
for determining the ordering relation.
The tree will never store two elements that compare .eq
under the cmp
function,
but the function does not have to satisfy cmp x y = .eq → x = y
, and in the map case
α
is a key-value pair and the cmp
function only compares the keys.
In a red-black tree, every node has a color which is either "red" or "black" (this particular choice of colors is conventional). A nil node is considered black.
- red : RBColor
A red node is required to have black children.
- black : RBColor
Every path from the root to a leaf must pass through the same number of black nodes.
Instances For
A red-black tree. (This is an internal implementation detail of the RBSet
type,
which includes the invariants of the tree.) This is a binary search tree augmented with
a "color" field which is either red or black for each node and used to implement
the re-balancing operations.
See: Red–black tree
- nil
{α : Type u}
: RBNode α
An empty tree.
- node {α : Type u} (c : RBColor) (l : RBNode α) (v : α) (r : RBNode α) : RBNode α
Instances For
Equations
The minimum element of a tree is the left-most value.
Equations
Instances For
The maximum element of a tree is the right-most value.
Equations
Instances For
Fold a function on the values from left to right (in increasing order).
Equations
Instances For
Fold a function on the values from right to left (in decreasing order).
Equations
Instances For
O(n)
. Convert the tree to a list in ascending order.
Equations
Instances For
An auxiliary data structure (an iterator) over an RBNode
which lazily
pulls elements from the left.
- nil
{α : Type u_1}
: RBNode.Stream α
The stream is empty.
- cons
{α : Type u_1}
(v : α)
(r : RBNode α)
(tail : RBNode.Stream α)
: RBNode.Stream α
We are ready to deliver element
v
with right childr
, and wheretail
represents all the subtrees we have yet to destructure.
Instances For
O(log n)
. Turn a node into a stream, by descending along the left spine.
Equations
Instances For
O(1)
amortized, O(log n)
worst case: Get the next element from the stream.
Equations
Instances For
Fold a function on the values from left to right (in increasing order).
Equations
Instances For
Fold a function on the values from right to left (in decreasing order).
Equations
Instances For
O(n)
. Convert the stream to a list in ascending order.
Equations
Instances For
Equations
Equations
Equations
Equations
True if x
is an element of t
"exactly", i.e. up to equality, not the cmp
relation.
Equations
Instances For
Equations
Instances For
We say that x < y
under the comparator cmp
if cmp x y = .lt
.
- In order to avoid assuming the comparator is always lawful, we use a
local
∀ [Std.TransCmp cmp]
binder in the relation so that the ordering properties of the tree only need to hold if the comparator is lawful. - The
Nonempty
wrapper is a no-op because this is already a proposition, but it prevents the[Std.TransCmp cmp]
binder from being introduced when we don't want it.
Equations
Instances For
Equations
Equations
O(n)
. Reverses the ordering of the tree without any rebalancing.
Equations
Instances For
The core of the insert
function. This adds an element x
to a balanced red-black tree.
Importantly, the result of calling ins
is not a proper red-black tree,
because it has a broken balance invariant.
(See Balanced.ins
for the balance invariant of ins
.)
The insert
function does the final fixup needed to restore the invariant.
Equations
Instances For
insert cmp t v
inserts element v
into the tree, using the provided comparator
cmp
to put it in the right place and automatically rebalancing the tree as necessary.
Equations
Instances For
The number of nodes in the tree.
Equations
Instances For
erase #
The erase cut t
function removes an element from the tree t
.
The cut
function is used to locate an element in the tree:
it returns .gt
if we go too high and .lt
if we go too low;
if it returns .eq
we will remove the element.
(The function cmp k
for some key k
is a valid cut function, but we can also use cuts that
are not of this form as long as they are suitably monotonic.)
Equations
Instances For
upperBound? cut
retrieves the smallest entry larger than or equal to cut
, if it exists.
Equations
Instances For
lowerBound? cut
retrieves the largest entry smaller than or equal to cut
, if it exists.
Equations
Instances For
Returns the root of the tree, if any.
Equations
Instances For
Converts the tree into an array in increasing sorted order.
Equations
Instances For
A RBNode.Path α
is a "cursor" into an RBNode
which represents the path
from the root to a subtree. Note that the path goes from the target subtree
up to the root, which is reversed from the normal way data is stored in the tree.
See Zipper for more information.
- root
{α : Type u}
: Path α
The root of the tree, which is the end of the path of parents.
- left
{α : Type u}
(c : RBColor)
(parent : Path α)
(v : α)
(r : RBNode α)
: Path α
A path that goes down the left subtree.
- right
{α : Type u}
(c : RBColor)
(l : RBNode α)
(v : α)
(parent : Path α)
: Path α
A path that goes down the right subtree.
Instances For
Like find?
, but instead of just returning the element, it returns the entire subtree
at the element and a path back to the root for reconstructing the tree.
Equations
Instances For
This function does the second part of RBNode.ins
,
which unwinds the stack and rebuilds the tree.
Equations
Instances For
path.del t c
does the second part of RBNode.del
, which unwinds the stack
and rebuilds the tree. The c
argument is the color of the node before the deletion
(we used t₀.isBlack
for this in RBNode.del
but the original tree is no longer
available in this formulation).
Equations
Instances For
modify cut f t
uses cut
to find an element,
then modifies the element using f
and reinserts it into the tree.
Because the tree structure is not modified,
f
must not modify the ordering properties of the element.
The element in t
is used linearly if t
is unshared.
Equations
Instances For
alter cut f t
simultaneously handles inserting, erasing and replacing an element
using a function f : Option α → Option α
. It is passed the result of t.find? cut
and can either return none
to remove the element or some a
to replace/insert
the element with a
(which must have the same ordering properties as the original element).
The element is used linearly if t
is unshared.
Equations
Instances For
The ordering invariant of a red-black tree, which is a binary search tree.
This says that every element of a left subtree is less than the root, and
every element in the right subtree is greater than the root, where the
less than relation x < y
is understood to mean cmp x y = .lt
.
Because we do not assume that cmp
is lawful when stating this property,
we write it in such a way that if cmp
is not lawful then the condition holds trivially.
That way we can prove the ordering invariants without assuming cmp
is lawful.
Equations
Instances For
Equations
Instances For
The red-black balance invariant. Balanced t c n
says that the color of the root node is c
,
and the black-height (the number of black nodes on any path from the root) of the tree is n
.
Additionally, every red node must have black children.
- nil
{α : Type u_1}
: nil.Balanced RBColor.black 0
A nil node is balanced with black-height 0, and it is considered black.
- red
{α : Type u_1}
{x : RBNode α}
{n : Nat}
{y : RBNode α}
{v : α}
: x.Balanced RBColor.black n → y.Balanced RBColor.black n → (node RBColor.red x v y).Balanced RBColor.red n
A red node is balanced with black-height
n
if its children are both black with with black-heightn
. - black
{α : Type u_1}
{x : RBNode α}
{c₁ : RBColor}
{n : Nat}
{y : RBNode α}
{c₂ : RBColor}
{v : α}
: x.Balanced c₁ n → y.Balanced c₂ n → (node RBColor.black x v y).Balanced RBColor.black (n + 1)
A black node is balanced with black-height
n + 1
if its children both have black-heightn
.
Instances For
The well-formedness invariant for a red-black tree. The first constructor is the real invariant,
and the others allow us to "cheat" in this file and define insert
and erase
,
which have more complex proofs that are delayed to Batteries.Data.RBMap.Lemmas
.
- mk
{α : Type u_1}
{cmp : α → α → Ordering}
{t : RBNode α}
{c : RBColor}
{n : Nat}
: Ordered cmp t → t.Balanced c n → WF cmp t
The actual well-formedness invariant: a red-black tree has the ordering and balance invariants.
- insert {α : Type u_1} {cmp : α → α → Ordering} {t : RBNode α} {a : α} : WF cmp t → WF cmp (RBNode.insert cmp t a)
- erase {α : Type u_1} {cmp : α → α → Ordering} {t : RBNode α} {cut : α → Ordering} : WF cmp t → WF cmp (RBNode.erase cut t)
Instances For
An RBSet
is a self-balancing binary search tree.
The cmp
function is the comparator that will be used for performing searches;
it should satisfy the requirements of TransCmp
for it to have sensible behavior.
Equations
Instances For
O(1)
. Construct a new empty tree.
Equations
Instances For
O(1)
. Construct a new empty tree.
Equations
Instances For
Equations
O(1)
. Construct a new tree with one element v
.
Equations
Instances For
Equations
O(log n)
. Remove an element from the tree using a cut function.
The cut
function is used to locate an element in the tree:
it returns .gt
if we go too high and .lt
if we go too low;
if it returns .eq
we will remove the element.
(The function cmp k
for some key k
is a valid cut function, but we can also use cuts that
are not of this form as long as they are suitably monotonic.)
Equations
Instances For
O(log n)
. upperBoundP cut
retrieves the smallest entry comparing gt
or eq
under cut
,
if it exists. If multiple keys in the map return eq
under cut
, any of them may be returned.
Equations
Instances For
O(log n)
. upperBound? k
retrieves the largest entry smaller than or equal to k
,
if it exists.
Equations
Instances For
O(log n)
. lowerBoundP cut
retrieves the largest entry comparing lt
or eq
under cut
,
if it exists. If multiple keys in the map return eq
under cut
, any of them may be returned.
Equations
Instances For
O(log n)
. lowerBound? k
retrieves the largest entry smaller than or equal to k
,
if it exists.
Equations
Instances For
Asserts that t₁
and t₂
have the same number of elements in the same order,
and R
holds pairwise between them. The tree structure is ignored.
Equations
Instances For
Equations
Equations
Instances For
O(log n)
. In-place replace an element found by cut
.
This takes the element out of the tree while f
runs,
so it uses the element linearly if t
is unshared.
The ModifyWF
assumption is required because f
may change
the ordering properties of the element, which would break the invariants.
Equations
Instances For
O(log n)
. alterP cut f t
simultaneously handles inserting, erasing and replacing an element
using a function f : Option α → Option α
. It is passed the result of t.findP? cut
and can either return none
to remove the element or some a
to replace/insert
the element with a
(which must have the same ordering properties as the original element).
The element is used linearly if t
is unshared.
The AlterWF
assumption is required because f
may change
the ordering properties of the element, which would break the invariants.
Equations
Instances For
O(n₁ * log (n₁ + n₂))
. Intersects the maps t₁
and t₂
using mergeFn a b
to produce the new value.
Equations
Instances For
O(n * log n)
. Map a function on every value in the set.
If the function is monotone, consider using the more efficient RBSet.mapMonotone
instead.
Equations
Instances For
An RBMap
is a self-balancing binary search tree, used to store a key-value map.
The cmp
function is the comparator that will be used for performing searches;
it should satisfy the requirements of TransCmp
for it to have sensible behavior.
Equations
Instances For
Equations
Equations
An "iterator" over the keys of the map. This is a trivial wrapper over the underlying map,
but it comes with a small API to use it in a for
loop or convert it to an array or list.
Equations
Instances For
Equations
Equations
An "iterator" over the values of the map. This is a trivial wrapper over the underlying map,
but it comes with a small API to use it in a for
loop or convert it to an array or list.
Equations
Instances For
Equations
Equations
O(log n)
. lowerBound? k
retrieves the key-value pair of the largest key
smaller than or equal to k
, if it exists.
Equations
Instances For
Asserts that t₁
and t₂
have the same number of elements in the same order,
and R
holds pairwise between them. The tree structure is ignored.
Equations
Instances For
O(n₂ * log (n₁ + n₂))
. Merges the maps t₁
and t₂
, if a key a : α
exists in both,
then use mergeFn a b₁ b₂
to produce the new merged value.
Equations
Instances For
O(n₁ * log (n₁ + n₂))
. Intersects the maps t₁
and t₂
using mergeFn a b
to produce the new value.
Equations
Instances For
O(n log n)
. Build a tree from an unsorted list by inserting them one at a time.