A Month Later
So, not too long after I wrote my last entry, I woke up with another idea and then another idea. Since I’d decided to learn Ruby and use it to script out Prot�g�-OWL projects, I’d be wrestling with the best way to go against the Prot�g�-OWL API. I’m not exactly sure which idea came first, but I immediately started working on them both and this last weekend, I’d finally got some things I could see and work with. Here’s what I came up with:- ���
- Map OWL namespaces into Ruby modules, map OWL classes into Ruby classes and map OWL properties into Ruby attributes. ���
- Develop an importable Ontology the describes (catalogs) where Ruby files are (and Java jars, too).
The idea of the catalog was obvious. I needed some way of setting up Ruby’s directory search paths. Prot�g� Script Tab ignores environment variables and provides no facility for passing command line arguments to the JRuby engine. This means that telling Ruby what to do must be done using a script. It occurred to me that the simplest use case would be to launch the Prot�g�-OWL project, switch to the Prot�g� Script Tab, enter
load 'project'. The
project.rbscript would read the directory paths from an imported Ontology and set up the environment.
I got the proof of concept pretty much completed over the course of two weekends. And things were going pretty well. At the end of the The Prot�g�-OWL API - Programmer’s Guide is some good advice on how to construct classes for working with the Prot�g� API. I actually worked with some of the code generation utilities that Prot�g� provides and studied what I thought might be some best practices. Because I wanted to publish the whole kit, I built a little example Prot�g�-OWL project (based on some music things I had laying around) and started coding.
I started working with properties and classes first. I realized that OWL properties are in fact a class of a sort and I coded some example properties as classes. The next thing I decided was that literal property ranges were basically classes/properties too. A range such as
xsd:Stringlooks and feels just like
rdfs:labelso I coded them that way as well. An OWL namespace is encapsulated generally by the prefix and maps (rather nicely) to a Ruby modue (which is described in the pickaxe as a “sort of” namespace. Other Ruby classes, representing OWL classes, would simply be collections of instantiated property classes. The property class’s job would be to retrieve values from the Prot�g�-OWL ontlogy. Classes and properties would all inherit from each other as specified on the sub-class/sub-property hierarch of the Prot�g�-OWL ontlogy.
While putting together this in code, I made the range classes (
xsd:AnyURIand
Literal) inherit from a worker class called . This worked so well, that I was able to eliminate all of the code from the range classes. Then it occurred to me that I could eliminate all of the code from the property classes because everything inherited from everything. So these two sets of classes were simply aliases for the worker class . I thought about doing something similar with the OWL Class classes but I’ll save that for a later date. At the moment, those classes are restricted to a simple collection of attributes that instantiate property classes (as specified in the Prot�g�-OWL ontology).
This took a week or two to accomplish. Every time I sat down to work on through some ideas, I told myself to keep it all mechanical. I acted as if I was a computer program constructing classes. This, I think, is how I was able to eliminate so much code. Then I started reading on how to do things dynamically.
Because the system was so simple - a set of very base classes that Prot�g�-OWL names inherit from, I figured it would be relatively easy to write code that constructed the classes. Note the use of terminology here. I didn’t want to generate code. There’s already programs out there that will do this for other languages. Ruby is different. Classes are executable and are run-time objects. This means, I could create a system where the classes and attributes are synthesized based on instructions. In our case the instructions for the construction of the classes come from Prot�g�-OWL.
And that is going to make all the difference.
]]>

