BeanShell

From Protege Wiki
Revision as of 10:14, June 15, 2011 by Tredmond (talk | contribs) (Counting (with and without a reasoner))

Jump to: navigation, search

The BeanShell

As a Protege developer, I have a unique ability to answer complex questions about large ontologies. All I have to do is to start Protege inside eclipse, open the ontology and set a breakpoint and I will have access to a full array of powerful Java tools for analyzing the ontology. These tools range from the full set of OWL API features, direct access to reasoners and the ability to make a complex script out of simple primitives. I have often thought that this power would be much more useful in the hands of the end user but it has been unclear how to get there. What is really needed is a very powerful scripting language.

The beanshell (a CO-ODE plugin developed at the University of Manchester) can fill some of these needs. The primary disadvantage of the bean shell is that it requires some experience with Java and knowledge of the OWL API. This will severely limit the audience but I thought it would still be useful to include some pages on how to use the beanshell. The beanshell also requires some understanding of the Protege API but to start with all that is really needed is to know one call:

      ontology = mngr.getActiveOntology();

Here the mgnr is the Protege Model Manager which keeps track of such things as which ontologies are displayed, how enties in the ontology should be display and the active OWL reasoner.

Some documentation for the beanshell can be found here. My idea in writing this page was to supplement that page with some examples of queries that I have used in my work.

Property Puns

I am just starting this page so I will start with a query that is so simple that it could have been done even in a simple language like SPARQL. I will look at properties that are punned with each other. Any such problem represents a problem in the ontology. To make this interesting I will show what happens when I run this script on the foaf ontology which is known to have some problems as an OWL 2 file. The script is as follows:

OWLOntology ontology = mngr.getActiveOntology();
print("\nActive Ontology = " + ontology);

for (OWLAnnotationProperty ap : ontology.getAnnotationPropertiesInSignature()) {
    if (ontology.containsDataPropertyInSignature(ap.getIRI())) {
       print("The annotation property " + ap.toString()
                                 + " is also a data property");
    }
}

for (OWLAnnotationProperty ap : ontology.getAnnotationPropertiesInSignature()) {
    if (ontology.containsObjectPropertyInSignature(ap.getIRI())) {
       print("The Annotation Property " + ap.toString() 
                                + " is also an object property");
    }
}

for (OWLDataProperty dp : ontology.getDataPropertiesInSignature()) {
    if (ontology.containsObjectPropertyInSignature(dp.getIRI())) {
       print("The data property " + dp.toString() 
                      + " is also an object property");
    }
}

This script can either be run interactively:

bsh % ontology = mngr.getActiveOntology();
bsh % print(ontology);
Ontology(<http://xmlns.com/foaf/0.1/> [Axioms: 550] [Logical axioms: 157])
bsh % 

or by being copied into a file and then run with the Run script command. The output looks like this:

Active Ontology = Ontology(<http://xmlns.com/foaf/0.1/> [Axioms: 550] [Logical axioms: 157])
The annotation property <http://xmlns.com/foaf/0.1/name> is also a data property
The data property <http://xmlns.com/foaf/0.1/yahooChatID> is also an object property
The data property <http://xmlns.com/foaf/0.1/mbox_sha1sum> is also an object property
The data property <http://xmlns.com/foaf/0.1/jabberID> is also an object property
The data property <http://xmlns.com/foaf/0.1/icqChatID> is also an object property
The data property <http://xmlns.com/foaf/0.1/msnChatID> is also an object property
The data property <http://xmlns.com/foaf/0.1/aimChatID> is also an object property

This is useful information to know about this ontology because each of these puns represents a potential problem for ontologies that import the foaf ontology and are saved in the popular RDF/XML format. Just to give some notion of the interactive nature of the development of this script, here is a run with some errors that I corrected:

bsh % for (OWLDatatypeProperty dp : ontology.getAnnotationPropertiesInSignature()) {
    if (ontology.containsObjectPropertyInSignature(dp.getIRI())) {
       print("The data property " + dp.toString() 
                      + " is also an object property");
    }
}
// Error: EvalError: Class: OWLDatatypeProperty not found in namespace : at Line: 1 : in file: <unknown file> : OWLDatatypeProperty 

bsh % for (OWLDataProperty dp : ontology.getAnnotationPropertiesInSignature()) {
    if (ontology.containsObjectPropertyInSignature(dp.getIRI())) {
       print("The data property " + dp.toString() 
                      + " is also an object property");
    }
}
// Error: // Uncaught Exception: for loop iterator variable:dp: null : at Line: 1 : in file: <unknown file> : for ( OWLDataProperty dp : ontology .getAnnotationPropertiesInSignature ( ) ) { 

Target exception: java.lang.ClassCastException: Cannot cast uk.ac.manchester.cs.owl.owlapi.OWLAnnotationPropertyImpl to org.semanticweb.owlapi.model.OWLDataProperty

bsh % for (OWLDataProperty dp : ontology.getDataPropertiesInSignature()) {
    if (ontology.containsObjectPropertyInSignature(dp.getIRI())) {
       print("The data property " + dp.toString() 
                      + " is also an object property");
    }
}
The data property <http://xmlns.com/foaf/0.1/yahooChatID> is also an object property
The data property <http://xmlns.com/foaf/0.1/mbox_sha1sum> is also an object property
The data property <http://xmlns.com/foaf/0.1/jabberID> is also an object property
The data property <http://xmlns.com/foaf/0.1/icqChatID> is also an object property
The data property <http://xmlns.com/foaf/0.1/msnChatID> is also an object property
The data property <http://xmlns.com/foaf/0.1/aimChatID> is also an object property
bsh % 

It would be better if the bean shell offered some command completion like eclipse and I will see what can be done about this (it might be tricky?).

Counting With a Reasoner

This is a problem that came off the list and it is a bit complicated for the bean shell. But it is a good illustration because it uses several things that might be useful. The user wanted to count the individuals in two classes, calculate the percentage of them that are in the second class and then attach the result to a data property assertion. I am not positive exactly what the data property assertion was supposed to look like but I made an example here. The ontology is as follows:

Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Prefix(:=<http://www.semanticweb.org/ontologies/2011/5/furniture#>)
Prefix(Marouns_problem:=<http://www.semanticweb.org/ontologies/2011/5/Marouns_problem#>)

Ontology(<http://www.semanticweb.org/ontologies/2011/5/furniture>

EquivalentClasses(Marouns_problem:having_final_value_0 ObjectComplementOf(Marouns_problem:having_final_value_1))
EquivalentClasses(Marouns_problem:having_final_value_1 
                  ObjectUnionOf(
                     ObjectSomeValuesFrom(Marouns_problem:has_mechanism owl:Thing) 
                     ObjectSomeValuesFrom(Marouns_problem:has_protocol owl:Thing)
                     ObjectSomeValuesFrom(Marouns_problem:has_service owl:Thing)))

ObjectPropertyRange(Marouns_problem:has_mechanism Marouns_problem:mechanism)
ObjectPropertyRange(Marouns_problem:has_protocol Marouns_problem:protocol)
ObjectPropertyRange(Marouns_problem:has_service Marouns_problem:service)

ClassAssertion(Marouns_problem:moderate Marouns_problem:a)
ClassAssertion(ObjectExactCardinality(1 Marouns_problem:has_mechanism Marouns_problem:mechanism) Marouns_problem:a)
ClassAssertion(ObjectExactCardinality(1 Marouns_problem:has_protocol Marouns_problem:protocol) Marouns_problem:a)
ClassAssertion(ObjectExactCardinality(1 Marouns_problem:has_service Marouns_problem:service) Marouns_problem:a)

ClassAssertion(Marouns_problem:moderate :b)
ClassAssertion(ObjectExactCardinality(1 Marouns_problem:has_mechanism Marouns_problem:mechanism) :b)
ClassAssertion(ObjectExactCardinality(1 Marouns_problem:has_protocol Marouns_problem:protocol) :b)

ClassAssertion(Marouns_problem:moderate :c)

ClassAssertion(Marouns_problem:moderate :d)
ClassAssertion(ObjectExactCardinality(0 Marouns_problem:has_mechanism) :d)
ClassAssertion(ObjectExactCardinality(0 Marouns_problem:has_protocol) :d)
ClassAssertion(ObjectExactCardinality(0 Marouns_problem:has_service) :d)
)