Reification is a mechanism to make RDF statements about other RDF statements. This document introduces a SHACL constraint component based on the property dash:reifiableBy that can be used to instruct processors about the shape that reified statements should conform to. dash:reifiableBy links a SHACL property shape with a SHACL node shape that may be used to drive user input or to validate reified statements.

This document uses the prefix dash which represents the DASH Data Shapes namespace http://datashapes.org/dash# which is accessible via its URL http://datashapes.org/dash.

Goals

This document introduces a general-purpose vocabulary that can easily be supported by APIs and tools from various vendors. The approach is, for example, implemented as part of TopBraid EDG.

Like most features from the DASH namespace, the specifications here may serve as input to future iterations of the official SHACL standards.

Background: Implementation Approaches to Reification in RDF

Reification is the ability to make statements about statements. For example, you may want to track the date a statement was made and who made it:

ex:Bob ex:age 23 .
    # ex:date "2019-12-05"^^xsd:date ; 
    # ex:author ex:Claire ;
			

In its current stable version 1.1, the RDF data model is based on subject-predicate-object triples only, but does not have a built-in mechanism to efficiently represent such reified statements. However, the upcoming version 1.2 includes support for an extension called RDF-star. RDF-star introduces a new type of RDF nodes that can represent a "quoted" triple, and these nodes can appear as subject or object of other triples, representing statements about these triples.

In the current RDF 1.2 draft, there are two syntaxes to represent such statements. The most general syntax uses <<...>> to enclose quoted triples:

ex:Bob ex:age 23 .

<<ex:Bob ex:age 23>>
	ex:date "2019-12-05"^^xsd:date ;
	ex:author ex:Claire .

Alternatively, so-called annotations provide this short-hand for cases where a statement is both asserted and the subject of statements about statements:

ex:Bob ex:age 23 {|
	ex:date "2019-12-05"^^xsd:date ;
	ex:author ex:Claire ;
|}

In TopBraid's current version, the syntax for that case uses [[ ... ]]:

ex:Bob ex:age 23 [[
	ex:date "2019-12-05"^^xsd:date ;
	ex:author ex:Claire ;
]] .

Furthermore, the current TopBraid implementation uses "long" URI nodes to represent quoted triples. These will only be visible when you browse source code but are usually hidden by the user interface. A future version of TopBraid will support RDF-star, for example once RDF 1.2 becomes official.

dash:reifiableBy

The property dash:reifiableBy can be used to link a SHACL property shape with one or more node shapes. Any reified statement must conform to these node shapes.

The following example states that all reified values of ex:age at the class ex:Person must conform to the (provenance) shape that defines date and author properties:

ex:ProvenanceShape
	a sh:NodeShape ;
	sh:property [
		a sh:PropertyShape ;
		sh:path ex:date ;
		sh:datatype xsd:date ;
		sh:maxCount 1 ;
		sh:order "0"^^xsd:decimal ;
	] ;
	sh:property [
		a sh:PropertyShape ;
		sh:path ex:author ;
		sh:nodeKind sh:IRI ;
		sh:maxCount 1 ;
		sh:order "1"^^xsd:decimal ;
	] .

ex:PersonShape
	a sh:NodeShape ;
	sh:targetClass ex:Person ;
	sh:property ex:PersonShape-age .

ex:PersonShape-age
	a sh:PropertyShape ;
	sh:path ex:age ;
	sh:datatype xsd:integer ;
	sh:maxCount 1 ;
	dash:reifiableBy ex:ProvenanceShape .

Regardless of which specific reification implementation is chosen, the information above can be exploited by tools to drive and validate user input. For example, in TopBraid 6.3, the edit forms will display a "nested" form section that can be opened below each value that is of a reifiable property:

Similar reification shapes can be defined to attach metadata about SKOS labels, covering some of the use cases of SKOS-XL:

Tools can use dash:reifiableBy triples to check for the presence of reified triples and then highlight them in the user interface. Then, as the user enters details, the shape definition can be used to drive the input forms.

The SHACL validation component for dash:reifiableBy is called dash:ReifiableByConstraintComponent. Depending on the implemented reification approach, it may produce constraint violations on the focus node, path and value node of the base triple, and then use sh:detail to list the problems that were found on the reification shape.

dash:reificationRequired

The property dash:reificationRequired can be used in conjunction with dash:reifiableBy to indicate that there must be at least one reification value for the focus node/path combination in the data graph.

In the following variation of the above example, there will be a constraint violation if the age of a person is not reified by any triple.

ex:PersonShape-age
	a sh:PropertyShape ;
	sh:path ex:age ;
	sh:datatype xsd:integer ;
	sh:maxCount 1 ;
	dash:reifiableBy ex:ProvenanceShape ;
	dash:reificationRequired true .

For example, this instance would be invalid:

ex:InvalidPerson
    a ex:Person ;
    ex:age 42 .

Reification SPARQL Functions supported by TopBraid

This appendix lists some SPARQL functions that can be used within TopBraid to translate between reification URIs and triples. These functions may change and hopefully become obsolete in future versions, once TopBraid fully supports the upcoming SPARQL 1.2 functions. Meanwhile this section is provided as reference to TopBraid users.

tosh:reificationURI

The SPARQL function tosh:reificationURI constructs a URI that is used to represent a reified triple. The input is a subject, a predicate and an object node, and the output is a URI node that can then be used for example to add reified values or to query existing reifications.

The following query produces reification URIs for each triple that has owl:Thing as its subject and then fetches those reification URIs that have a value for ex:creator:

SELECT *
WHERE {
	BIND (owl:Thing AS ?s) .
	?s ?p ?o .
	BIND (tosh:reificationURI(?s, ?p, ?o) AS ?uri) .
	?uri ex:creator ?creator .
}

tosh:reificationURIOf

The SPARQL property function (magic property) tosh:reificationURIOf can be used to convert a reification URI (e.g., produced by tosh:reificationURI) back into subject, predicate and object components. It requires a reification URI on the left hand side and three unbound variables for subject, predicate and object on the right hand side.

In the following example query, we first iterate over all reification URIs that have a value for ex:creator and then disassemble them into subject, predicate and object components to learn the original triples that have been reified.

SELECT *
WHERE {
	?uri ex:creator ?creator .
	?uri tosh:reificationURIOf ( ?s ?p ?o ) .
}

tosh:reificationSubject/Predicate/Object

The SPARQL functions tosh:reificationSubject, tosh:reificationPredicate and tosh:reificationObject can be used to convert a reification URI (e.g., produced by tosh:reificationURI) back into subject, predicate and object components.

In the following example query, we first iterate over all reification URIs that have a value for ex:creator and then disassemble them into subject, predicate and object components to learn the original triples that have been reified.

SELECT *
WHERE {
	?uri ex:creator ?creator .
	BIND (tosh:reificationSubject(?uri) AS ?s) .
	BIND (tosh:reificationPredicate(?uri) AS ?p) .
	BIND (tosh:reificationObject(?uri) AS ?o) .
}

tosh:reifiedValue

The SPARQL function tosh:reifiedValue provides direct access to a value of a reified triple, e.g. the timestamp. It is primarily a convenience function to look up values if you already know subject, predicate and object.

The following example fetches the creator of the triple owl:Thing rdf:type rdfs:Class, if any exists.

SELECT ?creator
WHERE {
	BIND (tosh:reifiedValue(owl:Thing, rdf:type, rdfs:Class, ex:creator) AS ?creator) . 
}