AbcDatalog’s AST nodes use the visitor pattern to let you process different node types with compile-time safety and without casting. Three independent visitor hierarchies cover every part of a program: heads of clauses, premises (body conjuncts), and terms within atoms. Each hierarchy ships with a fluent builder, two base classes (one that crashes on unhandled nodes, one that returnsDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/HarvardPL/AbcDatalog/llms.txt
Use this file to discover all available pages before exploring further.
null), and a matching default implementation you can override selectively.
Visitor hierarchies
HeadVisitor<I, O>
Visits the head of a Clause. Currently the only concrete head type is PositiveAtom, so the interface has one method:
I is an arbitrary input state threaded through the visit call; O is the return type.
PremiseVisitor<I, O>
Visits body premises. A clause body can contain five node types:
AnnotatedAtom is an internal wrapper used by bottom-up evaluation engines; user-facing programs typically contain PositiveAtom, NegatedAtom, BinaryUnifier, and BinaryDisunifier.
TermVisitor<I, O>
Visits the two kinds of term that appear in atom argument lists:
Builder APIs
Each visitor interface has a corresponding builder that lets you register per-type handlers as lambdas and choose a fallback strategy.PremiseVisitorBuilder<I, O>
HeadVisitorBuilder<I, O>
TermVisitorBuilder<I, O>
this, enabling chaining. Handlers not registered via a builder method fall through to the or/orNull/orCrash fallback.
Example: collecting all PositiveAtom premises from a clause body
Default and crash base classes
When subclassing is more convenient than a builder, four abstract base classes are available:| Class | Implements | Unhandled case |
|---|---|---|
CrashHeadVisitor<I, O> | HeadVisitor<I, O> | throws UnsupportedOperationException |
CrashPremiseVisitor<I, O> | PremiseVisitor<I, O> | throws UnsupportedOperationException |
DefaultConjunctVisitor<I, O> | PremiseVisitor<I, O> | returns null |
DefaultTermVisitor<I, O> | TermVisitor<I, O> | returns null |
When to use each visitor type
HeadVisitor— when iterating over a set of clauses to inspect or rewrite heads; used in normalization passes and rule indexing.PremiseVisitor— when implementing analyses or transformations that must distinguish between positive atoms, negated atoms, and unification constraints in a rule body.TermVisitor— when you need to recurse into atom arguments, for example to collect all variables, check groundness, or apply a substitution.