You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rya.apache.org by ca...@apache.org on 2017/08/16 23:10:11 UTC
incubator-rya git commit: RYA-297 Added owl:equivalentClass
inference. Closes #184.
Repository: incubator-rya
Updated Branches:
refs/heads/master 30475023d -> 85caccf41
RYA-297 Added owl:equivalentClass inference. Closes #184.
If A and B are equivalent classes, then A is a subclass of B and B is a subclass of A. Handled the same way as owl:equivalentProperty.
Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/85caccf4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/85caccf4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/85caccf4
Branch: refs/heads/master
Commit: 85caccf410ac53a8f6b21ef8bab9949cfa21728a
Parents: 3047502
Author: Jesse Hatfield <je...@parsons.com>
Authored: Tue Jul 25 17:08:31 2017 -0400
Committer: Caleb Meier <ca...@parsons.com>
Committed: Wed Aug 16 16:09:13 2017 -0700
----------------------------------------------------------------------
.../inference/InferenceEngine.java | 84 +++++++++-----------
.../inference/SubClassOfVisitor.java | 2 +-
.../inference/InferenceEngineTest.java | 79 ++++++++++++++++++
.../rdftriplestore/inference/InferenceIT.java | 37 +++++++++
4 files changed, 156 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/85caccf4/sail/src/main/java/org/apache/rya/rdftriplestore/inference/InferenceEngine.java
----------------------------------------------------------------------
diff --git a/sail/src/main/java/org/apache/rya/rdftriplestore/inference/InferenceEngine.java b/sail/src/main/java/org/apache/rya/rdftriplestore/inference/InferenceEngine.java
index 2c2ba62..d0ff51b 100644
--- a/sail/src/main/java/org/apache/rya/rdftriplestore/inference/InferenceEngine.java
+++ b/sail/src/main/java/org/apache/rya/rdftriplestore/inference/InferenceEngine.java
@@ -127,22 +127,12 @@ public class InferenceEngine {
public void refreshGraph() throws InferenceEngineException {
ValueFactory vf = ValueFactoryImpl.getInstance();
try {
+ CloseableIteration<Statement, QueryEvaluationException> iter;
//get all subclassof
Graph graph = TinkerGraph.open();
- CloseableIteration<Statement, QueryEvaluationException> iter = RyaDAOHelper.query(ryaDAO, null,
- RDFS.SUBCLASSOF, null, conf);
- try {
- while (iter.hasNext()) {
- String edgeName = RDFS.SUBCLASSOF.stringValue();
- Statement st = iter.next();
- addStatementEdge(graph, edgeName, st);
- }
- } finally {
- if (iter != null) {
- iter.close();
- }
- }
-
+ addPredicateEdges(RDFS.SUBCLASSOF, Direction.OUT, graph, RDFS.SUBCLASSOF.stringValue());
+ //equivalentClass is the same as subClassOf both ways
+ addPredicateEdges(OWL.EQUIVALENTCLASS, Direction.BOTH, graph, RDFS.SUBCLASSOF.stringValue());
// Add unions to the subclass graph: if c owl:unionOf LIST(c1, c2, ... cn), then any
// instances of c1, c2, ... or cn are also instances of c, meaning c is a superclass
// of all the rest.
@@ -189,41 +179,12 @@ public class InferenceEngine {
iter.close();
}
}
-
subClassOfGraph = graph; //TODO: Should this be synchronized?
graph = TinkerGraph.open();
-
- iter = RyaDAOHelper.query(ryaDAO, null,
- RDFS.SUBPROPERTYOF, null, conf);
- try {
- while (iter.hasNext()) {
- String edgeName = RDFS.SUBPROPERTYOF.stringValue();
- Statement st = iter.next();
- addStatementEdge(graph, edgeName, st);
- }
- } finally {
- if (iter != null) {
- iter.close();
- }
- }
-
+ addPredicateEdges(RDFS.SUBPROPERTYOF, Direction.OUT, graph, RDFS.SUBPROPERTYOF.stringValue());
//equiv property really is the same as a subPropertyOf both ways
- iter = RyaDAOHelper.query(ryaDAO, null, OWL.EQUIVALENTPROPERTY, null, conf);
- try {
- while (iter.hasNext()) {
- String edgeName = RDFS.SUBPROPERTYOF.stringValue();
- Statement st = iter.next();
- addStatementEdge(graph, edgeName, st);
- //reverse is also true
- addStatementEdge(graph, edgeName, new StatementImpl((Resource) st.getObject(), st.getPredicate(), st.getSubject()));
- }
- } finally {
- if (iter != null) {
- iter.close();
- }
- }
-
+ addPredicateEdges(OWL.EQUIVALENTPROPERTY, Direction.BOTH, graph, RDFS.SUBPROPERTYOF.stringValue());
subPropertyOfGraph = graph; //TODO: Should this be synchronized?
iter = RyaDAOHelper.query(ryaDAO, null, RDF.TYPE, OWL.SYMMETRICPROPERTY, conf);
@@ -417,6 +378,39 @@ public class InferenceEngine {
}
}
+ /**
+ * Query for all triples involving a given predicate and add corresponding edges to a
+ * {@link Graph} in one or both directions.
+ * @param predicate Find all connections via this predicate URI
+ * @param dir Direction of interest: for a matching triple, if {@link Direction#OUT} add an edge
+ * from subject to object; if {@link Direction#IN} add an edge from object to subject;
+ * if {@link Direction#BOTH} add both.
+ * @param graph A TinkerPop graph
+ * @param edgeName Label that will be given to all added edges
+ * @throws QueryEvaluationException
+ */
+ private void addPredicateEdges(URI predicate, Direction dir, Graph graph, String edgeName)
+ throws QueryEvaluationException {
+ CloseableIteration<Statement, QueryEvaluationException> iter = RyaDAOHelper.query(ryaDAO,
+ null, predicate, null, conf);
+ try {
+ while (iter.hasNext()) {
+ Statement st = iter.next();
+ if (Direction.OUT.equals(dir) || Direction.BOTH.equals(dir)) {
+ addStatementEdge(graph, edgeName, st);
+ }
+ if (Direction.IN.equals(dir) || Direction.BOTH.equals(dir)) {
+ addStatementEdge(graph, edgeName, new StatementImpl((Resource) st.getObject(),
+ st.getPredicate(), st.getSubject()));
+ }
+ }
+ } finally {
+ if (iter != null) {
+ iter.close();
+ }
+ }
+ }
+
private void refreshPropertyRestrictions() throws QueryEvaluationException {
// Get a set of all property restrictions of any type
CloseableIteration<Statement, QueryEvaluationException> iter = RyaDAOHelper.query(ryaDAO, null, OWL.ONPROPERTY, null, conf);
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/85caccf4/sail/src/main/java/org/apache/rya/rdftriplestore/inference/SubClassOfVisitor.java
----------------------------------------------------------------------
diff --git a/sail/src/main/java/org/apache/rya/rdftriplestore/inference/SubClassOfVisitor.java b/sail/src/main/java/org/apache/rya/rdftriplestore/inference/SubClassOfVisitor.java
index 89d3b7b..7fb1b4a 100644
--- a/sail/src/main/java/org/apache/rya/rdftriplestore/inference/SubClassOfVisitor.java
+++ b/sail/src/main/java/org/apache/rya/rdftriplestore/inference/SubClassOfVisitor.java
@@ -68,7 +68,7 @@ public class SubClassOfVisitor extends AbstractInferVisitor {
String s = UUID.randomUUID().toString();
Var typeVar = new Var(s);
FixedStatementPattern fsp = new FixedStatementPattern(typeVar, new Var("c-" + s, RDFS.SUBCLASSOF), objVar, conVar);
- fsp.statements.add(new NullableStatementImpl(subclassof_uri, RDFS.SUBCLASSOF, subclassof_uri));
+ parents.add(subclassof_uri);
for (URI u : parents) {
fsp.statements.add(new NullableStatementImpl(u, RDFS.SUBCLASSOF, subclassof_uri));
}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/85caccf4/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceEngineTest.java
----------------------------------------------------------------------
diff --git a/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceEngineTest.java b/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceEngineTest.java
index 05adbc8..58aeb88 100644
--- a/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceEngineTest.java
+++ b/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceEngineTest.java
@@ -18,6 +18,7 @@ package org.apache.rya.rdftriplestore.inference;
* under the License.
*/
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -86,6 +87,84 @@ public class InferenceEngineTest extends TestCase {
}
@Test
+ public void testSubClassGraph() throws Exception {
+ String insert = "INSERT DATA { GRAPH <http://updated/test> {\n"
+ + " <urn:A> rdfs:subClassOf <urn:C> . \n"
+ + " <urn:B> rdfs:subClassOf <urn:C> . \n"
+ + " <urn:C> rdfs:subClassOf <urn:D> . \n"
+ + " <urn:E> owl:equivalentClass <urn:D> . \n"
+ + " <urn:E> rdfs:subClassOf <urn:G> . \n"
+ + " <urn:Z> a owl:Class . \n"
+ + " <urn:F> owl:equivalentClass <urn:G> . \n"
+ + "}}";
+ conn.prepareUpdate(QueryLanguage.SPARQL, insert).execute();
+ inferenceEngine.refreshGraph();
+ Graph graph = inferenceEngine.getSubClassOfGraph();
+ URI a = vf.createURI("urn:A");
+ URI b = vf.createURI("urn:B");
+ URI c = vf.createURI("urn:C");
+ URI d = vf.createURI("urn:D");
+ URI e = vf.createURI("urn:E");
+ URI f = vf.createURI("urn:F");
+ URI g = vf.createURI("urn:G");
+ URI z = vf.createURI("urn:Z");
+ URI missing = vf.createURI("urn:Missing");
+ Set<URI> empty = new HashSet<>();
+ Set<URI> belowLevel2 = new HashSet<>(Arrays.asList(new URI[] { a, b }));
+ Set<URI> belowLevel3 = new HashSet<>(Arrays.asList(new URI[] { a, b, c, d, e }));
+ Set<URI> belowLevel4 = new HashSet<>(Arrays.asList(new URI[] { a, b, c, d, e, f, g }));
+ Assert.assertEquals(empty, inferenceEngine.findParents(graph, a));
+ Assert.assertEquals(empty, inferenceEngine.findParents(graph, b));
+ Assert.assertEquals(empty, inferenceEngine.findParents(graph, z));
+ Assert.assertEquals(empty, inferenceEngine.findParents(graph, missing));
+ Assert.assertEquals(belowLevel2, inferenceEngine.findParents(graph, c));
+ Assert.assertEquals(belowLevel3, inferenceEngine.findParents(graph, d));
+ Assert.assertEquals(belowLevel3, inferenceEngine.findParents(graph, e));
+ Assert.assertEquals(belowLevel4, inferenceEngine.findParents(graph, f));
+ Assert.assertEquals(belowLevel4, inferenceEngine.findParents(graph, g));
+ }
+
+ @Test
+ public void testSubPropertyGraph() throws Exception {
+ String insert = "INSERT DATA { GRAPH <http://updated/test> {\n"
+ + " <urn:p> rdfs:subPropertyOf <urn:q> . \n"
+ + " <urn:p> rdfs:subPropertyOf <urn:r> . \n"
+ + " <urn:r> owl:equivalentProperty <urn:s> . \n"
+ + " <urn:q> rdfs:subPropertyOf <urn:t> . \n"
+ + " <urn:t> rdfs:subPropertyOf <urn:u> . \n"
+ + " <urn:s> rdfs:subPropertyOf <urn:u> . \n"
+ + " <urn:v> owl:equivalentProperty <urn:u> . \n"
+ + " <urn:w> a owl:FunctionalProperty . \n"
+ + "}}";
+ conn.prepareUpdate(QueryLanguage.SPARQL, insert).execute();
+ inferenceEngine.refreshGraph();
+ Graph graph = inferenceEngine.getSubPropertyOfGraph();
+ URI p = vf.createURI("urn:p");
+ URI q = vf.createURI("urn:q");
+ URI r = vf.createURI("urn:r");
+ URI s = vf.createURI("urn:s");
+ URI t = vf.createURI("urn:t");
+ URI u = vf.createURI("urn:u");
+ URI v = vf.createURI("urn:v");
+ URI w = vf.createURI("urn:w");
+ URI missing = vf.createURI("urn:Missing");
+ Set<URI> empty = new HashSet<>();
+ Set<URI> belowQ = new HashSet<>(Arrays.asList(new URI[] { p }));
+ Set<URI> belowR = new HashSet<>(Arrays.asList(new URI[] { p, r, s }));
+ Set<URI> belowT = new HashSet<>(Arrays.asList(new URI[] { p, q }));
+ Set<URI> belowU = new HashSet<>(Arrays.asList(new URI[] { p, q, r, s, t, u, v }));
+ Assert.assertEquals(empty, inferenceEngine.findParents(graph, p));
+ Assert.assertEquals(empty, inferenceEngine.findParents(graph, w));
+ Assert.assertEquals(empty, inferenceEngine.findParents(graph, missing));
+ Assert.assertEquals(belowQ, inferenceEngine.findParents(graph, q));
+ Assert.assertEquals(belowR, inferenceEngine.findParents(graph, r));
+ Assert.assertEquals(belowR, inferenceEngine.findParents(graph, s));
+ Assert.assertEquals(belowT, inferenceEngine.findParents(graph, t));
+ Assert.assertEquals(belowU, inferenceEngine.findParents(graph, u));
+ Assert.assertEquals(belowU, inferenceEngine.findParents(graph, v));
+ }
+
+ @Test
public void testHasValueGivenProperty() throws Exception {
String insert = "INSERT DATA { GRAPH <http://updated/test> {\n"
+ " <urn:Biped> owl:onProperty <urn:walksUsingLegs> . \n"
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/85caccf4/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceIT.java
----------------------------------------------------------------------
diff --git a/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceIT.java b/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceIT.java
index d3f2faf..6824751 100644
--- a/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceIT.java
+++ b/sail/src/test/java/org/apache/rya/rdftriplestore/inference/InferenceIT.java
@@ -35,6 +35,7 @@ import org.junit.Test;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.model.vocabulary.FOAF;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.QueryResultHandlerException;
@@ -105,6 +106,42 @@ public class InferenceIT extends TestCase {
}
@Test
+ public void testSubClassInferenceQuery() throws Exception {
+ final String ontology = "INSERT DATA { GRAPH <http://updated/test> {\n"
+ + " <urn:Agent> owl:equivalentClass <http://dbpedia.org/ontology/Agent> . \n"
+ + " <urn:Person> rdfs:subClassOf <urn:Agent> . \n"
+ + " [ owl:equivalentClass <http://schema.org/Person> ] rdfs:subClassOf <http://dbpedia.org/ontology/Agent> . \n"
+ + " <" + FOAF.PERSON.stringValue() + "> owl:equivalentClass <http://dbpedia.org/ontology/Person> . \n"
+ + " <" + FOAF.PERSON.stringValue() + "> owl:equivalentClass <urn:Person> . \n"
+ + " <http://dbpedia.org/ontology/Engineer> rdfs:subClassOf <http://dbpedia.org/ontology/Person> . \n"
+ + " <http://dbpedia.org/ontology/Engineer> rdfs:subClassOf <http://example.org/Person> . \n"
+ + " <http://dbpedia.org/ontology/Engineer> owl:equivalentClass <http://www.wikidata.org/entity/Q81096> . \n"
+ + "}}";
+ final String instances = "INSERT DATA { GRAPH <http://updated/test> {\n"
+ + " <urn:Alice> a <http://schema.org/Person> . \n"
+ + " <urn:Bob> a <http://www.wikidata.org/entity/Q81096> . \n"
+ + " <urn:Carol> a <http://example.org/Person> . \n"
+ + " <urn:Dan> a <http://example.org/Engineer> . \n"
+ + " <urn:Eve> a <urn:Agent> . \n"
+ + "}}";
+ final String query = "SELECT ?x { GRAPH <http://updated/test> { ?x a <urn:Agent> } } \n";
+ conn.prepareUpdate(QueryLanguage.SPARQL, ontology).execute();
+ inferenceEngine.refreshGraph();
+ conn.prepareUpdate(QueryLanguage.SPARQL, instances).execute();
+ conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(resultHandler);
+ Set<Value> expected = new HashSet<>();
+ expected.add(vf.createURI("urn:Alice"));
+ expected.add(vf.createURI("urn:Bob"));
+ expected.add(vf.createURI("urn:Eve"));
+ Set<Value> returned = new HashSet<>();
+ for (BindingSet bs : solutions) {
+ returned.add(bs.getBinding("x").getValue());
+ }
+ Assert.assertEquals(expected, returned);
+ Assert.assertEquals(expected.size(), solutions.size());
+ }
+
+ @Test
public void testHasValueTypeQuery() throws Exception {
final String ontology = "INSERT DATA { GRAPH <http://updated/test> {\n"
+ " <urn:Biped> owl:onProperty <urn:walksOnLegs> ; owl:hasValue \"2\"^^<xsd:integer> . \n"