<!-- note: need to add all termdefs, otherwise termrefs dont work : but XQ contains dupes of termdefs in intro --><!-- SB 2004-01-28: added entities date.day thru ndash, removed "xpath-backwards-compat", "errors", "XQ" --><spec xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" id="spec-top" w3c-doctype="wd"><header>
<title>XQuery 1.0 and XPath 2.0 Full-Text</title>
<w3c-designation>WD-xquery-full-text-20050915</w3c-designation>
<w3c-doctype>W3C Working Draft</w3c-doctype>
<pubdate>
 <day>15</day>
 <month>September</month>
 <year>2005</year>
</pubdate>

<publoc>
   <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/2005/WD-xquery-full-text-20050915/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/2005/WD-xquery-full-text-20050915/</loc>
</publoc>

<altlocs>
   <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/2005/WD-xquery-full-text-20050915/full-text.xml" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XML</loc>
</altlocs>

<latestloc>
  <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/xquery-full-text/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/xquery-full-text/</loc>
</latestloc>

<prevlocs>
  <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/2005/WD-xquery-full-text-20050404/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/2005/WD-xquery-full-text-20050404/</loc>
  <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/2004/WD-xquery-full-text-20040709/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/2004/WD-xquery-full-text-20040709/</loc>
</prevlocs>

<authlist>
<author>
	<name>Sihem Amer-Yahia</name>
	<affiliation>AT&amp;T Labs - Research</affiliation>
	<email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:sihem@research.att.com" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">sihem@research.att.com</email>
</author>
<author>
	<name>Chavdar Botev</name>
	<affiliation>Invited Expert</affiliation>
	<email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:cbotev@cs.cornell.edu" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">cbotev@cs.cornell.edu</email>
</author>
<author>
	<name>Stephen Buxton</name>
	<affiliation>Oracle Corporation</affiliation>
	<email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:stephen.buxton@oracle.com" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">stephen.buxton@oracle.com</email>
</author>
<author>
	<name>Pat Case</name>
	<affiliation>Library of Congress</affiliation>
	<email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:pcase@crs.loc.gov" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">pcase@crs.loc.gov</email>
</author>
<author>
        <name>Jochen Doerre</name>
        <affiliation>IBM</affiliation>
        <email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:doerre@de.ibm.com" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">doerre@de.ibm.com</email>
</author>
<author>
	<name>Darin McBeath</name>
	<affiliation>Elsevier</affiliation>
	<email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:D.McBeath@elsevier.com" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">D.McBeath@elsevier.com</email>
</author>
<author>
	<name>Michael Rys</name>
	<affiliation>Microsoft</affiliation>
	<email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:mrys@microsoft.com" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">mrys@microsoft.com</email>
</author>
<author>
	<name>Jayavel Shanmugasundaram</name>
	<affiliation>Invited Expert</affiliation>
	<email xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:jai@cs.cornell.edu" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">jai@cs.cornell.edu</email>
</author>
</authlist>

<abstract>
<p>This document defines the syntax and formal semantics of XQuery 1.0 and XPath 2.0 Full-Text
which is a language that extends XQuery 1.0 <bibref ref="xquery"/> and XPath 2.0 <bibref ref="xpath20"/> with full-text search capabilities.</p>
</abstract>


<status>
<p><emph>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 <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">W3C technical reports index</loc> at
http://www.w3.org/TR/.</emph></p>

<p>This document has been produced
following the procedures set out for the W3C Process. This document
was produced through the efforts of <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/XML/Query" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XML Query Working Group </loc> and
the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/Style/XSL/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> XSL Working Group </loc>
(both part of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/XML/Activity.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> XML
Activity </loc>). It is designed to be read in conjunction with the
following documents: W3C XQuery and XPath Full-Text Requirements
<bibref ref="xqueryft-requirements"/> and the W3C XQuery Full-Text Use
Cases <bibref ref="xmlquery-full-text-use-cases"/>.</p>

<p>
This is the third version of this document. Since the last version
technical and editorial changes have been made to all the sections of
the document. Among the most significant changes are the introduction
of a new, richer scoring syntax, new semantics and syntax for FTTimes,
FTIgnore, FTCase, FTDiacritics, and FTWindow. Numerous issues were
closed and four new issues were opened. Appendix <specref ref="id-xqft-static-context-components"/> was added listing 
static context components of the full-text extensions. See the new
Appendix <specref ref="id-xqft-changelog"/> (Change Log) 
for more information on these and other changes. 
</p>

<p>The text of the XQuery functions used to define the semantics have
not been completely syntax checked. </p>

<p>This is a public W3C Working Draft for review by W3C members and
other interested parties. Publication as a Working Draft does not
imply endorsement by the W3C Membership. This is a draft document and
may be updated, replaced or obsoleted by other documents at any
time. It is inappropriate to cite this document as other than work in
progress.</p>

<!-- 20050905 JM: Removed paragraph re: instability/risk per Paul Cotton review -->
<!-- 20050905 JM: Moved paragraph re: functions/syntax check per Paul Cotton review -->
<p>The text of the XQuery functions used to define the semantics have
not been completely syntax checked.</p>

<p>Public comments on this document and its
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ft-issues" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">open issues</loc> are invited.
Comments should be entered into the
last-call issue tracking system for this specification (instructions
can be found at
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/XML/2005/04/qt-bugzilla" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/XML/2005/04/qt-bugzilla</loc>). 
If access to that system is not feasible, you may send your
comments to the W3C mailing list,
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="mailto:public-qt-comments@w3.org" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">public-qt-comments@w3.org</loc>
(<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Public/public-qt-comments/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
http://lists.w3.org/Archives/Public/public-qt-comments/</loc>) with
"[FT]" at the beginning of the subject field of email messages
involving such comments.</p>

<p>The patent policy for this document is specified in the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/Consortium/Patent-Policy-20040205/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">5 February
2004 W3C Patent Policy</loc>. Patent disclosures
relevant to this specification may be found on the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/2002/08/xmlquery-IPR-statements" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XML Query
Working Group's patent disclosure page</loc> and the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/Style/XSL/Disclosures" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XSL Working Group's
patent disclosure page</loc>. An individual who has actual knowledge
of a patent which the individual believes contains Essential Claim(s)
with respect to this specification should disclose the information in
accordance with <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">section
6 of the W3C Patent Policy</loc>.
</p>

</status>

<langusage>
		<language id="EN">English</language>
		<language id="ebnf">EBNF</language>
</langusage>
	
<revisiondesc>

<p>SA January 2004: First version of document before Feb F2F</p>
<p>SA 26 February 2004: Second version of document before Feb F2F
    meetings.</p>

</revisiondesc>
</header>
<body>
<!-- *********************************************************************
      Section 1. Introduction
     ********************************************************************* -->

<div1 id="introduction">
  <head>Introduction</head>

  <p>This document defines the language and the formal semantics of
  XQuery 1.0 and XPath 2.0 Full-Text. This language is designed to meet the requirements
  identified in W3C XQuery and XPath Full-Text Requirements
  <bibref ref="xqueryft-requirements"/> and the W3C XQuery Full-Text Use
  Cases <bibref ref="xmlquery-full-text-use-cases"/>. </p>

  <p>XQuery 1.0 and XPath 2.0 Full-Text extends the syntax and semantics of XQuery 1.0 and
  XPath 2.0. </p>

	<div2 id="tq-ftsearch-xml">
		<head>Full-Text Search and XML</head> 

<p>XML documents may contain highly-structured data (numbers, dates),
unstructured data (untagged free-flowing text), and semi-structured
data (text with embedded tags). Where a document contains unstructured
or semi-structured data, it is important to be able to search that
data using Information Retrieval techniques such as full-text search.
Full-text search is different from substring search in many ways:</p>

<olist>
<item><p>A full-text search searches for phrases (a sequence of words)
rather than substrings. A substring search for news items that contain
the string "lease" will return a news item that contains "Foobar
Corporation releases the 20.9 version ...". A full-text search for the
phrase "lease" will not. </p>
</item>

<item><p>There is an expectation that a full-text search will support
language- and token-based searches which substring search cannot. An
example of a language-based search is "find me all the news items that
contain a word with the same linguistic stem as "mouse" (finds "mouse"
and "mice"). An example of a token-based search is "find me all the
news items that contain the word "XML" within 3 words (tokens) of
"Query".</p>
</item>

<item>
<p>Full-text search is subject to the vageries and nuances of
language. The results it returns are often of varying usefulness. When
you search a web site for all cameras that cost less than $100, this
is an exact search.  There is a set of cameras that match this search,
and a set that do not.  Similarly, when you do a string search across
news items for "mouse", there is only 1 expected result set. When you
do a full-text search for, say, all the news items that contain the
word "mouse", you probably expect to find news items with the word
"mice", and possibly "rodents" (or possibly "computers"!).  But not
all results are equal : some results are more "mousey" than others.
Because full-text search can be inexact, we have the notion of score
or relevance : we generally expect to see the most relevant results at
the top of the results list. Of course, relevance is in the eye of the
beholder.  Note: as XQuery/XPath evolves, it may apply the notion of
score to querying structured search. For example, when making travel
plans or shopping for cameras, it is sometimes more useful to get an
ordered list of near-matches. If XQuery/XPath defines a generalized
inexact match, we assume that XQuery/XPath can utilize the scoring
framework provided by the full-text language.
</p>
</item>
</olist>

<p>The following definitions apply to full-text search:</p>

<olist>
<item>
<p>As XML becomes mainstream, users expect to be able to store and
search all their documents in XML. This requires a standard way to do
full-text search, as well as structured searches, against XML
documents.  A similar requirement for full-text search led ISO to
define the <!-- <loc
href="ftp://sqlstandards.org/SC32/WG4/Progression_Documents/CD/cd-fulltext-2001-05.pdf">SQL/MM-FT
standard</loc>.  --> SQL/MM-FT <bibref ref="sqlmm"/> standard.
SQL/MM-FT <bibref ref="sqlmm"/> defines extensions to SQL to express
full-text queries providing similar functionality as this full-text
language extension to XQuery 1.0/XPath 2.0 does.
</p>
</item>

<item>
<p>Full-text queries are performed on text which has been tokenized,
i.e., broken into a sequence of words, units of punctuation, and
spaces.
</p>
</item>

<item>
<p>A word is defined as any character, n-gram, or sequence of
characters returned by a tokenizer as a basic unit to be queried. Each
instance of a word consists of one or more consecutive characters.
Beyond that, words are implementation defined. Note that consecutive
words need not be separated by either punctuation or space, and words
may overlap. A phrase is a sequence of ordered words which can contain
any number of words.
</p>
</item>

<item>
<p>Tokenization enables functions and operators which work with the
relative positions of words (e.g., proximity operators). It also
uniquely identifies sentences and paragraphs in which words appear.
Tokenization also enables functions and operators which operate on a
part or the root of the word (e.g., wildcards, stemming). Whatever a
tokenizer for a particular language chooses to do, it must preserve
the containment hierarchy: paragraphs contain sentences which contain
words. The tokenizer has to give the same answers for two equal
strings, i.e., it should identify the same tokens. Everything else is
implementation-defined.

Sentences and paragraphs are important concepts in Western languages
(which belong to a rather important market for a great many
implementors of XQuery). So, we choose to keep the full-text
primitives that make use of them.

The specification does not want to impose any requirements on
cross-language tokenizers.
</p>
</item>

<item>
<p>
This specification recognizes that some XML elements represent semantic
markup, e.g., &lt;title&gt;. Others represent formatting markup, e.g.,
&lt;b&gt; to indicate bold.  Semantic markup serves well as token
boundaries, while formatting markup sometimes do not. Implementations
are free to provide ways to differentiate between the markup's effect on
token boundaries during tokenization in an implementation-defined or
implementation-dependent way.
</p>
</item>


<item>
<p>
This specification focuses on functionality that serves all
languages. It also selectively includes functionalities useful within
specific families of languages. For example, searching within
sentences and paragraphs is useful to many western languages and to
some non-western languages, so that functionality is incorporated into
this specification.
</p>
</item>

<!--<item>
<p>We use the namespace "ft" (for full-text) that corresponds to the
URL http://www.w3.org/2004/07/xquery-full-text and defines the namespace of
full-text search. We also use "fts" for definitional purposes in <loc
href="#tq-semantics">semantics Section</loc>.
</p>
</item>
-->

</olist>
</div2>

<div2>
 <head>Organization of this document</head> 

<p>This document is organized as follows. We first present a <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-extensions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">high level syntax</loc> for the XQuery 1.0 and XPath 2.0 Full-Text
language along with some examples. Then, we present the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselectionsftmatchoptions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">syntax and examples</loc> of the
basic primitives in the XQuery 1.0 and XPath 2.0 Full-Text language. This is followed by the
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-semantics" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">semantics</loc> of the XQuery 1.0 and XPath 2.0 Full-Text
language. The appendix contains a section that provides an <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#id-xpath-grammar" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">EBNF for the XPath 2.0 Grammar with Full-Text
extensions</loc>, an <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#id-grammar" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">EBNF for XQuery 1.0
Grammar with Full-Text extensions</loc>, a list of <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ft-issues" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">issues</loc>, <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ft-acknowledgements" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">acknowledgements</loc> and a <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ft-glossary" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">glossary</loc></p>

	</div2>

<div2>
  <head>A word about namespaces</head>

<p>Certain namespace prefixes are predeclared by XQuery 1.0 and, by implication, by this specification,
and bound to fixed namespace URIs. These namespace prefixes are as follows:
</p>

<ulist>

<item>
<p>
<code>xml = http://www.w3.org/XML/1998/namespace</code>
</p>
</item>

<item>
<p>
<code>xs = http://www.w3.org/2001/XMLSchema</code>
</p>
</item>

<item>
<p>
<code>xsi = http://www.w3.org/2001/XMLSchema-instance</code>
</p>
</item>

<item>
<p>
<code>fn = http://www.w3.org/2005/xpath-functions</code>
</p>
</item>

<item>
<p>
<code>xdt = http://www.w3.org/2005/xpath-datatypes</code>
</p>
</item>

<item>
<p>
<code>local = http://www.w3.org/2005/xquery-local-functions</code>
</p>
</item>

</ulist>

<p>
In addition to the prefixes in the above list, this document uses the prefix
<code>err</code> to represent the namespace URI <code>http://www.w3.org/2005/xqt-errors</code>, 
This namespace prefix is not predeclared and its use in this document is not normative. 
Error codes that are not defined in this document are defined in other XQuery 1.0 and XPath 2.0
specifications, particularly <bibref ref="xpath20"/> and <bibref ref="xpath-functions"/>. 
</p>

<p>
Finally, this document uses the prefix <code>fts</code> to represent a namespace
containing a number of functions used in this document to describe the semantics
of various Full-Text operators. Because those functions are not required to be
implemented by Full-Text implementations, there is no URI associated with the prefix. 
</p>

</div2>
  
</div1>



<!--
2. TeXQuery Expressions
2.1.  FTContainsExpr 
2.2.  Scoring
2.3   Extensions to the Static Context

-->
<div1 id="tq-extensions">
   <head>Full-Text Extensions to XQuery and XPath</head>
<p>The languages of XQuery and XPath are extended in three
ways. First, we
introduce a new kind of expression, called FTContainsExpr. Second, 
the syntax of FLWOR expressions in XQuery and of <code>for</code>
expressions in XPath is enhanced with optional score variables which allow to
refer to the score of an evaluation. And third, static context
declarations for full-text match options are added to the query
prolog.</p>
   <div2 id="tq-ext-contains">
      <head>Expression FTContainsExpr</head>
<p>The XQuery and XPath Languages are extended by adding the expression
FTContainsExpr. An FTContainsExpr is in many ways similar to a
comparison expression (see <xspecref spec="XQ" ref="id-general-comparisons"/>).
This is the grammar rule which introduces FTContainsExpr.</p>


   <scrap headstyle="show">
<head/>
<prodrecap ref="ComparisonExpr" id="no-id_ComparisonExpr"/>

</scrap>
<p>An FTContainsExpr can be used anywhere a ComparisonExpr could be
used in the original languages of XQuery and XPath. Moreover, an
FTContainsExpr has 
higher precedence than the comparison operators, meaning that you can
compare the Boolean result of such an expression without the need to
enclose it in parentheses.
</p>

<div3 id="tq-ext-contains-description">
      <head>FTContainsExpr Description</head>


<scrap headstyle="show">
<head/>
<prodrecap ref="FTContainsExpr" id="FTContainsExpr"/>
</scrap><p>An expression of the form FTContainsExpr returns a Boolean
value. It returns true, if there is some node in
RangeExpr that matches FTSelection. For the purpose of determining
a match some parts of the structure dominated by nodes in RangeExpr
may be ignored, as specified in 
FTIgnoreOption. The precise semantics of matching is described in
Section <specref ref="tq-semantics"/>.</p>

<p>Expressions of the form <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> are
composed of the following ingredients:</p>

<olist>
   <item><p>words or combinations of words, that are the search strings to
   be found as matches</p>
   </item>
   <item><p>match options, such as case sensitivity or indication to use
   stop words</p> 
   </item>
   <item><p>Boolean operators, that allow to compose an FTSelection from simpler FTSelections
      </p>
   </item>
   <item><p>constraints on the positions of matches, such as indication of match distance or
   window, or on the cardinality of matches.</p>
   </item>
</olist>

   </div3>
   <div3 id="tq-ext-contains-examples">
   <head>FTContainsExpr Examples</head>

<p>The following example returns the author of each book whose title
contains a word with the same root as <code>dog</code> and the word
<code>cat</code>.

		<eg role="xquery" xml:space="preserve">
for $b in /books/book
where $b/title ftcontains ("dog" with stemming) &amp;&amp; "cat" 
return $b/author</eg>
</p>
		<p>The same example in XPath 2.0:

		<eg role="xpath" xml:space="preserve">

/books/book[title ftcontains ("dog" with stemming) &amp;&amp; "cat"]/author</eg>
</p>
   </div3>

	</div2>

	<div2 id="tq-ext-score">
	<head>Score Variables</head>
	<p>Besides specifying what constitutes a match of a full-text 
        search as a Boolean condition, full-text search applications
        typically also require the ability to associate scores with
        the results. Such scores are meant to express grades of relevance of
        those results to the full-text search conditions. To this end
        we introduce score variables as follows.</p>

        <p>The XQuery language is extended by adding optional
        <code>score</code> variables to the <code>for</code> and
        <code>let</code> clauses of FLWOR expressions. Let us consider
        the enhanced <code>for</code> clause at first.</p>


<scrap headstyle="show">
<head/>
<prodrecap ref="ForClause" id="ForClause"/>
<prodrecap ref="FTScoreVar" id="FTScoreVar"/>
</scrap> 


<p>When a <code>score</code> variable is present in a <code>for</code> 
clause the evaluation of the expression following the <code>in</code>
keyword not only needs to determine the result sequence of the
expression, i.e., the sequence of items which are used to iteratively
bind the <code>for</code> variable to, but also for each such item a relevance
"score" of the evaluation. This value is what the <code>score</code>
variable gets bound to.</p> 

<p>In the following example book elements are determined that satisfy
the condition <code>[content ftcontains "web site" &amp;&amp; "usability" and
.//chapter/title ftcontains "testing"]</code>. The relevance of the
book elements with respect to that query are returned.

		<eg role="xquery" xml:space="preserve">
for $b score $s 
    in /books/book[content ftcontains "web site" &amp;&amp; "usability" 
                   and .//chapter/title ftcontains "testing"]
return $s
</eg>
</p>

<p>Scores are typically used as an ordering criterion, like in the 
following, more complete example.
		<eg role="xquery" xml:space="preserve">
for $b score $s 
    in /books/book[content ftcontains "web site" &amp;&amp; "usability"]
where $s &gt; 0.5
order by $s descending
return &lt;result&gt;  
          &lt;title&gt; {$b//title} &lt;/title&gt; 
          &lt;score&gt; {$s} &lt;/score&gt; 
       &lt;/result&gt;
</eg>
</p>

<p>The <code>score</code> variable always gets bound to a value of type xs:float in the range
[0, 1]. The value reflects the relevance of the match criteria in the
FTSelections to the nodes in the respective RangeExprs. The way
relevance is calculated is left 
implementation-dependent, but score evaluation must follow these
rules:</p>

<olist>
<item><p>Score values are of type xs:float in the range
[0, 1].</p></item> 
<item><p>For score values greater than 0, a higher score must imply a
higher degree of relevance </p></item>
</olist>

<p>Similar to their use in a <code>for</code> clause, score variables
may be specified in a <code>let</code> clause. A score variable in a
<code>let</code> clause again gets bound to the score of the expression
evaluation, but in this case one score needs to be determined for the
complete result. In the case of the <code>let</code> clause the syntax also
allows to drop the <code>let</code> variable, if the
<code>score</code> variable is present, as it is expected to be a
common use case to be interested only in the score and not the value
of an expression.

<scrap headstyle="show">
<head/>
<prodrecap ref="LetClause" id="LetClause"/>
</scrap> 
</p>

<p>While the score option in a <code>for</code> clause conveniently
allows to specify that the filtering expression which drives the
iteration is at the same time the expression that determines the
scores, it is possible to separate the filtering from the scoring
expression using the <code>let</code> clause syntax. The following is
an example of this.
		<eg role="xquery" xml:space="preserve">
for $b in /books/book[.//chapter/title ftcontains "testing"]
let score $s := $b/content ftcontains "web site" &amp;&amp; "usability" 
order by $s descending
return &lt;result score="{$s}"&gt;{$b}&lt;/result&gt;
</eg>
Here an iteration over book elements is defined, such that the chapter
titles of those books satisfy the FTSelection "testing". These books
are scored with respect to another condition, namely that their 
content elements contain "web site" and "usability".</p>

<p>Another aspect of scoring which we want to illuminate with this
example is that it is not a requirement of the score of an
FTContainsExpr to be 0, if the expression evaluates to false.
In the example, note that a
result element is produced even for books that do not satisfy the
expression in the <code>let</code> clause. While for such books the score
is likely to be 0, this need not be the case. An implementation may
want to assign a non-zero score to a book that contained only "web
site", but not "usability", as this may be considered more relevant
than a book that does not contain either of both.
</p>



<p>In XPath 2.0 we extend the <code>for</code> expression in the same
way with optional score variables. The first example above is actually
also a legal example of the XPath 2.0 extension.</p>


<p>The use of <code>score</code> variables introduces a second-order
aspect to the evaluation of expressions which cannot be emulated by
(first-order) XQuery functions. Consider the following replacement of
the clause <code>let score $s := FTContainsExpr</code></p>

		<eg xml:space="preserve">
let $s := score(FTContainsExpr)
</eg>

<p>where a function <code>score</code> is applied to some
FTContainsExpr. Being a first-order function <code>score</code> is 
only applied to the result of the evaluation of its argument, which is
one of the Boolean constants <code>true</code> or <code>false</code>
in our case. Hence, there can be at most two possible values
<code>score</code> will return and no further differentiation is
possible. </p>


   <div3 id="tq-ext-using-weights">
      <head>Using Weights Within a Scored FTContainsExpr</head>

<p>Scoring can be influenced by adding weight declarations to the
individual search terms, like in the following example (detailed
syntax is given in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Section 3.1</loc>).
		<eg role="xquery" xml:space="preserve">
for $b in /books/book
let score $s := $b/content ftcontains ("web site" weight 0.2)
                                  &amp;&amp; ("usability" weight 0.8)
return &lt;result score="{$s}"&gt;{$b}&lt;/result&gt;
</eg>
</p>

<p>The effect of weights on the result score is also
implementation-dependent. However, these two rules must be
followed.</p>
<olist>
<item><p>Only the relative values of the weights in an FTContainsExpr
with respect to each other are significant.</p></item>
<item><p>When no explicit weight is specified, the default weight is 0.5</p></item>
</olist>

<p>
Weight declarations in an FTContainsExpr for which no scores are
evaluated are ignored. 
</p>

   </div3>
	</div2>


   <div2 id="tq-ext-static-context">
      <head>Extensions to the Static Context</head>
<p>
The XQuery Static Context is extended by a component for each of the
match options. Thus, the default of a match option in a query can be
adjusted by providing a setting in the static context using the
following declaration syntax.
<scrap headstyle="show"><head/>
	<prodrecap ref="Prolog" id="Prolog"/>
	<prodrecap ref="FTOptionDecl" id="FTOptionDecl"/>
</scrap>
Match options are used to control the operational semantics of the
actual full-text operations and are described in detail in 
Section <specref ref="ftmatchoptions"/>. When a match
option is specified in a query directly as described below, that
setting overrides the setting of the respective match option in the
static context.
</p>



   </div2>
</div1>


<div1 id="ftselectionsftmatchoptions">
	<head>FTSelection and FTMatchOptions</head>
<div2 id="ftselection">
      <head>FTSelection</head>
<p>This section describes <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc>
that gives the full-text selection expressions used in the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-extensions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTContainsExpr</loc>, and the match options in
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmatchoptions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTMatchOptions</loc> that are used to
adjust the matching semantics of the full-text selection
expressions. </p>

<p>The <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> production
specifies all permitted kinds of full-text search conditions. </p>

<scrap headstyle="show">
<head/>
<prodrecap ref="FTSelection" id="FTSelection"/>
</scrap>

<p>In the following we will define the syntax and semantics of the
individual full-text selection operators and provide some examples
based on an example document presented in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection-example" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Section 3.1.1</loc>.</p>

<div3 id="ftselection-example">
	<head>FTSelection Example</head> <p>We will use the following
XML document as an example throughout this section.</p>

 <eg xml:space="preserve">&lt;book number="1"&gt;
  &lt;title shortTitle="Improving Web Site Usability"&gt;Improving  
      the Usability of a Web Site Through Expert Reviews and
      Usability Testing&lt;/title&gt;
   &lt;author&gt;Millicent Marigold&lt;/author&gt;
   &lt;author&gt;Montana Marigold&lt;/author&gt;
   &lt;editor&gt;Véra Tudor-Medina&lt;/editor&gt;
   &lt;content&gt;
     &lt;p&gt;The usability of a Web site is how well the  
         site supports the users in achieving specified  
         goals. A Web site should facilitate learning,  
         and enable efficient and effective task  
         completion, while propagating few errors.
     &lt;/p&gt;
     &lt;note&gt;This book has been approved by the Web Site  
         Users Association.
     &lt;/note&gt;
   &lt;/content&gt;
 &lt;/book&gt;</eg>

</div3>

<div3 id="ftwords">
	<head>FTWords</head>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwords" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWords</loc> specifies the words and phrases
that are being searched for in the searched text that is provided as
the left-hand side argument of <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-extensions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTContainsExpr</loc>.</p>

<scrap headstyle="show">
<head/>
<prodrecap ref="FTWords" id="FTWords"/>
</scrap>
	

<p>The right hand side Expr of the above production must evaluate to a
sequence of string values or nodes of type "xs:string". The result of
the Expr is then atomized into a sequence of strings which then is
being tokenized into a sequence of phrases (see section 2.x.x for
details). If the atomized sequence is not a subtype of "xs:string*", a
type error [err:XPTY0004] is raised.</p>

<p>If the "any" option is specified, then a match occurs, if and only if at least
one phrase in the sequence has a match in the searched text.</p>

<p>If the "all" option is specified, then a match occurs, if and only if all of the
phrases in the sequence of phrases are matched in the searched
text.</p>

<p>If the "phrase" option is specified, then the sequence of phrases is
used to create a single phrase by concatenating the phrases and
interleaving whitespace. A match occurs, if and only if the resulting phrase is
matched in the searched text.</p>

<p>If the "any word" option is specified, then a match occurs, if and
only if at least one word in the sequence of phrases is matched in the
searched text.</p> 

<p>If the "all word" option is specified, then a
match occurs, if and only if all words in the sequence of phrases are
matched in the searched text.</p>

<p>If no option is specified, then "any" is implied as default.</p>

<p>Note that if Expr results in a single string, the default and
"any", "all" and "phrase" are equivalent.</p>

<p>If Expr results in the empty sequence or the tokenization results
in a zero-length phrase, this is discussed in the issue 
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#zero-length-phrase" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">zero-length-phrase (Cluster G, Issue 47)</loc>.</p>

<p>Note: The results assume a case-insensitive match in the following
expressions.</p>


<eg role="xpath" xml:space="preserve">/book[@number="1" and ./title ftcontains "Expert"]</eg>

<p>returns the <code>book</code> element, because the phrase "Expert"
is contained in the <code>title</code> child.</p>


<eg role="xpath" xml:space="preserve">/book[@number="1" and ./title ftcontains "Expert Reviews"]</eg>

<p>returns the <code>book</code> element, because the phrase "Expert
Reviews" is contained in the <code>title</code> child.</p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and ./title ftcontains {"Expert",
"Reviews"} all]</eg>

<p>also returns the <code>book</code> element, because the two phrases
"Expert" and "Reviews" are both contained in the <code>title</code> child.</p>

 
<eg role="xpath" xml:space="preserve">/book[@number="1"]//p ftcontains "Web Site Usability"</eg> 

<p>returns the empty sequence, because the <code>p</code> element in the
<code>book</code> element doesn't contain the phrase "Web Site
Usability" though it contains all of the words in the phrase.</p>


<eg role="xquery" xml:space="preserve"> for $book in /book[.//author ftcontains "Marigold"] 
let score $score := $book/title ftcontains "Web Site Usability" 
where $score &gt; 0.8 
order by $score descending
return $book/@number</eg> 

<p> returns numbers of the most relevant <code>book</code> elements by
Marigold with a title about "Web Site Usability" sorted by descending score.</p>


</div3>
<div3 id="ftor">
	<head>FTOr</head>

<scrap headstyle="show"><head/>
<prodrecap ref="FTOr" id="FTOr"/>
</scrap>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftor" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTOr</loc> finds matches that satisfy at least
one of the input selection criteria. </p>

<p> Any match should satisfy at least one of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> criteria. </p>

<eg role="xpath" xml:space="preserve"> /book[.//author ftcontains "Millicent" ||
"Voltaire"] </eg>

<p>returns <code>book</code> elements written by "Millicent" or
"Voltaire". The <code>book</code> element of our sample document is
returned, because it it written by "Millicent".</p>
	
</div3>

<div3 id="ftand">
	<head>FTAnd</head>

<scrap headstyle="show"><head/>
<prodrecap ref="FTAnd" id="FTAnd"/>
</scrap>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftand" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTAnd</loc> finds matches that satisfy
simultaneously two selection criteria.  </p>

<p> Any match must satisfy all of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#prod-xquery-FTSelection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> criteria which are specified by
one or more <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#prod-xquery-FTUnaryNot" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTUnaryNot</loc> expressions.</p>

<eg role="xpath" xml:space="preserve">/book[@number="1"]/title ftcontains ("usability"
&amp;&amp; "testing") case insensitive</eg>

<p> returns true for our sample document, because the text of the
title element contains "usability" and "testing", if we
ignore the letter case (see <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftcaseoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTCaseOption</loc> for more details on case
sensitivity).</p>

<eg role="xpath" xml:space="preserve">/book[@number="1"]/author ftcontains "Millicent"
&amp;&amp; "Montana"</eg>

<p> returns false, because "Millicent" and "Montana" are not contained
by the same <code>author</code> element of the <code>book</code>
element.  </p>

</div3>

<div3 id="ftunarynot">
	<head>FTUnaryNot</head>

<scrap headstyle="show"><head/>
<prodrecap ref="FTUnaryNot" id="FTUnaryNot"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftunarynot" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTUnaryNot</loc> finds matches that do not
satisfy words and phrases that are being searched for in the searched
text that is provided as the left-hand side argument of <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-extensions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTContainsExpr</loc>. </p><p> This is unary
negation. Only one operand is required. </p>
	
<eg role="xpath" xml:space="preserve">/book[. ftcontains "information" &amp;&amp;
"retrieval" &amp;&amp; ! "information retrieval"]</eg>

<p>returns <code>book</code> elements containing "information" and
"retrieval" but not "information retrieval".</p>

<eg role="xpath" xml:space="preserve">/book[. ftcontains "web site usability" &amp;&amp; 
!"usability testing"]</eg>

<p>returns <code>book</code> elements about "web site usability" but
not "usability testing".</p>

</div3>
<div3 id="ftmildnegation">
	<head>FTMildNegation</head>

<scrap headstyle="show"><head/>
<prodrecap ref="FTMildnot" id="FTMildnot"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmildnegation" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTMildNegation</loc> is a milder form
of "&amp;&amp; !". 'a mild not b' matches an expression that contains
a on its own, and not just as part of b.  For example, if I want to
find articles that mention Mexico, I might search for ' "Mexico" not
in "New Mexico" '.  '"Mexico" not in "New Mexico"' matches any Expr
that contains Mexico on its own.  An Expr that contains "New Mexico"
is not <quote>excluded</quote> from the result - it may mention
"Mexico" as well.  An Expr that contains "Mexico" only as part of the
phrase "New Mexico" will <quote>not</quote> match ' "Mexico" not in
"New Mexico".  </p>

<p> A match to <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmildnegation" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTMildNegation</loc> must
contain at least one word occurrence that satisfies the first
condition and does not satisfy the second condition. If it contains a
word occurrence that satisfies both the first and the second
condition, the occurrence is not considered as a result.</p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and . ftcontains "usability"
not in "usability testing"]</eg>

<p>returns the <code>book</code> since occurrences of "usability" appear in the
<code>title</code> and the <code>p</code> elements of the
<code>book</code>, even if the occurrence within the phrase "Usability
Testing" in the <code>title</code> element is not considered.</p>

<p>The right-hand side of a <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmildnegation" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTMildNegation</loc>
cannot contain a <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> which evaluates
to a <term>AllMatches</term> that contain a <term>StringExclude</term> as defined in the 
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-semantics" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Formal Semantics</loc> section. Such 
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc>s are <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftunarynot" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
FTUnaryNot</loc> and <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#fttimes" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTTimes</loc> with 
at-most, from-to, and exactly occurrencies range. </p>

</div3>
<div3 id="ftorder">
	<head>FTOrder</head>

<scrap headstyle="show"><head/>
<prodrecap ref="FTOrderedIndicator" id="FTOrderedIndicator"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftorder" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTOrder</loc> enforces that the order of word
occurrences in the match is the same as their order in the query.
</p>

<p> By default, there are no restrictions on the order in which the
query words are matched in the document. </p>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftorder" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTOrder</loc> imposes such an order. A match
must satisfy the nested selection condition and the match must contain
the words in the order specified in the query.</p>

<eg role="xpath" xml:space="preserve">/book[. ftcontains ("web site" &amp;&amp; "usability")
ordered]/title </eg>

<p>returns titles of <code>book</code> elements that contain "web
site" and "usability" in the order in which they appear in the query,
i.e., "web site" must precede "usability".</p>

<eg role="xpath" xml:space="preserve">/book[@number="1"]/title ftcontains ("Montana" &amp;&amp;
"Millicent") ordered </eg>

<p>returns false, because although "Montana" and "Millicent" appear in
the <code>title</code> element, they do not appear in the order
specified in the query. </p>


</div3>
<div3 id="ftscope">
	<head>FTScope</head>

<scrap headstyle="show"><head/>
<prodrecap ref="FTScope" id="FTScope"/>
</scrap>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftscope" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTScope</loc> specifies a condition on the
scope of the occurrences of the matched words. </p>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftscope" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTScope</loc> specifies whether any matched
word in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> should be directly
contained in the same ('same') or different ('different') scope. </p>

<p> Possible scopes are sentence (e.g., delimited by ".", "!", or
"?"), and paragraph (e.g., delimited by blank lines and EOLN/CR
characters). Sentences and paragraphs are defined in the
introduction.</p>

<p> By default, there are no restriction on the scope of the
occurrences, i.e. they may occur in a sentence or a paragraph. <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftscope" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTScope</loc> is used to restrict this scope. </p>

<p> If two words appear in the same sentence and in different
sentences then both 'same sentence' and 'different sentence' return
true. The same thing applies to the 'paragraph' scope.</p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and . ftcontains "usability"
&amp;&amp; "Marigold" same sentence]</eg>

<p> will not return the <code>book</code> element, because the words
"usability" and "Marigold" are not contained within the same
sentence. </p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and . ftcontains "usability"
&amp;&amp; "Marigold" different sentence]</eg>

<p> will return the <code>book</code> element, because the words
"usability" and "Marigold" are contained within different sentences. </p>

<eg role="xpath" xml:space="preserve">/book[. ftcontains "usability" &amp;&amp; "testing"
same paragraph] </eg>

<p> returns <code>book</code> elements mentioning "usability" and "testing" in the same
paragraph.</p>

<eg role="xpath" xml:space="preserve">/book[. ftcontains "site" &amp;&amp; "errors"
same sentence] </eg>

<p> returns the <code>book</code> element, because "site" and "errors"
appear in the same sentence. Note that the book is returned even
though there is another occurrence of "site", namely the one in the
<code>title</code> element, which does not appear in the same sentence
as the occurrence of "errors". </p>

<p>Some subtle relationships between <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftscope" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTScope</loc> and <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftdistance" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTDistance</loc> will be discussed in the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-semantics" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">semantics</loc> section. </p>

</div3>

<div3 id="ftdistance">
	<head>FTDistance</head>

<scrap headstyle="show"><head/>
<prodrecap ref="FTDistance" id="FTDistance"/>
<prodrecap ref="FTRange" id="FTRange"/>
</scrap>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftdistance" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTDistance</loc> limits the distance in
number of words, sentences, or paragraphs between consecutive
occurrences of the words in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc>. These correspond to "word
distance", "sentence distance", and "paragraph distance" forms of <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftdistance" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTDistance</loc>. </p>
 
<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftdistance" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTRange</loc> specifies a range of integer
values, providing a minimum and maximum value that defines the
distance limits.  Each UnionExpr in an FTRange must evaluate (after
atomization) to a singleton sequence with an atomic value of type
"xs:integer". Otherwise, a type error [err:XPTY0004] is raised.  </p>

<p>Let the value of the first (or only) UnionExpr be M.  If "from" is 
specified, let the value of the second UnionExpr be N. </p>

<p>FTDistance may cross element boundaries when computing
distance:</p>
<olist>
<item><p> Zero words means adjacent.</p></item> <item><p> Zero
sentences means the same sentence.</p></item> <item><p> Zero
paragraphs means the same paragraph. </p></item>
</olist>

<p>If "exactly" is specified, then the range is the closed interval [M, 
M].  If "at least" is specified, then the range is the half-closed interval 
[M, unbounded).  If "at most" is specified, then the range is the closed 
interval [0, M].  If "from" is specified, then the range is the closed 
interval [M, N].  For example:</p>

<olist><item><p>'exactly 0' specifies the range [0, 0].</p></item>
    <item><p>'at least 1' specifies the range [1,unbounded].</p></item> 
    <item><p>'at most 1' specifies the range [0, 1]. </p></item>
    <item><p>'from 5 to 10' specifies the range [5, 10].</p></item>
</olist>

<p>The distances computed by FTDistance are not affected by the presence or 
absence of element boundaries in the text over which the distances are 
computed.  Stop words are included in those computations.</p>


<eg role="xpath" xml:space="preserve">/book[. ftcontains ("information" &amp;&amp;
"retrieval") not in ("information" &amp;&amp; "retrieval" 
distance at least 11 words)]
</eg>

<p>returns <code>book</code> elements containing "information" and "retrieval" and discards
those occurrences of the words that are more than 10 words apart. </p>

<eg role="xpath" xml:space="preserve">/book[. ftcontains "web" &amp;&amp; "site" &amp;&amp;
"usability" distance at most 2 words]/title</eg>

<p>returns the titles of <code>book</code> elements mentioning "web", "site", and
"usability" with at most 2 intervening words between consecutive
occurrences of the words.</p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and . ftcontains "web site"
&amp;&amp; "usability" distance at most 1 words]/title </eg>

<p>returns the <code>title</code> element; a similar query for the
<code>p</code> element would return the empty sequence
when stop words are not ignored, because its occurrences of "web site"
and "usability" are only within a word distance of 2. </p>

<!-- JD, 2005-08-17: need to revise the foll. 2 examples;
<eg role="xpath">/book[@number="1" and . ftcontains ("web site"
&amp;&amp; "completion" &amp;&amp; !  "learning") distance
exactly 15 words]/title
</eg>

<p>returns the
<code>title</code> element, because the word "learning" not appears
within 15 words of the words "web site" and "completion".</p>

<eg role="xpath">/book[@number="1" and . ftcontains "web site"
&amp;&amp; "completion" distance exactly 15 words same
paragraph]/title </eg>

<p>returns the <code>title</code>
element if the words "web site" and "completion" appear within 15
words of each other and in the same paragraph.</p>
-->

</div3>

<div3 id="ftwindow">
	<head>FTWindow</head>

<scrap headstyle="show"><head/>
	<prodrecap ref="FTWindow" id="FTWindow"/>
</scrap>


<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwindow" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWindow</loc> allows to impose the
constraint that a match must occur within a window of the document of
a given size.</p>

<p> <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwindow" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWindow</loc> limits the window size in
units of words, sentences, or paragraphs. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwindow" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWindow</loc> may cross element boundaries
when computing window sizes.</p>

<p>UnionExpr must evaluate to an atom of type "xs:integer".</p> 

<p>A match of an FTSelection is considered a match within a window, if
there exists a window of the given number of consecutive units (words,
sentences, or paragraphs) in the document within which the match lies.
</p>

<eg role="xpath" xml:space="preserve">/book[./title ftcontains "web" &amp;&amp; "site"
&amp;&amp; "usability" window 5 words]/@number</eg>

<p>returns the numbers of <code>book</code> elements containing "web",
"site", and "usability" in their title within a window of 5 words.</p>

<eg role="xpath" xml:space="preserve">/book[. ftcontains ("web" &amp;&amp; "site" ordered)
&amp;&amp; ("usability" || "testing") window 10 words] </eg>

<p>returns <code>book</code> elements that contain "web" and "site" in
this order plus either "usability" or "testing" and all the matched
words occur within a window of at most 10 words. </p>

<eg role="xpath" xml:space="preserve">/book//*[. ftcontains "web site" 
&amp;&amp; "usability" window 3 words]</eg>

<p>returns the <code>title</code> element, because it contains "Web
Site Usability"; the <code>p</code> element will not be returned,
because its occurrences of "web site" and "usability" are not within a
window of 3.</p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and . ftcontains "efficient" 
&amp;&amp; ! "and" window 3 words]</eg>

<p>returns the empty sequence, because in the selected
<code>book</code> element there is no occurrence of 
"efficient" in a window of 3 words which would not also contain an
occurrence of "and".</p>

</div3>

<div3 id="fttimes">
	<head>FTTimes</head>

<scrap headstyle="show"><head/>
			<prodrecap ref="FTTimes" id="FTTimes"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#fttimes" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTTimes</loc> controls the number of times a
specified <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> must be
matched. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#fttimes" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTTimes</loc> limits the number of different
occurrences of <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc>, which must
be within the specified range.  </p>

<p>An occurrence of the criterion is a distinct set of word
occurrences that satisfies it.</p>

<olist>

<item>
<p>
The <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> '("very big")' has one
occurrence in the text fragment "very very big": it consists of the
second "very" and "big".
</p>
</item>

<item>
<p>
The <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> '"very" &amp;&amp;
"big"' has two occurrences in the text fragment "very very big": one
consisting of the first "very" and "big", and the other containing the
second "very" and "big".
</p>
</item>

<item>
<p>
The <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> '"very" || "big"' has 3
occurrences in "very very big". 
</p>
</item>

<item>
<p>
The <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> '!"small"' has 1
occurrence in "very very big". 
</p>
</item>

</olist>

<eg role="xpath" xml:space="preserve">/book[. ftcontains "usability" occurs at least 2 times]/@number</eg>

<p>returns the numbers of the <code>book</code> elements that contain
2 or more occurrences of "usability".</p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and title ftcontains "usability" ||
"testing" occurs at most 3 times] </eg>

<p>returns false, because "usability" 3 occurrences and "testing" 1
occurrences; therefore, there are 4 occurrences of "usability" ||
"testing".</p>

<eg role="xpath" xml:space="preserve">/book[@number="1" and . ftcontains "usability" occurs at least 2 times]
</eg>

<p>returns the <code>book</code> element, because its
<code>title</code> element contains 3 occurrences of "usability"
although its <code>p</code> element contains only one occurrence.
</p>


</div3>

<div3 id="ftcontent">
	<head>FTContent</head>

<scrap headstyle="show"><head/>
			<prodrecap ref="FTContent" id="FTContent"/>
</scrap>
 
<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftcontent" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTContent</loc> finds matches when the words
and phrases are the first, last or all of the words and phrases in the
tokenized string value of the element that is being searched.</p>

<p> The "at" "start" option finds matches when the words or phrases
are the first words or phrases in the tokenized string value of the
element that is being searched.</p>

<p> The "at" "end" option finds matches when the words or phrases are
the last words or phrases in the tokenized string value of the element
that is being searched.</p>
 
<p>The "entire" content" option finds matches when the words or
phrases are the entire content of the tokenized string value of the
element that is being searched.</p>
 
<eg role="xpath" xml:space="preserve">/books//title[. ftcontains "improving the usability
of a web site" at start]</eg> 

<p>returns each title element starting with the phrase "improving the
usability of a web site".</p>
 
<eg role="xpath" xml:space="preserve">/books//p[. ftcontains "propagat*" &amp;&amp; "few
errors" distance at most 2 words at end]</eg>

<p>returns each p element ending with the phrase "propagating few
errors".</p>
 
<eg role="xpath" xml:space="preserve">/books//note[. ftcontains "this site has been
approved by the web site users association" entire content]</eg>

<p>returns each note element where "this site has been approved by the
web site users association" is the entire content of the tokenized
string of that element.</p>

</div3>


</div2>


<div2 id="ftmatchoptions">
	<head>FTMatchOptions</head>


<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmatchoptions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTMatchOptions</loc> modify the
operational semantics of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc> they are applied on. </p>

<scrap headstyle="show"><head/>
			<prodrecap ref="FTMatchOption" id="FTMatchOption"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmatchoptions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTMatchOptions</loc> set an
environment for the matching options of <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftselection" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTSelection</loc>. If a match option isn't
specified directly in the query, its value is given by its static
context component. Details about these context components, including
their default values, are given in
Appendix <specref ref="id-xqft-static-context-components"/>.</p>

<p>As a result of these default values of the match options, when no
<code>ft-option</code> declarations are present, the query:</p>

<eg role="xpath" xml:space="preserve">/book/title ftcontains "usability" </eg>

<p>is equivalent to the query </p>

<eg role="xpath" xml:space="preserve">/book/title ftcontains "usability" case insensitive 
    diacritics insensitive 
    without stemming without thesaurus  
    without stop words language "none" without wildcards</eg>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmatchoptions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTMatchOptions</loc> are applied in the
order in which they are given in the query. More information on their
semantics is given in <specref ref="FTMatchOptionsSec"/>.</p>

<p> We illustrate each match option in more detail in the following
sections.</p>



<div3 id="ftcaseoption">
	<head>FTCaseOption</head>

<scrap headstyle="show"><head/>
			<prodrecap ref="FTCaseOption" id="FTCaseOption"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftcaseoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTCaseOption</loc> controls the way
words are matched with regards to the letter case.</p>

<p>The option "lowercase" ("uppercase") specifies that only words in lower-case
(upper-case) letters can be matched exactly. The option "case insensitive"
specifies that matching word occurrences can have both small and
capital letters; their case is ignored. The option "case sensitive" specifies
that the case of the letters in the result must match the case of the
letters in the word from the query. </p>

<p>The default is "case insensitive". </p>

<p>The following table summarizes the interaction between 
the case match option and the use of the default collation.</p>

<p>
 <table border="1">
      <caption>Case Matrix</caption>
      <thead>
       <tr>
        <td rowspan="1" colspan="1">Default collation options/Case options</td>
        <td rowspan="1" colspan="1">UCC (Unicode Codepoint Collation)</td>
        <td rowspan="1" colspan="1">CCS (some generic case-sensitive collation)</td>
        <td rowspan="1" colspan="1">CCI (some generic case-insensitive collation) </td>
       </tr>
      </thead>
      <tbody>
       <tr>
        <td rowspan="1" colspan="1">insensitive</td>
        <td rowspan="1" colspan="1">compare as if both lower</td>
        <td rowspan="1" colspan="1">case-insensitive variant of CCS if it exists, else error</td>
        <td rowspan="1" colspan="1">CCI</td>
       </tr>
       <tr>
        <td rowspan="1" colspan="1">sensitive</td>
        <td rowspan="1" colspan="1">UCC</td>
        <td rowspan="1" colspan="1">CCS</td>
        <td rowspan="1" colspan="1">case-sensitive variant of CCI if it exists, else error</td>
       </tr>
       <tr>
        <td rowspan="1" colspan="1">uppercase</td>
        <td rowspan="1" colspan="1">uppercase(Expr) + UCC</td>
        <td rowspan="1" colspan="1">uppercase(Expr) + CSS</td>
        <td rowspan="1" colspan="1">CCI</td>
       </tr>
       <tr>
        <td rowspan="1" colspan="1">lowercase</td>
        <td rowspan="1" colspan="1">lowercase(Expr) + UCC</td>
        <td rowspan="1" colspan="1">lowercase(Expr) + CSS</td>
        <td rowspan="1" colspan="1">CCI</td>
       </tr>
      </tbody>
     </table>
</p>

<note><p>In this table, "else error" means "Otherwise, an error
[err:FOCH0002] is raised.". The phrase "if it exists" is used, because
the case-sensitive collation CCS does not always have a
case-insensitive variant (and, even if one exists, it may not be
possible to determine it algorithmically), and because the
case-insensitive collation CCI does not always have a case-sensitive
variant (and, even if one exists, it may not be possible to determine
it algorithmically).</p></note>

<eg role="xpath" xml:space="preserve">/book[@number="1"]/title ftcontains "Usability" lowercase </eg>

<p>returns false, because the <code>title</code> element doesn't contain
"usability" (in lower case).  </p>

<eg role="xpath" xml:space="preserve">/book[@number="1"]/title ftcontains "usability" 
case insensitive
</eg>

<p>returns true, because the case of the letters is not
considered. </p>


</div3>

<div3 id="ftdiacriticsoption">
	<head>FTDiacriticsOption</head>

<scrap headstyle="show"><head/>
			<prodrecap ref="FTDiacriticsOption" id="FTDiacriticsOption"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftdiacriticsoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTDiacriticsOption</loc> controls
the way words are matched with regards to the use of diacritic
symbols.</p>


<p>The option "with" ("without") "diacritics" specifies that only words that
contain (do not contain) diacritics can be matched exactly. The option
"diacritics insensitive" specifies that there are no restrictions on
the matching word occurrences with regards to diacritic symbols:
letters containing diacritics can be matched with their non-diacritics
counterparts and vice versa. The option "diacritics sensitive" specifies that the 
diacritic symbols must match the symbols in the word from the query.
</p>

<p>The default is "diacritics insensitive". </p>

<p>The following table summarizes the 
interaction between the diacritics match option and the use of the default 
collation.</p>

<p>
    <table border="1">
      <caption>Diacritics Matrix</caption>
      <thead>
       <tr>
        <td rowspan="1" colspan="1">Default collation options/Diacritics options</td>
        <td rowspan="1" colspan="1">UCC (Unicode Codepoint Collation)</td>
        <td rowspan="1" colspan="1">CDS (some generic diacritics-sensitive collation)</td>
        <td rowspan="1" colspan="1">CDI (some generic diacritics-insensitive collation) </td>
       </tr>
      </thead>
      <tbody>
       <tr>
        <td rowspan="1" colspan="1">insensitive</td>
        <td rowspan="1" colspan="1">compare as if with and without</td>
        <td rowspan="1" colspan="1">diacritics-insensitive variant of CDS
                                  if it exists, else error</td>
        <td rowspan="1" colspan="1">CDI</td>
       </tr>
       <tr>
        <td rowspan="1" colspan="1">sensitive</td>
        <td rowspan="1" colspan="1">UCC</td>
        <td rowspan="1" colspan="1">CDS</td>
        <td rowspan="1" colspan="1">diacritics-insensitive variant of CDI if it exists, else error</td>
       </tr>
       <tr>
        <td rowspan="1" colspan="1">with diacritics</td>
        <td rowspan="1" colspan="1">"resume diacritic
              insensitive" not in
              "resume"</td>
        <td rowspan="1" colspan="1">"resume diacritic insensitive" not in
                                  "resume"</td>
        <td rowspan="1" colspan="1">CDI</td>
       </tr>
       <tr>
        <td rowspan="1" colspan="1">without diacritics</td>
        <td rowspan="1" colspan="1">"resume" not in
              "resume diacritic
              sensitive" </td>
        <td rowspan="1" colspan="1">"resume" not in "resume diacritic
                                  sensitive"</td>
        <td rowspan="1" colspan="1">CDI</td>
       </tr>
      </tbody>
     </table>
</p>

<note><p>In this table, "else error" means "Otherwise, an error
[err:FOCH0002] is raised.". The phrase "if it exists" is used, because
the diacritics-sensitive collation CDS does not always have a
diacritics-insensitive variant (and, even if one exists, it may not be
possible to determine it algorithmically), and because the
diacritics-insensitive collation CDI does not always have a
diacritics-sensitive variant (and, even if one exists, it may not be
possible to determine it algorithmically).</p></note>

<eg role="xpath" xml:space="preserve">/book[@number="1"]//editor ftcontains "Vera" with diacritics </eg>

<p>returns the <code>editor</code> element.</p>

<eg role="xpath" xml:space="preserve">/book[@number="1"]/editors ftcontains "Véra" without diacritics </eg>

<p>returns false.</p>


</div3>
<!--<div3 id="ftspecialcharoption">
	<head>FTSpecialCharOption</head>

<scrap><head></head>
			<prodrecap ref="FTSpecialcharOption"/>
</scrap>

<p><loc href="#ftspecialcharoption">FTSpecialCharOption</loc>
specifies whether special characters such as punctuation should or
should not be ignored. </p>

<p>Influences the way <loc href="#ftwords">FTWords</loc> is
applied. </p>

<p>The option "with special characters" specifies that special
characters such as punctuation must also be matched. The option
"without special characters" specifies that special characters such as
punctuation need not be matched.
</p>

<p>The default is "without special characters". </p>


<eg role="xpath">/book[@number="1"]//editor ftcontains "Tudor Medina" with 
special characters </eg> 

<p>returns true.</p>

<eg role="xpath">/book[@number="1"]/editors ftcontains "Tudor-Medina" without
special characters </eg> 

<p>returns false.</p>


</div3>
-->

<div3 id="ftstemoption">
	<head>FTStemOption</head>

<scrap headstyle="show"><head/>
			<prodrecap ref="FTStemOption" id="FTStemOption"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftstemoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTStemOption</loc> controls the use of
stemming during string matching. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftstemoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTStemOption</loc> influences the way
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwords" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWords</loc> is applied. It produces a disjunction
of the query words by expanding the words into the list of words that
share the same stem. By definition, the query words are included in
that disjunction. </p>

<p>When the "with stemming" option is present, string matches may also
contain words that have the same stem as the query string. It is
implementation-defined what a stem of a word is. </p>

<p>The clause "without stemming" turns off the use of stemming when
words are matched. </p>

<p>It is implementation-defined whether the stemming will based on an
algorithm, dictionary, or mixed approach. </p>

<p>The default is "without stemming". </p>


<eg role="xpath" xml:space="preserve">/book[@number="1"]/title ftcontains "improve" with stemming </eg>

<p>returns true, because it contains "improving" that has the same stem
as "improve".  </p>


</div3>
<div3 id="ftthesaurusoption">
	<head>FTThesaurusOption</head>

<scrap headstyle="show"><head/>
	<prodrecap ref="FTThesaurusOption" id="FTThesaurusOption"/>
	<prodrecap ref="FTThesaurusID" id="FTThesaurusID"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftthesaurusoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTThesaurusOption</loc> controls the
use of thesauri during string matching. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftthesaurusoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTThesaurusOption</loc> influences the way <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwords" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWords</loc> is applied.</p>

<p>The StringLiteral following the keyword <code>at</code> in FTThesaurusID is of the form of a URI Reference.</p>

<p>
The use of thesauri allows for substitutes in FTWords of any search 
token or sequence of such tokens (a phrase) with related tokens or 
phrases. The related tokens or phrases can be obtained using a
thesaurus, taxonomy, soundex, ontology, or topic map. Thus, the user can 
narrow, broaden, or otherwise modify the search using synonyms, 
hypernyms (more generic terms), etc. The search is performed as though 
the user has specified all related search tokens in a disjunction 
(FTOr). </p>

<p>The thesauri used  in an XQuery 1.0 and XPath 2.0 implementation may 
be standards-based or locally-defined.</p>

<note><p>It is implementation-defined how a thesaurus is
represented. This includes files in a predefined format, or modules
using a common interface.</p></note>

<p>Relationships include, but are not limited to, the relationship
terms and their abbreviations presented in <bibref ref="iso-2788"/>
and their equivalents in other languages:</p>
<olist>
<item><p> <emph>equivalence relationships (synoymns):</emph> PREFERRED TERM (USE), 
NONPREFERRED USED FOR TERM (UF);</p></item>
<item><p> <emph>hierarchical relationships:</emph> BROADER TERM (BT), 
NARROWER TERM (NT),  BROADER TERM GENERIC (BTG), NARROWER TERM GENERIC (NTG), 
BROADER TERM PARTITIVE (BTP), NARROWER TERM PARTITIVE (NTP), 
TOP Terms (TT); and</p></item> 
<item><p> <emph>associative relationships:</emph> RELATED TERM (RT).</p></item>
</olist>

<p>FTThesaurusID allows to specify the number of levels to be queried in hierarchical relationships 
by including an FTRange "levels". If no levels are specified, the default 
is to query all levels in hierarchical relationships.</p>

<p>When the "with thesaurus" match option is specified, string matches
also include words that can be found in one of the specified thesauri and
that correspond to the query string. </p>

<p>The statement "without thesaurus" instructs the query engine not to
use thesauri when matching words. </p>

<p>When the option "with default thesaurus" is specified, a
system-defined default thesaurus with a system-defined relationship is
used. The default thesaurus can also be used in combination with other
explicitly specified thesauri.</p>

<p>The default is "without thesaurus". </p>

<eg role="xpath" xml:space="preserve">doc("http://bstore1.example.com/full-text.xml")
/books/book[count(.//introduction ftcontains "quote" with thesaurus
at "http://bstore1.example.com/UsabilityThesaurus.xml" relationship
"synonyms")&gt;0]</eg>

<p>finds all introductions which quote someone.</p>

<eg role="xpath" xml:space="preserve">doc("http://bstore1.example.com/full-text.xml")
/books/book[count(./content ftcontains "web site components" with
thesaurus at "http://bstore1.example.com/UsabilityThesaurus.xml"
relationship "narrower terms" at most 2 levels)&gt;0]</eg>

<p>finds all books with text on improving "web site components". Also
finds books with the words "navigation" and "layout".</p>

<eg role="xpath" xml:space="preserve">doc("http://bstore1.example.com/full-text.xml")
/books/book[count(. ftcontains "Merrygould" with thesaurus at
"http://bstore1.example.com/UsabilitySoundex.xml" relationship
"sounds like")&gt;0]</eg>

<p>finds all books with words which sound like "Merrygould". This
includes answers containing "Merigold".</p>


<!--
<eg role="xpath">/book[@number="1"]//p ftcontains "buttress" with
thesaurus "Synonyms"</eg>

<p>returns the true if "Synonyms" is a thesaurus for synonyms in the
English language.</p>
-->


</div3>
<div3 id="ftstopwordoption">
	<head>FTStopwordOption</head>

<scrap headstyle="show"><head/>
	<prodrecap ref="FTStopwordOption" id="FTStopwordOption"/>
	<prodrecap ref="FTRefOrList" id="FTRefOrList"/>
	<prodrecap ref="FTInclExclStringLiteral" id="FTInclExclStringLiteral"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftstopwordoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTStopWordOption</loc> controls the
use of stop words (frequent functional words such as "a", "an", "the"
that are ignored) during string matching. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftstopwordoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTStopWordOption</loc> influences the way <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwords" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWords</loc> is
applied. </p>

<p>FTRefOrList allows to specify the list of stop words either explicitly as a
comma-separated list of string literals, or by a URI following the
keyword <code>at</code>. If a URI is used, it must point to a sequence of string atoms or nodes of
type "xs:string". In both cases, no tokenization is performed on the
strings: they are used as they occur in the sequence. </p>

<p>When the "with stop words" option is used, if a query word is
within the specified collection of stop words, it should be
ignored. However, when the stop word appears in a query phrase, or other query
operation that is sensitive to the distance of query tokens, the
position of the stop word is not ignored. In such a case, the stop
word will match any word in the document.</p>

<p>When the option "with default stop words" is used, an
implementation-defined collection of stop words 
is used. Stop word lists can be combined using the usual semantics
of "except" and "union".</p>

<p>The option "without stop words" turns off stop word
processing. This is equivalent to specifying an empty list of stop words.</p>

<p>The default is "without stop words". </p>


<eg role="xpath" xml:space="preserve">/book[@number="1"]//p ftcontains "propagation of errors"
with stemming with stop words ("a", "the", "of") </eg>

<p>returns true, because the document contains the matching tokens
"propagating few errors". Note the asymmetry in the stop word
semantics: the property of being a stop word is only relevant to query
terms, not to document terms. Hence, it is irrelevant for the
above-mentioned match whether "few" is a stop word or not, and on the
other hand we do not want the query above to match
"propagation" followed by 2 stop words, or even a sequence of 3 stop
words in the document.
</p>

<eg role="xpath" xml:space="preserve">/book[@number="1"]//p ftcontains "propagation of errors" 
with stemming without stop words</eg> 

<p>returns false. </p>

<eg role="xpath" xml:space="preserve">
doc("http://bstore1.example.com/full-text.xml")
/books/book[count(.//content ftcontains "planning then 
conducting" with stop words at 
"http://bstore1.example.com/StopWordList.xml")&gt;0]
</eg>

<p>uses the stop words list specified at the URL. Assuming that the
specified stop word list contains the word "then", this query is
reduced to a query on the phrase "planning X conducting", allowing any word as a
substitute for X.</p>


<eg role="xpath" xml:space="preserve">
doc("http://bstore1.example.com/full-text.xml")
/books/book[count(.//content ftcontains "planning then conducting"
with stop words at "http://bstore1.example.com/StopWordList.xml"
except ("the then"))&gt;0]
</eg>

<p>will find "planning then conducting" in the sample data, but not
"planning and conducting", because it is exempting "then" from being a
stop word. </p>


</div3>

<div3 id="ftlanguageoption">
	<head>FTLanguageOption</head>

<scrap headstyle="show"><head/>
	<prodrecap ref="FTLanguageOption" id="FTLanguageOption"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftlanguageoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTLanguageOption</loc> allows to
specify the language of query words. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftlanguageoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTLanguageOption</loc> influences the way <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwords" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWords</loc> is applied.  </p>

<p>The StringLiteral following the keyword <code>language</code> can
only designate one language. It must either be castable
to "xs:language", or be the value "none". Otherwise, a type error
[err:XPTY0004] is raised.</p>

<p>Language can have implications in various aspect of string
matching. This includes how the tokenization into words is performed,
how stemming is performed, or which words can considered to be stop
words. In particular, the language option may imply what are the
default thesaurus/stop word sets.</p>

<p>If <code>language "none"</code> is specified, this means
that there is no language selected; otherwise, it should be valid
identifier of a language. The set of valid language identifiers is 
implementation-defined.</p>

<p>By default, there is no language selected. </p>


<eg role="xpath" xml:space="preserve">/book[@number="1"]//editor ftcontains "salon de the"
with default stop words language "fr"</eg> <p>This is an example where
the language option is used to select the appropriate stop word list. </p>


</div3>

<div3 id="ftignoreoption">
        <head>FTIgnoreOption</head>

<scrap headstyle="show"><head/>
                        <prodrecap ref="FTIgnoreOption" id="FTIgnoreOption"/>
                </scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftignoreoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTIgnoreOption</loc> specifies a set of
element nodes whose content should be ignored. The set of nodes is
identified by the XQuery expression Expr that should evaluate to a
sequence of element nodes. This "ignore" is done recursively which
means that ignored elements will also be searched and within those
elements, other elements may be ignored. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftignoreoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTIgnoreOption</loc> chabges the
semantics of phrase matching. It does not have an impact on a single
word search.</p>

<p>If <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftignoreoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTIgnoreOption</loc> is specified,
all the subtree directly contained by the elements is ignored for the
purpose of searching a phrase at a given level. For example, "Web
&lt;b&gt;Site&lt;/b&gt; Usability" is matched by "Web Usability" if
the option is "without content .//b". However, "Web Site" will not be
matched. If the XQuery sub-expression evaluates to an empty sequence
no words from element content are ignored. </p>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftignoreoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTIgnoreOption</loc> is applied
recursively. For example, if the option is "without content .//b",
"Web &lt;b&gt;This is my Web Site&lt;/b&gt; Site Usability" is matched
twice by "Web Site". Ignoring an element does not mean that it will
not be searched, it means that it is ignored when searching its parent
element. This is done recursively.  </p>

<p>More generally, if .//notation is ignored, "Web Usability" will
be found 5 times in the following fragment:</p>

 <eg xml:space="preserve">&lt;book&gt;
   &lt;title&gt;Web Usability and Practice&lt;/title&gt;
   &lt;author&gt;Montana &lt;annotation&gt; this author is 
   an expert in Web Usability&lt;/annotation&gt; 
   Marigold&lt;/author&gt;
   &lt;editor&gt;Véra Tudor-Medina on Web
   &lt;annotation&gt; best editor on Web 
   Usability&lt;/annotation&gt;Usability&lt;/editor&gt;
   &lt;content&gt;
     &lt;p&gt;Web Usability is defined as how well the  
         site supports the users in achieving specified  
         goals.
     &lt;/p&gt;
   &lt;/content&gt;
 &lt;/book&gt;</eg>

<p>By default element content is not ignored. </p>

</div3>


<div3 id="ftwildcardoption">
	<head>FTWildCardOption</head>

<scrap headstyle="show"><head/>
	<prodrecap ref="FTWildCardOption" id="FTWildCardOption"/>
</scrap>

<p><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwildcardoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWildCardOption</loc> controls the
use of wildcards appending or inserting a character or sequence of
characters to a word (or part of a word). It influences the way words
in FTWords are interpreted.</p>
 

<p>In addition to specifying the "with wildcards"' option, indicators
(represented by periods (.)) and qualifiers are appended to or
inserted into words being searched. Zero or more characters replace
each indicator and qualifier.</p>

 
<p>Indicators are mandatory. When the "with wildcards"' option is
present, one or more periods (.) must be appended at the beginning or
end of words or inserted into words. If the period is at the beginning
of a word, the wildcard is a prefix wildcard. If the period is at the
end of a word, it is a suffix wildcard. If the period is inserted into
a word, it is an infix wildcard.</p>
 

<p>When the "with wildcards" option and one or more periods (.)
appended to or inserted into words are present, characters are
appended or inserted at each of the periods. Any characters may be
appended or inserted except newline characters (#xA), return
characters (#xD), and tab characters (#x9). The number of characters
depends on the qualifier.  Qualifiers available are none, question
mark, asterisk, plus sign, and two numbers separated by a comma, both
enclosed by curly braces.</p>
 
 
<p>If a period is present, but no qualifiers, any one character is
appended or inserted. </p>
 
 
<p>If a period is followed by a question mark (.?), zero or one
characters are appended or inserted. </p>
 
 
<p>If a period is followed by an asterisk (.*), zero or more
characters are appended or inserted.</p>

 
<p>If a period is followed by a plus sign (.+), one or more characters
are appended or inserted. </p>
 
 
<p>If a period is followed by two numbers separated by a comma, both
enclosed by curly braces (.{n,m}), a specified range of characters is
appended or inserted. </p>

 
<p>The option "without wildcards" finds words without recognizing
wildcard indicators and qualifiers. Periods, question marks,
asterisks, plus signs, and two numbers separated by a comma, both
enclosed by curly braces recognized as regular characters.</p>
 

<p>The default is "without wildcards".</p>

 
<eg role="xpath" xml:space="preserve">/book[@number="1"]/title ftcontains "improv.*" with
wildcards</eg> <p>returns true, because it contains "improving".</p>

 
<eg role="xpath" xml:space="preserve">/book[@number="1"]/title ftcontains ".?site" with
wildcards</eg> <p>returns true, because it contains "site".</p>

 
<eg role="xpath" xml:space="preserve">/book[@number="1"]/p ftcontains "w.ll" with
wildcards</eg> <p>returns true, because it contains "well".</p>



</div3>

</div2>

</div1>


<div1 id="tq-semantics">
    <head>Semantics</head>
    
    <div2 role="xquery" id="SemanticsIntroSec">
        <head>Introduction</head>
    
        <p>This section describes the formal semantics of XQuery 1.0 and XPath 2.0 Full-Text.
        The figure below shows how XQuery 1.0 and XPath 2.0 Full-Text integrates with XQuery
        and XPath.</p>
    
        <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/Composability.png" alt="Composability diagram" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
    
        <p> The arrow (1) represents the composability of the XQuery
        and XPath expressions. It is described in the XQuery language
        specification. Regular XQuery expressions can be nested inside
        <term>FTSelection</term>s (arrow (2)) by evaluating them to a sequence of
        items and then converting them to a tokenized text; depending
        on the role they are used in a XQuery 1.0 and XPath 2.0 Full-Text expression. The
        process is described in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#NestedXQuerySec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Nested
        XQuery and XPath Expressions</loc>. Similarly to arrow (1),
        there is a full composability of <term>FTSelection</term>s (arrow (3)).
        The composability is achived by evaluating <term>FTSelection</term>s to
        <term>AllMatches</term>. Each <term>FTSelection</term> operates on zero or more
        <term>AllMatches</term> and returns <term>AllMatches</term>. The process is
        described in the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#FTSelectionEvalSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Evaluation 
        of FTSelections</loc> section. Finally,
        the result of the evaluation of XQuery 1.0 and XPath 2.0 Full-Text and scoring
        expressions needs to be integrated in the XPath and XQuery
        model (arrow (4)). The section <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#FullTextExprSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XQuery 1.0 and XPath 2.0 Full-Text and scoring
        expressions</loc> describes how this is achieved.</p>
		
		<p>All functions and schemata defined in this section are
		considered to be within the fts: namespace. These functions and schemata
		are used only for the purpose of describing the semantics. They need
		not be available directly to users, and there is no requirement
		that implementations should actually provide these functions
		and schemata. For this reason, no URI is associated with the 
		fts: prefix. </p>
    
    </div2>

    <div2 role="xquery" id="NestedXQuerySec">
        <head>Nested XQuery and XPath Expressions</head>
    
        <p>The following section discusses the nesting of XQuery and XPath
    expressions inside <term>FTContainsExpr</term>. </p>
    
        <p>The general rule is that the nested XQuery and XPath
        expressions are evaluated to a sequence of items before the
        evaluation of <term>FTContainsExpr</term>. The sequence of items must
        satisfy certain constraints depending on the context in which
        it is used. These constraints are described below. </p>
        
        <div3 role="xquery">
            <head>Left-hand Side of a FTContainsExpr</head>
            
            <p>Full-text queries are performed on text which has been tokenized,
            i.e., broken into a sequence of words, units of punctuation, and
            spaces. The <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#TokenizationSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">tokenization</loc> is applied on
            the string value of the evaluation of the left-hand side of the <term>FTContainsExpr</term> 
            expression.
            </p>
            
        </div3>
        
        <div3 role="xquery">
            <head>FTWords</head>
            
            <p>The XQuery expression nested inside an <term>FTWords</term> must
            evaluate to a sequence of string values after applying
            atomization (otherwise the entire <term>FTSelection</term> causes a
            type error [err:XPTY0004] to be raised). Then, <term>FTWords</term>
            performs an <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#TokenizationSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">tokenization</loc> on the string
            values from the sequence.
            </p>
            
        </div3>
        
        <div3 role="xquery">
            <head>FTRangeSpec</head>
            
            <p>The XQuery expression (or expressions, in the case of a
            "from-to" range) must evaluate to a singleton sequence of
            integers after applying atomization (otherwise the entire
            <term>FTSelection</term> causes a type error [err:XPTY0004] to be
            raised). The resulting integer values are treated as
            boundaries for the corresponding range.</p>
            
        </div3>
        
        <div3 role="xquery" id="semantics-ftstopwordoption">
            <head>FTStopWordOption</head>
            
            <p>The XQuery expression must evaluate to a sequence of
            string values after applying atomization (otherwise the
            entire <term>FTSelection</term> causes a type error [err:XPTY0004] to
            be raised). The resulting string values are treated as
            stop words that must be ignored during string
            matching.</p>
            
        </div3>
        
        <div3 role="xquery">
            <head>FTThesaurusOption</head>
            
            <p>The XQuery sub-expression must evaluate to a sequence
            of string values after applying atomization (otherwise, the
            entire <term>FTSelection</term> causes a type error [err:XPTY0004] to
            be raised). The resulting string values are treated as
            names of thesauri to use during string matching.</p>
            
        </div3>
        
        <div3 role="xquery">
            <head>FTLanguageOption</head>
            
            <p>The XQuery sub-expression must evaluate to either an
            empty sequence or a singleton sequence of a string value
            or an empty sequence after applying atomization (otherwise
            the entire <term>FTSelection</term> causes a type error
            [err:XPTY0004] to be raised). The resulting string value
            is treated as a language identifier specifying the
            language of the matched document/documents. </p>
            
        </div3>
        
<!--         <div3 role="xquery">
            <head>FTIgnoreOption</head>
            
            <p>The XQuery sub-expression must evaluate to a sequence of element
            nodes (otherwise the entire &FTSelection; returns an error). The
            resulting element nodes define the nodes whose element tags/content
            must be ignored.</p>
 -->
<!-- Clarification proposals are being added as indicated in
http://lists.w3.org/Archives/Member/member-query-fttf/2004Dec/0072.html-->
<!--
        </div3>
-->
 
        
    <!-- **************************************************************
         *                            Tokenization                       *
         ************************************************************** -->
    <div3 role="xquery" id="TokenizationSec">
        <head>Tokenization</head>
        
        <p><termdef id="TokenizationDef" term="Tokenization">Tokenization</termdef> is the process of converting
        a string to a sequence of <term>TokenInfo</term>s.</p>
        
        <p>A <termdef id="TokenInfoDef" term="TokenInfo">TokenInfo</termdef> is
        the identity of a word occurrence inside an XML document. Each <term>TokenInfo</term> is
        associated with:</p>
        
        <ulist>
            <item>
                <p>the word it identifies: <code>word</code>
                </p>
            </item>
            <item>
                <p>a unique identifier that captures the relative position of 
                the word in the document order: <code>pos</code></p>
            </item>
            <item>
                <p>the relative position of the sentence containing the word: 
                <code>sentence</code></p>
            </item>
            <item>
                <p>the relative position of the paragraph containing the word: 
                <code>para</code></p>
            </item>
        </ulist>
        
        <p>The tokenization is performed by the formal semantics functions:</p>
        
        <eg role="parse-text" xml:space="preserve">
function fts:getTokenInfo(
             $searchContext as node(),   
             $matchOptions as fts:FTMatchOptions, 
             $searchToken as fts:TokenInfo) 
             as fts:Tokeninfo*
            </eg>
            
        <p>The above function returns all the <term>TokenInfo</term>s in nodes in
        <code>$searchContext</code> that match the search string in <code>
        $searchToken</code> when using the match options in <code>$matchOptions
        </code>. The match options that occur at the beginning of the list
        should be applied before match options that occur later in the list.</p>
            
        
        <eg role="parse-text" xml:space="preserve">
function fts:getSearchTokenInfo(
             $searchString as xs:string,
             $matchOptions as fts:FTMatchOptions) 
             as fts:Tokeninfo*
            </eg>
            
        <p>The above function tokenizes the search string <code>$searchString
        </code> and returns a sequence of <term>TokenInfo</term> that describe the sequence 
        of tokens in the search string. </p>

        <p>A compliant implementation should provide implementations of the above
        functions.</p>

        <p>As an illustration, consider the following XML fragment:</p>
        
        <eg role="parse-text" xml:space="preserve">
&lt;offers&gt;
    &lt;offer id="1000" price="10000"&gt;
        Ford Mustang 2000, 65K, excellent condition, runs 
        great, AC, CC, power all
    &lt;/offer&gt;
    &lt;offer id="1001" price="8000"&gt;
        Honda Accord 1999, 78K, A/C, cruise control, runs 
        and looks great, excellent condition
    &lt;/offer&gt;
    &lt;offer id="1005" price="5500"&gt;
        Ford Mustang, 1995, 150K highway mileage, no rust, 
        excellent condition
    &lt;/offer&gt;
&lt;/offers&gt;
        </eg>
        
        <p>If we assume that words are delimited by punctuation and whitespace 
        symbols (as in English), the first word "Ford" from the first element 
        content will 
        be assigned a <term>TokenInfo</term> with relative position of 1, the word 
        "Mustang" will be assigned a <term>TokenInfo</term> with 
        relative position of 2, the word "2000" will be 
        assigned a <term>TokenInfo</term> with a relative position of 3, and so on. 
        The relative positions of the <term>TokenInfo</term>s are shown below in 
        parenthesis.</p>
        
        <eg role="parse-text" id="SampleTokenizedDoc" xml:space="preserve">
&lt;offers&gt;
    &lt;offer id="1000" price="10000"&gt;
        Ford(1) Mustang(2) 2000(3), 65K(4), excellent(5)
        condition(6), runs(7) great(8), AC(9), CC(10), 
        power(11) all(12)
    &lt;/offer&gt;
    &lt;offer id="1001" price="8000"&gt;
        Honda(13) Accord(14) 1999(15), 78K(16), A(17)/C(18),
        cruise(19) control(20), runs(21) and(22) looks(23)
        great(24), excellent(25) condition(26)
    &lt;/offer&gt;
    &lt;offer id="1005" price="5500"&gt;
        Ford(27) Mustang(28), 1995(29), 150K(30) highway(31)
        mileage(32), little(33)  rust(34), excellent(35) 
        condition(36)
    &lt;/offer&gt;
&lt;/offers&gt;
        </eg>
        
        <p>The relative positions of paragraphs are determined similarly. Assuming 
        that the paragraph delimiters are start tag, end tag, and end of line characters, the words in the 
        first element's content will be 
        assigned a paragraph relative number 1, the words from the following 
        element content will 
        be assigned a relative number 2, and so on.</p>
        
        <p>The relative positions of sentences are also determined similarly using 
        sentence delimiters such as ".", "!", and "?".</p>
        
    </div3>
    </div2>

    
    <!-- ***********************************************
         ***               AllMatches                ***
         *********************************************** -->
    <div2 role="xquery" id="FTSelectionEvalSec">
        <head>Evaluation of FTSelections</head>
        
        <p>The XQuery/XPath data model of a "sequence of nodes" is
        inadequate for fully composable <term>FTSelection</term>s. The main reason is that
        full-text operations (such as <term>FTSelection</term>s) operate on linguistic
        units, such as positions of words, and such information is not captured
        in the XQuery/XPath data model. We thus define <term>AllMatches</term> that allows
        for fully compositional <term>FTSelection</term>s. </p>
        
        <!-- **********************************************************************
         *                            AllMatches                              *
         ********************************************************************** -->
        <div3 role="xquery" id="AllMatchesSec">
            <head>AllMatches</head>

            <div4 role="xquery">
                <head>Formal Model</head>
                
                <p>An <termdef id="AllMatchesDef" term="AllMatches">AllMatches</termdef> object
                describes all the posible results an <term>FTSelection</term>.
                The UML Static Class diagram of <term>AllMatches</term> is shown
                on the diagram.</p>
            
                <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/AllMatchesClassDiagram.png" alt="AllMatches class diagram" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                
                <p>The <term>AllMatches</term> object contains zero or more <term>Match</term>es. Each
                <term>Match</term> describes one result to the <term>FTSelection</term>.
                The result
                is described in terms of zero or more <term>StringInclude</term>s and zero
                or more <term>StringExclude</term>s, which describe the <term>TokenInfo</term>s that
                must be contained and respectively, those that must not be
                contained. Both <term>StringInclude</term> and <term>StringExclude</term> are of type
                <term>StringMatch</term>, which describes a possible match of a query
                search token with a document word. The <term>queryString</term>
                attribute of <term>StringMatch</term> contains the query search token that
                has been matched. The <term>queryPos</term> attribute specifies
                the position of this search token in the query (this attribute
                is needed for <term>FTOrder</term>s). The <term>TokenInfo</term> associated
                with the <term>StringMatch</term> describes the word in the document that
                matches the query search token.</p> 
                
                <p>Intuitively, <term>AllMatches</term> specifies the <term>TokenInfo</term>s that a
                node should contain, and the <term>TokenInfo</term>s that a node should not
                contain, in order to satisfy an <term>FTSelection</term></p>
                
                <p>The <term>AllMatches</term> structure resembles the Disjunctive Normal
                Form (DNF) in propositional and first-order logic. The
                <term>AllMatches</term> is a disjunction of <term>Match</term>es. Each <term>Match</term> is a
                conjunction of positive "atoms", the <term>StringInclude</term>s, and
                negative "atoms", the <term>StringExclude</term>s. </p>
                
            </div4>

            <div4 role="xquery">
                <head>Examples</head>
                
                <p>Consider the <term>FTWords</term> <code>"Mustang"</code> evaluated over
                the sample document fragment in the previous section. The
                <term>AllMatches</term> corresponding to this <term>FTWords</term> is shown in figure
                below. </p>
                
                <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/SampleAllMatches1.jpg" alt="Sample AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                
                <p>As shown, the <term>AllMatches</term> consists of two <term>Match</term>es. Each
                <term>Match</term> represents one possible result of the <term>FTWords</term>
                <code>"Mustang"</code>. The result represented by the first
                <term>Match</term> contains (represented as <term>StringInclude</term>) the word
                "Mustang" at position 2. The result described by the second <term>Match</term>
                contains the word "Mustang" at position 28. </p>
                
                <p>Let us now consider a more complex example. Consider the
                <term>FTWords</term> <code>"Ford Mustang"</code> evaluated over the XML
                fragment used above. The <term>AllMatches</term> for this <term>FTWords</term> is shown
                on the figure below.</p>
                
                <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/SampleAllMatches2.jpg" alt="Sample AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                
                <p>There are two possible results of this <term>FTWords</term>, and
                these are represented by the two <term>Match</term>es. Each of the
                <term>Match</term>es requires two words to be matched. The result
                corresponding to the first <term>Match</term> is obtained by matching
                "Ford" at position 1 and matching "Mustang" at position 2.
                Similarly, the result described by the second <term>Match</term> is obtained by
                matching "Ford" at position 27 and "Mustang" at position 28.</p>
                
                <p>Let us now consider a more sophisticated example of a
                <term>AllMatches</term>. Consider the <term>FTSelection</term> <code>"Mustang"
                &amp;&amp; ! "rust"</code> that searches for nodes that contain
                "Mustang" but not "rust". The <term>AllMatches</term> for this
                <term>FTSelection</term> is shown in the figure below.</p>
                
                <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/SampleAllMatches3.jpg" alt="Sample AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>

                <p>Observe the use of <term>StringExclude</term>. This is 
                the component that corresponds to negation. It specifies that the 
                result desribed by the corresponding <term>Match</term> should not match the word at 
                the specified position. For instance, the first <term>Match</term> specifies 
                the solution that "Mustang" should be matched at position 2, and "rust" 
                should not be matched at position 34.</p>
                
            </div4>
            
        
        <!-- **********************************************************************
             *                            XML Representation                      *
             ********************************************************************** -->
             <div4>
                <head>XML representation</head>
            
                <p> <term>AllMatches</term> has a well-defined hierarchical
                structure. Therefore, the <term>AllMatches</term> can be easily
                modeled in XML. In subsequent sections, we will use
                this XML representation to formally describe the
                semantics of <term>FTSelection</term>s. In particular, we will
                use the XML representation of <term>AllMatches</term> to formally
                specify how an <term>FTSelection</term> operates on zero or more
                <term>AllMatches</term> to produce a resulting <term>AllMatches</term>. We
                will also use the XML representation to specify the
                formal semantics of the <term>FTContainsExpr</term>.</p>
                
                <p>The XML schema for representing <term>AllMatches</term> is
                given below:</p>
            
                <eg role="parse-text" xml:space="preserve">
&lt;xs:schema 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     elementFormDefault="qualified" 
     attributeFormDefault="unqualified"&gt;
  &lt;xs:complexType name="AllMatches"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="match" 
                  type="fts:Match" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="stokenNum" type="xs:string" use="required" /&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="Match"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="stringInclude" 
                  type="fts:StringMatch" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/&gt;
      &lt;xs:element name="stringExclude" 
                  type="fts:StringMatch" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/&gt;
   &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="StringMatch"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="tokenInfo" type="fts:TokenInfo"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="queryString" 
                  type="xs:string" 
                  use="required"/&gt;
    &lt;xs:attribute name="queryPos" 
                  type="xs:integer" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="TokenInfo"&gt;
    &lt;xs:attribute name="word" 
                  type="xs:string" 
                  use="required"/&gt;
    &lt;xs:attribute name="pos" 
                  type="xs:integer" 
                  use="required"/&gt;
    &lt;xs:attribute name="para" 
                  type="xs:integer" 
                  use="required"/&gt;
    &lt;xs:attribute name="sentence" 
                  type="xs:integer" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
&lt;/xs:schema&gt;
                </eg>
		
	<p>Notice the use of the <code>stokenNum</code> attribute in 
	<term>AllMatches</term>. This attribute was not previously discussed because it
	is related to the representation of the semantics as XQuery functions. 
	Therefore, it is not considered part of the <term>AllMatches</term> model.
	Intuitively, the <code>stokenNum</code> attribute is used for keeping
	the number of search tokens used when evaluating the <term>AllMatches</term>. This 
	value is used to compute the correct value for the <code>queryPos</code>
	attribute in new <term>StringMatch</term>es. </p> 
		
            </div4>
        
        </div3>

        
        
    <!-- *************************************************************
         ***                       FTSelections                    ***
         ************************************************************* -->
    <div3 role="xquery" id="FTSelectionsSec">
        <head>FTSelections</head>
        
        <p>In this section, we define the semantics of <term>FTSelection</term>s.
        <term>FTSelection</term>s are fully composable, and can be arbitrarily nested under
        other <term>FTSelection</term>s. Also, each <term>FTSelection</term> can be associated with
        match options (such as stemming, stop words, etc.) and score weights.
        Since score weights are solely interpreted by the formal semantics
        scoring function, score weights do not influence the semantics of
        <term>FTSelection</term>s in any way. We will thus not consider score weights when
        defining the formal semantics.</p>

        <div4 role="xquery" id="FTSelectionsXMLSec">
            <head>XML Representation</head>
            
            <p>Here, we define the XML representation of the
            <term>FTSelection</term>s as used in the 
            <function>fts:evaluate</function> function. The XML representation
	    closely follows the grammar of the language. It can be viewed as
	    an XML representation of an abstract syntax tree (AST) of a
	    parsed full-text search query. In general, every <term>FTSelection</term>
	    is represented as an XML element. Every nested <term>FTSelection</term> is
	    represented as a nested sub-element in the above XML element. 
	    For binary <term>FTSelection</term>s (e.g. <term>FTAnd</term>) the nested <term>FTSelection</term>s
	    are represented in <code>&lt;left&gt;</code> and <code>&lt;left&gt;
	    </code> sub-elements. For unary <term>FTSelection</term>s, a 
	    <code>&lt;selection&gt;</code> sub-element is used. Additional,
	    characteristics of <term>FTSelection</term>s (e.g. the distance unit for
	    <term>FTDistance</term>) are stored in attributes. </p>
            
            <eg role="parse-text" xml:space="preserve">
&lt;xs:schema
     elementFormDefault="qualified" 
     attributeFormDefault="unqualified"&gt;
           
  &lt;xs:include schemaLocation="AllMatches.xsd" /&gt;
  &lt;xs:include schemaLocation="MatchOptions.xsd" /&gt;
           
  &lt;xs:complexType name="FTSelection"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:choice&gt;
        &lt;xs:element name="FTWords" type="fts:FTWords"/&gt;
        &lt;xs:element name="FTAnd" type="fts:FTAnd"/&gt;
        &lt;xs:element name="FTOr" type="fts:FTOr"/&gt;
        &lt;xs:element name="FTUnaryNot" type="fts:FTUnaryNot"/&gt;
        &lt;xs:element name="FTMildNot" type="fts:FTMildNot"/&gt;
        &lt;xs:element name="FTOrder" type="fts:FTOrder"/&gt;
        &lt;xs:element name="FTScope" type="fts:FTScope"/&gt;
        &lt;xs:element name="FTContent" type="fts:FTContent"/&gt;
        &lt;xs:element name="FTDistance" type="fts:FTDistance"/&gt;
        &lt;xs:element name="FTWindow" type="fts:FTWindow"/&gt;
        &lt;xs:element name="FTTimes" type="fts:FTTimes"/&gt;
      &lt;/xs:choice&gt;
      &lt;xs:element name="matchOption" 
                  type="fts:FTMatchOption" 
                  minOccurs="0"/&gt;
      &lt;xs:element name="weight" 
                  type="xs:float" 
                  minOccurs="0"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTWords"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="searchToken" 
                  type="fts:TokenInfo" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="type" 
                  type="fts:FTWordsType" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTAnd"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="left" type="fts:FTSelection"/&gt;
      &lt;xs:element name="right" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTOr"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="left" type="fts:FTSelection"/&gt;
      &lt;xs:element name="right" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTUnaryNot"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="selection" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTMildNot"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="selection" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTOrder"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="selection" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTScope"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="selection" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="type" 
                  type="fts:ScopeType" 
                  use="required"/&gt;
    &lt;xs:attribute name="scope" 
                  type="fts:ScopeSelector" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTContent"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="selection" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="type" 
                  type="fts:ContentMatchType" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTDistance"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="range" type="fts:FTRangeSpec"/&gt;
      &lt;xs:element name="selection" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="type" 
                  type="fts:DistanceType" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTWindow"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="selection" type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="size" 
                  type="xs:integer" 
                  use="required"/&gt;
    &lt;xs:attribute name="type" 
                  type="fts:DistanceType" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTTimes"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="range" type="fts:FTRangeSpec"/&gt;
            &lt;xs:element name="selection" 
                        type="fts:FTSelection"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
    
  &lt;xs:complexType name="FTCaseOption"&gt;
    &lt;xs:attribute name="value" use="required"&gt;
      &lt;xs:simpleType&gt;
        &lt;xs:restriction base="xs:string"&gt;
          &lt;xs:enumeration value="lowercase"/&gt;
          &lt;xs:enumeration value="uppercase"/&gt;
          &lt;xs:enumeration value="case insensitive"/&gt;
          &lt;xs:enumeration value="case sensitive"/&gt;
        &lt;/xs:restriction&gt;
      &lt;/xs:simpleType&gt;
    &lt;/xs:attribute&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTRangeSpec"&gt;
    &lt;xs:attribute name="type" 
                  type="fts:RangeSpecType" 
                  use="required"/&gt;
    &lt;xs:attribute name="m" 
                  type="xs:integer"/&gt;
    &lt;xs:attribute name="n" 
                  type="xs:integer" 
                  use="required"/&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:simpleType name="FTWordsType"&gt;
    &lt;xs:restriction base="xs:string"&gt;
      &lt;xs:enumeration value="any"/&gt;
      &lt;xs:enumeration value="all"/&gt;
      &lt;xs:enumeration value="phrase"/&gt;
      &lt;xs:enumeration value="any word"/&gt;
      &lt;xs:enumeration value="all word"/&gt;
    &lt;/xs:restriction&gt;
  &lt;/xs:simpleType&gt;
  
  &lt;xs:simpleType name="ScopeType"&gt;
    &lt;xs:restriction base="xs:string"&gt;
      &lt;xs:enumeration value="same"/&gt;
      &lt;xs:enumeration value="different"/&gt;
    &lt;/xs:restriction&gt;
  &lt;/xs:simpleType&gt;
  
  &lt;xs:simpleType name="ScopeSelector"&gt;
    &lt;xs:restriction base="xs:string"&gt;
      &lt;xs:enumeration value="paragraph"/&gt;
      &lt;xs:enumeration value="sentence"/&gt;
    &lt;/xs:restriction&gt;
  &lt;/xs:simpleType&gt;
  
  &lt;xs:simpleType name="RangeSpecType"&gt;
    &lt;xs:restriction base="xs:string"&gt;
      &lt;xs:enumeration value="exactly"/&gt;
      &lt;xs:enumeration value="at least"/&gt;
      &lt;xs:enumeration value="at most"/&gt;
      &lt;xs:enumeration value="from to"/&gt;
    &lt;/xs:restriction&gt;
  &lt;/xs:simpleType&gt;
  
  &lt;xs:simpleType name="DistanceType"&gt;
    &lt;xs:restriction base="xs:string"&gt;
      &lt;xs:enumeration value="paragraph"/&gt;
      &lt;xs:enumeration value="sentence"/&gt;
      &lt;xs:enumeration value="word"/&gt;
    &lt;/xs:restriction&gt;
  &lt;/xs:simpleType&gt;
  
  &lt;xs:simpleType name="ContentMatchType"&gt;
    &lt;xs:restriction base="xs:string"&gt;
      &lt;xs:enumeration value="at start"/&gt;
      &lt;xs:enumeration value="at end"/&gt;
      &lt;xs:enumeration value="entire content"/&gt;
    &lt;/xs:restriction&gt;
  &lt;/xs:simpleType&gt;
&lt;/xs:schema&gt;
            </eg>

            <p>The XML representation of the match options is discussed in the
            <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#FTMatchOptionsSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> match options section</loc> </p>
        
        </div4>


        
        <!-- **********************************************************************
             *                       The evaluate function                        *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>The <function>evaluate</function> function</head>
            
            <p>We present denotational semantics for the evaluation of
            <term>FTSelection</term>s. Specifically, we define a function
            <function>fts:evaluate</function> that takes in three
            parameters: (1) an <term>FTSelection</term>, (2) a search
            context node, and (3) the default set of match options
            that apply to the evaluation of the <term>FTSelection</term>. The
            <function>fts:evaluate</function> function returns the
            <term>AllMatches</term> that is the result of evaluating the
            <term>FTSelection</term>. When <function>fts:evaluate</function> is applied to some
            <term>FTSelection</term> X, it calls the function
            <function>fts:applyX</function> to build the resulting <term>AllMatches</term>.
            If X is applied on nested <term>FTSelection</term>s, the 
            <function>fts:evaluate</function> function is recursively called on these nested
            <term>FTSelection</term>s and the returned <term>AllMatches</term> are used in the evaluation of
            <function>fts:applyX</function>.
            </p>
            
            <p>See the section <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#FTMatchOptionsSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Match Options 
            Semantics</loc> for the semantics of 
            the full-text match options.</p>
        
            <p>We first present a high-level description of the
            <function>fts:evaluate</function> function, and then describe the
            details.</p>
            
            <p>The <function>fts:evaluate</function> function is given below.</p>
            
            <eg role="parse-text" xml:space="preserve">
function evaluate($ftSelect as element(*, fts:FTSelection), 
                  $searchContext as node(),
                  $matchOptions as FTMatchOptions,
                  $searchTokenNum as xs:integer)
                  as AllMatches
{
 if (fn:count($ftSelect/FTMatchOption) &gt; 0) then 
   (: First we deal with all match options that the    :)
   (: FTSelection might bear: we add the match options :)
   (: in front of the current match options sequence   :)
   (: and pass the new sequence to the recursive call  :)
   let $newFTSelection := 
       $ftSelect/*[!(. instance of element(FTMatchOption))]
   return fts:evaluate($newFTSelection, 
                       $searchContext, 
                       ($ftSelect/matchOption, 
                        $matchOptions),
                       $searchTokenNum)
 else if (fn:count($ftSelect/weight) &gt; 0) then
   (: Weight has no bearing on semantics – just :)
   (: call "evaluate" on nested FTSelection     :)
   let $newFTSelection := $ftSelect/*[! (. instance of 
                                         element(weight)]
   return fts:evaluate($newFTSelection, 
                       $searchContext, 
                       $matchOptions,
                       $searchTokenNum)
 else
   typeswitch ($ftSelect) 
        case ($nftSelection as element(FTWords)) 
             (: Apply the FTWords in the search context :)
             return applyFTWords($searchContext,
                                $matchOptions,
                                $nftSelection/searchToken,
                                $searchTokenNum + 1);
        case ($nftSelection as element(FTAnd))
             return let $left = 
                        fts:evaluate($nftSelection/left,
                                     $searchContext,
                                     $matchOptions,
                                     $searchTokenNum)
                    let $newSearchTokenNum = 
                        $left/@stokenNum
                    let $right = 
                        fts:evaluate($nftSelection/right,
                                     $searchContext,
                                     $matchOptions,
                                     $newSearchTokenNum)
                    return applyFTAnd($left, $right)
        case ($nftSelection as element(FTOr))
             return let $left = 
                        fts:evaluate($nftSelection/left,
                                     $searchContext,
                                     $matchOptions,
                                     $searchTokenNum)
                    let $newSearchTokenNum = 
                        $left/@stokenNum
                    let $right = 
                        fts:evaluate($nftSelection/right,
                                     $searchContext,
                                     $matchOptions,
                                     $newSarchTokenNum)
                    return applyFTOr($left, $right)
        case ($nftSelection as element(FTUnaryNot))
             return applyFTUnaryNot($nftSelection/selection)
        case ($ftSelection as element(FTMildNot))
             return let $left = 
                        fts:evaluate($nftSelection/left,
                                     $searchContext,
                                     $matchOptions,
                                     $searchTokenNum)
                    let $newSearchTokenNum = 
                        $left/@stokenNum
                    let $right = 
                        fts:evaluate($nftSelection/right,
                                     $searchContext,
                                     $matchOptions,
                                     $newSearchTokenNum)
                    return applyFTMildNot($left, $right)
        case ($nftSelection as element(FTOrder))
             let $nested := 
                 fts:evaluate($nftSelection/selection,
                              $searchContext,
                              $matchOptions,
                              $searchTokenNum)
             return applyFTOrder($nested)
        case ($nftSelection as element(FTScope))
             let $nested := 
                 fts:evaluate($nftSelection/selection,
                              $searchContext,
                              $matchOptions,
                              $searchTokenNum)
             return applyFTScope($nftSelection/@type, 
                                 $nftSelection/@scope,
                                 $nested)
        case ($nftSelection as element(FTContent))
             let $nested := 
                 fts:evaluate($nftSelection/selection,
                              $searchContext,
                              $matchOptions,
                              $searchTokenNum)
             return applyFTContent($searchContext,
                                   $nftSelection/@type, 
                                   $nested)
        case ($nftSelection as element(FTDistance))
             let $nested := 
                 fts:evaluate($nftSelection/selection,
                              $searchContext,
                              $matchOptions,
                              $searchTokenNum)
             return applyFTDistance($matchOptions,
                                    $nftSelection/@type,
                                    $nftSelection/range,
                                    $nested)
        case ($nftSelection as element(FTWindow))
             let $nested := 
                 fts:evaluate($nftSelection/selection,
                              $searchContext,
                              $matchOptions,
                              $searchTokenNum)
             return applyFTWindow($matchOptions,
                                  $nftSelection/@type,
                                  $nftSelection/@size,
                                  $nested)
        case ($nftSelection as element(FTTimes))
             let $nested := 
                 fts:evaluate($nftSelection/selection,
                              $searchContext,
                              $matchOptions,
                              $searchTokenNum)
             return applyFTTimes($nftSelection/range,
                                     $nested)
}
            </eg>
            
            <p>Let us now walk through the above pseudo-code to
            understand the semantics of the function. For
            concreteness, let us assume that the FTSelection was
            invoked inside an <code>ftcontains</code> expression such
            as <code>searchContext ftcontains ftselection</code>. In order to 
	    determine the
            <term>AllMatches</term> result of <code>ftselection</code>, the
            <function>fts:evaluate</function> function is invoked as
            follows: <code>fts:evaluate($ftselection,
            $searchContext, $matchOptions, 0)</code>, where
            <code>$ftselection</code> is the XML representation of the
            <code>ftselection</code> and
            <code>$searchContext</code> is bound to the result of
            the evaluation of the XQuery expression
            <code>searchContext</code>. </p>
            
            <p>Initially, the
            <code>$searchTokensNum</code> is 0, i.e. currently 0
            search tokens have been processed.</p>
            
            <p>The <code>$matchOptions</code> above is the default
            (implementation-defined) list of match options that apply to the
            evaluation of <code>ftselection</code> (such as stemming but not
            thesaurus) and is implementation-defined. Match options embedded in
            <code>ftselection</code> can change the match options collection as
            evaluation proceeds. In order to express the order in which match
            options are applied to an <term>FTSelection</term>, the match options are
            organized in a stack. The top match option in the stack is to be
            applied first, the next match option is to be applied second, and so
            on. The ordering among match options is necessary because match
            options are not always commutative. For example,
            synonym(stem(word)) is not always the same as stem(synonym(word)).
            Of course, match optionss can be reordered when they commute, but
            this is an optimization issue and is beyond the scope of this
            semantics document.</p>
            
            <p>Given the invocation of: <code>fts:evaluate($ftselection,
            $searchContext, $matchOptions)</code>, evaluation proceeds as
            follows. First, <code>$ftselection</code> is checked to see whether
            it is a match option applied on a nested <term>FTSelection</term> (case 1), a
            weight specification (case 2), a <term>FTWords</term> (case 3), or some other
            <term>FTSelection</term> (case 4). Let us consider these four cases in
            turn.</p>
            
            <p>Case 1: If <code>$ftselection</code> contains a match option,
            then it modifies the context for the nested <term>FTSelection</term>.
            Consequently, a new match option element is created and pushed onto
            the top of the stack of match options. The
            <function>createOptionElement</function> function used to create a
            stack element corresponding to the match option simply creates a
            data structure that stores the type of match option (such as
            stemming, thesaurus, synonyms, ignore, etc.) and the details
            relating to the match option (such as the name of the thesaurus, the
            words to ignore, etc.). The context match option created is added to
            the top of the stack because, in the <term>FTSelection</term>, it was applied
            before the other match options in the current match options stack.
            The <function>evaluate</function> function is then invoked on the
            nested <term>FTSelection</term> with the new match options stack. When the
            function returns, the match option is popped from the stack, and the
            result of the nested <function>evaluate</function> function is
            returned. The match option is popped because the match options
            should not apply to <term>FTSelection</term>s outside its scope. </p>
            
            <p>Case 2: If <code>$ftselection</code> contains a weight
            specification, then the specification is simply ignored (because it
            does not alter semantics). The <function>evaluate</function>
            function is recursively called on the nested <term>FTSelection</term> and the
            resulting <term>AllMatches</term> is directly returned. </p>
            
            <p>Case 3: If <code>$ftselection</code> is a <term>FTWords</term>, then it does
            not have any nested <term>FTSelection</term>s. Consequently, this is the base
            of the recursive call, and the <term>AllMatches</term> result of the <term>FTWords</term>
            is computed and returned. The <term>AllMatches</term> is computed by invoking
            the <function>applyFTWords</function> function with the current
            search context and other necessary information. The semantics of
            how exactly the corresponding <function>applyFTWords</function>
            creates <term>AllMatches</term> for <term>FTWords</term> will be specified in the next
            section.</p>
            
            <p>Case 4: If <code>$ftselection</code> contains neither a match
            option nor a weight specification and is not a <term>FTWords</term>, the
            <term>FTSelection</term> performs some form of full-text operation such as
            <code>&amp;&amp;</code>, <code>||</code>, <code>window</code>, etc.
            Note that these operations are fully-compositional, and can be
            invoked on nested <term>FTSelection</term>s. Consequently, evaluation proceeds
            as follows. First, the <function>evaluate</function> function is
            recursively invoked on each nested <term>FTSelection</term>. The result of
            evaluating each nested <term>FTSelection</term> is <term>AllMatches</term>. These
            <term>AllMatches</term> are transformed into a result <term>AllMatches</term> by applying
            the full- text operation corresponding to <code>FTSelection1</code>
            (generically named <function>applyX</function> for some type of
            <term>FTSelection</term> X in the pseudo-code). As an example, let
            <code>FTSelection1</code> be <code>FTSelection2 &amp;&amp;
            FTSelection3 </code>. Here <code>FTSelection2</code> and
            <code>FTSelection3</code> can themselves be arbitrarily nested
            <term>FTSelection</term>s. Thus, <function> evaluate</function> is invoked on
            <code>FTSelection2</code> and <code> FTSelection3</code>, and the
            resulting <term>AllMatches</term> are transformed to the output <term>AllMatches</term>
            using the <function> applyFTAnd</function> function corresponding to
            <code>&amp;&amp; </code>.</p>
            
            <p>Note that specifying the semantics of the
            <function>applyFTSelection </function> function for each
            <term>FTSelection</term> is key to specifying the semantics of the
            <term>FTSelection</term> itself. In the subsequent sections, we define the
            semantics of the <function>applyX</function> function for
            each <term>FTSelection</term> kind X.</p>
            
        </div4>
        
        
        
        <!-- **********************************************************************
             *                     Formal semantics functions                     *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>Formal semantics functions</head>
            
            <p>The formal semantics of the <function>ApplyX</function>
            functions for each <term>FTSelection</term> kind X is specified in terms of
            four functions. How these four functions are computed is
            implementation-defined, but the functions have to satisfy some
            well-defined properties. We first present the properties of the
            formal semantics functions, and then present the semantics of the
            family of functions <function>applyX</function> in terms of these
            functions.</p>
            
            <p>The first function, <function>getTokenInfo</function> has been
            described in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#TokenizationSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">tokenization
            section</loc>.</p>
            
            <p>The <function>wordDistance</function> returns the
            number of words that occur between the positions of the
            <term>TokenInfo</term>s <code>$tokenInfo1</code> and
            <code>$tokenInfo2</code>. For example, two consecutive
            words have a distance of 0. </p>
            
            <eg role="parse-text" xml:space="preserve">
function fts:wordDistance(
             $tokenInfo1 as fts:TokenInfo,
             $tokenInfo2 as fts:TokenInfo,
             $matchOptions as fts:FTMatchOptions) 
             as xs:integer
            </eg>
            
            <p>Similarly, the function
            <function>getParaDistance</function>returns the number of
            paragraphs that occur between the <term>TokenInfo</term>s
            <code>$tokenInfo1</code> and <code>$tokenInfo2
            </code>.</p>
            
            <eg role="parse-text" xml:space="preserve">
function fts:paraDistance(
             $tokenInfo1 as fts:TokenInfo,
             $tokenInfo2 as fts:TokenInfo,
             $matchOptions as fts:FTMatchOptions) 
             as xs:integer
            </eg>
            
            <p>The function <function>sentenceDistance</function>
            returns the number of sentences that occur between the
            <term>TokenInfo</term>s <code>$tokenInfo1</code> and
            <code>$tokenInfo2 </code>. </p>
            
            <eg role="parse-text" xml:space="preserve">
function fts:sentenceDistance(
             $tokenInfo1 as fts:TokenInfo,
             $tokenInfo2 as fts:TokenInfo,
             $matchOptions as fts:FTMatchOptions) 
             as xs:integer
            </eg>

            <p>The function <function>isStartToken</function>
            checks if the <term>TokenInfo</term> <code>$tokenInfo</code> 
            describes the first token of the node <code>$searchContext
            </code>. </p>

            <eg role="parse-text" xml:space="preserve">
function fts:isStartToken(
             $searchContext as node(),
             $tokenInfo as fts:TokenInfo) 
             as xs:boolean
            </eg>

            <p>The function <function>isEndToken</function>
            checks if the <term>TokenInfo</term> <code>$tokenInfo</code> 
            describes the last token of the node <code>$searchContext
            </code>. </p>

            <eg role="parse-text" xml:space="preserve">
function fts:isEndToken(
             $searchContext as node(),
             $tokenInfo as fts:TokenInfo) 
             as xs:boolean
            </eg>
            
        </div4>
        
        
        <!-- **********************************************************************
             *                            FTWords                       *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>FTWords</head>
            
            <p>We first consider the case where <term>FTWords</term> consists of a single
            search string. The parameters of the
            <function>applySingleSearchToken </function> function are the
            search context, the list of match options, the search
            <term>TokenInfo</term>, and the position where the latter occurs in the query.
            </p>
            
            <p>In general for all cases of <term>FTWords</term>, if the after the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#FTMatchOptionsSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">application of all FTMatchOptions
            </loc>, the sequence of search tokens is empty, an empty
            <term>AllMatches</term> is returned. </p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:applySingleSearchToken(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchToken as fts:TokenInfo,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
 &lt;allMatches stokenNum="{$queryPos}"&gt;
    {
     let $token_pos := fts:getTokenInfo($searchContext,
                                        $matchOptions,
                                        $searchToken)
     for $pos in $token_pos
     return 
       &lt;match&gt; 
         &lt;stringInclude queryPos="{$queryPos}" 
                        queryString="{$searchToken/@word}" &gt; 
           {$pos} 
         &lt;/stringInclude&gt;
       &lt;/match&gt;
    }
 &lt;/allMatches&gt;
}
</eg>

            <p>Intuitively, the <term>AllMatches</term> corresponding to an
            <term>FTWords</term> corresponds to a set of <term>Match</term>es, each of which
            is associated with a position where the corresponding
            search token was found. For example, the <term>AllMatches</term>
            result for the <term>FTWords</term> "Mustang" evaluated in
            the context of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">sample
            document</loc> will be (in graphical terms): </p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTWordEx.jpg" alt="FTWords example" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            
            <p>The other cases can be rewritten as complex
            <term>FTSelection</term>s that operate on single string <term>FTWords</term>s.
            </p>
            
            <p>In the case of a <term>FTWords</term> with <code>any word</code>
            specified, the semantics is given below. Since <term>FTWords</term>
            does not have nested <term>FTSelection</term>s, the
            <function>ApplyFTWords</function> function does not take in
            any <term>AllMatches</term> parameters corresponding to nested
            <term>FTSelection</term> results.</p>

            <eg role="parse-text" xml:space="preserve">
declare function 
fts:MakeDisjunction($curRes as element(allMatches, 
                                       fts:AllMatches),
                    $rest as element(allMatches, 
                                     fts:AllMatches)*) 
                    as element(allMatches, 
                               fts:AllMatches) 
{
 if (fn:count($rest) = 0)
 then $curRes
 else let $firstAllMatches := $rest[1]
      let $restAllMatches := fn-subsequence($rest, 2)
      let $newCurRes := fts:ApplyFTOr($curRes, 
                                      $firstAllMatches)
      return fts:MakeDisjunction($newCurRes, 
                                 $restAllMatches)
}

declare function fts:ApplyFTWordsAnyWord(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchStrings as xs:string*,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
  let $searchTokens := 
    for $searchString in $searchStrings
    return fts:getSearchTokenInfo($searchString,
                                  $matchOptions)
  return 
    if (fn:count($searchTokens) eq 0) then &lt;allMatches stokenNum="0" /&gt;
    else
      let $allAllMatches = 
        for $searchToken at $pos in $searchTokens
        return fts:applySingleSearchToken(
                   $searchContext,
                   $matchOptions,
                   $searchToken,
                   $queryPos + $pos - 1)
      let $firstAllMatches := $allAllMatches[1]
      let $restAllMatches := fn:subsequence($allAllMatches, 2)
      return fts:MakeDisjunction($firstAllMatches, $restAllMatches)
}
</eg>

            <p>Intuitively, all search strings are tokenized and a single sequence
            that consists of all <term>TokenInfo</term>s is constructed. For each of these,
            the result of <term>FTWords</term> is computed using
            <function>ApplySingleSearchSelection</function>. Finally, the
            conjunction of all resulting <term>AllMatches</term> is computed.</p>
            
            <p>Similarly, in the case of a <term>FTWords</term> with <code>all word</code>
            specified, the semantics is given below. </p>

            <eg role="parse-text" xml:space="preserve">
declare function 
fts:MakeConjunction($curRes as element(allMatches, 
                                       fts:AllMatches),
                    $rest as element(allMatches, 
                                     fts:AllMatches)*) 
                    as element(allMatches, 
                               fts:AllMatches) 
{
 if (fn:count($rest) = 0)
 then $curRes
 else let $firstAllMatches := $rest[1]
      let $restAllMatches := fn-subsequence($rest, 2)
      let $newCurRes := fts:ApplyFTAnd($curRes, 
                                       $firstAllMatches)
      return fts:MakeConjunction($newCurRes, 
                                 $restAllMatches)
}

declare function fts:ApplyFTWordsAllWord(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchStrings as xs:string*,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
  let $searchTokens := 
    for $searchString in $searchStrings
    return fts:getSearchTokenInfo($searchString,
                                  $matchOptions)
  return
    if (fn:count($searchTokens) eq 0) then &lt;allMatches stokenNum="0" /&gt;
    else
      let $allAllMatches = 
        for $searchToken at $pos in $searchTokens
        return fts:applySingleSearchToken(
                   $searchContext,
                   $matchOptions,
                   $searchToken,
                   $queryPos + $pos - 1)
      let $firstAllMatches := $allAllMatches[1]
      let $restAllMatches := fn:subsequence($allAllMatches, 2)
      return fts:MakeConjunction($firstAllMatches, $restAllMatches)
}
</eg>
            
            <p>In the case of a <term>FTWords</term> with <code>phrase</code>
            specified, the semantics is given below. </p>

            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTWordsPhrase(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchStrings as xs:string*,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
    let $conj := fts:ApplyFTWordsAllWord($searchContext,
                                         $matchOptions,
                                         $searchStrings,
                                         $queryPos)
    let $ordered := fts:ApplyFTOrder($conj)
    let $distance1 := 
        fts:ApplyFTDistance($matchOptions,
                            $ordered,
                            &lt;fts:range type="exactly" n="0"&gt;)
    return $distance1
}
</eg>
            
            <p>The semantics of this function differs from the 
            semantics of the functions</p>
            <p>The above function is similar to the one in the case of
            <code>all word</code>. The only difference is that the
            additional <term>FTSelection</term>s <code>ordered</code> and
            <code>word distance 1</code> are applied.</p>

            <p>The semantics for the case of <term>FTWords</term> with
            <code>any</code> specified is given below.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTWordsAny(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchStrings as xs:string*,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
 if (fn:count($searchTokens) eq 0) 
 then &lt;allMatches stokenNum="0" /&gt;
 else let $firstSearchString := $searchStrings[1]
      let $restSearchString := fn:subsequence($searchStrings, 2)
      let $firstAllMatches := 
        fts:ApplyFTWordsPhrase($searchContext,
                              $matchOptions,
                              $firstSearchString,
                              $queryPos)
      let $newQueryPos := fn:max($firstAllMatches//@queyrPos) + 1
      let $restAllMatches :=
        fts:ApplyFTWordsAny($searchContext,
                           $matchOptions,
                           $restSearchString,
                           $newQueryPos)
      return fts:ApplyFTOr($firstAllMatches, $resAllMatches)
}
</eg>

            <p>Intuitively, the <term>FTWords</term> with <code>any</code>
            specified forms the disjunction of the <term>AllMatches</term> that
            are the result of the matching of each seperate search
            string as a phrase.</p>
            
            <p>Analogously, the semantics for the case of a <term>FTWords</term> with
            <code>all</code> specified is:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTWordsAll(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchStrings as xs:string*,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
 if (fn:count($searchTokens) = 0) 
 then &lt;allMatches stokenNum="0" /&gt;
 else let $firstSearchString := $searchStrings[1]
      let $restSearchString := fn:subsequence($searchStrings, 2)
      let $firstAllMatches := 
        fts:ApplyFTWordsPhrase($searchContext,
                              $matchOptions,
                              $firstSearchString,
                              $queryPos)
      let $newQueryPos := fn:max($firstAllMatches//@quetyPos) + 1
      let $restAllMatches :=
        fts:ApplyFTWordsAll($searchContext,
                           $matchOptions,
                           $searchStrings,
                           $newQueryPos)
      return fts:ApplyFTAnd($firstAllMatches, $resAllMatches)
}
</eg>

            <p>As before, the difference from the case of
            <code>any</code> is the use of conjunction instead of
            disjunction.</p>
            
            <p>Finally, we define the function that combines all of
            the above cases.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function 
  fts:ApplyFTWords($searchContext as Node*, 
                  $matchOptions as fts:FTMatchOptions,
                  $type as element(type, fts:FTWordsType),
                  $searchTokens as xs:string*,
                  $queryPos as xs:integer)
                  as element(allMatches, fts:AllMatches) {
  if ($type eq "any word")
  then fts:ApplyFTWordsAnyWord($searchContext,
                              $matchOptions,
                              $searchTokens,
                              $queryPos)
  else if ($type eq "all word")
  then fts:ApplyFTWordsAllWord($searchContext,
                              $matchOptions,
                              $searchTokens,
                              $queryPos)
  else if ($type eq "phrase")
  then fts:ApplyFTWordsPhrase($searchContext,
                             $matchOptions,
                             $searchTokens,
                             $queryPos)
  else if ($type eq "any")
  then fts:ApplyFTWordsAny($searchContext,
                          $matchOptions,
                          $searchTokens,
                          $queryPos)
  else fts:ApplyFTWordsAll($searchContext,
                          $matchOptions,
                          $searchTokens,
                          $queryPos)
}
                </eg>
        </div4>
        
        
        
        <div4 role="xquery">
            <!-- **********************************************************************
             *                            FTOr                          *
             ********************************************************************** -->
            <head>FTOr</head>
            <p>The parameters of the <function>ApplyFTOr</function> 
            function are the two <term>AllMatches</term> parameters 
            corresponding to the results of the two nested 
            <term>FTSelection</term>s. The search context and the match
            options stack are not used in this case. The function 
            definition is given below.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function 
  fts:ApplyFTOr($allMatches1 as element(allMatches, 
                                        fts:AllMatches),
                $allMatches2 as element(allMatches, 
                                        fts:AllMatches)) 
                as element(allMatches, fts:AllMatches) {
    &lt;allMatches stokenNum="{fn:max(($allMatches1/@stokenNum, 
                                    $allMatches2/@stokenNum))}"&gt;
      ($allMatches1/match 
       $allMatches2/match)
    &lt;/allMatches&gt;
  }
            </eg>
            
            <p>The function creates a new <term>AllMatches</term> whose 
            <term>Match</term>es are simply the union of those found 
            in the input <term>AllMatches</term>. The rationale for 
            this semantics is that each <term>Match</term> represents 
            one possible "solution" to the corresponding 
            <term>FTSelection</term>. Thus, if we "or" two 
            <term>AllMatches</term>, a <term>Match</term> from either 
            of the <term>AllMatches</term> should also be a solution. </p>
            <p>As an example, consider the <term>FTSelection</term>
            <code>"Mustang" || "Honda"</code> in 
            the context of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">sample 
            document</loc>. The <term>AllMatches</term> corresponding to 
            "Mustang" and "Honda" are:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrEx1.jpg" alt="FTOr input AllMatches 1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrEx2.jpg" alt="FTOr input AllMatches 2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            
            <p>The <term>AllMatches</term> produced by <function>
            ApplyFTOr</function> is:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrEx3.jpg" alt="FTOr result AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
        </div4>
        
        
        
        <div4 role="xquery">
            <!-- **********************************************************************
             *                            FTAnd                         *
             ********************************************************************** -->
            <head>FTAnd</head>
            <p>The parameters of the <function>ApplyFTAnd</function> 
            function are the two <term>AllMatches</term> parameters 
            corresponding to the results of the two nested 
            <term>FTSelection</term>s. The search context and the match 
            options are not used in this case. The function 
            definition is given below.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function 
  fts:ApplyFTAnd ($allMatches1 as element(allMatches, 
                                          fts:AllMatches),
                  $allMatches2 as element(allMatches, 
                                          fts:AllMatches)) 
                  as element(allMatches, fts:AllMatches) {
    &lt;allMatches stokenNum="{fn:max(($allMatches1/@stokenNum, 
    				    $allMatches2/@stokenNum))}" &gt;
      {for $sm1 in $allMatches1/match
       for $sm2 in $allMatches2/match
       return &lt;match&gt;
                {$sm1/* $sm2/*}
              &lt;/match&gt;
      }
    &lt;/allMatches&gt;
  } 
            </eg>
            
            <p>Intuitively, the result of a conjunction is a new 
            <term>AllMatches</term> that contains the "Cartesian 
            product" of the simple matches of the participating 
            <term>FTSelection</term>s. Every resulting <term>Match</term> 
            is formed the combination of the stringInclude components 
            and stringExclude components from each of the 
            <term>AllMatches</term> of the nested <term>FTSelection</term> 
            conditions. Thus every simple match will contain the positions 
            to satisfy a <term>Match</term> from both original 
            <term>FTSelection</term>s and will exclude the positions that 
            will violate the same <term>Match</term>es. </p>
            <p>As an example let us consider the <term>FTSelection</term>
            <code>"Mustang" &amp;&amp; "rust"</code> 
            in the context of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">sample 
            document</loc>. The source <term>AllMatches</term> are:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTAndEx1.jpg" alt="FTAnd input AllMatches 1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTAndEx2.jpg" alt="FTAnd input AllMatches 2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            
            <p>The <term>AllMatches</term> produced by <function>ApplyFTAnd
            </function> is:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTAndEx3.jpg" alt="FTAnd result AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
        </div4>
        
        
        
        <div4 role="xquery"> 
        <!-- **************************************************
             *                  FTUnaryNot                    *
             ************************************************** --> 
        <head>FTUnaryNot</head> 
        
        <p>The parameters of the <function>ApplyFTUnaryNot</function>
        function are the search context, the list of match
        optionss, and one <term>AllMatches</term> parameter corresponding to the
        result of the nested <term>FTSelection</term> to be negated. The
        search context and the match options are not used in this
        case. The function definition is given below.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:InvertStringMatch($strm) {
  if ($strm instanceof element(stringExclude)) then
    &lt;stringInclude queryPos="{$strm/@queryPos}"
                   queryString="{$strm/@queryString}"&gt;
      {$strm/docPos}
    &lt;/stringInclude&gt;
  else
    &lt;stringExclude queryPos="{$strm/@queryPos}"
                   queryString="{$strm/@queryString}"&gt;
      {$strm/docPos}
    &lt;/stringInclude&gt;
  }

declare function fts:UnaryNotHelper($sms) { 
  &lt;allMatches stokenNum="{$stokenNum}"&gt;
    {
     for $sm in $sms/match[1]/child::element()
     for $rest in fts:UnaryNotHelper(
                      fn:subsequence($sms/match, 2)/match
     return 
       &lt;match&gt;
         (fts:InvertStringMatch($sm)
          $rest/*)
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}

declare function 
  fts:ApplyFTUnaryNot($allMatches as 
                      element(allMatches, fts:AllMatches))
                      as element(allMatches, 
                                 fts:AllMatches) {
  if ($allMatches/match) then
    {fts:UnaryNotHelper($allMatches)}
  else
    &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
        &lt;match /&gt;
    &lt;/allMatches&gt;
}
            </eg>
            
            <p>The process of the generation of the resulting
            AllMatches of an <term>FTUnaryNot</term> resembles the transformation
            of a negation of prepositional formula in DNF back to DNF.
            The intuition is that negation of <term>AllMatches</term> requires
            the inversion of all the conditions on the nodes encoded
            by the <term>AllMatches</term> .</p>
            
            <p>In the implementation above, this inversion is
            implemented as follows. The function <function>
            fts:invertStringMatch</function> inverts a
            <term>stringInclude </term> into a
            <term>stringExclude</term> and vice versa. The function
            <function>fts:neg_helper</function> transforms the source
            <term>Match</term>es into the resulting <term>Match</term>es by combining a the
            inversions of a <term>stringInclude</term> or
            <term>stringExclude</term> component from every source
            <term>Match</term> into a new <term>Match</term>.</p>
            
            <p>As an example, let us consider the <term>FTSelection</term>
            <code>! ("Mustang" || "Honda")</code> 
            in the context of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
            sample document</loc>. The source <term>AllMatches</term> 
            is:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTNegationEx1.jpg" alt="FTUnaryNot input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                     
            <p>The <term>FTUnaryNot</term> will transform it to:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTNegationEx2.jpg" alt="FTUnaryNot result AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
        </div4>
        
        
        
        <!-- **********************************************************************
             *                            FTMildNot                          *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>FTMildNot</head>
            
            <p>The parameters of the <term>ApplyFTMildNot</term>
            function are the two <term>AllMatches</term> parameters corresponding
            to the results of the two nested <term>FTSelection</term>s. The
            search context and the match options stack are not
            used in this case. The function definition is given
            below.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function 
  fts:ApplyFTMildNot($allMatches1 as 
                       element(allMatches, fts:AllMatches),
                     $allMatches2 as 
                       element(allMatches, fts:AllMatches)) 
                     as element(allMatches, fts:AllMatches){
    if (fn:count($allMatches2//stringExclude) gt 0) then
      fn:error("Invalid expression on the right-hand side of a not-in")
    else
    &lt;allMatches stokenNum="{$allMatches1/@stokenNum}"&gt;
     {let $posSet2 = $allMatches2/match/stringInclude/pos
      return 
        $allMatch1/match[every $pos1 in ./stringInclude/pos,
                               $pos2 in $posSet2
                         satisfies $pos1 ne $pos2]
     }
    &lt;/allMatches&gt;
  }
            </eg>
            
            <p>The resulting <term>AllMatches</term> consists of those <term>Match</term>es
            of the first operand that do not mention in their
            <term>stringInclude</term> components positions mentioned
            in a <term>stringInclude</term> component in the
            <term>AllMatches</term> of the second operand.</p> 
            
            <p>As an example, consider the <term>FTSelection</term>
            <code>("Ford" mildnot "Ford
            Mustang")</code> in the context of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> sample document</loc>. The
            source <term>AllMatches</term> are:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTMildNegationEx1.jpg" alt="FTMildnot input AllMatches 1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTMildNegationEx2.jpg" alt="FTMildnot input AllMatches 2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                     
            <p>The <term>FTMildNot</term> will transform these to empty
            <term>AllMatches</term> because both position 1 and position 27 from
            the first <term>AllMatches</term> contain only <term>TokenInfo</term>s from
            <term>stringInclude</term> components of the second
            <term>AllMatches</term>.</p>
            
        </div4>
        
        
        
        <!-- **********************************************************************
             *                                FTOrder                             *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>FTOrder</head>
            
            <p>The parameters of the <function>ApplyFTOrder</function>
            function are the search context, the list of match
            options, and one <term>AllMatches</term> parameter corresponding to
            the result of the nested <term>FTSelection</term>s. The evaluation
            context and the match options are not used in this case.
            The function definition is given below.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function 
  fts:ApplyFTOrder($allMatches as element(allMatches, 
                                          fts:AllMatches))
                  as element(allMatches, fts:AllMatches) {
    &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
      {
       for $match in $allMatches/match
       where every $stringInclude1 in $match,
                   $stringInclude2 in $match    
             satisfies (($stringInclude1/tokenInfo/@pos &lt;= 
                         $stringInclude2/tokenInfo/@pos)
                        and
                        ($stringInclude1/@queryPos &lt;= 
                         $stringInclude2/@queryPos))
                       or
                        (($stringInclude1/tokenInfo/@pos&gt;= 
                          $stringInclude2/tokenInfo/@pos)
                         and
                         ($stringInclude1/@queryPos &gt;= 
                          $stringInclude2/@queryPos))
       return 
         &lt;match&gt;
           {$match/stringInclude}
           {
            for $stringExcl in $match/stringExclude
            where every $stringIncl in $match/stringInclude
                  satisfies (($stringExcl/tokenInfo/@pos &lt;= 
                              $stringIncl/tokenInfo/@pos)
                             and
                              ($stringExcl/@queryPos &lt;= 
                               $stringIncl/@queryPos))
                            or
                             (($stringExcl/tokenInfo/@pos &gt;= 
                               $stringIncl/tokenInfo/@pos)
                              and
                              ($stringExcl/@queryPos &gt;= 
                               $stringIncl/@queryPos))
           }
         &lt;/match&gt;
      }         
    &lt;/allMatches&gt;
  }
            </eg>
            
            <p>The resulting <term>AllMatches</term> contains all <term>Match</term> of the
            parameter whose positions in the <term>
            stringInclude</term> elements are in the order of the
            query positions of their query strings. Only those <term>
            stringExcludes</term> are retained that preserve the
            order.</p>
            
            <p>As an example, consider the <term>FTSelection</term>
            <code>("great" &amp;&amp; "condition")
            ordered</code> in the context of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> sample document</loc>. The
            source <term>AllMatches</term> is:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrderEx1.jpg" alt="FTOrder input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrderEx2.jpg" alt="FTOrder input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrderEx3.jpg" alt="FTOrder input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                     
            <p>The <term>FTOrder</term> will return:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrderEx4.jpg" alt="FTOrder result AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTOrderEx5.jpg" alt="FTOrder result AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
        </div4>
        
        
        
        <!-- **********************************************************************
             *                            FTScope                        *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>FTScope</head>
            
            <p>The parameters of the <function>ApplyFTScope</function>
            function are the search context, the list of match
            options, the type of the scope (same or different), the
            linguistic unit (sentence or paragraph) and one
            <term>AllMatches</term> parameter corresponding to the result of the
            nested <term>FTSelection</term>s. The search context and the
            match options are not used in this case. The functions
            definitions depending on the type of the scope (paragraph,
            sentence) and the scope predicate (same, different) are
            given below.</p>
            
            <p>In case of <code>same sentence</code>, the semantics is
            given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTScopeSameSentence(
      $allMatches as element(allMatches, fts:AllMatches)
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
     {
      for $match in $allMatches/match
      where every $stringInclude1 in $match,
                  $stringInclude2 in $match 
            satisfies $stringInclude1/tokenInfo/@sentence = 
                      $stringInclude2/tokenInfo/@sentence
      return 
        &lt;match&gt;
          {$match/stringInclude}
          {
           for $stringExcl in $match/stringExclude
           where every $stringIncl in $match/stringInclude
                 satisfies $stringIncl/tokenInfo/@sentence = 
                           $stringExcl/tokenInfo/@sentence
          }
        &lt;/match&gt;
     }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>Similarly, the semantics for <code>different sentence
            </code> is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTScopeDifferentSentence(
      $allMatches as element(allMatches, fts:AllMatches)
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     where every $stringInclude1 in $match,
                 $stringInclude2 in $match  
           satisfies $stringInclude1 = $stringInclude2 or
                     $stringInclude1/tokenInfo/@sentence != 
                     $stringInclude2/tokenInfo/@sentence
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where every $stringIncl in $match/stringInclude
                satisfies $stringIncl/tokenInfo/@sentence != 
                          $stringExcl/tokenInfo/@sentence
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>In case of <code>same paragraph</code>, the semantics 
            is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTScopeSameParagraph(
      $allMatches as element(allMatches, fts:AllMatches)
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     where every $stringInclude1 in $match,
                 $stringInclude2 in $match  
           satisfies $stringInclude1/tokenInfo/@para = 
                     $stringInclude2/tokenInfo/@para
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where every $stringIncl in $match/stringInclude
                satisfies $stringIncl/tokenInfo/@para = 
                          $stringExcl/tokenInfo/@para
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>Finally, the semantics for <code>different paragraph</code> 
            is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTScopeDifferentParagraph(
      $type
      $allMatches as element(allMatches, fts:AllMatches)
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     where every $stringInclude1 in $match,
                 $stringInclude2 in $match  
           satisfies $stringInclude1 = $stringInclude2 or
                     $stringInclude1/tokenInfo/@para != 
                     $stringInclude2/tokenInfo/@para
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where every $stringIncl in $match/stringInclude
                satisfies $stringIncl/tokenInfo/@para != 
                          $stringExcl/tokenInfo/@para
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>If for instance the type of the scope is
            "sentence", the semantics is straightforward.
            For every <term>Match</term> from the <term>AllMatches</term> of the operand, it
            filters those that contain string matches from
            <term>stringInclude</term> only in the same (different) element
            sentence. From the <term>stringExclude</term>s of the <term>AllMatches</term>,
            only those that refer to the same node are retained. The
            case for scope type paragraph is analogous.</p>
            
            <p>The semantics for the general case is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTScope(
      $type as fts:ScopeType,
      $selector fts:ScopeSelector, 
      $allMatches as element(allMatches, fts:AllMatches)
      ) as element(allMatches, fts:AllMatches) {
  if ($type eq "same" and $selector eq "sentence")
  then fts:ApplyFTScopeSameSentence($allMatches)
  else if ($type eq "different" and $selector eq "sentence")
       then fts:ApplyFTScopeDifferentSentence($allMatches)
  else if ($type eq "same" and $selector eq "paragraph")
       then fts:ApplyFTScopeSameParagraph($allMatches)
  else fts:ApplyFTScopeDifferentParagraph($allMatches)
}
</eg>
            
            <p>As an example, consider the <term>FTSelection</term>
            <code>("Mustang" &amp;&amp; "Honda") same 
            paragraph</code> in the context of the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
            sample document</loc>. The source <term>AllMatches</term> is:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTScopeEx.jpg" alt="FTScope input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                     
            <p>The <term>FTScope</term> will convert this to an empty
            <term>AllMatches</term> because neither <term>Match</term>es contain <term>TokenInfo</term>s
            from a single element.</p>
            
        </div4>
        
        
        
        <!-- ***************************************************************
             *                            FTContent                        *
             *************************************************************** -->
        <div4 role="xquery">
            <head>FTContent</head>
            
            <p>The parameters of the <function>ApplyFTContent</function>
            function are the search context, the match options,
            and the type of the content
            match (at the start of the current node, at the end of it,
            or its entire content), and one
            <term>AllMatches</term> parameter corresponding to the result of the
            nested <term>FTSelection</term>s. The semantics is given
            given below.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTContent(
      $searchContext as node(),
      $matchOptions as element(matchOptions, fts:FTMatchOptions),
      $type as fts:CotnentMatchType,
      $allMatches as element(allMatches, fts:AllMatches)
      ) as element(allMatches, fts:AllMatches) {
  if ($type eq "entire content") then
       let $temp1 := fts:ApplyFTWordDistanceExactly(
                        $matchOptions,
                        $allMatches,
                        1)
       let $temp2 := fts:ApplyFTContent(
                        $searchContext,
                        $matchOptions,
                        $temp1,
                        "at start")
       let $temp3 := fts:ApplyFTContent(
                        $searchContext,
                        $matchOptions,
                        $temp2,
                        "at end")
       return $temp3
  else
      &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
         {
          for $match in $allMatches/match
          where if ($type eq "at start") then
                   some $si in $math/stringInclude
                   satisfies fts:isStartToken($searchContext,
                                              $si/tokenInfo)
                else (: $type eq "at end" :) then
                   some $si in $math/stringInclude
                   satisfies fts:isEndToken($searchContext,
                                            $si/tokenInfo)
                else 
          return {$match}
      &lt;/allMatches&gt;
}
</eg>
            
        <p>The above functions considers three cases depending on 
        the type of the content match. The case of <code>entire match
        </code> is evaluated as <code>distance exactly 1 word at 
        start at end</code>, i.e. all the <term>StringInclude</term>s should
        match every token in the content of the current search context
        node. The case <code>at start</code> retains only those 
        <term>Match</term>es that contain a <term>StringInclude</term> that matches the 
        first token. This is checked using the semantic function
        <code>fts:isStartToken</code>. Similarly, the case <code>at
        end</code> retains only those 
        <term>Match</term>es that contain a <term>StringInclude</term> that matches the 
        last token. This is checked using the semantic function
        <code>fts:isEndToken</code>.
        </p>
        </div4>
        
        
        <!-- **********************************************************************
             *                            FTDistance                     *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>FTDistance</head>
            
            <p>The parameters of the
            <function>ApplyFTDistance</function> function are the
            search context, the list of match options, one
            <term>AllMatches</term> parameter corresponding to the result of the
            nested <term>FTSelection</term>s, the unit of the distance (words,
            sentences, paragraphs) and the range specification used.
            The search context is not used in this case. The
            semantics for the different cases depending on the
            distance units and the range specification are given
            below.</p>
            
            <p>The function for the case <code>word distance exactly
            N</code> is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTWordDistanceExactly(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer)
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $idx in (1 to fn:count($sorted) - 1)
           satisfies fts:wordDistance(
                         $sorted[$idx]/tokenInfo,
                         $sorted[$idx+1]/tokenInfo,
                         $matchOptions) = $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:wordDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) = $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>Similarly, the semantics for the case of <code>word 
            distance at least N</code> is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFWordDistanceAtLeast(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:wordDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &gt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:wordDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &gt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }           
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The semantics for the case of <code>word distance 
            at most N</code> is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFWordDistanceAtMost(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@Identifier ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:wordDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &lt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:wordDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &lt;= $n
		  return $stringExclude
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The semantics for the final case of  <code>word 
            distance from M to N</code> is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFWordDistanceFromTo(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $m as xs:integer,
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                  order by $si/tokenInfo/@pos ascending
                  return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:wordDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &gt;= $m 
                     and
                     fts:wordDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &lt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:wordDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &gt;= $m
                          and
                          fts:wordDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &lt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The function for the case <code>sentence distance 
            exactly N</code> is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFSentenceDistanceExactly(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:sentenceDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) = $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:sentenceDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) = $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }           
  &lt;/allMatches&gt;
}
</eg>
            
            <p>Similarly, the semantics for the case of <code>sentence 
            distance at least N</code> is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFSentenceDistanceAtLeast(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:sentenceDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &gt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:sentenceDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &gt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }           
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The semantics for the case of <code>sentence distance 
            at most N</code> is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFSentenceDistanceAtMost(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:sentenceDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &lt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:sentenceDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &lt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }           
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The semantics for the final case of  <code>sentence 
            distance from M to N</code> is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFSentenceDistanceFromTo(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $m as xs:integer,
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                  return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:sentenceDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &gt;= $m 
                     and
                     fts:sentenceDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &lt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:sentenceDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &gt;= $m
                          and
                          fts:sentenceDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &lt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The function for the case <code>paragraph distance 
            exactly N</code> is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTParagraphDistanceExactly(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:paraDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) = $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:paraDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) = $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }           
  &lt;/allMatches&gt;
}
</eg>
            
            <p>Similarly, the semantics for the case of <code>paragraph 
            distance at least N</code> is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTParagraphDistanceAtLeast(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:paraDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &gt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:paraDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &gt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }           
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The semantics for the case of <code>paragraph 
            distance at most N</code> is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTParagraphDistanceAtMost(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $si/tokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:paraDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &lt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:paraDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &lt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }           
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The semantics for the final case of  <code>paragraph 
            distance from M to N</code> is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTParagraphDistanceFromTo(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $m as xs:integer,
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt;
    {
     for $match in $allMatches/match
     let $sorted = for $si in $match/stringInclude          
                   order by $sitokenInfo/@pos ascending
                   return $si
     where every $index in in (1 to fn:count($sorted) - 1)
           satisfies fts:paraDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &gt;= $m 
                     and
                     fts:paraDistance(
                         $sorted[$index]/tokenInfo,
                         $sorted[$index+1]/tokenInfo,
                         $matchOptions) &lt;= $n 
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExcl in $match/stringExclude
          where some $stringIncl in $match/stringInclude
                satisfies fts:paraDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &gt;= $m
                          and
                          fts:paraDistance(
                              $stringIncl/tokenInfo,
                              $stringExcl/tokenInfo,
                              $matchOptions) &lt;= $n
		  return $stringExcl
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>Intuitively, the resulting <term>AllMatches</term> contains those
            <term>Match</term>es of the operand that satisfy the condition that
            the distance (measured in words, sentences, or paragraphs)
            for every couple of consecutive valid positions in
            <term>stringInclude</term> elements is in the specified interval.
            Here by consecutive, we mean with no other valid positions
            from the same <term>stringInclude</term> element between them.</p>
            
            <p>In the general case, the semantics is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTDistance(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $type as fts:DistanceType,
      $range as element(range, fts:FTRangeSpec),
      $allMatches as element(allMatches, fts:AllMatches)
      ) as element(allMatches, fts:AllMatches) {
  if ($type eq "word") then
    if ($range/@type eq "exactly") then
      fts:ApplyFTWordDistanceExactly($matchOptions, 
                                     $allMatches, 
                                     $range/@n)
    else if ($range/@type eq "at least") then 
      fts:ApplyFTWordDistanceAtLeast($matchOptions, 
                                     $allMatches, 
                                     $range/@n)
    else if ($range/@type eq "at most") then
      fts:ApplyFTWordDistanceAtMost($matchOptions, 
                                    $allMatches, $
                                    range/@n)
    else fts:ApplyFTWordDistanceFromTo($matchOptions, 
                                       $allMatches, 
                                       $range/@m,
                                       $range/@n)
 else if ($type eq "sentence") then
    if ($range/@type eq "exactly") then
      fts:ApplyFTSentenceDistanceExactly($matchOptions, 
                                         $allMatches, 
                                         $range/@n)
    else if ($range/@type eq "at least") then
      fts:ApplyFTSentenceDistanceAtLeast($matchOptions, 
                                         $allMatches, 
                                         $range/@n)
    else if ($range/@type eq "at most") then
      fts:ApplyFTSentenceDistanceAtMost($matchOptions, 
                                        $allMatches, 
                                        $range/@n)
    else fts:ApplyFTSentenceDistanceFromTo($matchOptions, 
                                           $allMatches, 
                                           $range/@m,
                                           $range/@n)
 else 
    if ($range/@type eq "exactly") then
      fts:ApplyFTParagraphDistanceExactly($matchOptions, 
                                          $allMatches, 
                                          $range/@n)
    else if ($range/@type eq "at least") then
      fts:ApplyFTParagraphDistanceAtLeast($matchOptions, 
                                          $allMatches, 
                                          $range/@n)
    else if ($range/@type eq "at most") then
      fts:ApplyFTParagraphDistanceAtMost($matchOptions, 
                                         $allMatches, 
                                         $range/@n)
    else fts:ApplyFTParagraphDistanceFromTo($matchOptions, 
                                            $allMatches, 
                                            $range/@m,
                                            $range/@n)
}
</eg>
            
            <p>As an example, consider the <term>FTDistance</term> selection
            <code>("Ford Mustang" &amp;&amp;
            "excellent") word distance at most 3</code> over
            the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">sample document</loc>.
            The six <term>Match</term>es of the source <term>AllMatches</term> for
            <code>("Ford Mustang" &amp;&amp;
            "excellent")</code> are given below:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTDistanceEx1.jpg" alt="FTDistance input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTDistanceEx2.jpg" alt="FTDistance input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTDistanceEx3.jpg" alt="FTDistance input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTDistanceEx4.jpg" alt="FTDistance input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTDistanceEx5.jpg" alt="FTDistance input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTDistanceEx6.jpg" alt="FTDistance input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>

            <p>The result for the above <term>FTDistance</term> selection will
            consist of only the first <term>Match</term> because only its the
            distance between consecuive <term>TokenInfo</term>s (distance 1 and
            distance 3 in this case) is less or equal to 3.</p>
            
        </div4>
        
        
        
        <!-- **********************************************************************
             *                            FTWindow                       *
             ********************************************************************** -->
        <div4 role="xquery">
            <head>FTWindow</head>
            
            <p>The parameters of the
            <function>ApplyFTWindow</function> function are the
            search context, the list of match options, the unit of
            type fts:DistanceType, a size, and one
            <term>AllMatches</term> parameter 
            corresponding to the result of the nested <term>FTSelection</term>s.
            The search context is not used
            in this case. For each of the different unit types we define
            an individual function as follows.</p>
            
            <p>The function for the case <code>window N words
            </code> is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
define function fts:ApplyFTWordWindow(
      $matchOptions as element(matchOptions, fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches&gt;
   {
    for $match in $allMatches/match
    let $minpos := fn:min($match/*/tokenInfo/@pos),
        $maxpos := fn:max($match/*/tokenInfo/@pos)
     for $windowStartPos in ($minpos to $maxpos-n+1)
     let $windowEndPos := $windowStartPos+n-1
     where fn:min($match/stringInclude/tokenInfo/@pos) &gt;= $windowStartPos
           and fn:max($match/stringInclude/tokenInfo/@pos) &lt;= $windowEndPos
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExclude in $match/stringExclude
          where $stringExclude/tokenInfo/@pos &gt;= $windowStartPos
                and $stringExclude/tokenInfo/@pos &lt;= $windowEndPos
          return $stringExclude
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The function for the case <code>window N sentences</code> 
            is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
define function fts:ApplyFTSentenceWindow(
      $matchOptions as element(matchOptions, fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches&gt;
   {
    for $match in $allMatches/match
    let $minpos := fn:min($match/*/tokenInfo/@sentence),
        $maxpos := fn:max($match/*/tokenInfo/@sentence)
     for $windowStartPos in ($minpos to $maxpos-n+1)
     let $windowEndPos := $windowStartPos+n-1
     where fn:min($match/stringInclude/tokenInfo/@sentence) &gt;= $windowStartPos
           and fn:max($match/stringInclude/tokenInfo/@sentence) &lt;= $windowEndPos
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExclude in $match/stringExclude
          where $stringExclude/tokenInfo/@sentence &gt;= $windowStartPos
                and $stringExclude/tokenInfo/@sentence &lt;= $windowEndPos
          return $stringExclude
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>The function for the case <code>word N paragraphs
            </code> 
            is presented below:</p>
            
            <eg role="parse-text" xml:space="preserve">
define function fts:ApplyFTParagraphWindow(
      $matchOptions as element(matchOptions, fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches&gt;
   {
    for $match in $allMatches/match
    let $minpos := fn:min($match/*/tokenInfo/@para),
        $maxpos := fn:max($match/*/tokenInfo/@para)
     for $windowStartPos in ($minpos to $maxpos-n+1)
     let $windowEndPos := $windowStartPos+n-1
     where fn:min($match/stringInclude/tokenInfo/@para) &gt;= $windowStartPos
           and fn:max($match/stringInclude/tokenInfo/@para) &lt;= $windowEndPos
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExclude in $match/stringExclude
          where $stringExclude/tokenInfo/@para &gt;= $windowStartPos
                and $stringExclude/tokenInfo/@para &lt;= $windowEndPos
          return $stringExclude
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
</eg>
            
            <p>Intuitively, the resulting <term>AllMatches</term> contains those
            <term>Match</term>es of the operand that satisfy the condition that
            there exists a sequence of the specified number of
            consecutive (word, sentence, or paragraph) positions, such
            that all <term>StringInclude</term>s are within that window and only
            those <term>StringExclude</term>s are retained, that also lie within
            that window. </p>
            
            <p>In the general case, the semantics is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTWindow(
      $matchOptions as element(matchOptions, 
                               fts:FTMatchOptions),
      $type as fts:DistanceType,
      $size as xs:integer,
      $allMatches as element(allMatches, fts:AllMatches),
      ) as element(allMatches, fts:AllMatches) {
  if ($type eq "word") then
    fts:ApplyFTWordWindow($matchOptions, 
                          $allMatches, 
                          $size)
  else if ($type eq "sentence") then 
    fts:ApplyFTSentenceWindow($matchOptions, 
                              $allMatches, 
                              $size)
  else
    fts:ApplyFTParagraphWindow($matchOptions, 
                               $allMatches, 
                               $size)
}
</eg>
            
            <p>As an example, consider the <term>FTWindow</term> selection
            <code>("Ford Mustang" &amp;&amp;
            "excellent") window 10 words</code> over the
            <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> sample document</loc>.
            The six <term>Match</term>es of the source <term>AllMatches</term> for
            <code>("Ford Mustang" &amp;&amp;
            "excellent")</code> are given below:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTWindowEx1.jpg" alt="FTWindow AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTWindowEx2.jpg" alt="FTWindow AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTWindowEx3.jpg" alt="FTWindow AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTWindowEx4.jpg" alt="FTWindow AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTWindowEx5.jpg" alt="FTWindow AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTWindowEx6.jpg" alt="FTWindow AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                     
            <p>The result for the above <term>FTWindow</term> selection will
            consist of only the first, the fifth, and the sixth
            <term>Match</term>es because their respective window sizes are 5, 4,
            and 9.</p>
            
        </div4>
        
        
        
        <!-- *************************************************************
             *                            FTTimes                        *
             ************************************************************* -->
        <div4 role="xquery">
            <head>FTTimes</head>
            
            <p>The parameters of the <function>ApplyFTTimes</function>
            function are the search context, the list of match
            options, one <term>AllMatches</term> a range specification, and
            parameter corresponding to the result of the nested
            <term>FTSelection</term>. The search context and the match
            options stack are not used in this case. </p>
            
            <p>The function definitions, depending the range
            specification <term>FTRange</term> limiting the number of
            occurrences, follow.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:FormCombinations($sms, $times) {
  if (fn:count($sms) lt $times) then ()
  else  if (fn:count($sms) eq $times) then 
      &lt;match&gt; {$sms/*} &lt;/match&gt;
  else 
      {
       fts:FormCombination(fn:subsequence($sms, 2), $times)
       &lt;match&gt;
         {$sms[1]/*}
         {fts:FormCombinations(fn:subsequence($sms, 2),
                               $times-1)/*}
       &lt;/match&gt;
      }
  }

declare function fts::FormRange($sms, $l, $u, $stokenNum) {
  let $lower_match := &lt;allMatches stokenNum="{$stokenNum}"&gt;
                        {fts:FormCombinations($sms, $l) }   
                      &lt;/allMatches&gt;
  return if ($l &gt; $u) then ()
         else fts:ApplyFTAnd(&lt;allMatches stokenNum="{$stokenNum}"&gt;
                            {fts:FormCombinations($sms, $l)}
                             &lt;/allMatches&gt;,
                             fts::ApplyFTUnaryNot(
                               &lt;allMatches&gt;
                               {fts:FormCombinations($sms, 
                                                     $u+1)}
                               &lt;/allMatches&gt;)
                            )
  }
            </eg>
            
            <p>We now define the semantics for the case <code>exactly 
            N occurrences</code>:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTTimesExactly(
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  fts:FormRange($allMatches/match, $n, $n, $allMatches/@stokenNum)      
}
</eg>
            
            <p>We next define the semantics for the case <code>at least 
            N occurrences</code>:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTTimesAtLeast(
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches stokenNum="{$allMatches/@stokenNum}"&gt; 
    {fts:formCombinations($allMatches/match, $n)} 
  &lt;/allMatches&gt;       
}
</eg>
            
            <p>We next define the semantics for the case <code>at most 
            N occurrences</code>:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTTimesAtMost(
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  fts:formRange($allMatches/match, 0, $n, $allMatches/@stokenNum)
}
</eg>
            
            <p>Finally, we define the semantics for the case <code>from M to 
            N occurrences</code>:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTTimesFromTo(
      $allMatches as element(allMatches, fts:AllMatches),
      $m as xs:integer,
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  fts:formRange($allMatches/match, $m, $n, $allMatches/@stokenNum)  
}
</eg>
            
            <p>The intuition is as follows. The way to ensure that
            there are at least <term>N</term> different matches of an
            <term>FTSelection</term> is to ensure that at least <term>N</term> of
            its <term>Match</term>es occur simultaneously. This is similar to
            forming their conjunction: combine <term>N</term> distinct
            <term>Match</term>es into one simple match. Therefore, the full match
            for the selection condition involving the range specifier
            <code>at least N </code> is to form all possible
            combinations of <term>N</term> simple matches of the
            operand and form one simple match for each combination
            negating the rest of the simple matches. This operations
            is performed in the function <function>
            fts:FormCombinations</function>.</p>
            
            <p>In the case of the range [<term>l</term>,
            <term>u</term>], it is treated as the condition <code>at
            least l and not at least u + 1</code>. This transformation
            is performed in the function
            <function>fts:FormRange</function>.</p>
            
            <p>The semantics in the general case is given by:</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTTimes(
      $range as element(range, fts:FTRangeSpec),
      $allMatches as element(allMatches, fts:AllMatches),
      ) as element(allMatches, fts:AllMatches) {
  if ($range/@type eq "exactly") then
    fts:ApplyFTTimesExactly($allMatches, $range/@n)
  else if ($range/@type eq "at least") then 
    fts:ApplyFTTimesAtLeast($allMatches, $range/@n)
  else if ($range/@type eq "at most") then
    fts:ApplyFTTimesAtMost($allMatches, $range/@n)
  else fts:ApplyFTTimesFromTo($allMatches, 
                              $range/@m, 
                              $range/@n)
}
</eg>
            
            <p>As an example, consider the <term>FTTimes</term> selection
            <code>"Mustang" at least 2 occurrences</code>
            over the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">sample
            document</loc>. The source <term>AllMatches</term> of the <term>FTWords</term>
            selection <code>"Mustang"</code> is:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTTimesEx1.jpg" alt="FTTimes input AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                     
            <p>The result will consist of all couples of <term>Match</term>es
            from above:</p>
            
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/FTTimesEx2.jpg" alt="FTTimes result AllMatches" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
                     
        </div4>
    </div3>

    
    
    
    <!-- *************************************************************
         ***                  Match Options Semantics              ***
         ************************************************************* -->
    <div3 role="xquery" id="FTMatchOptionsSec">
        <head>Match Options Semantics</head>
        <div4 role="xquery">
            <head>Types</head>
            <p>We take a similar approach to the one used for defining 
            the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#FTSelectionsSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">semantics of 
            FTSelections.</loc>. We will use XQuery functions to 
            define the semantics of <term>FTMatchOption</term>s. These functions 
            operate on an XML representation of the <term>FTMatchOption</term>s. 
            The representation closely follows the 
            <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftmatchoptions" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">syntax</loc>. As in the case of the
	    XML representation of <term>FTSelection</term>s, the XML representation of
	    <term>FTMatchOption</term>s is essentially an AST. Each <term>FTMatchOption</term> is 
	    represented by an XML element. Additional characteristics of the
	    option are generally represented as attributes.
	    The schema is given below.</p>
            
            <eg xml:space="preserve">
&lt;xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified" 
    attributeFormDefault="unqualified"&gt;

  &lt;xs:complexType name="FTMatchOptions"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="matchOption" 
                  type="fts:FTMatchOption"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
  
  &lt;xs:complexType name="FTMatchOption"&gt; 
    &lt;xs:choice&gt; 
     &lt;xs:element name="case" 
                 type="fts:FTCaseOption" /&gt;
     &lt;xs:element name="diacritics" 
                 type="fts:FTDiacriticsOption" /&gt;
     &lt;xs:element name="thesaurus" 
                 type="fts:FTThesaurusOption" /&gt;
     &lt;xs:element name="stem" 
                 type="fts:FTStemOption" /&gt;
     &lt;xs:element name="wildcard" 
                 type="fts:FTWildCardOption" /&gt;
     &lt;xs:element name="language" 
                 type="fts:FTLanguageOption" /&gt;
     &lt;xs:element name="stopWord" 
                 type="fts:FTStopwordOption" /&gt; 
    &lt;/xs:choice&gt;
  &lt;/xs:complexType&gt; 
 
 &lt;xs:complexType name="FTCaseOption"&gt;
   &lt;xs:attribute name="caseIndicator"&gt;
      &lt;xs:simpleType&gt;
        &lt;xs:restriction base="xs:string"&gt;
          &lt;xs:enumeration value="insensitive"/&gt;
          &lt;xs:enumeration value="sensitive"/&gt;
          &lt;xs:enumeration value="lowercase"/&gt;
          &lt;xs:enumeration value="uppercase"/&gt;
        &lt;/xs:restriction&gt;
      &lt;/xs:simpleType&gt;
    &lt;/xs:attribute&gt;
    &lt;xs:attribute name="caseLanguage" type="xs:string"/&gt;
  &lt;/xs:complexType&gt;

  &lt;xs:complexType name="FTDiacriticsOption"&gt;
    &lt;xs:attribute name="diacriticsIndicator"&gt;
      &lt;xs:simpleType&gt;
        &lt;xs:restriction base="xs:string"&gt;
          &lt;xs:enumeration value="insensitive"/&gt;
          &lt;xs:enumeration value="sensitive"/&gt;
          &lt;xs:enumeration value="with"/&gt;
          &lt;xs:enumeration value="without"/&gt;
        &lt;/xs:restriction&gt;
      &lt;/xs:simpleType&gt;
    &lt;/xs:attribute&gt;
    &lt;xs:attribute name="language" type="xs:string"/&gt;
  &lt;/xs:complexType&gt;
           
  &lt;xs:complexType name="FTThesaurusOption"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="thesaurusName" type="xs:string" 
                  minOccurs="0" maxOccurs="1"/&gt;
      &lt;xs:element name="relationship" type="xs:string" 
                  minOccurs="0" maxOccurs="1"/&gt;
      &lt;xs:element name="range" type="fts:FTRangeSpec" 
                  minOccurs="0" maxOccurs="1"/&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="thesaurusIndicator"&gt;
      &lt;xs:simpleType&gt;
        &lt;xs:restriction base="xs:string"&gt;
          &lt;xs:enumeration value="with"/&gt;
          &lt;xs:enumeration value="without"/&gt;
        &lt;/xs:restriction&gt;
      &lt;/xs:simpleType&gt;
    &lt;/xs:attribute&gt;
    &lt;xs:attribute name="language" type="xs:string"/&gt;
  &lt;/xs:complexType&gt;
 
  &lt;xs:complexType name="FTStemOption"&gt;
    &lt;xs:attribute name="stemIndicator"&gt;
      &lt;xs:simpleType&gt;
        &lt;xs:restriction base="xs:string"&gt;
          &lt;xs:enumeration value="with"/&gt;
          &lt;xs:enumeration value="without"/&gt;
        &lt;/xs:restriction&gt;
      &lt;/xs:simpleType&gt;
    &lt;/xs:attribute&gt;
    &lt;xs:attribute name="language" type="xs:string"/&gt;
  &lt;/xs:complexType&gt;
 
  &lt;xs:complexType name="FTWildCardOption"&gt;
    &lt;xs:attribute name="wildcardIndicator"&gt;
      &lt;xs:simpleType&gt;
        &lt;xs:restriction base="xs:string"&gt;
          &lt;xs:enumeration value="with"/&gt;
          &lt;xs:enumeration value="without"/&gt;
        &lt;/xs:restriction&gt;
      &lt;/xs:simpleType&gt;
    &lt;/xs:attribute&gt;
    &lt;xs:attribute name="language" type="xs:string"/&gt;
  &lt;/xs:complexType&gt;
 
  &lt;xs:complexType name="FTLanguageOption"&gt;
    &lt;xs:attribute name="languageName" type="xs:string"/&gt;
  &lt;/xs:complexType&gt;

  &lt;xs:complexType name="FTStopwordOption"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:choice&gt;
        &lt;xs:element name="default-stopwords"&gt;
            &lt;xs:complexType /&gt;
        &lt;/xs:element&gt;
        &lt;xs:element name="stop-word" type="xs:string" /&gt;
        &lt;xs:element name="uri" type="xs:anyURI" /&gt;
      &lt;/xs:choice&gt;
      &lt;xs:element name="oper" minOccurs="0" maxOccurs="unbounded"&gt;
        &lt;xs:choice&gt;
            &lt;xs:element name="stop-word" type="xs:string" /&gt;
            &lt;xs:element name="uri" type="xs:anyURI" /&gt;
        &lt;/xs:choice&gt;
        &lt;xs:attribute name="type"&gt;
          &lt;xs:simpleType&gt;
            &lt;xs:restriction base="xs:string"&gt;
              &lt;xs:enumeration value="union"/&gt;
              &lt;xs:enumeration value="except"/&gt;
            &lt;/xs:restriction&gt;
          &lt;/xs:simpleType&gt;
        &lt;/xs:attribute&gt;
      &lt;/xs:element&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
 
&lt;/xs:schema&gt;            
</eg>

    <p>In addition, we need the explicit representation of the concept of a 
    phrase.  We need this representation to 
    support thesauri lookups. Each lookup produces a sequence of such
    phrases. Each phrase is one possible 
    alternative for the search string.
    </p>
            <eg xml:space="preserve">
&lt;xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified" 
    attributeFormDefault="unqualified"&gt;
 
  &lt;xs:complexType name="TokenPhrase"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="token" type="xs:string"  
                  minOccurs="1" maxOccurs="unbounded"/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
&lt;/xs:schema&gt;            
</eg>
        </div4>
        
        <div4 role="xquery">
            <head>High-Level Semantics</head>
            
            <p>The section on the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#FTSelectionsSec" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">semantics
            of FTSelections</loc> focused on the case if no 
            <term>FTMatchOption</term>s are present in the language. Next, we
            describe how this model is extended to support 
            <term>FTMatchOption</term>s.</p> 
            
            <p>The extension is achieved by (a)modifying the existing 
            semantic functions of <term>FTSelection</term>s and (b)adding 
            additional semantic functions that are specific to the
            <term>FTMatchOption</term>s.</p>
            
            <p>With regards to point (a), the semantics of most the
            <term>FTSelection</term>s remains unchanged. The modifications are
            to the method for matching search tokens. The changes in
            point (b) are more significant and will be discussed 
            later.</p>

            
            <p>We start with the changes pertaining to (a). These
            changes are in the semantics of <term>FTWords</term> because it
            is the most influenced by the <term>FTMatchOption</term>s. Under the
            extended semantics, the search tokens are modified
            (<emph>search token expansion</emph>) depending on the applied
            <term>FTMatchOption</term>s. For example, in the presence of
            <term>FTThesaurusOption</term> search tokens may be replaced with
            related tokens based on a thesaurus lookup.</p>

            <eg xml:space="preserve">

declare function fts:applySingleSearchToken(
      $searchContext as node(), 
      $matchOptions as fts:FTMatchOptions,  
      $searchToken as fts:TokenInfo, 
      $queryPos as xs:integer) 
      as element(allMatches, fts:AllMatches) 
{  
   let $withDiacriticsOption :=
       $matchOptions[(fn:local-name(.) eq "diacritics") and
                     (./@type eq "with")][1]
   return 
        if ($withDiacriticsOption) then
              let $newOption1 := &lt;diacritics type="insensitive" /&gt;
              let $newOption2 := &lt;diacritics type="without" /&gt;
              let $lhs := fts:applySingleSearchToken(
                                    $searchContext,
                                    ($newOption1, $matchOptions),
                                    $searchToken,
                                    $queryPos)
              let $rhs := fts:applySingleSearchToken(
                                    $searchContext,
                                    ($newOption2, $matchOptions),
                                    $searchToken,
                                    $queryPos)
              return fts:ApplyMildNot($lhs, $rhs)
        else
           let $thesaurusOption :=
               $matchOptions[(fn:local-name(.) eq "thesaurus") and
                             (./@type eq "with")][1]
           return
           if ($thesaurusOption) then
                let $noThesaurusOption := (&lt;theasurus 
                                           thesaurusIndicator="without" /&gt;,
                                           $matchOptions)
                let $lookupRes := fts:applyThesaurusOption(
                                                $thesaurusOption,
                                                $searchStrings)            
               return fts:ApplyPhraseAlternatives($searchContext,
                                                  $noThesaurusOptions,
                                                  $lookupRes,
                                                  $queryPos)
          else
          &lt;allMatches stokenNum="{$queryPos}"&gt; 
            {let $searchTokens :=
               if ($matchOptions//wildcard) then
                 fts:applyWildCardOption($searchContext,
                                         $matchOptions,
                                         $searchToken)
               else
                 $searchToken
             let $effectiveOptions := $matchOptions except 
                                      $matchOptions[self::wildcard]
             let $token_pos := fts:matchStr($searchContext,
                                            $effectiveOptions, 
                                            $searchTokens) 
             for $pos in $token_pos 
              return  
                &lt;match&gt;  
                 &lt;stringInclude queryPos="{$queryPos}" 
                              queryString="{$searchToken/@word}" &gt; 
                   &lt;tokenInfo&gt;{$pos}&lt;/tokenInfo&gt; 
                 &lt;/stringInclude&gt; 
               &lt;/match&gt;} 
           &lt;/allMatches&gt; 
};

declare function fts:ApplyPhraseAlternatives(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchPhrases as fts:TokenPhrase*,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
 if (fn:count($searchPhrases) eq 0) 
 then &lt;allMatches stokenNum="0" /&gt;
 else let $firstSearchPhrase := $searchPhrase[1]
      let $restSearchPhrases := fn:subsequence($searchPhrases, 2)
      let $firstAllMatches := 
        fts:ApplyFTWordsPhrase($searchContext,
                              $matchOptions,
                              $firstSearchPhrase/word,
                              $queryPos)
      let $newQueryPos :=  fn:max($firstAllMatches//@queyrPos) + 1
      let $restAllMatches :=
        fts:ApplyPhraseAlternatives($searchContext,
                                    $matchOptions,
                                    $restSearchPhrases,
                                    $newQueryPos)
      return fts:ApplyFTOr($firstAllMatches, $resAllMatches)
};
</eg>

    <p>There are several major differences to the semantics of
    the single-token search as described in the previous section. All
    are related to processing match options. Three <term>FTMatchOption</term>s are
    processed differently than the rest of the <term>FTMatchOption</term>s. The
    <term>FTDiacriticsOption</term> option with type "with" is processed as though
    the query is <code>$searchToken/@word diacratics insensitive
    mildnot $searchToken/@word without diacritics</code>. Intuitively,
    the desired <term>Match</term>es are those that contain any version of the
    search token except the one without any diacritics. The reason for
    this seemingly unnatural semantics is to avoid having to guess
    which letters should be replaced with their diacritics equivalent.
    </p>
    <p>The second <term>FTMatchOption</term> that is processed differently is
    <term>FTThesaurusOption</term>. The reason is that its semantic cannot
    be represented simply in terms of search token expansion. Since
    the result of a thesaurus lookup can be a sequence of alternatives, 
    we need a higher level processing. Intuitively, all returned 
    alternatives are connected in a disjunction using
    the <code>fts:ApplyPhraseAlternatives</code>. The latter function
    is almost identical to <code>fts:ApplyFTWordsAny</code> but
    takes into consideration the specific representation of
    the search tokens in <code>$searchPhrases</code>. It should be
    noted that the matching of the alternatives is performed with
    <term>FTThesaurusOption</term> turned off. Thus, we avoid double expansions,
    i.e. expanstions of an already expanded token.</p>
    
    <p>The last <term>FTMatchOption</term> that is processed differently is 
    <term>FTWildCardOption</term>. It commutes with all other options and therefore
    it is possible to ignore its position within the <term>FTMatchOption</term>s 
    stack. </p>
    
    <p>All other <term>FTMatchOption</term>s are processed in the 
    <code>MatchStr</code> function.</p>
    
<eg role="parse-text" xml:space="preserve">
declare function fts:matchStr(
      $searchContext as node(), 
      $matchOptionss as fts:FTMatchOptions,
      $searchToken as fts:TokenInfo)
      as element(tokenInfo, fts:TokenInfo)*
{
   let $nonexpOptions := $matchOptions[self::language or
                                       self::ignore]
   let $expOptions := $matchOptions except $nonexpOptions
   let $searchTokens := applyMatchOptions($matchOptions,
                                         $searchTokens),
                                         $searchTokens
   
   return getTokenInfo($searchContext, 
                       $nonexpOptions, 
                       $searchToken)
}
</eg>

<p>Intuitively, the above function rewrites the search tokens based on
the applied <term>FTMatchOption</term>s and obtains the resulting sequence
of <term>TokenInfo</term>s that match the search tokens. <term>FTThesaurusOption</term> 
is treated differently than the others. The reason we want to avoid
repeated theasurus expansion if it has already been applied to the 
search tokens. In this case, all <term>FTThesaurusOption</term>s are removed. </p>

<p>Each other <term>FTMatchOption</term>s 
transforms the search tokens by means of the <code>
fts:applyMatchOption</code> function. Its 
structure is very similar to the one used for the <code>fts:evaluate
</code> function. It inspects the supplied <term>FTMatchOption</term>s and applies
them using per-<term>FTMatchOption</term> functions much like the 
per-<term>FTSelection</term> functions. These will be discussed later.</p>

<p>One last change to search token matching is with regards to
matching phrases. The change allows multi-token thesauri lookups. I.e.,
it allows that entire search phrases be modified using a thesaurus.</p>

<eg role="parse-text" xml:space="preserve">
declare function fts:ApplyFTWordsPhrase(
         $searchContext as node(), 
         $matchOptions as fts:FTMatchOptions, 
         $searchStrings as xs:string*,
         $queryPos as xs:integer) 
         as element(allMatches, fts:AllMatches) 
{
   let $thesaurusOption := $matchOptions[fn:local-name(.) eq "thesaurus"][1]
   return if ($thesaurusOption and $thesaurusOption/@type eq "with") then
       let $noThesaurusOptions := $matchOptions[fn:local-name(.) ne "thesaurus"]
       let $lookupRes := fts:applyThesaurusOption($thesaurusOption,
                                                  $searchStrings)
       return fts:ApplyPhraseAlternatives($searchContext,
                                          $noThesaurusOptions,
                                          $lookupRes,
                                          $queryPos)
   else
        let $conj := fts:ApplyFTWordsAllWord($searchContext,
                                             $matchOptions,
                                             $searchStrings,
                                             $queryPos)
        let $ordered := fts:ApplyFTOrder($conj)
        let $distance1 := 
            fts:ApplyFTDistance($matchOptions,
                                $ordered,
                                &lt;fts:range type="exactly" n="0"&gt;)
        return $distance1 
};
</eg>

    <p>The difference in the case of the <code>fts:ApplyFTWordsPhrase
    </code> fucntion is that an explicit check for the presence of
    a <term>FTThesaurusOption</term> is done. This allows that
    phrase lookups be done in the thesaurus. If an <term>FTThesaurusOption</term>,
    it is processed as in <code>fts:ApplySingleSearchToken</code>.
    </p>

    <p>Now, we move to second type of modifications to the semantics,
    namely the functions that implement the semantics of the 
    <term>FTMatchOption</term>. </p>
    
<eg role="parse-text" xml:space="preserve">
declare function fts:applyMatchOption(
      $matchOptions as fts:FTMatchOption*,  
      $searchTokens as fts:TokenInfo*
      ) as element(tokenInfo, fts:TokenInfo)*
{
   if ($matchOptions) then
       let $firstOption := $matchOptions[1]
       let $firstOptionType := fn:local-name($firstOption)
       let $restOptions := $matchOptions[fn:local-name(.) ne $firstOptionType]
       let $applyFirst := fts:applyMatchOption($firstOption, $searchTokens)
       return fts:applyMatchOptions($restOptions, $$applyFirst)
   else $searchTokens
};

declare function fts:applyMatchOption(
      $matchOption as fts:FTMatchOption,  
      $searchTokens as fts:TokenInfo*
      ) as element(tokenInfo, fts:TokenInfo)*
{
   if (fn:local-name($matchOption) eq "stopWord") then
         fts::applyStopWordOption($matchOptions, $searchTokens)
   else if (fn:local-name($matchOption) eq "case")
      return applyCaseOption($matchOption,$searchTokens)
   else if (fn:local-name($matchOption) eq "diacritics")
       return fts:applyDiacriticsOption($matchOption, $searchTokens)
   else if (fn:local-name($matchOption) eq "stem")
       return fts:applyStemOption($matchOption, $searchTokens)
};
</eg>

    <p>Intuitively, the <code>fts:ApplyMatchOptions</code> function
    expands the search tokens by the consequtive appliaction of
    each specified <term>FTMatchOption</term>. Once a <term>FTMatchOption</term> of a particular
    type has been applied. All other options of the same type are 
    ignored since the former overrides them. </p>
    
    <p>The application of each <term>FTMatchOption</term> is performed by the
    dispatcher function <code>fts:ApplyMatchOption</code>, which 
    invokes the repective function implementing the semantics of
    the option.</p>
    
    <p>The semantic functions for earch option are described in 
    subsequent sections.</p>
        
        </div4>
        
        
        <div4 role="xquery" id="options-sem-functions">
            <head>Formal Semantics Functions</head>
            
            <p>Before describing the functions implementing the 
            semantics of each <term>FTMatchOption</term>, we will present
            a list of formal semantics functions that must be 
            provided by each XQuery 1.0 and XPath 2.0 Full-Text
            implementation.</p>
            <eg xml:space="preserve">
function fts:lowerCase($token as fts:TokenInfo,
                       $caseLanguage as xs:string) 
                       as fts:TokenInfo
            </eg>
            <eg xml:space="preserve">
function fts:upperCase($token as fts:TokenInfo,
                       $caseLanguage as xs:string) 
                       as fts:TokenInfo
            </eg>
            <eg xml:space="preserve">
function fts:insensitiveCase($token as fts:TokenInfo,
                             $caseLanguage as xs:string) 
                             as fts:TokenInfo
            </eg>
            
            <p>Intuitively, the three functions above convert the
            token in a <term>TokenInfo</term> object to lower-case, upper-case,
            or case-insensitive form.</p>
            
            <eg xml:space="preserve">
function fts:removeDiacritics(
             $token as fts:TokenInfo,
             $diacriticsLanguage as xs:string) 
             as fts:TokenInfo
            </eg>
            <eg xml:space="preserve">
function fts:insensitiveDiacritics(
             $token as fts:TokenInfo,
             $diacriticsLanguage as xs:string) 
             as fts:TokenInfo
            </eg>
            
            <p>Intuitively, the two functions above convert the
            token in a <term>TokenInfo</term> object to a form without diacritics
            or to a diacritics-insensitive form.</p>
            
            <eg xml:space="preserve">
function fts:lookupThesaurus($tokens as fts:TokenInfo*,
                             $thesaurusName as xs:string, 
                             $thesaurusLanguage as xs:string,
                             $relationship as xs:string,
                             $range as fts:FTRanceSpec?) 
                             as element(tokenPhrase, 
                                        fts:TokenPhrase)*
            </eg>
            <p>The above function finds all words related to 
            <code>$tokens</code>
            in the thesaurus <code>$thesaurusName</code> for the language
            <code>$thesaurusLanguage</code> using the relationship 
            <code>$relationship</code> within the optional number of levels
            <code>$range</code>. If <code>$tokens</code> consists of 
            more than one <term>TokenInfo</term>s, it is regarded as a phrase.
            </p>
            
           <p>The function returns a sequence of expansion
           alternatives. Each alternative is regarded as a new search
           phrase and is represented as a tokenized phrase. All the
           alternatives are treated as though they are connected with
           a disjunction (<term>FTOr</term>). </p>
          
            <eg xml:space="preserve">
function fts:stemmedForm($word as fts:TokenInfo,
                         $stemLanguage as xs:string) 
                         as fts:TokenInfo
            </eg>
            
            <p>The above function converts the
            token in a <term>TokenInfo</term> object to a form that represents
            its stem.</p>
            
            <eg xml:space="preserve">
function fts:wildcardForm($word as fts:TokenInfo,
                       $wildcardLanguage as xs:string) 
                       as fts:TokenInfo*
            </eg>
            
            <p>The above function converts the
            token in a <term>TokenInfo</term> object to a sequence of forms that
            can be used by the tokenizer to match document tokens.</p>
        
        </div4>
        
        <div4 role="xquery">
            <head>FTCaseOption</head>
            <eg xml:space="preserve">
declare function 
  fts:applyCaseOption($matchOption as fts:FTMatchOption,  
                      $searchTokens as fts:TokenInfo*) 
                      as fts:TokenInfo*
{
    let $searchToken := $searchTokens[1]
    let $nextTokens := $searchTokens[position() ge 2]

    let $returnedTokens := 
        if ($matchOption/@caseIndicator = "lowercase") then
           (fts:lowerCase($searchToken/@word, $matchOption/@language),
            applyCaseOption($matchOption, $nextTokens))
        else
        if ($matchOption/@caseIndicator = "uppercase") then 
            (fts:upperCase($searchToken, $matchOption/@language),
             applyCaseOption($matchOption, $nextTokens))
        else
        if ($matchOption/@caseIndicator = "insensitive") then
            (insensitiveCase($searchToken, $matchOption/@language),
             applyCaseOption($matchOption, $nextTokens))
        else $searchTokens
   return $returnedTokens
}
            </eg>
        
        </div4>
        
        <div4 role="xquery">
            <head>FTDiacriticsOption</head>
            
            <eg xml:space="preserve">
declare function fts:applyDiacriticsOption(
                     $matchOption as fts:FTMatchOption,  
                     $searchTokens as fts:TokenInfo*) 
                     as fts:TokenInfo*
{
    let $searchToken := $searchTokens[1]
    let $nextTokens := $searchTokens[position() ge 2]
    let $indicator := $matchOption/@diacriticsIndicator
    let $returnedTokens := 
        if ($indicator eq "with") then
            (addDiacritics($searchToken, $matchOption/@language),
             applyDiacriticsOption($matchOption, $nextTokens))
        else if ($indicator eq "without") then
            (removeDiacritics($searchToken, $matchOption/@language),
             applyDiacriticsOption($matchOption, $nextTokens))
        else if ($indicator eq "insensitive") then
            (insensitiveDiacritics($searchToken, $matchOption/@language),
              applyDiacriticsOption($matchOption, $nextTokens))
        else (: $indicator eq "sensitive" :)
            $searchTokens
      return $returnedTokens
}
            </eg>
        
        </div4>        
        
        <div4 role="xquery">
            <head>FTStemOption</head>
            <eg xml:space="preserve">
declare function 
  fts:applyStemOption($matchOption as fts:FTMatchOption,  
                      $searchTokens as fts:TokenInfo*) 
                      as fts:TokenInfo*
{
    if ($matchOption/@stemIndicator = "with") then
      let $searchToken := $searchTokens[1]
      let $nextTokens := $searchTokens[position() ge 2]
      return 
          (stemmedForm($searchToken, $matchOption/@language),
           applyStemOption($matchOption, $nextTokens)
    else if ($matchOption/@stemIndicator = "without") then
           $returnedTokens
         else ()
}
            </eg>
        </div4>
        
        <div4 role="xquery">
            <head>FTStopWordOption</head>
            <p>Stop-Words interact with FTDistanceSelection and 
            FTWindowSelection.</p>
            <eg xml:space="preserve">

declare function 
  fts:applyStopwordOption($matchOption as fts:FTMatchOption,  
                          $searchTokens as fts:TokenInfo*) 
                           as fts:TokenInfo*
{
    let $rootElem := fn:local-name($matchOption/element()[1])
    let $rootWords := $matchOption/element()[1]/text()
    let $swords := if ($rootElem eq "stop-word") then
                      $rootWords
                   else
                      fts:resolveStopwordsUri($rootWords)
    let $tokenizedSwords := for $sw in $swords
                            return &lt;tokenInfo word="{$sw}" 
                                              pos="0"
                                              sentence="0"
                                              para="0" /&gt;
    let $restOpers := $matchOption/element()[position() ge 2]
    let $effectiveStopwords := fts:calcStopwords($tokenizedSwords, 
                                                 $resOpers)
    return fts:remStopwords($searchTokens, $stopWords)
};

declare function fts:addStopwords($stopWords as fts:TokenInfo*, 
                                  $newStopwords as fts:TokenInfo*)
                                  as fts:TokenInfo*
{
    if ($newStopwords) then
        let $firstStopword := $newStopwords[1]
        let $restStopwords := $newStopwords[position() ge 2]
        let $temp :=
            if ($stopWords[@word eq $firstStopword/@word]) then $stopWords
            else ($stopWords, $firstStopword)
        return addStopwords($temp, $restStopwords)
    else $stopWords
};
            
declare function fts:remStopwords($stopWords as fts:TokenInfo*, 
                                  $remStopwords as fts:TokenInfo*)
                                  as fts:TokenInfo*
{
    if ($newStopwords) then
        let $firstStopword := $newStopwords[1]
        let $restStopwords := $newStopwords[position() ge 2]
        let $temp :=
            if ($stopWords[@word eq $firstStopword/@word]) then 
                $stopWords[@word ne $firstStopword]
            else $stopWords
        return remStopwords($temp, $restStopwords)
    else $stopWords
};

declare function fts:calcStopwords($stopWords as fts:TokenInfo*,
                                   $opers)
                                   as fts:TokenInfo*
{
    if ($opers) then
        let $firstOper := $opers[1]
        let $restOpers := $opers[position() ge 2]
        let $operType := $firstOper/@type
        let $operElem := fn:local-name($firstOper/element())
        let $operWords := $firstOper/element()/text()
        let $swords := if ($operElem eq "stop-word") then
                          $operWords
                       else
                          fts:resolveStopwordsUri($operWords)
        return
            if ($operType eq "union") then
                  calcStopwords(fts:addStopword($stopWords, $swords,
                                $restOpers)
            else
                  calcStopwords(fts:remStopword($stopWords, $swords),
                                $restOpers)
    else $stopWords
};
            </eg>
            <p>Intuitively, the semantics of the option is as follows. First, 
            the set of effective stop words set is computed using the
            <code>fts:calcStopwords</code> function. The function applies the
            general set operations on the set of stop words. The function uses
            the function <code>fts:resoleStopwordsUri</code> to resolve any URI
            to a sequence of strings. Then, the effective stop words are
            removed from the set of search tokens. </p>
        </div4>
        
        <div4 role="xquery">
            <head>FTLanguageOption</head>
        </div4>
        
        <div4 role="xquery">
            <head>FTWildCardOption</head>
            <eg xml:space="preserve">
declare function 
  fts:applyWildCardOption($matchOption as fts:FTMatchOption,  
                          $searchTokens as fts:TokenInfo*) 
                          as xs:TokenInfo*
{
    if ($matchOption/@wildcardIndicator = "with") {
      let $searchToken := $searchTokens[1]
      let $nextTokens := $searchTokens[position() ge 2]
      return 
           wildcardForm($searchToken,
                        $matchOption/@language),
                        applyWildCardOption($matchOption, $nextTokens)
    }
    else if ($matchOption/@wildcardIndicator eq "without") then
            $searchTokens
         else ()
};
            </eg>
        </div4>
        
<!--         <div4 role="xquery">
            <head>FTIgnoreOption</head>
            <p>The semantics of this match option is captured in phrase 
            matching,
FTDistance and FTWindow.</p>
        </div4>
 -->
       </div3>
    </div2>
    
    
    <div2 role="xquery" id="FullTextExprSec">
    <head>XQuery 1.0 and XPath 2.0 Full-Text and Scoring Expressions</head>
    
    
    <!-- *************************************************************
         ***                     FTContains                    ***
         ************************************************************* -->
    <div3 role="xquery" id="FTContainsSec">
        <head>FTContainsExpr</head>
        
        <p>We now present the formal semantics of the <term>FTContainsExpr</term>
        expression. It takes in (1) an search context consisting of a
        sequence of nodes (which is the result of a regular XQuery/XPath
        expression), and (2) <term>AllMatches</term> corresponding to an <term>FTSelection</term>, and
        returns a sequence of nodes. Since <term>FTContainsExpr</term> returns results in
        the XQuery data model (a sequence of nodes), it can be treated like
        regular XQuery expressions and can be fully composed with other XQuery
        expressions. In addition, since <term>FTContainsExpr</term> maps
        <term>AllMatches</term> to a sequence of nodes, it provides the "glue"
        and well-defined semantics for mapping from <term>AllMatches</term> to the XQuery
        data model.</p>
        
        <p>The formal semantics of <term>FTContainsExpr</term> is specified in terms 
        of an <emph>formal semantics functions</emph>. The functions have to comply with the
        prototype defined below. The semantics of <term>FTContainsExpr</term> will 
        be presented based on this function.</p>
        
        
        <!-- **********************************************************************
             *                    Semantics of FTContainsExpr                     *
             ********************************************************************** -->
        <div4>
            <head>Semantics of FTContainsExpr</head>
                        
            <p>Consider an <term>FTContainsExpr</term> expression of the form
            <code>EvaluationContext ftcontains FTSelection</code>,
            where <code>EvaluationContext</code> is an XQuery
            expression that returns a sequence of nodes, and
            <code>FTSelection</code> is an <term>FTSelection</term> that returns
            <term>AllMatches</term>. Intuitively, the <term>FTContainsExpr</term> returns
            true if and only if some node in the result of
            <code>EvaluationContext</code> satisfies the <term>AllMatches</term>
            returned by <code>FTSelection</code>.</p>
	    
	    <p>If the <term>FTContainsExpr</term> is of the form <code>EvaluationContext 
	    ftcontains FTSelection without content IgnoreExpr</code> for
	    some XQuery expression <code>IgnoreExpr</code>, then that
	    <term>FTContainsExpr</term> is evaluated as: </p>

            <eg role="parse-text" xml:space="preserve">
declare function reconstruct($n as node(), 
                             $ignore as node()*) as node()? {
   if (some $i in $ignore satisfies $n is $i) then ()
   else if ($n instance of element()) then
            let $nodeName := fn:node-name($n)
	    let $nodeContent := for $nn in $n/node()
                                return reconstruct($nn)
	    return element {$nodeName} {$nodeContent}
        else $n
}
	    
let $newEvalContext := 
   let $ignoreNodes := EvaluationContext/IgnoreExpr/text()
   return for $n in EvaluationContext
          return reconstruct($n, $ignoreNodes)
return$newEvalContext ftcontains FTSelection 
            </eg>
	    
	    <p>Intuitively, we rewrite <code>EvaluationContext</code> so it
	    does not include any text node children from nodes that should be
	    ignored.</p>
            
            <p>We now formally define the semantics of <term>FTContainsExpr</term>. The
            semantics is defined in terms of a regular XQuery function (without
            any XQuery 1.0 and XPath 2.0 Full-Text extensions). The XQuery function takes in three
            parameters: the first parameter is the sequence of nodes returned by
            <code>EvalationContext</code>; the second parameter is the XML node
            representation of <code>FTSelection</code>; the
            third parameter is the XML representation of the set of
            default values for each of the
            <term>FTMatchOption</term>s, as given by the static context. The XQuery
            function (by definition) returns true if and only if the corresponding
            <term>FTContainsExpr</term> returns true, and thus specifies the semantics of
            <term>FTContainsExpr</term>. Note that by using regular XQuery to specify the
            formal semantics, we avoid the need to introduce new formalism.
            We simply reuse the formal semantics of XQuery.</p>
            
            <eg role="parse-text" xml:space="preserve">
declare function FTContainsExpr(
                 $searchContext as node()*,
                 $ftSelection as fts:FTSelection,
                 $defOptions as fts:FTMatchOptions)
                 as xs:Boolean 
{ 
 return some $node in $searchContext
        satisfies 
          let $allMatches := fts:evaluate($ftSelection,
                                          $node,
                                          $defOptions,
                                          0)
          return some $match in $allMatches/match
                 satisfies 
                   fn:count($match/stringExclude) eq 0
}
            </eg>
            
            <p>Intuitively, the above function returns true if and only if the
            <term>AllMatches</term> that is the result of the application of the
            <term>FTSelection</term> for some node in the search context contains a
            <term>Match</term> with no <term>StringExclude</term>s. This means that there is a set of
            <term>TokenInfo</term>s in that node which satisfy the condition of the
            <term>FTSelection</term></p>
            
        </div4>
        
        
        
    <!-- ***************************************************
         ***                    Example                  ***
         *************************************************** -->
        <div4 role="xquery">
            <head>Example</head>
            
            <p>We will now show the evaluation of a more elaborate
            example of <term>FTContainsExpr</term>. We use the same <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#SampleTokenizedDoc" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> sample document</loc>. For
            convenience, we present it again here.</p>
            
            <eg role="parse-text" xml:space="preserve">
&lt;offers&gt;
    &lt;offer id="1000" price="10000"&gt;
        Ford(1) Mustang(2) 2000(3), 65K(4), excellent(5)
        condition(6), runs(7) great(8), AC(9), CC(10), 
        power(11) all(12)
    &lt;/offer&gt;
    &lt;offer id="1001" price="8000"&gt;
        Honda(13) Accord(14) 1999(15), 78K(16), A(17)/C(18),
        cruise(19) control(20), runs(21) and(22) looks(23)
        great(24), excellent(25) condition(26)
    &lt;/offer&gt;
    &lt;offer id="1005" price="5500"&gt;
        Ford(27) Mustang(28), 1995(29), 150K(30) highway(31)
        mileage(32), little(33)  rust(34), excellent(35) 
        condition(36)
    &lt;/offer&gt;
&lt;/offers&gt;
</eg>
            
            <p>Let the above document be assigned to <code>$doc</code>. 
            We will walk through the evaluation of the following
            <term>FTContainsExpr</term></p>
            
            <eg role="parse-text" xml:space="preserve">
    $doc ftcontains (
      (
       "mustang" &amp;&amp; (("great" || "excellent") 
       at least 2 occurrences)
      ) window 30 words
      &amp;&amp;
      ! "rust"
    ) same node
</eg>
                
            <p>We first evaluate the <term>FTSelection</term> to <term>AllMatches</term></p>
            
            <eg role="parse-text" xml:space="preserve">
    (
      (
       "mustang" &amp;&amp; (("great" || "excellent") 
       at least 2 occurrences)
      ) window 30 words
      &amp;&amp;
      ! "rust"
    ) same node
</eg>
                
            <p>Step 1: Evaluate the <term>FTWords</term>
                <code>"Mustang"</code>
            </p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample01.jpg" alt="Example, step 1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 2: Evaluate the <term>FTWords</term>
                <code>"great"</code>
            </p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample02.jpg" alt="Example, step 2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 3: Evaluate the <term>FTWords</term>
                <code>"excellent"</code>
            </p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample03.jpg" alt="Example, step 3" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 4 - Apply the <term>FTOr</term>
                <code>("great" || "excellent")</code>: form the union of the <term>Match</term>es</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample04.jpg" alt="Example, step 4" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 5 - Apply the <term>FTTimes</term>
                <code>("great" || "excellent") at least 2 occurrences</code>: form 2-tuples (couples) of <term>Match</term>es</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample05_1.jpg" alt="Example, step 5.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample05_1_2.jpg" alt="Example, step 5.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample05_2.jpg" alt="Example, step 5.2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 6 - Apply the <term>FTAnd</term>
                <code>"Mustang" 
                &amp;&amp; (("great" || "excellent") at least 2 
                occurrences)</code>: form the "Cartesian product" of <term>Match</term>es</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_1.jpg" alt="Example, step 6.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_1_2.jpg" alt="Example, step 6.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_2.jpg" alt="Example, step 6.2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_2_2.jpg" alt="Example, step 6.2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_3.jpg" alt="Example, step 6.3" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_3_2.jpg" alt="Example, step 6.3" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_4.jpg" alt="Example, step 6.4" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_4_2.jpg" alt="Example, step 6.4" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_5.jpg" alt="Example, step 6.5" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample06_5_2.jpg" alt="Example, step 6.5" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 7 - Apply the <term>FTWindow</term>
                <code>("Mustang" 
                &amp;&amp; (("great" || "excellent") 
                at least 2 occurrences)) window 30 words</code>: filter out <term>Match</term>es 
                for which the window is not less than or equal to 30</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample07_1.jpg" alt="Example, step 7.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample07_1_2.jpg" alt="Example, step 7.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample07_2.jpg" alt="Example, step 7.2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample07_2_2.jpg" alt="Example, step 7.2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 8 - Match <term>FTWords</term>
                <code>"rust"</code>
            </p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample08.jpg" alt="Example, step 8" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 9 - Apply the <term>FTUnaryNot</term>
                <code>! "rust"</code>: 
                transform the <code>stringInclude</code> into <code>stringExclude</code>
            </p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample09.jpg" alt="Example, step 9" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            <p>Step 10 - Apply the <term>FTAnd</term>
                <code>(("Mustang"
                &amp;&amp; (("great" || "excellent") at least 2 occurrences)) 
                window 30 words) &amp;&amp; ! "rust"</code>: form the "Cartesian 
                product" of the <term>Match</term>es</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample10_1.jpg" alt="Example, step 10.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><p/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample10_1_2.jpg" alt="Example, step 10.1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><p/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample10_2.jpg" alt="Example, step 10.2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><p/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample10_2_2.jpg" alt="Example, step 10.2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><p/>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample10_3.jpg" alt="Example, step 10.3" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><p/>
            <p>Step 11: Apply the final <term>FTScope</term>  filter out <term>
                Match</term>es whose <term>TokenInfo</term>s are not within the same node</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink" source="images/CompleteExample11.jpg" alt="Example, step 11" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
            
            <p>This is the final <term>AllMatches</term> from the evaluation of
            the <term>FTSelection</term>.</p>
            
            <p>The resulting <term>AllMatches</term> does not contain a <term>Match</term> 
            that does not contain a <term>StringExclude</term>. Therefore, the
            sample <term>FTContainsExpr</term> returns <code>false</code>.</p>
            
        </div4>
    
    </div3>
    


    <!-- **********************************************************
         ***                     Scoring                    ***
         *********************************************************** -->
        <div3 role="xquery" id="ScoreSec">
            <head>Scoring</head>
            
            <p>In this section, we discuss the semantics of the use of
               scoring variables in <code>for</code> and
               <code>let</code> clauses, or XPath 2.0 <code>for</code>
               expressions. 
               The semantics of these constructs cannot be expressed
               in terms of XQuery, because they
               requires the presence of second-order functions (i.e. functions
               that do not evaluate their argument(s) as regular XQuery 
               expression(s) but use them interpreted).</p>
            <p>Nevertheless, in the interest of the exposition, we will assume 
               that such functions are present. In particular, we assume that 
               there are two semantic second-order function
               <code>fts:score</code> and <code>fts:scoreSequence</code>
               that take one argument (an expression) and return the
               score value of this expression, respectively a sequence
               of score values, one for each item that the expression
               evaluates to. The scores must satisfy <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#tq-ext-score" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">scoring properties</loc>.</p>
            <p>A <code>for</code> clause involving a score variable:
<eg xml:space="preserve">
for $result score $score in Expr
...
</eg>
               is evaluated as
               though it is replaced with the set of clauses
<eg xml:space="preserve">
let $scoreSeq := fts:scoreSequence(Expr)
for $result at $i in Expr
let $score := $scoreSeq[$i]
...
</eg>
               Here, <code>$scoreSeq</code> and <code>$i</code> are
               new variables, not appearing elsewhere, and
               <code>fts:scoreSequence</code> is the 
               second-order function described in the previous paragraph.
            </p>
            <p>Similarly, a <code>let</code> clause involving a score variable:
<eg xml:space="preserve">
let $result score $score := Expr
...
</eg>
               is evaluated as
               though it is replaced with
<eg xml:space="preserve">
let $result := Expr
let $score := fts:score(Expr)
...
</eg>
            </p>
        </div3>
    </div2>
    
</div1>

	</body>
	<back id="id-appendices">
	
<div1 id="id-grammar">
		<head>EBNF for XQuery 1.0 Grammar with Full-Text
		extensions</head>

<p>The EBNF in this document and in this section is aligned with
the current XML Query 1.0 grammar (see <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/2005/WD-xquery-20050915/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/2005/WD-xquery-20050915/</loc>.</p>

		<scrap role="non-terminal-structure-expand" headstyle="show"><head/>
<prodrecap ref="BNF-Grammar-prods" role="BNF-Grammar-prods" at="../temp-full-text/temp-xquery-grammar.xml"/>
</scrap>

<div2><head>Terminal Symbols</head><scrap headstyle="show">
		    
		  <head/><prodrecap ref="DefinedLexemes" role="DefinedLexemes" at="../temp-full-text/temp-xquery-grammar.xml"/> 
		   
		</scrap>
<p>The following symbols are used only in the definition of
  terminal symbols; they are not terminal symbols in the
  grammar of <specref ref="id-grammar"/>.</p><scrap headstyle="show">
		    
		  <head/><prodrecap ref="LocalTerminalSymbols" at="../full-text/temp-full-text/temp-xquery-grammar.xml" role="LocalTerminalSymbols" id="LocalTerminalSymbols"/> 
		   
		</scrap>
</div2></div1>

	
<div1 id="id-xpath-grammar">
		<head>EBNF for XPath 2.0 Grammar with Full-Text
		extensions</head>

<p>The EBNF in this document and in this section is aligned with
the current XPath 2.0 grammar (see <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/2005/WD-xpath20-20050915/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/2005/WD-xpath20-20050915/</loc>.</p>

		<scrap role="non-terminal-structure-expand" headstyle="show"><head/>
<prodrecap ref="BNF-Grammar-prods" role="BNF-Grammar-prods" at="../temp-full-text/temp-xpath-grammar.xml"/>
</scrap>

<div2><head>Terminal Symbols</head><scrap headstyle="show">
		    
		  <head/><prodrecap ref="DefinedLexemes" role="DefinedLexemes" at="../temp-full-text/temp-xpath-grammar.xml"/> 
		   
		</scrap>
<p>The following symbols are used only in the definition of
  terminal symbols; they are not terminal symbols in the
  grammar of <specref ref="id-xpath-grammar"/>.</p><scrap headstyle="show">
		    
		  <head/><prodrecap ref="LocalTerminalSymbols" at="../full-text/temp-full-text/temp-xpath-grammar.xml" role="LocalTerminalSymbols" id="LocalTerminalSymbols-xpath"/> 
		   
		</scrap>
</div2></div1>

	<div1 id="References">
<head>References</head>
<div2 id="id-normative-references">
<head>Normative References</head>
<blist>
<bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xquery" key="XQuery 1.0: An XML Query Language" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>

<bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath20" key="XML Path Language (XPath) 2.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>

<bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath-functions" key="XQuery 1.0 and XPath 2.0 Functions and Operators" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>

<bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xqueryft-requirements" key="XQuery and XPath Full-Text Requirements" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"><emph><loc href="http://www.w3.org/TR/xquery-full-text-requirements/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XQuery
and XPath Full-Text Requirements</loc></emph>,
Stephen Buxton, Michael Rys, Editors. World Wide Web Consortium, 02 May 2003.
This version is http://www.w3.org/TR/2003/WD-xquery-full-text-requirements-20030502/.
The <loc href="http://www.w3.org/TR/xquery-full-text-requirements/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">latest version</loc>
is available at <loc href="http://www.w3.org/TR/xquery-full-text-requirements/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/xquery-full-text-requirements/</loc>.
</bibl>

<bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlquery-full-text-use-cases" key="XQuery 1.0 and XPath 2.0 Full-Text Use Cases" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>

<!--  <bibl id="xqueryft-usecases" key="XQuery 1.0 and XPath 2.0 Full-Text Use Cases"><emph><loc href="http://www.w3.org/TR/xmlquery-full-text-use-cases/">XQuery 1.0 and XPath 2.0 Full-Text Use Cases</loc></emph>, -->
<!--  Sihem Amer-Yahia, Pat Case, Editors. World Wide Web Consortium, 04 April 2005. -->
<!--  This version is http://www.w3.org/TR/2004/WD-xmlquery-full-text-use-cases-20040709/. The -->
<!--  <loc href="http://www.w3.org/TR/xmlquery-full-text-use-cases/">latest version</loc> is available at -->
<!--  <loc href="http://www.w3.org/TR/xmlquery-full-text-use-cases/">http://www.w3.org/TR/xmlquery-full-text-use-cases/.</loc> -->
<!--  </bibl> -->

</blist>
</div2>
<div2 id="id-non-normative-references">
<head>Non-normative References</head>
<blist>

<bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="iso-2788" key="ISO 2788" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
Documentation Guidelines for the Establishment and Development of
Monolingual Thesauri, Geneva: International Organization for
Standardization, 2nd edition, 1986.
</bibl>


<bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="sqlmm" key="SQL/MM" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> ISO/IEC 13249-2 Information technology
--- Database languages --- SQL Multimedia and Application Packages ---
Part 2: Full-Text. Geneva: International Organization for
Standardization, 2nd edition, 2003.
</bibl>


</blist>
</div2>
</div1>

	<div1 id="ft-issues">
	<head>Issues List</head>

<p> This section contains the current issues related to this document. </p>

<p>This list of issues is classified in clusters. Each cluster has a
unique name that reflects its topic. Each issue has a unique
number. Some issues are labelled VNext. The clusters are: 
       <olist>
	  <item>
	    <p>Cluster A: Scoring and Weighting</p>
          </item>
	  <item>
	    <p>Cluster B: IgnoreOption, Markup vs. Structure</p>
          </item>
	  <item>
	    <p>Cluster C: Wildcards, Regex, Match Anchoring</p>
          </item>
	  <item>
	    <p>Cluster D: Thesaurus, Match Option Defaults and Policies</p>
          </item>
	  <item>
	    <p>Cluster E: Other MatchOptions Details</p>
          </item>
	  <item>
	    <p>Cluster F: Grammar Integration, Syntax Details, and Naming</p>
          </item>
	  <item>
	    <p>Cluster G: Semantics Details</p>
          </item>
	  <item>
	    <p>Cluster H: Extensions</p>
          </item>
	  <item>
	    <p>Cluster I: Simplifications and Variations of Language Constructs</p>
          </item>
	  <item>
	    <p>Cluster J: IgnoreOption, Markup vs. Structure</p>
          </item>
	  <item>
	    <p>Cluster K: Issue closed before we started clustering</p>
          </item>
       </olist>
</p>

<issue id="scoring-properties" status="closed">
	<head>Scoring Properties (Cluster A, Issue 1)</head>
	<p>Is it possible to specify anything
    other than range ? Examples: do we want to define scoring rules
    for efficient scoring, rules to guarantee score monotonicity?</p>
    <resolution>
        <p>CLOSED.</p> <p>No changes required. Closed at FTTF Meeting
        62: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Oct/0020.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
    </resolution>
</issue>


<issue id="scoring-values" status="closed">
	<head>Scoring Values (Cluster A, Issue 2)</head>

<p>Answers that do not contain a match (in the Boolean sense) are
assigned a score value that depends on the scoring algorithm and that
might be greater than 0.</p>

<p>The following implications should hold:</p>

<p>score = 0 implies ftcontains is false.</p>
<p>score &lt;&gt; 0 does not imply anything for ftcontains.</p>
<p>ftcontains is true implies score &gt; 0.</p>
<p>ftcontains is false does not imply anything for score.</p>

<p>This interpretation enables the use of query relaxation in the
ftcontains expression and thus, return a score value greater than 0
for those nodes that do not match the ftcontains expression (in a
Boolean sense).</p> <p>For example, given the query:</p>

<eg xml:space="preserve"> for $b in //books
   score $score as $b//content ftcontains "usability &amp;&amp; testing"
   where $score &gt; 0
   return {$b} </eg> 

<p>The scoring algorithm could rewrite it to: </p>

<eg xml:space="preserve"> for for $b in //books
   score $score as $b//content ftcontains "usability || testing
               with stemming"
   where $score &gt; 0
   return {$b} </eg> 

<p>and thus, some of the books that are not returned by the first query
will be returned by the second query. </p>

<resolution>
<p>CLOSED.</p> <p>We discussed several alternatives in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Dec/0024.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
and we would like to adopt the one described above.</p> <p>However,
this issue is still under discussion.</p><p>See resolution in Cluster
A, Issue 60.</p>
</resolution>

</issue>

<issue id="data-model" status="closed">
	<head>Semantics Data Model (Cluster K, Issue 3)</head> <p>Data model incorporates
	new names - TokenInfo, Match, AllMatches.</p>
        <resolution>
           <p>CLOSED.</p> <p>All occurrences of FullMatch,
           SimpleMatch, and Position in the text, in the schemas, and
           in the XQuery implementations of the semantics have been
           replaced with AllMatches, Match, and TokenInfo
           respectively.</p>
        </resolution>
</issue>


<issue id="ftcontains-grammar" status="closed">
	<head>FTContains Grammar (Cluster K, Issue 4)</head> <p>Expr "ftcontains"
	FTSelection FTIgnoreCtxMod?. One production for FTSelection
	which includes FTIgnoreCtxMod?</p>
        <resolution>
           <p>CLOSED.</p>
           <p>We replaced the previous grammar production Expr
           "ftcontains" FTSelection that allowed FTIgnoreCtxMod to be
           combined with any FTSelection with the new one
           that restricts the application of FTIgnoreCtxMod to the
           highest level.</p>
        </resolution>
</issue>


<issue id="ftcontextmodifiers" status="closed">
	<head>FTContextModifiers (Cluster K, Issue 5)</head> <p> Paul
	C.: Change the name of the FTContextModifer production which
	modify the operational semantics of the FTSelections they are
	applied to. Abandon the use of "ContextModifier" as in
	FTCaseCtxMod, FTStemCtxMod, FTIgnoreCtxMod.  Issue raised at
	FTTF Feb 5-6, 2004 meeting. Find in the minutes at: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Feb/0010.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
	(Cntl-F on FTContextModifiers)</p>
        <resolution>
           <p> CLOSED.</p>
           <p>Replaced FTContextModfiers with FTMatchOptions as in
FTCaseOption, FTStemOption, FTIgnoreOption in the Feburary 26, 2004
Editor's Draft.  </p><p> CLOSED February 26, 2004.</p>
        </resolution>
</issue>


<issue id="grammar" status="closed">
	<head>Grammar (Cluster K, Issue 6)</head> <p>Grammar: Where does the
	ftcontains expression belong in the XQuery grammar: Boolean
	expression or comparison expression?</p>
        <resolution>
           <p> CLOSED.</p>
           <p>The ftcontains expression plugs in to the XQuery grammar in the "FTComparisonExpr" production. This seems to give ftcontains the correct precedence among other XQuery operations, and it makes intuitive sense.</p>
        </resolution>
</issue>

<issue id="wildcards" status="closed">
	<head>Wildcards (Cluster C, Issue 7)</head> <p>Pat Case: There are a few
	inconsistencies between this document and the Use Cases
	Working Draft. </p> <p>This document and the Use Cases Working
	Draft present different syntax in regex examples. I can find
	no syntax provided in this document for the starts-with and
	exact match functionality. Should we rename the Wildcard
	section in the Use Cases to Regex Section and possibly rethink
	the use cases?</p>
        <resolution>
           <p>CLOSED.</p> <p>We dropped regular expression support in
           favor of wildcard support. Closed at Meeting 67: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0051.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p> 
        </resolution>
</issue>


<issue id="thesaurus" status="closed">
	<head>Thesaurus (Cluster D, Issue 8)</head> <p>Thesaurus
	names: "synonyms", "narrower terms", "soundex", "spellcheck"
	and "wordnet". We need to define Thesaurus operators. We need
	more options when specifying thesaurs: Name, URI, Depth,
	Dimension. Standards. ISO 2788/ANSI Z39.19.</p> <p>We need to
	discuss what the grammar of ThesaurusMatchOption is. Current
	grammar is: </p><p>FTThesaurusOption ::= ("with"?  "thesaurus"
	Expr) | "without thesaurus". </p> <p>Proposed grammar is:</p>
	<p>FTThesaurusOption ::= ("with"?  "thesaurus" Expr
	"operation" Expr) | "without
	thesaurus". </p>
         <resolution><p> CLOSED.</p>
           <p>Changed the syntax and semantics
	of thesaurus according to
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0111.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
        </p></resolution>
</issue>


<issue id="window" status="closed">
	<head>Window (VNext, Cluster H, Issue 9)</head> <p>Currently, FTDistanceSpec only permits
	a single distance specification for all of the terms specified
	by an FTSelection.</p>
        <p>For example:</p>

        <p>("dog" &amp;&amp; "cat" &amp;&amp; "bird") with word
        distance at most 10</p>

        <p>In this scenario above, the terms "dog", "cat", and "bird"
        must all occur within 10 words of one another.</p>
        
        <p>However, if one would want to return documents where "dog"
	occurs within 10 words of "cat" and this SAME "cat" term
	occurs within 5 words of "bird", it is currently not possible
	with the current language specification.  The best that could
	be done is the following:</p>

        <p>(("dog" &amp;&amp; "cat") with word distance at most 10) and
           (("cat" &amp;&amp; "bird") with word distance at most 5)</p>
 
        <p>But, this will not lead to the exact desired result because
	the "cat" and "bird' comparison will not use only those "cat"
	terms which occurred within 10 positions of "dog" ... it can
	use any "cat" term within the search context.</p>
<resolution>
<p>CLOSED.</p> <p>The issue has been closed on April 25, 2005 &lt;<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Apr/0072.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
&gt;. No changes are made to the language. Although the current
language can express a lot of the specified types in question, the
group recognizes that the query expressions are clumsy and difficult
to write. Therefore, this issue will be considered again for
VNext.</p> </resolution>

</issue> 

  
<issue id="mildnot" status="closed">
	<head>MildNot (Cluster I, Issue 10)</head> <p>Andrew E.: Should we remove the mild
	not? It has never been included in a query language
	before. </p><p>Pat Case has provided use cases to justify its
	inclusion at:
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2003Dec/0034.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
	</p> <p>Discussion followed. Michael Rys' reply:
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2003Dec/0038.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
	</p><p>Pat Case's reply:
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2003Dec/0043.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
	</p>
	<p>Use case paraphrase (for non-members): Consider a collection of 3 documents:</p>
	<olist>
	  <item>
	    <p>The Delights of Mexico - a document that includes "Mexico" several times.</p>
	  </item>
	  <item>
	    <p>The Perils of New Mexico - a document that includes "New Mexico" several times.</p>
	  </item>
	  <item>
	    <p>Travel in North America - a document that includes both "Mexico" and "New Mexico" several times.</p>
	  </item>
	</olist>
  <p>Suppose you are planning a trip to Mexico. You want documents 1
  and 3, but not 2. You could search for "Mexico" and get documents 1,
  2 and 3. Or you could search for "Mexico AND NOT 'New Mexico'" and
  get just document 1. But the "strong not" has ruled out document 3 -
  even though it contained the thing you were looking for - just
  because it contained the thing you were not looking for.</p> <p>The
  "mild not" operator allows you to say "Mexico MILD NOT 'New
  Mexico'", which means "find me all the documents that contain
  'Mexico'. Do not take any notice of occurrences of 'New Mexico', but
  do not rule out a document just because it contains 'New
  Mexico'".</p> <p>There are many cases where you may want to search
  for a word, but NOT get documents just because they contain a common
  phrase that includes that word. e.g. "security" mildnot "social
  security", "house" mildnot "house of representatives", "estate tax"
  mildnot "real estate tax"</p>
    <resolution>
        <p>CLOSED.</p> <p>Issues 10 and 41 are now closed. We add the mildnot functionality and FTMildNot is spelled as "not in". Closed at FTTF Meeting
        80: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005May/att-0030/fttf-20050503.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
    </resolution>
</issue>

    
<issue id="markup-vs-structure" status="closed">
	<head>Markup vs Structure (Cluster J, Issue 11)</head> <p>Some
	tags are "markup" - e.g. b - some are "structure" -
	e.g. title.  We generally want to treat structure tags as word
	boundaries, but not markup tags.  How do we distinguish
	between markup and structure?</p> <p>Michael to provide
	reformulation. </p><resolution><p> CLOSED.</p> <p>Closed on
	April 29, 2005 and updated Section 1.1 as in
	http://lists.w3.org/Archives/Member/member-query-fttf/2005Apr/0091.html.</p></resolution>
</issue>

      
<issue id="matchoption-policy" status="open">
	<head>MatchOption Policy (Cluster D, Issue 12)</head> 
        <p>We need some indirection to
	specify match context, defaults "Thesaurus name" gives us a
	way to define a thesaurus, then specify it in the query - an
	indirection.  Steve Buxton proposes there are many classes of
	things that are needed for context-match (stoplist, special
	characters, etc.) that need an indirection. So we need an
	extra level of indirection - a named policy that refers to a
	set of named things.</p>
</issue>

       
  <issue id="loose-grammar" status="closed">
      <head>Loose Grammar (Cluster I, Issue 13)</head> 
      <p>The grammar allows lots of
           queries that do not make sense.  e.g. "(dog || cat) within
           word distance N", "dog within word distance N", "(dog || cat)
           ordered", "!dog 5 times" If the grammar does not provide a way
           of identifying these "nonsense queries", then the
           implementation still has to identify them - i.e. implementors
           will have to augment the grammar to identify nonsense queries,
           and augment the semantics to do something with them.  </p>
           <p>
           J. Doerre asks if we should allow nested FTNegations in the
           RHS of a FTMildNegation. From his email (<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Apr/0019.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>)
           point 3: "The ApplyFTSelection ignores all StringExcludes
           in the arguments of the FTMildNegation. I think, if we
           don't want to deal with StringExcludes in that function, we
           should explicitly forbid them to appear, i.e.  require
           arguments of FTMildNegation to not include any FTNegation."

           </p><resolution><p> CLOSED.</p> <p>Leave the grammar as it
           is for a couple of reasons. 1. We cannot solve this problem
           with a (context-free) grammar without complicating it
           unnecessary. For example, apart from "(dog || cat) word
           distance N", the "no-op" rule can be also applied to "(dog
           with diacritics || cat) case-insensitive without stop words
           word distance N".</p> <p>2. It is hard if not impossible to
           enumerate all "no-ops". Here are some additional ones: "a"
           &amp;&amp; !"a", (dog &amp;&amp; cat) distance at most 5
           words distance at most 6 words, "To be or not to be"
           distance at least 10 words, etc. It should be left to the
           application to determine what constitutes a no-op and
           optimize if possible.</p><p>See F2F minutes in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jul/0049.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p></resolution>
</issue>
    
<issue id="fttimesselection" status="closed">
	<head>FTTimesSelection (Cluster G, Issue 14)</head> 
        <p>How do I count occurrences, where the query
        is NOT a single term?.  How many occurrences of "!dog" are
        there in "very very big"?  Zero or very many?</p>
<resolution><p> CLOSED.</p></resolution>
</issue>

 
<issue id="regexp-escape" status="closed">
	<head>RegExp Escape (Cluster C, Issue 15)</head> <p>Need to
        define some escaping mechanism for regexp characters, and for
        (||, ...).</p> <resolution><p> CLOSED.</p>
           <p>Closed on Feb. 14, 2005 because
        regular expressions are not part of the language
        anymore.</p></resolution> </issue>


<issue id="ftscopeselection" status="closed">
	<head>FTScopeSelection (Cluster I, Issue 16)</head> <p>Is
        there a need for both FTScopeSelection and FTDistance ? For
        example, how is the 'same sentence' or 'same paragraph' really
        different than a FTDistance of 'with sentence exactly 1' or
        'with paragraph exactly 1'?.</p> <resolution><p> CLOSED.</p><p>We
        decided to keep both FTScopeSelection and
        FTDistance.</p></resolution>
</issue>

 
<issue id="weighting" status="closed">
	<head>Weighting (Cluster A, Issue 17)</head> <p>Michael R.:
        What syntactic form should scoring take? How do we describe
        the constraints on the types of expressions that are allowed?
        Should scoring be expressed using a second-order function, a
        stand-alone operator, or as a clause in a FLWOR expression?
        Consider moving weighting to ftContains, something like the
        following: TreatExpr ("ftcontains" FTSelection ("weight"
        Expr)? )? </p><p>Options in presentation of full-text language
        proposal and some discussion at XQuery January meeting, Tampa
        at: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/XML/Group/2004/01/xquery-minutes" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
        (Cntl-F on Report of Full-Text Task Force)</p>
        <resolution><p> CLOSED.</p>
           <p>Added weight to FTSelection inside a scoring
        expression.</p></resolution>
</issue>

     
<issue id="weight-values" status="closed">
	<head>Weight Values (Cluster A, Issue 18)</head> <p>Valid
        values for weights must be defined.</p> 
        <resolution><p> CLOSED.</p>
           <p>Weight values in scoring expressions are in the interval
        [0,1].</p></resolution>
</issue>

     
<issue id="ftscopeselection-on-structure" status="closed">
	<head>FTScopeSelection on structure (VNext, Cluster H, Issue 19)</head> 
       <p>Scoping based on structure (e.g. same node and different
        node) should be considered. Support for queries where distance
        is measured in terms of "number of intervening elements" where
        elements can be any markup including chapter, paragraph and
        sentence. Consider sentence/paragraph/node distance.</p>
        <resolution><p> CLOSED.</p><p>Postponed to VNext.</p></resolution>
</issue> 

     
<issue id="languagematchoption" status="closed">
	<head>LanguageMatchOption (Cluster E, Issue 20)</head> <p>What is the default
           language?  SA: Dana F.: does the language have to be a
           literal or an Expr that returns xs:string?  Is there an
           implementation-defined list of valid languages ?</p>
<resolution><p> CLOSED.</p>
<p>1. Default language is "None". </p>
<p>The Working Draft states explicitly in Section 3.2.7 the possibility
to have no language selected. I think this is a good choice for the
default (and it is specified as the default in the Working Draft). A
typical application that uses XQuery-FT will probably have logic in
place to override the default by the language setting from the locale
of the client, so the default is really unimportant.</p>

<p>2. The language is given by a UnionExpr that must return an
xs:string, or an empty sequence.  This is what the Working Draft
specifies. Let us keep it like that.</p>

<p>3. Yes, there is an implementation-defined list of valid languages.
We added a statement on this to Section 3.2.7. See
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0083.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
</resolution>

</issue>

           
<issue id="casematchoption-specialcharmatchoption" status="closed">
	<head>CaseMatchOption and SpecialCharMatchOption (Cluster E, Issue 21)</head>
           <p>Paul C. pointed out whether "lowercase", "uppercase",
           "case sensitive" and "case insensitive" should be defined
           in the context of Unicode. J. Doerre provided this link to
           the Unicode standard is: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.unicode.org" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>. The
           current version is 4.0.0. Case folding is described in
           Chapter 3.13.  Please note that the case folding
           operations, like toUppercase(X), only depend on the
           characters to be folded, not on additional information,
           like language.</p>
<resolution><p> CLOSED.</p>
           <p>There will be no syntax for special character handling in the
current draft. Issues to consider for v. next are in this list of issues.
           </p></resolution>

</issue> 

          
<issue id="diacriticsmatchoption" status="closed">
	<head>DiacriticsMatchOption (Cluster E, Issue 22)</head>
           <p>Paul C.: We need to define what a diacritic is. Steve
           B. pointed out whether "with diacritics" and "without
           diacritics" are needed or not.</p> 
           <resolution><p> CLOSED.</p>
           <p>We removed
           the special character match option as instructed in
           <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0051.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
           </p></resolution>

</issue>


<issue id="tokenizers" status="closed">
	<head>Tokenizers (Cluster J, Issue 23)</head> <p>Darin/Paul
           C.: What is the most general behavior for
           tokenizers?</p><p>Michael Kay: Can we define a set of rules
           that apply regardless of which tokenizer we are using in
           the same manner as the rues we defined for scoring?  For
           example, we could impose constraints on words, sentences
           and paragraphs.</p>
           <resolution><p> CLOSED.</p>
           <p>Modified item 7 in Section
           1.1 to reflect conditions on tokenizers.</p></resolution>
</issue>


<issue id="specialcharmatchoption" status="closed">
	<head>SpecialCharMatchOption (Cluster E, Issue 24)</head>
        <p>We need to say more about special characters, what kind of
        special characters do we want to consider, what is their
        impact on the ability to use a given index, their impact on
        tokenization.</p> 
        <resolution><p> CLOSED.</p>
           <p>We decided to remove this match
        option from the current WD and create new issues
        to be considered for v. next.</p></resolution>

</issue>


<issue id="matchoption-syntax" status="closed">
	<head>MatchOption Syntax (Cluster E, Issue 25)</head> <p>Paul C.: It maybe that we
        should reconsider the syntax and allow to apply modifiers to
        individual words.</p>
        <resolution><p> CLOSED.</p></resolution> 
</issue>


<issue id="stopwordsmatchoption" status="closed">
	<head>StopWordsMatchOption (Cluster E, Issue 26)</head> <p>We
        need to say more about stopwords, what kind of stop words do
        we want to consider, what is their impact on the ability to
        use a given index, their impact on tokenization. Should we
        allow to specify the URI of a StopWords list? Paul C.: What
        would a single search with a stop word
        return?</p>
        <resolution><p> CLOSED.</p>
           <p>We changed the syntax of stop words
        sepcification to allow for using a URI as a stop word
        list. The new syntax is given in:
        <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0109.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
        </p></resolution>
</issue>



<issue id="matchoptionstokenization" status="closed">
	<head>MatchOption and Tokenization (Cluster C, Issue
27)</head> <p> Does the language document clearly state the impact of
match options on tokenization? Consider regex * when does it get
applied? What effect does it have on word breaks? Example: expr
ftcontains "brown .ox" with regex, expr ftcontains "brown .*ox" with
regex.  </p>
<resolution><p> CLOSED.</p>
<p>Closed, on Feb. 17, 2005, because no longer an issue.</p>
<p>The only impact of match options on tokenization that needs to be
addressed in the specification is the impact of the wildcard match option.
Other match options, like "language", are allowed to impact tokenization
in an implementation-dependent way.</p>
<p>For the wildcard match option its implication on tokenization is now
clearly stated in its description, namely that wildcards, i.e., the
character sequences ".", ".*", ".+", etc., are to be interpreted as
token-internal character sequences when within an FTWords that is inside
the scope of the wildcard match option.</p>
</resolution>
</issue>



<issue id="ignoresyntax" status="closed">
	<head>IGNORE Syntax (Cluster B, Issue 28)</head> <p> Do we need special syntax for
IGNORE in case of level by level search?</p>
<resolution>
<p>CLOSED.</p>
<p>We already have a syntax for this.</p>
</resolution>
</issue>



<issue id="scoping" status="closed">
	<head>Scoping (Cluster I, Issue 29)</head> <p> Do we need same sentence, same paragraph
search? * in semantics, not in requirements.
</p>
<resolution>
<p>CLOSED.</p>
<p>
Closed by Pat Case in
http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0230.html</p>
<p>This recommendation should focus on functionality which serves all
languages. It should also selectively include functionalities useful
within families of languages. Searching within sentences and paragraphs
is useful to many western languages and some non-western languages. They
should remain in the recommendation. 
</p>
</resolution>
</issue>



<issue id="precedencexqueryfulltext" status="closed">
	<head>Precedence of XQuery and full-text (Cluster F, Issue 30)</head> <p> We need
	to distinguish between XQuery expressions embedded in
	full-text expressions and FTSelections themselves. S. Buxton
	suggests that we use different kinds of parentheses to
	distinguish between these two expressions. See his message in
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Apr/0042.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
	and subsequent messages.  A simple example is to distinguish
	between ("cat") as an XQuery expression that builds an XQuery
	sequence and ("cat") as an FTSelection.  </p> <p> In the
	current draft of the document, we are using lookahead </p> <p>
	Other possibilities include the use of "{}" to switch from
	full-text to XQuery when XQuery expressions are embedded in
	full-text expressions. This is similar to element construction
	in XQuery and has been pointed out by Mary H in her email at
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004May/0163.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
        <resolution>
           <p>CLOSED.</p> <p>We decided to use {} to delimit XQuery
           expressions inside XQuery Full-Text ones according to the
           discussion in
           <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0019.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
        </resolution>
</issue>



<issue id="ftdistancewith" status="closed">
<head> Optional Keyword "with" in FTDistance (Cluster F, Issue 31)</head>
<p>In 3.1.9 FTDistance: Do we need "with" in
FTDistance?</p>
<p>Raised by Pat Case by email April 28, 2004</p>

        <resolution>
           <p>CLOSED.</p> <p>We removed the optional keyword "with"
        from FTDistance. Closed at FTTF Meeting 69, by accepting text
        at
        <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0112.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
        as amended.</p> 
        </resolution>
</issue>



<issue id="ftwindowwithin" status="closed">
<head> Optional Keyword "within" in FTWindow (Cluster F, Issue 32)</head>
<p>In 3.1.20 FTWindow: Do we need "within" in
FTWindow?</p>
<p>Raised by Pat Case by email April 28, 2004</p>
        <resolution>
           <p>CLOSED.</p> <p>We removed the optional keyword "within" from FTWindow. Closed at FTTF Meeting 69, by accepting text
        at
        <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0112.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
        as amended.</p>
        </resolution>
</issue>



<issue id="ftspecialcharoption-issue" status="closed">
<head> FTSpecialCharOption (Cluster E, Issue 33)</head>
<p>In 3.2.3 FTSpecialCharOption: Should we have to or be able to
specify which special characters are to be matched or not? Should the
following syntax be allowed "without special characters "-" or "with
special characters "-"?</p>
<p>Raised by Pat Case by email April 28, 2004</p>
<resolution><p> CLOSED.</p>
           <p>Closed on 14 Feb. 2005 because special character match
options is not part of the language anymore.</p></resolution>
</issue>



<issue id="ftnegationunarynot" status="closed">
<head> FTNegation Includes Unary Not (Cluster F, Issue 34)</head>
<p>In 3.1.5 FTNegation: If we are supporting the unary not which is
shown in the production, please add text and examples to show that both
the "unary not" and the "and not" are supported.</p>
<p>Raised by Pat Case by email April 28, 2004</p>
<resolution>
<p>CLOSED.</p> <p>Closed by Pat Case in http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0230.html</p>
</resolution>
</issue>



<issue id="ftorderunordered" status="closed">
<head> FTOrder Unordered Option (Cluster F, Issue 35)</head>
<p>In 3.1.7 FTOrder: [30] FTOrder  ::=   FTSelection  "ordered" should
we have an explicit "unordered" for the default?</p>
<p>Raised by Pat Case by email April 28, 2004</p>
        <resolution>
           <p>CLOSED.</p> <p>We don't introduce an explicit
           "unordered" operator. This would necessitate the semantics
           to deal with partial orders inside ALLMATCHES. There are no
           use cases warranting such complications in the
           semantics. 
           Closed at FTTF Meeting 68:
           <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Feb/0020.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
           </p>
        </resolution>
</issue>



<issue id="ftignoreoptionnaming" status="closed">
<head> FTIgnoreOption Naming (Cluster F, Issue 36)</head>
<p>Would FTFilterOption be a better name than FTIgnoreOption?</p>
<p>Raised by Pat Case by email April 28, 2004</p>
<resolution>
<p>CLOSED.</p>
<p>Closed by Pat Case in
http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0208.html</p>
<p>Since filter and skip are already used in the XQuery recommendation,
the name of this functionality should remain FTIgnore. 
</p>
</resolution>
</issue>


<issue id="ftrangespecsyntax" status="closed">
<head> FTRangeSpec Syntax for 1 to 4 (Cluster F, Issue 37)</head>
<p>We should consider aligning the syntax for the FTRangeSpec with an
upper and lower boundary in 3.1.9 FTDistance (from 1 to 4) with the
syntax for using range expressions to construct sequences in XQuery and
XPath (1 to 4), See the XQuery/XPath language document Section 3.3.1
Constructing Sequences.</p>
<p>Raised by Pat Case by email April 28, 2004</p>
<resolution>
<p>CLOSED.</p>
<p>Closed by Pat Case in http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0227.html</p>
<p>The document will continue to use the syntax (from 1 to 4) for number
ranges in FTRange. This syntax for number ranges is the most
user-friendly. There is no need to align this syntax with the XML
Schema/XQuery regular expression syntax for number ranges.
</p>
</resolution>
</issue>

 

<issue id="booleannaming" status="closed">
<head> Boolean (&amp;&amp; || !) Naming (Cluster F, Issue 38)</head>
<p>Is it not possible and maybe preferable to use ftand ftor ftnot
instead of  &amp;&amp; || ! following the lead of ftcontains?</p>
<p>Raised by Pat Case by email April 28, 2004</p>
<resolution><p> CLOSED.</p></resolution>
</issue>

 

<issue id="exactelementcontent" status="closed">
<head> Exact Element Content (Cluster C, Issue 39)</head>
<p>We have a use case for an exact element content query which finds
the exact words or phrases being queried, no more and no less in an
element and allows variations on case, diacritics, and special
characters. Should this functionality be in XQuery full-text? If so,
should we use the keywords "exact content"?</p>
<p>Raised by Pat Case by email April 28, 2004</p>
<resolution><p> CLOSED.</p>
<p>We added an FTSelection in Section 3.1.12 to express exact content.
</p></resolution>
</issue>

 

<issue id="startswith" status="closed">
<head> Starts With (Cluster C, Issue 40)</head>
<p>We have a use case for a starts with query which finds the words or
phrases being queried as the first content of an element. Should this
functionality be in XQuery full-text? If so, should we use the keywords
"starts with"? </p>
<p>Raised by Pat Case by email April 28, 2004</p>
<resolution><p> CLOSED.</p>
<p>We added an FTSelection in Section 3.1.12 to express start with.
</p></resolution>
</issue>



<issue id="mild-not-naming" status="closed">
<head> What should we call the mild not (Cluster F, Issue 41)</head>
<p>The name "mild not" or "mild negation" is not really helpful in
understanding what we want it to denote. We should try hard to find a
better name for this construct. Since it is used to exclude certain
matches, why not call it "FTMatchExclude" or just "FTExclude"? Keeping
"mild not" as the name makes it recognizable as a form of "not". If it
remains as "mild not" and the ! continues as the syntax for "not",
consider using mild! as the syntax for "mild not".</p>
<p>Raised by Jochen by email April 21, 2004; Additional comments by Pat
Case May 4, 2004</p>
    <resolution>
        <p>CLOSED.</p> <p>Issues 10 and 41 are now closed. We add the mildnot functionality and FTMildNot is spelled as "not in". Closed at FTTF Meeting
        80: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005May/att-0030/fttf-20050503.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
    </resolution>
</issue>



<issue id="multi-word-phrases-thesauri-lookup" status="closed">
        <head>Thesauri lookup for multi-word phrases (Cluster D, Issue 42)</head>
       <p>It should be decided whether thesauri lookups can be performed
              only on single words or whether it is possible to apply it on
              multi-word phrases. For example, should we allow the 
thesaurus to
              replace "bells and whistles" with "frills"?  </p>
        <p>In the latter case, should thesauri lookup be applied only to 
the
               FTWord "bells andwhistles", or should it applied also on
               ("bells" "and" "whistles") phrase? Another question is if
               the thesauri expansion can be applied on phrase and on a word
               in the phrase, which one takes precedence. </p>
<resolution><p> CLOSED.</p>
<p>The semantics has been modified so that thesauri lookups can be performed on
multi-token phrases. They are applied only on phrases that are explictly
specified by the user; e.g., they will be applied in FTWord selections
"('bells', 'and', 'whistles') phrase" or "'bells and whistles' any/all/phrase".
Multi-token phrase lookup for "bells and whistles" will no be performed for
"('bells', 'and', 'whistles') all word" or "'various bells and whistles'
phrase". Multi-token phrase lookups take precedence over single-token lookups:
once a multi-token phrase lookup is performed no more thesauri lookups will be
performed. </p>
</resolution>
</issue> 
   



<issue id="exactly" status="closed">
       <head>Exactly in FTRangeSpec (Cluster F, Issue 43)</head>
      <p>Should "exactly" be optional? Should we allow both "word
      distance 6" and "word distance exactly 6"? Raised at Redmond May
      2004 by Steve Buxton and Pat Case.</p><resolution>
      <p>CLOSED.</p><p>Exactly is required and is not
      optional.</p></resolution>
</issue>
    

  
<issue id="ftcontains-semantics" status="closed">
       <head>FTContains Semantics (VNext, Cluster H, Issue 44)</head> <p>FTContains operates on
      a sequence of nodes. Strings cannot be searched.</p>
      <p>Raised at Redmond May 2004 by Steve Buxton. See also:
      <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004May/0085.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/> </p><resolution>
           <p>CLOSED.</p><p>Postponed to VNext.</p></resolution>
 </issue>



<issue id="matchoptions-defaults" status="open">
       <head>MatchOptions Default (Cluster D, Issue 45)</head> <p>We need to specify
      defaults for MatchOptions. We should align this default with
      the static content for XQuery/XPath and add to the XQuery prolog
      corresponding declarations to set query-wide defaults.</p>
</issue>



<issue id="ftnegation-semantics" status="closed">
       <head>FTNegation Semantics (Cluster K, Issue 46)</head> <p>We need to specify the
      semantics of FTNegation. </p><p>Raised by Jochen Doerre. See
      <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004May/0082.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p> 
      <resolution><p> CLOSED.</p>
      <p>we decided to use
      &lt;allMatches/&gt; to denote false. See answer to <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004May/0082.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p></resolution>
</issue>



<issue id="zero-length-phrase" status="closed">
      <head>Zero-length phrase (Cluster G, Issue 47)</head>
      <p>If Expr in FTWords  results in the empty sequence or the
tokenization results
      in a zero-length phrase, the result is? Always a match, never a
match?
      Depending on the keyword?</p>

        <resolution>
           <p>CLOSED.</p> <p>As agreed by the FTTF, an FTWords with an
           empty list of search tokens returns an empty
           AllMatches. This applies for both the search tokens
           supplied directly by the user (as an XQuery expression) and
           the final search tokens after the application of all match
           options. Closed at FTTF Meeting 70:
           <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Feb/0105.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
        </resolution>
</issue>

<issue id="stopwordsoptions" status="closed">
      <head>Stop words option (Cluster E, Issue 48)</head> <p>The
      syntax and semantics of stop words are still under
      discussion.</p> <p><specref ref="ftstopwordoption"/> is
      inconsistent with the grammar and semantics.</p>
      <olist>
        <item>
          <p>the second example includes "without stop words" NOT
          followed by an expression, which is not valid according to
          the EBNF (see also the default options query in <specref ref="ftmatchoptions"/>)</p>
        </item>
        <item>
          <p>the keyword "additional" is not part of the current grammar</p>
        </item>
        <item>
          <p>the text and examples in <specref ref="ftstopwordoption"/> imply that queries work as though
          stop words were removed from documents before positions are
          calculated, which is inconsistent with the description in
          <specref ref="semantics-ftstopwordoption"/></p>
        </item>
      </olist>
    <resolution><p> CLOSED.</p>
        <p>We changed the syntax of stop words sepcification to
        allow for using a URI as a stop word list. The new syntax is
        given in:
        <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jan/0109.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p></resolution>
</issue>

<issue id="grammar-precedence" status="closed">
	<head>Grammar Precedence and Lookahead (Cluster F, Issue 49)</head>
	<p>When integrating the XQuery Full-Text grammar with the XQuery 1.0 grammar, 
           there were a number of challenges. Challenges include (using pseudo-code for examples):</p>
<olist>
  <item>
    <p>The Full-Text operators must have the correct precedence
    (binding order) with respect to XQuery operators</p>
  </item>
  <item>
    <p>It must be possible to override the default precedence of the 
    Full-text operators - e.g. you must be able to express "(cat and dog) 
    or mouse" as well as "cat and (dog or mouse)"</p>
  </item>
  <item>
    <p>You must be able to embed XQuery expressions in the Full-Text expression, e.g. "cat and $i"</p>
  </item>
  <item>
    <p>You must be able to embed the XQuery Full-Text expression in an 
       arbitrarily-complex XQuery expression, e.g. "where title ftcontains ('dog' and 'cat') 
       and price/dollars &lt; 3 or disclaimer ftcontains 'buy this'"</p>
  </item>
</olist>
  <p>The Working Groups discussed a number of ways of achieving
   this. The current grammar satisfies these requirements at the cost
   of introducing ambiguity in one place. The current XQuery 1.0
   grammar is LL(1) - i.e. it is possible to write a parser that reads
   a query from left to right and only looks 1 token ahead. But the
   XQuery Full-Text grammar is NOT LL(1). At <specref ref="prod-xquery-FTWordsSelection"/> the parser must lookahead a
   full non-terminal - it must try to expand FTWords, and if that
   fails it must try to expand (FTSelection).</p> <p>This is still
   under discussion - the Working Groups may remove the requirement
   for lookahead in a future publication.</p>
   <resolution>
           <p>CLOSED.</p> <p>We decided to use {} to delimit XQuery expressions inside XQuery Full-Text 
           ones accroding to the discussion in  
           http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0019.html</p>
   </resolution>
</issue>


<issue id="ignore-queries" status="closed">
	<head>IGNORE Queries (VNext, Cluster B, Issue 50)</head>

	<p>There are 3 main issues with IGNORE queries:</p>
	<olist>
	<item><p> Do we
	need to specify the UnionExpr that follows IGNORE in the
	grammar? </p> <p>Yes, we do.</p>  <p> This issue has been resolved in
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Aug/0059.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
 	</item>
	<item>
	<p> Should IGNORE be made composable with other
	FTSelections or should it be kept at the top level in the
	grammar?</p> 
	</item>
	<item><p> Does the semantics of level-by-level IGNORE
	(used in the Use Cases document) differ from the semantics of
	IGNORE in the language document?</p>
	</item>
	</olist>
   <resolution>
           <p>CLOSED.</p> <p>Point 1. We are using UnionExpr in the
           current syntax. Point 2. Composing FTIgnore at any level of
           FTSelections is too complex at this stage and should be
           postponed to VNext after we have some implementation
           experience. See examples where semantics of composing
           ignore with FTSelection is not clear. Point 3. No, the
           semantics of FTIgnore is now the level by level
           semantics. See minutes in http://lists.w3.org/Archives/Member/member-query-fttf/2005May/0007.html </p>
           </resolution>
</issue>

<issue id="ftwindow-alternative-semantics" status="open">
<head>Alternative Semantics for FTWindow (Cluster I, Issue 51)</head>

<p>The current semantics of FTWindow does not capture the most
intuitive notion of window as a matching constraint. Suppose we have a
simple query like: </p> <p><code>"Internet" &amp;&amp;
"Cafe"</code>,</p> <p> and we want to restrict a match to say, a
window of 5. The interpretation I think is most natural for this
query, is that it restricts each match, such that it is required to
"lie" within a "window of 5 (word) positions" (but we could also use
sentence or paragraph as position unit). Note that this does not imply
that the search terms have to be a certain distance apart in any
way. The window in which a match can be found exists independently of
the match. In our current semantics, however, the "window" is defined
by the first and last stringInclude (matching term) position. This
allows us to constrain the window size using "exactly", "at most" and
"at least".  I find this notion of window counter-intuitive and
confusing. Finding a match in a larger window should always be a
weaker condition than finding a match in a smaller window!
</p>

<p>The difference in the notion of window also comes to bear when looking 
at 
queries with negative parts. A query like: </p>
<p><code>"Internet" &amp;&amp; ! "Cafe" within window 5</code>, </p>
<p>has the very intuitive meaning of searching for any occurrence of 
"Internet" such 
that inside some window of 5 positions that includes that occurrence there 
is not 
an occurrence of "Cafe". With our current notion of window, such a query 
simply 
cannot be expressed.
</p>

<p>Here is the formalization of the proposed window semantics.
</p>
  <eg role="parse-text" xml:space="preserve">
define function fts:ApplyFTWordWindow(
      $matchOptions as element(matchOptions, fts:FTMatchOptions),
      $allMatches as element(allMatches, fts:AllMatches),
      $n as xs:integer
      ) as element(allMatches, fts:AllMatches) {
  &lt;allMatches&gt;
   {
    for $match in $allMatches/match
    let $minpos := fn:min($match/*/tokenInfo/@pos),
        $maxpos := fn:max($match/*/tokenInfo/@pos)
     for $windowStartPos in ($minpos to $maxpos-n+1)
     let $windowEndPos := $windowStartPos+n-1
     where fn:min($match/stringInclude/tokenInfo/@pos) &gt;= $windowStartPos
           and fn:max($match/stringInclude/tokenInfo/@pos) &lt;= $windowEndPos
     return 
       &lt;match&gt;
         {$match/stringInclude}
         {
          for $stringExclude in $match/stringExclude
          where $stringExclude/tokenInfo/@pos &gt;= $windowStartPos
                and $stringExclude/tokenInfo/@pos &lt;= $windowEndPos
          return $stringExclude
         }
       &lt;/match&gt;
    }
  &lt;/allMatches&gt;
}
    </eg>
<p>Raised by Jochen.
</p>

<resolution><p>
	CLOSED.</p><p>The proposed new semantics has been accepted. 
        Closed at F2F Meeting 84: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jul/0061.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</p></resolution>
</issue>

<issue id="with-stop-words-UnionExpr" status="open">
	<head>UnionExpr in StopWords(Cluster D, Issue 52)</head>
	<p>The change from "UnionExpr" to "some complicated rewrite of
	UnionExpr that only includes literals" makes the grammar more
	complex, makes the language less clear and comprehensible, and
	adds only some questionable optimization possibilities (the
	query may be optimizable statically instead of at runtime).</p>

<p>Raised by Steve Buxton in
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Dec/0065.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
</issue>

<issue id="matchoptions-default-functions" status="closed"> 

        <head>Functions returning defaults
	for match options (VNext, Cluster D, Issue 53)</head> 

        <p>We would like to create functions that return the defaults
	for match options. Each implementation may choose different
	default values for match options. The purpose of these
	functions is to query and return those defaults.</p><p>This
	issue was raised at the Dec. 2004 F2F in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Dec/0072.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p><resolution><p>
	CLOSED.</p><p>If we decide to pursue this functionality, we
	decided to do it in VNext and it will most likely be pursued
	in XQuery instead of XQuery and XPath Full-Text because if
	users want to query for defaults, they will be interested in
	those for both XQuery and XQuery and XPath
	Full-Text.</p><p>See F2F minutes in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jul/0049.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p></resolution>
</issue>


<issue id="weight-granularity" status="closed">
	<head>Weight Granularity in Scoring (Cluster A, Issue
	54)</head> <p>Michael Rys: Should we permit weights to be
	expressed at the level of FTContainsExpr and FTSelection or
	should we only permit them at the level of individual terms
	(FTWords)?</p><resolution><p> CLOSED.</p><p>Resolved by
	Cluster A, Issue 17</p></resolution>
</issue>
     
<issue id="specialcharacters" status="closed">
	<head>Special Characters (VNext, Cluster E, Issue 55)</head>
	<p>We removed the special characters match option from the
	current draft and we will consider it for V next.</p>
	<p>Discussion initiated in
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Dec/0072.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p><resolution><p> CLOSED.</p><p>Postponed to VNext.</p></resolution>
</issue>
        
<issue id="scoring-corpus" status="closed">
	<head> Scoring Corpus (VNext, Cluster A, Issue 56)</head>
	<p>Do we want to alows users to specify a scoring corpus such as in:</p>
        <p>Discussion initiated in
	<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Dec/0072.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p><resolution><p> CLOSED.</p><p>Postponed to VNext.</p></resolution>
</issue>


<issue id="collations-match-option" status="closed">
	<head> Collations Match Option (VNext, Cluster D, Issue 57)</head>

       <p>Currently, XQuery 1.0 and XPath 2.0 Full-Text depends on the
collation chosen in XQuery. It can be modified by the FTCaseOption and
the FTDiacriticsOption match options. We need to explore the
interaction of the collation with FTLanguageOption. Presumably, the
latter will change the collation. What if there are more than one
collations available for a given language? Moreover, if we decide to
introduce back the FTSpecialCharsOption (see Issue 24), there might be
different collations that treat special characters differently.</p>

<p>One approach is to have a FTCollationOption:</p>

<p>FTCollationOption ::=  "using"? "collation" CollationUri</p>

<p>Another option is to have a collation only associated with 
FTLanguageOption (and possibly a future version of FTSpecialCharsOption)</p>

<p>FTLanguageOption := "language" UnionExpr ("collation" CollationUri)?</p><resolution><p> CLOSED.</p><p>Postponed to VNext.</p></resolution>
</issue>


<issue id="ft-about-operator" status="closed">
	<head> Free-text search operator ft-about (VNext, Cluster H, Issue 58)</head>

       <p>While 'ftcontains' is aimed at supporting full text queries
       for XPath/XQuery still it lacks internet-style IR searches
       where the user can't express precisely her needs and would like
       to let the search engine return also close matches. For example
       a user need like "+cat dog" which request to find documents
       that contain a 'cat' but rank those that contain also a 'dog'
       higher is hard to express with 'ftcontains'. With
       'ftcontains' one can express either ftcontains(cat and dog)
       which will return only documents that have both cat and dog or
       ftcontains(cat or dog) which will return documents containing
       cat or dog. None is what the user needs. </p>

       <p>In order to express the above user need in XQuery-FT one
       needs to separate the user need into a filtering part and a
       scoring part. For example, the XQuery syntax to find all books
       with a title that contains a 'cat', but give those that contain
       also a 'dog' a higher ranking is shown below. </p>

  <eg role="parse-text" xml:space="preserve">
for $book in /books/book
where $book/title ftcontains "cat" 
let $score := ft:score($book/title ftcontains "cat" || "dog")
where $score &gt; 0
order by $score
return $book
    </eg>
       <p>The first 'ftcontains' is needed for filtering while the
       second 'ftcontains' is for scoring. We see that the search
       arguments of the two 'ftcontains' predicates are quite similar
       with the difference that the first contains 'cat' while the
       second contains also 'dog'. In general, this results in rather
       complex queries that redundantly have to repeat the same query
       terms in different query parts, even for simple user needs.</p>

       <p>A proposal to overcome this problem has been put forward by
       Yosi Mass (IBM Research) and Jochen Doerre 
       by introducing a free-text operator 'ft-about' that allows to
       specify Internet-style searches directly. For instance, the
       query above could be expressed without duplication as:</p> 
  <eg role="parse-text" xml:space="preserve">
for $book in /books/book
let $score := ft:score($book/title ft-about "+cat dog")
where $score &gt; 0
order by $score
return $book
    </eg>

    <p>For more details see 
       <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2004Nov/0019.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
    </p>
    <p>Open question: how can ft-about be integrated more tightly with
    ftcontains?</p>

<p>Raised by Jochen.
</p>
<resolution><p> CLOSED.</p> <p>No change to the document with
  resolution that it is to be considered for VNext, because it is not
  clear how it will fit with the grammar and the data model and it is
  not clear what the ftabout search would do and how tightly we could
  define it.</p><p>See F2F minutes in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jul/0049.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p></resolution>
</issue>
  
<issue id="error-codes" status="open">
	<head>Error Codes(Cluster J, Issue 59)</head> <p>XPath
        2.0, XQuery 1.0, and associated documents use 8-character
        error codes. The Full-Text spec uses 6-character error codes.
        Full-Text must be brought up to date and use 8-character error
        codes.</p>
</issue>



<issue id="extended-scoring" status="closed">
	<head> Extended Scoring (Cluster A, Issue 60)</head>

<p>
Motivation:</p>
<p>The proposal extends the previous (SCORE AS) scoring proposal in
two ways.
</p>

<olist>
<item>
<p>It provides a iterator that can iterate over an item *and* its score
in a single construct.</p></item>

<item>
<p>It allows users to relax the semantics of XPath/XQuery expressions
so that users can obtain "fuzzy" results along with their scores.</p>
</item>
</olist>

<p>
The benefit of (1) is that it makes queries easier to write since the
score is directly attached to an item in a single construct. This is
in contrast to the original scoring proposal, where a FOR clause is
required to iterate over items and a separate SCORE AS clause
is required to score the items.
</p>

<p>
The benefit of (2) is that it generalizes traditional Information Retrieval (IR) and can
capture the class of queries used by the XML IR community (notably INEX). 
In traditional IR, end-users who ask keyword queries are perfectly 
happy when the system returns documents that contains those keywords or
stemmed versions of those keywords or synonyms. By analogy, XQuery FT
(like INEX) should allow the possibility of interpreting XQuery expressions
(i.e., queries on both content and structure) in a fuzzy way on behalf of 
users. This should make the query specification less cumbersome for users 
since they do not have to (and may not be able to) explicitly specify all 
the query variants. 
</p>

<p>
The proposal can be divided into three separate parts that can be decided upon independently.</p>
<olist>
<item>
<p> Extend FOR clause with a score binding option.</p>
<p>
Proposed syntax: 
  <eg xml:space="preserve">
    for $res scored $score in EXPR
    </eg>
</p>

<p>Semantics:</p>
<p>
Let S be the result of evaluating the XQuery expression EXPR.</p>

<p>
As a normal FOR clause this clause iterates over each item in S and 
binds $res to the item, but also binds $s to the score of the item. 
</p>

<p>
Like in the SCORE AS clause we need to assume a second-order 
function for the evaluation of EXPR. E.g., it makes a difference, 
whether EXPR is a just a function call which evaluates to some 
sequence, or is the equivalent body of the function. Only in the
latter case the scoring can take the evaluation of the function
body into account.
</p>

<p>
We might want to restrict the kinds of expressions allowed in EXPR as 
discussed below in 3.
</p>
</item>


<item>
<p> Add FUZZY keyword to scoring constructs.</p>
<p>
Proposed syntax (when combined with extended for):
  <eg xml:space="preserve">
    for $res scored $score in fuzzy EXPR
    </eg>
</p>

<p>
(when combined with SCORE AS):
  <eg xml:space="preserve">
    score $s as fuzzy EXPR
    </eg>
</p>

<p>
Motivation: allow for query relaxation based on relevance; find 
also items relevant to the query that are near matches.</p>

<p>
Semantics:
Based on super-sequence (as specified in 
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0152.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>)
Any result to the non-scoring variant of the expression
is a result, but there may be more.
</p>
</item>

<item>
<p> Should we restrict expressions over which scoring is
done to, say, Boolean combinations of FTContainsExpr?</p>

<p>
This applies to both the proposed new FOR syntax, as well as
the SCORE AS clause.</p>
<p>
Note: Because scoring semantics is completely implementation-dependent, 
implementations are free to simply ignore the embedding of search 
expression inside XPaths, for instance.</p>
</item>

<item>
<p> In combination with 1., extend LET clauses with a
score binding option, just as 1. extends FOR clauses.</p>

<p>
This syntax replaces the SCORE AS clause.</p>
<p>
Proposed syntax: 
  <eg xml:space="preserve">
    let $v := EXPR scored $score
    </eg>
</p>
<p>
In contrast to the SCORE AS clause where EXPR is evaluated to 
only calculate a score, but not a result, this syntax allows
to calculate a pair (result, score), as it is done in the
FOR clause extension above.

</p>
</item>
</olist>

<p>
Benefits of extended scoring:
</p>

<ulist>
<item><p>Can score over all of XQuery (note that Expr can be an arbitrary
XQuery expression).</p>
</item>
<item><p>Can support query relaxation using the FUZZY keyword.</p>
</item>
<item><p>Makes the syntax of queries simpler (illustrated below).</p>
</item>
<item><p>Can be integrated with XPath.</p>
</item>
<item><p>Can be combined with the ORDERBY clause of FLWOR to sort results based
on their scores.</p>
</item>
</ulist>

<p>
Examples:</p>
<p>
One of the main motivations for the  scoring FOR proposal is the ability to
express XML information retrieval queries such as the INEX queries 
(see http://inex.is.informatik.uni-duisburg.de:2004/). INEX is an
effort that collects XML documents to assess scoring methods for XML
in the same way as TREC was defined for assessing keyword search.
</p>
<p>
We give some examples below and explain the syntax/semantics of the
new scoring construct.
</p>

<p>
Query 1: Find articles on "Usability"
</p>

<p>Expressed using scoring FOR:

  <eg xml:space="preserve">
for $result scored $score in //article[. ftcontains "Usability"]
return &lt;result score="{$score}"&gt;{$result}&lt;/result&gt;
    </eg>

The above query returns all articles and their score, where the score
is computed with respect to the predicate: $a ftcontains "Usability".
</p>

<p>
Expressed using SCORE AS:

  <eg xml:space="preserve">
for $result in //article
score $score as $result ftcontains "Usability"
return &lt;result score="{$score}"&gt;{$result}&lt;/result&gt;
    </eg>

This illustrates how "scoring FOR" has a more compact syntax than SCORE AS
when scoring over Boolean expressions such as ftcontains.
</p>

<p>
Query 2: Find articles and other documents on "Usability".
</p>
<p>
Expressed using scoring FOR:

  <eg xml:space="preserve">
for $result scored $score in fuzzy //article [. ftcontains "Usability"]
order by $score
return &lt;result score = "{$score}"&gt;{$result}&lt;/result&gt; 
    </eg>

The above query returns articles and other documents along with their scores,
ordered by score. Note that //article can be interpreted in a fuzzy
way since  scoring FOR can return a super-sequence of the corresponding
XQuery sequence.
</p>

<p>
Expressed using SCORE AS (Version 1):

  <eg xml:space="preserve">
for $result in //article
score $score as $result ftcontains "Usability"
order by $score
return &lt;result score = "{$score}"&gt;{$result}&lt;/result&gt;
    </eg>

The above query only returns articles (and not other documents) that
are relevant to "Usability". In this sense, this SCORE AS query is
not semantically the same as the above scoring FOR query.
</p>
<p>
Expressed using SCORE AS (Version 2):

  <eg xml:space="preserve">
for $result in //*
score $score as tagname($result) = "article" and $result ftcontains "Usability"
order by $score
return &lt;result score = "{$score}"&gt;{$result}&lt;/result&gt;
    </eg>

The above query returns all elements (not just articles) ordered by
the score of how well the element's tag name matches "article" and
how relevant it is to "Usability". However, this syntax has two
disadvantages compared to the scoring FOR. First, it is more clumsy to write
compared to the scoring FOR syntax. Second, the system has to return *all*
elements (not just those closely related to article) unless the
user performs some explicit filtering based on scores; in contrast,
the scoring FOR query only returns elements that are related to articles.
</p>

<p>
Query 3 (topic 128 in INEX): Find discussions about on-board route planning or navigation systems
which are in publications about intelligent transport systems for
automobiles.
</p>
<p>
Expressed using  scoring FOR:
 
  <eg xml:space="preserve">
for $result scored $score 
  in fuzzy //article[. ftcontains "intelligent transport systems"]
             /sec[. ftcontains 
                  "on-board route planning navigation system for automobiles"]
return &lt;result score = "{$score}"&gt;{$result}&lt;/result&gt; 
    </eg>

Since scoring FOR interprets the entire expression in a fuzzy way, it can relax
the tag names of //article and /sec. In addition, it can relax /sec to
//sec to find sections that may be indirectly contained in article.
</p>
<p>
Expressed using SCORE AS (Version 1):

  <eg xml:space="preserve">
for $a in //article, $s in $a/sec
score $score as $a ftcontains "intelligent transport systems"
      and $s ftcontains "on-board route planning navigation system for automobiles"
return &lt;result score = "{$score}"&gt;{$s}&lt;/result&gt;
    </eg>

Using this version of SCORE AS, we cannot support relaxations of the
tag names of //article and /sec. Further, SCORE AS cannot explicitly
support the relaxation of /sec to //sec. Note that simply replacing
$a/sec with $a//sec is not semantically equivalent because, in this case,
$a/sec will *not* be ranked higher than $a//sec (which it will be in
the case of scoring FOR).
</p>
<p>
Expressed using SCORE AS (Version 2):

  <eg xml:space="preserve">
for $a in //*, $s in $a/*
score $score as tagname($a) = "article" and tagname($s) = "section" 
      and $a ftcontains "intelligent transport systems"
      and $s ftcontains "on-board route planning navigation system for automobiles"
return &lt;result score = "{$score}"&gt;{$s}&lt;/result&gt;
    </eg>

This version of SCORE AS is less readable than the version using
scoring FOR. Also, it is not possible to relax $a/* to $a//* (as in the
Version 1) without losing some scoring semantics.
</p>

<p>
Raised by Sihem and Jai in 
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Mar/0152.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
</p>
<resolution><p> CLOSED.</p> <p>1. Use in definition of score: Score is
between 0 and 1 regardless of whether the ftcontains expression
returns true or false. Score is inherently fuzzy. Can compute a score
independently of computing the Boolean value. </p> <p>2. Use two
syntaxes for score, replacing the current syntax: 1) Use to return
exactly what the Boolean returns.  for $b score $s in
//books[. ftcontains "dog"] return &lt;r&gt;{$b, $s}&lt;/r&gt; 2.a) Use to return
more or less than the Boolean returns. To use fuzzy within score. Must
have one let clause, could have more than one.  for $b in //books let
score $s := $b ftcontains "dog" let $t := $b ftcontains "dog" return
&lt;r&gt;{$b, $s}&lt;/r&gt; 2.b) Use to return more or less than the Boolean
returns. To use fuzzy within score.  for $b in //books let $t score $s
:= $b ftcontains "dog" return &lt;r&gt;{$b, $s}&lt;/r&gt;.</p><p> 3. Use this
semantics: for $res score $s in Expr has the semantics of for
$scoreSeq := fts:scoreSequence (Expr) for $res at $i in Expr let $s :=
$scoreSeq [$i] </p><p>See F2F minutes in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jul/0049.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p></resolution>

</issue>

<issue id="desired-fttimes-semantics" status="open">
	<head>Desired semantics of FTTimes (Cluster G, Issue 61)</head>
	<p>Consider the document</p>
	<eg xml:space="preserve">cat cat</eg>
	<p>and the query</p>
	<eg xml:space="preserve">("cat" &amp;&amp; "cat") occurrences exactly 4</eg>
	<p>Currently, it returns true. Is this the desired semantics 
	for FTTimes?  If yes, how do we explain it in the language 
	document?</p>
</issue>
 
<issue id="doublenegation-semantics" status="open">
	<head>Precise semantics of double negation (Cluster G, Issue 62)</head>
	<p>Currently, (! ! Q) does not produce the same AllMatches 
	   as (Q). There seem to be two reasons for that. First, 
	   there are duplicate StringIncludes, StringExcludes, and 
	   Matches. Second, there are Matches that are subsumed by 
	   other Matches (i.e. the former are a logical consequence 
	   of the latter). How do we handle these situations? It 
	   seems reasonable to expect that !!Q produces the same 
	   result as Q.</p>
</issue>

<issue id="phrases-with-distance" status="open">
	<head>Distance constraints do not work on phrases (Cluster G, Issue 63)</head>
	<p>It is not possible to combine the distance operation with 
        searching for phrases.</p>

        <p>Example: 
<eg xml:space="preserve">
[. ftcontains "Redmond-based" &amp;&amp; "company" distance at least 2]
</eg>
        The problem is that a phrase is internally resolved into a
        distance operation itself, which can impose a contradicting
        requirement to the explicit distance operation used in the
        query. Here it is (with some assumptions on tokenization):  

<eg xml:space="preserve">
[. ftcontains ("Redmond" &amp;&amp; "-" &amp;&amp; "based" ordered with distance 0) &amp;&amp; "company" distance at least 2]
</eg>

        The second distance constraint is then imposed to all
        individual tokens (including those from the phrase) and hence
        cannot be satisfied. The query will also return false.</p> 
</issue>
  
<issue id="relativedefaults" status="open">
	<head>System Relative Operator Defaults (Cluster E, Issue 64)</head>
	<p>Do we want to add system relative operator defaults? Do we
        want to add "closer and "farther" to FTDistance for novice
        users who do not want to enter specific numbers of intervening
        words, sentences, and paragraphs? Similar relative defaults
        might also be added to other operators which call FTRange and
        score weighting.</p> 
        <p>Raised by Dana Florescu at Redmond Face to Face Meeting on
        July 15, 2005.</p>
</issue>


<issue id="nested-ftnegations-right-side-ftmildnegation" status="closed">
	<head>Nested FTNegations on Right Side of FTMildNegation
	(VNext, Cluster I, Issue 65)</head> <p/>
    <resolution>
        <p>CLOSED.</p> <p> Raise a dynamic error semantically if there
is a StringExclude on the right side of an FTMildNegation. Users can
replace "&amp;&amp; not" with FTMildNegation. Possibly reconsider for
VNext.</p> <p>No changes required. Closed at F2F Meeting 84: <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://lists.w3.org/Archives/Member/member-query-fttf/2005Jul/0061.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></p>
    </resolution>
</issue>

                                                                
</div1>

        <div1 id="ft-acknowledgements">
	<head>Acknowledgements</head>

<p>We would like to thank the members of the XQuery and XPath
Full-Text group for their fruitful discussions. </p>

<p>We would like to thank the following people for their contributions on earlier drafts of this document.</p>

<ulist>
  <item><p> "Andrew Eisenberg" - IBM - andrew.eisenberg@us.ibm.com</p></item>
  <item><p> "Roland Seiffert" - IBM -  seiffert@de.ibm.com</p></item>
  <item><p> "Andrew Cencini" - Microsoft - acencini@microsoft.com </p></item>
  <item><p> "Nimish Khanolkar" - Microsoft - nimishk@exchange.microsoft.com </p></item>
  <item><p> "Ashok Malhotra" Oracle - ashok.malhotra@oracle.com </p></item>
  <item><p> "Tapas Nayak" Microsoft - tapasnay@exchange.microsoft.com </p></item>
</ulist>
</div1>

        <div1 id="ft-glossary">
	<head>Glossary</head>

<p> This section contains definitions of important terms in this document. </p>

<p>Certain aspects of language
		processing are described in this specification as
		<term>implementation-defined</term> or
		<term>implementation-dependent</term>.</p>

<ulist>
  <item>
    <p><termdef id="dt-implementation-defined" term="implementation defined"><term>Implementation-defined</term>
		indicates an aspect that may differ between
		implementations, but must be specified by the
		implementor for each particular
		implementation.</termdef></p>
  </item>
  <item>
    <p><termdef id="dt-implementation-dependent" term="implementation   dependent"><term>Implementation-dependent</term>
		indicates an aspect that may differ between
		implementations, is not specified by this or any W3C
		specification, and is not required to be specified by
		the implementor for any particular
		implementation.</termdef></p>
  </item>
</ulist>

<p><termdef id="dt-module" term="module">A <term>module</term> is a 
  fragment of XQuery code that conforms to
  the module grammar defined in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/TR/xquery/#doc-xquery-Module" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XQuery 1.0: An
  XML Query Language draft</loc>.</termdef> Each module is either a <termref def="dt-main-module">main module</termref> or a <termref def="dt-library-module">library module</termref>.
</p>
<p><termdef id="dt-main-module" term="main module">A <term>main
  module</term> consists of a <termref def="dt-prolog">Prolog</termref>
  followed by a <termref def="dt-queryBody">Query
  Body</termref>.</termdef> A query has exactly one main module. In a
  main module, the <termref def="dt-queryBody">Query Body</termref> can
  be evaluated, and its value is the result of the query.
</p>
<p><termdef id="dt-library-module" term="library module">A module that does not
  contain a <termref def="dt-queryBody">Query Body</termref> is called a
  <term>library module</term>. A library module consists of a <termref def="dt-module-declaration">module declaration</termref> followed by a
  <termref def="dt-prolog">Prolog</termref>.</termdef> A library module
  cannot be evaluated directly; instead, it provides function and
  variable declarations that can be imported into other
  modules.
</p>
<p>The XQuery syntax does not allow a <termref def="dt-module">module</termref> to contain both a <termref def="dt-module-declaration">module declaration</termref> and a
<termref def="dt-queryBody">Query Body</termref>.
</p>
<p><termdef id="dt-prolog" term="Prolog">A <term>Prolog</term> is a series of
  declarations and imports that define the processing environment for
  the <termref def="dt-module">module</termref> that contains the
  Prolog.</termdef> Each declaration or import is followed by a
  semicolon. A Prolog is organized into two parts. 
</p>
<p>
  The first part of the Prolog consists of setters, imports, 
  namespace declarations, and default namespace declarations. 
  <termdef term="setter" id="dt-setter"><term>Setters</term> are 
  declarations that set the value of some property that affects query 
  processing, such as construction mode, ordering mode, or default 
  collation.</termdef>
  Namespace declarations and default namespace declarations affect the
  interpretation of QNames within the query.  Imports are used to import
  definitions from schemas and modules. <termdef term="target namespace" id="dt-target-namespace">Each imported schema or module is identified
  by its <term>target namespace</term>, which is the namespace of the
  objects (such as elements or functions) that are defined by the schema
  or module.</termdef> 
</p>
<p>The second part of the Prolog consists of
  declarations of variables, functions, and options. These declarations
  appear at the end of the Prolog because they may be affected by
  declarations and imports in the first part of the
  Prolog.
</p>
<p><termdef id="dt-queryBody" term="query body">The
  <term>Query Body</term>, if present, consists of an expression that
  defines the result of the query</termdef>. A module can be evaluated only if it
  has a Query Body.</p>

<p><termdef id="dt-module-declaration" term="module declaration">A
  <term>module declaration</term> serves to identify a <termref def="dt-module">module</termref> as a <termref def="dt-library-module">library module</termref>. A module declaration
  begins with the keyword <code>module</code> and contains a namespace
  prefix and a URILiteral</termdef>.</p>

</div1>

        
<!-- JD
<div1 role="xquery" id="id-xqft-context-components"><head>Context
Components</head><p>The tables in this section describe how values are
assigned to the various components of the static context and dynamic
context, and to the parameters that control the serialization
process.</p>
-->

<div1 id="id-xqft-static-context-components"><head>Static Context
Components</head><p>The following table describes the full-text components of
the <term>static context</term>. The following aspects of each
component are described:</p><ulist><item><p><emph>Default initial
value:</emph> This is the initial value of the component if it is not
overridden or augmented by the implementation or by a query.</p>
</item><item><p><emph>Can be overwritten or augmented by
implementation:</emph> Indicates whether an XQuery implementation is
allowed to replace the default initial value of the component by a
different, <termref def="dt-implementation-defined">implementation-defined</termref> value
and/or to augment the default initial value by additional <termref def="dt-implementation-defined">implementation-defined</termref>
values.</p></item><item><p><emph>Can be overwritten or augmented by a
query:</emph> Indicates whether a query is allowed to replace and/or
augment the initial value provided by default or by the
implementation. If so, indicates how this is accomplished (for
example, by a declaration in the
prolog).</p></item><item><p><emph>Scope:</emph> Indicates where the
component is applicable. "Global" indicates that the component applies
globally, throughout all the modules used in a query. "Module"
indicates that the component applies throughout a <termref def="dt-module">module</termref>. "Lexical" indicates that the
component applies within the expression in which it is defined
(equivalent to "module" if the component is declared in a <termref def="dt-prolog">Prolog</termref>.)</p></item><item><p><emph>Consistency
Rules:</emph> Indicates rules that must be observed in assigning
values to the component. </p></item></ulist><table width="100%" border="1" summary="Static Context" role="small">
<caption>Static Context Components</caption>

<tbody>
<tr>
<th rowspan="1" colspan="1">Component</th> <th rowspan="1" colspan="1">Default initial value</th> <th rowspan="1" colspan="1">Can be
overwritten or augmented by implementation?</th> <th rowspan="1" colspan="1">Can be
overwritten or augmented by a query?</th> <th rowspan="1" colspan="1">Scope</th>
<th rowspan="1" colspan="1">Consistency rules</th>
</tr>

<tr>
<td rowspan="1" colspan="1"><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftcaseoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTCaseOption</loc></td> <td rowspan="1" colspan="1"><code>case
insensitive</code></td> <td rowspan="1" colspan="1">overwriteable</td>
<td rowspan="1" colspan="1">overwriteable by prolog</td> <td rowspan="1" colspan="1">lexical</td> 
<td rowspan="1" colspan="1">Value must be
<code>case insensitive</code> or <code>case sensitive</code>.</td>
</tr>

<tr>
<td rowspan="1" colspan="1"><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftdiacriticsoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTDiacriticsOption</loc></td>
<td rowspan="1" colspan="1"><code>diacritics insensitive</code></td> <td rowspan="1" colspan="1">overwriteable</td> 
<td rowspan="1" colspan="1">overwriteable by prolog</td> <td rowspan="1" colspan="1">lexical</td> 
<td rowspan="1" colspan="1">Value must be <code>diacritics insensitive</code> or
<code>diacritics sensitive</code>.</td>
</tr>

<tr>
<td rowspan="1" colspan="1"><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftstemoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTStemOption</loc></td>
<td rowspan="1" colspan="1"><code>without stemming</code></td> <td rowspan="1" colspan="1">overwriteable</td> 
<td rowspan="1" colspan="1">overwriteable by prolog</td> <td rowspan="1" colspan="1">lexical</td> 
<td rowspan="1" colspan="1">Value must be <code>without stemming</code> or
<code>with stemming</code>.</td>
</tr>

<tr>
<td rowspan="1" colspan="1"><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftthesaurusoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTThesaurusOption</loc></td>
<td rowspan="1" colspan="1"><code>without thesaurus</code></td> <td rowspan="1" colspan="1">overwriteable</td> 
<td rowspan="1" colspan="1">overwriteable by prolog (refer to default to augment)</td> 
<td rowspan="1" colspan="1">lexical</td> 
<td rowspan="1" colspan="1"> Value must be part of the statically known thesauri.</td>
</tr>

<tr>
<td rowspan="1" colspan="1">Statically known thesauri</td>
<td rowspan="1" colspan="1">none</td> <td rowspan="1" colspan="1">augmentable</td> 
<td rowspan="1" colspan="1">cannot be augmented or overwritten by prolog</td> <td rowspan="1" colspan="1">module</td> 
<td rowspan="1" colspan="1"> Each URI uniquely identifies a thesaurus list.</td>
</tr>

<tr>
<td rowspan="1" colspan="1"><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftstopwordoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTStopWordOption</loc></td>
<td rowspan="1" colspan="1"><code>without stopwords</code></td> <td rowspan="1" colspan="1">overwriteable</td> 
<td rowspan="1" colspan="1">overwriteable by prolog (refer to default to augment)</td> 
<td rowspan="1" colspan="1">lexical</td>
<td rowspan="1" colspan="1">Value must be part of the statically known stop word lists.</td>
</tr>

<tr>
<td rowspan="1" colspan="1">Statically known stop word lists</td>
<td rowspan="1" colspan="1">none</td> <td rowspan="1" colspan="1">augmentable</td> 
<td rowspan="1" colspan="1">cannot be augmented or overwritten by prolog</td> <td rowspan="1" colspan="1">module</td> 
<td rowspan="1" colspan="1">Each URI uniquely identifies a stop word list.</td>
</tr>

<tr>
<td rowspan="1" colspan="1"><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftlanguageoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTLanguageOption</loc></td> 
<td rowspan="1" colspan="1">no language is selected</td> <td rowspan="1" colspan="1">overwriteable</td>
<td rowspan="1" colspan="1">overwriteable by prolog</td> <td rowspan="1" colspan="1">lexical</td> 
<td rowspan="1" colspan="1">Value must be castable to "xs:language" or "none".</td>
</tr>

<tr>
<td rowspan="1" colspan="1"><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#ftwildcardoption" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FTWildCardOption</loc></td>
<td rowspan="1" colspan="1"><code>without wildcards</code></td> <td rowspan="1" colspan="1">no</td> 
<td rowspan="1" colspan="1">overwriteable by prolog</td> <td rowspan="1" colspan="1">lexical</td>
<td rowspan="1" colspan="1">Value must be <code>without wildcards</code> or <code>without
wildcards</code>.</td>
</tr>

</tbody>
</table>

</div1>


        <div1 id="id-xqft-changelog">
<head>Change Log</head>
<table border="0" summary="Change Log Table">
<tbody>
<!--
=================== commented out from here
<tr>
<td>Jochen Doerre</td>
<td>2004-10-04</td>
<td>Added issue on FTIgnore</td>
<td>Added Cluster B, Issue 50 IGNORE Queries.</td>
</tr>
<tr>
<td>Jochen Doerre</td>
<td>2004-10-04</td>
<td>Added issue on FTWindow</td>
<td>Added Cluster I, Issue 51 Alternative Semantics for FTWindow.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-14</td>
<td>Added issue on UnionExpr in StopWords</td>
<td>Added Cluster D, Issue 52 UnionExpr in StopWords.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-16</td>
<td>Added FTStartswith to syntax</td>
<td>Added Section 3.1.12 on startswith. Closed Cluster C, Issue 40 Starts With</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-16</td>
<td>Removed FTSpecialCharacter syntax</td>
<td>Removed the Special Character match option in section 3 and closed Cluster E, Issue 22 DiacriticsMatchOption and Cluster E, Issue 24 SpecialCharMatchOption.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-16</td>
<td>Updated FTLanguage syntax</td>
<td>Added the sentence "The set of valid language identifiers is implementation-defined." in Section 3.2.7 (now 3.2.6) FTLanguage.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-16</td>
<td>Updated score syntax</td>
<td>Changed syntax of ft:score() into score $var as Expr in Section 3.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-16</td>
<td>Added score weighting syntax</td>
<td>Added 1) weight to FTSelection inside a scoring expression and 2) text stating that Weight values in scoring expressions are in the interval [0,1]. Closed Cluster A, Issue 17 Weighting and Cluster A, Issue 18 Weight Values.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-24</td>
<td>Changed FTStartswith syntax to FTContent syntax</td>
<td>Changed FTStartswith to FTContent and changed wording to use "the tokenized string of elements".</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-24</td>
<td>Added issue on defaults</td>
<td>Added issue Cluster D, Issue 45 MatchOptions Default.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-01-24</td>
<td>Changed FTStopWords and FTThesaurus syntax</td>
<td>Closed Cluster E, Issue 26 StopWordsMatchOption, Cluster E, Issue 48 Stop words option, and Cluster D, Issue 8 Thesaurus, among other things changing the syntax to allow URIs for a stop word list or thesaurus.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-01</td>
<td>Added issue on score weights</td>
<td>Added Issue 54 Cluster A on weights in scores.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-10</td>
<td>Updated FTStopwords syntax</td>
<td>Updated syntax in Section 2.3.5 Stop Words.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-10</td>
<td>Updated FTThesaurus section</td>
<td>Updated descriptive text, adding reference to ISO 2788, in Section 2.3.4 Theasurus.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-10</td>
<td>Updated introduction</td>
<td>Modified item 7 in Section 1.1 to reflect conditions on tokenizers.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-10</td>
<td>Updated FTDistance syntax</td>
<td>Removed the optional keyword "with" from FTDistance.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-10</td>
<td>Updated FTWindow syntax</td>
<td>Removed the optional keyword "within" from FTWindow.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-14</td>
<td>Updated FTDiacritics syntax</td>
<td>Closed Cluster E, Issue 33 FTSpecialCharOption and Updated Section 3.2.2 Diacritics according to its resolution.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-14</td>
<td>Added FTCase and FTDiacritics matrices</td>
<td>Added matrices which summarize the interaction between the diacritics and case match options and types of collations.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-14</td>
<td>Added FTRegex escape syntax</td>
<td>Closed Cluster C, Issue 15 RegExp Escape by adding wildcard escape syntax.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-14</td>
<td>Updated FTThesaurusOption and FTRegexOption semantics</td>
<td>Updated FTThesaurusOption and FTRegexOption in Section 4 Semantics.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-14</td>
<td>Updated FTDiacritics semantics</td>
<td>The fts:applySingleSearchToken function in the match-options semantics section has been modified. Now it explicitly checks for the diacritics option and applies the necessary semantic functions.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-14</td>
<td>Removed FTSpecialCharacter semantics</td>
<td>Removed the special-characters option semantics.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-14</td>
<td>Updated FTStopWord semantics</td>
<td>Changed the XML representation and the fts:ApplyStopwordOption semantic function to reflex the new syntax.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-14</td>
<td>Added FTContent semantics</td>
<td>Added an XML representation and a semantic function for FTContent.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-18</td>
<td>Updated FTRegex syntax</td>
<td>Closed Cluster C, Issue 27 MatchOption and Tokenization which required changes only to FTRegex specifying it impact on tokenization. Text added.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-21</td>
<td>Replaced FTRegex syntax with FTWildcard syntax</td>
<td>Replaced FTRegex syntax with FTWildcard syntax in Section 3.2.8</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-02-21</td>
<td>Added issue proposing FTCollationOption</td>
<td>Added Cluster D, Issue 57 Collations Match Option.</td>
</tr>
<tr>
<td>Jochen Doerre</td>
<td>2005-02-22</td>
<td>Closed issues resolved previously</td>
<td>Closed Cluster A, Issue 1 Scoring Properties with no change to the document. Closed Cluster C, Issue 7 Wildcards - regular expressions were dropped in favor of wildcards. Closed Cluster F, Issue 31 Optional Keyword "with" in FTDistance - "with" was dropped. Closed Cluster F, Issue 32 Optional Keyword "within" in FTWindow - "within" was dropped. Closed Cluster F, Issue 34 FTNegation Includes Unary Not with no change to the document.</td>
</tr>
<tr>
<td>Jochen Doerre</td>
<td>2005-02-22</td>
<td>Added issue on ft-about</td>
<td>Added Cluster H, Issue 58 Free-text search operator ft-about.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-22</td>
<td>Updated FTDistance semantics</td>
<td>Removed the optional keyword "with" from FTDistance.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-22</td>
<td>Updated FTWindow semantics</td>
<td>Removed the optional keyword "within" from FTWindow.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-22</td>
<td>Updated FTWords semantics</td>
<td>Updated FTWords semantics to allow for zero-length string: An FTWords with an empty list of search tokens returns an empty AllMatches.</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-02-22</td>
<td>Replaced FTRegex semantics with FTWildcards semantics</td>
<td>Replaced FTRegex semantics with FTWildcards semantics.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-03-03</td>
<td>Updated FTWildcards syntax</td>
<td>Updated FTWildcards syntax in Section 3.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-03-04</td>
<td>Updated Section 2 (syntax) and issues list</td>
<td>Closed and updated Section 2 to reflect resolutions for 1) Cluster F, Issue 30 Precedence of XQuery and full-text, 2) Cluster G, Issue 47 Zero-length phrase, 3) Cluster F, Issue 49 Grammar Precedence and Lookahead. Also added introduction to the Issues List explaining the clusters.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-03-04</td>
<td>Updated FTIgnoreOption syntax</td>
<td>Updated FTIgnoreOption in Section 3.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-03-04</td>
<td>Updated FTThesaurus examples</td>
<td>Added "at" in thesaurus examples in Section 3.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-03-04</td>
<td>Updated FTWindow section</td>
<td>Added descriptive text to FTWindow.</td>
</tr>
<tr>
<td>Scott Boag</td>
<td>2005-03-10</td>
<td>Updated grammar</td>
<td>1) Integrated full-text grammar (including the "{" "}" bracketing of expressions) into the main XPath grammar file. 2) Changed the way ftcontains is called. 3) Generated parser is now generated without any lookahead enabled.</td> 
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-03-17</td>
<td>Updated Thesauri lookup</td>
<td>Closed Cluster D, Issue 42 Thesauri lookup for multi-word phrases, and updated section 4 to reflect the changes.
</td>
</tr>
<tr>
<td>Chavdar Botev</td>
<td>2005-03-17</td>
<td>Added text to describe schemas</td>
<td>Added two paragraphs to FTSelections and FTMatchOptions which describe the schemas.
</td>
</tr>
<tr>
<td>Scott Boag</td>
<td>2005-03-19</td>
<td>Updated FTThesaurus production</td>
<td>Updated FTThesaurus production by adding "at" before "except" and "union".</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-03-22</td>
<td>Removed ft and fts namespace references</td>
<td>Removed references to the ft (full-text) and fts (full-text semantics) namespaces.</td>
</tr>
<tr>
<td>Sihem Amer-Yahia</td>
<td>2005-03-28</td>
<td>Updated FTThesaurus syntax</td>
<td>Updated FTThesaurus in Section 3.</td>
</tr>
============= commented out upto here
-->

<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-04-08</td>
<td rowspan="1" colspan="1">Updated case matrix</td>
<td rowspan="1" colspan="1">Updated case matrix row "sensitive", column "CCI" from "case-insensitive variant of CCI if it exists, else error" to 
"case-sensitive variant of CCI if it exists, else error".</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-02</td>
<td rowspan="1" colspan="1">Closed issues with no changes</td>
<td rowspan="1" colspan="1">Closed Cluster B, Issue 28 IGNORE Syntax with no change to the document. Closed Cluster B, Issue 50 IGNORE Queries with no change to the document.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-02</td>
<td rowspan="1" colspan="1">Updated FTTimes syntax</td>
<td rowspan="1" colspan="1">Closed Cluster G, Issue 14 FTTimesSelection and added a related bullet item in Section 3.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-02</td>
<td rowspan="1" colspan="1">Updated FTWildCard syntax</td>
<td rowspan="1" colspan="1">Updated FTWildCardOption in Section 3.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-03</td>
<td rowspan="1" colspan="1">Updated introduction</td>
<td rowspan="1" colspan="1">Replaced "semantic element" with "semantic markup" and "tag" with "element" in the introduction.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-03</td>
<td rowspan="1" colspan="1">Added issue on error codes</td>
<td rowspan="1" colspan="1">Added Cluster J, Issue 59 Error Codes.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-03</td>
<td rowspan="1" colspan="1">Closed issues with no change</td>
<td rowspan="1" colspan="1">Closed Cluster A, Issue 54 Weight Granularity in Scoring with same resolution as for Cluster A, Issue 5 Score Weighting, no further change to document. Closed Cluster H, Issue 9 Window with no change to the document. Closed Cluster H, Issue 19 FTScopeSelection on structure with no change to the document. Closed Cluster E, Issue 25 MatchOption Syntax with no change to the document. Closed Cluster H, Issue 44 FTContains Semantics with no change to the document.
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-03</td>
<td rowspan="1" colspan="1">Updated FTContent syntax</td>
<td rowspan="1" colspan="1">Updated FTContent adding "entire content", Closed Cluster C, Issue 39 Exact Element Content.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-03</td>
<td rowspan="1" colspan="1">Closed issue on Boolean Naming</td>
<td rowspan="1" colspan="1">Closed Cluster F, Issue 38 Boolean Naming. Changes to the document are pending awaiting a decision on whether it is OK to use "and", "or", "not" for full-text. If so change existing symbols to "and", "or", "not". If not change existing symbols to "ftand", "ftor", "ftnot".</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Chavdar Botev</td>
<td rowspan="1" colspan="1">2005-05-03</td>
<td rowspan="1" colspan="1">Updated FTDistance semantics</td>
<td rowspan="1" colspan="1">Updated the semantics for distance.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-03</td>
<td rowspan="1" colspan="1">Updated FTRange syntax</td>
<td rowspan="1" colspan="1">Made "exactly" required before an exact number in FTRange. Closed Cluster F, Issue 43 Exactly in FTRangeSpec.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-05-04</td>
<td rowspan="1" colspan="1">Closed issue on collations</td>
<td rowspan="1" colspan="1">Closed Cluster D, Issue 57 Collations Match Option.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-05-19</td>
<td rowspan="1" colspan="1">Added issue on scoring</td>
<td rowspan="1" colspan="1">Added Cluster A, Issue 60 Extended Scoring.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Chavdar Botev</td>
<td rowspan="1" colspan="1">2005-06-29</td>
<td rowspan="1" colspan="1">Added issue on FTNegation</td>
<td rowspan="1" colspan="1">Added Cluster G, Issue 62 Precise semantics of double negation.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Chavdar Botev</td>
<td rowspan="1" colspan="1">2005-06-29</td>
<td rowspan="1" colspan="1">Added issue on FTTimes</td>
<td rowspan="1" colspan="1">Added Cluster G, Issue 61 Desired semantics of FTTimes.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-07-11</td>
<td rowspan="1" colspan="1">Updated FTMildNegation syntax</td>
<td rowspan="1" colspan="1">Updated the mild not syntax from "mild not" to "not in". Closed Cluster I, Issue 10 MildNot and Cluster F, Issue 41 Mildnot Naming.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Chavdar Botev</td>
<td rowspan="1" colspan="1">2005-07-12</td>
<td rowspan="1" colspan="1">Updated FTIgnore semantics</td>
<td rowspan="1" colspan="1">Changed semantics of FTIgnoreOption.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-07-18</td>
<td rowspan="1" colspan="1">Corrected error codes</td>
<td rowspan="1" colspan="1">Corrected and added error codes, closing and implementing the resolution for Cluster J Issue 59 Error Codes.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-07-18</td>
<td rowspan="1" colspan="1">Closed issues with no changes</td>
<td rowspan="1" colspan="1">closed Cluster I, Issue 13 "loose-grammar" leaving the grammar as it is. Closed issue Cluster D, Issue 53 "matchoptions-default" with no change to the document. Closed Cluster H, Issue 58 "ft-about-operator" with no change to the document.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-07-21</td>
<td rowspan="1" colspan="1">Updated score syntax</td>
<td rowspan="1" colspan="1">Closed Cluster A, Issue 60 "new-scoring-proposal" and Issue 2
"scoring-values" and updated Section 2.2 Score Clause to reflect new score syntaxes. There are now syntaxes for scored queries 1) returning the same results as queries with Boolean predicates and 2) for returning more or fewer results.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-07-21</td>
<td rowspan="1" colspan="1">Added appendix for defaults</td>
<td rowspan="1" colspan="1">Added appendix for defaults in the query prolog analogous to C.1 in the XQuery language document.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-07-21</td>
<td rowspan="1" colspan="1">Updated FTThesaurus section</td>
<td rowspan="1" colspan="1">Aligned description in Section 3.2.4 FTThesaurusOption with current grammar.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-07-21</td>
<td rowspan="1" colspan="1">Opened and closed issue on nested FTNegation</td>
<td rowspan="1" colspan="1">Opened and closed Cluster I, Issue 65 Nested FTNegations on the right side of an FTMildNegation.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Chavdar Botev</td>
<td rowspan="1" colspan="1">2005-07-25</td>
<td rowspan="1" colspan="1">Updated FTMildNegation semantics</td>
<td rowspan="1" colspan="1">Changed the semantics of MildNot.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Sihem Amer-Yahia</td>
<td rowspan="1" colspan="1">2005-08-10</td>
<td rowspan="1" colspan="1">Added Change Log</td>
<td rowspan="1" colspan="1">Added Change Log harvesting back entries from CVS change log.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-17</td>
<td rowspan="1" colspan="1">Grammar changes</td>
<td rowspan="1" colspan="1">Changed XQuery/XPath grammar for new scoring syntax (resolution of
Issue 60), for match option defaults in query prolog (resolution of
Issue 45), for simplified window operator (resolution to Issue 51),
renamed "mild not" to "not in" (resolution of Issue 41), modified
FTThesaurusOption, FTStopwordOption and FTLanguageOption to require
StringLiterals as decided in May 05 F2F.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-17</td>
<td rowspan="1" colspan="1">Changes to Section 2</td>
<td rowspan="1" colspan="1">New scoring syntax introduced; rewritten most of 2.2. Corrected use
of weights in 2.2.1 (wrong default, wrong use of 1.5)</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-17</td>
<td rowspan="1" colspan="1">Changes to Section 3</td>
<td rowspan="1" colspan="1">Adapting the explanations to changed syntax for FTWindow,
FTThesaurusOption, FTStopwordOption and FTLanguageOption. Also
corrected a couple of example explanations. Removed FTIgnoreOption
from the list of match option defaults in 3.2 Corrected explanation
and example of FTLanguageOption (diacritics nor case are
language-specific!). Commented out last two examples of FTDistance,
because distance 15 does not work for phrases.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-17</td>
<td rowspan="1" colspan="1">Appendices A+B</td>
<td rowspan="1" colspan="1">Adapted introductory comment about which version of the
XQuery/XPath grammars we are aligned to.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-17</td>
<td rowspan="1" colspan="1">Dates in Header</td>
<td rowspan="1" colspan="1">Adapted current date and previous date and links in
full-text-query-language-semantics.xml and in tqheader.xml.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-19</td>
<td rowspan="1" colspan="1">Added Section 2.3, Changes in 3+4</td>
<td rowspan="1" colspan="1">Added Section 2.3 Extension to Static Context. Changed Sections 3.2
and 4.4.1.1 to refer to match option settings in the static context.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-19</td>
<td rowspan="1" colspan="1">Added Issue 63</td>
<td rowspan="1" colspan="1">Added Cluster G Issue 63: Distance constraints do not work on phrases.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-19</td>
<td rowspan="1" colspan="1">Changes in Section 4</td>
<td rowspan="1" colspan="1">Adapted semantics to new scoring feature (resolution of Issue 60),
changed FTWindow semantics according to resolution of Issue
51, and cleaned examples. </td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-19</td>
<td rowspan="1" colspan="1">Appendix G</td>
<td rowspan="1" colspan="1">Added lines for statically known thesauri and stop lists.</td>
</tr>
<tr>
<td rowspan="1" colspan="1">Jochen Doerre</td>
<td rowspan="1" colspan="1">2005-08-25</td>
<td rowspan="1" colspan="1">Added Issue 64</td>
<td rowspan="1" colspan="1">Added Cluster E Issue 64:System Relative Operator Defaults (using wording proposed by Pat Case).</td>
</tr>
</tbody>
</table>
</div1>

	</back>
</spec>