X

Oracle Spatial and Graph – technical tips, best practices, and news from the product team

RDFn - Extending RDF to Support Named Triples

Named Graph component (in RDF quads) can be used to name triples, but what if we want to name both graphs and triples? Letting the predicate carry the triple name is one way to do it! 

Oracle Database has provided support for Resource Description Framework (RDF) since 2005 as it evolved over time. The early versions of W3C RDF – published in 1999 and 2004 –  supported RDF Triples only. The latest version of RDF –  published in 2014 – allowed RDF Quads as well. The fourth component in a quad is usually referred to as the named graph, because of its envisioned use for partitioning the content of an RDF graph into multiple named subsets. The RDF 1.1 Recommendation, however, noted that “RDF does not place any formal restrictions on what resource the graph name may denote... .

In a recent blog article [2], we showed that the fourth component of a quad can be used to name a triple. This approach is well-known to many in the RDF community. Then we went on to explain how the ability to name RDF triples (via “quadification”) allows maintaining backward compatibility (specifically, pre-existing queries remain valid) even in the face of complex additions to an RDF graph.

The question that arises, however, is the following: if we use the fourth component of an RDF quad for naming the triple contained in the quad, what happens if we also need to make that triple belong to a named graph (i.e., a named subset of the RDF graph)?

Note: This question is not relevant in the context of a comparison with Property Graph or Labeled Property Graph because those graph models do not support partitioning a graph into arbitrary named subsets. In a purely RDF context, however, providing the ability to name the triples ideally should not preclude the ability to create named subsets of a graph.

Motivating Example: Consider the rather mundane everyday content shown in the first row and its evolution to accommodate addition of the somewhat sensational assertion in the second row of the table below:

 

Type of Addition to a Graph

(Cumulative) Content to model as graph

Vertex, Edge, Vertex-Property

John donated to Top University. Mary, a child of John, got admitted to Top University.

Edge as Endpoint of an Edge

… John’s donation helped Mary’s admission.

 

RDF Graph: Initially, three edges (triples) – with labels (predicates) “donatedTo”, “admittedTo”, and “childOf” –  make up a named graph :factGraph to represent the first row data in the above table. To reflect the changed data in the second row, the RDF graph is augmented by creating a new named graph :gossipGraph to store a new assertion that the “donatedTo” triple helped the “admittedTo” triple.

The “before and after” diagram below shows how this can be accomplished if we had the ability to assign names to the relevant triples, even when they belong to named graphs. The nodes with dotted outline shown adjacent to edges represent the names assigned to the corresponding triples. (The diagram does not explicitly show the named graphs :factGraph and :gossipGraph.)

RDF Data: The table below shows the relevant “before and after” quads (in TriG serialization) with the proposed syntax extension for naming RDF triples described below. It is worth noting that each named triple is fully self-contained, that is, each named triple includes its name inline. This makes it fully aligned with line-oriented serializations such as N-Triple and N-Quad and allows creating duplicate triples (quads) with identical subject, predicate, object, (graph,) but with distinct names. The ability to assign custom name to each triple (explicit naming) further enables assigning the same name to a group of triples, not necessarily just one, if needed.

Original RDF quads

 

If we could name triples, we could represent “donation helped admission”

graph :factGraph { 
  :v1    :donatedTo    :v2  .
  :v3    :admittedTo   :v2  .
  :v3    :childOf          :v1  .

}

=>

graph :factGraph { 
  :v1   
[:v4]:donatedTo    :v2  .
  :v3   
[:v5]:admittedTo   :v2  .
  :v3    :childOf                 :v1  .

}

graph :gossipGraph { :v4    :helped    :v5 .}

 

RDFn - A Proposal to Extend RDF to Support Named Triples

This article presents a proposal for extending RDF to support named triples without affecting its support for named graphs. The extension, that would maintain validity of any existing RDF data (in all serializations such as N-Triple, Turtle, N-Quad, TriG), and SPARQL queries, could be stated simply as follows:

  • Allow predicate component of an RDF triple to optionally hold the name of the triple. For SPARQL query, this applies to the predicate component of a triple-pattern.
  • Syntax:

RDF/SPARQL component

grammar

example

(extended) predicate

( ‘[’ ( IRI | blankNodeLabel | var ) ? ‘]’ ) ? predicate

<http://ex/donatedTo>

[<http://ex/donTriple>]<http://ex/donatedTo>

[_:donTriple]<http://ex/donatedTo>

[]<http://ex/donatedTo>

[?tname]<http://ex/donatedTo>

[?tname]?pred

 

Example 1: RDF data with named or unnamed triples:

RDF triple

Unnamed Graph (shown as N-Triple)

Named Graph (shown as TriG)

Unnamed triple

    :v1           :donatedTo   :v2 .

graph :factGraph {  :v1           :donatedTo    :v2  }

Named Triple

    :v1  [:e12]:donatedTo   :v2 .
   
:e12         :year             2010 .
   
:e12         :amount        1000000 .

graph :factGraph {  :v1  [:e12]:donatedTo    :v2 .
                               
:e12        :year            2010 .
                               
:e12        :amount  1000000 }

 

Example 2: Named or unnamed triple-pattern in a SPARQL query (to match RDF triples in a dataset):

SPARQL triple-pattern

default graph

Named Graph

Unnamed triple-pattern

    ?x           :donatedTo   ?y .

graph :factGraph {  ?x           :donatedTo  ?y  }

Named triple-pattern

    ?x     [?t]:donatedTo   ?y .
   
?t           :year             ?yr .
   
?t           :amount        ?amt . 

graph :factGraph {  ?x     [?t]:donatedTo   ?y  .
                                ?t          :year              ?yr .
                                ?t          :amount         ?amt }

 

Example 3: Turtle Shortcuts for RDF data with named triples

RDF data using Turtle shortcuts (each example below is independent)

is shortcut for …

Example 3a: v1 donated an amount of 1 million dollar to  v2 in the year 2010

[ :v1     [:e12]:donatedTo   :v2 ]       :year       2010 ;  :amount  1000000 .

:v1     [:e12]:donatedTo   :v2 .
:e12   :year                      2010 .
:e12   :amount                1000000 .

Note: [:e12] could be eliminated (or replaced with [] ), to have an auto-generated name for the triple:
[ :v1    :donatedTo    :v2 ]  :year 2010 ; :amount 1000000 .

Example 3b: v1’s donation to v2 helped v3 get admitted to v2

[ :v1  [:e12]:donatedTo   :v2 ]  :helped [ :v3  [:e32]:admittedTo   :v2 ] .

:v1     [:e12]:donatedTo   :v2 .
:v3    
[:e32]:admittedTo   :v2 .
:e12            :helped         :e32 .

Note: If auto-generated triple names are acceptable instead of :e12 and :e32, we could use the following:
 
[ :v1  :donatedTo   :v2 ]  :helped [ :v3  :admittedTo   :v2 ] .

Example 3c: v7 suspects that v1’s donation to v2 helped v3 get admitted to v2

:v7  :suspects

[ [ :v1  [:e12]:donatedTo   :v2 ]  [:e1232]:helped [ :v3  [:e32]:admittedTo   :v2 ] ] .

:v1     [:e12]:donatedTo   :v2 .
:v3    
[:e32]:admittedTo   :v2 .
:e12   [:e1232]:helped      :e32 .
:v7    
:suspects               :e1232 .

Note: We could have auto-generated triple names instead of :e12, :e32, and :e1232, to rewrite as follows:
:v7
:suspects [ [ :v1  :donatedTo   :v2 ]  :helped [ :v3  :admittedTo   :v2 ] ] .

 

Related Work

Our March 2014 EDBT paper [1] discussed, while staying within the capabilities of W3C RDF 1.1 Recommendation, three approaches for representing property graphs in RDF: reification, named graphs, and subproperty (i.e., rdfs:subPropertyOf) based. Use of the fourth component, usually referred to as “named graph”, for representing the names of triples, was shown to achieve the goal and proposed as the preferred approach. The disadvantage, although not relevant for comparison with Property Graph due to its lack of support for graph partitioning, was that the use of “named graph” component for naming the triples inhibited its use for partitioning an RDF graph into named subsets. Unlike [1], this article focuses on a proposal, RDFn, for a minimal extension to RDF that allows naming a triple without making any use of the “named graph” component.

 

In [2] we showed that, by using the fourth component (“named graph”) in an RDF quad to name the triples (as suggested in [1]), any type of relationships allowed directly in property graph and far more (such as, edge with edges, edge-properties, and/or vertex-properties as endpoints) can be represented in RDF and ongoing data changes in a graph can be managed in a backward-compatible way such that pre-existing queries will continue to remain valid. In the Appendix section below, we show similar power for RDFn, by working out a complete example involving changing graph data.

 

A prominent RDF extension proposal, RDF*, first published in June 2014 [3], extends the RDF graph model by allowing use of an RDF triple (identified by specifying its subject, predicate, and object inside << … >>: for example, << :v1 :donatedTo  :v2 >> ) as the subject or object component of another triple. Nested use of this capability allows expressing compound facts such as that shown in Example 3c above as follows: :v7 :suspects << << :v1 :donatedTo  :v2 >> :helped << :v3 :admittedTo  :v2 >> >> . RDFn too supports these by allowing the user to assign a name to (i.e., do explicit naming of) a triple and then use that name as subject or object of another triple which itself can be assigned a name, and so on. RDFn allows implicit naming too in case the to-be-named triple does not need to be referred to more than once. For example, as we showed above in Example 3c, the same compound fact may be expressed using implicit naming in RDFn as follows: :v7 :suspects [ [ :v1  :donatedTo   :v2 ]  :helped [ :v3  :admittedTo   :v2 ] ] . The main difference between RDF* and RDFn becomes apparent when the same triple needs to be referred to more than once from arbitrary contexts. The option of using explicit naming of triples in RDFn and lack of it in RDF* creates this difference rooted in name-based equivalence vs. value-based equivalence. Unlike RDF* and another approach, RDF+ [4], that use value-based equivalence, RDFn uses name-based equivalence which allows simultaneous presence (even within the same named graph, if applicable) of multiple distinctly named triples with same subject-predicate-object value: for example, following two value-identical triples with distinct (explicitly-specified) names: :v1  [:e12]:donatedTo   :v2 . and :v1  [e12-2]:donatedTo   :v2 . .

References

  1. Das, S., Srinivasan, J., Perry, M., Chong, E., Banerjee, J. A Tale of Two Graphs: Property Graphs as RDF in Oracle. Published in Proc. Of 17th International Conference on Extending Database Technology (Athens, Greece, March 24–28, 2014) EDBT’14, on OpenProceedings.org.
  2. Das, S. Modeling Evolving Data in Graphs: The Power of RDF Quads. Posted January 14, 2020. Online: https://blogs.oracle.com/oraclespatial/modeling-evolving-data-in-graphs%3a-the-power-of-rdf-quads
  3. Hartig, O., Thompson, B. Foundations of an Alternative Approach to Reification in RDF. CoRR, abs/1406.3399, June 2014. Latest revision: Online: http://arxiv.org/abs/1406.3399.
  4. Schueler, B., Sizov, S., Staab, S., Tran, D. T. Querying for Meta Knowledge. Published in Proceedings of the 17th international conference on World Wide Web (Beijing, China, April 21–25, 2008) WWW’08.

Appendix: A Complete Example

To illustrate representing and handling change in graph data using RDFn, we show in the table below the steps involved in handling the cumulative content additions in the table shown below. The changes for each step are shown in red color in the diagram. 

#

Type of Addition to a Graph

(Cumulative) Content to model as graph

1

Vertex, Edge, Vertex-Property

John, whose net worth is $1 billion, donated to Top University. Mary, a child of John, got admitted to Top University.

2

Duplicate Edge

John … donated twice to Top University. …

3

Edge-Property

John … donated twice to Top University, in the years 2010 and 2012, respectively. Mary … got admitted to Top University in 2011.

4

Edge as Endpoint of an Edge

Bob suspects that John’s 2010 donation helped Mary’s admission.

5

Edge-Property as Endpoint of an Edge

John … donated twice to Top University,  in the years 2010 and 2012 (the year 2012 was confirmed by Alex)

6

Vertex-Property as Endpoint of an Edge

John, whose net worth is $1 billion (according to Dan),

 

Shorthand Notations: (To make the descriptions below more objective and concise)

#

Notation

Vertex Representing … (in RDF terminology)

Vertex Representing … (in Graph Terminology)

1

R-vertex

resource: <http://John>

vertex

2

V-vertex

value: “John”

VALUE : not shown as a vertex in the diagrams (see below)

3

T-vertex

triple: <http://John>  <http://name> “John”

edge, edge-property, or vertex-property

#

Notation

Represents Triple … (in RDF terminology)

Represents … in Graph Terminology

4

RpR triple

< Resource, predicate, Resource >

edge: vertex to vertex

4

RpV triple

< Resource, predicate, VALUE >

vertex-property : shown in box attached to the vertex in the diagram

4

RpT triple

< Resource, predicate, Triple >

edge: vertex to edge

4

TpR triple

< Triple, predicate, Resource >

edge: edge to vertex

4

TpV triple

< Triple, predicate, VALUE >

edge-property : shown in box attached to the edge in the diagram

4

TpT triple

< Resource, Predicate, Resource >

edge: edge to edge

 

Using RDFn for Adding Data to an RDF Graph (in six steps)

 

  1. Add Vertices, Edges, and Vertex-Properties

John, whose net worth is $1 billion, donated to Top University.
Mary, a
child of John, got admitted to Top University.

  • unnamed triples:
    :v1  :name  “John” .             # RpV triple (vertex-property)
    :v1  :worth  “1 Bil” .              # RpV triple (vertex-property)
    :v2  :name  “TopUniv” .        # RpV triple (vertex-property)
    :v3  :name  “Mary” .             # RpV triple (vertex-property)
    :v1  :donatedTo  :v2 .           # RpR triple (edge)
    :v3  :admittedTo  :v2 .          # RpR triple (edge)
    :v3  :childOf  :v1 .                 # RpR triple (edge)

 

  1. Add Duplicate Edge

John … donated twice to Top University. …

  • Add a named triple with e12-2 as the name to reflect the second donation. (Note: Needs a named triple to distinguish from the unnamed triple representing the first donation and thus avoid automatic de-duplication in RDF.)
  • named triple:
    :v1 
    [:e12-2]:donatedTo  :v2 .   # named RpR triple (edge)

 

  1. Add Edge-Properties

John … donated twice to Top University, in the years 2010 and 2012, respectively.
Mary … got admitted to Top University
in 2011.

  • There are three target triples to hang the edge-properties from. One of these is already a named triple, with e12-2 as its name. Name the remaining two target triples as e12 and e32.
  • Next, using as subject each of the T-vertices corresponding to the three named target triples, simply add a TpV triple to reflect the desired edge-property.

named triples: (uses delete-triple followed by insert-named-triple)
:v1  :donatedTo  :v2 .               # RpR triple (edge)
:v3  :admittedTo  :v2 .              # RpR triple (edge)
:v1  [:e12]:donatedTo  :v2  .     # named RpR triple (edge)
:v3  [:e32]:admittedTo  :v2  .    # named RpR triple (edge)
unnamed triples:
:e12  :year  2010 .                    # TpV triple (edge-property)
:e12-2  :year  2012 .                 # TpV triple (edge-property)
:e32  :year  2011 .                    # TpV triple (edge-property)

 

  1. Add Edge with Edges as Endpoints

Bob suspects that John’s 2010 donation helped Mary’s admission.

  • Create named TpT triple e1232 connecting T-vertex e12 (for “donatedTo” triple) to T-vertex e32 (for “admittedTo” triple) via “helped” predicate.
  • Create RpV triple (vertex-property) for “name = Bob” attribute-value of new R-vertex v7.
  • Create an unnamed RpT triple connecting R-vertex v7 to
    T-vertex e1232 (created above) via “suspects” predicate.

named triple:
:e12  [:e1232]:helped  :e32  . # named TpT triple (edge)
unnamed triples:
:v7  :name  “Bob” .                # RpV triple (vertex-property)
:v7  :suspects  :e1232 .         # RpT triple (edge)

 

  1. Add Edge with Edge-Property as Endpoint

John … donated twice to Top University, in the years 2010 and 2012 (the year 2012 was confirmed by Alex)

  • Name as e12-2year the TpV triple that was created in STEP 3 above assigning the “year = 2012” attribute-value pair to the T-vertex e12-2.
  • Create a new R-vertex v10 and then create a new RpV triple for assigning “name = Alex” attribute-value pair to v10.
  • Finally, create a new TpR triple connecting the e12-2year
    T-vertex (created above) to the R-vertex v10 (created above) via the “confBy” predicate.

named triples: (uses delete-triple followed by insert-quad)
:e12-2  :year  2012 .                     # TpV triple (vertex-property)
:e12-2  [:e12-2year]:year  2012 . # named TpV triple (vertex-property)
unnamed triples:
:v10  :name  “Alex” .                     # RpV triple (vertex-property)
:e12-2year  :confBy  :v10  .          # TpR triple (edge)

 

  1. Add Edge with Vertex-Property as Endpoint

John, whose net worth is $1 billion (according to Dan),

  • Name as v1worth the RpV triple that was created in STEP 1 above assigning the “worth = 1 Bil” attribute-value pair to the R-vertex v1.
  • Create a new R-vertex v12 and then create a new RpV triple for assigning “name = Dan” attribute-value pair to v12.
  • Finally, create a new TpR triple connecting the v1worth
    T-vertex (created above) to the R-vertex v12 (created above) via the “accTo” predicate.

named triples: (uses delete-triple, then insert-named-triple)
:v1  :worth  “1 Bil” .                    # RpV triple (vertex-property)
:v1  [:v1worth]:worth  “1 Bil”  .  # named RpV triple (vertex-property)
unnamed triples:
:v12  :name  “Dan” .                   # RpV triple (vertex-property)
:v1worth  :accTo  :v12 .              # TpR triple (edge)