From 61ede29fa7937e11e827f7455a18a333b59dc671 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 21 Sep 2012 16:34:27 +0000 Subject: [PATCH] NIHVIVO-3967 retraction of inferences by SimpleBridgingRule in batch mode and NIHVIVO-3955 batch mode retraction performance improvments for SimpleReasoner --- .../webapp/dao/jena/JenaChangeListener.java | 4 + .../rdfservice/impl/RDFServiceImpl.java | 2 +- .../vitro/webapp/reasoner/SimpleReasoner.java | 174 ++++++++++----- .../reasoner/plugin/SimpleBridgingRule.java | 209 ++++++++++++++++++ .../plugin/SimplePropertyAndTypeRule.java | 137 ++++++++++++ .../reasoner/plugin/SimpleBridgingRule.java | 136 ------------ 6 files changed, 470 insertions(+), 192 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java delete mode 100644 webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java index aaa1af321..2dc022c34 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java @@ -7,6 +7,7 @@ import java.io.UnsupportedEncodingException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.openjena.riot.RiotException; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelChangedListener; @@ -64,6 +65,9 @@ public class JenaChangeListener implements ChangeListener { } return s; } + } catch (RuntimeException riot) { + log.error("Unable to parse triple " + serializedTriple, riot); + throw riot; } catch (UnsupportedEncodingException uee) { throw new RuntimeException(uee); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java index 6b089debd..64d05f844 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java @@ -201,7 +201,7 @@ public abstract class RDFServiceImpl implements RDFService { literalBuff.append("\""); if (node.getLiteralDatatypeURI() != null) { literalBuff.append("^^<").append(node.getLiteralDatatypeURI()).append(">"); - } else if (node.getLiteralLanguage() != null && node.getLiteralLanguage() != "") { + } else if (node.getLiteralLanguage() != null && node.getLiteralLanguage().length() > 0) { literalBuff.append("@").append(node.getLiteralLanguage()); } return literalBuff.toString(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index 0cb91e71b..b12811daf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -6,13 +6,13 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.AnnotationProperty; -import com.hp.hpl.jena.ontology.ConversionException; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; @@ -23,6 +23,7 @@ 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.RDFNode; +import com.hp.hpl.jena.rdf.model.ResIterator; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; @@ -417,13 +418,27 @@ public class SimpleReasoner extends StatementListener { } } + /* + * If it is removed that B is of type A, then for each superclass of A remove + * the inferred statement that B is of that type UNLESS it is otherwise entailed + * that B is of that type. + * + */ + protected void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) { + removedABoxTypeAssertion(stmt, inferenceModel, null); + } + /* * If it is removed that B is of type A, then for each superclass of A remove * the inferred statement that B is of that type UNLESS it is otherwise entailed * that B is of that type. + * + * remainingTypeURIs is an optional list of asserted type URIs for the subject of + * stmt, and may be null. Supplying a precompiled list can yield performance + * improvement when this method is called repeatedly for the same subject. * */ - protected void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) { + protected void removedABoxTypeAssertion(Statement stmt, Model inferenceModel, List remainingTypeURIs) { tboxModel.enterCriticalSection(Lock.READ); try { Resource cls = null; @@ -450,7 +465,8 @@ public class SimpleReasoner extends StatementListener { // of classes not individuals. if (parentClass.isAnon()) continue; - if (entailedType(stmt.getSubject(),parentClass)) { + List typeURIs = (remainingTypeURIs == null) ? getRemainingAssertedTypeURIs(stmt.getSubject()) : remainingTypeURIs; + if (entailedType(stmt.getSubject(),parentClass, typeURIs)) { continue; // if a type is still entailed without the } // removed statement, then don't remove it @@ -882,31 +898,64 @@ public class SimpleReasoner extends StatementListener { } // Returns true if it is entailed by class subsumption that - // subject is of type cls; otherwise returns false. + // subject is of type cls; otherwise returns false. protected boolean entailedType(Resource subject, Resource cls) { - - List sameIndividuals = getSameIndividuals(subject,inferenceModel); - sameIndividuals.add(subject); + return entailedType(subject, cls, null); + } + + // Returns true if it is entailed by class subsumption that + // subject is of type cls; otherwise returns false. + // remainingTypeURIs is an optional list of asserted type URIs for the subject + // resource, and may be null. Supplying a precompiled list can yield performance + // improvement when this method is called repeatedly for the same subject. + protected boolean entailedType(Resource subject, Resource cls, List remainingTypeURIs) { List subClasses = getSubClasses(cls); - aboxModel.enterCriticalSection(Lock.READ); - try { - Iterator iter = subClasses.iterator(); - while (iter.hasNext()) { - Resource childClass = iter.next(); - if (childClass.equals(cls)) continue; - Iterator sameIter = sameIndividuals.iterator(); - while (sameIter.hasNext()) { - Statement stmt = ResourceFactory.createStatement(sameIter.next(), RDF.type, childClass); - if (aboxModel.contains(stmt)) { - return true; - } - } - } - return false; - } finally { - aboxModel.leaveCriticalSection(); - } + Set subClassURIs = new HashSet(); + for (Resource subClass : subClasses) { + if (!subClass.isAnon()) { + subClassURIs.add(subClass.getURI()); + } + } + + List typeURIs = (remainingTypeURIs == null) ? getRemainingAssertedTypeURIs(subject) : remainingTypeURIs; + + for (String typeURI : typeURIs) { + if (!typeURI.equals(cls.getURI()) && subClassURIs.contains(typeURI)) { + return true; + } + } + + return false; + + } + + protected List getRemainingAssertedTypeURIs(Resource resource) { + + List typeURIs = new ArrayList(); + + List sameIndividuals = getSameIndividuals(resource,inferenceModel); + sameIndividuals.add(resource); + + aboxModel.enterCriticalSection(Lock.READ); + try { + Iterator sameIter = sameIndividuals.iterator(); + while (sameIter.hasNext()) { + Resource res = sameIter.next(); + StmtIterator typeIt = aboxModel.listStatements(res, RDF.type, (RDFNode) null); + while (typeIt.hasNext()) { + Statement stmt = typeIt.nextStatement(); + if (stmt.getObject().isURIResource()) { + String typeURI = stmt.getObject().asResource().getURI(); + typeURIs.add(typeURI); + } + } + } + } finally { + aboxModel.leaveCriticalSection(); + } + + return typeURIs; } protected List getSubClasses(Resource cls) { @@ -1555,41 +1604,56 @@ public class SimpleReasoner extends StatementListener { } retractions.enterCriticalSection(Lock.READ); - StmtIterator iter = null; int num = 0; try { log.info("started computing inferences for batch " + qualifier + " updates"); - iter = retractions.listStatements(); - - while (iter.hasNext() && !stopRequested) { - Statement stmt = iter.next(); - num++; - - try { - if (stmt.getPredicate().equals(RDF.type)) { - removedABoxTypeAssertion(stmt, inferenceModel); - } - setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet()); - doPlugins(ModelUpdate.Operation.RETRACT,stmt); - } catch (NullPointerException npe) { - abort = true; - break; - } catch (Exception e) { - log.error("exception in batch mode ",e); - } - - if ((num % 6000) == 0) { - log.info("still computing inferences for batch " + qualifier + " update..."); - } - - if (stopRequested) { - log.info("a stopRequested signal was received during DeltaComputer.run. Halting Processing."); - return; - } - } + + + ResIterator subIt = retractions.listSubjects(); + while (subIt.hasNext()) { + Resource subj = subIt.nextResource(); + StmtIterator iter = retractions.listStatements( + subj, null, (RDFNode) null); + boolean typesModified = false; + try { + List typeURIs = null; + while (iter.hasNext() && !stopRequested) { + Statement stmt = iter.next(); + num++; + try { + if (stmt.getPredicate().equals(RDF.type)) { + typesModified = true; + if (typeURIs == null) { + typeURIs = getRemainingAssertedTypeURIs(stmt.getSubject()); + } + removedABoxTypeAssertion(stmt, inferenceModel, typeURIs); + } + doPlugins(ModelUpdate.Operation.RETRACT,stmt); + } catch (NullPointerException npe) { + abort = true; + break; + } catch (Exception e) { + log.error("exception in batch mode ",e); + } + + if ((num % 6000) == 0) { + log.info("still computing inferences for batch " + qualifier + " update..."); + } + + if (stopRequested) { + log.info("a stopRequested signal was received during DeltaComputer.run. Halting Processing."); + return; + } + } + } finally { + iter.close(); + if (typesModified) { + setMostSpecificTypes(subj, inferenceModel, new HashSet()); + } + } + } } finally { - iter.close(); retractions.removeAll(); retractions.leaveCriticalSection(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java new file mode 100644 index 000000000..974a9bc16 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java @@ -0,0 +1,209 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.reasoner.plugin; + +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.ontology.OntModel; +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.QueryParseException; +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.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.sparql.util.graph.GraphFactory; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.DifferenceGraph; +import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; +import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; + +/** + * handles rules of the form + * assertedProp1(?x, ?y) ^ assertedProp2(?y, ?z) -> inferredProp(?x, ?z) + * + */ +public abstract class SimpleBridgingRule implements ReasonerPlugin { + + private static final Log log = LogFactory.getLog(SimpleBridgingRule.class); + + private Property assertedProp1; + private Property assertedProp2; + private Property inferredProp; + + private String queryStr; + private String retractionTestString; + + private SimpleReasoner simpleReasoner; + + protected SimpleBridgingRule(String assertedProp1, String assertedProp2, String inferredProp) { + this.assertedProp1 = ResourceFactory.createProperty(assertedProp1); + this.assertedProp2 = ResourceFactory.createProperty(assertedProp2); + this.inferredProp = ResourceFactory.createProperty(inferredProp); + + this.queryStr = "CONSTRUCT { \n" + + " ?x <" + inferredProp + "> ?z \n" + + "} WHERE { \n" + + " ?x <" + assertedProp1 + "> ?y . \n" + + " ?y <" + assertedProp2 + "> ?z \n" + + "}"; + + this.retractionTestString = + " ASK { \n" + + " ?x <" + assertedProp1 + "> ?y . \n" + + " ?y <" + assertedProp2 + "> ?z \n" + + " } "; + + } + + public boolean isInterestedInAddedStatement(Statement stmt) { + return isRelevantPredicate(stmt); + } + + public boolean isInterestedInRemovedStatement(Statement stmt) { + return isRelevantPredicate(stmt); + } + + public void addedABoxStatement(Statement stmt, + Model aboxAssertionsModel, + Model aboxInferencesModel, + OntModel TBoxInferencesModel) { + if (ignore(stmt)) { + return; + } + Model inf = constructInferences(this.queryStr, stmt, aboxAssertionsModel); + StmtIterator sit = inf.listStatements(); + while(sit.hasNext()) { + Statement s = sit.nextStatement(); + if (simpleReasoner != null) simpleReasoner.addInference(s,aboxInferencesModel); + } + } + + private boolean ignore(Statement stmt) { + return ( + (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) + // can't deal with blank nodes + || + (!stmt.getObject().isResource()) + // don't deal with literal values + ); + } + + private Query createQuery(String queryString, Statement stmt, Statement statement2) { + String queryStr = new String(queryString); + if (stmt.getPredicate().equals(assertedProp1)) { + queryStr = queryStr.replace( + "?x", "<" + stmt.getSubject().getURI() + ">"); + queryStr = queryStr.replace( + "?y", "<" + ((Resource) stmt.getObject()).getURI() + ">"); + } else if (stmt.getPredicate().equals(assertedProp2)) { + queryStr = queryStr.replace( + "?y", "<" + stmt.getSubject().getURI() + ">"); + queryStr = queryStr.replace( + "?z", "<" + ((Resource) stmt.getObject()).getURI() + ">"); + } else { + // should never be here + return null; + } + if (statement2 != null) { + queryStr = queryStr.replace( + "?x", "<" + stmt.getSubject().getURI() + ">"); + queryStr = queryStr.replace( + "?z", "<" + ((Resource) stmt.getObject()).getURI() + ">"); + } + + if (log.isDebugEnabled()) { + log.debug(queryStr); + } + Query query = null; + try { + query = QueryFactory.create(queryStr); + } catch (QueryParseException e) { + log.error("Unable to parse query for SimpleBridgingRule. \n" + + "This may mean that one of the following URIs is malformed: \n" + + stmt.getSubject() + "\n" + stmt.getObject() + "\n" + ); + log.error(e, e); + throw(e); + } + return query; + } + + private Model constructInferences(String queryString, Statement stmt, Model aboxAssertionsModel) { + Query query = createQuery(queryString, stmt, null); + QueryExecution qe = QueryExecutionFactory.create(query, aboxAssertionsModel); + try { + return qe.execConstruct(); + } finally { + qe.close(); + } + + } + + public void removedABoxStatement(Statement stmt, + Model aboxAssertionsModel, + Model aboxInferencesModel, + OntModel TBoxInferencesModel) { + + if (ignore(stmt)) { + return; + } + + // I initially tried constructing the statements to remove with a single + // SPARQL CONSTRUCT statement, but that didn't seem to perform very well. + // So this first retrieves a list of candidate ?x ?z + // statements, and then runs an ASK query to determine if there are still + // statements ?x ?y and ?y ?z that entail + // the statement in question. If not, the statement is removed. + + // find-based candidate identification + Resource x = null; + RDFNode z = null; + if (stmt.getPredicate().equals(assertedProp1)) { + x = stmt.getSubject(); + } else if (stmt.getPredicate().equals(assertedProp2)) { + z = stmt.getObject(); + } + StmtIterator sit = aboxInferencesModel.listStatements(x, this.inferredProp, z); + + while(sit.hasNext()) { + Statement s = sit.nextStatement(); + Query ask = createQuery(this.retractionTestString, stmt, s); + QueryExecution qe = QueryExecutionFactory.create(ask, aboxAssertionsModel); + try { + if (!qe.execAsk()) { + if (log.isDebugEnabled()) { + log.debug("==> removing " + s); + } + if (simpleReasoner != null) simpleReasoner.removeInference(s,aboxInferencesModel); + } + } finally { + qe.close(); + } + } + } + + private boolean isRelevantPredicate(Statement stmt) { + return (assertedProp1.equals(stmt.getPredicate()) + || assertedProp2.equals(stmt.getPredicate())); + } + + public void setSimpleReasoner(SimpleReasoner simpleReasoner) { + this.simpleReasoner = simpleReasoner; + } + + public SimpleReasoner getSimpleReasoner() { + return this.simpleReasoner; + } +} + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java new file mode 100644 index 000000000..0518bf617 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java @@ -0,0 +1,137 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.reasoner.plugin; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Property; +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.vocabulary.RDF; +import com.hp.hpl.jena.vocabulary.RDFS; + +import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; +import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; + +/** + * handles rules of the form + * assertedProp(?x, ?y) ^ type(?x) -> inferredProp(?x, ?y) + * + * @author bjl23 + * + */ +public abstract class SimplePropertyAndTypeRule implements ReasonerPlugin { + + private Property ASSERTED_PROP; + private Resource TYPE; + private Property INFERRED_PROP; + private SimpleReasoner simpleReasoner; + + protected SimplePropertyAndTypeRule(String assertedProp, String type, String inferredProp) { + TYPE = ResourceFactory.createResource(type); + ASSERTED_PROP = ResourceFactory.createProperty(assertedProp); + INFERRED_PROP = ResourceFactory.createProperty(inferredProp); + } + + public boolean isInterestedInAddedStatement(Statement stmt) { + return (RDF.type.equals(stmt.getPredicate()) || isRelevantPredicate(stmt)); + } + + public boolean isInterestedInRemovedStatement(Statement stmt) { + return (RDF.type.equals(stmt.getPredicate()) || isRelevantPredicate(stmt)); + } + + public void addedABoxStatement(Statement stmt, + Model aboxAssertionsModel, + Model aboxInferencesModel, + OntModel TBoxInferencesModel) { + boolean relevantType = isRelevantType(stmt, TBoxInferencesModel); + boolean relevantPredicate = isRelevantPredicate(stmt); + + if (relevantType) { + StmtIterator stmtIt = aboxAssertionsModel.listStatements( + stmt.getSubject(), ASSERTED_PROP, (RDFNode)null); + while (stmtIt.hasNext()) { + Statement s = stmtIt.nextStatement(); + tryToInfer(stmt.getSubject(), + INFERRED_PROP, + s.getObject(), + aboxAssertionsModel, + aboxInferencesModel); + } + } else if (relevantPredicate) { + if(aboxAssertionsModel.contains( + stmt.getSubject(), RDF.type, TYPE) + || aboxInferencesModel.contains( + stmt.getSubject(), RDF.type, TYPE)) { + tryToInfer(stmt.getSubject(), + INFERRED_PROP, + stmt.getObject(), + aboxAssertionsModel, + aboxInferencesModel); + } + } + } + + private void tryToInfer(Resource subject, + Property predicate, + RDFNode object, + Model aboxAssertionsModel, + Model aboxInferencesModel) { + // this should be part of a superclass or some class that provides + // reasoning framework functions + Statement s = ResourceFactory.createStatement(subject, predicate, object); + if (simpleReasoner != null) { + simpleReasoner.addInference(s,aboxInferencesModel); + } + } + + public void removedABoxStatement(Statement stmt, + Model aboxAssertionsModel, + Model aboxInferencesModel, + OntModel TBoxInferencesModel) { + + if (isRelevantPredicate(stmt)) { +// if (aboxAssertionsModel.contains( +// stmt.getSubject(), RDF.type, BIBO_DOCUMENT) +// || aboxInferencesModel.contains( +// stmt.getSubject(), RDF.type, BIBO_DOCUMENT)) { + if (simpleReasoner != null) { + simpleReasoner.removeInference(ResourceFactory.createStatement(stmt.getSubject(), INFERRED_PROP, stmt.getObject()), aboxInferencesModel); + } +// } + } else if (isRelevantType(stmt, TBoxInferencesModel)) { + if(!aboxInferencesModel.contains( + stmt.getSubject(), RDF.type, TYPE)) { + StmtIterator groundIt = aboxAssertionsModel.listStatements( + stmt.getSubject(), ASSERTED_PROP, (RDFNode) null); + while (groundIt.hasNext()) { + Statement groundStmt = groundIt.nextStatement(); + simpleReasoner.removeInference(ResourceFactory.createStatement(groundStmt.getSubject(), INFERRED_PROP, groundStmt.getObject()), aboxInferencesModel); + } + } + } + } + + private boolean isRelevantType(Statement stmt, Model TBoxInferencesModel) { + return (RDF.type.equals(stmt.getPredicate()) + && (TYPE.equals(stmt.getObject()) + || TBoxInferencesModel.contains( + (Resource) stmt.getObject(), RDFS.subClassOf, TYPE))); + } + + private boolean isRelevantPredicate(Statement stmt) { + return (ASSERTED_PROP.equals(stmt.getPredicate())); + } + + public void setSimpleReasoner(SimpleReasoner simpleReasoner) { + this.simpleReasoner = simpleReasoner; + } + + public SimpleReasoner getSimpleReasoner() { + return this.simpleReasoner; + } +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java deleted file mode 100644 index 5528d6ecd..000000000 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java +++ /dev/null @@ -1,136 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.reasoner.plugin; - -import com.hp.hpl.jena.ontology.OntModel; -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.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; -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 edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; -import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; - -/** - * handles rules of the form - * assertedProp1(?x, ?y) ^ assertedProp2(?y, ?z) -> inferredProp(?x, ?z) - * - */ -public abstract class SimpleBridgingRule implements ReasonerPlugin { - - private Property assertedProp1; - private Property assertedProp2; - private String queryStr; - private SimpleReasoner simpleReasoner; - - protected SimpleBridgingRule(String assertedProp1, String assertedProp2, String inferredProp) { - this.assertedProp1 = ResourceFactory.createProperty(assertedProp1); - this.assertedProp2 = ResourceFactory.createProperty(assertedProp2); - - this.queryStr = "CONSTRUCT { \n" + - " ?x <" + inferredProp + "> ?z \n" + - "} WHERE { \n" + - " ?x <" + assertedProp1 + "> ?y . \n" + - " ?y <" + assertedProp2 + "> ?z \n" + - "}"; - } - - public boolean isInterestedInAddedStatement(Statement stmt) { - return isRelevantPredicate(stmt); - } - - public boolean isInterestedInRemovedStatement(Statement stmt) { - return isRelevantPredicate(stmt); - } - - public void addedABoxStatement(Statement stmt, - Model aboxAssertionsModel, - Model aboxInferencesModel, - OntModel TBoxInferencesModel) { - if (ignore(stmt)) { - return; - } - Model inf = constructInferences(stmt, aboxAssertionsModel); - StmtIterator sit = inf.listStatements(); - while(sit.hasNext()) { - Statement s = sit.nextStatement(); - if (simpleReasoner != null) simpleReasoner.addInference(s,aboxInferencesModel); - } - } - - private boolean ignore(Statement stmt) { - return ( - (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) - // can't deal with blank nodes - || - (!stmt.getObject().isResource()) - // don't deal with literal values - ); - } - - private Model constructInferences(Statement stmt, Model aboxAssertionsModel) { - String queryStr = new String(this.queryStr); - if (stmt.getPredicate().equals(assertedProp1)) { - queryStr = queryStr.replace( - "?x", "<" + stmt.getSubject().getURI() + ">"); - queryStr = queryStr.replace( - "?y", "<" + ((Resource) stmt.getObject()).getURI() + ">"); - } else if (stmt.getPredicate().equals(assertedProp2)) { - queryStr = queryStr.replace( - "?y", "<" + stmt.getSubject().getURI() + ">"); - queryStr = queryStr.replace( - "?z", "<" + ((Resource) stmt.getObject()).getURI() + ">"); - } else { - // should never be here - return ModelFactory.createDefaultModel(); - } - Query query = QueryFactory.create(queryStr); - QueryExecution qe = QueryExecutionFactory.create(query, aboxAssertionsModel); - try { - return qe.execConstruct(); - } finally { - qe.close(); - } - - } - - public void removedABoxStatement(Statement stmt, - Model aboxAssertionsModel, - Model aboxInferencesModel, - OntModel TBoxInferencesModel) { - if (ignore(stmt)) { - return; - } - Model m = ModelFactory.createDefaultModel(); - m.add(stmt); - Model union = ModelFactory.createUnion(m, aboxAssertionsModel); - - Model inf = constructInferences(stmt, union); - StmtIterator sit = inf.listStatements(); - while(sit.hasNext()) { - Statement s = sit.nextStatement(); - if (simpleReasoner != null) simpleReasoner.removeInference(s,aboxInferencesModel); - } - } - - private boolean isRelevantPredicate(Statement stmt) { - return (assertedProp1.equals(stmt.getPredicate()) - || assertedProp2.equals(stmt.getPredicate())); - } - - public void setSimpleReasoner(SimpleReasoner simpleReasoner) { - this.simpleReasoner = simpleReasoner; - } - - public SimpleReasoner getSimpleReasoner() { - return this.simpleReasoner; - } -} -