Did you know ... | Search Documentation: |
Whitepaper: The ClioPatria Semantic Web server |
ClioPatria is a (SWI-)Prolog hosted HTTP application-server with libraries for Semantic Web reasoning and a set of JavaScript libraries for presenting results in a browser. Another way to describe ClioPatria is as ``Tomcat+Sesame (or Jena) with additional reasoning libraries in Prolog, completed by JavaScript presentation components''.
Prolog is a logic-based language using a simple depth-first resolution strategy (SLD resolution). This gives two readings to the same piece of code: the declarative reading and the procedural reading. The declarative reading facilitates understanding of the code and allows for reasoning about it. The procedural reading allows for specifying algorithms and sequential aspects of the code, something which we often need to describe interaction. In addition, Prolog is reflexive: it can reason about Prolog programs and construct them at runtime. Finally, Prolog is, like the RDF triple-model, relational. This match of paradigms avoids the complications involved with using Object Oriented languages for handling RDF (see below). We illustrate the fit between RDF and Prolog by translating an example query from the official SPARQL document:
SPARQL:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name . ?x foaf:mbox ?mbox }
Below we define this query as a Prolog predicate. The translation is natural and compact. The query is expressed as a Prolog program rather than a string. This ensures that Prolog can reason about it: it validates the syntax and verifies the dependencies between this code fragment and the remainder of the application. See Wikipedia if you need some introduction to the language.
:- rdf_register_ns(foaf, 'http://xmlns.com/foaf/0.1/'). name_mbox(Name, MBox) :- rdf(X, foaf:name, literal(Name)), rdf(X, foaf:mbox, MBox).
We can run this query interactively from the terminal as illustrated
below. Here, the `;
' is typed by the user asking for another
solution and the final `.
' indicates there are no more solutions.
?- name_mbox(Name, MBox). Name = 'Johnny Lee Outlaw', MBox = 'mailto:jlow@example.com' ; Name = 'Peter Goodguy', MBox = 'mailto:peter@example.org'.
Returning all solutions is all that is provided by the SPARQL query. However, our program is capable of doing more because it describes the logical relation ``_Name_ is the name of an entity that has mailbox _MBox_''. Therefore, we can ask:
?- name_mbox('Johnny Lee Outlaw', X). MBox = 'mailto:jlow@example.com'.
This is different from a loop over the resuls from the SPARQL query
because the query does not iterate over all name-mailbox tuples, but
only over those that have a resource with a name-property with the value
'Johnny Lee Outlaw'
. Finally, we can use the relation as a boolean
test:
?- name_mbox('Johnny Lee Outlaw', 'mailto:peter@example.org'). false.
Prolog's resolution technique has created a powerful building block for more complex queries from this simple translation of the SPARQL query. We can use this to create more complex queries. E.g., if we want to send a personalised message to all members on a mailinglist, we need the members and their names. The code below combines a simple statement query with the already-defined relation name_mbox/2.
employee_name_email(List, MBox, Name) :- rdf(List, list:member, MBox), name_mbox(Name, MBox).
Above, we used simple Prolog SLD resolution to join RDF statement queries. Proper RDF query language implementation perform optimisation. Here we can exploit Prolog's reflexive capabilities. The code below reorganises the conjunction of the two rdf/3 goals to achieve optimal performance dynamically. This optimisation is based on the database dynamics and which arguments are given (instantiated). E.g., if we call this relation with a given MBox it will swap the two RDF statements.
:- use_module(serql(rdf_optimise)). name_mbox(Name, MBox) :- rdf_optimise((rdf(X, foaf:name, Name), rdf(X, foaf:mbox, MBox)), Goal), call(Goal).
rdf(Subject, Predicate, Object)
(rdf/3)
suffices to realise all the basic graph-pattern matching that
can be done in SPARQL.Above, we compared querying the triple-store in Prolog with SPARQL. What if we compare Prolog to using Sesame/Jena as a library? The marriage between Object Oriented systems and relational data in general and RDF in particular is discussed in ActiveRDF: embedding Semantic Web data into object-oriented languages. Roughly, static languages such as Java allow for three approaches. Each of these either require setting up an enumerator or dealing with sets.
Joining results from any of these three possibilities requires hand-crafted (nested) loops. Statically typed Object Oriented languages cannot easily overcomes these problems. For dynamically typed languages such as Ruby, the situation can be improved significantly as demonstrated by the ActiveRDF project. ActiveRDF abstracts from the RDF store and builds upon a well-established web-application development platform, but its handling of RDF is still cumbersome compared to what a relational language such as Prolog can achieve.
This section gives the highlights of the functionality you can find in ClioPatria.
You need two things to run ClioPatria: the ClioPatria sources and
a recent version of SWI-Prolog that fits your computer. If you
want thumbnail support to show images, you also need convert
from the ImageMagic project. Here are the URLs for downloading:
ClioPatria runs on all major platforms supported by SWI-Prolog: Windows (32- and 64-bits), MacOSX, Linux (32- and 64-bits) and, from source, almost any Unix system.