A short example of how the CIDOC-CRM use case can be encoded with nested named graphs, modelled after Niklas' example on the mailinglist.
ex:Ioannes_68 a crm:E21_Person , ex:Gender_Eunuch ;
rdfs:label "John the Orphanotrophos" .
<#assignment-1> { ex:Ioannes_68 a ex:Gender_Eunuch }
a crm:E17_Type_Assignment ;
crm:P14_carried_out_by ex:Paphlagonian_family ;
rdfs:label "Castration gender assignment" .
[] { ex:Ioannes_68 a ex:Gender_Male }
a crm:E17_Type_Assignment ;
crm:P14_carried_out_by ex:emperor ;
crm:P182_inverse_starts_after_or_with_the_end_of <#assignment-1> ;
rdfs:label "Gender assignment by decree" .
[] { ex:Ioannes_68 a ex:Gender_Male }
a crm:E17_Type_Assignment ;
crm:P14_carried_out_by ex:Paphlagonian_family ;
crm:P183_ends_before_the_start_of <#assignment-1> ;
rdfs:label "Birth gender assignment" .
Descriptions and Situations (DnS) is an ontology design patterns that distinguishes the description of objects and the relations between these objects - not un-similar to the way Labeled Property Graphs model information. A particularly interesting concept is that of a "shortcut relation": a basic relation that captures the essential information hidden in a much more complex n-ary relation.
In the example below the central piece of information is that Alice visits the ISWC conference. That statement is annotated with links to background information like a detailed travel schedule and what she plans to do at the conference.
:T1 {
:Alice :travelsTo :ISWC23 .
THIS nng:predicate [ rdfs:seeAlso :S1 , # THIS graph self reference
:P1 ] .
} a :Travel .
:S1 {
:Schedule :startsAt :Hamburg ;
:byMeans :Plane ;
:date "05.11.2023" ;
:gate ...
} a :Schedule .
:P1 {
:Purpose :present :Poster ;
:topic :MetaVisualization ;
...
}
This example combines several orthogonal dimensions of annotation: application specific dimensions and unsound graph naming practices, administrative annotations intermixed with qualifying annotations.
:Bob :source :Laptop ;
:status :Unredacted ;
:visibility :Private .
:Bob {
:Z {
:Y {
:X {
:Alice :buys :Car .
}
nng:subject [ :age 20 ] ;
nng:predicate [ :payment :Cash ;
:purpose :JoyRiding ] ;
nng:object [ :color :black ;
:model :Coupe ] ;
nng:graph [ :source :Denis ] .
}
} :FirstCarEvent ;
:source :GreenDiary ;
:date :10_12_08 .
}
Imagine adding more levels of nesting for different accounts of Alice buying her first car, eg her parents helping fund it, the insurance company having yet a different view, etc. Nothing breaks, it's just adding more layers of nesting.
The notorious Superman problem can be addressed as an application of graph literals, for example using the proposed syntactic sugar for nng:Record
s (asserted, but referentially opaque types):
[] {":LoisLane :loves :Superman"} .
Even a much more precise variant via a term literal is thinkable:
:LoisLane :loves []{":Superman"} .
Here only the reference to Superman himself is referentially opaque - no need to apply the same mechanism to Lois Lane or the concept of love. However, term literals are still "at risk".
Souri Das' examples stress the RDFn approach's virtues w.r.t. to resilience against updates and change. We think that nested graphs provide these very desirable properties as well.
Add a second AliceBuysCar event, and add detail to the first, without changing the data topology
:Y {
:X {
:Alice :buys :Car .
} nng:subject [ :age 20 ]
nng:predicate [ :payment :Cash ;
:purpose :JoyRiding ] ;
nng:object [ :color :black ;
:model :Coupe ] ;
nng:Interpretation ; # disambiguating identification
:source :Denis .
:W {
:V {
:Alice :buys :Car .
} nng:subject [ :age 28 ] ;
:source :Eve .
} :todo :AddDetail . # add detail, then remove this nesting
} # without changing the data topology
The OneGraph paper discusses a problem related to the type/token distinction. Annotations on types suffer from dangling link problems and unclear belonging when multiple occurrences have been annotated and some of them get removed from the data. We believe that our token-based approach provides a robust basis in which this problem can't occur. [TODO]
Object attributes and relations between objects [TODO]
N-ary relations have a tendency to get rather un-wieldy. Branching out requires to change existing statements. NNG can help with both. [TODO]
With NNG the core of an annotated relation, its unannotated form, is front and center, providing a distinct usability advantage over the semantically very sound singleton properties approach. [TODO]
Repeating an example from he introduction:
:X {
:Alice :buys :Car .
}
nng:subject [ :age 20 ] ;
nng:object [ :color :black ;
:model :Coupe ] ;
:payment :Cash ;
:purpose :JoyRiding ;
:source :Denis .
A sloppy mapping to RDF-star:
:Alice :buys :Car .
<< :Alice :buys :Car >>
rdf-star:hasOccurrence :X .
:X nng:subject [ :age 20 ] ;
nng:object [ :color :black ;
:model :Coupe ] ;
:payment :Cash ;
:purpose :JoyRiding ;
:source Denis .
An exact mapping:
:Alice_1 :buys_1 :Car_1 .
:Alice_1 rdf:type :Alice ;
:age 20 .
<< :Alice_1 :buys :Car_1 >> :source Denis .
<< :Alice_1 rdf:type :Alice >> :source Denis .
<< :Alice_1 :age 20 >> :source Denis .
:buys_1 rdfs:subPropertyOf :buys ;
:payment :Cash ;
:purpose :JoyRiding .
<< :buys_1 rdfs:subPropertyOf :buys >> :source Denis .
<< :buys_1 :payment :Cash >> :source Denis .
<< :buys_1 :purpose :JoyRiding >> :source Denis .
:Car_1 rdf:type :Car ;
:color :Black ;
:model :Coupe .
<< :Car_1 rdf:type :Car >> :source Denis .
<< :Car_1 :color :Black >> :source Denis .
<< :Car_1 :model :Coupe >> :source Denis .
Imagine what happens with a second level of nesting or even the TEP mechanism.
Graph literals provide an elegant solution to some hard problems.
(what RDF standard reification is popularly misused to represent)
:Bob :says [] "{ :Moon :madeOf :Cheese . }" .
# " ... " indicate un-assertedness
# { ... } indicate referential transparency
Less syntactic sugar, same meaning:
:Bob :says [ nng:reports ":Moon :madeOf :Cheese"^^nng:GraphLiteral ]
We hope that graph literals provide everything needed to properly support N3 formulas in standard RDF, but we await a comment from the experts :) [TODO]
Graph literals provide an easy way to document RDF state verbatim in the most unambiguous way.
:Y {
:X {
:Alice :buys :Car .
} nng:subject [ :age 20 ]
nng:predicate [ :payment :Cash ;
:purpose :JoyRiding ] ;
nng:object [ :color :black ;
:model :Coupe ] ;
:source :Denis .
nng:statedAs ":X { # documenting the original source
:Alice :buys :Car .
} nng:subject [ :age 20 ]
nng:predicate [ :payment :Cash ;
:purpose :JoyRiding ] ;
nng:object [ :color :black ;
:model :Coupe ] ;
:source :Denis ."^^nng:GraphLiteral .
}
Graph literals provide a clear distinction between an abstract graph - as a literal - and its application. Reasoning over abstract graphs can be performed on literal types, saving it from the ambiguities of graph instantiation in practice. This effectively introduces a level of indirection that makes the distinction between the two realms explicit, but also links them explicitly - to the benefit of both. [TODO]