Beyond positive atoms, AbcDatalog rule bodies can contain three additional kinds of premises: explicit unification (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.
=), explicit disunification (!=), and negated atoms (not). Each of these extends what you can express, but each also carries safety requirements and must be explicitly enabled in DatalogValidator before the engine will accept them.
Explicit unification
The= operator, represented by the BinaryUnifier AST node, requires two terms to unify. When both terms are variables, it equates them; when one is a constant, it binds the variable to that constant.
X=Y form is useful when a variable has already been introduced by a different body atom and you need to assert equality after the fact.
Unification can also bind a variable to a constant:
X=a fixes X to the constant a for the rest of the rule. This also satisfies the safety requirement for X — a variable unified with a constant is considered bound.Enabling unification in the validator
Unification in rule bodies is an optional feature. You must opt in viaDatalogValidator before calling validate:
BinaryUnifier and this method has not been called, validate throws a DatalogValidationException with the message "Binary unification is not allowed".
Explicit disunification
The!= operator, represented by the BinaryDisunifier AST node, requires that two terms are not equal. A body containing X!=Y succeeds only for substitutions where X and Y are bound to distinct constants.
Enabling disunification in the validator
BinaryDisunifier and this has not been called, the validator raises "Binary disunification is not allowed".
Negation
Thenot keyword, represented by the NegatedAtom AST node, holds when the atom it negates is not provable given the current set of derived facts. This is the closed-world assumption: anything not explicitly derived is treated as false.
node relation is necessary here to supply a finite domain for X and Y. Without it, the variables would be unbound — see the safety discussion below.
Safety rule for negation
Variables that appear inside anot atom are not bound by that atom. They must be bound by a positive body atom elsewhere in the same rule — either directly or through a chain of unifications.
Enabling negation in the validator
Stratified negation
AbcDatalog supports stratified negation. A program is stratifiable when its predicate dependency graph has no cycle that passes through a negated edge — that is, no predicate can indirectly depend on the negation of itself. Stratification ensures that when a negated atomnot p(X,Y) is evaluated, the relation for p is already fully computed. The evaluation proceeds stratum by stratum: all predicates whose definitions do not involve negation (stratum 0) are computed first, then predicates that depend negatively only on stratum-0 predicates (stratum 1), and so on.
Why does stratification matter?
Why does stratification matter?
Without stratification, negation can produce paradoxical or non-deterministic results. Consider a hypothetical rule
p :- not p. — p holds if and only if p does not hold, which has no sensible semantics under the closed-world assumption.Stratified programs avoid this by guaranteeing that by the time the engine evaluates not p(...), the complete set of p facts has already been derived. The result is deterministic and well-defined: the perfect model semantics.AbcDatalog engines that support negation perform stratification as part of program initialization and will refuse programs that are not stratifiable.Engine support
Not all AbcDatalog engines support these extended features. The following engines handle unification and stratified negation:SemiNaiveEngine
Supports binary unification (
=), binary disunification (!=), and stratified negation (not). This is the standard bottom-up semi-naive evaluation engine.ConcurrentStratifiedNegationBottomUpEngine
A concurrent variant that evaluates strata in parallel where possible, also supporting unification, disunification, and stratified negation.
Always configure
DatalogValidator to match the features your chosen engine supports before calling validate. Passing a program with unification or negation to an engine that does not handle those features will produce incorrect or incomplete results.Complete example
The following excerpt fromtc.dtlg demonstrates all three features together in a single program:
in_cycle1(X)? returns every node that can reach itself. Querying not_tc(X,Y)? returns every ordered pair of nodes (X,Y) for which no path from X to Y exists in the graph.