Path operations; modify
and alter
#
This develops the necessary theorems to construct the modify
and alter
functions on RBSet
using path operations for in-place modification of an RBTree
.
path balance #
Asserts that property p
holds on the root of the tree, if any.
Equations
- Std.RBNode.OnRoot p x = match x with | Std.RBNode.nil => True | Std.RBNode.node c l x r => p x
Instances For
Auxiliary definition for zoom_ins
: set the root of the tree to v
, creating a node if necessary.
Equations
- Std.RBNode.setRoot v x = match x with | Std.RBNode.nil => Std.RBNode.node Std.RBColor.red Std.RBNode.nil v Std.RBNode.nil | Std.RBNode.node c a v b => Std.RBNode.node c a v b
Instances For
Auxiliary definition for zoom_ins
: set the root of the tree to v
, creating a node if necessary.
Equations
- Std.RBNode.delRoot x = match x with | Std.RBNode.nil => Std.RBNode.nil | Std.RBNode.node c a v b => Std.RBNode.append a b
Instances For
Same as fill
but taking its arguments in a pair for easier composition with zoom
.
Equations
- Std.RBNode.Path.fill' x = match x with | (t, path) => Std.RBNode.Path.fill path t
Instances For
- root: ∀ {c₀ : Std.RBColor} {n₀ : Nat} {α : Type u_1}, Std.RBNode.Path.Balanced c₀ n₀ Std.RBNode.Path.root c₀ n₀
The root of the tree is
c₀, n₀
-balanced by assumption. - redL: ∀ {c₀ : Std.RBColor} {n₀ : Nat} {α : Type u_1} {y : Std.RBNode α} {n : Nat} {parent : Std.RBNode.Path α} {v : α},
Std.RBNode.Balanced y Std.RBColor.black n →
Std.RBNode.Path.Balanced c₀ n₀ parent Std.RBColor.red n →
Std.RBNode.Path.Balanced c₀ n₀ (Std.RBNode.Path.left Std.RBColor.red parent v y) Std.RBColor.black n
Descend into the left subtree of a red node.
- redR: ∀ {c₀ : Std.RBColor} {n₀ : Nat} {α : Type u_1} {x : Std.RBNode α} {n : Nat} {v : α} {parent : Std.RBNode.Path α},
Std.RBNode.Balanced x Std.RBColor.black n →
Std.RBNode.Path.Balanced c₀ n₀ parent Std.RBColor.red n →
Std.RBNode.Path.Balanced c₀ n₀ (Std.RBNode.Path.right Std.RBColor.red x v parent) Std.RBColor.black n
Descend into the right subtree of a red node.
- blackL: ∀ {c₀ : Std.RBColor} {n₀ : Nat} {α : Type u_1} {y : Std.RBNode α} {c₂ : Std.RBColor} {n : Nat}
{parent : Std.RBNode.Path α} {v : α} {c₁ : Std.RBColor},
Std.RBNode.Balanced y c₂ n →
Std.RBNode.Path.Balanced c₀ n₀ parent Std.RBColor.black (n + 1) →
Std.RBNode.Path.Balanced c₀ n₀ (Std.RBNode.Path.left Std.RBColor.black parent v y) c₁ n
Descend into the left subtree of a black node.
- blackR: ∀ {c₀ : Std.RBColor} {n₀ : Nat} {α : Type u_1} {x : Std.RBNode α} {c₁ : Std.RBColor} {n : Nat} {v : α}
{parent : Std.RBNode.Path α} {c₂ : Std.RBColor},
Std.RBNode.Balanced x c₁ n →
Std.RBNode.Path.Balanced c₀ n₀ parent Std.RBColor.black (n + 1) →
Std.RBNode.Path.Balanced c₀ n₀ (Std.RBNode.Path.right Std.RBColor.black x v parent) c₂ n
Descend into the right subtree of a black node.
The balance invariant for a path. path.Balanced c₀ n₀ c n
means that path
is a red-black tree
with balance invariant c₀, n₀
, but it has a "hole" where a tree with balance invariant c, n
has been removed. The defining property is Balanced.fill
: if path.Balanced c₀ n₀ c n
and you
fill the hole with a tree satisfying t.Balanced c n
, then (path.fill t).Balanced c₀ n₀
.
Instances For
The defining property of a balanced path: If path
is a c₀,n₀
tree with a c,n
hole,
then filling the hole with a c,n
tree yields a c₀,n₀
tree.
Asserts that p
holds on all elements to the left of the hole.
Equations
- Std.RBNode.Path.AllL p Std.RBNode.Path.root = True
- Std.RBNode.Path.AllL p (Std.RBNode.Path.left c parent v r) = Std.RBNode.Path.AllL p parent
- Std.RBNode.Path.AllL p (Std.RBNode.Path.right c a x_1 parent) = (Std.RBNode.All p a ∧ p x_1 ∧ Std.RBNode.Path.AllL p parent)
Instances For
Asserts that p
holds on all elements to the right of the hole.
Equations
- Std.RBNode.Path.AllR p Std.RBNode.Path.root = True
- Std.RBNode.Path.AllR p (Std.RBNode.Path.left c parent v r) = (Std.RBNode.Path.AllR p parent ∧ p v ∧ Std.RBNode.All p r)
- Std.RBNode.Path.AllR p (Std.RBNode.Path.right c a x_1 parent) = Std.RBNode.Path.AllR p parent
Instances For
The property of a path returned by t.zoom cut
. Each of the parents visited along the path have
the appropriate ordering relation to the cut.
Equations
- Std.RBNode.Path.Zoomed cut Std.RBNode.Path.root = True
- Std.RBNode.Path.Zoomed cut (Std.RBNode.Path.left c parent v r) = (cut v = Ordering.lt ∧ Std.RBNode.Path.Zoomed cut parent)
- Std.RBNode.Path.Zoomed cut (Std.RBNode.Path.right c a x_1 parent) = (cut x_1 = Ordering.gt ∧ Std.RBNode.Path.Zoomed cut parent)
Instances For
path.RootOrdered cmp v
is true if v
would be able to fit into the hole
without violating the ordering invariant.
Equations
- Std.RBNode.Path.RootOrdered cmp Std.RBNode.Path.root x = True
- Std.RBNode.Path.RootOrdered cmp (Std.RBNode.Path.left c parent x_2 r) x = (Std.RBNode.cmpLT cmp x x_2 ∧ Std.RBNode.Path.RootOrdered cmp parent x)
- Std.RBNode.Path.RootOrdered cmp (Std.RBNode.Path.right c l x_2 parent) x = (Std.RBNode.cmpLT cmp x_2 x ∧ Std.RBNode.Path.RootOrdered cmp parent x)
Instances For
The ordering invariant for a Path
.
Equations
- One or more equations did not get rendered due to their size.
- Std.RBNode.Path.Ordered cmp Std.RBNode.Path.root = True
Instances For
alter #
The alter
function preserves the ordering invariants.
The alter
function preserves the balance invariants.
The modify
function preserves the ordering invariants.
The modify
function preserves the balance invariants.
A sufficient condition for ModifyWF
is that the new element compares equal to the original.
O(log n)
. In-place replace the corresponding to key k
.
This takes the element out of the tree while f
runs,
so it uses the element linearly if t
is unshared.
Equations
- Std.RBMap.modify t k f = Std.RBSet.modifyP t (fun x => cmp k x.fst) fun x => match x with | (a, b) => (a, f b)
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
- Std.RBMap.alter t k f = Std.RBSet.alterP t (fun x => cmp k x.fst) (Std.RBMap.alter.adapt k f)