A city that takes this seriously ends up with several digital twins. One for emergency response. One for mobility. One for infrastructure assets — tunnels, bridges, structures. Different teams, different platforms, different refresh rates. And each one works.
The problem shows up the first time a question crosses two of them. Smoke is detected in a motorway tunnel. The infrastructure twin knows: it is watching the jet fans and the detectors. The emergency twin does not, so nobody can say which escape routes serve that tunnel. The mobility twin does not either, so the buses keep being routed into it.
The instinct is to connect the twins to each other. That is the wrong move. What you want is a Twin of Digital Twins: a layer that makes the three cohere without any of them having to know about the others.
That layer is not a bigger twin. It is a knowledge infrastructure sitting underneath them, and its load-bearing component is a knowledge graph.
Table of contents
Open Table of contents
What a knowledge graph is actually made of
“Knowledge graph” has been stretched to mean almost anything with nodes and edges. It is worth being precise, because the difference between a graph that supports a Twin of Digital Twins and one that does not is a component list.
Figure 1. The required and optional components of a domain knowledge graph. Source: Jessica Talisman, The Ontology Pipeline.
Four components are required, and all four have a direct reading in a city:
- Vocabulary, aligned to external standards. You do not invent the word “tunnel”. You take terms from SAREF4CITY, GTFS, IEC CIM, INSPIRE. Alignment is the point: it is what lets a second city, or a concession operator, understand your graph without a translation project.
- Ontology, a deeply axiomatized TBox. Not a class list. Axioms: a road segment runs through at most one tunnel, an emergency exit is an egress point of exactly one structure,
runsThroughcomposed withtraversestells you which routes a tunnel closure affects. - Knowledge base, structurally homogeneous. The tunnel SCADA, the GTFS feed and the asset register arrive in completely different shapes and leave in one. Homogeneous is what makes a single query possible.
- Reasoner, first-class and inference-producing. This is the component people quietly drop, and dropping it is what turns a knowledge graph back into a join table. The reasoner is what derives the facts nobody asserted.
Three more are optional, and in a city two of them stop being optional quite fast:
- SHACL validation as a gate at ingest, not a report you read later. An asset with no location cannot be dispatched to.
- Metadata schemas — DCAT and PROV — so that “where did this come from?” has an answer.
- Federation, so you can query the tunnel concessionaire’s endpoint without copying their data into your graph.
On top sits the query layer, federated SPARQL 1.1. Underneath sit the external dependencies: domain ontologies, standards bodies, external endpoints. That bottom row is the part that makes it infrastructure rather than a dataset — you are inheriting maintenance from ETSI, OGC and W3C instead of carrying it yourself, and you are building something that outlives any of the twins plugged into it.
The architecture
Figure 2. The emergency, mobility and infrastructure twins bind to shared entities in the knowledge graph. They are related to each other only through those entities — never directly.
Read it from the outside in:
The domain twins sit at the edges. Each keeps its own model, its own simulation, its own cadence. The emergency twin is not obliged to know what a jet fan is. The mobility twin is not obliged to know what a tunnel is made of.
The bindings are the dashed arrows. A twin declares which entities it binds to, reads their state, and writes back what it has computed. That declaration is its entire contract with the outside world.
The graph holds the shared entities and the relations between them — installedIn, egressFrom, runsThrough, traverses. No twin owns an entity; every twin reads it.
Notice what is missing: there is not a single arrow from one twin to another.
Twins relate because their entities relate
This is the whole idea, so it is worth saying plainly.
You never connect the infrastructure twin to the mobility twin. You connect both to the graph. The infrastructure twin binds Tunnel_M30_North. The mobility twin binds BusRoute_27. The graph already knows that the route traverses a segment, and that the segment runs through that tunnel.
The relation between the two twins is not something you built. It is a consequence of relations between entities — which is exactly the job of the reasoner in Figure 1.
And because it is a consequence, it chains:
- The infrastructure twin asserts smoke in
Tunnel_M30_North. - The emergency twin follows
egressFromand opens the four exits that serve that tunnel. - The mobility twin follows
runsThroughto the road segment andtraversesto the routes on it, and divertsBusRoute_27.
Nobody wrote an infrastructure-to-mobility integration. Nobody could have: when the tunnel twin was commissioned, the mobility twin did not exist yet.
What it looks like in the graph
Short enough to read in one go. First the shared entities and their relations:
ex:Tunnel_M30_North a city:Tunnel .
ex:JetFan_V12 a saref:Device ;
city:installedIn ex:Tunnel_M30_North .
ex:EmergencyExit_E4 a city:EgressPoint ;
city:egressFrom ex:Tunnel_M30_North .
ex:RoadSegment_Km7 a city:RoadSegment ;
city:runsThrough ex:Tunnel_M30_North .
ex:BusRoute_27 a gtfs:Route ;
city:traverses ex:RoadSegment_Km7 .
Then the twins, declaring what they bind to:
ex:InfrastructureTwin a city:DigitalTwin ;
city:binds ex:Tunnel_M30_North, ex:JetFan_V12 .
ex:EmergencyTwin a city:DigitalTwin ;
city:binds ex:EmergencyExit_E4 .
ex:MobilityTwin a city:DigitalTwin ;
city:binds ex:BusRoute_27 .
Read it again and note that no twin mentions another twin. That absence is the architecture.
The question that pays for all of it
There is smoke in
Tunnel_M30_North. Which twins are affected?
SELECT DISTINCT ?twin ?entity
WHERE {
ex:Tunnel_M30_North (^city:egressFrom|^city:runsThrough|^city:traverses)+ ?entity .
?twin city:binds ?entity .
}
| ?twin | ?entity |
|---|---|
ex:EmergencyTwin | ex:EmergencyExit_E4 |
ex:MobilityTwin | ex:BusRoute_27 |
The infrastructure twin asked a question about a tunnel and got back a list of twins. It did not know the mobility twin existed. It did not need to.
Swap the tunnel for a bridge, or a flood zone, and the same query tells you which twins a different incident touches. The query does not change. That is the sign you have built infrastructure rather than an integration.
Necessary, not sufficient
The graph is load-bearing, but on its own it is a very accurate picture of a city that does nothing. Three more things turn it into a running system:
- A twin registry. The bindings above are the start of it: which twins exist, what each one binds, which version it is on. Without it, nothing is discoverable.
- An event backbone. The query tells you who is affected; something still has to deliver the notification — NGSI-LD subscriptions, MQTT, pub/sub. The graph reasons, the backbone acts.
- Federated simulation. “If we close the tunnel for six hours, what happens?” is not a question any single twin can answer, and it is not a question a graph can answer either. It needs the twins to run together, over shared identities.
Each of these leans on the graph — the registry is a list of bindings to graph entities, the backbone routes along graph relations, the simulation federates over graph identities. Which is why the graph goes first, and why getting it wrong is expensive.
In summary
The usual framing is that a knowledge graph is where you put the city’s data. It is not. The data stays in the twins, which is where the models and the domain expertise live.
What goes in the graph is narrower and more valuable: the entities the twins share, and the relations between them. That is a small amount of data, and it is the part nobody else can own, because by definition it sits between teams.
Build it as a knowledge infrastructure — standards-aligned vocabulary, an axiomatized ontology, a homogeneous knowledge base, a reasoner you actually use — and you stop having three digital twins plus an integration backlog. You have one Twin of Digital Twins. And when smoke appears in a tunnel at two in the morning, the exits open and the buses are rerouted because of a relation somebody asserted once, years earlier.