Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Writing a blog using SWI Prolog

By Robert “Joe Blog” Laing

“You think you know when you learn, are more sure when you can write, even more when you can teach, but certain when you can program.” ― Alan Perlis

These are notes I'm writing on how to use SWI Prolog to write web applications as I discover it to develop my strategy game playing website

My aim here is to gradually re-implement a web development course I did a few years ago given by Reddid founder Steve Huffman which Udacity still offers for free.

Following the original course's basic outline, I plan to split the tutorial into about seven units which build on each other to create a fairly fully featured blog which includes user authentication and storing comments in a database.

Whereas Huffman's course involved signing up for a free Google Appengine account offering a Python framework and a built in SQL server, I'm redoing it on a Linux localhost with SWI-Prolog talking to PostgreSQL via its ODBC package.

My main objective is to provide some simple examples for my own reference and education, and I like Linux, Postgres, and SWI Prolog obviously. If you prefer, say Windows and MySQL, hopefully it will only take you a bit of googling to adapt these examples.

Each unit's subdirectory has a SWI Prolog file called along with a file for that tutorial. Until recently, everything was on this page, but I decided to "chapterize" as my tutorial started turning into a book.

I've addopted a common subdirectory structure in each unit where html files are in the root directory with (though there's nothing stopping you from putting them in their own subdirectory), jpg, png etc go in images, css files in styles and javascript in scripts.

├── index.html
├── about.html
├── images
│   └── swipl.png
├── scripts
│   └── form_validator.js
└── styles
    └── basic.css

The server is started with, say,

swipl --port=3030 --workers=4

and stopped with

kill $(cat

and accessed by pointing your browser to http://localhost:3030/.

The number of workers you select — I picked 4 in the above example — would typically be the number of cores in the processor of your server. A SWI Prolog command to get the number of cores is:

current_prolog_flag(cpu_count, Cores).

I recently went through the process of placing a SWI Prolog powered site on the internet with its own domain name using Digital Ocean where I picked Centos 7 for my virtual machine and there was a gotcha — whatever port number you pick will work locally, but nginx, Apache, or whatever reverse proxy won't be able to serve it without the following magic incantation as root user:

semanage port -a -t http_port_t -p tcp 3030

Once the port permissions are right, for nginx, all that's needed is creating an /etc/nginx/conf.d/mydomain.conf file along these lines:

server {
  access_log /var/log/nginx/mydomain.access.log main;
  error_log /var/log/nginx/mydomain.error.log notice;
  location / {
    proxy_pass http://localhost:3030/;

As this tutorial developed, it took a couple of digressions into providing tips to Prolog novices, which experienced Prolog programmers can simply skip.

Unit 1 Handlers and generating HTML

This unit introduces SWI Prologs' http_handler(+Path, :Closure, +Options) and its reply_html_page(:Head, :Body) predicates, which are fundamental to using it as a web application development language.

I've also explained the basics of reading Prolog documentation — something I suspect most novices will battle with.

Unit 2 HTML Forms with GET and POST

This unit covers the basics of web forms, which SWI Prolog makes fairly easy with one predicate http_parameters(+Request, ?Parameters) which can be used without modification for GET or POST, and allows you to validate or give default values to the incoming key=value list.

Unit 3 Linking to a database

This unit covers hooking SWI Prolog to an SQL database. I like Postgresql, but thanks to the ODBC Interface, you can pick just about any database you like.

This also introduces SWI Prolog's Dicts which are a handy way to circumvent the prolog problem of having to pass too many arguments between predicates.

Unit 4 User authentication

In this unit we create a system whereby a user identifies themself to the server without a password ever leaving the browser. Part of this involves SWI Prolog's SHA* Secure Hash Algorithms library.

Unit 5 Web services

This unit looks at getting data from an external source — I've used for this example — using http_open(+URL, -Stream, +Options) and introduces SWI Prolog's support for Json and XML.

I also introduce call_with_time_limit(+Time, :Goal) to handle cases where the webapp we are requesting data from does not respons timeously.

Unit 6 Caching


Some simple examples of how to use SWI Prolog as a webserver




No releases published


No packages published