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 parses a dialect of Datalog whose surface syntax is designed to be compact and readable. This page is a complete reference for every syntactic element you will encounter when writing programs for AbcDatalog: how clauses are structured, how identifiers are lexed into constants and variables, what operators are available in rule bodies, and how queries are written.

Program structure

A Datalog program is an unordered set of clauses. AbcDatalog reads all clauses before evaluation begins, so the order in which you write them in a file does not matter. Each clause is terminated by a period (.).
% A complete program: four facts and two rules
edge(a,b).
edge(b,c).
edge(c,c).
edge(c,d).

tc(X,Y) :- edge(X,Y).
tc(X,Y) :- edge(X,Z), tc(Z,Y).

Clause format

Every clause has a head — a single positive atom — and an optional body — a comma-separated list of premises.
FormMeaning
a0.A fact: a0 is unconditionally true.
a0 :- a1, ..., an.A rule: a0 holds if every a1 through an holds.
The :- token is read as “if”. The head atom must be a positive atom (predicate symbol with zero or more term arguments). Body premises may be positive atoms, negated atoms, binary unifiers, or binary disunifiers — each detailed further below.

Atoms

An atom has the form p or p(t1, ..., tk) where p is a predicate symbol and each ti is a term. The arity of a predicate symbol is fixed throughout a program: a predicate used as edge(a,b) always takes exactly two arguments everywhere it appears.
% Zero-arity atom (propositional fact)
done.

% Binary atom
edge(a,b).

% Atom with a variable argument
tc(X,Y) :- edge(X,Y).

Terms

A term is either a constant or a variable.
  • Constants begin with a lowercase letter. They denote fixed values in the domain. Examples: a, b, node1, start.
  • Variables begin with an uppercase letter or an underscore. They range over constants during evaluation. Examples: X, Y, Node, _Tmp.
  • Wildcards: a bare _ (a single underscore) is parsed as a fresh anonymous variable — it is guaranteed to be distinct from every other occurrence of _ in the same clause. Use it when a position’s value is irrelevant.
% Constants: a, b, c, d
edge(a,b).
edge(b,c).

% Variables: X, Y, Z
tc(X,Y) :- edge(X,Y).
tc(X,Y) :- edge(X,Z), tc(Z,Y).

% Wildcards: collect all nodes from both endpoints of edges
node(X) :- edge(X,_).
node(X) :- edge(_,X).

Identifiers

Identifiers can contain letters, digits, and underscores only. The first character determines the syntactic role:
First characterRole
Lowercase letter (az)Constant or predicate symbol
Uppercase letter (AZ)Variable
Underscore _ (followed by more chars)Variable
Bare _ (alone)Anonymous wildcard variable
Predicate symbols must begin with a lowercase letter — the parser rejects any atom whose predicate starts with an uppercase letter or underscore.
Identifiers are case-sensitive. node and Node are different tokens: node is parsed as a predicate symbol or constant, while Node is parsed as a variable.

Comments

A % character begins a line comment. Everything from % to the end of the line is ignored by the tokenizer. AbcDatalog has no block comment syntax.
% This entire line is a comment.
edge(a,b).  % Inline comment after a fact.
tc(X,Y) :- edge(X,Y).  % Inline comment after a rule.

Queries

A query is an atom terminated by ? instead of .. When submitted interactively or via DatalogParser.parseQuery, it asks the engine to return all ground substitutions of the query atom that are entailed by the program.
% Return every pair in the transitive closure
tc(X,Y)?

% Return every node reachable from a
tc(a,X)?

% Check whether a specific fact holds
edge(a,b)?
Query atoms follow the same identifier rules as body atoms: uppercase-starting tokens in the query are variables that range over constants in the result, and lowercase-starting tokens are constants that must match exactly.

Syntactic elements reference

ElementSyntaxExample
Facthead.edge(a,b).
Rulehead :- body.tc(X,Y) :- edge(X,Y).
Body separator,edge(X,Z), tc(Z,Y)
Atompred or pred(t1,...,tk)tc(X,Y)
Constantlowercase-start identifiera, node1
Variableuppercase-start or _-start identifierX, _Tmp
Wildcardbare _edge(X,_)
Line comment% ...% a comment
Query terminator?tc(X,Y)?
Unificationt1 = t2X=Y
Disunificationt1 != t2X!=Y
Negationnot atomnot tc(X,Y)

Build docs developers (and LLMs) love