Skip to content

Commit

Permalink
Added code to recommend property path between two variables sindice#3
Browse files Browse the repository at this point in the history
Refactored the code to map a query to a DGS query using a Pipeline design pattern
  • Loading branch information
bibhas committed Jul 18, 2012
1 parent a30ead3 commit cd2d756
Show file tree
Hide file tree
Showing 40 changed files with 2,180 additions and 1,253 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import org.openrdf.query.Binding;
import org.openrdf.query.BindingSet;
import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder;
import org.sindice.analytics.queryProcessor.QueryProcessor;
import org.sindice.analytics.queryProcessor.QueryProcessor.RecommendationType;
import org.sindice.analytics.queryProcessor.RecommendationType;
import org.sindice.analytics.queryProcessor.SparqlToDGSQueryInterface;
import org.sindice.analytics.ranking.Label;
import org.sindice.analytics.ranking.Label.LabelType;
import org.sindice.core.sesame.backend.SesameBackend.QueryIterator.QueryResultProcessor;
Expand All @@ -50,27 +50,34 @@ public Context getContext() {
@Override
public Label process(Object o, Context c) {
final Label label;
final BindingSet set = (BindingSet) o; // The DGS query is a SELECT query
final Iterator<Binding> it = set.iterator();
if(o instanceof BindingSet) {
final BindingSet set = (BindingSet) o; // The DGS query is a SELECT query
final Iterator<Binding> it = set.iterator();

final Value pof = set.getValue(SyntaxTreeBuilder.PointOfFocus);
final Value pofCard = set.getValue(QueryProcessor.CARDINALITY_VAR);
final Value pofResource = set.getValue(QueryProcessor.POF_RESOURCE);
final Value pof = set.getValue(SyntaxTreeBuilder.PointOfFocus);
final Value pofCard = set.getValue(SparqlToDGSQueryInterface.CARDINALITY_VAR);
final Value pofResource = set.getValue(SparqlToDGSQueryInterface.POF_RESOURCE);

if (pof != null && pofCard != null && pofResource != null) {
final LabelType type = (pof instanceof URI) ? LabelType.URI : LabelType.LITERAL;
label = new Label(type, pof.stringValue(), Long.valueOf(pofCard.stringValue()));
while (it.hasNext()) {
final Binding binding = it.next();
if (pof != null && pofCard != null && pofResource != null) {
final LabelType type = (pof instanceof URI) ? LabelType.URI : LabelType.LITERAL;
label = new Label(type, pof.stringValue(), Long.valueOf(pofCard.stringValue()));
while (it.hasNext()) {
final Binding binding = it.next();

if (!binding.getName().equals(SyntaxTreeBuilder.PointOfFocus) &&
!binding.getName().equals(QueryProcessor.CARDINALITY_VAR)) {
label.addContext(binding.getName(), binding.getValue().stringValue());
}
}
return label;
if (!binding.getName().equals(SyntaxTreeBuilder.PointOfFocus) &&
!binding.getName().equals(SparqlToDGSQueryInterface.CARDINALITY_VAR)) {
label.addContext(binding.getName(), binding.getValue().stringValue());
}
}
return label;
}
}
else if(o instanceof Boolean){
final Boolean ans = (Boolean) o;
return new Label(LabelType.NONE, ans.toString(), -1);
}
return new Label(LabelType.NONE, "", -1);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public Object visit(ASTAskQuery node, Object data)
final StringBuilder sb = (StringBuilder) data;

sb.append("ASK\n");
node.childrenAccept(this, data);
return data;
}

Expand Down Expand Up @@ -562,8 +563,14 @@ public Object visit(ASTIRI node, Object data)
public Object visit(ASTVar node, Object data)
throws VisitorException {
final StringBuilder sb = (StringBuilder) data;

sb.append('?').append(node.getName()).append(' ');

// if (node.getName().startsWith("?")) { // only the POF can start with '?'
// sb.append(node.getName()).append("< ");
// }
if (node.getName().equals("?POF"))
sb.append(node.getName()).append(' ');
else
sb.append('?').append(node.getName()).append(' ');
return data;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*******************************************************************************
* Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved.
*
*
* This project is a free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This project is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package org.sindice.analytics.queryProcessor;

import java.util.ArrayList;
import java.util.List;

import org.openrdf.query.MalformedQueryException;
import org.openrdf.sindice.query.parser.sparql.ASTVisitorBase;
import org.openrdf.sindice.query.parser.sparql.ast.ASTBasicGraphPattern;
import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer;
import org.openrdf.sindice.query.parser.sparql.ast.ASTTriplesSameSubjectPath;
import org.openrdf.sindice.query.parser.sparql.ast.ASTVar;
import org.openrdf.sindice.query.parser.sparql.ast.ParseException;
import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilder;
import org.openrdf.sindice.query.parser.sparql.ast.SyntaxTreeBuilderTreeConstants;
import org.openrdf.sindice.query.parser.sparql.ast.VisitorException;
import org.sindice.analytics.backend.DGSQueryResultProcessor.Context;
import org.sindice.analytics.ranking.Label;
import org.sindice.core.sesame.backend.SesameBackendException;
import org.sindice.core.sesame.backend.SesameBackend.QueryIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author bibhas [Jul 9, 2012]
* @email bibhas.das@deri.org
*
*/
public class AddOneHopPropertyPath implements BasicOperation {

private static final Logger logger = LoggerFactory.getLogger(AddOneHopPropertyPath.class);

private final SparqlTranslationProcessor sparql2dgs;
private final Select2Ask selectToAsk = new Select2Ask();

public AddOneHopPropertyPath(SparqlTranslationProcessor sparql2dgs) {
this.sparql2dgs = sparql2dgs;
}

private class HopsVarsPair {
int hops;
final ArrayList<String> varsToProject = new ArrayList<String>();

public void reset(int hops) {
this.hops = hops;
varsToProject.clear();
}
}

public PipelineObject process(PipelineObject po)
throws VisitorException, MalformedQueryException, ParseException, SesameBackendException {
if (!po.getType().equals(RecommendationType.PREDICATE)) {
return po;
}

String query = AST2TextTranslator.translate(po.getAst());
final AddHopVisitor obj = new AddHopVisitor();
int hops = 1;
final HopsVarsPair hopsVars = new HopsVarsPair();
while (hops <= po.getMAX_HOPS()) {
po = sparql2dgs.process(po);
ASTQueryContainer ast = selectToAsk.convert(po.getAst());
QueryIterator<Label, Context> qit = po.getBackend().submit(
AST2TextTranslator.translate(ast));
qit.hasNext();
if (qit.next().getLabel().equals("true")) {
logger.debug("Property Path Recommendation: Breaking out....");
break;
}
if (++hops > po.getMAX_HOPS())
break;
hopsVars.reset(hops);
po.setAst(SyntaxTreeBuilder.parseQuery(query));
obj.visit(po.getAst(), hopsVars);
query = AST2TextTranslator.translate(po.getAst());
po.getVarsToProject().addAll(hopsVars.varsToProject);
}
po.setAst(SyntaxTreeBuilder.parseQuery(query));
return po;
}

public class AddHopVisitor extends ASTVisitorBase {
public Object visit(ASTBasicGraphPattern node, Object data)
throws VisitorException {
final HopsVarsPair hopsVars = (HopsVarsPair) data;
final int hops = hopsVars.hops;
final ArrayList<String> set = hopsVars.varsToProject;
boolean foundPOF = false;

final ASTBasicGraphPattern bgpDGS = new ASTBasicGraphPattern(SyntaxTreeBuilderTreeConstants.JJTBASICGRAPHPATTERN);
ASTTriplesSameSubjectPath triple = null;

// find the ?POF variable in the triple pattern
final List<ASTTriplesSameSubjectPath> tpList = node
.jjtGetChildren(ASTTriplesSameSubjectPath.class);
while (true) {
triple = tpList.remove(0);
if (triple.jjtGetChild(1).jjtGetChild(0) instanceof ASTVar) {
if (((ASTVar) triple.jjtGetChild(1).jjtGetChild(0)).getName().equals(SyntaxTreeBuilder.PointOfFocus)) {
foundPOF = true;
break;
}
}
bgpDGS.jjtAppendChild(triple);
}

if (foundPOF) {
for (int i = 2; i < hops; i++) {
bgpDGS.jjtAppendChild(triple);
triple = tpList.remove(0);
}
final ASTVar targetNode = (ASTVar) triple.jjtGetChild(1).jjtGetChild(1)
.jjtGetChild(0);

// change the existing triple
final ASTVar newObject = ASTVarGenerator.getASTVar("ob");
set.add(newObject.getName());
final ASTVar newPOF = ASTVarGenerator.getASTVar(SyntaxTreeBuilder.PointOfFocus);
set.add(newPOF.getName());
final ASTTriplesSameSubjectPath t1 = ASTProcessorUtil.createTriple(triple
.jjtGetChild(0), triple.jjtGetChild(1).jjtGetChild(0), newObject);
final ASTTriplesSameSubjectPath t2 = ASTProcessorUtil.createTriple(newObject,
newPOF, targetNode);

bgpDGS.jjtAppendChild(t1);
bgpDGS.jjtAppendChild(t2);

// add rest of the triples in the BGP
for (ASTTriplesSameSubjectPath tp: tpList) {
bgpDGS.jjtAppendChild(tp);
}
node.jjtReplaceWith(bgpDGS);
}

return super.visit(node, data);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2012 National University of Ireland, Galway. All Rights Reserved.
*
*
* This project is a free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This project is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package org.sindice.analytics.queryProcessor;

import org.sindice.analytics.queryProcessor.PipelineObject;

/**
* @author bibhas [Jul 11, 2012]
* @email bibhas.das@deri.org
*
*/
public interface BasicOperation {

public PipelineObject process(PipelineObject obj) throws Exception;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.openrdf.sindice.query.parser.sparql.ast.ASTPathAlternative;
import org.openrdf.sindice.query.parser.sparql.ast.ASTPropertyList;
import org.openrdf.sindice.query.parser.sparql.ast.ASTPropertyListPath;
import org.openrdf.sindice.query.parser.sparql.ast.ASTQueryContainer;
import org.openrdf.sindice.query.parser.sparql.ast.ASTRDFLiteral;
import org.openrdf.sindice.query.parser.sparql.ast.ASTTriplesSameSubjectPath;
import org.openrdf.sindice.query.parser.sparql.ast.ASTTrue;
Expand All @@ -47,15 +46,12 @@
* @email stephane.campinas@deri.org
*
*/
public final class ContentRemovalProcessor {
public final class ContentRemovalProcessor implements BasicOperation{

private ContentRemovalProcessor() {
}

public static void process(ASTQueryContainer ast)
throws VisitorException {
public PipelineObject process(PipelineObject obj) throws VisitorException {
final ContentRemovalVisitor c = new ContentRemovalVisitor();
c.visit(ast, null);
c.visit(obj.getAst(), null);
return obj;
}

private static class ContentRemovalVisitor extends ASTVisitorBase {
Expand Down
Loading

0 comments on commit cd2d756

Please sign in to comment.