« Programming as a craft | Main | Querying RDF »

2005-05-02

Adding triples to a Wilbur database

Richard Newman has a good idea of how to add triples to a Wilbur database. Basically, he introduces a function that takes "Lisp-like" descriptions of RDF resources. It's funny, Wilbur used to support a function a bit like this; perhaps the whole idea should be revisited in Wilbur2 (yes, I know, I have said that it's coming, and it really is...).

Richard's function add-triple-list is, however, a bit too much like a function from, say, Java or C++ "transcribed" into Common Lisp. I couldn't help writing my own (mostly because of my mental disease). So here goes:

(defun db-add-description (db description)
  (destructuring-bind (frame &rest slot-and-values) description
    (dolist (slot-and-value slot-and-values)
      (destructuring-bind (slot &rest values) slot-and-value
        (dolist (value values)
          (db-add-triple db (triple frame slot value)))))
    frame))

(defun db-add-descriptions (db descriptions)
  (mapcar #'(lambda (description)
              (db-add-description db description))
          descriptions))

Basically, db-add-description takes two parameters: a database instance and a special description of a resource (an rdf:Description, that is; hence the name of the function). The syntax for the description is

( frame { ( slot { value } * ) } * )

It returns the node affected. The function db-add-descriptions merely takes a list of special descriptions and returns a list of the nodes affected.

Looking at the code, doesn't it make you think that it would be so nice to have a special version of dolist that instead of a variable would use a destructuring pattern. We could define it as follows:

(defmacro dolist+ ((pattern list &optional (value nil)) &body body)
  (if (symbolp pattern)
    `(dolist (,pattern ,list ,value) ,@body)
    (let ((i (gentemp)))
      `(dolist (,i ,list ,value)
         (destructuring-bind ,pattern ,i ,@body)))))

We could now rewrite db-add-description as follows:

(defun db-add-description (db description)
  (destructuring-bind (frame &rest slot-and-values) description
    (dolist+ ((slot &rest values) slot-and-values)
      (dolist (value values)
        (db-add-triple db (triple frame slot value))))
    frame))

No big deal, I guess, but I have a bunch of other code where this type of constructs abound.

Posted by ora at 11:55

Comments

You're absolutely right; my abysmal code was the result of (a) never having used destructuring-bind, and (b) being a two-minute hack :D I think it would be worth my while to look at destructuring-bind.

I was aiming for one feature; the ability to either provide a list of values or a single value, just like Notation 3 with its semicolon and comma operators. Your version does this without having to explicitly use lists, which is a benefit.

Add in a declarative prefix form, and you've got a great competitor for N3 :)

Thanks Ora! I'm honoured to have such a valuable critique.

Posted by: Richard Newman at May 2, 2005 05:48 PM

I have noticed one difference, though -- I don't think the solution presented above will deal with a single triple, e.g.

(db-add-description db '(!a:a !a:p !a:o))

which my original code did (i.e. it checks both the properties and objects to see if they are lists before processing them, so at either stage you can present a list or a value). This example must be written as:

(db-add-description db '(!a:a (!a:p !a:o)))

Posted by: Richard Newman at May 2, 2005 06:09 PM

Perhaps the time has come to fulfill one of my original dreams about RDF: an s-expression syntax! XML vs. s-expressions was a subject of lengthy (and at times heated) debates in the original RDF M+S WG. I have often felt that choosing an XML-based syntax for RDF was a big mistake. It has created more confusion than good.

Posted by: Ora Lassila at May 3, 2005 08:29 AM

I think it would be advantageous. There's a relationship between RDF formats and languages, I think... RDF/XML is Java, Notation 3 is Python.

SPARQL feels a little bit like a good C program.

Lisp could do with its own concise format... perhaps this weekend ;)

Posted by: Richard Newman at May 3, 2005 10:22 AM