Statement graphs and tiramemsu: one idea, one row deep
In 2023 Ewout Gelling, George Fletcher (Eindhoven University of Technology) and Michael Schmidt (Amazon Web Services) published Bridging graph data models: RDF, RDF-star, and property graphs as directed acyclic graphs. It defines Statement Graphs: one data model under RDF, RDF-star and labeled property graphs, so that one graph can be queried in SPARQL or Gremlin. The full version appeared at DASFAA 2024 as Statement Graphs: Unifying the Graph Data Model Landscape.
The paper matters beyond academia. Statement Graphs formalize Amazon's OneGraph (1G) vision, and the paper calls its combined image the “OneGraph-Image”. OneGraph is the metamodel at the core of Amazon Neptune Analytics: when Neptune Analytics added openCypher over RDF in August 2024, the Neptune team described the design at ISWC 2024 (openCypher over RDF: Connecting Two Worlds). In that paper, RDF and property-graph data are both loaded into OneGraph's internal model as “relationship statements” and “property statements”, and statement graphs are named as directly inspired by OneGraph. The statement is the unit that one of the largest managed graph databases uses to unify two graph worlds.
Tiramemsu starts from the same idea: everything is a statement with its own id. This article compares the two and argues one point. Tiramemsu stores each statement as a single record, and that physical choice gives it things a logical model leaves open.
A naming clash first. In tiramemsu's own docs, a “statement graph” is something narrower: a named graph whose name is a statement id, so an edge can hold a subgraph (see metagraphs). In this article, Statement Graphs always means the Gelling, Fletcher and Schmidt model.
What the paper defines
A Statement Graph is a directed acyclic graph with two kinds of vertices:
- Leaves hold concrete values: IRIs, blank nodes, literals, property-graph labels, property names and values. Each value appears once.
- Internal vertices hold statement identifiers. Each has exactly three outgoing edges, labeled
subject,predicateandobject. The subject and object may point at another statement; the predicate may not. No path may lead back to where it started.
An internal vertex and its three targets are “a piece of identifiable information”: a statement. The model gives no meaning to statements by itself. Meaning comes from images, the subsets of statement graphs that encode each surface model:
- RDF-star image: triple statements, which may point at other statements, and membership statements
(t, in, g)that put each triple in a named graph or the default graph. Two statements with the same three targets are not allowed, which is how RDF's set semantics is kept. - RDF image: the same, but statements may be referenced only by membership statements.
- LPG image: edge statements between nodes, label statements with the reserved predicate
lp, and property statements whose subject is a node or an edge. Label and property statements cannot be referenced by anything. - OneGraph image: a mix of RDF-star and LPG images in one graph, with duplicate statements allowed.
Mappings from the OneGraph image back to RDF and to property graphs define how SPARQL and Gremlin read the shared graph. The authors' prototype, the 1G Playground, keeps one statement graph in memory and two derived stores beside it, TinkerPop for Gremlin and RDF4J for SPARQL, which it reloads from the statement graph after each write. The paper says Statement Graphs are “a purely logical and conceptual model” and imply no physical layout.
The same core
Take the paper's own example: a flight route from Frankfurt to London Heathrow with a distance of 655. In RDF 1.0 the distance needs four extra triples of reification. In a statement graph it is one statement for the route and one property statement whose subject is that route. In tiramemsu it is two rows:
-- eid s p o
e1 :FRA :route :LHR
e2 e1 :distance 655
Both front ends see those two rows. SPARQL uses RDF 1.2 annotation syntax, and Cypher reads e2 as a relationship property:
SELECT ?d WHERE { v:FRA v:route v:LHR {| v:distance ?d |} }
MATCH ()-[r:route]->() RETURN r.distance
The vocabulary lines up almost one to one:
| Statement Graphs | tiramemsu |
|---|---|
| Internal vertex with a statement identifier | A row's eid |
Its subject, predicate, object edges | The row's s, p, o columns |
| Subject or object may be a statement; the predicate may not | Same: s and o may hold an eid, p is always an IRI |
Membership statement (t, in, g) | Membership layer (e, sys:inGraph, g), a row like any other |
Label statement (n, lp, label) | A label is an rdf:type statement |
| IRIs and property-graph node ids side by side | IRIs plus skolem IRIs (urn:tiramemsu:node:<n>) that round-trip to the same id |
| Relationship and property statements | A row with a node or statement object is a relationship; a row with a literal object is a property |
Statement graphs and tiramemsu also give the same answer to Neptune's hardest identity problem, global IRIs versus local property-graph ids: keep both, and give local ids a reversible IRI form. This is no coincidence. OneGraph is listed in tiramemsu's prior art, and the uniform statement model and the RDF/LPG mapping were taken from it. Tiramemsu's metagraph paper states the formal relationship plainly: replacing each row by a statement vertex with three role edges gives the corresponding statement-graph view. That is a correspondence of representations, not a claim that either model can express more.
The strong side: a statement is one record
A statement graph is a graph of vertices and edges, and a store that keeps it literally has to manage four things per statement: a vertex and three edges. Tiramemsu stores the same structure as one row (eid, s, p, o), plus its lifetime and valid time. That choice shows up in six places.
1. The row shape enforces the definition
Definition 4.1 of the paper requires that every statement vertex have exactly three outgoing edges, one of each label, and that the predicate edge never point at a statement. In a graph these are constraints to check. In a row they are the schema: a row cannot have two subjects or no object, and p is typed to hold only an IRI. The identity and the content of a statement are written in one insert, so no reader can ever see a statement id whose edges are not there yet.
2. One store, no derived copies
The 1G Playground evaluates SPARQL and Gremlin by keeping a TinkerPop store and an RDF4J store as copies of the statement graph and rebuilding them after writes. That is a reasonable shortcut for a prototype, and the paper says so: it avoids writing a query engine from scratch. Tiramemsu has no copies. SPARQL and Cypher both compile to one logical IR over the same table, so a write in either language is the same row, read and write go through one transaction, and a differential test suite checks that equivalent queries in the two languages return equal results. (Neptune Analytics itself is a production engine whose internals are not public, so this point compares tiramemsu with the paper's prototype, not with Neptune.)
3. Time fits on the record
Statement graphs have no time. Adding it to the logical model means more statements per statement (a “valid from” statement, a “retracted at” statement) or a side structure outside the model. Because a tiramemsu statement is a record, its lifetime is four more columns on the same row: t_add and t_ret for when the database believed it, v_from and v_to for when it was true. Every statement is bitemporal at no extra row, and a query can read any past state with asOf (see time travel). Rows are never deleted or edited: SQLite triggers reject it inside the file.
4. Retraction follows the edges
In a statement graph, “everything that depends on e1” is the set of statements with an incoming path to e1. Tiramemsu turns this into a write: retracting a statement retracts, in the same transaction and recursively, every live statement whose subject or object is that eid. It is a walk over two indexes, s = e and o = e. Retracting the route takes its distance with it, and never touches other facts about Frankfurt. The cascaded rows get the same t_ret, so the whole structure is still readable as of the moment before. The paper's mappings define how queries read the unified graph; writes, and what they take with them, are left to future work.
5. Occurrences are kept; sets are recovered
The RDF image forbids two statement vertices with the same three targets, and the OneGraph image allows them. A store has to choose. Tiramemsu keeps every occurrence as its own row, because an agent's memory needs “Alice worked at Acme, left, and came back” as two episodes with two histories. SPARQL's set semantics is recovered per query, and a query can still list every eid behind one (s, p, o). Duplicate removal is skipped for predicates that have never held two eids for the same triple, so the common case pays nothing.
6. Every record can be talked about
In the LPG image, label and property statements cannot have incoming edges: you cannot annotate a property, and an edge cannot point at another edge, so the mapping to property graphs drops such statements. In tiramemsu every row is addressable, properties included, and Cypher sees it: an eid is both a relationship and a node with the label :Statement, so a relationship variable may stand in node position.
MATCH (a)-[r:worksAt]->(c), (b:Belief)-[:supportedBy]->(r)
RETURN a, c, r.confidence, r.txAdded, b
A confidence on a confidence, the source of that confidence, and a belief that rests on an edge are all one row each. This is what tiramemsu calls a layered graph. A predicate can also be declared to annotate only statements, so a query for ?e v:confidence ?c never confuses a fact's confidence with a person's.
Where statement graphs are stronger
The single record is a physical choice, and it has costs. Statement graphs are better in several ways:
- Formal images. The paper defines an exact image for RDF, RDF-star and property graphs, with lossless mappings in both directions in its full version. Tiramemsu's mapping between SPARQL and Cypher is defined by its implementation and tests. Its metagraph paper does the image work for metagraph encodings, with a Lean proof of the directed roundtrip, but not for RDF and property graphs as a whole.
- Freedom of layout. Because the model is logical, an engine like Neptune Analytics can lay it out in memory however it likes. Tiramemsu has committed to one table on SQLite.
- Acyclicity. Statement graphs are acyclic by definition, which makes reasoning simpler. Tiramemsu forbids only a statement that points at itself; longer cycles are allowed, and the cascade walk keeps a visited set so it ends.
- Storage and set joins. An id per row is not free. In tiramemsu's own benchmark, the id layout was about half again larger than a quad-and-reifier layout, and a 2-hop SPARQL join with duplicate removal was about twice as slow. It won on reading and writing annotations.
- Scale and maturity. Neptune is a managed service. Tiramemsu is a young embedded library on SQLite, built for one agent's memory, not a cluster.
Side by side
| Statement Graphs (OneGraph) | tiramemsu | |
|---|---|---|
| What it is | A logical model, with a prototype and a production engine (Neptune Analytics) built on its ideas | An embedded database on SQLite |
| Unit | A statement vertex with three labeled edges | One row (eid, s, p, o) |
| Languages | SPARQL and Gremlin in the prototype; openCypher over RDF in Neptune Analytics | SPARQL and Cypher over one IR |
| Time | Not in the model | Two clocks on every row |
| Writes | Mappings define reads; writes are future work | Assert, create, supersede, confirm, retract with cascade |
| Duplicates | Forbidden in RDF images, allowed in the OneGraph image | Kept as occurrences; set semantics per query |
| Annotating properties and edges | Not in the LPG image | Any row, at any depth |
| Cycles | Forbidden | Only self-reference is forbidden |
| Formal mappings | Exact images for RDF, RDF-star and LPG | Exact images for metagraph encodings; RDF and Cypher by tests |
The takeaway
Statement Graphs show that one statement-centric model can hold RDF, RDF-star and property graphs without loss, and Neptune shows that this idea holds up in production. Tiramemsu agrees with the model and makes one further decision: a statement is a record. That record is where its identity, content and two clocks live together, which is why retraction, history, episodes and annotations of annotations are ordinary operations on one table.
References
- E. Gelling, G. Fletcher, M. Schmidt. Bridging graph data models: RDF, RDF-star, and property graphs as directed acyclic graphs [extended abstract]. arXiv:2304.13097, 2023.
- E. Gelling, G. Fletcher, M. Schmidt. Statement Graphs: Unifying the Graph Data Model Landscape. DASFAA 2024, LNCS, pp. 364–376.
- O. Lassila, M. Schmidt et al. The OneGraph Vision: Challenges of Breaking the Graph Model Lock-In. Semantic Web Journal 14(1), 2023.
- M. Schmidt et al. (Amazon Neptune team). openCypher over RDF: Connecting Two Worlds. ISWC 2024 Posters, Demos and Industry Tracks, CEUR-WS Vol. 3828.
- AWS. Amazon Neptune Analytics now supports openCypher queries over RDF graphs. August 2024.
Follow-up. The paper When Is a Temporal Statement Store a Statement Graph? makes this comparison exact. It shows which part of the store exports to a Statement Graph, what an exporter drops and reports, and how both clocks travel into RDF-star. Plain-language version: what leaves the store intact.