« March 2006 | Main | May 2006 »



I just discovered from Wikipedia that "OINK" (the sound that English-speaking pigs make) is "GROK" in Serbian (maybe that's "ГРОК" but I am not sure). Pretty cool. Better than "RÖH", the sound that Finnish-speaking pigs make.

Posted by ora at 07:16 | Comments (3)


NRC Cambridge Grand Opening

Yesterday we held the "grand opening" of our new Cambridge research center (press release is here).

Among other things, we demonstrated the integration of OINK (and Wilbur) with live RDF data from W3C "Zakim" teleconference bridge controller. In this application, we use Wilbur's reasoner (RDFS + owl:sameAs + owl:InverseFunctionalProperty) to connect Zakim's understanding of who is on the call with FoaF data published from callers' mobile phones. This, in effect, creates an ad hoc social network of the teleconference participants. Small Python application on the phones "injects" RDF data into OINK via an XML-RPC call.

Posted by ora at 12:48


Self Portrait

I call this "Hiding among trees". Sorry, nothing to do with the Semantic Web.

Posted by ora at 22:20


OINK Dashboard Widget

OINK has an XML-RPC interface for "remote control" (e.g., an external application can instruct OINK to load a data source). It is also possible to get some basic data - the status of the cache, effectively.

OINK Status Dashboard Widget

I wanted to experiment with building a MacOS X Dashboard Widget. What better way to do this than to build a special widget to show the status of OINK's cache. The finished widget basically makes an XML-RPC call from JavaScript to OINK, gets back a struct with various status data, and fills an HTML table with this data. The whole thing took less than one hour to build.

OK, so I went a bit crazy with PhotoShop when editing the background graphic...

Posted by ora at 19:32 | Comments (2)


On Datatypes in Wilbur

One of the features I built into Wilbur but haven't used all that much is mapping of XSD datatypes to Common Lisp data. In my previous post I used a typed literal:


To turn this into something Common Lisp can handle, we say

(literal-value *)

and (assuming that * was bound to the particular literal) it returns


which is the universal time representation of that particular timestamp. Parsing and conversion of the data values is done only once, and cached with the literal (since literals are immutable in Wilbur).

Wilbur now handles all the basic XSD datatypes. The method literal-value->string is the mapping in the opposite direction. For example, to create the above literal, one could say:

(db-make-literal *db*
                 (literal-value->string !xsd:dateTime 3352995745)
                 :datatype !xsd:dateTime)

Similarily, evaluating

(db-make-literal *db*
                 (literal-value->string !xsd:integer 13)
                 :datatype !xsd:integer)

would return


Posted by ora at 18:53

Rewrite Rule Engine

Wilbur employs an RDF(S) reasoner based on rewriting WilburQL queries so that the results reflect the deductive closure of the contents of the triple store (as described in my ISWC 2002 paper). I realized that with just a little bit of work (= 2 hours) I could generalize this in a "rewrite rule engine", where "virtual" properties can be associated with a more complex query expression; at access time, these properties are rewritten by substituting the query expression.

Moving right along, I realized that this (with minimal work) also buys me "computed properties", i.e., properties whose values are the result of some (access-time) computational process. These are like slot access daemons in frame systems. Properties instantiated from the class "AccessDaemon" (in the Wilbur RDF schema) are recognized by the query engine, who calls the method db-compute-daemon-values. One can specialize this method, using eql specializers, to associate behavior with a property.

For example, one could first, in some RDF document, say

<wilbur:AccessDaemon rdf:about="&example;timestamp"/>

and then, in the CL source code say

(defmethod db-compute-daemon-values ((db db)
                                     (slot (eql !example:timestamp)))
  (list (db-make-literal db (iso8601-date-string (get-universal-time))
                         :datatype !xsd:dateTime)))

Then, if you call, say

(all-values !example:foo !example:timestamp)

the result is something like


I think this is pretty cool. You don't have to agree.

Posted by ora at 15:06 | Comments (2)