W3C | Semantic Web | Advanced Development | SWAP | Tutorial | Comparing Formats

Shorthand: Paths and lists, and @keywords

You don't need to know this. It just makes life easier, and of course helps when reading other people's work.


Often it turns out that you need to refer to something indirectly through a string of properties, such as "George's mother's assistant's home's address' zipcode". This is traversal of the graph. In the N3 we have dealt with up till now, this would look something like

[is con:zipcode of [
    is con:address of [
        is con:home of [
            is off:assistant of [
                is rel:mother of :George]]]]]

which reads "that which is the zipcode of that which is the address of that which is the home of that which is the assistant of that which is the mother of :George", which isn't very convenient to read or write. And this is when in an object-oriented language, you would just cascade methods or attributes on properties using ".".

To make it easier in N3 there is a shortcut for the above would just be written


The dot must be immediately followed by the next thing, with no whitespace.

This is forward traversal of the graph, where with each "." you move from something to its property. So ?x.con:mailbox is x's mailbox, and in fact in english you can read the "." as " 's".

You can do backward traversal, using "^" instead of "." as punctuation. So if :me.con:mailbox means my mailbox, then <mailto:ora@lassila.com>^con:mailbox is that which has <mailto:ora@lassila.com> as a mailbox. This backward traversal is less usual - you can't do it object-oriented programming languages -- but sometimes its what you need.

Note that there isn't necessarily only one match for a path - often there are many, when it is used on the left side of a rule.


would be "Some x such that I have parent x", and


would mean "Some y such that for some x, I had parent x and y had parent x", or loosely, some sibling of mine. In this imaginary ontology, ".rel:child" is equivalent to "^rel:parent".

Whatever the sequence of "." and "^", they always are read left to right across the page.

These are known as "paths". If you are used to XML, think: Xpath but simpler. If you think of the circles and arrows graph of data, think of a path from node to node.

Cwm doesn't currently use paths on output, so getting cwm to input and output a file will turn it into the form of N3 you already know.


A common need is to represent an ordered collection of things. This is done in RDF as a rdf:Collection. In N3, the list is represented by separating the objects with whitespace and surrounding them with parentheses. Examples are:

( "Monday" "Tuesday" "Wednesday" )

(:x :y)

( :cust.bus:order.bus:number 
          .bus:number )

These lists are actually shorthand for statements which knit blank nodes together using rdf:first and rdf:rest. rdf:first is the relationship between a list and its first component. rdf:rest if the relationship between a list and the list of everything except its first element. rdf:nil is the name for the empty list. Therefore,

( "Monday" "Tuesday" "Wednesday" )

is equivalent to

[ rdf:first "Monday";
  rdf:next [ rdf:first "Tuesday";
             rdf:rest [ rdf:first "Wednesday";
                        rdf:rest rdf:nil ]]]

One of the common uses of lists is as parameter to a relationship which has more than one argument.

(  "Dear " ?name " "," )   
             string:concatenation   ?salutation.

for example, indicates that the salutation is the string concatenation of the three strings "Dear", whatever ?name is, and a comma. This will be used with built-in functions which we will discuss later.

Getting rid of the leading ":" with @keywords

In the examples, often we have been using terms in the default namespace, like :me or :father or :People. The ":" is there because we don't want to get confused with keywords which are part of the syntax, like a, is, of, and prefix. Further, we want to be able to add more keywords later to extend the syntax, and you don't want to find that your files which happened to use that word as a name are all out of date.

The solution is that if you really want to be able to write N3 without that leading ":", then you can declare which keywords you are going to use. When you have done that, then everything which is not in the list is allowed without a colon, and will be taken as a name. To actually use the keyword, you have to use an explicit "@" as you have been doing with "prefix" all along.

Here is an example in which all they keywords are removed, so "@" is used all the time:

@prefix : <#>.
me @a Person.
Jo @a Person; @is sister @of me.
Jo father Alan; mother Flo.
Alan father Zak; brother Ed, Julian.

Here is an example in which the normal keywords used are all declared.

@keywords a, is, of, this.
@prefix : <#>.
me a Person.
Jo a Person; is sister of me.
Jo father Alan; mother Flo.
Alan father Zak; brother Ed, Julian.

Note that is you have declared something a keyword, then you can still use the "@" in front of it if you want to, as in "@prefix" above.

Obviously, you can't declared a to be a keyword, and then call your variables a, b and c!

Tim BL, with his director hat off

$Id: Shortcuts.html,v 1.11 2004/02/29 20:21:48 timbl Exp $