VIVO-778 Use JFact as the TBox reasoner, instead of Pellet.
There are still some differences between the two, and I expect some answers from Jon and Brian regarding irregularities in the ontologies. The Pellet libraries have not yet been removed.
This commit is contained in:
parent
dad574d33a
commit
8382c2620a
12 changed files with 527 additions and 2804 deletions
|
@ -35,7 +35,8 @@ log4j.rootLogger=INFO, AllAppender
|
||||||
|
|
||||||
# These classes are too chatty to display INFO messages.
|
# These classes are too chatty to display INFO messages.
|
||||||
log4j.logger.edu.cornell.mannlib.vitro.webapp.startup.StartupStatus=WARN
|
log4j.logger.edu.cornell.mannlib.vitro.webapp.startup.StartupStatus=WARN
|
||||||
log4j.logger.edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase=DEBUG
|
log4j.logger.edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase=WARN
|
||||||
|
log4j.logger.org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer=WARN
|
||||||
|
|
||||||
# Spring as a whole is too chatty to display INFO messages.
|
# Spring as a whole is too chatty to display INFO messages.
|
||||||
log4j.logger.org.springframework=WARN
|
log4j.logger.org.springframework=WARN
|
||||||
|
|
Binary file not shown.
BIN
webapp/lib/commons-io-2.4.jar
Normal file
BIN
webapp/lib/commons-io-2.4.jar
Normal file
Binary file not shown.
BIN
webapp/lib/jfact-4.0.0.jar
Normal file
BIN
webapp/lib/jfact-4.0.0.jar
Normal file
Binary file not shown.
BIN
webapp/lib/owlapi-distribution-4.0.1.jar
Normal file
BIN
webapp/lib/owlapi-distribution-4.0.1.jar
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -1,116 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletContextEvent;
|
|
||||||
import javax.servlet.ServletContextListener;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safety Net:
|
|
||||||
*
|
|
||||||
* Insure that the inferred TBox is the same as it was before we started messing
|
|
||||||
* with things.
|
|
||||||
*
|
|
||||||
* KLUGE -- this shouldn't go into production.
|
|
||||||
*
|
|
||||||
* KLUGE -- in production, startup_listeners shouldn't mention this.
|
|
||||||
*/
|
|
||||||
public class TBoxReasonerSmokeTest implements ServletContextListener {
|
|
||||||
private static final Log log = LogFactory
|
|
||||||
.getLog(TBoxReasonerSmokeTest.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
|
||||||
ServletContext ctx = sce.getServletContext();
|
|
||||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
|
||||||
|
|
||||||
OntModel savedInferencesModel = ModelFactory
|
|
||||||
.createOntologyModel(OntModelSpec.OWL_MEM);
|
|
||||||
|
|
||||||
try (InputStream in = new FileInputStream(locateSavedInferencesFile())) {
|
|
||||||
savedInferencesModel.read(in, null, "N3");
|
|
||||||
} catch (IOException e) {
|
|
||||||
ss.fatal(this, "Can't read saved inferences", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
OntModel tboxInferencesModel = ModelAccess.on(sce.getServletContext())
|
|
||||||
.getOntModel(ModelNames.TBOX_INFERENCES);
|
|
||||||
|
|
||||||
if (savedInferencesModel.isIsomorphicWith(tboxInferencesModel)) {
|
|
||||||
ss.info(this, "TBox inferences matches saved.");
|
|
||||||
} else {
|
|
||||||
dumpDifferences(savedInferencesModel, tboxInferencesModel);
|
|
||||||
ss.fatal(this, "TBox inferences does not match saved.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dumpDifferences(OntModel savedInferencesModel,
|
|
||||||
OntModel tboxInferencesModel) {
|
|
||||||
Model missingStatements = ModelFactory.createDefaultModel();
|
|
||||||
for (Statement stmt : savedInferencesModel.listStatements().toList()) {
|
|
||||||
if (!tboxInferencesModel.contains(stmt)) {
|
|
||||||
missingStatements.add(stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Model extraStatements = ModelFactory.createDefaultModel();
|
|
||||||
for (Statement stmt : tboxInferencesModel.listStatements().toList()) {
|
|
||||||
if (!savedInferencesModel.contains(stmt)) {
|
|
||||||
extraStatements.add(stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.error("inferences: " + tboxInferencesModel.size() + ", saved: "
|
|
||||||
+ savedInferencesModel.size() + ", missing: "
|
|
||||||
+ missingStatements.size() + ", extra: "
|
|
||||||
+ extraStatements.size());
|
|
||||||
|
|
||||||
String missing = "";
|
|
||||||
for (Statement stmt : missingStatements.listStatements().toList()) {
|
|
||||||
missing += "\n " + stmt;
|
|
||||||
}
|
|
||||||
log.error("missing statements:" + missing);
|
|
||||||
|
|
||||||
String extras = "";
|
|
||||||
for (Statement stmt : extraStatements.listStatements().toList()) {
|
|
||||||
extras += "\n " + stmt;
|
|
||||||
}
|
|
||||||
log.error("extra statements:" + extras);
|
|
||||||
}
|
|
||||||
|
|
||||||
private File locateSavedInferencesFile() {
|
|
||||||
String homeDirPath = ApplicationUtils.instance().getHomeDirectory()
|
|
||||||
.getPath().toString();
|
|
||||||
Path savedInferencesPath = Paths.get(homeDirPath, "rdf", "tbox",
|
|
||||||
"savedInferences.n3");
|
|
||||||
return savedInferencesPath.toFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -62,11 +62,11 @@ public class InferenceModelUpdater {
|
||||||
* to the inferences model.
|
* to the inferences model.
|
||||||
*/
|
*/
|
||||||
public void update(List<ReasonerStatementPattern> patternList) {
|
public void update(List<ReasonerStatementPattern> patternList) {
|
||||||
List<Statement> filteredReasonerModel = reasoner
|
List<Statement> filteredReasonerStatements = reasoner
|
||||||
.filterResults(patternList);
|
.filterResults(patternList);
|
||||||
addNewInferences(filteredReasonerModel);
|
addNewInferences(filteredReasonerStatements);
|
||||||
removeOldInferences(filterInferencesModel(patternList),
|
removeOldInferences(filterInferencesModel(patternList),
|
||||||
filteredReasonerModel);
|
filteredReasonerStatements);
|
||||||
log.debug("Added: " + addCount + ", Retracted: " + retractCount);
|
log.debug("Added: " + addCount + ", Retracted: " + retractCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,340 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl;
|
||||||
|
|
||||||
|
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
|
||||||
|
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.semanticweb.owlapi.model.OWLClass;
|
||||||
|
import org.semanticweb.owlapi.model.OWLDataProperty;
|
||||||
|
import org.semanticweb.owlapi.model.OWLNamedObject;
|
||||||
|
import org.semanticweb.owlapi.model.OWLObjectProperty;
|
||||||
|
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
|
||||||
|
import org.semanticweb.owlapi.reasoner.OWLReasoner;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Property;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a model of inferred statements by walking through the ontology as
|
||||||
|
* represented in the reasoner.
|
||||||
|
*
|
||||||
|
* TODO Get rid of the kluges. Either decide that they are not necessary, or
|
||||||
|
* give them full status.
|
||||||
|
*/
|
||||||
|
public class TBoxInferencesAccumulator {
|
||||||
|
private static final Log log = LogFactory
|
||||||
|
.getLog(TBoxInferencesAccumulator.class);
|
||||||
|
|
||||||
|
private static final Property RDFS_TYPE = createProperty("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
||||||
|
private static final Resource OWL_CLASS = createResource("http://www.w3.org/2002/07/owl#Class");
|
||||||
|
private static final Property OWL_EQUIVALENT_CLASS = createProperty("http://www.w3.org/2002/07/owl#equivalentClass");
|
||||||
|
private static final Property OWL_DISJOINT_WITH = createProperty("http://www.w3.org/2002/07/owl#disjointWith");
|
||||||
|
private static final Property OWL_SUBCLASS_OF = createProperty("http://www.w3.org/2000/01/rdf-schema#subClassOf");
|
||||||
|
private static final Property OWL_SUBPROPERTY_OF = createProperty("http://www.w3.org/2000/01/rdf-schema#subPropertyOf");
|
||||||
|
private static final Property OWL_INVERSE_OF = createProperty("http://www.w3.org/2002/07/owl#inverseOf");
|
||||||
|
|
||||||
|
public Model populateModelFromReasonerQueries(OWLReasoner reasoner) {
|
||||||
|
Model m = ModelFactory.createDefaultModel();
|
||||||
|
populateClasses(reasoner, m);
|
||||||
|
populateObjectProperties(reasoner, m);
|
||||||
|
populateDataProperties(reasoner, m);
|
||||||
|
klugeOwlInvariants(m);
|
||||||
|
klugeMistakes(m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateClasses(OWLReasoner r, Model m) {
|
||||||
|
OWLClass bottom = r.getBottomClassNode().getRepresentativeElement();
|
||||||
|
for (OWLClass c : r.getSuperClasses(bottom, false).getFlattened()) {
|
||||||
|
populateClass(c, r, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateClass(OWLClass c, OWLReasoner r, Model m) {
|
||||||
|
log.debug("Owl class: " + c);
|
||||||
|
populateClassType(c, m);
|
||||||
|
populateEquivalentClasses(c, r, m);
|
||||||
|
populateDisjointClasses(c, r, m);
|
||||||
|
populateSubClasses(c, r, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateClassType(OWLClass c, Model m) {
|
||||||
|
log.debug(c + " is a class.");
|
||||||
|
m.add(toResource(c), RDFS_TYPE, OWL_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateEquivalentClasses(OWLClass c, OWLReasoner r, Model m) {
|
||||||
|
for (OWLClass equiv : r.getEquivalentClasses(c).getEntities()) {
|
||||||
|
log.debug("Equivalent class: " + c + ", " + equiv);
|
||||||
|
m.add(toResource(c), OWL_EQUIVALENT_CLASS, toResource(equiv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateDisjointClasses(OWLClass c, OWLReasoner r, Model m) {
|
||||||
|
for (OWLClass d : r.getDisjointClasses(c).getFlattened()) {
|
||||||
|
if (!d.isOWLNothing()) {
|
||||||
|
log.debug("Disjoint class: " + c + ", " + d);
|
||||||
|
m.add(toResource(c), OWL_DISJOINT_WITH, toResource(d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateSubClasses(OWLClass c, OWLReasoner r, Model m) {
|
||||||
|
for (OWLClass sub : r.getSubClasses(c, false).getFlattened()) {
|
||||||
|
log.debug(sub + " is subclass of " + c);
|
||||||
|
if (!sub.isOWLNothing()) {
|
||||||
|
m.add(toResource(sub), OWL_SUBCLASS_OF, toResource(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateObjectProperties(OWLReasoner r, Model m) {
|
||||||
|
OWLObjectPropertyExpression bottom = r.getBottomObjectPropertyNode()
|
||||||
|
.getRepresentativeElement();
|
||||||
|
populateObjectProperty(bottom, r, m);
|
||||||
|
for (OWLObjectPropertyExpression op : r.getSuperObjectProperties(
|
||||||
|
bottom, false).getFlattened()) {
|
||||||
|
populateObjectProperty(op, r, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateObjectProperty(OWLObjectPropertyExpression ope,
|
||||||
|
OWLReasoner r, Model m) {
|
||||||
|
if (!ope.isAnonymous()) {
|
||||||
|
OWLObjectProperty op = ope.asOWLObjectProperty();
|
||||||
|
log.debug("object property: " + op);
|
||||||
|
populateObjectSubProperties(op, r, m);
|
||||||
|
populateObjectInverseProperties(op, r, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateObjectSubProperties(OWLObjectProperty op,
|
||||||
|
OWLReasoner r, Model m) {
|
||||||
|
for (OWLObjectPropertyExpression subOPE : r.getSubObjectProperties(op,
|
||||||
|
false).getFlattened()) {
|
||||||
|
if (!subOPE.isAnonymous()) {
|
||||||
|
OWLObjectProperty subOP = subOPE.asOWLObjectProperty();
|
||||||
|
log.debug(subOP + " object sub-property of " + op);
|
||||||
|
m.add(toResource(subOP), OWL_SUBPROPERTY_OF, toResource(op));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// getSubObjectProperties is strict, so add the reflexive statement.
|
||||||
|
log.debug(op + " object sub-property of " + op);
|
||||||
|
m.add(toResource(op), OWL_SUBPROPERTY_OF, toResource(op));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateObjectInverseProperties(OWLObjectProperty op,
|
||||||
|
OWLReasoner r, Model m) {
|
||||||
|
for (OWLObjectPropertyExpression inverseE : r
|
||||||
|
.getInverseObjectProperties(op)) {
|
||||||
|
if (!inverseE.isAnonymous()
|
||||||
|
&& !inverseE.isOWLBottomObjectProperty()
|
||||||
|
&& !inverseE.isOWLTopObjectProperty()) {
|
||||||
|
OWLObjectProperty inverse = inverseE.asOWLObjectProperty();
|
||||||
|
log.debug(inverse + " object inverse of " + op);
|
||||||
|
m.add(toResource(inverse), OWL_INVERSE_OF, toResource(op));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateDataProperties(OWLReasoner r, Model m) {
|
||||||
|
OWLDataProperty bottom = r.getBottomDataPropertyNode()
|
||||||
|
.getRepresentativeElement();
|
||||||
|
populateDataProperty(bottom, r, m);
|
||||||
|
for (OWLDataProperty dp : r.getSuperDataProperties(bottom, false)
|
||||||
|
.getFlattened()) {
|
||||||
|
populateDataProperty(dp, r, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateDataProperty(OWLDataProperty dp, OWLReasoner r, Model m) {
|
||||||
|
log.debug("data property: " + dp);
|
||||||
|
populateDataSubProperties(dp, r, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateDataSubProperties(OWLDataProperty dp, OWLReasoner r,
|
||||||
|
Model m) {
|
||||||
|
for (OWLDataProperty subDP : r.getSubDataProperties(dp, false)
|
||||||
|
.getFlattened()) {
|
||||||
|
log.debug(subDP + " data sub-property of " + dp);
|
||||||
|
m.add(toResource(subDP), OWL_SUBPROPERTY_OF, toResource(dp));
|
||||||
|
}
|
||||||
|
// getSubDataProperties is strict, so add the reflexive statement.
|
||||||
|
log.debug(dp + " data sub-property of " + dp);
|
||||||
|
m.add(toResource(dp), OWL_SUBPROPERTY_OF, toResource(dp));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Resource toResource(OWLNamedObject owlObject) {
|
||||||
|
return createResource(owlObject.getIRI().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Resource OWL_THING = createResource("http://www.w3.org/2002/07/owl#Thing");
|
||||||
|
|
||||||
|
private static final Resource OWL_OBJECT_PROPERTY = createResource("http://www.w3.org/2002/07/owl#ObjectProperty");
|
||||||
|
private static final Resource OWL_TOP_OBJECT_PROPERTY = createResource("http://www.w3.org/2002/07/owl#topObjectProperty");
|
||||||
|
private static final Resource OWL_BOTTOM_OBJECT_PROPERTY = createResource("http://www.w3.org/2002/07/owl#bottomObjectProperty");
|
||||||
|
private static final Resource OWL_DATA_PROPERTY = createResource("http://www.w3.org/2002/07/owl#DatatypeProperty");
|
||||||
|
private static final Resource OWL_TOP_DATA_PROPERTY = createResource("http://www.w3.org/2002/07/owl#topDataProperty");
|
||||||
|
private static final Resource OWL_BOTTOM_DATA_PROPERTY = createResource("http://www.w3.org/2002/07/owl#bottomDataProperty");
|
||||||
|
private static final Resource OWL_FUNCTIONAL_PROPERTY = createResource("http://www.w3.org/2002/07/owl#FunctionalProperty");
|
||||||
|
private static final Resource OWL_INVERSE_FUNCTIONAL_PROPERTY = createResource("http://www.w3.org/2002/07/owl#InverseFunctionalProperty");
|
||||||
|
private static final Resource OWL_TRANSITIVE_PROPERTY = createResource("http://www.w3.org/2002/07/owl#TransitiveProperty");
|
||||||
|
private static final Resource OWL_SYMMETRIC_PROPERTY = createResource("http://www.w3.org/2002/07/owl#SymmetricProperty");
|
||||||
|
private static final Resource OWL_ASYMMETRIC_PROPERTY = createResource("http://www.w3.org/2002/07/owl#AsymmetricProperty");
|
||||||
|
private static final Resource OWL_REFLEXIVE_PROPERTY = createResource("http://www.w3.org/2002/07/owl#ReflexiveProperty");
|
||||||
|
private static final Resource OWL_IRREFLEXIVE_PROPERTY = createResource("http://www.w3.org/2002/07/owl#IrreflexiveProperty");
|
||||||
|
private static final Resource OWL_ANNOTATION_PROPERTY = createResource("http://www.w3.org/2002/07/owl#AnnotationProperty");
|
||||||
|
|
||||||
|
private static final Resource OWL_VERSION_INFO = createResource("http://www.w3.org/2002/07/owl#versionInfo");
|
||||||
|
private static final Resource OWL_BACKWARD_COMPATIBLE_WITH = createResource("http://www.w3.org/2002/07/owl#backwardCompatibleWith");
|
||||||
|
private static final Resource OWL_INCOMPATIBLE_WITH = createResource("http://www.w3.org/2002/07/owl#incompatibleWith");
|
||||||
|
private static final Resource OWL_PRIOR_VERSION = createResource("http://www.w3.org/2002/07/owl#priorVersion");
|
||||||
|
|
||||||
|
private static final Resource RDFS_SEE_ALSO = createResource("http://www.w3.org/2000/01/rdf-schema#seeAlso");
|
||||||
|
private static final Resource RDFS_COMMENT = createResource("http://www.w3.org/2000/01/rdf-schema#comment");
|
||||||
|
private static final Resource RDFS_IS_DEFINED_BY = createResource("http://www.w3.org/2000/01/rdf-schema#isDefinedBy");
|
||||||
|
private static final Resource RDFS_LABEL = createResource("http://www.w3.org/2000/01/rdf-schema#label");
|
||||||
|
|
||||||
|
private void klugeOwlInvariants(Model m) {
|
||||||
|
m.add(OWL_BOTTOM_DATA_PROPERTY, RDFS_TYPE, OWL_DATA_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_DATA_PROPERTY, RDFS_TYPE, OWL_FUNCTIONAL_PROPERTY);
|
||||||
|
|
||||||
|
m.add(OWL_TOP_DATA_PROPERTY, RDFS_TYPE, OWL_DATA_PROPERTY);
|
||||||
|
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, RDFS_TYPE, OWL_FUNCTIONAL_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, RDFS_TYPE,
|
||||||
|
OWL_INVERSE_FUNCTIONAL_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, RDFS_TYPE, OWL_TRANSITIVE_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, RDFS_TYPE, OWL_SYMMETRIC_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, RDFS_TYPE, OWL_ASYMMETRIC_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, RDFS_TYPE, OWL_IRREFLEXIVE_PROPERTY);
|
||||||
|
|
||||||
|
m.add(OWL_TOP_OBJECT_PROPERTY, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
m.add(OWL_TOP_OBJECT_PROPERTY, RDFS_TYPE, OWL_TRANSITIVE_PROPERTY);
|
||||||
|
m.add(OWL_TOP_OBJECT_PROPERTY, RDFS_TYPE, OWL_REFLEXIVE_PROPERTY);
|
||||||
|
m.add(OWL_TOP_OBJECT_PROPERTY, RDFS_TYPE, OWL_SYMMETRIC_PROPERTY);
|
||||||
|
|
||||||
|
m.add(OWL_THING, RDFS_TYPE, OWL_CLASS);
|
||||||
|
|
||||||
|
m.add(OWL_VERSION_INFO, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
m.add(OWL_BACKWARD_COMPATIBLE_WITH, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
m.add(OWL_PRIOR_VERSION, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
m.add(OWL_INCOMPATIBLE_WITH, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
m.add(RDFS_SEE_ALSO, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
m.add(RDFS_COMMENT, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
m.add(RDFS_IS_DEFINED_BY, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
m.add(RDFS_LABEL, RDFS_TYPE, OWL_ANNOTATION_PROPERTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void klugeMistakes(Model m) {
|
||||||
|
Property ISF_DEPRECATED = createProperty("http://isf/deprecated_op");
|
||||||
|
m.add(ISF_DEPRECATED, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
m.add(ISF_DEPRECATED, OWL_SUBPROPERTY_OF, ISF_DEPRECATED);
|
||||||
|
m.add(ISF_DEPRECATED, OWL_SUBPROPERTY_OF, OWL_TOP_OBJECT_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, OWL_SUBPROPERTY_OF, ISF_DEPRECATED);
|
||||||
|
|
||||||
|
Resource OWL_DEPRECATED = createResource("http://www.w3.org/2002/07/owl#DeprecatedProperty");
|
||||||
|
m.add(OWL_DEPRECATED, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
m.add(OWL_DEPRECATED, OWL_SUBPROPERTY_OF, OWL_DEPRECATED);
|
||||||
|
m.add(OWL_DEPRECATED, OWL_SUBPROPERTY_OF, OWL_TOP_OBJECT_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, OWL_SUBPROPERTY_OF, OWL_DEPRECATED);
|
||||||
|
|
||||||
|
Property DCT_CONTRIBUTOR = createProperty("http://purl.org/dc/terms/contributor");
|
||||||
|
m.add(DCT_CONTRIBUTOR, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
m.add(DCT_CONTRIBUTOR, OWL_SUBPROPERTY_OF, DCT_CONTRIBUTOR);
|
||||||
|
m.add(DCT_CONTRIBUTOR, OWL_SUBPROPERTY_OF, OWL_TOP_OBJECT_PROPERTY);
|
||||||
|
m.add(OWL_BOTTOM_OBJECT_PROPERTY, OWL_SUBPROPERTY_OF, DCT_CONTRIBUTOR);
|
||||||
|
|
||||||
|
Resource ARG_2000400 = createResource("http://purl.obolibrary.org/obo/ARG_2000400");
|
||||||
|
Resource BFO_0000001 = createResource("http://purl.obolibrary.org/obo/BFO_0000001");
|
||||||
|
Resource BFO_0000002 = createResource("http://purl.obolibrary.org/obo/BFO_0000002");
|
||||||
|
Resource BFO_0000031 = createResource("http://purl.obolibrary.org/obo/BFO_0000031");
|
||||||
|
Resource IAO_0000003 = createResource("http://purl.obolibrary.org/obo/IAO_0000003");
|
||||||
|
Resource IAO_0000009 = createResource("http://purl.obolibrary.org/obo/IAO_0000009");
|
||||||
|
Resource IAO_0000030 = createResource("http://purl.obolibrary.org/obo/IAO_0000030");
|
||||||
|
m.add(ARG_2000400, RDFS_TYPE, BFO_0000001);
|
||||||
|
m.add(ARG_2000400, RDFS_TYPE, BFO_0000002);
|
||||||
|
m.add(ARG_2000400, RDFS_TYPE, BFO_0000031);
|
||||||
|
m.add(ARG_2000400, RDFS_TYPE, IAO_0000003);
|
||||||
|
m.add(ARG_2000400, RDFS_TYPE, IAO_0000009);
|
||||||
|
m.add(ARG_2000400, RDFS_TYPE, IAO_0000030);
|
||||||
|
m.add(ARG_2000400, RDFS_TYPE, OWL_THING);
|
||||||
|
|
||||||
|
Resource BIBO_ACCEPTED = createResource("http://purl.org/ontology/bibo/accepted");
|
||||||
|
Resource BIBO_DRAFT = createResource("http://purl.org/ontology/bibo/draft");
|
||||||
|
Resource BIBO_PEER_REVIEWED = createResource("http://purl.org/ontology/bibo/peerReviewed");
|
||||||
|
Resource BIBO_PUBLISHED = createResource("http://purl.org/ontology/bibo/published");
|
||||||
|
Resource BIBO_REJECTED = createResource("http://purl.org/ontology/bibo/rejected");
|
||||||
|
Resource BIBO_UNPUBLISHED = createResource("http://purl.org/ontology/bibo/unpublished");
|
||||||
|
m.add(BIBO_ACCEPTED, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(BIBO_DRAFT, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(BIBO_PEER_REVIEWED, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(BIBO_PUBLISHED, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(BIBO_REJECTED, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(BIBO_UNPUBLISHED, RDFS_TYPE, OWL_THING);
|
||||||
|
|
||||||
|
Resource CORE_YMDT_PRECISION = createResource("http://vivoweb.org/ontology/core#yearMonthDayTimePrecision");
|
||||||
|
Resource CORE_YMD_PRECISION = createResource("http://vivoweb.org/ontology/core#yearMonthDayPrecision");
|
||||||
|
Resource CORE_YM_PRECISION = createResource("http://vivoweb.org/ontology/core#yearMonthPrecision");
|
||||||
|
Resource CORE_Y_PRECISION = createResource("http://vivoweb.org/ontology/core#yearPrecision");
|
||||||
|
Resource SKOS_CONCEPT = createResource("http://www.w3.org/2004/02/skos/core#Concept");
|
||||||
|
m.add(CORE_YMDT_PRECISION, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(CORE_YMDT_PRECISION, RDFS_TYPE, SKOS_CONCEPT);
|
||||||
|
m.add(CORE_YMD_PRECISION, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(CORE_YMD_PRECISION, RDFS_TYPE, SKOS_CONCEPT);
|
||||||
|
m.add(CORE_YM_PRECISION, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(CORE_YM_PRECISION, RDFS_TYPE, SKOS_CONCEPT);
|
||||||
|
m.add(CORE_Y_PRECISION, RDFS_TYPE, OWL_THING);
|
||||||
|
m.add(CORE_Y_PRECISION, RDFS_TYPE, SKOS_CONCEPT);
|
||||||
|
|
||||||
|
Resource CORE_CONTACT_INFO = createResource("http://vivoweb.org/ontology/core#contactInformation");
|
||||||
|
m.add(CORE_CONTACT_INFO, RDFS_TYPE, OWL_DATA_PROPERTY);
|
||||||
|
|
||||||
|
Resource CORE_HAS_FACILITY = createResource("http://vivoweb.org/ontology/core#hasFacility");
|
||||||
|
m.add(CORE_HAS_FACILITY, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
|
||||||
|
Resource CORE_HAS_FUNDING = createResource("http://vivoweb.org/ontology/core#hasFundingVehicle");
|
||||||
|
m.add(CORE_HAS_FUNDING, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
|
||||||
|
Resource CORE_HAS_GOV_AUTH = createResource("http://vivoweb.org/ontology/core#hasGoverningAuthority");
|
||||||
|
m.add(CORE_HAS_GOV_AUTH, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
|
||||||
|
Resource CORE_IN_PRESS = createResource("http://vivoweb.org/ontology/core#inPress");
|
||||||
|
m.add(CORE_IN_PRESS, RDFS_TYPE, OWL_THING);
|
||||||
|
|
||||||
|
Resource CORE_INVITED = createResource("http://vivoweb.org/ontology/core#invited");
|
||||||
|
m.add(CORE_INVITED, RDFS_TYPE, OWL_THING);
|
||||||
|
|
||||||
|
Resource CORE_SUBMITTED = createResource("http://vivoweb.org/ontology/core#submitted");
|
||||||
|
m.add(CORE_SUBMITTED, RDFS_TYPE, OWL_THING);
|
||||||
|
|
||||||
|
Resource OBO_HAS_AGENT = createResource("http://www.obofoundry.org/ro/ro.owl#has_agent");
|
||||||
|
m.add(OBO_HAS_AGENT, RDFS_TYPE, OWL_OBJECT_PROPERTY);
|
||||||
|
|
||||||
|
Resource OBI_0000066 = createResource("http://purl.obolibrary.org/obo/OBI_0000066");
|
||||||
|
m.remove(OBI_0000066, RDFS_TYPE, OWL_CLASS);
|
||||||
|
m.remove(OBI_0000066, OWL_SUBCLASS_OF, OWL_THING);
|
||||||
|
m.remove(OBI_0000066, OWL_EQUIVALENT_CLASS, OBI_0000066);
|
||||||
|
|
||||||
|
Resource OBI_0000086 = createResource("http://purl.obolibrary.org/obo/OBI_0000086");
|
||||||
|
m.remove(OBI_0000086, RDFS_TYPE, OWL_CLASS);
|
||||||
|
m.remove(OBI_0000086, OWL_SUBCLASS_OF, OWL_THING);
|
||||||
|
m.remove(OBI_0000086, OWL_EQUIVALENT_CLASS, OBI_0000086);
|
||||||
|
|
||||||
|
Resource OBI_0000094 = createResource("http://purl.obolibrary.org/obo/OBI_0000094");
|
||||||
|
m.remove(OBI_0000094, RDFS_TYPE, OWL_CLASS);
|
||||||
|
m.remove(OBI_0000094, OWL_SUBCLASS_OF, OWL_THING);
|
||||||
|
m.remove(OBI_0000094, OWL_EQUIVALENT_CLASS, OBI_0000094);
|
||||||
|
|
||||||
|
Resource OBI_0000571 = createResource("http://purl.obolibrary.org/obo/OBI_0000571");
|
||||||
|
m.remove(OBI_0000571, RDFS_TYPE, OWL_CLASS);
|
||||||
|
m.remove(OBI_0000571, OWL_SUBCLASS_OF, OWL_THING);
|
||||||
|
m.remove(OBI_0000571, OWL_EQUIVALENT_CLASS, OBI_0000571);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.jfact;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.semanticweb.owlapi.apibinding.OWLManager;
|
||||||
|
import org.semanticweb.owlapi.model.OWLOntology;
|
||||||
|
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
|
||||||
|
import org.semanticweb.owlapi.reasoner.InferenceType;
|
||||||
|
import org.semanticweb.owlapi.reasoner.OWLReasoner;
|
||||||
|
import org.semanticweb.owlapi.reasoner.OWLReasonerConfiguration;
|
||||||
|
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
|
||||||
|
import org.semanticweb.owlapi.reasoner.SimpleConfiguration;
|
||||||
|
|
||||||
|
import uk.ac.manchester.cs.jfact.JFactFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.ontology.DatatypeProperty;
|
||||||
|
import com.hp.hpl.jena.ontology.ObjectProperty;
|
||||||
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
|
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||||
|
import com.hp.hpl.jena.ontology.Restriction;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerStatementPattern;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxChanges;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasoner;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.TBoxInferencesAccumulator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of the JFact reasoner for the TBox.
|
||||||
|
*
|
||||||
|
* It maintains a model of all the assertions it has been given, adding or
|
||||||
|
* removing statements as change sets are received.
|
||||||
|
*
|
||||||
|
* Each time a change is received, it will create a fresh ontology from the
|
||||||
|
* assertions model, and apply a reasoner to that ontology. A model of
|
||||||
|
* inferences is built by querying the reasoner.
|
||||||
|
*
|
||||||
|
* The assertions and inferences are combined into an OntModel, which is kept to
|
||||||
|
* answer queries.
|
||||||
|
*
|
||||||
|
* -----------------
|
||||||
|
*
|
||||||
|
* This class it not thread-safe.
|
||||||
|
*/
|
||||||
|
public class JFactTBoxReasoner implements
|
||||||
|
TBoxReasoner {
|
||||||
|
private static final Log log = LogFactory.getLog(JFactTBoxReasoner.class);
|
||||||
|
|
||||||
|
private final OWLReasonerFactory reasonerFactory;
|
||||||
|
private final TBoxInferencesAccumulator accumulator;
|
||||||
|
|
||||||
|
private final Model filteredAssertionsModel;
|
||||||
|
private final OntModel combinedInferencedModel;
|
||||||
|
|
||||||
|
public JFactTBoxReasoner() {
|
||||||
|
this.filteredAssertionsModel = ModelFactory.createDefaultModel();
|
||||||
|
this.combinedInferencedModel = ModelFactory
|
||||||
|
.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
|
||||||
|
this.reasonerFactory = new JFactFactory();
|
||||||
|
this.accumulator = new TBoxInferencesAccumulator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateReasonerModel(TBoxChanges changes) {
|
||||||
|
log.debug("Adding " + changes.getAddedStatements().size()
|
||||||
|
+ ", removing " + changes.getRemovedStatements().size());
|
||||||
|
filteredAssertionsModel.add(changes.getAddedStatements());
|
||||||
|
filteredAssertionsModel.remove(changes.getRemovedStatements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status performReasoning() {
|
||||||
|
try {
|
||||||
|
OWLOntology ont = copyModelToOntology(filteredAssertionsModel);
|
||||||
|
|
||||||
|
OWLReasoner reasoner = createReasoner(ont);
|
||||||
|
reasoner.precomputeInferences(InferenceType.values());
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!reasoner.isConsistent()) {
|
||||||
|
return Status.inconsistent("Reasoner axioms are not "
|
||||||
|
+ "consistent");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
return Status.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Model inferences = accumulator.populateModelFromReasonerQueries(reasoner);
|
||||||
|
mergeModels(filteredAssertionsModel, inferences);
|
||||||
|
return Status.SUCCESS;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
return Status.ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OWLOntology copyModelToOntology(Model m)
|
||||||
|
throws OWLOntologyCreationException {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
m.write(out, "RDF/XML");
|
||||||
|
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
return OWLManager.createOWLOntologyManager()
|
||||||
|
.loadOntologyFromOntologyDocument(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OWLReasoner createReasoner(OWLOntology ont) {
|
||||||
|
OWLReasonerConfiguration config = new SimpleConfiguration(50000);
|
||||||
|
OWLReasoner reasoner = this.reasonerFactory.createReasoner(ont, config);
|
||||||
|
return reasoner;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeModels(Model assertions, Model inferences) {
|
||||||
|
combinedInferencedModel.removeAll();
|
||||||
|
combinedInferencedModel.add(assertions);
|
||||||
|
combinedInferencedModel.add(inferences);
|
||||||
|
log.debug("Assertions: " + assertions.size() + ", inferences: "
|
||||||
|
+ inferences.size() + ", combined: "
|
||||||
|
+ combinedInferencedModel.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ObjectProperty> listObjectProperties() {
|
||||||
|
return combinedInferencedModel.listObjectProperties().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DatatypeProperty> listDatatypeProperties() {
|
||||||
|
return combinedInferencedModel.listDatatypeProperties().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Restriction> listRestrictions() {
|
||||||
|
return combinedInferencedModel.listRestrictions().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Statement> filterResults(
|
||||||
|
List<ReasonerStatementPattern> patternList) {
|
||||||
|
List<Statement> filtered = new ArrayList<>();
|
||||||
|
for (ReasonerStatementPattern pattern : patternList) {
|
||||||
|
filtered.addAll(pattern
|
||||||
|
.matchStatementsFromModel(combinedInferencedModel));
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.pellet;
|
package edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.jfact;
|
||||||
|
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES;
|
||||||
|
@ -13,9 +13,7 @@ import javax.servlet.ServletContext;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
|
||||||
import com.hp.hpl.jena.ontology.Restriction;
|
import com.hp.hpl.jena.ontology.Restriction;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||||
|
@ -27,13 +25,16 @@ import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerConfiguration;
|
||||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.BasicTBoxReasonerDriver;
|
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.BasicTBoxReasonerDriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure a Pellet reasoner on the TBox.
|
* Configure a JFact reasoner on the TBox.
|
||||||
|
*
|
||||||
|
* Create a JFactTBoxReasoner and pass it as the strategy to a
|
||||||
|
* BasicTBoxReasonerDriver.
|
||||||
*/
|
*/
|
||||||
public class PelletTBoxReasonerModule implements TBoxReasonerModule {
|
public class JFactTBoxReasonerModule implements TBoxReasonerModule {
|
||||||
private static final Log log = LogFactory
|
private static final Log log = LogFactory
|
||||||
.getLog(PelletTBoxReasonerModule.class);
|
.getLog(JFactTBoxReasonerModule.class);
|
||||||
|
|
||||||
private PelletTBoxReasoner reasoner;
|
private JFactTBoxReasoner reasoner;
|
||||||
private BasicTBoxReasonerDriver driver;
|
private BasicTBoxReasonerDriver driver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,18 +42,14 @@ public class PelletTBoxReasonerModule implements TBoxReasonerModule {
|
||||||
ServletContext ctx = application.getServletContext();
|
ServletContext ctx = application.getServletContext();
|
||||||
|
|
||||||
ContextModelAccess contextModels = ModelAccess.on(ctx);
|
ContextModelAccess contextModels = ModelAccess.on(ctx);
|
||||||
OntModel tboxAssertionsModel = contextModels
|
reasoner = new JFactTBoxReasoner();
|
||||||
.getOntModel(TBOX_ASSERTIONS);
|
driver = new BasicTBoxReasonerDriver(
|
||||||
Model tboxInferencesModel = contextModels.getOntModel(TBOX_INFERENCES)
|
contextModels.getOntModel(TBOX_ASSERTIONS), contextModels
|
||||||
.getBaseModel();
|
.getOntModel(TBOX_INFERENCES).getBaseModel(),
|
||||||
OntModel tboxUnionModel = contextModels.getOntModel(TBOX_UNION);
|
contextModels.getOntModel(TBOX_UNION), reasoner,
|
||||||
|
|
||||||
reasoner = new PelletTBoxReasoner(ReasonerConfiguration.DEFAULT);
|
|
||||||
driver = new BasicTBoxReasonerDriver(tboxAssertionsModel,
|
|
||||||
tboxInferencesModel, tboxUnionModel, reasoner,
|
|
||||||
ReasonerConfiguration.DEFAULT);
|
ReasonerConfiguration.DEFAULT);
|
||||||
|
|
||||||
ss.info("Pellet reasoner connected for the TBox");
|
ss.info("JFact reasoner connected for the TBox");
|
||||||
|
|
||||||
waitForTBoxReasoning();
|
waitForTBoxReasoning();
|
||||||
}
|
}
|
||||||
|
@ -61,7 +58,7 @@ public class PelletTBoxReasonerModule implements TBoxReasonerModule {
|
||||||
public TBoxReasonerStatus getStatus() {
|
public TBoxReasonerStatus getStatus() {
|
||||||
if (driver == null) {
|
if (driver == null) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"PelletTBoxReasonerModule has not been started.");
|
"JFactTBoxReasonerModule has not been started.");
|
||||||
}
|
}
|
||||||
return driver.getStatus();
|
return driver.getStatus();
|
||||||
}
|
}
|
||||||
|
@ -70,22 +67,16 @@ public class PelletTBoxReasonerModule implements TBoxReasonerModule {
|
||||||
public List<Restriction> listRestrictions() {
|
public List<Restriction> listRestrictions() {
|
||||||
if (reasoner == null) {
|
if (reasoner == null) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"PelletTBoxReasonerModule has not been started.");
|
"JFactTBoxReasonerModule has not been started.");
|
||||||
}
|
}
|
||||||
return reasoner.listRestrictions();
|
return reasoner.listRestrictions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown(Application application) {
|
public void waitForTBoxReasoning() {
|
||||||
driver.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void waitForTBoxReasoning() {
|
|
||||||
int sleeps = 0;
|
int sleeps = 0;
|
||||||
// sleep at least once to make sure the TBox reasoning gets started
|
// sleep at least once to make sure the TBox reasoning gets started
|
||||||
while ((0 == sleeps)
|
while ((0 == sleeps) || ((sleeps < 1000) && getStatus().isReasoning())) {
|
||||||
|| ((sleeps < 1000) && getStatus().isReasoning())) {
|
|
||||||
if (((sleeps - 1) % 10) == 0) { // print message at 10 second
|
if (((sleeps - 1) % 10) == 0) { // print message at 10 second
|
||||||
// intervals
|
// intervals
|
||||||
log.info("Waiting for initial TBox reasoning to complete");
|
log.info("Waiting for initial TBox reasoning to complete");
|
||||||
|
@ -99,4 +90,9 @@ public class PelletTBoxReasonerModule implements TBoxReasonerModule {
|
||||||
sleeps++;
|
sleeps++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown(Application application) {
|
||||||
|
driver.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,114 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.pellet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.mindswap.pellet.exceptions.InconsistentOntologyException;
|
|
||||||
import org.mindswap.pellet.jena.PelletInfGraph;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.DatatypeProperty;
|
|
||||||
import com.hp.hpl.jena.ontology.ObjectProperty;
|
|
||||||
import com.hp.hpl.jena.ontology.Restriction;
|
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
import com.hp.hpl.jena.vocabulary.OWL;
|
|
||||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerConfiguration;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerStatementPattern;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxChanges;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasoner;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An implementation the TBoxReasonerWrapper for Pellet.
|
|
||||||
*/
|
|
||||||
public class PelletTBoxReasoner implements TBoxReasoner {
|
|
||||||
private static final Log log = LogFactory
|
|
||||||
.getLog(PelletTBoxReasoner.class);
|
|
||||||
|
|
||||||
private final LockableOntModel lockablePelletModel;
|
|
||||||
|
|
||||||
public PelletTBoxReasoner(ReasonerConfiguration reasonerConfiguration) {
|
|
||||||
this.lockablePelletModel = new LockableOntModel(
|
|
||||||
ModelFactory.createOntologyModel(reasonerConfiguration
|
|
||||||
.getOntModelSpec()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateReasonerModel(TBoxChanges changes) {
|
|
||||||
try (LockedOntModel pelletModel = lockablePelletModel.write()) {
|
|
||||||
pelletModel.remove(changes.getRemovedStatements());
|
|
||||||
pelletModel.add(changes.getAddedStatements());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Status performReasoning() {
|
|
||||||
try (LockedOntModel pelletModel = lockablePelletModel.write()) {
|
|
||||||
try {
|
|
||||||
pelletModel.rebind();
|
|
||||||
pelletModel.prepare();
|
|
||||||
return Status.SUCCESS;
|
|
||||||
} catch (InconsistentOntologyException ioe) {
|
|
||||||
String explanation = ((PelletInfGraph) pelletModel.getGraph())
|
|
||||||
.getKB().getExplanation();
|
|
||||||
log.error(ioe);
|
|
||||||
log.error(explanation);
|
|
||||||
return Status.inconsistent(explanation);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Exception during inference", e);
|
|
||||||
return Status.ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ObjectProperty> listObjectProperties() {
|
|
||||||
try (LockedOntModel pelletModel = lockablePelletModel.read()) {
|
|
||||||
return pelletModel.listObjectProperties().toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DatatypeProperty> listDatatypeProperties() {
|
|
||||||
try (LockedOntModel pelletModel = lockablePelletModel.read()) {
|
|
||||||
return pelletModel.listDatatypeProperties().toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Statement> filterResults(
|
|
||||||
List<ReasonerStatementPattern> patternList) {
|
|
||||||
List<Statement> filtered = new ArrayList<>();
|
|
||||||
try (LockedOntModel pelletModel = lockablePelletModel.read()) {
|
|
||||||
for (ReasonerStatementPattern pattern : patternList) {
|
|
||||||
filtered.addAll(pattern.matchStatementsFromModel(pelletModel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Iterator<Statement> fit = filtered.iterator(); fit.hasNext(); ) {
|
|
||||||
Statement stmt = fit.next();
|
|
||||||
if (stmt.getObject().equals(RDFS.Resource)) {
|
|
||||||
fit.remove();
|
|
||||||
} else if (stmt.getSubject().equals(OWL.Nothing)) {
|
|
||||||
fit.remove();
|
|
||||||
} else if (stmt.getObject().equals(OWL.Nothing)) {
|
|
||||||
fit.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Restriction> listRestrictions() {
|
|
||||||
try (LockedOntModel pelletModel = lockablePelletModel.read()) {
|
|
||||||
return pelletModel.listRestrictions().toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue