Chris@0: Chris@0: Chris@0: Chris@0: Chris@0: SWI-Prolog Semantic Web Server Chris@0: Chris@0: Chris@0: Chris@0:

Chris@0:

SWI-Prolog Semantic Web Server
Chris@0:
Jan Wielemaker
Chris@0: Human Computer Studies (HCS),
Chris@0: University of Amsterdam
Chris@0: The Netherlands
Chris@0: E-mail: wielemak@science.uva.nl
Chris@0:
Chris@0:
Abstract
SWI-Prolog offers an Chris@0: extensive library for loading, saving and querying Semantic Web Chris@0: documents. Internally, the query language is `Prolog', building on top Chris@0: of an efficient implementation of a predicate rdf/3 Chris@0: expressing the content of the triple store. Chris@0: Chris@0:

Emerging dedicated Semantic Web query languages change this view. Chris@0: Supporting such languages provides a comfortable infrastructure for Chris@0: distributed Semantic Web processing systems. This document describes the Chris@0: SWI-Prolog Semantic Web Server. The server provides access to the Prolog Chris@0: triple store using either SeRQL or SPARQL. At the same time it is an Chris@0: extensible platform for realising Semantic Web based applications. Chris@0:

Chris@0: Chris@0:

Table of Contents

Chris@0: Chris@0:
Chris@0:
1Introduction
Chris@0:
2Query Chris@0: Languages
Chris@0:
2.1SPARQL Chris@0: Support
Chris@0:
2.2SeRQL Chris@0: Support
Chris@0:
3Installation Chris@0: and Administration
Chris@0:
3.1Getting Chris@0: started
Chris@0:
3.2Persistent Chris@0: store
Chris@0:
4Roadmap
Chris@0:
4.1Query Chris@0: processing and entailment
Chris@0:
4.2Query Chris@0: optimisation
Chris@0:
4.3Webserver
Chris@0:
5The Chris@0: Sesame client
Chris@0:
6Sesame Chris@0: interoperability
Chris@0:
7The Chris@0: SPARQL client
Chris@0:
8Security Chris@0: issues
Chris@0:
9Downloading
Chris@0:
Chris@0: Chris@0:

Chris@0: Chris@0:

1Introduction

Chris@0: Chris@0:

The SWI-Prolog Semantic Web Server unifies the SWI-Prolog general Web Chris@0: support and Semantic Web support, providing both a starting point for Chris@0: dedicated applications and a platform for exchange of RDF-based data Chris@0: using a standardised language and protocol. An overview of the Chris@0: SWI-Prolog Web support libraries can be found in SWI-Prolog Chris@0: and the Web,1Submitted to Chris@0: Theory and Practice of Logic Programming Chris@0: Chris@0:

2Query Chris@0: Languages

Chris@0: Chris@0:

The current server supports two query languages: Chris@0: SeRQL and Chris@0: SPARQL. Chris@0: For both languages we provide an interactive service that presents the Chris@0: results as a human-readable HTML table, a service presenting its result Chris@0: as RDF/XML or XML that follows the HTTP protocol definition for the Chris@0: query language, the possibility to query the local database using a Chris@0: query language in Prolog and a Prolog client that can be used to query Chris@0: remote services supporting the query language and HTTP service. Chris@0: Chris@0:

For both query languages, queries are translated to a complex Prolog Chris@0: goal calling rdf/3 Chris@0: to resolve edges in the graph and calls to predicates from Chris@0: rdfql_runtime.pl that realise constraints imposed by the SeRQL Chris@0: WHERE clause and SPARQL FILTER clauses. Chris@0: Chris@0:

2.1SPARQL Chris@0: Support

Chris@0: Chris@0:

SPARQL support is based on the SPARQL specification, versioned April Chris@0: 6, 2006. Status: Chris@0: Chris@0:

Chris@0: Chris@0:

2.2SeRQL Chris@0: Support

Chris@0: Chris@0:

SeRQL support and compatibility is based on development version Chris@0: 20040820, with additional support for the new 1.2 syntax and some of the Chris@0: built-in functions. Both SeRQL and the HTTP API are fully defined in the Chris@0: Sesame documentation. Chris@0: Chris@0:

3Installation Chris@0: and Administration

Chris@0: Chris@0:

3.1Getting Chris@0: started

Chris@0: Chris@0:

The file parms.pl contains a number of settings relevant Chris@0: to the server. Notable the port to connect to, where to store user Chris@0: information, etc. Persistent data kept by the server is a list of users Chris@0: and their access rights (default users.db) and a file-based Chris@0: backup of the in-memory store (default in the directory SeRQL-store). Chris@0: Please check the content of parms.pl and follow directions Chris@0: in the comments. On Unix-like systems, edit run.pl to Chris@0: adjust the location of SWI-Prolog on the !# line. Next, Chris@0: start run.pl and launch the server using the command below. Chris@0: Chris@0:

Chris@0: ?- serql_server.
Chris@0: 
Chris@0: Chris@0:

Now direct your browser to the server, using the default setup this Chris@0: is http://localhost:3020. Chris@0: If no users are defined the browser will prompt to enter the Chris@0: administrative password. After that the admin and anonymous users are Chris@0: created. Accounts can be created and modified by users with Chris@0: administrative rights through the Chris@0: List users ... link on the sidebar. Chris@0: Chris@0:

To restart from scratch, stop the server, delete the users database Chris@0: file and/or the triple backup file and restart the server as described Chris@0: above. Chris@0: Chris@0:

3.2Persistent Chris@0: store

Chris@0: Chris@0: Chris@0: Chris@0:

The parms.pl setting persistent_store(Directory, Chris@0: Options) can be used to specify file-based persistent backup for Chris@0: the in-memory triple store. The store is a combination of quick-load Chris@0: triple databases and journal files that hold the modifications made to Chris@0: the triple store. Details of the persistent store are documented with Chris@0: the SWI-Prolog Chris@0: Semantic Chris@0: Web package Chris@0: Chris@0:

4Roadmap

Chris@0: Chris@0:

4.1Query Chris@0: processing and entailment

Chris@0: Chris@0: Chris@0: Chris@0:

The kernel of the system is formed by serql.pl and sparql, Chris@0: that implement the DCG parsers for the respective query languages as Chris@0: well as a compiler that translates this into a Prolog goal executing the Chris@0: query op top of the SWI-Prolog SemWeb package. The file Chris@0: rdfql_runtime.pl contains predicates that implement the Chris@0: constraints (SeRQL WHERE or SPARQL FILTER) and other constructs Chris@0: generated by the query-compiler. Chris@0: Chris@0:

Entailment reasoning is defined by rdf_entailment.pl. Chris@0: Specific entailments are in seperate files: Chris@0: Chris@0:

Chris@0:
no_entailment.pl
Chris@0:
Chris@0: Defines entailment none. Query explicitely stored triples Chris@0: only.
Chris@0:
rdf_entailment.pl
Chris@0:
Chris@0: Defines entailment rdf. Any resource appearing in a Chris@0: predicate position is of type rdf:Property. Any subject is Chris@0: an instance of rdf:Resource
Chris@0:
rdfs_entailment.pl
Chris@0:
Chris@0: Defines entailment rdfs. Adds class- and property-hierarchy Chris@0: reasoning to RDF reasoning, as well as reasoning on the basis of Chris@0: property domain and range.
Chris@0:
rdfslite_entailment.pl
Chris@0:
Chris@0: Defines entailment rdfslite. Only considers the class- and Chris@0: property-hierarchy. Using a backward chaining solver this is much Chris@0: faster, while normally keeping the intended meaning. Chris@0:
Chris@0:
Chris@0: Chris@0:

The query compiler and execution system can be called directly from Chris@0: Prolog. Chris@0: Chris@0:

Chris@0:
serql_compile(+Query, Chris@0: -Compiled, +Options)
Chris@0:
Chris@0: Compile Query, which is either an atom or a list of character Chris@0: codes and unify Compiled with an opaque term representing the Chris@0: query and suitable for passing to serql_run/2. Chris@0: Defined Chris@0: Options are: Chris@0: Chris@0:
Chris@0:
entailment(Entailment)
Chris@0:
Chris@0: Entailment to use. Default is rdfs. See section Chris@0: 4.1.
Chris@0:
type(-Type)
Chris@0:
Chris@0: Extract the type of query compiled and generally useful information on Chris@0: it. SeRQL defines the types construct and Chris@0: select(VarNames), where VarNames is a list of Chris@0: variables appearing in the projection.
Chris@0:
optimise(Bool)
Chris@0:
Chris@0: Whether or not to optimise the query. Default is defined by the setting Chris@0: optimise_query. Chris@0:
Chris@0:
Chris@0: Chris@0:
Chris@0:
sparql_compile(+Query, Chris@0: -Compiled, +Options)
Chris@0:
Chris@0: Similar to to serql_compile/3. Chris@0: Defined types are extended with Chris@0: describe and ask. Addional options are: Chris@0: Chris@0:
Chris@0:
base_uri(-URI)
Chris@0:
Chris@0: Base URI used to compile the query if not specified as part of the Chris@0: query.
Chris@0:
ordered(-Bool)
Chris@0:
Chris@0: Unify Bool with true if query contains an ORDER BY Chris@0: clause.
Chris@0:
distinct(-Bool)
Chris@0:
Chris@0: Unify Bool with true if query contains a DISTINCT Chris@0: modifier. Chris@0:
Chris@0:
Chris@0: Chris@0:
Chris@0:
serql_run(+Compiled, Chris@0: -Answer)
Chris@0:
Chris@0: Run a query compiled by serql_compile/3, Chris@0: returning terms row(Arg ...) for select queries and terms rdf(Subject, Chris@0: Predicate, Object) for construct queries. Subsequent results are Chris@0: returned on backtracking.
Chris@0:
sparql_run(+Compiled, Chris@0: -Answer)
Chris@0:
Chris@0: Similar to serql_run/2. Chris@0: Queries of type describe return rdf-terms like construct. Chris@0: Queries of type ask return either true or false.
Chris@0:
serql_query(+Query, Chris@0: -Answer, +Options)
Chris@0:
Chris@0: Utility combining of serql_compile/3 Chris@0: and serql_run/2. Chris@0: Note this gives no access to the column-names.
Chris@0:
sparql_query(+Query, Chris@0: -Answer, +Options)
Chris@0:
Chris@0: Similar to serql_query/3. Chris@0:
Chris@0:
Chris@0: Chris@0:

4.2Query Chris@0: optimisation

Chris@0: Chris@0:

By default, but under control of the setting/1 Chris@0: option Chris@0: optimise_query(Bool), and the option optimise(Bool), Chris@0: the query compiler optimises initial goal obtained from naive Chris@0: translation of the query text. The optimiser is defined in rdf_optimise.pl. Chris@0: The optimiser is described in detail in An Chris@0: optimised Semantic Web query language implementation in Prolog. The Chris@0: optimiser reorders goals in the generated conjunction and prepares for Chris@0: independent execution of independent parts of the generated goal. With Chris@0: the optimiser enabled (default), the provided order of path-expressions Chris@0: on the query text is completely ignored and constraints are inserted at Chris@0: the earliest possible point. Chris@0: Chris@0:

The SeRQL LIKE operator applies to both resources and Chris@0: literals, while the SWI-Prolog RDF-DB module can only handle LIKE Chris@0: efficiently on literals. The optimiser can be made aware of this using Chris@0: WHERE label(X) LIKE "joe*". Taking the label informs the Chris@0: optimiser that it only needs to consider literals. Likewise, equivalence Chris@0: tests where one of the arguments is used as subject or predicate or has Chris@0: the isResource(X) constraint tell the system it can do straight Chris@0: identifier comparison rather then the much more expensive general Chris@0: comparison. Chris@0: Chris@0:

Query optimisation is not yet supported for SPARQL. Chris@0: Chris@0:

4.3Webserver

Chris@0: Chris@0:

The webserver is realised by server.pl, merely loading Chris@0: both components: http_data.pl providing the Sesame HTTP API Chris@0: using the same paths and parameters and http_user.pl Chris@0: providing a browser-friendly frontend. Error messages are still very Chris@0: crude and almost all errors return a 500 server error page with a Chris@0: transcription of the Prolog exception. Chris@0: Chris@0:

The Sesame HTTP API deals with a large number of data formats, only Chris@0: part of which are realised by the current system. This realisation is Chris@0: achieved through rdf_result, providing an extensible API Chris@0: for reading and writing in different formats. rdf_html, Chris@0: rdf_write and xml_result provide some Chris@0: implementations thereof. Chris@0: Chris@0:

5The Chris@0: Sesame client

Chris@0: Chris@0:

The file sesame_client.pl, created by Maarten Chris@0: Menken provides an API to remote Sesame servers. Below is a brief Chris@0: documentation of the available primitives. All predicates take an option Chris@0: list. To simplify applications that communicate with a single server Chris@0: defauls for the server and reposititory locations can be specified using Chris@0: set_sesame_default/1. Chris@0: Chris@0:

Chris@0:
set_sesame_default(+DefaultOrList)
Chris@0:
Chris@0: This predicate can be used to specify defaults for the options available Chris@0: to the other Sesame interface predicates. A default is a term Option(Value). Chris@0: If a list of such options is provided all options are set in the order Chris@0: of appearance in the list. This implies options later in the list may Chris@0: overrule already set options. Defined options are: Chris@0: Chris@0:
Chris@0:
host(Host)
Chris@0:
Chris@0: Hostname running the Sesame server. Chris@0:
Chris@0:
port(Port)
Chris@0:
Chris@0: Por the sesame server listens on. Chris@0:
Chris@0:
path(Path)
Chris@0:
Chris@0: Path from the root to the Sesame server. For the SWI-Prolog Sesame Chris@0: client, this is normally the empty atom (''). For thte Java Chris@0: based Sesame this is normally '/sesame'. Chris@0:
Chris@0:
repository(Repository)
Chris@0:
Chris@0: Name of the repository to connect to. See also Chris@0: sesame_current_repository/3. Chris@0:
Chris@0:
Chris@0: Chris@0:

Below is a typical call to connect to a sesame server: Chris@0: Chris@0:

Chris@0: ...,
Chris@0: set_sesame_default([ host(localhost),
Chris@0:                      port(8080),
Chris@0:                      path('/sesame'),
Chris@0:                      repository('mem-rdfs-db')
Chris@0:                    ]).
Chris@0: 
Chris@0: Chris@0:
Chris@0:
sesame_current_repository(-Id, Chris@0: -Properties, +Options)
Chris@0:
Chris@0: Enumerate the currently available Sesame repositories. Id is Chris@0: unified to the name of the repository. Properties is a list Chris@0: of Name(Value) terms providing title and access details. Chris@0: Options specifies the host, port and path of the server.
Chris@0:
sesame_clear_repository(+Options)
Chris@0:
Chris@0: Remove all content from the repository. Options specifies the Chris@0: host, port and path of the server as well as the target repository.
Chris@0:
sesame_login(+User, Chris@0: +Password, +Options)
Chris@0:
Chris@0: Login to a Sesame server. On success the returned cookie is stored and Chris@0: transmitted with each query on the same server. Options Chris@0: specifies the host, port and path of the server.
Chris@0:
sesame_logout(+Options)
Chris@0:
Chris@0: Options specifies the host, port and path of the server.
Chris@0:
sesame_graph_query(+Query, Chris@0: -Triple, +Options)
Chris@0:
Chris@0: Execute Query on the given server and return the resulting Chris@0: triples on backtracking. Options specifies the host, port and Chris@0: path of the server as well as the target repository. The example below Chris@0: extracts all type relations from the default server. Chris@0: Chris@0:
Chris@0: ...,
Chris@0: sesame_graph_query('construct * from {s} <rdf:type> {o}',
Chris@0:                    rdf(S,P,O),
Chris@0:                    []),
Chris@0: 
Chris@0: Chris@0:
Chris@0:
sesame_table_query(+Query, Chris@0: -Row, +Options)
Chris@0:
Chris@0: Execute Query on the given server and return the resulting Chris@0: rows on backtracking. Each Row is a term of the format Chris@0: row(Col1, Col2, ... ColN). Options specifies the Chris@0: host, port and path of the server as well as the target repository.
Chris@0:
sesame_extract_rdf(-Triple, Chris@0: +Options)
Chris@0:
Chris@0: Extract all content from an RDF repository. In addition to the server Chris@0: and repository options the following options are defined: Chris@0: Chris@0:
Chris@0:
schema(OnOff)
Chris@0:
Chris@0: Extract the schema information. Chris@0:
Chris@0:
data(OnOff)
Chris@0:
Chris@0: Extract the plain data Chris@0:
Chris@0:
explicit_only(OnOff)
Chris@0:
Chris@0: Determine whether or not entailed triples are returned. Default is off, Chris@0: returning both explicit and inferred triples. Chris@0:
Chris@0:
Chris@0: Chris@0:
Chris@0:
sesame_upload_file(+File, Chris@0: +Options)
Chris@0:
Chris@0: dd the content of File to the repository. In addition to the Chris@0: server and repository options the following options are defined: Chris@0: Chris@0:
Chris@0:
data_format(+Format)
Chris@0:
Chris@0: Format of the input file. Default is rdfxml. Chris@0:
Chris@0:
base_uri(+BaseURI)
Chris@0:
Chris@0: URI for resolving local names. Default is foo:bar. Chris@0:
Chris@0:
verify_data(OnOff)
Chris@0:
Chris@0: Do/do not verify the input. Default is off. Chris@0:
Chris@0:
Chris@0: Chris@0:
Chris@0:
sesame_assert(+TripleOrList, Chris@0: +Options)
Chris@0:
Chris@0: Assert a single rdf(Subject, Predicate, Object) or a list Chris@0: of such terms. In addition to the server and repository options the Chris@0: following options are defined: Chris@0: Chris@0:
Chris@0:
base_uri(+BaseURI)
Chris@0:
Chris@0: URI for resolving local names. Default is foo:bar. Chris@0:
Chris@0:
Chris@0: Chris@0:
Chris@0:
sesame_retract(+Triple, Chris@0: +Options)
Chris@0:
Chris@0: Remove a triple from the repository. Variables in Triple match all Chris@0: values for that field. Chris@0:
Chris@0:
Chris@0: Chris@0:

6Sesame Chris@0: interoperability

Chris@0: Chris@0:

The SWI-Prolog SeRQL engine provides a (still incomplete) drop-in Chris@0: replacement for the Sesame HTTP access protocol. Sesame's remote server Chris@0: class can be used to access the SWI-Prolog SeRQL engine through the Chris@0: Sesame Java API. Likewise the Prolog client realised by Chris@0: sesame_client.pl provides a Prolog API that can be used to Chris@0: access both Sesame and the SWI-Prolog SeRQL engine. Chris@0: Chris@0:

7The Chris@0: SPARQL client

Chris@0: Chris@0:

The file sparql_client.pl provides a client to the Chris@0: SPARQL HTTP protocol. The protocol defines how a SPARQL query is asked Chris@0: over HTTP and how the results are presented. It is possible to use the Chris@0: SeRQL protocol on the same server to perform tasks such as modifying the Chris@0: triple store. Chris@0: Chris@0:

The structure of the SPARQL client API is closely based on the SeRQL Chris@0: client. Chris@0: Chris@0:

Chris@0:
sparql_query(+Query, Chris@0: -Row, +Options)
Chris@0:
Chris@0: Run a SPARQL query on a remote server, retrieving the results one-by-one Chris@0: on backtracking. Options provide the host, port and path of Chris@0: the server. sparql_set_server/1 Chris@0: can be used to define default locations.
Chris@0:
sparql_set_server(+Options)
Chris@0:
Chris@0: List of options that act as defaults for sparql_query/3. Chris@0: Commonly set to specify the server location. For example: Chris@0: Chris@0:
Chris@0: ?- sparql_set_server([ host(localhost),
Chris@0:                        port(3020),
Chris@0:                        path('/sparql/')
Chris@0:                      ]).
Chris@0: 
Chris@0: Chris@0:

Chris@0:
Chris@0: Chris@0:

8Security Chris@0: issues

Chris@0: Chris@0:

HTTP Communication with the server, including usernames and Chris@0: passwords, is in cleartext and therefore sensitive to sniffing. The Chris@0: overall security of the server is unknown. It is advised to run the Chris@0: server as user with minimal access rights, only providing write access Chris@0: to the user database file. Chris@0: Chris@0:

9Downloading

Chris@0: Chris@0:

The SWI-Prolog SeRQL engine is available from CVS using the following Chris@0: commands: Chris@0: Chris@0:

Chris@0: % cvs -d :pserver:pl@gollem.science.uva.nl:/usr/local/cvspl login
Chris@0: Password: prolog
Chris@0: % cvs -d :pserver:pl@gollem.science.uva.nl:/usr/local/cvspl co SeRQL
Chris@0: 
Chris@0: Chris@0:

Infrequently announces and snapshots are provided through the Chris@0: Prolog Chris@0: Wiki Chris@0: Chris@0:

Acknowledgements

Chris@0: Chris@0:

The SeRQL server has been realised as part of the HOPS Chris@0: project and could not have been done without Sesame and feedback Chris@0: from Jeen Broekstra and Maarten Menken from the Free University of Chris@0: Amsterdam (VU). Adding SPARQL support has been realised as part of the Chris@0: E-culture sub-project of Dutch MultiMedia project. Chris@0: Chris@0:

Index

Chris@0: Chris@0:
Chris@0:
R
Chris@0:
Chris@0:
Chris@0:
rdf/3
Chris@0:
Chris@0: 2
Chris@0:
S
Chris@0:
Chris@0:
Chris@0:
serql_compile/3
Chris@0:
Chris@0: 4.1 4.1 4.1
Chris@0:
serql_query/3
Chris@0:
Chris@0: 4.1
Chris@0:
serql_run/2
Chris@0:
Chris@0: 4.1 4.1 4.1
Chris@0:
sesame_assert/2
Chris@0:
Chris@0:
Chris@0:
sesame_clear_repository/1
Chris@0:
Chris@0:
Chris@0:
sesame_current_repository/3
Chris@0:
Chris@0: 5
Chris@0:
sesame_extract_rdf/2
Chris@0:
Chris@0:
Chris@0:
sesame_graph_query/3
Chris@0:
Chris@0:
Chris@0:
sesame_login/3
Chris@0:
Chris@0:
Chris@0:
sesame_logout/1
Chris@0:
Chris@0:
Chris@0:
sesame_retract/2
Chris@0:
Chris@0:
Chris@0:
sesame_table_query/3
Chris@0:
Chris@0:
Chris@0:
sesame_upload_file/+File, Chris@0: +Options
Chris@0:
Chris@0:
Chris@0:
set_sesame_default/1
Chris@0:
Chris@0: 5
Chris@0:
setting/1
Chris@0:
Chris@0: 4.2
Chris@0:
sparql_compile/3
Chris@0:
Chris@0:
Chris@0:
sparql_query/3
Chris@0:
Chris@0: 7
Chris@0:
sparql_run/2
Chris@0:
Chris@0:
Chris@0:
sparql_set_server/1
Chris@0:
Chris@0: 7
Chris@0:
Chris@0: Chris@0: