142 lines
4.6 KiB
Java
142 lines
4.6 KiB
Java
![]() |
package org.vivoweb.reasoner.plugin;
|
||
|
|
||
|
import org.apache.commons.logging.Log;
|
||
|
import org.apache.commons.logging.LogFactory;
|
||
|
|
||
|
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;
|
||
|
|
||
|
/**
|
||
|
* handles rules of the form
|
||
|
* assertedProp1(?x, ?y) ^ assertedProp2(?y, ?z) -> inferredProp(?x, ?z)
|
||
|
*
|
||
|
* @author bjl23
|
||
|
*
|
||
|
*/
|
||
|
public abstract class SimpleBridgingRule implements ReasonerPlugin {
|
||
|
|
||
|
private static final Log log = LogFactory.getLog(SimpleBridgingRule.class);
|
||
|
|
||
|
private Property assertedProp1;
|
||
|
private Property assertedProp2;
|
||
|
private String queryStr;
|
||
|
|
||
|
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();
|
||
|
tryToInfer(s, aboxAssertionsModel, 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();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
private void tryToInfer(Statement s,
|
||
|
Model aboxAssertionsModel,
|
||
|
Model aboxInferencesModel) {
|
||
|
// this should be part of a superclass or some class that provides
|
||
|
// reasoning framework functions
|
||
|
if (!aboxAssertionsModel.contains(s) && !aboxInferencesModel.contains(s)) {
|
||
|
aboxInferencesModel.add(s);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void removedABoxStatement(Statement stmt,
|
||
|
Model aboxAssertionsModel,
|
||
|
Model aboxInferencesModel,
|
||
|
OntModel TBoxInferencesModel) {
|
||
|
if (ignore(stmt)) {
|
||
|
return;
|
||
|
}
|
||
|
// The following should probably be improved, as it is likely to be
|
||
|
// inefficient.
|
||
|
// The SPARQL query will currently depend on the existence of the triple
|
||
|
// that has just been removed, so we'll union it in temporarily.
|
||
|
// TODO: make the SPARQL query construction smarter.
|
||
|
Model m = ModelFactory.createDefaultModel();
|
||
|
m.add(stmt);
|
||
|
Model union = ModelFactory.createUnion(m, aboxAssertionsModel);
|
||
|
aboxInferencesModel.remove(constructInferences(stmt, union));
|
||
|
}
|
||
|
|
||
|
private boolean isRelevantPredicate(Statement stmt) {
|
||
|
return (assertedProp1.equals(stmt.getPredicate())
|
||
|
|| assertedProp2.equals(stmt.getPredicate()));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|