[UMN logo]

CSCI 5106: Programming Languages
Using Prolog (Quick Guide)


The version of Prolog that is available at UMN is called SWI-Prolog. I have never used this version of Prolog before so I will be learning about it together with you. 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).

?-
The final line containing ?- 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:

?- [app].
true.

?- 
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 with 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]:

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

?-
Prolog finds a value for L, the third list, and displays this. In general, there could be more than one solution to a query you pose to Prolog and, in this case, Prolog will wait and let you indicate if you want it to search some more as we discuss below. However, in this case, Prolog is able to determine that there are no more solutions to the query. It signals this fact by terminating the solution with a period and presenting you with a prompt for the next query.

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:

? app(L1,L2,[1,2,3]).
L1=[]
L2=[1,2,3]
There are obviously several solutions to the query under consideration and what we see above is that Prolog has produced one of them. The other interesting thing to note is that Prolog has determined that there might be more solutions and hence it has stopped after displaying the solution it has found; it is kind of difficult to show this in the display above, but Prolog has suspended the cursor at the end of the second line of the solution, waiting for the user to make the next move.

At this stage, there are two possible action the user can take. One of them is to indicate that this one solution suffices and there isn't anything more to be done. The user signals this by typing a period at the end of the displayed answer. Doing so terminates the query and Prolog readies itself for the next one as seen in the interaction below; note that the period at the end of the third line (i.e. after the presentation of the solution) is a user input.

?- app(L1,L2,[1,2,3]).
L1 = [],
L2 = [1, 2, 3] .

?- 
The other possibility is for the user to indicate that they want more solutions. This is done by typing a semicolon (;) after the display of the solution. In this case, Prolog will try to find more solutions. The following interaction shows this possibility, where the user has repeatedly asked for another solution:
?- 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 = [] ;
false.

?- 
The interaction after the last solution has been presented shows that Prolog cannot always determine ahead of time that there are no more solution. Thus it searches some more and, when it finally figures out that there are no more solutions, it indicates that there are no more solutions by displaying the word false. There are, of course, possibilities between being satisfied with one solution and wanting to see all of them. The user can pick where they want Prolog to stop simply by typing a period after a solution has been displayed.

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.


Created by gopalan atsign cs dot umn dot edu. Maintained by ngopalan atsign umn dot edu and evw atsign umn dot edu. Last modified: August 30, 2019.


The views and opinions expressed in this page are strictly those of the page author(s). The contents of this page have not been reviewed or approved by the University of Minnesota.