RDF Applications with Prolog
In the first article in this series, I explained some of the semantics of RDF via Prolog (and vice versa). In this article, I'll explore some of the nitty-gritty of working with RDF in Prolog using the SWI-Prolog system.
Using RDF with SWI-Prolog
SWI-Prolog is a fast, robust, and free open-source Prolog system with great support for XML and RDF. It's being used as an inference engine for Mozilla and in several other RDF projects. With the release of SWI-Prolog 4.0.0 the graphics, GUI, and object library XPCE have been bundled in. XPCE is a rich and powerful cross-platform (Windows and Unixen) toolkit with a number of immediately useful demos, including various drawing systems, a partial HTML renderer, a help system, and an Emacs clone.
All in all, a wonderful system both for play and for serious work, and for play that becomes serious work!
A good example application of SWI-Prolog's RDF support is the online RDF parser demo. Here you can upload or paste RDF documents in RDF/XML syntax and get an HTML table presentation of the statements. Even with its few quirks, I find it handy for debugging RDF documents (indeed, somewhat handier than the oft-recommended RDFviz, especially for anything other than small documents).
First Steps with SWI-Prolog's RDF Tools
SWI-Prolog comes bundled with several modules for parsing RDF/XML and manipulating the result at various levels of detail and convenience. Assuming you have a SWI-Prolog 4.0.x installation running, you can load the bundled modules by typing at the "command", (ie. query), prompt:
?-[library(rdf)].
and hitting enter. On my machine, it prints back:
% library(sgml) compiled into sgml 0.27 sec, 12,536 bytes % uri compiled into uri 0.00 sec, 1,804 bytes % rewrite compiled into rewrite 0.00 sec, 5,716 bytes % rdf_parser compiled into rdf_parser 0.17 sec, 24,168 bytes % library(gensym) compiled into gensym 0.00 sec, 2,096 bytes % rdf_triple compiled into rdf_triple 0.06 sec, 10,924 bytes % library(rdf) compiled into rdf 0.56 sec, 56,080 bytes
In other words, all the modules on which the RDF library depends get loaded. The library(sgml) module handles SGML, HTML, and XML parsing, and it's quite nifty in its own right.
In Prolog lingo, to load a file that contains a knowledge
base/list-of-definitions is to consult it. The square
brackets are just a bit of syntactic sugar for this process. The
consulting involves reading each clause, perhaps doing a bit
of processing on the read terms, and then asserting the
clause into the Prolog knowledge base. Consulting a file puts all of
its predicates right into the global knowledge base, which can be a
problem if there are conflicts. Fortunately, SWI-Prolog has a
module system and, as one can see above, facilities for indicating
and managing dependencies. Thus, it might have been better to have
used use_module(library(rdf)). instead of (the syntactic
sugar for) consult(library(rdf). above, but in the
current context it doesn't really matter.
Prolog predicates are distinguished by name and arity
(i.e., number of permissible arguments). So you'll see things like
cool_predicate/1, cool_predicate/2,
etc. Each of these is a completely different predicate. This may feel
odd to folks used to the possibility of having optional and defaulted
arguments (e.g., as in Python), but it works out very well in
practice.