RDF 1.2#
This chapter is a short introduction to RDF 1.2 using rudof.
Preliminaries: install and configure rudof#
%pip install -q "pyrudof>=0.3.22"
%pip install -q plantuml
Note: you may need to restart the kernel to use updated packages.
Note: you may need to restart the kernel to use updated packages.
from pyrudof import Rudof, ResultDataFormat
rudof = Rudof()
import subprocess
import sys
from pathlib import Path
from IPython.display import Image
def show_graph(session, name="out"):
"""Render the RDF data currently loaded in `session` as a diagram."""
Path(f"{name}.png").unlink(missing_ok=True)
Path(f"{name}.puml").write_text(
session.serialize_data(ResultDataFormat.PlantUML), encoding="utf-8"
)
subprocess.run(
[sys.executable, "-m", "plantuml", f"{name}.puml"],
check=True,
capture_output=True,
)
return Image(f"{name}.png")
Saying things about statements#
RDF 1.2 answers a question that plain RDF handles badly: how do you say something about a statement? Who claimed it, when, with what confidence, for what period of time.
In RDF 1.1 the usual answer was to invent an intermediate node (the “reification” pattern, or Wikidata’s statement nodes) which works but scatters one fact across four or five triples and loses the connection to the original statement.
RDF 1.2 introduces triple terms:
a triple can appear as the object of another triple, written between <<( and )>>.
Combined with the new rdf:reifies predicate, that gives a direct way to attach
information to a statement.
rudof.reset_all()
rudof.read_data("""
prefix : <http://example.org/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
:aliceBelief a :Statement ;
rdf:reifies <<( :bob :knows :dave )>> ;
:since 2025 ;
:accordingTo :dave .
""")
Read that as: :aliceBelief is a thing that reifies the statement “Bob knows Dave”, and
that thing has been held since 2025, according to Dave. The statement itself is a term, so
it can be pointed at; the annotations hang off the reifier, not off the statement.
rudof visualizes the two differently, which makes the distinction visible: a statement that is asserted as part of the graph is drawn as a box, while a triple term (which is not asserted) is drawn as a cloud.
show_graph(rudof)
Three ways to write it#
RDF 1.2 Turtle offers three syntaxes for this, of increasing convenience. They all produce triples of the same shape, so the choice is about readability, not meaning.
Triple terms#
The explicit form: write the triple term between <<( and )>> and say what reifies it.
This is what the example above used, and it is the form the other two expand into.
rudof.reset_all()
rudof.read_data("""
PREFIX : <http://www.example.org/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
_:e38 :familyName "Smith" .
_:anno rdf:reifies <<( _:e38 :jobTitle "Designer" )>> .
_:anno :accordingTo :eric .
""")
show_graph(rudof)
Reifying triples#
Enclosing a triple between << and >> is syntactic sugar: introduces a reifier for the triple, which can then be used as a subject. One line instead of
three.
rudof.reset_all()
rudof.read_data("""
PREFIX : <http://www.example.org/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
:employee38 :familyName "Smith" .
<< :employee38 :jobTitle "Assistant Designer" >> :accordingTo :employee22 .
""")
show_graph(rudof)
Annotation syntax#
The most compact form. Writing {| … |} right after a statement annotates that
statement, without repeating it. The optional ~ :t names the reifier, so you can refer
back to it later.
rudof.reset_all()
rudof.read_data("""
PREFIX : <http://example.com/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
:alice :name "Alice" ~ :t {|
:statedBy :bob ;
:recorded "2021-07-07"^^xsd:date
|} .
""")
show_graph(rudof)
Notice in the visualization that the statement :alice :name "Alice" is drawn as a box:
the annotation syntax asserts the statement as well as annotating it. That is the
difference from the explicit <<( … )>> form, where the triple term on its own asserts
nothing.
A worked example#
The annotation syntax comes into its own when the same statement is true several times over with different qualifications. Here, Tim Berners-Lee worked at CERN in two separate spells (1984–1994 and 1980) and received the Princess of Asturias Award in 2002 together with Vinton Cerf.
rudof.reset_all()
rudof.read_data("""
prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
:timbl rdfs:label "Tim Berners Lee" ;
:employer :CERN {| :start "1984" ;
:end "1994" |}
{| :start "1980" ;
:end "1980" |} ;
:award :PA {| :time "2002" ;
:togetherWith :vint |} .
:vint rdfs:label "Vinton Cerf" .
""")
show_graph(rudof)
The next chapter shows how to query these annotations with SPARQL 1.2.
References#
RDF 1.2 Primer - the introduction, including the motivation for triple terms.
RDF 1.2 Turtle - the three syntaxes used above.
RDF 1.2 Concepts - the normative data model.