Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > a2da5eab8fb68605fe995d94e514eeb0 > files > 37

cduce-0.5.3-2mdv2010.0.i586.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>CDuce: Queries</title><meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type"/><link type="text/css" rel="stylesheet" href="cduce.css"/></head><body style="margin: 0; padding : 0;"><table border="0" width="100&#37;" cellspacing="10" cellpadding="0"><tr><td valign="top" align="left" style="width:20&#37;;"><div class="leftbar" id="leftbar"><div class="smallbox"><ul><li><a href="#sel">Select from where</a></li><li><a href="#xpath">XPath-like expressions</a></li><li><a href="#exsel">Examples</a></li></ul><p>
You can cut and paste the code on this page and 
test it on the <a href="cgi-bin/cduce">online interpreter</a>.
</p></div></div></td><td><h1>Queries</h1><div class="mainpanel"><div class="smallbox"><p><a href="index.html">CDuce: documentation</a>: <a href="tutorial.html">Tutorial</a>: Queries</p><p><a href="tutorial_references.html"><img class="icon" width="16" alt="Previous page:" height="16" src="img/left.gif"/> References</a> <a href="tutorial_higherorder.html"><img class="icon" width="16" alt="Next page:" height="16" src="img/right.gif"/> Higher-order functions</a></p></div><div><h2><a name="sel">Select from where</a></h2><b style="color:#FF0080">WE SHOULD REWRITE THIS SECTION TO
GET RID OF THE MANY TYPE DEFINITIONS. JUST USE THE ONE 
OF USE CASES</b><p>
CDuce is endowed with a <b><tt>select_from_where</tt></b> syntax to perform some SQL-like queries. The general form of select expressions is
</p><div class="code"><pre>
select <i>e</i> from
   <i>p1</i> in <i>e1</i>,
   <i>p2</i> in <i>e2</i>,
       :
   <i>pn</i> in <i>en</i>
where <i>b</i>
</pre></div><p>
where <b><tt><i>e</i></tt></b> is an expression <b><tt><i>b</i></tt></b> a boolean expression, the <b><tt><i>pi</i></tt></b>'s are patterns, and  the <b><tt><i>ei</i></tt></b>'s are sequence expressions.
</p><p>
The <b><tt>select_from_where</tt></b> construction is translated into:
</p><div class="code"><pre>
transform <i>e1</i> with <i>p1</i> -&gt; 
   transform <i>e2</i> with <i>p2</i> -&gt; 
         ...
       transform <i>en</i> with <i>pn</i> -&gt; 
          if <i>b</i> then  [<i>e</i>] else []

</pre></div></div><div><h2><a name="xpath">XPath-like expressions</a></h2><p> XPath-like expressions are of two kind :
<b><tt> <i>e</i>/<i>t</i> </tt></b>, <b><tt> <i>e</i>/@<i>a</i> </tt></b>, (and  <b><tt> <i>e</i>//<i>t</i> </tt></b>) where <b><tt><i>e</i></tt></b> is an expression, <b><tt> <i>t</i> </tt></b> a type, and <b><tt> <i>a</i> </tt></b> an attribute.
</p><p> 
They are syntactic sugar for :</p><div class="code"><pre> flatten(select x from &lt;_ ..&gt;[(x::t | _ )*] in e) </pre></div><p>  and </p><div class="code"><pre>
select x from &lt;_ a=x ..&gt;_ in  e
</pre></div></div><div><h2><a name="exsel">Examples</a></h2><h3>Types and data for the examples</h3><p> Let us consider the following DTD and the CDuce types representing a Bibliography </p><div class="code"><pre>
&lt;!ELEMENT bib  (book* )&gt;
&lt;!ELEMENT book  (title,  (author+ | editor+ ), publisher, price )&gt;
&lt;!ATTLIST book  year CDATA  #REQUIRED &gt;
&lt;!ELEMENT author  (last, first )&gt;
&lt;!ELEMENT editor  (last, first, affiliation )&gt;
&lt;!ELEMENT title  (#PCDATA )&gt;
&lt;!ELEMENT last  (#PCDATA )&gt;
&lt;!ELEMENT first  (#PCDATA )&gt;
&lt;!ELEMENT affiliation  (#PCDATA )&gt;
&lt;!ELEMENT publisher  (#PCDATA )&gt;
&lt;!ELEMENT price  (#PCDATA )&gt;

type bib = &lt;bib&gt;[book*]
type book = &lt;book year=String&gt;[title  (author+ | editor+ ) publisher price ]
type author = &lt;author&gt;[last  first ]
type editor = &lt;editor&gt;[last  first  affiliation ]
type title  = &lt;title&gt;[PCDATA ]
type last  = &lt;last&gt;[PCDATA]
type first  = &lt;first&gt;[PCDATA]
type affiliation = &lt;affiliation&gt;[PCDATA]
type publisher  = &lt;publisher&gt;[PCDATA]
type price  = &lt;price&gt;[PCDATA]

</pre></div><p> and some values </p><div class="code"><pre>
let biblio : bib = 
           &lt;bib&gt;[
              &lt;book year=&quot;1994&quot;&gt;[
                 &lt;title&gt;['TCP/IP Illustrated']
                 &lt;author&gt;[
	            &lt;last&gt;['Stevens']
		    &lt;first&gt;['W.']]
                 &lt;publisher&gt;['Addison-Wesley']
	         &lt;price&gt;['65.95'] ]
	     &lt;book year=&quot;1992&quot;&gt;[
                &lt;title&gt;['Advanced Programming in the Unix environment']
		&lt;author&gt;[
		   &lt;last&gt;['Stevens'] 
		   &lt;first&gt;['W.']]
        	&lt;publisher&gt;['Addison-Wesley']
        	&lt;price&gt;['65.95'] ]
	     &lt;book year=&quot;2000&quot;&gt;[ 
	        &lt;title&gt;['Data on the Web']
        	&lt;author&gt;[
		  &lt;last&gt;['Abiteboul'] 
		  &lt;first&gt;['Serge']]
	        &lt;author&gt;[
		  &lt;last&gt;['Buneman'] 
		  &lt;first&gt;['Peter']]
                &lt;author&gt;[
		  &lt;last&gt;['Suciu'] 
		  &lt;first&gt;['Dan']]
	        &lt;publisher&gt;['Morgan Kaufmann Publishers']
                &lt;price&gt;['39.95'] ]
	     &lt;book year=&quot;1999&quot;&gt;[
	        &lt;title&gt;['The Economics of Technology and Content for Digital TV']
                &lt;editor&gt;[
                   &lt;last&gt;['Gerbarg'] 
		   &lt;first&gt;['Darcy']
                   &lt;affiliation&gt;['CITI'] ]
		&lt;publisher&gt;['Kluwer Academic Publishers']
                &lt;price&gt;['129.95']]
             ]

</pre></div><h3>Projections</h3><ul><li> All titles in the bibliography biblio 
<div class="code"><pre>
let titles = [biblio]/book/title

</pre></div><p> Which yields to:</p><div class="code"><pre>
val titles : [ title* ] = [ &lt;title&gt;[ 'TCP/IP Illustrated' ]
                            &lt;title&gt;[ 'Advanced Programming in the Unix environment' ]
                            &lt;title&gt;[ 'Data on the Web' ]
                            &lt;title&gt;[ 'The Economics of Technology and Content for Digital TV' ]
                          ]

</pre></div></li><li>All authors in the bibliography biblio
<div class="code"><pre>
let authors = [biblio]/book/&lt;author&gt;_

</pre></div><p> Yielding the result: </p><div class="code"><pre>
val authors : [ &lt;author&gt;[ last first ]* ] = 
                            [ &lt;author&gt;[ &lt;last&gt;[ 'Stevens' ] &lt;first&gt;[ 'W.' ] ]
                              &lt;author&gt;[ &lt;last&gt;[ 'Stevens' ] &lt;first&gt;[ 'W.' ] ]
                              &lt;author&gt;[
                                &lt;last&gt;[ 'Abiteboul' ]
                                &lt;first&gt;[ 'Serge' ] ]
                              &lt;author&gt;[
                                &lt;last&gt;[ 'Buneman' ]
                                &lt;first&gt;[ 'Peter' ] ]
                              &lt;author&gt;[ &lt;last&gt;[ 'Suciu' ] &lt;first&gt;[ 'Dan' ] ]
                            ]

</pre></div><p>Note the difference between this two projections.<br/> 
In the fist one, we use the preset type title (type title  = &lt;title&gt;[PCDATA ]
).<br/>
In the second one, the type &lt;author&gt;_ means all the xml fragments beginning by the tag author ( _ means Any), 
and this tag is without attribute. In contrary, we write note  &lt;author ..&gt;_. 
</p></li><li> All books having an editor in the bibliography biblio 
<div class="code"><pre>
let edibooks = [biblio]/&lt;book year=_&gt;[_* editor _*]

</pre></div><p> Yielding: </p><div class="code"><pre>
val edibooks : [ &lt;book year=String&gt;[ title editor+ publisher price]* ] = 
           [ &lt;book year=&quot;1999&quot;&gt;[
                 &lt;title&gt;[ 'The Economics of Technology and Content for Digital TV']
                 &lt;editor&gt;[
                    &lt;last&gt;[ 'Gerbarg' ]
                    &lt;first&gt;[ 'Darcy' ]
                 &lt;affiliation&gt;[ 'CITI' ] ]
                 &lt;publisher&gt;[ 'Kluwer Academic Publishers' ]
                 &lt;price&gt;[ '129.95' ] ]
          ]

</pre></div></li><li> All books without authors. 
<div class="code"><pre>
let edibooks2 = [biblio]/&lt;book ..&gt;[(Any\author)*]

</pre></div><p> Yielding: </p><div class="code"><pre>
val edibooks2 : [ &lt;book year=String&gt;[ title editor+ publisher price]* ] = 
           [ &lt;book year=&quot;1999&quot;&gt;[
                 &lt;title&gt;[ 'The Economics of Technology and Content for Digital TV']
                 &lt;editor&gt;[
                    &lt;last&gt;[ 'Gerbarg' ]
                    &lt;first&gt;[ 'Darcy' ]
                 &lt;affiliation&gt;[ 'CITI' ] ]
                 &lt;publisher&gt;[ 'Kluwer Academic Publishers' ]
                 &lt;price&gt;[ '129.95' ] ]
          ]

</pre></div></li><li> The year of books having a price of 65.95 in the bibliography biblio 
<div class="code"><pre>
let books = [biblio]/&lt;book ..&gt;[_* &lt;price&gt;['65.95']]/@year

</pre></div><p> Yielding: </p><div class="code"><pre>
val books : [ String* ] = [ &quot;1994&quot; &quot;1992&quot; ]

</pre></div></li><li> All the authors and editors in biblio
<div class="code"><pre>
let aebooks = [biblio]/book/(author|editor)

</pre></div><p> Yielding: </p><div class="code"><pre>
val aebooks : [ (editor | author)* ] = [ &lt;author&gt;[
                                         &lt;last&gt;[ 'Stevens' ]
                                         &lt;first&gt;[ 'W.' ]
                                         ]
                                       &lt;author&gt;[
                                         &lt;last&gt;[ 'Stevens' ]
                                         &lt;first&gt;[ 'W.' ]
                                         ]
                                       &lt;author&gt;[
                                         &lt;last&gt;[ 'Abiteboul' ]
                                         &lt;first&gt;[ 'Serge' ]
                                         ]
                                       &lt;author&gt;[
                                         &lt;last&gt;[ 'Buneman' ]
                                         &lt;first&gt;[ 'Peter' ]
                                         ]
                                       &lt;author&gt;[
                                         &lt;last&gt;[ 'Suciu' ]
                                         &lt;first&gt;[ 'Dan' ]
                                         ]
                                       &lt;editor&gt;[
                                         &lt;last&gt;[ 'Gerbarg' ]
                                         &lt;first&gt;[ 'Darcy' ]
                                         &lt;affiliation&gt;[ 'CITI' ]
                                         ]
                                       ]

</pre></div></li></ul><p>
An interesting point in Cduce is the static typing of an expression. By example if we consider the third projection, 
&quot;All books having an editor in the bibliography&quot;, CDuce knows the type of the result of the value <b><tt><i>edibooks</i></tt></b>:
</p><div class="code"><pre>
val edibooks : [ &lt;book year=String&gt;[ title editor+ publisher price]* ] = 
...

</pre></div><p>This type represents a book without author (see the book type in the type declaration in the top of this section).
Now if we want to know all authors of this list of books <b><tt><i>edibooks</i></tt></b>:
</p><div class="code"><pre>
let authorsofedibooks = edibooks/author

</pre></div><p>Yelding:</p><div class="code"><pre>
Warning at chars 24-39:
This projection always returns the empty sequence
val authorsofedibooks : [  ] = &quot;&quot;

</pre></div><p>
In fact the value <b><tt><i>edibooks</i></tt></b> must be a subtype of [&lt;_ ..&gt;[Any* author Any*] *], 
and here this is not the case. 
If you want to be sure, test this:
</p><div class="code"><pre>
match edibooks with [&lt;_ ..&gt;[_* author _*] *] -&gt; &quot;this is a subtype&quot; | _ -&gt; &quot;this is not a subtype&quot; ;;

</pre></div><p>
An other projection should be convince you, is the query:
</p><div class="code"><pre>
let freebooks = [biblio]/book/&lt;price&gt;['0']
]
</pre></div><p>Yelding:</p><div class="code"><pre>
val freebooks : [ &lt;price&gt;[ '0' ]* ] = &quot;&quot;

</pre></div><p>
There is no free books in this bibliography, That is not indicated by the type of biblio.
Then, this projection returns the empty sequence (<b><tt>&quot;&quot;</tt></b>)</p><h3>Select_from_where</h3><p>The same queries we wrote above can of course be programmed with the <b><tt>select_from_where</tt></b> construction </p><p> All the titles </p><div class="code"><pre>
let tquery = select y 
             from x in [biblio]/book ,
                  y in [x]/title

</pre></div><p> This query is programmed in a XQuery-like style largely relying on the projections. Note that <b><tt>x</tt></b> and <b><tt>y</tt></b> are CDuce's patterns. The result is:</p><div class="code"><pre> 
val tquery : [ title* ] = [ &lt;title&gt;[ 'TCP/IP Illustrated' ]
                            &lt;title&gt;[ 'Advanced Programming in the Unix environment' ]
                            &lt;title&gt;[ 'Data on the Web' ]
                            &lt;title&gt;[ 'The Economics of Technology and Content for Digital TV' ]
                          ]

</pre></div><p> Now let's program the same query with the translation given previously thus eliminating the <b><tt>y</tt></b> variable </p><div class="code"><pre>
let withouty = flatten(select [x] from x in [biblio]/book/title)

</pre></div><p> Yielding: </p><div class="code"><pre>
val tquery : [ title* ] = [ &lt;title&gt;[ 'TCP/IP Illustrated' ]
                            &lt;title&gt;[ 'Advanced Programming in the Unix environment' ]
                            &lt;title&gt;[ 'Data on the Web' ]
                            &lt;title&gt;[ 'The Economics of Technology and Content for Digital TV' ]
                          ]

</pre></div><p>
But the <b><tt>select_from_where</tt></b> expressions are likely to be used for
more complex queries such as the one that selects all titles whose at least one
author is &quot;Peter Buneman&quot; or &quot;Dan Suciu&quot;
</p><div class="code"><pre>
let sel = select y 
          from x in [biblio]/book ,
               y in [x]/title,
               z in [x]/author
where ( (z = &lt;author&gt;[&lt;last&gt;['Buneman']&lt;first&gt;['Peter']])
 || (z = &lt;author&gt;[&lt;last&gt;['Suciu'] &lt;first&gt;['Dan']]) )

</pre></div><p> Which yields: </p><div class="code"><pre>
val sel : [ title* ] = [ &lt;title&gt;[ 'Data on the Web' ]
                         &lt;title&gt;[ 'Data on the Web' ]
                         ]

</pre></div><p>Note that the corresponding semantics, as in SQL, is a multiset one.
Thus duplicates are not eliminated. To discard them, one has to use the <b><tt>distinct_values</tt></b> operator.
</p><h3>A pure pattern example</h3><p>
This example computes the same result as the previous query except that
duplicates are eliminated. It is written in a pure pattern form (i.e., without
any XPath-like projections)
</p><div class="code"><pre>
let sel = select t
from &lt;_ ..&gt;[(x::book| _ )*] in [biblio],
     &lt;_ ..&gt;[ t&amp;title _* (&lt;author&gt;[&lt;last&gt;['Buneman']&lt;first&gt;['Peter']]
                       | &lt;author&gt;[&lt;last&gt;['Suciu'] &lt;first&gt;['Dan']]) ; _]  in x  


</pre></div><p>
Note the pattern on the second line in the <b><tt> from </tt></b> clause. 
As the type of an element in <b><tt>x</tt></b> is 
<b><tt>type book = &lt;book year=String&gt;[title  (author+ | editor+ ) publisher price ]</tt></b>, 
we skip the tag : 
<b><tt>&lt;_ ..&gt;</tt></b>, then  
we then capture the corresponding title <b><tt>(t &amp;title)</tt></b>
then we skip authors <b><tt>_* </tt></b> 
until we find either Peter Buneman or Dan Suciu 
<b><tt> (&lt;author&gt;[&lt;last&gt;['Buneman']&lt;first&gt;['Peter']]| &lt;author&gt;[&lt;last&gt;['Suciu'] &lt;first&gt;['Dan']])</tt></b>,
then we skip the remaining authors and the tail of the sequence by writing <b><tt>; _</tt></b></p><p>
Result:
</p><div class="code"><pre>
val sel : [ title* ] = [ &lt;title&gt;[ 'Data on the Web' ] ]
</pre></div><p>
This pure pattern form of the query yields (in general) better performance than
the same one written in an XQuery-like programming style. However, the query
optimiser automatically translates the latter into a pure pattern one
</p><h3>Joins</h3><p>
This example is the exact transcription of <a href="http://www.w3.org/TR/xquery-use-cases/#xmp-queries-results-q5">query Q5 of XQuery use cases</a>.
On top of this section we give the corresponding CDuce types.
We give here the type of the document to be joined, and the sample value.
</p><div class="code"><pre>
type Reviews =&lt;reviews&gt;[Entry*]
type Entry = &lt;entry&gt; [ Title Price Review]
type Title = &lt;title&gt;[PCDATA]
type Price= &lt;price&gt;[PCDATA]
type Review =&lt;review&gt;[PCDATA]

let bstore2 : Reviews =
&lt;reviews&gt;[
    &lt;entry&gt;[
        &lt;title&gt;['Data on the Web']
        &lt;price&gt;['34.95']
        &lt;review&gt;
               ['A very good discussion of semi-structured database
               systems and XML.']
     ]
    &lt;entry&gt;[
        &lt;title&gt;['Advanced Programming in the Unix environment']
        &lt;price&gt;['65.95']
        &lt;review&gt;
               ['A clear and detailed discussion of UNIX programming.']
     ]
    &lt;entry&gt;[
        &lt;title&gt;['TCP/IP Illustrated']
        &lt;price&gt;['65.95']
        &lt;review&gt;
               ['One of the best books on TCP/IP.']
    ]
]

</pre></div><p>

The queries are expressed first in an XQuery-like style, then in a pure pattern style: the first pattern-based query is the one produced by the automatic translation from the first one. The last query correponds to a pattern aware programmer's version.
</p><p>
XQuery style
</p><div class="code"><pre>
&lt;books-with-prices&gt;
select &lt;book-with-price&gt;[t1 &lt;price-bstore1&gt;([p1]/Char) &lt;price-bstore2&gt;([p2]/Char)]
from b in [biblio]/book ,
     t1 in [b]/title,
     e in [bstore2]/Entry,
     t2 in [e]/Title,
     p2 in [e]/Price,
     p1 in [b]/price
 where t1=t2

</pre></div><p> Automatic translation of the previous query into a pure pattern (thus more efficient) one </p><div class="code"><pre>
&lt;books-with-prices&gt;
select &lt;book-with-price&gt;[t1 &lt;price-bstore1&gt;x10 &lt;price-bstore2&gt;x11 ]
from &lt;_ ..&gt;[(x3::book|_)*] in [biblio],
     &lt;_ ..&gt;[(x9::price|x5::title|_)*] in x3,
     t1 in x5,
     &lt;_ ..&gt;[(x6::Entry|_)*] in [bstore2],
     &lt;_ ..&gt;[(x7::Title|x8::Price|_)*] in x6,
     t2 in x7,
     &lt;_ ..&gt;[(x10::Char)*] in x9,
     &lt;_ ..&gt;[(x11::Char)*] in x8
 where t1=t2

</pre></div><p>  
Pattern aware programmer's version of the same query (hence hand optimised).
This version of the query is very efficient. Be aware of patterns.
</p><div class="code"><pre>
&lt;books-with-prices&gt;
select &lt;book-with-price&gt;[t2 &lt;price-bstore1&gt;p1 &lt;price-bstore2&gt;p2]
from &lt;bib&gt;[b::book*] in [biblio],
     &lt;book ..&gt;[t1&amp;title _* &lt;price&gt;p1] in b,
     &lt;reviews&gt;[e::Entry*] in [bstore2],
     &lt;entry&gt;[t2&amp;Title &lt;price&gt;p2 ;_] in e
where t1=t2

</pre></div><h3>More complex Queries: on the power of patterns</h3><div class="code"><pre>
let biblio = [biblio]/book;;

&lt;bib&gt;
    select &lt;book (a)&gt; x
      from &lt;book (a)&gt;[ (x::(Any\editor)|_ )* ] in biblio 

</pre></div><p>
This expression returns all book  in bib but removoing the editor element.
If one wants to write more explicitly:
</p><div class="code"><pre>
    select &lt;book (a)&gt; x
      from &lt;book (a)&gt;[ (x::(Any\<strong class="ocaml">&lt;editor ..&gt;_</strong>)|_ )* ] in biblio

</pre></div><p>Or even:
</p><div class="code"><pre>
    select &lt;book (a)&gt; x
      from &lt;book (a)&gt;[ (x::(&lt;(<strong class="ocaml">_</strong>\<strong class="ocaml">`editor</strong>) ..&gt;_)|_ )* ] in biblio

</pre></div><p>Back to the first one:</p><div class="code"><pre>
&lt;bib&gt;
    select &lt;book (a)&gt; x
      from &lt;<strong class="ocaml">(</strong>book<strong class="ocaml">)</strong> (a)&gt;[ (x::(Any\editor)|_ )* ] in biblio

</pre></div><p>
This query takes any element in bib, tranforms it in a book element and
removes sub-elements  editor, but you will get a warning as capture variable <b><tt>book</tt></b> in the <b><tt>from</tt></b> is never used: we should have written <b><tt>&lt;(_) (a)&gt;</tt></b> instead of <b><tt>&lt;(book) (a)&gt;</tt></b>
the from 
</p><div class="code"><pre>
    select &lt;<strong class="ocaml">(</strong>book<strong class="ocaml">)</strong> (a)&gt; x
      from &lt;(book) (a)&gt;[ (x::(Any\editor)|_ )* ] in biblio

</pre></div><p> Same thing but without tranforming tag to  &quot;book&quot;.<br/>
More interestingly:</p><div class="code"><pre>
    select &lt;(b) (a\<strong class="ocaml">id</strong>)&gt; x
      from &lt;(b) (a)&gt;[ (x::(Any\editor)|_ )* ] in biblio

</pre></div><p>removes all &quot;id&quot; attribute (if any) from the attributes of the element in bib.
</p><div class="code"><pre>

    select &lt;(b) (a\id+{bing=a.id})&gt; x
      from &lt;(b) (a)&gt;[ (x::(Any\editor)|_ )* ] in biblio

</pre></div><p>Changes attribute <b><tt>id=x</tt></b> into <b><tt>bing=x</tt></b>
However, one must be sure that each element in <b><tt>bib</tt></b> has an <b><tt>id</tt></b> attribute
if such is not the case the expression is ill-typed. If one wants to perform this only for those elements which certainly have an <b><tt>id</tt></b> attribute then:
</p><div class="code"><pre>
    select &lt;(b) (a\id+{bing=a.id})&gt; x
      from &lt;(b) (a&amp;{id=_})&gt;[ (x::(Any\editor)|_ )* ] in biblio

</pre></div><h3>An unorthodox query: Formatted table generation</h3><p>
The following program generates a 10x10 multiplication table:
</p><div class="code"><pre>
let bg ((Int , Int) -&gt; String) 
  (y, x) -&gt; if (x mod 2 + y mod 2 &lt;= 0) then &quot;lightgreen&quot; 
            else if (y mod 2 &lt;= 0) then &quot;yellow&quot;
	    else if (x mod 2 &lt;= 0) then &quot;lightblue&quot;
	    else &quot;white&quot;;;

&lt;table border=&quot;1&quot;&gt;
  select &lt;tr&gt; select &lt;td align=&quot;right&quot; style=(&quot;background:&quot;@bg(x,y)) &gt;[ (x*y) ]
              from y in [1 2 3 4 5 6 7 8 9 10] : [1--10*] 
  from x in [1 2 3 4 5 6 7 8 9 10] : [1--10*];;
 </pre></div><p>
The result is the xhtml code that generates the following table:
</p><table width="100&#37;"><tr><td align="center"><table border="1"><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><tr><td align="right" style="background:white">1</td><td align="right" style="background:lightblue">2</td><td align="right" style="background:white">3</td><td align="right" style="background:lightblue">4</td><td align="right" style="background:white">5</td><td align="right" style="background:lightblue">6</td><td align="right" style="background:white">7</td><td align="right" style="background:lightblue">8</td><td align="right" style="background:white">9</td><td align="right" style="background:lightblue">10</td></tr><tr><td align="right" style="background:yellow">2</td><td align="right" style="background:lightgreen">4</td><td align="right" style="background:yellow">6</td><td align="right" style="background:lightgreen">8</td><td align="right" style="background:yellow">10</td><td align="right" style="background:lightgreen">12</td><td align="right" style="background:yellow">14</td><td align="right" style="background:lightgreen">16</td><td align="right" style="background:yellow">18</td><td align="right" style="background:lightgreen">20</td></tr><tr><td align="right" style="background:white">3</td><td align="right" style="background:lightblue">6</td><td align="right" style="background:white">9</td><td align="right" style="background:lightblue">12</td><td align="right" style="background:white">15</td><td align="right" style="background:lightblue">18</td><td align="right" style="background:white">21</td><td align="right" style="background:lightblue">24</td><td align="right" style="background:white">27</td><td align="right" style="background:lightblue">30</td></tr><tr><td align="right" style="background:yellow">4</td><td align="right" style="background:lightgreen">8</td><td align="right" style="background:yellow">12</td><td align="right" style="background:lightgreen">16</td><td align="right" style="background:yellow">20</td><td align="right" style="background:lightgreen">24</td><td align="right" style="background:yellow">28</td><td align="right" style="background:lightgreen">32</td><td align="right" style="background:yellow">36</td><td align="right" style="background:lightgreen">40</td></tr><tr><td align="right" style="background:white">5</td><td align="right" style="background:lightblue">10</td><td align="right" style="background:white">15</td><td align="right" style="background:lightblue">20</td><td align="right" style="background:white">25</td><td align="right" style="background:lightblue">30</td><td align="right" style="background:white">35</td><td align="right" style="background:lightblue">40</td><td align="right" style="background:white">45</td><td align="right" style="background:lightblue">50</td></tr><tr><td align="right" style="background:yellow">6</td><td align="right" style="background:lightgreen">12</td><td align="right" style="background:yellow">18</td><td align="right" style="background:lightgreen">24</td><td align="right" style="background:yellow">30</td><td align="right" style="background:lightgreen">36</td><td align="right" style="background:yellow">42</td><td align="right" style="background:lightgreen">48</td><td align="right" style="background:yellow">54</td><td align="right" style="background:lightgreen">60</td></tr><tr><td align="right" style="background:white">7</td><td align="right" style="background:lightblue">14</td><td align="right" style="background:white">21</td><td align="right" style="background:lightblue">28</td><td align="right" style="background:white">35</td><td align="right" style="background:lightblue">42</td><td align="right" style="background:white">49</td><td align="right" style="background:lightblue">56</td><td align="right" style="background:white">63</td><td align="right" style="background:lightblue">70</td></tr><tr><td align="right" style="background:yellow">8</td><td align="right" style="background:lightgreen">16</td><td align="right" style="background:yellow">24</td><td align="right" style="background:lightgreen">32</td><td align="right" style="background:yellow">40</td><td align="right" style="background:lightgreen">48</td><td align="right" style="background:yellow">56</td><td align="right" style="background:lightgreen">64</td><td align="right" style="background:yellow">72</td><td align="right" style="background:lightgreen">80</td></tr><tr><td align="right" style="background:white">9</td><td align="right" style="background:lightblue">18</td><td align="right" style="background:white">27</td><td align="right" style="background:lightblue">36</td><td align="right" style="background:white">45</td><td align="right" style="background:lightblue">54</td><td align="right" style="background:white">63</td><td align="right" style="background:lightblue">72</td><td align="right" style="background:white">81</td><td align="right" style="background:lightblue">90</td></tr><tr><td align="right" style="background:yellow">10</td><td align="right" style="background:lightgreen">20</td><td align="right" style="background:yellow">30</td><td align="right" style="background:lightgreen">40</td><td align="right" style="background:yellow">50</td><td align="right" style="background:lightgreen">60</td><td align="right" style="background:yellow">70</td><td align="right" style="background:lightgreen">80</td><td align="right" style="background:yellow">90</td><td align="right" style="background:lightgreen">100</td></tr></table></td></tr></table></div><div class="meta"><p><a href="sitemap.html">Site map</a></p></div><div class="smallbox"><p><a href="index.html">CDuce: documentation</a>: <a href="tutorial.html">Tutorial</a>: Queries</p><p><a href="tutorial_references.html"><img class="icon" width="16" alt="Previous page:" height="16" src="img/left.gif"/> References</a> <a href="tutorial_higherorder.html"><img class="icon" width="16" alt="Next page:" height="16" src="img/right.gif"/> Higher-order functions</a></p></div></div></td></tr></table></body></html>