Using Prolog

CSci 5106: Programming Languages

The version of Prolog that is available at UMN is called SWI-Prolog. The nice thing about this Prolog, in contrast to the better known SICStus Prolog, is that it is available in the public domain. It seems to be available for the Windows and Linux environments in addition to the SunOS/Solaris version; look up the SWI-Prolog project web page for details. To use the system on our local cluster, you have to load the module prolog. If you are new to the UMN setup and don't know about modules and how to load them, you can find some information about this in the system help pages; with specific regard to modules, you may look here.

The rest of this document relates to using SWI-Prolog that I will henceforth refer to simply as Prolog. I will assume that by this stage you already know how to create and store files in whatever environment you are using. You would have to do this using an editor such a emacs or vi. If you are not familiar with either of these, you are probably not sufficiently prepared to take this course and should seriously reconsider taking it. Come and talk to me if you need help in deciding.

Once you have loaded the Prolog module, you can start up a Prolog session simply by typing the command prolog. This will cause something of the following kind to be printed on the screen:

gopalan@rishabh (/soft/prolog/man) % prolog Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.4) SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software. Please run ?- license. for legal details. For online help and background, visit http://www.swi-prolog.org For built-in help, use ?- help(Topic). or ?- apropos(Word). 1 ?-

The final line containing 1 ?- is the Prolog prompt that signals that Prolog is now ready to solve any queries that you might give it. As with SML and Scheme, the mode of interaction is a loop: Prolog takes a query from you, tries to solve it and then gets ready for another query. (The terminology "query", "solving a query", etc. may appear a little confusing at first, but, hopefully, you will become more comfortable with it as you read on and the class discussions will also help.)

The general mode of interaction with Prolog is to create a file containing definitions of procedures (referred to as predicates in logic programming parlance), to load such definitions and to then request that queries using these predicates be solved. The first thing to do in this sequence, then, is to set up a file containing procedure definitions. Before you can actually create Prolog programs, you will have to learn a little about what these programs look like. We will talk briefly about this in the first few lectures in the course to get you started. However, you might also want to start looking at examples at other places. The reference books mentioned on the software page for this course are a good source for these as also is the online documentation page for SICSTUS Prolog. With regard to the latter a couple of specific things to consult are a quick introduction to Prolog and programming tips and examples.

Towards giving the discussion here some concreteness, let me already consider an example Prolog program. The lines of Prolog code below, define a predicate (procedure) that can be used for appending lists.

app([],L,L). app([X|L1],L2,[X|L3]) :- app(L1,L2,L3).

First, note that [] is the way to depict an empty list in Prolog and [X|L1] is the way to depict a list that has X as a head element and L1 as a tail. Also, symbols that begin with uppercase letters denote variables that can match with any appropriate value. Thus [1,2] that denotes a two element list matches with [X|L1], in the process setting X to 1 and L1 to [2]. Now, the two lines above correspond to two clauses in the definition of a predicate called app that expresses a relationship between three lists: in particular, app(L1,L2,L3) is intended to be true only in those situations where L3 is the list that results from appending the lists L1 and L2. Let us understand this definition. The first clause in it says, in effect, that appending the empty list to any other list yields back that list. Similarly, the second clause says that appending a list with some element X as head and L1 as tail to a list L2 yields a list with X as head and L3 as tail provided L3 is the result of appending L1 and L2. The symbol :- is the way of writing if in Prolog.

Make sure you see the correspondence between this description of the predicates and the actual Prolog code and understand also why this description is a correct one for the append relation. We will also talk about this in some detail in class.

Let us suppose then that you have placed the above lines of Prolog code in the file app.pl relative to the current path. You now want to make the definition of app available within an ongoing Prolog session. You can do this by consulting the file, something that is exemplified by the following interaction:

1 ?- [app]. app compiled, 0.00 sec, 816 bytes. Yes 2 ?-

At the first prompt, you have indicated the file to be consulted by including its name within square brackets. In the general case, the interaction messages that Prolog types out could indicate errors in the code or in trying to load the file, or it may indicate success in both endeavors. In the case under consideration, the code is correct, so consulting completes successfully. When this happens, Prolog will be ready for you to use the predicate app in queries you pose to it.

Perhaps the simplest kind of append query that can be posed is one in which the first two lists are given and we wish to know what the result of appending them is. Here is an example of such an interaction when the first two lists are, specifically, [1,2] and [3,4]:

3 ?- app([1,2],[3,4],L). L = [1,2,3,4] ; No 4 ?-

Prolog finds a value for L, the third list, and displays this. A point that is not immediately apparent from the interaction above is that it then waits for you to either say that you are satisfied with this answer or that you want another one. In the case above the assumption is that the user desires another answer. He/she indicates this by typing a semicolon after the answer is displayed; the ; following the display of L = [1,2,3,4] is in fact user input. Prolog tries to find a second answer and, failing in this attempt, it prints No and gets ready for the next query. The user could have indicated a satisfaction with the answer found by simply typing a carriage return thereby producing a slightly different display:

3 ?- app([1,2],[3,4],L). L=[1,2,3,4] Yes 4 ?-

The interesting thing about Prolog is that predicates such as app can be used to do more than just appending two given lists. For example, the result of appending could be given and the user can ask which two lists might be appended to produce the given one. This is epitomized in the query below where we are seeking values for L1 and L2 that can produce [1,2,3] as a result:

4 ? app(L1,L2,[1,2,3]). L1=[] L2=[1,2,3] ; L1=[1] L2=[2,3] ; L1=[1,2] L2=[3] ; L1=[1,2,3] L2=[] ; No 5 ?-

There are four answers to this and the interaction shows the user forcing the production of each of these by refusing every answer that is produced.

From the brief description here, you should be able to see that Prolog has quite a different approach to computing from any other programming language that you have been used to up to now. In particular, it thinks of ways to show that a given query is true and it shows you the instantiations for variables that, in fact, make the query true. The result of this is that it is quite natural to think of running procedures like app in a reverse way to what you can do in other languages: you can give the answer, so to speak, and ask for the input that produced it as well. Experiment with small Prolog programs (look at the sources indicated to get started). We will discuss this model in greater detail later in the course and, hopefully you will see larger programs that convince you of the genuine usefulness of this style of programming.

After you have played around with Prolog a bit, you will want to exit it. for this purpose, you can use the predicate halt:

5 ?- halt.

This will close up the Prolog session and bring you back to the shell command level.