Skip to content

Use case: reasoning & inference

little big brain can answer questions using facts you never explicitly wrote, by deriving them from the schema statements you did write. Every SPARQL read carries an entailment control that selects the reasoning regime for that one query:

entailment What a query matches
none (default) The facts exactly as written.
subclass Adds the asserted rdfs:subClassOf closure: a query for a broad class also matches its subclasses.
rdfs Adds subproperty value propagation and domain/range type derivation on top of subclass.
owl Adds the OWL vocabulary on top of rdfs: equivalence, inverse, symmetric, and transitive properties, property chains, class constructors, restriction rules, and owl:sameAs identity.

Reasoning is deterministic and snapshot-consistent: the regime is evaluated at query time against the schema triples of the pinned published snapshot, the same answer comes back every time for the same snapshot, and a time-travel pin (as_of_valid_time, as_of_commit_seq) reasons over the graph as it was. There is nothing to rebuild and nothing to republish when the schema changes: the next generation’s queries read the next schema.

Write ordinary RDFS schema triples with your data:

ex:ElectricCar rdfs:subClassOf ex:Car .
ex:Car rdfs:subClassOf ex:Vehicle .
ex:tesla3 a ex:ElectricCar .

A default query matches asserted triples only, so ?v a ex:Vehicle returns nothing here. Under entailment: "subclass" (or any broader regime) the same query returns ex:tesla3, without duplicating any facts. The mode works on already-published data, and a schema change takes effect with the next published generation.

# Default: exact-type matching only.
lbb.sparql("SELECT ?v WHERE { ?v a <https://example.com/Vehicle> }")
# Subclass closure: matches Vehicle and all its subclasses.
lbb.sparql(
"SELECT ?v WHERE { ?v a <https://example.com/Vehicle> }",
entailment="subclass",
)

entailment: "rdfs" applies the practical RDFS core: subclass membership and transitivity, subproperty transitivity and value propagation (a query for rdfs:label matches values written under a declared subproperty), and domain/range type derivation (a subject of hasPet is a Person when the schema declares that domain).

entailment: "owl" is a strict superset of rdfs. On top of the RDFS core it applies, from the asserted OWL schema triples:

  • Equivalence: owl:equivalentClass and owl:equivalentProperty share members and values in both directions.
  • Property semantics: owl:inverseOf answers a triple from either direction, owl:SymmetricProperty matches both orders, owl:TransitiveProperty closes chains of the property and its subproperties, and bounded acyclic owl:propertyChainAxiom declarations derive head properties. One chain may use another chain head, up to eight composition levels and 256 expanded path terms.
  • Class constructors: owl:unionOf operands are subclasses of the union, owl:intersectionOf decomposes and derives joint membership, and owl:oneOf enumerations declare their members.
  • Restrictions: owl:hasValue derives membership from an entailed property value and the value from membership, owl:someValuesFrom derives membership from an entailed filler-typed neighbor, and owl:allValuesFrom types objects reached by an entailed restricted property. These rules compose with inverse, symmetric, transitive, subproperty, property-chain, and hasValue-derived assertions.
  • Identity: asserted owl:sameAs cliques make a constant match through any member and a variable bind every member.
lbb.sparql(
"SELECT ?who WHERE { <https://example.com/rex> <https://example.com/ownedBy> ?who }",
entailment="owl",
)
# Answers through the declared inverse of owns, no ownedBy triple stored.

A schema outside the supported envelope fails closed with a typed error instead of returning incomplete answers: a closure over the size cap, a recursive, over-depth, or over-expanded property-chain composition, or an owl:sameAs identity set over its caps refuses entailment: "owl" while asserted queries keep working. Existential superclasses, cardinality-derived inference, and owl:imports are out of scope for the regime; cardinality-style declarations are checked as validation in the published conformance report.

The regimes stay inside the engine’s normal query bounds:

  • The schema closure is extracted once per published generation, on the first entailed query, and cached; queries after that pay only their own pattern work.
  • A query whose patterns the schema does not mention runs the same plan with and without entailment.
  • Transitive and chain reach evaluate as guided index traversals from the bound end of the pattern, under the same read deadline as every query.
  • Aggregations over large entailed classes scan the class members; the answer is exact and the cost is proportional to the member count.

A branch’s stored inference rules run when a generation is published, and the derived edges are part of the asserted dataset every query reads. There is no query-time rule switch: requesting reason: true returns a typed error pointing at the entailment regimes.

An AI agent should not have to re-derive what the system can entail. Reasoning gives an agent:

  • Deterministic derivation. Transitive relationships, classifications, and type generalizations are computed the same way every run, while ad-hoc LLM reasoning varies from call to call and consumes tokens.
  • Broader answers without more writes. A query for a broad concept returns its specific instances through the closure, so the agent does not have to enumerate every subtype.
  • One identity for one thing. owl:sameAs lets an agent write facts under the identifier it knows and read the facts written under every equivalent identifier.

See why RDF & SHACL suit AI agents for how this fits an agent’s write loop.