Sensemaking AI · Sensemaking Semantic Web
Submodule 1.2 · Foundations

SPARQL, deeper.

Five query patterns beyond the basics — DESCRIBE, UNION, property paths, FILTER NOT EXISTS, and VALUES — applied to a graph of Greek and Roman deities. Start Fuseki before you begin.

Module 1 · Weeks 1–3 Requires Fuseki + starter kit ~90 min hands-on DESCRIBE · UNION · paths · VALUES
Dataset Naruto Greek mythology
Checking for Fuseki at localhost:3030…

This picks up where 1.1 left off.

The five query patterns here — DESCRIBE, UNION, property paths, FILTER NOT EXISTS, VALUES — build on the SELECT, GROUP BY, ASK, OPTIONAL, and CONSTRUCT patterns in the 1.1 workbook. If those patterns still feel uncertain, work through the 1.1 mythology workbook before continuing here.

The mythology domain has a different structure than the Naruto dataset. Deities belong to realms rather than teams. Relationships are championed and hasPower rather than senseiOf and hasJutsu. The sensemaking: prefix is bound to https://sensemaking-ai.com/ns/mythology# — these queries will not return results against the Naruto dataset.

Loading the mythology data

From the starter-kit root: fuseki-server --config=fuseki/config.ttl. In the Fuseki UI, update the dataset to point at data/mythology.ttl. The sensemaking: prefix in these queries is https://sensemaking-ai.com/ns/mythology# — different from the Naruto workbook's https://sensemaking-ai.com/ns/example#. Mixing the two datasets will return empty results.

Why both domains?

The mythology domain forces you to read the data rather than rely on Naruto knowledge. If a query returns nothing, you cannot guess what should be there — you have to look at the file. That is the more honest test of whether you understand the query, not the data.

The ideas behind these queries.

If you've worked through the Sub-module 1.2 synthesis doc, skip ahead — this section condenses that material for quick reference. If you haven't, expand below before running the query lab.

Core SPARQL concepts — expand to review

The endpoint model

A SPARQL endpoint is an HTTP service: you POST a query, you get results back. Two endpoints in this curriculum:

  • Local Fuseki at localhost:3030 — your data, no rate limits, no internet required.
  • Wikidata at query.wikidata.org — one of the largest open knowledge graphs, read-only, rate-limited, with Wikidata-specific extensions (SERVICE wikibase:label).

Query anatomy

① PREFIX declarations — short aliases for full IRIs
PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

② SELECT clause — which variables to project
SELECT ?name ?realmName

③ WHERE clause — graph pattern that must match
WHERE {
  ?deity a sensemaking:Deity ;
         schema:name ?name ;
         sensemaking:memberOfRealm ?realm .
  ?realm schema:name ?realmName .
  FILTER (LANG(?realmName) = "en")
}

④ Solution modifiers — ORDER BY, LIMIT, GROUP BY
ORDER BY ?realmName ?name

The four query forms

FormReturnsUse when
SELECTTable of variable bindingsYou want a list of facts — the everyday form.
ASKtrue / falseYou only need to know whether a pattern exists.
CONSTRUCTA new RDF graphYou want to derive or transform triples.
DESCRIBEAll known facts about a URIYou're exploring an unknown resource.

Three things that surprise people

  • The LANG tag trap. The mythology dataset has Greek (@el) and Latin (@la) labels on every deity. A query binding rdfs:label without a LANG filter returns two rows per deity. Always add FILTER (LANG(?label) = "la") (or "en" for realm names) when working with this data.
  • OPTIONAL is a left join. A deity with two powers appears twice in results. Use GROUP_CONCAT or restructure to collapse to one row.
  • Plain SPARQL sees only what's in the store. OWL property declarations (symmetric, inverse) have no effect without a reasoner. Module 2 is where that changes.

Full detail, query anatomy diagrams, and three live Wikidata queries: Sub-module 1.2 synthesis doc.

Eight deities, three realms, intentional gaps.

Three patterns in mythology.ttl that are directly relevant to this workbook's queries.

# championed: directed, Zeus sponsors three
sensemaking:Zeus
    sensemaking:championed
        sensemaking:Athena ,
        sensemaking:Apollo ,
        sensemaking:Ares .

sensemaking:Poseidon
    sensemaking:championed
        sensemaking:Triton .
championed is not symmetric. Zeus champions Athena; there is no triple stating Athena champions Zeus. Query q02 uses UNION to find deities who appear on either side of championed. Query q03 uses a property path to chain championed into a power lookup in one step. Challenge C3 asks who Zeus can reach transitively via championed.
# hasPower: not all deities have it
sensemaking:Apollo
    sensemaking:hasPower sensemaking:Prophecy .
sensemaking:Athena
    sensemaking:hasPower sensemaking:Wisdom .
sensemaking:Poseidon
    sensemaking:hasPower sensemaking:SeasAndEarthquakes .
sensemaking:Zeus
    sensemaking:hasPower sensemaking:Thunder .

# Ares: intentionally no hasPower triple
Ares, Hades, Persephone, and Triton have no hasPower triple. This is intentional — not a mistake. Query q04 uses FILTER NOT EXISTS to find exactly these deities. The open-world distinction matters: "no power asserted here" is not the same as "no power." Ares is the god of war; his domain simply is not represented in this dataset.
# Greek (el) and Latin (la) labels
sensemaking:Ares rdfs:label
    "Ἄρης"@el ,
    "Mars"@la .

sensemaking:Zeus rdfs:label
    "Ζεύς"@el ,
    "Iuppiter"@la .

# Realms also have bilingual schema:name
sensemaking:Olympians schema:name
    "Olympians"@en ,
    "Caelestes"@la .
Language-tagged literals multiply rows without a LANG filter. A query that binds ?label to rdfs:label without filtering returns two rows per deity — one Greek, one Latin. The q02 UNION query uses schema:name (untagged) to avoid this. The q05 VALUES query uses Greek names as IRIs, not labels — IRIs are always unambiguous regardless of language.

Five patterns, five queries.

The same five patterns as the Naruto workbook — DESCRIBE, UNION, property path, FILTER NOT EXISTS, VALUES — applied to mythology data. Read the data section above and predict each output before running the query.

q01
Tell me everything the dataset knows about Zeus.
Pattern: DESCRIBE · all outgoing triples for a named resource
Open Fuseki ↗
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

DESCRIBE sensemaking:Zeus
q02
Which deities either have a power listed OR are in the Underworld?
Pattern: UNION · merge two independent conditions · DISTINCT deduplication
Open Fuseki ↗
PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT DISTINCT ?name ?reason WHERE {
  {
    ?deity sensemaking:hasPower ?power .
    ?deity schema:name ?name .
    BIND("has power" AS ?reason)
  }
  UNION
  {
    ?deity sensemaking:memberOfRealm sensemaking:Underworld .
    ?deity schema:name ?name .
    BIND("underworld" AS ?reason)
  }
}
ORDER BY ?reason ?name
q03
Which champions sponsored a deity who has the power of prophecy?
Pattern: property path · / (sequence) chains championed into hasPower
Open Fuseki ↗
PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT ?championName WHERE {
  ?champion schema:name ?championName ;
            sensemaking:championed/sensemaking:hasPower
                sensemaking:Prophecy .
}
ORDER BY ?championName
q04
Which deities have no powers listed in the dataset?
Pattern: FILTER NOT EXISTS · closed-world query on an open-world dataset
Open Fuseki ↗
PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT ?name WHERE {
  ?deity a sensemaking:Deity ;
         schema:name ?name .
  FILTER NOT EXISTS {
    ?deity sensemaking:hasPower ?p .
  }
}
ORDER BY ?name
q05
Show me the realm and any powers for these three specific deities.
Pattern: VALUES · inline data · parameterized lookup with OPTIONAL
Open Fuseki ↗
PREFIX rdfs:        <http://www.w3.org/2000/01/rdf-schema#>
PREFIX schema:      <https://schema.org/>
PREFIX skos:        <http://www.w3.org/2004/02/skos/core#>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT ?name ?realmName ?powerLabel WHERE {
  VALUES ?deity {
    sensemaking:Zeus
    sensemaking:Ares
    sensemaking:Poseidon
  }
  ?deity schema:name ?name ;
         sensemaking:memberOfRealm ?realm .
  ?realm schema:name ?realmName .
  FILTER (LANG(?realmName) = "en")
  OPTIONAL {
    ?deity sensemaking:hasPower ?power .
    ?power skos:prefLabel ?powerLabel .
    FILTER (LANG(?powerLabel) = "en" || LANG(?powerLabel) = "")
  }
}
ORDER BY ?name

Four things to build.

Write each query before opening the solution panel.

C1 Find all deities involved in a championed relationship — either side

championed is asserted one way: Zeus championed Athena, Apollo, Ares; Poseidon championed Triton. Use UNION to find all deities who appear on either side of a championed triple. Return each name once (DISTINCT). Who is a champion, who is championed, and who is neither?

Expected result and one approach

Expected: 6 rows — Apollo, Ares, Athena, Poseidon, Triton, Zeus. Hades and Persephone appear in neither role — they are in the Underworld, not part of the championing structure.

PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT DISTINCT ?name WHERE {
  {
    ?d sensemaking:championed ?other .
    ?d schema:name ?name .
  }
  UNION
  {
    ?other sensemaking:championed ?d .
    ?d schema:name ?name .
  }
}
ORDER BY ?name
C2 Use an inverse path to find all deities championed by a given sponsor

The ^ operator inverts a path. Use ^sensemaking:championed starting from a specific deity to find who championed them. Write a query that finds which deity championed sensemaking:Apollo, using the inverse path rather than traversing the triple in its asserted direction.

Expected result and one approach

Expected: 1 row — Zeus (Zeus championed Apollo, so Apollo is championed-by Zeus).

PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT ?sponsorName WHERE {
  ?sponsor ^sensemaking:championed sensemaking:Apollo ;
           schema:name ?sponsorName .
}

Equivalently: ?sponsor sensemaking:championed sensemaking:Apollo traverses the triple in its natural direction. ^championed is useful when you only know the object side and want to "walk back" to the subject — the same query, from the other end.

C3 Find all deities Zeus can reach transitively via championed

Use sensemaking:championed+ (one-or-more hops) starting from Zeus to find every deity reachable through the championed relationship — directly or indirectly. With this dataset, how deep does the chain go? Return the reachable deities and their names.

Expected result and one approach

Expected: 3 rows — Apollo, Ares, Athena. Zeus champions these three directly; none of them champion anyone else in this dataset, so there are no second-hop reachable nodes.

PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT DISTINCT ?reachableName WHERE {
  sensemaking:Zeus sensemaking:championed+ ?reachable .
  ?reachable schema:name ?reachableName .
}
ORDER BY ?reachableName

If Ares championed a fourth deity, + would include that deity too — that is the transitive closure. With a single hop, you would need to know the chain length in advance and write it explicitly. + handles arbitrary depth.

C4 Combine UNION and FILTER NOT EXISTS to find uninvolved Olympians

Find all Olympians (members of sensemaking:Olympians) who are neither a champion of anyone nor championed by anyone. In other words: Olympians who appear in no championed triple on either side. Return their names.

Expected result and one approach

Expected: 0 rows — every Olympian in this dataset either champions someone (Zeus) or is championed by Zeus (Athena, Apollo, Ares). If you had an Olympian with no championed relationship, they would appear here.

PREFIX schema:      <https://schema.org/>
PREFIX sensemaking: <https://sensemaking-ai.com/ns/mythology#>

SELECT ?name WHERE {
  ?deity sensemaking:memberOfRealm sensemaking:Olympians ;
         schema:name ?name .
  FILTER NOT EXISTS {
    { ?deity sensemaking:championed ?other . }
    UNION
    { ?other sensemaking:championed ?deity . }
  }
}
ORDER BY ?name

FILTER NOT EXISTS with a UNION inside it: the filter removes rows where either direction of the championed relationship exists. The result — zero rows — tells you something about the structure of this dataset: all four Olympians are woven into the championing network. This is a useful pattern for finding "isolated" nodes in any graph.

Five good next reads.

Query reference

Learning SPARQL

DuCharme. Chapters 3–4 cover property paths, aggregation, and CONSTRUCT in depth. The natural next step from both 1.2 workbooks.

Synthesis doc

Sub-module 1.2 synthesis

The reading companion for this workbook. Covers the four query forms conceptually and has three live Wikidata queries to run on the public endpoint.

Public endpoint

Wikidata Query Service

Apply UNION and property paths on a large, real dataset. The mythology domain is actually well-represented in Wikidata — try looking up these same deities there.

W3C spec

SPARQL 1.1 specification

Section 9 (property paths) is authoritative on /, +, *, ^, and |. Read it when path behavior surprises you.

Domain variant

Naruto workbook

Same five patterns on the Naruto dataset. If you found the mythology domain unfamiliar, the Naruto workbook applies the same queries to data you can verify from general knowledge.

Module context

Module 1 README

The exercise list and primary project. The SPARQL patterns in both 1.2 workbooks map directly to the queries Exercise 1.3 asks you to write against your own Resume Graph data.

Cheatsheet

Module 1 SPARQL quick-reference (coming soon)

Prefix block, query anatomy, all five query patterns from this workbook — one-page reference card. Available when Module 1 materials are complete.