Glomus - Prolog Help

SWI-Prolog

This course will use a non-commercial version of Prolog called
SWI-Prolog. SWI-Prolog is available for both Windows9x/NT and for Linux. You can visit the SWI-Prolog site to download and install it on your machine if you wish.

Online Prolog Resources

Here are some Prolog resources:


Getting Started with Prolog

Prolog "Programs"

A Prolog "program" consists of one or more text files that contain Prolog predicate clauses which are roughly based on Horn-clauses. Prolog clauses consist of a head and a body. The syntax for a Prolog clause is
head :- body
which can be read
head is true if body is true
or alternatively,
body implies the head
For example mortal(Thing):- man(Thing) declares that anything which is a man is mortal (Prolog clauses are universally quantified, thus this clause would read for all Thing such that man(Thing) is true, mortal(Thing) is true).

Prolog clauses are often called either facts or rules.

A fact is a clause of the form:

head :- true
which states that the head of the clause is asserted to be true - the truth of the head does not depend on any other clauses. In Prolog, we could write facts as: man(socrates):- true, but Prolog allows us to dispense with the obvious, and merely write:
man(socrates).
as a fact.

A rule is a clause of the form we saw above, mortal(Thing):- man(Thing), which has unbound, free variables. Rules are used to describe how to infer additional facts.

It is important to note that in Prolog, any term beginning with a capital letter is an unbound variable. Thus we use uppercase Thing in the clauses above to denote a variable while lowercase strings such as socrates, mortal, and true denote "ground" terms - terms that are not variables.

It is important to understand that Prolog is, fundamentally, a simple pattern-matching engine. For the most part there are no data types, there are no flow-of-control constructs, etc. Thus, a Prolog program consisting of the following:

man(socrates).
dog(lassie).
essentially declares four terms, two of which are predicates - man/1 and dog/1, and two of which are atoms - socrates and lassie. It is up to the programmer and user to determine whether these predicates and assignments make any sense.

Here is a Prolog program that contains a set of rules and facts about a portion of my family tree. You can download this program and use it to test Prolog. I will use this program for demonstration purposes below.

Running Prolog

The Prolog interpreter is a simple text-oriented shell. To start the Prolog interpreter:
Linux
Type pl at the shell prompt
Windows
Start SWI-Prolog from the Start menu
You will see a "banner" and prompt:
Welcome to SWI-Prolog (Version 3.2.8)
Copyright (c) 1993-1998 University of Amsterdam.  All rights reserved.

For help, use ?- help(Topic). or ?- apropos(Word).

?-

At the ?- prompt, you enter goals for Prolog to attempt to prove. The term goals is technically correct, though there are many sorts of goals you might need to enter such as asking for help, loading a file, or trying to solve a particular query. Note that a period (.) is used as the terminator character in Prolog - Prolog does not evaluate what you have typed until it encounters a period at the end of your input.

Typically, the first thing you will do is to "consult" a file (i.e., load it) that contains a set of Prolog facts and rules. You do this using the consult/1 predicate as your goal (Note: Prolog predicates are usually written as "name"/"# parameters" so consult/1 is the name of the consult predicate that accepts one parameter - in this case the name of the file to read). For example, this file contains a bit of my family history as a set of Prolog facts, and some Prolog rules for inferring relationships. You can download this file and then, at the Prolog prompt, you can load this set of facts and rules:

?- consult(family).

An alternative syntax for consulting files is the more traditional:
?- ['family'].
which has the same effect. Consulting a file loads and compiles the facts and rules.

Prolog includes a large set of built-in predicates such as consult/1, help/1, etc. See the SWI-Prolog documentation for more information on the built-in predicates. You can use the built-in help/1 predicate to get online help for all built-in predicates:

?- help(consult).
would give you help on the consult predicate. You can be more specific and request help on the consult/1 predicate as well.

To illustrate some particular interactions with prolog, consider the following sample session. Comments are provided using the comment syntax, /* ... */ and the number in the comment corresponds to the notes following this example:

?- ['family'].          /* 1. Load a program from a local file*/
yes
?- listing(ancestor/2). /* 2. List ancestor/2 facts and rules to the screen*/

ancestor(A, B) :-
        parent(A, B).
ancestor(A, B) :-
        parent(C, B),
        ancestor(A, C).

Yes
?- ancestor(Who,david).   /* 3. Find an ancestor of david */

Who = richard

Yes
?- ancestor(Who,david), married(Who,abelone).  /* 4. Conjunction of goals */

Who = augie

Yes
?- sibling(david,Sibling).  /* 5. Multiple solutions to a goal */

Sibling = beth ;

Sibling = paul ;

Sibling = beth ;

Sibling = paul ;

No
?- halt.                         /* 6. Return to OS */

Notes:

  1. A Prolog goal is terminated with a period (.) In this case the goal was to load a program file. Multiple files can be loaded simultaneously with multiple filenames separated by commas, or sequentially with multiple load goals - loading programs does not replace previously loaded programs, but continues to augment the facts and rules. The file family.pl contains facts about my family history as well as predicates that can be used to infer additional facts (e.g., sibling/2, cousin/2, ancestor/2, parent/2). Note: omitting the period is a common mistake that merely results in Prolog prompting you for more goals with the continuation prompt |. Simply enter the period at any prompt to get Prolog moving.

  2. The built-in predicate listing will list the program in memory -- in this case, the family program. There are two forms of the listing predicate, listing/0 (typed as ?- listing. with no parameters or parenthesis) which lists the entire program, and listing/1, used here, to list all facts and rules matching a specific predicate. Also note that asking for help on the listing predicate without specifying which form (i.e., ?- help(listing).) will give you help on all forms. The appearance of this listing is a little different than the appearance of the source code in the file.

  3. The goal here, ancestor(Who,david), essentially says "an ancestor of david is Who?". The symbol Who begins with an upper-case letter, denoting a logical variable. Prolog satisfies the goal by finding a value for the variable Who. Prolog pauses after displaying Who = richard, waiting for the user to enter a carriage return, or to ask for additional solutions to the goal (see note 5 below).

  4. A compound or conjunctive goal asks that multiple individual goals be satisfied. Note that Prolog will attempt to satisfy these goals in left-to-right order, just as they would be read. Thus the ordering of goals can have a dramatic affect on Prolog's ability to satisfy the goals efficiently, or at all!

  5. Many goals will have more than one solution. As we saw in note 3, Prolog initially returns a solution (if one exists) and then pauses. To see additional solutions, the user can enter n for "next" or, alternatively, a semi-colon (;). Notice two things about the additional solutions. First, all values are listed twice! This is because the rules in this program provide more than one way to prove that beth, for example, is a sibling of david. Prolog makes an exhaustive search to find solutions to the goal(s) without regard to whether the answer has already been proven. The second thing to notice is that Prolog returned No at the end of this query. This is because we entered ;, asking Prolog to find another solution to this goal when no further solutions exist. Entering a goal with no solutions at all will result in Prolog replying No immediately.

  6. To quit SWI-Prolog, use the halt/0 goal (i.e., enter halt. at the prompt) which always succeeds and returns the user to the operating system.