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 13:41:24 UTC

incubator-rya git commit: RYA-293 Added owl:unionOf inference. Closes #180.

Repository: incubator-rya
Updated Branches:
  refs/heads/master 41c1e9115 -> 637e3ff35


RYA-293 Added owl:unionOf inference. Closes #180.

If A is the union of B and C, then B and C are subclasses of A.


Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/637e3ff3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/637e3ff3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/637e3ff3

Branch: refs/heads/master
Commit: 637e3ff3501608f5879633f1a38e3c8bd1cb3751
Parents: 41c1e91
Author: Jesse Hatfield <je...@parsons.com>
Authored: Thu Jul 20 18:48:24 2017 -0400
Committer: Caleb Meier <ca...@parsons.com>
Committed: Wed Aug 16 06:40:13 2017 -0700

----------------------------------------------------------------------
 .../inference/InferenceEngine.java              | 49 +++++++++++++++++++-
 .../inference/InferenceEngineTest.java          | 31 +++++++++++++
 .../rdftriplestore/inference/InferenceIT.java   | 37 +++++++++++++++
 3 files changed, 116 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/637e3ff3/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 a87dd8d..2c2ba62 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
@@ -125,6 +125,7 @@ public class InferenceEngine {
     }
 
     public void refreshGraph() throws InferenceEngineException {
+        ValueFactory vf = ValueFactoryImpl.getInstance();
         try {
             //get all subclassof
             Graph graph = TinkerGraph.open();
@@ -142,6 +143,53 @@ public class InferenceEngine {
                 }
             }
 
+            // 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.
+            // (In principle, an instance of c is likewise implied to be at least one of the other
+            // types, but this fact is ignored for now to avoid nondeterministic reasoning.)
+            iter = RyaDAOHelper.query(ryaDAO, null, OWL.UNIONOF, null, conf);
+            try {
+                while (iter.hasNext()) {
+                    Statement st = iter.next();
+                    Value unionType = st.getSubject();
+                    // Traverse the list of types constituting the union
+                    Value current = st.getObject();
+                    while (current instanceof Resource && !RDF.NIL.equals(current)) {
+                        Resource listNode = (Resource) current;
+                        CloseableIteration<Statement, QueryEvaluationException> listIter = RyaDAOHelper.query(ryaDAO,
+                                listNode, RDF.FIRST, null, conf);
+                        try {
+                            if (listIter.hasNext()) {
+                                Statement firstStatement = listIter.next();
+                                if (firstStatement.getObject() instanceof Resource) {
+                                    Resource subclass = (Resource) firstStatement.getObject();
+                                    Statement subclassStatement = vf.createStatement(subclass, RDFS.SUBCLASSOF, unionType);
+                                    addStatementEdge(graph, RDFS.SUBCLASSOF.stringValue(), subclassStatement);
+                                }
+                            }
+                        } finally {
+                            listIter.close();
+                        }
+                        listIter = RyaDAOHelper.query(ryaDAO, listNode, RDF.REST, null, conf);
+                        try {
+                            if (listIter.hasNext()) {
+                                current = listIter.next().getObject();
+                            }
+                            else {
+                                current = RDF.NIL;
+                            }
+                        } finally {
+                            listIter.close();
+                        }
+                    }
+                }
+            } finally {
+                if (iter != null) {
+                    iter.close();
+                }
+            }
+
             subClassOfGraph = graph; //TODO: Should this be synchronized?
 
             graph = TinkerGraph.open();
@@ -221,7 +269,6 @@ public class InferenceEngine {
             }
             inverseOfMap = invProp;
             
-            ValueFactory vf = ValueFactoryImpl.getInstance();
             iter = RyaDAOHelper.query(ryaDAO, null, 
             		vf.createURI("http://www.w3.org/2002/07/owl#propertyChainAxiom"),
             		null, conf);

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/637e3ff3/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 f60a1e2..05adbc8 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
@@ -29,6 +29,7 @@ import org.apache.accumulo.core.client.security.tokens.PasswordToken;
 import org.apache.rya.accumulo.AccumuloRdfConfiguration;
 import org.apache.rya.accumulo.AccumuloRyaDAO;
 import org.apache.rya.rdftriplestore.RdfCloudTripleStore;
+import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.junit.After;
 import org.junit.Assert;
 
@@ -115,6 +116,7 @@ public class InferenceEngineTest extends TestCase {
         Assert.assertEquals(typeToValueImplications, inferenceEngine.getHasValueByProperty(vf.createURI("urn:taxon")));
     }
 
+    @Test
     public void testHasValueGivenType() throws Exception {
         String insert = "INSERT DATA { GRAPH <http://updated/test> {\n"
                 + "  <urn:Biped> owl:onProperty <urn:walksUsingLegs>  . \n"
@@ -164,4 +166,33 @@ public class InferenceEngineTest extends TestCase {
         valuesImplyingAnimal.get(taxon).addAll(valuesImplyingTunicate.get(taxon));
         Assert.assertEquals(valuesImplyingAnimal, inferenceEngine.getHasValueByType(vf.createURI("urn:Animal")));
     }
+
+    @Test
+    public void testUnionOf() throws Exception {
+        final String ontology = "INSERT DATA { GRAPH <http://updated/test> {\n"
+                + "  <urn:A> owl:unionOf <urn:list1> . \n"
+                + "  <urn:B> owl:unionOf <urn:list2> . \n"
+                + "  <urn:list1> rdf:first <urn:X> . \n"
+                + "  <urn:list1> rdf:rest <urn:list2> . \n"
+                + "  <urn:list2> rdf:first <urn:Y> . \n"
+                + "  <urn:list2> rdf:rest <urn:list3> . \n"
+                + "  <urn:list3> rdf:first <urn:Z> . \n"
+                + "  <urn:Y> rdfs:subClassOf <urn:SuperY> . \n"
+                + "  <urn:SubY> rdfs:subClassOf <urn:Y> . \n"
+                + "}}";
+        conn.prepareUpdate(QueryLanguage.SPARQL, ontology).execute();
+        inferenceEngine.refreshGraph();
+        Graph subClassGraph = inferenceEngine.getSubClassOfGraph();
+        Set<URI> subClassesA = inferenceEngine.findParents(subClassGraph, vf.createURI("urn:A"));
+        Set<URI> subClassesB = inferenceEngine.findParents(subClassGraph, vf.createURI("urn:B"));
+        Set<URI> expectedA = new HashSet<>();
+        Set<URI> expectedB = new HashSet<>();
+        expectedB.add(vf.createURI("urn:Y"));
+        expectedB.add(vf.createURI("urn:SubY"));
+        expectedB.add(vf.createURI("urn:Z"));
+        expectedA.addAll(expectedB);
+        expectedA.add(vf.createURI("urn:X"));
+        Assert.assertEquals(expectedA, subClassesA);
+        Assert.assertEquals(expectedB, subClassesB);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/637e3ff3/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 c950a3e..d3f2faf 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
@@ -178,4 +178,41 @@ public class InferenceIT extends TestCase {
         expected.add(new ListBindingSet(varNames, vf.createURI("urn:Hank"), vf.createURI("urn:Mammalia")));
         Assert.assertEquals(expected, new HashSet<>(solutions));
     }
+
+    @Test
+    public void testUnionQuery() throws Exception {
+        final String ontology = "INSERT DATA { GRAPH <http://updated/test> {\n"
+                + "  <urn:A> owl:unionOf <urn:list1> . \n"
+                + "  <urn:B> owl:unionOf <urn:list2> . \n"
+                + "  <urn:list1> rdf:first <urn:X> . \n"
+                + "  <urn:list1> rdf:rest <urn:list2> . \n"
+                + "  <urn:list2> rdf:first <urn:Y> . \n"
+                + "  <urn:list2> rdf:rest <urn:list3> . \n"
+                + "  <urn:list3> rdf:first <urn:Z> . \n"
+                + "  <urn:SubY> rdfs:subClassOf <urn:Y> . \n"
+                + "  <urn:Y> rdfs:subClassOf <urn:SuperY> . \n"
+                + "}}";
+        final String instances = "INSERT DATA { GRAPH <http://updated/test> {\n"
+                + "  <urn:Alice> a <urn:X>  . \n"
+                + "  <urn:Bob> a <urn:Y>  . \n"
+                + "  <urn:Carol> a <urn:Z>  . \n"
+                + "  <urn:Dan> a <urn:SuperY>  . \n"
+                + "  <urn:Eve> a <urn:SubY>  . \n"
+                + "}}";
+        final String query = "SELECT ?x { GRAPH <http://updated/test> { ?x a <urn:B> } } \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:Bob"));
+        expected.add(vf.createURI("urn:Carol"));
+        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());
+    }
 }