Tiramemsu

An export with a proof

Tiramemsu articles · 31 October 2026 · companion to Taking memory out whole

An export format is a promise: what goes out can come back. Usually the promise is backed by a few round-trip tests. For tm export --format sg-nt12 it is backed by theorems. The format is defined in LeanRDF, a Lean 4 library that writes the W3C semantics of RDF as Lean definitions, and the tiramemsu exporter is checked against that definition on every build.

What is proven

LeanRDF's leanrdf-statements package models a tiramemsu statement as a record: an id, a subject and an object (each a term or another record's id), a predicate, a transaction interval and a valid interval. toRDF v is the export in a view v, and decode v reads a graph back. Two theorems connect them:

theorem decode_toRDF (hw : sg.WellFormed) : decode v (sg.toRDF v) = .ok sg
theorem toRDF_decode (h : decode v g = .ok sg) :
    sg.WellFormed ∧ ∀ t, t ∈ sg.toRDF v ↔ t ∈ g

The first says that nothing is lost: export, then decode, and you get back the same statements. The second matters more for checking. Anything the decoder accepts is exactly the export of a well-formed set of statements. A stray triple, a missing clock or a missing assertion is rejected with an error that names it, and nothing is dropped silently. So a file that decodes is correct by that theorem, whoever wrote it.

Lean checks these proofs with its kernel. The library has no sorry and uses only the three standard axioms.

The paper, executable

The paper When Is a Temporal Statement Store a Statement Graph? came with an abstract Lean development. LeanRDF vendors it, with its DOI and source commit, and applies it to real RDF terms:

$ leanrdf-sg kernel snapshot.jsonl
kernel: [6]
removed eid 4: dangling reference to eid 1
removed eid 5: depends on removed eid 4
removed eid 7: on a reference cycle
removed eid 8: on a reference cycle

Proofs are about the definitions. To catch a definition that says the wrong thing, an exhaustive check runs every statement graph of at most four records over a small alphabet: 406,901 of them. On each one it compares the kernel with a brute-force search, quoting with the kernel, and decoding with exporting in three views.

Why the clocks are integers

Valid time was meant to be an xsd:dateTime. Then the decoder theorems would need a proven round trip between epoch milliseconds and calendar dates. The arithmetic behind that conversion turned out to be hard to prove in Lean, and the attempt was slow and incomplete. So the export writes milliseconds as xsd:integer. Their round trip is already proven in LeanRDF's core. Because tiramemsu's own tm:validFrom is a dateTime, the export uses tm:validFromMs instead (LeanRDF v0.3.1).

Closing the loop between Rust and Lean

A proof about LeanRDF's definition says nothing about tiramemsu's Rust code. Three choices connect them:

Together these give a narrower claim than "the exporter is correct", but a precise one: for every recorded case, what tiramemsu wrote is exactly the export of a well-formed statement graph, by toRDF_decode. When either side changes, one of the two test suites fails.

What is trusted

The linear-time bound of the paper's kernel algorithm is not mechanized: kernel is proven correct, not fast.

LeanRDF's site has a chapter on statement graphs and the package reference. The source is at github.com/Volland/rdf-lean.