
		 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		 %	   CASE 1: SeRQL	%
		 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Case study --- A Semantic Web Query Language}
\label{sec:serql}

In this case-study we describe the SWI-Prolog SeRQL implementation.%
    \footnote{\url{http://www.swi-prolog.org/packages/SeRQL}}
SeRQL is an RDF query language developed as part of the Sesame project%
    \footnote{\url{http://www.openrdf.org}} \cite{Broekstra:02a}.
SeRQL uses HTTP as its access protocol. Sesame consists of an
implementation of the server as a Java servlet and a Java
client-library. By implementing a compatible framework we made our
Prolog based RDF storage and reasoning engine available to Java clients.
The Prolog SeRQL implementation uses all of the described SWI-Prolog
infrastructure and building it has contributed significantly to the
development of the infrastructure. \Figref{serql} lists the main
components of the server.

\begin{figure}
    \centerline{\includegraphics[width=0.7\linewidth]{serql}}
    \caption{Module dependencies of the SeRQL system.  Arrows denote
	     `imports from' relations.}
    \label{fig:serql}
\end{figure}

The \jargon{entailment} modules are plugins that implement the
entailment approach to RDF reasoning described in \secref{rdfreasoning}.
They implement \index{rdf/3}\predref{rdf}{3} as a pure predicate, adding implicit triples to the
raw triples loaded from RDF/XML documents. \Figref{rdfentail2} shows the
somewhat simplified entailment module for RDF. The multifile rule
registers the module as entailment module for the SeRQL system. New
modules can be loaded dynamically into the platform, providing support
for other SW languages or application-specific server-side reasoning.
Prolog's dynamic loading and re-loading allows for updating such
reasoning modules on the life server.

\begin{figure}
\figrule
\begin{verbatim}
:- module(rdf_entailment, [rdf/3]).

rdf(S, P, O) :-
        rdf_db:rdf(S, P, O).
rdf(S, rdf:type, rdf:'Property') :-
        rdf_db:rdf(_, S, _),
        \+ rdf_db:rdf(S, rdf:type, rdf:'Property').
rdf(S, rdf:type, rdfs:'Resource') :-
        rdf_db:rdf_subject(S),
        \+ rdf_db:rdf(S, rdf:type, rdfs:'Resource').

:- multifile serql:entailment/2.
serql:entailment(rdf, rdf_entailment).
\end{verbatim}

\noindent
    \caption{RDF entailment module}
    \label{fig:rdfentail2}
\figrule
\end{figure}

The SeRQL parser is a DCG-based parser translating a SeRQL query
text into a compound goal calling \index{rdf/3}\predref{rdf}{3} and predicates from the
SeRQL runtime library which provide comparison and functions built into
the SeRQL language. The resulting control-structure is passed to the
query optimiser \cite{Wielemaker:05a} which uses statistics maintained
by the RDF database to reorder the pure \index{rdf/3}\predref{rdf}{3} calls for best
performance. The optimiser uses a generate-and-evaluate approach to find
the optimal order. Considering the frequently long conjunctions of \index{rdf/3}\predref{rdf}{3}
calls, the conjunction is split into independent parts.
\Figref{rdfsplit} illustrates this in a very simple example. During
abstract execution, information on instantiation and types implied by
the runtime library predicates is attached to the variables using
dynamic attributed variables. \cite{Demoen:CW350}. 

\begin{figure}
\figrule
\begin{verbatim}
        ...
        rdf(Paper, author, Author),
        rdf(Author, name, Name),
        rdf(Author, affiliation, Affil),
        ...
\end{verbatim}

\noindent
    \caption{Split rdf conjunctions.  After executing the first \index{rdf/3}\predref{rdf}{3}
	     query \arg{Author} is bound and the two subsequent queries
	     become independent.  This is also true for other orderings,
	     so we only need to evaluate 3 alternatives instead of 3!
	     (6).}
    \label{fig:rdfsplit}
\figrule
\end{figure}

HTTP access consists of two parts. The human-centred portal consists of
HTML pages with forms to administer the server as well as view
statistics, load and unload documents and run SeRQL queries
interactively presenting the result as an HTML table. Dynamic pages are
generated using the \file{html_write.pl} library described in
\secref{htmlwrite}. Static pages are served from HTML files by the
Prolog server. Machines use HTTP POST requests to provide query data and
get a reply in XML or RDF/XML.

The system knows about various RDF input and output formats. To reach
modularity the kernel exchanges RDF graphs as lists of terms
\term{rdf}{S,P,O} and result-tables as lists of terms using the functor
\const{row} and arity equal to the number of columns in the table. The
system calls a multifile predicate using the format identifier and data
to realise the requested format. The HTML output format use
\file{html_write.pl}. The RDF/XML format uses \index{rdf_write_xml/2}\predref{rdf_write_xml}{2} described
in \secref{rdfio}. Both \index{rdf_write_xml/2}\predref{rdf_write_xml}{2} and the other XML output format
use straight calls \index{format/3}\predref{format}{3} to write the document, where quoting values
is realised by quoting primitives provided by the SGML/XML parser
described in \secref{markupdom}. Using direct writing instead of
techniques described in \secref{htmlwrite} avoids potentially large
intermediate datastructures and is not very complicated given the very
simple structure of the documents.


\subsection{Evaluation}

The SeRQL server and the SWI-Prolog library development is too closely
integrated to use it as an evaluation of the functionality provided
by the Web enabling libraries. We compared our server to Sesame, written
in Java. The source code of the Prolog based server is 6,700 lines,
compared to 86,000 for Sesame. As both systems have very different
coverage in functionality and can re-use libraries at different
levels it is hard to judge these figures. Both answer trivial queries in
approximately 5ms on a dual AMD 1600+ PC running Linux 2.6. On complex
queries the two systems perform very different. Sesame's forward
reasoning make it handle some RDFS queries much faster. Sesame does not
contain a query optimizer which cause order-dependent and sometimes very
long response times on large conjunctions.

The power of LP where programs can be handled as data is exploited by
parsing the SeRQL query into a program, optimizing the program by
manipulating it as data, after which we can simply call it to answer the
query. The non-deterministic nature of \index{rdf/3}\predref{rdf}{3} allow for a trivial
translation of the query to a non-deterministic program that produces
the answers on backtracking.

The server only depends on the standard SWI-Prolog distribution and
therefore runs unmodified on all systems supporting SWI-Prolog. It has
been tested on Windows, Linux and MacOS X.

All infrastructure described is used in the server. We use \index{format/3}\predref{format}{3},
exploiting XML quoting primitives provided by the Prolog XML library to
print highly repetitive XML files such as the SeRQL result-table.
Alternatively we could have created the corresponding DOM term and
call \index{xml_write/2}\predref{xml_write}{2} from the library \file{sgml_write.pl}.
