Sensemaking AI · Sensemaking Semantic Web
Submodule 3.1 · Reasoning ★

Inferencing.

What a reasoner actually computes. RDFS vs OWL entailment regimes, the cascade from property declarations, materialization tradeoffs — and the promise made in Module 2's Challenge C4, finally paid off.

Module 3 · Weeks 7–9 ★ Hardest module — pace accordingly Requires Protégé + Fuseki inferencing · HermiT · entailment
Checking for Fuseki at localhost:3030…

The thread that's been building since 1.1.

Submodule 1.1 workbook, Challenge C4: "rivalOf is declared owl:SymmetricProperty. Does a plain SPARQL query pick up the inferred triples?" The answer was no. Submodule 2.1 showed the inference in Protégé with HermiT. Submodule 2.2 named the property characteristics that trigger reasoning. This submodule explains the full mechanism — what a reasoner actually computes and when, and what you can rely on versus what surprises you.

What changes in Module 3

Modules 1 and 2 established that you can declare schema rules and observe their effects in Protégé. Module 3 establishes that you can reason over those rules in production — and that doing so has costs, tradeoffs, and failure modes that matter for real systems. The conceptual shift: from "reasoning as a demo" to "reasoning as infrastructure."

What to load

This submodule runs queries against the Naruto ontology from Module 2. Load modules/02-modeling/artifacts/naruto-ontology/naruto-ontology-starter.ttl into Fuseki. The query lab also references the extended ontology with the OWL restriction you added in Submodule 2.2 — if you saved that as naruto-ontology-restricted.ttl, load it as well or substitute it for the starter.

Not all reasoning is the same reasoning.

When Fuseki loads RDF data without a configured reasoner, it returns only explicitly asserted triples. That is the simple entailment regime — the most conservative setting. More expressive regimes add derived triples based on vocabulary declarations.

RegimeWhat it derivesHow to enable
Simple Nothing. Only asserted triples. Default in Fuseki.
RDF entailment Typing of triples themselves (each triple's predicate a rdf:Property), container membership. Enable in Fuseki config: ja:reasoner [ja:reasonerURL <...RDFS>].
RDFS entailment Subclass/subproperty inheritance, domain/range inferences. What Submodule 2.1 demonstrated. Fuseki config with RDFS reasoner or --rdfs schema.ttl flag.
OWL DL entailment Property characteristics (symmetric, transitive, inverse, functional), restrictions (someValuesFrom, allValuesFrom, cardinality), class equivalences, disjointness. Load into Protégé + HermiT or Pellet. Or configure Fuseki with Jena's OWL reasoner (slower, not OWL-Full).
SPARQL-native (materialized) Whatever you CONSTRUCT and INSERT into the store. Full control, no magic. SPARQL CONSTRUCT + INSERT DATA or SPARQL Update.

Most production systems do not run a full OWL DL reasoner at query time — the cost is prohibitive at scale. They either materialize inferences offline (compute once, store, refresh on schedule) or use lighter RDFS entailment for the few rules that matter. Knowing which entailment regime your store is operating under is essential for debugging surprising query results.

The most common confusion

Declaring naruto:rivalOf a owl:SymmetricProperty does not make Fuseki derive the reverse triples automatically. It declares the rule to any reasoner that reads the ontology. Whether a reasoner acts on it depends entirely on which entailment regime is active. Fuseki in simple mode ignores it. HermiT in Protégé acts on it. This is why "I declared it in the ontology but the query doesn't see it" is the most common Module 2→3 confusion.

One declaration triggers many derivations.

OWL declarations compose. A single set of well-designed property declarations triggers a cascade of inferences. The Exercise 3.1 example from the Module 3 README illustrates this cleanly:

# Declare senseiOf as a sub-property of colleagueOf
naruto:senseiOf rdfs:subPropertyOf naruto:colleagueOf .

# Declare colleagueOf symmetric
naruto:colleagueOf a owl:SymmetricProperty .

# Declare an instance
naruto:JiraiyaSannin naruto:senseiOf naruto:NarutoUzumaki .

From these three statements, a reasoner derives:

The cascade is: one fact + two schema rules = two derived facts. And critically, the schema rules prevent an unwanted third derivation that would be semantically wrong. The OWL property declarations are doing design work, not just documentation.

Declaring a contradiction and what happens

A useful exercise: add a contradictory assertion and observe the reasoner's response.

# Declare senseiOf asymmetric (A teaches B → B does NOT teach A)
naruto:senseiOf a owl:AsymmetricProperty .

# Now add a circular teaching relationship — this contradicts asymmetry
naruto:NarutoUzumaki naruto:senseiOf naruto:JiraiyaSannin .

HermiT will flag the ontology as inconsistent — because AsymmetricProperty on senseiOf means if Jiraiya teaches Naruto, then Naruto cannot also teach Jiraiya. The reasoner found the logical contradiction. This is what consistency checking is for: catching modeling errors before they silently propagate into wrong query results.

The transitivity trap revisited

Declaring any property owl:TransitiveProperty triggers the reasoner to compute the full transitive closure. On the Naruto graph with 87 characters and complex relationship chains, a transitive familyOf or colleagueOf property would force the reasoner to traverse every path in the graph for every query. This is why the naruto-ontology-starter.ttl has a comment explicitly documenting the decision NOT to declare transitivity. Transitivity should always be a deliberate, scope-bounded decision.

Compute once vs compute always.

Two strategies for making inferred triples available to SPARQL queries:

Most production systems use materialization for OWL DL inferences and query-time reasoning for lightweight RDFS rules. The boundary is set by performance requirements and data change frequency. There is no universal right answer.

SPARQL CONSTRUCT is the manual version of materialization — you write the inference rule explicitly in SPARQL and INSERT the results. It gives full control at the cost of maintaining the rule yourself rather than declaring it in the ontology. The query lab below includes a CONSTRUCT-as-materialization example.

Watch the inference cascade live — Exercise 3.1.

Exercise 3.1 walkthrough — open to expand all steps
1 Load the Naruto ontology and add new property declarations expand

Open naruto-ontology-starter.ttl in Protégé (or your extended version from Module 2). Do not start the reasoner yet.

In the Object Properties tab, create two new object properties:

  1. Create naruto:colleagueOf: click the Add Object Property button (⊕), name it colleagueOf. In the Description panel, add the characteristic Symmetric. Set domain and range: naruto:Ninja.
  2. Select the existing naruto:senseiOf property. In the Description panel, add a Sub Property Of relationship pointing to naruto:colleagueOf.
Screenshot: Object Properties tab showing naruto:senseiOf selected. Description panel shows "Sub Property Of: naruto:colleagueOf" in the SubPropertyOf section. Property hierarchy on the left shows colleagueOf with senseiOf nested under it.
2 Add a new individual with a senseiOf assertion expand

In the Individuals by class tab, select naruto:Ninja. Add a new individual: naruto:JiraiyaSannin. Add:

  1. Data property: naruto:canonicalName = "Jiraiya"^^xsd:string
  2. Object property assertion: naruto:senseiOf naruto:NarutoUzumaki
  3. Object property assertion: naruto:memberOfVillage naruto:VillageHiddenLeaf
Screenshot: Individuals tab, naruto:JiraiyaSannin selected. Property Assertions panel shows the two object property assertions and one data property assertion as asserted facts.
3 Run HermiT and observe the cascade expand

Reasoner → HermiT → Start Reasoner. Wait for the status bar to show "Synchronized."

Select naruto:JiraiyaSannin. In the inferred property assertions panel, look for:

  • naruto:colleagueOf naruto:NarutoUzumaki — derived from subPropertyOf

Now select naruto:NarutoUzumaki. In the inferred panel, look for:

  • naruto:colleagueOf naruto:JiraiyaSannin — derived from symmetry of colleagueOf
  • naruto:studentOf naruto:JiraiyaSannin — derived from inverseOf(senseiOf)

Crucially, naruto:senseiOf naruto:JiraiyaSannin does NOT appear for Naruto — senseiOf is not symmetric, and the reasoner correctly does not derive the reverse.

Screenshot: Individuals tab, naruto:NarutoUzumaki selected with reasoner active. Inferred property assertions show colleagueOf and studentOf; the asserted section shows only the original assertions from the TTL.
4 Add a contradiction and watch the reasoner complain expand

Stop the reasoner. Select naruto:senseiOf in the Object Properties tab. Add the characteristic Asymmetric.

Now also add a contradictory assertion in the Individuals tab: select naruto:NarutoUzumaki and add object property assertion naruto:senseiOf naruto:JiraiyaSannin.

Start HermiT again. Because senseiOf is now asymmetric (if A teaches B then B does NOT teach A), having both directions asserted is a logical contradiction. The reasoner will mark the ontology as inconsistent — you may see a red error banner or the class hierarchy collapse to show only owl:Nothing.

Undo: remove the asymmetric characteristic from senseiOf and remove the contradictory assertion. Restart the reasoner to restore consistency.

Screenshot: Protégé with the inconsistency active. Red highlighting on the ontology or class hierarchy showing owl:Nothing as a subclass of everything, indicating the reasoner found a logical contradiction.
5 Export the inferred ontology expand

With the reasoner active and no contradictions: Reasoner → Compute Inferences, then File → Save As. Save as naruto-ontology-inferred.ttl in the artifacts folder. This is the materialized graph — the full set of asserted + inferred triples in one file.

Compare the file size to the original starter TTL. The inferred version is larger: it contains all the derived triples that HermiT computed. Load both into Fuseki and compare query results for the same SPARQL query — plain SPARQL will return identical results from both, because the plain store doesn't know the difference between asserted and inferred triples once materialized.

Screenshot: File save dialog or text editor showing naruto-ontology-inferred.ttl with noticeably more content than the starter — the extra lines are the materialized inference results.

Five queries — schema introspection and inference demonstration.

Queries q01–q03 run against the starter ontology in Fuseki (simple entailment — no reasoner). They show what's explicitly in the store. q04–q05 show how SPARQL CONSTRUCT can manually materialize the inferences you observed in Protégé.

q01
Which properties have entailment-triggering characteristics declared?
Pattern: introspecting OWL declarations · querying the schema to understand what a reasoner would fire
Open Fuseki ↗
PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl:    <http://www.w3.org/2002/07/owl#>
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

SELECT ?property ?label ?characteristic WHERE {
  ?property a owl:ObjectProperty ; rdfs:label ?label .
  VALUES ?characteristic {
    owl:SymmetricProperty owl:TransitiveProperty
    owl:FunctionalProperty owl:AsymmetricProperty
    owl:InverseFunctionalProperty owl:ReflexiveProperty
    owl:IrreflexiveProperty
  }
  ?property a ?characteristic .
  FILTER (LANG(?label) = "en" || LANG(?label) = "")
}
ORDER BY ?characteristic ?label
q02
What does plain SPARQL see for rivalOf — vs what a reasoner would derive?
Pattern: documenting the plain vs reasoned gap · UNION for both directions
Open Fuseki ↗
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

# What plain SPARQL sees: only asserted direction
SELECT ?aName ?bName ("asserted" AS ?source) WHERE {
  ?a naruto:rivalOf ?b ;
     naruto:canonicalName ?aName .
  ?b naruto:canonicalName ?bName .
}
UNION
# What a reasoner would add: the symmetric direction
{
  ?b naruto:rivalOf ?a .
  ?a naruto:canonicalName ?aName .
  ?b naruto:canonicalName ?bName .
  FILTER NOT EXISTS { ?a naruto:rivalOf ?b . }
  BIND("reasoner-derived" AS ?source)
}
ORDER BY ?source ?aName
q03
What would RDFS entailment derive from the class hierarchy?
Pattern: simulating RDFS entailment with property paths · subClassOf transitive closure
Open Fuseki ↗
PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
PREFIX schema: <https://schema.org/>
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

# Every class that naruto:Ninja is a subclass of (transitively)
SELECT DISTINCT ?superclass WHERE {
  naruto:Ninja rdfs:subClassOf+ ?superclass .
}
ORDER BY ?superclass
q04
CONSTRUCT: materialize the subPropertyOf inference (senseiOf → colleagueOf).
Pattern: CONSTRUCT as manual entailment · subPropertyOf derivation without a reasoner
Open Fuseki ↗
PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

CONSTRUCT {
  ?sensei naruto:colleagueOf ?student .
  ?student naruto:colleagueOf ?sensei .
}
WHERE {
  ?sensei naruto:senseiOf ?student .
  # senseiOf rdfs:subPropertyOf colleagueOf (declared in ontology)
  # colleagueOf is symmetric (declared in ontology)
  # This CONSTRUCT replicates what an RDFS+OWL reasoner would derive.
}
q05
What does the naruto-ontology-inferred.ttl contain that the starter doesn't?
Pattern: comparing asserted vs materialized · counting additional triples by type
Open Fuseki ↗
PREFIX owl:    <http://www.w3.org/2002/07/owl#>
PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

# Load naruto-ontology-inferred.ttl into a second Fuseki dataset,
# then compare triple counts by predicate type between the two datasets.
# This query runs against the INFERRED dataset to show what was added.

SELECT ?predicate (COUNT(*) AS ?tripleCount) WHERE {
  ?s ?predicate ?o .
  FILTER (STRSTARTS(STR(?predicate),
         "https://sensemaking-ai.com/ns/naruto#"))
}
GROUP BY ?predicate
ORDER BY DESC(?tripleCount)

Reading and next steps.

Primary reading

Allemang et al. — Ch 9–10

Chapter 9 covers OWL reasoning in depth; Chapter 10 covers inference rules and their interaction with open-world semantics. Front-load this in Week 7 before the Protégé walkthrough.

Reference

W3C OWL 2 Profiles

Each profile's introduction explains what is gained and lost relative to OWL Full. Read EL and DL introductions side by side to understand why HermiT (which implements DL) is more expressive but slower than EL reasoners.

Background

Knowledge Graphs, Section 6

Hogan et al. — deductive knowledge. The clearest single-source explanation of the relationship between OWL, entailment, and what a triplestore can claim to know. Free at kgbook.org.

Starter data

Naruto ontology starter

The Module 2 artifact used in this workbook. Load into Protégé for the Exercise 3.1 walkthrough. The property characteristics already declared (symmetric, inverseOf) are what triggers the cascade observed in Step 3.

Next submodule

Submodule 3.2 — Reification

The four approaches for annotating individual triples with provenance. Itachi's backstory is the canonical teaching example — contested canon with multiple sources is exactly where reification earns its complexity cost.

Cheatsheet

Module 3 reasoning quick-reference (coming soon)

OWL property characteristics, entailment regimes, inference cascade examples, and the materialization decision tree — one page. Available when Module 3 materials are complete.