Single Query - RittoShadow/QCan GitHub Wiki

Single Query

This class encapsulates the steps of the algorithm used to canonicalise. There are two main constructors:

public SingleQuery(String q, boolean canon, boolean rewrite, boolean minimise, boolean pathNormalisation, boolean verbose)

This constructor takes the query as a String, and various booleans in order to customise the canonicalisation process:

  • canon To enable the canonical labeling.
  • rewrite To enable the rewriting of monotonic sub-queries into equivalent UCQs.
  • minimise To enable the leaning of BGPs and UCQs.
  • pathNormalisation To enable the normalisation of property paths. Still mostly experimental.
  • verbose To show intermediate results such as the structure of the r-graph during execution.
public SingleQuery(Op op) {
		this.op = op;
		parseQuery(op);
		canonicalise();
		buildQuery();
	}

Op is the superclass of operators that compose the SPARQL Algebra provided by Jena. This constructor takes an Op structure, while the canonical labeling, rewrite and minimisation steps are enabled by default.

The method parseQuery constructs an r-graph that represents the input query. The class RGraphBuilder (using the interface OpVisitor provided by Jena) traverses the Op structure in a bottom-up manner. In addition, if the rewrite is enabled, the Op structure is first normalised by rewriting monotonic sub-queries into equivalent (U)CQs, filter expressions are pushed outside and rewritten when possible, etc. Most of the rewriting rules are described in the work of Schmidt et al. (available here). The result of this is an RGraph object corresponding to the input query.

Following this, and assuming either the canonical labeling or leaning are enabled, the canonicalise method calls the RGraph method getCanonicalForm which computes a new RGraph that represents the canonical form of the original query.

Finally, the buildQuery method creates a QueryBuilder object that takes the canonical RGraph and computes the Op structure of the query. Subsequently, we use Jena's native methods to transform the Op structure into a Query structure, and then finally a String.