Unfortunately, RDF, the data model underlying Linked Data and the Semantic Web, has no built-in mechanism to attach data to its source. To some extent, this is a deliberate choice in the design of the model, and also a deep one. True facts can’t really have sources, so a knowledge representation system that includes connections of facts to their sources is, in a way, polluted. Instead, RDF takes the point of view that statements are asserted, and if you want to deal with assertions and how they are asserted in a clean logic system, the assertions should be reified. — https://blogs.library.duke.edu/dcthree/2013/07/27/the-trouble-with-triples/

Let’s say we have following RDF graph:

:Alice → foaf:knows → :Bob

Or as graph (not a real notation, just for visualisation purposes)

flowchart LR
	:Alice ==> foaf:knows ==> :Bob	

And we want to add metadata to this relation, for example to specify that Alice knows Bob since 2002.

It would be straightforward task in labeled property Graph: ,

:Alice - {label=foaf:knows, ex:since="2002"} → :Bob
flowchart LR
	:Alice == "label=foaf:knows, ex:since=2002" ==> :Bob	

But in RDF you need to use reification for this task. And there is more than one approach how to do reification

Standard reification

:id1 → ex:subject → :Alice
:id1 → ex:predicate → foaf:knows
:id1 → ex:object → :Bob
:id1 → ex:since → "2002"
flowchart TD
	classDef red fill:red
	:id1:::red
	:id1 -- ex:subject --> :Alice
	:id1 -- ex:predicate --> foaf:knows
	:id1 -- ex:object --> :Bob
	:id1 -- ex:since --> q["2002"]

Singleton properties

:Alice → ex:knows → :Bob
ex:knows → ex:singletonPropertyOf → foaf:knows
ex:knows → ex:since → "2002"
flowchart LR
	classDef red fill:red
	ex:knows:::red
	:Alice ==> ex:knows ==> :Bob
	ex:knows --> ex:singletonPropertyOf --> foaf:knows
	ex:knows --> ex:since --> q["2002"]

Companion properties (cpprop)

It suppose to be similar to singleton property, but with lower number of unique properties

:Alice → ex:knows.1 → :Bob
:Alice → ex:knows.1.SID → :id1
ex:knows.1.SID → rdf:idPropertyOf → ex:knows.1
ex:knows.1.SID → rdf:companionPropertyOf → foaf:knows
:id1 → ex:since →  "2002"
flowchart LR
	classDef red fill:red
	ex:knows.1:::red
	:Alice ==> ex:knows.1 ==> :Bob
	:Alice --> ex:knows.1.SID --> :id1
	ex:knows.1.SID --> rdf:idPropertyOf --> ex:knows.1
	ex:knows.1.SID --> rdf:companionPropertyOf --> foaf:knows
	:id1 --> ex:since --> q["2002"]

Universal property graph

Read: A novel property graph model for knowledge representation on the Web

:Alice → ex:knows → :Bob
ex:knows → za:datatype → foaf:knows
ex:knows → ppi:1 → properties[ex:since → 2002]
flowchart LR
	classDef red fill:red
	ex:knows:::red
	:Alice ==> ex:knows ==> :Bob
	ex:knows --> za:datatype --> foaf:knows
	ex:knows --> ppi:1 --> properties["ex:since → 2002"]

N-ary relation

:Alice → foaf:knows → :id1
:id1 → ex:naryValue → :Bob
:id1 → ex:since → "2002"
flowchart LR
	classDef red fill:red
	:id1:::red
	:Alice ==> foaf:knows ==> :id1
	:id1 ==> ex:naryValue ==> :Bob
	:id1 --> ex:since --> q["2002"]

Named graphs

Named graphs is extension of RDF. Each triple additionaly contains one more IRI value (which make it quad) - identifier of the graph. This allows to put more than one graph in one document. Can be used to preserve source (for provenance), to version graphs, etc. But as well can be used for reification.

In different notations graph id can be in head or tail position. If in the head position:

graph:id1 → :Alice → foaf:knows → :Bob
ex:meta → graph:id1 → ex:since → "2002"

If in the tail position:

:Alice → foaf:knows → :Bob → graph:id1
graph:id1 → ex:since → "2002" → ex:meta
flowchart LR
	classDef red fill:red
	:id1["graph:id1"]:::red
	:Alice ==> foaf:knows ==> :Bob --> :id1
	:id1 --> ex:since --> q["2002"] --> ex:meta

Multilayer graph

Multilayer graph is extension of RDF-graph by adding unique id to each edge. This id can be used as node in the “next layer”. Neptune (1G) is implementation of multilayer graph

Neptune (1G)

Neptune is quad-store - triple store where each has unique id. The main saling point is that it can be used as RDF store and as property graph store.

:Alice → foaf:knows → :Bob → :id1
:id1 → ex:since → "2002" → :id2
flowchart LR
	classDef red fill:red
	:id1:::red
	:Alice ==> foaf:knows ==> :Bob --> :id1
	:id1 --> ex:since --> q["2002"] --> :id2

RDF-star

RDF-star is an extension of RDF

(:Alice → ex:knows → :Bob) → ex:since → 2002
flowchart LR
	subgraph X[ ]
		direction LR
		:Alice ==> foaf:knows ==> :Bob
	end
	X --> ex:since --> q["2002"]

If we would assign blank node (as opaque id) to each triple it would look the same as approach above.