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 standard AbcDatalog engine API evaluates a program in one shot: you supply a complete set of facts and rules, and the engine returns all derived facts when evaluation finishes. The executor API takes a different approach. A DatalogExecutor runs evaluation as an ongoing process — you can feed new EDB facts into it while it is running, and you can register callbacks that fire the moment a new fact is derived. This makes the executor API the right choice whenever your input data arrives incrementally or you need to react to conclusions as they are drawn rather than after the full fixpoint has been reached.

The DatalogExecutor interface

DatalogExecutor is the central interface in the edu.harvard.seas.pl.abcdatalog.executor package. It exposes five methods that together define a simple lifecycle for an ongoing Datalog evaluation.
public interface DatalogExecutor {
    void initialize(Set<Clause> program, Set<PredicateSym> extendibleEdbPreds)
        throws DatalogValidationException;

    void registerListener(PredicateSym p, DatalogListener listener);

    void start();

    void addFactAsynchronously(PositiveAtom edbFact);

    void shutdown();
}
The two capabilities that distinguish this interface from a plain engine are:
  1. Asynchronous fact addition. After evaluation has started, you can call addFactAsynchronously(PositiveAtom) to inject new EDB facts. The executor incorporates each new fact into the running evaluation and derives any consequences that follow from it.
  2. Listener callbacks. Before evaluation starts, you can register DatalogListener callbacks for specific predicate symbols. Each listener is invoked whenever a new fact bearing that predicate is derived, letting your application react in real time without polling.

Key use cases

Event-driven reasoning

New events arrive as facts. The executor derives conclusions and fires listeners as each event is processed, without waiting for a batch to accumulate.

Reactive systems

Register listeners on output predicates to trigger side effects — notifications, UI updates, or downstream computations — the instant a new conclusion is reached.

Incremental fact loading

Load facts from a stream or external source one at a time as they become available, rather than waiting for the full dataset before beginning evaluation.

Executor lifecycle

A DatalogExecutor must be used in a fixed sequence. Calling methods out of order throws IllegalStateException.
1

Initialize

Call initialize(program, extendibleEdbPreds) exactly once, passing the parsed set of Clause objects and the set of PredicateSym values whose EDB relations you intend to extend at runtime. Facts for any predicate not in extendibleEdbPreds cannot be added after this point.
DatalogParallelExecutor ex = new DatalogParallelExecutor();
ex.initialize(ast, Collections.singleton(edge));
2

Register listeners

Call registerListener(PredicateSym, DatalogListener) for each predicate you want to observe. All listener registrations must happen before start() is called.
ex.registerListener(tc, fact -> System.out.println("Derived: " + fact));
3

Start evaluation

Call start() to begin the evaluation. The executor starts running in background threads. Once started, no further listeners can be registered.
ex.start();
4

Add facts asynchronously

Call addFactAsynchronously(PositiveAtom) at any time after start() to inject new ground EDB facts. Each added fact can trigger additional derivations and listener callbacks.
ex.addFactAsynchronously(newEdgeFact);
5

Shut down

Call shutdown() when you are done. The executor cannot be reused after shutdown.
ex.shutdown();
Listeners can be invoked in arbitrary threads by the executor. A listener must not block — doing so risks stalling the evaluation. Use non-blocking operations inside listeners, and synchronize only when strictly necessary (e.g., when writing to a shared output stream).

Concrete implementation

DatalogParallelExecutor is the only concrete implementation of DatalogExecutor provided by AbcDatalog. It runs the Datalog evaluation concurrently in separate threads using a parallel bottom-up evaluation strategy. For a complete working example and a step-by-step breakdown of each stage, see Adding facts asynchronously. For details on the listener callback interface and thread-safety patterns, see Reacting to derived facts with DatalogListener.

Build docs developers (and LLMs) love