SPARQL Store Backend Notes#

This note records the current direction for making SPARQL evaluation stop assuming that an RDF graph is just a plain in-memory list of triples.

Problem#

Today the algebra layer effectively assumes:

let graph_triples (g : rdf_graph) : list triple = g

That means:

This is acceptable for parser validation and small examples, but it does not scale to larger corpora.

Direction#

Keep the SPARQL algebra and value semantics in F*, but put a storage/query boundary underneath them.

Decision: Default In-Memory Graph Representation#

The default in-memory representation should not remain an unindexed list triple for normal query execution.

Factoidal should keep rdf_graph = list triple as the logical, portable RDF graph representation used for parser output, semantic tests, small examples, and proof-friendly graph operations. That representation is simple and remains the easiest place to express RDF graph set semantics.

The default runtime backend for SPARQL evaluation, however, should be an indexed in-memory graph store built from that logical graph:

This means callers should not have to choose between "correct list semantics" and "usable query execution." The list graph remains the semantic baseline; the indexed memory store becomes the ordinary ephemeral backend for parsed data.

GB_List should remain available as a compatibility and testing backend, but it should not be the long-term default for data loaded for querying.

The first implementation target is:

That gives us a seam for later backends such as HDT, HDTQ-style dataset stores, and COTTAS-style columnar quad stores.

The same seam should also support future SQL-backed storage, especially:

The algebra should target a storage interface, not an HDT-only worldview. That same interface family should be able to host:

Corpus Shape#

Factoidal should not be treated as one monolithic always-live SPARQL dataset.

The better model is:

In that model:

This means named graphs are not merely SPARQL syntax. They become units of:

HDT Position#

HDT should be treated as a physical storage backend, not as a parser replacement.

For now the safer dataset design is:

This avoids making correctness depend on HDT-native quad support.

For quad-aware storage, the native target should be an F*-defined HDTQ-style dataset backend, not an opaque external engine. See also:

For the current dataset-storage focus, COTTAS should be treated as a first-class native target too:

Questions To Keep In Scope#

Can Factoidal serialize its own graphs to binary on-disk data?#

Yes, in principle, but there are two distinct meanings:

  1. Factoidal-specific binary persistence
  2. Standard HDT-compatible serialization

The first is easier. We already own the RDF term and triple structures, so an F*/OCaml backend could serialize:

The second is harder because it means conforming to HDT container and index structure, not just inventing our own binary store.

Recommended stance:

Can the HDT structure also serve as an in-memory ephemeral index?#

Yes, conceptually.

The useful split is:

That physical layer could be:

So the abstraction should not be named too narrowly around files. It should be closer to:

This allows one API to cover:

Can one in-memory corpus contain several indexed ephemeral graphs?#

Yes. The same store abstraction should support:

That implies that Corpus eventually needs a runtime representation as well as an on-disk layout. The runtime representation should not assume every graph comes from an HDT file.

Immediate Refactor Targets#

  1. Introduce triple_pattern_bound, graph_store, and rdf_dataset_store types in the algebra layer.
  2. Implement a list-backed default store so current semantics stay unchanged.
  3. Rewrite eval_single_tp to use store_search.
  4. Add cardinality-estimate hooks for future BGP reordering.
  5. Later, route named graph lookup through dataset stores backed by TOC/HDT metadata.

Constraints#

See also#