Cartesian tree
DefinitionMin-heap ordered binary tree#✓fully proved
Let \(\alpha\) be a type with a relation \(\le\). A binary tree with keys in \(\alpha\) is min-heap ordered when, at every node, the key \(k\) of that node satisfies \(k \le y\) for every key \(y\) in its left subtree and every key \(y\) in its right subtree. The empty tree is min-heap ordered.
public def HeapOrdered [LE α] : BinaryTree α → Prop
| .nil => True
| .node key left right =>
HeapOrdered left ∧ HeapOrdered right ∧
BinarySearchTree.All (key ≤ ·) left ∧
BinarySearchTree.All (key ≤ ·) right
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
Uses 1 · Used by 2
DefinitionOptional root key of a binary tree#✓fully proved
For a binary tree \(T\) with keys in \(\alpha\), the root key of \(T\) is an optional element of \(\alpha\): it is absent (none) when \(T\) is empty, and it is \(k\) when the top node of \(T\) holds the key \(k\).
public def root : BinaryTree α → Option α
| .nil => none
| .node key _ _ => some key
TheoremA predicate holds on every key iff it holds along the inorder traversal#✓fully proved
For every predicate \(p\) on \(\alpha\) and every binary tree \(T\) with keys in \(\alpha\), every key of \(T\) satisfies \(p\) if and only if every element of the inorder traversal of \(T\) satisfies \(p\).
public theorem all_iff_forall_inorder {p : α → Prop} {tree : BinaryTree α} :
BinarySearchTree.All p tree ↔
∀ x ∈ BinarySearchTree.inorder tree, p x
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 inorder {α : Type u} (tree : BinaryTree α) : List α :=
inorderAux tree []
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:68
TheoremThe root of a binary tree is one of its keys#✓fully proved
For every binary tree \(T\) and every key \(k\), if \(T\) is nonempty with root key \(k\), then \(k\) is a key of \(T\).
public theorem mem_of_root_eq_some {tree : BinaryTree α} {key : α}
(hRoot : root tree = some key) : key ∈ tree
public def root : BinaryTree α → Option α
| .nil => none
| .node key _ _ => some key
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:68
Uses 2 · Used by 1
TheoremThe root of a heap-ordered tree is below every key#✓fully proved
Let \(T\) be a binary tree over a preordered type that is heap-ordered (in min-heap order). If \(T\) has root key \(k\), then \(k \le x\) for every key \(x\) occurring in \(T\).
public theorem root_le_of_heapOrdered [Preorder α] {tree : BinaryTree α}
{key : α}
(hHeap : HeapOrdered tree) (hRoot : root tree = some key) :
∀ x ∈ tree, key ≤ x
public def HeapOrdered [LE α] : BinaryTree α → Prop
| .nil => True
| .node key left right =>
HeapOrdered left ∧ HeapOrdered right ∧
BinarySearchTree.All (key ≤ ·) left ∧
BinarySearchTree.All (key ≤ ·) right
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:60
public def root : BinaryTree α → Option α
| .nil => none
| .node key _ _ => some key
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:68
Split At First
DefinitionSplitting a list at the first occurrence of a value#✓fully proved
For a value \(m\) of a type with decidable equality and a list \(xs\), the split of \(xs\) at \(m\) is the pair of the part of \(xs\) before the first occurrence of \(m\) and the part after it; that occurrence itself is dropped. If \(m\) does not occur in \(xs\), the split is the pair of \(xs\) and the empty list.
Only equality on the element type is needed, not the linear order required to build Cartesian trees.
TheoremSplitting at the first occurrence leaves the value out of the left part#✓fully proved
Let \(m\) be an element of a type with decidable equality and let \(xs\) be a list in which \(m\) occurs. When \(xs\) is split at the first occurrence of \(m\), the left part does not contain \(m\).
Together with the reconstruction property (the left part, then \(m\), then the right part give back \(xs\)), this characterizes the split point, including how duplicates of \(m\) are handled when building Cartesian trees; reconstruction alone would hold for a split at any occurrence.
public theorem splitAtFirst_not_mem_fst (m : α) :
∀ (xs : List α), m ∈ xs → m ∉ (splitAtFirst m xs).1
public def splitAtFirst (m : α) : List α → List α × List α
| [] => ([], [])
| a :: as =>
if a = m then ([], as)
else
let rest := splitAtFirst m as
(a :: rest.1, rest.2)
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:125
Uses 1
Build
DefinitionMinimum of a nonempty list#✓fully proved
For an element \(a\) and a list \(as\) over a linear order, the left-fold minimum of \(a\) and \(as\) is the minimum of the list with head \(a\) and tail \(as\). It is computed from the head: it equals \(a\) when \(as\) is empty, and when \(as\) has head \(b\) and tail \(bs\) it equals the left-fold minimum of \(\min(a, b)\) and \(bs\).
DefinitionFuel-bounded Cartesian tree construction#✓fully proved
Let \(\alpha\) be a linear order. For a natural number \(n\) (the fuel) and a list \(xs\) over \(\alpha\), the tree built from \(xs\) with fuel \(n\) is the empty tree if \(n = 0\) or \(xs\) is empty. Otherwise \(n = k + 1\) and \(xs\) is nonempty; let \(m\) be the minimum of \(xs\), and let \(L\) and \(R\) be the parts of \(xs\) before and after the first occurrence of \(m\). Then the tree has root \(m\), its left subtree is built from \(L\) with fuel \(k\), and its right subtree is built from \(R\) with fuel \(k\).
Each split produces strictly shorter lists, so a fuel of at least the length of \(xs\) never runs out.
public def buildFuel : Nat → List α → BinaryTree α
| 0, _ => .nil
| _ + 1, [] => .nil
| n + 1, (a :: as) =>
let m := listMin a as
let parts := splitAtFirst m (a :: as)
.node m (buildFuel n parts.1) (buildFuel n parts.2)
public def listMin (a : α) : List α → α
| [] => a
| b :: bs => listMin (min a b) bs
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:202
public def splitAtFirst (m : α) : List α → List α × List α
| [] => ([], [])
| a :: as =>
if a = m then ([], as)
else
let rest := splitAtFirst m as
(a :: rest.1, rest.2)
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:125
DefinitionCartesian tree of a list#✓fully proved
For a list \(xs\) over a linear order, the Cartesian tree of \(xs\) is the result of the fuel-bounded Cartesian tree construction on \(xs\) with fuel equal to the length of \(xs\). So the empty list gives the empty tree, and otherwise the root is the minimum \(m\) of \(xs\), the left subtree is built in the same way from the elements before the first occurrence of \(m\), and the right subtree from the elements after that occurrence.
Its inorder traversal is \(xs\) and it is min-heap ordered.
public def build (xs : List α) : BinaryTree α :=
buildFuel xs.length xs
public def buildFuel : Nat → List α → BinaryTree α
| 0, _ => .nil
| _ + 1, [] => .nil
| n + 1, (a :: as) =>
let m := listMin a as
let parts := splitAtFirst m (a :: as)
.node m (buildFuel n parts.1) (buildFuel n parts.2)
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:244
Uses 1 · Used by 6
TheoremInorder traversal of a Cartesian tree#✓fully proved
For every list \(xs\) over a linear order, the inorder traversal of the Cartesian tree of \(xs\) is \(xs\).
public theorem inorder_build (xs : List α) :
BinarySearchTree.inorder (build xs) = xs
public def inorder {α : Type u} (tree : BinaryTree α) : List α :=
inorderAux tree []
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:68
public def build (xs : List α) : BinaryTree α :=
buildFuel xs.length xs
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:260
TheoremThe keys of a Cartesian tree permute its input#✓fully proved
For every list \(xs\) over a linear order, the inorder traversal of the Cartesian tree of \(xs\) is a permutation of \(xs\).
public theorem perm_build (xs : List α) :
(BinarySearchTree.inorder (build xs)).Perm xs
public def inorder {α : Type u} (tree : BinaryTree α) : List α :=
inorderAux tree []
CSLibExt/Algorithms/Lean/DataStructures/BinarySearchTree.lean:68
public def build (xs : List α) : BinaryTree α :=
buildFuel xs.length xs
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:260
Uses 3
TheoremKeys of a Cartesian tree#✓fully proved
For every list \(xs\) over a linear order and every element \(x\), \(x\) is a key of the Cartesian tree of \(xs\) if and only if \(x\) occurs in \(xs\).
public theorem mem_build {x : α} {xs : List α} : x ∈ build xs ↔ x ∈ xs
public def build (xs : List α) : BinaryTree α :=
buildFuel xs.length xs
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:260
Uses 5 · Used by 1
TheoremCartesian trees are heap-ordered#✓fully proved
For every list \(xs\) over a linear order, the Cartesian tree of \(xs\) is min-heap ordered.
public theorem heapOrdered_build (xs : List α) : HeapOrdered (build xs)
public def HeapOrdered [LE α] : BinaryTree α → Prop
| .nil => True
| .node key left right =>
HeapOrdered left ∧ HeapOrdered right ∧
BinarySearchTree.All (key ≤ ·) left ∧
BinarySearchTree.All (key ≤ ·) right
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:60
public def build (xs : List α) : BinaryTree α :=
buildFuel xs.length xs
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:260
Uses 9 · Used by 1
TheoremThe Cartesian tree of a nonempty list has a root#✓fully proved
For every nonempty list \(xs\) over a linearly ordered type, the Cartesian tree of \(xs\) has a root key \(m\).
public theorem root_build_cons_isSome (a : α) (as : List α) :
∃ m, root (build (a :: as)) = some m
public def root : BinaryTree α → Option α
| .nil => none
| .node key _ _ => some key
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:68
public def build (xs : List α) : BinaryTree α :=
buildFuel xs.length xs
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:260
TheoremThe root of a Cartesian tree is a minimum of the list#✓fully proved
Let \(xs\) be a list over a linearly ordered type. If the Cartesian tree of \(xs\) has root key \(m\), then \(m\) occurs in \(xs\) and \(m \le y\) for every element \(y\) of \(xs\).
public theorem root_build_min {xs : List α} {m : α}
(hRoot : root (build xs) = some m) :
m ∈ xs ∧ ∀ y ∈ xs, m ≤ y
public def root : BinaryTree α → Option α
| .nil => none
| .node key _ _ => some key
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:68
public def build (xs : List α) : BinaryTree α :=
buildFuel xs.length xs
CSLibExt/Algorithms/Lean/DataStructures/CartesianTree.lean:260
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.