This document specifies RDF-H, a vocabulary and modeling pattern for representing
holarchic structures within the Resource Description Framework 1.2 [[RDF12-CONCEPTS]]. A
holarchy is a system of
holons, where each holon is a resource
that is simultaneously a whole in itself and a part of a larger whole. RDF-H provides a semantically
precise method for representing nested, contextual, and compositional knowledge. Each holon has a
content graph — the
set of triples filed in it — which is a view over the single asserted graph rather than
a separate theory (an additive semantics). RDF-H defines this content-graph model
abstractly and offers two interoperable serialization profiles that realize the
same content graph: a reifier profile built on the RDF 1.2 reifier model
(rdf:reifies and triple terms), which keeps everything in one graph and supports
per-occurrence metadata, and a named-graph profile built on RDF datasets, which is
cheaper and queryable with GRAPH on today's tooling. The core vocabulary centers on
h:inHolon (reifier-profile membership), h:contentGraph and
h:CompleteHolon (the content-graph boundary), together with a formal mereological
hierarchy of part-whole relations that couples a holon's contents to its composition. The
specification also proposes Turtle-H, a syntactic sugar over Turtle 1.2
[[RDF12-TURTLE]] providing a concise @holon directive for defining holons. By
grounding containment in formal mereology and content graphs, RDF-H enables the robust modeling
of digital twins, cyber-physical systems, fine-grained access control policies, and other
domains requiring a native understanding of "wholes-within-wholes."
This document is a draft proposal produced by Geoknoesis LLC. It is not an official specification produced by the W3C, nor is it an official work item of any W3C Group. This document is published with the aim of gathering feedback from the community for potential future submission to and standardization by the W3C.
This proposal builds on the RDF 1.2 family of specifications
([[RDF12-CONCEPTS]], [[RDF12-SEMANTICS]], [[RDF12-TURTLE]]), which are at Candidate
Recommendation status at the time of writing. In particular, RDF-H depends on the RDF 1.2
reifier model, the rdf:reifies predicate, the triple-term syntax
<<( s p o )>>, and the Turtle 1.2 reified-triple sugar
<< s p o >> and annotation syntax {| ... |}. Should
those RDF 1.2 designs change before final Recommendation, this document will be updated
accordingly.
Structure. The specification has three logically separable layers —
core vocabulary, mereology, and Turtle-H surface syntax — bundled in this single
document for v0.7 and sharing the namespace https://w3id.org/rdf-h#. See
for the full breakdown and reading
guidance.
License. This document, the accompanying RDF-H vocabulary
(rdfh.ttl), and all other content in the
geoknoesis/rdf-holon repository are
published under the Apache License,
Version 2.0. See the LICENSE file in the repository for the full text.
The Resource Description Framework (RDF) provides a powerful, graph-based data model for representing information about resources and the relationships between them. Its core structure, a set of subject-predicate-object triples, creates a directed, labeled graph that is flexible, extensible, and web-scalable. However, the "flat" nature of this graph, where all triples exist at the same structural level, presents significant challenges when modeling systems that possess inherent compositional or contextual hierarchies.
The key words MUST, MUST NOT, SHOULD, and MAY in this document are to be interpreted as described in [[RFC2119]].
Three logical layers. The specification is structured in three
logically separable layers, bundled in this document for v0.7 and sharing the
namespace https://w3id.org/rdf-h#:
h:Holon, h:inHolon, h:contentGraph, and
h:CompleteHolon — defines each holon's
content graph and its two serialization profiles
(,
).h:partOf hierarchy and its
sub-properties — is a general part-whole vocabulary that does not depend on
the holon machinery ().h:inHolon
annotations ().Layers (2) and (3) are candidates for future extraction into sibling specifications (see Open Issue 1 and Open Issue 6); whether to split namespaces pre-emptively is Open Issue 7.
Normative sections: , , , , , , and . Informative sections: , , , , , , and .
How to read. Readers familiar with RDF 1.2 may skim this introduction and start at . Readers new to the RDF 1.2 reifier model should consult [[RDF12-CONCEPTS]] §1.5 before . Implementers who want a one-page summary should jump to .
Many real-world and conceptual domains are fundamentally compositional. A car is a whole composed of parts like an engine and wheels; the engine, in turn, is a whole composed of its own parts. A digital twin of a factory floor is a whole that contains digital twins of individual assembly lines, which in turn contain twins of robotic arms. In systems biology, a cell contains organelles, which contain molecular complexes. In all these cases, the identity, boundary, and integrity of a subsystem (the "part") are as crucial as the relationships that exist within it.
While RDF can describe these part-whole relations using predicates (e.g.,
ex:engine ex:partOf ex:car), it lacks a simple, standardized pattern to represent this
containment in a way that is both structurally intuitive and semantically rich. Existing approaches
require developers to adopt specific modeling conventions or use mechanisms that were designed for
related but distinct purposes. This leads to semantic ambiguity, complex queries, and a disconnect
between the intuitive structure of the domain and its representation in the graph. This specification
for RDF-H introduces a vocabulary and modeling pattern to address this gap, providing a
native, semantically grounded way to model structural composition directly within the graph.
Before the formal definitions, here is what RDF-H looks like in practice. A car holon that contains an engine relation, in Turtle-H:
@prefix ex: <https://example.org/> .
@prefix h: <https://w3id.org/rdf-h#> .
@holon ex:Car {
ex:Engine h:componentOf ex:Car .
}
A Turtle-H-aware parser desugars this into the relation itself plus an annotation tying its reifier to the holon:
@prefix ex: <https://example.org/> . @prefix h: <https://w3id.org/rdf-h#> . ex:Engine h:componentOf ex:Car . << ex:Engine h:componentOf ex:Car >> h:inHolon ex:Car .
The asserted triple records the part-whole relation; the
h:inHolon annotation records the holonic context in which the
relation lives. The remainder of this specification formalizes this pattern, defines
validation rules that keep holonic graphs sound, and shows how to query them with
standard SPARQL.
Three existing RDF mechanisms cover overlapping ground. The table below summarizes where each falls short for compositional modeling; the paragraphs after it add what the table does not capture.
| Feature | Standard Reification | Triple Terms / Reifiers (RDF 1.2) | Named Graphs (RDF 1.1) | RDF-H Pattern |
|---|---|---|---|---|
| Granularity | Single Statement | Single Statement | Set of Statements (Graph) | Set of Relationships (Composition) |
| Semantic Precision | Weak (describes a statement token) | Strong syntactically; reifier denotation deliberately open [*] | Ambiguous (multiple interpretations of graph name) | Strong (formal mereological relation) |
| Syntactic Verbosity | High (4 extra triples) | Low (<<...>>) |
Moderate (quads) | Low (proposed @holon IRI {...} directive) |
| Querying Paradigm | Complex Joins | SPARQL 1.2 reified-triple patterns | GRAPH Clause (Scope Change) |
Property Path Traversal |
| Core Use Case | Provenance of a statement token | Metadata on a triple-occurrence | Dataset management, provenance | Modeling structural composition |
[*] rdf:reifies precisely fixes its syntactic target
(a triple term) but leaves the reifier's denotation open — statement, belief, event,
situation, etc. [[RDF12-CONCEPTS]]. RDF-H layers the
holon-occurrence reading on top; see
.
The columns above contrast the underlying mechanisms. RDF-H is not a fourth mechanism competing with them: its content-graph model is defined abstractly and realized on two of them — a reifier profile and a named-graph profile (). The "Named Graphs" column therefore describes plain named-graph usage; RDF-H's named-graph profile adds the abstract content-graph semantics, the additive invariant tying every content graph to one asserted graph, and the coupled mereology that plain named graphs lack.
The original RDF reification vocabulary (rdf:Statement,
rdf:subject, rdf:predicate, rdf:object) is
effectively superseded in RDF 1.2 [[RDF12-CONCEPTS]] by the
reifier model. The legacy vocabulary remains in the namespace for backward
compatibility but is independent of — and not used by — the RDF 1.2 reifier
machinery on which RDF-H is built.
RDF 1.2 introduces triple terms <<( s p o )>> and
the rdf:reifies predicate linking a reifier (IRI or blank
node) to a triple term [[RDF12-CONCEPTS]]. This is a mechanism,
not a pattern: it attaches metadata to individual edges but does
not standardize how to group a set of relationships into a containing
whole. Without a standard like RDF-H, ecosystems converge on incompatible
grouping properties (ex:hasContext, ex:isAbout,
ex:partOfGroup, …). RDF-H proposes
h:inHolon as the single reifier-attached grouping property.
Named graphs [[RDF11-DATASETS]] are often described as a dataset-management
feature rather than a resource-modeling primitive: they partition a store into
separately addressable triple sets, their semantics are deliberately
underspecified, and querying them requires GRAPH (a scope change at
the dataset level). RDF-H does not reject named graphs; rather, it recognizes that
a holon's content graph can be realized
either with RDF 1.2 reifiers inside a single graph or as a named
graph in a dataset, and specifies both as interoperable
profiles. The named-graph profile
pairs a holon IRI (a describable resource) with a content graph of the same name,
recovering GRAPH-scoped querying and an inexpensive boundary; the
reifier profile keeps everything in one graph and adds per-occurrence metadata.
What distinguishes RDF-H from plain named-graph usage is the abstract
content-graph semantics, the additive invariant tying every content graph to one
asserted graph, and the coupled mereology — none of which named graphs supply on
their own.
This section defines the core vocabulary for the RDF-H modeling pattern. The vocabulary namespace is
https://w3id.org/rdf-h#, bound by convention to the prefix h:.
CG(H) — the set of
triples filed in it (formalized in ).
The holon is the whole whose internal structure is its content graph, and
which may itself appear as a node — a part — in other holons' content
graphs. Class membership is entailed by the rdfs:range axiom on
h:inHolon: ?h is inferred to be an h:Holon
whenever ?r h:inHolon ?h appears in the graph (see
). No axiom requires a holon to
be non-empty or to be a part of anything: a holon
MAY have an empty content graph or be
top-level.
rdf:reifies — to the holon that contains the corresponding
triple-occurrence. The subject of h:inHolon is therefore the reifier (which
identifies one occurrence of an asserted triple); the object is the containing holon.
Its rdfs:range is h:Holon. No rdfs:domain is
declared, because RDF 1.2 places no class restriction on reifiers
[[RDF12-CONCEPTS]]. This property does not use the older
rdf:Statement reification vocabulary, which is independent of the
RDF 1.2 reifies / triple-term machinery. In Turtle 1.2 [[RDF12-TURTLE]] the
bare-brace syntax << :s :p :o >> (a reified
triple) expands to a fresh blank-node reifier
_:b rdf:reifies <<( :s :p :o )>>; RDF-H reuses this
reifier sugar so that h:inHolon is always asserted on an IRI or
blank node.
CG(H). The default
convention is that the content-graph name equals the holon IRI, so this
property is usually omitted; declare it only to decouple a holon's identity from
its content-graph name. It has no role in the reifier profile, where
CG(H) is defined by the h:inHolon pattern rather than by
a named graph. Its rdfs:domain is h:Holon.
h:Holon whose content graph is complete:
no triple-occurrence beyond those filed in H belongs to
CG(H). A consumer MAY therefore
rely on CG(H) being exhaustive — for example, treating the absence of a
matching triple in CG(H) as "there is none" for the purpose of
integrity checks scoped to the holon. This is a local completeness
contract, not a global closed-world assumption: it adds no entailment and
is honoured only by SHACL and opting-in consumers (see
), not by an OWL/RDFS reasoner.
The boundary it provides is what lets a holon act as a genuine whole.
Typing a holon h:CompleteHolon is optional.
Empty content graphs require explicit typing. The
rdfs:range axiom on h:inHolon only types resources that are
objects of at least one h:inHolon triple — i.e. holons with a non-empty
content graph. A holon with an empty content graph exists only via an explicit
rdf:type h:Holon assertion. With the content-graph model the empty case
is well-defined (an empty CG(H)) rather than degenerate; see
Open Issue 4.
OWL DL note. The owl:ObjectProperty declaration commits
every reifier in subject position of h:inHolon to being an individual
under OWL 2 DL semantics [[OWL2-DIRECT-SEMANTICS]] — strictly stronger than RDF 1.2,
which leaves reifiers untyped. In practice, useful reifiers are individuals anyway.
Holon and reifier roles are independent.
A resource MAY simultaneously be both a holon
(object of h:inHolon) and a reifier (subject of
rdf:reifies), and a reifier MAY be
the object of h:inHolon — placing one triple-occurrence inside the
context of another. RDF-H imposes no disjointness, inheriting the permissive stance
of RDF 1.2 [[RDF12-CONCEPTS]]. In most domains a holon is nonetheless best modeled
as a domain-level whole (building, system, process) rather than as a reifier itself.
RDF-H defines a hierarchy of part-whole relationships using
rdfs:subPropertyOf and owl:inverseOf, letting modelers be
specific while keeping queries general [[OEP-PARTWHOLE]]. A single transitive
top-level property, h:partOf, anchors the hierarchy and provides the
closure used for "is somewhere in the part hierarchy of" queries. Four sub-properties
refine it along orthogonal dimensions: h:componentOf and
h:memberOf for structural parthood and aggregate membership respectively
(both asymmetric and irreflexive), and
h:substanceOf and h:portionOf for material composition and
continuous-whole segmentation respectively (both transitive).
h:partOf
/ h:hasParth:hasPart is the inverse of
h:partOf.
h:componentOf
/ h:hasComponenth:partOf for functional or structural parts (e.g., an
engine is a component of a car). This relationship is essential for preserving the
distinct levels of a holarchy. h:hasComponent is the inverse of
h:componentOf.
h:memberOf
/ h:hasMemberh:partOf for elements in a collection or group where
the whole is an aggregate of its members (e.g., a player is a member of a team).
h:hasMember is the inverse of h:memberOf.
h:substanceOf
/ h:hasSubstanceh:partOf for material composition (e.g., clay is a substance
of a brick). A part of the substance is also a part of the whole. h:hasSubstance
is the inverse of h:substanceOf.
h:portionOf
/ h:hasPortionh:partOf for segments of a continuous whole (e.g., a slice is
a portion of a pie). A part of the portion is also a part of the whole.
h:hasPortion is the inverse of h:portionOf.
Ontology Definition (Turtle):
@prefix h: <https://w3id.org/rdf-h#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
# Top-level transitive part-of (closure for queries; acyclic via SHACL)
h:partOf a owl:ObjectProperty, owl:TransitiveProperty .
h:hasPart a owl:ObjectProperty, owl:TransitiveProperty ;
owl:inverseOf h:partOf .
# Non-transitive, asymmetric, irreflexive sub-properties of h:partOf
# (immediate structural parthood and aggregate membership)
h:componentOf a owl:ObjectProperty,
owl:AsymmetricProperty,
owl:IrreflexiveProperty ;
rdfs:subPropertyOf h:partOf .
h:hasComponent a owl:ObjectProperty,
owl:AsymmetricProperty,
owl:IrreflexiveProperty ;
rdfs:subPropertyOf h:hasPart ;
owl:inverseOf h:componentOf .
h:memberOf a owl:ObjectProperty,
owl:AsymmetricProperty,
owl:IrreflexiveProperty ;
rdfs:subPropertyOf h:partOf .
h:hasMember a owl:ObjectProperty,
owl:AsymmetricProperty,
owl:IrreflexiveProperty ;
rdfs:subPropertyOf h:hasPart ;
owl:inverseOf h:memberOf .
# Transitive sub-properties of h:partOf (acyclic via SHACL, like h:partOf)
h:substanceOf a owl:ObjectProperty, owl:TransitiveProperty ;
rdfs:subPropertyOf h:partOf .
h:hasSubstance a owl:ObjectProperty, owl:TransitiveProperty ;
rdfs:subPropertyOf h:hasPart ;
owl:inverseOf h:substanceOf .
h:portionOf a owl:ObjectProperty, owl:TransitiveProperty ;
rdfs:subPropertyOf h:partOf .
h:hasPortion a owl:ObjectProperty, owl:TransitiveProperty ;
rdfs:subPropertyOf h:hasPart ;
owl:inverseOf h:portionOf .
Acyclicity. No resource may stand in h:partOf+ with
itself; this is criterion 2 of the normative MUST-level requirements on a conformant RDF-H graph (see
), pinned to RDFS entailment so that
cycles introduced through custom sub-properties of h:partOf are caught
automatically. In a finite RDF graph (the only kind this specification considers),
acyclicity coincides with well-foundedness of the part-of relation. The SHACL-level
enforcement is described in .
OWL 2 DL note. OWL 2 DL (the Description Logic profile of
[[OWL2-SYNTAX]]) forbids combining owl:TransitiveProperty with
owl:AsymmetricProperty or owl:IrreflexiveProperty on the
same role, and does not propagate property characteristics across
rdfs:subPropertyOf. Each property in the hierarchy therefore declares
its own characteristics explicitly. h:componentOf and
h:memberOf remain OWL 2 DL simple roles because neither is
itself transitive nor has a transitive sub-property; their transitive super-property
h:partOf does not violate the simple-role restriction, which is
downward, not upward. See Open Issue 3 for the
design history.
Extension constraint. A conformant RDF-H ontology extension
MUST NOT introduce transitive sub-properties
of h:componentOf, h:memberOf, h:hasComponent,
or h:hasMember; doing so would make those properties non-simple
(§11 of [[OWL2-SYNTAX]]) and invalidate their owl:AsymmetricProperty and
owl:IrreflexiveProperty axioms under OWL 2 DL. More generally, an
extension SHOULD classify each custom
part-property it introduces as either a closure relation or an
immediate relation:
h:partOf itself, or
h:substanceOf / h:portionOf) ranges over the transitive
closure of parthood. It SHOULD be declared
owl:TransitiveProperty and a sub-property of h:partOf.h:componentOf /
h:memberOf) holds only one level deep. It SHOULD be declared a sub-property of h:componentOf
or h:memberOf (not of h:partOf directly), and — if it is
to carry owl:AsymmetricProperty / owl:IrreflexiveProperty
— it MUST NOT be transitive nor have a
transitive sub-property, so that it remains an OWL 2 DL simple role.
The built-in vocabulary is exactly this split: h:partOf,
h:substanceOf, h:portionOf are transitive closure relations,
while h:componentOf and h:memberOf are non-transitive
immediate relations — which is why a blanket "custom sub-properties should be
transitive" rule would be wrong.
Future direction. This mereology is logically separable from the holon machinery and is a candidate for extraction into a sibling vocabulary; the IRIs and semantics defined here are intended to remain stable across such an extraction. See Open Issue 1.
It is a deliberate design choice for the RDF-H vocabulary to focus exclusively on composition
(h:inHolon) and mereology (the h:partOf hierarchy). Other important
relationship types, such as peer-to-peer, dependency, or hierarchical supervision, are considered
domain-specific and are intentionally excluded from this core vocabulary.
This design follows the principle of minimality. RDF-H provides the universal, structural primitives for
building holarchies. Modelers are encouraged to define their own domain-specific properties (e.g.,
ex:isPeerOf, ex:dependsOn) in their own ontologies. The RDF-H pattern is then
used to place these custom relationships within the context of a holon. This approach promotes a more
flexible and composable ecosystem, where the core RDF-H pattern can be applied to any relationship,
without the RDF-H vocabulary itself becoming an exhaustive and overly prescriptive ontology.
Example of using a domain-specific property with RDF-H:
@prefix ex: <https://example.org/network#> .
@prefix h: <https://w3id.org/rdf-h#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
# A domain-specific property defined in an external ontology
ex:isPeerOf a owl:ObjectProperty, owl:SymmetricProperty .
# The holon resource. Explicit typing is RECOMMENDED for portability,
# even though h:inHolon's range axiom would entail it under RDFS.
ex:SystemCluster a h:Holon .
# Applying the RDF-H pattern to the domain-specific property
@holon ex:SystemCluster {
ex:ServiceA ex:isPeerOf ex:ServiceB .
}
This section defines the central semantic object of RDF-H — the content graph of a holon — abstractly, and then gives two interoperable serialization profiles that realize it. Defining the semantics over the content graph rather than over a particular syntax is what lets the reifier and named-graph encodings interoperate.
Let G be the asserted graph:
in the reifier profile, the single RDF graph; in the named-graph profile, the
union of the dataset's graphs (its default graph together with all of its
named graphs). This last point is an RDF-H-defined interpretation, not
default RDF behaviour: RDF 1.1/1.2 datasets deliberately fix no required
relationship between the default graph and the named graphs, and SPARQL does not query
their union by default [[RDF11-DATASETS]]. RDF-H stipulates that, for a dataset using
the named-graph profile, the asserted content is the union of its graphs. For a holon
H, its
content graph
CG(H) is the set of triples filed in H. RDF-H imposes one
normative constraint relating every content graph to G:
Additive invariant. For every holon H,
CG(H) ⊆ G: every triple filed in a holon is also in the
asserted graph G. A content graph is
therefore a view that carves up one true graph, not
a separate or hypothetical theory. This is the defining commitment of RDF-H's
additive semantics, and it is the general form of conformance
criterion 3. In the reifier profile it is
a genuine constraint (the base triple must be asserted alongside the reifier); in the
named-graph profile it holds by construction, since each CG(H) is
one of the graphs whose union is G. (A contextual reading, in
which a holon's triples would be true only "within" the holon and not globally, would
drop this invariant; that is deliberately out of scope — see
Open Issue 8.)
Because content graphs are views over G, part-whole entailments need no
special treatment: if ex:Engine h:componentOf ex:Car is in any
CG(H) it is (by the invariant) also in G, so
ex:Engine h:partOf ex:Car follows by the ordinary mereology of
regardless of which holon it was
filed in. What the content graph adds is where the relationship lives, not
whether it holds.
In the reifier profile, membership is recorded with the RDF 1.2 reifier model and the
h:inHolon property:
CG(H) = { (s,p,o) : ∃ r. (r, rdf:reifies, <<( s p o )>>) ∈ G
∧ (r, h:inHolon, H) ∈ G }.
Everything stays in a single graph, and because each occurrence has its own reifier the
profile supports per-occurrence metadata (the same relationship can be
filed in two holons with distinct provenance on each occurrence — see the
multi-holon pattern). The additive invariant is
operationalized here by h:AssertedBaseTripleShape
(). Turtle-H
() is surface syntax for this profile.
In the named-graph profile, a holon's content graph is a named graph in an RDF dataset [[RDF11-DATASETS]]:
CG(H) = the graph named N in the dataset, where
(H, h:contentGraph, N) is asserted in the default graph; by default
N = H, so the holon IRI doubles as its content-graph name and
h:contentGraph may be omitted.
The holon IRI remains an ordinary, describable resource in the default graph
(e.g. ex:Floor_3 a h:Holon ; bldg:floorNumber 3), while its internal
structure is the graph it names. Under the RDF-H interpretation that the
asserted graph G is the
union of the dataset's graphs (an RDF-H stipulation, not default
dataset semantics — see asserted graph), each named
graph CG(H) is a subset of G by construction: the
additive invariant holds with no
duplication and needs no separate check — a filed triple is asserted simply by
being in its named graph. This profile therefore costs one quad per filed triple (no
reifiers), is queryable with GRAPH on current SPARQL engines, and gets a
cheap boundary for free (a named graph is exactly its quads).
The two profiles are content-equivalent under a projection: they
realize the same CG(H) for every holon and the same set of
asserted base triples, but they are not equivalent as full RDF
graphs/datasets — occurrence identity, per-occurrence metadata, and the multiplicity of
a triple filed more than once in the same holon are visible in the reifier profile and
projected away in the named-graph profile. A conformant processor
MAY translate between them:
r h:inHolon H with
r rdf:reifies <<( s p o )>>, place
(s,p,o) in the graph named N (the content-graph name of
H, by default H itself).(s,p,o) in the
graph named N for holon H, mint a fresh reifier
r and emit
r rdf:reifies <<( s p o )>> . r h:inHolon H . in the single
graph.
These translations preserve CG(H) for every holon and the asserted base
triples, and are mutually inverse up to renaming of blank-node reifiers and the choice
of content-graph name N. They do not preserve the literal triple
set: the rdf:reifies/h:inHolon bookkeeping of the reifier
profile and the quad structure of the named-graph profile are profile-specific. The
reifier profile carries strictly more information only when distinct occurrences of one
relationship must be distinguished (per-occurrence metadata); when they need not be,
the round trip is lossless.
One profile per holon. A holon SHOULD be serialized in a single profile. Because
h:contentGraph is functional, a holon has at most one named content graph;
if a holon nonetheless carries both reifier-profile memberships
(h:inHolon) and a named content graph, its content graph
CG(H) is the union of the two, and processors MAY normalize such mixed data by converting to a single profile first.
The deep content of a holon rolls its parts' content graphs up into it, following the part-of hierarchy:
CG*(H) = ∪ { CG(K) : K h:partOf* H } — the union of the content graphs
of H and of every holon that is a part of H.
Roll-up follows parthood, not Turtle-H lexical nesting: a nested
@holon block () contributes to a
holon's deep content only when a part-of edge actually relates the two holons. Lexical
nesting on its own is purely a layout convenience and carries no containment. This
keeps the two channels — holonic context and parthood — explicit rather than implied
by indentation. gives the
CG* query.
Entailment posture. Deep content is defined with
h:partOf*, so the CG* query traverses the part hierarchy's
sub-properties only under RDFS entailment — unlike
h:AcyclicPartShape, which is deliberately entailment-independent (it
enumerates the sub-properties and their inverses). On an engine without RDFS
entailment, substitute the same alternation
(( h:partOf | h:componentOf | … | ^h:hasPortion )*) for
h:partOf* in the CG* query. CG* is an
informative convenience, not a conformance requirement.
The additive invariant guarantees a content graph is sound (its triples
really hold) but not that it is about its holon: nothing in the abstract
definition stops a triple whose subject and object are unrelated to H from
being filed in H. RDF-H therefore SHOULD-recommends two coherence conditions, surfaced as advisory
SHACL shapes ():
H SHOULD have H
(or a part of H) as its whole — so a holon's content describes the
holon's own composition. This rules out filing
ex:Wheel h:componentOf ex:Car inside an unrelated
@holon ex:Engine.H
SHOULD have at least one endpoint that is
H or a part of H, so the content graph stays about the
holon. Domain relations with one external endpoint (e.g.
ex:TempSensor_F3 bldg:monitors ex:HVAC_F3, filed in
ex:HVAC_F3) satisfy this.These are advisory, not conformance requirements: deliberate cross-context placements remain valid RDF-H, but they are the exception rather than the rule. This is a deliberate reversal of earlier drafts, which presented the independence of context and parthood as a headline feature; under the content-graph model it is a permitted edge case.
The semantics of RDF-H are defined by the standard RDF 1.2 model-theoretic semantics [[RDF12-SEMANTICS]] applied to graphs containing the RDF-H vocabulary. No new entailment regime is required; standard RDFS or OWL reasoners produce the desired inferences from the ontology. Two standard RDFS inferences carry the work:
rdfs:range axiom on
h:inHolon entails ?h rdf:type h:Holon for every object of
h:inHolon, via the standard RDFS rule rdfs3
[[RDF12-SEMANTICS]].rdfs:subPropertyOf axioms on
h:componentOf, h:memberOf, h:substanceOf, and
h:portionOf entail corresponding h:partOf triples, via
RDFS rule rdfs7. Combined with the
owl:TransitiveProperty axiom on h:partOf, this gives the
transitive closure used by part-of queries.
Given the ontology axiom h:inHolon rdfs:range h:Holon . and an RDF-H
graph containing _:r h:inHolon ex:Car ., an RDFS-aware reasoner entails
ex:Car rdf:type h:Holon. Similarly, given
ex:Engine h:componentOf ex:Car . the reasoner entails
ex:Engine h:partOf ex:Car.
Because h:Holon-typing is an entailment, it may be invisible to consumers
that do not apply RDFS reasoning. The
h:HolonIntegrityShape defined in
surfaces holons whose typing
relies on this entailment, and modelers SHOULD
declare h:Holon explicitly for portability.
The content-graph machinery adds no new entailments. The
content-graph model, the
additive invariant, and h:CompleteHolon are
view- and validation-level constructs, not model-theoretic ones: an RDFS
or OWL reasoner derives nothing further from them. In particular, a reasoner does
not infer negative facts from h:CompleteHolon — closure is honoured
only by SHACL and by opting-in consumers (see ). h:contentGraph is an ordinary functional property with
no special semantics beyond its rdfs:domain.
To simplify the authoring of holonic structures, this specification proposes Turtle-H, a syntactic sugar for Turtle that introduces a directive-led block syntax for defining a holon's context. A conformant RDF-H processor SHOULD support this syntax.
@holon Directive
A holon and its constituent relationships are defined by the @holon directive, followed
by the holon's identifier (IRI or blank node) and a block of Turtle statements enclosed in curly braces:
@holon <holon-iri> {
# Turtle statements that are constituents of this holon
}
Why a directive (not a bare IRI { ... } block)?
The bare-brace form denotes a named graph in TriG [[TRIG]]; reusing it would clash
with that vocabulary. The @holon keyword makes Turtle-H grammatically
distinct from TriG and unambiguous to a single parser pass. Turtle-H is not part of
Turtle 1.2 [[RDF12-TURTLE]] — it is a proposed sugar that lets developers write
a holonic relationship once and have a Turtle-H-aware parser generate both the
asserted triple and the h:inHolon annotation.
Content membership is not, by itself, part membership.
Filing a triple :s :p :o in @holon :H { ... } places that
relationship in the content graph of :H. It
does not on its own assert that :s or :o is a part of
:H; part-whole relations are carried by the h:partOf hierarchy
(). The two channels remain distinct, but
they are not meant to be used arbitrarily: recommends that a holon's content graph be about the holon —
a part-of relation filed in :H should describe :H's own
composition, and any relation filed in :H should touch :H or one
of its parts. A typical holon block therefore contains a h:componentOf /
h:memberOf / h:substanceOf / h:portionOf triple
that says what the parts are, plus domain relations among those parts. Filing a triple that
has nothing to do with :H is permitted but is the documented exception, not
the intended pattern (and is flagged by the advisory coherence shapes).
Example using Turtle-H Syntax:
@prefix ex: <https://example.org/> .
@prefix h: <https://w3id.org/rdf-h#> .
ex:Car_123 a h:Holon .
ex:Engine_456 a h:Holon .
@holon ex:Car_123 {
ex:Engine_456 h:componentOf ex:Car_123 .
@holon ex:Engine_456 {
ex:Piston_789 h:componentOf ex:Engine_456 .
}
}
This concise syntax is syntactic sugar for the standard RDF 1.2 representation. A Turtle-H parser MUST translate the block syntax into the equivalent set of standard triples.
The block @holon :H { :s :p :o . } desugars
per Turtle-H into:
:s :p :o .
<< :s :p :o >> h:inHolon :H .
The reified-triple form << :s :p :o >> is itself sugar in
Turtle 1.2 [[RDF12-TURTLE]] — it allocates a fresh blank-node reifier related to the
triple term <<( :s :p :o )>> via rdf:reifies. The
fully-expanded RDF 1.2 form is therefore three triples per
@holon-enclosed statement, as shown below.
Equivalent RDF 1.2 forms. Reified-triple sugar (left) and the
fully-expanded form (right) for the outer @holon ex:Car_123 block.
# Reified-triple sugar
ex:Engine_456 h:componentOf ex:Car_123 .
<< ex:Engine_456 h:componentOf ex:Car_123 >>
h:inHolon ex:Car_123 .
# Fully expanded (no syntactic sugar)
ex:Engine_456 h:componentOf ex:Car_123 .
_:r1 rdf:reifies
<<( ex:Engine_456 h:componentOf ex:Car_123 )>> .
_:r1 h:inHolon ex:Car_123 .
The nested @holon ex:Engine_456 block desugars analogously.
RDF 1.2 distinguishes three things that are easy to conflate [[RDF12-CONCEPTS]]:
:s :p :o . claims that
the relationship holds in the graph's interpretation.<<( :s :p :o )>>
denotes the triple (:s, :p, :o) as an RDF term. A triple
term may appear only as the object of another triple, never as a subject, and
asserting a triple that contains a triple term in object position does
not assert the inner triple.rdf:reifies. It identifies a particular occurrence of the
underlying triple and is itself an ordinary RDF resource that may appear as
either subject or object.
Three verbs therefore have distinct meanings in this specification:
a triple is asserted when it appears in the graph as a normal claim;
a triple term denotes a triple-as-RDF-term without claiming it;
a reifier reifies a triple term, attaching identity to one of its
occurrences without claiming it. RDF-H's
annotation verb (?r h:inHolon ?H) attaches the reifier to a
holon — it neither asserts the underlying triple on its own nor denotes it as an
RDF term. Criterion 4 of ties annotation
to assertion explicitly.
In Turtle 1.2 [[RDF12-TURTLE]] the bare-brace form << ?s ?p ?o >>
is syntactic sugar for a fresh blank-node reifier together with the
rdf:reifies triple that ties it to the underlying triple term. Concretely,
<< ?s ?p ?o >> h:inHolon ?H . expands to
_:b rdf:reifies <<( ?s ?p ?o )>> . _:b h:inHolon ?H .
Asserting this does not by itself assert ?s ?p ?o — it only asserts
that a reifier of that triple is in holon ?H.
RDF-H therefore imposes the following normative requirement:
?r with ?r h:inHolon ?H in a conformant
RDF-H graph, if ?r rdf:reifies <<( ?s ?p ?o )>> holds, then
the base triple ?s ?p ?o MUST also
be asserted in the same graph.@holon directive of Turtle-H satisfies this requirement automatically
by emitting both the asserted triple and the reifier-with-h:inHolon on
desugaring (see the desugaring rules)."Being in a holon" is therefore an annotation on a relationship that is already claimed to hold; it never substitutes for the assertion itself.
The asserted-base-triple requirement is necessary because RDF 1.2 Semantics
[[RDF12-SEMANTICS]] places no truth-preserving constraint on
rdf:reifies: asserting that a reifier reifies a triple term carries no
model-theoretic commitment to the truth of the underlying triple.
Without the explicit RDF-H rule above, an RDF-H graph could legitimately contain
?r h:inHolon ?H for a reifier of a triple that is not itself asserted, which
would make holons unsound containers for the relationships they purport to gather. RDF 1.2
Semantics likewise places no identity constraint on reifiers of the same triple term, which
is what enables the multiple-holons-per-triple pattern shown below.
The Turtle 1.2 annotation syntax {| h:inHolon ?H |} is equivalent to the
reified-triple sugar (forms (b) and (c) shown in )
and idiomatic when the holon context is attached to a single triple. The
multi-holon pattern below uses it directly.
A single base triple MAY appear in more than one holon.
Each additional containing holon is recorded by an additional reifier carrying its own
h:inHolon. There is no implicit relationship between the holons that share a
triple.
@prefix ex: <https://example.org/> .
@prefix h: <https://w3id.org/rdf-h#> .
ex:Engine_456 h:componentOf ex:Car_123
{| h:inHolon ex:Car_123 |}
{| h:inHolon ex:DriveTrain_789 |} .
Each {| ... |} block allocates a fresh blank-node reifier for the
surrounding triple [[RDF12-TURTLE]]. The two annotation blocks above therefore produce two
distinct reifiers of the same base triple, each carrying its own
h:inHolon annotation — placing the single relationship into both
ex:Car_123 and ex:DriveTrain_789 without identifying the two
holons or their respective triple-occurrences. A reader who naturally assumes "one reifier
per asserted triple" should note that RDF 1.2 imposes no such constraint: distinct
reifiers MAY reify the same triple term, and RDF-H
relies on this freedom for the multi-holon pattern.
In the named-graph profile the same pattern is even
more direct: the triple simply appears in both content graphs —
GRAPH ex:Car_123 { ex:Engine_456 h:componentOf ex:Car_123 } and
GRAPH ex:DriveTrain_789 { ex:Engine_456 h:componentOf ex:Car_123 } — with no
reifiers involved.
Turtle-H is surface syntax for the reifier profile: a Turtle-H processor
MUST NOT treat an @holon block
as a TriG [[TRIG]] named graph, and desugars it to h:inHolon annotations
within a single graph. This is distinct from the named-graph profile
(), where a holon's content graph
is a named graph realized in a dataset and authored with ordinary TriG /
GRAPH syntax. Both encode the same content graph
(); the prohibition here is only
that the @holon directive is not itself TriG. The converse is a
grammar property (see ), not a normative
requirement on TriG processors.
Future direction. Turtle-H is a Turtle 1.2 surface-syntax extension
whose only specified semantics is its desugaring (above). The @holon token,
the EBNF productions in , and the desugaring
rules are intended to remain stable across possible extraction or upstreaming; see
Open Issue 6.
Querying RDF-H graphs requires no SPARQL extension. The exact surface depends on the
serialization profile (): the
named-graph profile is queried with plain SPARQL 1.1 [[SPARQL11-QUERY]] using the
GRAPH clause, while the reifier profile additionally uses the SPARQL
1.2 reified-triple patterns and triple-term syntax that accompany the RDF 1.2 reifier model
[[RDF12-CONCEPTS]]. Two query patterns recur throughout:
<< ?s ?p ?o >> h:inHolon ?H matches any reifier of a
triple ?s ?p ?o filed in holon ?H (fully expanded:
?r rdf:reifies <<( ?s ?p ?o )>> . ?r h:inHolon ?H .). In the
named-graph profile the same membership is GRAPH ?H { ?s ?p ?o }.h:partOf+ for the transitive closure across the whole part-of
hierarchy (under RDFS entailment), or h:componentOf+ /
h:memberOf+ /
h:substanceOf+ /
h:portionOf+ for the specific sub-relations.shows how these combine to extract a holon's content graph and deep content; the worked example in demonstrates them with domain-specific predicates.
A holon's content graph CG(H) is recovered by a
one-line query. In the reifier profile:
PREFIX h: <https://w3id.org/rdf-h#>
SELECT ?s ?p ?o WHERE {
<< ?s ?p ?o >> h:inHolon ex:Floor_3 .
}
In the named-graph profile the same content graph is the named graph itself:
SELECT ?s ?p ?o WHERE {
GRAPH ex:Floor_3 { ?s ?p ?o }
}
Deep content CG*(H) rolls the content
graphs of H and all its parts together (reifier profile;
h:partOf* binds ?w to ex:Building_A and every
part of it, under RDFS entailment):
PREFIX h: <https://w3id.org/rdf-h#>
SELECT ?s ?p ?o WHERE {
?w h:partOf* ex:Building_A .
<< ?s ?p ?o >> h:inHolon ?w .
}
The named-graph form replaces the reified-triple pattern with
GRAPH ?w { ?s ?p ?o }.
The Shapes Constraint Language (SHACL) [[SHACL]] is the standard mechanism for validating RDF
graphs. The RDF-H vocabulary ships five ready-to-run SHACL shapes;
their full Turtle definitions live in rdfh.ttl and are summarized below.
A conformant RDF-H Graph MUST pass the two
normative shapes; the other three are advisory (sh:Warning)
— they encode portability and modeling-discipline recommendations, not conformance
requirements. All five target the reifier profile; the named-graph profile's additive
invariant is a dataset-level property checked out of band
().
SPARQL 1.2 dependency. Three of the five shapes —
h:AssertedBaseTripleShape, h:MereologicalCoherenceShape, and
h:ContextualCoherenceShape — match a reifier against its triple term with the
SPARQL 1.2 pattern rdf:reifies <<( ?s ?p ?o )>>, so they require a
SHACL engine whose embedded SPARQL supports triple terms. Processors targeting an earlier
SPARQL profile MAY substitute an equivalent extraction
of the reified triple's components, provided the resulting shape accepts exactly the same
set of graphs. h:AcyclicPartShape and h:HolonIntegrityShape use
only SPARQL 1.1. All five queries are pre-binding-safe: they avoid the
VALUES, MINUS, and SERVICE constructs that
SHACL-SPARQL prohibits in constraint queries [[SHACL]], so they are accepted by conformant
SHACL-SPARQL processors (verified against pySHACL for the SPARQL 1.1 shapes).
Complete holons. Completeness of a complete holon's content graph is checked by domain-specific shapes rather than a single built-in shape; the pattern is in .
Validating the named-graph profile. All five shipped shapes target the
reifier profile (subjects of h:inHolon, or subjects/objects of the
part properties), so they do not fire on a dataset that records membership purely as named
graphs (). The additive invariant needs
no check here — it holds by construction (). For the rest: (1) for the membership-keyed shapes
(asserted-base-triple, coherence, holon-typing), convert to the reifier profile using the
profile translation and apply the shapes, or run an
equivalent GRAPH-based check per holon; and (2) check acyclicity by applying
h:AcyclicPartShape to the union of the dataset's graphs (the
asserted graph G), which contains every part-of triple. Native dataset-aware
SHACL validation across named graphs is not covered by standard SHACL and is left to
implementations.
Each shape carries its own target(s) and expresses its check as a standard
SPARQL-based constraint (sh:sparql with an inline
sh:SPARQLConstraint), so loading rdfh.ttl as the shapes
graph validates an RDF-H data graph directly — no additional shape wiring is required.
The shapes follow an identical pattern; only the targets, the
sh:select query, and the message differ. The acyclicity shape is shown in
full below:
h:AcyclicPartShape
a sh:NodeShape ;
sh:targetSubjectsOf h:partOf, h:componentOf, h:memberOf,
h:substanceOf, h:portionOf ;
sh:targetObjectsOf h:hasPart, h:hasComponent, h:hasMember,
h:hasSubstance, h:hasPortion ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "The focus node participates in a part-of cycle." ;
sh:select """
PREFIX h: <https://w3id.org/rdf-h#>
SELECT $this WHERE {
$this ( h:partOf | h:componentOf | h:memberOf | h:substanceOf | h:portionOf
| ^h:hasPart | ^h:hasComponent | ^h:hasMember | ^h:hasSubstance | ^h:hasPortion )+ $this .
}
""" ;
] .
Why SPARQL-based constraints (not a custom constraint component)?
A SHACL sh:ConstraintComponent is activated on a shape only when the shape
supplies values for the component's mandatory sh:parameters; a
parameter-less component never fires. These checks take no parameters, so they are
expressed directly as SPARQL-based constraints. (Earlier drafts declared
parameter-less sh:ConstraintComponents; see
.)
h:AcyclicPartShape
Enforces criterion 2.
A focus node violates the constraint if there exists a non-empty path from the
focus node back to itself that steps "towards the whole." To make the check
robust on engines that do not apply an entailment regime, the
sh:select path alternates over every built-in part-property in
both the part-of direction
(h:partOf, h:componentOf, h:memberOf,
h:substanceOf, h:portionOf) and the inverse
has-direction (^h:hasPart, … ^h:hasPortion). The inverse
arms matter because owl:inverseOf is not an RDFS rule: a cycle
authored with h:hasPart / h:hasComponent would escape a
plain h:partOf+ check.
Because h:partOf is itself in the alternation, the same shape also
catches cycles through custom extension sub-properties whenever the graph
is evaluated under RDFS entailment [[SPARQL11-ENTAILMENT]] (which
entails an h:partOf edge for every sub-property edge). Engines
without RDFS entailment catch every cycle in the built-in vocabulary; they catch
extension-introduced cycles only after the relevant
rdfs:subPropertyOf / owl:inverseOf entailments are
materialized.
Targets cover every node with an outgoing "part" step — subjects of the
part-of-direction properties and objects of the has-direction properties.
Targeting only sh:targetClass h:Holon would be insufficient: cycles
among untyped resources would go undetected.
h:AssertedBaseTripleShape
Enforces criterion 3 (the additive
invariant): every
reifier carrying an h:inHolon annotation must reify a triple that
is itself asserted in the graph. A focus node violates the constraint if it is
the subject of both h:inHolon and
rdf:reifies <<( ?s ?p ?o )>> but the underlying base
triple ?s ?p ?o is not asserted.
Recommended target: sh:targetSubjectsOf h:inHolon. The Turtle-H
@holon directive satisfies this constraint automatically; the validator
primarily catches violations introduced by hand-authored fully-expanded RDF 1.2
forms, graph merges that drop the base triple, or buggy serialization pipelines.
This shape uses the SPARQL 1.2 triple-term pattern
<<( ?s ?p ?o )>>; see the
SPARQL 1.2 dependency note above for the substitution
allowance on earlier-profile engines.
These three shapes are declared sh:severity sh:Warning; they surface
portability and coherence recommendations and never report a conformance-level
sh:Violation.
h:HolonIntegrityShape
Surfaces holons whose h:Holon typing depends on RDFS entailment
rather than an explicit rdf:type assertion. Under an RDFS-aware
engine the constraint is trivially satisfied via the
rdfs:range axiom on h:inHolon; under a non-inferring
engine the focus node violates the constraint if it is the object of an
h:inHolon triple but is not explicitly typed h:Holon.
Modelers SHOULD declare
h:Holon explicitly for every holon. Target:
sh:targetObjectsOf h:inHolon.
h:MereologicalCoherenceShape
Encodes mereological coherence:
a part-of relation filed in holon H should describe H's
own composition. The focus node (a reifier with h:inHolon ?H) is
flagged if it reifies a built-in part-of relation whose whole is neither
?H nor a part of ?H. Both reading directions are handled:
for a part-of-direction predicate (h:partOf, h:componentOf,
h:memberOf, h:substanceOf, h:portionOf) the
whole is the object; for a has-direction predicate (h:hasPart …
h:hasPortion) the whole is the subject. The "towards-the-whole" test
reuses the same part-step alternation as h:AcyclicPartShape with a
* quantifier (so whole = ?H passes via the
zero-length path). Custom sub-properties of h:partOf are not enumerated
(an advisory limitation mirroring the entailment caveat on
h:AcyclicPartShape). Target:
sh:targetSubjectsOf h:inHolon.
h:ContextualCoherenceShape
Encodes contextual coherence: an
occurrence filed in H should touch H. The focus node is
flagged if it reifies a triple ?s ?p ?o neither of whose
endpoints is ?H or a part of ?H (same part-step
alternation, applied to subject and object under UNION). Relations
with one external endpoint — a sensor monitoring a subsystem, an occupant of a
room — pass. Target: sh:targetSubjectsOf h:inHolon.
A complete holon asserts that its content graph is
complete, which licenses a closed-world reading within the holon. Completeness
is necessarily domain-specific (what counts as "complete" depends on the kind of
holon), so RDF-H does not ship a single closure validator; instead, model the expected
content with an ordinary SHACL shape and target it at the complete holons. For example,
requiring that every closed bldg:Floor holon contain exactly one HVAC
component:
ex:CompleteFloorShape
a sh:NodeShape ;
sh:targetClass h:CompleteHolon ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A closed floor holon must contain exactly one HVAC component." ;
sh:select """
PREFIX h: <https://w3id.org/rdf-h#>
PREFIX bldg: <https://example.org/bldg#>
SELECT $this WHERE {
$this a bldg:Floor .
{
# Ungrouped COUNT — yields 0 (not an empty result) when the
# closed floor has no HVAC component, so the zero case is caught.
SELECT (COUNT(?hvac) AS ?n) WHERE {
<< ?hvac h:componentOf $this >> h:inHolon $this .
?hvac a bldg:HVAC .
}
}
FILTER (?n != 1)
}
""" ;
] .
The closed-world reading is sound precisely because h:CompleteHolon
promises that CG(H) is complete: the absence of a second HVAC occurrence
in the content graph can be read as "there is no second HVAC component," which an
open-world holon could not guarantee.
Closure is an advisory contract, not an entailment.
h:CompleteHolon carries no RDFS or OWL semantics: an OWL or RDFS reasoner
does not derive negative facts from it, and merging a complete holon's graph
with new triples does not automatically re-validate it. The closed-world reading is
honoured only by SHACL shapes (which are closed-world by construction) and by
consumers that opt in. Implementers MUST NOT
assume a reasoner enforces closure; treat it as a signal that the closed-world
checks above are intended to apply.
This specification defines two classes of conformance: RDF-H Processor (a software component that consumes or produces RDF-H graphs) and RDF-H Graph (a body of RDF data that uses the RDF-H vocabulary). The criteria below summarize requirements stated normatively in the preceding sections.
Because the two serialization profiles () have very different tooling demands, conformance is stated against one of two named implementation profiles; an implementation MUST declare which it supports (it MAY support both):
rdf:reifies +
h:inHolon), including Turtle-H. It requires RDF 1.2 triple terms and,
for the shipped SHACL shapes, a SHACL engine whose embedded SPARQL supports triple
terms (SPARQL 1.2). This support is still maturing across implementations, so a
conformant processor MAY use the
component-extraction fallback noted in .GRAPH clause), and depends on the RDF-H asserted-graph interpretation
(asserted graph).The two profiles are content-equivalent under a projection (), so a graph authored for one can be consumed in the other by a processor that supports both.
A conformant RDF-H Processor MUST:
rdf:reifies, and the Turtle 1.2 reified
triple / annotation forms [[RDF12-TURTLE]]); for the Dataset Profile, a conformant RDF
dataset / SPARQL 1.1 processor [[RDF11-DATASETS]], [[SPARQL11-QUERY]].A conformant RDF-H Processor SHOULD:
h:Holon typing
for objects of h:inHolon via the standard rdfs3 rule (see
) and rdfs:subPropertyOf traversal
for the h:partOf hierarchy.CG(H) (and, where applicable,
its deep content CG*(H)) for the
profile(s) it supports. A processor that supports
both profiles SHOULD implement the
profile translation so that data authored in one
profile can be consumed in the other.A conformant RDF-H Graph MUST:
h:partOf hierarchy. Concretely, no
resource ?x may stand in the relation
?x h:partOf+ ?x under RDFS entailment
[[SPARQL11-ENTAILMENT]]. This requirement is enforced by the
h:AcyclicPartShape defined in
.CG(H) MUST also be in the
asserted graph G. In the reifier
profile this is a genuine constraint: whenever ?r h:inHolon ?H and
?r rdf:reifies <<( ?s ?p ?o )>> are both present, the base
triple ?s ?p ?o MUST also be
asserted (enforced by h:AssertedBaseTripleShape,
). In the named-graph profile,
where G is the union of the dataset's graphs, the invariant holds by
construction (each named graph is part of that union), so there is nothing to
enforce.Coherence between a holon's content and the holon () is SHOULD-level and surfaced by advisory shapes (); it is not a MUST-level conformance criterion.
Acyclicity is enforced jointly: the SHACL validator under RDFS entailment catches
cycles through any sub-property of h:partOf (including custom
extension-defined ones); OWL DL additionally rules out one-step cycles in
h:componentOf and h:memberOf through their
owl:AsymmetricProperty declarations. See
and
for details.
This section presents a realistic, end-to-end RDF-H example: a digital twin of a single floor of an office building, including its HVAC (Heating, Ventilation, and Air Conditioning) subsystem, occupants, and material composition.
This example illustrates:
h:componentOf,
h:memberOf, h:substanceOf, h:portionOf);bldg:cooledBy,
bldg:monitors, bldg:occupies) placed inside a holon's
content graph — context membership that is not parthood, yet
coherent because each touches its holon;ex:Building_A_EnergyHistory holon, so the
portionOf relation about energy history lives in its own coherent
content graph rather than being filed under the building.
The example uses two namespace prefixes in addition to the RDF-H prefix:
bldg: for building-domain vocabulary defined in an external ontology, and
ex: for the instance data.
Turtle-H source:
@prefix bldg: <https://example.org/bldg#> .
@prefix ex: <https://example.org/twin/> .
@prefix h: <https://w3id.org/rdf-h#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
# --- Domain-specific vocabulary (external ontology) ---
bldg:monitors a owl:ObjectProperty .
bldg:occupies a owl:ObjectProperty .
bldg:cooledBy a owl:ObjectProperty .
bldg:address a owl:DatatypeProperty .
# --- Holon declarations (explicit typing recommended for portability) ---
ex:Building_A a h:Holon ; bldg:address "1 Market St, San Francisco, CA" .
ex:Building_A_EnergyHistory a h:Holon .
ex:Floor_3 a h:Holon .
ex:HVAC_F3 a h:Holon .
ex:Compressor_F3 a h:Holon .
ex:Room_301 a h:Holon .
# --- Top-level holon: the building, with its floors and tenant ---
@holon ex:Building_A {
ex:Floor_3 h:componentOf ex:Building_A .
ex:Floor_4 h:componentOf ex:Building_A .
ex:Tenant_Acme h:memberOf ex:Building_A .
}
# --- A separate holon for the building's energy history. The portionOf
# relation about annual energy belongs in its OWN content graph,
# not the building's: AnnualEnergy_2026 is a portion of the energy
# history, not a part of the building. ---
@holon ex:Building_A_EnergyHistory {
ex:AnnualEnergy_2026 h:portionOf ex:Building_A_EnergyHistory .
}
# --- Floor 3, with its rooms and shared HVAC subsystem ---
@holon ex:Floor_3 {
ex:Room_301 h:componentOf ex:Floor_3 .
ex:Room_302 h:componentOf ex:Floor_3 .
ex:HVAC_F3 h:componentOf ex:Floor_3 .
# Domain-specific relationships placed within the floor's content
# graph. cooledBy is not a part-of relation, but each relationship
# touches the floor (its endpoints are parts of Floor_3), so it is
# contextually coherent.
ex:Room_301 bldg:cooledBy ex:HVAC_F3 .
ex:Room_302 bldg:cooledBy ex:HVAC_F3 .
}
# --- Room 301: its wall (a component), occupants, and wall material ---
@holon ex:Room_301 {
ex:Room_301_NorthWall h:componentOf ex:Room_301 .
ex:Person_Smith bldg:occupies ex:Room_301 .
ex:Person_Jones bldg:occupies ex:Room_301 .
# Concrete is the substance of the north wall, which is a part of
# the room — so this part-of relation is mereologically coherent
# with the Room_301 holon.
ex:Concrete_Mix_C30 h:substanceOf ex:Room_301_NorthWall .
}
# --- HVAC subsystem: components and a domain-specific monitoring relation ---
@holon ex:HVAC_F3 {
ex:Compressor_F3 h:componentOf ex:HVAC_F3 .
ex:DuctNetwork_F3 h:componentOf ex:HVAC_F3 .
ex:TempSensor_F3 bldg:monitors ex:HVAC_F3 .
}
# --- Compressor: refrigerant is substance, transitive via h:partOf ---
@holon ex:Compressor_F3 {
ex:Refrigerant_R410A h:substanceOf ex:Compressor_F3 .
}
Each enclosed triple desugars to that triple plus an
h:inHolon annotation on its reifier — for example,
ex:Room_301 bldg:cooledBy ex:HVAC_F3 inside
@holon ex:Floor_3 picks up
<< ex:Room_301 bldg:cooledBy ex:HVAC_F3 >> h:inHolon ex:Floor_3.
See the desugaring rules. The above is the
reifier profile.
Same content, named-graph profile (TriG). The Floor 3 holon, written
as a named graph instead of @holon + reifiers. The holon IRI is both a
describable resource (default graph) and the name of its content graph:
# Default graph: the holon as a resource
ex:Floor_3 a h:Holon .
# Named graph ex:Floor_3 IS the content graph CG(ex:Floor_3)
GRAPH ex:Floor_3 {
ex:Room_301 h:componentOf ex:Floor_3 .
ex:Room_302 h:componentOf ex:Floor_3 .
ex:HVAC_F3 h:componentOf ex:Floor_3 .
ex:Room_301 bldg:cooledBy ex:HVAC_F3 .
ex:Room_302 bldg:cooledBy ex:HVAC_F3 .
}
These five triples are in the asserted graph G simply by being in the
named graph, because G is the union of the dataset's graphs — the
additive invariant holds with no duplication into
the default graph. Both encodings yield the same CG(ex:Floor_3)
(); the reifier profile
additionally allows the same relationship to carry distinct per-occurrence
metadata across holons.
The following queries illustrate the kinds of questions the holonic structure makes straightforward to answer.
Query 1: List every part of ex:Building_A, at any depth,
regardless of part-of sub-type. RDFS-aware engines traverse all sub-properties of
h:partOf.
PREFIX ex: <https://example.org/twin/>
PREFIX h: <https://w3id.org/rdf-h#>
SELECT DISTINCT ?part WHERE {
?part h:partOf+ ex:Building_A .
}
Expected results (under RDFS entailment): ex:Floor_3,
ex:Floor_4, ex:Tenant_Acme,
ex:Room_301, ex:Room_302,
ex:HVAC_F3, ex:Room_301_NorthWall,
ex:Concrete_Mix_C30, ex:Compressor_F3,
ex:DuctNetwork_F3, ex:Refrigerant_R410A.
The wall and its concrete are now in the closure because the wall is a declared
component of ex:Room_301 and the concrete is its substance — both
transitively parts of the building.
ex:AnnualEnergy_2026 is not returned: it lives in the
separate ex:Building_A_EnergyHistory holon and is a
h:portionOf the energy history, not of the building. Neither are
ex:Person_Smith, ex:Person_Jones, or
ex:TempSensor_F3 — they appear in holon content graphs via
domain predicates (bldg:occupies,
bldg:monitors), not part-of relations, so they are contextually
related to their holons without being parts. Content membership and part
membership remain distinct; they are simply
coherent here.
Query 2: What relationships are scoped to the floor's holonic context?
This finds every triple-occurrence whose reifier is h:inHolon ex:Floor_3.
PREFIX ex: <https://example.org/twin/>
PREFIX h: <https://w3id.org/rdf-h#>
SELECT ?s ?p ?o WHERE {
<< ?s ?p ?o >> h:inHolon ex:Floor_3 .
}
Returns the five statements inside @holon ex:Floor_3. Structurally
identical triples in other holons are not returned, because each
assertion has its own reifier.
Query 3: Find every temperature sensor that monitors an HVAC
subsystem somewhere in ex:Building_A, joining a domain-specific
relationship with the holonic structure.
PREFIX bldg: <https://example.org/bldg#>
PREFIX ex: <https://example.org/twin/>
PREFIX h: <https://w3id.org/rdf-h#>
SELECT ?sensor ?hvac WHERE {
?sensor bldg:monitors ?hvac .
?hvac h:partOf+ ex:Building_A .
}
Returns (ex:TempSensor_F3, ex:HVAC_F3). The query mentions neither
floors nor rooms — the transitive h:partOf+ traversal does the work.
Applying the SHACL shapes from to the example graph produces no violations:
h:AcyclicPartShape finds no
part-of cycle.h:AssertedBaseTripleShape reports no violations because the
Turtle-H @holon desugaring emits both the base triple and the
h:inHolon annotation for every enclosed statement.h:HolonIntegrityShape finds nothing missing because every
holon used as the object of h:inHolon is explicitly typed
h:Holon (the holon declarations near the top of the example).h:MereologicalCoherenceShape and
h:ContextualCoherenceShape raise no warnings: every part-of relation
is filed in the holon it composes, and every domain relation touches its holon.
(Before this revision, filing AnnualEnergy_2026 h:portionOf
ex:Building_A_EnergyHistory inside @holon ex:Building_A would
have raised a mereological-coherence warning — which is why it now lives in its
own holon.)To illustrate detection, consider the following invalid addition to the graph:
# A bug: the building is mistakenly declared a component of one of its own floors. ex:Building_A h:componentOf ex:Floor_3 .
The h:AcyclicPartShape reports a violation on
ex:Building_A: its path traverses h:componentOf
directly (no entailment needed), producing the cycle
ex:Building_A → ex:Floor_3 → ex:Building_A. An OWL DL reasoner
additionally flags the graph as inconsistent because
h:componentOf is declared owl:AsymmetricProperty.
Because a holon's content graph is a well-defined subset of the
asserted graph, it is a natural unit of authorization. Suppose the building's owner
wants the tenant ex:Tenant_Acme to see only the model of the
floor it occupies. In the named-graph profile that
is a one-line grant, because CG(ex:Floor_3) is the named graph
ex:Floor_3: the store authorizes the tenant to read that graph (and
whichever sub-holon graphs roll up into it) and nothing else. A SPARQL endpoint can
enforce the same scoping with a dataset that exposes only the permitted named graphs,
so the tenant's query
SELECT ?s ?p ?o WHERE { GRAPH ex:Floor_3 { ?s ?p ?o } }
returns Floor 3's relationships without revealing other floors, occupants, or the
building-level holon. The same projection is available in the reifier profile via the
content-graph query, though there the base
triples also live in the single asserted graph, so view scoping must be enforced by the
query/authorization layer rather than by graph isolation (see
). Declaring
ex:Floor_3 a h:CompleteHolon additionally lets the tenant treat the exposed
content graph as complete for the floor.
Turtle-H extends Turtle 1.2 [[RDF12-TURTLE]] with one additional alternative on the statement production. Italicized productions (e.g., iri, BlankNode, triples) refer to Turtle 1.2 and are not redefined here.
[H1] statement ::= directive | triples '.' | holonBlock
[H2] holonBlock ::= '@holon' holonId '{' holonContent* '}'
[H3] holonId ::= iri | BlankNode
[H4] holonContent ::= triples '.' | holonBlock
Whitespace and comments follow Turtle 1.2 rules. The @holon keyword is
case-sensitive.
Desugaring. A Turtle-H parser
MUST translate each holonBlock per the
desugaring rules: each enclosed
?s ?p ?o . triple is emitted alongside
<< ?s ?p ?o >> h:inHolon ?H . for the enclosing holonId
?H. Predicate-object and object lists produce one
h:inHolon annotation per generated triple; nested
holonBlocks desugar recursively against their own enclosing holonId.
Disambiguation from TriG. The holonBlock begins with
@holon, which is not a valid token at the same grammatical position in
Turtle 1.2 or TriG [[TRIG]]. A Turtle-H parser
MUST NOT treat a TriG named-graph block
(iri '{' triples '}') as a holonBlock; conversely, a TriG parser
encountering Turtle-H input will reject it as a syntax error. This is a property of the
two grammars and imposes no requirements on TriG processors, which are governed by
[[TRIG]] and lie outside the scope of this specification.
The editors invite community feedback on the following questions, each intended to be resolved before v1.0.
h:partOf hierarchy be extracted into a standalone vocabulary
at a sibling namespace (e.g., https://w3id.org/rdf-mereo#)? If so, what
migration guidance is required for graphs authored against the bundled v0.x form?
w3id.org namespace redirecthttps://w3id.org/rdf-h# requires a redirect entry in
perma-id/w3id.org; until that PR is
merged, RDF-H IRIs are not dereferenceable on the open web.
h:directlyPartOf split and lifted asymmetry /
irreflexivity directly onto h:componentOf and h:memberOf,
with acyclicity enforced by SHACL alone. The vocabulary remains in OWL 2 DL.
Feedback welcome on whether to reopen alternatives (e.g., accepting OWL Full to
recover a strict immediate-part top-level relation).
CG(H) = ∅ — a well-defined, non-degenerate case — reachable via an
explicit rdf:type h:Holon assertion
(see ). The spec therefore keeps the
permissive interpretation and does not require non-emptiness. Feedback welcome on
whether any domain genuinely needs a non-empty constraint (which can in any case be
imposed with a domain SHACL shape).
h:CompleteHolon)CG(H)"? — is resolved by
h:CompleteHolon: typing a holon
h:CompleteHolon asserts CG(H) is complete and supports a
completeness-scoped (local closed-world) reading, validated by domain SHACL shapes
() rather than by entailment. Open
sub-question: should completeness also be expressible per-relation (e.g. "these are
all the components of H") rather than only per-holon?
@holon — or a
predicate-parameterized generalization — to the Turtle Working Group for
possible inclusion in a future Turtle revision?https://w3id.org/rdf-h#. Should they be split pre-emptively
(e.g., hv: / hm: / hsh:) to ease future
extraction (see Open Issue 1,
Open Issue 6), defer the question until
extraction, or rely on owl:equivalentClass /
owl:equivalentProperty aliases at extraction time?
rdf:reifies, which carries no truth
force)?
RDF-H introduces no new security or privacy considerations beyond those of the underlying specifications it depends on ([[RDF12-CONCEPTS]], [[RDF12-SEMANTICS]], [[RDF12-TURTLE]], [[SPARQL11-QUERY]], [[SHACL]]). Implementers and consumers of RDF-H graphs should however be aware of the following:
h:inHolon annotations
identify occurrences of triples (via reifiers), an RDF-H graph may carry more
identifying or contextual information about a triple than a flat RDF graph would. When
merging or publishing RDF-H graphs that originated from access-controlled subgraphs,
publishers SHOULD review which holons are
exposed and whether the resulting triple-occurrence metadata constitutes an
information leak.@holon directive)
are not stable across graph serializations. Applications that rely on reifier identity
across exchanges SHOULD use IRI reifiers
explicitly.CG(H) as a whole. This is the basis of the
fine-grained access-control use case (see
). Publishers SHOULD nonetheless remember that the additive invariant keeps every
filed triple in the asserted graph G, so restricting a content-graph
view does not by itself hide a triple that is also reachable through
G or another holon.CG(H)" as "does not exist."
When a complete holon is derived from an access-controlled or redacted source, that
completeness claim can itself leak information (it reveals that nothing was withheld).
Publishers SHOULD avoid marking a holon
h:CompleteHolon when its content was filtered for confidentiality.CG(H), defined abstractly and
realized by two interoperable profiles — a reifier profile
(rdf:reifies + h:inHolon, single graph,
per-occurrence metadata) and a named-graph profile (RDF datasets,
GRAPH-queryable) — with a stated equivalence between them
(). Added the
additive invariant CG(H) ⊆ G
(the general form of the v0.6 asserted-base-triple rule), h:contentGraph,
h:CompleteHolon (a local completeness contract, not a global
closed-world assumption), and
deep content CG*(H). The
named-graph profile's asserted graph G is the
union of the dataset's graphs — an RDF-H
stipulation, not default RDF dataset semantics — and the two profiles are
content-equivalent under a projection
(). Defined
Reifier and Dataset implementation profiles,
and gave closure-vs-immediate guidance for custom part-properties. Reframed
named graphs from "rejected" to an alternative profile, and recast the abstract
around content graphs.h:MereologicalCoherenceShape,
h:ContextualCoherenceShape) so a holon's content graph is normally
about the holon; cross-context placement is now the documented
exception. Reworked the worked example accordingly (the energy-history
portionOf now lives in its own holon). Clarified that Turtle-H
nesting is purely lexical and that roll-up follows parthood.sh:ConstraintComponents — which declared a sh:validator
but no sh:parameter and so could never activate on a standard SHACL
processor — with plain sh:NodeShapes using standard SPARQL-based
constraints (sh:sparql / sh:SPARQLConstraint) that
carry their own targets, so loading rdfh.ttl as the shapes graph
validates a data graph directly. Removed the invalid
sh:constraint [ a … ] invocation example. Renamed the shapes
(…ConstraintComponent → …Shape) and split
into Normative and
Advisory groups. The acyclicity path now alternates explicitly over all
five part-of-direction sub-properties and their five inverse has-direction
properties — catching cycles authored via h:hasPart /
h:hasComponent without relying on owl:inverseOf
entailment — while keeping h:partOf in the alternation so
RDFS-entailing engines still catch cycles through custom extension
sub-properties. Advisory shapes are sh:severity sh:Warning.h:CompleteHolon); added Issue 8
(contextual holons).h:directlyPartOf /
h:hasDirectPart; h:componentOf and
h:memberOf are now direct asymmetric/irreflexive sub-properties of
h:partOf. Added a normative
MUST NOT on transitive sub-properties
of the asymmetric/irreflexive part-properties (OWL 2 simple-role safety).h:AssertedBaseTripleConstraintComponent
operationalized the asserted-base-triple MUST as a new conformance criterion 4; §validation split into
Normative and Portability validators. (The constraint
components and acyclicity check were reworked in v0.7.)@holon block scopes the relationship, not its endpoints;
holon and reifier roles are independent. (This independence framing was
revisited in v0.7 in favour of content/holon coherence.)h-holon-type rule
as RDFS rdfs3; renamed §Acyclicity (dropped the ZF analogy);
updated rdfh.ttl and README.md to match; added
Open Issue 7 (namespace split).rdf:reifies; no more
"RDF-star" or rdf:TripleTerm).h:partOf and a
non-transitive, asymmetric, irreflexive h:directlyPartOf (kept
the vocabulary in OWL 2 DL).@holon directive
to eliminate the TriG syntactic collision.RDF-H in a single page.
| Layer | Terms |
|---|---|
| Core vocabulary | h:Holon, h:inHolon,
h:contentGraph, h:CompleteHolon |
| Content graph | CG(H) view; reifier & named-graph profiles; additive
invariant CG(H) ⊆ G |
| Mereology (transitive top-level) | h:partOf / h:hasPart |
| Mereology (asymmetric, irreflexive sub-properties) | h:componentOf / h:hasComponent,
h:memberOf / h:hasMember |
| Mereology (transitive sub-properties) | h:substanceOf / h:hasSubstance,
h:portionOf / h:hasPortion |
| Surface syntax (Turtle-H) | @holon directive |
| SHACL shapes (normative) | h:AcyclicPartShape,
h:AssertedBaseTripleShape |
| SHACL shapes (advisory) | h:HolonIntegrityShape,
h:MereologicalCoherenceShape,
h:ContextualCoherenceShape |
Conformance criteria for an RDF-H Graph.
h:partOf under RDFS entailment.CG(H) ⊆ G: every triple filed in a
holon is also asserted. (Reifier profile: whenever ?r h:inHolon ?H and
?r rdf:reifies <<( ?s ?p ?o )>> both hold, ?s ?p ?o
MUST also be asserted.)The @holon desugaring.
@holon ?H { ?s ?p ?o . } emits two triples:
the base assertion ?s ?p ?o ., and the reifier annotation
<< ?s ?p ?o >> h:inHolon ?H .
The editors thank the Spatial Web Foundation for early feedback and discussions that have shaped this specification.