Skip to main content

Documentation 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.

The edu.harvard.seas.pl.abcdatalog.ast package defines the Java object model for a parsed Datalog program. Every clause produced by DatalogParser, and every clause you construct programmatically, is made up of these types. Understanding the AST classes is essential for building programs in code, for inspecting parsed results, and for writing visitors that traverse or transform programs.

Class hierarchy

Class / InterfaceRole
ClauseA rule or ground fact. Holds a Head and a List<Premise> body.
HeadInterface for the head of a clause. Currently only PositiveAtom implements it.
PremiseInterface for body elements. Implemented by PositiveAtom, NegatedAtom, BinaryUnifier, and BinaryDisunifier.
PositiveAtomA positive (non-negated) atom: a PredicateSym paired with a Term[] argument array. Implements both Head and Premise.
NegatedAtomWraps a PositiveAtom with negation (not atom). Implements Premise.
BinaryUnifierRepresents a left = right unification premise in a rule body. Implements Premise.
BinaryDisunifierRepresents a left != right disunification premise. Implements Premise.
TermInterface for terms. Implemented by Variable and Constant.
VariableA logic variable, identified by name. Names starting with uppercase or _ parse as variables.
ConstantA ground constant (zero-ary function symbol). Names starting with a lowercase letter parse as constants.
PredicateSymA predicate name plus its arity. All atoms with the same name and arity share the same PredicateSym instance.

Factory methods

All concrete AST types use static factory methods rather than public constructors. Both Variable and Constant memoize instances, so Variable.create("X") == Variable.create("X") holds by reference equality. PredicateSym.create does the same for (name, arity) pairs.
PredicateSym pred = PredicateSym.create("edge", 2);
Term x = Variable.create("X");
Term a = Constant.create("a");
PositiveAtom atom = PositiveAtom.create(pred, new Term[]{x, a});
Clause uses a public constructor directly:
Clause fact = new Clause(PositiveAtom.create(pred, new Term[]{a, b}), Collections.emptyList());

Visitor pattern

Both Head and Premise support the visitor pattern via accept methods that take a typed visitor and a state object. This is the preferred way to write code that handles multiple AST node kinds without instanceof chains.
See the edu.harvard.seas.pl.abcdatalog.ast.visitors package for PremiseVisitor, HeadVisitor, TermVisitor, and their builder helpers (PremiseVisitorBuilder, HeadVisitorBuilder, TermVisitorBuilder).

Facts vs. rules

A Clause with an empty body (getBody().isEmpty()) represents a ground EDB fact. A clause with a non-empty body is a rule. When you pass a Set<Clause> to DatalogEngine.init or DatalogValidator.validate, the validator separates the two automatically based on body emptiness and predicate membership in IDB vs. EDB.

Applying substitutions

Every Head, Premise, and Term instance implements applySubst(Substitution subst), which returns a new AST node with the substitution applied. This is used internally by the engines and is useful when working with ConstOnlySubstitution results from conjunctive queries.

Build docs developers (and LLMs) love