RDF and Friends#
RDF is one of the elephants in the room when it comes to triplet graphs and linked data. Its history is complex and torrid, known as hopelessly and aggressively complex or a divine calling, depending on your disposition.
p2p-ld does not necessarily seek to be an RDF-based p2p protocol, though strategizing for interoperability with RDF and RDF-derivative formats would be nice.
One of the primary challenges to using RDF-like formats is the conflation of URLs and URIs as the primary identifiers for schema and objects. This idea (roughly) maps onto the “neat” characterization of linked data where everything should have ideally one canonical representation, and there should be a handful of “correct” general-purpose schema capable of modeling the world.
We depart from that vision, instead favoring radical vernacularism [Saunders, 2023]. URIs are extremely general, and include decentralized identifiers like multiaddrs
RDF And Friends#
RDF has a lot of formats and
JSON-LD#
Challenges#
Tabular and Array Data#
Important
The edges from a node in a graph are unordered, which makes array and tabular data difficult to work with in RDF!
This has been approached in a few ways:
RDF uses a godforsaken rdf:first
rdf:rest
linked list syntax
eg. one would express MyList
which contains the Friends
["Arnold", "Bob", "Carly"]
in (longhand) turtle as
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <https://example.com> .
:MyList :Friends :list1 .
:list1
rdf:first :Amy ;
rdf:rest :list2 .
:list2
rdf:first :Bob ;
rdf:rest :list3 .
:list3
rdf:first :Carly ;
rdf:rest rdf:nil .
And thankfully turtle has a shorthand, which isn’t so bad:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <https://example.com> .
:MyList
:Friends (
:Amy
:Bob
:Carly
).
Both of these correspond to the triplet graph:
Which is not great.
JSON-LD uses a @list
keyword:
{
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
"@id": "http://example.org/people#joebob",
"foaf:nick": {
"@list": [ "joe", "bob", "jaybee" ]
},
}
which can be expanded recursively to mimic arrays
{
"@context": {
"@vocab": "https://purl.org/geojson/vocab#",
"coordinates": {"@container": "@list"}
},
"geometry": {
"coordinates": [
[
[-10.0, -10.0],
[10.0, -10.0],
[10.0, 10.0],
[-10.0, -10.0]
]
]
}
}
@prefix geojson: <https://purl.org/geojson/vocab#>.
[
a geojson:Feature ;
geojson:bbox (-10 -10 10 10) ;
geojson:geometry [
a geojson:Polygon ;
geojson:coordinates (
(
(-10 -10)
(10 -10)
(10 10)
(-10 -10)
)
)
]
] .
Naming#
All names have to be global. Relative names must resolve to a global name via contexts/prefixes. The alternative is blank nodes, which are treated as equivalent in eg. graph merges. Probably here enters pattern matching or whatever those things are called.
Blank nodes and skolemization https://www.w3.org/TR/rdf11-mt/#skolemization-informative
References#
W3C Recommendation on generating RDF from tabular data: [Tandy et al., 2015]
JSON Schema in RDF: [Charpenay et al., 2023]
Libraries#
biolink-model for a nice example of generating multiple schema formats from a .yaml file.
linkml - modeling language for linked data [Moxon et al., 2021]
Multidimensional arrays in linkml https://linkml.io/linkml/howtos/multidimensional-arrays.html
oaklib - python package for managing ontologies
rdflib - maybe the canonical python rdf library
See Also#
HYDRA vocabulary - Linked Data plus REST