//// (c) 2005 Andreas Harth //package org.semanticweb.yars.engine; // //import java.util.ArrayList; //import java.util.Collections; //import java.util.Iterator; //import java.util.logging.Logger; // //import org.semanticweb.yars.api.n3.List; //import org.semanticweb.yars.api.n3.Quad; //import org.semanticweb.yars.api.n3.QuadSet; //import org.semanticweb.yars.api.n3.Query; //import org.semanticweb.yars.api.rdf.NodeSet; //import org.semanticweb.yars.api.rdf.Resource; //import org.semanticweb.yars.engine.datalog.Answer; //import org.semanticweb.yars.engine.datalog.DatalogPlan; //import org.semanticweb.yars.engine.datalog.FilterIneq; //import org.semanticweb.yars.engine.datalog.NafOp; //import org.semanticweb.yars.engine.datalog.NotOp; //import org.semanticweb.yars.engine.datalog.OrOp; //import org.semanticweb.yars.engine.datalog.Subgoal; //import org.semanticweb.yars.engine.exec.local.ExecIterator; //import org.semanticweb.yars.engine.exec.local.ExecPlan; //import org.semanticweb.yars.engine.relational.RelationalOp; //import org.semanticweb.yars.engine.relational.RelationalPlan; //import org.semanticweb.yars.index.DataStore; // ///** // * Here are static methods that perform the compilation steps // * from the logic program to relational algebra to access // * operators. // * // * see http://hake.stanford.edu/~widom/cs346/qpnotes.html // * // * @author aharth // */ //public class RewriteEngine { // // logging // private static Logger _log = Logger.getLogger("org.semanticweb.yars.engine.RewriteEngine"); // // /** // * get the plans in XML format. // * // * @param query // * @param ds // * @return // */ // public static String getPlansXML(Query rule, DataStore ds, Resource context) throws QueryException { // StringBuffer buf = new StringBuffer(); // long timeStart = System.currentTimeMillis(); // // buf.append("<?xml version='1.0' encoding='utf-8'?>\n"); // // buf.append("<query><n3>"); // buf.append(rule.toN3()); // /* // for (int i = 0; i < query.size(); i++) { // buf.append("<quad><![CDATA[\n"); // buf.append(query.get(i)); // buf.append("]]></quad>\n"); // } // */ // buf.append("</n3>"); // // DatalogPlan p = RewriteEngine.queryToLogic(rule, context); // buf.append("<log>"); // buf.append(p.toXML()); // buf.append("</log>"); // LogicalOlapQueryPlan rp = RewriteEngine.logicToRelational(p); // buf.append("<rp>"); // buf.append(rp.toXML()); // buf.append("</rp>"); // buf.append("<acc>"); // ExecPlan ap = RewriteEngine.relationalToExec(rp, ds); // buf.append(ap.toXML()); // buf.append("</acc>"); // // long timeEnd = System.currentTimeMillis(); // // buf.append("<time>"); // buf.append(timeEnd-timeStart); // buf.append(" ms</time>"); // buf.append("</query>"); // // return new String(buf); // } // // /** // * Get a complete physical access plan. // * // * @param context the context which should be the default context for this query // */ // public static ExecPlan getAccessPlan(Query query, DataStore ds, Resource context) throws QueryException { // DatalogPlan log = queryToLogic(query, context); // LogicalOlapQueryPlan rp = logicToRelational(log); // // return relationalToExec(rp, ds); // } // // /** // * Rewrite a query to a program. // * This is done here and not in a Query2Datalog object using the visitor pattern (XXX why not?) // * // * @param query the query object // * @param context the context where the query was posed // */ // public static DatalogPlan queryToLogic(Query query, Resource context) { // _log.fine("rewriting query " + query); // // NodeSet select = query.getSelect(); // QuadSet where = query.getWhere(); // // where.setDefaultContext(context); // // OrOp root = new OrOp(); // Iterator it = null; // // // select part can be either a set of quads (template) or a list // if (select instanceof QuadSet) { // it = select.iterator(); // // while (it.hasNext()) { // root.add(new Subgoal((Quad)it.next())); // } // } else if (select instanceof List) { // ArrayList list = ((List)select).getList(); // root.add(new Answer(list, query.getDistinct())); // } // // // optimize (sort statements based on number of variables) // // that's resembling a join reordering optimization // // keyword quads have weight 0, that is, they // // are evaluated first // Collections.sort(where); // // it = where.iterator(); // // // the keyword stuff is only evaluated in // // raltional2exec, because the keywords things // // amounts to a join // while (it.hasNext()) { // NotOp not = new NotOp(); // Quad quad = (Quad)it.next(); // if (quad.isNafQuad()) { // NafOp naf = new NafOp(); // naf.add(new Subgoal(quad)); // not.add(naf); // } else if (quad.isIneqQuad()) { // FilterIneq ineq = new FilterIneq(quad); // not.add(ineq); // } else { // not.add(new Subgoal(quad)); // } // // root.add(not); // } // // return new DatalogPlan(root); // } // // /** // * Rewrite a program to a plan. // * // * Basically, do a union-find to detect unions and joins. // */ // public static LogicalOlapQueryPlan logicToRelational(DatalogPlan p) throws QueryException { // RelationalOp newRoot = (RelationalOp)p.visitAll(new Datalog2Relational()); // // return new LogicalOlapQueryPlan(newRoot); // } // // /** // * Rewrite a relational algebra plan to a physical access plan. // */ // public static ExecPlan relationalToExec(LogicalOlapQueryPlan rp, DataStore ds) throws QueryException { // Relational2Exec r2a = new Relational2Exec(ds); // ExecIterator newRoot = (ExecIterator)rp.visitAll(r2a); // // _log.finer("bytes iterator " + newRoot); // // ExecPlan ap = new ExecPlan(newRoot); // // return ap; // } //}