Chapter 10 — Iron
Status, stated at maximum bluntness. The engine this chapter describes is designed and not built. What exists today is the CPU reference implementation you have been running since chapter 6 — deliberately slow, deliberately obvious, exhaustively cross-checked. This chapter therefore contains not a single benchmark number, and any figure you meet is an asymptotic or architectural claim, not a measurement. What it offers instead is the design rationale: why the language of chapters 6–9 is shaped so that this engine can exist, and why the shape of modern hardware makes the bet reasonable. When the engine ships, its numbers will be published against the reference oracle described at the end — that commitment is part of the design.
FGCS spent a decade and a national budget learning that you cannot build hardware for a logic language whose execution model is a sequential walk. Chapter 2 promised the inverse was now possible — a logic language built for hardware that already exists. This chapter pays that promise out, in four decisions.
Decision one: the unit of work is a pass, not a step
Recall what running a Strata-K program is: apply every rule to everything known, collect the new facts, repeat until nothing new appears. The imperative mind pictures that as a loop over facts — pop one, extend it, push the results; that was the worklist of chapter 1, and one-at-a-time is precisely the shape a GPU cannot use.
But nothing in the fixpoint’s definition says one at a time. A pass can take the entire set of known facts and apply a rule to all of it simultaneously: a rule body like owns(X, Y), controls(Y, Z) applied in bulk is a join of two tables — the same operation your database’s planner executes — followed by projection and deduplication. Set in, set out, no fact’s processing depending on any other’s within the pass. That is what “embarrassingly parallel” meant every time Part I used the phrase, and it is a property of the branch: the fixpoint family computes over sets, where the search family (Prolog’s SLD, ASP’s solver core) walks one path of a tree, backtracks, and walks another — inherently one-after-another, meaning attached to the walk’s order. The parallelism was never something to add to Datalog. It was in the definition, waiting thirty years for hardware with enough lanes — and the delta trick from chapter 1 survives intact: each pass joins only against facts new since the last pass, so the engine does bulk work without redundant work.
Decision two: facts live in columns, sorted
How the facts sit in memory decides whether the lanes starve. A GPU is a memory-bandwidth machine: thousands of lanes reading adjacent addresses fly; the same lanes chasing pointers crawl. So the design stores each relation as sorted, compressed columns — all the first arguments contiguous, then all the second arguments — with every constant dictionary-encoded to a fixed-width integer. owns(apex, brightwater) occupies a few bytes across two integer columns, join keys compare as integers, and a bulk join streams through memory in the access pattern the hardware was priced for. If this sounds like what your analytics warehouse did to your row-store — same move, same reason. The full relation and the current pass’s delta are kept separately (sorted runs, merged after each pass), which is the storage-level shadow of the delta trick; and one consequence of chapter 6’s design quietly pays off here: facts are never updated in place — the model only ever adds — so the storage never faces the concurrent-mutation problem that makes parallel imperative code miserable.
Two further consequences of the language design land in this section. Mandatory domain declarations mean every column’s value universe is known and dense — dictionary encoding is not an optimization pass, it falls out of the type system. And the absence of term construction (chapter 1’s “no new”) means a fact is always a fixed-width tuple of scalars: nothing variable-length, nothing heap-shaped, nothing to chase. The language was kept small in exactly the places that would have broken columnar storage.
Decision three: plans are chosen, not worshiped
A rule body is a small query, and queries have plans. For most bodies the classic strategy — a pipeline of pairwise joins, cheapest first — is right. But some shapes defeat it: a body asking for triangles (r(X,Y), s(Y,Z), t(Z,X)) can produce enormous pairwise intermediates that the third condition then throws away, and for such cyclic cores the design uses the newer strategy chapter 5’s frontier proved out — walking three sorted relations simultaneously, intersecting as it goes, never materializing the doomed intermediate. The planner’s rule is unglamorous: decompose each rule body, give the cyclic core the simultaneous walk, give the acyclic remainder the pairwise pipeline, decide by estimated cost. No single-algorithm dogma — the autopsies of chapter 4 were one long lesson in what dogma costs. (The same pragmatism, incidentally, is why the design’s most speculative idea — executing small dense sub-joins as tensor operations on the GPU’s matrix units — is explicitly fenced as a last-phase optimization, legal only where measured density justifies it. Early drafts of this project made tensor contraction the foundation; the critical review that produced the current design demoted it to a footnote. Constitutions exist because first drafts don’t survive contact.)
One engineering constraint shapes every kernel in the design: GPU code cannot allocate memory mid-flight the way host code does. So every materialization is two-phase — a light pass counts exact result sizes, a prefix sum turns counts into offsets, a heavy pass writes into pre-sized buffers. Deterministic, allocation-free, and — a property this book cares about more than most engine papers do — bit-reproducible: the same program on the same facts produces the same relations, to the byte, run after run. Determinism is not a debugging luxury here; it is what makes the correctness story below possible at all.
Decision four: three processors, three jobs
The full system, GPU alone can’t be. Chapter 8’s stable-model search is combinatorial choice — propagate, guess, learn from conflict, backtrack — and its core is exactly the sequential, branchy, latency-bound computation CPUs are built for and GPUs are worst at. Pretending otherwise would repeat FGCS’s category error in mirror image. So the division of labor is explicit, and it is the architecture the whole book has been drawing one panel at a time:
- GPU: everything set-shaped — the deductive fixpoint (chapters 6–7), the massive grounding step that chapter 4 measured as ASP’s entry wall, pedigree capture, and the bulk simplification that shrinks a combinatorial problem before search ever sees it.
- CPU: everything path-shaped — the stable-model search itself (chapter 8), circuit compilation’s hard steps (chapter 7’s mode B), orchestration.
- Neural hardware, eventually: everything heuristic — proposals for which branch to try first, candidate answers to verify. Under the constitution’s third invariant, never deciding — a neural hint may reorder the search, and may not change what the search accepts. Chapter 9 showed that principle with an LLM; here it is again with a GNN, unchanged.
Notice the shape: it is chapter 4’s autopsy table, inverted into a deployment diagram. Each paradigm’s “fundamentally sequential part” — the thing that killed its parallel ambitions — is assigned to the processor that likes it, instead of being asked to vanish.
The part that keeps it honest
Now the question this chapter must not dodge: when the fast engine exists, why should anyone believe its answers?
Because the slow engine exists first, and that ordering is the point. The reference implementation you have been running — naive fixpoint, then an independent semi-naive engine, cross-checked against each other, against an external engine on the shared fragment, and against exhaustive-by-construction oracles for probability and stable models, over tens of thousands of fuzzed programs — is not a placeholder awaiting deletion. It is the specification, executable. The constitution’s fifth invariant binds the GPU engine to match it: bit-for-bit on Bool, within declared tolerance on numeric semirings, on the same corpus plus differential fuzzing, forever. A performance claim without an oracle is marketing; Phase 0 was built slow-and-obvious first precisely so that every fast thing after it has something unforgiving to answer to.
And because others are already proving the direction, the claim “Datalog rides GPUs” no longer rests on this project’s word alone: the research engines chapter 5 cited have published order-of-magnitude results for exactly the bulk-join fixpoint architecture described here. What no one has yet shipped is that architecture carrying this language — semirings, pedigrees, the mode split, the fenced choice layer — which is Strata-K’s actual wager, and it remains a wager until the code exists. You have my status box; hold me to it.
The design is now fully on the table — language, semantics, authorship story, iron. One chapter remains: the road from the repository you can clone today to the system this chapter described, and the honest map of what’s known, what’s designed, and what’s still research.