Prolog/Introduction
This section covers the installation of a prolog compiler, loading your first program, and querying it. It then explains how to use facts and variables in your programs and queries.
Getting Started
[edit | edit source]Before anything can be done, a prolog compiler and a text editor need to be installed on your system. A text editor will allow you to write your prolog programs and the prolog compiler (also known as the interpreter) will allow you to execute them.
Prolog Compilers
The following prolog implementations are free (at least for personal or educational use, be sure to read the terms). Simply download one and install it according to the instructions on the website:
- B-Prolog
- http://www.picat-lang.org/bprolog/
- A Prolog compiler for standard Prolog with extended features such as tabling and constraint solving. Supports many platforms.
- SWI Prolog (recommended for use with this book)
- https://www.swi-prolog.org/
- A small and robust open-source implementation that is compliant with both Prolog standards (ISO and Edinburgh) and has many extra libraries and built-in predicates. There's even a separate toolkit for creating windows and graphics, called XPCE. Supports many platforms.
- GNU Prolog
- http://www.gprolog.org/ (was: http://pauillac.inria.fr/~diaz/gnu-prolog/ )
- A relatively new open source implementation. Has support for Constraint Logic Programming, an extension of prolog.
- Visual Prolog
- http://www.visual-prolog.com/
- A complete development environment for an Object-Oriented extension of Prolog. Includes compiler, linker, text editor, graphical dialog editors, build system, debugger, large library, and much more
The following implementations aren't free:
- SICSTUS Prolog
- http://www.sics.se/
- Probably the most well known professional prolog implementation and development suite. ISO-compliant, many libraries and support for constraint logic programming. Free for evaluation.
- Quintus Prolog
- http://www.sics.se/quintus/
- An especially robust and dependable implementation intended for commercial use and research projects by the same company that makes SICSTUS. Free for evaluation.
Text Editors
The programs that you will write are simple text files, to be read and written with any text editor. Some prolog implementations come with their own editor, but for those that don't here's a list of text editors. These provide the basic function that are useful for writing prolog programs, such as indentation, bracket matching and some can even be adjusted to highlight the syntax of your prolog code.
- Crimson Editor
- http://www.crimsoneditor.com/
- A free text-editor for windows with many features.
- GNU Emacs
- http://www.gnu.org/software/emacs/emacs.html
- A free, open-source implementation of unix' classic text editor. May be difficult to understand, has lots of features.
- Vim
- http://www.vim.org/
- A free, open-source implementation of Emacs' long-standing rival.
- Textpad
- http://www.textpad.com/
- A windows text-editor with many features. Free for evaluation.
- Eclipse Prolog Plugin
- http://eclipse.ime.usp.br/projetos/grad/plugin-prolog/index.html
- A free plugin for Eclipse.
First Steps
[edit | edit source]Once you've installed your prolog implementation, it's time to write the first program and load it into the interpreter (mainly to see if everything works). Fire up your text editor and create a text file with just the following line in it:
human(john).
Be precise, capitalization is important in prolog, as is the period. This will be your program (also known as the database or the knowledge base). Give it a nice name like prolog1.pl and save it. Note: The extension pl isn't officially associated with prolog and can cause conflicts if you're also programming in Perl, which uses .pl as well. If this is a problem you can use pro or pr or anything you like just as well. Now start your prolog interpreter. Most prolog interpreters will show you a window with some startup information and then the line
?-
with a cursor behind it. There is usually a menu for loading files into the interpreter. If there isn't, you can type the following to load your file:
consult('FILEPATH').
And press enter. Once again, be precise, no capitals and remember the dot. Replace FILEPATH with the name and directory of your file. For instance if your file is located in C:\My Documents\Prolog\prolog1.pl then use
consult('c:/my documents/prolog/prolog1.pl').
or the shorthand
['c:/my documents/prolog/prolog1.pl'].
Note that the slashes are the other way around, since the backslash (\) has special meaning in Prolog (and most other languages). If you are using a UNIX based system such as Linux, the commands may look something like this
consult('/home/yourName/prolog/prolog1.pl'). ['/home/yourName/prolog/prolog1.pl'].
Your interpreter will now hopefully tell you that the file is loaded correctly. If it doesn't, consult the help file or manual of your implementations on how to consult files.
Also, you can tell prolog interpreter to load file automatically, if running it with the key -s
, like this[1]:
prolog -s /home/yourName/prolog/prolog1.pl
After some information you will see
?-
To see if everything is working, type
human(john).
(don't forget the period) and press Enter. Prolog will answer with
true.
Type
human(Who).
, press Enter and Prolog will answer
Who = john.
To exit prolog, type
halt.
Syntax, Facts and Queries
[edit | edit source]The line human(john). in the previous example was a prolog sentence in the form of a predicate. This type of sentence is called a fact. Predicates consist of one word of one or more characters, all lowercase, possibly followed by a number of terms. The following are examples of valid predicates:
human(john) father(david, john) abc(def,ghi,jkl,m) tree p(a ,f ,d)
The terms (the 'words' within parentheses) can take many forms, but for now we will stick to constants. These are words, again all lowercase. The first character of both a predicate and a constant needs to be a letter. Using predicates we can add facts to a program:
human(john). human(suzie). human(eliza). man(david). man(john). woman(suzie). woman(eliza). parent(david, john). parent(john, eliza). parent(suzie, eliza).
Note the period '.' behind each line to show that the line is over. This is very important, if you forget it, your interpreter will not understand the program. You should also be aware that the names chosen for the predicates and terms do not actually mean anything to the prolog interpreter. They're just chosen to show what meaning you have for the program. We could easily replace the word human with the word spaceship everywhere and the interpreter wouldn't know the difference.
If we load the above program into the interpreter we can run a query on it. If you type
human(john).
Prolog will answer
true.
and if you type
woman(john).
Prolog will answer
false.
This also seems fairly obvious, but it's important to see it the right way. If you ask Prolog human(john).
, it means you are asking Prolog if this statement is true. Clearly Prolog can't see from the statement whether it's true, so it consults your file. It checks all the lines in the program to see if anyone matches the statement and answers Yes if it finds one. If it doesn't, it answers false.
.
Note that if you ask
?- human(david).
Prolog will answer false.
, because we have not added that fact to the database. This is important: if Prolog can't prove something from the program, it will consider it not true. This is known as the closed world assumption.
Variables
[edit | edit source]We'll update the program with human(david), so that all people in the database are human, and either a man or a woman
human(david). human(john). human(suzie). human(eliza). man(david). man(john). woman(suzie). woman(eliza). parent(david, john). parent(john, eliza). parent(suzie, eliza).
What we have now is still not a very expressive language. We can gain a lot more expressiveness by using variables in our query. A variable is a word, just like terms and predicates, with the exception that it starts with an uppercase letter and can have both upper and lowercase characters after that. Consider the following query
human(A).
Now, the term of the predicate is a variable. Prolog will try to bind a term to the variable. In other words, you are asking Prolog what A needs to be for human(A) to be true.
?- human(A).
Prolog will answer
A = david ;
Which is true, because the database contains the line human(david). If you press enter, Prolog will answer Yes and give you back your cursor. If you press semicolon ;
Prolog will show you the rest of the possibilities
A = john ; A = suzie ; A = eliza.
After eliza, there are no further possibilities. If you query Prolog with more than one variable it will show you all instantiations of the variables for which the query is true:
?- parent(Parent, Child). Parent = david Child = john ; Parent = john Child = eliza ; Parent = suzie Child = eliza ; No
When prolog is asked a query with a variable it will check all lines of the program, and attempt to unify each predicate with the query. This means that it will check if the query matches the predicate when the variables are instantiated a certain way. It can unify human(A) with human(john) by making A john, but it can't unify man(A) with human(john), because the predicates don't match.
If we want to make it even more difficult for prolog we can use two predicates in our query, for instance:
?- human(A), parent(B,A).
Now we are asking prolog for a human A who has a parent B. The comma means and, indicating that both predicates need to be true, for the query to be true. To check this query, prolog will first find an instantiation to make the first predicate true--say it make A equal to john--and then it will try to make the second predicate true--with A equal to john. If it has found two instantiations for A and B that make both predicates true, it will return them to you. You can press Enter to end the program, or a semi-colon to see more options.
Prolog may make a choice for A, to satisfy the first predicate that doesn't work with the second. Say it chooses A = suzie to satisfy human(A); no choice for B will satisfy parent(B, suzie), so prolog will give up its choice of suzie for A, and try another name. This is called backtracking.
In the example above, prolog will first find human(david) in the program and unify A with david. To make the second predicate true, it needs to find an instantiation for parent(B, david). It can't find any, so it will look for a new instantiation of human(A). It tries the next option: A = john. Now it needs to instantiate parent(B, john). It finds B = david in the line parent(david, john) and reports back to you
A = john B = david
If you press semicolon it will try to find a new instantiation for the second predicate. If that fails it will try to find a new instantiation for the first predicate and so forth until it runs out of options.
There is one special variable, called the anonymous variable, for which the underscore (_) character is used. When you use this character in a query, you basically say that you don't care how this variable is instantiated, i.e. you don't care which term it's bound to, as long as it's bound to something. If you ask Prolog
?- parent(A, _).
Prolog will answer
A = david; A = john; A = suzie;
It will not tell you how it instantiates _. However if you ask Prolog
?- abc(_,_,_).
This will not be true by default, Prolog needs to find an instantiation for all three anonymous variables in the database, such as abc(d,e,f). Since the predicate abc isn't in the database at all, the query fails. You can use the anonymous variable in your database as well. Placing
human(_).
in your database will mean that any term, whether it already exists or not, is human. So the queries
?- human(mark).
and
?- human(orange).
would be true with the above fact in the database. Here the anonymous variable is used to state a property of all objects, instead of just one. If we want to state that a specific group of objects has a certain property, we need rules. The next section deals with this.
Examples
[edit | edit source]The following program describes the public transport systems of some cities:
transport(dresden, tram). transport(amsterdam, tram). transport(amsterdam, subway). transport(new_york, subway).
We can ask prolog if there is a city which has both a tram system and a subway:
?- transport(A, subway), transport(A, tram). A = amsterdam ; fail.
Exercises
[edit | edit source](x) Find a Family Tree somewhere, or make one up (a real one will make it easier to check your answers). Implement part of the tree (around ten people) in a prolog program using the predicates woman/1, man/1, parent/2. The number behind the predicate describes how many arguments the predicate takes. So parent/2 describes a predicate like parent(john, mary).
You can peruse w:Category:Family_trees for a suitable family tree.
Write prolog queries for the following commands and questions. Don't worry if some people are returned more than once. We'll discover how to deal with this later on.
- List the women in the database
- List the children in the database
- List all combinations of a father and his son.
- which women have both a father and a son in the database?
Can you think of a way to display those women that do not have a father listed in the database? Can you describe what you would need to write such a query?
The answers to select excercises can be found here: Prolog/Introduction/Answers
References
[edit | edit source]- ↑ Working with the SWI-Prolog, don't sure about other.
next: Rules