Repository: incubator-rya Updated Branches: refs/heads/master 35e8634aa -> 5867d545d
RYA-168 initial checkin Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/da8a2e60 Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/da8a2e60 Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/da8a2e60 Branch: refs/heads/master Commit: da8a2e609d942f01bef3b69ec174fcb539fc3159 Parents: 35e8634 Author: pujav65 <[email protected]> Authored: Thu Aug 25 13:40:23 2016 -0400 Committer: pujav65 <[email protected]> Committed: Tue Sep 27 11:21:27 2016 -0400 ---------------------------------------------------------------------- .../src/main/java/MongoRyaDirectExample.java | 140 +++++++++++++------ .../RdfCloudTripleStoreConnection.java | 2 + .../inference/InferenceEngine.java | 138 ++++++++++++++++-- .../inference/PropertyChainVisitor.java | 111 +++++++++++++++ 4 files changed, 336 insertions(+), 55 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/da8a2e60/extras/indexingExample/src/main/java/MongoRyaDirectExample.java ---------------------------------------------------------------------- diff --git a/extras/indexingExample/src/main/java/MongoRyaDirectExample.java b/extras/indexingExample/src/main/java/MongoRyaDirectExample.java index 60b437e..2bc0924 100644 --- a/extras/indexingExample/src/main/java/MongoRyaDirectExample.java +++ b/extras/indexingExample/src/main/java/MongoRyaDirectExample.java @@ -85,9 +85,10 @@ public class MongoRyaDirectExample { testAddNamespaces(conn); testAddPointAndWithinSearch(conn); testAddAndFreeTextSearchWithPCJ(conn); - // to test out inference, set inference to true in the conf + // to test out inference, set inference to true in the conf if (USE_INFER){ testInfer(conn, sail); + testPropertyChainInference(conn, sail); } log.info("TIME: " + (System.currentTimeMillis() - start) / 1000.); @@ -281,49 +282,106 @@ public class MongoRyaDirectExample { } - public static void testAddAndDelete(SailRepositoryConnection conn) throws MalformedQueryException, RepositoryException, - UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException { - - // Add data - String query = "INSERT DATA\n"// - + "{ GRAPH <http://updated/test> {\n"// - + " <http://acme.com/people/Mike> " // - + " <http://acme.com/actions/likes> \"A new book\" ;\n"// - + " <http://acme.com/actions/likes> \"Avocados\" .\n" + "} }"; - - log.info("Performing Query"); - - Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query); - update.execute(); - - query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}"; - CountingResultHandler resultHandler = new CountingResultHandler(); - TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); - tupleQuery.evaluate(resultHandler); - log.info("Result count : " + resultHandler.getCount()); - - Validate.isTrue(resultHandler.getCount() == 2); - - resultHandler.resetCount(); - - // Delete Data - query = "DELETE DATA\n" // - + "{ GRAPH <http://updated/test> {\n" - + " <http://acme.com/people/Mike> <http://acme.com/actions/likes> \"A new book\" ;\n" - + " <http://acme.com/actions/likes> \"Avocados\" .\n" + "}}"; - - update = conn.prepareUpdate(QueryLanguage.SPARQL, query); - update.execute(); - - query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}"; - tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); - tupleQuery.evaluate(resultHandler); - log.info("Result count : " + resultHandler.getCount()); - - Validate.isTrue(resultHandler.getCount() == 0); + UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException { + + // Add data + String query = "INSERT DATA\n"// + + "{ GRAPH <http://updated/test> {\n"// + + " <http://acme.com/people/Mike> " // + + " <http://acme.com/actions/likes> \"A new book\" ;\n"// + + " <http://acme.com/actions/likes> \"Avocados\" .\n" + "} }"; + + log.info("Performing Query"); + + Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query); + update.execute(); + + query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}"; + CountingResultHandler resultHandler = new CountingResultHandler(); + TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); + tupleQuery.evaluate(resultHandler); + log.info("Result count : " + resultHandler.getCount()); + + Validate.isTrue(resultHandler.getCount() == 2); + + resultHandler.resetCount(); + + // Delete Data + query = "DELETE DATA\n" // + + "{ GRAPH <http://updated/test> {\n" + + " <http://acme.com/people/Mike> <http://acme.com/actions/likes> \"A new book\" ;\n" + + " <http://acme.com/actions/likes> \"Avocados\" .\n" + "}}"; + + update = conn.prepareUpdate(QueryLanguage.SPARQL, query); + update.execute(); + + query = "select ?p ?o { GRAPH <http://updated/test> {<http://acme.com/people/Mike> ?p ?o . }}"; + tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); + tupleQuery.evaluate(resultHandler); + log.info("Result count : " + resultHandler.getCount()); + + Validate.isTrue(resultHandler.getCount() == 0); } + public static void testPropertyChainInference(SailRepositoryConnection conn, Sail sail) throws MalformedQueryException, RepositoryException, + UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException, InferenceEngineException { + + // Add data + String query = "INSERT DATA\n"// + + "{ GRAPH <http://updated/test> {\n"// + + " <urn:paulGreatGrandfather> <urn:father> <urn:paulGrandfather> . " + + " <urn:paulGrandfather> <urn:father> <urn:paulFather> . " + + " <urn:paulFather> <urn:father> <urn:paul> . " + + " <urn:paul> <urn:father> <urn:paulSon> . }}"; + + log.info("Performing Query"); + + Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query); + update.execute(); + + query = "select ?p { GRAPH <http://updated/test> {<urn:paulGreatGrandfather> <urn:father>/<urn:father> ?p}}"; + CountingResultHandler resultHandler = new CountingResultHandler(); + TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); + tupleQuery.evaluate(resultHandler); + log.info("Result count : " + resultHandler.getCount()); + + + // try adding a property chain and querying for it + query = "INSERT DATA\n"// + + "{ GRAPH <http://updated/test> {\n"// + + " <urn:greatGrandfather> owl:propertyChainAxiom <urn:1234> . " + + " <urn:1234> <http://www.w3.org/2000/10/swap/list#length> 3 . " + + " <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (0 <urn:father>) . " + + " <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (1 <urn:father>) . " + + " <urn:1234> <http://www.w3.org/2000/10/swap/list#index> (2 <urn:father>) . }}"; + update = conn.prepareUpdate(QueryLanguage.SPARQL, query); + update.execute(); + query = "INSERT DATA\n"// + + "{ GRAPH <http://updated/test> {\n"// + + " <urn:grandfather> owl:propertyChainAxiom <urn:12344> . " + + " <urn:12344> <http://www.w3.org/2000/10/swap/list#length> 2 . " + + " <urn:12344> <http://www.w3.org/2000/10/swap/list#index> (0 <urn:father>) . " + + " <urn:12344> <http://www.w3.org/2000/10/swap/list#index> (1 <urn:father>) . }}"; + update = conn.prepareUpdate(QueryLanguage.SPARQL, query); + update.execute(); + ((RdfCloudTripleStore) sail).getInferenceEngine().refreshGraph(); + + resultHandler.resetCount(); + query = "select ?p { GRAPH <http://updated/test> {<urn:paulGreatGrandfather> <urn:greatGrandfather> ?p}}"; + resultHandler = new CountingResultHandler(); + tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); + tupleQuery.evaluate(resultHandler); + log.info("Result count : " + resultHandler.getCount()); + + resultHandler.resetCount(); + query = "select ?s ?p { GRAPH <http://updated/test> {?s <urn:grandfather> ?p}}"; + resultHandler = new CountingResultHandler(); + tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); + tupleQuery.evaluate(resultHandler); + log.info("Result count : " + resultHandler.getCount()); + + } public static void testInfer(SailRepositoryConnection conn, Sail sail) throws MalformedQueryException, RepositoryException, UpdateExecutionException, QueryEvaluationException, TupleQueryResultHandlerException, InferenceEngineException { http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/da8a2e60/sail/src/main/java/mvm/rya/rdftriplestore/RdfCloudTripleStoreConnection.java ---------------------------------------------------------------------- diff --git a/sail/src/main/java/mvm/rya/rdftriplestore/RdfCloudTripleStoreConnection.java b/sail/src/main/java/mvm/rya/rdftriplestore/RdfCloudTripleStoreConnection.java index 24ec109..048046f 100644 --- a/sail/src/main/java/mvm/rya/rdftriplestore/RdfCloudTripleStoreConnection.java +++ b/sail/src/main/java/mvm/rya/rdftriplestore/RdfCloudTripleStoreConnection.java @@ -50,6 +50,7 @@ import mvm.rya.rdftriplestore.evaluation.RdfCloudTripleStoreSelectivityEvaluatio import mvm.rya.rdftriplestore.evaluation.SeparateFilterJoinsVisitor; import mvm.rya.rdftriplestore.inference.InferenceEngine; import mvm.rya.rdftriplestore.inference.InverseOfVisitor; +import mvm.rya.rdftriplestore.inference.PropertyChainVisitor; import mvm.rya.rdftriplestore.inference.SameAsVisitor; import mvm.rya.rdftriplestore.inference.SubClassOfVisitor; import mvm.rya.rdftriplestore.inference.SubPropertyOfVisitor; @@ -343,6 +344,7 @@ public class RdfCloudTripleStoreConnection extends SailConnectionBase { && this.inferenceEngine != null ) { try { + tupleExpr.visit(new PropertyChainVisitor(queryConf, inferenceEngine)); tupleExpr.visit(new TransitivePropertyVisitor(queryConf, inferenceEngine)); tupleExpr.visit(new SymmetricPropertyVisitor(queryConf, inferenceEngine)); tupleExpr.visit(new InverseOfVisitor(queryConf, inferenceEngine)); http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/da8a2e60/sail/src/main/java/mvm/rya/rdftriplestore/inference/InferenceEngine.java ---------------------------------------------------------------------- diff --git a/sail/src/main/java/mvm/rya/rdftriplestore/inference/InferenceEngine.java b/sail/src/main/java/mvm/rya/rdftriplestore/inference/InferenceEngine.java index 0e2e930..c323892 100644 --- a/sail/src/main/java/mvm/rya/rdftriplestore/inference/InferenceEngine.java +++ b/sail/src/main/java/mvm/rya/rdftriplestore/inference/InferenceEngine.java @@ -1,5 +1,30 @@ package mvm.rya.rdftriplestore.inference; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import java.util.TreeMap; + +import org.openrdf.model.Resource; +import org.openrdf.model.Statement; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.model.impl.StatementImpl; +import org.openrdf.model.impl.ValueFactoryImpl; +import org.openrdf.model.vocabulary.OWL; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.model.vocabulary.RDFS; +import org.openrdf.query.QueryEvaluationException; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -26,25 +51,12 @@ import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Graph; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.tg.TinkerGraphFactory; + import info.aduna.iteration.CloseableIteration; import mvm.rya.api.RdfCloudTripleStoreConfiguration; import mvm.rya.api.persist.RyaDAO; import mvm.rya.api.persist.RyaDAOException; import mvm.rya.api.persist.utils.RyaDAOHelper; -import org.openrdf.model.Resource; -import org.openrdf.model.Statement; -import org.openrdf.model.URI; -import org.openrdf.model.Value; -import org.openrdf.model.impl.StatementImpl; -import org.openrdf.model.vocabulary.OWL; -import org.openrdf.model.vocabulary.RDF; -import org.openrdf.model.vocabulary.RDFS; -import org.openrdf.query.QueryEvaluationException; - -import java.util.*; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; /** * Will pull down inference relationships from dao every x seconds. <br> @@ -66,6 +78,7 @@ public class InferenceEngine { private long refreshGraphSchedule = 5 * 60 * 1000; //5 min private Timer timer; + private HashMap<URI, List<URI>> propertyChainPropertyToChain = new HashMap<URI, List<URI>>(); public static final String URI_PROP = "uri"; public void init() throws InferenceEngineException { @@ -204,6 +217,92 @@ 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); + Map<URI,URI> propertyChainPropertiesToBNodes = new HashMap<URI, URI>(); + propertyChainPropertyToChain = new HashMap<URI, List<URI>>(); + try { + while (iter.hasNext()){ + Statement st = iter.next(); + propertyChainPropertiesToBNodes.put((URI)st.getSubject(), (URI)st.getObject()); + } + } finally { + if (iter != null) { + iter.close(); + } + } + // now for each property chain bNode, get the indexed list of properties associated with that chain + for (URI propertyChainProperty : propertyChainPropertiesToBNodes.keySet()){ + URI bNode = propertyChainPropertiesToBNodes.get(propertyChainProperty); + // query for the list of indexed properties + iter = RyaDAOHelper.query(ryaDAO, bNode, vf.createURI("http://www.w3.org/2000/10/swap/list#index"), + null, conf); + TreeMap<Integer, URI> orderedProperties = new TreeMap<Integer, URI>(); + // TODO refactor this. Wish I could execute sparql + try { + while (iter.hasNext()){ + Statement st = iter.next(); + String indexedElement = st.getObject().stringValue(); + System.out.println(indexedElement); + CloseableIteration<Statement, QueryEvaluationException> iter2 = RyaDAOHelper.query(ryaDAO, vf.createURI(st.getObject().stringValue()), RDF.FIRST, + null, conf); + String integerValue = ""; + Value anonPropNode = null; + Value propURI = null; + if (iter2 != null){ + while (iter2.hasNext()){ + Statement iter2Statement = iter2.next(); + integerValue = iter2Statement.getObject().stringValue(); + break; + } + iter2.close(); + } + iter2 = RyaDAOHelper.query(ryaDAO, vf.createURI(st.getObject().stringValue()), RDF.REST, + null, conf); + if (iter2 != null){ + while (iter2.hasNext()){ + Statement iter2Statement = iter2.next(); + anonPropNode = iter2Statement.getObject(); + break; + } + iter2.close(); + if (anonPropNode != null){ + iter2 = RyaDAOHelper.query(ryaDAO, vf.createURI(anonPropNode.stringValue()), RDF.FIRST, + null, conf); + while (iter2.hasNext()){ + Statement iter2Statement = iter2.next(); + propURI = iter2Statement.getObject(); + break; + } + iter2.close(); + } + } + if (!integerValue.isEmpty() && propURI!=null) { + try { + int indexValue = Integer.parseInt(integerValue); + URI chainPropURI = vf.createURI(propURI.stringValue()); + orderedProperties.put(indexValue, chainPropURI); + } + catch (Exception ex){ + // TODO log an error here + + } + } + } + } finally{ + if (iter != null){ + iter.close(); + } + } + List<URI> properties = new ArrayList<URI>(); + for (Map.Entry<Integer, URI> entry : orderedProperties.entrySet()){ + properties.add(entry.getValue()); + } + propertyChainPropertyToChain.put(propertyChainProperty, properties); + } } catch (QueryEvaluationException e) { throw new InferenceEngineException(e); } @@ -365,6 +464,17 @@ public class InferenceEngine { return subClassOfGraph; } + public Map<URI, List<URI>> getPropertyChainMap() { + return propertyChainPropertyToChain; + } + + public List<URI> getPropertyChain(URI chainProp) { + if (propertyChainPropertyToChain.containsKey(chainProp)){ + return propertyChainPropertyToChain.get(chainProp); + } + return new ArrayList<URI>(); + } + public Graph getSubPropertyOfGraph() { return subPropertyOfGraph; } http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/da8a2e60/sail/src/main/java/mvm/rya/rdftriplestore/inference/PropertyChainVisitor.java ---------------------------------------------------------------------- diff --git a/sail/src/main/java/mvm/rya/rdftriplestore/inference/PropertyChainVisitor.java b/sail/src/main/java/mvm/rya/rdftriplestore/inference/PropertyChainVisitor.java new file mode 100644 index 0000000..06d557f --- /dev/null +++ b/sail/src/main/java/mvm/rya/rdftriplestore/inference/PropertyChainVisitor.java @@ -0,0 +1,111 @@ +package mvm.rya.rdftriplestore.inference; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.openrdf.model.URI; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.model.vocabulary.RDFS; +import org.openrdf.model.vocabulary.SESAME; +import org.openrdf.query.algebra.Join; +import org.openrdf.query.algebra.QueryModelNode; +import org.openrdf.query.algebra.StatementPattern; +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.algebra.Var; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import mvm.rya.api.RdfCloudTripleStoreConfiguration; +import mvm.rya.api.utils.NullableStatementImpl; +import mvm.rya.rdftriplestore.utils.FixedStatementPattern; +import mvm.rya.rdftriplestore.utils.FixedStatementPattern; + +/** + * All predicates are changed + * Class SubPropertyOfVisitor + * Date: Mar 29, 2011 + * Time: 11:28:34 AM + */ +public class PropertyChainVisitor extends AbstractInferVisitor { + + public PropertyChainVisitor(RdfCloudTripleStoreConfiguration conf, InferenceEngine inferenceEngine) { + super(conf, inferenceEngine); + include = true; + } + + + @Override + protected void meetSP(StatementPattern node) throws Exception { + StatementPattern sp = node.clone(); + final Var predVar = sp.getPredicateVar(); + + URI pred = (URI) predVar.getValue(); + String predNamespace = pred.getNamespace(); + + final Var objVar = sp.getObjectVar(); + final Var cntxtVar = sp.getContextVar(); + if (objVar != null && + !RDF.NAMESPACE.equals(predNamespace) && + !SESAME.NAMESPACE.equals(predNamespace) && + !RDFS.NAMESPACE.equals(predNamespace) + && !EXPANDED.equals(cntxtVar)) { + + URI chainPropURI = (URI) predVar.getValue(); + List<URI> chain = inferenceEngine.getPropertyChain(chainPropURI); + List<StatementPattern> expandedPatterns = new ArrayList<StatementPattern>(); + if (chain.size() > 0) { + Var originalSubj = sp.getSubjectVar(); + Var originalObj = sp.getObjectVar(); + + Var nextSubj = originalSubj; + StatementPattern lastStatementPatternAdded = null; + for (URI chainElement : chain ){ + String s = UUID.randomUUID().toString(); + Var currentObj = new Var("c-" + s); + StatementPattern statementPattern = new StatementPattern(nextSubj, new Var(chainElement.stringValue()), currentObj, sp.getContextVar()); + expandedPatterns.add(statementPattern); + lastStatementPatternAdded = statementPattern; + nextSubj = statementPattern.getObjectVar(); + } + lastStatementPatternAdded.setObjectVar(originalObj); + + TupleExpr lastRight = null; + // replace the statement pattern with a series of joins + for (StatementPattern pattern : expandedPatterns){ + if (lastRight == null){ + lastRight = pattern; + } + else { + Join newJoin = new Join(pattern, lastRight); + lastRight = newJoin; + } + System.out.println(pattern); + } + if (lastRight != null){ + node.replaceWith(lastRight); + } + + } + } + } +}
