Prolog Server Pages

Random Photo
Random Photo:
My Favorite City
 

Prolog is one of my favorite languages. I thought it would be fitting to write my website using the language, rather than one of the more mundane web development languages such as PHP or JSP. To do this, I could have put together some simple CGI scripts, but I thought it would be much more elegant to implement Prolog Server Pages. I believe that the successful implementation of the first version of a simple "Server Pages" system in just a few hours, is quite a testament to the flexibility and power of Prolog, and it's suitability for certain kinds of web development.

While it is possible to implement a minimal PSP interpreter in a few hours, I've significantly expanded and rewritten my first PSP interpreter several times to finally create a version that I believe has a nice syntax, and that is quite powerful and robust.

The idea of Prolog Server Pages (PSP) is quite simple - to create a web-based scripting language that allows Prolog programmers to create interactive websites in Prolog, but without the complexity and difficulty of having to manually parse and generate HTTP/HTML. So basically, I just want to be able to mix HTML and Prolog without having to worry about too much manual coding. PHP, ASP and JSP are well known web development languages that are based on the same kind of idea and have a similar syntax to PSP.

To go straight to the download page, click here.

Prior Work

I'm not certainly not the first to have had this idea, in fact I'm not even the first to use the name "Prolog Server Pages". Consider some of the other Prolog based systems and approaches that I am aware of:

Minerva Prolog

Minerva Prolog is a commercial Prolog system which appears to be specifically designed for integration with Java and web projects. Minerva offers a web scripting language (apparently called *.mss, after the file extension) based on Prolog. In this white paper, Oskar Bartenstein presents an example of the language:

<%@ function simple_mss %>
<html><head><head>
<body>
     <% begin Greeting='Hello' %>
          &Greeting;
     <% end %>
</body>
</html>
<% end %>

Further examples can be seen by downloading a trial version of Minerva Prolog from the Minerva website. It becomes clear on examining the language, that while it may certainly be a powerful and useful language for web-based development, it isn't really a dialect of Prolog, but is more like a macro language for web-based Prolog development.

Prolog Server Pages

Prolog Server Pages is another project with a similar objective and the same name as mine. I can't find any information about the system other than one paper (available here). In the paper Alin Suciu, Kalman Pusztai and Andrei Vancea describe their PSP implementation. Here is an example from their paper:

<html>
<head>
<title>Hello World example</title>
</head>
<body>
<?psp
msg('Hello, World!').
?-msg(X), write(X).
?>
</body>
</html>

In my opinion, this is an improvement over the Minerva approach because it does not depend on learning new directives and syntax. However, this approach is still deficient in that it doesn't really separate between declaration and execution in Prolog. Presumably the described system compiles the PSP into Prolog by replacing HTML blocks with code such as ?- write('<html>...), and then consulting the compiled file. HTML can therefore not be used conveniently within Prolog clauses - for example, if I understand the paper correctly, it is not possible to either generate tables and repeating HTML elements without manually coding such HTML into the clause, or to have variables with scope greater than a single block of text (i.e., a <?= X ?> style of include is not possible).

General Server Pages

General Server Pages (GSP) is a generalization of the "Server Pages" concept to allow any language to be embedded into a server-side HTML document. The author, Sebastian Devaux, added a backend to support Prolog:

<html>
<%@ language="prolog"
	mime type = "text/html"
	%>
<%!
/*
 * a comment to test the ! tag
 */
%>
<body>
<%
	Hello='Hello world',
	A=20,
	B=22,
	C is A+B,
%>
<h1><%=Hello%></h1>
<p>The answer is <%=C%></p>
</body>
</html>

Personally, I really like this syntax. In fact, I probably wouldn't have attempted creating my own PSP had I come across GSP at first. However, I think my implementation is slightly better because it solves three deficiencies in the above syntax:

  • GSP appears to be slightly inconsistent (with commas)
  • GSP does not appear to support declaring more than one clause
  • GSP can be difficult to debug

SWI Prolog HTTP Server

SWI Prolog (and I'm sure many other Prolog systems) includes a HTTP library that allows you create a HTTP server in Prolog (even including SSL support!). SWI Prolog also incorporates support for a natural syntax for HTML manipulation where prolog terms represent HTML tags. This is a fantastic way of creating logic intensive web applications.

While I have used SWI Prolog's HTTP Server library for writing web applications, I wrote PHP because I had a different objective in mind. Here are what I saw as the deficiencies of the pure-prolog approach:

  • The difficulty of managing largely textual sites that contain small amounts of minimal logic.
  • The difficulty of using the approach in a mixed environment (e.g., with PHP, JSP and even just plain old Apache SSL).

In this Usenet posting, Jan Wielemaker mentions his syntax for "Prolog Server Pages". Jan admits it was just for the fun of it, but doesn't publicly distribute the code (except on special request) and doesn't support it either.

CGI Scripting

CGI Scripting is a very easy popular way of integrating Prolog with a webserver (in fact, for integrating any programming language with a webserver). When CGI is used, the webserver takes requests, starts an application and captures its output to send back to the user. Any text-based Prolog application can be converted to a web service, by wrapping it up into a script that can be called by a webserver.

The obvious deficiency of CGI is that you have to write a separate CGI application for each page. This is fine if you've got maybe a handful of quite logic-intensive pages on a website, but not quite as useful if you just want to use Prolog as a general purpose scripting language. CGI is great for implementing web applications, but a bit over-the-top if all you want to do is use Prolog to load a random image, count the number of visitors or retreive data from a database.

In fact, the ease of CGI is why I have used it for my implementation of Prolog Server pages. In previous versions, I used SWI Prolog's HTTP Server library (and it would not be difficult to convert it back to using it) but needed to switch back to CGI so that I could use it in Apache (and also to resolve a few minor connection problems I was having with the SWI libraries).

JavaScript

jsProlog is a JavaScript implementation of Prolog. Sure, it isn't really a server-based technology, and it doesn't really do what I am setting out to do, however it is very cool and I thought it was appropriate to include.

Mauro DiNuzzo's Prolog Server Pages

After the release of and based on my version of PSP, Mauro DiNuzzo created his own Prolog Server Pages. The syntax and functionality of our systems are very similar, however we've taken slightly different approaches to each other. The benefits of his approach are:

  • More generalised syntax than mine that allows for interleaving goals and clause definitions.
  • Pages are compiled for slightly better performance.

However, of course I prefer my own version:

  • Mauro's version doesn't support higher level predicates for persistence (it must be done manually with cookies).
  • Mauro's version doesn't allow pages to be as easily 'consulted' directly from SWI-Prolog for debugging.

You can find more information and download Mauro's system here.

Prolog Server Pages (Ben-style)

For illustrative purposes, I'll first show you a taste of the syntax, then go into some more complex examples.


greeting_noun(Noun) :-
	Noun = 'world'.

/*<html>
<body>
<?, greeting_noun(X) ,?>

Hello <?= X ?>

</body>
</html>*/

I think the best way to explain would be to show you some examples. The family tree is the "hello world" of prolog, and I think it makes for some nice simple examples (the first two below). The third is "inspired" by one of the Links examples.

Simple Deduction

This simple example shows the results of some simple deductions from a prolog database. You can view the source here.

Interactivity

Interactive web pages are also possible in PSP. Click here to see an example which parses user input and executes simple Prolog queries. You can view the the PSP source here.

Session Management

PSP automatically manages session - it maintains state across invocations for predicates declared as session_predicate. Click here to see a simple to-do list manager (all data is limited to your current session). You can view the the PSP source here.

Syntax

The syntax for PHP is quite intuitive for developers familiar with other "server pages" technologies.

psp_page ::= declaration_section 
                    "/*" document_section 
                    "*/" whitespace |
             declaration_section

document_section ::= "Content-Type:" psp_code |
                     psp_code

psp_code ::= psp_text "<?" prolog_code "?>" psp_code |
             psp_text

psp_text ::= raw_html "<?=" prolog_term "?>" psp_text |
             raw_html

The code is executed as follows:

  1. The declaration_section is consulted by the prolog interpreter (as though plain Prolog source).
  2. The psp_text sections are replaced with write/1 statements that generate appropriate HTML.
  3. The prolog_code and psp_text sections are weaved together into a single prolog clause.
  4. Free variables are bound to the environment as appropriate (e.g., Get is bound to a list of the HTTP GET parameters).
  5. The single clause is then executed. (If Content-Type: is supplied, PSP assumes that the HTTP response headers are included in the document_section so does not automatically generate headers.)

In effect, what this means is that any bits of HTML that appears in the PSP page are simply replaced by appropriate write/1 statements. Consider the following example mappings (sorry, they're a little hard to read):

Simple HTML

/* simple <?, true, ?> example */
becomes
write(' simple '), true, write(' example ')

Nested HTML

/* another <?, once(?> simple <?), ?> example */
becomes
write(' another '), once(write(' simple ')), write(' example ')

HTML with direct term expressions

/* another <?= example ?> again */
becomes
write(' another '), write(example), write(' again ')

In the above examples, it is particularly important to note the use of commas. It is easy to work out where to put a comma... just imagine the HTML sections of the code (including the <?= Foo ?> bits) as a single write statement - put in commas if you're sequencing parts of a clause, but don't put in commas if you're using nested calls such as once/1, forall/2, call/1, etc.

Benefits

I think the benefits of this syntax are quite obvious:

  • The syntax will be familiar to programmers with "server pages" experiences.
  • Prolog clause declarations, and inline HTML generation are permitted in a single file.
  • The syntax allows for plain CGI programming (i.e., if you don't include a document_section, and simply :- write('...').).
  • Allows the PSP page to be consulted in a Prolog interpreter for development and debugging (the HTML escapes are comment delimiters in SWI-Prolog, so the document_section will be ignored).

Download and Installation

Installation directions and source download is available from here.

Feedback

If you have any questions or suggestions, please do not hesitate to contact me.

I can be reached by email or by a web-based email/SMS form.

To return to the homepage, click here.