Monday, November 20, 2006

Robotic introspection

One of the topics I got very interested in while I was working on my PhD, though I didn't have time to pursue it very far, was agent introspection. How does a computing device notice things about itself, and, especially, detect deviations from a stable norm. I came across this problem when trying to devise non-brittle strategies for detecting and repairing failed interactions and dialogue turns, but it features quite prominently in any attempt to visualise how a truly autonomous agent would react. It's a topic I'd like to get back to working on, some day soon. Anyway, via Ray Kurzweil's newsletter, Lipson, Zykov and Bongard of universities Cornell and Vermont have created a robot that uses a vision system to build a concept of itself, including its normal range of motion, and then detect deviations from that norm and figure out compensation actions. For example, if one of the legs is shortened, the robot apparently learns, by itself, to limp. That is very, very impressive.

One of the marks, it is said, of a really good program is that when you look at what it does you can't say, immediately, "I know how they did that". Kudos to the team. I'll have to go read their paper now!

del.icio.us: AI, robotics, introspection,

Thursday, November 02, 2006

Jena tip: renaming RDF resources

We rather frequently get asked, on the Jena support list, something along the lines of "how do I rename an RDF resource?" or "how do I change the local-name of an OWL class?" or something similar. We get asked this often enough that we made a FAQ entry about it. That FAQ entry is fairly terse, because many users are fine to read the Javadoc, figure out how to apply the renameResource in their application, and off they go. For inexperienced Jena users, especially those without much Java experience either, a more detailed explanation is probably in order however.

For a variety of good design reasons, the Java class representing RDF resources in Jena, com.hp.hpl.jena.rdf.model.Resource is immutable - once created, it can never be changed. This means that there is not, and never will be, a method on Resource called something like rename(). This also means that all the classes that extend Resource, such as OntClass also can't be renamed in place. Suppose you are developing a semantic web editor. It's a perfectly natural requirement to change the name of a class as your understanding of the ontology grows. So, what to do?

It's important to note that the Resource object in a Jena model doesn't contain any state information. All the RDF object state is held in the RDF Model) (and, internally within the Model in a Graph object, but that's another topic). Resource, therefore, isn't really an information container but an accessor for information that is contained in the model. Moreover, Model itself doesn't contain Resource's per se: Model only contains RDF subject-predicate-object triples. A resource is in a model only to the extent that it appears in one of the triples in that model. This, then, gives us a way to achieve the effect of renaming a resource: to rename a resource from A0 to A1, simply replace every triple that contains A0 with one that contains A1. A quick example should make this clearer. Suppose we have the following information in the model (I'm using N3/Turtle syntax for compactness; it would be exactly the same with RDF/XML):

@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix eg: <http://example.com/eg#>.

eg:Device 
      rdf:type owl:Class
    .
eg:MobilePhone
      rdf:type owl:Class
    ; rdfs:subClassOf eg:Device
    .
eg:JavaPhone
      rdf:type owl:Class
    ; rdfs:subClassOf eg:MobilePhone
    .

This model fragment contains five triples. To rename eg:MobilePhone to eg:CellPhone, we need to replace three of those triples, to produce the following model:

eg:Device 
      rdf:type owl:Class
    .
eg:CellPhone
      rdf:type owl:Class
    ; rdfs:subClassOf eg:Device
    .
eg:JavaPhone
      rdf:type owl:Class
    ; rdfs:subClassOf eg:CellPhone
    .

This can be done manually by the calling Jena program, and that's fine. However, we do provide a helper method to assist with this, in ResourceUtils. The following code fragment shows one way of achieving the above example. Assume that m is a Java variable containing an already-loaded Jena model which, in turn, contains the resource we want to rename:

Model m = .... ; // source model, already initialised

String NS = "http://example.com/eg#";
Resource cls = m.getResource( NS + "MobilePhone" );

// this is the step where eg:MobilePhone becomes eg:CellPhone
ResourceUtils.renameResource( cls, NS + "CellPhone" );

// it's important that we forget about, or re-assign,
// cls, since as yet it's not pointing to the 
// revised definition
cls = m.getResource( NS + "CellPhone" );

// now we can, for example, look at the updated definition
for (StmtIterator i = cls.listProperties(); i.hasNext();) {
    System.out.println( " m contains triple " + i.nextStatement() );
}

And that's all there is to it.

del.icio.us: jena, semanticweb, java,