<docbook><section><title>VirtTipsAndTricksTransitivityInferenceLists</title><title>How Do I use Transitivity via Inference Rules and Transitivity for lists?</title>How Do I use Transitivity via Inference Rules and Transitivity for lists?
<para>Two methods can be used for typical recursions, transitivity on inference and plain transitive patterns (or subqueries).</para>
<para>The advantage of inference is that queries are short and one inference rule set may be maintained for numerous queries.</para>
<para>If queries are about trees of classes or properties, or about equivalences of nodes, consider using inference rule sets.</para>
<para>Transitive patterns are inconvenient and may easily result in queries that runs too long or hard to debug, but they&#39;re unavoidable in traversing social networks or plain querying of RDF lists.</para>
<para>So consider a rule set, a handful of nodes with classes from the rule set and a couple of RDF Lisp-style lists defined on demo.openlinksw.com:</para>
<para> </para>
<programlisting>SQL&gt; SPARQL CLEAR GRAPH &lt;http://example.com/2/owl&gt;;
callret-0
VARCHAR
_______________________________________________________________________________

Clear &lt;http://example.com/2/owl&gt;  -- done

1 Rows. -- 0 msec.

SQL&gt; TTLP (&#39; @prefix rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;  . 
  @prefix rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;  . 
  @prefix owl: &lt;http://www.w3.org/2002/07/owl#&gt;  . 
  @prefix e: &lt;http://example.com/e/&gt;  .   
  e:c1 rdfs:subClassOf e:c1or2 . 
  e:c2 rdfs:subClassOf e:c1or2 . 
  e:c1-10 rdfs:subClassOf e:c1 . 
  e:c1-20 rdfs:subClassOf e:c1 . 
  e:c2-30 rdfs:subClassOf e:c2 . 
  e:c2-40 rdfs:subClassOf e:c2 . 
  &#39;, &#39;http://example.com/2/owl&#39;, &#39;http://example.com/2/owl&#39; );

Done. -- 0 msec.
</programlisting><para>You can also use the SPARUL equivalent variant:</para>
<programlisting>SPARQL 
PREFIX rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;  
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;  
PREFIX owl: &lt;http://www.w3.org/2002/07/owl#&gt;  
PREFIX e: &lt;http://example.com/e/&gt;  

INSERT IN GRAPH &lt;http://example.com/2/owl&gt;
  {
    e:c1 rdfs:subClassOf e:c1or2 .
    e:c2 rdfs:subClassOf e:c1or2 .
    e:c1-10 rdfs:subClassOf e:c1 .
    e:c1-20 rdfs:subClassOf e:c1 .
    e:c2-30 rdfs:subClassOf e:c2 .
    e:c2-40 rdfs:subClassOf e:c2 .
  } ;

</programlisting><para>Define the inference rule:</para>
<para> </para>
<programlisting>SQL&gt; rdfs_rule_set (&#39;http://example.com/2/owl&#39;, &#39;http://example.com/2/owl&#39;);

Done. -- 0 msec.

SQL&gt; SPARQL CLEAR GRAPH &lt;http://example.com/2/data&gt; ;
callret-0
VARCHAR
_______________________________________________________________________________

Clear &lt;http://example.com/2/data&gt;  -- done

1 Rows. -- 0 msec.

SQL&gt;  TTLP (&#39;
  @prefix e: &lt;http://example.com/e/&gt;  .
  @prefix rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;  .
  @prefix owl: &lt;http://www.w3.org/2002/07/owl#&gt;  .
  e:s1 a e:c1 ; e:p1 &quot;Value of p1 for s1&quot; .
  e:s2 a e:c2 ; e:p1 &quot;Value of p1 for s2&quot; .
  e:s1-10 a e:c1-10 ; e:p1 &quot;Value of p1 for s1-10&quot; .
  e:s1-20 a e:c1-20 ; e:p1 &quot;Value of p1 for s1-20&quot; .
  e:s2-30 a e:c2-30 ; e:p1 &quot;Value of p1 for s2-30&quot; .
  e:s2-40 a e:c2-40 ; e:p1 &quot;Value of p1 for s2-40&quot; .
  e:lists
       rdf:_1 ( e:list1-item1 e:list1-item2 e:list1-item3 ) ;
       rdf:_2 (
           [ e:p2 &quot;Value of p2 of item1 of list2&quot; ; e:p3 &quot;Value of p3 of item1 of list2&quot; ]
           [ e:p2 &quot;Value of p2 of item2 of list2&quot; ; e:p3 &quot;Value of p3 of item2 of list2&quot; ]
           [ e:p2 &quot;Value of p2 of item3 of list2&quot; ; e:p3 &quot;Value of p3 of item3 of list2&quot; ] ) .
  &#39;, &#39;http://example.com/2/data&#39;, &#39;http://example.com/2/data&#39; );

Done. -- 0 msec.

</programlisting><para> You can also use the SPARUL equivalent variant:</para>
<para> </para>
<programlisting>SPARQL 
PREFIX e: &lt;http://example.com/e/&gt;  
PREFIX rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;  
PREFIX owl: &lt;http://www.w3.org/2002/07/owl#&gt;  

INSERT IN GRAPH &lt;http://example.com/2/data&gt;
  {
    e:s1 a e:c1 ; e:p1 &quot;Value of p1 for s1&quot; .
    e:s2 a e:c2 ; e:p1 &quot;Value of p1 for s2&quot; .
    e:s1-10 a e:c1-10 ; e:p1 &quot;Value of p1 for s1-10&quot; .
    e:s1-20 a e:c1-20 ; e:p1 &quot;Value of p1 for s1-20&quot; .
    e:s2-30 a e:c2-30 ; e:p1 &quot;Value of p1 for s2-30&quot; .
    e:s2-40 a e:c2-40 ; e:p1 &quot;Value of p1 for s2-40&quot; .
    e:lists
      rdf:_1 ( e:list1-item1 e:list1-item2 e:list1-item3 ) ;
      rdf:_2 (
           [ e:p2 &quot;Value of p2 of item1 of list2&quot; ; e:p3 &quot;Value of p3 of item1 of list2&quot; ]
           [ e:p2 &quot;Value of p2 of item2 of list2&quot; ; e:p3 &quot;Value of p3 of item2 of list2&quot; ]
           [ e:p2 &quot;Value of p2 of item3 of list2&quot; ; e:p3 &quot;Value of p3 of item3 of list2&quot; ] )
  };
</programlisting><para>SPARQL DESCRIBE works fine with inference, deriving additional type information:</para>
<programlisting>DEFINE input:inference &lt;http://example.com/2/owl&gt;
DESCRIBE &lt;http://example.com/e/s1&gt;
FROM &lt;http://example.com/2/data&gt;

fmtaggret-
LONG VARCHAR
_______________________________________________________________________________

@prefix rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;  .
@prefix ns1: &lt;http://example.com/e/&gt;  .
ns1:s1 rdf:type ns1:c1or2 ,
ns1:c1 ;
ns1:p1 &quot;Value of p1 for s1&quot; .

1 Rows. -- 0 msec.
</programlisting><para>Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E%0D%0ADESCRIBE+%3Chttp%3A%2F%2Fexample.com%2Fe%2Fs1%3E%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E&amp;should-sponge=&amp;format=application%2Frdf%2Bxml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E%0D%0ADESCRIBE+%3Chttp%3A%2F%2Fexample.com%2Fe%2Fs1%3E%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E&amp;should-sponge=&amp;format=application%2Frdf%2Bxml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><programlisting>DEFINE input:inference &lt;http://example.com/2/owl&gt;
DESCRIBE &lt;http://example.com/e/s2&gt; 
FROM &lt;http://example.com/2/data&gt;
fmtaggret-
LONG VARCHAR
_______________________________________________________________________________

@prefix rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;  .
@prefix ns1: &lt;http://example.com/e/&gt;  .
ns1:s2 rdf:type ns1:c1or2 ,
ns1:c2 ;
ns1:p1 &quot;Value of p1 for s2&quot; .

1 Rows. -- 0 msec.
</programlisting><para>Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E%0D%0ADESCRIBE+%3Chttp%3A%2F%2Fexample.com%2Fe%2Fs2%3E+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E&amp;should-sponge=&amp;format=application%2Frdf%2Bxml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E%0D%0ADESCRIBE+%3Chttp%3A%2F%2Fexample.com%2Fe%2Fs2%3E+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E&amp;should-sponge=&amp;format=application%2Frdf%2Bxml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><para> Querying is simple as well:</para>
<para> </para>
<programlisting>SQL&gt;SPARQL DEFINE input:inference &lt;http://example.com/2/owl&gt;  
PREFIX e:&lt;http://example.com/e/&gt;
SELECT * 
FROM &lt;http://example.com/2/data&gt; 
WHERE 
  { 
    ?s a e:c1or2 ; 
          e:p1 ?o 
  }
  
s                            o
VARCHAR                      VARCHAR
___________________________

http://example.com/e/s1      Value of p1 for s1
http://example.com/e/s1-10   Value of p1 for s1-10
http://example.com/e/s1-20   Value of p1 for s1-20
http://example.com/e/s2-30   Value of p1 for s2-30
http://example.com/e/s2-40   Value of p1 for s2-40
http://example.com/e/s2      Value of p1 for s2

6 Rows. -- 0 msec.
</programlisting><para>Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E++%0D%0APREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+*+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E+%0D%0AWHERE+%0D%0A++%7B+%0D%0A++++%3Fs+a+e%3Ac1or2+%3B+%0D%0A++++++++++e%3Ap1+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E++%0D%0APREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+*+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E+%0D%0AWHERE+%0D%0A++%7B+%0D%0A++++%3Fs+a+e%3Ac1or2+%3B+%0D%0A++++++++++e%3Ap1+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><para> </para>
<programlisting>SQL&gt;SPARQL DEFINE input:inference &lt;http://example.com/2/owl&gt;  
PREFIX e:&lt;http://example.com/e/&gt;
SELECT * FROM &lt;http://example.com/2/data&gt;  
WHERE 
  { 
    ?s a e:c1 ; 
       e:p1 ?o 
  }
  
s                            o
VARCHAR                      VARCHAR
___________________________

http://example.com/e/s1      Value of p1 for s1
http://example.com/e/s1-10   Value of p1 for s1-10
http://example.com/e/s1-20   Value of p1 for s1-20

3 Rows. -- 0 msec.
</programlisting><para>Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E++%0D%0APREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+*+FROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B+%0D%0A++++%3Fs+a+e%3Ac1+%3B+%0D%0A+++++++e%3Ap1+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E++%0D%0APREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+*+FROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B+%0D%0A++++%3Fs+a+e%3Ac1+%3B+%0D%0A+++++++e%3Ap1+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><para>However you should care about duplicates if both types and properties are queried: the join will result in all combinations of types and property values.</para>
<programlisting>SQL&gt;SPARQL DEFINE input:inference &lt;http://example.com/2/owl&gt;  
PREFIX e:&lt;http://example.com/e/&gt;
SELECT * FROM &lt;http://example.com/2/data&gt;  
WHERE 
  { 
    ?s a ?t ; 
     e:p1 ?o 
  }
  
s                            t                            o
VARCHAR                      VARCHAR                      VARCHAR
___________________________

http://example.com/e/s1      http://example.com/e/c1      Value of p1 for s1
http://example.com/e/s1      http://example.com/e/c1or2   Value of p1 for s1
http://example.com/e/s1-10   http://example.com/e/c1-10   Value of p1 for s1-10
http://example.com/e/s1-10   http://example.com/e/c1      Value of p1 for s1-10
http://example.com/e/s1-10   http://example.com/e/c1or2   Value of p1 for s1-10
http://example.com/e/s1-20   http://example.com/e/c1-20   Value of p1 for s1-20
http://example.com/e/s1-20   http://example.com/e/c1      Value of p1 for s1-20
http://example.com/e/s1-20   http://example.com/e/c1or2   Value of p1 for s1-20
http://example.com/e/s2-30   http://example.com/e/c2-30   Value of p1 for s2-30
http://example.com/e/s2-30   http://example.com/e/c2      Value of p1 for s2-30
http://example.com/e/s2-30   http://example.com/e/c1or2   Value of p1 for s2-30
http://example.com/e/s2-40   http://example.com/e/c2-40   Value of p1 for s2-40
http://example.com/e/s2-40   http://example.com/e/c2      Value of p1 for s2-40
http://example.com/e/s2-40   http://example.com/e/c1or2   Value of p1 for s2-40
http://example.com/e/s2      http://example.com/e/c2      Value of p1 for s2
http://example.com/e/s2      http://example.com/e/c1or2   Value of p1 for s2

16 Rows. -- 0 msec.
</programlisting><para> Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E++%0D%0APREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+*+FROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B+%0D%0A++++%3Fs+a+%3Ft+%3B+%0D%0A+++++e%3Ap1+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=DEFINE+input%3Ainference+%3Chttp%3A%2F%2Fexample.com%2F2%2Fowl%3E++%0D%0APREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+*+FROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B+%0D%0A++++%3Fs+a+%3Ft+%3B+%0D%0A+++++e%3Ap1+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><para> Transitive queries are convenient as SPARQL 1.1 &quot;predicate+&quot; equivalent.
 The equivalent of &quot;predicate*&quot; requires the use of a union:</para>
<para> </para>
<programlisting>SQL&gt;SPARQL PREFIX e:&lt;http://example.com/e/&gt;
SELECT ?item 
FROM &lt;http://example.com/2/data&gt;  
WHERE 
  {
    { 
      ?lists rdf:_1 ?node 
    }
    UNION
    { 
      ?lists rdf:_1 ?l .
      ?l rdf:rest ?node option (transitive) . 
    }
    ?node rdf:first ?item 
  }
  
item
VARCHAR
_______________________________________________________________________________

http://example.com/e/list1-item1
http://example.com/e/list1-item2
http://example.com/e/list1-item3

3 Rows. -- 0 msec.
</programlisting><para> Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=PREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+%3Fitem+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_1+%3Fnode+%0D%0A++++%7D%0D%0A++++UNION%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_1+%3Fl+.%0D%0A++++++%3Fl+rdf%3Arest+%3Fnode+option+%28transitive%29+.+%0D%0A++++%7D%0D%0A++++%3Fnode+rdf%3Afirst+%3Fitem+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=PREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+%3Fitem+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_1+%3Fnode+%0D%0A++++%7D%0D%0A++++UNION%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_1+%3Fl+.%0D%0A++++++%3Fl+rdf%3Arest+%3Fnode+option+%28transitive%29+.+%0D%0A++++%7D%0D%0A++++%3Fnode+rdf%3Afirst+%3Fitem+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><para> </para>
<programlisting>SQL&gt; SPARQL PREFIX e:&lt;http://example.com/e/&gt;
SELECT ?p ?o 
FROM &lt;http://example.com/2/data&gt;  
WHERE 
  {
    { 
      ?lists rdf:_2 ?node 
    }
    UNION
    { 
      ?lists rdf:_2 ?l .
      ?l rdf:rest ?node option (transitive) . 
    }
    ?node rdf:first ?item .
    ?item ?p ?o 
  }
  
p                         o
VARCHAR                   VARCHAR
________________________

http://example.com/e/p2   Value of p2 of item1 of list2
http://example.com/e/p3   Value of p3 of item1 of list2
http://example.com/e/p2   Value of p2 of item2 of list2
http://example.com/e/p3   Value of p3 of item2 of list2
http://example.com/e/p2   Value of p2 of item3 of list2
http://example.com/e/p3   Value of p3 of item3 of list2

6 Rows. -- 0 msec.
</programlisting><para>Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=PREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+%3Fp+%3Fo+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fnode+%0D%0A++++%7D%0D%0A++++UNION%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fl+.%0D%0A++++++%3Fl+rdf%3Arest+%3Fnode+option+%28transitive%29+.+%0D%0A++++%7D%0D%0A++++%3Fnode+rdf%3Afirst+%3Fitem+.%0D%0A++++%3Fitem+%3Fp+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=PREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+%3Fp+%3Fo+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fnode+%0D%0A++++%7D%0D%0A++++UNION%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fl+.%0D%0A++++++%3Fl+rdf%3Arest+%3Fnode+option+%28transitive%29+.+%0D%0A++++%7D%0D%0A++++%3Fnode+rdf%3Afirst+%3Fitem+.%0D%0A++++%3Fitem+%3Fp+%3Fo+%0D%0A++%7D&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><para>Note that the result set can be in order of items in the list, but it don&#39;t have to.
 If the order should be preserved, then fix the direction of transitive scan, get step number as a variable, order by that variable.</para>
<para> </para>
<programlisting>SQL&gt; SPARQL PREFIX e:&lt;http://example.com/e/&gt;
SELECT ?p ?o bif:coalesce(?step_no, 0) 
FROM &lt;http://example.com/2/data&gt;  
WHERE 
  {
    { 
      ?lists rdf:_2 ?node 
    }
    UNION
    { 
      ?lists rdf:_2 ?l .
      ?l rdf:rest ?node OPTION (transitive, t_direction 1, t_step(&quot;step_no&quot;) as ?step_no) . 
    }
    ?node rdf:first ?item .
    ?item ?p ?o 
  } 
ORDER BY ASC (?step_no)

p                         o                               callret-2
VARCHAR                   VARCHAR                         VARCHAR
________________________

http://example.com/e/p2   Value of p2 of item1 of list2   0
http://example.com/e/p3   Value of p3 of item1 of list2   0
http://example.com/e/p2   Value of p2 of item2 of list2   1
http://example.com/e/p3   Value of p3 of item2 of list2   1
http://example.com/e/p2   Value of p2 of item3 of list2   2
http://example.com/e/p3   Value of p3 of item3 of list2   2

6 Rows. -- 7 msec.
</programlisting><para> Example links against <ulink url="http://demo.openlinksw.com/sparql">Virtuoso Demo Server SPARQL Endpoint</ulink> with SPARQl Protocol URLs:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;query=PREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+%3Fp+%3Fo+bif%3Acoalesce%28%3Fstep_no%2C+0%29+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fnode+%0D%0A++++%7D%0D%0A++++UNION%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fl+.%0D%0A++++++%3Fl+rdf%3Arest+%3Fnode+OPTION+%28transitive%2C+t_direction+1%2C+t_step%28%22step_no%22%29+as+%3Fstep_no%29+.+%0D%0A++++%7D%0D%0A++++%3Fnode+rdf%3Afirst+%3Fitem+.%0D%0A++++%3Fitem+%3Fp+%3Fo+%0D%0A++%7D+%0D%0AORDER+BY+ASC+%28%3Fstep_no%29%0D%0A&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View results page</ulink> </listitem>
<listitem><ulink url="http://demo.openlinksw.com/sparql?default-graph-uri=&amp;qtxt=PREFIX+e%3A%3Chttp%3A%2F%2Fexample.com%2Fe%2F%3E%0D%0ASELECT+%3Fp+%3Fo+bif%3Acoalesce%28%3Fstep_no%2C+0%29+%0D%0AFROM+%3Chttp%3A%2F%2Fexample.com%2F2%2Fdata%3E++%0D%0AWHERE+%0D%0A++%7B%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fnode+%0D%0A++++%7D%0D%0A++++UNION%0D%0A++++%7B+%0D%0A++++++%3Flists+rdf%3A_2+%3Fl+.%0D%0A++++++%3Fl+rdf%3Arest+%3Fnode+OPTION+%28transitive%2C+t_direction+1%2C+t_step%28%22step_no%22%29+as+%3Fstep_no%29+.+%0D%0A++++%7D%0D%0A++++%3Fnode+rdf%3Afirst+%3Fitem+.%0D%0A++++%3Fitem+%3Fp+%3Fo+%0D%0A++%7D+%0D%0AORDER+BY+ASC+%28%3Fstep_no%29%0D%0A&amp;should-sponge=&amp;format=text%2Fhtml&amp;CXML_redir_for_subjs=121&amp;CXML_redir_for_hrefs=&amp;timeout=0&amp;debug=on">View editor page</ulink></listitem>
</itemizedlist><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2">Related</bridgehead>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="VirtTipsAndTricksGuide">Virtuoso Tips and Tricks Collection</ulink> </listitem>
<listitem><ulink url="http://docs.openlinksw.com/virtuoso/rdfsparqlrule.html#rdfsparqlrulesubclassandsubprop">Virtuoso Documentation: Subclasses and Subproperties</ulink> </listitem>
<listitem><ulink url="VirtsubClassOfOrientedSubsumptionTransitiveOptions">Transitive SPARQL query options and Exploit Inference Rules Examples</ulink> </listitem>
</itemizedlist></section></docbook>