30 minutes (Inkscape .43):
Instead of trying to come up with a web site for the project, I made the built in wiki the website. What probably should have taken a couple of hours to do, turned into an all Saturday marathon session.
I started writing up some basic information on the por project. And right from the beginning, I started running into an issue with showing example code. Just about everything in programming nowadays uses camel back style for names, i.e.
RubyBookCite. Naturally, when you type this into a wiki, you’ll get a nice little question mark at the end of the name like so:
RubyBookCite?. The wiki is basically saying you should go create a page for that “WikiWord”. But when the name is embedded in code, you’ll want to shut that off. That’s where all my time went. I couldn’t figure out what type of wiki was being used at RubyForge. I searched through dozens of posts at the support forum there but it just wasn’t working. I tried a variety of syntax things I read at various other wiki guides but absolutely nothing worked. I was simply overwhelmed. In the end, I was able to determine that the wiki was UseMod and that got me to some syntax I could use.
Just Need to VentI was able to determine where the wiki was stored for my project, so I began to create a simple graphic banner/icon thingy - wiki.gif - shows up on every page. Yesterday, I grew to absolutely positively despise Jasc Paint Shop Pro. No matter how powerful the program is, this program (and all the other ones out there just like it - photo shop) have the worst user interface ever designed. This whole thing with the 85 different selection tools and pallets freakin everywhere and no view menu to turn them off and on, is that absolute worst design I’ve come across. Absolutely nothing works intuitively. Everything takes 15 mouse strokes to accomplish. The most common task in the world is to copy a bit of a bitmap from somewhere into a graphic, move it around, and push it to the top or the bottom, you know, simple sprite operations I’ve been doing since the freakin early 80s. None of these programs can do it. They all lock you into weird-ass layer model with no intuitive way for just clicking and moving. No, there’s gotta be a mode change (and a freakin paradigm shift) just to get something behind something else. And modify some text you just typed into the graphic? Forget it. You’d think you just be able to click the text and open the dialog but NO. Forget it.
Most of this stuff came originally from the Mac - should I blame Apple?
WORST USER INTERFACE DESIGN EVER
I will find a better graphics package and remove Jasc forever. Every session with Jasc for the last four years has ended with me in tears.
]]> a new project at RubyForge. The project is called Protege+OWL+Ruby. It’s a slightly lofty name, I’m sure, maybe even a little pretentious. But after working with my new system (see previous post), I could see where it would be quite easy to create a full JRuby IDE using Protege as the user interface.
The code I have creates a nice set of classes that wrap around OWL individuals defined in protege. There is a general routine called
create_ind(ind)that returns an object representing an individual with properties that reflect the OWL class of the individual. For instance in my example ontology:
load 'project' maj2nd = create_ind("Interval_Maj2nd") p maj2nd.hasNotation #-> images/intmaj2nd.png p maj2nd.class #-> Interval p maj2nd.methods(nil)
The result of the last statement from above is a listing of the methods available to the OWL individual:
["isAlsoDiminished", "rdfs_label", "is_it_safe", "hasInversion", "hasResolve", "looksLike", "hasNotationDim", "rdfs_comment", "isAlsoAugmented", "hasNotationAug", "hasNotation", "hasWidth"]
See the method
is_it_safein the method list above? This method was implemented with code entered into the OWL ontology (using the imported POR ontology) as an individual of
por:InstanceMethodwhich is basically just a wrapper around an
xsd:Stringproperty. I created an individual of
Intervaland hooked that to the OWL class
rdfs:isDefinedByby adding an existing resource as an annotation in the Protege OWLClasses tab. The annotation property is a . I’m pretty sure I’m in the ball park as far as the recommendation goes from the W3C. Using this annotation property this way is still OWL-DL as far as I can tell and does not cause Protege to declare the ontology OWL-FULL.
Annotating the OWL ontology with Ruby code this way starts making Protege feel exactly like a really sophisticated IDE. I can change the body of the method using the Protege user interface. To test my changes I simply issue a command or two in the Protege Script Tab. It’s the most natural way to develop I’ve encountered. A nice little map of all the Ruby classes and properties and data wrapped up with a great little IRB.
All that’s needed is a juicy little debugger, some syntax coloring and (maybe one day) autocomplete.
- 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 (
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.