datalog-dafsa
A DAFSA-backed Datalog engine written in C. You load facts into an on-disk minimal-acyclic-DAFSA fact store, compile Datalog rules to a small VM, materialize derived relations, and serve reads from an mmap’d snapshot.
Two things that stand out
A database that shares its suffixes — so it’s genuinely compact
Every relation is stored as a minimized acyclic DAFSA:
common suffix paths between facts are merged into a single shared
state, not duplicated. A store that keeps thousands of
edge(1,…) prefixes over the same tail columns is
dramatically smaller than a row store, because the shared tails exist
once. Reads are mmap’d zero-copy — the DAFSA is the
index, so there is no separate index file and no deserialization on the
read path. Exact lookup and prefix enumeration are the two most common
join access patterns, and both are native DAFSA primitives.
Every publish is a point-in-time — time-travel as a first-class feature
Every dl_publish_snapshot writes an immutable,
versioned snapshot and keeps the full history by default. That
makes as-of queries a native capability: read the database as it
was at version n — audit, replay, or diff the evolution of a
derived relation — without touching live routing. Old snapshots are
immutable; later writes never disturb them. Opt-in
retention bounds disk growth.
Typed projects — schema, validated data, and typechecked rules
The dlp tool defines the database schema in Dhall
(schema.dhall), validates and coerces CSV/JSON data against
it, and typechecks every rule before compilation. A
variable can’t silently be Natural in one atom and
Text in another — mixed-type rules are rejected with
file:line:col diagnostics. Closed-world and typed, so type
errors surface early instead of mis-evaluating.
Quickstart
make # build libdatalog.so, dl CLI, test binaries
make test # run the full test suite
make bench # run the demonstration benchmark
The dl CLI loads facts and answers queries. The database
directory defaults to dl-test-db and can be overridden with
-d <dir>.
$ cat edges.csv
1,2
1,3
2,3
2,4
3,5
# Load a headerless CSV (arity 1-8) into a relation.
$ ./dl -d /tmp/db load edges.csv --rel edge
Loaded 5 facts into edge
# Exact lookup.
$ ./dl -d /tmp/db lookup edge 1 2
found
# Prefix enumeration (bind leading columns).
$ ./dl -d /tmp/db prefix edge 2
2 3
2 4
# Run a Datalog rule (compile + publish + query in one step):
# transitive closure of edge.
$ ./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
# Publish a snapshot for read-only serving.
$ ./dl -d /tmp/db publish
Snapshot published.
CSV values that parse as integers are stored raw as u32; anything else is
interned to a symbol id. Other commands include bound,
pattern (regex), and qmagic (magic-sets).
See the CLI reference.
Feature summary
| Area | Capabilities | Details |
|---|---|---|
| DAFSA storage | Fixed-width u32BE key encoding; one DAFSA + WAL per relation; symbol interner; WAL + compaction | Architecture |
| Datalog syntax | Facts, rules, recursion, negation, aggregates (count/sum/min/max), equality, comparisons, arithmetic, strings, lists, range, regex | Language Reference |
| Evaluation strategies | Semi-naive fixpoint, stratified negation, bushy joins, permutation-index selection + hash-join, magic-sets / QSQ top-down, incremental view maintenance | Architecture § strategies |
| Order statistics | rank / select / range_count / count, bound + perm variants, pull-iterator + merge-join, lazy range generator | Order Statistics |
| Time-travel | Versioned snapshots, as-of queries, opt-in retention | Time Travel |
| Durability | Per-relation WAL + fsync, single-writer lock, atomic snapshot publish, mmap read path | Architecture § durability |
Reference pages
- Language Reference — the complete rule language.
- CLI Reference — the 8
dlsubcommands. - C API Reference — the full
dl.hsurface. - Architecture — storage thesis, lifecycle, join & evaluation strategies.
- Order Statistics — rank / select / range / count and the sorted iterator.
- Time Travel — versioned snapshots and as-of queries.
- Typed Projects — schema.dhall + validated data + typechecked rules.