Skip to content

Proposal: Named Node Expressions

Kurt Cagle edited this page Jun 21, 2024 · 27 revisions

Overview

The named node expression proposal is a proposal made to extend the Turtle language in order to make certain Turtle expressions more compact and referenceable. It is an alternative that is intended to address several critical use cases currently under consideration by the RDF-Star Working Group. It should have no impact upon the underlying RDF.

Definitions: Core Terms

Definition: Anonymous Node

An anonymous node is a node in a graph that is created via notational means (e.g., part of a brace expression "[]", linked list expression "()", reification expression "<<>>" or graph expression "{}"). Anonymous nodes are not directly referenceable even locally, and while they are usually rendered as blank node in RDF, in Turtle there is no way to explicitly name such nodes without losing the appropriate advantages of the notation.

Definition: Named Blank Node

A named blank node is a node in a graph that uses bnode notation to define a name that only has scope within a given Turtle file depiction of a graph, and that typically assigned as a bnode URI by the parser when the Turtle file is parsed. In this respect, named blank nodes are locally scoped. An anonymous node is not synonymous with a named blank node, though most anonymous nodes in Turtle are representable as blank nodes in RDF. An anonymous node is not referenceable at all within Turtle from outside the data structure, while a named blank node can be, so long as it is within the scope of a graph when encoded in Turtle.

Definition: Named Node Identifier

A named node identifier is either a URI or blank node used by a named node expression to create a referenceable name for an anonymous node.

Definition: Named Node Expression

A named node expression is a mechanism in Turtle to assign a named node identifier to an anonymous node, where the name can be either a fully qualified IRI or a named blank node, when the Turtle is parsed.

## BNF Notation
<namedNodeExpression> ::= <op> <namedNode> "=>" <partialExpression> <endOp> 
<op> ::= "[" | "(" | "<<" | "{"
<namedNode> ::= <iri> | <blankNode>
; :partialExpression is an expression dependent upon <op>, see below
<endOp> ::= "]" | ")" | ">>" | "}" 

Definition: Expansion

An expansion is a translation from a Turtle-star form to an RDF form, in which all anonymous nodes have either been named or assigned node identifiers by the system if un-named (the default behaviour in the absence of named node identifier).

Brace Expressions

Definition: Anonymous Brace Expression

An anonymous brace expression is an expression that creates an anonymous node as a blank node, then references this blank node in subsequent expressions.

A typical anonymous brace expression will look like the following:

Person:JaneDoe Person:hasName [ a Name: ; Name:firstName "Jane" ; Name:lastName "Doe"]. 

This anonymous expression has the following expansion form:

Person:JaneDoe Person:hasName _:a1234 .
_:a1234 a Name: .
_:a1234 Name:firstName "Jane" . 
_:a1234 Name:lastName "Doe" . 

where _:a1234 is a system-assigned blank node that represents an anonymous node.

Definition: Named Brace Expression

A named brace expression is a brace expression in which the anonymous node is replaced with a named node identifier that can be referenced in subsequent expressions.

A *named brace expression resolves as a named node identifier that take the corresponding internal predicates and objects. For instance,

Person:JaneDoe Person:hasName [Name:JaneDoeBirthName => a Name: ; Name:firstName "Jane" ; Name:lastName "Doe" ]. 

This expands to the following RDF:

Person:JaneDoe Person:hasName Name:JaneDoeBirthName.
Name:JaneDoeBirthName a  Name: . 
Name:JaneDoeBirthName Name:firstName "Jane" .
Name:JaneDoeBirthName Name:lastName "Doe" .

where Name:JaneDoeBirthName is a named node identifier that is also an IRI.

Similarly,

Person:JaneDoe Person:hasName [_:JaneDoeBirthName => Name:firstName "Jane" ; Name:lastName "Doe" ; a Name: ]. 

resolves to

Person:JaneDoe Person:hasName _:JaneDoeBirthName .
 _:JaneDoeBirthName Name:firstName "Jane" .
 _:JaneDoeBirthName Name:lastName "Doe" .
 _:JaneDoeBirthName a  Name: . 

where _:JaneDoeBirthName is a named node identifier that is also a blank node.

The expression

[:namedNode => :p1 :o1 ; :p2 :o2 ; ...] .

is a named Node expression that evaluates to the single node :namedNode.

:namedNode :p1 :o1 .
:namedNode :p2 :o2 .
...

Such an expression can be used in either the subject, predicate or object position as follows:

As object:

:s :p [:namedNode => :p1 :o1 ; :p2 o2 ; ...] .

This evaluates to

:s :p :namedNode .
:namedNode :p1 :o1 .
:namedNode ;p2 :o2 .
...

Example:

As given above, the following named brace expression can be written as follows:

Person:JaneDoe Person:hasName [Name:JaneDoeName => Name:firstName "Jane" ; Name:lastName "Doe"].
Name:JaneDoeName a Name; Entity:dateStart "1998-03-07" ; Entity:dateEnd "2021-11-05".

This creates a named node called Name:JaneDoeName bound with the first name and last name. This is then referenced in another set of triples indicating a range. This is equivalent to the RDF:

Person:JaneDoe Person:hasName Name:JaneDoeName .
Name:JaneDoeName Name:firstName "Jane" ; Name:lastName "Doe".
Name:JaneDoeName a Name; Entity:dateStart "1998-03-07" ; Entity:dateEnd "2021-11-05".

As predicate:

:s [:namedNode => :p1 :o1 ; :p2 o2 ; ...] :o .

This evaluates to

:s :namedNode :o .
:namedNode :p1 :o1 .
:namedNode ;p2 :o2 .
...

As subject:

[:namedNode => :p1 :o1 ; :p2 o2 ; ...] :p :o .

This evaluates to

:namedNode :p :o .
:namedNode :p1 :o1 .
:namedNode ;p2 :o2 .
...

Note in the case of a subject replacement of a named node expression, this defaults to the expression:

:namedNode :p1 :o1 ; :p2 o2 ; ... ; :p :o .

Composition

A named node expression can be composed within another named expression. For instance,

Clone this wiki locally