datalog-dafsa

CLI Reference

The dl binary is the command-line front end. There are exactly 8 subcommands. The database directory defaults to dl-test-db and can be set with -d <dir>. Command values that parse as bare integers are stored raw as u32; anything else is interned to a string symbol id.

dl [-d <dir>] load    <csv> --rel <name>
dl [-d <dir>] lookup  <rel> <val> [<val> ...]
dl [-d <dir>] prefix  <rel> [<val> ...]
dl [-d <dir>] query   '<rule>' | <file.dl> <goal-rel>
dl [-d <dir>] qmagic  '<rule>' | <file.dl> <goal-rel> [-a <adorn>] <val> [<val> ...]
dl [-d <dir>] publish
dl [-d <dir>] bound   <rel> <val> [<val> ...]
dl [-d <dir>] pattern <rel> '<regex>'

load

Load facts from a headerless CSV file into a relation (arity 1–8).

$ ./dl -d /tmp/db load edges.csv --rel edge
Loaded 5 facts into edge

The relation’s arity is inferred from the first non-empty CSV row. Values: quoted strings are interned; bare integers are stored raw as u32.

lookup

Exact lookup of a fact by its full column values. Prints found or not found.

$ ./dl -d /tmp/db lookup edge 1 2
found

$ ./dl -d /tmp/db lookup edge 9 9
not found

prefix

Bind the leading columns to the given values and enumerate every matching complete tuple.

# all tuples
$ ./dl -d /tmp/db prefix edge
1 2
1 3
2 3
2 4
3 5

# tuples with leading column == 2
$ ./dl -d /tmp/db prefix edge 2
2 3
2 4

With no bound values, this lists the whole relation.

query

Parse, compile, and run a Datalog rule in one step, then stream the goal relation’s tuples. The rule source may be a quoted inline string or a .dl file path; the goal is the relation to print.

$ ./dl -d /tmp/db query \
    'tc(X,Y) :- edge(X,Y). tc(X,Y) :- edge(X,Z), tc(Z,Y).' tc
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 5

Internally this loads the rules, publishes a snapshot (running the VM if the fixpoint is dirty), then queries the goal relation.

qmagic

Magic-sets bound query: evaluates a scoped fixpoint seeded by the bound values, materialising only the reachable IDB slice. The result is byte-for-byte identical to dl_query_bound over the fully materialized goal.

# leading-prefix form: bind the first k args
$ ./dl -d /tmp/db qmagic \
    'tc(X,Y) :- edge(X,Y). tc(X,Y) :- edge(X,Z), tc(Z,Y).' tc 1

# arbitrary-adornment form: -a <adorn> binds named positions
$ ./dl -d /tmp/db qmagic \
    'tc(X,Y) :- edge(X,Y). tc(X,Y) :- edge(X,Z), tc(Z,Y).' tc -a "bf" 1

The optional -a <adorn> is a string of exactly goal-arity characters, each b (bound) or f (free); vals are packed left-to-right in the order of the b positions. Programs using negation, aggregates, or cross-predicate mutual recursion are rejected with a diagnostic.

publish

Atomically publish a versioned snapshot of the database.

$ ./dl -d /tmp/db publish
Snapshot published.

After publishing, query reads from mmap instead of running the VM.

bound

Bound query (snapshot path): bind leading columns and enumerate via the snapshot view.

$ ./dl -d /tmp/db bound edge 1
1 2
1 3

pattern

Enumerate all tuples whose full key matches a regex.

$ ./dl -d /tmp/db pattern edge '(a|b).*'

A bad pattern is a loud error.

What is not in the CLI

The top-down / QSQ path (dl_query_topdown / dl_query_topdown_adorn) is available only through the C API — there is no topdown CLI subcommand. Likewise, order-statistics (rank / select / range / count) and time-travel (as-of queries) are C-API only; they have no CLI command.