Thursday, October 07, 2004

All Different
I started on owl:allDifferent today, but was unable to finish.

This predicate uses owl:distinctMembers, which is a predicate used to refer to a collection. When this type of collection is turned into statements it becomes a linked list (actually, a cons list). This means that any query which needs the contents of this list has to be capable of walking down the list. Enter the walk() function.

Walk() allows the query to specify a starting point (the head of the list) and the predicate to traverse (the rdf:rest predicate). The starting point is fixed, so it will either be a set value, or else it will be a variable holding a single value. The way to get the variable set to a single value is to pass it in to a subquery and perform the walk in there.

In the case of a collection, the starting point is a blank node, so there is no way to use a set starting point, and it must be passed in as a variable. Even if lists did start with a named node, there are an unknown number of lists, so they all have to be found, and the heads of each list put into a variable. The only way to reach each of these values one at a time, is again with a subquery.

Unfortunately, when I tried to use a subquery there was an error stating that a variable could not be used as the starting point of a walk. The iTQL parsing code expects to see a fixed value for the starting point, even though the implementing code is able to deal with a variable (of a single value). Theoretically this is a simple fix, and AN said he would do this for me.

Intersections
One of the last predicates to deal with is owl:IntersectionOf. There are several others, but not in OWL Lite. Also, OWL Lite only uses owl:IntersectionOf for restrictions, so it should not be too difficult to work with.

I am still convinced that we need a simple method in iTQL to check if a node matches a description, as described by the OWL abstract syntax. I had an attempt at doing the iTQL for each of these, and the results did not satisfy me. In the case of owl:hasValue it is easy to perform a query for nodes which meet a restriction. However, for other restrictions, such as cardinality, it gets very difficult to check if a class instance meets the restriction, and the result is not of an easily usable form. For instance, finding if nodes of a type which is an intersection of a class and a cardinality restriction, will return a node, along with a tuples which will be empty if it does not meet the restriction, and will have a line of data if the restriction is met.

Once AN saw the query required for this, he agreed that just because we could do this in iTQL, the complexity demonstrated that we shouldn't. The only issue now is how to do it.

AN favoured an approach where we use a rules engine, and create statements which indicate if an instance meets a description. Performing this iteratively expands what can be determined. While I approve of anything that will work (and this will), I prefer the approach of developing a recursive iTQL function which can do it for us. If we like, this function could even create new statements on the way, to help with future processing.

I prefer this for two reasons. The first is that it avoids going through the iTQL layer over and over again. The second is that it makes iTQL statements far more powerful, and does not require the use of a rules engine in order to run.

The most significant detriment for a function that determines description is that it introduces knowledge of OWL into iTQL. iTQL is an RDF query language. It provides the facilities for performing OWL queries, but it is not itself OWL aware. A function like this would be easy to implement, and very valuable, but it would step outside of the domain of iTQL, which does make me a little uncomfortable.

Back To Intersections
I also had a question on what can be inferred from intersections in OWL Lite. Often, a class will describe that it is an intersection of another class and an intersection. This is demonstrated in the example camera ontology:

<owl:Class rdf:ID="Large-Format">

<owl:intersectionOf rdf:parseType="Collection">
<owl:Class rdf:about="#Camera"/>
<owl:Restriction>
<owl:onProperty rdf:resource="#body"/>
<owl:allValuesFrom rdf:resource="#BodyWithNonAdjustableShutterSpeed"/>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
Instances of the "Large-Format" class must be of type "Camera", and must have something of type "BodyWithNonAdjustableShutterSpeed" for its "body" property.

Obviously, to check if an instance of "Large-Format" is consistent it must also be of the "Camera" class, and if it has any "body" properties then these must all be instances of the "BodyWithNonAdjustableShutterSpeed" class. My question is this: If such an instance were found, then is it legal to infer that it is of type "Large-Format"? I'm guessing not.

Alternatively, the intersection is permitted without a class declaration:
<owl:intersectionOf rdf:about="#MyIntersection" rdf:parseType="Collection">

<owl:Class rdf:about="#Camera"/>
<owl:Restriction>
<owl:onProperty rdf:resource="#body"/>
<owl:allValuesFrom rdf:resource="#BodyWithNonAdjustableShutterSpeed"/>
</owl:Restriction>
</owl:intersectionOf>
Any compliant instance will meet this. I'm wondering if this should be used in any inferencing, though I'm not sure how, at least for OWL Lite. The only thing I can think of where this might be useful is if it were used by a restriction, in which case the recursive procedure I described earlier will cover everything. Of course, it can also be used in class definitions, but as I said just now, I think that will only be used for consistency checking.

No comments: