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#

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:

flowchart LR MyList list1 list2 list3 nil Amy Bob Carly MyList -->|Friends| list1 list1 -->|rest| list2 list2 -->|rest| list3 list3 -->|rest| nil list1 -->|first| Amy list2 -->|first| Bob list3 -->|first| Carly

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#

Libraries#

See Also#