You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by bu...@apache.org on 2012/01/25 00:39:41 UTC

svn commit: r803222 - in /websites/staging/jena/trunk/content/jena/documentation/query: index.html manipulating_sparql_using_arq.html

Author: buildbot
Date: Tue Jan 24 23:39:41 2012
New Revision: 803222

Log:
Staging update by buildbot for jena

Added:
    websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html
Modified:
    websites/staging/jena/trunk/content/jena/documentation/query/index.html

Modified: websites/staging/jena/trunk/content/jena/documentation/query/index.html
==============================================================================
--- websites/staging/jena/trunk/content/jena/documentation/query/index.html (original)
+++ websites/staging/jena/trunk/content/jena/documentation/query/index.html Tue Jan 24 23:39:41 2012
@@ -185,6 +185,7 @@ SPARQL is the query language developed b
 <li><a href="cmds.html">Command line utilities</a></li>
 <li><a href="logging.html">Logging</a></li>
 <li><a href="explain.html">Explaining queries</a></li>
+<li><a href="manipulating_sparql_using_arq.html">Tutorial: manipulating SPARQL using ARQ</a></li>
 </ul>
 <h2 id="advanced_sparql_use">Advanced SPARQL use</h2>
 <p>Features of ARQ that are legal SPARQL syntax.</p>

Added: websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html
==============================================================================
--- websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html (added)
+++ websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html Tue Jan 24 23:39:41 2012
@@ -0,0 +1,360 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE- 2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+  <link href="/jena/css/jena.css" rel="stylesheet" type="text/css">
+  <title>Apache Jena - Tutorial - Manipulating SPARQL using ARQ</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  <script src="/jena/js/jquery-1.6.4.min.js" type="text/javascript"></script>
+  <script src="/jena/js/jena-navigation.js" type="text/javascript"></script>
+</head>
+
+<body>
+  <div id="header">
+    <div id="logoblock">
+    <img alt="Apache Jena" src="/jena/images/jena-logo/jena-logo-small.png"/>
+    </div>
+
+    <div id="titleblock">
+      <h1 class="title">Apache Jena</h1>
+      <div id="topmenu" class="tabbar round-10">
+        <ul>
+        <li class="round-top-8"><a class="round-top-8" href="/jena/index.html" id="home_menu">Home</a></li>
+        <li class="round-top-8"><a class="round-top-8" href="/jena/help_and_support/index.html">Support</a></li>
+        <li class="round-top-8"><a class="round-top-8" href="/jena/getting_started/index.html">Getting started</a></li>
+        <li class="round-top-8"><a class="round-top-8" href="/jena/tutorials/index.html">Tutorials</a></li>
+        <li class="round-top-8"><a class="round-top-8" href="/jena/documentation/index.html">Documentation</a></li>
+        </ul>
+      </div>
+    </div>
+  </div>
+
+  <div id="navigation" class="clear">
+  <h1 id="quick_links">Quick links</h1>
+<ul>
+<li><a href="/jena/index.html">Home</a></li>
+<li><a href="/jena/download/index.html">Downloads</a></li>
+<li><a href="/jena/help_and_support/index.html">Help and support</a></li>
+<li><a href="/jena/help_and_support/bugs_and_suggestions.html">Report a bug</a></li>
+<li><a href="/jena/about_jena/roadmap.html">Roadmap</a></li>
+<li><a href="/jena/getting_involved/index.html">Getting involved</a></li>
+<li><a href="/jena/documentation/">Documentation</a></li>
+</ul>
+<h1 id="about_jena">About Jena</h1>
+<ul>
+<li><a href="/jena/index.html">Home</a></li>
+<li><a href="/jena/about_jena/about.html">About Jena</a></li>
+<li><a href="/jena/about_jena/architecture.html">Architecture</a></li>
+<li><a href="/jena/about_jena/roadmap.html">Roadmap</a></li>
+<li><a href="/jena/about_jena/team.html">Project team</a></li>
+<li><a href="/jena/about_jena/contributions.html">Related projects</a></li>
+</ul>
+<h1 id="download">Download</h1>
+<ul>
+<li><a href="/jena/download/index.html">Downloading Jena</a></li>
+<li><a href="/jena/download/maven.html">Using Maven</a></li>
+<li><a href="/jena/download/osgi.html">Using OSGi</a></li>
+</ul>
+<h1 id="help_and_support">Help and support</h1>
+<ul>
+<li><a href="/jena/help_and_support/index.html">Getting help</a></li>
+<li><a href="/jena/help_and_support/bugs_and_suggestions.html">Bugs and suggestions</a></li>
+</ul>
+<h1 id="getting_started">Getting Started</h1>
+<ul>
+<li><a href="/jena/getting_started/index.html">A first Jena project</a></li>
+<li><a href="/jena/getting_started/rdf_api.html">RDF API overview</a></li>
+<li><a href="/jena/getting_started/sparql.html">Querying RDF with SPARQL</a></li>
+<li><a href="/jena/getting_started/fuseki.html">Serving RDF over HTTP</a></li>
+<li><a href="/jena/getting_started/tell_me_how.html">Tell me how to ...</a></li>
+</ul>
+<h1 id="tutorials">Tutorials</h1>
+<ul>
+<li><a href="/jena/tutorials/index.html">Tutorials index</a></li>
+<li><a href="/jena/tutorials/rdf_api.html">RDF tutorial</a></li>
+<li><a href="/jena/tutorials/sparql.html">SPARQL queries</a></li>
+<li><a href="/jena/tutorials/using_jena_with_eclipse.html">Using Jena with Eclipse</a></li>
+</ul>
+<h1 id="documentation">Documentation</h1>
+<ul>
+<li><a href="/jena/documentation/index.html">Overview</a></li>
+<li><a href="/jena/documentation/javadoc">Javadoc</a></li>
+<li><a href="/jena/documentation/rdf/index.html">RDF</a></li>
+<li><a href="/jena/documentation/query/index.html">SPARQL (ARQ)</a><ul>
+<li><a href="/jena/documentation/query/app_api.html">Application API</a></li>
+<li><a href="/jena/documentation/query/cmds.html">Command line utilities</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/tdb/index.html">TDB</a><ul>
+<li><a href="/jena/documentation/tdb/tdb_transactions.html">API for Transactions</a></li>
+<li><a href="/jena/documentation/tdb/assembler.html">Dataset Assembler</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/sdb/index.html">SDB</a></li>
+<li><a href="/jena/documentation/larq/index.html">LARQ</a></li>
+<li><a href="/jena/documentation/serving_data/index.html">Fuseki: Serving Data</a></li>
+<li><a href="/jena/documentation/ontology/index.html">Ontology</a></li>
+<li><a href="/jena/documentation/inference/index.html">Inference</a></li>
+<li><a href="/jena/documentation/assembler/index.html">Assembler</a><ul>
+<li><a href="/jena/documentation/assembler/assembler-howto.html">Assembler how-to</a></li>
+<li><a href="/jena/documentation/assembler/inside-assemblers.html">Inside assemblers</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/io/index.html">I/O</a><ul>
+<li><a href="/jena/documentation/io/iohowto.html">I/O how-to</a></li>
+<li><a href="/jena/documentation/io/riot.html">RIOT</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/notes/index.html">Notes</a><ul>
+<li><a href="/jena/documentation/notes/concurrency-howto.html">Concurrency how-to</a></li>
+<li><a href="/jena/documentation/notes/event-handler-howto.html">Event handler how-to</a></li>
+<li><a href="/jena/documentation/notes/file-manager.html">File manager how-to</a></li>
+<li><a href="/jena/documentation/notes/model-factory.html">Model factory how-to</a></li>
+<li><a href="/jena/documentation/notes/rdf-frames.html">RDF frames</a></li>
+<li><a href="/jena/documentation/notes/reification.html">Reification how-to</a></li>
+<li><a href="/jena/documentation/notes/typed-literals.html">Typed literals how-to</a></li>
+<li><a href="/jena/documentation/notes/iri.html">Support for IRI's</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/tools/index.html">Tools</a><ul>
+<li><a href="/jena/documentation/tools/schemagen.html">schemagen</a></li>
+<li><a href="/jena/documentation/tools/eyeball-getting-started.html">eyeball</a></li>
+</ul>
+</li>
+</ul>
+<h1 id="getting_involved">Getting Involved</h1>
+<ul>
+<li><a href="/jena/getting_involved/index.html">Contributing to Jena</a></li>
+</ul>
+<h1 id="asf_links">ASF links</h1>
+<ul>
+<li><a href="http://www.apache.org">Apache Software Foundation</a></li>
+<li><a href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li>
+<li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+<li><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a></li>
+<li><a href="http://www.apache.org/security/">Security</a></li>
+</ul>
+  </div>
+
+  <div id="content">
+    <h1 class="title">Tutorial - Manipulating SPARQL using ARQ</h1>
+    <p>When you've been working with SPARQL you quickly find that static
+queries are restrictive. Maybe you want to vary a value, perhaps add a
+filter, alter the limit, etc etc. Being an impatient sort you dive in to
+the query string, and it works. But what about <a href="http://xkcd.com/327/">little Bobby
+Tables</a>? And, even if you
+sanitise your inputs, string manipulation is a fraught process and
+syntax errors await you. Although it might seem harder than string
+munging, the ARQ API is your friend in the long run.</p>
+<p><em>Originally published on the <a href="http://researchrevealed.ilrt.bris.ac.uk/?p=35">Research Revealed project
+blog</a></em></p>
+<h2 id="inserting_values_simple_prepared_statements">Inserting values (simple prepared statements)</h2>
+<p>Let's begin with something simple. Suppose we wanted to restrict the
+following query to a particular person:</p>
+<div class="codehilite"><pre>   <span class="nb">select</span> <span class="o">*</span> <span class="p">{</span><span class="err"> </span><span class="p">?</span><span class="n">person</span> <span class="sr">&lt;http://xmlns.com/foaf/0.1/name&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">name</span> <span class="p">}</span>
+</pre></div>
+
+
+<p><code>String#replaceAll</code> would work, but there is a safer way.
+<code>QueryExecutionFactory</code> in most cases lets you supply a <code>QuerySolution</code>
+with which you can prebind values.</p>
+<div class="codehilite"><pre>   <span class="n">QuerySolutionMap</span> <span class="n">initialBinding</span> <span class="o">=</span> <span class="k">new</span> <span class="n">QuerySolutionMap</span><span class="p">();</span>
+   <span class="n">initialBinding</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">,</span> <span class="n">personResource</span><span class="p">);</span>
+   <span class="n">qe</span> <span class="o">=</span> <span class="n">QueryExecutionFactory</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">dataset</span><span class="p">,</span> <span class="n">initialBinding</span><span class="p">);</span>
+</pre></div>
+
+
+<p>This is often much simpler than the string equivalent since you don't
+have to escape quotes in literals. (Beware that this doesn't work for
+<code>sparqlService</code>, which is a great shame. It would be nice to spend some
+time remedying that.)</p>
+<h2 id="making_a_query_from_scratch">Making a Query from Scratch</h2>
+<p>The previously mentioned limitation is due to the fact that prebinding
+doesn't actually change the query at all, but the execution of that
+query. So what how do we really alter queries?</p>
+<p>ARQ provides two ways to work with queries: at the syntax level (<code>Query</code>
+and <code>Element</code>), or the algebra level (<code>Op</code>). The distinction is clear in
+filters:</p>
+<div class="codehilite"><pre>   <span class="n">SELECT</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="p">{</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;http://example.com/val&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">val</span> <span class="o">.</span> <span class="n">FILTER</span> <span class="p">(</span><span class="err"> </span><span class="p">?</span><span class="n">val</span> <span class="o">&lt;</span> <span class="mi">20</span> <span class="p">)</span> <span class="p">}</span>
+</pre></div>
+
+
+<p>If you work at the syntax level you'll find that this looks (in pseudo
+code) like:</p>
+<div class="codehilite"><pre>   <span class="p">(</span><span class="n">GROUP</span> <span class="p">(</span><span class="n">PATTERN</span> <span class="p">(</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;http://example.com/val&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">val</span> <span class="p">))</span> <span class="p">(</span><span class="n">FILTER</span> <span class="p">(</span> <span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">val</span> <span class="mi">20</span> <span class="p">)</span> <span class="p">))</span>
+</pre></div>
+
+
+<p>That is there's a group containing a triple pattern and a filter, just
+as you see in the query. The algebra is different, and we can see it
+using <code>arq.qparse --print op</code></p>
+<div class="codehilite"><pre>   <span class="nv">$</span> <span class="nv">java</span> <span class="n">arq</span><span class="o">.</span><span class="n">qparse</span> <span class="o">--</span><span class="k">print</span> <span class="n">op</span> <span class="s">&#39;SELECT ?s { ?s &lt;http://example.com/val&gt; ?val . FILTER ( ?val &lt; 20 ) }&#39;</span>
+   <span class="p">(</span><span class="n">base</span> <span class="sr">&lt;file:///...&gt;</span>
+       <span class="p">(</span><span class="n">project</span> <span class="p">(?</span><span class="n">s</span><span class="p">)</span>
+           <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">val</span> <span class="mi">20</span><span class="p">)</span>
+               <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;http://example.com/val&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">val</span><span class="p">)))))</span>
+</pre></div>
+
+
+<p>Here the filter contains the pattern, rather than sitting next to it.
+This form makes it clear that the expression is filtering the pattern.</p>
+<p>Let's create that query from scratch using ARQ. We begin with some
+common pieces: the triple to match, and the expression for the filter.</p>
+<div class="codehilite"><pre>   <span class="sr">//</span><span class="err"> </span><span class="p">?</span><span class="n">s</span><span class="err"> </span><span class="p">?</span><span class="n">p</span><span class="err"> </span><span class="p">?</span><span class="n">o</span> <span class="o">.</span>
+   <span class="n">Triple</span> <span class="n">pattern</span> <span class="o">=</span>
+       <span class="n">Triple</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">&quot;s&quot;</span><span class="p">),</span> <span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">&quot;p&quot;</span><span class="p">),</span> <span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">&quot;o&quot;</span><span class="p">));</span>
+   <span class="sr">//</span> <span class="p">(</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="o">&lt;</span> <span class="mi">20</span> <span class="p">)</span>
+   <span class="n">Expr</span> <span class="n">e</span> <span class="o">=</span> <span class="k">new</span> <span class="n">E_LessThan</span><span class="p">(</span><span class="k">new</span> <span class="n">ExprVar</span><span class="p">(</span><span class="s">&quot;s&quot;</span><span class="p">),</span> <span class="k">new</span> <span class="n">NodeValueInteger</span><span class="p">(</span><span class="mi">20</span><span class="p">));</span>
+</pre></div>
+
+
+<p><code>Triple</code> should be familiar from jena. <code>Var</code> is an extension of <code>Node</code>
+for variables. <code>Expr</code> is the root interface for expressions, those
+things that appear in <code>FILTER</code> and <code>LET</code>.</p>
+<p>First the syntax route:</p>
+<div class="codehilite"><pre>   <span class="n">ElementTriplesBlock</span> <span class="n">block</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ElementTriplesBlock</span><span class="p">();</span> <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">BGP</span>
+   <span class="n">block</span><span class="o">.</span><span class="n">addTriple</span><span class="p">(</span><span class="n">pattern</span><span class="p">);</span>                              <span class="sr">//</span> <span class="n">Add</span> <span class="k">our</span> <span class="n">pattern</span> <span class="n">match</span>
+   <span class="n">ElementFilter</span> <span class="n">filter</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ElementFilter</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>           <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">filter</span> <span class="n">matching</span> <span class="n">the</span> <span class="n">expression</span>
+   <span class="n">ElementGroup</span> <span class="n">body</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ElementGroup</span><span class="p">();</span>                <span class="sr">//</span> <span class="n">Group</span> <span class="k">our</span> <span class="n">pattern</span> <span class="n">match</span> <span class="ow">and</span> <span class="n">filter</span>
+   <span class="n">body</span><span class="o">.</span><span class="n">addElement</span><span class="p">(</span><span class="n">block</span><span class="p">);</span>
+   <span class="n">body</span><span class="o">.</span><span class="n">addElement</span><span class="p">(</span><span class="n">filter</span><span class="p">);</span>
+
+   <span class="n">Query</span> <span class="sx">q = </span><span class="n">QueryFactory</span><span class="o">.</span><span class="n">make</span><span class="p">();</span>
+   <span class="sx">q.setQueryPattern(body);                               // Set the body of the query to our group</span>
+<span class="sx">   q.</span><span class="n">setQuerySelectType</span><span class="p">();</span>                                <span class="sr">//</span> <span class="n">Make</span> <span class="n">it</span> <span class="n">a</span> <span class="nb">select</span> <span class="n">query</span>
+   <span class="n">q</span><span class="o">.</span><span class="n">addResultVar</span><span class="p">(</span><span class="s">&quot;s&quot;</span><span class="p">);</span>                                   <span class="sr">//</span> <span class="n">Select</span><span class="err"> </span><span class="p">?</span><span class="n">s</span>
+</pre></div>
+
+
+<p>Now the algebra:</p>
+<div class="codehilite"><pre>   <span class="n">Op</span> <span class="n">op</span><span class="p">;</span>
+   <span class="n">BasicPattern</span> <span class="n">pat</span> <span class="o">=</span> <span class="k">new</span> <span class="n">BasicPattern</span><span class="p">();</span>                 <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">pattern</span>
+   <span class="n">pat</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">pattern</span><span class="p">);</span>                                      <span class="sr">//</span> <span class="n">Add</span> <span class="k">our</span> <span class="n">pattern</span> <span class="n">match</span>
+   <span class="n">op</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OpBGP</span><span class="p">(</span><span class="n">pat</span><span class="p">);</span>                                   <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">BGP</span> <span class="n">from</span> <span class="n">this</span> <span class="n">pattern</span>
+   <span class="n">op</span> <span class="o">=</span> <span class="n">OpFilter</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">op</span><span class="p">);</span>                           <span class="sr">//</span> <span class="n">Filter</span> <span class="n">that</span> <span class="n">pattern</span> <span class="n">with</span> <span class="k">our</span> <span class="n">expression</span>
+   <span class="n">op</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OpProject</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="n">Arrays</span><span class="o">.</span><span class="n">asList</span><span class="p">(</span><span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">&quot;s&quot;</span><span class="p">)));</span> <span class="sr">//</span> <span class="n">Reduce</span> <span class="n">to</span> <span class="n">just</span><span class="err"> </span><span class="p">?</span><span class="n">s</span>
+   <span class="n">Query</span> <span class="sx">q = </span><span class="n">OpAsQuery</span><span class="o">.</span><span class="n">asQuery</span><span class="p">(</span><span class="n">op</span><span class="p">);</span>                       <span class="sr">//</span> <span class="n">Convert</span> <span class="n">to</span> <span class="n">a</span> <span class="n">query</span>
+   <span class="n">q</span><span class="o">.</span><span class="n">setQuerySelectType</span><span class="p">();</span>                                <span class="sr">//</span> <span class="n">Make</span> <span class="n">is</span> <span class="n">a</span> <span class="nb">select</span> <span class="n">query</span>
+</pre></div>
+
+
+<p>Notice that the query form (<code>SELECT, CONSTRUCT, DESCRIBE, ASK</code>) isn't
+part of the algebra, and we have to set this in the query (although
+SELECT is the default). <code>FROM</code> and <code>FROM NAMED</code> are similarly absent.</p>
+<h2 id="navigating_and_tinkering_visitors">Navigating and Tinkering: Visitors</h2>
+<p>You can also look around the algebra and syntax using visitors. Start by
+extending <code>OpVisitorBase</code> (<code>ElementVisitorBase</code>) which stubs out the
+interface so you can concentrate on the parts of interest, then walk
+using <code>OpWalker.walk(Op, OpVisitor)</code>
+(<code>ElementWalker.walk(Element, ElementVisitor)</code>). These work bottom up.</p>
+<p>For some alterations, like manipulating triple matches in place,
+visitors will do the trick. They provide a simple way to get to the
+right parts of the query, and you can alter the pattern backing BGPs in
+both the algebra and syntax. Mutation isn't consistently available,
+however, so don't depend on it.</p>
+<h2 id="transforming_the_algebra">Transforming the Algebra</h2>
+<p>So far there is no obvious advantage in using the algebra. The real
+power is visible in transformers, which allow you to reorganise an
+algebra completely. ARQ makes extensive use of transformations to
+simplify and optimise query execution.</p>
+<p>In Research Revealed I wrote some code to take a number of constraints
+and produce a query. There were a number of ways to do this, but one way
+I found was to generate ops from each constraint and join the results:</p>
+<div class="codehilite"><pre>   <span class="k">for</span> <span class="p">(</span><span class="n">Constraint</span> <span class="n">con:</span> <span class="n">cons</span><span class="p">)</span> <span class="p">{</span>
+       <span class="n">op</span> <span class="o">=</span> <span class="n">OpJoin</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="n">consToOp</span><span class="p">(</span><span class="n">cons</span><span class="p">));</span> <span class="sr">//</span> <span class="nb">join</span>
+   <span class="p">}</span>
+</pre></div>
+
+
+<p>The result was a perfectly correct mess, which is only barely readable
+with just three conditions:</p>
+<div class="codehilite"><pre>   <span class="p">(</span><span class="nb">join</span>
+       <span class="p">(</span><span class="nb">join</span>
+           <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">o0</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;urn:ex:prop0&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">o0</span><span class="p">)))</span>
+           <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">o1</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;urn:ex:prop1&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">o1</span><span class="p">))))</span>
+       <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">o2</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;urn:ex:prop2&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">o2</span><span class="p">))))</span>
+</pre></div>
+
+
+<p>Each of the constraints is a filter on a bgp. This can be made much more
+readable by moving the filters out, and merging the triple patterns. We
+can do this with the following <code>Transform</code>:</p>
+<div class="codehilite"><pre>   <span class="n">class</span> <span class="n">QueryCleaner</span> <span class="n">extends</span> <span class="n">TransformBase</span>
+   <span class="p">{</span>
+       <span class="nv">@Override</span>
+       <span class="n">public</span> <span class="n">Op</span> <span class="n">transform</span><span class="p">(</span><span class="n">OpJoin</span> <span class="nb">join</span><span class="p">,</span> <span class="n">Op</span> <span class="n">left</span><span class="p">,</span> <span class="n">Op</span> <span class="n">right</span><span class="p">)</span> <span class="p">{</span>
+           <span class="sr">//</span> <span class="n">Bail</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">of</span> <span class="n">the</span> <span class="n">right</span> <span class="n">form</span>
+           <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">left</span> <span class="n">instanceof</span> <span class="n">OpFilter</span> <span class="o">&amp;&amp;</span> <span class="n">right</span> <span class="n">instanceof</span> <span class="n">OpFilter</span><span class="p">))</span> <span class="k">return</span> <span class="nb">join</span><span class="p">;</span>
+           <span class="n">OpFilter</span> <span class="n">leftF</span> <span class="o">=</span> <span class="p">(</span><span class="n">OpFilter</span><span class="p">)</span> <span class="n">left</span><span class="p">;</span>
+           <span class="n">OpFilter</span> <span class="n">rightF</span> <span class="o">=</span> <span class="p">(</span><span class="n">OpFilter</span><span class="p">)</span> <span class="n">right</span><span class="p">;</span>
+
+           <span class="sr">//</span> <span class="n">Add</span> <span class="n">all</span> <span class="n">of</span> <span class="n">the</span> <span class="n">triple</span> <span class="n">matches</span> <span class="n">to</span> <span class="n">the</span> <span class="n">LHS</span> <span class="n">BGP</span>
+           <span class="p">((</span><span class="n">OpBGP</span><span class="p">)</span> <span class="n">leftF</span><span class="o">.</span><span class="n">getSubOp</span><span class="p">())</span><span class="o">.</span><span class="n">getPattern</span><span class="p">()</span><span class="o">.</span><span class="n">addAll</span><span class="p">(((</span><span class="n">OpBGP</span><span class="p">)</span> <span class="n">rightF</span><span class="o">.</span><span class="n">getSubOp</span><span class="p">())</span><span class="o">.</span><span class="n">getPattern</span><span class="p">());</span>
+           <span class="sr">//</span> <span class="n">Add</span> <span class="n">the</span> <span class="n">RHS</span> <span class="n">filter</span> <span class="n">to</span> <span class="n">the</span> <span class="n">LHS</span>
+           <span class="n">leftF</span><span class="o">.</span><span class="n">getExprs</span><span class="p">()</span><span class="o">.</span><span class="n">addAll</span><span class="p">(</span><span class="n">rightF</span><span class="o">.</span><span class="n">getExprs</span><span class="p">());</span>
+           <span class="k">return</span> <span class="n">leftF</span><span class="p">;</span>
+       <span class="p">}</span>
+   <span class="p">}</span>
+   <span class="o">...</span>
+   <span class="n">op</span> <span class="o">=</span> <span class="n">Transformer</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="k">new</span> <span class="n">QueryCleaner</span><span class="p">(),</span> <span class="n">op</span><span class="p">);</span> <span class="sr">//</span> <span class="n">clean</span> <span class="n">query</span>
+</pre></div>
+
+
+<p>This looks for joins of the form:</p>
+<div class="codehilite"><pre>   <span class="p">(</span><span class="nb">join</span>
+       <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exp1</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp1</span><span class="p">))</span>
+       <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exp2</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp2</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>And replaces it with:</p>
+<div class="codehilite"><pre>   <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exp1</span> <span class="o">&amp;&amp;</span> <span class="n">exp2</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp1</span> <span class="o">&amp;&amp;</span> <span class="n">bgp2</span><span class="p">))</span>
+</pre></div>
+
+
+<p>As we go through the original query all joins are removed, and the
+result is:</p>
+<div class="codehilite"><pre>   <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exprlist</span> <span class="p">(</span><span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">o0</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">o1</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="o">&lt;</span><span class="err"> </span><span class="p">?</span><span class="n">o2</span> <span class="mi">20</span><span class="p">))</span>
+       <span class="p">(</span><span class="n">bgp</span>
+           <span class="p">(</span><span class="n">triple</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;urn:ex:prop0&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">o0</span><span class="p">)</span>
+           <span class="p">(</span><span class="n">triple</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;urn:ex:prop1&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">o1</span><span class="p">)</span>
+           <span class="p">(</span><span class="n">triple</span><span class="err"> </span><span class="p">?</span><span class="n">s</span> <span class="sr">&lt;urn:ex:prop2&gt;</span><span class="err"> </span><span class="p">?</span><span class="n">o2</span><span class="p">)</span>
+   <span class="p">))</span>
+</pre></div>
+
+
+<p>That completes this brief introduction. There is much more to ARQ, of
+course, but hopefully you now have a taste for what it can do.</p>
+  </div>
+
+  <div id="footer">
+    <div class="copyright">
+      <p>
+        Copyright &copy; 2011&ndash;12 The Apache Software Foundation, Licensed under
+        the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
+        <br />
+        Apache Jena, Jena, the Apache Jena project logo,
+        Apache and the Apache feather logos are trademarks of The Apache Software Foundation.
+      </p>
+    </div>
+  </div>
+
+</body>
+</html>