Wilbur: RDF Data API
-
Top-Level API
-
Abbreviated Syntax for URIs
-
Nodes
-
Dictionaries
-
Triples
-
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)