Fast Algorithms for Finding Nearest Common Ancestors II: Nearest Common Ancestors in a Complete Binary Tree by Symmetric-Order ArithmeticResearch Paper
Motivation
The nearest common ancestor (nca) problem asks, for a fixed rooted tree and a sequence of vertex pairs , for the deepest vertex that is an ancestor of both. It is a basic step in suffix-tree string algorithms and is equivalent to range-minimum queries (Bender, Farach-Colton, 2000). Harel and Tarjan, Fast Algorithms for Finding Nearest Common Ancestors, SIAM J. Comput. 13 (1984) 338–355, gave the first algorithm answering each query on a static tree in constant time on a random-access machine after linear preprocessing.
Their construction reduces the general problem to the case of a complete binary tree, where §3 of the paper shows that nca queries can be answered "by direct calculation" on vertex numbers: multiplication, division, powers of two, the base-two logarithm and bitwise exclusive or. The later simplification of Schieber and Vishkin (1988) is built on the same in-order numbering of a complete binary tree. This mission formalizes that arithmetic core.
Timeline, as reviewed in the paper's §1 (pp. 338–340):
- 1976: Aho, Hopcroft and Ullman (SIAM J. Comput. 5) give an -time off-line algorithm on a pointer machine, and for static trees a random-access algorithm with preprocessing and time per query.
- 1976: van Leeuwen (unpublished report) gives an -time algorithm for linking roots and static trees that runs on a pointer machine in space.
- 1980: Harel (Proc. 21st FOCS) gives a preliminary version of the paper's results.
- 1984: Harel and Tarjan prove that pointer machines need time per query on static trees (Theorem 1), and give the -preprocessing, -query random-access algorithm whose base case is the subject of this mission.
Setting
Fix and let be the complete binary tree of depth . A vertex is identified with the path from the root to it, a word of at most left or right turns; the root is the empty word and has vertices. Following the paper's Appendix (pp. 354–355):
- is an ancestor of ( a descendant of ) if the word is a prefix of the word ; every vertex is its own ancestor. and are unrelated if neither is an ancestor of the other.
- The depth of is its distance to the root; its height is the length of the longest path from a leaf to , which in is .
- is the vertex of greatest depth that is an ancestor of both: the longest common prefix.
The vertices of are numbered from to in symmetric order (in-order): at every vertex, first the left subtree, then the vertex, then the right subtree. is the number of and the vertex numbered . For (Fig. 1 of the paper) the root is , its children and , and the leaves . denotes bitwise exclusive or and the base-two logarithm.
Two procedures of §3 use only numbers, heights and :
- the nca depth algorithm: return if ; else if the same holds with exchanged; else ;
- the depth algorithm: given and a depth , with , return .
Formalization targets
Goal: the nca algorithm is correct
The algorithm to compute (p. 342) runs the nca depth algorithm to obtain and then the depth algorithm on . The goal states that it returns the nearest common ancestor: for all vertices of , with the output of the nca depth algorithm and ,
Milestones
In the order the paper uses them:
- Numbers at height (p. 341): the vertices of height are numbered from left to right.
- Lemma 1: is the largest with .
- Lemma 2: the descendants of are the vertices numbered in .
- Lemma 3: for a height , the height- ancestor of has number .
- Lemma 4: for unrelated ,
- The nca depth algorithm returns .
- The depth algorithm returns the number of the depth- ancestor of .
Two supporting statements pin the definitions to the paper: is a bijection onto , and the longest common prefix is the deepest common ancestor.
Significance
The constant-time nca computation on complete binary trees is the base case of the whole paper: §§4–5 embed an arbitrary tree into a moderately sized complete binary tree through a compressed tree and a balanced binary tree, and every query ends with the arithmetic of §3. The same idea, that in-order numbers encode ancestry in their low-order bits, underlies the Schieber–Vishkin algorithm. Lemma 1 identifies the height with the 2-adic valuation of the number, and Lemma 4 identifies the nca height with the position of the highest differing bit.
The results are proved in the paper, with the proofs left as "easy to verify". No machine-checked version of this numbering or of these four lemmas is known to exist in Mathlib or on this platform. A formal development supplies proofs of the four lemmas and the two algorithms, and a reusable library connecting in-order ranks of a complete binary tree to binary arithmetic (Nat.log, bitwise xor, 2-adic valuation).
Difficulty
The numbering is defined by a traversal order, while the lemmas speak about divisibility, floor division and exclusive or. The work lies in connecting the rank of a vertex in symmetric order to its closed form , where is its left-to-right position. That counting argument sums the sizes of the subtrees that precede and is where most of the effort goes. Lemma 4 then needs the observation that two unrelated numbers agree in all bits above the height of their nca and differ in the bit at that height. This is a statement about Nat.testBit of the exclusive or, and it fails for related vertices. The algorithm statements add a case analysis whose first two cases overlap when .
Formalization scope
- A vertex of the tree of depth is a
List Boolof length at most (false= left). Ancestry is the prefix relation, the longest common prefix, depth the length, and height . None of these structural notions uses the numbering. - is the number of vertices whose in-order sort key is lexicographically at most that of . The key is the path with left , right , followed by . The numbering is not defined by the closed form or by a recursion on numbers: a definition of that kind would make the height- numbering and Lemma 1 immediate and move the content of the mission into an uncheckable definition.
- is
Nat.log 2 x, which agrees for . is^^^on , and floor division is/on . - Interval tests are written additively as and . The subtractions and never truncate for heights and depths of vertices.
- Lemma 3 states explicitly that (" is a height") and that the ancestor exists. The depth algorithm assumes , as printed.
- is not defined as a function. The goal and the depth algorithm state that a vertex has the computed number if and only if it is the nearest common ancestor (respectively the ancestor at depth ), which says that of that number is that vertex.
- The time bounds are not formalized, since the random-access machine model is out of scope.
Proofs of any milestone are welcome.
Selected references
- D. Harel and R. E. Tarjan, Fast Algorithms for Finding Nearest Common Ancestors, SIAM J. Comput. 13(2) (1984), 338–355. https://doi.org/10.1137/0213024
- A. V. Aho, J. E. Hopcroft and J. D. Ullman, On Finding Lowest Common Ancestors in Trees, SIAM J. Comput. 5(1) (1976), 115–132. https://doi.org/10.1137/0205011
- B. Schieber and U. Vishkin, On Finding Lowest Common Ancestors: Simplification and Parallelization, SIAM J. Comput. 17(6) (1988), 1253–1262. https://doi.org/10.1137/0217079
- M. A. Bender and M. Farach-Colton, The LCA Problem Revisited, LATIN 2000, LNCS 1776, 88–94. https://doi.org/10.1007/10719839_9