« Phase 07 · Warmup · Track Overview
Hitchhiker's Guide — Financial Knowledge Graphs
The 30-second mental model
Vectors find text that resembles the question. Graphs answer questions about paths.
"Which counterparties are ultimately controlled by a sanctioned entity" is a path — four documents each say one hop, none of them shares vocabulary with the question, and no embedding composes hops.
Then the two-sentence version of the whole phase:
- OWL infers, SHACL validates.
- The reason you need both is the open-world assumption: what is not stated is unknown, not false — so OWL can never tell you a record is incomplete, which is exactly the KYC question.
The data model
(subject, predicate, object) subject: always an IRI
predicate: always an IRI
object: an IRI or a LITERAL
A literal is never a subject. You say things about entities, not about strings — which is why
rdfs:range can type an IRI object and never a literal one.
A graph is a set. Asserting twice changes nothing, and that idempotence is what makes forward chaining terminate.
RDF vs LPG
| RDF | LPG (Neo4j) | |
|---|---|---|
| Identity | global IRIs | local ids |
| Edge properties | reification (awkward) | native |
| Semantics | RDFS/OWL, standard | none |
| Validation | SHACL | your code |
| Query | SPARQL (W3C) | Cypher (vendor) |
| Federation | native | no |
Rule: RDF when meaning must cross an organizational boundary. LPG when the graph is yours and edges carry data. In a bank, often both — FIBO-aligned RDF as the vocabulary of record, an LPG for path analytics.
The four OWL constructs that earn their keep
| Construct | Does | Why it matters here |
|---|---|---|
owl:TransitiveProperty | A→B, B→C ⟹ A→C | ultimate beneficial ownership is transitive closure |
owl:inverseOf | controls ⟷ controlledBy | traverse either direction, store once |
owl:SymmetricProperty | A→B ⟹ B→A | isCounterpartyOf, isAffiliateOf |
rdfs:subPropertyOf | majorityOwns ⟹ controls | encode a regulatory definition of control once |
And the composition that is the phase's headline:
Northgate majorityOwns Acme ← asserted
majorityOwns subPropertyOf controls ← ontology (rdfs7)
controls a owl:TransitiveProperty ← ontology (owl)
──────────────────────────────────────────────────
Meridian controls Acme ← nobody asserted this
SPARQL property paths
| Path | Means |
|---|---|
p | one hop |
p+ | one or more — transitive closure |
p* | zero or more (includes the start) |
^p | inverse |
p1/p2 · p1|p2 · p? | sequence · alternative · optional |
SELECT ?owner WHERE {
?owner bank:controls+ ent:Acme .
?owner bank:onSanctionsList true .
}
Three hops. One query. The alternatives are a recursive CTE nobody can review or a hand-written traversal with a bug in its visited set.
One-liners
rdfs:domainis an inference rule, not a constraint. It concludes a type; it rejects nothing.- Entailment is monotone — adding facts never retracts a conclusion. That is what makes materialization a valid cache.
- Deletion breaks the cache, and derived triples look exactly like asserted ones.
- Validate after materializing, or nodes typed only by inference are silently skipped.
OPTIONALis a left join. Inner-joining onlegalNamehides the shell company — the entity you most want to see.- Variables are the join. There is no
ONclause because shared names are the condition. - Cycles are real (circular shareholdings), so both the reasoner and the walker need a visited
set — and
controls+will say A controls itself. - OWL 2 RL is the tractable, rule-based profile. Full DL needs a tableau reasoner.
- Subclass FIBO; never modify it. Modifying it destroys the shared meaning you adopted it for.
- Never reuse an IRI for a different concept.
- Bound your neighbourhood expansion, or it is a context-window incident.
Vocabulary
IRI · a global identifier. CURIE · prefix:local, expanded before use. Literal · a
value, never a subject. Triple / quad · a statement, optionally in a named graph.
Entailment · what follows without being said. Materialization · storing the entailed
closure. Forward / backward chaining · derive up front vs at query time. Monotonic ·
adding facts never retracts. OWA · open-world assumption. Reification · representing a
statement as a node, to say things about it. Shape / focus node / validation report · SHACL's
three nouns. BGP · basic graph pattern. Property path · p+, ^p, etc. FIBO · the
EDM Council's financial ontology. n10s · Neo4j's RDF bridge.
War stories
The KYC query that hid the shell. An inner join on legalName in the ownership query. The
entity with no name and no LEI — the one an analyst most wants to see — was silently absent from
every result. OPTIONAL would have surfaced it.
The closure that went stale. A majorityOwns triple was corrected, the derived controls
closure was not recomputed, and an ownership report was wrong for six weeks. Nothing errored;
derived triples look exactly like asserted ones.
The traversal that never returned. Two companies owning each other — a legitimate and common structure. No visited set. The job ran until it was killed.
The https prefix. A full IRI passed to a CURIE expander, parsed as prefix https, and the
resulting KeyError sent someone looking for a missing namespace declaration for an hour.
The second, worse schema. No ontology owner. Every team added the classes it needed, nothing aligned, and after a year the bank had the mapping problem it adopted RDF to avoid — plus an unfamiliar query language.
Reasoning that took the graph down. Full OWL 2 DL reasoning enabled on a live store "because it's more complete". Know the profiles; RL is the one designed for this.
The two-hop expansion that blew the context. Neighbourhood expansion with no predicate restriction on a well-connected entity. Several hundred entities into a prompt.
Beginner mistakes
- Expecting OWL to catch missing data.
- Reading
rdfs:domainas a constraint. - Validating before materializing.
- No visited set on a transitive walk.
- Inner-joining where
OPTIONALwas meant. - Mixing expanded and abbreviated IRIs.
- Parsing
https://...as a CURIE. - Materializing, then deleting, then trusting the closure.
- Presenting a derived triple as a source record.
- Reusing an IRI for a new concept.
- Adopting all of FIBO.
- Modifying FIBO instead of subclassing it.
- Unbounded neighbourhood expansion.
- Choosing RDF for a purely internal operational graph.
What "good" sounds like
"Ultimate beneficial ownership is transitive closure, so I model
majorityOwnsas a sub-property ofcontrolsand declarecontrolstransitive — then two rules compose and the ownership chain is entailed rather than computed in application code. The query is one line with a property path. OWL does the inference; SHACL does the validation, and I need both because the open-world assumption means OWL can never tell me a record is missing an LEI. I materialize the closure because reads dominate, keep asserted and derived triples in separate named graphs so recomputation is cheap and so an auditor can tell them apart, and I validate after materializing or nodes typed only by inference get skipped. And I'd useOPTIONALfor anything that might be absent, because inner-joining on legal name hides exactly the shell companies a KYC analyst is looking for."