nx_disctree.nx
buildroot/runtime/nx_disctree.nx
about
nx_disctree.nx -- discrimination tree term index.
Per Vampire-displacement roadmap Phase 2. THE biggest perf win
for saturation provers: replaces the O(n_processed) iteration in
forward subsumption + demodulation candidate lookup with an O(d)
trie walk where d is the term depth. Vampire's hot path goes
from O(n^2) to O(n * d * branching) per saturation step.
Standard "perfect discrimination tree" (Stickel 1989 lineage):
- Trie keyed on preorder linearization of terms.
- Each token is (sym, n_args); a STAR token marks variables.
- Edges from a node match by (sym, n_args).
- Insertion: walk the linearization, allocate edges + nodes
as needed; mark terminal node with the stored value.
- Lookup (find generalizations of Q): at each tree node, follow
EITHER the matching (sym, n_args) edge OR a STAR edge. STAR
consumes one whole subterm of Q (skip via pending-counter).
API:
nx_dt_new() -> *DiscTree
nx_dt_insert(tree, term, value) -- attach value
nx_dt_find_generalizations(tree, query, results, *n)
Bits-up nx_int. Variables in queries are not yet handled (TODO):
for v1 the caller passes ground queries. Variables in stored
terms ARE handled via the STAR edge.
dependencies 5 imports · 8 importers
imports: nx_syscalls.nxnx_runtime.nxnx_tier.nxnx_result.nxnx_unify.nx
imported by: nx_avatar_solve_test.nxnx_casc_runner_test.nxnx_disctree_test.nxnx_indexed_subsume_test.nxnx_saturation.nxnx_solve.nxnx_solve_test.nxnx_tptp_write_test.nx
structs
| 46 | struct DTToken |
| 52 | struct DTEdge |
| 60 | struct DTNode |
| 67 | struct DiscTree |
consts
| 42 | const NX_DT_STAR: nx_int = 0 |
| 43 | const NX_DT_MAX_TOKENS: nx_int = 256 |
| 44 | const NX_DT_MAX_RESULTS: nx_int = 64 |
| 50 | const NX_DT_TOKEN_BYTES: nx_int = 16 |
| 58 | const NX_DT_EDGE_BYTES: nx_int = 32 |
| 65 | const NX_DT_NODE_BYTES: nx_int = 24 |
| 70 | const NX_DT_BYTES: nx_int = 8 |
functions
| 73 | func nx_dt_node_new() -> *DTNode |
| 81 | func nx_dt_new() -> *DiscTree |
| 88 | func nx_dt_node_descend(node: *DTNode, sym: nx_int, n_args: nx_int) -> *DTNode |
| 109 | func nx_dt_linearize(t: *Term, out_tokens: *DTToken, out_n: *nx_int) called by 3: nx_dt_linearizenx_dt_insertnx_dt_find_generalizations calls 2: nx_dt_linearizenx_term_arg |
| 130 | func nx_dt_insert(tree: *DiscTree, t: *Term, value: nx_int) |
| 152 | func nx_dt_skip_subterm(tokens: *DTToken, n: nx_int, cursor: nx_int) -> nx_int called by 1: nx_dt_walk |
| 166 | func nx_dt_walk(node: *DTNode, tokens: *DTToken, n_tokens: nx_int, |
| 197 | func nx_dt_find_generalizations(tree: *DiscTree, query: *Term, |
| 218 | func nx_dt_delete_value_node(node: *DTNode, target: nx_int) |
| 229 | func nx_dt_delete_value(tree: *DiscTree, target: nx_int) |