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.

AbcDatalog is designed for extensibility: every built-in engine is just one concrete implementation of a common interface, and you can slot in your own evaluation strategy without touching any other part of the library. The two main extension points are the DatalogEngine interface, which imposes minimal obligations and suits fully custom engines, and BottomUpEngineFrame, a generic scaffold that handles initialization bookkeeping and query dispatch so you only need to supply a saturation algorithm via EvalManager.

The DatalogEngine interface

All engines in AbcDatalog implement edu.harvard.seas.pl.abcdatalog.engine.DatalogEngine. The interface declares two required methods:
public interface DatalogEngine {
    void init(Set<Clause> program) throws DatalogValidationException;
    Set<PositiveAtom> query(PositiveAtom q);
}
  • init(Set<Clause> program) — called once with the full program (EDB facts encoded as clauses with empty bodies, plus IDB rules). Throws DatalogValidationException if the program is invalid and IllegalStateException if the engine has already been initialized.
  • query(PositiveAtom q) — returns every fact derivable from the program that unifies with q. Throws IllegalStateException if init has not been called.
A third method, query(List<PositiveAtom> query), is provided as a default that delegates to ConjunctiveQueryHelper, so you do not need to implement it yourself.

Bottom-up scaffold: BottomUpEngineFrame

For engines that saturate a fact set bottom-up, BottomUpEngineFrame<E extends EvalManager> provides a ready-made DatalogEngine implementation. It stores the EvalManager, calls its lifecycle methods inside init, caches the resulting IndexableFactCollection, and implements query via indexed lookup. You only need to provide an EvalManager. The frame constructor takes the manager directly:
public BottomUpEngineFrame(E manager) {
    this.manager = manager;
}
ConcurrentBottomUpEngine shows the minimal pattern — a single constructor that passes a concrete manager to super:
public class ConcurrentBottomUpEngine extends BottomUpEngineFrame<EvalManager> {
    public ConcurrentBottomUpEngine() {
        super(new BottomUpEvalManager());
    }
}

The EvalManager interface

Your custom manager must implement edu.harvard.seas.pl.abcdatalog.engine.bottomup.EvalManager:
public interface EvalManager {
    void initialize(Set<Clause> program) throws DatalogValidationException;
    IndexableFactCollection eval();
}
  • initialize(Set<Clause> program) — parse and validate the program, set up internal data structures.
  • eval() — run saturation to a fixed point and return the complete fact collection as an IndexableFactCollection.
BottomUpEngineFrame.init calls manager.initialize(program) followed by manager.eval() and stores the result; you never invoke these methods directly from outside the frame.

Minimal custom engine skeleton

import edu.harvard.seas.pl.abcdatalog.ast.Clause;
import edu.harvard.seas.pl.abcdatalog.ast.validation.DatalogValidationException;
import edu.harvard.seas.pl.abcdatalog.engine.bottomup.BottomUpEngineFrame;
import edu.harvard.seas.pl.abcdatalog.engine.bottomup.EvalManager;
import edu.harvard.seas.pl.abcdatalog.util.datastructures.IndexableFactCollection;
import java.util.Set;

public class MyCustomEngine extends BottomUpEngineFrame<EvalManager> {

    public MyCustomEngine() {
        super(new MyEvalManager());
    }

    // Optional: override query() for specialized lookup behaviour
}

class MyEvalManager implements EvalManager {

    @Override
    public void initialize(Set<Clause> program) throws DatalogValidationException {
        // Validate and index the program
    }

    @Override
    public IndexableFactCollection eval() {
        // Saturate and return all derivable facts
        return /* your IndexableFactCollection implementation */;
    }
}
The existing engines — SemiNaiveEngine, ConcurrentBottomUpEngine, and their provenance variants — are full working reference implementations. Reading their EvalManager subclasses is the fastest way to understand what initialize and eval need to do in practice.
Before writing a custom engine from scratch, open a GitHub issue on the AbcDatalog repository to describe your use case. Maintainers can advise whether an existing engine can be extended, point you to relevant internals, or flag API surface that is still in flux.

Build docs developers (and LLMs) love