some refactoring of SimpleReasoner

This commit is contained in:
stellamit 2012-06-16 23:41:13 +00:00
parent f327e91a3c
commit 491c4f6d9a
4 changed files with 516 additions and 404 deletions

View file

@ -0,0 +1,443 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.reasoner;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
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.OntProperty;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.JenaException;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
public class ABoxRecomputer {
private static final Log log = LogFactory.getLog(ABoxRecomputer.class);
private OntModel tboxModel; // asserted and inferred TBox axioms
private OntModel aboxModel; // ABox assertions
private Model inferenceModel; // ABox inferences
private Model inferenceRebuildModel; // work area for recomputing all ABox inferences
private Model scratchpadModel; // work area for recomputing all ABox inferences
private SimpleReasoner simpleReasoner;
private Object lock1 = new Object();
private volatile boolean recomputing = false;
private boolean stopRequested = false;
/**
* @param tboxModel - input. This model contains both asserted and inferred TBox axioms
* @param aboxModel - input. This model contains asserted ABox statements
* @param inferenceModel - output. This is the model in which inferred (materialized) ABox statements are maintained (added or retracted).
* @param inferenceRebuildModel - output. This the model is temporarily used when the whole ABox inference model is rebuilt
* @param inferenceScratchpadModel - output. This the model is temporarily used when the whole ABox inference model is rebuilt
*/
public ABoxRecomputer(OntModel tboxModel,
OntModel aboxModel,
Model inferenceModel,
Model inferenceRebuildModel,
Model scratchpadModel,
SimpleReasoner simpleReasoner) {
this.tboxModel = tboxModel;
this.aboxModel = aboxModel;
this.inferenceModel = inferenceModel;
this.inferenceRebuildModel = inferenceRebuildModel;
this.scratchpadModel = scratchpadModel;
this.simpleReasoner = simpleReasoner;
recomputing = false;
stopRequested = false;
}
/**
* Returns true if the recomputer is in the process of recomputing
* all inferences.
*/
public boolean isRecomputing() {
return recomputing;
}
/**
* Recompute all inferences.
*/
public void recompute() {
synchronized (lock1) {
if (recomputing) {
return;
} else {
recomputing = true;
}
}
try {
recomputeABox();
} finally {
synchronized (lock1) {
recomputing = false;
}
}
}
/*
* Recompute the entire ABox inference graph. The new
* inference graph is built in a separate model and
* then reconciled with the inference graph in active
* use. The model reconciliation must be done
* without reading the whole inference models into
* memory in order to support very large ABox
* inference models.
*/
protected void recomputeABox() {
// recompute class subsumption inferences
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
try {
HashSet<String> unknownTypes = new HashSet<String>();
inferenceRebuildModel.removeAll();
log.info("Computing class subsumption ABox inferences.");
int numStmts = 0;
ArrayList<String> individuals = this.getAllIndividualURIs();
for (String individualURI : individuals) {
Resource individual = ResourceFactory.createResource(individualURI);
try {
addedABoxTypeAssertion(individual, inferenceRebuildModel, unknownTypes);
simpleReasoner.setMostSpecificTypes(individual, inferenceRebuildModel, unknownTypes);
StmtIterator sit = aboxModel.listStatements(individual, null, (RDFNode) null);
while (sit.hasNext()) {
Statement s = sit.nextStatement();
for (ReasonerPlugin plugin : simpleReasoner.getPluginList()) {
plugin.addedABoxStatement(s, aboxModel, inferenceRebuildModel, tboxModel);
}
}
} catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
npe.printStackTrace();
return;
} catch (JenaException je) {
if (je.getMessage().equals("Statement models must no be null")) {
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
return;
}
log.error("Exception while recomputing ABox inference model: ", je);
} catch (Exception e) {
log.error("Exception while recomputing ABox inference model: ", e);
}
numStmts++;
if ((numStmts % 10000) == 0) {
log.info("Still computing class subsumption ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
}
}
log.info("Finished computing class subsumption ABox inferences");
log.info("Computing inverse property ABox inferences");
Iterator<Statement> invStatements = null;
tboxModel.enterCriticalSection(Lock.READ);
try {
invStatements = tboxModel.listStatements((Resource) null, OWL.inverseOf, (Resource) null);
} finally {
tboxModel.leaveCriticalSection();
}
numStmts = 0;
while (invStatements.hasNext()) {
Statement stmt = invStatements.next();
try {
OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI());
if (prop1 == null) {
//TODO make sure not to print out a million of these for the same property
log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI());
continue;
}
OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
if (prop2 == null) {
//TODO make sure not to print out a million of these for the same property
log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI());
continue;
}
simpleReasoner.addedInverseProperty(prop1, prop2, inferenceRebuildModel);
} catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
npe.printStackTrace();
return;
} catch (JenaException je) {
if (je.getMessage().equals("Statement models must no be null")) {
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
return;
}
log.error("Exception while recomputing ABox inference model: ", je);
} catch (Exception e) {
log.error("Exception while recomputing ABox inference model: ", e);
}
numStmts++;
if ((numStmts % 10000) == 0) {
log.info("Still computing inverse property ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
}
}
log.info("Finished computing inverse property ABox inferences");
log.info("Computing sameAs ABox inferences");
Iterator<Statement> sameAsStatements = null;
aboxModel.enterCriticalSection(Lock.READ);
try {
sameAsStatements = aboxModel.listStatements((Resource) null, OWL.sameAs, (Resource) null);
} finally {
aboxModel.leaveCriticalSection();
}
numStmts = 0;
while (sameAsStatements.hasNext()) {
Statement stmt = sameAsStatements.next();
try {
simpleReasoner.addedABoxSameAsAssertion(stmt, inferenceRebuildModel);
} catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
npe.printStackTrace();
return;
} catch (JenaException je) {
if (je.getMessage().equals("Statement models must no be null")) {
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
return;
}
log.error("Exception while recomputing ABox inference model: ", je);
} catch (Exception e) {
log.error("Exception while recomputing ABox inference model: ", e);
}
numStmts++;
if ((numStmts % 10000) == 0) {
log.info("Still computing sameAs ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
}
}
log.info("Finished computing sameAs ABox inferences");
try {
if (updateInferenceModel(inferenceRebuildModel)) {
log.info("a stopRequested signal was received during updateInferenceModel. Halting Processing.");
return;
}
} catch (Exception e) {
log.error("Exception while reconciling the current and recomputed ABox inference model for class subsumption inferences. Halting processing." , e);
}
} catch (Exception e) {
log.error("Exception while recomputing ABox inferences. Halting processing.", e);
} finally {
inferenceRebuildModel.removeAll();
inferenceRebuildModel.leaveCriticalSection();
}
}
/*
* Get the URIs for all individuals in the system
*/
protected ArrayList<String> getAllIndividualURIs() {
String queryString = "select distinct ?subject where {?subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type}";
return getIndividualURIs(queryString);
}
protected ArrayList<String> getIndividualURIs(String queryString) {
ArrayList<String> individuals = new ArrayList<String>();
aboxModel.enterCriticalSection(Lock.READ);
try {
try {
Query query = QueryFactory.create(queryString, Syntax.syntaxARQ);
QueryExecution qe = QueryExecutionFactory.create(query, aboxModel);
ResultSet results = qe.execSelect();
while (results.hasNext()) {
QuerySolution solution = results.next();
Resource resource = solution.getResource("subject");
if ((resource != null) && !resource.isAnon()) {
individuals.add(resource.getURI());
}
}
} catch (Exception e) {
log.error("exception while retrieving list of individuals ",e);
}
} finally {
aboxModel.leaveCriticalSection();
}
return individuals;
}
protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
StmtIterator iter = null;
aboxModel.enterCriticalSection(Lock.READ);
try {
iter = aboxModel.listStatements(individual, RDF.type, (RDFNode) null);
while (iter.hasNext()) {
Statement stmt = iter.next();
simpleReasoner.addedABoxTypeAssertion(stmt, inferenceModel, unknownTypes);
}
} finally {
iter.close();
aboxModel.leaveCriticalSection();
}
}
/*
* reconcile a set of inferences into the application inference model
*/
protected boolean updateInferenceModel(Model inferenceRebuildModel) {
log.info("Updating ABox inference model");
StmtIterator iter = null;
// Remove everything from the current inference model that is not
// in the recomputed inference model
int num = 0;
scratchpadModel.enterCriticalSection(Lock.WRITE);
scratchpadModel.removeAll();
try {
inferenceModel.enterCriticalSection(Lock.READ);
try {
iter = inferenceModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
if (!inferenceRebuildModel.contains(stmt)) {
scratchpadModel.add(stmt);
}
num++;
if ((num % 10000) == 0) {
log.info("Still updating ABox inference model (removing outdated inferences)...");
}
if (stopRequested) {
return true;
}
}
} finally {
iter.close();
inferenceModel.leaveCriticalSection();
}
try {
iter = scratchpadModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
inferenceModel.remove(stmt);
} finally {
inferenceModel.leaveCriticalSection();
}
}
} finally {
iter.close();
}
// Add everything from the recomputed inference model that is not already
// in the current inference model to the current inference model.
try {
scratchpadModel.removeAll();
iter = inferenceRebuildModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
inferenceModel.enterCriticalSection(Lock.READ);
try {
if (!inferenceModel.contains(stmt)) {
scratchpadModel.add(stmt);
}
} finally {
inferenceModel.leaveCriticalSection();
}
num++;
if ((num % 10000) == 0) {
log.info("Still updating ABox inference model (adding new inferences)...");
}
if (stopRequested) {
return true;
}
}
} finally {
iter.close();
}
iter = scratchpadModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
inferenceModel.add(stmt);
} finally {
inferenceModel.leaveCriticalSection();
}
}
} finally {
iter.close();
scratchpadModel.removeAll();
scratchpadModel.leaveCriticalSection();
}
log.info("ABox inference model updated");
return false;
}
/**
* This is called when the application shuts down.
*/
public void setStopRequested() {
this.stopRequested = true;
}
}

View file

@ -16,13 +16,6 @@ import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.listeners.StatementListener;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
@ -33,7 +26,6 @@ import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.JenaException;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.vocabulary.OWL;
@ -62,17 +54,18 @@ public class SimpleReasoner extends StatementListener {
private OntModel tboxModel; // asserted and inferred TBox axioms
private OntModel aboxModel; // ABox assertions
private Model inferenceModel; // ABox inferences
private Model inferenceRebuildModel; // work area for re-computing all ABox inferences
private Model scratchpadModel; // work area for re-computing all ABox inferences
private static final String mostSpecificTypePropertyURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#mostSpecificType";
private static final AnnotationProperty mostSpecificType = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createAnnotationProperty(mostSpecificTypePropertyURI);
//TODO check this for thread safety
// DeltaComputer
private CumulativeDeltaModeler aBoxDeltaModeler1 = null;
private CumulativeDeltaModeler aBoxDeltaModeler2 = null;
private volatile boolean batchMode1 = false;
private volatile boolean batchMode2 = false;
private int batchMode = 0; // values: 0, 1 and 2
// Recomputer
private ABoxRecomputer recomputer = null;
private boolean stopRequested = false;
private List<ReasonerPlugin> pluginList = new CopyOnWriteArrayList<ReasonerPlugin>();
@ -84,20 +77,24 @@ public class SimpleReasoner extends StatementListener {
* @param inferenceRebuildModel - output. This the model is temporarily used when the whole ABox inference model is rebuilt
* @param inferenceScratchpadModel - output. This the model is temporarily used when the whole ABox inference model is rebuilt
*/
public SimpleReasoner(OntModel tboxModel, RDFService rdfService, Model inferenceModel,
Model inferenceRebuildModel, Model scratchpadModel) {
public SimpleReasoner(OntModel tboxModel,
RDFService rdfService,
Model inferenceModel,
Model inferenceRebuildModel,
Model scratchpadModel) {
this.tboxModel = tboxModel;
this.aboxModel = ModelFactory.createOntologyModel(
OntModelSpec.OWL_MEM, ModelFactory.createModelForGraph(
new DifferenceGraph(new RDFServiceGraph(rdfService), inferenceModel.getGraph())));
OntModelSpec.OWL_MEM, ModelFactory.createModelForGraph(
new DifferenceGraph(new DifferenceGraph(new RDFServiceGraph(rdfService),inferenceModel.getGraph()),
tboxModel.getGraph())));
this.inferenceModel = inferenceModel;
this.inferenceRebuildModel = inferenceRebuildModel;
this.scratchpadModel = scratchpadModel;
this.batchMode1 = false;
this.batchMode2 = false;
this.batchMode = 0;
aBoxDeltaModeler1 = new CumulativeDeltaModeler();
aBoxDeltaModeler2 = new CumulativeDeltaModeler();
recomputer = new ABoxRecomputer(tboxModel,this.aboxModel,inferenceModel,inferenceRebuildModel,scratchpadModel,this);
stopRequested = false;
if (rdfService == null) {
@ -122,13 +119,11 @@ public class SimpleReasoner extends StatementListener {
this.tboxModel = tboxModel;
this.aboxModel = aboxModel;
this.inferenceModel = inferenceModel;
this.inferenceRebuildModel = ModelFactory.createDefaultModel();
this.scratchpadModel = ModelFactory.createDefaultModel();
aBoxDeltaModeler1 = new CumulativeDeltaModeler();
aBoxDeltaModeler2 = new CumulativeDeltaModeler();
this.batchMode1 = false;
this.batchMode2 = false;
this.batchMode = 0;
stopRequested = false;
recomputer = new ABoxRecomputer(tboxModel,this.aboxModel,inferenceModel,ModelFactory.createDefaultModel(),ModelFactory.createDefaultModel(),this);
}
public void setPluginList(List<ReasonerPlugin> pluginList) {
@ -160,8 +155,7 @@ public class SimpleReasoner extends StatementListener {
} catch (Exception e) {
// don't stop the edit if there's an exception
log.error("Exception while computing inferences: " + e.getMessage());
e.printStackTrace(); //TODO remove this for release
log.error("Exception while computing inferences: ",e);
}
}
@ -174,9 +168,6 @@ public class SimpleReasoner extends StatementListener {
public void removedStatement(Statement stmt) {
try {
// if (!isInterestedInRemovedStatement(stmt)) { return; }
// interested in all of them now that we are doing inverse
// property reasoning
handleRemovedStatement(stmt);
} catch (Exception e) {
@ -191,11 +182,11 @@ public class SimpleReasoner extends StatementListener {
* with DeltaComputer.
*/
protected synchronized void handleRemovedStatement(Statement stmt) {
if (batchMode1) {
if (batchMode == 1) {
aBoxDeltaModeler1.removedStatement(stmt);
} else if (batchMode2) {
} else if (batchMode == 2) {
aBoxDeltaModeler2.removedStatement(stmt);
} else {
} else { // batchMode == 0
if (stmt.getPredicate().equals(RDF.type)) {
removedABoxTypeAssertion(stmt, inferenceModel);
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
@ -349,27 +340,6 @@ public class SimpleReasoner extends StatementListener {
}
}
/*
* This signature used when recomputing the whole ABox
*/
protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
StmtIterator iter = null;
aboxModel.enterCriticalSection(Lock.READ);
try {
iter = aboxModel.listStatements(individual, RDF.type, (RDFNode) null);
while (iter.hasNext()) {
Statement stmt = iter.next();
addedABoxTypeAssertion(stmt, inferenceModel, unknownTypes);
}
} finally {
iter.close();
aboxModel.leaveCriticalSection();
}
}
/*
* Performs incremental reasoning based on a new type assertion
* added to the ABox (assertion that an individual is of a certain
@ -942,8 +912,7 @@ public class SimpleReasoner extends StatementListener {
// Returns true if the triple is entailed by inverse property
// reasoning or sameAs reasoning; otherwise returns false.
protected boolean entailedStatement(Statement stmt) {
//TODO think about checking class subsumption here
//TODO think about checking class subsumption here (for convenience)
// Inverse properties
List<OntProperty> inverses = getInverseProperties(stmt);
@ -1324,345 +1293,29 @@ public class SimpleReasoner extends StatementListener {
* Returns true if the reasoner is in the process of recomputing all
* inferences.
*/
private boolean recomputing = false;
public boolean isRecomputing() {
return recomputing;
}
/**
* Recompute all inferences.
*/
public synchronized void recompute() {
recomputing = true;
try {
recomputeABox();
} finally {
recomputing = false;
}
}
/*
* Recompute the entire ABox inference graph. The new
* inference graph is built in a separate model and
* then reconciled with the inference graph in active
* use. The model reconciliation must be done
* without reading the whole inference models into
* memory in order to support very large ABox
* inference models.
*/
protected synchronized void recomputeABox() {
// recompute class subsumption inferences
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
try {
HashSet<String> unknownTypes = new HashSet<String>();
inferenceRebuildModel.removeAll();
log.info("Computing class subsumption ABox inferences.");
int numStmts = 0;
ArrayList<String> individuals = this.getAllIndividualURIs();
for (String individualURI : individuals) {
Resource individual = ResourceFactory.createResource(individualURI);
try {
addedABoxTypeAssertion(individual, inferenceRebuildModel, unknownTypes);
setMostSpecificTypes(individual, inferenceRebuildModel, unknownTypes);
StmtIterator sit = aboxModel.listStatements(individual, null, (RDFNode) null);
while (sit.hasNext()) {
Statement s = sit.nextStatement();
for (ReasonerPlugin plugin : getPluginList()) {
plugin.addedABoxStatement(s, aboxModel, inferenceRebuildModel, tboxModel);
}
}
} catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
return;
} catch (JenaException je) {
if (je.getMessage().equals("Statement models must no be null")) {
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
return;
}
log.error("Exception while recomputing ABox inference model: ", je);
} catch (Exception e) {
log.error("Exception while recomputing ABox inference model: ", e);
}
numStmts++;
if ((numStmts % 10000) == 0) {
log.info("Still computing class subsumption ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
}
}
log.info("Finished computing class subsumption ABox inferences");
log.info("Computing inverse property ABox inferences");
Iterator<Statement> invStatements = null;
tboxModel.enterCriticalSection(Lock.READ);
try {
invStatements = tboxModel.listStatements((Resource) null, OWL.inverseOf, (Resource) null);
} finally {
tboxModel.leaveCriticalSection();
}
numStmts = 0;
while (invStatements.hasNext()) {
Statement stmt = invStatements.next();
try {
OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI());
if (prop1 == null) {
//TODO make sure not to print out a million of these for the same property
log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI());
continue;
}
OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
if (prop2 == null) {
//TODO make sure not to print out a million of these for the same property
log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI());
continue;
}
addedInverseProperty(prop1, prop2, inferenceRebuildModel);
} catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
return;
} catch (JenaException je) {
if (je.getMessage().equals("Statement models must no be null")) {
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
return;
}
log.error("Exception while recomputing ABox inference model: ", je);
} catch (Exception e) {
log.error("Exception while recomputing ABox inference model: ", e);
}
numStmts++;
if ((numStmts % 10000) == 0) {
log.info("Still computing inverse property ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
}
}
log.info("Finished computing inverse property ABox inferences");
log.info("Computing sameAs ABox inferences");
Iterator<Statement> sameAsStatements = null;
aboxModel.enterCriticalSection(Lock.READ);
try {
sameAsStatements = aboxModel.listStatements((Resource) null, OWL.sameAs, (Resource) null);
} finally {
aboxModel.leaveCriticalSection();
}
numStmts = 0;
while (sameAsStatements.hasNext()) {
Statement stmt = sameAsStatements.next();
try {
addedABoxSameAsAssertion(stmt, inferenceRebuildModel);
} catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
return;
} catch (JenaException je) {
if (je.getMessage().equals("Statement models must no be null")) {
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
return;
}
log.error("Exception while recomputing ABox inference model: ", je);
} catch (Exception e) {
log.error("Exception while recomputing ABox inference model: ", e);
}
numStmts++;
if ((numStmts % 10000) == 0) {
log.info("Still computing sameAs ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
}
}
log.info("Finished computing sameAs ABox inferences");
try {
if (updateInferenceModel(inferenceRebuildModel)) {
log.info("a stopRequested signal was received during updateInferenceModel. Halting Processing.");
return;
}
} catch (Exception e) {
log.error("Exception while reconciling the current and recomputed ABox inference model for class subsumption inferences. Halting processing." , e);
}
} catch (Exception e) {
log.error("Exception while recomputing ABox inferences. Halting processing.", e);
} finally {
inferenceRebuildModel.removeAll();
inferenceRebuildModel.leaveCriticalSection();
}
}
/*
* Get the URIs for all individuals in the system
*/
protected ArrayList<String> getAllIndividualURIs() {
String queryString = "select distinct ?subject where {?subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type}";
return getIndividualURIs(queryString);
}
protected ArrayList<String> getIndividualURIs(String queryString) {
ArrayList<String> individuals = new ArrayList<String>();
aboxModel.enterCriticalSection(Lock.READ);
try {
try {
Query query = QueryFactory.create(queryString, Syntax.syntaxARQ);
QueryExecution qe = QueryExecutionFactory.create(query, aboxModel);
ResultSet results = qe.execSelect();
while (results.hasNext()) {
QuerySolution solution = results.next();
Resource resource = solution.getResource("subject");
if ((resource != null) && !resource.isAnon()) {
individuals.add(resource.getURI());
}
}
} catch (Exception e) {
log.error("exception while retrieving list of individuals ",e);
}
} finally {
aboxModel.leaveCriticalSection();
if (recomputer == null) {
return false;
}
return individuals;
return recomputer.isRecomputing();
}
/*
* reconcile a set of inferences into the application inference model
*/
protected boolean updateInferenceModel(Model inferenceRebuildModel) {
log.info("Updating ABox inference model");
StmtIterator iter = null;
// Remove everything from the current inference model that is not
// in the recomputed inference model
int num = 0;
scratchpadModel.enterCriticalSection(Lock.WRITE);
scratchpadModel.removeAll();
try {
inferenceModel.enterCriticalSection(Lock.READ);
try {
iter = inferenceModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
if (!inferenceRebuildModel.contains(stmt)) {
scratchpadModel.add(stmt);
}
num++;
if ((num % 10000) == 0) {
log.info("Still updating ABox inference model (removing outdated inferences)...");
}
if (stopRequested) {
return true;
}
}
} finally {
iter.close();
inferenceModel.leaveCriticalSection();
public void recompute() {
if (recomputer != null) {
recomputer.recompute();
}
try {
iter = scratchpadModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
inferenceModel.remove(stmt);
} finally {
inferenceModel.leaveCriticalSection();
}
}
} finally {
iter.close();
}
// Add everything from the recomputed inference model that is not already
// in the current inference model to the current inference model.
try {
scratchpadModel.removeAll();
iter = inferenceRebuildModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
inferenceModel.enterCriticalSection(Lock.READ);
try {
if (!inferenceModel.contains(stmt)) {
scratchpadModel.add(stmt);
}
} finally {
inferenceModel.leaveCriticalSection();
}
num++;
if ((num % 10000) == 0) {
log.info("Still updating ABox inference model (adding new inferences)...");
}
if (stopRequested) {
return true;
}
}
} finally {
iter.close();
}
iter = scratchpadModel.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.next();
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
inferenceModel.add(stmt);
} finally {
inferenceModel.leaveCriticalSection();
}
}
} finally {
iter.close();
scratchpadModel.removeAll();
scratchpadModel.leaveCriticalSection();
}
log.info("ABox inference model updated");
return false;
}
/**
* This is called when the application shuts down.
*/
public void setStopRequested() {
if (recomputer != null) {
recomputer.setStopRequested();
}
this.stopRequested = true;
}
@ -1681,7 +1334,7 @@ public class SimpleReasoner extends StatementListener {
* Asynchronous reasoning mode (DeltaComputer) is used in the case of batch removals.
*/
public boolean isABoxReasoningAsynchronous() {
if (batchMode1 || batchMode2) {
if (batchMode > 0) {
return true;
} else {
return false;
@ -1710,9 +1363,7 @@ public class SimpleReasoner extends StatementListener {
log.info("received a bulk update begin event while processing in asynchronous mode. Event count = " + eventCount);
return;
} else {
batchMode1 = true;
batchMode2 = false;
batchMode = 1;
if (aBoxDeltaModeler1.getRetractions().size() > 0) {
log.warn("Unexpected condition: the aBoxDeltaModeler1 retractions model was not empty when entering batch mode.");
}
@ -1738,34 +1389,32 @@ public class SimpleReasoner extends StatementListener {
private synchronized boolean switchBatchModes() {
if (batchMode1) {
if (batchMode == 1) {
aBoxDeltaModeler2.getRetractions().removeAll();
if (aBoxDeltaModeler1.getRetractions().size() > 0) {
batchMode2 = true;
batchMode1 = false;
log.info("entering batch mode 2");
batchMode = 2;
log.info("entering batch mode " + batchMode);
} else {
deltaComputerProcessing = false;
if (eventCount == 0) {
batchMode1 = false;
batchMode = 0;
}
}
} else if (batchMode2) {
} else if (batchMode == 2) {
aBoxDeltaModeler1.getRetractions().removeAll();
if (aBoxDeltaModeler2.getRetractions().size() > 0) {
batchMode1 = true;
batchMode2 = false;
log.info("entering batch mode 1");
batchMode = 1;
log.info("entering batch mode " + batchMode);
} else {
deltaComputerProcessing = false;
if (eventCount == 0) {
batchMode2 = false;
batchMode = 0;
}
}
} else {
log.warn("unexpected condition, invoked when batchMode1 and batchMode2 are both false");
log.warn("unexpected condition, invoked when batchMode is neither 1 nor 2. batchMode = " + batchMode);
deltaComputerProcessing = false;
}
@ -1786,10 +1435,10 @@ public class SimpleReasoner extends StatementListener {
while (deltaComputerProcessing && !stopRequested) {
if (switchBatchModes()) {
if (batchMode1) {
if (batchMode == 1) {
qualifier = "2";
retractions = aBoxDeltaModeler2.getRetractions();
} else if (batchMode2) {
} else if (batchMode == 2) {
qualifier = "1";
retractions = aBoxDeltaModeler1.getRetractions();
}
@ -1853,7 +1502,7 @@ public class SimpleReasoner extends StatementListener {
log.debug("\t--> processed " + num + " statements");
}
log.info("ending DeltaComputer.run. batchMode1 = " + batchMode1 + ", batchMode2 = " + batchMode2);
log.info("ending DeltaComputer.run. batchMode = " + batchMode);
}
}
}

View file

@ -28,6 +28,7 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass {
//Turn off log messages to console
setLoggerLevel(SimpleReasoner.class, Level.OFF);
setLoggerLevel(SimpleReasonerTBoxListener.class, Level.OFF);
setLoggerLevel(ABoxRecomputer.class, Level.OFF);
}
/*
@ -447,6 +448,12 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass {
aBox.add(a,P,b);
aBox.add(c,X,d);
Assert.assertTrue(inf.contains(b,Q,a));
Assert.assertTrue(inf.contains(d,Y,c));
inf.remove(b,Q,a);
inf.remove(d,Y,c);
//recompute whole abox
simpleReasoner.recompute();

View file

@ -35,6 +35,7 @@ public class SimpleReasonerSameAsTest extends AbstractTestClass {
//Turn off log messages to console
setLoggerLevel(SimpleReasoner.class, Level.OFF);
setLoggerLevel(SimpleReasonerTBoxListener.class, Level.OFF);
setLoggerLevel(ABoxRecomputer.class, Level.OFF);
}
/*
@ -675,6 +676,18 @@ public class SimpleReasonerSameAsTest extends AbstractTestClass {
aBox.add(b,T,literal2);
aBox.add(a,OWL.sameAs,b);
Assert.assertTrue(inf.contains(b,OWL.sameAs,a));
Assert.assertTrue(inf.contains(b,P,c));
Assert.assertTrue(inf.contains(b,S,literal1));
Assert.assertTrue(inf.contains(a,Q,d));
Assert.assertTrue(inf.contains(a,T,literal2));
inf.remove(b,OWL.sameAs,a);
inf.remove(b,P,c);
inf.remove(b,S,literal1);
inf.remove(a,Q,d);
inf.remove(a,T,literal2);
simpleReasoner.recompute();
while (simpleReasoner.isRecomputing()) {