Wilbur: RDF Data API

  1. Top-Level API
  2. Abbreviated Syntax for URIs
  3. Nodes
  4. Dictionaries
  5. Triples
  6. Databases

1. Top-Level API

The RDF Data API allows the creation and manipulation of RDF graphs. The API is layered, consisting of a simple "top-level" API, and details lower-level APIs for the four different principal types of objects: nodes (which represent URIs and thus nodes in an RDF graph), dictionaries (which are essentially like symbol tables for nodes; they map URIs to nodes), triples (which represent RDF triples or arcs of an RDF graph), and databases (which represent sets of triples, and allow simple querying). In addition, the data manager also contains a simplified syntax for URIs, based on the XML namespace idea.

node (thing) [Function]

Creates a node instance and, if the node is named, stores it in the current node dictionary. The parameter thing can be a URI string which names the node; if a node with that name already exists, then that node is returned. If thing is a node, then it is returned. If thing is nil, an anonymous node is created.

triple (subject predicate object &optional source) [Function]

Creates a triple instance (but does not store it in any triple database). Parameters subject and predicate must be node instances, object can be anything (typically either a string or a node instance). The optional parameter source should be a node representing the source document of the triple (typically with a file URI or an http URI).

add-triple (triple) [Function]

Add a triple instance into the current triple database. The triple is returned.

del-triple (triple) [Function]

Deletes a triple instance from the current triple database. The triple is returned.

query (subject predicate object) [Function]

Queries the current triple database. Parameters subject, predicate and object can either be filled or nil, and they represent a (potentially partially filled) triple. All triples matching the parameters are returned (as a list); nil parameter values represent wildcards.

reify (triple &key statement-uri source) [Function]

Reifies (according to the RDF M+S definition) a triple, and stores the resulting new triples in the current triple database. The node representing the statement is returned; this node is named with the URI passed in the parameter statement-uri (it defaults to nil, i.e., an anonymous node). The source parameter is passed as the source parameter to the triple function.

add-namespace (prefix uri) [Function]

Adds a namespace mapping to the current node dictionary. This mapping is used when reading in and printing out nodes: the parameter prefix gets substituted for the URI uri when node names are printed. See the section titled "Abbreviated Syntax for URIs" for more information.

The namespace mappings do not affect parsing in any way.

del-namespace (prefix) [Function]

Deletes a namespace mapping (identified by prefix) from the current node dictionary.

namespaces [Function]

Returns a list of current namespace mapping prefixes.

2. Abbreviated Syntax for URIs

URIs are used everywhere in the Wilbur system. In order to avoid having to write (and read) full URIs which typically are rather long, the system provides an abbreviated syntax for reading and printing URIs. This abbreviated syntax is based on the same idea as namespace-qualified names in XML. Given that we have called add-namespace to add "foo" as the prefix for the URI "http://foo.com/schema#", then the name "foo:bar" would be an abbreviation for "http://foo.com/schema#bar". Node dictionaries maintain prefix-to-URI mappings (these are manipulated using functions add-namespace and del-namespace or their lower-level counterparts dictionary-add-namespace and dictionary-remove-namespace).

When nodes are printed, the current namespace mappings are examined and node URIs are (potentially) converted to the abbreviated form in output. For node input, the reader macro ! has been established. Writing !foo:bar causes the reader to create a node instance whose name (if we follow the previous example) is "http://foo.com/schema#bar". One can also write this node as !"http://foo.com/schema#bar". If one writes !foo:bar and the prefix "foo" has not been defined, no error is signaled; instead, the node is created with an "unresolved" name (see the function node-name-resolved-p). The node dictionary keeps track of unresolved nodes, and once a prefix is established, resolves and converts all unresolved nodes. This mechanism allows one to use the !-syntax in source files, compile these files, and expect the right thing to happen when the compiled files are later loaded into the system.

Note that by default all node dictionaries establish the mappings from "rdf" to -rdf-uri- and from "rdfs" to -rdfs-uri-.

For example, assuming that the prefix "rdf" has been defined but the prefix "foo" has not, the following illustrates how the node input/output mechanism works (this is a dribble file from MCL, the character ? is the listener prompt):

? (node-uri !rdf:type) ; resolved
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
? (node-uri !foo:type) ; not resolved
"foo:type"
? (add-namespace "foo" "http://foo.com/schema#")
"foo"
? (node-uri !foo:type) ; just got resolved
"http://foo.com/schema#type"
? (node nil)
#<node #xA6779A6>
? (node-uri *) ; anonymous
nil
? (node "http://www.w3.org/1999/02/22-rdf-syntax-ns#type")
!rdf:type
? !"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
!rdf:type

3. Nodes

node-uri (node) [Generic function]

Accesses the URI of a node instance.

node-name-resolved-p (node) [Generic function]

Accesses the flag in a node instance which indicates whether the node name was already resolved (i.e., a prefix:name form was turned into a real URI).

node [Class]
:uri [Initarg]
:name-resolved-p [Initarg]

Instances of this class represent nodes in an RDF graph.

index-uri (index) [Function]

Returns an RDF collection index URI (a string) with the specified index. It is an error to call this function repeatedly and specify indices out of order, unless these URIs have already been created (by calling this function earlier).

4. Dictionaries

Node dictionaries provide a mapping between URI strings and node instances (in this respect, they are a lot like Common Lisp symbol tables).

dictionary-node-class (dictionary) [Generic function]

Accesses the class from which new nodes are instantiated for a particular dictionary.

dictionary-add-namespace (dictionary prefix uri) [Generic function]

Adds a namespace mapping to a dictionary. Used to implement add-namespace.

dictionary-remove-namespace (dictionary prefix) [Generic function]

Removes a namespace mapping from a dictionary. Used to implement del-namespace.

dictionary-rename-namespace (dictionary old-prefix new-prefix) [Generic function]

Renames the prefix of a namespace mapping for a dictionary. No counterpart in the top-level API.

find-node (dictionary uri) [Generic function]

Finds a node with the given URI in a dictionary. If no node exists, nil is returned.

find-short-name (dictionary uri) [Generic function]

Maps a URI into a "short form" name (of the form prefix:name).

find-long-name (dictionary name) [Generic function]

Maps a name (of the form prefix:name) into the corresponding full URI.

dictionary-apropos-list (dictionary pattern) [Generic function]

Finds all nodes from a dictionary whose URI contains the string pattern. Think of this function as the dictionary counterpart of the Common Lisp function apropos-list.

dictionary [Class]
:node-class [Initarg]

Base class of all dictionaries. Currently the implementation does not have subclasses of this class.

*nodes* [Variable]

This global variable contains the current node dictionary. It is initialized when the system is loaded. Since a node dictionary is just like the Common Lisp symbol table, one can typically use the one and the same node dictionary even if one uses multiple triple databases.

5. Triples

Triples are used to represent RDF statements in the underlying RDF graph. One can think of them either as the vertices of the graph (with associated endpoints), or as object-attribute-value triplets (which is useful connection of the frame system interface). Triples are actually quadruples, if you think about it, since they also record their source document (as a node).

triple-subject (triple) [Generic function]

Accesses the subject component of a triple (a node).

triple-predicate (triple) [Generic function]

Accesses the predicate component of a triple (a node).

triple-object (triple) [Generic function]

Accesses the object component of a triple.

(setf triple-object) (value triple) [Generic function]

Assigns the object component of a triple.

triple-source (triple) [Generic function]

Accesses the source component of a triple (a node).

triple [Class]

Base class of all triples. Use the function triple to create triples.

6. Databases

Databases are used to store triples. The system can have an arbitrary number of databases, but only one can be current at any given time (the default database in the top-level API operations).

db-triples (db) [Generic function]

Returns a list of all triples in a database. It is an error to destructively modify this list.

db-add-triple (db triple) [Generic function]

Add a triple to a database. Used to implement the top-level function add-triple.

db-del-triple (db triple) [Generic function]

Removes a triple from a database. Used to implement the top-level function del-triple.

db-query (db subject predicate object) [Generic function]

Queries a database for triples. Used to implement the top-level function query (see this function for an explanation of how querying works).

db-reify (triple db &optional statement-uri source) [Generic function]

Reifies a triple. Used to implement the top-level function reify (see this function for an explanation of the reification functionality).

db-del-source (db source) [Generic function]

Deletes all triples corresponding to a given source from a database. No counterpart in the top-level API.

db-sources (db) [Generic function]

Returns a list (of nodes) of all sources of a given database. No counterpart in the top-level API.

db-query-by-source (db source) [Generic function]

Returns a list of triples corrsponding to the current source (a node). It is an error to destructively modify this list.

is-container-p (db node &optional errorp) [Generic function]

Returns true if node represents an RDF container (a Bag, a Seq, or an Alt) in the database db. If errorp is true (default is false), a continuable error is signalled if is-container-p would return false (the error is instantiated from the condition class container-required).

db-merge (to from) [Generic function]

Copies all triples from the database from into the database to.

db-allow-merge-p (to from) [Generic function]

Returns true is merging from the database from to the database to is allowed. If false is returned, a second return value is a string indicating the reason why merging is not allowed. This function is used by db-merge who will signal a continuable error (an instance of cannot-merge) in case the merge attempt fails.

db [Class]
:emptyp [Initarg]
:rdf-schema-pathname [Initarg]

This is the base class of all databases. The initarg emptyp when false (the default) causes the system to initialize the database by reading in a schema whose file system pathname is specified using the initarg rdf-schema-pathname (it defaults to the logical pathname "wilbur:schemata;rdf-schema.rdf").

*db* [Variable]

This variable holds the current database. It is not initialized when the system is loaded, but has to be assigned separately, typically by something like
(setf *db* (make-instance 'db))

Copyright © 2001 Nokia. All Rights Reserved.
Subject to the NOKOS License version 1.0
Author: Ora Lassila (ora.lassila@nokia.com)