Sources: original to this vault (design and analysis; no single paper); Bonchi, Seeber & Sobociński, Graphical Conjunctive Queries, CSL 2018, arXiv:1804.07626; Abo Khamis et al., Convergence of Datalog over (Pre-) Semirings, arXiv:2105.14435
Theory (CT-ML wiki): Conjunctive Query · Least Fixed Point · Monad Comprehension · Provenance Semiring
Concrete queries against Graph Schema, in the three dialects that match the candidate backends. The point of writing them out is that “a compiler is queries over a database” is only credible if the queries are ordinary.
1. Fetch a definition’s full core term
SQL (DuckDB / SQLite / Turso) — recursive CTE over the CHILD edges:
WITH RECURSIVE subtree(h, depth) AS (
SELECT ?root, 0
UNION ALL
SELECT e.dst, s.depth + 1
FROM subtree s JOIN edge e ON e.src = s.h
WHERE e.kind = :CHILD AND s.depth < 10000
)
SELECT n.h, n.kind, n.payload, e.ord
FROM subtree s
JOIN node n ON n.h = s.h
LEFT JOIN edge e ON e.dst = s.h AND e.kind = :CHILD
ORDER BY s.depth, e.ord;Cypher (FalkorDB / Neo4j):
MATCH p = (root:Term {h: $root})-[:CHILD*0..]->(n:Term)
RETURN nodes(p), relationships(p)Datalog:
reach(R, R).
reach(R, C) :- reach(R, P), child(P, _, C).The SQL version is the one to benchmark first; see the chunked-storage caveat in Compilation as Query.
2. What breaks if I change this?
The single most valuable query in the system — exact, not heuristic.
MATCH (changed:Decl {h: $h})<-[:DEPENDS_ON*]-(affected:Decl)
OPTIONAL MATCH (affected)<-[:TESTS]-(t:Test)
RETURN affected.h, collect(t.h) AS tests_to_rerunWith a materialised transitive closure this is a single index lookup. See Tests and Documentation as Nodes.
3. Find an alternative implementation within a modulo budget
The query a compiler runs when it wants to substitute a faster implementation.
MATCH path = (a:Decl {h: $h})-[rels:EQUIV*1..4]-(b:Decl)
WHERE ALL(r IN rels WHERE r.level IN ['defeq','rewrite','observational'])
AND ALL(r IN rels WHERE ALL(m IN r.modulo WHERE m IN $allowed_modulo))
MATCH (b)-[:BENCHMARKS]->(bm:Bench {target: $target})
RETURN b.h, bm.median_ns, [r IN rels | r.level] AS chain
ORDER BY bm.median_ns ASC
LIMIT 1Note the two ALL guards: they enforce the substitutability rule and the modulo budget from Equivalence and Witnesses. Dropping either is how this system would produce wrong code.
4. Constant folding as a rewrite rule
equiv(App, Folded, "rewrite", []) :-
term(App, "app"),
child(App, 0, F), prim(F, "add.wrap.i64"),
child(App, 1, X), lit(X, A),
child(App, 2, Y), lit(Y, B),
Folded = intern_lit(wrap_add_64(A, B)).Compare LLVM Pass: the same transformation, expressed as a fact-producing rule rather than as an in-place mutation, and therefore both persistable and reversible.
5. Which definitions have no test coverage?
SELECT n.h FROM node n
WHERE n.kind = :DECL
AND NOT EXISTS (SELECT 1 FROM edge e
WHERE e.dst = n.h AND e.kind = :TESTS);6. Find duplicated logic across languages
Definitions that elaborate to the same core term but came from different frontends — free cross-language equivalence, discovered rather than asserted (Equivalence and Witnesses).
MATCH (s1:SurfaceNode)-[:ELABORATES_TO]->(t:Term)<-[:ELABORATES_TO]-(s2:SurfaceNode)
WHERE s1.lang <> s2.lang
RETURN t.h, collect(DISTINCT s1.lang + '/' + s2.lang)7. Trust audit of a build artifact
MATCH (a:Module {h: $artifact})-[:DEPENDS_ON*]->(x)
OPTIONAL MATCH (x)-[e:EQUIV]-()
WITH collect(DISTINCT e.level) AS levels, collect(DISTINCT e.modulo) AS mods
RETURN levels, apoc.coll.toSet(apoc.coll.flatten(mods)) AS total_moduloImplements the trust(artifact) = min over derivation rule from Trusted Computing Base.
8. Cache lookup for precompilation
SELECT code FROM artifact
WHERE h_run = ? AND h_target = ? AND h_opts = ?;Trivially simple, and that simplicity is the whole argument of Content-Addressed Precompilation.
9. Dispatch invalidation (Julia-specific)
Which cached specialisations are contradicted by a newly added method?
MATCH (m:Method {h: $new_method})
MATCH (spec:Decl)-[:DEPENDS_ON]->(f:DispatchFact)
WHERE f.fname = m.fname AND sigOverlaps(f.argtypes, m.sig) AND moreSpecific(m.sig, f.chosen_sig)
RETURN spec.hsigOverlaps and moreSpecific are Julia’s own subtyping predicates, which would need exposing as database functions — a concrete piece of work, and the crux of whether the invalidation-precision claim holds up. See World Age.
Query patterns that will be slow
Worth stating up front, since they determine the storage design:
- Unbounded
-[:CHILD*]->over large functions ⇒ use chunked subtree blobs. - Unbounded
-[:EQUIV*]-closure ⇒ must be bounded and modulo-filtered; never materialise. - Anything joining across all IR layers at once ⇒ partition by layer.
- Text search over
DocandName⇒ wants a separate inverted index, not the graph.