<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE spec SYSTEM "xmlspec.dtd" [
  <!ENTITY base.uri "http://www.w3.org/2009/sparql/docs/property-paths/">
  <!ENTITY maturity.level "WD">
  <!ENTITY doc.shortname "sparql11-property-paths">
  <!ENTITY draft.year "2010">
  <!ENTITY draft.month.name "Summer">
  <!ENTITY draft.month "08">
  <!ENTITY draft.day "01">
  <!ENTITY iso6.doc.date "&draft.year;&draft.month;&draft.day;">
  <!ENTITY doc.ident "&maturity.level;-&doc.shortname;-&iso6.doc.date;">
  <!ENTITY this.version "&base.uri;&doc.ident;">
  <!ENTITY versionOfSPARQL "1.1">
  <!ENTITY nbsp "&#160;">
  <!ENTITY mdash "&#x2014;">
  <!ENTITY magicents "<code>amp</code>,
<code>lt</code>,
<code>gt</code>,
<code>apos</code>,
<code>quot</code>">
  <!ENTITY may "may">
  <!ENTITY MAY "<rfc2119>MAY</rfc2119>">
  <!ENTITY must "must">
  <!ENTITY MUST "<rfc2119>MUST</rfc2119>">
  <!ENTITY should "should">
  <!ENTITY SHOULD "<rfc2119>MAY</rfc2119>">
  <!ENTITY % local.common.att "xml:lang    CDATA  #IMPLIED">
  <!ENTITY mu      "&#956;">
   <!ENTITY Omega  "&#937;">

]>

<?xml-stylesheet type="text/xsl" href="REC-xml.xsl"?> 

<spec w3c-doctype="wd" xml:lang="en">

  <header>
    <title>SPARQL &versionOfSPARQL; Property Paths</title>
    <w3c-designation>&doc.ident;</w3c-designation>
    <w3c-doctype>Editor's Draft</w3c-doctype>
    <pubdate>
      <day>:</day>
      <month>Summer</month>
      <year>2010</year>
<!--
      <day>&draft.day;</day>
      <month>&draft.month.name;</month>
      <year>&draft.year;</year>
-->
    </pubdate>
    <publoc>
<!--
      <loc href="&this.version;/">&this.version;/</loc>
-->
     <loc>&base.uri;</loc>
    </publoc>
    <!--
      <altlocs>
      <loc href="&xml.version;">XML</loc>
      <loc href="&pdf.version;">PDF</loc>
      <loc href="&review.version;">XHTML with color-coded revision indicators</loc>
    </altlocs>
    -->
    <latestloc>
      <loc href="http://www.w3.org/TR/&doc.shortname;/">http://www.w3.org/TR/&doc.shortname;/</loc>
    </latestloc>
    <prevlocs>
      <loc href="http://www.w3.org/TR/2010/WD-sparql11-property-paths-20100126/">http://www.w3.org/TR/2010/WD-sparql11-property-paths-20100126/</loc>
    </prevlocs>
    <authlist>
      <author role="Editor">
        <name>Andy Seaborne</name>
        <affiliation>Invited Expert</affiliation>
        <email href="mailto:andy.seaborne@epimorphics.com">andy.seaborne@epimorphics.com</email>
      </author>
    </authlist>
<!--    <errataloc href="&errataloc;"/>
    <preverrataloc href="&preverrataloc;"/>
    <translationloc href="&translationloc;"/>   -->

<abstract>
  <p>This document describes SPARQL Property Paths.  Property Paths
  give a more succinct way to write parts of basic graph patterns
  and also extend matching of triple pattern to arbitrary length paths.
  Property paths do not invalidate or change any existing SPARQL query 
  See <a href="http://www.w3.org/TR/rdf-sparql-query/">SPARQL Query Language for RDF (W3C Recommendation 15 January 2008)</a>.</p>
</abstract>

<status>
  <p><em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/">W3C technical reports index</a> at http://www.w3.org/TR/.</em></p>

  <p>This is a <a href="http://www.w3.org/2005/10/Process-20051014/tr.html#RecsWD">Editors' Working Draft</a>.</p>

  <div class="issue">
  <p>This material has be incorporated into the
  <a href="http://www.w3.org/TR/sparql11-query/"
  >main SPARQL query document</a> and readers should refer to that document.
  This document is out of date and may not reflect later working group decisions.</p>
  </div>
<!--
  <p>Comments on this document should be sent to <a 
  href="mailto:public-rdf-dawg-comments@w3.org">public-rdf-dawg-comments@w3.org</a>,
  a mailing list with a <a 
  href="http://lists.w3.org/Archives/Public/public-rdf-dawg-comments">public archive</a>. 
  Questions and comments about SPARQL that are not related to this specification, 
  including extensions and features, can be discussed on the mailing list <a
  href="mailto:public-sparql-dev@w3.org">public-sparql-dev@w3.org</a>,
  (<a href="http://lists.w3.org/Archives/Public/public-sparql-dev">public archive</a>).</p>
-->
  <p>This document was produced by the <a 
  href="http://www.w3.org/2001/sw/DataAccess/">SPARQL Working Group</a>,
  which is part of the <a href="http://www.w3.org/2001/sw/Activity">W3C
  Semantic Web Activity</a>.</p>

      <p>This document was produced by a group operating under the <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 W3C Patent Policy</a>. W3C maintains a <a rel="disclosure" href="http://www.w3.org/2004/01/pp-impl/35463/status">public list of any patent disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section 6 of the W3C Patent Policy</a>.</p>
</status>

<pubstmt>
  <p>@@@ World-Wide Web Consortium, SPARQL Working Group, 2009.</p>
</pubstmt>

<sourcedesc>
  <p>Created in electronic form.</p>
</sourcedesc>

<langusage>
  <language id="EN">English</language>
  <language id="ebnf">Extended Backus-Naur Form (formal grammar)</language>
</langusage>

<revisiondesc>
  <p role="cvsid">$Id: Overview.xml,v 1.40 2010/09/08 20:40:31 aseaborne Exp $</p>
</revisiondesc>

</header>

<body>
  <p><b>Editor's Working Notes</b></p>
  <p>Material being sorted out into the positions needed for integration into rq25</p>
  <p>&nbsp;</p>

  <div1 id="sec-intro">
    <head>Introduction</head>
    <p>A property path is a possible route through a graph between two graph nodes
    A trivial case is a property path of length exactly 1, which is a triple pattern. 
    Property paths allow for more concise expression of
    some SPARQL basic graph patterns and also add the ability 
    to match arbitrary length paths.</p>
  </div1>

  <div1 id="path-language">
    <head>Path Language</head>

    <p>A property path expression (or just 'path') is similar to a
    string regular expression but over properties, not characters.
    The ends of the path may be RDF terms or variables. Variables 
    can not be used as part of the path itself, only the ends.
    Query evaluation determines all matches of a path expression
    and binds subject or object as appropriate. 
    any given path expression.
    </p>

    <p>Cycles in the graph and in paths are possible.</p>

    <p>A path of length zero connects a graph node to itself.</p>

    <p>In the description below, <i><tt>uri</tt></i> is either a URI or a 
    prefixed name and <i><tt>elt</tt></i> is a path element, which may itself 
    be composed of path syntax constructs.
    </p>

    <table border="1" cellspacing="0">
      <tbody>
	<tr>
	  <th>Syntax Form</th>
	  <th>Matches</th>
	</tr>
	<tr>
	  <td><tt><i>uri</i></tt></td>
	  <td> A URI or a prefixed name. A path of length one.</td>
	</tr>
	<tr>
	  <td><tt><i>^elt</i></tt></td>
	  <td> Inverse path (object to subject).</td>
	</tr>
	<tr>
	  <td><tt><i>!uri</i></tt> or <tt><i>!(uri<sub>1</sub>| ...|uri<sub>n</sub>)</i></tt></td>
	  <td>Negated property set. A URI which is not one of <tt><i>uri<sub>i</sub></i></tt></td>
	</tr>
	<tr>
	  <td><tt><i>!^uri</i></tt> and <tt><i>!(uri<sub>1</sub>| ...|uri<sub>j</sub>|^uri<sub>j+1</sub>| ...|^uri<sub>n</sub>)</i></tt></td>
	  <td>Negated property set. A URI which is not one of 
	    <tt><i>uri<sub>i</sub></i></tt>, nor uri<sub>j+1</sub>...^uri<sub>n</sub>as reverse paths 
	  </td>
	</tr>
	<tr>
	  <td><i><tt>(elt)</tt></i></td>
	  <td> A group path <i><tt>elt</tt></i>, brackets control precedence.</td>
	</tr>
	<tr>
        <td><i><tt>elt1 / elt2</tt></i></td>
	<td>A sequence path of <i><tt>elt1</tt></i>, followed by <i><tt>elt2</tt></i></td>
	</tr>
	<tr>
	  <td> <i><tt>elt1 | elt2</tt></i></td>
	  <td>A alternative path of <i><tt>elt1</tt></i>, or <tt><i>elt2</i></tt> (all possibilities are tried).</td>
	</tr>
	<tr>
	  <td><i><tt>elt*</tt></i></td>
	  <td>A path of zero or more occurrences of <i><tt>elt</tt></i>.</td>
	</tr>

	<tr>
	  <td><i><tt>elt+</tt></i></td>
	  <td> A path of one or more occurrences of <i><tt>elt</tt></i>.</td>
	</tr>
	<tr>
	  <td><i><tt>elt?</tt></i></td>
	  <td>A path of zero or one <i><tt>elt</tt></i>.</td>
	</tr>
	<tr>
	  <td><i><tt>elt{n,m}</tt></i></td>
	  <td> A path between n and m occurrences of <i><tt>elt</tt></i>.</td>
	</tr>
	<tr>
	  <td> <i><tt>elt{n}</tt></i></td>
	  <td> Exactly <i><tt>n</tt></i> occurrences of <i><tt>elt</tt></i>.</td>
	</tr>
	<tr>
	  <td><i><tt>elt{n,}</tt></i></td>
	  <td><i><tt>n</tt></i> or more occurrences of <i><tt>elt</tt></i>.</td>
	</tr>
	<tr>
	  <td><i><tt>elt{,n}</tt></i></td>
	  <td> Between 0 and <i><tt>n</tt></i> occurrences of <i><tt>elt</tt></i>.</td>
	</tr>
      </tbody>
    </table>

    <p>The order of URIs, and reverse URIs, in a negated property sets is not significant
    and they can occur in a mixed order.</p>

    <p>The precedence of the syntax forms is, from highest to lowest:
    </p>
    <ul>
      <li>URI, prefixed names</li>
      <li>Negated property sets</li>
      <li>Groups</li>
      <li>Unary operators <tt>*</tt>, <tt>?</tt>, <tt>+</tt> and <tt>{}</tt> forms</li>
      <li>Unary ^ inverse links</li>
      <li>Binary operators <tt>/</tt> and ^</li>
      <li>Binary operator <tt>|</tt></li>
    </ul>
    <p>Precedence is left-to-right within groups.
    </p>
  </div1>

  <div1>
    <head>Examples</head>
    <p>See also <a href="http://www.w3.org/2009/sparql/wiki/TaskForce:PropertyPaths#Use_Cases" 
    title="TaskForce:PropertyPaths">uses cases</a>.</p>

    <example>
      <head>Alternatives</head>
      <p>Match one or both possibilities</p>
      <pre>{ :book1 dc:title | rdfs:label ?displayString }</pre>
    </example>

    <example>
      <head>Sequence</head>
      <p>Find the name of any people that Alice knows.</p>
      <pre>{
  ?x foaf:mbox &lt;mailto:alice@example&gt; .
  ?x foaf:knows/foaf:name&nbsp;?name .
}</pre>
    </example>

    <example>
      <head>Sequence</head>
      <p>Find the names of people 2 "<tt>foaf:knows</tt>" links away.</p>
      <pre>{ 
  ?x foaf:mbox &lt;mailto:alice@example&gt; .
  ?x foaf:knows/foaf:knows/foaf:name&nbsp;?name .
 }</pre>
<p>This can be written as:</p>
     <pre>{
  ?x foaf:mbox &lt;mailto:alice@example&gt; .
  ?x foaf:knows{2}/foaf:name ?name .
}</pre>
     <p>This is the same as the strict SPARQL query:</p>
     <pre>{ &nbsp;?x  foaf:mbox &lt;mailto:alice@example&gt; .
   ?x  foaf:knows [ foaf:knows [ foaf:name&nbsp;?name ]]. }</pre>
      <p>or, with explicit variables:</p>
      <pre>{
  ?x  foaf:mbox &lt;mailto:alice@example&gt; .
  ?x  foaf:knows&nbsp;?a1 .
  ?a1 foaf:knows&nbsp;?a2 .
  ?a2 foaf:name&nbsp;?name .
}</pre>
    </example>

    <example>
      <head>Filtering duplicates</head>
      <p>Because someone Alice knows may well know Alice, the example above may 
      include Alice herself. This could be avoided with:
      </p>
      <pre>{&nbsp;?x foaf:mbox &lt;mailto:alice@example&gt; .
   ?x foaf:knows/foaf:knows&nbsp;?y .
   FILTER (&nbsp;?x&nbsp;!=&nbsp;?y )
   ?y foaf:name&nbsp;?name 
}</pre>
    </example>

    <example>
      <head>Inverse Property Paths</head>
      <p>These two are the same query: the second is just reversing the property 
      direction which swaps the roles of subject and object.</p>
      
      <pre>{&nbsp;?x foaf:mbox &lt;mailto:alice@example&gt; }</pre>
      <pre>{ &lt;mailto:alice@example&gt; ^foaf:mbox&nbsp;?x }</pre>
    </example>

    <example>
      <head>Inverse Path Sequence</head>
      <p>Find all the people who know someone <tt>?x</tt> knows.</p>
      <pre>{
  ?x foaf:knows^foaf:knows ?y .  
  FILTER(?x != ?y)
}</pre>
    </example>

    <example>
      <head>Arbitrary length match</head>
        <p>Find the names of all the people that can be reached from Alice by <tt>foaf:knows</tt>:</p>
        <pre>{
  ?x foaf:mbox &lt;mailto:alice@example&gt; .
  ?x foaf:knows+/foaf:name&nbsp;?name .
 }</pre>
    </example>

    <example>
      <head>Alternatives in an arbitrary length path</head>
      <pre>?ancestor (ex:motherOf|ex:fatherOf)+ &lt;#me&gt;</pre>
    </example>

    <example>
      <head>Arbitrary length match</head>
      <p>Some forms of limited inference are possible as well. For example: all types 
      and supertypes of a resource:</p>
      <pre>{ &lt;http://example/thing&gt; rdf:type/rdfs:subClassOf*&nbsp;?type }</pre>

      <p>All resources and all their inferred types:</p>
      <pre>{&nbsp;?x rdf:type/rdfs:subClassOf*&nbsp;?type }</pre>
    </example>

    <example>
      <head>Subproperty</head>
      <pre>{ ?x ?p ?v . ?p rdfs:subPropertyOf* :property }</pre>
    </example>

    <example>
      <head>Find nodes connected but not by rdf;type (either way round)</head>
      <pre>{ ?x !(rdf:type|^rdf:type) ?y }</pre>
    </example>

    <example>
      <head>Elements in an RDF collection</head>
      <pre>{ :list rdf:rest*/rdf:next ?element }</pre>
      <p>Note: This path expression does not gaurantee the order of the results</p>
    </example>

  </div1>

  <div1 id="path-syntax">
    <head>Syntax</head>

    <p class="note">This syntax will be incorporated into the main SPARQL grammar if the time-permitting 
    feature is accepted.</p>

    <div style="font-family: monospace;">
    <table>
      <tbody>
	<tr>
	  <td> TriplesSameSubjectPath</td>
	  <td>&nbsp;::=&nbsp;&nbsp;</td>
	  <td> VarOrTerm PropertyListNotEmptyPath | TriplesNode PropertyListPath</td>
	</tr>
	<tr>
	  <td> PropertyListPath</td>
	  <td>&nbsp;::=</td>
	  <td> PropertyListNotEmpty?</td>
	</tr>
	<tr>
	  <td> PropertyListNotEmptyPath</td>
	  <td>&nbsp;::= </td>
	  <td> ( VerbPath | VerbSimple ) ObjectList ( ';' ( ( VerbPath | VerbSimple ) ObjectList )? )*</td>
	</tr>
	<tr>
	  <td> VerbPath </td>
	  <td>&nbsp;::=</td><td> Path</td>
	</tr>
	<tr>
	  <td> VerbSimple
	  </td><td>&nbsp;::=
	  </td><td> Var
	</td></tr>
	<tr>
	  <td> Path
	  </td><td>&nbsp;::=
	  </td><td> PathAlternative
	</td></tr>
	
	<tr>
	  <td> PathAlternative
	  </td><td>&nbsp;::=
	  </td><td> PathSequence ( '|' PathSequence )*
	</td></tr>
	<tr>
	  <td> PathSequence
	  </td><td>&nbsp;::=
	  </td><td> PathEltOrInverse ( '/' PathEltOrInverse | '^' PathElt )*
	</td></tr>
	<tr>
	  <td> PathElt
	  
	  </td><td>&nbsp;::=
	  </td><td> PathPrimary PathMod?
	</td></tr>
	<tr>
	  <td> PathEltOrInverse
	  </td><td>&nbsp;::=
	  </td><td> PathElt | '^' PathElt
	</td></tr>
	<tr>
	  <td> PathMod
	  </td><td>&nbsp;::=
	  </td><td> ( '*' | '?' | '+' | '{' ( Integer ( ',' ( '}' | Integer '}' ) | '}' ) ) )
	  </td>
	</tr>

	<tr>
	  <td> PathPrimary </td>
	  <td>&nbsp;::= </td>
	  <td> ( IRIref | 'a' | '!' PathNegatedPropertySet | '(' Path ')' )</td>
	</tr>
	
	<tr>
	  <td>PathNegatedPropertySet</td>
	  <td>&nbsp;::=&nbsp;</td>
	  <td>PathOneInPropertySet | ( '(' PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')' )</td>
	</tr>
	<tr>
	  <td>PathOneInPropertySet</td>
	  <td>&nbsp;::=&nbsp;</td>
	  <td>IRIref  | 'a' | '^' IRIref</td>
	</tr>
      </tbody>
    </table>
    </div>
  </div1>

  <div1 id="path-algebra">
    <head>Algebra</head>
    <p>This section describes the translation of the path syntax forms into other
    SPARQL expressions and hence to the <a href="#sparqlAlgebra">SPARQL algebra</a>.
    Three new algebra operators are introduced: 
    <a href="#defn_algZeroPath"><tt>ZeroLengthPath</tt></a> which defines the evaluation of 
    zero-length path (e.g. <tt>?x :p{0} ?y</tt>),
    <a href="#defn_algArbitraryLengthPath"><tt>ArbitraryLengthPath</tt></a> which defines
    the evaluation of path of one or more steps (e.g. <tt>?x :p+ ?y</tt>) and
    <a href="#defn_algNegatedPropertySet"><tt>NegatedPropertySet</tt></a> which defines
    the evaluation of a path element not matching a set of properties.
    </p>
    

    <div2 id="path-translate">
      <head>Translation of Property Paths</head>

      <p>Two steps: this set of rewrites, followed by recombining into BGPs</p>

      <p>Notes:</p>
      <ul>
	<li>X and Y are RDF terms or variables.</li>
	<li>Occurences of 'path' on the right are recursively translated.</li>
	<li>The order of forms URI and ^URI in negated property sets is not relevant.</li>
	<li>UNION is SPARQL UNION.</li>
	<li>Variables introduced, e.g. ?V, are fresh - not used anywhere else in the current query</li>
      </ul>

      <table border="1" cellspacing="0">
	<tbody>
	  <tr>
	    <th>Syntax Form (path)</th>
	    <th>translate(path)</th>
	  </tr>
	  <tr>
	    <td><code><i>X</i> uri <i>Y</i></code></td>
	    <td>Triple pattern: <code><i>X</i> uri <i>Y</i></code></td>
	  </tr>
	  <tr>
	    <td><code><i>X</i> !(:uri<sub>1</sub>|...|:uri<sub>n</sub>) <i>Y</i></code></td>
	    <td>NegatedPropertySet(X,{:uri<sub>1</sub> ... :uri<sub>n</sub>} ,Y)</td>
	  </tr>
	  <tr>
	    <td><code><i>X</i> !(^:uri<sub>1</sub>|...|^:uri<sub>n</sub>)<i>Y</i></code></td>
	    <td><code>^(<i>X</i> !(:uri<sub>1</sub>|...|:uri<sub>n</sub>) <i>Y</i>)</code></td>
	  </tr>

	  <tr>
	    <td><code><i>X</i> !(:uri<sub>1</sub>|...|:uri<sub>i</sub>|^:uri<sub>i+1</sub>|...|^:uri<sub>m</sub>) <i>Y</i></code>&nbsp;</td>
	    <td><code>{ <i>X</i> !(:uri<sub>1</sub>|...|:uri<sub>i</sub>|)<i>Y</i> } UNION { <i>X</i> !(^:uri<sub>i+1</sub>|...|^:uri<sub>m</sub>) <i>Y</i> } </code></td>
	  </tr>

	  <tr>
	    <td><code><i>X</i> ^path <i>Y</i></code></td>
	    <td><code><i>Y</i> path <i>X</i></code></td>
	  </tr>

	  <tr>
	    <td><code><i>X</i> path1 / path2 <i>Y</i></code></td>
	    <td><code><i>X</i> path1 ?V . ?V path2 <i>Y</i></code></td>
	  </tr>
	  <tr>
	    <td><code><i>X</i> path1 | path2 <i>Y</i></code></td>
	    <td><code>{ <i>X</i> path1 <i>Y</i> } UNION { <i>X</i> path2 <i>Y</i>} </code> </td>
	  </tr>

	  <tr>
	    <td><code><i>X</i> path* <i>Y</i></code></td>
	    <td><code>{ <i>X</i> path{0} <i>Y</i> } UNION { <i>X</i> path+ <i>Y</i>}</code></td>
	  </tr>

	  <tr>
	    <td><code><i>X</i> path+ <i>Y</i></code></td>
	    <td>ArbitraryPath(X, path, Y)</td>
	  </tr>

	  <tr>
	    <td><code><i>X</i> path? <i>Y</i></code></td>
	    <td><code>{ <i>X</i> path{0} <i>Y</i> } UNION { <i>X</i> path <i>Y</i>}</code></td>
	  </tr>

	  <tr>
	    <td><code><i>X</i> path{0} <i>Y</i></code></td>
	    <td>ZeroLengthPath(X, path, Y)</td>
	  </tr>
	  
	  <tr>
	    <td><code><i>X</i> path{n} <i>Y</i></code> where n > 0 </td>
	    <td><code><i>X</i> path ?V<sub>1</sub> . ?V<sub>1</sub> path ?V<sub>2</sub> ... ?V<sub>n-1</sub> path <i>Y</i></code></td>
	  </tr>

	  <!-- Recursive version of {n}
	  <tr>
	    <td><code><i>X</i> path{n} <i>Y</i></code></td>
	    <td><code><i>X</i> path ?V<sub>1</sub> . ?V<sub>1</sub> path{n-1} <i>Y</i></code></td>
	  </tr>
	  <tr>
	    <td><code><i>X</i> path{1} <i>Y</i></code></td>
	    <td><code><i>X</i> path <i>Y</i></code></td>
	  </tr>
	  -->

	  <tr>
	    <td><code><i>X</i> path{n,m} <i>Y</i></code></td>
	    <td><code>{ <i>X</i> path{n} <i>Y</i> } UNION { <i>X</i> path{n+1} <i>Y</i> } ... UNION { <i>X</i> path{m} <i>Y</i>}</code></td>
	  </tr>
	  
	  <!-- To go with recursive version
	  <tr>
	    <td><code><i>X</i> path{n,m} <i>Y</i></code></td>
	    <td><code><i>X</i> path{n} ?V . ?V path{0,m-n} <i>Y</i></code></td>
	  </tr>
	  -->

	  <tr>
	    <td><code><i>X</i> path{n,} <i>Y</i></code></td>
	    <td><code><i>X</i> path{n} <i>?V</i> . <i>?V</i> path* <i>Y</i></code></td>
	  </tr>
	  <tr>
	    <td><code><i>X</i> path{,n} <i>Y</i></code></td>
	    <td><code><i>X</i> path{0,n} <i>Y</i></code></td>
	  </tr>
	</tbody>
      </table>
    </div2>

    <div2>
      <head>Material for the "Initial Definitions" section</head>

      <div3 id="define-property-paths">
	<head>Property Paths Patterns</head>

	<div class="defn">
	  <b>Definition: <a id="defn_PropertyPath" name="defn_PropertyPath">Property Path</a></b>
	  <p>A Property Path is a sequence of triples, t<sub>i</sub> in ST, such that, for i=0 to length(ST)-1,
	  the object of t<sub>i</sub> is the same term as the subject of t<sub>i+1</sub>.</p>
	  <p>We call the subject of t<sub>0</sub> the start of the path.</p>
	  <p>We call the object of t<sub>n</sub> the end of the path.</p>
	  <p>Property Path PP is a path in graph G if each t<sub>i</sub> is a triple of G.</p>
	</div>

	<div class="defn">
	  <b>Definition: <a id="defn_PropertyPathExpr" name="defn_PropertyPathExpr">Property Path Expression</a></b>
	  <p>A property path expression is an expression form after translation of the path syntax 
	  as defined <a href="#path-translate">above</a>.</p>
	</div>

	<p>More commonly called a property path or path, when clear.</p>

	<div class="defn">
	  <b>Definition: <a id="defn_PropertyPathPattern" name="defn_PropertyPathPattern">Property Path Pattern</a></b>
	  <p>Let PP be the set of all property path expressions. 
	  A property path pattern is a member of the set:<br/>
	  (RDF-T union V) x PP x (RDF-T union V)</p>
	</div>

	<p>A Property Path Pattern is a generalization of a 
	<a href="#defn_TriplePattern">Triple Pattern</a> 
	to include a property path in the property position.</p>

      </div3>

    </div2>

    <div2 id="path-matching">
      <head>Property Path Expression Matching</head>

      <p class="todo">To go after <a href="#BasicGraphPattern">Basic Graph Patterns</a></p>
      <p class="todo">Alt: in evaluation section</p>
      <p class="todo">Rename "Basic Graph Patterns" as "Basic Graph Pattern Matching"</p>
      
      <div3 id="path-matching">
	<head>SPARQL Property Path Pattern Matching</head>
	
	<div class="defn">
	  <b>Definition: <a id="defn_PropertyPathMatching" name="defn_PropertyPathMatching">Property Path Pattern Matching</a></b>
	</div>
      </div3>
    </div2>

    <div2>
      <head>Material for the SPARQL syntax to SPARQL algebra section</head>
      
      <p>@@The material of "translate"</p>

      <blockquote>
	<p>If the form is <code class="gRuleBody"><a href="#rTriplesBlock">TriplesBlock</a></code></p>
      </blockquote>
      <p>@@Extend for Property Paths</p>
      <pre class="codeBlock">The result is BGP(list of triple patterns)</pre>
      <pre class="codeBlock">@@Translate can go straight to algebra form 
+ combine any adjacent triples patterns into
one BGP (but not across {} boundaries)</pre>
    </div2>

    <div2>
      <head>Material for the SPARQL algebra section</head>

      <div class="defn">
	<p><b>Definition: <a name="defn_algZeroPath">ZeroLengthPath</a></b></p>
	<p>A zero length path matches subjects and all objects in the graph, 
	and also any IRIs explitictly given as endpoints of the path pattern.</p>
      </div>
	
      <div class="defn">
	<p><b>Definition: <a name="defn_algArbitraryLengthPath">ArbitraryLengthPath</a></b></p>
	<p>An arbitrary length path P = (X (path)+ Y) is all solutions from X to Y such that a 
	intermediate nodes in the graph are trarversed once only.</p>
      </div>
	
      <div class="defn">
	<p><b>Definition: <a name="defn_algNegatedPropertySet">Negated Property Set</a></b></p>
	<p>A Negated Property Set, NPS, is a pair (F,B) where F and B are sets of IRIs. 
	F is the set of forward links and B is the set of the backward links.</p>
      </div>

    </div2>
    

    <div2>
      <head>Material for the SPARQL Evaluation Semantics section</head>
      <p class="todo">Maybe better in with the path evaluation after BGP</p>
      <p class="todo">@@ Add X:T syntax to the intro to "Evaluation Semantics in rq25</p>

            <pre>eval(D(G), pathPattern) =
  eval(D(G), translate(x, path, y)) =

* translate(PathpathExpression) only depends on BGP, UNION, ArbitraryPath and ZeroLengthPath.

Definition: nodes(G)
  nodes(G) = { n | n is an RDF term and either n is a subject or an object of some triple T in G }

* nodes(G) is the node set of the graph.
      </pre>


      <div3>
	<head>Zero-length paths</head>

	<div class="defn">
	  <p><b>Definition: Evaluation of <a name="defn_evalZeroPath">ZeroLengthPath</a></b></p>
	  <pre class="code">
eval(D(G), ZeroLengthPath(vx:var, path, vy:var))) = 
  { {(vx, term), (vy, term)} | term in nodes(G) }
  card[] = 1

eval(D(G), ZeroLengthPath(vx:var, path, y:term)) =
 { { (vx, y) } }
  card[] = 1

eval(D(G), ZeroLengthPath(x:term, path, vy:var)) = 
  { { (y, x) } }
  card[] = 1

* does not matter if x or y is in nodes(G) or not.

eval(D(G), ZeroLengthPath(x:term, path, y:term)) = 
  { {} }
  card[] = 1

* Multiset of one solution mapping, which is the solution mapping of no variables
	  </pre>
	</div>
      </div3>

      <div3>
	<head>Arbitrary length paths</head>

	<div class="defn">
	  <p><b>Definition: Evaluation of <a name="defn_evalArbitraryLengthPath">ArbitraryLengthPath</a></b></p>
	  <p>An arbitrary length path @@</p>
	  <blockquote>
	  <p>ArbitraryLengthPath(?x (path)+ ?y) = @@</p>
	  </blockquote>
	</div>
	
	<p>The matching algorithm is based on following all paths, and deteching
	when a graph node (subject or object), has been already visited by the path.
	</p>
	
	<pre>
Definition: Evaluation of ArbitraryLengthPath

eval(D(G), ArbitraryLengthPath(x, path, y)) =

i.e. the SPARQl pattern x path+ y .


Define: ALP

ALP(x:term, path) = ALP(x:term, path), {})

ALP(x:term, path, Visited) =
  if ( x in Visited ) return empty set.
  Visited = Visited union {x}
  T = Path(x, path, y)
  R = empty list
  for t in T
    R = R + t + ALP(t, Path, Visted)
  Visited = Visited \ {x}
  result is R

then

eval(D(G), ArbitraryLengthPath(x:term, path, vy:var)) =
    { {(vy, n) | n in ALP(x, path) }

eval(D(G), ArbitraryLengthPath(vx:var, path, vy:var)) =
    multiset-union(ArbitraryLengthPath(t, path, vy) | t in nodes(G))

eval(D(G), ArbitraryLengthPath(vx:var, path, y:term)) =
   multiset-union({(vx,t} | | t in nodes(G) and y in ArbitraryLengthPath(t, path, y) })
card[]

Note that
    ArbitraryLengthPath(vx:var, path, vy:term) = ArbitraryLengthPath(y:term, ^path, vx:var)

eval(D(G), ArbitraryLengthPath(x:term, path, y:term)) = 
    { { } } if y in ALP(x, path)
    { } if y not in ALP(x, path)
	</pre>

	<p>Informally, this algorithm attempts to extend the multiset of results by one 
	application of 
	<tt>path</tt> at each step, noting which nodes it has visited 
	for this particular path in <tt>Visited</tt>. If a node has been visited for the path 
	under consideration, it is not a candidate for another step.
	A node can still be visited multiple times if there are two different
	paths that visit it.</p>
      </div3>
	

    </div2>
    
  </div1>

</body>
<back>  
  <div1 id="sec-cvsLog">
    <head>CVS History</head>
      <pre>
  $Log: Overview.xml,v $
  Revision 1.40  2010/09/08 20:40:31  aseaborne
  Material moved to query language document

  Revision 1.39  2010/08/10 15:51:00  aseaborne
  work-in-progress

  Revision 1.38  2010/08/10 14:01:33  aseaborne
  work-in-progress

  Revision 1.37  2010/08/10 10:26:20  aseaborne
  Preparing for integration into query doc

  Revision 1.36  2010/08/06 14:16:05  aseaborne
  Revise the evaluation of path expressions (work-in-progress)

  Revision 1.35  2010/08/06 12:07:33  aseaborne
  Update author details for Andy

  Revision 1.34  2010/08/05 18:55:27  aseaborne
  All terms, not all IRIs, for zeropath

  Revision 1.33  2010/07/08 15:42:41  aseaborne
  Drafting for the defn of arbitrary length path (work in-progress)

  Revision 1.32  2010/07/08 15:14:49  aseaborne
  Drafting for the defn of arbitrary length path (work in-progress)

  Revision 1.31  2010/07/08 12:37:29  aseaborne
  Defn and eval of zero length paths

  Revision 1.30  2010/07/07 14:39:36  aseaborne
  Complete translation of paths

  Revision 1.29  2010/07/06 13:46:18  aseaborne
  Clearup after publication.
  
  Remove redundant text.
  
  Remove mention of time-permitting now that the WG
  has decided to include the feature.
  
  Consolidate examples.
  
  Added "negated property sets" to syntax and examples.

  Revision 1.28  2010/06/20 15:59:26  aseaborne
  Editing notes

  Revision 1.27  2010/06/09 09:38:06  aseaborne
  Added doc structure for zero length and arbitrary length paths

  Revision 1.26  2010/06/08 12:32:46  aseaborne
  Add translation/evaluation table

  Revision 1.25  2010/05/27 16:15:22  aseaborne
  Sort out XSL processing to be self contained

  Revision 1.24  2010/05/27 16:07:38  aseaborne
  Note conclusions of TC 2010-05-27 in issues section

  Revision 1.22  2010/05/27 14:03:23  aseaborne
  Update issues

  Revision 1.21  2010/03/16 15:06:15  aseaborne
  Editor's notes

  Revision 1.20  2010/03/16 09:40:44  aseaborne
  Added editor's note

  Revision 1.19  2010/01/27 01:48:05  apollere2
  fixed broken fragment ID.

  Revision 1.18  2010/01/24 14:24:10  apollere2
  Document type is WD, not FPWD.

  Revision 1.17  2010/01/22 21:19:25  aseaborne
  Fix validation problems after XSLT transformation

  Revision 1.16  2010/01/22 16:26:23  apollere2
  XSLT conversion to gen.html for FPWD.

  Revision 1.15  2010/01/11 10:27:00  aseaborne
  Corrections and improvements in response to <a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2010JanMar/0099.html">2010JanMar/0099</a>.

  Revision 1.14  2010/01/06 11:08:59  aseaborne
  Corrections and improvements in response to <a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2010JanMar/0055.html">2010JanMar/0055</a>. See <a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2010JanMar/0057.html">2010JanMar/0057</a>.

  Revision 1.13  2010/01/05 11:21:14  aseaborne
  Correct the description of operator precedence

  Revision 1.12  2010/01/04 12:11:14  aseaborne
  Fix markup

  Revision 1.11  2010/01/04 12:08:41  aseaborne
  Fix markup

  Revision 1.10  2010/01/04 12:07:23  aseaborne
  Fix markup

  Revision 1.9  2010/01/04 12:06:31  aseaborne
   Abstract expanded.
   Terminolgy change: "inverse", not "reverse"
   Issues section placed at front.  Added issues for path length and "^"
   Various editorial corrections.
   Fix example using foaf:knows^foaf:knows

  Revision 1.8  2009/11/06 15:11:30  aseaborne
  Transfer content from wiki

  Revision 1.7  2009/11/06 15:09:51  aseaborne
  Transfer content from wiki

  Revision 1.6  2009/11/06 15:05:47  aseaborne
  Transfer content from wiki

  Revision 1.5  2009/11/06 15:03:25  aseaborne
  Transfer content from wiki
  
  Revision 1.4  2009/11/06 14:57:35  aseaborne
  Transfer content from wiki
  
  Revision 1.3  2009/11/06 14:47:33  aseaborne
  Transfer content from wiki
  
  Revision 1.2  2009/11/06 14:34:53  aseaborne
  Transfer content from wiki
  
  Revision 1.1  2009/11/06 13:51:34  aseaborne
  xmlspec template
  
      </pre>
  </div1>
</back>

</spec>
