\documentclass[11pt]{article}

\usepackage{epsf,epsfig,subfigure,latexsym,makeidx,latexsym,xspace,amssymb,alltt}

\pagestyle{headings}
\bibliographystyle{plain}

%%\setlength{\topmargin}{-0.25in}
\setlength{\headheight}{10pt}
\setlength{\headsep}{30pt}
\setlength{\oddsidemargin}{0.0in}
\setlength{\evensidemargin}{0.0in}
\setlength{\textheight}{8.5in}
\setlength{\textwidth}{6.5in}
\setlength{\footskip}{50pt}


\setlength{\parskip}{2mm}               % space between paragraphs

\def\cut{\mbox{\tt '!'/0}}

\newtheorem{example}{Example}[section]

\newenvironment{Prog}{\begin{tt}\begin{tabular}[c]{l}}{\end{tabular}\end{tt}}

\newcommand{\comment}[1]{}

\newcommand{\demo}[1]{\hspace*{1.5cm}{\tt #1}}
\newcommand{\desc}[1]{\item[{\tt #1}]\hspace*{1mm}\newline}
\newcommand{\desce}[1]{\item[{\tt #1}]}
\newcommand{\ourrepeatitem}[1]{\item[{\mbox{\tt #1}}]\ \\ \vspace*{-.35in}}
\newcommand{\ouritem}[1]{\item[{\mbox{\tt #1}}]\ \\}
\newcommand{\ournewitem}[2]{\item[{\mbox{\tt #1}}]\hspace*{\fill}{\mbox{\sf #2}}\ \\}

\newcommand{\stuff}[1]{
        \begin{minipage}{4in}
        {\tt \samepage
        \begin{tabbing}
        \hspace{8mm} \= \hspace{6mm} \= \hspace{10mm} \= \hspace{55mm} \= \kill
        #1 \hfill
        \end{tabbing}
        }
        \end{minipage}
}

\newcommand{\longline}{\noindent\rule{\textwidth}{.01in}}


\newenvironment{qrules}{\begin{quote}\sf\begin{tabular}[t]{l}}%
{\end{tabular}\end{quote}}


\newcommand{\obj}{\textit{obj}\xspace}
\newcommand{\db}[1]{\ensuremath{\mathcal{#1}}}

\newcommand{\xany}{\textsf{any}}

\newcommand{\xplus}{\ensuremath{^+}}
\newcommand{\xstar}{\ensuremath{^*}}
\newcommand{\xinv}{\ensuremath{^{-1}}}
\newcommand{\xopt}{\ensuremath{^{?}}}

\newcommand{\xto}[1]{\ensuremath{^{#1}}}
\newcommand{\xcond}[1]{\ensuremath{\textsf{if}(#1)}}
\newcommand{\xif}[1]{\ensuremath{\textsf{if}(#1)}}
\newcommand{\xmu}[1]{\ensuremath{\tcmu(#1)}}
\newcommand{\xmuif}[2]{\ensuremath{\tcmu(#1,#2)}}


\newcommand{\xconc}{\ensuremath{{\cdot}}}
\newcommand{\xor}{\ensuremath{|}}

\newcommand{\nnot}{\mbox{$\neg$}}                           % negation
\newcommand{\query}{\mbox{$\, ?\! - \, $}}                  % query
\newcommand{\impl}                                          % implication
  {\mbox{\Large $\; {\bf \leftarrow} \;$}}  
\newcommand{\isa}{\,{\bf{:}}\,}
\newcommand{\subcl}{\,{\bf{::}}\,}
\newcommand{\eq}{\ensuremath{\doteq}}                           % equation

% f-logic arrows

\newcommand{\fd}{\ensuremath{{\rightarrow}}}                   % scalar
\newcommand{\bfd}{\ensuremath{{\bullet\!\!\!\fd}}}            % " + inheritable
\newcommand{\mvd}{\ensuremath{{\rightarrow\!\!\!\!\rightarrow}}}  % multivalued
\newcommand{\bmvd}{\ensuremath{{\bullet\!\!\!\mvd}}}              % " + inheritable
\newcommand{\Fd}{\ensuremath{{\Rightarrow}}}                      % scalar signature
\newcommand{\Mvd}{\ensuremath{{\Rightarrow\!\!\!\!\Rightarrow}}}  % multiv signature



% curved f-logic arrows

\newcommand{\anyd}{\ensuremath{\leadsto}}                       % non-inheritable
\newcommand{\bleadsto}{\ensuremath{\bullet\!\!\!\leadsto}}     % inheritable
\newcommand{\banyd}{\bleadsto}                              % "
\newcommand{\Leadsto}{\ensuremath{\approx}\!\!{>}}            % signature
\newcommand{\Anyd}{\Leadsto}                                % "

\newcommand{\FdConstr}{\ensuremath{\stackrel{constr}{\Fd}}}
\newcommand{\MvdConstr}{\ensuremath{\stackrel{constr}{\Mvd}}}

\newlength{\flogicindent}


\newlength{\flength}
\newlength{\counterlength}


\newcommand{\la}{\ensuremath{\,\leftarrow\,}}

\newcommand{\anon}{\_}

\newcommand{\note}[1]{\textit{[[#1]]}}
\newcommand{\nterm}[1]{\ensuremath{\langle}\textit{#1}\ensuremath{\rangle}}



\newcommand{\bs}{\ensuremath{\backslash}}
\newcommand{\FLIP}{{\mbox{\sc Flip}}\xspace}
\newcommand{\FLORA}{{\mbox{${\cal F}${\sc lora}}}\xspace}
\newcommand{\FLORID}{{\mbox{\sc Florid}}\xspace}
\newcommand{\fl}{{F-logic}\xspace}


\newcommand{\consts}{\ensuremath{\mathcal{C}}}
\newcommand{\funcs}{\ensuremath{\mathcal{F}}}
\newcommand{\preds}{\ensuremath{\mathcal{P}}}
\newcommand{\vars}{\ensuremath{\mathcal{V}}}

\newcommand{\HU}{\ensuremath{U}}
\newcommand{\HB}{\ensuremath{\mathcal{HB}}}
\newcommand{\ext}{\ensuremath{^{\star}}}

\newcommand{\bksl}{\symbol{92}}
\newcommand{\dq}{\symbol{34}}


\title{\FLORA: The Secret of Object-Oriented Logic Programming}

\author{
  Bertram Lud\"ascher
  \and
  Guizhen Yang
  \and
  Michael Kifer
  }
  
\makeindex
\begin{document}

\maketitle
\thispagestyle{empty}

\newpage
\pagenumbering{roman}
\setcounter{page}{1}

\tableofcontents

\newpage

\pagenumbering{arabic}
\setcounter{page}{1}


\section{Introduction}

\FLORA is a sophisticated F-logic to XSB compiler. It translates a program
written in the F-logic language \cite{KLW95} (which must be in a file with
extension {\tt .flr}, {\it e.g.}, {\tt file.flr}) and outputs a file with
extension {\tt .P} ({\it e.g.}, {\tt file.P}), which is a regular XSB
program. This program is then passed to XSB for compilation (yielding {\tt
  file.O}) and execution.

\index{FLIP}
The current version of \FLORA was implemented by Guizhen Yang, but its 
origins trace back to the \FLIP compiler developed by Bertram
Lud\"aescher, and the basic architectures of the two compilers are similar.
However, unlike \FLIP, \FLORA is a complete application development
platform with many features not found in \FLIP. It has a much more
optimized compiler, and its tokenizer and parser are very different from
\FLIP's.

\index{FLORID}
The programming language supported by \FLORA is a dialect of F-logic that
is mostly compatible with the extensions introduced in \FLORID, a C++-based
F-logic system developed at Freiburg University.\footnote{
  %%
  See {\tt http://www.informatik.uni-freiburg.de/$\sim$dbis/florid/} for more
  details.
  %%
  }
%%
In particular, \FLORA fully supports the versatile syntax of \FLORID path
expressions. However, \FLORA has numerous extensions of its own, and some
features differ significantly.

\FLORA is part of the official distribution of XSB beginning with version
2.0. It is organized as an XSB package and lives in the directory
%%
\begin{quote}
 \verb|<xsb-installation-directory>/packages/flora/|  
\end{quote}
%%
\FLORA is fully integrated into the XSB system, including its module
system. In particular, \FLORA modules can invoke predicates defined in
other XSB modules, and regular XSB modules can query the objects defined in
\FLORA modules. At present, XSB is the only platform where \FLORA can run,
because it heavily relies on tabling and the well-founded semantics for
negation that at the moment are available only in XSB.

As mentioned earlier, an XSB programmer can invoke \FLORA objects from
other XSB programs. However, the easiest way to get a feel of the system
is to start \FLORA shell and begin to enter queries interactively.  To
this end, you must first invoke XSB and then load the {\tt flora}
package:
%%
\begin{quote}
  \tt
foo>~~xsb  \\
\tt
... XSB loading messages omitted ...\\
\tt
| ?- [flora].\\
\tt
[flora loaded]\\
\tt
| ?-
\end{quote}
%%
At this point, it is possible to use a limited number of \FLORA
commands, but to run queries you must enter the \FLORA command loop:
%%
\begin{quote}
  \tt
| ?- flora\_shell.  \\
 \tt
... FLORA messages omitted ... \\
 \tt
flora ?-
\end{quote}
%%

At this point, \FLORA takes over and \fl syntax becomes the
norm. To get back to the XSB command loop, type {\tt Control-D} or 
%%
\begin{quote}
  \tt
| ?- end.  
\end{quote}
%%

\noindent
\FLORA comes with a number of demo programs that live in
%%
\begin{quote}
 \verb|<xsb-installation-directory>/packages/flora/demos/|  
\end{quote}
%%
The demos can be run by issuing the command
``\verb|rundemo(demo-filename).|''
at the \FLORA prompt, {\it e.g.},
%%
\begin{verbatim}
   rundemo(flogic_basics). 
\end{verbatim}
%%
There is no need to change to the demo directory.


\section{\FLORA Shell Commands} \label{sec-shell-commands}

The following \FLORA shell commands are supported:
\texttt{
\begin{tabbing}
  dynconsult('FILE',[...]) \= : \=  dynconsult('FILE') with options [...] \kill
  help                      \> : \> show this info \\
  compile('FILE')           \> : \> compile FILE.P; create FILE.O \\
  flcompile('FILE')         \> : \> compile FILE.flr; create FILE.P and FILE.O \\
  flcompile('FILE',[...])\footnotemark  \> : \> flcompile('FILE') with options [...] \\
  flconsult('FILE')         \> : \> compile FILE.flr, then consult FILE.P \\
  flconsult('FILE',[...])   \> : \> flconsult('FILE') with options [...] \\
  flload('FILE[.EXT]')\footnotemark  \> : \> consult FILE.flr, FILE.P or FILE.O \\
  \symbol{91}'FILE[.EXT]',...\symbol{93}        \> : \> consult a list of .flr, .P, or .O files \\
  dyncompile('FILE')        \> : \> compile FILE.flr to dynamic code \\
  dyncompile('FILE',[...])  \> : \> dyncompile('FILE') with options [...] \\
  dynconsult('FILE')        \> : \> dyncompile FILE.flr, then dynamically load FILE.P \\
  dynconsult('FILE',[...])  \> : \> dynconsult('FILE') with options [...] \\
  dynload('FILE[.EXT]')\footnotemark    \> : \> dynamically load FILE.flr or FILE.P \\
  <'FILE[.EXT]',...>        \> : \> dynload a list of .flr or .P files \\
  rundemo('FILE')           \> : \> flconsult a demo from \FLORA demos directory \\
  rundemo('FILE',[...])     \> : \> rundemo('FILE') with options [...] \\
  abolish\_all\_tables\footnotemark        \> : \> flush all tabled data \\
  all                       \> : \> show all solutions at once (default) \\
  one                       \> : \> show solutions one by one \\
  maxerr(all/N)             \> : \> set/show the max number of errors \FLORA reports \\
  end                       \> : \> say Ciao to \FLORA \\
  halt                      \> : \> quit \FLORA and XSB
\end{tabbing}
}
\addtocounter{footnote}{-3}\footnotetext{Currently supported is equality checking option: eqlevel(N), N=0,1.}
\addtocounter{footnote}{1}\footnotetext{File extension is optional, but must be .flr, .P or .O if supplied.}
\addtocounter{footnote}{1}\footnotetext{File extension is optional, but must be .flr or .P if supplied.}
\addtocounter{footnote}{1}\footnotetext{Tables need to be flushed if the database has been
changed since last evaluation.}

All commands with a FILE argument passed to them use the XSB {\tt
  library\_directory} predicate to search for the module, except that the
command {\tt rundemo(FILE)} first looks for {\tt FILE} in the \FLORA demo
directory. In general, all XSB commands can be executed from \FLORA shell,
if the corresponding XSB library has already been loaded.

After a syntax error, parsing error, or compiling error, \FLORA shell will
discard tokens read from the current input stream until the end of file or a
rule delimiter (.) is encountered. If \FLORA shell seems to hang forever
after the prompt:
\begin{verbatim}
[FLORA: discarding tokens]
\end{verbatim}
hitting the Enter key once, then entering a ``.'' character and Enter again
will normally reset the current input buffer and cause \FLORA issue a
command prompt:
\begin{verbatim}
flora ?-
\end{verbatim}

 
\section{\fl and \FLORA by Example}

In the future, this section will contain a number of small
introductory examples illustrating the use of F-logic and \FLORA. Meanwhile, the
reader is referred to the excellent tutorial written by the members of the
\FLORID project.\footnote{
  %%
  See {\tt http://www.informatik.uni-freiburg.de/$\sim$dbis/florid/} for more
  details.
  %%
  }
%%
Since \FLORA and \FLORID share much of the same syntax, most examples in that
tutorial are also valid \FLORA programs.



\section{Inside \FLORA}


\FLORA consists of the following modules:
\begin{itemize}
\item \texttt{flrshell.P}: top-level module that provides the \FLORA shell
  commands for compiling and consulting \FLORA programs
  (\texttt{flcompile/1}, \texttt{flconsult/1}), for setting the output mode
  (\texttt{all/0} or \texttt{one/0} solution(s) at a time), and -- last but
  not the least -- for directly issuing queries against the loaded
  database/program (see Section~\ref{sec-shell-commands} for a full
  description of shell commands).
\item \texttt{flrtokens.P}: \FLORA tokenizer.
\item \texttt{flrparser.P}: DCG parser for \fl.
\item \texttt{flrcompiler.P}: \FLORA compiler that translates \fl to XSB.
\item \texttt{flrutils.P}: miscellaneous utility predicates.
\end{itemize}
%%
Additional libraries are located in the {\tt lib/} subdirectory, and there
is also a number of files in the {\tt closure/} subdirectory that serve as
headers and trailers that are automatically attached to the {\tt *.P} files by
\FLORA compiler (explained later).



\subsection{How \FLORA Works}



\paragraph{Overview.}

As an \fl-to-XSB compiler, \FLORA first parses its argument file and then
compiles it to XSB syntax. For instance the command
\begin{verbatim}
        flora ?- flconsult(myprog).
\end{verbatim}
compiles the program \verb|'myprog.flr'| into the XSB file
\verb|'myprog.P'|.  Take a look at this file to see what has become of your
F-logic program! The compilation consists mainly of a flattening procedure
sketched below.  Next, \verb|'myprog.P'| is compiled by XSB, yielding
byte-code \verb|'myprog.O'|, which is then loaded and executed.  If
\verb|'myprog.flr'| contains queries, they are immediately executed by XSB
(provided there are no errors).

The main purpose of the \FLORA shell, however, is to allow the evaluation
of ad-hoc F-logic queries. For example, after having requested the
execution of the \texttt{'default.flr'} file from the demo directory (using
the command \texttt{flora~?-~rundemo(default).}), you may ask
\begin{verbatim}
    flora ?-  X..kids[                 % Whose kids
                 self -> K;             % ... (list them by name)
                 hobbies ->>            % ... have hobbies
                 {H:dangerous_hobby}    % ... that are dangerous?
    ]. 
\end{verbatim}
\FLORA will parse, flatten, and evaluate this query in the same way as
the queries in a source file.


\paragraph{Flattening F-logic.}

Consider, e.g., the following complex F-logic molecule, representing
facts about the object \texttt{mary} (the syntax of \fl is given in
Section \ref{sec-basic-flogic}):

\begin{quote}
{\small\begin{verbatim}
mary:employee[age->29;kids->>{tim,leo};salary@(1998)->a_lot].
\end{verbatim}}
\end{quote}

As described in \cite{KLW95}, any complex F-logic molecule can be
decomposed into a conjunction of simpler F-logic atomic formulas. These
latter atoms can be directly represented using Prolog syntax.  For the
different kinds of F-logic atoms we use different Prolog predicates. For
instance, the result of translating the above F-molecule might be:

\begin{quote}
{\small
\begin{verbatim}
'_$_$_flora_isa'(mary,employee).              % mary:employee.
'_$_$_flora_fd'(mary,@(age),29).              % mary[age->29].
'_$_$_flora_mvd'(mary,@(kids),tim).           % mary[kids->>{tim}].
'_$_$_flora_mvd'(mary,@(kids),leo).           % mary[kids->>{leo}].
'_$_$_flora_fd'(mary,@(salary,1998),a_lot).   % mary[salary@(1998)->a_lot].
\end{verbatim}
  }
\end{quote}



\paragraph{Closure Axioms.}

\index{closure axioms}
The flattening process alone is not enough to convert an \fl program
into Prolog, because of the semantics ``hidden'' behind the notions of
the subclass relationship, inheritance, and scalar methods. This semantics
is captured through the facts and rules called \emph{closure axioms}, which
must be explicitly added to the flattened user program.  Closure axioms are
static and reside in the subdirectory \texttt{closure/}; these files are
appended to every {\tt *.P} file by the \FLORA compiler. These closure
rules also perform the following tasks:

\begin{itemize}
\item Transitive closure of ``\subcl'' (the subclass relationship).  A
  runtime check warns about cycles in the subclass hierarchy.
\item Closure of ``\isa'' with respect to ``\subcl'', i.e., if $X\isa C,
  C\subcl D$ then $X\isa D$.
\item Perform monotone and non-monotone inheritance.
\item Make sure that scalar methods are, indeed, scalar.
\end{itemize}


\subsection{\FLORA vs. \FLORID}

\index{FLORID}
The syntax of \FLORA and some of its design decisions are borrowed from
\FLORID, an \fl interpreter developed at Freiburg University, Germany.
For more information on Florid please visit the project home page at:
\verb|http://www.informatik.uni-freiburg.de/~dbis/florid/|. The following
is a list of differences between these two systems.

\begin{itemize}
\item \FLORID
  \begin{itemize}
  \item (Semi-)naive bottom-up evaluation.
  \item ``Hard-wired'' closure axioms.
  \item Nonmonotonic inheritance (trigger semantics).
  \item C++ based system.
  \end{itemize}
\item \FLORA
  \begin{itemize}
  \item Translation of \fl into XSB rules.
  \item Top-down evaluation of the generated rules. When tabling is used,
    the compiled programs can be much more efficient than the corresponding
    \FLORID programs.
  \item Closure axioms implemented as Prolog rules and are easy to
    experiment with.
  \item Non-monotonic inheritance implemented using closure axioms and the
    well-founded semantics.
  \item Flora has a module system that fully integrates with the XSB module
    system.
  \item Flora programs have full access to the underlying XSB system, and
    vice-versa.
  \end{itemize}
\end{itemize}



\section{Syntax of \FLORA}

The following is adopted from \cite{ludaescher-himmeroeder-IS-98}.


\subsection{Basic F-logic Syntax}\label{sec-basic-flogic}


\begin{itemize}
\item \emph{Symbols}: The \fl alphabet of \emph{object constructors}
  \index{object constructor}
  consists of the sets \funcs (function symbols), \preds (predicate symbols
  including $\eq$), and \vars (variables).  Variables are denoted by
  capitalized symbols or an underscore followed by zero or more letters
  and/or digits (e.g., $X,\textit{Name}, \_, \_v5$).\footnote{
    %%
    The symbol ``$\_$'' denotes an anonymous variable, as in Prolog.
    %%
    }
  %%
  All other symbols, including the constants (which are 0-ary object
  constructors), are symbols that start with a lowercase letter (e.g., $a,
  \textit{john}$). Constants can also start with uppercase and include
  non-alphanumeric symbols, but then they must be enclosed in single
  quotes ({\it e.g.}, {\tt 'AB@*c'}). 
  
  In addition to the usual first-order connectives and symbols,
  there is a number of special symbols: ], [, \}, \{, \fd, \mvd, \Fd,
  \Mvd,
  \isa, \subcl. Later we shall introduce additional symbols used by the
  inheritance mechanism.
  %%
  \index{id-term}
  \index{oid}
\item \emph{Id-Terms/Oids}: \footnote{
  %%
    Numbers (including integers and floats) may also be used as id-terms. But
    such use might be confusing and is not recommended.
    %%
    }
  %%
\medskip
  
  \index{object identifier}
    First-order terms over \funcs\ and \vars\ are called \emph{id-terms},
    and are used to name objects, methods, and classes.  Ground id-terms
    ({\it i.e.}, terms with no variables) correspond to \emph{logical
      object identifiers} (\emph{oid}s), also called object \emph{names}.
  \index{atom!in F-logic}
\item \emph{Atomic formulas}: Let $O,M,R_{i},X_{i},C,D,T$ be id-terms.  In
  addition to the usual first-order atoms, like $p(X_1,\dots,X_n)$, there
  are the following basic types of formulas: \medskip

  \begin{math}
    \hfill (1)~~O[M\fd R_0] \hfill (2)~~O[M\mvd \{R_1,\dots,R_n\}]
    \hfill (3)~~C[M\Fd T] \hfill (4)~~C[M\Mvd T]. \hfill
  \end{math} \medskip
  
  \index{atom!data}
  \index{method}
  \index{method!single-valued}
  \index{method!scalar}
  \index{method!set-valued}
  (1) and (2) are \emph{data atoms}, which specify that a \emph{method} $M$
  applied to an object $O$ yields the result-object $R_i$. In (1), $M$ is a
  \emph{single-valued} (or \emph{scalar}) method, i.e., there is
  at most one $R_0$ such that $O[M\fd R_0]$ holds. In contrast, in
  (2), $M$ is \emph{multi-valued}, so there can be several result-objects
  $R_i$. For $n=1$ the curly braces can be omitted.\\ 
  \\
  \index{atom!signature}
  \index{signature!in \fl}
  (3) and (4) denote \emph{signature atoms}. They specify that method $M$,
  applied to objects of \emph{class} $C$, yields results of type $T$.
  In (3), $M$ is declared as single-valued, and in (4) as set-valued.
  
  Objects are classified into classes using
  \index{atom!isa}
  \emph{isa-atoms}: \medskip

  \begin{math}
    \hfill (5)~~O\isa C \hfill (6)~~C\subcl D. \hfill
  \end{math} \medskip

  \index{class}
  \index{subclass}
  \index{class!subclass}
  \index{class!instance}
  (5) defines that $O$ is an \emph{instance} of class $C$, while (6)
  specifies that $C$ is a \emph{subclass} of $D$. 
\item \emph{Parameters}: Methods can have arguments, {\it i.e.}, 
  \begin{math}
    M@(P_1,\dots,P_k)
  \end{math}
  is allowed in (1)~--~(4), where $P_1,\dots,P_k$ are
  id-terms, e.g., \textsf{john[salary@(1998)\fd 50000]}.
  
\item \emph{Programs}: \fl\ \emph{literals}, \emph{rules}, and
  \emph{programs} are defined as usual, based on \fl atoms.
\end{itemize}

\noindent
\index{F-molecule}
\emph{F-molecules} provide a shortcut for specifying properties of the same
object. For instance, instead of
$\textsf{john:person}\land\textsf{john[age\fd
  31]}\land\textsf{john[children\mvd\{bob,mary\}]}$, we can simply write
\textsf{john\isa person[age\fd 31; children\mvd\{bob,mary\}]}.


\begin{example}
  {\bf (Publications Database)} \rm Figure~\ref{fig-flogic-model} depicts
  an \fl representation of a fragment of an object-oriented publications
  database.
\end{example}


\begin{figure}[htb]
\begin{tabular}{c}
  \begin{tabular}{l}
    {\bf Schema:}\\
    conf\_p\subcl paper. \\
    journal\_p\subcl paper.\\
    paper[authors\Mvd  person; title\Fd string].\\
    journal\_p[in\_vol\Fd volume]. \\
    conf\_p[at\_conf\Fd conf\_proc].\\
    journal\_vol[of \Fd journal; volume\Fd integer; 
               number\Fd integer; year\Fd integer].\\  
    journal[name\Fd string; publisher\Fd string;
            editors@(integer)\Mvd person]. \\
    conf\_proc[of\_conf\Fd conf\_series; year\Fd integer;
               editors@(integer)\Mvd person]. \\
    conf\_series[name\Fd string]. \\
    publisher[name\Fd string].\\
    person[name\Fd string; affil@(integer)\Fd institution]. \\
    institution[name\Fd string; address\Fd string].\smallskip\\

    {\bf Objects:}\\
    $o_{j1}$\isa journal\_p[%
      title\fd ``Records, Relations, Sets, Entities, and Things'';
      authors\mvd$\{o_{mes}\}$; in\_vol\fd $o_{i11}$]. \\
    $o_{di}$\isa conf\_p[
      title\fd ``DIAM II and Levels of Abstraction'';
      authors\mvd$\{o_{mes},o_{eba}\}$; at\_conf\fd $o_{v76}$]. \\
    $o_{i11}$\isa journal\_vol[of\fd $o_{is}$; number\fd 1; volume\fd 1; year\fd1975]. \\
    $o_{is}$\isa journal[name\fd``Information Systems''; editors@(...)\mvd $\{o_{mj}\}$]. \\
    $o_{v76}$\isa conf\_proc[of\fd vldb; year\fd 1976; editors\mvd $\{o_{pcl},o_{ejn}\}$].\\
    $o_{vldb}$\isa conf\_series[name\fd``Very Large Databases'']. \\
    $o_{mes}$\isa person[name\fd``Michael E. Senko'']. \\
    $o_{mj}$\isa person[name\fd``Matthias Jarke''; affil@($\dots$)\fd $o_{rwt}$]. \\
    $o_{rwt}$\isa institution[name\fd``RWTH\_Aachen''].
\end{tabular}
\end{tabular}
\caption{A Publications Object Base and its Schema Represented 
  Using \fl}\label{fig-flogic-model}
\end{figure}





\subsection{Path Expressions in the Rule Body}

\index{path expression}
\index{path expression!in rule body}
In addition to the basic \fl syntax, the \FLORA  system also supports
\emph{path expressions} to simplify object navigation along
single-valued and multi-valued method applications, and to avoid
explicit join conditions \cite{frohn-lausen-uphoff-VLDB-94}.  The
basic idea is to allow the following \emph{path expressions} wherever
id-terms are allowed:
%%

  \medskip

\begin{math}
  \hfill (7)~~O.M \hfill (8)~~O..M \hfill
\end{math} \medskip

\noindent
The path expression in (7) is \emph{single-valued}; it refers to the unique
object $R_0$ for which $O[M\fd R_0]$ holds; (8) is a \emph{multi-valued}
path expression; it refers to each $R_i$ for which $O[M\mvd\{R_i\}]$ holds.
The symbols $O$ and $M$ stand for an id-term or path a expression.
Moreover, $M$ can be a method that takes arguments, i.e.,
$O..M@(P_1,\dots,P_k)$ is a valid path expression.
  
In order to obtain a unique syntax and to specify different orders of
method applications, parentheses can be used. By default, path expressions
associate to the left, so $a.b.c$ is equivalent to $(a.b).c$ and specifies
the unique object $o$ such that $a[b\fd x] \land x[c\fd o]$ holds (note
that $x=a.b$). In contrast, $a.(b.c)$ is the object $o'$ such that $b[c\fd
x'] \land a[x'\fd o']$ holds (here, $x'=b.c$). In general, these can be
different objects. Note that in $(a.b).c$, $b$ is a method name, whereas in
$a.(b.c)$ it is used as an object name.  Observe that function symbols can
also be applied to path expressions, since path expressions (like id-terms)
are used to reference objects. Thus, $f(a.b)$ is legal.
  
As path expressions and \fl atoms can be arbitrarily nested, this leads
to a concise and very flexible specification language for object
properties, as illustrated in the following example.

\begin{example}[Path Expressions]\label{Ex:PathExpr}
  \rm
  Consider again the schema given in Figure~\ref{fig-flogic-model}.
  Given the name $n$ of a person, the following path expression
  references all editors of conferences in which $n$ had a
  paper:\footnote{Each occurrence of ``\_'' denotes a distinct
    don't-care variable (existentially quantified at the
    innermost level).}
\begin{qrules}
  \anon\isa conf\_p[authors\mvd\{\anon [name\fd $n$]\}].at\_conf..editors
\end{qrules}
Therefore, the answer to the \emph{query}
\begin{qrules}
  ?- P\isa conf\_p[authors\mvd\{\anon [name\fd
  $n$]\}].at\_conf[editors\mvd\{E\}].
\end{qrules}
is the set of all pairs (\textsf{P},\textsf{E}) such that \textsf{P}
is (the logical oid of) a paper written by $n$, and \textsf{E} is the
corresponding proceedings editor.  If one is also interested in the
affiliations of the above editors when the papers were published, we only
need to slightly modify our query:
\begin{qrules}
  ?- P\isa conf\_p[authors\mvd\{\anon [name\fd
  $n$]\}].at\_conf[year\fd Y]..editors[affil@(Y)\fd A].
\end{qrules}
\end{example}
Thus, \FLORA's path expressions support navigation 
along the method application dimension using the operators
``.''  and
``..''. In addition, intermediate objects through which such navigation
takes place can be selected by specifying the properties of such objects
inside square brackets.

\index{method!self}
To access intermediate objects that arise implicitly in the middle
of a path expression, one can define the method \textsf{self} as
$X[\textsf{self}\fd X]$ and then simply
write $\dots[\textsf{self}\fd O]\dots$ anywhere in a complex
path expression. This would bind the id of the current object to the
variable $O$.\footnote{
  %%
  A similar feature is used in other
  languages, e.g., XSQL \cite{xsql-92}.
  %%
  }
%%

\begin{example}[Path Expressions with \textsf{self}]\label{ex-path-self}
  \rm
  Recall the second query in Example~\ref{Ex:PathExpr}. If the user is
  also interested in the respective conferences, the query can be
  reformulated as
\begin{qrules}
  X[self\fd X].\\
   ?- P\isa conf\_p[authors\mvd\{\anon [name\fd
   $n$]\}].at\_conf[self\fd C; year\fd Y]..editors[affil@(Y)\fd A]. 
\end{qrules}
\end{example}



\subsection{Path Expressions in the Rule Head}

Only single-valued path expressions are allowed in a rule head. Set-valued
path expressions are not allowed because the semantics is not always clear
in such cases.

\index{path expression!in rule head}
The following is an example of a path expression in rule head. It says
that the mother of person X. The rule defines the grandsons of $X$'s
mother.
\begin{qrules}
X.mother[grandson{\mvd}Y] :- X{\isa}person[son{\mvd}Y].
\end{qrules}
%%
Complications arise if we specify the following later on:
%%
\begin{qrules}
john[mother{\fd}mary]. \\
john[son{\mvd}david].
\end{qrules}
and ask the following query:
\begin{qrules}
?- mary[grandson{\mvd}S].
\end{qrules}

Here, we should be able to identify ${\tt mary}$ and ${\tt john.mother}$,
since the attribute {\tt mother} is scalar. To deal with single-valued path
expressions in rule heads, \FLORA \emph{skolemizes} ${\tt john.mother}$ and
derives the requisite equalities.  All this is done by the
\FLORA compiler transparently to the user: if a path expression in rule head
is detected, \FLORA replaces this expression with a Skolem constant and
then appends appropriate rules to the target {\tt .P} file to ensure that
proper equalities are maintained.

The user must be aware, however, that \emph{equality maintenance} is costly.
Performance can be improved if path expressions in the rule heads are
avoided.  Our experiments show that without equality checking \FLORA can be
10 times faster in some cases.


\subsection{References: Truth Value vs.\ Object Value}\label{sec-references}

Id-terms, F-logic atoms, and path expressions can all be used to
reference objects. This is obvious for id-terms and path
expressions (7~--~8). Similarly, F-logic atoms (1~--~6) have not only a
truth value, but they also reference objects, i.e., yield an object value.
For example, $o\isa c[m\fd r]$ is a reference to $o$ and additionally,
it specifies $o$'s membership in class $c$ and the value of the attribute $m$.

\index{reference}
Consequently, all F-logic expressions of the form (1~--~8) are called
\emph{references}. F-logic references have a dual reading. Given an
\fl\ database \db I (see below), a reference has:
\begin{itemize}
  \index{reference!object value of}
\item An \emph{object value}, which yields the name(s) of the objects
  reachable in \db I by the corresponding expression, and 
  \index{reference!truth value of}
\item A \emph{truth value}, like any other literal or molecule of the
  language. In particular, a reference $r$ evaluates to \emph{false} if
  there is no object that is referenced by $r$ in \db I.
\end{itemize}
Thus, a path expression can be viewed as a logical formula (\emph{the
  deductive perspective}), or as an expression that represents one or more
objects (\emph{the object-oriented perspective}).

Consider the following path expression and an equivalent (with respect to
the truth value) flattening:

\begin{displaymath}
a..b[c\mvd\{d.e\}] \quad\ \Leftrightarrow \quad\  a[b\mvd\{X_{ab}\}]
\land d[e\fd X_{de}] \land X_{ab}[c\mvd\{X_{de}\}]. \hspace{4em} (*)
\end{displaymath}


\noindent
Such flattening is used to determine the truth value of arbitrarily complex
path expressions in the \emph{body} of a rule.  Let {\tt \obj(path)} denote
the ids of all objects represented by the path expression. Then, for $(*)$,
we have:
\begin{displaymath}
\obj(a..b) = \{x_{ab} \mid \db I \models a[b\mvd\{x_{ab}\}]\}
\qquad\textrm{ and }\qquad \obj(d.e) = \{x_{de} \mid \db I \models d[e\fd 
x_{de}]\} ~,
\end{displaymath}
%
where $\db I \models \varphi$ means that $\varphi$ holds in \db I.
Observe that $\obj(d.e)$ contains at most one element because the
\emph{single-valued} method $e$ is applied to a single oid $d$. Thus, two
formulas might be equivalent logically, but their values as objects might
be different!

In general, for an \fl\ database \db I, the object values of ground
expressions are given by the following mapping \obj from ground references
to sets of ground references:
%
\begin{displaymath}
  \begin{array}{cll@{\hspace{4em}}c}
    \obj(t) & := & \{t \mid  \db I\models t[] \}, 
     \textrm{ for a ground id-term $t$}  \\   
                                %
    \obj(o[\dots]) & :=& \{o'\in\obj(o) \mid \db I \models o'[\dots]
    \} \\  
                                %
    \obj(o\isa c) & := & \{o'\in\obj(o) \mid \db I \models o'\isa c\}
     \\ 
                                %
    \obj(c\subcl d) & := & \{c'\in\obj(c) \mid \db I \models c'\subcl
    d\} \\ 
                                %
    \obj(o.m) & :=  & \{r'\in\obj(r) \mid \db I \models o[m\fd
    r]\} \\ 
                                %
    \obj(o..m) & := &  \{ r'\in\obj(r) \mid \db I \models
    o[m{\mvd}\{r\}] \}
  \end{array}
\end{displaymath}
Observe that if $\tt t[]$ does not occur in \db{I}, then $\obj(t)$ is
$\emptyset$.  Conversely, a ground reference $r$ is called \emph{active} if
$\obj(r)$ is not empty. A reference, $r$, can be 
single-valued or multi-valued:
%%
\begin{itemize}
\item $r$ is called \emph{multi-valued} if
 \begin{itemize}
  \item it has the form $o..m$, or 
  \item it has one of the forms $\underline{o}[\dots]$,
    $\underline{o}\isa c$, $\underline{c}\subcl d$, or
    $\underline{o}.\underline{m}$, and any of the underlined
    subexpressions is multi-valued;
 \end{itemize}
\item in all other cases, $r$ is \emph{single-valued}.
\end{itemize}


\subsection{Symbols, Strings, Comments}


\index{atom!in XSB}
\index{symbol}
\index{string}
\index{comment}
%%
\paragraph{Symbols.}
\FLORA symbols (that are used for the names of constants, predicates, and
object constructors) begin with a lowercase letter followed by zero or more
letters ($A \ldots Z, a \ldots z$), digits ($0 \ldots 9$), or underscores
(\_), e.g., $\textit{student}, \textit{apple\_pie}$. Symbols can also be
\emph{any} sequence of characters enclosed in a pair of single quotes,
e.g., $\texttt{'JOHN SMITH'},\texttt{'default.flr'}$.  Internally, \FLORA
symbols are represented as XSB atoms, which are used there as names of 
predicates and function symbols.

\begin{table}[htb]
\begin{quote}
\texttt{ \small
\begin{tabular}{|c|r@{\hspace{1.5cm}}|@{\hspace{5mm}}l@{\hspace{5mm}}|}
\hline
Escaped String &
  \multicolumn{1}{c|@{\hspace{5mm}}}{ASCII (decimal)} &
  \multicolumn{1}{c|}{Symbol} \\ \hline
{\bksl}{\bksl} &  92 & {\bksl} \\ \hline
{\bksl}n &  10 &		 NewLine \\ \hline
{\bksl}N &  10 &		 NewLine \\ \hline
{\bksl}t &   9 &		 Tab \\ \hline
{\bksl}T &   9 &		 Tab \\ \hline
{\bksl}r &  13 &		 Return \\ \hline
{\bksl}R &  13 &		 Return \\ \hline
{\bksl}v &  11 &		 Vertical Tab \\ \hline
{\bksl}V &  11 &		 Vertical Tab \\ \hline
{\bksl}b &   8 &		 Backspace \\ \hline
{\bksl}B &   8 &		 Backspace \\ \hline
{\bksl}f &  12 &		 Form Feed \\ \hline
{\bksl}F &  12 &		 Form Feed \\ \hline
{\bksl}e &  27 &		 Escape \\ \hline
{\bksl}E &  27 &		 Escape \\ \hline
{\bksl}d & 127 &		 Delete \\ \hline
{\bksl}D & 127 &		 Delete \\ \hline
{\bksl}s &  32 &		 Whitespace \\ \hline
{\bksl}S &  32 &		 Whitespace \\
\hline
\end{tabular}
}
\end{quote}
\caption{Escaped Character Strings and Their Corresponding Symbols}
\label{tab:tab-esc-str}
\end{table}

\index{escaped character}
\FLORA also recognizes escaped characters inside single quotes
($\texttt{'}$).  An escaped character normally begins with a backslash
($\texttt{\bksl}$).  Table~\ref{tab:tab-esc-str} lists the special escaped
character strings and their corresponding special symbols. An escaped
character may also be any ASCII character. Such a character is preceded
with a backslash together with a lowercase $\texttt{x}$ (or an uppercase
$\texttt{X}$) followed by one or two hexadecimal symbols representing its
ASCII value. For example, $\texttt{{\bksl}xd}$ is the ASCII character
Carriage Return, whereas $\texttt{{\bksl}x3A}$ represents the semicolon. In
other cases, a backslash is recognized as itself.

One exception is that inside a quoted symbol, a single quote character is
escaped by another single quote, e.g., $\texttt{'isn''t'}$.

\paragraph{Strings (character lists).}

\index{string}
\index{character list}
Like XSB strings, \FLORA strings are enclosed in a pair of double quotes
($\texttt{{\dq}}$).  These strings are represented internally as lists of
ASCII characters. For instance, \mbox{\texttt{[102,111,111]}} is the same
as \texttt{{\dq}foo{\dq}}.

Escape characters are recognized inside \FLORA strings similarly to
\FLORA symbols.  However, inside a string, a single quote character does
not need to be escaped. A double quote character, however, needs to be
escaped by another double quote, e.g.,
$\texttt{{\dq}{\dq}{\dq}foo{\dq}{\dq}{\dq}}$.

\paragraph{Numbers.}

\index{number}
%%
\index{integer}
%%
\index{float}
%%
Normal \FLORA integers are decimals represented by a sequence of digits,
e.g., $892, 12$.  \FLORA also recognizes integers in other bases (2 through
36). The base is specified by a decimal integer followed by a single quote
($\texttt{'}$). The digit string immediately follows the single quote. The
letters $A \ldots Z$ or $a \ldots z$ are used to represent digits greater
than 9.  Table~\ref{tab:tab-int-rep} lists a few sample integers.
%%
\begin{table}[htb]
\begin{quote}
\texttt{ \small
\begin{tabular}{|r@{'}l|r@{\hspace{1.5cm}}|c|}
\hline
  \multicolumn{2}{|c|}{Integer} &
  \multicolumn{1}{c|}{Base (decimal)} &
  \multicolumn{1}{c|}{Value (decimal)} \\ \hline
\multicolumn{1}{|r}{} & \multicolumn{1}{@{}l|}{1023} &  10 & 1023 \\ \hline
2 & 1111111111 & 2 & 1023 \\ \hline
8 & 1777 & 8 & 1023 \\ \hline
16 & 3FF &  16 & 1023 \\ \hline
32 & vv & 32 & 1023 \\
\hline
\end{tabular}
}
\end{quote}
\caption{Representation of Integers}
\label{tab:tab-int-rep}
\end{table}

Underscore (\texttt{\_}) can be put inside any sequence of digits as
delimiters. It is used to partition some long numbers. For instance,
$\texttt{2'11\_1111\_1111}$ is the same as $\texttt{2'1111111111}$.
However, ``\texttt{\_}'' cannot be the first symbol of an integer, since
variables can start with an underscore. For example, $1\_2\_3$ represents
the number $123$ whereas $\_12\_3$ represents a variable named $\_12\_3$.

Floating numbers normally look like $24.38$. The decimal point must be
preceded by an integral part, even if it is $0$, i.e., $0.3$ must be
entered as $0.3$, not as $.3$. Each float may also have an optional
exponent. It begins with a lowercase $e$ (or uppercase $E$) followed by an
optional minus sign ($-$) or plus sign ($+$) and an integer. This exponent
is recognized as in base 10. For example, \mbox{\tt 2.43E2=243} whereas
\mbox{\tt 2.43e-2=0.0243}.

\paragraph{Comments.}

\FLORA supports three kinds of comments: (1) all characters following the
{\tt \%} symbol are interpreted as a comment line; (2) all characters
following {\tt //} are also interpreted as a comment line;
(3) all characters inside a pairs of {\tt /*} and {\tt */} are
interpreted as comments. Only (3) can span multiple lines.

Note that comments are considered to be white space. Therefore, tokens can
also be delimited by comments.


\subsection{Aggregation}

\FLORA uses the same syntax for aggregation as in \FLORID. An aggregate
looks like this:
%%
\begin{qrules}
agg\{X[Gs]; body\}
\end{qrules}
%%
\index{aggregation!aggregate operator}
\index{aggregation!grouping}
Here, ${\it agg}$ represents the aggregate operator. $X$ is called the
aggregation variable; $Gs$ is a list of comma-separated \emph{grouping}
variables. Finally, ${\it body}$ is a list of literals that specify the
conditions. The grouping variables, $Gs$, are optional.

All the variables appearing in ${\it body}$ but not in $X$ and $Gs$ are
considered to be existentially \mbox{quantified}. Furthermore, the syntax of an
aggregate must satisfy the following conditions:\\
(1) Both $X$ and $Gs$ must
appear in ${\it body}$; (2) $Gs$ should not contain $X$.

\index{aggregates!min}
\index{aggregates!max}
\index{aggregates!count}
\index{aggregates!sum}
\index{aggregates!avg}
\index{aggregates!collectset}
\index{aggregates!collectbag}
The following aggregate operators are supported: {\it min}, {\it max},
{\it count}, {\it sum}, {\it avg}, {\it collectset} and {\it collectbag}.

The operators {\it min} and {\it max} can be applied to any list of terms. The
order is specified by the XSB operator {\tt @=<}.  In contrast, the operators
{\it sum} and {\it avg} can take numbers only. If the aggregate variable is
instantiated to a non-number, {\it sum} and {\it avg} will discard it and
generate a runtime warning message.

For each group, the operator {\it collectbag} collects all the bindings of
the aggregation variable into a list. The operator {\it collectset} works
similarly to {\it collectbag}, except that all the duplicates are removed
from the result list.

In general, aggregates can appear wherever a number or a list is
allowed. Therefore, aggregates can be nested. The following examples
illustrate the use of aggregates (some borrowed from the \FLORID manual):
%%
\begin{qrules}
  ?- Z = min\{S; john[salary@(Year){\fd}S]\}. \\
  ?- Z = count\{Year; john.salary@(Year) $<$ max\{S; john[salary@(Y){\fd}S],
  Y$<$Year\}\}. \\
  ?- avg\{S[Who]; Who{\isa}employee[salary@(Year){\fd}S]\} $>$ 20000. 
\end{qrules}
%%
If an aggregate contains grouping variables that are \emph{not} bound by a
preceding subgoal, then this aggregate would backtrack over such grouping
variables. (In other words, they are considered to be existentially
quantified). For instance, in the last query above, the aggregate will
backtrack over the variable {\tt Who}. Thus, if {\tt john's} and {\tt
  mary's} average salary is greater than 20000, this query will backtrack
and return both {\tt john} and {\tt mary}.

The following example is a query that for each employee asks for a list of
years when this employee had salary less than 60. This illustrates the use
of the {\tt collectset} aggregate.
%%
\begin{quote}
\begin{verbatim}
?- Z= collectset{Year [Who]; Who[salary@(Year) -> X], X < 60}.
Z = [1990,1991]
Who = mary

Z = [1990,1991,1997]
Who = john
\end{verbatim}
\end{quote}
%%

\subsection{Arithmetic Expressions}

\index{arithmetic expression}
Unlike XSB, in \FLORA arithmetic expressions are always evaluated (in XSB,
$+$ can also be used as a binary functor). Both single-valued and
multi-valued path expressions are allowed in arithmetic expressions, and
all objects (variables) are considered to be existentially quantified. For
example, the following query
\begin{qrules}
?- john..bonus $+$ mary..bonus $>$ $1000$.
\end{qrules}
is actually equivalent to
\begin{qrules}
?- john[bonus{\mvd}{\tt V1}], mary[bonus{\mvd}{\tt V2}], ${\tt V1}+{\tt V2} > 1000$.
\end{qrules}
The only difference is that the values of {\tt V1} and {\tt V2} will be
printed out for the latter query, but not for the former one.

Order matters in \FLORA. All variables appearing in an arithmetic
expression must be instantiated at the time of evaluation. Otherwise, a
runtime error will occur.

\FLORA allows arithmetic expressions to appear in path expressions. Since
arithmetic expressions are always evaluated, an arithmetic expression
inside a path expression is treated as the number to which the
expression evaluates. Furthermore, \FLORA recognizes numbers as oid's, so
the result of the evaluation is treated as a regular object.

To illustrate, consider the following example:
%%
\begin{verbatim}
 ?- 1.m+2.n.k = X.
\end{verbatim}
%%
Since \FLORA allows path expressions inside arithmetic expressions, and
{\it vice versa}, it is not immediately obvious whether the previous
example stands for the arithmetic expression $(1.m)+(2.n.k)$, or for the
path expression $(1.m+2.n).k$, or $(1.m + 2).n.k$, or $1.(m+2).n.k$.  The
correct answer is the first path expression, because ``.'' in a path expression
binds stronger than ``+'' in an arithmetic expression.

One more confusing example is $2.3.4$. Does it mean $(2).(3).(4)$, or
(2.3).4, or 2.(3.4)?  In \FLORA, $2.3.4$ alone means $(2.3).4$, since all
tokens, like integers, floats, operators, etc., are first
processed by \FLORA tokenizer and then passed to \FLORA parser.
In general, the interpretation of ``.'' as a decimal point takes precedence
over the interpretation as part of a single-valued path expression.

Another ambiguous situation arises when the symbols $-$ and $+$ are used.
Indeed, they can be used as minus/plus signs, e.g., $-3$ and $+3$, or as binary
arithmetic operators; e.g., $4-7$ and $4+7$. Actually, the minus and plus
signs are defined in \FLORA as unary operators which take precedence over
binary operators.

Table~\ref{tab:tab-op-pre} lists various operators in decreasing precedence
order, their associativity, and arity.
%%
\begin{table}[htb]
\begin{quote}
\texttt{ \small
\begin{tabular}{|c|c|c|c|c|}
\hline
%%
Precedence & Operator & Use & Associativity & Arity \\ \hline
1 & () & parentheses & not applied & not applied\\ \hline
2 & . & decimal point & not applied & not applied \\ \hline
3 & $-$ & minus sign & right & unary \\ \cline{2-5}
  & $+$ & plus sign & right & unary \\ \hline
4 & . & path expression & left & binary \\ \hline
5 & $*$ & multiplication & left & binary \\ \cline{2-5}
  & $/$ & division & left & binary \\ \hline
6 & $-$ & subtraction & left & binary \\ \cline{2-5}
  & $+$ & addition & left & binary \\ \hline
  & =< & less than or equal to & not applied & binary \\ \cline{2-5}
  & >= & greater than or equal to & not applied & binary \\ \cline{2-5}
7 & =:= & equal to & not applied & binary \\ \cline{2-5}
  & ={\bksl}= & unequal to & not applied & binary \\ \cline{2-5}
  & := & assignment & not applied & binary \\ \cline{2-5}
  &is & \multicolumn{3}{c|}{same as :=} \\
\hline
\end{tabular}
}
\end{quote}
\caption{Operators in Non-Increasing Precedence Order and Their Associativity and Arity}
\label{tab:tab-op-pre}
\end{table}

Wherever ambiguity may arise, parentheses can be used to avoid misleading
expressions. Here are more examples of legal expressions in \FLORA:

\begin{table}[ht]
%%
\begin{tabular}{lll}
($o_1$.$m_1$+$o_2$.$m_2$).{\tt method} \\
2.(3.4) \\
$3+--2$ && equivalent to $3+(-(-2))$ \\
$5*-6$ && equivalent to $5*(-6)$ \\
$5.(-6)$ &~~~~~& method ``$-6$'' applied to object ``5''
\end{tabular}
\end{table}

\noindent
The interpretation of the last expression stems from the fact that both the
minus sign and the plus sign are defined as unary operators. Therefore,
$-6$ is a \emph{complex} arithmetic expression (with an arithmetic operator
$-$) that represents a method, but not a negative integer.

To avoid further confusion, \FLORA insists that all \emph{complex}
arithmetic expressions representing oid's in path expressions must be
enclosed in parentheses. Thus, although $5.$$-6$ may seem legal according
to Table~\ref{tab:tab-op-pre}, it has to be entered as $5.(-6)$.

\subsection{Negation in \FLORA}

\FLORA uses the well-founded semantics for negation and relies on the
underlying XSB system for this service. Negation is specified using the
{\tt tnot} operator. However, the current implementation has the
restriction that {\tt tnot} can be applied only to Prolog predicates, not
F-molecules (this restriction will be dropped in a future release). Thus,
to negate an F-molecule, one has to introduce an auxiliary predicate as
shown below. Furthermore, this predicate must be tabled (see
Section~\ref{sec-tabling-flora}):
%%
\begin{verbatim}
:- table aux/1.
aux(X,Y) :- a[m ->> X; a -> Y].
d[f->Z] :- e[w->Z; v->f(X,Y)], tnot(aux(X,Y)).
\end{verbatim}
%%
One other restriction, due to the underlying XSB system, is that all
variables in negated predicates must be bound before {\tt tnot} is called.

\subsection{Inheritance}

\index{inheritance!structural}
\index{inheritance!behavioral}
\fl identifies two types of inheritance: \emph{structural} and
\emph{behavioral}.  Structural inheritance applies to signatures only. For
instance, if {\tt student::person} and the program has the signature {\tt
  person[name \Fd string]} then the query {\tt ?- student[name \Fd X]}
succeeds with {\tt X = string}.

\index{inheritance!non-monotonic}
Behavioral inheritance is much more complex. The problem  is that it is
\emph{non-monotonic}. That is, addition of new facts might change previously
established inferences.

\index{attribute!inheritable}
\index{attribute!non-inheritable}
F-logic (and \FLORA) distinguishes between attributes and methods that can
inherit values from superclasses and those that do not. The syntax that we
used so far applies to \emph{non-inheritable} attributes only.
\emph{Inheritable attributes} are declared using the {\tt *=>}, {\tt *=>>}
style arrows and defined using the {\tt *->}, {\tt *->>} style arrows. For
instance, the following is a \FLORA program for the classical Royal
Elephant example:
%%
\begin{verbatim}
elephant[color *=> color].
royal_elephant :: elephant.
clyde : elephant.
elephant[color *-> gray].
\end{verbatim}
%%
The question is what is the color of Clyde?
Clyde's color has not been defined in the above program. However, since
Clyde is an elephant and the default color for elephants is gray, Clyde
must be gray. Thus, we can derive:
%%
\begin{verbatim}
clyde[color -> gray].  
\end{verbatim}
%%
Observe that when inheritable methods are inherited from a class by its
members, the attribute becomes non-inheritable. On the other hand, when
such a method is inherited by a subclass from its superclass, then the
method is still inheritable, so it can be further inherited by the members
of that subclass or by its subclasses. For instance, if we have
%%
\begin{verbatim}
circus_elephant :: elephant.
\end{verbatim}
%%
then we can derive 
%%
\begin{verbatim}
circus_elephant[color *-> gray].  
\end{verbatim}
%%

Non-monotonicity of behavioral inheritance becomes apparent when certain new
information gets added to the knowledge base. For instance, suppose that we
learn that
%%
\begin{verbatim}
royal_elephant[color *-> white].  
\end{verbatim}
%%
Although we have previously established that Clyde is gray, this new
information renders our earlier conclusion invalid. Indeed,
Since Clyde is a royal elephant, he must be white, while being an elephant
he must be gray.
The conventional wisdom in object-oriented languages, however, is that
inheritance from more specific classes must take precedence. Thus, we must
retract our earlier conclusion that Clyde is gray and assume that he is white:
%%
\begin{verbatim}
clyde[color -> white].    
\end{verbatim}
%%

Behavioral inheritance in F-logic is discussed at length in \cite{KLW95}.
The above problem of non-monotonicity is just a tip of the iceberg. Much
more difficult problems arise when inheritance interacts with the regular
deduction. To illustrate, consider the following program:
%%
\begin{verbatim}
b[m *->> c].
a : b.
a[m ->> d] :- a[m ->> c].
\end{verbatim}
%%
In the beginning, it seems that \verb|a[m ->> c]| should be derived by
inheritance, and so we can derive \verb|a[m ->> d]|. Now, however, we can
reason in two different ways:
%%
\begin{enumerate}
\item \verb|a[m ->> c]| was derived based on the belief that attribute {\tt
    m} is not defined for the object {\tt a}. However, once inherited,
  necessarily we must have \verb|a[m ->> {c,d}]|. So, the value of
  attribute {\tt m} is not really that produced by inheritance. In other
  words, inheritance of \verb|a[m ->> c]| negates the very premise on which
  the original inheritance was based, so we must undo the operation and the
  ensuing rule application.
\item We did derive \verb|a[m ->> d]| as a result of inheritance, but
  that's OK --- we should not really be looking back and undo previously
  made inheritance inferences. Thus, the result must be \verb|a[m ->> {c,d}]|.
\end{enumerate}
%%
A semantics that favors the second interpretation was proposed in
\cite{KLW95}. This approach is based on a fixpoint computation of
non-monotonic behavioral inheritance.  However, this semantics is very hard
to implement efficiently, especially using a top-down deductive engine
provided by XSB. Thus, \FLORA uses a different, more cautious semantics for
inheritance, which favors the first interpretation above.  The idea can be
summarized using the following rules, which define how class instances
inherit from the classes they belong to. Similar rules are needed to
describe how classes inherit from superclasses.
%%
\begin{verbatim}
// Inheritance rules for scalar attributes
:- table defined/2, overwritten/3.
Obj[A -> V] <- not defined(Obj,A) & Obj:Class & Class[A *-> V]
               & not overwritten(Obj,Class,A) & not conflict(Obj,Class,A).
overwritten(Obj,Class,A) <- Obj:Class1 & Class1::Class 
                            & Class1[A *-> W] & Class1 \= Class
defined(Obj,A) <- Obj[A -> V]
conflict(Obj,Class,A) <- defined(Super,A) & Obj:Super
                         & not Super::Class & not Class::Super.

// Inheritance rules for set attributes
:- table definedSet/2, overwrittenSet/3.
Obj[A ->> V] <- not definedSet(Obj,A) & Obj:Class & Class[A *->> V]
                & not overwrittenSet(Obj,Class,A)
                & not conflictSet(Obj,Class,A).
overwrittenSet(Obj,Class,A) <- Obj:Class1 & Class1::Class
                               & Class1[A *->> W] & Class1 \= Class
definedSet(Obj,A) <- Obj[A ->> V]
conflictSet(Obj,Class,A) <- definedSet(Super,A) & Obj:Super
                            & not Super::Class & not Class::Super.
\end{verbatim}
%%
\index{well-founded semantics}
Negation here is implemented using the {\em well-founded semantics} for
negation \cite{gelder-alternating-89,gelder-ross-schlipf-91} (as indicated
by the {\tt tnot} operator).

One problem with the current implementation of behavioral inheritance is
that the well-founded semantics for negation in the presence of equality is
not yet sufficiently developed. Since \FLORA's treatment of inheritance
relies on well-founded negation, interaction of equality and inheritance
becomes an issue. Fortunately, it is not hard to extend the semantics to
the case when derived equalities do not depend on negation or inheritance.
In the current implementation of \FLORA, it is the responsibility of the
programmer to ensure that this is the case: if a derived equality does
depend on negation, the result is unpredictable.  Interaction between
equality and inheritance will be made more structured in a future release.

\paragraph{Inheritable attributes and path expressions.}
In the previous examples, path expressions used only non-inheritable
attributes. Clearly, there is no reason to disallow inheritable attributes
in such expressions. To distinguish inheritable from non-inheritable
attributes in path expressions, \FLORA uses ``!'' and ``!!''. For instance, 
%%
\begin{verbatim}
clyde!color           means: some X, such that clyde[color *-> X]
obj!!attr             means: some Y, such that obj[attr *->> Y].
\end{verbatim}
%%

\subsection{Type Checking}

\index{type checking}
%%
Although \FLORA allows the user to specify object types through signatures,
type correctness is not being checked automatically. So, what are the
signatures good for then? One answer is that future versions of \FLORA
might support some forms of type checking. However, because F-logic can
natively support powerful meta-programming, even the current level
of support for signatures is useful. For instance, the programmer can write
simple queries to check the types of methods that might look suspicious.
Here is one way to construct such a type-checking query:
%%
\begin{verbatim}
scalar_type_incorrect(O,M,R) :- O[X -> R] , O:C, C[X => D], tnot(R:D).
?- scalar_type_incorrect(obj, meth, Result).
\end{verbatim}
%%
Here, we defined what it means to violate type checking using the usual
F-logic semantics. The corresponding predicate can then be queried. The
``no'' answer means that the corresponding attribute \emph{does not}
violate the typing rules.

In this way, one can easily consruct special purpose type checkers.  This
feature is particularly important when dealing with \emph{semi-structured}
data. (Semi-structured data has object-like structure but normally does not
need to conform to any type; or if it does, the type would normally cover
only certain parts of the object structure.)

\subsection{Meta-programming in \FLORA}

The syntax of \fl lends itself naturally to meta-programming. For instance,
it is easy to examine the methods and types defined for the various classes.
Here are some simle examples:
%%
\begin{verbatim}
// All classes where John is a member
?- john : X.  

// All superclasses of student
?- student :: X

// All unary scalar methods defined for object John
?- john[M@(_) -> _].

// All unary scalar methods that apply to John, i.e., for which a
// signature was declared
?- john[M@(_) => _].
\end{verbatim}
%%
However, a number of meta-programming primitives are still needed
since they cannot be directly expressed in \fl. Many such features are
provided by the underlying XSB system and \FLORA simply takes advantage of
them: 
%%
\begin{verbatim}
flora ?- functor(X,f,3).
X = f(_h455,_h456,_h457)
Yes.

flora ?- compound(f(X)).
X = _h472
Yes.

flora ?- X =.. [f,a,b].
X = f(a,b)
Yes.
\end{verbatim}
%%
\index{meta-variable} These primitives are described in the XSB manual.
However, \FLORA provides one primitive of its own: a {\em meta variable\/}
that can range over methods of any arity.

A meta variable is specified by a normal variable immediately prefixed with
the ``@'' sign, {\it e.g.}, @Method, @\_var, @\_. Note that @\_ represents
a \emph{don't care} meta variable. The ``@'' sign is always considered to
be a part of the meta variable's name.  Thus, @M and M represent two
different variables.

The operator ``=..'' (similar to that of XSB) is used to obtain a method and
its arguments from a meta variable that is bound to a method invocation
expression. Alternatively, this operator can be used to \emph{build} a
method invocation expression from a list and assign the result to a meta
variable. The first element in the list is assumed to represent the method
name and the rest represent the arguments.  For instance,
%%
\begin{verbatim}
flora ?- @M =.. [m,a1,a2].
@M = m@(a1,a2)
Yes.
\end{verbatim}
%%
\noindent
The left hand side of ``=..'' can also be a normal Prolog term. In this
case,
``=..'' acts exactly as in Prolog, {\it i.e.}, it decomposes the term into
a list or constructs a term from a list.
%%
\begin{figure}[tb]
\begin{quote}
\begin{tabular}{l}
{\bf metavar.flr:}\\ \\
:- import length/2 from basics. \\ \\
$o_1$[$m_1$@($a_1$){\fd}$r_1$]. \\
$o_1$[$m_2$@($b_1$,$b_2$){\fd}$r_2$]. \\
$o_1$[$m_3${\fd}$r_3$]. \\
$o_1$[$m_4$@($c_1$,$c_2$,$c_3$){\fd}$r_4$]. \\ \\
$o_2$[@M{\fd}R] :- \\
\hspace{1.5cm}	$o_1$[@M{\fd}R], \\
\hspace{1.5cm}	@M =.. [Meth$|$Args], \\
\hspace{1.5cm}	length(Args,2).
\end{tabular}
\end{quote}
\caption{Using Meta Variables} \label{fig:fig-metavar}
\end{figure}

Consider the example in Figure~\ref{fig:fig-metavar}.  The rule there
``copies'' the definitions of methods of arity 1 and 2 from object {\tt o1}
to {\tt o2}. To do the same without the meta-variable would require two
rules (and more, if we were to copy the methods of higher arities).  To see
how this works in \FLORA, try the following:
%%
\begin{verbatim}
flora ?- rundemo(metavar).
Yes.

flora ?- o2[@M->R].
@M = m2@(b1,b2)
R = r2
Yes.
\end{verbatim}

Currently, a meta variable can appear only where a method invocation is
allowed or on the left side of the ``{\tt =..}'' operator. For instance,
$\mathtt{john[@M{\fd}Salary],~ o_1.@M1.o_2[@M2{\mvd}r]}$. Thus, unlike the
regular variables, meta variables represent method invocations and
\emph{not} object. Because of this, you cannot directly pass meta-variables 
as arguments to predicates and methods. However, you can always convert a
meta-variable into a regular variable ({\it e.g.}, \verb|@M=..N|), pass the 
regular variable as a parameter, and then convert it back into a
meta-variable, as shown below:
%%
\begin{verbatim}
/* Get some method invocation, convert to normal var, pass on to foo/1 */
?- mary[@Meth -> V], @Meth =.. Param, foo(Param).
/* Convert Param to meta var for method invocations, test object property */
f(Param) :- @M =.. Param, abc[@M ->> 123].
\end{verbatim}
%%



\section{Compiled Code vs. Dynamic Code}

A \FLORA program consists of facts and rules all of which take part in the
derivation of new facts and object properties.
However, there is a distinction between static facts and rules and dynamic
ones. The former are immutable, while the latter can be added or deleted at
will.

\index{code!compiled}
\index{code!static}
\index{code!dynamic}
Conceptually, the runtime environment of \FLORA is partitioned into two
areas: static and dynamic. \emph{Static code} is generated using the
predicate {\tt flcompile(file)}, and is loaded into the static runtime
environment by {\tt flconsult(file)}, {\tt flload(file)}, or {\tt [file]}.
\emph{Dynamic code} can be compiled by {\tt dyncompile(file)} and loaded
into the dynamic runtime environment by {\tt dynconsult(file)},
{\tt dynload(file)}, or \texttt{<file>}.  we have shown the syntax of
these predicates in Section~\ref{sec-shell-commands}.

The above predicates can also be called from within a \FLORA program, but
except for {\tt [file]} and \texttt{<file>}, all of them must first be
imported from {\tt flrutils} (see Section~\ref{sec-module} for details).

\noindent
{\bf Note 1:} When a file is compiled and loaded into the dynamic area, all
queries that appear in that file are ignored.

\noindent
{\bf Note 2:} The same \FLORA program can be compiled statically and
dynamically, and \FLORA puts the two compiled versions into different
files.  When the program is loaded into the dynamic part of the code, the
loader is looking for a dynamically compiled version of the program; when
it is loaded into the static part of the code, the loader tries to find a
statically compiled version. In particular, it is not possible to load
statically what has been compiled dynamically, and vice versa.

Although static and dynamic code resides in different areas, the rules and
facts in both these areas are considered as a whole and executed together.

A small example should help illustrate this. Suppose there are two
programs, {\it static.flr} and {\it dynamic.flr}, as shown in
Figure~\ref{fig:fig-static-dynamic-code}.
%%
\begin{figure}[htb]
\begin{quote}
\begin{tabular}{l}
{\bf static.flr:}\\ \\
department[faculty{\Mvd}professor; coursesOffered{\Mvd}string]. \\
professor[teaches@(string,number){\Mvd}string]. \\
\\
X{\isa}department[coursesOffered{\mvd}C] :-
	X..faculty[teaches@(S,Y){\mvd}C]. \\ \\

cse{\isa}department[faculty{\mvd}smith]. \\
smith{\isa}professor. \\
smith[teaches@(fall,1998){\mvd}cse220]. \\
smith[teaches@(spring,1999){\mvd}cse310]. \\
smith[teaches@(spring,1999){\mvd}cse530]. \\
\\
{\bf dynamic.flr:}\\ \\
math{\isa}department[faculty{\mvd}john]. \\
john{\isa}professor. \\
john[teaches@(spring,1999){\mvd}math230]. \\
john[teaches@(spring,1999){\mvd}math101].
\end{tabular}
\end{quote}
\caption{Static Code vs. Dynamic Code} \label{fig:fig-static-dynamic-code}
\end{figure}
Start XSB in the directory where both \emph{static.flr} and
\emph{dynamic.flr} reside. Then start \FLORA shell and type:
\begin{verbatim}
flora ?- flconsult(static).
Yes.

flora ?- dynconsult(dynamic).
Yes.

flora ?- D:department[coursesOffered->>C].

D = cse
C = cse220

D = cse
C = cse310

D = cse
C = cse530

D = math
C = math101

D = math
C = math230
Yes.
\end{verbatim}
%%
It can be seen that the two parts of the code work in union. The difference
comes when we are trying to modify the code dynamically, {\it e.g.}, by
deleting or adding facts.

\FLORA provides the users with several predicates to modify the runtime
database.  These predicates can be executed either from the static area or
the dynamic area. However, only the facts that reside in the dynamic area
can be asserted or retracted. (In the furture, \FLORA might support 
asserting and retracting rules in the dynamic area). The database
modification predicates supported by
\FLORA are explained below:

\paragraph{$\bullet~~\mathtt{assert(P_1,\ldots,P_n)}$:} asserts a list of facts
into the dynamic area.
$\mathtt{P_i~(i=1{\ldots}n)}$ can be any \mbox{\fl} molecule or user defined
predicate, e.g.,
\[\mathtt{assert(david{\isa}professor[teaches@(fall,1999){\mvd}cse505])}.\]

\paragraph{$\bullet~~\mathtt{retract(P_1,\ldots,P_n | C_1,\ldots,C_n)}$}
retracts the \emph{ground} facts corresponding to $\mathtt{P_1,\ldots,P_n}$ for
which the conjunction of $\mathtt{P_1,\ldots,P_n,C_1,\ldots,C_n}$ succeeds.
$\mathtt{C_1,\ldots,C_n}$ can be considered as the conditions qualifying
the facts to be retracted.  For instance,
\[
\mathtt{retract(john[teaches@(S,Y){\mvd}C]|smith[teaches@(S,Y){\mvd}C])}
\]
retracts the teaching information about {\it john} when it duplicates {\it
  smith}'s ({\it i.e.}, when John and Smith appear to have taught the same
course during the same semester). In contrast,
\[
\mathtt{retract(john[teaches@(S,Y){\mvd}C],smith[teaches@(S,Y){\mvd}C])}
\]
retracts the teaching records of both John and Smith when they duplicate
each other.

Special built-in predicates like arithmetic comparison operators cannot be
retracted.  If $\mathtt{P_i}$ happens to be one of those special
predicates, \FLORA compiler will interpret it as an additional condition
$\mathtt{C_i}$ and generate a warning. For example,
%%
\begin{displaymath}
\mathtt{retract(john[teaches@(S,Y){\mvd}C],~Y\,=<\,1999)}
\end{displaymath}
is equivalent to
\begin{displaymath}
\mathtt{retract(john[teaches@(S,Y){\mvd}C]\,|~Y\,=<\,leq1999)};
\end{displaymath}
%%

\paragraph{$\bullet~~\mathtt{retractall(P_1,\ldots,P_n | C_1,\ldots,C_n)}$} retracts \emph{all ground}
facts corresponding to $\mathtt{P_1,\ldots,P_n}$ for which the conjunction
of $\mathtt{P_1,\ldots,P_n,C_1,\ldots,C_n}$ succeeds. The difference
between $\mathtt{retract}$ and $\mathtt{retractall}$ is that:
$\mathtt{retract}$ retracts facts one by one and fails if it is unable to
retract any facts, whereas $\mathtt{retractall}$ always succeeds no matter
what facts reside in the database. Actually, $\mathtt{retractall}$ is
implemented using $\mathtt{retract}$ with the following schema (where the
arguments are omitted):
\begin{qrules}
retractall :- retract, fail. \\
retractall.
\end{qrules}

\paragraph{$\bullet~~\mathtt{erase(P_1,\ldots,P_n | C_1,\ldots,C_n)}$}
retracts \emph{all ground facts} 
similarly to $\mathtt{retract}$. However, in addition, it traces the object
reference links and retracts all ground facts referenced along those paths.

To see the effects of $\mathtt{erase}$, continue
the example of Figure~\ref{fig:fig-static-dynamic-code}:
%%
\begin{verbatim}
flora ?- erase(cse[faculty->>smith]).
No.
\end{verbatim}
%%
Here, \FLORA returns ``no'' because the fact {\tt cse[faculty->>smith]} is
located in the static area and thus cannot be retracted.

\begin{verbatim}
flora ?- erase(math[faculty->>john]).
Yes.
\end{verbatim}
%%
Here, the removal of {\tt math[faculty->>john]} proceeds without a hitch,
because this fact resides in the dynamic area. More interestingly, all the
information about John is also gone as well!
This can be seen from the following queries:
%%
\begin{verbatim}
flora ?- P:professor[teaches@(Semester,Year)->>Course].

P = smith
Semester = fall
Year = 1998
Course = cse220

P = smith
Semester = spring
Year = 1999
Course = cse310

P = smith
Semester = spring
Year = 1999
Course = cse530
Yes.

flora ?- P:professor.
P = smith
Yes.
\end{verbatim}
%%
Note that when erasing $O_1{\isa}O_2$ or $O_1{\subcl}O_2$, only the object
references that originate from $O_1$ are followed. For other \fl facts, such as
$O_1[method{\fd}O_2],O_1[method{\mvd}O_2]$, only the object references
that originate at $Q_2$ are followed.

\paragraph{$\bullet~~\mathtt{eraseall(P_1,\ldots,P_n | C_1,\ldots,C_n)}$} erases \emph{all ground}
facts corresponding to $\mathtt{P_1,\ldots,P_n}$ for which the conjunction
of $\mathtt{P_1,\ldots,P_n,C_1,\ldots,C_n}$ succeeds. Like
$\mathtt{retractall}$, $\mathtt{eraseall}$ always succeeds and is
implemented using $\mathtt{erase}$ via the following schema:
\begin{qrules}
eraseall :- erase, fail. \\
eraseall.
\end{qrules}

\paragraph{Asserting, retracting, and tabling.}
To implement object properties, \FLORA relies on a feature of XSB called
\emph{tabling} (see Section~\ref{sec-tabling-flora} for more details).
Unfortunately, tabling and {\tt retract} do not mix well.
The problem is that results from previous queries are cached in
tables, and {\tt retract} does not delete facts from tables. Thus, you
might get the following counterintuitive result:
%%
\begin{verbatim}
flora ?- assert(o[m->1]).
Yes.
flora ?- o[m->1].
Yes.
flora ?- retract(o[m->1]), o[m->1].
Yes.
\end{verbatim}
%%
The reason for the wrong positive answer here is that the cache remembers
that the query {\tt o[m->1]} is true. So, when the same query is asked
after {\tt retract}, a wrong result is returned from the cache. Similarly,
tabling might interact poorly with {\tt assert}:
%%
\begin{verbatim}
flora ?- o[m->1].
No.
flora ?- assert(o[m->1]), o[m->1].
No.
\end{verbatim}
%%
The reason for the wrong result here is, again, that the cache remembers
that {\tt o[m->1]} is false, which is no longer correct after the assert
operation.

\index{abolish\_all\_tables}
%%
In a future release, \FLORA will provide a workaround for these problems
(and it is even possible that a future release of XSB will start doing the
right thing in these situations. For now, the only remedy is to use a call
to {\tt abolish\_all\_tables}, which would drop all tables.
However, at present, the only safe way to do this is by executing {\tt
  abolish\_all\_tables} as a separate query.


\section{\FLORA Modules and Interaction with XSB}\label{sec-module}

Besides static area and dynamic area, \FLORA also has a module system that
is integrated with the XSB's own module system. In this section we discuss
how \FLORA programs can talk with each other and how they can
talk to XSB.

\index{calling \FLORA from \FLORA}
\index{module! in \FLORA}
\index{signature!in \fl}
%%
\paragraph{Calling \FLORA from \FLORA.}
\FLORA modules communicate with each other by importing/exporting either
\emph{ground} \fl signatures or normal Prolog predicates. With the rest of
XSB, \FLORA modules communicate using the normal Prolog predicates only
(because bare XSB does not speak F-logic).

\index{module}
To illustrate, consider the two \FLORA modules \emph{module1.flr} and
\emph{module2.flr} in Figure~\ref{fig:fig-module}.
Let us start XSB in the directory where both \emph{module1.flr} and
\emph{module2.flr} reside, and type the following from the \FLORA
shell:
%%
\begin{figure}[htb]
\begin{quote}
\begin{tabular}{l}
{\bf module1.flr:}\vspace{3mm} \\
:- import employee[salary@(number){\Fd}number] from module2. \vspace{2mm}\\
john{\isa}employee. \\
john[salary@(1994){\fd}70]. \\
john[salary@(1995){\fd}80]. \\
john[salary@(1996){\fd}70]. \\
john[salary@(1997){\fd}50]. \\
john[salary@(1998){\fd}80]. \\
\\
{\bf module2.flr:}\vspace{3mm}
\\
:- export employee[salary@(number){\Fd}number]. \vspace{2mm}\\
employee[salary@(number){\Fd}number]. \\
mary{\isa}employee. \\
mary[salary@(1994){\fd}60]. \\
mary[salary@(1995){\fd}60]. \\
mary[salary@(1996){\fd}70]. \\
mary[salary@(1997){\fd}80]. \\
mary[salary@(1998){\fd}90].
\end{tabular}
\end{quote}
\caption{Example \FLORA Modules} \label{fig:fig-module}
\end{figure}
%%

%%
\begin{verbatim}
flora ?- flcompile(module2).
... FLORA messages omitted ...
Yes.

flora ?- [module1].
Yes.

flora ?- X=count{Year; john.salary@(Year) < mary.salary@(Year)}.
X = 2
Yes.
\end{verbatim}
%%
What you see here is that {\tt module1} is loaded and the query is posed.
However, {\tt module1} only contains information about John. Mary's
information is kept in {\tt module2}. However, {\tt module1} \emph{imports}
this information from {\tt module2}, and the imported information
takes part in the query evaluation process.

\index{module!import directive}
\index{module!export directive}
The import/export directives can take a list of predicate/arity pairs (as
XSB does) and/or \emph{ground} \fl signatures (no variables are allowed in
the signatures that are imported or exported). For example,
\[
\tt
:- import ~~tc/2,~
student[grade@(string){\Fd}number],~ p/1~~from~~foo.
\]
is allowed, but 
\[
\tt
:- import ~~student[G@(string){\Fd}number]~~from~~foo.
\]
is not.

When a \FLORA module imports from another module, say, module {\tt foo.flr}, 
the latter must already be compiled, or else a runtime error will be
issued. Furthermore, a \FLORA module can not import and export the same
signature. These restrictions result from the limitations of the underlying
XSB module system.

Import directives can appear in both static and dynamic code. However, all
export directives (as well as queries, as mentioned earlier) are ignored
when a \FLORA module is compiled as dynamic code and/or is dynamically loaded
into the dynamic area. This is, again, due to the current limitations of
the XSB module system.

\index{calling XSB from \FLORA}
\paragraph{Calling XSB from \FLORA.}
Since \FLORA supports import/export directives much the same way as XSB
does, \FLORA modules have full access to the underlying XSB's
functionality.  In general, a \FLORA program can call any XSB predicate
that is exported by some XSB module. This is done by importing this
predicate in the \FLORA program.

\FLORA programs can freely mix F-logic statements and XSB predicates
defined in other XSB modules as long as these XSB predicates are properly
imported and are used correctly.
%%
\begin{figure}[tb]
\begin{quote}
\begin{tabular}{l}
{\bf mix.flr:}\\ \\
:- import findall/3 from setof. \\
\\
edge(a,b). \\
edge(b,c). \\
edge(c,b). \\
\\
string[reachableTo{\Mvd}string]. \\
\\
X{\isa}activeNode[reachableTo{\mvd}Y] :- edge(X,Y). \\
X{\isa}activeNode[reachableTo{\mvd}Y] :- edge(X,Z), Z[reachableTo{\mvd}Y]. \\
\\
tc(X,Y) :- X[reachableTo{\mvd}Y]. \\
\\
show(X) :- \\
\hspace{1cm} X{\isa}activeNode, \\
\hspace{1cm} write(X), \\
\hspace{1cm} write({\tt'}[reachableTo{\mvd}{\tt \{'}), \\
\hspace{1cm} findall(Y,tc(X,Y),L), \\
\hspace{1cm} writelist(L), \\
\hspace{1cm} writeln({\tt '\}}]{\tt '}). \\
\\
writelist([X]) :- write(X). \\
writelist([$X_1,X_2|$Xs]) :- write($X_1$), write(','), writelist([$X_2|$Xs]).
\end{tabular}
\end{quote}
\caption{Mixing \FLORA code with XSB code} \label{fig:fig-mix}
\end{figure}

Consider the example in Figure~\ref{fig:fig-mix} and suppose that the
following queries are entered at the \FLORA prompt:
%%
\begin{verbatim}
flora ?- [mix].
Yes.

flora ?- show(a), show(b).
a[reachableTo->>{b,c}]
b[reachableTo->>{b,c}]
Yes.
\end{verbatim}

Observe that in Figure~\ref{fig:fig-mix} we created a new predicate, {\tt
  tc}, and used \emph{it} as an argument to {\tt findall} (which is a
standard Prolog predicate; see the XSB manual). It seems more natural to
write $\mathtt{findall(Y,X[reachableTo{\mvd}Y],L)}$ instead.  This more
natural syntax will be supported in the future, but it does not work at the
present time. The reason is that \FLORA compiler always treats \fl
molecules as oid's, if they appear as predicate arguments.  However, in
{\tt findall}, we want the molecules in the second argument to be treated
as logical formulas that evaluate to true or false.  This will be supported
in a future release via a special compiler directive.

Since \FLORA can use most of the services provided by XSB, reading the XSB
manual is highly recommended in order to be productive. Some services, such
as I/O, are of obvious importance. However, there are many other useful
packages, which provide pattern matching capabilities, interaction with the
OS, foreign C interface, etc.

\index{calling \FLORA from XSB}
\paragraph{Calling \FLORA from XSB.}
Programs written in \FLORA can be used by XSB program as well.
Of course, XSB does not understand \FLORA syntax directly, but they share
the same common denominator: Prolog predicates. Thus, a \FLORA module can
define a predicate, export it, and XSB programs can then import and call it.
Full power of F-logic syntax can be used in such a definition. The
predicate syntax is needed only at the final stage, to create a
communication channel to XSB.

XSB programs can even compile and consult \FLORA programs.
To this end, they must have the import statements of the following form:

%%
\begin{verbatim}
   :- import bootstrap_flora/0 from flora.
   :- import flcompile/1 from flrutils.
   :- import flconsult/1 from flrutils.
   ?- bootstrap_flora.
\end{verbatim}
%%

The statement {\tt bootstrap\_flora} is a non-interactive equivalent of the
command {\tt flora\_shell}. It makes all the \FLORA facilities available
without actually starting the shell (which is what one really wants while
calling \FLORA programs from other programs).
Once the {\tt bootstrap\_flora} statement has been executed, 
we can call, say, {\tt flconsult(foobar)} from within XSB programs to
compile (if necessary) and load the \FLORA program {\tt foobar.flr}.


\section{\FLORA and Tabling}\label{sec-tabling-flora}

\index{tabling}
Tabling is a technique that enhances top-down evaluation with a mechanism
that remembers the calls previously made during query evaluation.
This technique is known to be essentially equivalent to the Magic Sets
method for bottom-up evaluation. However, tabling combined with top-down
evaluation has the advantage of being able to utilize highly optimized
compilation techniques developed for Prolog. The result is a very efficient
deductive engine.

XSB lets the user specify which predicates must be tabled.  The \FLORA
compiler automatically tables the predicates used to flatten \fl molecules.
However, the user is responsible for telling the system which other
predicates must be tabled. (Normally, these are predicates defined by the
user.)  \FLORA programs accepts the same tabling directives as XSB does
(Section~\ref{sec-comp-directives} lists all the compiler directives).

It is important to keep in mind that XSB does not do reordering of objects
and predicates during joins. Instead, all joins are performed left-to-right.
The programmer, thus, must write program clauses in such a way as to ensure
that smaller predicates and classes appear early on in the join. Also, even
though XSB tables the results obtained from previous queries, the current
tabling engine has several limitations. In particular, when a new query
comes in, XSB tries to determine if this query is ``similar'' to one that
already has been answered (or is in the process of being evaluated).
Unfortunately, the current notion of similarity used by XSB is fairly weak,
and many unnecessary recomputations might result. This problem will be
corrected in a future release.

\index{abolish\_all\_tables}
%%
It is also important to be aware that when XSB (and \FLORA) evaluate a program,
all tabled predicates are partially materialized and all the computed
tuples are stored in XSB tables. Thus, if you change the set of facts, the
existing tables must be discarded in order to allow XSB to recompute the
results. This is accomplished by issuing the predicate {\tt
  abolish\_all\_tables/0} described in the XSB manual.

Furthermore, tabling sometimes has undesirable side effects in
``real-world'' programming, especially when writing methods with
non-logical side effects ({\it e.g.}, writing or reading a file).  If a
tabled predicate has such side effects, then the first time the predicate
is called the side effect will be performed, but the second time the call
simply returns with success or failure (depending on the outcome of the
first call).  Thus, if the predicate was intended to perform the side
effect each time it is called, it will not operate correctly.

All this is, of course, old news to XSB programmers, but is there anything
\FLORA-specific in this? It turns out that yes, and the problem is not
immediately apparent.  In the object-oriented style, people tend to define
methods with side effects and attach them to objects.  However, because
\FLORA tables everything that comes from F-molecules, methods with side
effects are subject to the same problem as described above. The current
interim solution is to use predicates instead of methods whenever side
effects are needed. In a future release, \FLORA will have special syntax
for methods with side effects, so this restriction will be lifted.

\index{cut in \FLORA}
\index{cutting across tables}
%%
No discussion of a logic programming language is complete without a few
words about the infamous Prolog cut (!). Although Prolog cut has been
(mostly rightfully) excommunicated by as far as Database Query Languages
are concerned, it is sometimes indispensable when doing ``real work'', like
pretty-printing \FLORA programs or implementing a pattern matching
algorithm.  To facilitate this kind of tasks, \FLORA lets the programmer
use cuts.  However, the current implementation of XSB has a limitation that
Prolog cuts cannot ``cut across tabled predicates.''  Without trying to
pretend to be experts, we refer the reader to the XSB manual for details on
this obscure problem. The XSB team is considering correcting this problem
in a future release.

For now, enjoy your cut.  If you get an error message telling something
about cutting across the tables --- you know that you may have cut too much
:-). The basic rule that can keep you out of trouble is: do not put a cut
in the body of a rule \emph{after} any F-molecule. However, it is (usually)
OK to to put a cut before any F-molecule. It is even OK to have a cut in
the body of a rule that \emph{defines} an F-molecule (again, provided that
the body has no F-molecule to the left of that cut).


\section{\FLORA Compiler} \label{sec-comp-directives}

Like XSB compiler, \FLORA compiler can take compilation directives. All
such directives must begin with {\tt :-} (while all queries must begin with
{\tt ?-}). The following is a list of all the compiler directives supported
by \FLORA:

\index{compiler directive}
\index{compiler directive!tabling}
\paragraph{Tabling Directive} Tabling directive can be either ``{\tt
  :- auto\_table.}'', which lets XSB automatically decide which predicates
should be tabled, or ``{\tt :- table p\_a\_list.}'', where {\tt p\_a\_list}
is a coma-separated list of \mbox{predicate/arity} pairs specifying those
predicates to be tabled. Note that the tabling directive is needed only for
the user-defined predicates inside \FLORA modules. The internal \FLORA
predicates that are used to implement \fl atoms are tabled automatically.

\index{compiler directive!import}
\paragraph{Import Directive} Import directive is of the form
``{\tt :- import sig\_p\_a\_list.}'', where {\tt sig\_p\_a\_list} is a
list of \emph{ground} \fl signatures \mbox{and/or} \mbox{predicate/arity}
pairs.

\index{compiler directive!export}
\paragraph{Export Directive} Export directive is of the form
``{\tt :- export sig\_pa\_list.}'', where \emph{sig\_p\_a\_list} is a list of
\emph{ground} \fl signatures \mbox{and/or} \mbox{predicate/arity} pairs.
All export directives are ignored if a \FLORA module is compiled as dynamic
code and/or is loaded dynamically.

\index{compiler directive!equality maintenance}
\paragraph{Equality Maintenance Directive} Equality maintenance directive has
the form ``{\tt :- eqlevel(N).}''  where the level number \emph{N}
specifies the degree to which \FLORA will try to maintain the equalities
among objects derived during query evaluation. Currently, only two levels
of equality maintenance are supported: 0 (no equality maintenance) and 1
(full equality maintenance).

Equality maintenance directives can appear in several places in a \FLORA
program. However, if  {\tt eqlevel(1)} is requested somewhere in the
module, \FLORA will compile the module with equality maintenance
level 1.

Note that equality level 1 should not be specified unnecessarily, since it
can slow \FLORA down by an order of magnitude.  The default equality
maintenance level is 0. However, if \FLORA compiler detects a path
expression in a rule head, which requires Skolemization (which, for
correctness, requires full equality maintenance), it automatically switches
to the equality level 1.  Therefore, path expressions in the rule head must
be avoided if at all possible.

Equality maintenance can also be requested when \FLORA modules are compiled
using predicates such as {\tt flcompile} and {\tt flconsult} (which must be
imported from the module {\tt flrutils}).  For instance, {\tt
  flcompile(benchmark,[eqlevel(1)])} will compile {\tt benchmark.flr} with
equality maintenance level 1.  If equality maintenance is given both in the
{\tt flcompile} command and inside the flora module being compiled, the
highest level will be selected by the compiler.

Here is the full list of compilation and loading predicates, all imported
from {\tt flrutils}, that can be used in conjunction with \FLORA:
%%
\begin{tabbing}
 \tt flcompile(FILE, Directives)  \= ---- \= compile\kill
 \tt flcompile(File, Directives) \> -- \> compile File with compilation Directives.\\
 \tt flcompile(File) \> -- \> same with default directives.\\
 \tt flconsult(File, Directives) \> -- \> consult File with compilation Directives.\\
 \tt flconsult(File) \> -- \> same with default directives.\\
 \tt dyncompile(File, Directives) \> -- \> like flcompile/2, but compiles
 as \FLORA dynamic code.\\
 \tt dyncompile(File) \> -- \> same with default directives.\\
 \tt dynconsult(File, Directives) \> -- \> like flconsult/2, but consults
 as \FLORA dynamic code.\\
 \tt dynconsult(File) \> -- \> same with default directives.\\
 \tt flload(File) \> -- \> load File.\{flr,P,O\} as static code.\\
 \tt dynload(File) \> -- \> load File.\{flr,P,O\} as dynamic code.\\
\end{tabbing}
%%

\section{\FLORA Debugger}
\index{debugging}

\FLORA debugger is essentially a presentation layer on top of the XSB
debugger, so familiarity with the latter is highly recommended (XSB Manual,
Part I). Here we sketch only a few basics.

The debugger has two facilities: tracing and spying. Tracing allows the
user to watch the program being executed step by step, and spying allows
one to tell \FLORA that it must pose when execution reaches certain 
predicates or object methods. The user can trace the execution from then
on. At present, only the tracing facility has been implemented.

\index{tracing}
To start tracing, you must issue the command {\tt flora\_trace} at the
\FLORA prompt. It is also possible to put the subgoal {\tt flora\_trace} in
the middle of the program. In tat case, tracing will start after this
subgoal gets executed. This is useful when you know where exactly you want
to start tracing the program. To stop tracing, type {\tt flora\_notrace}.

During tracing, the user is normally prompted at the four ports of subgoal
execution: {\tt Call} (when a subgoal is first called), {\tt Exit} (when
the call exits), {\tt Redo} (when the subgoal is tried with a different
binding on backtracking), and {\tt Fail} (when a subgoal fails).
At each of the prompts, the user can issue a number of commands. The most
common ones are listed below. See the XSB manual for more.
%%
\begin{itemize}
  \item {\tt carriage return (creep)}:  to go to the next step  
  \item {\tt s (skip)}: execute this subgoal non-interactively; prompt
    again when the call exits (or fails)
  \item {\tt S (verbose skip)}: like {\tt s}, but also show the trace
    generated by this execution
  \item {\tt l (leap)}: stop tracing and execute the remainder of the
    program
\end{itemize}
%%
The behavior of the debugger is controled by the predicate {\tt
  debug\_ctl}. For instance, executing {\tt debug\_ctl(profile, on)} at the
\FLORA prompt tells XSB to measure the CPU time it takes to execute each
call. This is useful for tuning your program for performance. Other useful
controls are: {\tt debug\_ctl(prompt, off)}, which causes the trace to be
generated without user intervention; and {\tt debug\_ctl(redirect,
  foobar)}, which redirects debugger output to the file named {\tt foobar}.
The latter feature is usually useful only in conjunction with the
  aforesaid prompt-off mode. See the XSB manual for additional information
  on debugger control.


\section{Emacs Support}

Editing and debugging \FLORA programs can be greatly simplified with the
help of \emph{flora-mode}, a special Emacs editing mode designed
specifically for \FLORA programs. Flora-mode provides support for syntactic
highlighting, automatic indentation, and the ability to run \FLORA programs
right out of the Emacs buffer.

\subsection{Instalation}
To install \emph{flora-mode}, you must perform the following steps. Put the
file
%%
\begin{quote}
  {\tt XSB/packages/flora/emacs/flora.el} 
\end{quote}
%%
found in your XSB distribution on the load path of Emacs or XEmacs
(whichever you are using). The best way to work with Emacs is to make a
separate directory for Emacs libraries (if you do not have one), and put
{\tt flora.el} there. Such a directory can be added to emacs search path by
putting the following command in the file \verb|~/.emacs| (or
\verb|~/.xemacs|, if you are running one of the newer versions of XEmacs):
%%
\begin{quote}
  \tt
   (setq load-path (cons "your-directory" load-path)) 
\end{quote}
%%
It is also a good idea to compile emacs libraries. To compile flora.el,
use this:
%%
\begin{quote}
  \tt
   emacs -batch -f batch-byte-compile flora.el 
\end{quote}
%%
If you are using XEmacs, use {\tt xemacs} instead of {\tt emacs} above ---
the two emacsen often use incompatible byte code.

Finally, you must tell X/Emacs how to recognize \FLORA program files, so
Emacs will be able to invoke the Flora major mode automatically when you
are editing such files:
%%
\begin{verbatim}
(setq auto-mode-alist (cons '("\\.flr$" . flora-mode) auto-mode-alist))
(autoload 'flora-mode "flora" "Major mode for editing Flora programs." t)
\end{verbatim}
%%$

To enable syntactic highlighting of Emacs buffers (not just for \FLORA
programs), you can do the following:
%%
\begin{itemize}
  \item  {\sf In Emacs:} select {\tt Help.Options.Global Font Lock} on
    the menubar.  To enable highlingting permanently, put 
    %%
    \begin{quote}
      \tt
      (global-font-lock-mode t)
    \end{quote}
    %%
    in \verb|~/.emacs|.
  \item {\sf In XEmacs:} select {\tt Options.Syntax
        Highlighting.Automatic} in the menubar. To enable this permanently, put
      %%
      \begin{quote}
        \tt
        (add-hook 'find-file-hooks 'turn-on-font-lock)
      \end{quote}
      %%
      in \verb|~/.emacs| or \verb|~/.xemacs| (whichever is used by your
      XEmacs).
\end{itemize}
%%

\subsection{Functionality}
\paragraph{Menubar menu.}
Once flora editing mode is installed, it provides a number of functions.
First, whenever you edit a \FLORA program, you will see the ``Flora'' menu
in the menubar. This menu provides commands for controlling the Flora
process ({\it i.e.}, XSB with the \FLORA shell). You can start and stop
this process, type queries to it, and you can tell it to consult regions of
the buffer you are editing, the entire buffer, or some other file.

Because Emacs provides automatic file completion and allows you to edit
what you typed, performing these functions right out of the buffer takes
much less effort than typing the corresponding commands on XSB command
line.

\paragraph{Keyboard functions.}
In addition to the menu, \emph{flora-mode} lets you execute most of the
menu commands using the keyboard. Once you get the hang of it, keyboard
commands are much faster to invoke:
%%
\begin{verbatim}
Consult file:                 Ctl-c Ctl-f
Consult file dynamically:     Ctl-u Ctl-c Ctl-f
Consult buffer:               Ctl-c Ctl-b
Consult buffer dynamically:   Ctl-u Ctl-c Ctl-b
Consult region:               Ctl-c Ctl-r
Consult region dynamically:   Ctl-u Ctl-c Ctl-r
\end{verbatim}
%%
When you invoke any of the above commands, a \FLORA process is started,
unless it is already running. However, if you want to invoke this process
explicitly, type
%%
\begin{verbatim}
ESC x run-flora  
\end{verbatim}
%%
You can control the \FLORA process using the following commands:
%%
\begin{verbatim}
Interrupt Flora Process:      Ctl-c Ctl-c
Quit Flora Process:           Ctl-c Ctl-d
Restart Flora Process:        Ctl-c Ctl-s
\end{verbatim}
%%
Interrupting \FLORA is equivalent to typing {\tt Ctl-c} at the \FLORA
prompt, quitting the process stops XSB, and restarting the process shuts
down the old XSB process and starts a new one with \FLORA shell running.

\paragraph{Indentation.}
Flora editing mode understands some aspects of the \FLORA syntax, which
enables it to provide correct indentation of program lines (in many cases).
In the future, flora mode will know more about the syntax, which will let
it provide even better support for indentation.

The most common use of \FLORA indentation facility is by typing the {\tt
  TAB}-key. If \emph{flora-mode} manages to understand where the cursor is,
it will indent the line accordingly. Another way is to put the following in
your emacs startup file (\verb|~/.emacs| or \verb|~/.xemacs|):
%%
\begin{verbatim}
    (setq flora-electric t)  
\end{verbatim}
%%
In this case, whenever you type the return key, the next line will be
indented automatically.





\section{Future Enhancements}

\FLORA is work in progress. We are still experimenting with features and
nothing is cast in stone. So, although we do not intend to make the life of 
\FLORA users harder than it already is, we cannot give a guarantee of
backward compatibility. The following enhancements and features are among
currently planned:

%%
\begin{description}
  \item  [Syntax enhancements:]
    At present, the {\tt not} operator can be applied to predicates only.
    This restriction will be removed in the future, so it will be possible
    to negate arbitrary F-molecules.

    A future version of \FLORA will support a no-op. So, it will be possible
    to write F-molecules without worrying about the semicolon, {\it i.e.}, 
    {\tt a[m->b;;c->d;]}. It will be also possible to have extraneous commas:
    {\tt head :- b1,,b2,.}
  \item[Equality:] In a future release, equality
    maintenance will most
    likely be more restrictive: only the objects that are explicitly
    equated via an equality predicate in the head of a rule will be allowed
    to be equated. Any other derived equality will be treated as an error 
    (or a very stern warning).
  \item[Aggregates:] \FLORA will provide builtin functions that will
    directly apply to the outcome of the aggregates {\tt collectbag} and
    {\tt collectset}. This will make it possible to do grouping once and
    then compute multiple aggregates over the groups.
  \item[Work areas:] At present, \FLORA supports only one dynamic work area.
    A future version of \FLORA will support multiple dynamic work areas.
  \item[If-then-else:] \FLORA will provide the equivalent of the
    if-then-else construct, to make programs more readable.
  \item[Transaction logic:] \FLORA will be enhanced with Transaction Logic
    syntax.
  \item[Additional compiler directives:] An F-molecule and a path
    expression have two meanings: as an oid and as a truth value.
    Currently, an F-molecule or a path expression that occurs inside a
    predicate is interpreted as an object. This is not always desirable,
    however. For instance, in {\tt findall}, it is more appropriate to
    evaluate F-molecules that occur in the second argument to truth values.
    This can be done with compiler directives like:
    %%
    \begin{verbatim}
       :- arguments findall(oid,truth,oid)
    \end{verbatim}
    %%
    meaning that the first and the third arguments should be evaluated to
    their oids and the second argument should be evaluated to a truth
    value.

    \FLORA will also allow database declarations, like those 
    used in the XSB database interface.
\end{description}
%%


\bibliography{../../../docs/userman/manual}

\printindex

\end{document}
