There is an individual in another organization of my company that is struggling
to get something working in Jena. I have advised him several times to post his
issue to this group, but he won’t. He is trying to have an instance get
dynamically associated with a subclass. I don’t have the time bandwidth to
figure this out for him because I am busy with my own Jena evaluation work due
in about a week. His issue deals with how/whether Jena does inferencing on the
fly. He is not getting the results he expects. Below is his sample ontology and
also the Jena Java code. His challenge/question is in the comments at the very
end of the code.
This is part of a multi-organizational evaluation of Jena, considering its
adoption. So getting this resolved will be helpful to Jena.
I am off on vacation next week, so it would be good if a solution could be
provided by tomorrow.
I hope this is possible in Jena, I was surprised it was not working.
<!DOCTYPE rdf:RDF [
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
<!ENTITY owl "http://www.w3.org/2002/07/owl#" >
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" > ]>
<rdf:RDF xmlns="http://blsdev1.vsticorp.com/veh#"
xmlns:terror="http://blsdev1.vsticorp.com/veh#"
xml:base="http://blsdev1.vsticorp.com/veh#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<owl:Ontology rdf:about="Vehicles">
<rdfs:comment>Vehicle Ontology</rdfs:comment>
<rdfs:label>Vehicle Ontology</rdfs:label>
</owl:Ontology>
<owl:Class rdf:ID="Vehicle">
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#numWheels" />
<owl:maxCardinality
rdf:datatype="&xsd;nonNegativeInteger">1
</owl:maxCardinality>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
<owl:Class rdf:ID="Motorcycle">
<rdfs:subClassOf rdf:resource="#Vehicle" />
<owl:equivalentClass>
<owl:Restriction>
<owl:onProperty rdf:resource="#numWheels"/>
<owl:hasValue
rdf:datatype="&xsd;nonNegativeInteger">2</owl:hasValue>
</owl:Restriction>
</owl:equivalentClass>
</owl:Class>
<owl:Class rdf:ID="Truck">
<rdfs:subClassOf rdf:resource="#Vehicle" />
<owl:disjointWith rdf:resource="#Motorcycle" />
</owl:Class>
<owl:Class rdf:ID="Bicycle">
<rdfs:subClassOf rdf:resource="#Vehicle" />
<owl:disjointWith rdf:resource="#Motorcycle" />
<owl:disjointWith rdf:resource="#Truck" />
</owl:Class>
<owl:DatatypeProperty rdf:ID="numWheels">
<rdfs:domain rdf:resource="#Vehicle" />
<rdfs:range rdf:resource="&xsd;integer" />
</owl:DatatypeProperty>
<owl:Class rdf:ID="Race">
<owl:disjointWith rdf:resource="#Vehicle" />
</owl:Class>
<owl:Class rdf:ID="BmxRace" >
<rdfs:subClassOf rdf:resource="#Race" />
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#hasRacer" />
<owl:allValuesFrom rdf:resource="#Motorcycle" />
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
<owl:ObjectProperty rdf:ID="hasRacer">
<rdfs:domain rdf:resource="#Race" />
<rdfs:range rdf:resource="#Vehicle" />
</owl:ObjectProperty>
<owl:TransitiveProperty rdf:ID="fasterThan">
<rdfs:domain rdf:resource="#Vehicle" />
<rdfs:range rdf:resource="#Vehicle" />
</owl:TransitiveProperty>
<owl:DatatypeProperty rdf:ID="hasRating">
<rdfs:domain rdf:resource="#Vehicle" />
<rdfs:range>
<owl:DataRange>
<owl:oneOf>
<rdf:List>
<rdf:first
rdf:datatype="&xsd;string">Positive</rdf:first>
<rdf:rest>
<rdf:List>
<rdf:first
rdf:datatype="&xsd;string">Negative</rdf:first>
<rdf:rest>
<rdf:List>
<rdf:first
rdf:datatype="&xsd;string">Neutral</rdf:first>
<rdf:rest
rdf:resource="&rdf;nil" />
</rdf:List>
</rdf:rest>
</rdf:List>
</rdf:rest>
</rdf:List>
</owl:oneOf>
</owl:DataRange>
</rdfs:range>
</owl:DatatypeProperty>
</rdf:RDF>
package assign;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ReasonerRegistry;
import com.hp.hpl.jena.reasoner.ValidityReport;
import com.hp.hpl.jena.util.PrintUtil;
public class RefineTest {
public static void main(String[] args) throws IOException {
// load the ontology
OntModel m = ModelFactory.createOntologyModel();
FileInputStream inStream = new FileInputStream("ontology/vehicle.owl");
m.read(inStream, null);
inStream.close();
// create an OWL reasoner and bind it to the ontology
// Reasoner reasoner = PelletReasonerFactory.theInstance().create();
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
reasoner = reasoner.bindSchema(m);
// create a container for the data, and bind it to the reasoner
Model data = ModelFactory.createDefaultModel();
InfModel model = ModelFactory.createInfModel(reasoner, data);
// get the Vehicle class. Vehicle has a cardinality restricton on the
// property numWheels
String uriBase = m.getNsPrefixURI("");
OntClass vehCls = m.getOntClass(uriBase + "Vehicle");
OntClass bmxClass = m.getOntClass(uriBase + "BmxRace");
Individual myCar = vehCls.createIndividual(uriBase + "data/myCar");
Individual bmxRace =
bmxClass.createIndividual(uriBase + "data/bmxRace");
ObjectProperty prop = m.getObjectProperty(uriBase + "hasRacer");
System.out.println("Dom " + prop.getDomain() + " Rng: "
+ prop.getRange());
// by specifying that myCar is in the BMX race, it should force myCar
// to be a motorcycle
bmxRace.addProperty(prop, myCar);
// The statements below show that the individual objects do not change
// as a result of
// the property assignment (aside from the assignment itself)
for (StmtIterator sti = myCar.listProperties(); sti.hasNext();) {
Statement st = sti.nextStatement();
System.out.println(" - " + PrintUtil.print(st));
}
for (StmtIterator sti = bmxRace.listProperties(); sti.hasNext();) {
Statement st = sti.nextStatement();
System.out.println(" - " + PrintUtil.print(st));
}
// By iterating through the model statements though, we show that the
// myCar resource does include Motorcycle as a type
for (StmtIterator sti =
model.listStatements(myCar, null, (RDFNode) null); sti.hasNext();) {
Statement st = sti.nextStatement();
System.out.println(" * " + PrintUtil.print(st));
}
ValidityReport rept = model.validate();
System.out.println("Rept is Clean: " + rept.isClean() + " valid: "
+ rept.isValid());
for (Iterator<ValidityReport.Report> riter = rept.getReports(); riter
.hasNext();) {
ValidityReport.Report rep = riter.next();
System.out.println("ValRep: " + rep.getDescription());
}
// Now the challenge is to get the myCar individual to update with the
// statements
// automatically - I need to show that myCar is a Motorcycle without
// iterating
// through the entire set of statements in the model
}
}
David Jordan
Senior Software Developer
SAS Institute Inc.
Health & Life Sciences, Research & Development
Bldg R ▪ Office 4467
600 Research Drive ▪ Cary, NC 27513
Tel: 919 531 1233 ▪ [email protected]<mailto:[email protected]>
www.sas.com<http://www.sas.com/>
SAS® … THE POWER TO KNOW®