So, it all started when someone posted the following meme in a Facebook Computer Science meme group I was in about a week or two ago:
As I learned from the comment section of that post, quite a few Computer Science programs across various universities require their students to learn the Prolog programming language, usually in a discrete math course, and that students generally find it to be a rather unpleasant experience. The post also reminded me that the professor delivering the discrete math course I was enrolled in back in September also briefly mentioned Prolog when introducing the famous logical puzzle known as the Zebra Puzzle / Einstein's Riddle (more on that later) but then explicitly stated that Prolog was not required for the course (guess I was lucky :p) so I subsequently forgot about it. Nevertheless, the meme prompted me to try out Prolog to see what the fuss was all about.
The Prolog programming language first appeared in 1972, making it as old as the infamous C programming language. In contrast to C which is highly imperative and procedural, Prolog is a predominantly declarative programming language (with a few procedural elements) based on Horn clauses, a Turing-complete subset of first-order predicate logic. It was originally designed with natural language processing in mind but currently also finds use in other fields such as Artificial Intelligence. Although nowhere near as influential as C, Prolog has influenced a number of notable programming languages including Clojure and Erlang.
It took me about a week and a half to learn the basics of Prolog programming which is just a bit short of 12 days, hence the title ;)
There is a free online version of Learn Prolog Now! which is a great book for beginners wanting to get started on SWI-Prolog, one of the few (two?) widely-accepted major Prolog implementations, SICStus Prolog being the other one. Note that although different Prolog implementations share the same syntax and semantics, they can differ greatly in terms of the built-ins and libraries provided so Prolog programs are generally not fully portable between implementations.
If you're using a Mac as I do then I'd highly recommend installing Homebrew if you haven't already. Homebrew is a command-line package manager for Mac which makes it much more simple and straightforward to install all sorts of things from and on the command line. Then simply execute:
$ brew install swi-prolog
to install the
swi-prolog formula (as they are called in Homebrew). Alternatively, you can go to the SWI-Prolog official website which should contain links to downloading the official SWI-Prolog interpreter which should be available for multiple operating systems.
No problem - the SWI-Prolog official website offers SWISH, an online service for experimenting with and sharing SWI-Prolog programs.
Absolutely not - in fact, without at least a basic understanding of terms and concepts in formal (first-order) logic such as propositions, predicates, logical conjunction and disjunction, implication and modus ponens, one would likely struggle to understand even the simplest of Prolog programs. Incidentally, (classical) propositional logic (and its associated notation) is typically taught at or near the beginning of most discrete math courses - no wonder many such courses introduce Prolog programming into its curriculum. Furthermore, a good grasp of either recursion or mathematical induction would be beneficial in learning Prolog - recursion in Prolog is extremely commonplace since there are no (imperative) looping constructs such as
Not in my opinion. Once you get used to the way of Prolog programming, you'll probably realize that Prolog is a rather simple language - after all, there are only a handful of data types (atoms, integers, variables, complex terms) and the meaning of Prolog programs are generally transparent provided that its procedural features (such as various forms of I/O or operations involving side effects such as the cut) are not abused. In fact, since Prolog is declarative, you can read Prolog statements like simple logical statements most of the time. For example:
lazy(X) :- hates(X, prolog).
is a valid Prolog statement (and indeed a valid Prolog program) which simply means "X is lazy if X hates Prolog" (see what I did there?) ;)
Much of the perceived difficulty of learning Prolog is simply due to the programmer's inability to set aside the imperative mindset of programming ingrained in his/her mind by countless hours of "indoctrination" by conventional programming languages (the vast majority of which are highly imperative and object-oriented) which often give the false impression that programming is all about telling the computer to "do this" and "do that".
Glad to hear that. Remember the Zebra Puzzle I mentioned above? It is also known as Einstein's Riddle and it is rumored (not proven!) to be first proposed by the great scientist Albert Einstein. Furthermore, it is rumored that only about 2% of the world's population can solve this riddle correctly. Ready? Here is the riddle:
- There are five houses.
- The Englishman lives in the red house.
- The Spaniard owns the dog.
- Coffee is drunk in the green house.
- The Ukrainian drinks tea.
- The green house is immediately to the right of the ivory house.
- The Old Gold smoker owns snails.
- Kools are smoked in the yellow house.
- Milk is drunk in the middle house.
- The Norwegian lives in the first house.
- The man who smokes Chesterfields lives in the house next to the man with the fox.
- Kools are smoked in the house next to the house where the horse is kept.
- The Lucky Strike smoker drinks orange juice.
- The Japanese smokes Parliaments.
- The Norwegian lives next to the blue house.
Now, who drinks water? Who owns the zebra?
In the interest of clarity, it must be added that each of the five houses is painted a different color, and their inhabitants are of different national extractions, own different pets, drink different beverages and smoke different brands of American cigarets [sic]. One other thing: in statement 6, right means your right.
(excerpt taken from Wikipedia)
OK, we could try to solve it on paper. But wouldn't it be more interesting if we could write a program that could solve it for us? These types of problems is one of the few areas that Prolog shines in - constraint programming. In a more conventional programming language such as Python, you may have to devise an algorithm to search for a solution to the riddle which is no easy task. However, in Prolog, all we have to do is state the constraints (rules) and Prolog will solve it for us through backtracking! To give you an idea of what this is like, here are the first (and last) few lines of a predicate (function) in Prolog stating the constraints of the riddle:
% riddle.pl solve(WhoDrinksWater, WhoOwnsTheZebra) :- length(Houses, 5), % 1. There are 5 houses. member(house(red, english, _, _, _), Houses), % 2. The Englishman lives in the red house. member(house(_, spanish, dog, _, _), Houses), % 3. The Spaniard owns the dog. ... , member(house(_, WhoDrinksWater, _, water, _), Houses), % Who drinks water? member(house(_, WhoOwnsTheZebra, zebra, _, _), Houses). % Who owns the zebra?
Then we can just load our file
riddle.pl into the interpreter:
?- [riddle]. true.
And pose our query:
?- solve(WhoDrinksWater, WhoOwnsTheZebra). WhoDrinksWater = norwegian, WhoOwnsTheZebra = japanese ; false.
Ta-da! Prolog correctly tells us that the Norwegian drinks water and the Japanese owns the zebra. It also correctly tells us that this is the only possible solution to the riddle - it answers
false. after we prompted it for the next solution set using
The full code for this solver can be found here.
The Zebra Puzzle was interesting - do you have a more concrete example on using Prolog in real life?
Recall that Prolog was originally designed with natural language processing in mind. In fact, it even has syntactical sugar for expressing definite clause grammars (DCGs) built into the language itself. A DCG allows us to unambiguously define all valid sentences in a particular grammar which could be a (subset of a) natural language, or, by extension, programming languages (since programming languages are generally more rigorously defined than natural languages). Here is a simple example directly taken from Learn Prolog Now! - 7.2 Definite Clause Grammars:
s --> np,vp. np --> det,n. vp --> v,np. vp --> v. det --> [the]. det --> [a]. n --> [woman]. n --> [man]. v --> [shoots].
In the subset of valid English sentences described by this grammar, sentences such as "A man shoots a woman" or "A woman shoots" are considered grammatical while "Woman shoots man" and "A man shoots woman a" are not. Notice how simple and intuitive the Prolog code for expressing this grammar is. In contrast, analyzing such grammars (even trivial ones such as this!) in a more conventional language such as C++/Java or even Haskell would be a right pain in the ass.
I hope this post provided you insight into what Prolog is, how, where and when it might be useful and where you could start learning Prolog if this post piqued your interest. Feel free to leave your thoughts in the comments below :)
Some of the content from this article was derived from or directly taken from the sources listed below. There are also a few links which may be of interest.