diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core/SQueryRecommendationWorker.java b/squire/src/main/java/uk/ac/open/kmi/squire/core/SQueryRecommendationWorker.java deleted file mode 100644 index c15bc91..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core/SQueryRecommendationWorker.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package uk.ac.open.kmi.squire.core; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.QueryParseException; - -import uk.ac.open.kmi.squire.operation.SPARQLQuerySatisfiable; -import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; -import uk.ac.open.kmi.squire.treequerypatterns.QueryRecommendation; - -/** - * - * @author callocca - */ -public class SQueryRecommendationWorker implements IQueryRecommendation, Runnable { - - private String queryString; - private IRDFDataset rdfd1; - private IRDFDataset rdfd2; - - public SQueryRecommendationWorker(String qString, IRDFDataset d1, IRDFDataset d2) { - queryString = qString; - rdfd1 = d1; - rdfd2 = d2; - - } - - // public List queryRecommendation(String querySPARQL) { - @Override - public List queryRecommendation() { - - // //Step 1. Computing the query template. - // System.out.println("[SQueryRecommendationWorker, queryRecommendation()]We are - // processing the query " + this.queryString); - // IQueryTemplate qT = new SelectQueryTemplate(queryString, rdfd1, rdfd2); - // Query qt = qT.generateQueryTemplate(); - // System.out.println("[SQueryRecommendationWorker::queryRecommendation()] This - // is the query Template" + qt); - // - // //Step 2. Computing the query template. - return null; - } - - // public List queryRecommendation1() { - // - // //System.out.println("[SQueryRecommendationWorker, queryRecommendation()]We - // are processing the query " + this.queryString); - // // From a String to a SPARQL query Object - // System.out.println(" "); - // Query query = QueryFactory.create(queryString); - // System.out.println(" "); - // - // System.out.println("[SQueryRecommendationWorker, queryRecommendation()]We are - // processing the query "); - // System.out.println(query); - // System.out.println(" "); - // - // // Identify the Group Graph Patterns - // ElementPathBlockVisitor epb = new ElementPathBlockVisitor(); - // ElementWalker.walk(query.getQueryPattern(), epb); - // System.out.println(" "); - // System.out.println("[SQueryRecommendationWorker, queryRecommendation()] which - // has got the following list of triple patterns "); - // System.out.println(epb.getElementPathBlock()); - // List tpList = epb.getElementPathBlock().getPattern().getList(); - // - // TreeNode> root = new TreeNode(tpList, null); - // - // //QTTree qttree=new QTTree(root, rdfd1, rdfd2); - // QTTree qttree = new QTTree(queryString, root, rdfd1, rdfd2); - // qttree.generateQTTree(root); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // qttree.evaluateQTTree(qttree.getRoot(), 0);//evaluateQTTree - // - // //IQueryTemplate qT = new SelectQueryTemplate(queryString, rdfd1, rdfd2); - // //Query qt = qT.generateQueryTemplate(); - // //System.out.println("[SQueryRecommendationWorker::queryRecommendation()] - // This is the query Template" + qt); - // //Step 2. Computing the query template. - // return null; - // } - - // this is working with TreeNode> - // public List queryRecommendation2() { - // - // //System.out.println("[SQueryRecommendationWorker, queryRecommendation()]We - // are processing the query " + this.queryString); - // // From a String to a SPARQL query Object - // System.out.println(" "); - // Query query = QueryFactory.create(queryString); - // System.out.println(" "); - // - // System.out.println("[SQueryRecommendationWorker, queryRecommendation()]We are - // processing the query "); - // System.out.println(query); - // System.out.println(" "); - // - // // Identify the Group Graph Patterns - // ElementPathBlockVisitor epb = new ElementPathBlockVisitor(); - // ElementWalker.walk(query.getQueryPattern(), epb); - // System.out.println(" "); - // System.out.println("[SQueryRecommendationWorker, queryRecommendation()] which - // has got the following list of triple patterns "); - // System.out.println(epb.getElementPathBlock()); - // List tpList = epb.getElementPathBlock().getPattern().getList(); - // - // TreeNode> root = new TreeNode(tpList, null); - // - // //QTTree qttree=new QTTree(root, rdfd1, rdfd2); - // QTTree qttree = new QTTree(queryString, root, rdfd1, rdfd2); - // //qttree.generateQTTree(root); - // - // // GENRALIZE - // qttree.generalizeToQueryTemplate(); - // - // // building the tree of specialize queries. - // //qttree.specializeToQueryInstance(qttree.getRootTemplate()); - // HashMap parentPTMap = new HashMap(); - // HashMap parentCTMap = new HashMap(); - // - //// System.out.println("1111111111111111111 - // "+rdfd2.getPropertySet().toString()); - //// System.out.println("2222222222222222222 "+rdfd2.getClassSet().toString()); - // // SPECIALIZE - //// qttree.specializeToQueryInstance1(qttree.getRootTemplate(), - // qttree.specializeToQueryInstance4(qttree.getRootTemplate(), - // rdfd2.getPropertySet(), parentPTMap, - // rdfd2.getClassSet(), parentCTMap); - // - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - //// qttree.evaluateQTTree(qttree.getRoot(), 0);//evaluateQTTree - // qttree.printQTTree(qttree.getRootTemplate(), 0);//evaluateQTTree - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // - // qttree.evaluateQTTree(qttree.getRootTemplate(), 0);//evaluateQTTree - // - // return null; - // } - - // This is working with TreeNode, but does not manage the removal - // operation. - // public List queryRecommendation3() { - // - // List resultQueryList=new ArrayList(); - // - // Query query; - // //...checking if the input query is parsable.... - // try { - // query = QueryFactory.create(queryString); - // } catch (org.apache.jena.query.QueryParseException ex) { - // //QueryParseException - // throw new - // QueryParseException("[SQueryRecommendationWorker::queryRecommendation3] The - // input query is not parsable!!!", -1, -1); - // } - // //...checking if the input query is satisfiable w.r.t. D1 .... - // SPARQLQuerySatisfiable qs = new SPARQLQuerySatisfiable(); - // if (qs.isSatisfiable(query, rdfd1)) { - // System.out.println(query); - // System.out.println(" "); - // - // QueryRecommendation qr = new QueryRecommendation(query, rdfd1, rdfd2); - // //... generalizing the input query into a SPARLQ Template Query .... - // qr.generalizeToQueryTemplate(); - // - // - // //... generalizing the input query into a SPARLQ Template Query .... - // qr.specializeToQueryInstance(); - // - // - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" /////////////////////// PRINTING THE TREE - // ///////////////"); - // System.out.println(" "); - // System.out.println(" "); - // - // - // qr.printQueryTemplateTree1(qr.getRootTemplate(), - // 0);//.printQueryTemplateTree(qr.getRootTemplate(), 0);//evaluateQTTree - // - // - // } else { - // System.out.println("[SQueryRecommendationWorker::queryRecommendation3]The - // input query is not satisfiable w.r.t the input dataset... "); - // } - // - //// // building the tree of specialize queries. - //// //qttree.specializeToQueryInstance(qttree.getRootTemplate()); - //// HashMap parentPTMap=new HashMap(); - //// HashMap parentCTMap=new HashMap(); - //// - //// // SPECIALIZE - ////// qttree.specializeToQueryInstance1(qttree.getRootTemplate(), - //// qrtree.specializeToQueryInstance4(qttree.getRootTemplate(), - //// rdfd2.getPropertySet(), parentPTMap, - //// rdfd2.getClassSet(),parentCTMap); - //// - //// - //// - // - //// System.out.println(" "); - //// System.out.println(" "); - //// System.out.println(" "); - //// System.out.println(" "); - //// System.out.println(" "); - ////// qttree.evaluateQTTree(qttree.getRoot(), 0);//evaluateQTTree - //// qttree.printQTTree(qttree.getRootTemplate(), 0);//evaluateQTTree - //// System.out.println(" "); - //// System.out.println(" "); - //// System.out.println(" "); - //// System.out.println(" "); - //// System.out.println(" "); - //// System.out.println(" "); - //// - //// qttree.evaluateQTTree(qttree.getRootTemplate(), 0);//evaluateQTTree - // return resultQueryList; - // } - - // This is UNDER DEVELOPMENTS and working with TreeNode, we are going - // to include the management of the removal operation too. - // public List queryRecommendation4() { - // - // List resultQueryList=new ArrayList(); - // Query query; - // //...checking if the input query is parsable.... - // try { - // query = QueryFactory.create(queryString); - // } catch (org.apache.jena.query.QueryParseException ex) { - // //QueryParseException - // throw new - // QueryParseException("[SQueryRecommendationWorker::queryRecommendation4] The - // input query is not parsable!!!", -1, -1); - // } - // //...checking if the input query is satisfiable w.r.t. D1 .... - // SPARQLQuerySatisfiable qs = new SPARQLQuerySatisfiable(); - // if (qs.isSatisfiable(query, rdfd1)) { - // //System.out.println(query); - // //System.out.println(" "); - // - // System.out.println(" "); - // System.out.println("[SQueryRecommendationWorker::queryRecommendation4] - // Original Query "); - // System.out.println(query.toString()); - // - // QueryRecommendation qr = new QueryRecommendation(query, rdfd1, rdfd2); - // //... generalizing the input query into a SPARLQ Template Query .... - // qr.generalizeToQueryTemplate(); - // - // - // //... generalizing the input query into a SPARLQ Template Query .... - // //qr.specializeToQueryInstance(); - // - // System.out.println(" "); - // System.out.println("[SQueryRecommendationWorker::queryRecommendation4] We are - // specializing the input query ... "); - // qr.specializeToQueryInstance1(); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" "); - // System.out.println(" /////////////////////// PRINTING THE TREE - // ///////////////"); - // System.out.println(" "); - // System.out.println(" "); - // qr.printQueryTemplateTree1(qr.getRootTemplate(), 0); - // - // - // } else { - // System.out.println("[SQueryRecommendationWorker::queryRecommendation4]The - // input query is not satisfiable w.r.t the input dataset... "); - // } - // - // return resultQueryList; - // } - - // This is UNDER DEVELOPMENTS and working with TreeNode, we are going - // to include the management of the removal operation too. - public List queryRecommendation5() { - - List resultQueryList = new ArrayList(); - Query query; - // ...checking if the input query is parsable.... - try { - query = QueryFactory.create(queryString); - System.out.println(""); - System.out.println("[SQueryRecommendationWorker::queryRecommendation5] THE SOURCE QUERY "); - System.out.println(""); - System.out.println(query.toString()); - } catch (org.apache.jena.query.QueryParseException ex) { // QueryParseException - throw new QueryParseException( - "[SQueryRecommendationWorker::queryRecommendation5] THE SOURCE QUERY is not parsable!!!", -1, -1); - } - // ...checking if the input query is satisfiable w.r.t. D1 .... - SPARQLQuerySatisfiable qs = new SPARQLQuerySatisfiable(); - if (qs.isSatisfiable(query, rdfd1)) { - - QueryRecommendation qr = new QueryRecommendation(query, rdfd1, rdfd2); - // ... generalizing the input query into a SPARLQ Template Query .... - qr.generalizeToQueryTemplate(); - - System.out.println(" "); - System.out.println( - "[SQueryRecommendationWorker::queryRecommendation5] We are specializing the input query ... "); - qr.specializeToQueryInstance1(); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - - qr.computeRecommendateQueryScore(qr.getRootTemplate(), 0); - // sort the result list - Collections.sort(qr.getQueryRecommendatedList(), QueryScorePair.queryScoreComp); - - return qr.getQueryRecommendatedList(); - } else { - System.out.println( - "[SQueryRecommendationWorker::queryRecommendation5]The input query is not satisfiable w.r.t the input dataset... "); - } - - return resultQueryList; - } - - @Override - public void run() { - // this.queryRecommendation(); - // this.queryRecommendation1(); - } - - @Override - public List queryRecommendation(String querySPARQL, IRDFDataset d1, IRDFDataset d2) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public List queryRecommendation(String querySPARQL) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryAndContextNode.java b/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryAndContextNode.java index 3b0204d..541b622 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryAndContextNode.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryAndContextNode.java @@ -8,13 +8,9 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Map; -import java.util.Set; import org.apache.jena.query.Query; import org.apache.jena.query.QuerySolution; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.sparql.core.Var; import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; @@ -36,43 +32,37 @@ public int compare(QueryAndContextNode p1, QueryAndContextNode p2) { float score2 = p2.getqRScore(); // ...For ascending order return Float.compare(score2, score1); - // return (-1)*Float.compare(score1, score2); // For discending order + // return -1*Float.compare(score1, score2); // For descending order } } - private String entityqO, entityqR; + private IRDFDataset ds1, ds2; - // private Set qRTemplateVariableSet; - // private Set qRTriplePathSet; - - private String op; // It can be either R (for Removal) or I (Instantiation). + private String op; private Query qO, qR; private float qRScore; - - private float queryResultSizeSimilarity; - private float queryResultTypeSimilarity; private float queryRootDistance; - private float queryRootDistanceSim; private float querySpecificityDistance; private List queryTempVarSolutionSpace; - private Map> queryTempVarValueMap; - - private IRDFDataset rdfD1, rdfD2; - - public String getEntityqO() { - return entityqO; + public IRDFDataset getDataset1() { + return ds1; } - public String getEntityqR() { - return entityqR; + public IRDFDataset getDataset2() { + return ds2; } - public String getOp() { + /** + * It can be either R (for Removal) or I (Instantiation). + * + * @return + */ + public String getLastOperation() { return op; } @@ -84,22 +74,10 @@ public float getqRScore() { return qRScore; } - public float getQueryResultSizeSimilarity() { - return queryResultSizeSimilarity; - } - - public float getQueryResultTypeSimilarity() { - return queryResultTypeSimilarity; - } - public float getQueryRootDistance() { return queryRootDistance; } - public float getQueryRootDistanceSimilarity() { - return queryRootDistanceSim; - } - public float getQuerySpecificityDistance() { return querySpecificityDistance; } @@ -108,28 +86,16 @@ public List getQueryTempVarSolutionSpace() { return queryTempVarSolutionSpace; } - public Map> getQueryTempVarValueMap() { - return queryTempVarValueMap; - } - - public IRDFDataset getRdfD1() { - return rdfD1; - } - - public IRDFDataset getRdfD2() { - return rdfD2; - } - public Query getTransformedQuery() { return qR; } - public void setEntityqO(String entityqO) { - this.entityqO = entityqO; + public void setDataset1(IRDFDataset rdfD1) { + this.ds1 = rdfD1; } - public void setEntityqR(String entityqR) { - this.entityqR = entityqR; + public void setDataset2(IRDFDataset rdfD2) { + this.ds2 = rdfD2; } public void setOp(String op) { @@ -144,38 +110,14 @@ public void setqRScore(float qRScore) { this.qRScore = qRScore; } - public void setQueryResultSizeSimilarity(float queryResultSizeSimilarity) { - this.queryResultSizeSimilarity = queryResultSizeSimilarity; - } - - public void setQueryResultTypeSimilarity(float queryResultTypeSimilarity) { - this.queryResultTypeSimilarity = queryResultTypeSimilarity; - } - public void setQueryRootDistance(float queryRootDistance) { this.queryRootDistance = queryRootDistance; } - public void setQueryRootDistanceSimilarity(float queryRootDistance) { - this.queryRootDistanceSim = queryRootDistance; - } - public void setQuerySpecificityDistance(float querySpecificityDistance) { this.querySpecificityDistance = querySpecificityDistance; } - public void setQueryTempVarValueMap(Map> queryTempVarValueMap) { - this.queryTempVarValueMap = queryTempVarValueMap; - } - - public void setRdfD1(IRDFDataset rdfD1) { - this.rdfD1 = rdfD1; - } - - public void setRdfD2(IRDFDataset rdfD2) { - this.rdfD2 = rdfD2; - } - public void setSolutionSpace(List queryTempVarSolutionSpace) { if (queryTempVarSolutionSpace == null) this.queryTempVarSolutionSpace = new ArrayList<>(); else this.queryTempVarSolutionSpace = queryTempVarSolutionSpace; diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryTempVarSolutionSpace.java b/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryTempVarSolutionSpace.java index cde216f..f8983e8 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryTempVarSolutionSpace.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core2/QueryTempVarSolutionSpace.java @@ -7,19 +7,25 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import org.apache.jena.atlas.json.JsonParseException; import org.apache.jena.graph.Node; import org.apache.jena.query.Query; import org.apache.jena.query.QueryFactory; import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.QuerySolutionMap; +import org.apache.jena.rdf.model.RDFNode; import org.apache.jena.sparql.core.TriplePath; import org.apache.jena.sparql.core.Var; +import org.apache.jena.sparql.resultset.ResultSetException; import org.apache.jena.sparql.syntax.Element; import org.apache.jena.sparql.syntax.ElementGroup; import org.apache.jena.sparql.syntax.ElementPathBlock; @@ -78,31 +84,48 @@ public Query getQuery() { */ public List computeTempVarSolutionSpace(Query qChild, IRDFDataset rdfd2, Var... projectToThese) throws TooGeneralException { - List qTsol; + List qTsol = new ArrayList<>(); // Defer the check for template variables to the templatizeAndReduce() function. + String res = null; + Query qT = qChild; try { // 1. Transform the query qChild so that only template variables are projected. - Query qT = templatizeAndReduce(qChild, projectToThese); + qT = templatizeAndReduce(qChild, projectToThese); // 1a. Check if the resulting query is not too general to be executed. checkGenerality(qT); // 2. Compute the solution space for the templated (and possibly reduced) query. log.debug("Computing solution space for subquery:"); log.debug("{}", qT); - String res = SparqlUtils.doRawQuery(qT.toString(), rdfd2.getEndPointURL().toString()); + res = SparqlUtils.doRawQuery(qT.toString(), rdfd2.getEndPointURL().toString()); qTsol = SparqlUtils.extractProjectedValues(res, qT.getProjectVars()); - // 2a. Re-expand the solution space to include the variables that were reduced + } catch (SparqlException | JsonParseException ex) { + if (ex instanceof SparqlException) log.error("Connection failed while checking solution space.", ex); + else if (ex instanceof JsonParseException) { + log.error("Solution space result size is not valid JSON. Content follows:"); + log.error("{}", res); + } + log.error("Falling back to paginated querying."); + final Set> fallbackSol = new HashSet<>(); + computeSolutionSpacePaginated(qT, rdfd2, 0, 100, fallbackSol); + log.debug("Fallback procedure computed {} solutions", fallbackSol.size()); + for (Map sol : fallbackSol) { + QuerySolutionMap qs = new QuerySolutionMap(); + for (Entry entry : sol.entrySet()) + qs.add(entry.getKey(), entry.getValue()); + qTsol.add(qs); + log.trace("Added {}", qs); + } + log.debug("Templated solution size now = {}", qTsol.size()); + } catch (NotTemplatedException ex) { + log.error("Apparently the query has no template variables."); + log.error("Assuming empty solution space."); + qTsol = Collections.emptyList(); + } finally { + // 2a. Re-expand the solutions space to include the variables that were reduced // earlier. Map> diocane = filter(reductions, qT.getProjectVars().toArray(new Var[0])); qTsol = SparqlUtils.inflateResultSet(qTsol, diocane); log.debug(" ... Solution space size = {} ", qTsol.size()); - } catch (SparqlException ex) { - log.error("Connection failed while checking solution space.", ex); - log.error("Assuming empty solution space."); - qTsol = new ArrayList<>(); - } catch (NotTemplatedException ex) { - log.error("Apparently the query has no template variables."); - log.error("Assuming empty solution space."); - qTsol = new ArrayList<>(); } return qTsol; } @@ -253,4 +276,61 @@ private void keep(TriplePath tp, ElementPathBlock pathBlock) throws NotTemplated return qT; } + protected void computeSolutionSpacePaginated(Query baseQuery, IRDFDataset dataset, int step, int stepLength, + final Set> solutions) { + if (stepLength <= 0) throw new IllegalArgumentException("Step length must be a positive integer."); + long before = System.currentTimeMillis(); + Query paginatedQuery = QueryFactory.create(baseQuery); + paginatedQuery.setLimit(stepLength); + paginatedQuery.setOffset(step * stepLength); + String res = ""; + boolean error = false; + try { + res = SparqlUtils.doRawQuery(paginatedQuery.toString(), dataset.getEndPointURL().toString()); + List items = SparqlUtils.extractProjectedValues(res, paginatedQuery.getProjectVars()); + boolean doAgain = false; + if (items.size() > 0) { + int added = 0; + // Inspect for new bindings: if at least one is found, do another round (rhyme + // unintentional) + for (QuerySolution sol : items) { + QuerySolutionMap solMap; + if (sol instanceof QuerySolutionMap) solMap = (QuerySolutionMap) sol; + else { + solMap = new QuerySolutionMap(); + solMap.addAll(sol); + } + Map mapSol = solMap.asMap(); + if (!solutions.contains(mapSol)) { + solutions.add(mapSol); + added++; + doAgain = true; + } + } + log.debug("Added {} new solutions (time={} ms)", added, System.currentTimeMillis() - before); + } else log.debug("No new solutions, stopping at size {}", solutions.size()); + doAgain &= items.size() == stepLength; + if (doAgain) computeSolutionSpacePaginated(baseQuery, dataset, step + 1, stepLength, solutions); + } catch (SparqlException ex) { + log.error("Query failed.", ex); + error = true; + } catch (JsonParseException ex) { + log.error("Malformed JSON returned at index ({},{}).", ex.getLine(), ex.getColumn()); + log.error("Content follows:\r\n{}", res); + log.error("Stopping iteration and keeping previous results."); + error = true; + } catch (ResultSetException ex) { + log.error("Returned JSON does not seem to be a SPARQL result set. Reason: {}", ex.getMessage()); + log.error("Content follows:\r\n{}", res); + error = true; + } catch (Exception ex) { + log.error("An unthought-of error occurred. Check exception trace", ex); + error = true; + } + if (error) { + log.error("Failing query follows:\r\n{}", paginatedQuery); + log.error("Stopping iteration and keeping previous results."); + } + } + } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/AbstractQueryRecommendationObservable.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/AbstractQueryRecommendationObservable.java index f71d0f7..6146e6f 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core4/AbstractQueryRecommendationObservable.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/AbstractQueryRecommendationObservable.java @@ -32,46 +32,26 @@ public void unregister(IQueryRecommendationObserver o) { @Override public void notifyQueryRecommendation(Query qR, float score) { - for (IQueryRecommendationObserver obs : observers) { + for (IQueryRecommendationObserver obs : observers) obs.updateQueryRecommendated(qR, score, token); - } } @Override public void notifyQuerySatisfiableValue(Query query, boolean value) { - for (IQueryRecommendationObserver observer : observers) { - System.out.println("[AbstractQueryRecommendationObservable::notifyQuerySatisfiableValue] value:" + value); + for (IQueryRecommendationObserver observer : observers) observer.updateSatisfiableValue(query, value, token); - } - // - // if(value){ - // for (IQueryRecommendationObserver observer : observers) { - // System.out.println("[AbstractQueryRecommendationObservable::notifyQuerySatisfiableValue] - // The input query is satisfiable w.r.t. D2"); - // observer.updateSatisfiableMessage("[AbstractQueryRecommendationObservable::notifyQuerySatisfiableValue] - // The input query is satisfiable w.r.t. D2", token); - // } - // } - // else{ - // for (IQueryRecommendationObserver observer : observers) { - // observer.updateSatisfiableMessage("[AbstractQueryRecommendationObservable::notifyQuerySatisfiableValue] - // The input query is NOT satisfiable w.r.t. D2",token); - // } - // } } @Override public void notifyDatatsetSimilarity(float score) { - for (IQueryRecommendationObserver obs : observers) { + for (IQueryRecommendationObserver obs : observers) obs.updateDatasetSimilarity(score, token); - } } @Override public void notifyQueryRecommendationCompletion(Boolean finished) { - for (IQueryRecommendationObserver obs : observers) { + for (IQueryRecommendationObserver obs : observers) obs.updateQueryRecommendationCompletion(finished, token); - } } } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/AbstractQueryRecommender.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/AbstractQueryRecommender.java new file mode 100644 index 0000000..88c6a4d --- /dev/null +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/AbstractQueryRecommender.java @@ -0,0 +1,65 @@ +package uk.ac.open.kmi.squire.core4; + +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryFactory; + +import uk.ac.open.kmi.squire.evaluation.Metrics; +import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; + +public abstract class AbstractQueryRecommender extends AbstractQueryRecommendationObservable + implements QueryRecommender, IQueryRecommendationObserver { + + protected final Metrics metrics; + + protected final Query q0; + + protected final IRDFDataset rdfD1, rdfD2; + + public AbstractQueryRecommender(Query query, IRDFDataset d1, IRDFDataset d2, Metrics metrics) { + q0 = QueryFactory.create(query.toString()); + rdfD1 = d1; + rdfD2 = d2; + this.metrics = metrics; + } + + @Override + public Metrics getMetrics() { + return this.metrics; + } + + @Override + public Query getQuery() { + return this.q0; + } + + @Override + public IRDFDataset getSourceDataset() { + return this.rdfD1; + } + + @Override + public IRDFDataset getTargetDataset() { + return this.rdfD2; + } + + @Override + public void updateDatasetSimilarity(float simScore, String token) { + // Nothing to do + } + + @Override + public void updateQueryRecommendated(Query qR, float score, String token) { + this.notifyQueryRecommendation(qR, score); // Just propagate + } + + @Override + public void updateQueryRecommendationCompletion(Boolean finished, String token) { + this.notifyQueryRecommendationCompletion(finished); // Just propagate + } + + @Override + public void updateSatisfiableValue(Query query, boolean value, String token) { + // Nothing to do + } + +} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/Generalizer.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/Generalizer.java index 4895bf1..4f79a1f 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core4/Generalizer.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/Generalizer.java @@ -20,7 +20,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import uk.ac.open.kmi.squire.operation.SPARQLQueryGeneralization; +import uk.ac.open.kmi.squire.entityvariablemapping.VarMapping; +import uk.ac.open.kmi.squire.operation.SparqlQueryGeneralization; import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; /** @@ -31,9 +32,9 @@ public class Generalizer extends QueryOperator { private final Logger log = LoggerFactory.getLogger(getClass()); - private final Query originalQuery; + protected final Query originalQuery; - private final IRDFDataset rdfd1, rdfd2; + protected final IRDFDataset rdfd1, rdfd2; public Generalizer(Query query, IRDFDataset d1, IRDFDataset d2) { super(); @@ -50,8 +51,8 @@ public Generalizer(Query query, IRDFDataset d1, IRDFDataset d2) { public Query generalize() { // The generalized query is created from a clone of the original one. Query qGeneral = QueryFactory.create(this.originalQuery.toString()); - // Three separate generalization steps are performed - SPARQLQueryGeneralization qg = new SPARQLQueryGeneralization(); + // Instantiated once, applied wherever possible. + SparqlQueryGeneralization qg = new SparqlQueryGeneralization(); // SUBJECT for (Node subj : getEntitySet(NodeRole.SUBJECT)) if (!(subj.isVariable()) && !(subj.isBlank())) { @@ -62,7 +63,7 @@ public Query generalize() { for (Node pred : getEntitySet(NodeRole.PREDICATE)) if (!(pred.isVariable()) && !(pred.isBlank())) { if (!this.rdfd2.getRDFVocabulary().contains(pred.getURI())) { - Var templateVarPred = ifPredicateIsNotD2ThenGenerateVariableNew(pred); + Var templateVarPred = makeTplVariableFromPredicate(pred, true); if (templateVarPred != null) qGeneral = qg.perform(qGeneral, pred, templateVarPred); } } @@ -105,76 +106,123 @@ public void visit(ElementPathBlock el) { return objects; } - private Var ifObjectIsNotD2ThenGenerateVariableNew(Node obj) { + protected Var ifObjectIsNotD2ThenGenerateVariableNew(Node obj) { if (obj == null) throw new IllegalArgumentException("Object node cannot be null."); final String varName; if (obj.isURI()) { String o = obj.getURI(); - if ((rdfd1.getClassSet().contains(o)) && !(rdfd2.getClassSet().contains(o))) - varName = classVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_CLASS); - else if (rdfd1.isInObjectPropertySet(o) && !(rdfd2.isInObjectPropertySet(o))) - varName = objectProperyVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_PROP_OBJ); - else if (rdfd1.isInDatatypePropertySet(o) && !(rdfd2.isInDatatypePropertySet(o))) - varName = datatypePropertyVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_PROP_DT); - else if (rdfd1.isInRDFVocabulary(o) && !(rdfd2.isInRDFVocabulary(o))) - varName = rdfVocVarTable.generateVarIfAbsent(o, "rdf"); + if (rdfd1.getClassSet().contains(o) && !rdfd2.getClassSet().contains(o)) + varName = classVarTable.getOrCreateVar(o, TEMPLATE_VAR_CLASS); + else if (rdfd1.isInObjectPropertySet(o) && !rdfd2.isInObjectPropertySet(o)) + varName = objectProperyVarTable.getOrCreateVar(o, TEMPLATE_VAR_PROP_OBJ); + else if (rdfd1.isInDatatypePropertySet(o) && !rdfd2.isInDatatypePropertySet(o)) + varName = datatypePropertyVarTable.getOrCreateVar(o, TEMPLATE_VAR_PROP_DT); + else if (rdfd1.isInRDFVocabulary(o) && !rdfd2.isInRDFVocabulary(o)) + varName = rdfVocVarTable.getOrCreateVar(o, "rdf"); else return null; } else if (obj.isLiteral()) { - varName = literalVarTable.generateVarIfAbsent(obj.getLiteralValue().toString(), + varName = literalVarTable.getOrCreateVar(obj.getLiteralValue().toString(), QueryOperator.TEMPLATE_VAR_LITERAL); } else return null; if (varName == null) throw new IllegalStateException("Object node generated a null variable name."); return Var.alloc(varName); } - private Var ifPredicateIsNotD2ThenGenerateVariableNew(Node pred) { - if (pred == null) throw new IllegalArgumentException("Predicate node cannot be null."); - final String varName; - if (!pred.isURI()) return null; - String p = pred.getURI(); - log.debug("Inspecting predicate '{}' for generalization.", p); - log.trace("rdfd1 object property list : {}", rdfd1.getObjectPropertySet()); - log.trace("rdfd1 datatype property list : {}", rdfd1.getDatatypePropertySet()); - log.trace("rdfd2 object property list : {}", rdfd2.getObjectPropertySet()); - log.trace("rdfd2 datatype property list : {}", rdfd2.getDatatypePropertySet()); - if (rdfd1.isInObjectPropertySet(p) && !(rdfd2.isInObjectPropertySet(p))) { - log.debug(" ... is an object property in <{}> and not in <{}>", rdfd1, rdfd2); - varName = objectProperyVarTable.generateVarIfAbsent(p, TEMPLATE_VAR_PROP_OBJ); - } else if (rdfd1.isInDatatypePropertySet(p) && !(rdfd2.isInDatatypePropertySet(p))) { - log.debug(" ... is a datatype property in <{}> and not in <{}>", rdfd1, rdfd2); - varName = datatypePropertyVarTable.generateVarIfAbsent(p, TEMPLATE_VAR_PROP_DT); - } else { - log.debug(" ... is either present both in <{}> and <{}>, or in neither. Will not generalize.", rdfd1, - rdfd2); - return null; - } - if (varName == null) throw new IllegalStateException("Predicate node generated a null variable name."); - return Var.alloc(varName); - } - - private Var ifSubjectIsNotD2ThenGenerateVariableNew(Node subj) { + protected Var ifSubjectIsNotD2ThenGenerateVariableNew(Node subj) { if (subj == null) throw new IllegalArgumentException("Subject node cannot be null."); final String varName; if (subj.isURI()) { String sub = subj.getURI(); - if ((rdfd1.getClassSet().contains(sub)) && !(rdfd2.getClassSet().contains(sub))) - varName = classVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_CLASS); - else if (rdfd1.isInObjectPropertySet(sub) && !(rdfd2.isInObjectPropertySet(sub))) - varName = objectProperyVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_PROP_OBJ); - else if (rdfd1.isInDatatypePropertySet(sub) && !(rdfd2.isInDatatypePropertySet(sub))) - varName = datatypePropertyVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_PROP_DT); - else if (rdfd1.isInRDFVocabulary(sub) && !(rdfd2.isInRDFVocabulary(sub))) - varName = rdfVocVarTable.generateVarIfAbsent(sub, "rdf"); + if (rdfd1.getClassSet().contains(sub) && !rdfd2.getClassSet().contains(sub)) + varName = classVarTable.getOrCreateVar(sub, TEMPLATE_VAR_CLASS); + else if (rdfd1.isInObjectPropertySet(sub) && !rdfd2.isInObjectPropertySet(sub)) + varName = objectProperyVarTable.getOrCreateVar(sub, TEMPLATE_VAR_PROP_OBJ); + else if (rdfd1.isInDatatypePropertySet(sub) && !rdfd2.isInDatatypePropertySet(sub)) + varName = datatypePropertyVarTable.getOrCreateVar(sub, TEMPLATE_VAR_PROP_DT); + else if (rdfd1.isInRDFVocabulary(sub) && !rdfd2.isInRDFVocabulary(sub)) + varName = rdfVocVarTable.getOrCreateVar(sub, "rdf"); else // We assume by exclusion that sub is an individual. // XXX is that assumption correct? - varName = individualVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_INDIVIDUAL); + varName = individualVarTable.getOrCreateVar(sub, TEMPLATE_VAR_INDIVIDUAL); } else if (subj.isLiteral()) { - varName = literalVarTable.generateVarIfAbsent(subj.getLiteralValue().toString(), + varName = literalVarTable.getOrCreateVar(subj.getLiteralValue().toString(), QueryOperator.TEMPLATE_VAR_LITERAL); } else return null; if (varName == null) throw new IllegalStateException("Subject node generated a null variable name."); return Var.alloc(varName); } + /** + * Creates a template variable for the given property URI if that property + * exists in the source dataset and one of the following conditions is met: + *
    + *
  • the property is not present in the target dataset, or + *
  • flag onlyIfNotInTargetDS is set to false. + *
+ * + * @param predicate + * the predicate URI (if not a URI the method will return null). + * @param onlyIfNotInTargetDS + * an override flag that forces the variable to be generated once + * it's found in the source dataset, regardless of its presence in + * the target dataset. + * @return + */ + protected Var makeTplVariableFromPredicate(Node predicate, boolean onlyIfNotInTargetDS) { + if (predicate == null) throw new IllegalArgumentException("Predicate node cannot be null."); + log.trace("Presence of properties in target dataset {} matter", onlyIfNotInTargetDS ? "DOES" : "does NOT"); + final String varName; + if (!predicate.isURI()) return null; + String p = predicate.getURI(); + log.debug("Inspecting predicate '{}' for generalization.", p); + log.trace("rdfd1 object property list : {}", rdfd1.getObjectPropertySet()); + log.trace("rdfd1 datatype property list : {}", rdfd1.getDatatypePropertySet()); + log.trace("rdfd2 object property list : {}", rdfd2.getObjectPropertySet()); + log.trace("rdfd2 datatype property list : {}", rdfd2.getDatatypePropertySet()); + + // XXX what if the property exist in the other dataset but is used as an + // object/data property unlike the first dataset? + if (rdfd1.isInObjectPropertySet(p) && (!onlyIfNotInTargetDS || !rdfd2.isInObjectPropertySet(p))) + varName = objectProperyVarTable.getOrCreateVar(p, TEMPLATE_VAR_PROP_OBJ); + else if (rdfd1.isInDatatypePropertySet(p) && (!onlyIfNotInTargetDS || !rdfd2.isInDatatypePropertySet(p))) + varName = datatypePropertyVarTable.getOrCreateVar(p, TEMPLATE_VAR_PROP_DT); + else if (rdfd1.isInPropertySet(p)) { + // If we don't care if the property exists in the target dataset, generate the + // template variable, but do take a peek at the target dataset anyway, to decide + // what kind of property it shall be. + if (!onlyIfNotInTargetDS) { + String prefix; + VarMapping table; + if (rdfd2.isInObjectPropertySet(p)) { + prefix = TEMPLATE_VAR_PROP_OBJ; + table = objectProperyVarTable; + } else if (rdfd2.isInDatatypePropertySet(p)) { + prefix = TEMPLATE_VAR_PROP_DT; + table = datatypePropertyVarTable; + } else { + prefix = TEMPLATE_VAR_PROP_PLAIN; + table = plainPropertyVarTable; + } + varName = table.getOrCreateVar(p, prefix); + } else if (!(rdfd2.isInPropertySet(p) || rdfd2.isInObjectPropertySet(p) + || rdfd2.isInDatatypePropertySet(p))) { + log.debug(" ... is a plain property in <{}> and not in <{}>", rdfd1, rdfd2); + varName = plainPropertyVarTable.getOrCreateVar(p, TEMPLATE_VAR_PROP_PLAIN); + } else { + log.debug(" ... is present in target dataset <{}> and override is not enable. Will not generalize.", + rdfd2); + return null; + } + } + // Add a case for "plain" properties + else { + log.debug(" ... is either present both in <{}> and <{}>, or in neither. Will not generalize.", rdfd1, + rdfd2); + return null; + } + if (varName == null) throw new IllegalStateException("Predicate node generated a null variable name."); + return Var.alloc(varName); + } + } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/HyperGeneralizingQueryRecommender.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/HyperGeneralizingQueryRecommender.java new file mode 100644 index 0000000..42f7488 --- /dev/null +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/HyperGeneralizingQueryRecommender.java @@ -0,0 +1,35 @@ +package uk.ac.open.kmi.squire.core4; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.jena.query.Query; + +import uk.ac.open.kmi.squire.core2.QueryAndContextNode; +import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; + +public class HyperGeneralizingQueryRecommender extends QueryRecommendator4 { + + public HyperGeneralizingQueryRecommender(Query query, IRDFDataset d1, IRDFDataset d2, + float resultTypeSimilarityDegree, float queryRootDistanceDegree, float resultSizeSimilarityDegree, + float querySpecificityDistanceDegree) { + super(query, d1, d2, resultTypeSimilarityDegree, queryRootDistanceDegree, resultSizeSimilarityDegree, + querySpecificityDistanceDegree); + } + + public void buildRecommendation() { + ProgrammableGeneralizer gen = new ProgrammableGeneralizer(getQuery(), getSourceDataset(), getTargetDataset()); + List recoms = new ArrayList<>(); + for (Query qGen : gen.generalizeMultiple()) { + Specializer qS = new Specializer(this.q0, qGen, this.rdfD1, this.rdfD2, gen, + getMetrics().resultTypeSimilarityCoefficient, getMetrics().queryRootDistanceCoefficient, + getMetrics().resultSizeSimilarityCoefficient, getMetrics().querySpecificityDistanceCoefficient, + this.token); + qS.register(this); + qS.specialize(); + recoms.addAll(qS.getRecommendations()); + } + rankRecommendations(recoms); + } + +} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/ProgrammableGeneralizer.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/ProgrammableGeneralizer.java new file mode 100644 index 0000000..857116b --- /dev/null +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/ProgrammableGeneralizer.java @@ -0,0 +1,101 @@ +package uk.ac.open.kmi.squire.core4; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.jena.graph.Node; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.sparql.core.TriplePath; +import org.apache.jena.sparql.core.Var; +import org.apache.jena.sparql.syntax.ElementPathBlock; +import org.apache.jena.sparql.syntax.ElementVisitorBase; +import org.apache.jena.sparql.syntax.ElementWalker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import uk.ac.open.kmi.squire.operation.SparqlQueryGeneralization; +import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; + +/** + * A {@link Generalizer} that is able to return multiple generalized queries + * depending on the parameters passed to the generalize operation. + * + * @author alessandro + * + */ +public class ProgrammableGeneralizer extends Generalizer { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + public ProgrammableGeneralizer(Query query, IRDFDataset d1, IRDFDataset d2) { + super(query, d1, d2); + } + + /** + * + * @param preservedNodes + * the maximum number of concrete nodes (URIs, Literals etc.) that + * the resulting general queries should have. A value of zero will + * result in a completely general query. A negative value lets the + * generalization algorithm decide. + * @return + */ + public Set generalizeMultiple() { + Set result = new HashSet<>(); + Query qGeneral = super.generalize(); + result.add(qGeneral); + generalizeStep(qGeneral, result); + log.debug("Total {} generalized queries", result.size()); + return result; + } + + private void generalizeStep(Query q, final Set results) { + SparqlQueryGeneralization op = new SparqlQueryGeneralization(); + ElementWalker.walk(q.getQueryPattern(), new ElementVisitorBase() { + @Override + public void visit(ElementPathBlock el) { + Iterator it = el.patternElts(); + while (it.hasNext()) { + TriplePath tp = it.next(); + visit(tp); + + } + } + + private void visit(TriplePath tp) { + log.debug("Triple path: {}", tp); + if (tp.getSubject().isConcrete()) + log.debug("Subject <{}> is concrete and can be generalized", tp.getSubject()); + if (tp.getPredicate().isConcrete()) { + boolean doit = true; + Node p = tp.getPredicate(); + log.debug("Predicate <{}> is concrete and can be generalized", p); + if (tp.getObject().isVariable()) { + Var o = (Var) tp.getObject(); + if (o.getName().startsWith(TEMPLATE_VAR_INDIVIDUAL) + || o.getName().startsWith(TEMPLATE_VAR_LITERAL) + || o.getName().startsWith(TEMPLATE_VAR_CLASS)) { + log.debug("However, object {} is already a template variable, so will skip for now.", + tp.getObject()); + doit = false; + } + } + if (doit) { + Var v = makeTplVariableFromPredicate(p, false); + // Remember to apply the operation to a clone of the query. + Query newQ = op.perform(QueryFactory.create(q.toString()), p, v); + results.add(newQ); + log.debug("Addinq query to result set:\r\n{}", newQ); + generalizeStep(newQ, results); + + } + } + if (tp.getObject().isConcrete()) + log.debug("Object <{}> is concrete and can be generalized", tp.getObject()); + } + }); + } + +} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryOperator.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryOperator.java index b7871ac..7d91a43 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryOperator.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryOperator.java @@ -10,13 +10,14 @@ protected enum NodeRole { } public static final String TEMPLATE_VAR_CLASS = "ct"; - public static final String TEMPLATE_VAR_PROP_DT = "dpt"; public static final String TEMPLATE_VAR_INDIVIDUAL = "it"; public static final String TEMPLATE_VAR_LITERAL = "lt"; + public static final String TEMPLATE_VAR_PROP_DT = "dpt"; public static final String TEMPLATE_VAR_PROP_OBJ = "opt"; + public static final String TEMPLATE_VAR_PROP_PLAIN = "ppt"; protected VarMapping classVarTable, datatypePropertyVarTable, individualVarTable, literalVarTable, - objectProperyVarTable, rdfVocVarTable; + objectProperyVarTable, rdfVocVarTable, plainPropertyVarTable; protected QueryOperator() { classVarTable = new GeneralVarMapping(); @@ -25,6 +26,7 @@ protected QueryOperator() { objectProperyVarTable = new GeneralVarMapping(); datatypePropertyVarTable = new GeneralVarMapping(); rdfVocVarTable = new GeneralVarMapping(); + plainPropertyVarTable = new GeneralVarMapping(); } public VarMapping getClassVarTable() { @@ -47,6 +49,10 @@ public VarMapping getObjectProperyVarTable() { return objectProperyVarTable; } + public VarMapping getPlainProperyVarTable() { + return plainPropertyVarTable; + } + public VarMapping getRdfVocVarTable() { return rdfVocVarTable; } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendator4.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendator4.java index 349e238..8c7ed62 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendator4.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendator4.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package uk.ac.open.kmi.squire.core4; import java.util.ArrayList; @@ -10,40 +5,20 @@ import java.util.List; import org.apache.jena.query.Query; -import org.apache.jena.query.QueryFactory; import uk.ac.open.kmi.squire.core.QueryScorePair; import uk.ac.open.kmi.squire.core2.QueryAndContextNode; -import uk.ac.open.kmi.squire.entityvariablemapping.GeneralVarMapping; -import uk.ac.open.kmi.squire.entityvariablemapping.VarMapping; +import uk.ac.open.kmi.squire.evaluation.Metrics; import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; /** * * @author carloallocca */ -public class QueryRecommendator4 extends AbstractQueryRecommendationObservable implements IQueryRecommendationObserver { - - private VarMapping classVarTable; - private VarMapping datatypePropertyVarTable; - private VarMapping individualVarTable; - private VarMapping literalVarTable; - private VarMapping objectProperyVarTable; - private VarMapping rdfVocVarTable; +public class QueryRecommendator4 extends AbstractQueryRecommender { - private final Query q0; + protected Query qTemplate; - /* - * This is for storing the output of the specializer - */ - // private List qRList = new ArrayList<>(); - private Query qTemplate; - private final IRDFDataset rdfD1, rdfD2; - - private final float queryRootDistanceDegree; - private final float querySpecificityDistanceDegree; - private final float resultSizeSimilarityDegree; - private final float resultTypeSimilarityDegree; /* * This is for storing the output of the QueryRecommendator */ @@ -51,71 +26,29 @@ public class QueryRecommendator4 extends AbstractQueryRecommendationObservable i public QueryRecommendator4(Query query, IRDFDataset d1, IRDFDataset d2, float resultTypeSimilarityDegree, float queryRootDistanceDegree, float resultSizeSimilarityDegree, float querySpecificityDistanceDegree) { - q0 = QueryFactory.create(query.toString()); - rdfD1 = d1; - classVarTable = new GeneralVarMapping(); - individualVarTable = new GeneralVarMapping(); - literalVarTable = new GeneralVarMapping(); - objectProperyVarTable = new GeneralVarMapping(); - datatypePropertyVarTable = new GeneralVarMapping(); - rdfVocVarTable = new GeneralVarMapping(); - rdfD2 = d2; - this.queryRootDistanceDegree = queryRootDistanceDegree; - this.querySpecificityDistanceDegree = querySpecificityDistanceDegree; - this.resultSizeSimilarityDegree = resultSizeSimilarityDegree; - this.resultTypeSimilarityDegree = resultTypeSimilarityDegree; + super(query, d1, d2, new Metrics(resultTypeSimilarityDegree, queryRootDistanceDegree, + resultSizeSimilarityDegree, querySpecificityDistanceDegree)); } - public void buildRecommendation() throws Exception { + public void buildRecommendation() { // GENERALIZE... - Generalizer qG = new Generalizer(this.q0, this.rdfD1, this.rdfD2); + Generalizer qG = new Generalizer(getQuery(), getSourceDataset(), getTargetDataset()); this.qTemplate = qG.generalize(); - System.out.println(" "); - System.out.println("[QueryRecommendation, generalizeToQueryTemplate()] THE GENERALIZED QUERY: "); - System.out.println(this.qTemplate.toString()); - - this.classVarTable = qG.getClassVarTable(); - this.individualVarTable = qG.getIndividualVarTable(); - this.literalVarTable = qG.getLiteralVarTable(); - this.objectProperyVarTable = qG.getObjectProperyVarTable(); - this.datatypePropertyVarTable = qG.getDatatypePropertyVarTable(); - this.rdfVocVarTable = qG.getRdfVocVarTable(); // SPECIALIZE... - Specializer qS = new Specializer(this.q0, this.qTemplate, this.rdfD1, this.rdfD2, this.classVarTable, - this.objectProperyVarTable, this.datatypePropertyVarTable, this.individualVarTable, - this.literalVarTable, this.rdfVocVarTable, this.resultTypeSimilarityDegree, - this.queryRootDistanceDegree, this.resultSizeSimilarityDegree, this.querySpecificityDistanceDegree, + Specializer qS = new Specializer(getQuery(), this.qTemplate, getSourceDataset(), getTargetDataset(), qG, + getMetrics().resultTypeSimilarityCoefficient, getMetrics().queryRootDistanceCoefficient, + getMetrics().resultSizeSimilarityCoefficient, getMetrics().querySpecificityDistanceCoefficient, this.token); qS.register(this); qS.specialize(); - // RANKING... + // RANK... rankRecommendations(qS.getRecommendations()); } - @Override - public void updateDatasetSimilarity(float simScore, String token) { - // Nothing to do - } - - @Override - public void updateQueryRecommendated(Query qR, float score, String token) { - this.notifyQueryRecommendation(qR, score); // Just propagate - } - - @Override - public void updateQueryRecommendationCompletion(Boolean finished, String token) { - this.notifyQueryRecommendationCompletion(finished); // Just propagate - } - - @Override - public void updateSatisfiableValue(Query query, boolean value, String token) { - // Nothing to do - } - - private void rankRecommendations(List qRList) { + protected void rankRecommendations(List qRList) { for (QueryAndContextNode qrRecom : qRList) { QueryScorePair pair = new QueryScorePair(qrRecom.getTransformedQuery(), qrRecom.getqRScore()); this.sortedRecomQueryList.add(pair); diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendatorForm4.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendatorForm4.java index 7149a2e..5e69f0b 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendatorForm4.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommendatorForm4.java @@ -5,7 +5,6 @@ */ package uk.ac.open.kmi.squire.core4; -import java.net.ConnectException; import java.nio.channels.ClosedByInterruptException; import java.util.Collections; import java.util.HashSet; @@ -113,13 +112,9 @@ private List recommendWithToken(String token) { SPARQLQuerySatisfiable qs = new SPARQLQuerySatisfiable(this.token); qs.register(this); boolean satisfiable = false; - try { - log.info("Checking satisfiability against source dataset <{}>", rdfd1.getEndPointURL()); - satisfiable = qs.isSatisfiableWrtResults(query, rdfd1); - log.info(" ... is satisfiable? {}", satisfiable); - } catch (ConnectException ex) { - throw new RuntimeException(ex); - } + log.info("Checking satisfiability against source dataset <{}>", rdfd1.getEndPointURL()); + satisfiable = qs.isSatisfiableWrtResults(query, rdfd1); + log.info(" ... is satisfiable? {}", satisfiable); fireSatisfiabilityChecked(query, satisfiable); notifyQuerySatisfiableValue(query, satisfiable); // FIXME legacy // Phase 2 : check dataset similarity @@ -135,7 +130,7 @@ private List recommendWithToken(String token) { log.info("Building recommended query tree"); qR.buildRecommendation(); } catch (Exception ex) { - log.error("", ex); + log.error("Exception caught while building recommendation.", ex); } return Collections.emptyList(); } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommender.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommender.java new file mode 100644 index 0000000..9c7316b --- /dev/null +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/QueryRecommender.java @@ -0,0 +1,20 @@ +package uk.ac.open.kmi.squire.core4; + +import org.apache.jena.query.Query; + +import uk.ac.open.kmi.squire.evaluation.Metrics; +import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; + +public interface QueryRecommender { + + public void buildRecommendation(); + + public Metrics getMetrics(); + + public Query getQuery(); + + public IRDFDataset getSourceDataset(); + + public IRDFDataset getTargetDataset(); + +} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/core4/Specializer.java b/squire/src/main/java/uk/ac/open/kmi/squire/core4/Specializer.java index 447045a..9f51713 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/core4/Specializer.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/core4/Specializer.java @@ -46,32 +46,39 @@ import uk.ac.open.kmi.squire.utils.PowerSetFactory; /** + * + * XXX for a {@link QueryOperator} in itself, this class has too much control + * over other operations. * * @author carloallocca */ public class Specializer extends QueryOperator { private static String OPID_INSTANTIATE = "I"; - private static String OPID_TP_REMOVE = "R"; + private final Logger log = LoggerFactory.getLogger(getClass()); - private Query qO, qR; + private final Query qO, qR; + private Map queryIndex = new HashMap<>(); + private IRDFDataset rdfd1, rdfd2; + private final List recommendations = new ArrayList<>(); + private float resultTypeSimilarityDegree, queryRootDistanceDegree, resultSizeSimilarityDegree, querySpecificityDistanceDegree; /** - * List of specializable query and context nodes + * List of query and context nodes that are still _left_ to specialize: it is + * emptied as the process goes on. */ private final List specializables = new ArrayList<>(); - public Specializer(Query qo, Query qr, IRDFDataset d1, IRDFDataset d2, VarMapping cVM, VarMapping opVM, - VarMapping dpVM, VarMapping indVM, VarMapping literalVM, VarMapping rdfVM, float resultTypeSimilarityDegree, - float queryRootDistanceDegree, float resultSizeSimilarityDegree, float querySpecificityDistanceDegree, - String token) { + public Specializer(Query qo, Query qr, IRDFDataset d1, IRDFDataset d2, Generalizer previousOp, + float resultTypeSimilarityDegree, float queryRootDistanceDegree, float resultSizeSimilarityDegree, + float querySpecificityDistanceDegree, String token) { super(); this.qO = QueryFactory.create(qo.toString()); @@ -80,12 +87,12 @@ public Specializer(Query qo, Query qr, IRDFDataset d1, IRDFDataset d2, VarMappin this.rdfd1 = d1; this.rdfd2 = d2; - this.classVarTable = cVM; - this.individualVarTable = indVM; - this.literalVarTable = literalVM; - this.objectProperyVarTable = opVM; - this.datatypePropertyVarTable = dpVM; - this.rdfVocVarTable = rdfVM; + this.classVarTable = previousOp.getClassVarTable(); + this.individualVarTable = previousOp.getIndividualVarTable(); + this.literalVarTable = previousOp.getLiteralVarTable(); + this.objectProperyVarTable = previousOp.getObjectProperyVarTable(); + this.datatypePropertyVarTable = previousOp.getDatatypePropertyVarTable(); + this.rdfVocVarTable = previousOp.getRdfVocVarTable(); this.resultTypeSimilarityDegree = resultTypeSimilarityDegree; this.queryRootDistanceDegree = queryRootDistanceDegree; @@ -117,23 +124,21 @@ public Specializer(Query qo, Query qr, IRDFDataset d1, IRDFDataset d2, VarMappin // float recommentedQueryScore = (querySpecificityDistanceDegree * // qSpecificitySim); // float recommentedQueryScore = (resultTypeSimilarityDegree * resultTypeSim); - float recommentedQueryScore = ((queryRootDistanceDegree * queryRootDistSim) - + (resultTypeSimilarityDegree * resultTypeSim) + (querySpecificityDistanceDegree * (qSpecificitySim))); - // // float recommentedQueryScore = ((queryRootDistanceDegree * queryRootDist) + // (resultTypeSimilarityDegree * resulttypeSim) + // (querySpecificityDistanceDegree * (qSpecDistVar + qSpecDistTP))); // float recommentedQueryScore = resulttypeSim + qSpecDistVar+qSpecDistTP; + /* * This is working as it should but it does not consider the similarity distance * between the replaced entities */ - // log.debug("[QueryGeneralizer4::QuerySpecializer4] recommentedQueryScore " + - // recommentedQueryScore); - - String op = ""; // It can be either R (for Removal) or I (Instanciation). + float recommentedQueryScore = ((queryRootDistanceDegree * queryRootDistSim) + + (resultTypeSimilarityDegree * resultTypeSim) + (querySpecificityDistanceDegree * (qSpecificitySim))); + String op = ""; // It can be either R (for Removal) or I (Instantiation). // B. Compute the qRTemplateVariableSet and qRTriplePatternSet + Set qRTemplateVariableSet = getQueryTemplateVariableSet(this.qR); Set qRTriplePatternSet = getQueryTriplePathSet(this.qR); @@ -142,7 +147,7 @@ public Specializer(Query qo, Query qr, IRDFDataset d1, IRDFDataset d2, VarMappin try { QueryTempVarSolutionSpace temVarValueSpace = new QueryTempVarSolutionSpace(); qTsol = temVarValueSpace.computeTempVarSolutionSpace(qr, this.rdfd2); - qTsol = eliminateSolutionsBoundToSameValue(qTsol); + qTsol = eliminateDuplicateBindings(qTsol); } catch (TooGeneralException gex) { log.warn("Query is too general to execute safely. Assuming solution exists."); log.warn(" * Query : '{}'", gex.getQuery()); @@ -154,16 +159,10 @@ public Specializer(Query qo, Query qr, IRDFDataset d1, IRDFDataset d2, VarMappin // qTsolMap=temVarValueSpace.computeTempVarSolutionSpace(qr, this.rdfd2, null); // D. Build the QueryAndContextNode from the query QueryAndContextNode qAndcNode = new QueryAndContextNode(); - - // ...set the original query and the recommended query; qAndcNode.setOriginalQuery(qo); qAndcNode.setTransformedQuery(qr); - - qAndcNode.setRdfD1(d1); - qAndcNode.setRdfD2(d2); - - qAndcNode.setEntityqO(""); - qAndcNode.setEntityqR(""); + qAndcNode.setDataset1(d1); + qAndcNode.setDataset2(d2); //// ...SET THE CLASS, OBJECT AND DATATYPE PROPERTIES SETs...; // qAndcNode.setcSetD2(d2.getClassSet()); @@ -181,30 +180,19 @@ public Specializer(Query qo, Query qr, IRDFDataset d1, IRDFDataset d2, VarMappin // qAndcNode.setRdfVD2(d2.getRDFVocabulary()); // ...set the score measurements qAndcNode.setQueryRootDistance(queryRootDist); - qAndcNode.setQueryRootDistanceSimilarity(queryRootDistSim); // do also for the other measurements, - // computeTempVarSolutionSpace them... - // qAndcNode.setQuerySpecificityDistanceSimilarity(qSpecDistVar + qSpecDistTP); qAndcNode.setQuerySpecificityDistance(qSpecificitySim); - - qAndcNode.setQueryResultTypeSimilarity(resultTypeSim); - qAndcNode.setQueryResultSizeSimilarity(queryResultSizeSimilarity); qAndcNode.setqRScore(recommentedQueryScore); - qAndcNode.setOp(op); - // qAndcNode.setqRTemplateVariableSet(qRTemplateVariableSet); // qAndcNode.setqRTriplePathSet(qRTriplePatternSet); // ...set the QueryTempVarSolutionSpace qAndcNode.setSolutionSpace(qTsol); // qAndcNode.setQueryTempVarValueMap(qTsolMap); - // log.info("[QueryGeneralizer4::QuerySpecializer4] qTsol size = " + - // qTsol.size()); // E. Sorted Insert of the QueryAndContextNode into the // specializableQueryAndContextNodeList // if(qTsol.size()>=1){ - this.specializables.add(qAndcNode); Collections.sort(this.specializables, new QueryAndContextNode.QRScoreComparator()); @@ -215,7 +203,40 @@ public List getRecommendations() { return recommendations; } - public List specialize() throws Exception { + /** + * This is how I understood it works: + *
    + *
  1. By this time the query has already been generalized and the solution + * space for the general variables has been computed. + *
  2. We have a set of one or more general queries. + *
  3. If the general query is not satisfiable in the target dataset (possible + * if e.g. there are several properties in common between the two datasets but + * they never appear together), then expand the general query to the power set + * of queries with every combination of its triple patterns. This seems to be + * replacing the removal operation. + *
  4. For every general query, perform an operation that instantiates ALL the + * template variables together atomically. Compute the satisfiability, solution + * space, score etc. for the resulting query. + *
+ * + * I see the following problems with this: + *
    + *
  1. Instantiating all the template variables together does not allow a greedy + * best-first (pure heuristic) approach, which could for example work alongside + * this one. + *
  2. It does not account for the case where the general query has a solution + * in the target dataset, but the solution does not include the query we are + * looking for (see e.g. the third query of the egov_1 gold standard: the + * properties match, but not for the type School): in the current + * implementation, no removal/powerset operation is performed and the desired + * query will not be recommended at all. + *
  3. Because the powerset/removal operations might be needed in such + * non-extreme cases, the computational impact of their brute-force nature can + * no longer be neglected. + *
+ */ + public List specialize() { + log.debug(" - {} specializable query templates", this.specializables.size()); for (QueryAndContextNode qctx : this.specializables) { log.debug(" - original query:\r\n{}", qctx.getOriginalQuery()); @@ -224,80 +245,71 @@ public List specialize() throws Exception { StatefulSPARQLQuerySatisfiable satisfiability = new StatefulSPARQLQuerySatisfiable(this.rdfd2); - if ((this.specializables.size() == 1) && (this.specializables.get(0).getQueryTempVarSolutionSpace().isEmpty()) - && (isIProcessable(this.specializables.get(0)))) { - - // log.info("WE WILL START THE SUB PROCESS SPECIALIZATION..."); - // 1. Get and Remove the QueryAndContextNode with qRScore max - QueryAndContextNode parentQctx = popTopScoredQueryCtx(this.specializables); - // log.info("getqO "+parentQctx.getqO()); - // log.info("getqR "+parentQctx.getqR()); - // ADD the code for generating the subqueries with removed triple patterns - // (QueryAndContextNode) - // The power set of the triple pattern set. - // P.S. Look at the code down in the section 3. - Query parentqRCopy = QueryFactory.create(parentQctx.getTransformedQuery()); - Set triplePathSet = getQueryTriplePathSet(parentqRCopy); - // List qRTemplateVariableSet=parentqRCopy.getProjectVars(); - List qRTemplateVariableSet = parentqRCopy.getResultVars(); - - List> triplePathPowerSet = PowerSetFactory.powerset(triplePathSet); - List> triplePathPowerSetOrdered = PowerSetFactory.order(triplePathPowerSet); - - for (List triplePathSubSet : triplePathPowerSetOrdered) { - // for (int i=0; i<15; i++) { - // List triplePathSubSet = triplePathPowerSetOrdered.get(i); - log.debug("triplePathSubSet ::" + triplePathSubSet.toString()); - if (!triplePathSubSet.isEmpty()) { - SelectBuilder sb = new SelectBuilder(); - // adding the triple patters - for (TriplePath tp : triplePathSubSet) - sb.addWhere(tp.asTriple()); // apply the removal operation - // adding the output variable - for (String var : qRTemplateVariableSet) - sb.addVar(var); - sb.setDistinct(true); - Query subQuery = sb.build(); - - // add here the rest of the code, - // including the fact that satisfiacibile and crete - // a node child from the node parent - // Check if it is alredy indexed and therefore generated - log.debug("subQuery Remove operation::: " + subQuery.toString()); - if (!(isQueryIndexed(subQuery))) { - // ...checking if the qWithoutTriple is satisfiable w.r.t. D2 ... - - boolean b = false; - - try { - b = satisfiability.isSatisfiableWrtResults(subQuery); - log.debug("isSatisfiableWRTResultsWithToken :: " + b); - } catch (Exception ex) { - log.error("{}", ex); - } - - if (b) { - log.debug("subQuery Remove operation::: " + subQuery); - QueryAndContextNode childNode = createQctxForRemoval(subQuery, parentQctx); - log.debug("childNode Solution List... " + childNode.getQueryTempVarSolutionSpace().size()); - - this.specializables.add(childNode); - - // this.specializableQueryAndContextNodeList.add(childNode); - + if (this.specializables.size() == 1) { + QueryAndContextNode singleQctx = this.specializables.get(0); + log.debug("Single specializable node:"); + log.debug(" - solution space size = {}", singleQctx.getQueryTempVarSolutionSpace().size()); + log.debug(" - has template variables that can be instantiated: {}", + canBeInstantiated(singleQctx) ? "YES" : "NO"); + if (singleQctx.getQueryTempVarSolutionSpace().isEmpty() && canBeInstantiated(singleQctx)) { + + // log.info("WE WILL START THE SUB PROCESS SPECIALIZATION..."); + // 1. Get and Remove the QueryAndContextNode with qRScore max + QueryAndContextNode parentQctx = popTopScoredQueryCtx(this.specializables); + // ADD the code for generating the subqueries with removed triple patterns + // (QueryAndContextNode) + // The power set of the triple pattern set. + // P.S. Look at the code down in the section 3. + Query parentqRCopy = QueryFactory.create(parentQctx.getTransformedQuery()); + Set triplePathSet = getQueryTriplePathSet(parentqRCopy); + List qRTemplateVariableSet = parentqRCopy.getResultVars(); + log.debug("Initial size of triple path set in query: {}", triplePathSet.size()); + List> tpPowerSet = PowerSetFactory.powerset(triplePathSet); + tpPowerSet = PowerSetFactory.order(tpPowerSet); + log.debug("Size of triple path power set: {}", tpPowerSet.size()); + + for (List triplePathSubSet : tpPowerSet) { + log.debug("triplePathSubSet ::" + triplePathSubSet.toString()); + if (!triplePathSubSet.isEmpty()) { + SelectBuilder sb = new SelectBuilder(); + // adding the triple patterns + for (TriplePath tp : triplePathSubSet) + sb.addWhere(tp.asTriple()); // apply the removal operation + // adding the output variable + for (String var : qRTemplateVariableSet) + sb.addVar(var); + sb.setDistinct(true); + Query subQuery = sb.build(); + + // add here the rest of the code, including the fact that satisfiable and create + // a node child from the node parent + // Check if it is alredy indexed and therefore generated + log.debug("subQuery Remove operation::: " + subQuery.toString()); + if (!(isQueryIndexed(subQuery))) { + // ...checking if the qWithoutTriple is satisfiable w.r.t. D2 ... + boolean sat = false; + try { + sat = satisfiability.isSatisfiableWrtResults(subQuery); + log.debug("isSatisfiableWRTResultsWithToken :: " + sat); + } catch (Exception ex) { + log.error("{}", ex); + } + if (sat) { + log.debug("subQuery Remove operation::: " + subQuery); + QueryAndContextNode childNode = createQctxForRemoval(subQuery, parentQctx); + log.debug("childNode Solution List... " + + childNode.getQueryTempVarSolutionSpace().size()); + this.specializables.add(childNode); + } // add qWithoutTriple to the index addQueryToIndexIFAbsent(subQuery); - // printQuerySolutionSpaceMap(parentQueryAndContextNode); - - } else addQueryToIndexIFAbsent(subQuery); + } } } + Collections.sort(this.specializables, new QueryAndContextNode.QRScoreComparator()); } - Collections.sort(this.specializables, new QueryAndContextNode.QRScoreComparator()); } - // The trivial case: there is only one specializable node and its query is - // satisfiable wrt. the target dataset. if (this.specializables.size() == 1) { QueryAndContextNode spec = this.specializables.get(0); if (spec.getQueryTempVarSolutionSpace().isEmpty() @@ -328,7 +340,7 @@ public List specialize() throws Exception { // parentQueryAndContextNode.getqRScore()); // 4. check if we can apply a instanciation operation; - if (isIProcessable(parentNode)) { + if (canBeInstantiated(parentNode)) { Query queryChild = QueryFactory.create(parentNode.getTransformedQuery()); log.debug("Child query: {}", queryChild); List qSolList = parentNode.getQueryTempVarSolutionSpace(); @@ -444,8 +456,7 @@ private void applyRemovalOp(QueryAndContextNode qRScoreMaxNode) { for (TriplePath tp : triplePathSet) { // 1. Remove the TriplePath tp from the qRCopy - RemoveTriple instance = new RemoveTriple(); - Query qWithoutTriple = instance.removeTP(qRCopy, tp.asTriple()); + Query qWithoutTriple = new RemoveTriple(qRCopy, tp.asTriple()).apply(); // 2. Check if it is alredy indexed and therefore generated if (!(isQueryIndexed(qWithoutTriple))) { @@ -487,6 +498,17 @@ private void applyRemovalOp(QueryAndContextNode qRScoreMaxNode) { } + /** + * + * @param node + * @return true iff there is at least one template variable in the transformed + * query. + */ + private boolean canBeInstantiated(QueryAndContextNode node) { + Set tempVarSet = getQueryTemplateVariableSet(node.getTransformedQuery()); + return tempVarSet.size() > 0; + } + /** * * @param node @@ -548,8 +570,14 @@ private float computeRemoveOperationCost(Query originalQuery, Query childQuery) QueryGPESim queryGPEsim = new QueryGPESim(); float sim = queryGPEsim.computeQueryPatternsSim(originalQuery, childQuery); return (float) 1.0 - sim; - // return sim; - // return 0; + } + + private QueryAndContextNode createNoOpQctx(Query qo) { + QueryAndContextNode qCtx = new QueryAndContextNode(); + qCtx.setOriginalQuery(QueryFactory.create(qo)); + qCtx.setTransformedQuery(QueryFactory.create(qo)); + qCtx.setqRScore(1); + return qCtx; } private QueryAndContextNode createQctxForInstantiation(Query queryPostOp, QueryAndContextNode parentNode, @@ -562,18 +590,23 @@ private QueryAndContextNode createQctxForInstantiation(Query queryPostOp, QueryA // (b) Set the (cloned) datasets on the node // XXX cloning the dataset object for the child nodes, why? - IRDFDataset rdfD1 = parentNode.getRdfD1(); - if (rdfD1 instanceof SparqlIndexedDataset) { - IRDFDataset clone = new SparqlIndexedDataset((String) parentNode.getRdfD1().getEndPointURL(), - (String) parentNode.getRdfD1().getGraph()); - node.setRdfD1(clone); + IRDFDataset d1 = parentNode.getDataset1(); + if (d1 instanceof SparqlIndexedDataset) { + // IRDFDataset clone = new SparqlIndexedDataset((String) + // parentNode.getRdfD1().getEndPointURL(), + // (String) parentNode.getRdfD1().getGraph()); + // node.setRdfD1(clone); + node.setDataset1(d1); // Not cloning to save memory + } else { // TO ADD the case of FILEBASED dataset } - IRDFDataset rdfD2 = parentNode.getRdfD2(); - if (rdfD2 instanceof SparqlIndexedDataset) { - IRDFDataset clone = new SparqlIndexedDataset(((String) parentNode.getRdfD2().getEndPointURL()), - (String) parentNode.getRdfD2().getGraph()); - node.setRdfD2(clone); + IRDFDataset d2 = parentNode.getDataset2(); + if (d2 instanceof SparqlIndexedDataset) { + // IRDFDataset clone = new SparqlIndexedDataset(((String) + // parentNode.getRdfD2().getEndPointURL()), + // (String) parentNode.getRdfD2().getGraph()); + // node.setRdfD2(clone); + node.setDataset2(d2); // Clone the solution space (XXX why?) node.setSolutionSpace(new ArrayList<>(parentNode.getQueryTempVarSolutionSpace())); } else { // TO ADD the case of FILEBASED dataset @@ -592,13 +625,11 @@ private QueryAndContextNode createQctxForInstantiation(Query queryPostOp, QueryA + computeInstanciationOperationCost(tplVarEntityQoQrInstantiated); node.setQueryRootDistance(newQueryRootDist); float queryRootDistSim = 1 - newQueryRootDist; - node.setQueryRootDistanceSimilarity(queryRootDistSim); // 3)...QueryResultTypeSimilarity QueryResultTypeSimilarity qRTS = new QueryResultTypeSimilarity(); float newResulttypeSim = qRTS.computeQueryResultTypeDistance(node.getOriginalQuery(), this.rdfd1, node.getTransformedQuery(), this.rdfd2); - node.setQueryResultTypeSimilarity(newResulttypeSim); float recommendedQueryScore = (queryRootDistanceDegree * queryRootDistSim) + (resultTypeSimilarityDegree * newResulttypeSim) @@ -616,8 +647,7 @@ private QueryAndContextNode createQctxForInstantiation(Query queryPostOp, QueryA return node; } - private QueryAndContextNode createQctxForRemoval(Query queryPostOp, QueryAndContextNode parentNode) - throws TooGeneralException { + private QueryAndContextNode createQctxForRemoval(Query queryPostOp, QueryAndContextNode parentNode) { QueryAndContextNode node = new QueryAndContextNode(); // ...set the original query and the recommendated query; Query clonedqO = QueryFactory.create(parentNode.getOriginalQuery()); @@ -625,24 +655,25 @@ private QueryAndContextNode createQctxForRemoval(Query queryPostOp, QueryAndCont Query clonedqR = QueryFactory.create(queryPostOp.toString()); node.setTransformedQuery(clonedqR); - - // ...set the entities: EntityqO and EntityqR - node.setEntityqO(""); - node.setEntityqR(""); // ..set the RDF dataset 1 - IRDFDataset rdfD1 = parentNode.getRdfD1(); - if (rdfD1 instanceof SparqlIndexedDataset) { - IRDFDataset newRdfD1 = new SparqlIndexedDataset(((String) parentNode.getRdfD1().getEndPointURL()), - (String) parentNode.getRdfD1().getGraph()); - node.setRdfD1(newRdfD1); + IRDFDataset d1 = parentNode.getDataset1(); + if (d1 instanceof SparqlIndexedDataset) { + // IRDFDataset newRdfD1 = new SparqlIndexedDataset(((String) + // parentNode.getRdfD1().getEndPointURL()), + // (String) parentNode.getRdfD1().getGraph()); + // node.setRdfD1(newRdfD1); + node.setDataset1(d1); } else { // TO ADD the case of FILEBASED dataset } // ..set the RDF dataset 2 - IRDFDataset rdfD2 = parentNode.getRdfD2(); - if (rdfD2 instanceof SparqlIndexedDataset) { - IRDFDataset newRdfD2 = new SparqlIndexedDataset(((String) parentNode.getRdfD2().getEndPointURL()), - (String) parentNode.getRdfD2().getGraph()); - node.setRdfD2(newRdfD2); + IRDFDataset d2 = parentNode.getDataset2(); + if (d2 instanceof SparqlIndexedDataset) { + // IRDFDataset newRdfD2 = new SparqlIndexedDataset(((String) + // parentNode.getRdfD2().getEndPointURL()), + // (String) parentNode.getRdfD2().getGraph()); + // node.setRdfD2(newRdfD2); + node.setDataset2(d2); + // //C. Compute the QueryTempVarSolutionSpace // QueryTempVarSolutionSpace temVarValueSpace = new QueryTempVarSolutionSpace(); // // [REPLACED] List qTsolMap = @@ -660,7 +691,7 @@ private QueryAndContextNode createQctxForRemoval(Query queryPostOp, QueryAndCont // e.g. ( ?opt2 = ) ( ?opt1 = // ), - List qTsolCleaned = eliminateSolutionsBoundToSameValue(qTsolTMP); + List qTsolCleaned = eliminateDuplicateBindings(qTsolTMP); qTsolChild.addAll(qTsolCleaned); node.setSolutionSpace(qTsolCleaned); @@ -681,13 +712,11 @@ private QueryAndContextNode createQctxForRemoval(Query queryPostOp, QueryAndCont + computeRemoveOperationCost(node.getOriginalQuery(), node.getTransformedQuery()); node.setQueryRootDistance(newQueryRootDist); float queryRootDistSim = 1 - newQueryRootDist; - node.setQueryRootDistanceSimilarity(queryRootDistSim); // 3)...QueryResultTypeSimilarity QueryResultTypeSimilarity qRTS = new QueryResultTypeSimilarity(); float resulTtypeDist = qRTS.computeQueryResultTypeDistance(this.qO, this.rdfd1, this.qR, this.rdfd2); float resultTypeSim = 1 - resulTtypeDist; - node.setQueryResultTypeSimilarity(resultTypeSim); // float recommentedQueryScore = ( ( newQueryRootDist) + // ( newResulttypeSim) + @@ -713,17 +742,9 @@ private QueryAndContextNode createQctxForRemoval(Query queryPostOp, QueryAndCont return node; } - private QueryAndContextNode createNoOpQctx(Query qo) throws Exception { - QueryAndContextNode qCtx = new QueryAndContextNode(); - qCtx.setOriginalQuery(QueryFactory.create(qo)); - qCtx.setTransformedQuery(QueryFactory.create(qo)); - qCtx.setqRScore(1); - return qCtx; - } - // e.g. ( ?opt2 = ) ( ?opt1 = // ) - private List eliminateSolutionsBoundToSameValue(List qSolList) { + private List eliminateDuplicateBindings(List qSolList) { List output = new ArrayList<>(); if (qSolList.isEmpty()) return qSolList; for (QuerySolution qs : qSolList) { @@ -796,11 +817,6 @@ public void visit(ElementPathBlock el) { return tpSet; } - private boolean isIProcessable(QueryAndContextNode qRScoreMaxNodeCloned) { - Set tempVarSet = getQueryTemplateVariableSet(qRScoreMaxNodeCloned.getTransformedQuery()); - return tempVarSet.size() > 0; - } - private boolean isQueryIndexed(Query qWithoutTriple) { Set triplePathCollection = getQueryTriplePathSet(qWithoutTriple); ArrayList s = new ArrayList<>(); // and use Collections.sort() diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/GeneralVarMapping.java b/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/GeneralVarMapping.java index e571618..aca8575 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/GeneralVarMapping.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/GeneralVarMapping.java @@ -5,21 +5,37 @@ public class GeneralVarMapping implements VarMapping { - protected int succ = 0; + /** + * This is appended to the next template variable when it is generated. + */ + protected int index = 0; protected Map valueToVar; protected Map varToValue; public GeneralVarMapping() { valueToVar = new HashMap<>(); varToValue = new HashMap<>(); - succ = 1; + index = 1; } @Override public void clear() { valueToVar = null; varToValue = null; - succ = 0; + index = 0; + } + + @Override + public String getOrCreateVar(String uri, String varPrefix) { + if (valueToVar == null || index == 0) + throw new IllegalStateException("The mapping table needs to be initialized before use."); + if (!valueToVar.containsKey(uri)) { + // this.classVar = "ct"+Integer.toString(++index); + String tmp = varPrefix + Integer.toString(index++); + valueToVar.put(uri, tmp); + varToValue.put(tmp, uri); + return tmp; + } else return valueToVar.get(uri); } @Override @@ -40,17 +56,4 @@ public Map getVarToValueTable() { return this.varToValue; } - @Override - public String generateVarIfAbsent(String uri, String varPrefix) { - if (valueToVar == null || succ == 0) - throw new IllegalStateException("The mapping table needs to be initialized before use."); - if (!valueToVar.containsKey(uri)) { - // this.classVar = "ct"+Integer.toString(++succ); - String tmp = varPrefix + Integer.toString(succ++); - valueToVar.put(uri, tmp); - varToValue.put(tmp, uri); - return tmp; - } else return valueToVar.get(uri); - } - } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/VarMapping.java b/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/VarMapping.java index 9b19373..ca1a902 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/VarMapping.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/entityvariablemapping/VarMapping.java @@ -6,7 +6,7 @@ public interface VarMapping { public void clear(); - public String generateVarIfAbsent(String uri, String varPrefix); + public String getOrCreateVar(String uri, String varPrefix); public String getValueFromVar(String varString); diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/evaluation/Metrics.java b/squire/src/main/java/uk/ac/open/kmi/squire/evaluation/Metrics.java index 8a5b5be..a65ec81 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/evaluation/Metrics.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/evaluation/Metrics.java @@ -9,12 +9,23 @@ */ public class Metrics { - public float resultTypeSimilarityCoefficient = 1.0f; - public float queryRootDistanceCoefficient = 1.0f; + public float querySpecificityDistanceCoefficient = 1.0f; + public float resultSizeSimilarityCoefficient = 1.0f; - public float querySpecificityDistanceCoefficient = 1.0f; + public float resultTypeSimilarityCoefficient = 1.0f; + + public Metrics() { + } + + public Metrics(float resultTypeSimilarityCoefficient, float queryRootDistanceCoefficient, + float resultSizeSimilarityCoefficient, float querySpecificityDistanceCoefficient) { + this.resultTypeSimilarityCoefficient = resultTypeSimilarityCoefficient; + this.queryRootDistanceCoefficient = queryRootDistanceCoefficient; + this.resultSizeSimilarityCoefficient = resultSizeSimilarityCoefficient; + this.querySpecificityDistanceCoefficient = querySpecificityDistanceCoefficient; + } } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/IOperation.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/IOperation.java deleted file mode 100644 index 20843a6..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/IOperation.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package uk.ac.open.kmi.squire.operation; - -/** - * - * @author carloallocca - */ -public interface IOperation { - - /** - * - * @return - */ - public Object apply(); - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/ISPARQLQuery.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/ISPARQLQuery.java deleted file mode 100644 index e669996..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/ISPARQLQuery.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package uk.ac.open.kmi.squire.operation; - -/** - * - * @author callocca - */ -public interface ISPARQLQuery { - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/InstantiateTemplateVar.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/InstantiateTemplateVar.java new file mode 100644 index 0000000..3fb0728 --- /dev/null +++ b/squire/src/main/java/uk/ac/open/kmi/squire/operation/InstantiateTemplateVar.java @@ -0,0 +1,39 @@ +package uk.ac.open.kmi.squire.operation; + +import org.apache.commons.lang3.NotImplementedException; +import org.apache.jena.query.Query; +import org.apache.jena.sparql.core.Var; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author carloallocca + */ +public class InstantiateTemplateVar implements Operation { + + private Logger log = LoggerFactory.getLogger(getClass()); + + private final String entity; + private final Query q; + private final Var varTemplate; + + public InstantiateTemplateVar(Query q, Var varTemplate, String entity) { + this.q = q; + this.varTemplate = varTemplate; + this.entity = entity; + } + + @Override + public Query apply() { + log.debug("Instantiating template variable {}", this.varTemplate); + log.debug(" - instantiation : {}", this.entity); + throw new NotImplementedException("NIY"); + } + + @Override + public Object[] getOperands() { + return new Object[] { q, varTemplate, entity }; + } + +} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/Operation.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/Operation.java new file mode 100644 index 0000000..b6aa203 --- /dev/null +++ b/squire/src/main/java/uk/ac/open/kmi/squire/operation/Operation.java @@ -0,0 +1,28 @@ +package uk.ac.open.kmi.squire.operation; + +/** + * An operation that, once applied, returns an object that can be assimilated + * with a query (e.g. a Query or set of queries). + * + * @author carloallocca, alessandro.adamou + */ +public interface Operation { + + /** + * Performs the operation. The operands are taken from the object that + * implements the operation. + * + * @return the result of applying the operation (can be e.g. a query or set + * thereof). + */ + public Q apply(); + + /** + * Returns the list of operands in the order supplied to the constructor of this + * Operation. + * + * @return the list of parameters. + */ + public Object[] getOperands(); + +} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/QueryOperationProcessor.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/QueryOperationProcessor.java deleted file mode 100644 index 4d443c3..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/QueryOperationProcessor.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package uk.ac.open.kmi.squire.operation; - -import org.apache.jena.query.Query; - -/** - * - * @author carloallocca - */ -public class QueryOperationProcessor { - - private final Query q; - private final IOperation op; - - public QueryOperationProcessor(Query q, IOperation op) { - this.q = q; - this.op = op; - } - - public static void applyOperation(Query q, IOperation op) { - Query newQuery = (Query) op.apply(); - // this.op.apply(); - } - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/RemoveTriple.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/RemoveTriple.java index 83a5031..f535944 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/RemoveTriple.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/operation/RemoveTriple.java @@ -5,8 +5,6 @@ */ package uk.ac.open.kmi.squire.operation; -import java.util.Set; - import org.apache.jena.graph.Triple; import org.apache.jena.query.Query; import org.apache.jena.sparql.syntax.ElementWalker; @@ -19,36 +17,35 @@ * * @author carloallocca */ -public class RemoveTriple { - - public RemoveTriple() { - super(); - } - - public Query removeTP(Query q, Triple tp) { - - SQGraphPatternExpressionVisitor gpeVisitorO = new SQGraphPatternExpressionVisitor(); - // ...get the GPE of qOri - ElementWalker.walk(q.getQueryPattern(), gpeVisitorO); - Set qGPE = gpeVisitorO.getQueryGPE(); - - if (qGPE.size() > 1) { +public class RemoveTriple implements Operation { - RemoveOpTransform rOpTransform = new RemoveOpTransform(q, tp); - Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform); - // if(queryWithoutTriplePattern.getGroupBy()!=null){ - // //Iterator - // orderBy=queryWithoutTriplePattern.getGroupBy().getVars().iterator(); - // // queryWithoutTriplePattern - // } - // queryWithoutTriplePattern.getAggregators() + private Query query; - return queryWithoutTriplePattern; + private Triple triple; - } + public RemoveTriple(Query q, Triple tp) { + this.query = q; + this.triple = tp; + } - return q; + @Override + public Query apply() { + SQGraphPatternExpressionVisitor gpeVisitorO = new SQGraphPatternExpressionVisitor(); + ElementWalker.walk(this.query.getQueryPattern(), gpeVisitorO); + if (gpeVisitorO.getQueryGPE().size() <= 1) return this.query; + RemoveOpTransform rOpTransform = new RemoveOpTransform(this.query, this.triple); + Query qPostOp = QueryTransformOps.transform(this.query, rOpTransform); + // if(qPostOp.getGroupBy()!=null){ + // //Iterator + // orderBy=qPostOp.getGroupBy().getVars().iterator(); + // } + // qPostOp.getAggregators() + return qPostOp; + } + @Override + public Object[] getOperands() { + return new Object[] { query, triple }; } } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/SPARQLQuerySatisfiable.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/SPARQLQuerySatisfiable.java index ad076ba..b9c8ace 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/SPARQLQuerySatisfiable.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/operation/SPARQLQuerySatisfiable.java @@ -124,7 +124,7 @@ public boolean isSatisfiableWRTProjectVar(Query qRec) { return qOvarList.containsAll(projectVarListString); } - public boolean isSatisfiableWrtResults(Query q, IRDFDataset rdfd2) throws java.net.ConnectException { + public boolean isSatisfiableWrtResults(Query q, IRDFDataset rdfd2) { String datasetPath = (String) rdfd2.getEndPointURL(); if (datasetPath == null || datasetPath.isEmpty()) { this.notifyQuerySatisfiableValue(q, false); diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/SPARQLQueryGeneralization.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/SparqlQueryGeneralization.java similarity index 58% rename from squire/src/main/java/uk/ac/open/kmi/squire/operation/SPARQLQueryGeneralization.java rename to squire/src/main/java/uk/ac/open/kmi/squire/operation/SparqlQueryGeneralization.java index 8902be3..7e9637f 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/SPARQLQueryGeneralization.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/operation/SparqlQueryGeneralization.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package uk.ac.open.kmi.squire.operation; import java.util.ListIterator; @@ -19,10 +14,13 @@ import org.slf4j.LoggerFactory; /** + * Performs a single generalization step replacing a node with a template + * variable in a query. All three objects are taken as arguments by the + * {@link #perform(Query, Node, Var)} method. * * @author callocca */ -public class SPARQLQueryGeneralization { +public class SparqlQueryGeneralization { private class SQGeneralizationVisitor extends ElementVisitorBase { @@ -30,10 +28,8 @@ private class SQGeneralizationVisitor extends ElementVisitorBase { private Var varTemplate; public SQGeneralizationVisitor(Node n, Var varTemplate) { - // System.out.println("The triple ==> " + tp.toString()); - if (n == null || varTemplate == null) { - throw new IllegalStateException("[SQGeneralizationVisitor]The Node or the varTemplate is null!!"); - } + if (n == null || varTemplate == null) + throw new IllegalArgumentException("The RDF node and template variable cannot be null."); this.node = n; this.varTemplate = varTemplate; } @@ -44,61 +40,43 @@ public void visit(ElementPathBlock el) { ListIterator it = el.getPattern().iterator(); while (it.hasNext()) { final TriplePath tp = it.next(); - // System.out.println("The triple ==> " + tp.toString()); + log.trace("Visiting triple: {}", tp); + // SUBJECT Node oldSubject = tp.getSubject(); final Node newSubject; - // SUBJECT if (!oldSubject.isVariable()) { if (oldSubject.isURI() && node.isURI()) { - if (oldSubject.getURI().equals(node.getURI())) { - newSubject = Var.alloc(varTemplate); - } else newSubject = oldSubject; + if (oldSubject.getURI().equals(node.getURI())) newSubject = Var.alloc(varTemplate); + else newSubject = oldSubject; } else newSubject = oldSubject; } else newSubject = oldSubject; + // PREDICATE Node oldPredicate = tp.getPredicate(); final Node newPredicate; - // PREDICATE if (!oldPredicate.isVariable()) { if (oldPredicate.isURI() && node.isURI()) { - if (oldPredicate.getURI().equals(node.getURI())) { - newPredicate = Var.alloc(varTemplate); - } else { - newPredicate = oldPredicate; - } - } else { - newPredicate = oldPredicate; - } - - } else { - newPredicate = oldPredicate; - } + if (oldPredicate.getURI().equals(node.getURI())) newPredicate = Var.alloc(varTemplate); + else newPredicate = oldPredicate; + } else newPredicate = oldPredicate; + } else newPredicate = oldPredicate; // OBJECT Node oldObject = tp.getObject(); final Node newObject; if (!oldObject.isVariable()) { if (oldObject.isURI() && node.isURI()) { - if (oldObject.getURI().equals(node.getURI())) { - newObject = Var.alloc(varTemplate); - } else { - newObject = oldObject; - } + if (oldObject.getURI().equals(node.getURI())) newObject = Var.alloc(varTemplate); + else newObject = oldObject; } else { if (oldObject.isLiteral() && node.isLiteral()) { - if (oldObject.getLiteral().toString().equals(node.getLiteral().toString())) { + if (oldObject.getLiteral().toString().equals(node.getLiteral().toString())) newObject = Var.alloc(varTemplate); - } else { - newObject = oldObject; - } - } else { - newObject = oldObject; - } + else newObject = oldObject; + } else newObject = oldObject; } - } else { - newObject = oldObject; - } + } else newObject = oldObject; TriplePath newTriplePattern = new TriplePath(new Triple(newSubject, newPredicate, newObject)); it.set(newTriplePattern); } @@ -106,18 +84,20 @@ public void visit(ElementPathBlock el) { } + private Logger log = LoggerFactory.getLogger(getClass()); + /** - * FIXME the operation alters the original query! is it safe? + * FIXME the operation alters the given query! is it safe? * * @param q * @param n * @param varTemplate - * @return + * @return the altered (not cloned!) q */ public Query perform(Query q, Node n, Var varTemplate) { - if (q == null || n == null || varTemplate == null) - throw new IllegalArgumentException("The Query or the Node or the Var is null"); - Logger log = LoggerFactory.getLogger(getClass()); + if (q == null) throw new IllegalArgumentException("The query cannot be null."); + if (n == null) throw new IllegalArgumentException("The node cannot be null."); + if (varTemplate == null) throw new IllegalArgumentException("The template variable cannot be null."); log.trace(" * Generalizing over node {}", n); SQGeneralizationVisitor genVisitor = new SQGeneralizationVisitor(n, varTemplate); ElementWalker.walk(q.getQueryPattern(), genVisitor); diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/StatefulSPARQLQuerySatisfiable.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/StatefulSPARQLQuerySatisfiable.java index dbee121..d5ea2c6 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/StatefulSPARQLQuerySatisfiable.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/operation/StatefulSPARQLQuerySatisfiable.java @@ -1,6 +1,5 @@ package uk.ac.open.kmi.squire.operation; -import java.net.ConnectException; import java.util.HashMap; import java.util.Map; @@ -40,7 +39,7 @@ public IRDFDataset getDataset() { return dataset; } - public boolean isSatisfiableWrtResults(Query q) throws ConnectException { + public boolean isSatisfiableWrtResults(Query q) { if (satisfiables.containsKey(q)) { log.debug("Satisfiability check already cached, not executing again"); boolean cond = satisfiables.get(q); diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/TooGeneralException.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/TooGeneralException.java index e6bc044..b0ec64e 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/TooGeneralException.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/operation/TooGeneralException.java @@ -2,7 +2,7 @@ import org.apache.jena.query.Query; -public class TooGeneralException extends Exception { +public class TooGeneralException extends RuntimeException { private Query q; diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/TripleRemovalOp.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/TripleRemovalOp.java deleted file mode 100644 index 53065fd..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/TripleRemovalOp.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package uk.ac.open.kmi.squire.operation; - -import org.apache.jena.query.Query; -import org.apache.jena.reasoner.TriplePattern; - -/** - * - * @author carloallocca - */ -public class TripleRemovalOp implements IOperation { - - private final Query q; - private final TriplePattern tp; - - public TripleRemovalOp(Query q, TriplePattern tp) { - this.q = q; - this.tp = tp; - } - - @Override - public Object apply() { - System.out.println(" Removing the TriplePattern " + this.tp + " from the query Q = " + this.q.toString()); - return null; // return this.q modified - } - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/operation/VarTemplateInstanciationOp.java b/squire/src/main/java/uk/ac/open/kmi/squire/operation/VarTemplateInstanciationOp.java deleted file mode 100644 index b4a7996..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/operation/VarTemplateInstanciationOp.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package uk.ac.open.kmi.squire.operation; - -import org.apache.jena.query.Query; -import org.apache.jena.sparql.core.Var; - -/** - * - * @author carloallocca - */ -public class VarTemplateInstanciationOp implements IOperation { - - private final Query q; - private final String entity; - private final Var varTemplate; - - public VarTemplateInstanciationOp(Query q, Var varTemplate, String entity) { - this.q = q; - this.varTemplate = varTemplate; - this.entity = entity; - } - - @Override - public Object apply() { - System.out.println(" Substitute the varTemplate" + this.varTemplate + " with the entity " + this.entity - + " in the query Q=" + this.q.toString()); - return null; // return this.q modified - } - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/querytemplate/SQTVisitor.java b/squire/src/main/java/uk/ac/open/kmi/squire/querytemplate/SQTVisitor.java index 3d08b91..fd16dc3 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/querytemplate/SQTVisitor.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/querytemplate/SQTVisitor.java @@ -92,8 +92,8 @@ public void visit(ElementPathBlock el) { && predicate.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") && rdfd1.getClassSet().contains(object)) { Var individualVar = Var - .alloc(individualVarTable.generateVarIfAbsent(subj.getURI(), TEMPLATE_VAR_INDIVIDUAL)); - Var classVar = Var.alloc(classVarTable.generateVarIfAbsent(obj.getURI(), TEMPLATE_VAR_CLASS)); + .alloc(individualVarTable.getOrCreateVar(subj.getURI(), TEMPLATE_VAR_INDIVIDUAL)); + Var classVar = Var.alloc(classVarTable.getOrCreateVar(obj.getURI(), TEMPLATE_VAR_CLASS)); it.set(new TriplePath(new Triple(individualVar, tp.getPredicate(), classVar))); } @@ -103,8 +103,8 @@ public void visit(ElementPathBlock el) { if (rdfd1.getIndividualSet().contains(subject) && rdfd1.getObjectPropertySet().contains(predicate) && rdfd1.getIndividualSet().contains(object)) { Var individualVar = Var - .alloc(individualVarTable.generateVarIfAbsent(subj.getURI(), TEMPLATE_VAR_INDIVIDUAL)); - Var classVar = Var.alloc(classVarTable.generateVarIfAbsent(obj.getURI(), TEMPLATE_VAR_CLASS)); + .alloc(individualVarTable.getOrCreateVar(subj.getURI(), TEMPLATE_VAR_INDIVIDUAL)); + Var classVar = Var.alloc(classVarTable.getOrCreateVar(obj.getURI(), TEMPLATE_VAR_CLASS)); it.set(new TriplePath(new Triple(individualVar, tp.getPredicate(), classVar))); } // @@ -126,7 +126,7 @@ else if (subj.isURI() && pred.isURI() && obj.isLiteral()) { System.out.println("subj.isURI() && pred.isURI() && obj.isLiteral()"); // Var literalVar1 = Var.alloc( // LiteralVarMapping.generateIFAbsentLiteralVar(obj.toString())); - Var literalVar1 = Var.alloc(literalVarTable.generateVarIfAbsent(obj.toString(), TEMPLATE_VAR_LITERAL)); + Var literalVar1 = Var.alloc(literalVarTable.getOrCreateVar(obj.toString(), TEMPLATE_VAR_LITERAL)); it.set(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), literalVar1))); } @@ -150,7 +150,7 @@ else if (subj.isVariable() && pred.isURI() && obj.isLiteral()) { // Var predVar1 = Var.alloc( pred.getURI() ); // Var literalVar1 = Var.alloc( // LiteralVarMapping.generateIFAbsentLiteralVar(obj.toString())); - Var literalVar1 = Var.alloc(literalVarTable.generateVarIfAbsent(obj.toString(), TEMPLATE_VAR_LITERAL)); + Var literalVar1 = Var.alloc(literalVarTable.getOrCreateVar(obj.toString(), TEMPLATE_VAR_LITERAL)); it.set(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), literalVar1))); } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/rdfdataset/SparqlIndexedDataset.java b/squire/src/main/java/uk/ac/open/kmi/squire/rdfdataset/SparqlIndexedDataset.java index ae24aad..32c1d9e 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/rdfdataset/SparqlIndexedDataset.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/rdfdataset/SparqlIndexedDataset.java @@ -436,6 +436,7 @@ private Set loadSingle(String field) { } /** + * * This is the variant that uses a Map as a container. * * @param partialQuery @@ -452,6 +453,10 @@ private Set loadSingle(String field) { * because they have already been indexed. If NULL, the method will * do pure pagination. * @return true iff the computation is deemed complete. + * + * @throws BootedException + * if the remote endpoint refused to even respond to the first step + * of the iteration. */ protected boolean iterativeComputation(final String partialQuery, final Map> targetContainer, int stepLength, int iteration, Set exclusions) throws BootedException { @@ -464,7 +469,7 @@ protected boolean iterativeComputation(final String partialQuery, final Map queryGPE = new HashSet(); - - public SQGraphPatternExpressionVisitor() { - super(); - } - - @Override - public void visit(ElementPathBlock el) { - if (el == null) { - throw new IllegalStateException( - "[SQGraphPatternExpressionVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!"); - } - // System.out.println("[SQGraphPatternExpressionVisitor::visit(ElementPathBlock - // el)] The ElementPathBlock contains "+el.toString()); - ListIterator it = el.getPattern().iterator(); - while (it.hasNext()) { - final TriplePath tp = it.next(); - queryGPE.add(tp); - } - } + private Set queryGPE = new HashSet<>(); public Set getQueryGPE() { return queryGPE; } @Override - public void visit(ElementAssign el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementAssign el))] "); - - } - - @Override - public void visit(ElementBind el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementBind el)] "); - - } - - @Override - public void visit(ElementSubQuery el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementSubQuery el)] "); - } - - @Override - public void visit(ElementService el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementService el)] "); - } - - @Override - public void visit(ElementMinus el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementMinus el)] "); - } - - @Override - public void visit(ElementNotExists el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementNotExists el)] "); - } - - @Override - public void visit(ElementExists el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementExists el)] "); - } - - @Override - public void visit(ElementNamedGraph el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementNamedGraph el)] "); - } - - @Override - public void visit(ElementGroup el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementGroup el)] "); - } - - @Override - public void visit(ElementOptional el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementOptional el)] "); - } - - @Override - public void visit(ElementDataset el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementDataset el)] "); - } - - @Override - public void visit(ElementUnion el) { - } - - @Override - public void visit(ElementData el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementData el)] "); - } - - @Override - public void visit(ElementFilter el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementFilter el)] "); - } - - @Override - public void visit(ElementTriplesBlock el) { - // System.out.println("[SQInstantiationVisitor::visit(ElementTriplesBlock el)] - // "); + public void visit(ElementPathBlock el) { + if (el == null) throw new IllegalArgumentException("The element path block must not be null."); + ListIterator it = el.getPattern().iterator(); + while (it.hasNext()) + queryGPE.add(it.next()); } } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/sparqlqueryvisitor/SQStarQueryAssessment.java b/squire/src/main/java/uk/ac/open/kmi/squire/sparqlqueryvisitor/SQStarQueryAssessment.java deleted file mode 100644 index c86797d..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/sparqlqueryvisitor/SQStarQueryAssessment.java +++ /dev/null @@ -1,189 +0,0 @@ -package uk.ac.open.kmi.squire.sparqlqueryvisitor; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.jena.graph.Node; -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryVisitor; -import org.apache.jena.sparql.core.Prologue; -import org.apache.jena.sparql.core.TriplePath; -import org.apache.jena.sparql.syntax.ElementPathBlock; -import org.apache.jena.sparql.syntax.ElementTriplesBlock; -import org.apache.jena.sparql.syntax.ElementVisitorBase; -import org.apache.jena.sparql.syntax.ElementWalker; -import org.apache.jena.vocabulary.RDF; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import uk.ac.open.kmi.squire.rdfdataset.ClassSignature; -import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; - -/** - * - * - * @author alessandro - * - */ -public class SQStarQueryAssessment extends ElementVisitorBase implements QueryVisitor { - - private IRDFDataset tgt; - - private Logger log = LoggerFactory.getLogger(getClass()); - - public SQStarQueryAssessment(IRDFDataset targetDataset) { - this.tgt = targetDataset; - } - - @Override - public void visit(ElementPathBlock el) { - // Classes in this star TP - Map> classesPerSubject = new HashMap<>(); - - // Scan for subject-class bindings. - for (Iterator it = el.patternElts(); it.hasNext();) { - TriplePath tp = it.next(); - Node sub = tp.getSubject(); - log.debug("Putting subject '{}' in map", sub); - if (!classesPerSubject.containsKey(sub)) classesPerSubject.put(sub, new HashSet<>()); - - if (tp.getPredicate().isURI() && RDF.type.getURI().equals(tp.getPredicate().getURI())) { - log.info("Got at RDF:type for class {}", tp.getObject()); - } - - if (tp.getPredicate().isURI() && RDF.type.getURI().equals(tp.getPredicate().getURI()) - && tp.getObject().isURI()) { - classesPerSubject.get(sub).add(tp.getObject().getURI()); - } - } - // Scan again for unsatisfiable predicates for instances of those types - for (Iterator it = el.patternElts(); it.hasNext();) { - TriplePath tp = it.next(); - Node sub = tp.getSubject(); - log.debug("is subject '{}' in map? {}", sub, classesPerSubject.containsKey(sub)); - Node pred = tp.getPredicate(); - - if (pred.isURI()) { - log.debug("predicate: {}", pred); - for (String clazz : classesPerSubject.get(sub)) { - log.debug("I want to check class <{}>", clazz); - ClassSignature cs = tgt.getClassSignatures().get(clazz); - if (cs != null && !cs.listPathOrigins().contains(pred.getURI())) { - log.warn("Property <{}> is not part of the indexed signature for class <{}>", pred.getURI(), - clazz); - log.warn("For the record, here are the known properties:\r\n{}", cs.listPathOrigins()); - log.warn("I woundn't recommend going down this branch."); - } - } - - } - } - - System.out.println("DIOCANE " + el); - } - - @Override - public void visit(ElementTriplesBlock el) { - System.out.println("DIOPORCO " + el); - } - - @Override - public void startVisit(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitPrologue(Prologue prologue) { - // TODO Auto-generated method stub - - } - - @Override - public void visitResultForm(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitSelectResultForm(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitConstructResultForm(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitDescribeResultForm(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitAskResultForm(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitDatasetDecl(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitQueryPattern(Query query) { - System.out.println("DIO MUFLONE"); - ElementWalker.walk(query.getQueryPattern(), this); - } - - @Override - public void visitGroupBy(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitHaving(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitOrderBy(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitLimit(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitOffset(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void visitValues(Query query) { - // TODO Auto-generated method stub - - } - - @Override - public void finishVisit(Query query) { - // TODO Auto-generated method stub - - } - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/sparqlqueryvisitor/TransformRemoveOp.java b/squire/src/main/java/uk/ac/open/kmi/squire/sparqlqueryvisitor/TransformRemoveOp.java deleted file mode 100644 index 2da57ec..0000000 --- a/squire/src/main/java/uk/ac/open/kmi/squire/sparqlqueryvisitor/TransformRemoveOp.java +++ /dev/null @@ -1,507 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package uk.ac.open.kmi.squire.sparqlqueryvisitor; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.apache.jena.graph.Node; -import org.apache.jena.graph.Triple; -import org.apache.jena.query.Query; -import org.apache.jena.sparql.algebra.Op; -import org.apache.jena.sparql.algebra.Transform; -import org.apache.jena.sparql.algebra.op.OpAssign; -import org.apache.jena.sparql.algebra.op.OpBGP; -import org.apache.jena.sparql.algebra.op.OpConditional; -import org.apache.jena.sparql.algebra.op.OpDatasetNames; -import org.apache.jena.sparql.algebra.op.OpDiff; -import org.apache.jena.sparql.algebra.op.OpDisjunction; -import org.apache.jena.sparql.algebra.op.OpDistinct; -import org.apache.jena.sparql.algebra.op.OpExt; -import org.apache.jena.sparql.algebra.op.OpExtend; -import org.apache.jena.sparql.algebra.op.OpFilter; -import org.apache.jena.sparql.algebra.op.OpGraph; -import org.apache.jena.sparql.algebra.op.OpGroup; -import org.apache.jena.sparql.algebra.op.OpJoin; -import org.apache.jena.sparql.algebra.op.OpLabel; -import org.apache.jena.sparql.algebra.op.OpLeftJoin; -import org.apache.jena.sparql.algebra.op.OpList; -import org.apache.jena.sparql.algebra.op.OpMinus; -import org.apache.jena.sparql.algebra.op.OpNull; -import org.apache.jena.sparql.algebra.op.OpOrder; -import org.apache.jena.sparql.algebra.op.OpPath; -import org.apache.jena.sparql.algebra.op.OpProcedure; -import org.apache.jena.sparql.algebra.op.OpProject; -import org.apache.jena.sparql.algebra.op.OpPropFunc; -import org.apache.jena.sparql.algebra.op.OpQuad; -import org.apache.jena.sparql.algebra.op.OpQuadBlock; -import org.apache.jena.sparql.algebra.op.OpQuadPattern; -import org.apache.jena.sparql.algebra.op.OpReduced; -import org.apache.jena.sparql.algebra.op.OpSequence; -import org.apache.jena.sparql.algebra.op.OpService; -import org.apache.jena.sparql.algebra.op.OpSlice; -import org.apache.jena.sparql.algebra.op.OpTable; -import org.apache.jena.sparql.algebra.op.OpTopN; -import org.apache.jena.sparql.algebra.op.OpTriple; -import org.apache.jena.sparql.algebra.op.OpUnion; -import org.apache.jena.sparql.core.BasicPattern; -import org.apache.jena.sparql.core.Var; -import org.apache.jena.sparql.expr.Expr; -import org.apache.jena.sparql.expr.nodevalue.NodeValueBoolean; - -/** - * - * @author carloallocca - */ -public class TransformRemoveOp implements Transform { - - private Query query; - private Triple triple; - - private boolean isParent = false; - private boolean isStarted = false; - private boolean isFinished = false; - - private int opBGPCounter = 1; - - public TransformRemoveOp(Query q, Triple tp) { - this.query = q; - this.triple = tp; - } - - @Override - public Op transform(OpTable opUnit) { - - System.out.println("[TransformRemoveOp::transform(OpTable opUnit)] " + opUnit.toString()); - System.out.println(""); - return opUnit; - - } - - @Override - public Op transform(OpGroup opGroup, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpGroup opGroup, Op subOp)] " + opGroup.toString()); - System.out.println(""); - - return opGroup; - } - - @Override - public Op transform(OpBGP opBGP) { - - System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++); - System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString()); - System.out.println(""); - Op newOpBGP = opBGP.copy(); - BasicPattern newBP = ((OpBGP) newOpBGP).getPattern(); - List tripleList = newBP.getList(); - - Iterator itr = tripleList.iterator(); - while (itr.hasNext()) { - Triple tp = itr.next(); - if (tp.matches(this.triple)) { - itr.remove(); - isParent = true; - isStarted = true; - } - } - // ...it can be empty - if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) { - System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString()); - // return subOp; - } - return newOpBGP; - } - - // @Override - // public Op transform(OpFilter opFilter, Op subOp) { - // Op op = null; - // if(subOp instanceof OpBGP ){ - // System.out.println("YOU ARE HERE!!!!!"); - // if (((OpBGP) subOp).getPattern().getList().isEmpty()){ - // System.out.println("YOU ARE HERE 22 2222222!!!!!"); - // return subOp; - // } - // } - // return op; - // } - // @Override - // public Op transform(OpFilter opFilter, Op subOp) { - // System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op - // subOp)] opFilter " + opFilter.toString()); - // System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op - // subOp)] subOp Name " + subOp.getName()); - // System.out.println(""); - // - // if (isParent == false) { - // return opFilter; - // } - // - // //...get the variables of the triple pattern that we want to delete - // Set tpVars = new HashSet(); - // Node subj = this.triple.getSubject(); - // if (subj.isVariable()) { - // tpVars.add((Var) subj); - // } - // Node pred = this.triple.getPredicate(); - // if (pred.isVariable()) { - // tpVars.add((Var) pred); - // } - // Node obj = this.triple.getObject(); - // if (obj.isVariable()) { - // tpVars.add((Var) obj); - // } - // //...get the variables of the FILTER expression - // Op opNew = opFilter.copy(subOp); - // Set expVars = ((OpFilter) opNew).getExprs().getVarsMentioned(); - // - // //...check whether the FILTER expression contains any of the triple pattern - // variable - // boolean isContained=false; - // for (Var var : expVars) { - // //..if it does then we have to delete the entire FILTER expression - // if (tpVars.contains(var)) { - // isContained=true; - // } - // //System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op - // subOp)] FILTER ? "); - // //System.out.println("111111 "+opFilter.getSubOp().getName()); - // - // - // ///////////// - // ///////////// - // - //// ExprList exprList=exprList = opFilter.getExprs(); - //// - //// ExprList newExprList = new ExprList(); // contains the translated - // expressions - //// - //// OpFilter copiedOpFilter = (OpFilter) OpFilter.filter(exprList, - // opFilter.getSubOp()); - //// exprList = copiedOpFilter.getExprs(); - //// - //// // for every expression of the filter, apply first DeMorgan-law and then - // Distributive-law - //// for (Expr expr : exprList) { - //// Expr e = new NodeValueBoolean(true); - //// newExprList.add(e); - //// } - //// return copiedOpFilter.filter(newExprList, opFilter);//filter(newExprList, - // opFilter); - // - // - // ///////////// - // ///////////// - // if (subOp instanceof OpBGP) { - // if (((OpBGP) subOp).getPattern().getList().isEmpty()) { - // System.out.println("YOU ARE HERE 22 2222222!!!!!"); - // return subOp; - // } - // Expr e = new NodeValueBoolean(true); - // Op newOP = OpFilter.filter(e, opFilter);//filter(e, ); - // - // // - // //opFilter.apply(this, subOp); - // //newOP = new OpProject(newOP, Arrays.asList(Var.alloc("s"))); - // //Op newNewOp= OpFilter.filter(e, newOP); - // isFinished = true; - // return newOP; - // } - // } - // - // // opFilter.apply(new TransformFilterCNF(), subOp); - // System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op - // subOp)] BEFORE RETURN"); - // return opFilter; - // } - // - @Override - public Op transform(OpFilter opFilter, Op subOp) { - System.out - .println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString()); - System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName()); - System.out.println(""); - - if (isParent == false) { - return opFilter; - } - - // ...get the variables of the triple pattern that we want to delete - Set tpVars = new HashSet(); - Node subj = this.triple.getSubject(); - if (subj.isVariable()) { - tpVars.add((Var) subj); - } - Node pred = this.triple.getPredicate(); - if (pred.isVariable()) { - tpVars.add((Var) pred); - } - Node obj = this.triple.getObject(); - if (obj.isVariable()) { - tpVars.add((Var) obj); - } - // ...get the variables of the FILTER expression - Op opNew = opFilter.copy(subOp); - Set expVars = ((OpFilter) opNew).getExprs().getVarsMentioned(); - - // ...check whether the FILTER expression contains any of the triple pattern - // variable - boolean isContained = false; - for (Var var : expVars) { - // ..if it does then we have to delete the entire FILTER expression - if (tpVars.contains(var)) { - isContained = true; - break; - } - } - // ... if the filter contains any variable of the triple that has been removed, - // then.... - if (isContained) { - Op newOP; - Expr e; - if (subOp instanceof OpBGP) { - if (((OpBGP) subOp).getPattern().getList().isEmpty()) { - e = new NodeValueBoolean(true); - newOP = OpFilter.filter(e, opFilter);// filter(e, ); - return newOP; - } else { - e = new NodeValueBoolean(false); - newOP = OpFilter.filter(e, opFilter);// filter(e, ); - return newOP; - } - } - } - return opFilter; - } - - @Override - public Op transform(OpTriple opTriple) { - System.out.println("[TransformRemoveOp::transform(OpTriple opTriple)] " + opTriple.toString()); - System.out.println(""); - - return opTriple; - } - - @Override - public Op transform(OpQuad opQuad) { - System.out.println("[TransformRemoveOp::transform(OpQuad opQuad)] " + opQuad.toString()); - System.out.println(""); - - return opQuad; - } - - @Override - public Op transform(OpPath opPath) { - System.out.println("[TransformRemoveOp::transform(OpPath opPath)] " + opPath.toString()); - System.out.println(""); - - return opPath; - } - - @Override - public Op transform(OpDatasetNames dsNames) { - System.out.println("[TransformRemoveOp::transform(OpDatasetNames dsNames)] " + dsNames.toString()); - System.out.println(""); - - return dsNames; - } - - @Override - public Op transform(OpQuadPattern quadPattern) { - System.out.println("[TransformRemoveOp::transform(OpQuadPattern quadPattern)] " + quadPattern.toString()); - System.out.println(""); - - return quadPattern; - } - - @Override - public Op transform(OpQuadBlock quadBlock) { - System.out.println("[TransformRemoveOp::transform(OpQuadBlock quadBlock)] " + quadBlock.toString()); - System.out.println(""); - - return quadBlock; - } - - @Override - public Op transform(OpNull opNull) { - System.out.println("[TransformRemoveOp::transform(OpNull opNull)] " + opNull.toString()); - System.out.println(""); - - return opNull; - } - - @Override - public Op transform(OpGraph opGraph, Op subOp) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpService opService, Op subOp) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpProcedure opProcedure, Op subOp) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpPropFunc opPropFunc, Op subOp) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpLabel opLabel, Op subOp) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpAssign opAssign, Op subOp) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpExtend opExtend, Op subOp) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpJoin opJoin, Op left, Op right) { - System.out.println("[TransformRemoveOp::transform(OpJoin opJoin, Op left, Op right)] " + opJoin.toString()); - System.out.println(""); - - return opJoin; - } - - @Override - public Op transform(OpLeftJoin opLeftJoin, Op left, Op right) { - System.out.println( - "[TransformRemoveOp::transform(OpLeftJoin opLeftJoin, Op left, Op right)] " + opLeftJoin.toString()); - System.out.println(""); - - return opLeftJoin; - } - - @Override - public Op transform(OpDiff opDiff, Op left, Op right) { - System.out.println("[TransformRemoveOp::transform(OpDiff opDiff, Op left, Op right)] " + opDiff.toString()); - System.out.println(""); - - return opDiff; - } - - @Override - public Op transform(OpMinus opMinus, Op left, Op right) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpUnion opUnion, Op left, Op right) { - System.out - .println("[TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: " + left.toString()); - System.out.println( - "[TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: " + right.toString()); - System.out.println(""); - - return opUnion; - } - - @Override - public Op transform(OpConditional opCondition, Op left, Op right) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpSequence opSequence, List elts) { - throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose - // Tools | Templates. - } - - @Override - public Op transform(OpDisjunction opDisjunction, List elts) { - System.out.println("[TransformRemoveOp::transform(OOpDisjunction opDisjunction, List elts)] " - + opDisjunction.toString()); - System.out.println(""); - - return opDisjunction; - } - - @Override - public Op transform(OpExt opExt) { - System.out.println("[TransformRemoveOp::transform(OpExt opExt)] " + opExt.toString()); - System.out.println(""); - - return opExt; - } - - @Override - public Op transform(OpList opList, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpList opList, Op subOp)] " + opList.toString()); - System.out.println(""); - - return opList; - } - - @Override - public Op transform(OpOrder opOrder, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpOrder opOrder, Op subOp)] " + opOrder.toString()); - System.out.println(""); - - return opOrder; - } - - @Override - public Op transform(OpTopN opTop, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpTopN opTop, Op subOp)] " + opTop.toString()); - System.out.println(""); - - return opTop; - } - - @Override - public Op transform(OpProject opProject, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpProject opProject, Op subOp)] " + opProject.toString()); - System.out.println(""); - - return opProject; - } - - @Override - public Op transform(OpDistinct opDistinct, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] " + opDistinct.toString()); - System.out.println(""); - - return opDistinct; - } - - @Override - public Op transform(OpReduced opReduced, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpReduced opReduced, Op subOp)] " + opReduced.toString()); - System.out.println(""); - - return opReduced; - } - - @Override - public Op transform(OpSlice opSlice, Op subOp) { - System.out.println("[TransformRemoveOp::transform(OpSlice opSlice, Op subOp)] " + opSlice.toString()); - System.out.println(""); - - return opSlice; - } - -} diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QTTree.java b/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QTTree.java index a45e6ed..53fc42c 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QTTree.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QTTree.java @@ -133,7 +133,7 @@ public void generateQTTree(TreeNodez> node) { if (rdfd1.getClassSet().contains(tp.getSubject().getURI())) { // System.out.println("[QTTree::generateQTTree] subject is an class uri"); Var classVar = Var - .alloc(classVarTable.generateVarIfAbsent(tp.getSubject().getURI(), TEMPLATE_VAR_CLASS)); + .alloc(classVarTable.getOrCreateVar(tp.getSubject().getURI(), TEMPLATE_VAR_CLASS)); childTPSet.add(new TriplePath(new Triple(classVar, tp.getPredicate(), tp.getObject()))); System.out.println("[QTTree::generateQTTree] subject is an class == BEFORE"); System.out.println(tpSet.toString()); @@ -148,7 +148,7 @@ public void generateQTTree(TreeNodez> node) { // s= individualURI } else if (rdfd1.isInIndividualSet(tp.getSubject().getURI())) { Var indVar = Var.alloc( - individualVarTable.generateVarIfAbsent(tp.getSubject().getURI(), TEMPLATE_VAR_INDIVIDUAL)); + individualVarTable.getOrCreateVar(tp.getSubject().getURI(), TEMPLATE_VAR_INDIVIDUAL)); childTPSet.add(new TriplePath(new Triple(indVar, tp.getPredicate(), tp.getObject()))); System.out.println("[QTTree::generateQTTree] subject is a individual uri == BEFORE"); System.out.println(tpSet.toString()); @@ -162,7 +162,7 @@ public void generateQTTree(TreeNodez> node) { // s = objectPropertyURI } else if (rdfd1.isInObjectPropertySet(tp.getSubject().getURI())) { Var obpVar = Var.alloc( - objectProperyVarTable.generateVarIfAbsent(tp.getSubject().getURI(), TEMPLATE_VAR_PROP_OBJ)); + objectProperyVarTable.getOrCreateVar(tp.getSubject().getURI(), TEMPLATE_VAR_PROP_OBJ)); childTPSet.add(new TriplePath(new Triple(obpVar, tp.getPredicate(), tp.getObject()))); System.out.println(tpSet.toString()); System.out.println("[QTTree::generateQTTree] subject is a objectproperty uri == BEFORE"); @@ -176,7 +176,7 @@ public void generateQTTree(TreeNodez> node) { } // s = datatypePropertyURI } else if (rdfd1.isInDatatypePropertySet(tp.getSubject().getURI())) { - Var dtpVar = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(tp.getSubject().getURI(), + Var dtpVar = Var.alloc(datatypePropertyVarTable.getOrCreateVar(tp.getSubject().getURI(), TEMPLATE_VAR_PROP_DT)); childTPSet.add(new TriplePath(new Triple(dtpVar, tp.getPredicate(), tp.getObject()))); System.out.println(tpSet.toString()); @@ -191,7 +191,7 @@ public void generateQTTree(TreeNodez> node) { } // s = RDFVocabularyURI } else if (rdfd1.isInRDFVocabulary(tp.getSubject().getURI())) { - Var rdfVar = Var.alloc(rdfVocVarTable.generateVarIfAbsent(tp.getSubject().getURI(), "rdf")); + Var rdfVar = Var.alloc(rdfVocVarTable.getOrCreateVar(tp.getSubject().getURI(), "rdf")); childTPSet.add(new TriplePath(new Triple(rdfVar, tp.getPredicate(), tp.getObject()))); System.out.println(tpSet.toString()); System.out.println("[QTTree::generateQTTree] subject is a RDFVocabulary uri == BEFORE"); @@ -227,7 +227,7 @@ public void generateQTTree(TreeNodez> node) { } } Var litVar = Var.alloc(literalVarTable - .generateVarIfAbsent(tp.getSubject().getLiteral().getValue().toString(), TEMPLATE_VAR_LITERAL)); + .getOrCreateVar(tp.getSubject().getLiteral().getValue().toString(), TEMPLATE_VAR_LITERAL)); childTPSet.add(new TriplePath(new Triple(litVar, tp.getPredicate(), tp.getObject()))); System.out.println("[QTTree::generateQTTree] subject is a literal == BEFORE"); System.out.println(tpSet.toString()); @@ -256,7 +256,7 @@ public void generateQTTree(TreeNodez> node) { } // s= RDFVocabulary if (rdfd1.isInRDFVocabulary(tp.getPredicate().getURI())) { - Var rdfVar = Var.alloc(rdfVocVarTable.generateVarIfAbsent(tp.getPredicate().getURI(), "rdf")); + Var rdfVar = Var.alloc(rdfVocVarTable.getOrCreateVar(tp.getPredicate().getURI(), "rdf")); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), rdfVar, tp.getObject()))); System.out.println("[QTTree::generateQTTree] predicate is an rdfvoc uri == BEFORE"); System.out.println(tpSet.toString()); @@ -269,7 +269,7 @@ public void generateQTTree(TreeNodez> node) { } // p= ObjPropertyURI or datatypePropertyURI } else if (rdfd1.isInObjectPropertySet(tp.getPredicate().getURI())) { - Var predVar = Var.alloc(objectProperyVarTable.generateVarIfAbsent(tp.getPredicate().getURI(), + Var predVar = Var.alloc(objectProperyVarTable.getOrCreateVar(tp.getPredicate().getURI(), TEMPLATE_VAR_PROP_OBJ)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), predVar, tp.getObject()))); @@ -285,7 +285,7 @@ public void generateQTTree(TreeNodez> node) { } // p = datatypePropertyURI } else if (rdfd1.isInDatatypePropertySet(tp.getPredicate().getURI())) { - Var predVar = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(tp.getPredicate().getURI(), + Var predVar = Var.alloc(datatypePropertyVarTable.getOrCreateVar(tp.getPredicate().getURI(), TEMPLATE_VAR_PROP_DT)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), predVar, tp.getObject()))); System.out.println("[QTTree::generateQTTree] predicate is a object property uri == BEFORE"); @@ -323,7 +323,7 @@ public void generateQTTree(TreeNodez> node) { // o = classURI if (rdfd1.getClassSet().contains(tp.getObject().getURI())) { Var classVar = Var - .alloc(classVarTable.generateVarIfAbsent(tp.getObject().getURI(), TEMPLATE_VAR_CLASS)); + .alloc(classVarTable.getOrCreateVar(tp.getObject().getURI(), TEMPLATE_VAR_CLASS)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), classVar))); System.out.println("[QTTree::generateQTTree] object is a class uri == BEFORE"); System.out.println(tpSet.toString()); @@ -337,7 +337,7 @@ public void generateQTTree(TreeNodez> node) { // o = individualURI } else if (rdfd1.isInIndividualSet(tp.getObject().getURI())) { Var indVar = Var.alloc( - individualVarTable.generateVarIfAbsent(tp.getObject().getURI(), TEMPLATE_VAR_INDIVIDUAL)); + individualVarTable.getOrCreateVar(tp.getObject().getURI(), TEMPLATE_VAR_INDIVIDUAL)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), indVar))); System.out.println("[QTTree::generateQTTree] object is an individual uri == BEFORE"); System.out.println(tpSet.toString()); @@ -351,7 +351,7 @@ public void generateQTTree(TreeNodez> node) { // o = objectpropertyURI } else if (rdfd1.isInObjectPropertySet(tp.getObject().getURI())) { Var obpVar = Var.alloc( - objectProperyVarTable.generateVarIfAbsent(tp.getObject().getURI(), TEMPLATE_VAR_PROP_OBJ)); + objectProperyVarTable.getOrCreateVar(tp.getObject().getURI(), TEMPLATE_VAR_PROP_OBJ)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), obpVar))); System.out.println("[QTTree::generateQTTree] object is an object property uri == BEFORE"); System.out.println(tpSet.toString()); @@ -364,7 +364,7 @@ public void generateQTTree(TreeNodez> node) { } // o = datatypepropertyURI } else if (rdfd1.isInDatatypePropertySet(tp.getObject().getURI())) { - Var dtpVar = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(tp.getObject().getURI(), + Var dtpVar = Var.alloc(datatypePropertyVarTable.getOrCreateVar(tp.getObject().getURI(), TEMPLATE_VAR_PROP_DT)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), dtpVar))); System.out.println("[QTTree::generateQTTree] object is an object property uri == BEFORE"); @@ -378,7 +378,7 @@ public void generateQTTree(TreeNodez> node) { } } // o = RDFVocabularyURI else if (rdfd1.isInRDFVocabulary(tp.getObject().getURI())) { - Var rdfVar = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(tp.getObject().getURI(), + Var rdfVar = Var.alloc(datatypePropertyVarTable.getOrCreateVar(tp.getObject().getURI(), TEMPLATE_VAR_PROP_DT)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), rdfVar))); System.out.println("[QTTree::generateQTTree] object is an object property uri == BEFORE"); @@ -413,7 +413,7 @@ else if (rdfd1.isInRDFVocabulary(tp.getObject().getURI())) { } } Var litVar = Var.alloc(literalVarTable - .generateVarIfAbsent(tp.getObject().getLiteral().getValue().toString(), TEMPLATE_VAR_LITERAL)); + .getOrCreateVar(tp.getObject().getLiteral().getValue().toString(), TEMPLATE_VAR_LITERAL)); childTPSet.add(new TriplePath(new Triple(tp.getSubject(), tp.getPredicate(), litVar))); System.out.println("[QTTree::generateQTTree] subject is a literal == BEFORE"); System.out.println(tpSet.toString()); @@ -572,20 +572,20 @@ private TriplePath generalize(TriplePath tp) { String subj = tp.getSubject().getURI(); // System.out.println("[QTTree::generalize] The Sub is an URI " + subj); if ((rdfd1.getClassSet().contains(subj)) && !(rdfd2.getClassSet().contains(subj))) { - subject = Var.alloc(classVarTable.generateVarIfAbsent(subj, TEMPLATE_VAR_CLASS)); + subject = Var.alloc(classVarTable.getOrCreateVar(subj, TEMPLATE_VAR_CLASS)); // System.out.println("[QTTree::generalize] The Sub is a class URI"); } else if (rdfd1.isInIndividualSet(subj) && !(rdfd2.isInIndividualSet(subj))) { - subject = Var.alloc(individualVarTable.generateVarIfAbsent(subj, TEMPLATE_VAR_INDIVIDUAL)); + subject = Var.alloc(individualVarTable.getOrCreateVar(subj, TEMPLATE_VAR_INDIVIDUAL)); // System.out.println("[QTTree::generalize] The Sub is an individual URI"); } else if (rdfd1.isInObjectPropertySet(subj) && !(rdfd2.isInObjectPropertySet(subj))) { - subject = Var.alloc(objectProperyVarTable.generateVarIfAbsent(subj, TEMPLATE_VAR_PROP_OBJ)); + subject = Var.alloc(objectProperyVarTable.getOrCreateVar(subj, TEMPLATE_VAR_PROP_OBJ)); // System.out.println("[QTTree::generalize] The Sub is an Object Property URI"); } else if (rdfd1.isInDatatypePropertySet(subj) && !(rdfd2.isInDatatypePropertySet(subj))) { - subject = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(subj, TEMPLATE_VAR_PROP_DT)); + subject = Var.alloc(datatypePropertyVarTable.getOrCreateVar(subj, TEMPLATE_VAR_PROP_DT)); // System.out.println("[QTTree::generalize] The Sub is an datatype Property // URI"); } else if (rdfd1.isInRDFVocabulary(subj) && !(rdfd2.isInRDFVocabulary(subj))) { - subject = Var.alloc(rdfVocVarTable.generateVarIfAbsent(subj, "rdf")); + subject = Var.alloc(rdfVocVarTable.getOrCreateVar(subj, "rdf")); // System.out.println("[QTTree::generalize] The Sub is an RDF voc term URI"); } else { subject = tp.getSubject(); @@ -594,7 +594,7 @@ private TriplePath generalize(TriplePath tp) { if (tp.getSubject().isLiteral()) { String subjAsString = tp.getSubject().getLiteralValue().toString(); if (rdfd1.isInLiteralSet(subjAsString) && !(rdfd2.isInLiteralSet(subjAsString))) { - subject = Var.alloc(literalVarTable.generateVarIfAbsent(subjAsString, TEMPLATE_VAR_LITERAL)); + subject = Var.alloc(literalVarTable.getOrCreateVar(subjAsString, TEMPLATE_VAR_LITERAL)); } else { subject = tp.getSubject(); } @@ -614,11 +614,11 @@ private TriplePath generalize(TriplePath tp) { // System.out.println("[QTTree::generalize] The predicate is an URI 111111111 " // + pred); if (rdfd1.isInObjectPropertySet(pred) && !(rdfd2.isInObjectPropertySet(pred))) { - predicate = Var.alloc(objectProperyVarTable.generateVarIfAbsent(pred, TEMPLATE_VAR_PROP_OBJ)); + predicate = Var.alloc(objectProperyVarTable.getOrCreateVar(pred, TEMPLATE_VAR_PROP_OBJ)); } else if (rdfd1.isInDatatypePropertySet(pred) && !(rdfd2.isInDatatypePropertySet(pred))) { - predicate = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(pred, TEMPLATE_VAR_PROP_DT)); + predicate = Var.alloc(datatypePropertyVarTable.getOrCreateVar(pred, TEMPLATE_VAR_PROP_DT)); } else if (rdfd1.isInRDFVocabulary(pred) && !(rdfd2.isInRDFVocabulary(pred))) { - predicate = Var.alloc(rdfVocVarTable.generateVarIfAbsent(pred, "rdf")); + predicate = Var.alloc(rdfVocVarTable.getOrCreateVar(pred, "rdf")); } else { // System.out.println("[QTTree::generalize] The predicate is an URI 22222222 " + // pred); @@ -636,15 +636,15 @@ private TriplePath generalize(TriplePath tp) { String obj = tp.getObject().getURI(); // System.out.println("[QTTree::generalize] The Object is " + obj); if (rdfd1.getClassSet().contains(obj) && !(rdfd2.getClassSet().contains(obj))) { - object = Var.alloc(classVarTable.generateVarIfAbsent(obj, TEMPLATE_VAR_CLASS)); + object = Var.alloc(classVarTable.getOrCreateVar(obj, TEMPLATE_VAR_CLASS)); } else if (rdfd1.isInIndividualSet(obj) && !(rdfd2.isInIndividualSet(obj))) { - object = Var.alloc(individualVarTable.generateVarIfAbsent(obj, TEMPLATE_VAR_INDIVIDUAL)); + object = Var.alloc(individualVarTable.getOrCreateVar(obj, TEMPLATE_VAR_INDIVIDUAL)); } else if (rdfd1.isInObjectPropertySet(obj) && !(rdfd2.isInObjectPropertySet(obj))) { - object = Var.alloc(objectProperyVarTable.generateVarIfAbsent(obj, TEMPLATE_VAR_PROP_OBJ)); + object = Var.alloc(objectProperyVarTable.getOrCreateVar(obj, TEMPLATE_VAR_PROP_OBJ)); } else if (rdfd1.isInDatatypePropertySet(obj) && !(rdfd2.isInDatatypePropertySet(obj))) { - object = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(obj, TEMPLATE_VAR_PROP_DT)); + object = Var.alloc(datatypePropertyVarTable.getOrCreateVar(obj, TEMPLATE_VAR_PROP_DT)); } else if (rdfd1.isInRDFVocabulary(obj) && !(rdfd2.isInRDFVocabulary(obj))) { - object = Var.alloc(rdfVocVarTable.generateVarIfAbsent(obj, "rdf")); + object = Var.alloc(rdfVocVarTable.getOrCreateVar(obj, "rdf")); } else { object = tp.getObject(); } @@ -656,7 +656,7 @@ private TriplePath generalize(TriplePath tp) { // "+rdfd2.getLiteralSet().toString()); if (rdfd1.isInLiteralSet(objAsString) && !(rdfd2.isInLiteralSet(objAsString))) { - object = Var.alloc(literalVarTable.generateVarIfAbsent(objAsString, TEMPLATE_VAR_LITERAL)); + object = Var.alloc(literalVarTable.getOrCreateVar(objAsString, TEMPLATE_VAR_LITERAL)); } else { object = tp.getObject(); } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QueryRecommendation.java b/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QueryRecommendation.java index ecc6bff..82ed55f 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QueryRecommendation.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/treequerypatterns/QueryRecommendation.java @@ -38,9 +38,9 @@ import uk.ac.open.kmi.squire.evaluation.QuerySpecificityDistance; import uk.ac.open.kmi.squire.ontologymatching.JaroWinklerSimilarity; import uk.ac.open.kmi.squire.operation.RemoveTriple; -import uk.ac.open.kmi.squire.operation.SPARQLQueryGeneralization; import uk.ac.open.kmi.squire.operation.SPARQLQueryInstantiation; import uk.ac.open.kmi.squire.operation.SPARQLQuerySatisfiable; +import uk.ac.open.kmi.squire.operation.SparqlQueryGeneralization; import uk.ac.open.kmi.squire.rdfdataset.IRDFDataset; import uk.ac.open.kmi.squire.utils.TreeNodez; @@ -247,7 +247,7 @@ public void generalizeToQueryTemplate() { // of Objects: " + // objects.toString()); - SPARQLQueryGeneralization qg = new SPARQLQueryGeneralization(); + SparqlQueryGeneralization qg = new SparqlQueryGeneralization(); // SUBJECT for (Node subj : subjects) { @@ -454,28 +454,28 @@ private Var ifObjectIsNotD2ThenGenerateVariable(Node obj) { // System.out.println("[QTTree::generalize] The Object is " + obj); // if (rdfd1.getClassSet().contains(o) && !(rdfd2.getClassSet().contains(o))) { if (!(rdfd2.getClassSet().contains(o))) { - result = Var.alloc(classVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_CLASS)); + result = Var.alloc(classVarTable.getOrCreateVar(o, TEMPLATE_VAR_CLASS)); return result; } else // if (rdfd1.isInIndividualSet(o) && !(rdfd2.isInIndividualSet(o))) { { if (!(rdfd2.isInIndividualSet(o))) { - result = Var.alloc(individualVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_INDIVIDUAL)); + result = Var.alloc(individualVarTable.getOrCreateVar(o, TEMPLATE_VAR_INDIVIDUAL)); return result; } else // if (rdfd1.isInObjectPropertySet(o) && !(rdfd2.isInObjectPropertySet(o))) { { if (!(rdfd2.isInObjectPropertySet(o))) { - result = Var.alloc(objectProperyVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_PROP_OBJ)); + result = Var.alloc(objectProperyVarTable.getOrCreateVar(o, TEMPLATE_VAR_PROP_OBJ)); return result; } else // if (rdfd1.isInDatatypePropertySet(o) && !(rdfd2.isInDatatypePropertySet(o))) // { { if (!(rdfd2.isInDatatypePropertySet(o))) { - result = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_PROP_DT)); + result = Var.alloc(datatypePropertyVarTable.getOrCreateVar(o, TEMPLATE_VAR_PROP_DT)); return result; } else // if (rdfd1.isInRDFVocabulary(o) && !(rdfd2.isInRDFVocabulary(o))) { { if (!(rdfd2.isInRDFVocabulary(o))) { - result = Var.alloc(rdfVocVarTable.generateVarIfAbsent(o, "rdf")); + result = Var.alloc(rdfVocVarTable.getOrCreateVar(o, "rdf")); return result; } else { result = null; @@ -492,7 +492,7 @@ private Var ifObjectIsNotD2ThenGenerateVariable(Node obj) { // "+rdfd2.getLiteralSet().toString()); if (rdfd1.isInLiteralSet(objAsString) && !(rdfd2.isInLiteralSet(objAsString))) { - result = Var.alloc(literalVarTable.generateVarIfAbsent(objAsString, TEMPLATE_VAR_LITERAL)); + result = Var.alloc(literalVarTable.getOrCreateVar(objAsString, TEMPLATE_VAR_LITERAL)); return result; } else { result = null; @@ -520,34 +520,34 @@ private Var ifObjectIsNotD2ThenGenerateVariableNew(Node obj) { String o = obj.getURI(); // System.out.println("[QTTree::generalize] The Sub is an URI " + subj); if ((rdfd1.getClassSet().contains(o)) && !(rdfd2.getClassSet().contains(o))) { - result = Var.alloc(classVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_CLASS)); + result = Var.alloc(classVarTable.getOrCreateVar(o, TEMPLATE_VAR_CLASS)); return result; } else if (rdfd1.isInObjectPropertySet(o) && !(rdfd2.isInObjectPropertySet(o))) { // if (!(rdfd2.isInObjectPropertySet(o))) { - result = Var.alloc(objectProperyVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_PROP_OBJ)); + result = Var.alloc(objectProperyVarTable.getOrCreateVar(o, TEMPLATE_VAR_PROP_OBJ)); // System.out.println("[QTTree::generalize] The Sub is an Object Property URI"); return result; } else if (rdfd1.isInDatatypePropertySet(o) && !(rdfd2.isInDatatypePropertySet(o))) { // if (!(rdfd2.isInDatatypePropertySet(o))) { - result = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_PROP_DT)); + result = Var.alloc(datatypePropertyVarTable.getOrCreateVar(o, TEMPLATE_VAR_PROP_DT)); // System.out.println("[QTTree::generalize] The Sub is an datatype Property // URI"); return result; } else if (rdfd1.isInRDFVocabulary(o) && !(rdfd2.isInRDFVocabulary(o))) { // if (!(rdfd2.isInRDFVocabulary(o))) { - result = Var.alloc(rdfVocVarTable.generateVarIfAbsent(o, "rdf")); + result = Var.alloc(rdfVocVarTable.getOrCreateVar(o, "rdf")); // System.out.println("[QTTree::generalize] The Sub is an RDF voc term URI"); return result; } else { // this means that it is an individual - result = Var.alloc(individualVarTable.generateVarIfAbsent(o, TEMPLATE_VAR_INDIVIDUAL)); + result = Var.alloc(individualVarTable.getOrCreateVar(o, TEMPLATE_VAR_INDIVIDUAL)); return result; } } else if (obj.isLiteral()) { String subjAsString = obj.getLiteralValue().toString(); - result = Var.alloc(literalVarTable.generateVarIfAbsent(subjAsString, TEMPLATE_VAR_LITERAL)); + result = Var.alloc(literalVarTable.getOrCreateVar(subjAsString, TEMPLATE_VAR_LITERAL)); return result; } else { // subject = tp.getSubject(); @@ -585,7 +585,7 @@ private Var ifPredicateIsNotD2ThenGenerateVariable(Node pred) { if (rdfd1.isInObjectPropertySet(pre) && !(rdfd2.isInObjectPropertySet(pre))) { // if (!(rdfd2.isInObjectPropertySet(pre)) && !(rdfd2.isInRDFVocabulary(pre)) && // !(rdfd1.isInDatatypePropertySet(pre))) { - result = Var.alloc(objectProperyVarTable.generateVarIfAbsent(pre, TEMPLATE_VAR_PROP_OBJ)); + result = Var.alloc(objectProperyVarTable.getOrCreateVar(pre, TEMPLATE_VAR_PROP_OBJ)); return result; } else if (rdfd1.isInDatatypePropertySet(pre) && !(rdfd2.isInDatatypePropertySet(pre))) { // { @@ -599,7 +599,7 @@ private Var ifPredicateIsNotD2ThenGenerateVariable(Node pred) { // rdfd2.isInObjectPropertySet(pre) " // + rdfd1.isInObjectPropertySet(pre)); - result = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(pre, TEMPLATE_VAR_PROP_DT)); + result = Var.alloc(datatypePropertyVarTable.getOrCreateVar(pre, TEMPLATE_VAR_PROP_DT)); return result; // if (!(rdfd2.isInDatatypePropertySet(pre)) && !(rdfd2.isInRDFVocabulary(pre))) @@ -610,7 +610,7 @@ private Var ifPredicateIsNotD2ThenGenerateVariable(Node pred) { // } } else if (rdfd1.isInRDFVocabulary(pre) && !(rdfd2.isInRDFVocabulary(pre))) { // if ((rdfd2.isInRDFVocabulary(pre))) { - result = Var.alloc(rdfVocVarTable.generateVarIfAbsent(pre, "rdf")); + result = Var.alloc(rdfVocVarTable.getOrCreateVar(pre, "rdf")); return result; } else { // System.out.println("[QTTree::ifPredicateIsNotD2ThenGenerateVariable(Node @@ -642,10 +642,10 @@ private Var ifPredicateIsNotD2ThenGenerateVariableNew(Node pred) { if (pred.isURI()) { String pre = pred.getURI(); if (rdfd1.isInObjectPropertySet(pre) && !(rdfd2.isInObjectPropertySet(pre))) { - result = Var.alloc(objectProperyVarTable.generateVarIfAbsent(pre, TEMPLATE_VAR_PROP_OBJ)); + result = Var.alloc(objectProperyVarTable.getOrCreateVar(pre, TEMPLATE_VAR_PROP_OBJ)); return result; } else if (rdfd1.isInDatatypePropertySet(pre) && !(rdfd2.isInDatatypePropertySet(pre))) { - result = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(pre, TEMPLATE_VAR_PROP_DT)); + result = Var.alloc(datatypePropertyVarTable.getOrCreateVar(pre, TEMPLATE_VAR_PROP_DT)); return result; } // else if (rdfd1.isInRDFVocabulary(pre) && !(rdfd2.isInRDFVocabulary(pre))) { // result = Var.alloc(rdfVocVarTable.generateIFAbsentRDFVocVar(pre)); @@ -674,23 +674,23 @@ private Var ifSubjectIsNotD2ThenGenerateVariable(Node subj) { String sub = subj.getURI(); if ((rdfd1.getClassSet().contains(subj)) && !(rdfd2.getClassSet().contains(subj))) { // if (!rdfd2.getClassSet().contains(o)) { - result = Var.alloc(classVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_CLASS)); + result = Var.alloc(classVarTable.getOrCreateVar(sub, TEMPLATE_VAR_CLASS)); return result; } else if (rdfd1.isInIndividualSet(sub) && !(rdfd2.isInIndividualSet(sub))) { // if (!(rdfd2.isInIndividualSet(o))) { - result = Var.alloc(individualVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_INDIVIDUAL)); + result = Var.alloc(individualVarTable.getOrCreateVar(sub, TEMPLATE_VAR_INDIVIDUAL)); return result; } else if (rdfd1.isInObjectPropertySet(sub) && !(rdfd2.isInObjectPropertySet(sub))) { // if (!(rdfd2.isInObjectPropertySet(o))) { - result = Var.alloc(objectProperyVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_PROP_OBJ)); + result = Var.alloc(objectProperyVarTable.getOrCreateVar(sub, TEMPLATE_VAR_PROP_OBJ)); return result; } else if (rdfd1.isInDatatypePropertySet(sub) && !(rdfd2.isInDatatypePropertySet(sub))) { // if (!(rdfd2.isInDatatypePropertySet(o))) { - result = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_PROP_DT)); + result = Var.alloc(datatypePropertyVarTable.getOrCreateVar(sub, TEMPLATE_VAR_PROP_DT)); return result; } else if (rdfd1.isInRDFVocabulary(sub) && !(rdfd2.isInRDFVocabulary(sub))) { // if (!(rdfd2.isInRDFVocabulary(o))) { - result = Var.alloc(rdfVocVarTable.generateVarIfAbsent(sub, "rdf")); + result = Var.alloc(rdfVocVarTable.getOrCreateVar(sub, "rdf")); return result; } else { // subject = tp.getSubject(); @@ -700,7 +700,7 @@ private Var ifSubjectIsNotD2ThenGenerateVariable(Node subj) { } else if (subj.isLiteral()) { String subjAsString = subj.getLiteralValue().toString(); if (rdfd1.isInLiteralSet(subjAsString) && !(rdfd2.isInLiteralSet(subjAsString))) { - result = Var.alloc(literalVarTable.generateVarIfAbsent(subjAsString, TEMPLATE_VAR_LITERAL)); + result = Var.alloc(literalVarTable.getOrCreateVar(subjAsString, TEMPLATE_VAR_LITERAL)); return result; } else { // subject = tp.getSubject(); @@ -726,28 +726,28 @@ private Var ifSubjectIsNotD2ThenGenerateVariableNew(Node subj) { // s= classURI String sub = subj.getURI(); if ((rdfd1.getClassSet().contains(subj)) && !(rdfd2.getClassSet().contains(subj))) { - result = Var.alloc(classVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_CLASS)); + result = Var.alloc(classVarTable.getOrCreateVar(sub, TEMPLATE_VAR_CLASS)); return result; } else if (rdfd1.isInObjectPropertySet(sub) && !(rdfd2.isInObjectPropertySet(sub))) { // if (!(rdfd2.isInObjectPropertySet(o))) { - result = Var.alloc(objectProperyVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_PROP_OBJ)); + result = Var.alloc(objectProperyVarTable.getOrCreateVar(sub, TEMPLATE_VAR_PROP_OBJ)); return result; } else if (rdfd1.isInDatatypePropertySet(sub) && !(rdfd2.isInDatatypePropertySet(sub))) { // if (!(rdfd2.isInDatatypePropertySet(o))) { - result = Var.alloc(datatypePropertyVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_PROP_DT)); + result = Var.alloc(datatypePropertyVarTable.getOrCreateVar(sub, TEMPLATE_VAR_PROP_DT)); return result; } else if (rdfd1.isInRDFVocabulary(sub) && !(rdfd2.isInRDFVocabulary(sub))) { // if (!(rdfd2.isInRDFVocabulary(o))) { - result = Var.alloc(rdfVocVarTable.generateVarIfAbsent(sub, "rdf")); + result = Var.alloc(rdfVocVarTable.getOrCreateVar(sub, "rdf")); return result; } else { // this means that it is an individual - result = Var.alloc(individualVarTable.generateVarIfAbsent(sub, TEMPLATE_VAR_INDIVIDUAL)); + result = Var.alloc(individualVarTable.getOrCreateVar(sub, TEMPLATE_VAR_INDIVIDUAL)); return result; } } else if (subj.isLiteral()) { String subjAsString = subj.getLiteralValue().toString(); - result = Var.alloc(literalVarTable.generateVarIfAbsent(subjAsString, TEMPLATE_VAR_LITERAL)); + result = Var.alloc(literalVarTable.getOrCreateVar(subjAsString, TEMPLATE_VAR_LITERAL)); return result; } else { // subject = tp.getSubject(); @@ -3191,8 +3191,7 @@ else if (isPropertyTemplateVariable(tp.getObject().getName())) { // APPLYING THE REMOVAL OPERATION if (tpSet.size() > 1) { Query parentQueryCopy = parentQuery; - RemoveTriple instance = new RemoveTriple(); - Query childQuery = instance.removeTP(parentQuery, tp.asTriple()); + Query childQuery = new RemoveTriple(parentQuery, tp.asTriple()).apply(); ArrayList childOperationList = new ArrayList(); childOperationList.addAll(pNode.getOperationList()); @@ -3813,8 +3812,7 @@ else if (isPropertyTemplateVariable(tp.getObject().getName())) { if (tpSet.size() > 1) { Query parentQueryCopy = parentQuery; - RemoveTriple instance = new RemoveTriple(); - Query childQuery = instance.removeTP(parentQuery, tp.asTriple()); + Query childQuery = new RemoveTriple(parentQuery, tp.asTriple()).apply(); ArrayList childOperationList = new ArrayList(); childOperationList.addAll(pNode.getOperationList()); diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/utils/PowerSetFactory.java b/squire/src/main/java/uk/ac/open/kmi/squire/utils/PowerSetFactory.java index 92a8ffe..928f4a0 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/utils/PowerSetFactory.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/utils/PowerSetFactory.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package uk.ac.open.kmi.squire.utils; import java.util.ArrayList; @@ -54,7 +49,6 @@ public static List> order(List> list) { public int compare(final List object1, final List object2) { // return Integer.compare(object1.size(),object2.size()); //ordering ascendende return -1 * Integer.valueOf(object1.size()).compareTo(object2.size()); // ordering discendete - } }); } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/utils/SparqlUtils.java b/squire/src/main/java/uk/ac/open/kmi/squire/utils/SparqlUtils.java index 888737b..046db15 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/utils/SparqlUtils.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/utils/SparqlUtils.java @@ -25,6 +25,7 @@ import org.apache.jena.atlas.json.JSON; import org.apache.jena.atlas.json.JsonArray; import org.apache.jena.atlas.json.JsonObject; +import org.apache.jena.atlas.json.JsonParseException; import org.apache.jena.atlas.json.JsonValue; import org.apache.jena.iri.IRIFactory; import org.apache.jena.query.QuerySolution; @@ -36,6 +37,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * A collection of utility methods for executing SPARQL queries or for + * manipulating them or their results. + * + * @author Alessandro Adamou + * + */ public class SparqlUtils { public static class SparqlException extends Exception { @@ -93,6 +101,8 @@ public static String doRawQuery(String queryString, String endpoint) throws Spar * if anything happens other than receiving a HTTP 200 OK */ public static String doRawQuery(String queryString, String endpoint, int timeout) throws SparqlException { + if (timeout < 1) throw new IllegalArgumentException( + "Sorry, waiting forever is disallowed. Timeout must be a positive integer."); log.debug("About to execute the following:"); log.debug(" * endpoint: {}", endpoint); log.debug(" * query: {}", queryString.replaceAll("\\s+", " ")); @@ -147,9 +157,22 @@ public static List extractProjectedValues(String rawJson, List inflateResultSet(List solution, log.trace("Fixed solution: {}", fixed); // Expand the other part of each reduced solution for (Map kepts : fixed2kept.get(fixed)) { - log.trace(" ... kept: {}", kepts); QuerySolutionMap solNu = new QuerySolutionMap(); // Add the part of the solution that is not reduced - for (Entry entry : fixed.entrySet()) + for (Entry entry : fixed.entrySet()) { solNu.add(entry.getKey(), entry.getValue()); - // Process every "kept" variable from the expandable part - for (Entry entry : kepts.entrySet()) { + log.trace(" ..... added: {} - {}", entry.getKey(), entry.getValue()); + } + log.trace(" ... kept: {}", kepts); + if (kepts.isEmpty()) inflated.add(solNu); + else + // Process every "kept" variable from the expandable part + for (Entry entry : kepts.entrySet()) { // First add the kept value solNu.add(entry.getKey(), entry.getValue()); log.trace(" ..... added: {} - {}", entry.getKey(), entry.getValue()); // Then iteratively expand every reduced variable over the kept one inflateSolution(solNu, reducedVars, fixed2kept, fixed, inflated); - } + } } } log.debug("DONE. Inflated to size {}", inflated.size()); @@ -317,18 +344,18 @@ private static void inflateSolution(QuerySolutionMap solution, Map return; } // TODO can we reduce this O(n^4) complexity, even though n is small for most? - for (Var kept : reducedVars.keySet()) { - log.trace("... - kept variable : {}", kept); - // iterate over the (pre-processed) variable-value bindings of the result set - for (Map keptBind : expansionPlan.get(fixedPart)) - for (Entry entry : keptBind.entrySet()) { - String var = entry.getKey(); - // Add the retained binding if not present. - // Iterate over e.g. { y1:X } , { y2:Y } - log.trace(" ... processing binding: {} - {}", var, entry.getValue()); - if (!solution.contains(var)) solution.add(var, entry.getValue()); - // Recursively expand the solution by re-adding the value for the variables that - // were reduced into the kept one. + // Iterate over the (pre-processed) variable-value bindings of the result set. + for (Map keptBind : expansionPlan.get(fixedPart)) + for (Entry entry : keptBind.entrySet()) { + String var = entry.getKey(); + // Add the retained binding if not present. + // Iterate over e.g. { y1:X } , { y2:Y } + log.trace(" ... processing binding: {} - {}", var, entry.getValue()); + if (!solution.contains(var)) solution.add(var, entry.getValue()); + // Recursively expand the solution by re-adding the value for the variables that + // were reduced into the kept one. + for (Var kept : reducedVars.keySet()) { + log.trace("... - kept variable : {}", kept); for (Var reduced : reducedVars.get(kept)) { // Each reduced variable generates a new (cloned) solution, so recurse into it log.trace("... - reduced variable : {}", reduced); @@ -344,7 +371,7 @@ private static void inflateSolution(QuerySolutionMap solution, Map } } - } + } } diff --git a/squire/src/main/java/uk/ac/open/kmi/squire/utils/TreeNodez.java b/squire/src/main/java/uk/ac/open/kmi/squire/utils/TreeNodez.java index 8d26591..df6d134 100644 --- a/squire/src/main/java/uk/ac/open/kmi/squire/utils/TreeNodez.java +++ b/squire/src/main/java/uk/ac/open/kmi/squire/utils/TreeNodez.java @@ -26,9 +26,7 @@ public TreeNodez(T data, List> children) { } public void addChild(TreeNodez child) { - if (this.children == null) { - this.children = new ArrayList<>(); - } + if (this.children == null) this.children = new ArrayList<>(); this.children.add(child);// .addSibling(childNode); } diff --git a/squire/src/test/java/uk/ac/open/kmi/squire/utils/SparqlUtilsTest.java b/squire/src/test/java/uk/ac/open/kmi/squire/utils/SparqlUtilsTest.java index 7857fd0..bc1f3ec 100644 --- a/squire/src/test/java/uk/ac/open/kmi/squire/utils/SparqlUtilsTest.java +++ b/squire/src/test/java/uk/ac/open/kmi/squire/utils/SparqlUtilsTest.java @@ -33,6 +33,34 @@ public class SparqlUtilsTest { + _valMod + "\" } , " + "\"title\": { \"type\": \"literal\" , " + "\"value\": \"" + _valTitle + "\" } } ] }}"; + @Test + public void inflateBindingsNoReduction() throws Exception { + // Build the reduction map + Map> reducedVars = new HashMap<>(); + + // Build the reduced query solutions + List solsRed = new ArrayList<>(); + addSolution(solsRed, "A", "X"); + addSolution(solsRed, "A", "Y"); + addSolution(solsRed, "B", "Z"); + addSolution(solsRed, "C", "Z"); + addSolution(solsRed, "B", "Y"); + + List expanded = SparqlUtils.inflateResultSet(solsRed, reducedVars); + assertFalse(expanded.isEmpty()); + assertSame(5, expanded.size()); + assertTrue(checkSolution(expanded, "A", "X")); + assertTrue(checkSolution(expanded, "A", "Y")); + assertTrue(checkSolution(expanded, "B", "Z")); + assertTrue(checkSolution(expanded, "C", "Z")); + assertTrue(checkSolution(expanded, "B", "Y")); + + assertFalse(checkSolution(expanded, "A", "Z")); + assertFalse(checkSolution(expanded, "B", "X")); + assertFalse(checkSolution(expanded, "C", "X")); + assertFalse(checkSolution(expanded, "C", "Y")); + } + @Test public void inflateBindingsEmptyReduction() throws Exception { // Build the reduction map @@ -50,6 +78,7 @@ public void inflateBindingsEmptyReduction() throws Exception { List expanded = SparqlUtils.inflateResultSet(solsRed, reducedVars); assertFalse(expanded.isEmpty()); + assertSame(5, expanded.size()); assertTrue(checkSolution(expanded, "A", "X")); assertTrue(checkSolution(expanded, "A", "Y")); assertTrue(checkSolution(expanded, "B", "Z"));