Professional Documents
Culture Documents
Documentation PrologIII Manual PdfA
Documentation PrologIII Manual PdfA
$%"!$"!%&$'&$" $"" +%$(%$"'%)&$!%$$&"&
%%"&"!!' $)(&""!%'&&"!"!&!&$!&!%#$!
*
"!&&%%"&"!#$""$&"$
Aociation Prolog
HERITAGE
Prolog III
Version 1.3
HERITAGE
Copyright
This manual and the software it describes are protected by copyright. According
to the legislation dealing with these rights, this manual and software must not
be copied or adapated either wholly or in part, without the written consent of
PrologIA except within the normal bounds of use or to create a back-up copy.
However these exceptions do not authorise the user to create copies to be used by
a third party, regardless of whether or not they are to be sold.
Prolog III is a registred trademark of PrologIA.
HERITAGE
Foreword
However this profound reworking and the power which results from it
are not without their consequences. The core of the interpreter is 50 times
bigger than that of Prolog II, and the challenge involved in tackling
exponential problems such as the processing of Boolean algebra or the
simplification of linear equation systems sometimes leads to disappointing
execution times. It should therefore be borne in mind that the expressive
power of a language sometimes veils the complexity of the solving process
thus produced.
Aociation Prolog
HERITAGE
We bring to an end this first contact between us, hoping that you will
appreciate programming in Prolog III and that this manual will help you to
do so. In it we have attempted to define, but more importantly to comment
upon and explain, the numerous new concepts which make Prolog III a
fundamentally different language from other Prologs. This double aim of
communicating in a way which is both precise - as concerns functionalities -,
and pedagogical - as concerns concepts -, naturally leads us to consider this
manual as a first stage. It seems obvious to us that only your help, remarks
and criticisms will make it possible to develop this documentation so that it
becomes a tool leading you to discover the tiniest details of a language
which initializes a new stage in logic programming.
The authors.
Aociation Prolog
HERITAGE
New built-in predicates and external procedures have been added, and we
have improved the documentation of some of the existing ones. Below is a
list of primitives that have been added or extended:
HERITAGE
The identifier form cut for the cut predicate has been withdrawn. You
should use '!' instead.
New error messages have been added. In particular the distinction between
"End of file" and "Unexpected end of file" makes it possible to take errors into
account better when reading a file.
The manual for this 1.3 version now comprises a folder and two separate
booklets: one for the user's manual and one for the new debugger.
PrologIA
Parc Technologique de Luminy - Case 919
13288 Marseille Cedex 09 - FRANCE
Tel. : + (33) 91 26 86 36
Fax : + (33) 91 41 96 37
e-mail (net) : prolia@dcftlx.das.net
e-mail (net) : prolia@tlxf.geomail.org
Telex : prolog 403 527 box : PrologIA
HERITAGE
General Contents
Reference Manual
Foreword.................................................................................................................i
Differences between the 1.2 version and the 1.3 version............................ iii
Introduction........................................................................................................... 1
Getting started with Prolog III.......................................................................... 5
1. Starting a Prolog III session................................................................. 6
2. Using an example program................................................................. 8
Loading a program................................................................................ 8
Deleting, editing, saving .....................................................................10
3. Some small examples.......................................................................... 12
Tuples and character strings.................................................................12
Arithmetic and numeric constraints......................................................14
Basic concepts ...................................................................................................... 19
1. Trees...................................................................................................... 20
2. Constants.............................................................................................. 23
Identifiers...........................................................................................23
Characters..........................................................................................24
Boolean values....................................................................................25
Non negative integers..........................................................................25
Floating numbers .................................................................................26
The empty tuple..................................................................................26
Character strings.................................................................................26
3. Operations............................................................................................ 27
Boolean operations..............................................................................28
Arithmetical operations......................................................................29
Tree construction operations .................................................................30
Standard lists .....................................................................................32
4. Variables............................................................................................... 33
5. Terms .................................................................................................... 34
Syntax ................................................................................................ 34
Limitations.........................................................................................36
HERITAGE
Examples............................................................................................ 37
Identifiers.................................................................................... 37
Incorrect identifiers...................................................................... 37
Integers........................................................................................ 38
Incorrect integers .......................................................................... 38
Floating numbers .......................................................................... 38
Incorrect floating numbers ............................................................. 39
Characters................................................................................... 39
Character strings.......................................................................... 39
Incorrect character strings............................................................. 40
Numeric expressions ..................................................................... 40
Incorrect numeric expressions......................................................... 41
Boolean expressions...................................................................... 42
"Mixed" arithmetico-boolean expressions ..................................... 42
Other terms.................................................................................. 43
Incorrect terms.............................................................................. 44
What do terms represent ?................................................................... 44
Assignment................................................................................... 45
Particularly subtle terms …................................................................. 46
6. Relations................................................................................................48
Equality and Inequality................................................................ 48
Implication.................................................................................. 50
Numeric comparisons.................................................................... 51
Unary relations............................................................................ 51
7. Constraints ...........................................................................................52
Syntax ......................................................................................... 53
Examples ..................................................................................... 54
8. Solving constraint systems.................................................................55
9. Rules and queries.................................................................................58
Syntax................................................................................................ 58
Meaning of a Prolog III program .......................................................... 60
The set of facts defined by a Prolog III program.............................. 60
Program execution......................................................................... 62
Trees, tuples, strings and lists ..........................................................................67
1. Introduction..........................................................................................68
2. Trees ......................................................................................................68
Operations on trees ............................................................................. 69
Constraints on trees............................................................................. 72
Examples............................................................................................ 72
Restrictions on the size constraint........................................................ 74
3. Tuples ....................................................................................................74
Operation........................................................................................... 74
Relations............................................................................................ 75
Restrictions concerning tuples .............................................................. 75
Examples of constraints on tuples......................................................... 76
A recap on operations and relations ..................................................... 77
vi © PrologIA
Prolog
Aociation
HERITAGE
General Contents
© PrologIA vii
Prolog
General Contents Aociation
HERITAGE
Important remarks.............................................................................119
Sets of boolean constraints..................................................................120
Examples of boolean constraints..........................................................120
Normal conjunctive form.....................................................................121
Boolean assignments ..........................................................................123
Solution of a boolean constraint system ...............................................124
Simplification of constraint systems...................................................124
Specific predefined rules.................................................................... 126
3. Some simple example programs.....................................................127
An or on two variables........................................................................127
An or on a list.....................................................................................128
At most one true .................................................................................129
K true elements in a list of n booleans..................................................131
4. Other examples..................................................................................133
Faults in a binary adder.....................................................................133
A logic puzzle....................................................................................141
Delay techniques...............................................................................................145
1. Introduction........................................................................................146
2. Known terms .....................................................................................146
The built-in predicates known, bound and free.....................................146
3. Delay of goal execution ....................................................................147
4. Delayed constraints...........................................................................149
Delayed sizes....................................................................................149
Delayed concatenation.......................................................................151
Delayed numeric constraints...............................................................154
Programming control and environment........................................................159
1. Control................................................................................................160
2. Expressions, static variables, arrays................................................166
Arithmetical expressions...................................................................166
Assignment. Arrays............................................................................171
3. Structuring, recording and modifying rules..................................173
Identifier families.............................................................................174
Closed part of a family......................................................................176
Reading and writing context...............................................................177
Modules.............................................................................................182
Adding, deleting and searching for rules.............................................184
Manipulation of object modules...........................................................189
4. Input / output....................................................................................190
Input ................................................................................................. 191
Output...............................................................................................193
5. Other elements of the environment...............................................195
Leaving Prolog III..............................................................................195
Time, other measurements..................................................................196
Predefined rules ...............................................................................................197
1. Introduction...........................................................................................198
Index of predefined rules and external procedures ............................369
viii © PrologIA
Prolog
Aociation
HERITAGE
General Contents
© PrologIA ix
Prolog
General Contents Aociation
HERITAGE
x © PrologIA
Prolog
Aociation
HERITAGE
General Contents
User's Manual
© PrologIA xi
Prolog
General Contents Aociation
HERITAGE
Debugger Manual
xii © PrologIA
Prolog
Aociation
HERITAGE
General Contents
© PrologIA xiii
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Prolog III
Version 1.3
Reference Manual
HERITAGE
Copyright
This manual and the software it describes are protected by copyright. According
to the legislation dealing with these rights, this manual and software must not
be copied or adapated either wholly or in part, without the written consent of
PrologIA except within the normal bounds of use or to create a back-up copy.
However these exceptions do not authorise the user to create copies to be used by
a third party, regardless of whether or not they are to be sold.
Prolog III is a registred trademark of PrologIA.
HERITAGE
Introduction
Finally, readers not used to Prolog may feel they are being given a rough
ride by this manual whose main aim is to present Prolog III and constraint
logic programming, sometimes to the detriment of a more pedagogical
approach giving details of the concepts often used in Prolog.
HERITAGE
Now for a few words about how this manual is organized. It is divided
into three sections; a reference manual in a folder, and a user's manual and
debugger manual both presented in separate booklets.
Our aim when writing this manual was to allow several different reading
levels. These levels may vary according to how much you know about
Prolog III, or according to the context in which you are using it at a given
moment.
The first chapter sets out the major principles governing Prolog III by
means of small examples. You might like to go through it via the keyboard
of your favorite computer.
The next few chapters then form what could be called, perhaps a little
pretentiously, a "lesson" in Prolog III. The basic concepts of the language are
given in detail, and particular attention is paid to the detail of three main
aspects: tuples, numbers and booleans. The last of these chapters explains
the delay concept . Examples are to be found throughout this general
presentation, to make it easier to understand.
The reader will then find a complete list of Prolog III primitives in
alphabetical order. First we present the primitives common to both
syntaxes, and then those specific to the Edinburgh syntax. There is usually
one primitive on each page, with the aim of maximizing the possibilites for
cross-referencing access to other primitives and other parts of the manual.
The "Syntaxes" chapter then presents the Prolog III syntaxes. Two
syntaxes are permitted; an original syntax close to Prolog II, and an English
Edinburgh-type syntax.
2 © PrologIA
Aociation Prolog
HERITAGE
Before the general and specific indices at the end of the Reference Manual,
the reader will find three appendices; the first is a list of Prolog III messages,
the second a list of predefined rules, and the third contains the examples
from the manual, translated into the Edinburgh syntax.
At the end of this booklet is a general index covering the Reference and
User's Manuals.
ststs
© PrologIA 3
Aociation Prolog
HERITAGE
4 © PrologIA
Aociation Prolog
HERITAGE
This chapter offers a first contact with Prolog III via a small number of exercises
whose main characteristic is that they are very simple. We are not trying to
introduce the fundamental concepts of Prolog III - this will be the aim of the
following chapters - but only to show how the Prolog III system is used in simple
practical situations: how to activate it, write a program, try it out and modify it etc.
HERITAGE
The way in which you enter the Prolog III universe depends on the
operating system of your computer. On UNIX , VMS, MS-DOS, etc… you
simply type the following command (we will assume that $ is the « prompt »
for your system) :
$ prolog3
Prolog prints :
>
>
From now on, Prolog III behaves in the same way on all machines, at least
as far as concerns the exercises in this chapter.
The > character is the Prolog III « prompt » and indicates to the user that it is
waiting for a command. A command can equally well be a rule or a query.
Here is a simple query to start with:
6 © PrologIA
Prolog
Aociation
HERITAGE
Getting started with Prolog III
> outml("Hello!");
Hello!
{}
>
Prolog prints braces to show that a query has been successfully executed.
Now here is a first small program: three rules expressing that Jacques, Annie
and Remi live in Paris, Marseille and Paris respectively:
The rules are inserted in the order we typed them. We now enter the list
command, which displays all the rules given by the user.
> list;
lives_in(Jacques, Paris) ->;
lives_in(Annie, Marseille) ->;
lives_in(Remi, Paris) ->;
{}
>
> lives_in(Jacques,x);
{ x=Paris }
>
> lives_in(x,Paris);
{ x=Jacques }
{ x=Remi }
>
© PrologIA 7
Prolog
Getting started with Prolog III Aociation
HERITAGE
> lives_in(x,y);
{ x=Jacques, y=Paris }
{ x=Annie, y=Marseille }
{ x=Remi, y=Paris }
>
Each time, the system's answer is a set of values to be given to the variables
appearing in the question, in order to satisfy the corresponding relation. To
end the session, we type the following command:
> quit;
$
Loading a program
In this section we will use the program contained in the menu.p3 file. This is
the calculation of light meals, rewritten in Prolog III, very well-known but of
great pedagogical value. The problem is supplied with the interpreter. It is
sufficient to start Prolog III as above and then load the menu.p3 file by typing
> input("menu.p3");
{}
>>>>>>>>>>>>>> Error 17: UNEXPECTED END OF INPUT
>
8 © PrologIA
Prolog
Aociation
HERITAGE
Getting started with Prolog III
The input("menu.p3") goal switches the current input to the menu.p3. file. Its
commands are read one by one, executed if they are queries, encoded in
memory if they are rules. When the input file is finished, the message
«Error 17: UNEXPECTED END OF INPUT» appears and the current input
switches to the previous input, which in this case is the keyboard. We can
display the inserted rules by:
> list;
LightMeal(h,m,d) ->
HorsDoeuvre(h,i)
MainCourse(m,j)
Dessert(d,k),
{-k -i -i +10 >= 0 ,
i >= 0 ,
j >= 0 ,
k >= 0 };
HorsDoeuvre(radishes,1) ->;
HorsDoeuvre(pate,6) ->;
Dessert(fruit,2) -> ;
Dessert(ice_cream,6) -> ;
Meat(beef,5) -> ;
Meat(pork,7) -> ;
Fish(sole,2) -> ;
Fish(tuna,4) -> ;
{}
>
First of all let us note that these rules are not completely identical to those in
the menu.p3 file. This does not matter, they are equivalent. Prolog has
encoded the rules taken from the menu.p3 file into a canonic form and can no
longer decode them to produce the initial text because there are an infinite
number of possible initial texts. The menu.p3 file is not modified by Prolog.
© PrologIA 9
Prolog
Getting started with Prolog III Aociation
HERITAGE
Let us try this program out. We can ask what constitutes a light meal; this is
expressed by:
> LightMeal(h,m,d);
{ h = radishes, m = beef, d = fruit }
{ h = radishes, m = pork, d = fruit }
{ h = radishes, m = sole, d = fruit }
{ h = radishes, m = sole, d = ice_cream }
{ h = radishes, m = tuna, d = fruit }
{ h = pate, m = sole, d = fruit }
>
Meat(beef,5) -> ;
Meat(pork,7) -> ;
Meat(veal,4) -> ;
Meat(beef,5) -> ;
Meat(pork,7) -> ;
we simply delete the group of rules called Meat, and insert the new group:
> suppress(Meat);
{}
> Meat(veal,4) -> ;
> Meat(beef,5) -> ;
> Meat(pork,7) -> ;
>
we can observe the group called Meat using the list command.
> list(Meat);
Meat(veal,4)
Meat(beef,5)
Meat(pork,7)
{}
10 © PrologIA
Prolog
Aociation
HERITAGE
Getting started with Prolog III
>
> LightMeal(h,m,d);
{ h = radishes, m = veal, d = fruit }
{ h = radishes, m = beef, d = fruit }
{ h = radishes, m = pork, d = fruit }
{ h = radishes, m = sole, d = fruit }
{ h = radishes, m = sole, d = ice_cream }
{ h = radishes, m = tuna, d = fruit }
{ h = pate, m = sole, d = fruit }
>
The output command switches the current output to the file given as an
argument, list will display our program on this output, and close_output
closes the current output and switches back to the previous output, which in
this case is the screen. We can now quit the session again by:
> quit;
$
Once we have returned to our operating system we can check that the
menub.p3 file has been created, including the modifications which we made
above.
Prolog III is a language which manipulates not only trees, which we assume
are well known, but also tuples, linear numeric expressions and boolean
formulæ. All these objects can be solutions of constraint systems.
© PrologIA 11
Prolog
Getting started with Prolog III Aociation
HERITAGE
In this section, some small examples will show how to manipulate these
different objects.
W ARNING . If you want to “play” with Prolog III, you will want to type
several small programs one after the other. Because Prolog III conserves all
these programs in memory, after a while you will doubtless obtain errors
caused by name conflicts, such as "RULE ALREADY DEFINED". To avoid
this, reset the rule space to zero after each example, by executing the
following command:
> kill_module("");
{}
>
> {x = <1,2,3>.<4,5>};
{ x=<1,2,3,4,5> }
> {x = y.z, y::2, y = <1,2>};
{ x=<1,2>.z, y=<1,2> }
> {x = y.z, y::2};
{ x=y.z, y::2 }
>
N.B. The examples above are given in order to explain the system, and the answer
provided by the machine may in fact have a different form, which is equivalent.
12 © PrologIA
Prolog
Aociation
HERITAGE
Getting started with Prolog III
Character strings are tuples whose elements are characters. The string
written "abc" is the tuple of characters <'a','b','c'> .
© PrologIA 13
Prolog
Getting started with Prolog III Aociation
HERITAGE
h= c + b and l = 4c + 2b
This time, Prolog tells us the solution is unique by providing the values of
the variables for which the set of constraints is verified. Of course we could
have set any pair of variable values in order to obtain a unique solution.
Before continuing with this example we are now going to declare a rule in
Prolog which links the four variables and the equations, so that the equation
system does not have be given explicitly each time. From now on, we will
use only this relation. We enter:
We have just introduced into Prolog a rule whose semantic meaning is:
provided the constraint system is verified, the relation CatsBirds(c, b, l, h) is true.
We can now write the following queries:
> CatsBirds(c,b,14,5);
{ c=2, b=3 }
> CatsBirds(1,b,l,5);
{ b=4, l=12 }
> CatsBirds(1,1,2,4);
> CatsBirds(c,b,6,4);
{ c=-1, b=5 }
>
14 © PrologIA
Prolog
Aociation
HERITAGE
Getting started with Prolog III
Prolog does not give an answer to the third query, because it is not solvable.
For the fourth, one of the variables in the solution is negative. It is quite true
that when we formalized our problem we at no time specified that the
solutions had to be positive! We must therefore rewrite our CatsBirds
relation so that the variables appearing in the system of equations are
constrained not to be negative. First of all we remove the CatsBirds relation
with the query:
> suppress(CatsBirds);
{}
>
and ask:
> CatsBirds(c,b,6,4);
>
> CatsBirds(c,b,7,3);
{ c=1/2, b=5/2 }
>
We end up with 21 a cat and 25 birds.... Once again, it is quite true that we
never specified that the solutions had to be integers. Prolog solves
arithmetical equations in the set Q of rational numbers. This example stops
here because the constraint to force a variable to be an integer does not
exist; to perform this verification we will have to a use a built-in predicate.
© PrologIA 15
Prolog
Getting started with Prolog III Aociation
HERITAGE
Remember that these three implies relations indicate that the three variables
a, b, c are equivalent and thus have the same truth value, without this
necessarily being known. Prolog replies with a system identical to the one
given as input, since this system is in fact already "simplified".
16 © PrologIA
Prolog
Aociation
HERITAGE
Getting started with Prolog III
This time there is a unique solution and Prolog replies that all the variables
take the value "true".
ststs
© PrologIA 17
Prolog
Getting started with Prolog III Aociation
HERITAGE
18 © PrologIA
Aociation Prolog
HERITAGE
Basic concepts
1. Trees
2. Constants
3. Operations
4. Variables
5. Terms
6. Relations
7. Constraints
8. Constraint system solving
9. Rules and queries
What are the fundamental concepts of Prolog III? What are the objects that the
language manipulates? What is the nature of the constraints acting upon these
objects? What does a Prolog III program mean to the programmer? How does the
machine execute it? What syntax are these objects and constraints expressed in?
The difference between most other programming languages and Prolog III is a
difference of nature, not degree. Prolog III cannot be approached without first
examining a certain number of concepts which are the basis of the language, and
indispensable for optimum use, or sometimes for any kind of use at all. This chapter
presents all the specifications for Prolog III in a fairly informal way, which is
accessible however familiar or unfamiliar you may be with logic programming. We
define the objects manipulated by the language, then the operations and relations
which enable constraints to be established applying to these objects. Then we show
what a Prolog III program is and also how it is executed.
HERITAGE
1 . Trees
"What is the nature of the manipulated objects?" This is one of the first
questions which must be answered in order to explain Prolog III. The
language is completely coherent and uniform:
Some are very complex, or even infinite, while others can be reduced to a
single node. Some have a particular name, while others can only be
designated using an operation which constructs them or by a constraint
system of which they are a solution.
The role of this manual does not include reproduction of the formal proofs
which justify the algorithms in the core of Prolog III, and so here is not the
place to give a strict definition of trees. The normal intuitive concept, in
which a tree as seen as a hierarchically organized unit, is quite sufficient.
Each node in the tree is in its turn the root of a tree called a sub-tree of the
initial tree, defined by this node, its sons, the sons of its sons, etc. and the
arrows which start from all these nodes.
20 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
A label is associated with each node of a Prolog III tree. Labels can be:
• identifiers
• characters
• the boolean values 0' and 1'
• numbers
• the double sign <>
name_married_weight
The number of the node's sons is always finite and independent from the
nature of its label. Of course the semantics of this label, i.e. what it means to
the programmer, may mean that a node only has a meaning if it is
accompanied by a determined number of sons, but this is not known by the
basic Prolog mechanisms.
The number of sons of a node can be zero, and this type of single node tree
is called a leaf. Prolog III does not distinguish between a leaf and the label
that it carries. Consequently identifiers, characters, boolean values and
numbers are considered to be special types of tree.
All these elements can be used to label a node. A particularly frequent case
is the use of an identifier as a label, as in the example given above. Very
often these trees represent relations. For the tree we are referring to, this
could be " is called Dupont, is married and weighs 75,5 Kg ".
© PrologIA 21
Prolog
Basic concepts Aociation
HERITAGE
Another frequent case is when the label for the initial node of the tree has no
meaning for the programmer, who is therefore only interested in the
sequence of sons. In this case the double sign <> is used as a label. Such
trees are called PIII-tuples or simply tuples, and they thus implement the
notion of a finite sequence of trees. In this way the tree reduced to the
symbol <> represents the empty sequence. Tuples are explained in more
detail in the chapter “Trees, tuples, strings and lists”
In Prolog III programs, trees are represented by formulæ called terms. Term
syntax will gradually become apparent during the next few paragraphs; it is
summarized in the chapter " Prolog III syntaxes ".
Trees and terms are not the same thing. The elements of the Prolog III domain
are trees, the syntactic entities that represent them are terms. Remember
that in the explanation of Prolog III which follows, it will virtually always be
the latter that are referred to, because they are the only written expression
of trees, in accordance with the syntax of the language. This may seem to
encourage confusion between the two concepts. We cannot warn the reader
strongly enough against such confusion, since it leads to many pitfalls. In
particular it will prevent the reader from understanding some of the most
important concepts.
This having been said, there is one case in which the tree and the term which
represents it do come together: this is the case of constants, which by
definition are trees represented by simple terms, expressed without an
operator, as explained in the next paragraph.
22 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
2 . Constants
Constants are elements in the Prolog III domain (of trees) which have special
names. As we have said we will make no distinction between a constant and
the term that represents it.
<>
Identifiers
pierre
light_meal
calcul12
© PrologIA 23
Prolog
Basic concepts Aociation
HERITAGE
Characters
All the characters available on your machine can be used in a Prolog III
program. Printable characters can be expressed by enclosing them in " back-
quotes" :
Non printable characters and those having a special role can be indicated
using the escape character back-slash ( \ ), according to a convention similar
to the one used in UNIX. For example:
The complete character syntax is given in the chapter "Prolog III syntaxes".
24 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
Boolean values
The boolean values are the two elements from standard Boolean algebra:
0'
1'
We do not interpret them as being true or false, because these terms are used
to describe constraints (we will refer to a constraint as true or false to
indicate whether or not it is satisfied). Constraints are explained below, in
section 7.
0
1
2
1991
815915283247897734345611269596115894272000000000
Rational numbers are represented in the machine in perfect precision; i.e. with
as many digits as is required to express them exactly. Of course this is
subject to the condition that this must not exceed your computer's memory
capacity.
© PrologIA 25
Prolog
Basic concepts Aociation
HERITAGE
Floating numbers
Examples:
12.345
-0.5
314.15926535e-2
1.2E12
<>
The double sign <> is a conventional symbol used to label trees which are
unlabeled from a semantic point of view. These trees can thus be reduced to
the sequence of their sons: in Prolog III they implement the concept of a
finite sequence of trees, which we call tuples.
As we will see, tuples are written <a1, … an>; the empty tuple is thus written
<>, hence its name.
Character strings
"Oh boy"
26 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
<>
The empty tuple and the empty string are both special cases and are the
same thing: the two notations "" and <> are therefore equivalent.
3 . Operations
To denote trees that are not constants you must write formulæ that combine
constants and operators, according to a syntax which will gradually be
revealed. These formulæ express the result of an operation. An operation is
defined on a set of tree tuples: it associates a tree with each one of these
tuples1 :
The set of tree tuples for which a given operation is defined is not
necessarily equal to the set of all the tuples; the operation is thus said to be
partial. The identification of the sub-set of tuples on which the operation is
defined is part of the definition of such an operation.
© PrologIA 27
Prolog
Basic concepts Aociation
HERITAGE
This statement may seem surprising but it is worth making, especially for
users of previous Prologs. In those languages, operations written as +, *,
& , etc… are defined or could be defined; however they do not have their
usual mathematical meaning; they are simply tree construction operations.
So in Prolog II, the formula 2 + 3 denotes a tree whose label is + and sons
are 2 and 3. A built-in predicate can then interpret this tree and extract
the number 5 from it, but this is foreign to the core of Prolog II, which does
not perform any specific processing of booleans or numbers.
This statement will be of even more interest when we consider terms which
have variables. As for the previous addition, the formula 2 + X will not
denote any non atomic tree, but truly the (unknown) number resulting from
the addition of 2 and the unknown number X.
Boolean operations
Boolean operations are only defined if the operands are boolean values, i.e.
leaves labeled by boolean constants.
a1 ~ a1
28 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
The results of these different operations are defined by the following table:
a1 a2 ~a2 a1 & a2 a1 | a2 a1 => a2 a1 <=> a2
0' 0' 1' 0' 0' 1' 1'
0' 1' 0' 0' 1' 1' 0'
1' 0' 0' 1' 0' 0'
1' 1' 1' 1' 1' 1'
Arithmetical operations
Arithmetical operations are only defined if the operands are numeric values,
i.e. leaves labeled by numbers.
© PrologIA 29
Prolog
Basic concepts Aociation
HERITAGE
To lighten notation, Prolog III allows a1a2 instead of a1*a2. Of course it only
allows it when the meaning of what is written is not changed. But be careful,
there are some fairly nasty traps: see section 5.
These operations are used to construct trees not reduced to leaves. These
are:
30 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
This is defined whatever the tuple (a1, … an), provided that n 1. It results in
the PIII-tuple whose elements are a1, … an . n is said to be the length of the
constructed tuple. The following equality derives from the definition itself of
tuples:
This is only defined if a1 and a2 are both tuples. It results in tuples whose
elements are those of a1 followed by those of a2. By definition we therefore
have the equality:
1 Strictly speaking, we should refer to "the tree labeled by the label of a 1 », but as
stated previously, Prolog III does not distinguish between a leaf and its label.
© PrologIA 31
Prolog
Basic concepts Aociation
HERITAGE
Standard lists
Standard 1 lists can also be used in Prolog III, based on the pointed pair
concept in the same way that they exist in Lisp or other Prologs. In the
Edinburgh syntax2, these lists are written as follows:
• empty list:
[]
• list having the elements e1, e2, … en and terminated by []:
[ e1, e2, … en ]
• list in which the head elements are e1, e2, … en and the tail is the list q :
[ e1 , e2 , … en | q ]
32 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
4 . Variables
Variables are not additional elements in the Prolog III domain which we
have not yet discussed and which exist in addition to trees. In essence,
variables are simply another way of representing trees, as will be shown by
the following explanations.
X
Y'
Z2
V_ariable
1 In the Marseille Prolog III syntax, variables do not have to start with an upper-
case letter, and identifiers do not have to start with a lower-case letter. However this is
the rule in the Edinburgh syntax. Therefore, although they are written in the original
syntax, most of the Prolog III expressions given as examples in this text will as far as
possible be compatible with both syntaxes.
© PrologIA 33
Prolog
Basic concepts Aociation
HERITAGE
X = (1/2)X + 1
Seen from this perspective, the aim of a Prolog III program is not to modify
the values of variables, but to determine them. As soon as they become
available, variables can appear in terms and constraints, such as X < 10 ;
indeed, programming in Prolog III will sometimes consist of nothing more
complicated than writing constraints that act upon an initially unknown tree,
represented by a variable. Prolog III's task is then to solve these constraints
and disclose the relevant tree.
5 . Terms
Here are the most significant of those BNF expressions that define term
syntax. The whole of these expressions are given in the chapter " Prolog III
syntaxes".
Syntax
<term>
::= <term1>
::= <term> => <term1>
::= <term> <=> <term1>
<term1>
::= <term2>
::= + <term2>
::= - <term2>
::= <term1> + <term2>
::= <term1> - <term2>
::= <term1> | <term2>
34 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
<term2>
::= <term3>
::= <term2> / <term3>
::= <term2> * <term3>
::= <multiplicand> <variable>
::= <term2> & <term3>
<term3>
::= <term4>
::= ~ <term3>
<term4>
::= <term5>
::= <term5> ( <sequence of terms> )
::= <term5> [ <term> ]
::= <term4> . <term5>
<term5>
::= <variable>
::= <constant>
::= < <sequence of terms> >
::= ( <term> )
<multiplicand>
::= <integer>
::= <real>
::= ( <term> )
<sequence of terms>
::= <term>
::= <term> , <sequence of terms>
© PrologIA 35
Prolog
Basic concepts Aociation
HERITAGE
Limitations
The above syntax thus allows all types of term to be written. In particular, it
does not establish dissymetry between the two operands of arithmetical,
boolean or tree construction operations. The reader should know that there
are two important restrictions at the level of Prolog III's basic mechanisms.
This means that in a multiplication a1 * a2 one of the two operands must not
contain any variables, and that in a division a1 / a2 the second operand a2,
must not contain any variables. This prohibits terms such as
(2x+3)*(4y+5) or x/y.
This prohibits the writing of terms such as x.y, unless a constraint such as
x = <z1,z2,z3> or x::3 (constraints are explained in section 7)
constrains x to have a determined length, in this case 3.
Although these are fundamental limitations at the level of Prolog III's basic
mechanisms, in most practical situations you will not need to take account of
them, since an automatic delay mechanism "freezes" the conflicting
expressions until enough variables are known for the expression to be
considered legitimate. This mechanism is described in the chapter "Delay
Techniques".
36 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
Examples
Identifiers
apple (1)
apple' (2)
nb_sons (3)
Paul_Hochon (4)
zZ44a_45b_c46' (5)
These are correct identifiers in the Marseille syntax. It should be noted that
in Edinburgh syntax (explained in the chapter "Prolog III syntaxes"), example
(4) is a variable instead of an identifier, because it starts with an upper-case
letter.
Incorrect identifiers 1
t_iti (1)
i'm_happy (2)
nb-brothers (3)
1dou (4)
Examples (1) and (2) are incorrect because their second character is not a
letter: they are correct variable names however. Examples (3) and (4) are
also illegal: the minus sign is not allowed inside a word; and an identifier
cannot start with a digit.
1 Strictly speaking, we should say "expressions which are not correct identifiers".
© PrologIA 37
Prolog
Basic concepts Aociation
HERITAGE
Integers
2500 (1)
815915283247897734345611269596115894272000000 (2)
012 (3)
00 (4)
Incorrect integers
2 500 (1)
8.0 (2)
0. (3)
The first expression defines not one integer, but two integers separated by a
space. The following two expressions define legitimate floating numbers,
not correct integers.
Floating numbers
1.e6 (1)
.5e6 (2)
31.4e-1 (3)
4. (4)
.666 (5)
These expressions define the numbers 106 ; 0.5 106 ; 31.4 10-1 ; 4 ; 0.666
respectively.
38 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
e10 (1)
.e10 (2)
1.2e (3)
3e10 (4)
Example (1) specifies a variable, not a number. The other examples show us
that a mantissa must have at least one digit (2), the exponent cannot be
omitted (3), and neither can the decimal point (4).
Characters
'A' (1)
'\x41' (2)
'\101' (3)
'\41' (4)
'\n' (5)
The first three examples specify the same charcter: the letter A, whose ASCII
code is 41 in hexadecimal, 101 in octal. It can be noted that the zero is
omitted in the fourth example, which specifies the character ! (041 in octal)
because there is no ambiguity about the character immediately after the
expression \41. Example (5) indicates the end of line character.
Character strings
© PrologIA 39
Prolog
Basic concepts Aociation
HERITAGE
Strings (1) and (2) are identical. The content of string (4) is:
The brackets "[" and "]" indicate…
String (5) is the empty string. It can also be written:
<>
Strings (6) and (7) are identical (A and B separated by a horizontal tab).
Example (8) represents the string
A{
""" (1)
"The brackets ""["" and…" (2)
"11\1112" (3)
Example (1) poses the well-known problem of the presence in a string of the
string delimiter itself. Example (2) shows one incorrect way of solving this
problem. Example (3) - in contrast with example (8) of correct strings -
shows a case in which the three digits of the octal ASCII code must be
written. The correct way to write this string would probably be:
Numeric expressions
-X (1)
+X (2)
355/113 (3)
4 + 1/2 + 0.333 (4)
X + 3Y + 5Z/4 + (14+9/17)T (5)
(1000 - 2*3*4*5)Y (6)
(1/2 + 2/3 + 3/4 + 4/5)*(X + Y - 2T/5) (7)
(X + Y)*(X - Y) (8)
(2T/5 + X - Y)/(X + Y - 1/2) (9)
40 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
Example (4) shows various cases where the Prolog III syntax enables the
operator * to be omitted. An equivalent notation of this expression is :
Since examples (8) and (9) are non linear expressions, an automatic delay
mechanism is installed. For more details, please refer to the "Delay
Techniques" chapter.
5(X + Y) (1)
4/5X (2)
X5 (3)
XY (4)
3*-X (5)
© PrologIA 41
Prolog
Basic concepts Aociation
HERITAGE
Boolean expressions
1' (1)
X | 0' (2)
X | ~Y (3)
~~Y (4)
X & X (5)
X & 1' (6)
(A & B) => (C & D) (7)
(U3 & ( ~X1 <=> X3 )) | 0' (8)
Here the rule is simple: they are all incorrect. In other words, in Prolog III no
correct arithmetical expression can comprise boolean sub-expressions, any
more than a correct boolean expression can comprise arithmetical sub-
expressions. This derives from the definitions of arithmetical and boolean
operations. The following formulæ are thus all incorrect:
-1' (1)
(X & Y) + Z (2)
~0 (3)
X & (Y + Z) (4)
These limitations can be accepted without any great difficulty; they exist in
all properly defined languages. It is less easy to adjust to the following
restriction: in Prolog III no operator provides a boolean result deriving from
properties of numbers. The operators that apply to numbers all give numbers
as their result, while those that produce booleans only have a meaning if
they are applied to booleans.
42 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
Other terms
4(X + Y) (5)
It should be noted that in Prolog III, terms (1) and (3) are not equivalent1.
On the other hand (1) and (2) are equivalent, as are (3) and (4). Example (5)
is a correct term, which is not the number 4 (x y) but the tree which is
labeled by 4 and whose only son is (x y).
It can also be noted that the label of the last example has to be
parenthesized.
1 In this example there are only terms with no variable, and so "to be equivalent"
simply means "representing the same tree".
© PrologIA 43
Prolog
Basic concepts Aociation
HERITAGE
Incorrect terms
From the syntactic point of view alone, example (2) could be corrected by
writing (ff(X,Y))(Z,T) . But this term would then be semantically
incorrect since the label of a tree must be a leaf.
Example (3) shows that in the case of a leaf, the syntax does not allow a pair
of parentheses to be written around the (empty) sequence of sons. This is
completely coherent with Prolog III's property that it does not distinguish
between a leaf and its label.
< P + L, 2P + 4L >
44 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
• A term represents a set of trees; i.e. the set obtained by giving all the
possible values to the variables it contains. Thus the term given as an
example above represents the infinite set of all two number tuples. This set
is identical to that defined by the term < +X, +Y > and has no element in
common with the sets defined by the tuples < X > or < X, Y, Z >
Of course here we come back to the two extreme cases of terms: a term
reduced to one variable represents the set of all the trees, whereas a term
without a variable represents the set reduced to the single tree which the
relevant term expresses in writing.
Assignment
Let us examine for a moment the concept of "giving values to the variables of a
term" and formalize it a little better. This will be useful later when we want
to understand constraint system solving. We have already stated that a
variable can represent any element in the Prolog III domain; when we define
an assignment of a set of variables we are simply choosing a value for each of
the relevant variables. If the set is
V = { x1, x2, … xn }
then an assignment of this set will be a set of pairs (xi, ai), written xi ai, as
follows:
A = { x1 a1, x2 a2, … xn an }
meaning that tree a 1 is given the value of variable x 1 , tree a 2 the value of
variable x2, etc… An assignment is therefore simply the mapping of a set of
variables in the Prolog III domain, defined by extension (element by
element).
© PrologIA 45
Prolog
Basic concepts Aociation
HERITAGE
- if t has the form t1(t2, … tn) and if a1, a2, … an are the trees t1/A, t2/A, …
tn/A then
- if a1 is a leaf, then a is the tree a1(a2, … an)
- else, a is undefined
- if t has the form t1[t2] and if a1 and a2 are the trees t1/A and t2/A then
- if a1 is a leaf and a2 a tuple, then a is the tree a1[a2]
- else, a is undefined
etc…
To end this section about terms, it is worth noting that the specific
consideration of arithmetical and boolean operations by Prolog III's core
has consequences whose subtlety ought to be emphasized. For example,
let's examine the two following terms:
X
X + 0
46 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
The first denotes the set of all trees: any element in the Prolog III domain can
be represented in a program by the variable X . The second comprises
known elements: the addition operation + and the constant 0. As we have
stated previously, this term represents the set of trees which we can obtain
by giving values to the variable X . Firstly, addition is only defined on
numeric values, i.e. trees reduced to a leaf labeled by a number, and the
results it produces are numeric values; in addition any number y can be
written y = x + 0. Consequently, the term X + 0 defines the sub-set of the
Prolog III domain which consists of all numbers.
1*X
+X
X & 1'
X | 0'
~~X
are three ways of denoting the set of all booleans. Alternatively, these three
expressions can be seen as representing a tree reduced to one leaf labeled by
a boolean, the rest of which is unknown.
© PrologIA 47
Prolog
Basic concepts Aociation
HERITAGE
6 . Relations
Like operations, relations are partial. The set of trees or pairs of trees on
which a relation is defined is not necessarily equal to the set of all trees or all
pairs of trees.
The condition
a1 = a2
48 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
The condition
a1 # a2
The tree equality relation is defined recursively by stating that two trees a1
and a2 are equal if
- the labels of a1 and a2 are equal-as-labels
© PrologIA 49
Prolog
Basic concepts Aociation
HERITAGE
Implication
The condition
a 1 => a 2
reads as: " trees a1 and a2 are both booleans and if a1 has the value 1' then a2
has the value 1' ". Since a1 and a2 are booleans, there are only four possible
cases and we can define this constraint by means of a table:
Numeric comparisons
The conditions
a1 < a2
a1 <= a 2
a1 > a2
a1 >= a 2
are verified if the trees a1 and a2 are both numbers and if a1 is less than (or
less than or equal to, greater than, greater than or equal to) a2
50 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
Unary relations
Unary relations are often called type relations because they mainly involve
the nature of the label attached to the initial node of the tree they apply to. In
certain cases, they also bring into play the number of sons of the initial node.
a !numt
a !chart
a !boolt
a !idt
These conditions are verified if the initial node of the tree a is labeled by a
number, a character, a boolean, or an identifier respectively. The other
nodes are not subject to any conditions.
a !tuple
This condition is verified if the initial node of the tree a is <> , in other words
if a is a PIII-tuple. The other nodes do not have to verify any conditions.
a :: n
This condition reads as " n is a non negative integer and n branches start
from the initial node of a". It is often put in conjunction with the previous
condition. Together they are equivalent to "a is a tuple of length n"
a !num
a !char
a !bool
a !id
These conditions are verified if a is a leaf and if its only node is labeled by a
number (or character, boolean, identifier). Therefore:
© PrologIA 51
Prolog
Basic concepts Aociation
HERITAGE
7 . Constraints
In the same way that we moved from trees to terms, we will now move
from conditions to constraints. A condition consists in the application of a
relation - a mathematical entity - to a tree or pair of trees - elements in the
Prolog III domain. A constraint will be a syntactic object, formed by the
symbol that expresses a relation, and a term or pair of terms which the
relation is stated to act upon. We therefore
- move to the syntactic level1
- introduce variables
Syntax
<constraint system>
::= { }
::= { <constraint> {, <constraint> } }
<constraint>
::= <term> = <term>
::= <term> # <term>
::= <term> => <term>
::= <type constraint>
::= <Sup constraint>
::= <Inf constraint>
52 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
<Sup constraint>
::= <term> <sup> <term>
::= <Sup constraint> <sup> <term>
<Inf constraint>
::= <term> <inf> <term>
::= <Inf constraint> <inf> <term>
<inf>
::= < | <=
<sup>
::= > | >=
<tree type>
::= !idt | !boolt | !numt | !chart | !tuple
::= !id | !bool | !num | !char
<type constraint>
::= <term> <tree type>
::= <term> :: <term>
Compared to what we already know, this syntax adds one important detail:
it is possible to stick together several <, , > or constraints provided that
they are all of the type <, or all of the type >, . We can thus write { 1 < x
< y 3 } instead of { 1 < x, x < y, y 3 }
Examples
X !num (1)
F !id (2)
A # B(I, J + 1) (3)
<P, "Durand"> = <"Pierre", N> (4)
A => B & C (5)
0 < T < 3X/4 + 5Y (6)
© PrologIA 53
Prolog
Basic concepts Aociation
HERITAGE
4X + Z (1)
TT(X) (2)
A & B (3)
(X = Y) & (Y = Z) (4)
(1), (2) and (3) suffer from the same disease; they are correct terms but
incorrect constraints. (4)'s problem is more serious: a constraint (in this case
X = Y) must never appear in a term; in addition (4) results from a confusion
between booleans - elements in the Prolog III domain - and the truth or
falsehood of constraints.
We have explained how the assignment of the set of all variables transforms
a term into a tree. By applying the same process to each term that appears in
a constraint applying to terms, this constraint can be transformed into a
condition applying to trees. A constraint system will be said to be
"verifiable" or rather solvable, if there is at least one assignment of the
system's variables which transforms it into a set of true conditions applying
to trees. This assignment is called a solution of the constraint system.
{ P 0, L 0, P + L = 16 }
54 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
{ P 8, L 8 }
{ 8 0, 8 0, 8 + 8 = 16 }
{ P 0, L 0, P + L = 16, 2P + 4L = 44 }
{ P 10, L 6 }
Constraints are written using partial relations, and terms which are also
constructed by means of partial relations. When considering an assignment
that transforms a constraint into a condition applying to trees, before finding
out whether or not the condition is satisfied, the trees that will appear in it
must first be defined. This is why Prolog III constraints generally set
substantially more limitations on their variables, than those expressed by the
relation that heads the constraint.
© PrologIA 55
Prolog
Basic concepts Aociation
HERITAGE
X = +Y
invokes the "unary +" operation, which is only defined on numbers. Any
assignment of X and Y which transforms this constraint into a true condition
must assign a number to Y. This constraint first constrains the variable Y to
be a number, and then to be equal to the variable X . In other words, the
systems { X = +Y } and { Y !num , X = Y } are equivalent1 . Similarly, the
systems { T = 1/X } and { X !num , X # 0 , T = 1/X } are also equivalent.
{ T = X[Y] } (1)
{ T = <>[y] } (2)
{ T = (~X)[Y] } (3)
{ T = (+X)[Y] } (4)
The term X[Y] represents the set of trees labeled by X whose sequence of
sons is Y, i.e. since no other constraint applies to X or Y, the set of all trees.
Constraint (1) is satisfied, whatever tree is given as the value of T.
Constraints (2), (3) and (4) do not add any other limitation to the sequence of
T's sons; however since they invoke arithmetical or boolean operators, they
fix the type of this tree's label. In their final definitions, these four constraint
systems are respectively equivalent to:
{ } (1)
{ T !tuple} (2)
{ T !boolt } (3)
{ T !numt } (4)
1 As in mathematics, we will say that two systems are equivalent when they have
the same set of solutions.
56 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
Let's continue to use these rather "strange" examples and examine the
following two constraints:
{ +X # ~Y } (1)
{ +X = ~Y } (2)
{ +X = ~X } (1)
{ +X # ~X } (2)
will be rejected by Prolog III's analyzer. Although they are correct from a
strictly syntactic point of view, since no tree can be simultaneously numeric
and boolean, no assignment exists which can transform these constraints
into verified conditions applying to trees.
Syntax
We can now finally examine Prolog III programs themselves. They consist
of rules having a head which is a term, and a body formed by a sequence of
goals and a constraint system. The sequence of goals can be empty and so
can the constraint system. When the constraint system is empty, it can be
omitted.
<rule>
::= <head>
-> { <goal> } [ , <constraint system> ] ;
© PrologIA 57
Prolog
Basic concepts Aociation
HERITAGE
<query>
::= { <goal> } [ , <constraint system> ] ;
<goal>
::= /
::= <term>
<head>
::= <term>
h o r s _d_oeuvre(X) m ain _ c o u r s e ( Y ) d e s s e r t ( Z ) ;
h e n s _rabbits(P, L, 1 6, 4 4 ) ;
58 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
t0 t1 t2 … tn , S ; (1)
a0 a1 a2 … an ; (2)
Such a rule without variables expresses a logical property: "if a1, a2 … an are
facts, then a0 is a fact".
a0 ; (3)
1 For the moment we will ignore the case of the cut /, which may appear in a rule
body in place of a term.
© PrologIA 59
Prolog
Basic concepts Aociation
HERITAGE
Under these conditions, the set that a Prolog III program defines is the
smallest set of facts that satisfies all the logical properties generated by the
rules of the program. The program thus consists of rules which state explicit
facts (rules of type (3) with no body and thus no variables), and all the other
rules, which can be seen as deductive processes to produce the implicit facts.
p r i c e(flowers,120) - > ;
p r i ce(chocolates,90) - > ;
p r i ce(wine,50) - > ;
p r i c e(dried_fish,40) - > ;
p r e sent(chocolates) - > ;
p r e sent(wine) - > ;
p r e s ent(flowers) - > ;
c h e a p_present(X) - >
present(X)
price(X,P) ,
{ P <= 100 } ;
Taking into account the constraints, the last rule leads to the following rules
on the trees:
c h e a p_present(dried_f i s h ) - >
present(dried_fish)
price(dried_fish,40);
c h e a p_present(chocola t e s ) - >
present(chocolates)
price(chocolates,90);
c h e a p_present(wine) - >
p resent ( w i n e ) p r i c e ( w i n e , 5 0 ) ;
60 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
and since p r e s e n t ( c h o c o l a t e s ) , p r i c e ( c h o c o l a t e s , 9 0 ) ,
present(wine) and price(wine,50) are facts, we can deduce from this
that cheap_present (chocolates) and cheap_present(wine) are also
facts. This program therefore defines the set of facts
{ price(flowers,120), price(chocolates,90), price(wine,50),
price(dried_fish,40), present(chocolates), present(wine),
p r e s e n t ( f l o w e r s ) , cheap_present (chocolates),
cheap_present(wine) }. Only the last two of these facts were not explicit.
Program execution
We have just shown what the implicit information contained in a Prolog III
program is. Let's now look at how it is executed by the machine. The aim of
this execution is to solve the following problem: "given a sequence t1 t2 … tn
of terms and a constraint system S, find the values of the variables which
transform the terms ti into facts defined by the program and the constraints
of S into verified conditions. "
t1 t2 … tn , S
- if the system S is empty and n = 1 then the query amounts to the question
"what values of variables are required for the term t1 to be transformed into
a fact defined by the program?"
To explain how Prolog III calculates the answer to these questions we will
introduce an abstract machine. This consists of a non deterministic machine
whose only basic instruction is described by the three following formulæ:
(1) ( W, t0 t1 … tn , S )
(2) s0 s1 … s m , R
(3) ( W, s1 … sm t1 … tn , S R { s0 = t0 } )
© PrologIA 61
Prolog
Basic concepts Aociation
HERITAGE
Formula (1) represents the state of the machine at a given moment. The
current query is t0 t1 … tn , S. W is the set of variables we are interested in.
Formula (2) represents the rule in the program that is used to change the
state of the machine. If necessary, some of its variables are renamed so that
none will be in common with (1). The other rules of the program could have
equally well been used; this one is used simply because we chose it.
Formula (3) represents the new state of the machine, when rule (2) has been
applied. It is only possible to pass to this state if the constraint system S R
{ s0 = t0 } possesses one solution in which each of the terms in the sequence
s1 … sm t1 … tn represents a defined tree.
To answer the query t0 … tn , S the machine will start from the initial state
( W, t0 … tn, S ), where W is the set of variables appearing in the query, and
will go through all the states that it can attain by repeating the basic
operation above. Of course the choice expressed by formula (2) is not left to
accident; Prolog III functions in such a way that all the rules are tried in
succession1, in the order they were written in the program. The Prolog III
machine is thus in fact the (determinstic) machine which produces all the
possible executions of the non deterministic machine defined by expressions
(1), (2), (3).
i.e. in which the sequence of goals is empty, the answer provided by Prolog
III will be the solution of system S on a set of variables W.
1 Or at least all the reasonable rules, i.e. all rules except those which would
obviously make the system S R { s0 = t0 } unsolvable.
62 © PrologIA
Prolog
Aociation
HERITAGE
Basic concepts
cheap_present(X);
the states of the machine will be as follows (not including the states destined
to fail):
{X}, cheap_pres e n t ( X ) , { } ;
{P100,cheap_present(X)=cheap_present(X')};
{X}, price(X',P') ,
{P'100,X=X',present(X')=present(chocolates)};
{X}, price(X',P') ,
{P'100,X=X',X'=chocolates};
{X}, , {P'100,X=X',X'=chocolates,
price(X',P')=price(chocolates,90)};
© PrologIA 63
Prolog
Basic concepts Aociation
HERITAGE
{X}, , {P'100,X=X',X'=chocolates,P'=90)};
Since the sequence of goals is now empty, Prolog III displays the solution of
the current system S = { P ' 1 0 0 , X = X ' , X ' = c h o c o l a t e s , P ' = 9 0 ) } , or
rather the most interesting part of this solution, which is
{X = c h o c o l a t e s }
Prolog III then explores the other possible executions of the non
determinstic machine: (1), (2), (3) ; in this way the solution
{X = w i n e }
ststs
64 © PrologIA
Aociation Prolog
HERITAGE
1. Introduction
2. Trees
3. Tuples
4. Predefined rules on the tuples
5. Lists
6. Strings
7. Examples
The Prolog III domain consists of trees (finite and infinite). A new universal
operator has been added which is not available in standard Prologs: the general tree
constructor. The list concept has been extended to that of the tuple, and this domain
is equipped with a true concatenation operation. In addition, character strings are
a sub-set of tuples. Finally for reasons of compatibility and efficiency, standard
Prolog lists are conserved. This chapter presents the operations and relations
defined on trees and tuples, and a number of examples using constraints on these
domains.
HERITAGE
1 . Introduction
2 . Trees
Trees form the most general class of all the objects defined in Prolog III. The
other objects defined in the rest of this manual, (tuples, lists, strings, numeric
or boolean values ...), are elements in the set of trees and any Prolog III
variable represents a value taken from this set.
68 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
maple
<> leaves
7 1'
Trees whose initial label is an identifier are called factual trees, and those
whose initial label is the sign <> are called tuples. Tuples in which all the
elements are characters are called character strings.
Operations on trees
© PrologIA 69
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
x (x … x ) = x
0 1 n 0
x1 … x
n
x0 … xn
x0 ( <> ) = x
0
x1 … x x … x
n 1 n
The general tree constructor can be used to represent any tree using just its
initial label and the tuple formed by its immediate sons.
Here are some examples of how to use these constructors. We give several
possible syntactic forms which use the various constructors, and the
corresponding trees:
70 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
example(1,2,3) example
example[<1,2,3>]
1 2 3
<1,2,3> <>
<>(1,2,3)
<>[<1,2,3>]
1 2 3
example(<1,2,3>) example
example[<<1,2,3>>]
<>
1 2 3
"123" <>
<>(`1`,`2`,`3`)
<>["123"]
<>[<`1`,`2`,`3`>]
`1` `2` `3`
© PrologIA 71
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
Constraints on trees
• equality (=),
• inequality (#),
• the unary relations which constrain a tree to have a determined
number of immediate sons. If this tree is represented by the variable
A and the number of its sons by N, this relation is written A::N
Examples
{X = Maple("acer",leaves(lobes(7),deciduous(1')))}
This constraint constrains the variable X to represent the tree given in the
previous example.
{X = E[U],Y = E[V]}
This set of constraints constrains the variables X and Y to represent two trees
whose initial labels are equal.
{X = E[U], E # <>}
The following are examples of executions which illustrate how this type of
constraint is used:
72 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
The following examples clearly show how certain equations on trees are
simplified:
Finally, these examples show constraints whose solutions are infinite trees:
© PrologIA 73
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
3 . Tuples
A tuple is any tree whose initial label is <>. This first definition enables
tuples to be considered as finite sequences of trees. In passing, we note that
this finite feature refers to the number of elements (not their depth), and
that the sequence characteristic results in these elements having an order
(tuples are not sets). We will often refer to the number of sons of a tuple as
size.
Operation
74 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
x1 … xn y1 … ym x1 …xn y1 …ym
Relations
{ U.V.W = <E>.Z,
U :: 4, V :: 2 }
The size of any tuple appearing in the left-hand member of a concatenation operation
must be explicitly known.
© PrologIA 75
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
{<1,2,3>.V = Z}
{<E>.U = V}
{U.<E,F>.V = W, U :: 4}
The reader will no doubt have noted from these examples that in any
concatenation, the sizes of the left-hand operands are known.
Now, here are some executions of this type of constraint, showing the set of
corresponding solutions:
To summarize, here are all the operations and relations which can be used
on trees and tuples:
76 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
operations
relations
equality x = y
inequality x # y
size x :: n
operations
concatenation u.v
relations
equality u = v
inequality u # v
size u :: n
type u !tuple
The predefined rules that concern tuple size divide into two classes, as will
often be the case: rules that cause delay and rules that don't. A detailed
© PrologIA 77
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
description with examples can be found in the chapter "Predefined rules and
external procedures".
arg3(N,T1,T2). This primitive sets the constraint {T2 = N'}, where N'
is the n-th argument of the tuple T1. If N is zero, T2 is equal to the initial
label of T1 i.e. <>. Fails if N is not a known positive integer, or if T1 is not a
tuple.
78 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
Miscellaneous
arg(N,T1,T2). This primitive sets the constraint {T2 = N'}, where N' is
the n-th argument of the term T1. If N is zero, T2 is equal to the initial label
of T1 . In particular, if T1 is a tuple T2 represents the n-th element of this
tuple. Fails if N is not a known positive integer.
split(U,L). Sets the constraint {L = L'}, where L' is the list consisting
of the elements which form the tuple U (please refer to the rest of this
chapter concerning lists). Fails if the tuple U is not completely known at
execution.
is_tuple(U). Checks that the term U represents a tuple; i.e. that the
constraint {U !tuple} belongs to the current system. Fails in all other
cases.
First of all here is the standard Prolog program, except that tuples are used
instead of lists. This is an opportunity to note how a tuple is expressed in
the "standard Prolog" manner (a head-of-list, tail-of-list pair), using
concatenation. In this case, it is clear that the relationship between the E.L
of Prolog II and the <E>.L of Prolog III is purely functional, since the
© PrologIA 79
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
naive_reverse(<>,<>) -> ;
naive_reverse(<E>.X,X') ->
naive_reverse(X,X'')
conc(X'',<E>,X') ;
conc(<>,X,X) -> ;
conc(<E>.X,Y,<E>.Z) ->
conc(X,Y,Z) ;
Now here is the same program, this time using Prolog III concatenation.
The bound_conc predicate installs the constraint {X' = X''.<E>} after
the execution of naive_reverse . We are then certain to know the size of
the tuple X''. Therefore, no delay is installed. This is a much more efficient
method than the first one, in that Prolog III concatenation is far superior to
the conc predicate described in the previous program.
naive_reverse(<>,<>) -> ;
naive_reverse(<E>.X,X'.<E>) ->
naive_reverse(X,X') ;
80 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
5 . Lists
For reasons of efficiency, and although the binary operator used for lists in
standard Prolog can easily be replaced by a concatenation, Prolog III enables
"standard" lists to be used, constructed using the pointed pair concept, by
means of a binary functional symbol represented by [].
There are no operations defined on Prolog III lists other than those
concerning trees, and therefore no particular constraints are applicable. It
will sometimes be possible to make maximum use of this type of structure in
programs without concatentation, in order to improve performance.
© PrologIA 81
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
You may be asking yourself, quite rightly, what is the exact status
of the double symbol [] which denotes the empty list. The
{ answer is that it is an identifier, which strictly speaking should be
written in quote marks, but for which they can in fact be omitted.
The notations [] and ' [ ] ' (and even s y s : [ ] ) are thus
equivalent.
> is_ident([]);
{}
List primitives
82 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
6 . Strings
As we have already mentioned, Prolog III character strings are tuples whose
elements are all characters. The concatenation operation can therefore be
applied to them, as can the unary and binary relations used on tuples.
Primitives on strings
We should also note that a certain number of predefined rules and built-in
predicates concern character strings. For more detail, please refer to the
chapter Predefined rules and external procedures.
String manipulations
© PrologIA 83
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
String conversions
string_ident(P,S,I) :
• If I is known, sets the set of constraints {S = S',P = P'} where S' is a
string consisting of the characters in the abbreviated representation of the
identifier I , and P' is a string consisting of the characters forming the
prefix of the identifier I.
• If S and P are known, sets the set of constraints {I = I'}, where I' is an
identifier consisting of the characters in the string representing its prefix
P, and of the string representing its abbreviated notation , S.
string_integer(S,N) :
• If S is known, sets the set of constraints {N = S'}where S' is an integer
formed by the characters of the string S.
• If N is known, sets the set of constraints {S = N'}, where N' is a string
formed by the characters which constitute the integer I.
string_real(S,F) :
• If S is known, sets the set of constraints {F = S'} where S' is a floating
number formed from the characters of the string S.
• If F is known, sets the set of constraints {S = F'}, where F' is a string
formed from the characters that constitute the floating number F.
string_bool(S,B) :
• If S is known, sets the set of constraints {B = S'} where S' is a boolean
formed from the characters of string S.
• If B is known, sets the set of constraints {S = B'}, where B' is a string
formed from the characters that constitute the boolean B.
84 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
Miscellaneous
7 . Examples
The following program searches for leaves different from <> in a tree. Here
we are making use of the power of the general tree construction operator,
and of delayed constraints.
leaves(<>,<>) ->;
leaves(A[<>], <A>) ->, {A#<>};
leaves(A[<U>.V], X.Y) ->
leaves(U, X)
leaves(V, Y);
> leaves(Maple("acer",leaves(lobes(7),
deciduous(1'))), L);
{ L = "acer".<7,1'> }
>
© PrologIA 85
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
Quick sort
Here is a recursive sort program, the “quick sort”, which uses constraints on
tuples. The algorithm used is as follows: to sort a tuple consisting of
numbers an element is chosen, the tuple is divided in two; the first tuple
contains elements less than or equal to the chosen element, the second tuple
elements strictly greater. The algorithm is then applied recursively to the
two tuples thus formed until the empty tuple is attained.
The choice of element can be made in several ways. Here we have decided
to choose the element located in the middle of the tuple, in order to highlight
the direct access.
sort(<>,<>) -> ;
sort(L,U.<X>.V) ->
partition(L,X,U',V')
sort(U',U)
sort(V',V);
partition(L,X,U',V') ->
trunc(N/2,N')
regroup(X,L',U',V'),
{ L :: N,
U :: N',
L = U.<X>.V,
L' = U.V};
regroup(X,<>,<>,<>) ->;
regroup(X,<X'>.L,<X'>.U,V) ->
regroup(X,L,U,V),
{ X' <= X};
regroup(X,<X'>.L,U,<X'>.V) ->
regroup(X,L,U,V),
{ X' > X};
> sort(<6,5,4,3,2,1>,L>);
{ L = <1,2,3,4,5,6> }
>
86 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
It is also possible to search for the tuples which once sorted give a known
tuple. For example:
> sort(L,<1,2,3>) { L :: 3 };
{ L = <1,2,3> }
{ L = <1,3,2> }
{ L = <2,1,3> }
{ L = <2,3,1> }
{ L = <3,2,1> }
{ L = <3,1,2> }
>
Finally, a tuple can be sorted whose elements are unknown but which have
a known order:
> sort(<X,Y,Z>,L),{Z>Y>=X};
{ Y = X + X1, Z = X + X2 + X1,
L = <X,X + X1,X + X2 + X1>,
X1 >= 0 ,
X2 > 0 }
>
A periodic sequence
The aim of this program is show that the sequence defined by:
X i+2 = |Xi+1| - Xi
© PrologIA 87
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
Sequence(<Y,X>) ->;
Sequence(<Y'-X,Y,X>.U) ->
Sequence(<Y,X>.U)
Absolute_value(Y,Y');
Absolute_value(Y,Y) -> , { Y >= 0 };
Absolute_value(Y,-Y) -> , { Y < 0 };
What are the 11 element tuples described by this program such that the
tuple formed by the first two elements is different from the tuple formed by
the last two elements? Here is this query:
> Sequence(U.V.W) ,
{U :: 2, V :: 7, W :: 2, U # W};
>
The query fails, signifying that the set of solutions is empty, thus proving the
property. Pretty neat!
Eratosthene's sieve
This program, which calculates prime numbers less than an integer N, can be
written more efficiently without using arithmetic on the tuple sizes.
However it is an excellent example of how to handle tuples and
concatenation. Here is the program:
88 © PrologIA
Prolog
Aociation
HERITAGE
Trees, tuples, strings and lists
prime_numbers(<1'>.Z) ->
sieves(2, X, Z),
{Z :: N, X :: N, X.<1'> = <1'>.X};
To construct a tuple formed from the boolean values in which the rank of
any element equal to 1' is a prime number, the following method is used
(sieves predicate). For a given element and a given number N (starting
with 2 and initializing the tuple so that all the elements are equal to 1'), if its
value is 0', it is sent back, otherwise 1' is sent back and all elements that are
multiples of N simply by stepping (i.e. using concatenation) are unified with
0'. This last operation is performed by the sieve predicate.
Here is an execution:
ststs
© PrologIA 89
Prolog
Trees, tuples strings and lists Aociation
HERITAGE
90 © PrologIA
Aociation Prolog
HERITAGE
Numeric constraints
1. Introduction
2. General definitions
- Numbers
- Numeric expressions
- Relations
- Numeric constraints
- Examples of numeric constraints
- Restrictions
- Normal form
3. Predefined rules and specific external procedures
4. Delaying non-linear constraints
5. Input-Output formats
6. Example programs
- Banking calculation
- Crypto-arithmetic
- Filling a rectangle with squares
Of all the different domains to which constraints can be applied in Prolog III, the
numeric domain already promises to be the one providing the most applications.
This is because Prolog III makes it possible to solve equation and inequation systems
on rational and real numbers, thus enabling logic programming to solve problems in
the areas of planning, scheduling, networks, financial analysis, etc. In this chapter
we take the opportunity to develop examples from these areas, having first explained
the various possibilities offered by the language with regard to this type of
constraint. This explanation ranges from a syntactic description of numeric systems
to the use of certain specific built-in predicates.
HERITAGE
1 . Introduction
2 . General definitions
Numbers
Prolog III numeric constraints apply to two types of object: rational numbers
and floating numbers.
92 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
© PrologIA 93
Prolog
Numeric constraints Aociation
HERITAGE
The following points indicate the correct way to view the sets of numbers
processed by Prolog III:
Numeric expressions
Numeric constants
In Prolog III there are two types of numeric constant: positive or zero
integers, and positive or zero floating numbers.
94 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
0
1
2
1789
815915283247897734345611269596115894272000000000 1
Examples :
12.345
0.5
1.2E12
0.888e87
The exact syntax for floating numbers is given in the chapter devoted to
syntax.
Numeric operators
+ : unary plus
- : unary minus
+ : addition
- : subtraction
/ : division
* : multiplication
1 The attentive reader will have recognized here the result of 40!
© PrologIA 95
Prolog
Numeric constraints Aociation
HERITAGE
First of all we should note that the unary plus and minus operators have the
same order of priority as the binary plus and minus operators. If the order
of priorities is equal, the left-hand operator has priority.
Example:
Below are some correct numeric expressions (for the exact numeric
expression syntax, please refer to the Syntax chapter):
(1) 1993/1989
(2) +X
(3) (3/2)X
(4) 2X+5Y
(5) 3/2-X+7.02
(6) X+2Y/Z
(7) 2(X)
96 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
(8) X2
(9) 3+-X
(10) 3 / 2 X
(11) X = 2Y+1
(7) is a correct term representing a tree labeled by the value 2 and whose
only son is represented by the variable X. Under no circumstances therefore
is this a numeric expression.
(8) is a term formed by a single identifier variable X2, and is not the product
of the variable X by the value 2.
© PrologIA 97
Prolog
Numeric constraints Aociation
HERITAGE
Relations
In the numeric part of Prolog III, two types of relation exist: unary relations
which are used to specify the numeric character of certain trees, which in
practical terms can be assimilated to formulating type constraints; and
binary relations which are used to consruct actual numeric constraints.
Below we list the different relations which can be used to construct numeric
constraints.
Unary relations.
Binary relations.
= : equality
# : inequality
< : strictly less than
> : strictly greater than
<= : less than or equal to
>= : greater than or equal to
Numeric constraints
98 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
• 2X-3 = 0
• X+5 = 3*(2X-1)+2
• X # 1+Y
• X > Y
Restrictions
© PrologIA 99
Prolog
Numeric constraints Aociation
HERITAGE
Normal form
The equations
First we will examine the normal form used to encode the equations. In a
case of equality between numeric expressions, one variable is given priority
(it will be a variable whose general domain of possible values encompasses
the general domain of possible values of the other variables. The order of
variable priority is: tree type, non constrained numeric, numeric constrained
to represent a positive or zero integer). This variable is then expressed
according to the other variables (if there are several possible variables the
choice is arbitrary, or more precisely it cannot be controlled by the user).
> { 1X = (1/2)Y+2Z-4 };
{ Z = -(1/4)Y+(1/2)X+2 }
> { X = (1/2)Y+2Z-4 };
{ X = 2Z+(1/2)Y-4 }
100 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
In the second example, X is any tree type variable, and the two variables Y
and Z are non-constrained numeric variables.
Inequations
Once this transformation has been performed, the equation constraint, is put
into normal form, as shown above.
Here are two examples of linear constraints, and the form given as output
by the interpreter:
The step variables created by Prolog III have been renamed, for increased
clarity.
© PrologIA 101
Prolog
Numeric constraints Aociation
HERITAGE
enum(N)
This predefined rule is used to enumerate all the integer values that the term
N can take in the domain of variables defined by the current set of
constraints. This predefined rule can be used to create programs which use
integers. The basic principle of course is to constrain the term we are
interested in as completely as possible, in order to minimize the number of
enumerated values.
max_value(R1,R2)
min_value(R1,R2)
102 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
Type verification
Miscellaneous
trunc(R, N) sets the constraint {N = R'}, where R' is the integer part of
the number R. Fails if R is not a known numeric value.
© PrologIA 103
Prolog
Numeric constraints Aociation
HERITAGE
Here is an example:
In the first case, when the set of constraints linked to the only rule which can
be applied to answer the query is processed, it is a linear set. The simple fact
that the value of Z is known suffices to create this condition. An answer is
thus obtained which provides the only values for X and Y which satisfy this
linear system of two equations with two unknowns.
However, in the second case the number of known values is not sufficient to
make the system linear, and the answer provided by Prolog III gives some
information about the variables frozen when this constraint is delayed. For
more details about this type of delay, please refer to the chapter "Delay
Techniques".
104 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
5 . Input-Output formats
The numbers used in Prolog III divide into two classes as we have seen:
perfect precision rationals and floating numbers. To improve ease of use
Prolog III allows a number of possible output formats. These formats are set
using the external procedure set_config(S,T).
6 . Example programs
Banking calculation
© PrologIA 105
Prolog
Numeric constraints Aociation
HERITAGE
instalments_capital(<>, 0) ->;
instalments_capital(<I>.X, C) ->
instalments_capital(X, C+(10/100)C-I);
The first rule expresses the fact that it is not necessary to pay instalments to
repay zero capital. The second rule expresses the fact that the sequence of
n+1 instalments to repay capital C consists of an instalment I and a
sequence X of N instalments to repay capital C increased by 10% interest, but
the whole reduced by instalment I .
This program can be used in different ways. One of the most spectacular is
to ask what value of i is required to have the sequence of instalments
<i,2i,3i> repay 1000F. All you need to do is write the query
> instalments_capital(<I,2I,3I>,1000);
{ I = 207 + 413/641 }
>
Crypto-arithmetic
We also bring into play the built-in predicate enum(X) which enumerates all
the integers X satisfying the accumulated constraints. In fact, the program is
completely deterministic until we call this predicate.
106 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
solution(I,J,K) ->
all_different_digits(<S,E,N,D,M,O,R,Y>)
all_integers(<M,S,O,E,N,R,D,Y>),
{ S # 0,M # 0,
I = 1000S+100E+10N+D,
J = 1000M+100O+10R+E,
K = 10000M+1000O+100N+10E+Y,
I+J = K};
all_integers(<>) ->;
all_integers(<X>.S) ->
enum(X)
all_integers(S);
all_different_digits(<>) ->;
all_different_digits(<X>.S) ->
outsideof(X,S)
all_different_digits(S),
{0 <= X,X <= 9};
outsideof(X,<>) ->;
outsideof(X,<Y>.S) -> outsideof(X,S),{X # Y};
> solution(I,J,K);
{ I=9567, J=1085, K=10652 }
>
© PrologIA 107
Prolog
Numeric constraints Aociation
HERITAGE
9 10
14
1 4
8 7
32
15 18
33
16
28 25
7 9
5
61 2
33 36
69
We will use a to denote the ratio between the length of the longest side of
the rectangle, and the length of its shortest side. Obviously, we can suppose
that the length of the shortest side is 1, and therefore that the length of the
longest side is a. Thus, we have to fill a rectangle having the size 1 a with
N squares, all of them different. This will be done by successively placing
each square in the lowest possible position, and if the height is equal, as far
to the left as possible. If we refer to the diagram below, the basis of the
filling algorithm will consist of:
108 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
Zones A and B will be filled recursively in the same way: a square is placed in
the lower left-hand corner and the two sub-zones are filled.
1 A
The zones and sub-zones are separated by jagged lines joining the right-
hand upper corner of the squares to the right-hand upper corner of the
rectangle. These jagged lines never descend and if it is possible to plot
several to join two points, we always consider the lowest one. For example,
here are the separation lines corresponding to the first solution to the
problem when N = 9 :
© PrologIA 109
Prolog
Numeric constraints Aociation
HERITAGE
To be more precise a zone or sub-zone has the form of the left hand
diagram below, while the whole of the rectangle is itself assimilated to the
particular zone drawn to the right
L'
Q P Q
L'
v 0 , h 1 , v 1 , ... , h n , v n ,
where vi denotes the length of the vertical segments, and hi the length of a
horizontal segment. The hi's are always strictly positive. The vi's are either
zero or positive to denote ascending segments, or negative to denote
descending segments. The vi's of the upper lines are never negative, and if
a zone is not empty only the first vertical segment v 0 of its lower line is
negative.
110 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
fill_zone(L,L',C,C')
which fills a zone having a lower boundary L with squares, and calculates its
upper limit L'. The squares are taken from the beginning of the list C and
C' is the list of remaining squares. This procedure calls the procedure
place_square(b,L,L')
which places a square with dimensions bb in the lower left-hand corner of
the zone to fill. Here L denotes the lower line of the zone, but from which
the first vertical segment has been removed, while L' denotes the line
descending from the upper right-hand corner of the square to join and be
prolonged by the rest of line L. The figure below shows the three possible
cases. Either the square overlaps on the first step which was in fact a false
step of zero height, or the square is flush against the first square, or the
square is not big enough to touch the first step.
L'
L'
L'
L L L
© PrologIA 111
Prolog
Numeric constraints Aociation
HERITAGE
fill_rectangle(A, C) ->
create_squares(C)
fill_zone(<-1, A, 1>, L, C, <>),
{A >= 1};
create_squares(<>) ->;
create_squares(<B>.C) ->
create_squares(C)
make_distinct(B, C),
{B > 0};
112 © PrologIA
Prolog
Aociation
HERITAGE
Numeric constraints
upper boundary of this zone is unknown at the start, but given that this line
must join two points which are at the same height and that it cannot
descend, it must be a horizontal line represented by a jagged line in which all
the steps have zero height. If we write the query :
{ a = 33/32,
C = <15/32,9/16,1/4,7/32,1/8,7/16,1/32,5/16,9/32> }
{ a = 69/61,
C =
<33/61,36/61,28/61,5/61,2/61,9/61,25/61,7/61,16/61>
}
ststs
© PrologIA 113
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Boolean constraints
1. Introduction
2. Some definitions and remarks
- Boolean expressions
- Boolean operator priorities
- Boolean constraints
- Important remarks
- Sets of boolean constraints
- Examples of boolean constraints
- Normal conjunctive form
- Boolean assignments
- Solution of a set of boolean constraints
- Simplifying constraint systems
- Specific predefined rules
3. Some simple example programs
- An or on two variables
- An or on a list
- At least one true
- K true elements in a list of booleans
4. Other examples
- Faults in a binary adder
- A logic puzzle
This chapter is devoted to boolean constraints and how they are used. The aim is to
remain accessible to the reader who is a newcomer to Boolean algebra and
propositional calculus. and boolean constraints are thus introduced via their
syntactic representation, although we then go on to tackle problems such as output
representation and the normal form. The chapter continues with an examination of
various examples whose levels of difficulty gradually increase, ending with an
example which is virtually a small application for fault diagnosis in a logic circuit.
HERITAGE
1 . Introduction
The boolean domain is one of the domains which Prolog III constraints can
be applied to. The constants, operations and relations defined within it can
be used to express all the formulæ of propositional calculus, and thus result
in an expressive power which is considerably greater than that offered by
Horn clauses or production rules. In this domain, we are thus in a position
to process disjunction and negation with precision.
However, there is a price to pay for this power. The algorithms that solve
boolean constraints are exponential. Certain difficulties may therefore be
encountered (execution times that are too long, even inacceptable) when the
set of boolean equations to process becomes too complex. In order to
improve this state of affairs, apart from the efforts that will be made to
improve the algorithms in future versions, it will often be possible to reduce
execution times, sometimes dramatically, by adopting special programming
techniques. That is why in this chapter we give programming advice with a
view to minimizing calculation times.
This section starts with a recap of what boolean expressions are in Prolog III,
before returning to the concepts of assignment and solution of a set of
boolean constraints. The section ends with a presentation of simplifications
and more exactly of equivalence on a sub-set of variables, a concept which
we will frequently encounter from now on.
116 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
Boolean expressions
~(f) ,
(f) | (g),
(f) (g),
(f) => (g),
(f) <=> (g), are boolean expressions
It is clear from the above that any boolean expression is a Prolog III term. .
© PrologIA 117
Prolog
Boolean constraints Aociation
HERITAGE
Examples :
• (~(a)|b)<=>(c&~(d)) is written more simply: ~a|b <=> c&~d
• (a|(b|c))|(~(d) is written more simply: a|b|c|~d
Boolean constraints
= (equals)
# (different)
=> (implies)
b !boolt
b !bool
118 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
Important remarks
1 In passing, it is worth noting that the expression b|~b always has the value 1'.
2 The expression b|0', like b1' always has the same value as b.
3 The constraint 0' => b is also always verified, for any value of b.
© PrologIA 119
Prolog
Boolean constraints Aociation
HERITAGE
As we have already seen, boolean constraint systems are sets in which all the
constraints must be verified simultaneously. However, we should note that
several different notations are often possible, since the implicit and connector
that links these constraints can appear as an explicit operator in an
equivalent constraint.
For example, the following notations are equivalent:
a | ~a = 1'
This constraint is always verified but constrains a to represent a
boolean value. Equivalent sets of constraints:
{0' => a},{a = (~x)[<>]},{a # ~a}, …
120 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
(a<=>b)&(b<=>c) = 1'
This constraint sets an equivalence between three boolean variables.
Equivalent sets of constraints:
{a!boolt,a::0,a=b,a=c},
{a=>b,b=>c,c=>a}, …
Below is a summary table of the operations and relations that can be used
with Boolean algebra.
Operations Relations
Used to construct Used to construct
boolean expressions boolean constraints
~ not = equals
& and # different
| or => implies
=> implies
< = > equivalent
The first is linked to the fact that the efficiency of the solving mechanism is
all the greater because the transformations to be performed for encoding
are minimal, since these transformations are extremely costly. The second
© PrologIA 121
Prolog
Boolean constraints Aociation
HERITAGE
concerns output, which in the case of boolean constraints is all printed in this
normal form.
where the li's and the l'j's are literals i.e. formulæ of the type v or not(v),
where v belongs to the set of variables V.
{(a&b&c)|(a'&b'&c')|(a''&b'')}
The output, including the display of the constraints associated with the rules
encoded by the interpreter, is displayed in the form of clauses which comply
with the following conventions:
122 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
• If all the literals are positive (in the form li), the following is written:
l1 | l2 |… | ln = 1'
• If all the literals are negative (in the form ~li), the following is written:
l1 l2 … ln = 0'
• If some literals are negative (in the form ~li) and others are positive (in
the form l'j ), the following is written:
l1… ln => l1 |… | lp
In order to visualize how these clauses are formed, we can examine the
following query and its answer:
Here are some other examples of how sets of constraints are put into
normal conjunctive form, which you can also test on your interpreter:
Boolean assignments
© PrologIA 123
Prolog
Boolean constraints Aociation
HERITAGE
• 0'/X = 0'
• 1'/X = 1'
• v/X = 1' if v:=1' X, v/X = 0' if v:=0' X
• ~f/X = 0' if f/X = 1', ~f/X = 1' else
• (f|g)/ X = 0' si f/X=0' et g/X = 0'(f|g)/ X = 1' else
• (fg)/X = 1' si f/X=1' et g/X = 1'(fg)/ X = 0' else
• (f=> g) /X = 0' si f/X = 1 et g/X, = 1', (f<=> g) /X = 0' else
• (f<=> g) /X = 1' si f/X = g/X, (f<=> g) /X = 0' else
Of course these values correspond to those given in the usual truth tables for
the operations in question.
Examples :
124 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
As regards the first aspect, Prolog III does not remove all the
redundancies in the boolean constraints, but nevertheless ensures that each
time the possible domain of values for a variable is reduced to one element,
the corresponding equation appears in the constraint system. For example,
let us examine the following query and the answer provided by the
interpreter:
The variable c is constrained to represent the value 1' in all the solutions of
the initial system. The equation is therefore produced and the set of
constraints is simplified, by replacing c with 1' in each constraint of the
query.
© PrologIA 125
Prolog
Boolean constraints Aociation
HERITAGE
126 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
There are few predefined rules specific to booleans Below is a concise list
(these rules can also be found in the chapter devoted to predefined rules and
built-in predicates in Prolog III).
© PrologIA 127
Prolog
Boolean constraints Aociation
HERITAGE
In this section we examine some Prolog III programs which use boolean
constraints
An or on two variables
> SimpleOr(1',0',b);
{ b = 1'}
>
> SimpleOr(b1,0',b);
{ b => b1,
b1 => b }
>
The result of or applied to false and to a variable is the value of this variable
(here equality is represented by a double implication).
128 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
> SimpleOr(b1,b2,0');
{ b1 = 0',
b2 = 0' }
>
An or on a list
The stop rule states there is not at least one true element in the empty list (of
course there are none). The other rule proceeds recursively, by calculating
the or on the list head and on the or of the list tail.
> Or(<1',b1,0'>,1');
{ b1 !bool }
>
Since the list already comprises one element whose value is true, no
constraint applies to b1, apart from the fact that b1 must represent a boolean
value.
© PrologIA 129
Prolog
Boolean constraints Aociation
HERITAGE
> Or(<b1,b1,b1>,1');
{ b1 = 1'}
>
> Or(<b1,b2,b3>,b);
{ b => b1|b2|b3,
b1 => b,
b2 => b,
b3 => b }
>
Since all the values remain variables, the equivalent constraint system
expresses equality between the value of b and that of the or of the elements
in the list.
This complicates the problem somewhat. This time we want to only have
one true variable in a list.
The writing of this predicate is not really a trivial matter, since there is no
immediate correspondance between the value of at most one true on the list
having the head b1 and the tail L, and the value of the list L.
130 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
Either the list head is true and the or of the list tail must be false, or the value
of the list head is false and there must be at most one true element in the list tail.
We can thus propose a first solution in the following form:
AtMostOneTrue(<>,1')->;
AtMostOneTrue(<b1>.L, b)->
Or(L,b2)
AtMostOneTrue(L,b3)
{ b = (b1&~b2) | (~b1&b3) };
> AtMostOneTrue(<1',b2,b3>,1');
{ b2 = 0', b3 = 0'}
> AtMostOneTrue(<b1,0',b2>,b);
{ b&b1&b2 = 0',
b|b1 = 1',
b|b2 = 1' }
>
This program can also be written without sending back the value of the
expression, enabling it to be optimized. To do this the problem is considered
in the following way: to have at most one true element in a list having the
head b1 and the tail L, the first constraint to verify is that the and of the head
and of the or of the list is false. However this constraint must also apply
© PrologIA 131
Prolog
Boolean constraints Aociation
HERITAGE
recursively to each of the lists from which the head of the previous one has
been removed.
{
b1 & (b2|b3|b4|b5) = 0'
b2 & (b3|b4|b5) = 0'
b3 & (b4|b5) = 0'
b4 & b5 = 0'
}
> AtMostOneTrue(<1',b2,b3>);
{ b2 = 0', b3 = 0' }
> AtMostOneTrue(<b1,0',b2>);
{ b1&b2 = 0' }
>
132 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
The idea behind this program is to consider the problem in the following
way:
There are exactly k true elements in a list of booleans having the head b1
and the tail L, if and only if one of the following two propositions is true:
(i) b1 is true and there are exactly k-1 true elements in the list L
(ii) b1 is false and there are exactly k true elements in the list L
> true(2,<X,Y,Z,T>,1');
{ X & Y & Z = 0',
X & Y & T = 0',
X & Z & T = 0',
Y & Z & T = 0',
X | Y | Z = 1',
X | Y | T = 1',
X | Z | T = 1',
Y | Z | T = 1' }
© PrologIA 133
Prolog
Boolean constraints Aociation
HERITAGE
4 . Other examples
134 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
x1 1 u1
3 y1
And 2 Or
x2 And u2
4 5 y2
x3 Xor u3 Xor
Here are the predicates which take account of this hypothesis. The
predicate at_most_one_true , is again used.
at_most_one_true(X) ->
at_most_one_true(X, A);
at_most_one_true(<>, 0') ->;
at_most_one_true(<A>.X, A | B) ->
at_most_one_true(X, B),
{ A & B = 0' };
The following predicate describes the links which unite the faults and input-
output values of the circuit.
circuit(<P1,P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>) ->
at_most_one_true(<P1,P2,P3,P4,P5>)
{ ~P1 => (u1 <=> X1 & X3),
~P2 => (u2 <=> X2 & u3),
~P3 => (Y1 <=> (u1 | u2)),
~P4 => (u3 <=> ~(X1 <=> X3)),
~P5 => (Y2 <=> ~(X2 <=> u3)) };
The constraints describe the fact that if one gate is not faulty then the result it
provides complies with the predictions we are able to make.
© PrologIA 135
Prolog
Boolean constraints Aociation
HERITAGE
This program can be used in two ways: either the circuit is given set input
and output values in order to obtain information about faulty gates, when
available, or we look for the sets of tests required to characterize a fault.
First of all here are two queries which search for a fault:
> circuit(<P1,P2,P3,P4,P5>,<1',1',0'>,<0',1'>);
{ P5=0',P4=1',P3=0',P2=0',P1=0' }
>
> circuit(<P1,P2,P3,P4,P5>,<1',0',1'>,<0',0'>);
{ P5=0',P4=0',P2=0',
P3&P1=0',
P3|P1=1' }
>
Now let's look for the sets of tests required to characterize a given fault. The
first idea we use is to launch the query with unknown input and output, and
leaving one fault at true. Below is such a query, where we are interested in
gate 1.
136 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
> circuit(<1',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>);
{ P2 = 0', P3 = 0',
P4 = 0', P5 = 0',
X3&X2 => Y1|X1,
X2&X1 => Y1|X3,
Y2&X3&X2 => X1,
Y2 => X3|X2|X1,
Y2&X2&X1 => X3,
Y2&X3&X1 => X2,
X2 => Y2|Y1,
X2 => Y2|X3|X1,
X3 => Y2|X2|X1,
X3&X2&X1 => Y2,
X1 => Y2|X3|X2 }
>
Apart from the fact that all the other faults are false, which is a normal
consequence of the predicate AtMostOneTrue, the information provided by
the simplified system is fairly indecipherable. One solution is to enumerate
the solutions of this system by displaying the different sets of data which
enable us to reach this result. To do this we add the following predicates to
the program, which instantiate the boolean variables in a non-deterministic
way.
booleans(<>)->;
booleans(<B>.L)->
boolean(B)
booleans(L);
boolean(0')->;
boolean(1')->;
© PrologIA 137
Prolog
Boolean constraints Aociation
HERITAGE
> circuit(<1',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>)
booleans(<X1,X2,X3,Y1,Y2>);
{ X1 = 0', X2 = 0', X3 = 0', Y1 = 0', Y2 = 0',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 0', X2 = 0', X3 = 0', Y1 = 1', Y2 = 0',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 0', X2 = 0', X3 = 1', Y1 = 0', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 0', X2 = 0', X3 = 1', Y1 = 1', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 0', X2 = 1', X3 = 0', Y1 = 0', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 0', X2 = 1', X3 = 0', Y1 = 1', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 0', X2 = 1', X3 = 1', Y1 = 1', Y2 = 0',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 1', X2 = 0', X3 = 0', Y1 = 0', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 1', X2 = 0', X3 = 0', Y1 = 1', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 1', X2 = 0', X3 = 1', Y1 = 0', Y2 = 0',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 1', X2 = 0', X3 = 1', Y1 = 1', Y2 = 0',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 1', X2 = 1', X3 = 0', Y1 = 1', Y2 = 0',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 1', X2 = 1', X3 = 1', Y1 = 0', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
{ X1 = 1', X2 = 1', X3 = 1', Y1 = 1', Y2 = 1',
P2 = 0', P3 = 0', P4 = 0', P5 = 0' }
>
We thus obtain all the solutions for which gate 1 might be faulty. However
we should note that some of the solutions have a correct result, for example
the first one, and in others the failure of gate 1 is not the only possible fault
(in the tenth solution we again find one of the previous examples in which
one of the gates 1 or 3 was faulty).
The processing must therefore be further refined so that the only sets of
tests obtained are those necessary and sufficient to isolate the fault. To
achieve this we must produce all the solutions such that only gate 1 is faulty.
This problem is not a trivial one. One way of solving it is not to produce
the sets of tests we are interested in, but rather their complements among
the previous solutions. This is done by only retaining those solutions which
verify the constraint system for P1 = 1', and which also verify the system
when P1 = 0'. Here is the corresponding query :
138 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
> circuit(<1',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>)
circuit(<0',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>)
booleans(<X1,X2,X3,Y1,Y2>);
First of all, here is the not predicate, a standard Prolog predicate which
executes if the predicate P cannot execute:
> circuit(<1',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>)
booleans(<X1,X2,X3,Y1,Y2>)
not(circuit(<0',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>));
© PrologIA 139
Prolog
Boolean constraints Aociation
HERITAGE
In this case it will be possible to verify, for each solution of the constraint
system in which P1 is true, that the system constrains P1 to represent the
value 1' (i.e. it is known) after another execution of the predicate circuit
in which we again use the input-output but where the variable P1 is this
time unknown.
> circuit(<1',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>)
booleans(<X1,X2,X3,Y1,Y2>)
circuit(<P1,P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>)
known(P1);
This solution is still not entirely satisfactory. Since the only variables
present in the Circuit predicate are boolean variables, it must be possible to
directly transfer negation onto boolean algebra and to thus process this
negation with perfect precision.
140 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
at_most_one_true(<>,1')->;
at_most_one_true(<B1>.L, B)->
or(L,B2)
at_most_one_true(L,B3)
{ B = (B1&~B2) | (~B1&B3) };
circuit(<P1,P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>,B1&B2) ->
at_most_one_true(<P1,P2,P3,P4,P5>, B1)
{ B2 = (P1|(U1 <=> X1 & X3)) &
(P2|(U2 <=> X2 & U3)) &
(P3|(Y1 <=> (U1 | U2))) &
P4|(U3 <=> ~(X1 <=> X3))) &
(P5 |(Y2 <=> ~(X2 <=> U3))) };
We can now apply negation to the last parameter of circuit and the
query will be written as follows:
A logic puzzle
© PrologIA 141
Prolog
Boolean constraints Aociation
HERITAGE
from these sentences, it is interesting to search for the links that exist
between certain propositions. This example is a typical case in which the
solution sought can only appear in the form of a simplification on a sub-set
of variables from the initial constraint system. Below are the sentences.
1. Any one, fit to be an M.P., who is not always speaking, is a public benefactor.
2. Clear-headed people, who express themselves well, have a good education.
3. A woman, who deserves praise, is one who can keep a secret.
4. People, who benefit the public, but do not use their influence for good purpose, are not fit
to go into Parliament.
5. People, who are worth their weight in gold and who deserve praise, are always
unassuming.
6. Public benefactors, who use their influence for good objects, deserve praise.
7. People, who are unpopular and not worth their weight in gold, never can keep a secret.
8. People, who can talk for ever and are fit to be Members of Parliament, deserve praise.
9. Any one, who can keep a secret and who is unassuming, is a never-to-be-forgotten public
benefactor.
10. A woman, who benefits the public, is always popular.
11. People, who are worth their weight in gold, who never leave off talking, and whom it
is impossible to forget, are just the people whose photographs are in all the shop-
windows.
12. An ill-educated woman, who is not clear-headed, is not fit to go to Parliament.
13. Any, one, who can keep a secret and is not for ever talking, is sure to be unpopular.
14. A clear-headed person, who has influence and uses it for good objects, is a public
benefactor.
15. A public benefactor, who is unassuming, is not the sort of person whose photograph is in
every shop-window.
16. People, who can keep a secret and who who use their influence for good purposes, are
worth their weight in gold.
17. A person, who has no power of expression and who cannot influence others, is certainly
not a woman.
18. People, who are popular and worthy of praise, either are public benefactors ore else
are unassuming.
Here is the program. The first predicate, Possibility , links the boolean
variables used and the propositions present in the above sentences, and sets
the constraints applying to these variables.
142 © PrologIA
Prolog
Aociation
HERITAGE
Boolean constraints
Possibility(<<a,"clear-headed">,
<b,"well-educated">,
<c,"constantly talking">,
<d,"using one's influence for good objects">,
<e,"exhibited in shop-windows">,
<f,"fit to be an M.P.">,
<g,"public benefactors">,
<h,"deserving praise">,
<i,"popular">,
<j,"unassuming">,
<k,"women">,
<l,"never-to-be-forgotten">,
<m,"influential">,
<n,"able to keep a secret">,
<o,"expressing oneself well">,
<p,"worth one's weight in gold">>) ->
{ (f & ~c) => g, (a & o) => b,
(k & h) => n, (g & ~d) => ~f,
(p & h) => j, (g & d) => h,
(~i & ~p) => ~n, (c & f) => h,
(n & j) => (g & l), (k & g) => i,
(p & c & l) => e, (k & ~a & ~ b) => ~f,
(n & ~c) => ~i, (a & m & d) => g,
(g & j) => ~e, (n & d) => p,
(~o & ~m) => ~k, (i & h) => (g | j) };
The rest of the program verifies that the list given as input is a sub-set of the
list given in Possibility . The constraints are then installed and the
algorithm for simplification on a sub-set of variables (see the remarks
concerning this functionality) enable us to view the links between the
variables in the relevant sub-set.
SubPossibility(x) ->
Possibility(y)
SubSet(x,y);
SubSet(<>,y) ->;
SubSet(<e>.x, y) ->
ElementOf(e,y)
SubSet(x,y);
© PrologIA 143
Prolog
Boolean constraints Aociation
HERITAGE
> SubPossibility(<<p,"clear_headed">,
<q,"popular">,
<r,"able to keep a secret">>);
{}
>
The answer is the empty constraint and tells us that according to Lewis
Caroll there is no relation between being "clear-headed", "popular" and "able
to keep a secret".
Now let's see what links unite the propositions "able to keep a secret", "fit to
be an M.P." and "worth one's weight in gold". We write the query shown
below:
> SubPossibility(<
<p,"able to keep a secret">,
<q,"fit to be an M.P.">,
<r,"worth one's weight in gold">>);
{ p & q => r }
>
This time the resulting constraint expresses the fact that someone who is
able to keep a secret and is fit to be an M.P. is worth their weight in gold.
ststs
144 © PrologIA
Aociation Prolog
HERITAGE
Delay techniques
1. Introduction
2. Known terms
- The built-in predicates known, bound and free
3. Delay of goal execution
4. Delayed constraints
- Delayed sizes
- Delayed concatenation
- Delayed numeric constraints
In Prolog III we again encounter the concept of delay in goal execution. To fully
understand this process it is necessary to spend some time explaining exactly what
is meant by a known variable. In addition, a complex constraint delaying process
applies when the basic restrictions on tree sizes, tuple concatenation or linearity of
numeric expressions are not explicitly obeyed. The use of this constraint delaying
process is an exercise which can prove to be very hazardous and in this chapter we
attempt to explain it in detail.
HERITAGE
1 . Introduction
Like Prolog II and Prolog II+, Prolog III enables goal execution to be delayed
while waiting for a term to become known. To understand this concept, it is
necessary to spend some time examining the meaning of the term known.
In addition, certain constraints which do not verify restrictions imposed by
Prolog III are automatically delayed. This chapter proposes a general survey
of these different delay techniques, and a certain number of examples. It
should be borne in mind that the concept of a delayed constraint lies outside
the theoretical framework of Prolog III, providing a tool which although it
may prove to be convenient for the user opens the way to programming
which is full of pitfalls.
2 . Known terms
These terms are often reduced to one variable, and we then refer to them as
known variables.
The following three built-in predicates are directly involved with what we
know about a given term during the execution of a program:
146 © PrologIA
Prolog
Aociation
HERITAGE
Delay techniques
> create(illusion(A),T,U);
{ U = <illusion(A),T> }
>
Since the first parameter is known (the label is known and we know
whether or not the number of sons, equal to one, is zero), the predicate
create' is immediately executed when called.
© PrologIA 147
Prolog
Delay techniques Aociation
HERITAGE
> create(T1,T2,U);
{ T1 = E[X],
E[X] !freeze(create'(E[X],T2,U)) }
>
The intermediate variables created by Prolog III have been renamed for the
sake of readability. Here the first parameter is not known at call time, and
will never be known up to the end of execution of the query. The Prolog III
output indicates that the variable T1, put into normal form by means of the
general tree constructor in the form E[X] remains frozen, and indicates
which is the predicate delayed on this variable.
We can now complicate this example a little and turn to the following two
predicates:
• create_and(T1, T2, U) which delays the creation of the tuple <T1, T2>
until the two terms T1 and T2 are known.
• create_or(T1, T2, U) which delays creation of the tuple <T1, T2> until
one of the two terms T1 and T2 is known.
It should be noted that the predicate create_or can be written in a more subtle
way, so that create' is not executed twice. One way of solving this problem is
shown in the paragraph devoted to delayed numeric constraints.
148 © PrologIA
Prolog
Aociation
HERITAGE
Delay techniques
4 . Delayed constraints
Now that the principle of delay of goal execution has been defined, we can
examine how Prolog III delays certain constraints which do not correspond
to the restrictions imposed by the language. This is the case for:
We will try not to lose sight of the fact that constraints not
complying with the basic Prolog III restrictions lie outside the
theoretical framework of Prolog III, and strictly speaking should
{ not appear in a program. Our desire to facilitate the
programmer's task has led us to allow such constraints and to
define how they are processed.
In these three cases, Prolog III automatically uses a certain type of delay,
which we will now explain.
Delayed sizes
We know (from the chapter "Trees, tuples, lists and strings") that in a size
constraint, the size must be explicitly known, i.e. it must appear in the form
of a positive integer constant. We also know that the predefined rule
bound_size(U, N) enables such a constraint to be set during the execution of a
program, if the value of N is known at the time when an attempt is made to
execute the predicate bound_size. Finally, Prolog III syntax allows us to
write {U :: N} type constraints directly, which seems to be in total
contradiction with the above statements.
In fact, this last type of constraint is a syntax feature. When Prolog III has to
process such a constraint, it first attempts to execute the size(U, N) predicate,
before executing the other goals in the rule containing this constraint.
size(U,N) is a built-in predicate using freeze, bound_size and known_part (for
details of these predicates please refer to the chapter concerning predefined
rules and external procedures).
© PrologIA 149
Prolog
Delay techniques Aociation
HERITAGE
delayed_size(T, N) ->
freeze(T, delayed_size'(T, N))
freeze(N, bound_size(T, N));
delayed_size'(E[<>], O) ->
delayed_size'(E[U], N) ->
known_part(U, U', U'')
bound_size(U', N')
delayed_size(U'', N-N')
{ U # <>, N # 0 };
Here are some simple examples (Prolog III's intermediate variables have
been replaced with more readable names):
> delayed_size(T,N);
{ T = E1[U1], N = E2[U2],
E1[U1] !freeze(delayed_size'(E1[U1],E2[U2])),
E2[U2] !freeze(bound_size(E1[U1],E2[U2])) }
> delayed_size(Arbre[<1,2>.U],N);
{ U !freeze(delayed_size'(U,N-2)),
N !freeze(bound_size(Arbre[<1,2>.U],N)),
N !freeze(bound_size(U,N-2)) }
>
We can now go into a little more detail. In fact Prolog performs a more
complex processing than this simple delay. Let's look at this on an example.
> {U :: N, U :: M, N # M};
>
150 © PrologIA
Prolog
Aociation
HERITAGE
Delay techniques
On a trivial level, the constraint system given as input does not allow any
solution, since no value of N in the interval ]0,1[ is an integer. However, the
delay process does not allow the failure which would have been expected to
occur.
Delayed concatenation
The second restriction concerns concatenation of tuples. The delay of these
constraints occurs when a concatenation has been written in which the size
of the left-hand operand is unknown.
In the same way as for delayed size constraints, we can give a preliminary
satisfactory explanation of the mechanism installed in this case, by writing
the corresponding Prolog III rules. The predefined rule which installs this
delay is conc3(U,V,W). Below is a predicate which will constitute a first
approach to delayed concatenation:
© PrologIA 151
Prolog
Delay techniques Aociation
HERITAGE
delayed_conc(U, V, W) ->
freeze(U, delayed_conc'(U,V,W));
delayed_conc'(<>, V, V) ->;
known_part(U, U', U'')
bound_conc(U', W', W)
delayed_conc(U'', V, W'),
{ U # <> };
As for size constraints, we use any partial information about the start of the
tuple U to unfreeze as much as possible.
delayed_conc2(U, V, W) ->
freeze(U, delayed_conc'(U,V,W))
size(U, N)
size(V, M)
size(W, N+M);
152 © PrologIA
Prolog
Aociation
HERITAGE
Delay techniques
> { U.V = W };
{ W = X,
U :: N1,
U.V = X,
V :: N2,
X :: N2 +N1,
N1 >= 0 ,
N2 >= 0 }
>
> { U :: N,
V :: M,
W :: P
W = U.V,
P # M+N };
>
© PrologIA 153
Prolog
Delay techniques Aociation
HERITAGE
Here are these rules, which reproduce the processing performed by the
predefined rule mult. The rule for delayed division is given for information:
delayed_mult(X, Y, Z)->
freeze(X, delayed_mult'(X, Y, Z, A))
freeze(Y, delayed_mult'(Y, X, Z, A));
delayed_divide(X, Y, Z)->
delayed_mult(Z, Y, X)
{ Y#0 };
154 © PrologIA
Prolog
Aociation
HERITAGE
Delay techniques
non_linear(X,Y,Z,T,V) ->
{Z = X*Y+2T/(X+(3/2)V)};
non_linear(X,Y,Z,T,V) ->
delayed_mult(X,Y,X')
delayed_divide(2T,X+(3/2)V,Y')
{Z = X'+Y'};
© PrologIA 155
Prolog
Delay techniques Aociation
HERITAGE
In fact, the predefined rule is mult which has been renamed so that you can
test out these examples on your interpreter
> non_linear(2,Y,Z,T,3);
{ Y = Y1, T = T1, Z = (4/13)T1+2Y1 }
>
> non_linear(X,3,Z,T,2);
{ X = X', Z = U'+3X', T = T',
X'+3 # 0,
U'*(X'+3) = 2T' }
>
We can also note the limitations of this delay process, which does not
provide any guarantee whatsoever that sets of incoherent non-linear
constraints will be systematically detected.
{ X*X = -2 }
> { X*Y > 0, X > 0 > Y };
{ Y = -Y',
(-Y')*X = U',
X > 0,
Y' > 0,
U' > 0 }
>
156 © PrologIA
Prolog
Aociation
HERITAGE
Delay techniques
ststs
© PrologIA 157
Prolog
Delay techniques Aociation
HERITAGE
158 © PrologIA
Aociation Prolog
HERITAGE
1. Control
2. Expressions, static variables, arrays
3. Structuring, recording
4. Input/Output
5. Other elements of the environment
HERITAGE
1 . Control
At each stage in the execution of a program, the Prolog III interpreter has to
make two choices: first it chooses one goal to execute from a sequence of
goals, and then it chooses the rule which will be used to execute it. In the
chapter entitled "Basic concepts", we gave the model of how a Prolog III
program executes.
(1) ( W, t0 t1 … tn , S )
(2) s0 s1 … s m , R
(3) ( W, s1 … sm t1 … tn , S R { s0 = t0 } )
We then explained how these two choices are made: the chosen goal is
always the first in the sequence of goals to be executed (here t0 ), and the
rules chosen to execute it are all the rules whose "head unifies with the
relevant goal", i.e. the rules s0 s1 … sm , R for which the system S R { s0
= t0 } is solvable. All these rules are examined in the order they were written.
> insert;
greater_than(Jo,Max) -> ;
greater_than(Max,Fred) -> ;
greater_than(x,y) -> g r e a t e r _ t h a n ( x , z )
greater_than(z,y);;
{}
> greater_than(Jo,x);
{ x = Max }
{ x = Fred }
160 © PrologIA
Prolog
Aociation
HERITAGE
The environment
OVERFLOW
>
> insert;
greater_than(Jo,Max) ->;
greater_than(Max,Fred) ->;
greater_than(x,z) ->
greater_than'(x,y) greater_or_less_than(y,z);
greater_or_less_than(x,x) ->;
greater_or_less_than(x,y) -> greater_than(x,y);;
{}
> greater_than(Jo,x);
{ x = Max }
{ x = Fred }
>
Example 2 : This example enumerates all the lists constructed with 1. With
the (incorrect) program above the infinite list should be produced first:
> insert;
list_of_one(<1>.x) -> list_of_one(x);
list_of_one(<>) - > ; ;
{}
> list_of_one(x);
OVERFLOW
>
© PrologIA 161
Prolog
The environment Aociation
HERITAGE
Of course, the right solution is obtained by switching the order of the two
rules:
> insert;
list_of_one(<>) ->;
list_of_one(<1>.x) -> list_of_one(x);;
{}
> list_of_one(x);
{ x = <> }
{ x = <1> }
{ x = <1,1> }
{ x = <1,1,1> }
USER INTERRUPT
The cut « / »
The “/” is a parasite which can only appear in the terms which constitute
the right-hand member of a rule. The remaining rule choices which
execution of “/” deletes are:
• the other rules having the same head as the rule containing “/”
• the other rules which could have been used to execute the terms
between the start of the rule body and the “/”
1 To harmonize with the Edinburgh syntax, the cut can also be written " ! "
162 © PrologIA
Prolog
Aociation
HERITAGE
The environment
> list;
color(red) ->;
color(blue) ->;
size(big) ->;
size(small) ->;
{}
> choice1(u);
{ u=[red,big }
{ u=[red,small }
{ u=[blue,big }
{ u=[blue,small }
{ u="that's all" }
> choice2(u);
{ u=[red,big] }
{ u=[red,small] }
{ u=[blue,big] }
{ u=[blue,small] }
> choice3(u);
{ u=[red,big] }
{ u=[red,small] }
> choice4(u);
{ u=[red,big] }
> choice1(u) / ;
{ u=[red,big] }
>
© PrologIA 163
Prolog
The environment Aociation
HERITAGE
« If then else »
if_then_else(p,a,b) -> p / a;
if_then_else(p,a,b) -> b;
« not »
not(p) -> p / fail;
not(p) ->;
In the case of not shown below, it should be noted that unexpected results
may be obtained if p contains free variables. This is shown by the following
example:
> list;
man(Abelard) -> ;
woman(x) -> not(man(x));
> woman(Abelard);
> woman(Eloise);
{}
> woman(x) eq(x,Eloise);
>
In addition:
- the label mentioned above is any Prolog III term, and it is assumed that
for two terms to represent the same label concerning the block_exit
mechanism, it is necessary and sufficient that they be unifiable.
164 © PrologIA
Prolog
Aociation
HERITAGE
The environment
Interruption
A Prolog program can be interrupted at any time by a specific key,
depending on the system used (for example: <Ctrl-C>). A short dialog then
appears:
User Interrupt by (^C). C(ontinue, K(ill, tT(race, Q(uit ?
The following primitives are additional tools for the control of program
execution.
bound(x)
bound(x) executes if x is bound. A variable is considered to be bound if it is
constrained to represent a tree whose
• initial label is known
• number of sons is known
default(t1, t2)
The predefined rule default is used to perform the following program
control: if t 1 can be executed then it is executed in all possible ways,
otherwise t2 is executed in all possible ways. It should be noted that this
primitive cannot be performed using " / ". Here is an example of how this
rule is used:
© PrologIA 165
Prolog
The environment Aociation
HERITAGE
> list;
reply(p) -> default(p,outml("nobody"));
man(jean) ->;
man(pierre) ->;
{}
> reply(man(x));
{ x=jean }
{ x=pierre }
> reply(woman(x));
nobody
{}
>
free(x)
Only executes if x is not bound; i.e. if the label of the tree represented by x is
not known, and it is not known whether or not the number of sons of x is
zero.
Arithmetical expressions
In Prolog III, the arithmetical operations are integrated into the core of the
language. However, we have maintained the val mechanism from Prolog II
for the sake of compatibility, because in some cases this mechanism is a very
efficient process for evaluating arithmetical expressions, and especially
because it remains the way in which static variables and arrays are handled.
The result of an evaluation performed using the predefined rule val is either
an integer, a real, an identifier or a string. Booleans are represented by the
integers 0 and 1. On most machines, the boundary values for integers are
-2 147 483 648 and 2 147 483 647 (231-1); for floating numbers they are
-1.7e38* and +1.7e38* and the greatest negative value and smallest positive
value are -0.29e-38* and +0.29e-38* respectively. Values strictly between
these two values are set to 0.
166 © PrologIA
Prolog
Aociation
HERITAGE
The environment
val(t1, t2)
Evaluates the expression t1 and produces the result t2. The expression to
evaluate is constructed recursively from constants, static variables (assigned
identifiers), identifiers, array components and evaluable functions.
Ordinary Prolog III variables can appear in an evaluable expression,
provided they are constrained to represent a known value.
Examples:
> val(add(mul(2,add(3,4)),1000),x);
{ x=1014 }
> val(2*(3+4)+1000,x);
{ x=1014 }
>
> {t=add(mul(2,add(3,4)),1000)};
{ t = add(mul(2,add(3,4)),1000) }
> {t=2*(3+4)+1000};
{ t = 1014 }
>
© PrologIA 167
Prolog
The environment Aociation
HERITAGE
> assign(one,1);
{}
> val(one,x) val(two,y);
{ x = 1, y = two }
>
add(t1, t2)
value(add(t1, t2)) = value(t1) + value(t2).
sub(t1, t2)
value(sub(t1, t2)) = value(t1) - value(t2).
mul(t1, t2)
value(mul(t1, t2)) = value(t1) value(t2).
168 © PrologIA
Prolog
Aociation
HERITAGE
The environment
div(t1, t2)
value(t1)
value(div(t1, t2)) =
value(t2)
mod(t1, t2)
value(mod(t1, t2)) = value(t1) modulo value(t2).
This is the modulo from the integer division of the absolute value of t1 by
the absolute value of t2. The values of t1 and t2 must be integers.
eql(t1, t2)
value(eql(t1, t2)) = if value(t1) = value(t2) then 1 else 0.
inf(t1, t2)
value(inf(t1, t2)) = if value(t1) < value (t2) then 1 else 0.
The values of t1 and t2 must be constants of the same type. For integers and
reals, the "<" relation is taken between numbers. For strings lexicographical
order is taken and for identifiers the lexicographical order of the associated
strings is taken.
infe(t1, t2)
value(infe(t1, t2)) = 1 if value(t1) value (t2) else 0.
The values of t1 and t2 must be constants of the same type. See inf.
sup(t1, t2)
value(sup(t1, t2)) = 1 if value(t1) > value (t2) else 0.
The values of t1 and t2 must be constants of the same type. See inf.
supe(t1, t2)
value(supe(t1, t2)) = 1 if value(t1) value (t2) else 0.
© PrologIA 169
Prolog
The environment Aociation
HERITAGE
The values of t1 and t2 must be constants of the same type. See inf.
trunc(t)
value(trunc(t)) = integer conversion of the value of t
abs(t)
value(abs(t)) = absolute value of value(t).
The following functions give a real result. The trignometric functions use
angles expressed in radians.
atan(t)
value (atan(t)) = tangent arc value(t).
cos(t)
value (cos(t)) = cosine(value(t)).
exp(t)
value (exp(t)) = exponential(value(t)).
ln(t)
value (ln(t)) = napierian logarithm(value(t)).
rad(t)
value (rad(t)) = radian conversion(value(t)).
sin(t)
value(sin(t)) = sine(value(t)).
sqrt(t)
value(sqrt(t)) = square root(value(t)).
170 © PrologIA
Prolog
Aociation
HERITAGE
The environment
tan(t)
value(tan(t)) = tangent(value(t)).
Assignment. Arrays.
assign(i, t)
Assigns the term t which must represent a constant, to the identifier i.
Everything happens as if i becomes the name of a variable which is "global"
(subsequently accessible during execution of any goal), "static" (resists
backtracking) and has the value t. So this is standard assignment, as used in
FORTRAN, Pascal, etc….
Example:
> assign(file_name,"myfile.txt");
{}
> val(file_name,x);
{ x="myfile.txt" }
>
> retract(file_name(x),[]);
> assert(file_name("myfile.txt"),[]);
{}
> file_name(x);
{ x="myfile.txt" }
>
assign(tab(i), t)
Assigns the value of t to the element of rank i in the array tab. This array
must have been previously defined using def_array (see below). The same
restrictions as before apply to t: i.e. it must be a constant. When we want to
obtain the value of an element of rank i in the array, if this element has not
been assigned (assign) or if the value of its rank i is outside the limits of the
array, val produces an error.
© PrologIA 171
Prolog
The environment Aociation
HERITAGE
Example :
> def_array(array,10);
{}
> assign(array(5), five);
{}
> val(array(5), x);
{ x = five }
> val(array(4), x);
Error 246: Error in val
> val(array(11), x);
Error 246: Error in val
>
def_array(i, n)
172 © PrologIA
Prolog
Aociation
HERITAGE
The environment
> insert;
inc(i) -> val(i,x) assign(i,x+1);
dec(i) -> val(i,x) assign(i,x-1);
push(v) ->
val(pointer,p) !
assign(stack(p), v)
inc(pointer)
, { p <= 100 };
push(v) -> outml("stack overflow") fail;
pop(v) ->
dec(pointer)
val(pointer,p) !
val(stack(p),v)
dec(pointer)
, { p >= 1 };
pop(v) -> outml("stack empty") assign(pointer,1) fail;;
{}
> initialize;
{}
> push(111);
{}
> push(222);
{}
> pop(x) pop(y);
{ x=222, y=111 }
> pop(x);
stack empty
>
Up to now all the examples we have given were small Prolog III programs
in which the number of identifiers was very low and easy for the
programmer to cope with. In such circumstances, it can be assumed that all
the identifiers present belong to a single "universe" which contains all of
them. If program size remains reasonable, there is no need to group
together rules and identifiers into functional sets.
© PrologIA 173
Prolog
The environment Aociation
HERITAGE
The method used is thus to paritition the known identifiers of a Prolog III
program. To be brief, the tools used to perform this partitioning can be
summarized as follows:
• the complete identifier syntax stipulates that a prefix is present at the
beginning of every identifier.
• a set of identifiers which has the same prefix is a family. Families can be
manipulated globally; many primitives apply to whole families,
represented by the prefix common to their members.
Identifier families
<prefix>
::= [ <name> { : <name> } ] orbis:lex
<name>
::= <letter> { <extended alphanumeric> }
174 © PrologIA
Prolog
Aociation
HERITAGE
The environment
<identifier>
::= <prefix> : <abbreviated identifier> sys:outm
::= <abbreviated identifier> outm
<abbreviated identifier>
::= <letter> <letter> { <extended alphanumeric> }
A complete identifier always comprises at least one occurrence of the " : "
character whereas an abbreviated identifer never includes an " : ". For
example, the first three identifiers below are complete and the last one is
abbreviated:
grammar:plural
sys:env:screen:clear_screen
:paul
paul
When we say a family corresponds to a given prefix, this refers to the set of
identifiers having this prefix. There is no hierarchy in the families: when a
complete identifier comprises several occurrences of the " : " character only
the last occurrence is considered by Prolog III, as being a separator between
the prefix and abbreviated identifier. The prefix then consists of several
words separated by " : ". Although this corresponds to a hierarchical
organization in the mind of the programmer, no such notion exists for
Prolog III for whom the families associated with prefixes, such as "aa" and
"aa:bb" for example, are not linked.
© PrologIA 175
Prolog
The environment Aociation
HERITAGE
The term module refers to the set of elements of code named by the
identifiers of a given family. By "elements of code" we mean not only the
Prolog III facts and rules which constitute the programs, but also the
evaluable functions, the static variables1 and the arrays.
The family and module concepts are completely dynamic; every new identifier
which is read and if necessary completed by Prolog III is automatically
incorporated into the family corresponding to its prefix. A family is never
fixed; it can be augmented at any time by the addition of new identifiers.
This dynamic aspect is generally very useful, but we will see that when the
reading and writing contexts are defined (see below) a certain stability is also
required so that the conventions defined by a context remain "timeless" as
far as possible, and so that an abbreviated identifier represents the same
complete identifier at any time in a Prolog III session, and from one session
to another.
These considerations create a need for the closed family concept, or rather
for a closed part of a family. Primitives are available (close_context_dictionary)
which fix a "hard core" of the family, equal to the family's state when it is
closed. Following this closure operation, other identifiers can still be added
to the family, but they will not be incorporated into its closed part. This
concept is used in the interpretation of an implicit list which appears in the
primitives used to define reading and writing contexts. In these cases, a
reference to a family only denotes its closed part. This reference is therefore
immovable and stable
176 © PrologIA
Prolog
Aociation
HERITAGE
The environment
A default reading and writing context is defined when Prolog III starts, and
primitives are available which enable you to define your own contexts, to
name them and store them for subsequent recovery etc. One (and only one)
reading and writing context is constantly defined throughout a Prolog III
session; we will call it the current context.
Explicit list and implicit list denote a list L of complete identifiers, by means of
a mechanism explained below. The conventions defined by such a context
are as follows during reading:
© PrologIA 177
Prolog
The environment Aociation
HERITAGE
For example, if the list L is [ aa:bb, aa:cc, aa:dd ] and the default prefix is "zz",
then
- pp:xx is understood as pp:xx, since it is read in its complete form
- cc is understood as aa:cc, since the latter appears in the list L
- xx is understood as zz:xx, since no complete identifier in L has xx as its
abbreviated form.
Now let's deal with the practical details of how reading and writing contexts
are defined in Prolog III programs.
178 © PrologIA
Prolog
Aociation
HERITAGE
The environment
sys:env:context(name,
explicit_sequence, implicit_sequence, default_prefix) -> ;
Note 2. If you define contexts which do not contain the "sys" family in
implicit-sequence, it is essential to be aware that a large number of
abbreviated identifiers lose their usual meaning, and predefined rules
become unknown by their abbreviated name. By far the most serious
problem is that commonly used abbreviated identifiers such as [] (equivalent
to nil in Prolog II) no longer have the complete form used in the predefined
rules which constitute the system library of Prolog III.
Note 3. When a rule contains a context declaration, it only comes into effect
when the rule is executed (not when it is read). In the following example,
the abbreviated identifier peach is completed as def:peach and not fruits:peach,
because the definition of the "new" context will only come into effect when
the apple program is executed.
© PrologIA 179
Prolog
The environment Aociation
HERITAGE
set_context(name)
Used to re-install a previously defined context as the current context. The
name argument must be the identifier or string associated with the relevant
context when it was defined.
close_context_dictionary(s)
Defines the present set of identifiers in the prefix family s as being the closed
part of this family. Identifiers added to this family after execution of this
command will not be automatically incorporated into this closed part.
add_implicit(s1, s2)
Adds the identifier whose abbreviated name is given by the string s2, to the
closed part of the family corresponding to the prefix s1.
remove_implicit(s1, s2)
Removes s2 from s1.
> current_context(t0,t1,t2,t3);
{ t0 = 1, t1 = '[]', t2 = ["sys"], t3 = <> }
> string_ident(p,a,dictionary) outl(sys:dictionary);
dictionary
{ p = "sys", a = "dictionary" }
>
> remove_implicit("sys","dictionary");
{}
180 © PrologIA
Prolog
Aociation
HERITAGE
The environment
Our identifier dictionary no longer belongs to the closed part of the "sys"
family. The behavior of the reading and writing context has changed: when
read, dictionary is completed as :dictionary, since according to the context the
default prefix is the empty string (which can be written "" or <>), whereas
when written, sys:dictionary is not transformed into its abbreviated form.
dictionary
This primitive writes on the current output the abbreviated form of the
accesses, whose prefixes are the same as the default prefix of the reading and
writing context. The term access refers to any identifer which names an
object in the code: rule, fact, static variable or array.
dictionary(L)
Unifies L with the list of prefixes of the user modules present in memory.
dictionary(s0, t0)
Given that s0 is a character string, this primitive unifies t0 with the list of
rules in the family corresponding to the prefix s0. Each rule is represented
by an <access, arity> pair.
Modules
© PrologIA 181
Prolog
The environment Aociation
HERITAGE
A module can exist in the form of text (before reading) or in internal form
(after reading). We will use the terms source module and object module to refer
to these two forms.
module (module-prefix,
explicit-sequence, implicit-sequence, default-prefix);
....
end_module( module-prefix ) ;
The module directive switches Prolog III into insertion mode and end_module
switches it out of this condition. Therefore, the elements enclosed by these
two directives must be rules (or comments, which are ignored).
The argument denoting the module-prefix in the module directive must be the
same as that which appears in the end_module directive, and all the rules
enclosed by these two directives must have an access identifier with this
prefix. This enables any naming errors to be detected during reading.
Basically, we can say that the meaning of the module directive is: " insert the
rules which follow with the reading context defined here, verifying that the rules
read possess (or acquire) the necessary prefix."
If all the arguments are not given, the following default values are applicable
(assuming that due to the reading context of the module directive it does not
have to be written sys:module):
The reading context defined by the heading of the module is used to read all
the remainder of the module, including the end_module directive. The
context which existed before the module was read is then re-established.
If a module m contains a rule with the prefix m and the abbreviated name
ini_module this rule is automatically executed after the module has been read
(or subsequently loaded).
182 © PrologIA
Prolog
Aociation
HERITAGE
The environment
Object module. Once the elements of code which form a module have been
read by Prolog III, they are said to constitute an object module. The
manipulation of object modules only concerns the internal representations
of the identifiers, and the context concept is therefore not involved in these
operations.
assert(t, q)
asserta(t,q)
Add a rule at the start of its group.
t must be a term capable of being a rule head, i.e. a term representing a tree
whose initial node comprises a known label, which is an identifier. q must be
a list of terms. The rule actually added using these primitives comprises an
empty constraint system.
© PrologIA 183
Prolog
The environment Aociation
HERITAGE
assert(conc([e|x],y,[e|z]),[conc(x,y,z)]);
assert(conc([],y,y),[]);
conc([],y,y) ->;
conc([e|x],y,[e|z]) -> conc(x,y,z);
assert''(t, q)
assertz(t, q)
Add a rule at the end of its group.
These two primitives function in the same way as assert, but the rule is
added below the group corresponding to t instead of above. For example,
the following two commands typed in the order indicated produce the
insertion of the same conc program as above:
assert''(conc([],y,y),[]);
assert''(conc([e|x],y,[e|z]),[conc(x,y,z)]);
current_predicate(<i,a>)
Is used to test for the presence of a rule.
This primitive executes successfully if there is a rule with name i and arity a.
If a is a variable and i is unknown it enumerates in succession all the arities of
the rules with name i. If i is a variable, and a is known, it enumerates in
succession all the names of rules with arity a. Finally, if a and i are variables,
this primitive enumerates in sucession all the <i,a> pairs corresponding to
the rules from the module associated with the default prefix of the current
context.
184 © PrologIA
Prolog
Aociation
HERITAGE
The environment
insert
reinsert
Insert rules.
This predefined rule switches the system into a mode in which statements
(rules, comments and directives) read on the current input unit are added to
the current program, in the order they are read. The directives (set_context,
module, etc…) are executed immediately they are encountered. The insert
mode terminates either when an empty statement is found, or when the end
of file is reached.
Example:
> insert;
conc([],y,y) ->;
conc([e|x],y,[e|z]) -> conc(x,y,z);;
{}
>
insert causes an error when a group is read which already exists, whereas
reinsert replaces the previous group with the new definition. But be very
careful; this can be dangerous. For example, when using reinsert, an error
on a rule inside a group can cause all the previous rules to be destroyed
when reading of the group continues.
insert(f)
reinsert(f)
Insert rules from a file.
Function in the same way as insert, but the statements are read on the
indicated file. Depending on whether or not the echo mode has been
activated (see echo rule), the rules are displayed on the console as they are
read.
© PrologIA 185
Prolog
The environment Aociation
HERITAGE
list
Lists on the current output all the rules determined by the default prefix of
the current context.
list(t)
Lists on the current output the group(s) of rules indicated by t, which must
be either a term of the form indicated below, or a list of such terms (c
denotes a character string, i an identifier, a an integer and v a variable):
c All the rules in the module named c.
<i, a> All the rules constituting the group with name i and arity a.
<i, v> All rules whose access is i, regardless of their arity.
<v, a> All the rules of arity a belonging to the module which has the
default prefix of the current reading and writing context
i Equivalent to <i, v>
Example:
> list([<aaa,2>,<aaa,3>,<bbb,X>]);
list(<i,a>, n)
Lists one rule.
predefined(t)
This primitive succeeds if t is a term corresponding to the call of a predefined
rule.
rule(n, a, t, q)
rule(n, t, q)
rule(t, q)
Search for rules corresponding to a given pattern.
186 © PrologIA
Prolog
Aociation
HERITAGE
The environment
> rule(n,conc,t,q);
{ n = 1, t = conc([],x_8,x_8), q = [] }
{ n = 2, t = conc([e_11 | x_11],y_11,[e_11 | z_11]),
q = [conc(x_11,y_11,z_11)] }
> rule(n,conc[v],q);
{ n = 1, v = <[],x_12,x_12>, q = [] }
{ n = 2, v = <[e_15 | x_15],y_15,[e_15 | z_15]>,
q = [conc(x_15,y_15,z_15)] }
>
retract(t, q)
Searches for and deletes rules corresponding to a given pattern.
This primitive searches for all the rules which satisfy the constraints t = rule
head, q = tail body, and deletes them. t must be sufficiently known to
remove any ambiguity concerning the name of the relevant rules.
suppress(i)
suppress(i, a)
suppress(i, a, n)
Delete rules.
© PrologIA 187
Prolog
The environment Aociation
HERITAGE
Example:
> insert;
data(1) ->;
data(2) ->;
data(3) ->;
> data(x);
{ x = 1 }
{ x = 2 }
{ x = 3 }
> suppress(data,1,2);
{}
> data(x);
{ x = 1 }
{ x = 3 }
>
kill_module(s)
Deletes all the rules in the module denoted by the character string s. The
module's arrays are de-allocated and the allocations of the module's
identifiers are cancelled.
reload(f, l)
Loads saved modules.
188 © PrologIA
Prolog
Aociation
HERITAGE
The environment
l is a list in the form [ <pref1 , subs1> , … <prefk , subsk> ] which specifies the
renaming of the loaded modules: pref1 will be replaced by subs 1, pref2 by
subs2, etc… This list may be empty.
save(l, f)
Saves modules.
Example:
> save(["","data","dict"], "myfile.mo");
{}
>
The file produced is a file of object code, which will be subsequently loaded in
another Prolog environment using the command load (see above).
4 . Input / output
At any given moment, the Prolog III system "knows" a certain number of
input/output units. These are the units which have been opened and have
not yet been closed. The descriptors for these units are arranged in a stack;
the unit at the top of the stack is called the current unit. All input/output
operations are performed on the current unit. At start-up an input unit
(called console) and an output unit (also called console) are automatically
opened by the system and are the current units. Usually these units are
associated with the keyboard and screen of the computer or terminal from
which Prolog was started.
© PrologIA 189
Prolog
The environment Aociation
HERITAGE
When a unit is changed (i.e; the primitives input(f) or output(f) are executed),
the current unit is not closed and its state does not change, but a new unit is
opened - if necessary - and is put at the top of the stack, above the previous
current unit, in such a way that the latter can be restored when the new
current unit is closed.
Input
in_char(t)
Reads a character.
Reads the next character, transforms it into a string of length 1 and attempts
to unify it with t.
Example:
In this example, the character obtained in the first reading is in fact the end-
of-line character which terminated the command line.
in_term(t)
Reads a sequence of Prolog III terms.
190 © PrologIA
Prolog
Aociation
HERITAGE
The environment
Example:
Example:
> thing;
> in_sentence(t1,t2,t3);
thing, Thing and line are k n o w n .
{t1 = <"thing",",","Thing","and","line","are","known",".">,
t2 = <<>,",",<>,"and","line","are","known",".">,
t3 = <"thing",",","thing","and","line","are","known",".">}
>
input(u)
The unit whose name is u becomes the current input unit. It must not be an
already opened unit. The corresponding file is found and opened.
For the moment no other action is executed apart from the change in
current input. In particular, Prolog III does not switch into some "reading
mode" but continues to execute the program in progress. Only when the
program performs reading operations on the current unit, or when it has
finished and Prolog III returns to its "reading a command" state, will the
effect of input(u) manifest itself, because reading will be performed by
means of the indicated unit and not on the current unit.
© PrologIA 191
Prolog
The environment Aociation
HERITAGE
Naturally, a file opened by input can just as easily contain rules and queries.
In addition it can itself contain an input command; the new current unit is
stacked above the previous one.
close_input
The current unit is closed and its descriptor is removed from the top of the
stack of units. The previous unit again becomes the current unit.
Output
out(t)
outl(t)
Write the term t on the current unit. If the written form of a term t
produced by out is read by in_term, the original term t is reconstructed.
outl(t) is equivalent to the sequence of goals out(t) line : when the term t has
been written a new line is started.
Example:
192 © PrologIA
Prolog
Aociation
HERITAGE
The environment
N.B. The braces printed after the term indicate that the goal out([1,
Pierre, "Hi!"]) has executed successfully. One way of preventing this
printing is to make the execution fail artificially:
outm(s)
outml(s)
Write the string s on the current output unit, without quotes and correctly
interpreting the formatting characters that s may contain (such as " \n ", etc).
If the string is longer than the remaining space on the current line it is cut by
a "hidden" carriage return. outml(s) is equivalent to outm(s) line.
Example:
outc(t)
Writes the term t and the constraints that apply to it
Examples :
line
Writes an end-of-line mark on the current output unit.
output(u)
The unit with name u becomes the current output unit. If need be a text file
is created, with the name indicated by the string u.
© PrologIA 193
Prolog
The environment Aociation
HERITAGE
close_output
The current unit is removed from the top of the stack of open output units.
If it corresponds to a file, it is closed.
echo
no_echo
Activates/cancels the option providing display on the console unit of the
terms read or written on another unit.
W ARNING . The terms are first read and encoded, then decoded and
displayed. What you will see is therefore equivalent to what has been read,
but may be different to a greater or lesser degree. The advantage of this
method is that you see the terms not as you have typed them, but as Prolog
III has "understood" them, which when debugging is obviously preferable.
exit
exit(s)
Leaves Prolog and saves all the currently known programs, including those
constituting the Prolog III supervisor. The name of the file produced is
prolog3.psv (first version) or the value of s, which must be a character string
(second version).
quit(n)
quit
Quits Prolog III without saving anything. The value n is sent to the
operating system as the "termination status". Whatever system is used, 0 is
translated into the corresponding code as "no error" (this value is not
necessarily zero); the other values are not converted.
194 © PrologIA
Prolog
Aociation
HERITAGE
The environment
reset_cpu_time
Resets the chronometer.
cpu_time(x)
cpu_time unifies x with the cpu time in milliseconds elapsed since the last
reset_cpu_time.
© PrologIA 195
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
This chapter contains a list in alphabetical order of all the predefined rules and
external procedures available in Prolog III.
This includes most of the Prolog II and Prolog II+ primitives, and a large number of
new predefined rules adapted to the special functionalities of Prolog III. Most of
these predicates have already been explained in the previous chapters. At the end of
this manual, thematic access to this dictionary of Prolog III primitives is also
provided.
HERITAGE
1. Introduction
This chapter presents Prolog III's predefined rules and external procedures.
As you develop your programs, this chapter will doubtless prove to be the
most important part of the manual. This is why we have tried to make life
easier for you by giving brief "instructions for use" for each primitive, and
maximizing the number of references to other relevant sections of the
manual.
You will thus find the following headings for each predicate:
This chapter has two separate sections; one describing the primitives which
can be used in standard syntax, the other describing the «Edinburgh
primitives».
198 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
At the end of each section you will also find an index relating to the
predefined rules, external procedures, evaluable functions, as well as certain
important identifiers which occur throughout this chapter.
© PrologIA 199
Prolog
Predefined rules and external procedures Aociation
HERITAGE
add_implicit(S1,S2)
Function : Adds an identifier
Description:
Adds the identifier with the abbreviated name S2 to the closed part of the
context S1. If S1 is not the prefix of a family having a closed part, an error is
obtained.
See the section « Structuring, recording and modifying rules» in the chapter
entitled « Programming control and environment» for more details.
See also:
• remove_implicit, dictionary
• set_context, current_context, close_context_dictionary
• module, end_module
200 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Description:
This primitive sets the constraint {T2 = N'}, where N' is the N-th argument of
the term T1. If N is zero, T2 is equal to the inital label of T1.
Examples:
> arg(2,example(X,Y,5),T);
{T = Y}
> arg(3,example[L],T);
{L = V.<T>.V',
V :: 2}
> arg(0,example[L],T);
{T = example, L !tuple}
> arg(5,example(X,Y,5),T);
ERROR 228: Bad argument type
>
See also:
• arg2, arg3
© PrologIA 201
Prolog
Predefined rules and external procedures Aociation
HERITAGE
arg2(N, L, T)
Function : Calculates the N-th element of a list
Description:
If N is zero, arg2 sets the constraint {T = S}, where S represents the number
of elements in the list L
If N is not zero, arg2 sets the constraint {T = X}, where X is the N-th element
of the list L.
Examples:
> arg2(4,[1,2,3,4,5],T);
{ T = 4 }
> arg2(2,[A,B,C|L],T);
{ B = T }
> arg2(3,[A|L],T);
ERROR 228: Bad argument type
>
See also:
• arg, arg3
202 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Description:
This primitive sets the constraint {T2 = N'}, where N' is the N-th argument of
the tuple T1. If N is zero, T2 is equal to the initial label of T1 i.e. <>. Fails if N
is not a known positive integer or if T1 is not a tuple.
Examples:
> arg3(2,<X,Y,5>,T);
{ T = Y }
> arg3(3,L,T);
{ L = <T>.V }
> arg3(0,E[L],T);
{ E = <>, T = <>, L !tuple }
> arg3(5,<X,Y,5>,T);
ERREUR 228: Bad argument type
> arg3(5,example(1,2,3),T);
>
See also:
•arg, arg2
© PrologIA 203
Prolog
Predefined rules and external procedures Aociation
HERITAGE
assert(T, Q)
Function : Adds a rule at the start of its group
Description:
Adds a rule at the start of its group. T must be a term capable of being a rule
head, i.e. representing a tree labeled by an identifier, and Q must be a list of
terms.
The execution of assert(T, Q) adds the rule T -> Q above the group of rules
having the same "name" as T, i.e. at the start of the group corresponding to
T. For example, the following two commands:
> assert(conc([e|x],y,[e|z]),[conc(x,y,z)]);
{}
> assert(conc([],y,y),[]);
{}
conc([],y,y) ->;
conc(conc([e|x],y,[e|z]) -> conc(x,y,z);
At first sight, it seems that assert does not enable rules to be added which
comprise a constraint system. However this is not the case, as shown by the
following example:
204 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
> assert(outside_of(x,[y|q]),[outside_of(x,q)]),{x#
y};
{x # y}
> assert(outside_of(x,[]),[]);
{}
> list;
outside_of(x,[]) -> ;
outside_of(x,[y | q]) ->
outside_of(x,q),
{x # y } ;
{}
>
asserta(T,Q)
Function : Identical to assert (Edinburgh compatibility)
Identical to assert.
© PrologIA 205
Prolog
Predefined rules and external procedures Aociation
HERITAGE
assert''(T, Q)
Function : Adds a rule at the end of its group
Description:
Adds a rule at the end of its group. Functions in the same way as assert, but
the rule is added below the group corresponding to T instead of above. For
example, the following two rules, typed in the order shown result in
insertion of the same conc program as above.
Example:
> assert''(conc([],Y,Y),[]);
{}
> assert''(conc([E|X],Y,[E|Z],[conc(X,Y,Z)]);
{}
assertz(T, Q)
Function : Identical to assert'' (Edinburgh compatibility)
Identical to assert''.
206 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
assign(I, T)
Function : Assigns
Description:
Assigns the term T, which must represent an identifier, a number, a
character or a character string, to the identifier I. Everything happens as if I
becomes the name of a variable which is "global" (subsequently accessible
during the execution of any goal), "static" (resists backtracking) and has the
value T. So this is standard assignment, as it occurs in FORTRAN , Pascal,
etc….
Example:
> retract(file_name(x), [] );
> assert(file_name("myfile.txt"), [] );
{}
> file_name(x);
{ x="myfile.txt" }
>
© PrologIA 207
Prolog
Predefined rules and external procedures Aociation
HERITAGE
assign(tab(N), T)
Function : Assigns an element of an array
Description:
Assigns the value of T to the element of rank N in the array tab. This array
must have been previously defined using def_array. The same restrictions as
previously apply to T: it must be a constant.
See also:
• val
• def_array, undef_array, redef_array
208 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Description:
In addition:
• The labels referred to above can be any Prolog III terms, and we
consider that for two terms to represent the same label as far as the
block_exit mechanism is concerned, it is necessary and sufficient for
them to be unifiable.
© PrologIA 209
Prolog
Predefined rules and external procedures Aociation
HERITAGE
The same mechanism is used for internal error management in Prolog III.
When an error is detected during execution of a program, the block_exit(I, C)
goal is executed, where I is an integer corresponding to the error number,
and C is additional information or the empty tuple. In this way, the user can
recover all Prolog III errors in order to process them in an application.
Examples:
execute_command ->
block(end_command, C, read_and_execute);
read_and_execute->
repeat
outm("? ")
in_char'(X)
execute(X);
In this example, the `t` command uses block_exit to return to the upper level
of execute_command by interrupting execution of read_and_execute and
deleting all the waiting choice points (repeat). The `c` command terminates
execution of read_and_execute in the normal way, and conserves the choice
points (repeat). Any other command can also use block_exit to transmit the
typed character as additional information for C.
210 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
reading_in_a_file(L) ->
input("file_to_read")
reading_loop(L);
reading_loop(L) ->
block(X, _, inl(D_ata))
reading_loop_continuation(X, D_ata, L);
This second example is used to read data (character strings) in a file and
construct the list (tuple) of these data. When the Prolog interpreter detects
an end of file, it generates a block_exit, with integer 17 as the value of the
main label, corresponding to the end of file error. This error can be
recovered by the enclosing block, since its main label was a variable.
reading_in_a_file_and_processing ->
input("file_to_read")
block(E, C, read_and_process(I_nfo))
read_and_process_continuation(E, C, I_nfo);
read_and_process(I_nfo) ->
repeat
inl(I_nfo)
process(I_nfo);
read_and_process_continuation(X, _, _) ->
free(X) !
fail;
read_and_process_continuation(17, _, _) -> ! % end of file
close_input("file_to_read");
read_and_process_continuation(X, Y, _) -> ! % errors not
recovered
close_input("file_to_read")
block_exit(X, Y),
{ X <= 9 };
read_and_process_continuation(X, Y, I) -> % errors processed
process_error(I, X, Y)
block(E, C, read_and_process(I_nfo))
read_and_process_continuation(E, C, I_nfo);
process_error(I, X, Y) ->
... ;
process(I) ->
... ;
© PrologIA 210 i
Prolog
Predefined rules and external procedures Aociation
HERITAGE
The last example is used to read data (character strings) in a file, and process
them without constructing the list (tuple) of these data. The same
mechanism as above is used when Prolog detects the end of file, and a
similar mechanism is used to manage other errors that may occur during
processing. Some of these errors, such as the stack overflow errors, can't be
recovered, and in this case block_exit is used to return to Prolog's upper level.
On the other hand, some other errors can be taken into account in the
processing in order to continue execution of the program. To do this you
must restart execution of another block since it is no longer possible to return
to the preceding block.
Note:
A program can be interrupted at any time using a special key combination
which varies according to the system used, e.g. it may be <Ctrl-C>. This
interruption is managed either as an error in which case it can be intercepted
using the block mechanism, or as a dialog in which case block cannot intercept
it. The user can configure interruption management using the external
procedure set_config.
See also:
•set_config
210 ii © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Description:
Functions in a similar way to the primitives above, but has a single "label" E
instead of two. B is the goal or sequence of goals to execute, and block(E, B)
starts execution of B. If block_exit is subsequently executed with one
argument, the system searches for a block whose first argument unifies with
the argument of block_exit.
Note:
A program can be interrupted at any time using a special key combination
which varies according to the system used, e.g. it may be <Ctrl-C>. This
interruption is managed either as an error in which case it can be intercepted
using the block mechanism, or as a dialog in which case block cannot intercept
it. The user can configure interruption management using the external
procedure set_config.
See also:
•set_config
© PrologIA 211
Prolog
Predefined rules and external procedures Aociation
HERITAGE
bool(B)
Function : Boolean verification
Description:
This predefined rule verifies that B is a term representing a known boolean
value. If this is not the case, bool(B) fails.
Examples:
> bool(1');
{}
> bool(A&B);
>
> bool(A|1');
{ A !bool }
> bool(A),{A|B = 1', A|~B = 1'};
{ A = 1',
B !bool }
> bool(2);
>
Notes:
This predefined rule does not only test whether B represents a boolean value
(the predefined rule is_bool(B) performs this verification).
It also enables the term B to be constrained to represent a known boolean
value, in a case where B represents the same value in all the solutions of the
current constraint system (see the third example above).
212 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
bound(T)
Function : Verifies that T represents a sufficiently "known"
term.
Class : Prolog III predefined rule
Category : Control
Description:
This predicate executes if T is a term representing a tree for which:
Please refer to the section « Known terms» in the chapter entitled « Delay
Mechanisms» for more details.
Examples:
> bound(1');
{}
> bound(123/456);
{}
> bound(aurora(A,B,C,D));
{}
> bound(borealis[L]),{L :: 12};
{ L :: 12, L !tuple }
> bound(E[L]),{L :: 12};
>
See also:
• known, bound_tree, bound_tree'
• free, free_label'
© PrologIA 213
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Error message : No
Description:
Sets the constraint {U3 = U1.U2}. Fails if the size of the tuple U1 is not
known.
Examples:
See also:
• conc3
214 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Error message : No
Description:
Sets the constraint {N3 = N1*N2}. Fails if N1 and N2 are not known numeric
values (in other words succeeds if one of the two is known, which makes the
constraint linear).
Examples:
> bound_mult(2,Y,Z);
{ Z = 2Y }
> bound_mult(X,X,4);
>
See also:
• mult
© PrologIA 215
Prolog
Predefined rules and external procedures Aociation
HERITAGE
bound_size(T, N)
Function : Size of a term
Error message : No
Description:
Sets the constraint { T :: N }, if N is a positive integer, or the constraint
{ N = k } if T is a term having a known number of sons k. Fails in all other
cases.
Examples
> bound_size(<1,2,3,4>,N);
{ N = 4 }
> bound_size("that's all!",N);
{ N = 11 }
> bound_size(U,2);
{ U = X1[X2],
X2 :: 2 }
> bound_size(U,N);
>
216 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
bound_tree(T)
Function : Verifies that T represents a unique tree
Error messages : No
Description:
Verifies that T represents a unique tree, i.e. that the term T does not
comprise any variables.
Notes
T must not represent an infinite tree. If this is the case, the primitive
bound_tree' should be used.
Examples:
> bound_tree(<1,2,3,4>);
{}
> bound_tree("that's all!");
{}
> bound_tree(E[U]) { U::4 };
>
See also:
• free, free_label, known, bound, bound_tree'
© PrologIA 217
Prolog
Predefined rules and external procedures Aociation
HERITAGE
bound_tree'(T)
Function : Verifies that T represents a unique tree, which
may be infinite.
Class : Prolog III predefined rule
Category : Trees, lists, tuples and strings
Description:
Verifies that T represents a unique tree, i.e. that the term T does not
comprise any variables. T can represent an infinite tree. If you are certain
that the contrary is true, the primitive bound_tree should be used, which is
more efficient.
Examples:
> bound_tree'(<1,2,3,4>);
{}
> bound_tree'(X),{X = 1(X)};
{ X = 1(X) }
>
See also:
• free, free_label, known, bound, bound_tree
218 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
break
break(S1)
break(S1, S2)
Function : Calls the Prolog III debugger
Class : Prolog III external procedure
Category : Environment
Known parameters : S1, S2
Error messages : No
Description:
This primitive switches the interpreter to debug mode. When it has
arguments, it can print the string S1 on the trace output and then execute the
commands contained in string S2 using the Prolog III debugger.
Placing calls to break in a program is like installing spy points by hand, except
that they are placed much more precisely than they would be using the
Prolog spy primitive, which sets spy points on a whole group of rules. Also,
the ability to pass on commands to the debugger via the S2 argument allows
for some automation (batch).
If the interpreter is not in debug mode when break is called, the commands
of S2 (if any) will only be taken into account and executed at the next port
(possibly after backtracking). Otherwise break's EXIT port is shown and the
S2 commands (if any) can be executed.
Example:
Here is an example from menu.p3. The group named Fish has been replaced
by the following:
© PrologIA 218 i
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Therefore we want to spy on the first rule of the Fish group. Each time this
rule is fired, we want the system to display the message "in Fish", display
the system of constraints applying to the variables in the question (sol),
print the status of the current port (p) and resume execution till the next
break point (C).
In the example of execution shown below, user input is in bold. The lines
displayed by the call to break are in italics. The interpreter is in normal mode
when the query is entered.
> BalancedMeal(h,m,d);
{h = radishes, m = beef, d = fruit}
{h = radishes, m = pork, d = fruit}
in Fish
6[0]CALL : Dessert(d,k_1)
{h = radishes, m = sole}
6[0]CALL : Dessert(d,k_1)
{h = radishes, m = sole, d = fruit}
{h = radishes, m = sole, d = ice_cream}
{h = radishes, m = tuna, d = fruit}
in Fish
5[2]EXIT(rC): break("in Fish","sol;p;C")
{h = pate, m = sole}
5[2]EXIT(rC): break("in Fish","sol;p;C")
{h = pate, m = sole, d = fruit}
>
Please refer to the chapter “Debugging Prolog III programs” for the
definition of spy points.
See also:
• spy
• debug, no_debug
218 ii © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
char(C)
Function : Verifies that C represents a known character
Error message : No
Description:
The goal char(C) executes if C is a term representing a known character.
Examples:
> char(`a`);
{}
> char(A), {A !char};
>
char("A");
>
© PrologIA 219
Prolog
Predefined rules and external procedures Aociation
HERITAGE
char_code(C, N)
Function : Links a character with its ISO code
Error message : No
Description:
Matches the character C with its ASCII code N and vice-versa.
Example:
> char_code(`A`,N);
{ N=65 }
> char_code(C,65);
{ C=`A` }
>
Note:
Characters whose ASCII code is between 0 and 31 are printed in the form
`\uu` where uu represents the octal writing of the relevant code.
220 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
close_context_dictionary(S)
Function : Closes an identifier family
Error message : No
Description:
Defines the closed part of the family S as being equal to the current state of
this family at the moment when this rule is executed. Any other identifier
which subsequently joins this family will not be in its closed part and will
therefore not be taken into account in operations using the "implicit list" of
the set_context command (see this primitive), unless it is called by the
add_implicit rule.
See also:
• add_implicit, remove_implicit, dictionary
• set_context, current_context
© PrologIA 221
Prolog
Predefined rules and external procedures Aociation
HERITAGE
close_input
Function : Closes the current input unit
Description:
The current unit is closed (unless it is the console) and its descriptor is
removed from the top of the stack of units: the previous unit becomes the
current unit again.
close_input(F)
Function : Closes the input unit called F
Description:
The unit called F, which must appear in the list of open units, is closed and its
descriptor is removed from this list.
See also:
• input
222 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
close_output
Function : Closes the current output unit
Description:
The current unit is removed from the top of the stack of open output units,
unless it is the console. If it corresponds to a file, then this file is closed.
close_output(F)
Function : Closes the output unit called F
Class : Prolog III predefined rule (II+)
Category : Input/Output
Description:
The unit called F, which must appear in the list of open output units, is closed
and its descriptor is removed from this list.
See also:
• output
© PrologIA 223
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Description:
Sets the constraint system {U3 = U1.U2, U1 :: N1, U2 :: N2, U3 :: N3, N3 =
N1+N2, N1 >= 0, N2 >= 0, N3 >= 0 }, with the delays necessary if N1, N2 or N3
are not known.
Examples:
> conc3(U,V,U);
{ V = <>,
U :: N,
U.<> = U,
N >= 0 }
>
See also:
224 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Error message : No
Description:
Enumerates all the triplets of strings S 1 , S 2 , S 3 such that S 3 is the
concatenation of S1 and S2. The strings S1, S2, S3 must be sufficiently
known to produce finite sets of triplets.
Examples:
> conc_string("ab","cd",s);
{ s="abcd"}
> conc_string(s1,s2,"abcd");
{ s1=<>,s2="abcd" }
{ s1="a",s2="bcd" }
{ s1="ab",s2="cd" }
{ s1="abc",s2="d" }
{ s1="abcd",s2=<> }
>
© PrologIA 225
Prolog
Predefined rules and external procedures Aociation
HERITAGE
cpu_time(N)
Function : Obtains the "cpu time"
Error message : No
Description:
cpu_time unifies N with the cpu time in milliseconds.
See also:
• reset_cpu_time
226 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
current_context(T0),
current_context(T0, T1, T2, T3)
Function : Context identification
Error message : No
Description:
Unifies T0 with the term identifying the current reading writing context, and
unifies T1, T2, T3 respectively with the term defining the explicit sequence,
the term defining the implicit sequence and the default prefix of this context.
See the section « Structuring, recording and modifying rules» in the chapter
entitled « Programming control and environment» for more details.
See also:
• set_context
© PrologIA 227
Prolog
Predefined rules and external procedures Aociation
HERITAGE
current_predicate(<I, A>)
Function : Tests for the presence of a rule
Error message : No
Description:
Tests for the presence of a rule. Executes if there exists a rule with access
identifier I and arity A. If A is a variable and I is known, it enumerates in
succession all the values of A corresponding to a rule with access I. If I is not
known, (i.e. is a variable) it unifies the argument in succession with all the
forms I, A of the rules in the module determined by the default prefix of the
current context.
See also:
• rule
228 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
/ ! '!'
Function : Cut
Error message : No
Description:
The '!' predicate executes in the same way as the / (slash) in the Marseille
syntax or the ! (cut) in Edinburgh syntax, i.e. it cuts all the possible choices in
the rule preceding the rule in which it is present. These choices are: the other
ways of executing the head of this rule, and the other ways of executing the
goals of this rule preceding the '!'.
The difference between these three notations is that the 'quoted identifier'
form(which is therefore a term) is the only one that can be used inside a
term (e.g., as an argument). The two other forms / and ! are just parasites
used only in a sequence of goals (body of a rule or query).
© PrologIA 229
Prolog
Predefined rules and external procedures Aociation
HERITAGE
> choice1(U);
{ U = <red,big> }
{ U = <red,small> }
{ U = <blue,big> }
{ U = <blue,small> }
{ U = "that's all" }
> choice2(U);
{ U = <red,big> }
{ U = <red,small> }
{ U = <blue,big> }
{ U = <blue,small> }
> choice3(U);
{ U = <red,big> }
{ U = <red,small> }
> choice4(U);
{ U = <red,big> }
> choice1(U) cut;
{ U = <red,big> }
>
229 i © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
debug
Function : Debug mode for execution of a program
Error messages : No
Description:
Activates the debugger to debug a program execution.
See also:
© PrologIA 229 ii
Prolog
Predefined rules and external procedures Aociation
HERITAGE
def_array(I, N)
Function : Array declaration
Description:
Dynamically defines an array of Prolog constants called I with size N. This
array will behave like a variable which is "global" (subsequently accessible
during the execution of any goal), and "static" (resists backtracking). The legal
values of the index are 1..N.
230 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Examples:
> list;
inc(i) -> val(i,x) assign(i,x+1);
push(v) ->
val(pointer,p)
!
assign(stack(p), v)
inc(pointer)
, { p <= 100 };
push(v) -> outml("stack overflow") fail;
pop(v) ->
dec(pointer)
val(pointer,p)
!
val(pile(p),v)
dec(pointer)
, { p >= 1 };
pop(v) -> outml("stack empty") assign(pointer,1) fail;
{}
> initialize;
{}
> push(111);
{}
> push(222);
{}
> pop(x) pop(y);
{x=222, y=111}
> pop(x);
stack empty
>
See also:
• assign, val
• undef_array, redef_array
© PrologIA 231
Prolog
Predefined rules and external procedures Aociation
HERITAGE
default(T1, T2)
Function : Control of execution
Description:
The predefined rule default performs the following control operation: if T1
can be executed, then it is executed in all possible ways, otherwise T2 is
executed. It should be noted that contrary to what you might think at first,
this primitive cannot be performed using “!”.
Example:
man(john) ->;
man(peter) ->;
> reply(man(x));
{ x=john }
{ x=peter }
> reply(woman(x));
nobody
{}
>
232 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
dictionary
Function : Searches for user modules
Error message : No
Description:
Writes on the current output the abbreviated from of the access identifiers of
the family having a prefix which is the same as the default prefix of the
reading/writing context. Each access is written in the form "identifier/arity".
dictionary(L)
Function : Searches for user modules
Description:
Unifies L with the list of prefixes of the user modules present in memory.
© PrologIA 233
Prolog
Predefined rules and external procedures Aociation
HERITAGE
dictionary(M, L)
Function : Searches for user modules
Description:
Unifies L with the list of access identifiers of module M. Each access is
represented in the form of a tuple: < identifier , arity >.
Example:
234 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
dif(T1, T2)
Function : Inequality
Error message : No
Description:
Sets the constraint {T1 #T2].
© PrologIA 235
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Description:
Sets the constraint {N3 = D}, where D is the result of integer division of the
absolute value of N1 by the value of N2. Care must be taken not to confuse
the predicate with the evaluable function of the same name (see the
predefined rule val).
Examples:
> div(9,2,N);
{ N = 4 }
> div(7,N1,N2):
>
See also:
• mod
• trunc
236 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
dot(T)
Function : Verifies that T represents a non empty binary list
Error message : No
Description:
Verifies that the term T represents a pointed pair. Fails if
T is free
or if
T does not represent a list
or if
T = [].
© PrologIA 237
Prolog
Predefined rules and external procedures Aociation
HERITAGE
echo
Function : Echo on the console
Error message : No
Description:
Causes all rules or queries read on the current input unit to be displayed on
the current output unit. Provided these rules are valid, they are encoded,
and then listed - therefore decoded - on the current output.
See also:
• no_echo
• set_config, set_configuration, get_config, get_configuration
238 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
edinburgh
Function : Switches to Edinburgh syntax
Error messages : No
Description:
Switches to Edinburgh syntax, if Prolog III syntax is currently being used. In
fact, this primitive behaves in exactly the same way as the call:
set_config("syntax","Edimbourg")
Note:
If preferred, it is possible to start each Prolog III session in the Edinburgh
syntactic mode. To do this, simply start the session by executing the
Edimbourg primitive (default syntactic mode: Prolog III), and then save the
current state using the exit command. Each user should first rename the
initial3.psv file so that a copy of the original version remains.
See also:
• prologIII
• exit, set_config
© PrologIA 239
Prolog
Predefined rules and external procedures Aociation
HERITAGE
edit(I)
Function : Edits rules
Error messages : No
Description:
The edit primitive is used to edit one or more groups of rules, and reinserts
the modified rules into Prolog III, having first destroyed the rules which
have become obsolete.
The I argument can have any of the forms described for the list primitive, i.e.
s denotes a character string, i an identifier, a and integer and v a variable.
s All the groups of rules from the module corresponding to the
prefix s
i The group (or groups) of rules with i as the access.
[i1, i2, … in]
The group (or groups) of rules with i1 as the access, then the
group (or groups) with i2 as the access, and so on.
v All the groups of rules from the module corresponding to the
default prefix. v is unified with the list of <ident, arity> pairs.
<i, a> All rules constituting the group with name i and arity a.
<i, v> All rules whose access is i, regardless of their arity.
<v, a> All rules with arity a belonging to the module having the
default prefix of the current reading/writing context.
A list of pairs in one of the three above formats.
To select the required host editor in a system which has one or more, the
user must position the environment variable PrologEdit. The User's Manual
explains how to do this.
240 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
end_module(P)
Function : Declaration of end of module
Error messages : No
Description:
Specifies that all the rules located between the module primitive and the
end_module primitive describe the same module. For a more detailed
explanation of these fairly complex concepts, the reader should refer to the
chapter “Programming control and Environment”. Remember that P is the
module prefix, and that this prefix must be the same as the prefix defined in
the corresponding module primitive.
See also:
• module
• set_context, current_context, close_context_dictionary
• add_implicit, remove_implicit, dictionary
© PrologIA 241
Prolog
Predefined rules and external procedures Aociation
HERITAGE
enum(R)
Function : Integer enumeration
Error message : No
Description:
Enumerates all the integer constraints n such that the constraint {R = n} is
consistent. The enumeration order is undefined. This predefined rule is
useful because it can be used to enumerate integer variables in a limited
domain of values by means of numeric constraints applying to rationals or
reals.
Example:
242 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
enum(R, R1)
Function : Integer enumeration with upper delimiter
Error message : No
Description:
Enumerates all the positive integer constants n such that the set of
constraints {R = n, 1<=R<=R1 } is consistent. The enumeration order is
undefined.
Description:
Enumerates all the positive integer constants n such that the set of
constraints {R = n, 1<=R1<=R<=R2 } is consistent. The order of enumeration
is undefined.
© PrologIA 243
Prolog
Predefined rules and external procedures Aociation
HERITAGE
eq(T1, T2)
Function : Equality
Error message : No
Description:
Simply sets the constraint {T1 = T2}
See also:
• dif
244 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
exit
Function : Leaving Prolog III
Error message : No
Description:
Is used to leave Prolog III and save all the modules, including those that
constitute the Prolog III supervisor (initial state), in coded form. The name
of the file produced is prolog3.psv.
See also:
© PrologIA 245
Prolog
Predefined rules and external procedures Aociation
HERITAGE
exit(S)
Function : Leaving Prolog III
Class : Prolog III external procedure (II+)
Category : Environment
Known parameters : S, which must a character string
Description
Is used to leave Prolog III and save in coded form all the modules, including
those that constitute the Prolog III supervisor (initial state), in a file called S.
See also:
246 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
fail
Function : Prolog failure
Error message : No
Description:
fail always causes a Prolog failure, and thus an exploration of the other
choice on standby (backtracking). It is preferable to use fail rather than an
undefined predicate, because it prevents the display of error and warning
messages at execution: for more information on this topic please refer to the
trace and set_config primitives.
© PrologIA 247
Prolog
Predefined rules and external procedures Aociation
HERITAGE
findall(V, P, L)
Function : Collects solutions
Error messages : No
Description:
Unifies the list L with a collection of all the solutions V when P is executed.
The goal P must be sufficiently known to be executed.
Example:
> list;
age(paul, 22) -> ;
age(jean, 28) -> ;
age(bruno, 25) -> ;
{}
> findall(<N,A>, age(N,A), L);
{ L=[<bruno,25>,<jean,28>,<paul,22>] }
>
248 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
find_pattern(S1, S2, N)
Function : Searches for a sub-string
Error message : No
Description:
Sets the constraint {N = D} where D is the position of the start of the string
S2 in the string S1. If the string S2 is not found find_pattern fails.
Example:
> find_pattern("1234567890","3456",p);
{ p=3 }
> find_pattern("1234567890","abcd",p);
>
See also:
• conc_string, substring
© PrologIA 249
Prolog
Predefined rules and external procedures Aociation
HERITAGE
free(T)
Function : Verifies that T does not represent a sufficiently
known term.
Class : Prolog III predefined rule (II+)
Category : Control
Description:
free(T) is executed successfully if
the initial label of T is known
and if
it is not known whether the number of its sons is zero or not.
Fails in all other cases.
T = E[L]
¬ known(L) known(L)
¬ known(E) free(T) ?
known(E) ? known(T)
Example
> free(X);
{X=V1[V2]}
> free((+X)[U]);
{ X !num, U !tuple }
> free(X(1,2,3));
> free(top[L]);
> free(top(X,Y,Z);
> free(top[L]) {L # <>};
>
See also:
250 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
free_label(T)
Function : Verifies that the label of term T is not known.
Error message : No
Description:
free_label(T) executes successfully if the initial label of T is not known. Fails
otherwise.
Example:
> free_label(X);
{ X=V1[V2] }
> free_label(+X);
{ X !num }
> free_label(X(1,2,3));
{}
> free_label(example[L]);
>
See also
© PrologIA 251
Prolog
Predefined rules and external procedures Aociation
HERITAGE
freeze(T, P)
Function : Delays execution of a goal
Error messages : No
Description:
Delays execution of a goal P for as long as the term T is not known. In
particular it should be noted that if the term T is reduced to a numeric or
boolean variable, the current set of constraints may reduce the domain of
possible values for this variable sufficiently to cause execution of P..
A term is known when we know the initial label of the tree it represents
{ and when we know whether or not it is a leaf (whether or not the number
of its sons is zero).
Note:
When T becomes known, the goals frozen on T insert themselves at the top
of the resolvent. It is impossible to predict in what order they will be
executed.
See also:
• known, free
252 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
garbage_collection
Function : Garbage collection
Error message : No
Description:
Causes execution of the garbage collection mechanism. This is required
because Prolog III automatically manages the memory which is allocated to
it at each step in the solving process. Therefore, when processing a
particularly complex step it sometimes proves necessary to activate this
mechanism by program, so that the maximum possible space is made
available. This is because the amount of occupied space before this step is
processed may not be large enough to cause automatic activation of the
garbage collector.
See also:
• state
© PrologIA 253
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Error messages : No
Description:
Sets the constraint {N3 = N3'}, where N3' is the greatest common divisor of
the integers N1 and N2. The calculation does not take signs into account. gcd
fails if N1 and N2 are not known or are not integers.
Examples:
> gcd(24,16,P);
{ P = 8 }
> gcd(24,-16,P);
{ P = 8 }
>
See also:
• lcm
• pgcd, ppcm
254 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
get_config(S,V)
Function : Current configuration status
Error message : No
Description:
If S is a string, sets the constraint {V = S'}, where S' is the current value
associated with field S. Otherwise, by backtracking get_config enumerates
the possible fields for S and their current value for V. For the complete list
of these fields and values, please refer to the explanations given for the
set_config primitive. .
Example:
> get_config("syntax",S).
{ S = "Edimbourg" }
>
See also:
• set_config, set_configuration, get_configuration
© PrologIA 255
Prolog
Predefined rules and external procedures Aociation
HERITAGE
get_configuration(U)
Function : Current configuration status
Error message : No
Description:
Sets the constraint {U = U'}, where U' is a tuple of < field, value > pairs that
describes the status of all the current parameters.. For the list of fields and
their possible values, please refer to set_config. .
Example:
> get_configuration(X).
{ X=<<"echo",0>,<"epsilon_float",7.450580596923828e-09>,
<"format_decimal",3>,<"format_float","%.15le">,
<"format_out_num","Fnormal">,<"statistics",0>,
<"syntax","Edimbourg">,<"trace",0>,<"tty_wrap",200>,
<"undefined_rule","fail">> }
>
See also:
256 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
getenv(S1,S2)
Function : Obtains the value of an environment variable.
Error messages : No
Description:
Sets the constraint {S2 = S2'}, where S2' is the value associated in the
operating system with the environment variable named S1. Using UNIX for
example, the value can be associated by means of the shell command setenv.
Example:
$ setenv try 17
$ prolog3
.....
>
getenv("try",S);
{ S = "17" }
>
© PrologIA 257
Prolog
Predefined rules and external procedures Aociation
HERITAGE
ident(I)
Function : Verifies that I represents a known identifier
Error message : No
Description:
Verifies that the term I represents a known identifier, and fails otherwise.
Examples:
> ident(sleepless_night);
{}
> ident("sleepless_night");
>
ident('*');
{}
> ident(`*`);
>
Notes:
In the third example, the goal executes successfully because the identifier is
quoted. In the fourth it is a character and the goal thus fails.
See also:
• is_ident
258 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
in_char(C)
Function : Reads a character
Description:
Reads a character on the active input unit. If an end of file is detected, an
error is indicated and everything happens as if a close_input had been
performed.
Examples:
See also:
• in_char', in_ident, in_integer, inl, in_real, in_sentence, in_string, in_term,
next_char, next_char'
© PrologIA 259
Prolog
Predefined rules and external procedures Aociation
HERITAGE
in_char'(C)
Function : Reads any character which is not a formatting
character.
Class : Prolog III external procedure (II+)
Category : Input/Output
Description:
Reads the first character whose ASCII code is not less than or equal to 32
(formatting characters, space, carriage return, tabs, etc.), on the active input
unit. If an end of file is detected, an error is indicated and everything
happens as if a close_input had been performed.
Examples:
> in_char'(C);
a
{C = `a`}
> in_char'(C);
a
{C = `a`}
> in_char'(C) in_char(C');
a
{C = `a`, C' = `\15`}
>
See also:
• in_char, in_ident, in_integer, inl, in_real, in_sentence, in_string, in_term,
next_char, next_char'
260 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
in_ident(I)
Function : Reads an identifier
Description:
Reads an identifier on the active inpput unit. If an end of file is detected, an
error is indicated and everything happens as if a close_input had been
performed.
Examples:
> in_ident(I);
this_is_an_identifier
{I = this_is_an_identifier}
> in_ident(I);
'->'
{I = '->'}
> in_ident(I);
[]
>
in_ident(I);
V_ariable
>
See also:
• in_char, in_char', in_integer, inl, in_real, in_sentence, in_string, in_term,
next_char, next_char'
© PrologIA 261
Prolog
Predefined rules and external procedures Aociation
HERITAGE
in_integer(N)
Function : Reads an integer
Description:
Reads an integer on the active input unit. If an end of file is detected, an
error is indicated and everything happens as if a close_input had been
performed.
Examples:
> in_integer(N);
124578956810000
{ N = 124578956810000 }
> in_integer(N);
this is obviously not an integer
>
in_integer(N) in_ident(I);
123we_want_some_tea
{ N = 123, I = we_want_some_tea }
> in_integer(N) in_real(R);
1213.06
{ N = 1213, R = 6.000000000000000e-02 }
>
Note.
in_integer reads any object having integer syntax. For example 12/2 will
not be read as the integer 6 , only the intger 12 will be considered by
in_integer.
See also:
• in_char, in_char', in_ident, inl, in_real, in_sentence, in_string, in_term,
next_char, next_char'
262 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
in_real(R)
Function : Reads a floating number
Description:
Reads a floating number on the active input unit. If an end of file is detected,
an error is indicated and everything happens as if a close_input had been
performed.
Examples:
> in_real(R);
52.451278952645213E17
{ R = 5.245127895264521e+18 }
>
> in_real(R);
100.00
{ R = 1.000000000000000e+02 }
> in_real(R);
100
>
Note:
in_real reads any object having floating number syntax, except for integers
(i.e. the decimal point is mandatory).
See also:
© PrologIA 263
Prolog
Predefined rules and external procedures Aociation
HERITAGE
in_sentence(T1,T2,T3)
Function : Reads a sentence
Description:
Reads a sentence ending in ".", "?" or "!" and transforms it into three lists,
unified with T1, T2 and T3 respectively. T1 is the list of lexcial units (words,
numbers, special characters, etc.) which form the sentence; T3 is the list
obtained by replacing each upper-case leter appearing in an element of T1
with the corresponding lower-case letter. T2 is the same as T3, but each
element of T3 that corresponds to a known identifier in the family of the
current context's default prefix is replaced by the symbol <> to indicate this
fact.
Example:
> fools(gooseberry)->;
> in_sentence(T1,T2,T3);
Only fools and horses work.
{ T1 = <"Only","fools","and","horses","work",".">,
T2 = <"only","<>","and","horses","work",".">,
T3 = <"only","fools","and","horses","work",".">}
>
See also:
• in_char, in_char', in_ident, in_integer, inl, in_real, in_string, in_term,
next_char, next_char'
264 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
in_sentence'(T)
Function : Reads a sentence
Description:
Reads a sentence ending in “.”, “?” or “!” and transforms it into a list unified
with T. T contains the list of lexical units (words, numbers, special characters,
etc.) which form the sentence.
Example:
> fools(gooseberry)->;
> in_sentence(T);
Only fools and horses work.
{ T1 = <"Only","fools","and","horses","work","."> }
>
See also:
• in_char, in_char', in_ident, in_integer, inl, in_real, in_string, in_term,
next_char, next_char'
© PrologIA 265
Prolog
Predefined rules and external procedures Aociation
HERITAGE
in_string(S)
Function : Reads any string
Description:
Reads a character string on the current input unit. If an end of file is
detected, an error is indicated, and everything happens as if a close_input had
been performed.
Examples:
> in_string(S);
"this is a string"
{S = "this is a string"}
> in_string(S);
this is not a string
>
in_string(S);
"126/45"
{S = "126/45"}
> in_string(S);
"123\
456"
{S = "123456"}
>
See also:
• in_char, in_char', in_ident, in_integer, inl, in_real, in_sentence, in_term,
next_char, next_char'
266 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
in_term(T)
Function : Reads any term
Description:
Reads a Prolog term.
Reads the largest sequence x of characters that constitutes a term. The term
must end with a semi-colon, which is not read.
Examples:
> in_term(X);
tree(-3/4,<a,b>) in_char(Y);
{ X=tree(-3/4,<a,b>), Y=`;` }
> in_term(X);
term1(u) term2(v), { u < v }
{ X=term1(u), u !num }
>
Notes:
1. Avoid putting spaces into any expression which is not in brackets.
2. Only the first term is taken into account.
3. There may be a constraint system, in which case it will be taken into
account.
See also:
• in_char, in_char', in_ident, in_integer, inl, in_real, in_sentence, in_string,
next_char, next_char'
© PrologIA 267
Prolog
Predefined rules and external procedures Aociation
HERITAGE
inl(S)
Function : Reads one line
Description:
Reads one line up to the first carriage return (\n) on the active input unit.
The result is given in the character string S. If an end of file is detected, an
error is indicated and everything happens as if a close_input had been
performed.
See also:
• in_char, in_char', in_ident, in_integer in_real, in_sentence, in_string,
in_term, next_char, next_char'
268 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
input(F)
Function : Defines the current input unit
Description:
The unit called F becomes the current input unit. If this unit does not appear
in the list of open units, then the corresponding file is found and opened.
Otherwise this unit goes to the top of the stack, unless it was there already,
in which case the message "File already open" is produced.
A command file opened with input can itself contain an input command; the
new current unit is then stacked above the previous one.
See also:
© PrologIA 269
Prolog
Predefined rules and external procedures Aociation
HERITAGE
input_is(F)
Function : Provides the current input unit
Description:
Sets the constraint {F = S}, where S is a character string describing the
current input unit.
Examples:
> input_is(X);
{ X = "console" }
>
See also:
• input, output, output_is
270 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
insert
Function : Inserts rules from the current unit
Description:
This predefined rule switches the system into a mode in which the rules,
read on the current input unit are added to the current program, in the
order they are read. Any queries are ignored. The insert mode ends either
when an empty rule is found, or when the end of the input file is detected.
Example:
> insert;
conc([],y,y) ->;
conc([e|x],y,[e|z]) -> conc(x,y,z);;
{}
>
© PrologIA 271
Prolog
Predefined rules and external procedures Aociation
HERITAGE
insert(F)
Function : Inserts rules from a file
Description:
This predefined rule enables statements (rules) to be added in the order they
are read from the file F. Any queries are ignored. Reading ends either
when the end of the file is reached, or when an empty rule is read, i.e. in
basic syntax two consecutive ";"
insert causes an error when a group which is read already exists. In this case
Prolog III leaves "insertion mode" but does not close the files which were
opened. It continues to read the file(s) currently in progress: the rules are
inserted and the queries are executed.
Depending on whether or not the echo mode (see echo rule) has been
activated or not, the rules are displayed on the console as they are read.
See also:
• insert,reinsert, reinsert(F)
272 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
integer(N)
Function : Verifies that N is a known integer number.
Error message : No
Description:
Executes successfully if N represents a known integer number. Fails in all
other cases.
Examples:
> integer(0);
{}
> integer(-1234*4567);
{}
> integer(X+2);
>
See also:
• num, is_num
© PrologIA 273
Prolog
Predefined rules and external procedures Aociation
HERITAGE
is_bool(B)
Function : Verifies that B represents a boolean value.
Error message : No
Description:
Verifies that the term B represents a boolean value, i.e. that the constraint {b
!bool} belongs to the current constraint system. Fails otherwise.
Examples:
> is_bool(1');
{}
> is_bool(B), {B !bool};
{ B !bool }
> is_bool(B), {B !boolt};
>
See also:
• bool
274 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
is_char(C)
Function : Verifies that C represents a character
Error message : No
Description:
Verifies that the term C represents a character, i.e. that the constraint {C
!char} belongs to the current system. Fails otherwise.
Examples:
> is_char(`$`);
{}
> is_char(C) {C !char};
{ C !char }
> is_char('$')
>
Notes:
Remember that characters are written in anti-quotes (see example 1 above).
This is why example 3 fails ('$' is a quoted identifier). To verify that C is a
known character, use char(C).
See also:
© PrologIA 275
Prolog
Predefined rules and external procedures Aociation
HERITAGE
is_ident(I)
Function : Verifies that I represents an identifier
Error message : No
Description:
Verifies that the term I represents a known identifier, i.e. that the constraint
{I !id} belongs to the current system. Fails otherwise.
Examples:
> is_ident(gwendoline);
{}
> is_ident('this is one too');
{}
> is_ident([]);
{}
> is_ident(I) {I !idt};
>
Notes:
In the second example, this is one too, is a quoted identifier, and the goal
executes normally.
See also:
• ident
276 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
is_leaf(T)
Function : Verifies that T represents a leaf.
Error message : No
Description:
Verifies that the term T represents a tree reduced to a leaf, i.e. that the
constraint {T :: 0} belongs to the current system. Fails otherwise.
Examples:
> is_leaf(X[<>]);
{ X::0 }
> is_leaf(B1|B2);
{ B1 !bool, B2 !bool }
> is_leaf(U.V) {U::2};
>
See also:
• bound_tree, bound_tree'
© PrologIA 277
Prolog
Predefined rules and external procedures Aociation
HERITAGE
is_num(R)
Function : Verifies that R represents a number
Error message : No
Description:
Verifies that the term R represents a numeric value, i.e. that the constraint
{ R !num } belongs to the current system. Fails otherwise.
Examples:
> is_num(91252525);
{}
> is_num(3.12e12*X);
{ X !num }
> is_num(X);
>
See also:
• num, integer
278 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
is_tuple(U)
Function : Verifies that U represents a tuple
Error message : No
Description:
Verifies that the term U represents a tuple, i.e. that the constraint { U !tuple }
belongs to the current system. Fails otherwise.
Examples:
> is_tuple(<A,B,C>);
{}
> is_tuple(U),{X = E[U]};
{ X = E[U] }
> is_tuple("a string can hide a tuple !");
{}
> is_tuple([A,B,C]);
>
See also:
• tuple
© PrologIA 279
Prolog
Predefined rules and external procedures Aociation
HERITAGE
is_univ(T)
Function : Verifies that the term T represents a non typed
tree.
Class : Prolog III predefined rule
Category : Type verification
Description:
Succeeds if the type of term T is not character, identifier, numeric, boolean,
tuple or binary list.
Examples:
> is_univ(X);
{}
> is_univ(E[U]);
{ E :: 0,
U !tuple }
> is_univ(tree(1,A));
{}
> is_univ((+X)(A,B,C));
{ X !num }
> is_univ(ident);
>
is_univ([1,2,3]);
>
is_univ(2X+4);
>
is_univ(B) { B !bool };
>
280 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
kill_module(S)
Function : Deletes the rules in a module
Description:
Deletes all the rules in the module denoted by the character string S. The
module arrays are de-allocated, and the assignments of the module
identifiers are canceled.
Example:
See also:
• new
© PrologIA 281
Prolog
Predefined rules and external procedures Aociation
HERITAGE
known(T)
Function : Verifies that T represents a known tree.
Error message : No
Description:
Executes successfully if the term T represents a sufficiently known term, i.e. a
tree:
• whose label is known
• whose number of sons is known to be zero or not.
Fails otherwise.
T = E[L]
¬ known(L) known(L)
¬ known(E) free(T) ?
known(E) ? known(T)
Examples:
> known(E[<>]);
> known(tree);
> known(tree[U]), {U#<>};
{ U=X1.X2, X1::1 }
> known(+X);
>
See also:
• free, bound
282 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Error message : No
Description
Sets the constraint {U1 = U2.U3}, where U2 is a tuple formed from the largest
known sequence of first elements of U1. By "known" we mean "has a
known label" and "has a number of sons which is known to be zero or not".
Examples
© PrologIA 283
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Error message : No
Description:
Sets the constraint {N3 = N3'}, where N3' is the lowest common multiple of
the integers N1 and N2. This primitive fails if N1 and N2 are not known or
are not integers.
Examples:
> lcm(12,18,P);
{ P = 36 }
> lcm(12,-18,P);
{ P = -36 }
>
See also:
• ppcm
• pgcd, gcd
284 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
line
Function : Skips a line
Error message : No
Description:
Writes a carriage return on the current output unit
Example:
> line;
{}
>
See also:
• outl, outml
© PrologIA 285
Prolog
Predefined rules and external procedures Aociation
HERITAGE
list
Function : Prints rules
Error message : No
Description:
All the rules in the module determined by the default prefix of the current
context are listed on the current output unit;
Note:
The rules are first decoded and then listed on the current output unit.
Therefore their original form may be slightly altered.
286 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
list(T)
Function : Prints rules
Description:
Lists the groups of rules specified by T on the current output. T must be a
term with the following form (s denotes a character string, i an identifier,
and v a variable):
s All the groups of rules from the module corresponding to the
prefix s
i The group (or groups) of rules which has i as its access.
[i1, i2, … in]
The group (or groups) of rules which has i1 as its access, then
the group (or groups) which has i2 as its access, and so on.
v All the groups of rules from the module corresponding to the
default prefix. v is unified with the pair <ident, arity>..
© PrologIA 287
Prolog
Predefined rules and external procedures Aociation
HERITAGE
list(<I, A>)
Function : Prints rules
Description:
Lists the group (or groups) of rules with name I and arity A from the
module determined by the default prefix of the current context (V denotes a
variable.
<I, A> All the rules constituting the group with name i and arity A.
<I, V> All the rules whose access is I, regardless of their arity.
<V, A> All rules with arity A that belong to the module with the default
prefix of the current reading/writing context, whose arity is A.
288 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Description:
Lists each group of rules denoted by the elements in the list, in the same way
as list(<A,I>).
© PrologIA 289
Prolog
Predefined rules and external procedures Aociation
HERITAGE
list(<I, A>,N)
Function : Prints rules
Description:
Rule number N from the group corresponding to the name I and with arity
(number of arguments) A is listed on the current output unit These three
parameters can each be represented by a variable.
290 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
list_string(L, S)
Function : List/string conversion
Error message : No
Description:
Sets the constraint {S = L'}, where L' is a string composed of characters
forming the list L.
Example:
See also:
• split
© PrologIA 291
Prolog
Predefined rules and external procedures Aociation
HERITAGE
list_tuple(L, U)
Function : List/tuple conversion
Error message : No
Description:
Sets the constraint {S = U'}, where U' is a tuple composed from the elements
which form the list L.
Example:
See also:
• split
292 © PrologIA
Prolog
Aociation
HERITAGE
Règles prédéfinies et procédures externes
lower_bound(R1, R2)
Function : Greatest lower bound of a numeric expression
Description:
Calculates the greatest lower bound m of R1 and adds the constraint R2 = m
to the current constraint system.
Causes an error when R1 cannot be numeric type (Error 60), or when the
numeric expression R1 is not bounded below (Error 59).
Examples:
Notes:
Remember that in the set of reals any non empty part that is bounded below
has a greatest lower bound. You should therefore ensure that R1 is
bounded below beforehand.
It should also be noted that the execution of lower_bound(R1, R2) does not set
the constraint R1 = R2.
The block primitive can be used to recover errors.
See also:
• upper_bound, maximum, minimum, maximize, minimize
© PrologIA 293
Prolog
Règles prédéfinies et procédures externes Aociation
HERITAGE
upper_bound(R1, R2)
Function : Least upper bound of a numeric expression
Description:
Calculates the least upper bound m of R1 and adds the constraint R2 = m to
the current constraint system.
Causes an error when R1 cannot be numeric type (Error 60), or when the
numeric expression R1 is not bounded above (Error 59).
Examples:
Notes:
Remember that in the set of reals any non empty part that is bounded above
has a least upper bound. You should therefore ensure that R1 is bounded
above beforehand.
It should also be noted that the execution of upper_bound(R1, R2) does not
set the constraint R1 = R2.
The block primitive can be used to recover errors.
See also:
• lower_bound, maximum, minimum, maximize, minimize
293 i © PrologIA
Prolog
Aociation
HERITAGE
Règles prédéfinies et procédures externes
maximize(R)
Function : Maximizes a numeric expression
Description:
Equivalent to (and more efficient than) maximum(R, R):
Examples:
Note:
Errors can be recovered in Prolog III using the block primitive.
See also:
• minimize, maximum, minimum, lower_bound, upper_bound
© PrologIA 293 ii
Prolog
Règles prédéfinies et procédures externes Aociation
HERITAGE
maximum(R1, R2)
Function : Maximum of a numeric expression
Description:
Calculates the maximum m of R1 and adds the constraint R2 = m to the
current constraint system.
Fails when R1 is bounded above and R1 cannot reach the maximum.
Causes an error when R1 cannot be numeric type (Error 60), or when the
numeric expression R1 is not bounded above (Error 59).
Examples:
Note:
Errors can be recovered in Prolog III using the block primitive.
See also:
• minimum, lower_bound, upper_bound, maximize, minimize
HERITAGE
Règles prédéfinies et procédures externes
minimize(R)
Function : Minimizes a numeric expression
Description:
Equivalent to (and more efficient than) minimum(R, R)
Examples:
Note:
Errors can be recovered in Prolog III using the block primitive.
See also:
• maximize, maximum, minimum, lower_bound, upper_bound
© PrologIA 293 iv
Prolog
Règles prédéfinies et procédures externes Aociation
HERITAGE
minimum(R1, R2)
Function : Minimum of a numeric expression
Description:
Calculates the minimum m of R1 and adds the constraint R2 = m to the
current constraint system.
Fails when R1 is bounded below, and R1 cannot reach the minimum.
Causes an error when R1 cannot be numeric type (Error 60), or when the
numeric expression R1 is not bounded below (Error 59).
Examples:
Note:
Errors can be recovered in Prolog III using the block primitive.
See also:
• maximum, lower_bound, upper_bound, maximize, minimize
294 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Description:
Sets the constraint {N3 = R}, where R is the modulo from integer division of
the absolute value of N1 by the absolute value of N2. Care must be taken
not to confuse the predicate with the evaluable function of the same name
(see predefined rule val).
Examples:
> mod(9,2,R);
{ N = 1 }
> mod(7,N1,N2):
>
See also:
• div
• trunc
© PrologIA 295
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Error messages : No
Description:
Specifies that all rules located between the calls to the module and end_module
primitives describe the same module. For more details concerning these
quite complex concepts, the reader should refer to the chapter
“Environment”. Remember that P1 is the module prefix, S1 is the explicit
sequence, S2 is the implicit sequence, and P2 is the default prefix.
The module primitive can be used with just the first, the first two, or the first
three arguments, in the precise circumstances described in the
“Environment“ chapter.
See also:
• end_module
• set_context, current_context, close_context_dictionary
• add_implicit, remove_implicit, dictionary
296 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Error messages : No
Description:
Sets the constraint {N3 = N1*N2} with delays if necessaary.
Examples:
> mult(X,Y,Z);
{ Z = X * Y }
>
See also:
• bound_mult
© PrologIA 297
Prolog
Predefined rules and external procedures Aociation
HERITAGE
new
Function : Deletes rules from a module
Error messages : No
Description:
Deletes all the rules in the module specified by the default prefix of the
current context. Unlike kill_module the module arrays are not deallocated,
and module identifier assignments are not canceled.
Example:
See also:
• kill_module
298 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
next_char(C)
Function : Reads a character in advance
Error messages : No
Description:
Sets the constraint {C = C'}, where C' is the next character to be detected on
the current input unit, without actually reading it.
See also:
© PrologIA 299
Prolog
Predefined rules and external procedures Aociation
HERITAGE
next_char'(C)
Function : Reads a character in advance which is not a
formatting character
Class : Prolog III external procedure (II+)
Category : Input/output
Description:
Sets the constraint {C = C'}, where C' is the next character to be detected
which is not a formatting character on the current input unit, without
actually reading it. In fact, all characters whose ASCII code is less than or
equal to 32 are ignored.
See also:
• in_char, in_char', in_ident, in_integer, inl, in_real, in_sentence, in_string,
in_term, next_char
300 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
no_debug
Function : Deactivates the debugger
Error messages : No
Description:
Cancels the effect of the debug primitives and any call to the debugger
resulting from the use of the set_config primitive.
See also:
© PrologIA 301
Prolog
Predefined rules and external procedures Aociation
HERITAGE
no_echo
Function : Cancels echo on the console
Error message : No
Description:
Cancels the effect of the echo primitive.
See also:
• echo
• set_config, set_configuration, get_config, get_configuration
301 i © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
no_spy(<I, N>)
no_spy(S)
Function : Removes spy points on a procedure
Description :
Removes any spy point set on one or several groups of rules.
In the first form, the procedure is specified by its name I and/or its arity A
(at least one of the two parameters must be known). Fails if there is no such
procedure.
In the second form, spy points are removed from all the procedures
belonging to the module denoted by the string S. Causes an error if there is
no such module.
Please refer to the chapter “Debugging Prolog III programs” for the
definition and use of spy points.
Voir également :
• spy
• debug, no_debug
© PrologIA 301 ii
Prolog
Predefined rules and external procedures Aociation
HERITAGE
no_trace
Function : Cancels the trace
Error message : No
Description:
Cancels the effect of the trace primitives and any trace resulting from use of
the set_config primitive. Returns to normal Prolog III interpretation mode for
program execution.
See also:
302 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
not(T)
Function : Negation by failure
Error message : No
Description:
Performs negation by failure. Here is the complete not(T) rule:
not(P) :- P, !, fail .
not(P) .
Note
Since not starts a goal, its behavior may depend on the position of the
"undefined_rule" parameter in the set_config primitive, if undefined goals are
likely to be started.
© PrologIA 303
Prolog
Predefined rules and external procedures Aociation
HERITAGE
num(R)
Function : Verifies that R represents a known number.
Error message : No
Description:
This predefined rule verifies that R is a term representing a known numeric
value. Fails otherwise.
Examples:
> num(1960);
{}
> num(3X+2);
>
> num(X),{X>0,Y>0,X+Y=12,2X+4Y=34};
{ X = 7, Y = 5 }
>
Notes:
This predefined rule does not only test whether R represents a numeric
value (the predefined rule is_num(R) performs this verification).
It also enables the term R to be constrained to represent a known numeric
value, in a case where R represents the same value in all the solutions of the
current constraint system, (see the third example above).
304 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Known parameters : R
Error messages : No
Description:
Sets the constraints {N1 = N1', N2 = N2'}, where N1' is the numerator of R,
and N2' the denominator of N2. The rule fails if R is not known.
Examples:
> numden(17,N1,N2);
{ N1 = 17,N2 = 1 }
> numden(9/6,N1,N2);
{ N1 = 3,N2 = 2 }
> numden(R,14,2);
>
© PrologIA 305
Prolog
Predefined rules and external procedures Aociation
HERITAGE
out(T)
Function : Writes terms
Error message : No
Description:
Writes the term T on the current output unit, without the constraints
associated with the variables that may appear in this term.
See also:
306 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
outc(T)
Function : Writes terms with constraints
Error message : No
Description:
Writes the term T on the current output unit, with the constraints associated
with the variables that may appear in this term.
See also:
© PrologIA 307
Prolog
Predefined rules and external procedures Aociation
HERITAGE
outl(T)
Function : Writes terms with <CR>
Error message : No
Description:
Writes the term T on the current output unit without the constraints
associated with the variables that may appear in this term, followed by a
carriage return.
See also:
308 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Description:
Writes the strings S1, S2, …, SN (N 1) on the current output unit. An error
is indicated if one of the strings is not known.
See also:
© PrologIA 309
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Description:
Writes the strings S1, S2, …, SN (N 1) on the current output unit, followed
by a carriage return. An error is indicated if one of these strings is not
known.
See also:
310 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
output(F)
Function : Definition of the current output unit
Error message : No
Description:
The unit with name F becomes the current output unit. If this unit does not
appear among the open units a file with the name F is created. Otherwise,
this unit goes to the top of the stack, unless it was there already.
© PrologIA 311
Prolog
Predefined rules and external procedures Aociation
HERITAGE
output_is(F)
Function : Provides the current output unit
Error messages : No
Description:
Sets the constraint {F = S}, where S is a character string describing the
current output unit.
Examples:
> output_is(X);
{ X = "console" }
>
See also:
• input, input_is, output
312 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
particular_value(R1, R2)
Function : Searches for a particular solution
Error message : No
Description:
Sets the constraint {R2 = R1'}, where R1' is any value of the term R1 which
satisfies the current set of constraints.
Examples
Notes
© PrologIA 313
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Error messages : No
Description:
Sets the constraint {N3 = N3'}, where N3' is the greatest common divisor of
the integers N1 and N2. The calculated greatest common divisor does not
take account of the sign. pgcd fails if N1 and N2 are not known or are not
integers.
Examples:
> pgcd(24,16,P);
{ P = 8 }
> pgcd(24,-16,P);
{ P = 8 }
>
See also:
• gcd
• ppcm, lcm
314 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Error messages : No
Description:
Sets the constraint {N3 = N3'}, where N3' is the lowest common multiple of
the integers N1 and N2.. ppcm fails if N1 and N2 are not known or are not
integers.
Examples:
> ppcm(12,18,P);
{ P = 36 }
> ppcm(12,-18,P);
{ P = -36 }
>
See also:
• lcm
• pgcd, gcd
© PrologIA 315
Prolog
Predefined rules and external procedures Aociation
HERITAGE
predefined(T)
Function : Tests whether the term T is a predefined rule or a
built-in predicate.
Class : Prolog III predefined rule (II+)
Category : Control
Known parameters : T
Error messages : No
Description:
Executes successfully if T is a term corresponding to a call to a predefined
rule or built-in predicate.
Examples:
> predefined(list);
{}
> predefined(predefined[U]);
{ U !tuple, U :: 1 }
> predefined(myrule);
>
316 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
prologIII
Function : Switches to Prolog III syntax
Error messages : No
Description:
Switches to Prolog III syntax if Prolog III is currently being used. Behaves in
exactly the same way as the call
set_config("syntax","Prolog III")
See also:
• edinburgh, set_config, set_configuration
© PrologIA 317
Prolog
Predefined rules and external procedures Aociation
HERITAGE
quit
Function : To leave Prolog III
Error message : No
Description:
Leaves Prolog III without saving anything.
See also:
• quit(N)
318 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
quit(N)
Function : To leave Prolog III
Error messages : No
Description:
Leaves Prolog III without saving anything. If N has the value 0, this value is
converted into the code corresponding to "no error" for the operating
system. Other values for N are not converted. This code is then transmitted
to the operating system as a "termination status".
Notes:
See also:
• quit
© PrologIA 319
Prolog
Predefined rules and external procedures Aociation
HERITAGE
rational(R)
Function : Verifies that R is a known rational number.
Error message : No
Description:
Executes successfully if R represents a known non integer rational value.
Fails otherwise.
Examples:
> rational(3004/1960);
{}
> rational(31.897);
>
rational(6/3);
>
rational(X);
>
320 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
real(F)
Function : Verifies that F is a known floating number.
Error message : No
Description:
Executes successfully if F represents a known floating number. Fails
otherwise.
Examples:
> real(3004.1960e20);
{}
>
real(31/897);
>
real(1.0);
{}
> real(X+2.0);
>
© PrologIA 321
Prolog
Predefined rules and external procedures Aociation
HERITAGE
redef_array(I,N)
Function : Modifies the size of an array.
Description:
Modifies the size allocated to an array created by the def_array primitive.
Examples:
See also:
322 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
reinsert
Function : Inserts rules from the input unit
Description:
This predefined rule switches the system into a mode in which rules, read on
the current input unit are added to the current program, in the order they
are read. The reinsert mode terminates either when an empty rule is found,
or when the end of the input file is reached.
Example:
> reinsert;
conc([],y,y) ->;
conc([e|x],y,[e|z]) -> conc(x,y,z);;
{}
>
See also:
• insert
© PrologIA 323
Prolog
Predefined rules and external procedures Aociation
HERITAGE
reinsert(F)
Function : Inserts rules from a file
Description:
Inserts rules from a file called F. The only difference from the insert
predicate is that if a group already exists, reinsert replaces the former group
with its new definition. However be very careful because this can be
dangerous: when using reinsert, a mistake in the number of aruments of a
rule inside a group will destroy the previous rules when reading of the
group continues.
See also:
• insert
324 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
reload(F, L)
Function : Loads saved modules
Description:
Loads saved modules. F (character string) is a file name and L is a “prefix
substitution list”. This command loads the saved modules in the indicated
file which must have been created using the commands save or exit.
Example:
> reload("myfile.mo",[<"data","donnees">]);
{}
>
Notes:
© PrologIA 325
Prolog
Predefined rules and external procedures Aociation
HERITAGE
remove_implicit(S1, S2)
Function : Modifies the context
Description:
Removes the identifier with the abbreviated name S2 from the closed part of
the family corresponding to prefix S1.
See also:
• add_implicit, dictionary
• set_context, current_context, close_context_dictionary
• module, end_module
326 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
repeat
Function : Looping
Error messages : No
Description:
It simply consists of the following predicate:
repeat -> ;
repeat -> repeat;
© PrologIA 327
Prolog
Predefined rules and external procedures Aociation
HERITAGE
reset_cpu_time
Function : Initializes cpu time
Error message : No
Description:
Reinitializes cpu time.
See also:
• cpu_time
328 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
resume_trace
Function : Restarts the trace if it has been suspended by the
suspend_trace primitive.
Class : Prolog III external procedure (II+)
Category : Environment
Description:
Restarts the trace if it was activated, and then suspended by suspend_trace.
Combined use of these two primitives is extremely useful when we want to
delete the trace of certain predicates. This is done by enclosing the predicate
with suspend_trace and resume_trace . If no trace has been activated,
suspend_trace executes without having any effect.
Examples:
> try ->
suspend_trace
outml("`no trace")
resume_trace ;
> trace line try line;
line
try = try
suspend_trace
no trace
line
{}
> no_trace;
no_trace
{}
> essai;
no trace
{}
>
See also:
• trace, no_trace, set_config, suspend_trace
© PrologIA 329
Prolog
Predefined rules and external procedures Aociation
HERITAGE
retract(T,Q)
Function : Deletes rules corresponding to a given pattern.
Error messages : No
Description:
Searches for and deletes rules whose head unifies with T and whose goals
unify with the elements in the list Q. However, the term T must be
sufficiently known to prevent any ambiguity concerning the names of the
targeted rules.
Examples:
> toto(aa) ->;
> toto(bb) ->;
> toto(x) -> titi(x,y) tutu(z,y);
> retract(toto(X),[]);
{ X = aa }
{ X = bb }
> list;
toto(x) ->
titi(x,y)
tutu(z,y) ;
{}
> retract(toto(aa),[titi[U], tutu[V]]);
{ U = <aa,y_8>, V = <z_8,y_8> }
> list;
{}
>
See also:
• suppress, assert, list
330 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
rule(T, Q)
Function : Searches for rules
Description:
Searches for rules corresponding to a given pattern. This primitive executes
as many times as there are rules whose head unifies with T and whose body
unifies with Q. If no such rule exists, rule(T,Q) produces an error.
Example:
> list;
conc([],L,L)->;
conc([A/L],L',[A/L'']) ->
conc(L,L',L'');
{}
> rule(conc(X,Y,Z),Q);
{ X = [], Z = Y, Q = [] }
{ X = [v149/v150], Z = [v149/v151],
Q = [conc(v150,y,v151)] }
> rule(concatenate(X,Y,Z),Q);
>
Note:
© PrologIA 331
Prolog
Predefined rules and external procedures Aociation
HERITAGE
rule(N,T,Q)
Function : Searches for rules
Description:
Searches for rules corresponding to a given pattern. This primitive searches
for a rule whose head unifies with T, the body with Q and has the rank N in
its group. If such a rule does not exist, rule(N,T,Q) produces an error.
Example:
> list;
conc([],L,L)->;
conc([A/L],L',[A/L'']) ->
conc(L,L',L'');
> rule(2,conc(X,Y,Z),Q);
{ X = [v149/v150], Z = [v149/v151],
Q = [conc(v150,y,v151)] }
>
Note:
332 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
rule(N,A,T,Q)
Function : Searches for rules
Description:
Searches for rules corresponding to a given pattern. This primitive executes
as many times as there are rules whose head or head identifier unifies with
A. The pattern can be refined by specifying the head T, the body Q and the
rank in the group N. If such a rule does not exist, rule(N,A,T,Q) produces an
error.
Example:
> list;
conc([],L,L)->;
conc([A/L],L',[A/L'']) ->
conc(L,L',L'');
> rule(1,conc,T,Q);
{ T = conc([],v149,v149), Q = [] }
> rule(2,conc(X,Y,Z),T,Q);
{ X = [v149/v150], Z = [v149/v151],
T = conc([v149/v150],y,[v149/v151])
Q = [conc(v150,y,v151)] }
>
Note:
© PrologIA 333
Prolog
Predefined rules and external procedures Aociation
HERITAGE
rule_nb(<I, A>, N)
Function : Counts the rules in a group
Description:
Counts the rules in the group specified by identifier I and arity A. N is then
unified with the number of rules in this group. This primitive fails if I and A
are not known or if the group does not exist.
Example:
> list;
conc([],L,L)->;
conc([A/L],L',[A/L'']) ->
conc(L,L',L'');
> rule_nb(<conc,3>,N);
{ N = 2 }
>
See also:
• rule, current_predicate
334 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
save
Function : Saves modules
Error message : No
Description:
Saves modules. This command saves all elements (rules, static variables and
arrays) from all modules in a file called prolog3.psv.
Note:
The resulting file is a object code file, which can subsequently be loaded in
another Prolog environment by means of the reload command.
See also:
• reload
• exit, quit
© PrologIA 335
Prolog
Predefined rules and external procedures Aociation
HERITAGE
save(S)
Function : Saves modules
Description:
Saves modules. This command saves all elements (rules, static variables and
arrays) from all modules in a file called S (character string).
Note:
The resulting file is a object code file, which can subsequently be loaded in
another Prolog environment by means of the reload command.
See also:
• reload
• exit, quit
336 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
save(L,S)
Function : Saves modules
Description:
Saves modules. S is a file name (character string) and L is a list of prefixes
(character strings). This command saves all elements (rules, static variables
and arrays) from modules corresponding to the prefixes specified in list L, in
the file indicated by S.
Example:
Note:
The resulting file is an object code file, which can subsequently be loaded in
another Prolog environment by means of the reload command. This file is
not a text file and thus cannot be used with input or insert predicates.
See also:
• reload
• exit, quit
© PrologIA 337
Prolog
Predefined rules and external procedures Aociation
HERITAGE
set_config(S, V)
Function : Modifies certain parameters
Error message : No
Description:
This predicate is used to specify certain aspects of Prolog III behavior listed
below. For each aspect, we indicate the string which must be provided as the
first parameter.
Below are the possible values for each string, and their default values.
machine_mode :
• 0: normal interpretation mode (without debugger or trace).
• 1: trace mode
• 2, 3 : debug mode.
Default value: 0
338 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
tracemode :
• 1 : Level 1 trace: displays the predicate name.
• 2: Level 2 trace: displays the predicate name and its arguments.
• 3: Level 3 trace: displays the predicate name, its arguments and the
constraint system concerning the variables occuring in the
arguments.
Default value: 2
echo :
• 0 No echo
• 1 All rules or queries read on the current input unit are displayed on
the current output unit. If these rules are valid, they are first
encoded in a canonic form, then decoded and listed on the current
output.
Default value: 0
undefined_rule :
• "fail": Prolog failure without warning or error message.
• "warning": Prolog failure, with warning message (predicate with
arity i not defined or non executable goal).
• "error": produces an error (access not defined)
Default value: "warning"
interrupt_is_error :
• 0: Program interruption ( <Ctrl-C> on some machines) is
not treated as a Prolog error. A dialog, described in the
user's manual, is displayed and allows the user to
continue, abort, activate the trace or leave the Prolog III
session.
• 1: Program interruption causes a Prolog error to occur. The
corresponding message is “Err 16: User interrupt”. The
error can then be caught using the block mechanism.
Default value : 0
syntax :
• "Prolog III": Prolog III (II+) syntactic mode
• "Edinburgh": Edinburgh syntactic mode
Default value: "Prolog III"
© PrologIA 339
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Note:
If preferred, it is possible to start each Prolog III session in the Edinburgh
syntactic mode. To do this, simply start the session by positioning the
"syntax" option on Edinburgh, and then save the current state using the exit
command. Each user should first be asked to rename the initial3.psv file, so
that a copy of the original version remains.
tty_wrap :
• An integer between 10 and 4000 representing the maximum permitted
length for a written line on the current output unit.
Default value: 130
format_out_num :
• "Fnormal" Display of rationals in infinite precision, and floating
numbers in scientific notation.
• "Fexact" Display of rationals in infinite precision, and floating
numbers are converted into rationals.
• "Fdecimal" Decimal display.
• "Ffloat" Display in scientific notation.
• "Fint+fract" Display in the form integer part + fraction part, if the
latter is not null.
Default value: Fnormal
Examples:
> set_config("format_out_num","Fnormal")
{X = 120/36, Y = 1.5};
{ X = 10/3, Y = 1.500000000000000e+00 }
> set_config("format_out_num","Fexact")
{X = 120/36, Y = 1.5};
{ X = 10/3, Y = 3/2 }
340 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
> set_config("format_out_num","Fdecimal")
{X = 120/36, Y = 1.5};
{ X = 3.333, Y = 1.5 }
> set_config("format_out_num","Ffloat")
{X = 120/36, Y = 1.5};
{ X = 3.333333333333333e+00, Y = 1.500000000000000e+00 }
> set_config("format_out_num","Fint+fract")
{X = 120/36, Y = 1.5};
{ X = (3+1/3), Y = (1+1/2) }
>
format_float
• A string representing an input/output format accepted by the C language
function printf(). In addition this string must start with the character %
and contain less than 19 characters.
Default value: "%.15le"
format_decimal
• An integer between 0 and 7 representing the number of digits displayed
after the decimal point )
Default value: 3
epsilon_float
• Floating number between 10-4 and 10 -12 representing the relative
tolerance interval permitted when comparing floating numbers.
Default value: 10-7
statistics :
• 0 No statistics
• 1 Display of execution statistics
Default value: 0
See also:
• set_configuration, get_config, get_configuration
• echo, no_echo, trace, no_trace, debug, no_debug
• edinburgh, prologIII
© PrologIA 341
Prolog
Predefined rules and external procedures Aociation
HERITAGE
set_configuration(U)
Function : Modifies certain parameters
Error message : No
Description:
Same functionality as set_config, but U is a tuple of <field, value>pairs. It is
thus possible to specify simultaneously the values of several fields.
Example:
> set_configuration(<<"syntax","Edinburgh">,
<"format_out_num","Ffloat">>);
{}
?- {X = 12}.
{ X = 1.200000000000000e+01 }
?-
See also:
• set_config, get_config, get_configuration
342 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
Error message : No
Description:
This command is used to describe a context and install it as the current
reading/writing context. When a new context is activated, the previous
context is no longer taken into account.
Please refer to "Structuring, recording and modifying rules " in the chapter
entitled "Programming control and environment" for an explanation of the
meaning of the arguments:
I : name of the newly defined context
S : explicit sequence
S' : implicit sequence
D : default prefix
© PrologIA 343
Prolog
Predefined rules and external procedures Aociation
HERITAGE
set_ident(I, N)
Function : Assigns an attribute to an identifier
Description:
This primitive associates a number with an identifier. It is mainly used to
associate a logical name with a number used in the userrule file to define an
external procedure. For more details concerning the definition of primitives
by the user, please consult the user's manual.
344 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
size(U, N)
Function : Size of a tuple
Error message : No
Description:
Sets the constraint {U :: N}, with the necessary delays if N or U are not
known..
See also:
• bound_size
© PrologIA 345
Prolog
Predefined rules and external procedures Aociation
HERITAGE
split(U, L)
Function : Splits a tuple
Error message : No
Description:
Splits a tuple (or therefore a string) into a list of its elements, i.e. it sets the
constraint {L = U'}, where U' is the list of elements of a tuple U. Fails if U is
not known at execution.
Examples:
> split("abcde",V);
{ V = [`a`,`b`,`c`,`d`,`e`] }
> split(<1,2,3>,V);
{ V = [1,2,3] }
> split(U,V), {U !tuple, U::3};
{ U = <X1,X2,X3>, V = [X1,X2,X3] }
See also:
• list_string, list_tuple
346 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
spy(<I, N>)
spy(S)
Function : Spies on a group of rules
Description:
Monitors one or several procedures by installing spy points.
In the first form, the procedure is specified by its name I and/or its arity A
(at least one of the two parameters must be known). Fails if there is no such
procedure.
In the second form, all the rules belonging to the module denoted by the
string S are specified as spy points for debugging. Causes an error if there is
no such module.
Please refer to the chapter “Debugging Prolog III programs” for the
definition and use of spy points.
See also:
• no_spy
• debug, no_debug
© PrologIA 346 i
Prolog
Predefined rules and external procedures Aociation
HERITAGE
346 ii © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
state
Function : Displays the occupation of certain Prolog zones.
Error message : No
Description:
Displays the current state of the stacks.
Example:
> state;
copy stack : 977/799900 lwords 0 %
back stack : 0/200000 lwords 0 %
rule space : 48235/100000 lwords 48 %
dictionary (acces) : 20556/36864 bytes 55 %
dictionary (names) : 4053+12144/32784 bytes 49 %
{}
>
© PrologIA 347
Prolog
Predefined rules and external procedures Aociation
HERITAGE
string(S)
Function : Verifies that S is a known string
Error message : No
Description:
• Executes successfully if S represents an entirely known string. Fails in all
other cases.
Examples:
348 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
string_bool(S, B)
Function : Converts a string into a boolean
Error messages : No
Description:
• If S is known sets the set of constraints {B = S'} where S' is a boolean
formed by the characters in the string S.
Examples:
> string_bool(S,1');
{ S = "1'" }
> string_bool("0'",B);
{ B = 0' }
>
© PrologIA 349
Prolog
Predefined rules and external procedures Aociation
HERITAGE
string_ident(S, I)
Function : Converts a string into an identifier
Error message : No
Description:
• If S is known it sets the set of constraints {I = I'}, where I' is an identifier
constituted by the characters of the string by which it is represented.
Examples:
> string_ident(S,history:valmy);
{ S = "history:valmy" }
> string_ident("history:valmy",I);
{ I = history:valmy }
350 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
string_ident(P,S, I)
Function : Converts a string into an identifier
Error message : No
Description:
• If I is known it sets the set of constraints: {S = S', P = P'} where S' is a
string constituted by the characters of the abbreviated representation of
of identifier I., and P' is a string constituted by the characters forming the
prefix of the identifier P.
• If S and P are known it sets the set of constraints {I = I'}, where I' is an
identifier constituted by the characters of the string representing its prefix
P, and by those of the string representing its abbreviated notation, S..
Examples:
> string_ident(P,S,history:valmy);
{ P = "history", S = "valmy" }
> string_ident("history","valmy",I);
{ I = history:valmy }
> string_ident("geography:river","Seine",I);
{ I = geography:river:Seine }
> string_ident("geography","river:Seine",I);
>
© PrologIA 351
Prolog
Predefined rules and external procedures Aociation
HERITAGE
string_integer(S,N)
Function : Converts a string into an integer
Description:
• If S is known it sets the set of constraints {I = S'} where S' is an integer
formed from the characters of the string S.
Examples:
> string_integer("12",N);
{ N = 12 }
> string_integer(S,24/2);
{ S = "12" }
> string_integer("12.3",N);
Error 234 : integer expected
>
352 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
string_real(S,F)
Function : Converts a string into a floating number
Error message : No
Description:
• If S is known it sets the set of constraints {F = S'} where S' is a floating
number formed by the characters of the string S.
• If F is known its sets the set of constraints {S = F'}, where F' is a string
fromed by the characters which compose the floating number F.
Examples:
> string_real("3.14e5",F);
{ F = 3.140000 e+05 }
> string_real(S,3.14e5);
{ S = "3.140000 e+05" }
>
© PrologIA 353
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Error message : No
Description:
Sets the constraint {S2 = S1'}, where S1' is the sub-string of S1 starting at the
position N1, and of length N2. Fails if no such sub-string exists or if S1 is not
known.
Example:
> substring("1234567890",3,4,X);
{ X = "3456" }
>
354 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
suppress(I)
Function : Deletes a group of rules
Description:
Deletes all the group of rules with name I . Fails if I is unknown or if no such
group exists.
Examples:
> try(1)->;
> try(2)->;
> try(1,2)->;
> try(X);
{ X = 1 }
{ X = 2 }
> suppress(try);
{}
> try(X);
>
try(X,Y);
{ X = 1,Y = 2 }
>
© PrologIA 355
Prolog
Predefined rules and external procedures Aociation
HERITAGE
suppress(I, A)
Function : Deletes a group of rules
Description:
Deletes all of the rule group with name I and arity A. Fails if I or A are not
known, or if no such group of rules exists.
Examples:
> try(1)->;
> try(2)->;
> try(1,2)->;
> try(X);
{ X = 1 }
{ X = 2 }
> suppress(try,1);
{}
> try(X,Y);
{ X = 1,Y = 2 }
>
356 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
suppress(I, A, N)
Function : Deletes one rule
Description:
Deletes rule number N from the group of rules with name I, and arity A.
Succeeds, but without executing, if no rule corresponds. Fails if the
arguments are unknown or of the wrong type.
Examples:
> try(1)->;
> try(2)->;
> try(1,2)->;
> try(X) try(Y,Z);
{ X = 1, Y = 1, Z = 2 }
{ X = 2, Y = 1, Z = 2 }
> suppress(try,1,2);
{}
> try(X) try(Y,Z);
{ X = 1, Y = 1, Z = 2 }
>
© PrologIA 357
Prolog
Predefined rules and external procedures Aociation
HERITAGE
suspend_trace
Function : Cancels the trace if it is active
Error messages : No
Description:
Cancels the trace if it is active, up to the next resume_trace. Combined use of
these two primitives is extremely useful when we want to delete the trace of
certain predicates. This is done by enclosing these predicates with the
primitives suspend_trace and resume_trace. If no trace has been activated, the
calls to suspend_trace and resume_trace do not have any effect.
Examples:
> try ->
suspend_trace
outml("no trace")
resume_trace ;
> trace line try line;
line
try = try
suspend_trace
no trace
line
{}
> no_trace;
no_trace
{}
> try;
no trace
{}
>
See also:
• trace, no_trace, set_config, resume_trace
358 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
sys_command(S)
Function : Executes an operating system command
Description:
Executes an operating system command represented by the string S. Please
consult the user's manual of your operating system for the list and syntax of
available commands.
© PrologIA 359
Prolog
Predefined rules and external procedures Aociation
HERITAGE
trace
Function : Traces the execution of a program
Error message : No
Description:
Program trace mode. The equality constraints between the goals and the
rule heads before unification are printed on the current trace output unit.
Backtracking points are displayed.
set_config("machine_mode", 1)
See also:
360 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
trace_file(S)
Function : Redirects the trace
Error messages : No
Description:
Redirects a program execution trace into a file whose name is defined by the
character string S.
If the character string is the empty string, the trace is redirected to the trace
unit defined at start-up of Prolog III.
This file used will only be closed by the next trace_file (e.g. the user can use
trace_file("") )
See also:
• trace, no_trace
© PrologIA 361
Prolog
Predefined rules and external procedures Aociation
HERITAGE
trunc(R, N)
Function : Integer part
Description:
Sets the constraint {N = R'}, where R' is the integer part of the number R.
Examples:
> trunc(5/4,N);
{ N = 1 }
> trunc(-3.56,N);
{ N = -4 }
>
362 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
tuple(U)
Function : Verifies that U is a known tuple.
Description:
Executes successfully if U represents a known tuple, i.e. its number of sons is
known to be zero or not. Fails otherwise.
Examples:
> tuple(<>);
{}
> tuple(<1,0',ceslawi>);
{}
> tuple("known");
{}
> tuple(<>[X]);
>
tuple(<A,B,C>);
{}
> tuple(U), {U !tuple};
>
© PrologIA 363
Prolog
Predefined rules and external procedures Aociation
HERITAGE
undef_array(I)
Function : De-allocates an arrary created by def_array
Description:
De-allocates an array created by the def_array primitive, and recovers the
corresponding space.
Examples:
See also:
364 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
val(T1, T2)
Function : Evalutes an expression constructed from
evaluable functions.
Class : Prolog III external procedure (II+)
Category : Control
Description:
Evalutes the expression T1 and produces the result T2. The expression to
evaluate is constructed recursively from constants, identifiers, array
elements and evaluble functions.
Examples:
> val(add(mul(2,add(3,4)),1000),x);
{x=1014}
> val(2*(3+4)+1000,x);
{x=1014}
>
Notes:
Each evaluable function must have arguments of a precise type; there is no
automatic type conversion. When a function has an incorrect number of
arguments or when some of its arguments are of the wrong type, val
produces an error.
© PrologIA 365
Prolog
Predefined rules and external procedures Aociation
HERITAGE
Examples:
(1) if a constant k has been assigned to i (using the rule assign) then the value
of i is k.
(2) if no assignment has been performed on i, then the value of i is i itself.
Examples:
sub(t1, t2)
value(sub(t1, t2)) = value(t1) - value(t2).
The values of t1 and t2 must be numeric.
mul(t1, t2)
value(mul(t1, t2)) = value(t1) value(t2).
The values of t1 and t2 must be numeric.
div(t1, t2)
value(t1)
value(div(t1, t2)) =
value(t2)
This is the default integer quotient.
The values of t1 and t2 must be integers.
366 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
mod(t1, t2)
value(mod(t1, t2)) = value(t1) modulo value(t2).
The values of t1 and t2 must be integers.
trunc(t1)
value(trunc(t1)) = integer part of value(t1).
The value of t1 must be numeric.
eql(t1, t2)
value(eql(t1, t2)) = if value(t1) = value(t2) then 1 else 0.
The values of t1 and t2 must be constants of the same type.
inf(t1, t2)
value(inf(t1, t2)) = if value(t1) < value (t2) then 1 else 0.
The values of t1 and t2 must be constants of the same type. For integers and
reals, we take the "<" relation between numbers. For strings we take the
lexicographic order and for identifiers we take the lexicographic order of the
associated strings.
infe(t1, t2)
value(infe(t1, t2)) = if value(t1) value (t2) then 1 else 0.
The values of t1 and t2 must be constants of the same type. See inf.
sup(t1, t2)
value(sup(t1, t2)) = si value(t1) > value (t2) then 1 else 0.
The values de t1 and t2 must be constants of the same type. See inf.
supe(t1, t2)
value(supe(t1, t2)) = if value(t1) value (t2) then 1 else 0.
The values of t1 and t2 must be constants of the same type. See inf.
if(t, t1, t2)
value(if(t, t1, t2)) = if (value(t)0) then value(t1) else value(t2)
© PrologIA 367
Prolog
Predefined rules and external procedures Aociation
HERITAGE
abs(t)
value(abs(t)) = absolute value of value(t).
The following functions give a real number result. The trignometric
functions use angles expressed in radians.
atan(t)
value (atan(t)) = tangent arc of value(t).
cos(t)
value (cos(t)) = cosine(value(t)).
exp(t)
value (exp(t)) = exponential(value(t)).
ln(t)
value(ln(t)) = Napierian logarithm(value(t)).
rad(t)
value (rad(t)) = radian conversion (value(t)).
sin(t)
value(sin(t)) = sine(value(t)).
sqrt(t)
value(sqrt(t)) = square root(value(t)).
tan(t)
value(tan(t)) = tangent(value(t)).
See also
• assign, def_array, undef_array, redef_array
368 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
© PrologIA 369
Prolog
Predefined rules and external procedures Aociation
HERITAGE
370 © PrologIA
Prolog
Aociation
HERITAGE
Predefined rules and external procedures
© PrologIA 371
Prolog
Predefined rules and external procedures Aociation
HERITAGE
372 © PrologIA
Aociation Prolog
HERITAGE
This chapter contains all the predefined rules available in Prolog III only when using
Edinburgh mode. They are in alphabetical order.
Since most of these predicates have been adapted to the functionalities specific to
Prolog III, the compatibility is not total. Some of them are synonyms of the
primitives described in the previous chapter, others are more original.
HERITAGE
Identifier - Arity
In Edinburgh syntax, it is normal to find terms in the form I/N at the rule
management level, where I represents an identifier and N represents an
integer denoting an arity. For obvious reasons, it is impossible to form such
terms in Prolog III (an identifier cannot be divided by an integer). Another
method must therefore be used to write these terms. We have chosen the
tuple notation. The ident/arity pair will therefore be defined by
<ident,arity> .
374 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
abolish(I)
abolish(<I, A>)
Function : Deletes a group of rules
Description:
First form :
Deletes the whole group of rules with name I. Behaves like suppress(I) .
Second form:
Deletes the whole group of rules with name I whose arity is A. Behaves like
suppress(I, A) . Fails when the arguments are not known.
See also:
• retract
© PrologIA 375
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
assert(T)
assertz(T)
Function : Adds a rule at the end of its group
Description:
Adds a rule at the end of its group. T must be a term having one of the
forms described in the introduction. The rule head must be a tree labeled by
a known identifier.
The execution of assert(T) adds the rule or the fact T below the group of rules
having the same "name" as the head of T. For example, the effect of the
following two commands:
?- assert(conc([],Y,Y),[]).
{}
?- assert( conc([E|X],Y,[E|Z]):- conc(X,Y,Z) ).
{}
conc([], Y, Y).
conc([E|X], Y, [E|Z]) :- conc(X, Y, Z).
There are two ways of adding rules that comprise a constraint system. The
first method sets constraints outside the call:
376 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
?- assert(outside_of(X,[]),[]).
{}
?- assert( outside_of(X,[Y|Q]):-outside_of(X,Q) ) {X #
Y}.
{X # Y}
?- list.
outside_of(X,[]) .
outside_of(X,[Y | Q]) :-
outside_of(X, Q)
{X # Y }.
{}
?-
The second method consists in passing the whole rule as an argument (since
the whole rule is a term). In this case assert translates the terms placed in
braces into true constraints, if this is possible. These constraints are not
conserved after the call.
?- assert((a :- b, c)).
{}
?-
© PrologIA 377
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
asserta(T)
Function : Adds a rule at the start of its group
Class : Edinburgh primitive
Category : Rule and identifier management
Known parameters : T
Description:
Adds a rule at the start of its group. T must be a term having one of the
forms described in the introduction. The rule head must be a tree labeled by
a known identifier.
Execution of assert(T) adds the rule or the fact T above the group of rules
having the same "name" as the head of T. For example, the effect of the
following two commands:
conc([], Y, Y).
conc([E|X], Y, [E|Z]) :- conc(X, Y, Z).
All the remarks applying to assertz are also valid for this primitive.
378 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
atom(T)
Function : Verifies that T is a known identifier
Class : Edinburgh primitive
Category : Type verification
Known parameters : None
Description:
Verifies that T is a known identifier. Fails otherwise. Behaves like the goal
ident(T) .
© PrologIA 379
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
atomic(T)
Function : Verifies that T is an atom
Class : Edinburgh primitive
Category : Type verification
Known parameters : None
Description:
Verifies that T is a known atom, i.e. that T is known, and that T is either a
number, an identifier, a boolean, a character or the empty tuple <> . Fails in
all other cases. It should be noted that a character string is not an atom,
since it can be divided up into characters.
See also:
• bound, known
380 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
call(P)
Function : Execution of a goal
Class : Edinburgh primitive
Category : Control
Known parameters : P
Description:
Executes the goal P. The primitive Call is defined by the following rule:
call(X) :- X .
© PrologIA 381
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
clause(T, Q)
Function : Obtains the head and body of a rule
Class : Edinburgh primitive
Category : Rule and identifier management
Known parameters : T
Description:
Unifies T and Q with the head and body respectively of all the clauses whose
accesses are defined by T. Behaves like rule apart from the structure of the
body. The body is represented by the identifier sys:true when it is empty, by
a term when it only comprises a single goal, and by a combed structure
labeled ',' in all other cases.
Notes:
At present it is not possible to recover the set of constraints in this rule in the
form of terms. These constraints are set immediately upon unification of the
head, and thus apply to the variables of T and of Q .
Examples:
?- consult("user").
different(A, B) {A#B}.
rule(A,B) :- a(A) {A#B}.
long_rule(A,B) :- a(A),b(B) {A#1}. .
?- clause(different(U,V), Body).
{ Body=true, U#V }
?- clause(rule(U,V), Body).
{Body=a(U), U#V}
?- clause(long_rule(U,V), Body).
{ Body=','(a(U), b(V)), U#1 }
?-
See also:
• rule
382 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
consult(S)
Function : Inserts rules
Class : Edinburgh primitive
Category : Input/output
Known parameters : F, which must be a string or an identifier
Description:
This predefined rule is used to add statements (rules) in the order they are
read from the file F. When F is an identifier, it is the string corresponding to
its abbreviation which is taken as the file name (the prefix is thus ignored).
When this string is "user", the read file is the console. Reading ends when
the end of file is reached or when an empty rule is read (an empty rule
consists of a "." followed by a space).
insert causes an error when a group is read which already exists. In this case
Prolog III leaves "insertion mode", but does not close the files which were
open. It therefore continues to reads the current file(s); the facts and queries
are executed, the rules cause syntax errors.
See also:
• reconsult, insert
© PrologIA 383
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
functor(T, E, N)
Function : General tree constructor
Class : Edinburgh primitive
Category : Trees, lists and tuples
Known parameters : None
Description:
Associates a tree T with its label E and its arity N . At present, this primitive
is written:
functor(E[U], E, N) {U :: N}.
Examples:
?- functor(a(b,c), X, N).
{ X=a, N=2 }
?- functor(T, a, 2).
{ T=a[U_1], U_1::2 }
?-
384 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
get(X)
Function : Gets the code of a non blank read character
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
X is unified with the ASCII code number of the first non blank character
read on the current input. The underlying primitive is in_char' . The
character is converted into ASCII code by means of the primitive char_code .
See also:
• in_char', get0
© PrologIA 385
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
get0(X)
Function : Gets the code of the next read character
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
X is unified with the ASCII code number of the next character read on the
current input. The underlying primitive is in_char . The character is
converted into ASCII code by the primitive char_code .
See also:
• in_char, get
386 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
is(X, T)
X is T
Function : Evaluates a tree
Description:
The term T is evaluated, and the value obtained is unified with X. The result
of evaluation of an identifer is the identifier itself, unless it has previously
been assigned a constant. Is is implemented by means of the primitive val :
X is Y :- val(Y, X).
Note:
The operators <, >, =<, >= are not available in the right-hand member of is.
inf, sup, infe, supe respectively must therefore be used in functional notation.
Examples:
?- X is add(exp(1.0), 1).
{ X=3.7182818284590e+00 }
?- Y is 3*4, X is add(2Y/4, sin(1)).
{ Y=12, X=6.8414709848078e+00 }
?- X is 3*4 < 44/3 . % put a blank between 3 and .
Error in val
?- X is inf(3,4).
{ X=1 }
?-
See also
• val
© PrologIA 387
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
listing
listing(I)
listing(<I, A>)
Function : Prints rules
Class : Edinburgh primitive
Category : Rule and identifier management
Known parameters : I and A
Description:
These primitives are respectively equivalent to:
list, list(I), list(<I,A>)
388 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
member(X, L)
Function : Searches for an element in a standard list
Class : Edinburgh primitive
Category : Trees, lists and tuples
Known parameters : None
Description:
Is described by the following rules :
member(X, [X|L]).
member(X, [_|L]) :- member(X, L).
Examples:
?- member(X, [1,2,3]).
{ X=1 }
{ X=2 }
{ X=3 }
?- member(3, [1,2,3]).
{}
?- member(2, [1,3,X]).
{ X=2 }
?-
© PrologIA 389
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
name(X, L)
Function : Converts constants into a list of character codes
Class : Edinburgh primitive
Category : Trees, lists and tuples
Known parameters : Either X , or L
Description:
If X is an identifier, a number, a character or a boolean, L is unified with the
list of ASCII codes of the characters that constitute the symbol X.
Examples:
?- name(12345678, L).
{ L=[49,50,51,52,53,54,55,56] }
?- name(X, [97,98,99]).
{ X=abc }
?- name(X, [65,66]). %Ascii codes of AB
Error: This is not an identifier
?-
See also:
390 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
nl
Function : Prints a carriage return on the current output
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
Writes a carriage return on the current output unit. Behaves like the line
primitive.
See also:
© PrologIA 391
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
nonvar(T)
Function : Verifies that T has a known label or a known list
of sons.
Class : Edinburgh primitive
Category : Control
Known parameters : None
Description:
nonvar(T) behaves like not(free(T)), i.e. nonvar succeeds if the label of T is
known or if we know whether or not the list of sons is empty or not. Fails
otherwise. The call nonvar(T) succeeds when var(T) fails and vice-versa .
See also:
392 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
number(R)
Function : Verifies that R ia a known number.
Class : Edinburgh primitive
Category : Type verification
Known parameters : See below
Description:
This predefined rule verifies that R is a term representing a known numeric
value. If this is not the case number(R) fails. number is a synonym of the num
primitive.
See also:
© PrologIA 393
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
op(N, I1, S)
op(N, I1, S, I2)
Function : Declares an operator
Description:
Declares the operator S with precedence N and the parenthesis type I1 . S is
an identifier or a character string whose contents do not start with a constant
or a variable or a space (in fact this string can contain an identifier if it is
completely filled by it). In the 3 argument form, S can be a list, in which case
the declaration applies to each element of the list. The functional symbol
represented by S is I2 if the latter is provided, otherwise by the quoted
symbol S. The associativity is specified by an identifier or a character string
combining one, two or three of the letters f,x,y with the following
conventions
Examples:
394 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
put(X)
Function : Sends the ASCII code X to the current unit
Class : Edinburgh primitive
Category : Input/output
Known parameters : X , which must an integer
Error messages : No
Description:
The ASCII character code X is sent to the current output unit. Fails if X is not
an integer.
Examples:
See also:
• out, outm
© PrologIA 395
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
read(X)
Function : Reads a term on the current unit.
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
Reads the next term on the current input. It must end in a dot followed by a
space (these characters are read). The argument X is then unified with this
term. This primitive is based on in_term .
Examples:
?- read(T).
[1,2].
{ T=[1,2] }
?-
See also:
• in_term
396 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
retract(X)
Function : Deletes rules according to a pattern
Class : Edinburgh primitive
Category : Rule and identifier management
Known parameters : X
Description:
Deletes all the rules which unify with X. X must be a term having one of the
forms described in the introduction. The rule head of X must be a tree
labeled by a known identifier. This primitive behaves like retract with arity
2, apart from the number of arguments
In a case where constraints in the form of terms placed in braces are given
in the rule, the primitive will "execute" these constraints, which are not
conserved after the call.
Examples:
?- consult("user").
titi(1) :- aa.
titi(2) :- aa.
titi(3) :- aa..
{}
?- retract(titi(X) :- aa {X#2}).
{ X=1 }
{ X=3 }
?-
See also:
• abolish, suppress
© PrologIA 397
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
retractall(T)
Function : Deletes rules according to a certain pattern
Class : Edinburgh primitive
Category : Rule and identifier management
Known parameters : T
Description:
Deletes all the rules whose head unifies with T , which is therefore not a rule
but a rule head. T must be a term whose label is a known identifier with a
known number of sons.
Examples:
?- consult("user").
titi(1) :- aa.
titi(2) :- bb.
titi(3) :- cc..
{}
?- retractall(titi(X)) {X#2}.
{ X=1 }
{ X=3 }
?-
See also:
398 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
see(F)
Function : Defines the current input unit.
Class : Edinburgh primitive
Category : Input/output
Known parameters : F which must be a string or an identifier
Description:
Behaves like input(F) if F is a string. If F is an identifier, it is the string
corresponding to its abbreviation which is taken as the name of the unit
passed to input (i.e. the prefix is ignored).
See also:
© PrologIA 399
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
seen
Function : Closes the current input unit
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
Behaves like close_input.
See also:
• input, close_input, see
400 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
tab(N)
Function : Prints N blanks on the current output
Class : Edinburgh primitive
Category : Input/output
Known parameters : N which must be a known integer
Description:
Sends N blanks to the current output unit. When N is not a known integer,
an error message is displayed.
See also:
© PrologIA 401
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
tell(F)
Function : Defines the current output unit
Class : Edinburgh primitive
Category : Input/output
Known parameters : F, which must be a string or an identifier.
Description:
Behaves like output(F) if F is a string. If F is an identifier, the string
corresponding to its abbreviation is taken as the unit name passed to the
output primitive (i.e. the prefix is ignored).
See also:
402 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
told
Function : Closes the current output unit
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
Behaves like close_output.
See also:
• output, close_output, tell
© PrologIA 403
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
true
Function : Succeeds
Class : Edinburgh primitive
Category : Control
Known parameters : None
Description:
Always executes successfully.
See also:
• clause
404 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
var(T)
Function : Verifies that T is a free variable
Class : Edinburgh primitive
Category : Control
Known parameters : None
Description:
var(T) executes successfully if the initial label of T is not known, and if it is not
known whether or not the number of its sons is zero. Fails otherwise.
Behaves like free .
Example:
?- var(X).
{}
?- var((+X)[U]).
{ X !num, U !tuple }
?- var(+X).
?- var(X(1,2,3)).
?- var(top[L]).
?- var(top(X,Y,Z)).
?- var(top[L]) {L # <>}.
?-
See also:
© PrologIA 405
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
write(T)
Function : Prints terms without delimiters
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
If T is an identifier, a string or a character, this primitive writes T without
quotes. Otherwise it writes the term in the same way as the out primitive.
At present it does not take account of operator declarations and uses
functional notation.
Example:
?- write('X').
X{}
?- write("string").
string{}
?- write(`c`).
c{}
?- write(a('X',1+2X,"str")).
a('X',2X+1,"str"){}
?-
See also:
406 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
writeq(T)
Function : Prints terms
Class : Edinburgh primitive
Category : Input/output
Known parameters : None
Description:
Writes the term T on the current output unit, without the constraints
associated with the variables which may appear in this term, unlike the out
primitive. At present this primitive does not take account of operator
declarations and uses functional notation.
Example:
?- writeq('X').
'X'{}
?- writeq("string").
string{}
?- writeq(a('X',1+2X,"str")).
a('X',2X+1,"str"){}
?-
See also:
• out, outm, write
© PrologIA 407
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
X =.. Y
Function : Splits terms
Class : Edinburgh primitive
Category : Trees, lists and tuples
Known parameters : X or Y
Description:
If the arity of X is known, Y is unified with a list in which the first element is
the label of X, and the other elements are the remaining arguments in order,
if any. Otherwise X has unknown arity, and Y must be a list (and not a
pointed pair) whose first element is atomic, i.e. a leaf. X is then unified with
the term which has the first element in the list as its functor, and the other
elements as its arguments. Therefore fails if X is of unknown arity and Y is
not a list, or if X aand Y are free (var) .
Examples:
?- X =.. [toto,1,2,3].
{ X=toto[<1,2,3>] } % X = toto(1,2,3)
?- out(X,a) =.. Y.
{ Y=[out,X,a] }
?- X =.. Y.
?- label[U] =.. [label,1,2|R].
?-
See also:
• functor
408 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
X<Y X =< Y
X>Y X >= Y
Function : Evaluate and verify relations
Description:
X and Y are evaluated (see val). Comparisons are then made between their
values, which may be numbers, identifiers, or character strings. In the case
of strings, the comparison is alphabetical. In the case of identifiers the
comparison is made on the strings constituting their abbreviations. These
four primitives are defined as follows:
Examples:
?- X>3.
Error in val
?- 3*4X > Y {X=1/4, Y=1}.
{X=1/4, Y=1}
?- "ABC" < "BCD".
{}
?- label >= labelle.
?-
See also:
• val, is
© PrologIA 409
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
X=Y
Function : Unifies two terms
Class : Edinburgh primitive
Category : Trees, lists and tuples
Known parameters : None
Description:
Behaves like the predefined rule eq . It is defined as follows:
X=X.
Examples:
?- X = 1.
{ X=1 }
?- X = f(X).
{ X=f(X) }
?- f(f(X)) = f(f(f(X))).
{ X=f(X) }
?-
See also:
• eq
410 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
X == Y
Function : Formal equality between two terms
Class : Edinburgh primitive
Category : Trees, lists and tuples
Known parameters : None
Description
Succeeds when the terms X and Y are formally equal, i.e. when the set of
solutions of X is the same as that of Y . Fails otherwise. This predefined rule
is declared as follows:
X == Y :- not(dif(X,Y)) .
Examples:
?- X == 1.
?- X == X.
{}
?- X == Y.
?-
See also:
• not, dif
© PrologIA 411
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
X \== Y
Function : Formal non equality of two terms
Class : Edinburgh primitive
Category : Trees, lists and tuples
Known parameters : None
Description:
Succeeds when the terms X and Y are not formally equal. This predefined
rule is declared as follows:.
X \== Y :- not(not(dif(X,Y))) .
Examples:
?- X \== 1.
{}
?- X \== X.
?- X \== Y.
{}
?-
See also:
• not, dif
412 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
X =:= Y
Function : Equality between the values of two terms
Class : Edinburgh primitive
Category : Evaluation of predefined functions
Known parameters : X and Y
Description:
Evaluates terms X and Y. Succeeds when the value of X is equal to the
value of Y , and fails otherwise. This predefined rule is declared as follows:
X =:= Y :- val(eql(X,Y), 1) .
Examples:
?- ln(exp(1)) =:= 1 .
{}
?- X =:= X.
Error in val
?-
See also:
• val, eql, =\=
© PrologIA 413
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
X =\= Y
Function : Non equality between the values of two terms
Class : Edinburgh primitive
Category : Evaluation of predefined functions
Known parameters : X and Y
Description:
Evaluates terms X and Y. Succeeds when the value of X is different from
the value of Y , and fails otherwise. This predefined rule is declared as
follows:
X =\= Y :- val(eql(X,Y), 0) .
Examples:
See also:
• val, eql, =:=
414 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
X -> Y
Function : If-Then
Class : Edinburgh primitive
Category : Control
Known parameters : X and Y which must be known when called
Description:
Tries to execute X once. If this is possible, then executes Y in all possible
ways. Here is this predefined rule
X -> Y :- X, !, Y .
© PrologIA 415
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
X,Y
Function : Execution sequence
Class : Edinburgh primitive
Category : Control
Known parameters : X and Y which must be known when called.
Description:
Executes X. If this is successful, then executes Y. This is the main mechanism
of a rule body. Here is this predefined rule:
X , Y :- X, Y .
416 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
X;Y
Function : Execution alternative
Class : Edinburgh primitive
Category : Control
Known parameters : X and Y which must be known when called
Description:
Installs a choice point. Here are these predefined rules:
X ; Y :- X .
X ; Y :- Y .
Examples:
?- write(1) ; write(2).
1{}2{}
?-
© PrologIA 417
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
'[]'(X, Y)
[X|Y]
[]
Function : List of goals to execute
Class : Prolog III predefined rule
Category : Control
Known parameters : X and Y which must be known when called
Description:
Executes X then Y. Behaves like ',' . Is described as follows:
'[]'.
'[]'(X, Y) :- X, Y .
Examples:
?- [out(a),out(b),out(c)].
abc{}
?- [].
{}
?-
418 © PrologIA
Prolog
Aociation
HERITAGE
Edinburgh Predefined Rules
© PrologIA 419
Prolog
Edinburgh Predefined Rules Aociation
HERITAGE
420 © PrologIA
Aociation Prolog
HERITAGE
1. Introduction
- Choosing the syntax mode
- Common features, differences
- Grammatical conventions
- Set of characters
- Common constants
2. Basic syntax
- Variables
- Identifiers
- Terms
- Constraints
- Rules and queries
- Some remarks
3. Edinburgh syntax
- Variables
- Identifiers
- Terms
- Constraints
- Rules and queries
- Some remarks
4. General remarks
You can program in Prolog III using two different syntaxes, which we call "basic
syntax" and "Edinburgh syntax". This chapter describes them both.
HERITAGE
1 . Introduction
At start-up of a Prolog III session, the syntax used is the basic syntax. You
can change it using the command
> edinburgh;
{}
?-
The appearance of the Edinburgh prompt , " ?- " tells you that the operation
has succeeded. Queries can be given immediately, but to input rules you
must use the built-in predicates insert or consult. To return to the basic
syntax, simply execute the following
?- prologIII.
{}
>
Briefly, the basic syntax originates to a large extent from that of Prolog II,
and its style bears the stamp of mathematical notation. The Edinburgh
syntax is more widespread throughout the world by means of its dialects.
Here is another one, extended of course to include the Prolog III
functionalities.
422 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
Although these two syntaxes may seem very different, at least in terms of
their presentation and outlook, considerable work to bring them together
has been carried out, to ensure that it is very easy to translate a given Prolog
III program from one syntax to another. It is absolutely essential that a
reader who is accustomed to using Edinburgh syntax should not be
penalized - or worse be led into making mistakes - because of certain
syntactic habits.
Now let's turn to common features and differences. One common feature to
mention is the set of characters (in a first approximation), especially the set
of constants, apart from the identifiers. A common identifier syntax does
exist, called the "quoted identifier" syntax, but is unfortunately difficult to
read. The variables have different syntaxes, but again there is a common
form called "variable underline". We would like to emphasize that there are
ways of avoiding use of these alternative forms, because the two variable
syntaxes have a non empty intersection. This also applies to identifiers.
Terms written in functional notation, tuples and lists are written identically in
both syntaxes. However, the syntaxes diverge when constraints, rules and
queries are described in the form of terms in Edinburgh syntax, because this
way of looking at things is facilitated by the use of operators; symbols which
allow infixed, postfixed or prefixed notations. But it we look at what can be
produced using these syntaxes, it is soon clear that constraints are written in
the same way (apart from one exception), and that rules and queries are
formed more or less according to a common model.
Grammatical conventions
The Prolog III grammars are described in the form of sets of context-free
rules augmented by some special signs. The re-write sign is "::=" and the left-
hand member of a rule is not repeated when it is identical to the left-hand
member of the previous rule.
• Non-terminals are sequences of words enclosed by "<" and ">" .
© Prolog IA 423
Prolog
Syntaxes Aociation
HERITAGE
• The terminals of the language are written in bold characters. The word
space denotes one character from the following set: space bar,
tabulation key, carriage return and other non-printable characters1.
The spaces appearing in the rules do not have any significance.
Set of characters
<set of characters>
::= <special character>
::= <letter>
::= <digit>
424 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<special character>
::= + | - | * | / | _ | !
::= ( | ) | { | } | [ | ] | < | >
::= . | | | & | ~ | , | ; | : | #
::= $ | ' | ` | ;
::= space
<letter>
::= <lower-case>
::= <upper-case>
<lower-case>
::= a | b | … | z accents will come later ...
<upper-case>
::= A | B | … | Z
<digit>
::= 0 | 1 | … | 9
<octal digit>
::= 0 | 1 | … | 7
<hexa digit>
::= 0 | 1 | … | 9 | A | … | F | a | … | f
At the end of this chapter, when the whole syntax has been described, we
will see the special status of the space character.
Constants
Constants are the simplest sort of data. The following constants can be
identified:
• identifiers,
© Prolog IA 425
Prolog
Syntaxes Aociation
HERITAGE
<constant>
::= <identifier>
::= [] “standard” empty list
::= <boolean>
::= <integer>
::= <empty list> empty tuple
::= <real>
::= <character constant>
::= <character string>
Here is the syntax of these different constants, apart from the identifiers
which are described below:
<integer >
::= <digit> { _ | <digit> } 1_123_456 or 432513
<boolean>
::= 0' | 1'
<empty list>
::= <>
<real>
::= <mantissa> [ <exponent> ] such as 1.4e-17
<mantissa>
::= <sequence of digits> . <sequence of digits>
::= <sequence of digits> .
::= . <sequence of digits>
<exponent>
::= <Ee> [ <sign> ] <sequence of digits>
426 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<sign>
::= + | -
<Ee>
::= E | e
<sequence of digits>
::= <digit>
::= <digit> <sequence of digits>
The syntax for reals is simple: at least one digit for the mantiassa, the dot is
mandatory but the exponent is optional. Warning: the real read is as long as
possible, which may create confusions (2.0f6 is read « 2 f6 », where f6 is
a variable, but 2.0e6 is read « 2 000 000 »).
© Prolog IA 427
Prolog
Syntaxes Aociation
HERITAGE
<escape sequence>
::= \ <letter except x>
::= \ <special character>
::= \ <octal digit> <octal digit> <octal digit>
::= \ <octal digit> <octal digit>
::= \ <octal digit>
::= \ x <hexa digit> <hexa digit>
::= \ x <hexa digit>
428 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
\b rubout ASCII 8
\t tabulation " 9
\l linefeed " 10
\f formfeed " 11
\r return " 13
\n newline "10 or 13 (machine)1
\e escape " 27
<character constant>
::= ` <constant character> ` this is the "grave accent"
<character string>
::= " { <constant character except"> | "" } "
<constant character>
::= <keyboard character except carriage return >
::= <denoted character>
© Prolog IA 429
Prolog
Syntaxes Aociation
HERITAGE
Strings (1) and (2) are identical, as are strings (3) and (4) . The content of
string (5) is:
The square brackets "[" and "]" indicate...
2 . Basic syntax
Variables
<extended alphanumeric>
::= <letter>
::= <digit>
::= ' quote
::= _ underline
::= $ dollar
<variable>
::= _ { <extended alphanumeric> }
<variable>
::= <letter> { <extended alphanumeric> }
430 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
N.B. : We advise against using the character $; Prolog III uses it to name the
variables that it needs to create internally.
Identifiers
<prefix>
::= [ <name> { : <name> } ] orbis:lex
<name>
::= <letter> { <extended alphanumeric> }
<identifier>
::= <prefix> : <abbreviated identifier> sys:outm
::= <abbreviated identifier> outm
<abbreviated identifier>
::= <letter> <letter> { <extended alphanumeric> }
© Prolog IA 431
Prolog
Syntaxes Aociation
HERITAGE
<abbreviated identifier>
::= ' { <all characters except ' > | '' } '
Terms
<term>
::= <term1>
::= <term> <=> <term1>
::= <term> => <term1>
<term1>
::= <term2>
::= + <term2>
::= - <term2>
::= <term1> + <term2>
::= <term1> - <term2>
::= <term1> | <term2>
<term2>
::= <term3>
::= <term2> & <term3>
::= <term2> * <term3>
::= <term2> / <term3>
::= <multiplicand> <variable>
432 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<term3>
::= <term4>
::= ~ <term3>
<term4>
::= <term5>
::= <term5> ( <sequence of terms> )
::= <term5> [ <term> ]
::= [ <sequence of terms> ] "standard" list
::= [ <sequence of terms> | <term> ] "standard" list
::= <term4> . <term5>
<term5>
::= <variable>
::= <constant>
::= < <sequence of terms> >
::= ( <term> )
<constant>
::= <identifier>
::= [] empty list
::= <boolean>
::= <integer>
::= <empty list> empty tuple
::= <real>
::= <character constant>
::= <character string>
<multiplicand>
::= <integer>
::= <real>
::= ( <term> )
<sequence of terms>
::= <term>
::= <term> , <sequence of terms>
© Prolog IA 433
Prolog
Syntaxes Aociation
HERITAGE
Numeric expressions
Boolean expressions
434 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
- It should be noted that the label of the two terms above is parenthesized.
- In the last example, the bar is the pointed-pair separator, and not the the boolean
"or" operation. If you wish to express a list containing the boolean expression
A|B, you must write [(A|B)] instead of [A|B].
We strongly emphasize the fact that correct syntax does not mean correct semantics.
Constraints
• the numeric constraints less than and greater than (or equal),
• the boolean constraint implies .
© Prolog IA 435
Prolog
Syntaxes Aociation
HERITAGE
<constraint system>
::= { }
::= { <constraint > {, <constraint > } }
<constraint >
::= <term> = <term>
::= <term> # <term>
::= <term> = <term>
::= <type constraint>
::= <Sup constraint>
::= <Inf constraint>
::= <variable> !freeze( <term> )
<Sup constraint>
::= <term> <sup> <term> a>b
::= <Sup constraint> <sup> <term> 1>a>b>c
<Inf constraint>
::= <term> <inf> <term>
::= <Inf constraint> <inf> <term>
<inf>
::= < | <=
<sup>
::= > | >=
<tree type>
::= !idt | !boolt | !numt | !chart | !tuple
::= !id | !bool | !num | !char
<type constraint>
::= <term> <tree type>
::= <term> :: <term>
436 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<rule>
::= head> -> { <goal> } [ , <constraint system> ] ;
<query>
::= { <goal> } [ , <constraint system> ] ;
<goal>
::= / | ! slash or cut; mean the same
::= <term>
<head>
::= <term>
© Prolog IA 437
Prolog
Syntaxes Aociation
HERITAGE
• the rules are arranged in groups having the same access predicate
name (head identifier) and in sub-groups where predicates have the
same arity.
Some remarks
Space character.
Some remarks need to be made about the status of the space character. It
can be inserted anywhere without any side effects, except inside:
- a variable,
- a constant,
- a goal tt(gg) , where a space between tt and the bracket would
create a split into two goals tt (gg), or a syntax error.
438 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
Line continuation.
rule(123456\
78912) ->;
(where the 7 is really at the start of the line) is the same as:
rule(12345678912) ->;
3 . Edinburgh syntax
Variables
© Prolog IA 439
Prolog
Syntaxes Aociation
HERITAGE
<extended alphanumeric>
::= <letter>
::= <digit>
::= ' quote
::= _ underline
::= $ dollar
<variable>
::= _ { <extended alphanumeric> } _underline
<variable>
::= <upper-case> { <extended alphanumeric> }
N.B. : We advise against using the character $; Prolog III uses it to name the
variables that is needs to create internally.
Identifiers
<prefix>
::= [ <name> { : <name> } ] orbis:lex
440 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<name>
::= <letter> { <extended alphanumeric> }
<identifier>
::= <prefix> : <abbreviated identifier> sys:outm
::= <abbreviated identifier> outm
<abbreviated identifier>
::= <lower-case> { <extended alphanumeric> }
<abbreviated identifier>
::= ' { <constant character except ' > | '' } '
Terms
Operators
© Prolog IA 441
Prolog
Syntaxes Aociation
HERITAGE
<operator>
::= <constant>
::= <variable>
::= <character sequence>
with the restriction that <character sequence> does not start with either a
constant or a variable or a space or % or /* .
There are four sorts of operator: prefixed which allow an operand to the
right, postfixed which have an operand to the left , infixed operators with
two operands (to right and left) and isolated operators (no operands). We
will write these types of operators fz zf zfz f which summarize the way the
expression is constructed ( f denotes the operator and the z('s) denote the
operands). A priority (or precedence) is attributed to each operator, in the
form of an integer number n. By convention, the precedence of the
operators is calculated using n and the exact form of the type of operator
(xf, yf, .f , …) as follows: if we find x in place of an operand (z) the precedence
is n-1, if we find y the precedence is n, otherwise we find a ‘.’, the precedence
is a number independent of n and is provided at the same time as the
operator. We should add straight away that the form where one of the
operands is a dot (.fx, …) is only used to construct compound terms1. Below
is a table summarizing how these precedences are calculated:
442 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
(continued )
type .f f. xf. .fx yf. .fy
op. precedence n n n n n n
precedence provided m m m m m m
left op. preced. (l) m n-1 m n m
right op. preced. (r m m n-1 m m
<f, n>
::= <operator>
<fz, n, r>
::= <operator>
<zf, n, l>
::= <operator>
<zfz, n,l,r>
::= <operator>
The terms
<term, n>
::= <fz, n,r> <term, r> +x
::= <term, l> <zfz, n,l,r> <term, r> a*b
::= <term, l> <zf, n,l> x--
::= <f, n> 18
::= <term, n-1>
::= <compound term, n>
The last rule <compound term, n> uses operators to describe the various
mechanisms for parenthesis using symbols such as parentheses, braces, etc
and any pair of simple operators that we want to bring together.
© Prolog IA 443
Prolog
Syntaxes Aociation
HERITAGE
1 Here, the term context refers to the top of a stack of characters (empty at first).
444 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
© Prolog IA 445
Prolog
Syntaxes Aociation
HERITAGE
integer ENTIER f 2
ident. IDENT f 2
[] IDENT f 2
charac. CHAR f 2
boolean BOOL f 2
string CHAINE f 2
<> VIDE f 2
floating NUMVAR fx 2
floating FLOAT f 2
variable VAR f 1
Since this table is somewhat minimalistic, below we also present the syntax
of terms in a more habitual form, in which compound operators and isolated
operators (f) no longer appear as such, and instead form the body of the
grammar rules.
<term>
::= <term, 1300>
<term, 1300>
::= <term, 1299> [ <constraint system> ]
::= <constraint system>
<constraint system>
::= { <term, 999> {, <term, 999> } }
<term, n>
::= <fz, n,r> <term, r> +x
::= <term, l> <zfz, n,l,r> <term, r> a*b
::= <term, l> <zf, n,l> x--
::= <term, n-1>
446 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<term, 50>
::= <term, 49>
::= <term, 49> ( <sequence of terms> ) function
::= <term, 49> [ <term> ] tree constructor
::= [ <sequence of terms> ] “standard” list
::= [ <sequence of terms> | <term, 999> ] pointed pair
::= <term, 50> . <term, 49> concatenation
<term, 2>
::= <variable>
::= <constant>
::= < <sequence of terms> > tuple
::= <multiplicand> <variable> product by default
::= ( <term, 1300> )
<constant>
::= <identifier>
::= [] empty list
::= <boolean>
::= <integer>
::= <empty list> empty tuple
::= <real>
::= <character constant>
::= <character string>
<multiplicand>
::= <integer>
::= <real>
::= ( <term, 1300> )
<sequence of terms>
::= <term, 999>
::= <term, 999> , <sequence of terms, 999>
© Prolog IA 447
Prolog
Syntaxes Aociation
HERITAGE
This syntax will enable us to construct numeric expressions using the four
operators + - * / in particular, boolean expressions using the boolean
operators | & ~ <=> =>, tuples with the tuple constructor < > and the
concatenation operator . , and will also enable us to form trees using
parentheses () or square brackets [] .
Numeric expressions
Boolean expressions
448 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
- It should be noted that the label of the two terms above is parenthesized.
- In the last example, the bar is the pointed-pair separator, and not the the boolean
"or" operation. If you wish to express a list containing the boolean expression
A|B, you must write [(A|B)] instead of [A|B].
We strongly emphasize the fact that correct syntax does not mean correct semantics.
© Prolog IA 449
Prolog
Syntaxes Aociation
HERITAGE
Constraints
<constraint system>
::= { <constraint > {, <constraint > } }
<constraint >
::= <term, 650>
450 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<term, 650>
::= <term, 649> = <term, 649> general equality
::= <term, 649> # <term, 649> general difference
::= <term, 649> => <term, 649> implies
::= <term, 649> < <term, 649> less than
::= <term, 649> =< <term, 649> less than or equal to
::= <term, 649> > <term, 649> greater than
::= <term, 649> >= <term, 649> greater than or equal to
::= <term, 649> :: <term, 649> size constraint
::= <term, 649> !tuple types
::= <term, 649> !boolt types
::= <term, 649> !bool types
::= <term, 649> !numt types
::= <term, 649> !num types
::= <term, 649> !chart types
::= <term, 649> !char types
::= <term, 649> !idt types
::= <term, 649> !id types
::= <term, 649> !freeze( <term> ) freeze
In cases where constraints do not have an effect, (for example when they are
positioned as a sub-term ), they behave like any tree. The same applies to
systems. Here is the result:
© Prolog IA 451
Prolog
Syntaxes Aociation
HERITAGE
452 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
<rule>
::= <term> <stop>
<query1>
::= [ ?- ] <term> <stop>
<stop>
::= . space
<rule>
::= <term> [ <constraint system> ] <stop>
::= <term> :- <body> [ <constraint system> ] <stop>
<query>
::= [ ?- ] [ <body> ] [ <constraint system> ] <stop>
<body>
::= <term>
::= <term> , <body>
© Prolog IA 453
Prolog
Syntaxes Aociation
HERITAGE
It is important to note that the only constraints which are going to "apply"
are those in the position indicated by the above rules. When inside a term,
(i.e. positioned as a sub-term), they behave like a tree. The same applies to
the operators forming the rules (such as ‘:-’ , ‘,’ and ‘;’ ). In this case the
following terms are constructed:
Some remarks
Space character.
Some remarks need to be made about the status of the space character. It
can be inserted anywhere without any side effects, except inside a variable
or a constant.
454 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
It is mandatory for a space to be placed after the . (dot) marking the end
of the rule or query. This is how we distinguish between this final dot and
the concatenation dot.
Line continuation.
rule(123456\
78912) ->;
(where the 7 is really at the start of the line) is the same as:
rule(12345678912) ->;
© Prolog IA 455
Prolog
Syntaxes Aociation
HERITAGE
Edinburgh operators
Additional “Edinburgh” operators not used directly by Prolog III are also
declared in this syntax. Below is a list of these operators with the
corresponding constructions:
Peculiarities
456 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
4 . General remarks
To end this chapter, we give below some differences between the two
syntactic modes
• The unary operators + and – do not have the same priorities in the two
syntaxes. In basic syntax they are at the same level as the binary + and
–
• In Edinburgh syntax, it is not possible to write a cascade of less than (or
greater than) constraints.
• The programmer cannot define an operator in the basic syntax (see the
op predicate in Edinburgh syntax).
One point which hinders cohabitation of rules from the two syntaxes is the
display of terms originating from the other syntax, which contain variables.
The example below makes this clear:
> equal(x,x) ->;
> edinburgh;
{}
?- list(equal).
equal(x,x). % x here does not have variable syntax .
{} % although it IS a variable.
?- equal(1,B).
{B=1}
?- assert(titi(Var,Var)).
{}
?- prologIII.
{}
> list(titi);
© Prolog IA 457
Prolog
Syntaxes Aociation
HERITAGE
This does not matter provided we do not require a term to be written (for a
solution or using the built-in predicates trace, out, write, etc). In these cases,
the terms written may seem confusing. We should point out that in this
version, assert uses the notation ….
458 © PrologIA
Prolog
Aociation
HERITAGE
Syntaxes
© Prolog IA 459
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Graphics Primitives
The Prolog III system includes an asynchronous system for event management.
This system enables the environment to function (windows, menus, etc), without
the user having to reorganize the program as an event management loop. Most
events - such as re-sizing of a window, scrolling in text windows, etc - are managed
automatically. The user can associate Prolog procedures with certain events, such
as menu selection or refreshing of a graphics window. Mouse positioning and
clicking events can be tested by a program, enabling the creation of mouse event
loops.
HERITAGE
For Unix or VMS, we will assume that the user is in an XWindows (X11) or
SunView type environment. First of all, Prolog III must be started with the
-W option corresponding to the available graphics environment; -WS for
SunView, -WX for XWindows.
On these machines the graphics environment is initialized by the Prolog III
command:
> load_graphic ;
The term “console” refers to Prolog III's initial window (in which PrologIA's
logo is displayed).
Two types of graphics window can be opened in Prolog III: “GRAPHICS” or
“MODAL”.
All the graphic effects obtained here must be considered from the Prolog
point of view as side effects. In particular, a drawn object is never erased
during backtracking. In the same way, the position of the writing point is a
global variable.
462 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
Y'
y
A group of rules with name Identifier and arity arity will be represented in
the form of an <Identifier, arity> pair.
1 It is possible to use the form [<X,Y> | <X',Y'>] to represent a rectangle (this term is a
pointed pair of pairs representing two of the rectangle's points). However, we advize
against using this obsolete form.
© PrologIA 463
Prolog
Graphics primitives Aociation
HERITAGE
file_window(s1)
file_window(s1,s2)
Creates a window called s2, if it does not exist already, initialized with
the text contained in the file called s1. file_window(s1) is equivalent to
file_window(s1,s1).
front_window(s)
Unifies s with the name of the front window.
get_screen(x,y)
get_screen(x,y,N)
Unifies x and y with the width and height respectively of the screen in
pixels. In the three argument version, N unifies with 1 if the screen
only has two colors (black and white), otherwise with a larger number.
get_window(s,b,x1,y1,x2,y2)
get_window(s,b)
Unifies the parameters s, b, x1, y1, x2, y2 with the values corresponding
to each existing window, by backtracking. Please see set_window for
the meaning of the parameters.
new_window(s,t)
new_window(s,t,v,x1,y1,x2,y2)
new_window(s,t,v,r)
These rules create a new window, and a new I/O unit with the name s
and of type t. s must be a name which has not already been used for
existing units. It is added to the Window menu. t has the form type or
[type|list_attributes]. It determines the type of window and thus the
operations which can be applied to it.
464 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
© PrologIA 465
Prolog
Graphics primitives Aociation
HERITAGE
<"SAVE", r >
This attribute can only be applied to a graphics or modal window.
It defines the rectangle r of the window associated with the
refreshment bitmap. If a color machine is used, a large zone may
require considerable memory space.
<"SAVE", b >
b is an integer (0 or 1) indicating whether or not a refreshment
bitmap is associated with the window. The default value is b = 0.
If b =1, a refreshment bitmap the same size as the window is
created.
X If b =1, a refreshment bitmap the same size as the screen is
created.
<"FONTSIZE", n >
Defines the size of the font used in a text window.
<"FONT", n >
Defines the number n of the font used for a text window. The
font associated with n varies depending on the host system.
The last four parameters which can be replaced by the tree r are:
x1,y1
Coordinates of the top left-hand corner of the drawing section in
the new window, in relation to the screen.
x2,y2
Coordinates of the bottom right corner of the drawing section in
the new window. The origin is located at the top left corner of the
screen.
Here is an example of how to create a graphics window, with
automatic saving:
> new_window("query",["GRAPHICS",<"SAVE",1>]);
466 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
save_window(s1, s2)
save_window(s1)
Saves the contents of the text window s1 in the file called s2. The one
argument version is equivalent to save_window(s1,s1).
set_window(s,b,x1,y1,x2,y2)
These rules enable you to control the position and visibility of the
windows already created by Prolog III.
s
Name of the window, as a character string ("console" or "graphic"
for predefined windows).
b
Integer indicating whether the window will be visible or not (0 =
invisible, 1 = visible).
x1,y1
coordinates of the top left corner of the drawing section of the
window in relation to the screen.
x2,y2
coordinates of the bottom right corner of the drawing section of
the new window. The origin is located at the top left hand corner
of the screen.
Example:
> set_window("graphic",1,50,50,300,300);
set_window(s,b)
Same as above, except that b can be:
either an integer indicating whether or not the window will be visible
(0 = invisible, 1 = visible),
or an attribute (see new_window). The possible attributes are as
follows:
For graphics and modal windows:
<"SAVE", 0 >
<"SAVE", 1 >
<"SAVE", r > where r is a rectangle.
For a text window:
© PrologIA 467
Prolog
Graphics primitives Aociation
HERITAGE
<"FONT", n >
<"FONTSIZE", n >
Example:
> set_window("console",<"FONTSIZE",12>);
X create_window(s,t,v,r1,r2)
X create_window(s,t,v,r1)
X create_window(s,t,r1)
Similar to new_window, but makes it possible to define a coordinate
system with a scale
r1
has the form <x1,y1,x2,y2> where x1,y1,x2,y2 are reals indicating
the coordinates of the "drawable" part of the window in a screen
[0,1] x [0,1]. The top left corner of the window must be in the
screen, and therefore x1 and y1 must be in the interval [0,1].
r2
has the form <x1,y1,x2,y2> where x1,y1,x2,y2 are integers (short
type, i.e. less than 32,700), defining a local user coordinate system.
This parameter is only specified for graphics windows
("GRAPHICS" or "MODAL"). If parameter r2 is not specified, the
graphics coordinates in the window will be given in pixels.
> create_window("wind","GRAPHICS",1,
<0.1,0.1,0.6,0.7>,<0,0,100,100>);
reset_window(s)
Repositions the reading cursor at the beginning of an editing window s.
The rule fails if s is not an editing window created by new_window.
clear_window(s)
468 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
gr_window(s)
Selects the graphics window s as the current graphics unit.
gr_window_is(s)
Unifies s with the name of the current graphics unit. When Prolog III is
started, the current graphics unit is the predefined window "graphic" .
kill_window(s)
Kills the window s. If window s was the current graphics unit, the
predefined window "graphic" becomes the current graphics unit again.
s must not be the name of a predefined window (i.e. it must have been
created by new_window)
print_window(s,f,t)
print_window(s)
Prints the contents of text window s with the font f of size t.
The one argument version prints the window with its current font.
option + closure
When you click in the closure box of a window, the corresponding unit
closes and its name is removed from the menu containing the window
names, unless it is a predefined window. However it is possible to
make a window invisible without closing it, by pressing the option key
when you click the closure box
:gr_update(u)
© PrologIA 469
Prolog
Graphics primitives Aociation
HERITAGE
In all the following rules, x and y stand for horizontal and vertical
coordinates respectively. The direction of y's positive axis is downwards. The
default origin (i.e. x=0, y=0) is the top inside left corner of the reference
element. For window positions, the reference element is the screen;
otherwise it is the current graphics window.
gr_moveto(x,y)
Moves the pen in the current graphics window to point (x,y).
gr_lineto(x,y)
Draws a line by moving the pen from the current position to point
(x,y).
gr_move(x,y)
Moves the pen x horizontal pixels and y vertical pixels. If the current
position was (x0, y0) the new position is (x0+x, y0+y).
gr_line(x,y)
Draws a line from the current pen position (x0, y0) to a point (x0+x,
y0+y)which becomes the new position.
gr_penloc(x,y)
Returns the integer coordinates describing the pen position in the
current graphics window.
470 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
gr_erase
Erases the contents of the current graphics window and moves the pen
to the top left corner.
gr_setorigin(x,y)
Moves the origin of the axes so that the top left corner has coordinate
(x,y). The window content is not changed.
gr_rect(n,r)
gr_rect(n,x1,y1,x2,y2)
The above rules produce calls to the basic routines for any drawing in a
rectangle. r is a tree describing a rectangle and must be of the form:
<x1,y1,x2,y2>
x1, y1 are the coordinates of the top left corner, x2, y2 are the
coordinates of the bottom right corner. The first argument n, which is
an integer or an identifier, determines which procedure is called:
0, :frameRect, :frame
Draws the perimeter of the rectangle.
1, :paintRect, :paint
Fills the rectangle with the current pen pattern.
2, :eraseRect, :erase
Erases the rectangle and its contents.
3, :invertRect, :invert
Inverts the color of each point inside the rectangle. If the
rectangle is not colored black and white, the result depends on the
machine.
4, :frameOval
Draws the perimeter of the oval in the rectangle.
5, :paintOval
Fills the oval with the current pen pattern.
6, :eraseOval
Erases the oval and its contents.
7, :invertOval
Inverts the bits of the oval.
8, :frameRoundRect
Same as :frameRect but with rounded corners.
9, :paintRoundRect
Same as :paintRect but with rounded corners.
© PrologIA 471
Prolog
Graphics primitives Aociation
HERITAGE
10, :eraseRoundRect
Same as :eraseRect but with rounded corners.
11, :invertRoundRect
Same as :invertRect but with rounded corners.
12, :clipRect
Defines a rectangle whose contour is not drawn. Only the parts of
drawings that are situated inside the rectangle will be visible. In
other words, a viewing field is defined for all future drawings. To
cancel the effect of this primitive, repeat gr_rect(12,r) and for r
enter the coordinates of a huge rectangle, e.g. <-1000, -1000, 1000,
1000>.
gr_polygon(n,L)
Draws a polygon in the current graphics window. L is a list of <x,y>
pairs indicating the coordinates of the points that define the polygon.
When the first argument n is an integer or identifier, it determines the
called function.
0, :frame
Draws the perimeter of the polygon.
1, :paint
Fills the polygon with current pen-pattern.
2, :erase
Erases the contents of the polygon (some broken lines
representing the polygon contour may remain).
3, :invert
Inverts the color of each point inside the polygon. If the polygon
is not colored black and white, the result depends on the machine.
gr_arc(n,r,a1,a2)1
gr_arc(n,x1,y1,x2,y2,a1,a2)
Draws an elliptical arc inside a rectangle r between angles a1 and a2.
Angles a1 and a2 are given in degrees.
The first argument n represents an integer or identifier, and specifies
the called procedure:
0, :frame
Draws the arc of the ellipse.
472 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
1, :paint
Fills the sector defined by the elliptical arc with the pen pattern.
2, :erase
Erases the elliptical arc and the sector contents.
3, :invert
Inverts the bits of the sector defined by the elliptical arc. If the
sector is not colored black and white, the result depends on the
machine.
Example:
> gr_arc(:frame,100,100,200,170,20,110);
a2
x1,y1
a1
x2,y2
gr_arc'(n,r,a1,a2)
gr_arc'(n,x1,y1,x2,y2,a1,a2)
Draws an elliptical arc inside rectangle r starting from angle a1 and a2.
a1 and a2 are given in degrees. This primitive differs from gr_arc
because it corresponds exactly to the Toolbox definition (origin on the
vertical axis, a2 is relative to position a1, positive direction is clockwise).
Example:
> gr_arc'(:frame,100,100,200,170,20,40);
© PrologIA 473
Prolog
Graphics primitives Aociation
HERITAGE
a1
a2
x1,y1
x2,y2
gr_icon(n,x1,y1,x2,y2)
gr_icon(n,r)
Draws an icon described in an 'ICON' resource numbered n in the
current graphics unit, and writes it in the rectangle indicated. The
system first looks for this resource in the Prolog runnable, and then in
the system file. The system permanently contains the following icons:
0 Stop sign.
1 Notification.
2 Danger sign.
The best result is obtained by entering a square with equal sides of 32
as the rectangle.
474 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
gr_clickb,x,y)
Tests whether a mouse button has been clicked since the last call to
gr_erase or gr_click. If it has, x and y are unified with the integer
coordinates of the mouse position when this click occurred.
Otherwise, the primitive's behavior is governed by b, an integer which
must be known when the call occurs. The meaning of the values of b
are as follows:
b=1
Wait for a click in the current graphics window.
b=0
Don't wait, and perform backtracking.
gr_click(b,x,y,m)
Identical to gr_click(b,x,y) but in addition indicates the state of the main
modification keys by unifying m with the sum of the following values:
1
The SHIFT key is pressed.
© PrologIA 475
Prolog
Graphics primitives Aociation
HERITAGE
2
The CONTROL1 key is pressed.
4
The OPTION key is pressed.
8
The COMMAND key is pressed.
16
The SHIFT LOCK key is pressed.
gr_getmouse(x,y)
gr_getmouse(x,y,b)
Returns in (x,y) the integer coordinates describing the current mouse
position in relation to the window origin. Returns the value 0 for b if
the mouse button(s) is (are) not pressed when the call occurs.
Otherwise it returns the number of the pressed button, starting from
the left for a multi-button mouse (the first button has the number 1).
gr_color(d,c)
Defines the color of the background (if d = 0) or of the graphics pen (if
d = 1) in the current graphics window. c is an integer representing one
of 8 possible colors as follows:
33 = black, 30 = white, 69 = yellow, 137 = magenta, 205 = red,
273 = cyan, 341 = green, 409 = blue.
gr_color2(b,p)
476 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
Defines the color of the background b and of the graphics penp in the
current graphics window. Arguments b and p are integers representing
one of the possible colors from among the following values:
0 = white, 1 = red, 2 = green, 3 = blue, 4 = pink, 5 = orange, 6 = brown,
7 = pink1, 8 = violet, 9 = green1, 10 = yellow, 11 = blue1, 12 = yellow1,
13 = magenta, 14 = cyan, 15 = black.
gr_color3(r,g,b)
Defines the color of the graphics pen in terms of components: r red, g
green, b blue. If the values are floating numbers, they must be
between 0.0 and 1.0, and they correspond to percentages of intensity
for each component (0.0 indicates the absence of the component, 1.0
indicates maximum intensity). If the values are integers, the specific
values corresponding to the machine must be used (0 to 65535 on
Macintosh).
gr_choosecolor(p, s, i, f)
This primitive is used to display the color selection dialog at point p (in
the form <x,y>) on the screen. s is a string which will be displayed in
the dialog. i and f are integer triplets between 0 and 65535; a triplet
<r, g, b> represents a color in components of red r , green g, and blue b.
i is the initial dialog color and must be known when the call is made. f
will be unified with the chosen color. This primitive fails if the user
clicks the Cancel button.
gr_pen(w,p)
gr_pen(w,h,p)
Defines the size in pixels of the graphics pen, and its pattern.
w = width1
h = height
p = pattern
0 white
1 black
2 gray
3 light gray
4 dark gray
© PrologIA 477
Prolog
Graphics primitives Aociation
HERITAGE
gr_stringwidth(s,n)
Unifies n with the length of the string s according to the character font,
size, and style defined for the current graphics window.
gr_mode(b,m)
Defines the mode for application of the pattern onto the background,
for the current graphics unit.
b=0
Concerns drawings, and therefore the pen pattern.
b=1
Concerns text, and therefore the pattern corresponding to the
character.
There are four basic operations: Copy, Or, Xor et Bic. The Copy
operation simply replaces the target pixels with the pixels in the pattern
or source. The target pixels are "painted over" regardless of their initial
state. The Or, Xor and Bic operations leave unchanged the target pixels
located under the white part of the pattern or source. They differ in the
way they process the pixels under the black part, as follows:
Depending on the mode, the operation is performed either from the pattern
itself (src), or from its opposite (notSrc). Below are the values of m for the
different modes.
m transfer modes
0 srcCopy
1 srcOr
2 srcXor
3 srcBic
4 notSrcCopy
5 notSrcOr
6 notSrcXor
7 notSrcBic
478 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
gr_text(f,t,s)
Defines the font, size and style of text output in the current graphics
window.
f = font number
t = font size.
s = list of style numbers.
N° font N° style
0 systemFont 0 bold
1 applFont 1 italics
2 newYork 2 underline
3 geneva 3 outline
4 monaco 4 shadow
5 venice 5 condensed
6 london 6 expanded
7 athens
8 san Franscico
...
The empty binary list for s represents normal text. The default
combination is gr_text(4,12,[]).
For example gr_text(3,18,[1,3,4]) corresponds to geneva size 18, italic,
outline and shadow.
It is possible to call this rule by giving it identifiers that have been
assigned appropriate constant values. For example:
>assign(Geneva,3) assign(Italic,1)
assign(Outline,3);
{}
> gr_text(Geneva,18,[Italic,Outline])
output("graphic") outm("Hello")
output("console");
© PrologIA 479
Prolog
Graphics primitives Aociation
HERITAGE
X gr_font(f)
Loads the font named f for the current graphics window. The basic
font is Courier; the other proposed fonts are variations on the height
and thickness of the characters:
"ft7r", "ft12r", "ft12b", "ft14r", "ft14b", "ft19r".
7, 12, 14, and 19 denote the font size, r represents a standard thickness
and b a greater thickness.
Example:
> gr_font("ft12r");
Button simulation
gr_draw_buttons(b)
This primitive draws one or more buttons in the current graphics
window.
A button is defined by a Prolog III rule with name b and arity 3.
These three arguments are as follows:
- the rectangle it is written in.
- the string displayed in the button.
- a term to encode additional information (e.g. an action
associated with thus button).
All the buttons defined by the group <b,3> are drawn.
Here is an example of a button database:
480 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
When this base is loaded, the two buttons are drawn by the following goal:
> gr_draw_button(wtButton) ;
gr_button_hit(b,<x,y>,t)
b is the access identifier for the button database described above.
This rule succeeds if x and y are the coordinates of a point inside one of
the buttons contained in the database <b,3>. .
t is then unified with the third argument of the corresponding button.
The gr_button_hit primitive combined with gr_click makes it easy to
write a button monitoring loop.
Entering text
gr_editf(<s1,p1,p2>,r,s,k)
gr_editf(<s1,p1,p2>,x1,y1,x2,y2,s,k)
These primitives create an edit field in the current graphics window. To
end editing, simply press the tabulation or carriage return key or click
the mouse outside the edit field. If k is not a variable, the rectangle and
its text are only drawn, without editing.
s1
is the string that initializes editing.
p1, p2
are integer numbers representing the beginning and end of
selected text (indicated by highlighting). The value 0 for p 1
indicates the position before the first character in the text; p 2
indicates the position after the last character. To initialize an
empty field, use the values <"",0,0>.
r
defines the position of the editing rectangle. The text is
automatically left justified in paragraph mode
s
is the variable which will be unified with the edited string.
k
If k is a variable, it is unified in output with the termination mode
0 for a return
© PrologIA 481
Prolog
Graphics primitives Aociation
HERITAGE
get_key(c)
get_key(a,t,m)
get_key is used to take a character. There is no echo of this character in
any window. This primitive can therefore be used to enter a pass-
word. It is explained in more detail in the stty paragraph.
get_key(c)
returns a character in c .
get_key(a, t, m)
returns three integers :
- in a the extended ASCII code
- in t the key number (virtual key code described in Inside
Macintosh vol. V p.192))
- in m the state of the modification keys (see the gr_click
primitive.)
stty("USEGETKEY", t)
governs use of the get_key primitive.
t=0
default mode, in which get_key will always fail. The characters
typed are inserted in the text windows if necessay. In this mode,
the use can edit text windows while Prolog III is working.
t<0
get_key will take a character which cannot be more than t ticks old
(1/60sec) before the call. Fails if no character is available when the
call is made, or if the character is too "old".
482 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
t>0
get_key will wait for a character, for at most t ticks. Will fail if no
character is available when the time has elapsed. get_key does not
wait for the time to elapse before succeeding if a character is
supplied in time. A character may have been typed in advance.
This mode can be used to enter a pass word in a given time
period.
Examples:
stty("USEGETKEY", -60);
The next call to get_key will fail if no unread character has been typed
less than a second before this call ( 1 s = 60 ticks).
stty("USEGETKEY", 300);
The next call to get_key will fail if no unread character can be obtained
in the five seconds following this call (1 s = 60 ticks). The character may
have been typed in advance. get_key succeeds immediately after
obtaining this character (it does not wait for the period to elapse).
stty("FLUSH")
Removes all the characters from the event queue. They are no longer
available for get_key. (enables get_key to get an answer which has not
been typed in advance.)
gtty(s, v)
Recovers the value of a parameter concerning the terminal:
gtty("USEGETKEY", v) returns 0 or a signed number of ticks.
gtty("TERM", x) at present returns "TTY" or "MPW" .
© PrologIA 483
Prolog
Graphics primitives Aociation
HERITAGE
Choice boxes
484 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
gr_popupItem(r,l,n1)
gr_popupItem(r,l,n1,n2)
Creates a field of proposed values. This corresponds to a pop-up menu
in the Toolbox. This type of object should not be confused with the
pop-up menus associated with windows, activated by option+click and
used to start actions asynchronously.
Here is a description of the arguments:
l is a list of constants.
r is the rectangle in which item number n1 in list l is displayed.
If n2 is absent, the item is simply drawn.
© PrologIA 485
Prolog
Graphics primitives Aociation
HERITAGE
> gr_popupItem(<20,20,120,40>,
["aa","bb","cc","dd",3,4], 2)
gr_click(1,x,y)
gr_popupItem(<20,20,120,40>,
["aa","bb","cc","dd",3,4], 2,
i);
When you click in the window and keep the button pressed down:
aa
bb
cc
dd
3
4
486 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
Printing windows
gr_print(s)
gr_print(s,r_x,r_y,x0,y0)
gr_print(s,r1,r2)
Print the contents of the graphics window s .
The 3 argument version can be used to specify the zone to print,
delimited by the rectangle r1, in which the result on paper is contained
in rectangle r2. Any necessary reductions and translations are
performed automatically. The one argument version prints the
window without any format modification.
The 5 argument version is used to specify reduction according to the
axes of the X's and Y's, in the form of two numbers r_x and r_y with
values between 0.0 and 1.0. x0 and y0 can be used to define the origin
position for printing on paper.
Example :
will print the "graphic" window reduced to a quarter of its original size (each
dimension is halved).
A pop-up menu can be attached to any window unit. The set_menu primitive
described in this section is used to define or redefine these menus.
© PrologIA 487
Prolog
Graphics primitives Aociation
HERITAGE
set_menu(u,p,v)
This primitive is used to define or redefine the value v of the item
indicated by p in the menu of unit u.
The meanings of each argument are as follows:
u (unit)
Represents the relevant unit; the integer 0 for the menu bar and
its descendants, otherwise the name of a window.
p (path)
Binary list of strings indicating a selection path in the hierarchical
menu of unit u. The terminal element in the path is replaced by v.
If the hierarchy did not already exist, it is created. If the list is [],
the whole of the menu is replaced.
v (value)
Tree describing the new value. This value can either be a leaf, or a
hierarchy.
Leaf type value.
A leaf is represented by a tuple with the following form:
<"Item name", Identifier, n>
The string Item Name is self explanatory.
Identifier is the name of a Prolog rule with arity 1, attached to the
item.
n is an integer (0 or 1) indicating whether the item is ticked or not
(a mark precedes the name of a ticked item).
When a menu item is selected and validated, the current program
is suspended, and the Identifier(u) goal is immediately activated.
If the goal terminates without any errors, the program continues
normally.
488 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
> set_menu(0,
["Control", "Insert window"],
<"Insert window", insertion_fen>)
set_menu("menu.p3", ["Insert"],
<"Insert", insertion_fen>);
{}
insertion_fen(0) ->
front_window(u)
reinsert(u);
insertion_fen(u) ->
string(u)
reinsert(u);
1On Sunview, each element in the list of values must be a leaf (a single level).
© PrologIA 489
Prolog
Graphics primitives Aociation
HERITAGE
Example :
File
Do
Size 1
2
3
File
Do goal1
Size Stop
In the following primitives, the first and last arguments are governed by the
same conventions as set_menu :
check_item(u,p,v)
This primitive installs or removes the "ticking" of an item. v indicates
whether an item has been ticked with the standard ticking mark: 0 for
not ticked, 1 for ticked.
If v is an integer greater than 1, the corresponding character of the host
machine is used to tick the item.
Example:
> check_item(0,["Windows","trace"],1);
490 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
command_menu(u,p,v)
v is the code of the character used in conjunction with the command
key (apple), as a keyboard equivalent to activate the item specified by
the first two arguments.
Example of a keyboard equivalent: T to activate the Prolog trace:
> char_code(`T`,n)
command_menu(0,["Control","trace"],n);
enable_menu(u,p,v)
Is used to deactivate (v =0) or reactivate (v =1) a menu or item. The
following example deactivates the whole editing menu:
> enable_menu(0,["Edit"],0);
style_menu(u,p,v)
Specifies the style of a menu item. v is an integer in which each bit
represents one of the styles specified in the gr_text primitive
The example below puts the trace item of the Windows menu in
underlined italics (bits 1 and 2 positioned):
> style_menu(0,["Fenêtres","trace"],6);
clear_menubar
Calls save_menubar and then clears the standard menu bar. This
primitive can be used to redefine the menu bar completely.
save_menubar
Saves the current menu bar. This rule can only be called once.
restore_menubar
Restores the menu bar saved with save_menubar.
© PrologIA 491
Prolog
Graphics primitives Aociation
HERITAGE
add_stdmenu(s)
This primitive is used to reinsert one or more standard menus following a
call to clear_menubar. s must be one of the following strings:
"apple" : to reinsert the Apple menu
"file" : to reinsert the File menu
"edit" : to reinsert the Edit menu
"find" : to reinsert the Find menu
"control" : to reinsert the Control menu
"window" : to reinsert the Window menu
gr_dialog(d,l1,l2)
gr_dialog(p,d,l1,l2)
To use this primitive, you must first load the dial.mo3 module. This
module contains the Prolog III dialog manager which is used to create
and activate dialogs described by the second argument d.
In its second form, the gr_dialog primitive also accepts an additional
argument p which enables the position of the top lef-hand corner of the
dialog to be parameterized, in the form of an <x,y> pair.
d
can either be a tree describing a dialog, or the identifier of a unary
rule which has such a tree as an argument.
l1
is a possibly empty list of pairs
zone_name | initial_value
where zone_name represents an identifier or constant. This list is
used to define or redefine the contents of the zones.
l2
In output, if l2 is a variable it is unified with the list of dialog pairs
[zone_name | final_value]. If l2 is a list of [zone_name | X], pairs, each
of these pairs is unified with the corresponding dialog pair.
492 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
Example:
> reload("dial.mo3");
{}
> gr_dialog(["Hello"|buttonD("OK")],[],L);
> gr_dialog(<50,50>,
[[field1|"John"]],
L);
:text(s) or s
Describes a line of non-editable text represented by s, where s is a
string.
© PrologIA 493
Prolog
Graphics primitives Aociation
HERITAGE
:text(i)
Describes a line of non-editable text with a zone name i where i is an
identifier. If a value is associated with i in l1 this will be the initial
value of the field, otherwise it is the empty string. A final value is
never associated with this zone, since it is not modifiable.
:cb(i), :cb(i,v)
Describes a check box. represented by one of the two possible values
for v: 1 or 0. If v's value is given neither in an argument nor in the
list l1, the value 0 will be given by default. When v is redefined in l1,
it is always this latter value which is taken into account.
:rb(<g,i>), :rb(<g,i>,v)
Describes a 'radio button' i in a group g (where g is an identifier, and
i is a constant). This radio button has the value 0 or 1, and is part of
the group g. There can only be one value at 1 in the group. If v's
value is given neither in an argument, nor in the list l1, the value 0
will be taken by default. When v is redefined in l1, it is always this
latter value which is taken into account. In output, zone_name is
represented by <g,i>1 and final_value by 0 or 1. This applies to each
radio-button in the group.
:rb1(<g,i>), :rb(<g,i>,v)
The same as rb apart from two differences: the elements in the
group cannot all be at zero, and only the element having the value 1
appears in the output list. zone_name is represented by g, and
final_value by i. This output format is therefore different from rb and
is also simpler.
:editf(n,i), :editf(n,i,s)
Describes a zone of an editable line of text named i, where i is an
identifier and s represents the initial value of the edit zone. This
initial value is the empty string if it is specified neither in an
argument nor in the list l1. n is an integer representing the
minimum number of characters in the zone. If s is greater, the zone
expands dynamically.
1In contrast to Prolog II+, the pair <g,i> does not represent the same tree as g(i).
494 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
:button(s,i)
Describes a button labeled s associated with an action defined by the
identifier i. When the button is pressed, an action is performed:
- If i is fail, the dialog terminates, and gr_dialog fails.
- If i is [], nothing happens.
- Otherwise, the goal i(l) is activated, in which l is the binary list
of [name|value] pairs in the dialog zones when the button is clicked.
Once the goal corresponding to the rule <i, 1> has been executed, the
dialog management continues as before. To stop the current dialog,
the user can program execution of a block_exit(<fail,L>) which will
cause backtracking of gr_dialog, or a block_exit(<[],L>) which will
result in normal termination.
:button2(s,i)
This item behaves in the same way as :button, except that the rule i is
called with two arguments. The first is a list describing the state of
the dialog items. The second is a variable when called, which must
be instantiated by the rule <i,2> with the list of items whose values
have changed. This rule is written by the user, and thus enables any
semantics to be associated with the buttons. The rule defines a
relation between the first argument (input argument representing
the list of present values), and the second argument (output
argument representing the list of new values).
:glist(l,c,i,l_init)
Defines a list of values, with a scroll bar. The meanings of the
arguments are as follows:
l
Integer representing the number of items which must be visible.
The height of the rectangle is automaticaly calculated in
accordance with this parameter.
© PrologIA 495
Prolog
Graphics primitives Aociation
HERITAGE
c
Integer representing the number of characters that must be
visible for an item. The width of the rectangle is automatically
calculated in accordance with this parameter.
i
Identifier giving the manager an internal name. It is used to give
the output result.
I_list
List of constants (strings, identifiers, numbers) which represents
the list of initial values. An initial selection can be proposed by
providing a triple describing the state of the manager. This triple
must have the following form:
<InitList, SelectedNbs, TopNumber>
- The first argument is a list of constants representing the list of
initial values.
- The second argument is the ordered list of the ranks of the
items constituting the initial selection. This list may comprise 0
(no selection), 1 or several elements).
- The third argument indicates the item number to display at
the top of the display rectangle.
:userItem(t, i, e, s)
This is used to extend the items processed by a dialog. The user
must provide a group of rules <i,2>, which is capable of responding
to a certain number of actions required by the dialog manager in
charge of event and activation management. The meanings of the
parameters are as follows:
496 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
t
Term identifying the relevant item, used as a zone name if the
value can be extracted.
i
Identifier of a two argument rule written by the user to
manage actions relevant to this item (see below for the possible
actions).
e
Value describing the state of the item, managed by the user
during the actions.
s
Describes the possible types of action on this item:
0 insensitive.
1 can be activated by a click.
2 can be activated by a click or text input (TAB).
:col(l), or l
Describes a left-aligned column whose contents are described by l. If
l is a list, the primitive calculates the size of each element in the list
and constitutes a column of elements arranged one above the other,
aligned to the left.
:ccol(l)
Describes a vertically centered column, whose contents are described
by the list l.
:row(l)
Describes a horizontal row described by the (series of) primitive(s) l,
whose elements are aligned to their top edges. If l is a list, the
primitive calculates the size of each element, and constitutes a row of
elements arranged side by side, aligned to their top edges.
© PrologIA 497
Prolog
Graphics primitives Aociation
HERITAGE
:crow(l)
Describes a row of objects described by l and centered horizontally,
i.e. arranged so that their middle points are aligned on the same
horizontal line.
:vfill(n)
Describes a vertical space of n pixels, where n is an integer.
:hfill(n)
Describes a horizontal space of n pixels, where n is an integer.
Examples:
> gr_dialog(<50,50>,
:ccol(["Do you want to re-start the test?",
:buttonD,:button("Cancel",fail) ] ),
[], L );
498 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
> gr_dialog(
["Choose the color you want",
:crow([ :rb(<rb1,red>,1),"Red",
:rb(<rb1,green>),"Green"] ),
:crow([ :cb(cb1,0),"Extended colors"] ),
:ccol([ :buttonD("Show Color"),
:button("Cancel",fail)] )
],
[[cb1|1]],
[[cb1|C],[<rb1,red>|R],[<rb1,green>|G]] );
{ C = 1, R = 1, G = 0 }
>
© PrologIA 499
Prolog
Graphics primitives Aociation
HERITAGE
> gr_dialog(<50,50>,
[:crow([
"abcdefgh",
:ccol([ :button("Stop",fail),
:buttonD("OK",[]),
:button("Cancel",fail),
"HELLO WORLD"
] ),
"ijklmnopq"
] )
],
[],
l );
> gr_dialog(
[:glist( 5,10,list1,
<[red,green,blue,yellow,
violet,black,white,orange],
[4,6], 2> ),
:buttonD],
[],
L);
500 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
>
enable(l1, l3) ->
set_item(l1, zone1, 1, l2)
set_item(l2, zone2, 0, l3);
© PrologIA 501
Prolog
Graphics primitives Aociation
HERITAGE
> gr_dialog(
[:group( [zone1,0],
[ "Hello",
:crow([:rb1(<color,red>,"Red"]),
:crow([:rb1(<color,green>,1),"Green"]),
:editf(5,ed1,"aa"),
:button2("Disable",disable)
] ),
:group( [zone2,1],
:button2("Enable",enable)),
buttonD
],
[],
L);
{ L = [[color|green], [ed1|"aa"]] }
User extensions
502 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
:size(IdentifyingTerm,State)
Requests calculation of the size of the item when the dialog is
initialized. The result must be a pair <dx,dy> of numbers of pixels.
© PrologIA 503
Prolog
Graphics primitives Aociation
HERITAGE
:draw(IdentifyingTerm,State,Rectangle,Active)
Requests drawing of the item IdentifyingTerm in the Rectangle
rectangle (in the form <x1,y1,x2,y2>) with a description of State and
located in an activated group if Active is 1, or a deactivated group if
Active is 0 (it is recommended not to show the field values in the
deactivated zones). The result is ignored.
:click(IdentifyingTerm,State,Rectangle,ClickedPoint)
Requests realization of the action associated with a click on the item.
ClickedPoint has the form <x,y,m> (see gr_click, 4).
The result is a pair <NewState,Termination> where:
NewState will replace the State field of the userItem.
Termination will have the following form:
<> If no user interaction is involved.
<n> If the rule manages a local loop to process the
item and interaction terminates with a CR character (n=0) a TAB
(n=2) or a non-read click (n=1).
<x,y,m> If the rule manages a local loop to process the item and
interaction terminates with a click outside the item rectangle.
If the state of the item changes, it must be drawn again before
termination.
:edit(IdentifyingTerm,State,Rectangle)
Requests input of characters in the item. The result will have the
same form as above.
:extract(IdentifyingTerm,State)
Requests extraction of the item's current value to form the pair
[IdentifyingTerm | Value] which is provided as output or passed to
the items which act upon the dialog (:button2 for example). If the
query fails, it is assumed that there is no result to associated with the
item. Otherwise the result must be the value part.
504 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
>
circ_list(:size(_,<N,L>), <x,20>) ->
max_width(L, 20, x);
circ_list(:draw(_,V,R, _active), _) ->
myItemDraw(V, R, _actif);
circ_list(:extract(_,<N,L>), V) ->
arg2(N, L, V);
circ_list(:click(i,<N,L>,R,P), <<N1,L>,<>>) ->
arg2(0, L, M)
mod(N, M, N1-1)
circ_list(:draw(i,<N1,L>,R,1), _) ;
© PrologIA 505
Prolog
Graphics primitives Aociation
HERITAGE
> gr_dialog(
[:row(
[:userItem( myItem(list1),
circ_list,
<1,["FIRST","abcd","e","LAST"]>,
,1),
"<-- user Item"
] ),
:buttonD
],
[],
L);
{ L = [[myItem(list1) | "e"]] }
506 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
Here is an example of an item that displays icons and changes icons when it
is clicked:
>
iconManager(:size(_,_), <32,32>) -> ;
iconManager(:draw(_,V, R, _), _) ->
gr_icon(V, R);
iconManager(:extract(_,V), V) -> ;
iconManager(:click(N,V,R,P), <V2,<>>) ->
mod(V+1, 3, V2)
iconManager(:draw(N,V2,R,1), _ ) ;
> gr_dialog(
[:row(
[:userItem(myIcon,iconManager,1,1),
"<-- user Item"
] ),
:buttonD ],
[], L);
{ L = [[myIcon | 1]] }
© PrologIA 507
Prolog
Graphics primitives Aociation
HERITAGE
9 . Active buttons
The primitives described in this section are used to associate Prolog goals
with buttons. The goals are started as soon as the button is pressed, in a
similar way to goal activation by menu, i.e. current execution is suspended.
Prolog III manages refreshment of the button.
X create_button(s,w,p,x1,y1)
Creates a button named s in the window named w (s and w must be
strings).
x1,y1
represent the coordinates of the button in relation to the top left-
hand corner of the window.
p
is the goal identifier (with no argument) which will be started
when the button is clicked.
X activate_button(s)
Makes it possible to activate button s.
X deactivate_button(s)
Makes the button named s inactive. The text is shown in gray.
X kill_button(s)
Deletion of the button named s.
input (x)
With x as a free variable, this primitive displays a file selection dialog
menu (text type only), and unifies x with the name and access path of
the chosen file, once it has been opened for reading. It fails if the Cancel
button is clicked (also refer to to the sfgetfile primitive).
508 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
output (x)
With x as a free variable, this primitive displays a file-name input dialog
menu (text type only), and unifies x with the entered file-name and
access path, once the file has been opened for writing. It fails if the
Cancel button is clicked (also refer to to the sfputfile primitive).
gr_load(s)
Draws the contents of a MacPaint or MacDraw graphics file called s, in
the current graphics window:
sfgetfile(s)
Displays a dialog box enabling the user to select a text file on the disk,
and unifies s with the access path and name of this file (the file is not
open). The rule fails if the Cancel button is pressed. This rule is a
simplified version of the next rule.
sfgetfile(point,L_types,filter,s)
Displays a dialog box enabling the user to view files located on the
disk(s) according to their type, and to select one of these files (the file is
not opened).
point
is a point in the format <x,y> indicating the location at which the
dialog is displayed.
L_types
is a list of types specifying which files are proposed. The types are
4-character strings, as defined in Inside Macintosh.
Example: ["TEXT","APPL"] will show all text only and application
type files.
filter
is another filtering procedure (in addition to the type filter),
applying to the proposed files. For the moment, this must be [].
© PrologIA 509
Prolog
Graphics primitives Aociation
HERITAGE
s
is unified with the selection made by the user. It has the form:
<C,T,N> where C is the creator (4-character string identifying the
application which created the file), T is the file type (4-character
string such as "TEXT", "APPL", etc.), and N is a string indicating
the access path and name of the selected file (the file is not open).
The rule fails if Cancel is pressed.
sfputfile(s)
Displays a dialog box enabling the user to enter a file-name on the disk,
and unifies s with the access path and name of this file. If the user
enters the name of a file that already exists, an alert box provides a
warning. The rule fails if the Cancel button is pressed.
510 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
© PrologIA 511
Aociation Prolog
HERITAGE
Prolog
Aociation
HERITAGE
Graphics primitives
:button 496
:button2 496 activate_button 509
:buttonD 496 add_stdmenu 493
:cb 495 "apple" 493
:ccol 498 button 481; 496
:clipRect 472 carriage return 485; 496; 505
:col 498 carriage return key 482
:crow 499 check box 495
:editf 496 check_item 491
:erase 471; 473 clear_menubar 492
:eraseOval 472 clear_window 469
:eraseRect 471 click 476; 482; 485; 486; 498; 504
:eraseRoundRect 472 command_menu 492
:frame 471; 472; 473 console 462
:frameOval 472 "control" 493
:frameRect 471 create_button 509
:frameRoundRect 472 create_window 468
:glist 497 current graphics window 470
:group 499 deactivate_button 509
:hfill 499 description primitives 495
:invert 472; 473 "DISTANCE" 465
:invertOval 472 "EDIT" 465
:invertRect 472 "edit" 493
:invertRoundRect 472 editable line of text 496
:paint 471; 472; 473 enable_menu 492
:paintOval 472 "file" 493
:paintRect 471 file selection dialog 509
:paintRoundRect 472 file-name input dialog 510
:rb 495 file_window 464
:rb1 495 "find" 493
:row 499 "FONT" 466; 468
:text 495 font 466; 469; 478; 479; 480
:userItem 498 "FONTSIZE" 466; 468
:vfill 499 font size 469; 478; 479; 480
© PrologIA 513
Prolog
Graphics primitives Aociation
HERITAGE
514 © PrologIA
Prolog
Aociation
HERITAGE
Graphics primitives
sfputfile 511
"SHAPE" 465
srcBic 479
srcCopy 479
srcOr 479
srcXor 479
stty 483
style 478; 479; 492
style_menu 492
tabulation 482; 485; 498; 505
termination button 496
ticked item 489
ticking mark 491
transfer modes 479
"TTY" 465; 484
user_item 504
vertical coordinates 470
vertical space 499
"window" 493
© PrologIA 515
Prolog
Graphics primitives Aociation
HERITAGE
516 © PrologIA
Aociation Prolog
HERITAGE
Appendices
HERITAGE
518 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
© PrologIA 519
Prolog
Appendices Aociation
HERITAGE
520 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
Control
assign(I, T)
assign(tab(N), T)
block(E, B)
block_exit(E)
block(E, C, B)
block_exit(E, C)
bound(T)
cut
default(T1, T2)
dif(T1, T2)
eq(T1, T2)
fail
findall(V, P, L)
free(T)
freelabel(T)
© PrologIA 521
Prolog
Appendices Aociation
HERITAGE
freeze(T, P)
known(T)
not(T)
predefined(T)
repeat
val(T1, T2)
Numeric constraints
bound_mult(N1, N2, N3)
div(N1, N2, N3)
enum(R)
enum(R, R1)
enum(R, R1, R2)
gcd(N1, N2, N3)
lcm(N1, N2, N3)
max_value(R1, R2)
min_value(R1, R2)
mod(N1, N2, N3)
mult(N1, N2, N3)
numden(R, N1, N2)
particular_value(R1, R2)
pgcd(A, B, P)
ppcm(A, B, P)
trunc(R, N)
Conversion
char_code(C, N)
list_string(L, S)
list_tuple(L, U)
split(U, L)
string_bool(S, B)
string_ident(P, S, I)
string_ident(S, I)
string_integer(S, N)
string_real(S, F)
Environment
cpu_time(N)
edinburgh
edit(I)
exit
exit(S)
garbage_collection
get_config(S, V)
get_configuration(U)
getenv(S1, S2)
no_trace
prologIII
quit
522 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
quit(N)
reset_cpu_time
resume_trace
save
save(L, F)
save(S)
set_config(S, V)
set_configuration(U)
state
suspend_trace
sys_command(S)
trace
trace_file(S)
Input/Output
close_input
close_input(F)
close_output
close_output(F)
echo
in_char(C)
in_char'(C)
in_ident(I)
in_integer(N)
in_real(R)
in_sentence(T1, T2, T3)
in_sentence'(T)
in_string(S)
in_term(T)
inl(S)
input(F)
input_is(F)
insert
insert(F)
line
next_char(C)
next_char'(C)
no_echo
out(T)
outc(T)
outl(T)
outm(S1, S2, …, SN)
outml(S1, S2, …, SN)
output(F)
output_is(F)
reinsert
reinsert(F)
reload(F, L)
© PrologIA 523
Prolog
Appendices Aociation
HERITAGE
Type verification
bool(B)
char(C)
dot(T)
ident(I)
integer(N)
is_bool(B)
is_char(C)
is_ident(I)
is_leaf(T)
is_num(R)
is_tuple(U)
is_univ(T)
num(R)
524 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
rational(R)
real(F)
string(S)
tuple(U)
Control
','(X, Y)
'->'(Y)
';'(X; Y)
'[]'(X, Y)
[]
[X|Y]
call(P)
nonvar(T)
true
var(T)
Input / Output
consult(S)
get(X)
get0(X)
nl
put(X)
© PrologIA 525
Prolog
Appendices Aociation
HERITAGE
read(T)
see(F)
seen
tab(N)
tell(F)
told
write(T)
writeq(T)
Type verification
atom(T)
atomic(T)
number(R)
526 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
The example programs in this appendix are translations into Edinburgh syntax of
the main example programs given in the manual.
© PrologIA 527
Prolog
Appendices Aociation
HERITAGE
The program:
lightMeal(H,M,D) :-
horsDoeuvre(H,I),
mainCourse(M,J),
dessert(D,K)
{I>=0, J>=0, K>=0, I+J+K=<10}.
mainCourse(M,I) :- meat(M,I).
mainCourse(M,I) :- fish(M,I).
horsDoeuvre(radishes,1).
horsDoeuvre(pate,6).
meat(beef,5).
meat(pork,7).
fish(sole,2).
fish(tuna,4).
dessert(fruit,2).
dessert(ice_cream,6).
Query:
?- lightMeal(H,M,D).
528 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
factorial(0, 1).
factorial(N, N*M) :- factorial(N-1, M) {N >= 1}.
Queries (the 4th may or may not work with floating-point numbers
since it depends on the floatting-point numbers implementation)
?- factorial(10, X).
?- factorial(40, X).
?- factorial(100, X).
?- factorial(100.0, X).
?- factorial(1000, X).
© PrologIA 529
Prolog
Appendices Aociation
HERITAGE
The program:
instalmentsCapital(<>, 0).
instalmentsCapital(<I>.X, C) :-
instalmentsCapital(X, C+(10/100)C-I).
530 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
The program:
leavesOf(A, X) :-
leavesOfTree(A, X, <>).
leavesOfTree(E[<>], <E>.X, X) .
leavesOfTree(E[U], X, X') :-
leavesOfList(U, X, X')
{U # <>}.
leavesOfList(<>, X, X) .
leavesOfList(<A>.U, X, X'') :-
leavesOfTree(A, X, X'),
leavesOfList(U, X', X'').
Queries:
© PrologIA 531
Prolog
Appendices Aociation
HERITAGE
The program:
valueOfSomethingHasAlwaysExisted(B)
{ A = 1',
A => (B | C) & ~(B & C),
A => (D | E) & ~(D & E),
D => B,
E => ~C }.
Query:
?- valueOfSomethingHasAlwaysExisted(B).
532 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
The program:
possibility(<
<A,"clear-headed">,
<B,"well-educated">,
<C,"constantly talking">,
<D,"using one's influence for good objects">,
<E,"exhibited in shop-windows">,
<F,"fit to be an M.P.">,
<G,"public benefactors">,
<H,"deserving praise">,
<I,"popular">,
<J,"unassuming">,
<K,"women">,
<L,"never-to-be-forgotten">,
<M,"influential">,
<N,"able to keep a secret">,
<O,"expressing oneself well">,
<P,"worth one's weight in gold">>)
{
(F & ~C) => G,
(A & O) => B,
(K & H) => N,
(G & ~D)=> ~F,
(P & H) => J,
(G & D) => H,
(~I & ~P) => ~N,
(C & F) => H,
(N & J) => (G & L),
(K & G) => I,
(P & C & L) => E,
(K & ~A & ~B) => ~F,
(N & ~C) => ~I,
(A & M & D) => G,
(G & J) => ~E,
(N & D) => P,
(~O & ~M) => ~K,
(I & H) => (G | J)
}.
© PrologIA 533
Prolog
Appendices Aociation
HERITAGE
subSet(<>,Y).
subSet(<E>.X,Y) :- elementOf(E,Y), subSet(X,Y).
elementOf(E,<E>.Y).
elementOf(E,<F>.Y) :- elementOf(E,Y) {E#F}.
?- subPossibility(<<A,"clear_headed">,
<I,"popular">,
<N,"able to keep a secret">>).
?- subPossibility(<<K,"women">,
<F,"fit to be an M.P.">>) {K!bool,F!bool}.
534 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
The program:
/*
Fault detector in an adder
Note that the 3rd constraint of the following rule contains
the term (U1|U2), parenthesed to avoid a bug during the
syntactic analysis of the OR operator (|) .
*/
circuit(<X1,X2,X3>, <Y1,Y2>, <P1,P2,P3,P4,P5>) :-
atMostOneTrue(<P1,P2,P3,P4,P5>)
{ ~P1 => ( U1 <=> X1 & X3 ),
~P2 => ( U2 <=> X2 & U3 ),
~P3 => ( Y1 <=> (U1 | U2) ), %() to patch a bug
%with the “|” op.
~P4 => ( U3 <=> ~(X1 <=> X3)),
~P5 => ( Y2 <=> ~(X2 <=> U3)) }.
atMostOneTrue(P) :- orOnAtMostOneTrue(P,_p).
orOnAtMostOneTrue(<>, 0').
orOnAtMostOneTrue(<E>.P, E|V) :-
orOnAtMostOneTrue(P, V)
{E&V = 0'}.
boolean(0').
boolean(1').
?- circuit(<1',1',0'>,<0',1'>,<P1,P2,P3,P4,P5>).
?- circuit(<0',0',1'>,<0',1'>,<P1,P2,P3,P4,P5>).
?- circuit(<1',0',1'>,<0',0'>,<P1,P2,P3,P4,P5>).
?- circuit(<X1,X2,X3>,<Y1,Y2>,<P1,P2,1',P4,P5>).
© PrologIA 535
Prolog
Appendices Aociation
HERITAGE
?- circuit(<X1,X2,X3>,<Y1,Y2>,<P1,P2,1',P4,P5>),
booleans(<X1,X2,X3,Y1,Y2>).
?- circuit(<X1,X2,X3>,<Y1,Y2>,<P1,P2,1',P4,P5>),
booleans(<X1,X2,X3,Y1,Y2>),
circuit(<X1,X2,X3>,<Y1,Y2>,<P1,P2,0',P4,P5>).
?- circuit(<X1,X2,X3>,<Y1,Y2>,<P1,P2,1',P4,P5>),
booleans(<X1,X2,X3,Y1,Y2>),
not(circuit(<X1,X2,X3>,<Y1,Y2>,<P1,P2,0',P4,P5>)).
536 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
The program:
SEND
+ MORE
------
MONEY
*/
solution(I, J, K) :-
allDifferentDigits(<M,S,O,E,N,R,D,Y>),
integers(<M,S,O,E,N,R,D,Y>)
{ S#0, M#0, I+J=K,
I = 1000S + 100E + 10N + D ,
J = 1000M + 100O + 10R + E ,
K = 10000M + 1000O + 100N + 10E + Y
}.
integers(<>).
integers(<E>.R) :- enum(E), integers(R).
allDifferentDigits(<>).
allDifferentDigits(<X>.S) :-
outsideOf(X, S),
allDifferentDigits(S)
{0 =< X, X =< 9}.
outsideOf(X, <>).
outsideOf(X, <Y>.S) :- outsideOf(X, S) {X#Y}.
The query:
?- solution(I,J,K).
© PrologIA 537
Prolog
Appendices Aociation
HERITAGE
The program:
fillRectangle(A, C) :-
createSquares(C),
fillZone(<-1,A,1>, L, C, <>)
{A >= 1}.
createSquares(<>).
createSquares(<B>.C) :-
createSquares(C),
makeDistinct(B, C)
{B > 0}.
makeDistinct(B, <>).
makeDistinct(B, <B'>.C) :-
makeDistinct(B, C)
{B # B'}.
fillZone(<V>.L, <V>.L, C, C)
{V >= 0}.
fillZone(<V>.L, L''', <B>.C, C'' ) :-
placeSquare(B, L, L'),
fillZone(L', L'', C, C'),
fillZone(<V + B, B>.L'', L''', C', C'')
{V < 0}.
?- fillRectangle(A, C) {C :: 9}.
538 © PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Prolog III
Version 1.3
User's Manual
MS-DOS
Aociation Prolog
HERITAGE
Copyright
This manual and the software it describes are protected by copyright. According
to the legislation dealing with these rights, this manual and software must not
be copied or adapated either wholly or in part, without the written consent of
PrologIA except within the normal bounds of use or to create a back-up copy.
However these exceptions do not authorise the user to create copies to be used by
a third party, regardless of whether or not they are to be sold.
Prolog III is a registred trademark of PrologIA.
Aociation Prolog
HERITAGE
This chapter explains those characteristics of the Prolog III system that are
dependent on the machine or operating system used.
It is mainly concerned with the installation procedure for the Prolog III system and
the particular characteristics relevant to its activation (execution parameters, space
sizes, etc.).
This chapter also explains how to add your own external predefined rules to Prolog
III, written in any programming language compatible with the C language.
HERITAGE
This section describes how to install the Prolog III software on an MS-DOS
PC. We recommend you read the whole section before starting the
installation.
The PC version of Prolog III only functions on equipment that uses the Intel
386 processor (or greater). A minimum of 4 Mb read/write memory is
required; more memory is advizable to ensure comfortable utilization, and a
hard disk is strongly recommended. The system must be a 3xx version or
more recent.
1002 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
The Prolog III distribution kit consists of two 51/4 " 1.2 Mb floppy disks
containing the files listed below. Source files, object files and executable files
intended for use in real mode are prefixed by "rm" (real mode).
Essential files
prolog3.exe
File containing the Prolog III interpreter (protected mode).
rmprolog.exe
Executable file of the real mode part of Prolog III.
prolog3.bst
File required for start-up of the interpreter.
© PrologIA 1003
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
prolog3.lex
Data file for Prolog III's syntactic analyzer.
prolog3.syn
Analyzer error messages. In fact this is a copy of either the
prolog3.sya or prolog3.syf file (see additional files).
prolog3.err
Interpreter error messages. This is a copy of either the prolog3.era or
prolog3.erf file (see additional files).
initial3.psv
Initial saved state, containing in particular the declarations of the
predefined rules in coded form.
prolog3.prf
Options file containing a configuration in the form of a modifiable
command line (see next section). In fact this file is only essential if a
non-default configuration is to be used, and the user wishes to avoid
having to type the DOS command to start Prolog III.
edinburg.mo
Module containing the declarations of the predefined rules available
in Edinburgh syntax, in a coded form. It is not required if you do
not wish to use these rules.
Additional files
prolog3.sya
Analyzer error messages (English version)
prolog3.syf
Analyzer error messages (French version)
prolog3.era
Interpreter error messages (English version)
prolog3.erf
Interpreter error messages (French version)
EXEMPLES
This directory contains a number of Prolog III source programs.
1004 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
REALMODE
This directory contains a number of source and object programs
which add primitives to Prolog III while remaining in real mode
(Microsoft C).
386PMODE
This directory contains a number of source and object programs
which add primitives to Prolog III using the protected mode
(Metaware High C).
Installation procedure
First create a directory to contain the files constituting the Prolog III system
(called \PIII for example). Copy the files and directories from the
distribution volumes into this directory, and then store the distribution
volumes in a safe place. To use Prolog with a minimum of disk space, you
can if you wish only copy the essential files listed above. It is preferable to
copy the following files into the same directory: prolog3.exe, rmprolog.exe,
initial3.psv, prolog3.bst, prolog3.err, prolog3.syn, prolog3.prf and prolog3.lex.
© PrologIA 1005
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
C> prolog3
Only the first line of the prolog3.prf file is taken into account. Here is a
relatively complex example:
1006 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
The first parameter must be present; for the moment it is ignored. These
specifications configur the Prolog III session as follows: the copy stack (c) is
given a size of 30,000 words, the restoration stack (b) a size of 2,000 words,
the rule space (r) has 100,000 words, and the auxiliary algebra space (u)
comprises 200 words. Also, standard output (O) is re-oriented to the
“output.log” file, and input (I) is read from the “input.log” file. Finally, the
display of all messages apart from error messages is canceled.
The user can store this command line in a file called prolog3.prf. If there is no
parameter on the command line, Prolog III searches for this file at start-up;
first in the current directory, otherwise in the directory indicated by
environment variable PrologDir3.
In general, the list of options has the following structure (the sign … signifies
that an argument must be present adjoining the option):
I… O… c… u… b… r… m… Y… -i… -e… q
Ifile specifies an input file which from the start of the Prolog III
session, will replace the keyboard. This assumes non-
interactive utilization of Prolog III. For this reason, this
option and the next one are not normally used.
csize specifies the size of the copy stack (space for structure
construction) in 4-byte words. Minimum recommended
value: 10,000.
rsize specifies the size of the rule space in 4-byte words. Minimum
recommended value: 50,000. The Edinburgh mode rules
contained in the edinburg.mo file take up 14,000 mots.
© PrologIA 1007
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
Y file specifies an error message file. The file used by default is the
supplied prolog3.syn file.
Program interruption
K to abort the current program (and return to the higher level of the
Prolog III interpreter).
T to activate or deactivate the trace (flip-flop).
It is also possible to type a digit from 0 to 3 indicating the level of the trace (0
for no trace, 2 for an "ordinary" trace). Please refer to the trace primitive for
more details.
1008 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
1. Integers are only limited by the size of your computer's memory, and by
the following restriction: the number of 4-byte words required to represent
an integer must be less than 16,777,215 (which is a pretty big integer !).
All these sizes are expressed in four-byte words, except for the two
dictionaries whose sizes are given in bytes. This configuration is perfect for
a machine with 4 Mb of read/write memory (therefore 3 Mb of extended
memory).
© PrologIA 1009
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
Prolog III enables you to edit rules without leaving Prolog using any editor
available on your system: edlin, m, etc… which we will refer to as host
editors. Evidently, this editor can only be called if there is enough memory
space to load it (the system will doubtless attempt to load in the 640K zone).
The host editor is activated by the Prolog III command edit. There are
several variants of this command, to modify one or more groups of rules.
This command is used to edit the groups of rules whose names are given as
arguments. When editing is terminated, the edited groups replace the
original groups. The groups can belong to several different modules, in
which case the reading-writing context of the first group's module is used.
edit(<ident, arity>)
edit(L)
<ident, arity> represents the group of rules whose access is the identifier ident
and whose number of arguments is arity. In the second version L is a list of
<ident, arity> elements, as in the example [<sentence,1>,<verb,2>]. If L is a
free variable all the groups of the current module are edited.
On return from a call to the host editor, Prolog III may detect a syntactic
error in the rules you have just edited. It will display the number and
contents of the line containing the error, together with the corresponding
diagnosis. At present, this feature is only available in Prolog III syntax (default
syntax), not Edinburgh syntax.
1010 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
The host editor called by Prolog III is the one defined by the environment
variable (in the DOS sense) PrologEdit. You can change the definition of this
variable. Prolog III calls the host editor by calling the program contained in
PrologEdit equipped with a parameter PROEDIT.P3; a temporary file into
which the rules to edit have been copied beforehand.
This section shows how to add new predefined rules to the standard set, and
describes the interface procedures. These rules can either be written entirely
in Prolog III (which therefore does not involve any new concept), or can
refer to external functions written in C or any other language compatible
with C. Communication procedures enable parameters to be passed
between the Prolog rules and the external program. These parameters must
be integers, reals or character strings. The external function may either
succeed or cause backtracking.
The user module acts as a link between Prolog and the user routines written
in C or another language compatible with C. In this way it is possible to
have predefined rules in both languages simultaneously. This user module
is a C source file supplied with the Prolog III system:
If you have a High C compiler, this module is the UserRule.c file located in
the 386PMODE directory
otherwise you must use the rmUser.c file located in the REALMODE
directory .
© PrologIA 1011
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
Method
When Prolog III is started for the first time, the standard initial state of the
work memory is loaded (initial3.psv file). The following steps must be
followed to add new predefined rules written in another language:
• choose a specific integer, different from all those already used for this
purpose, to create the link between the identifier which will be the
name of the rule in Prolog III and the identifier which will be the name
of the external procedure. This number must be greater than 500 and
if you are working in real mode (rmUser.c file), it must be greater than
20,000.
• in the Prolog III universe, associate this link-number with the name of
the new rule. This is done using the primitive set_ident(rule-name,
number). It will subsequently be necessary to save this declaration in a
new version of the initial3.psv file, which will then fulfill the role of an
"enriched" initial state.
Finally, the links must be edited between the external program and
Prolog III to produce an executable containing the new rule. Given that
Prolog III is formed by two executables prolog3.exe and rmProlog.exe running
at the same time - one for real mode, the other for protected mode - only
one of these two files must be reconstructed by the link editor:
1012 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
The interface between the Prolog III form of an external rule and its actual
implementation in another language is created by a C function constituting
the essential part of the UserRule.c file, which has the following heading:
The print-out of the UserRule.c file is at the end of this chapter. To execute
an external rule, you need to know that Prolog III calls this function with the
folllowing values as its arguments:
Ptr_to_BIP is the address of the Prolog III term corresponding to the
call to the external rule (i.e. the address of the goal to execute).
It is therefore a tree whose label is the name of the external rule
and whose sons are the arguments of the call.
UserRule(Ptr_to_BIP, Ident_num_of_BIP)
The value returned by the UserRule function determines whether the
execution of the external rule was successful or not. If UserRule sends back a
non zero value (for example the constant TRUE), then Prolog III considers
that, as far as concerns the external program, the execution was successful.
If UserRule sends back zero (FALSE) then the execution of the external rule is
considered to have ended in failure, which will produce backtracking.
© PrologIA 1013
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
1014 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
• The second data transfer system is compatible with Prolog II+ and is
formed by the following C procedures:
get_integer
get_real
get_string
put_integer
put_real
put_string
General functions:
adr GetArg(no_arg,term)
long int no_arg;
adr term;
int PutArg(no_arg,term,value)
long int no_arg;
adr term;
adr value;
© PrologIA 1015
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
GetArity(term)
Returns the arity, or number of arguments, of the term pointed by term.
GetArg(no_arg, term)
Returns a pointer to the term which is the son of rank no_arg in the term
pointed by term. An error occurs if this argument does not exist, indicated
by the fact that the function returns NULL.
In addition, GetArg(0, term) returns a pointer to the label of term.
Conversion functions
1 The adr type represents the "most general address", i;e; the " char * " type.
1016 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
adr Convert_StringC_to_StringP(buf)
char* buf;
long Convert_StringP_to_StringC(t,buf,size_buf)
adr t;
char* buf;
long int size_buf;
adr Convert_LongIntC_to_IntP(n)
long int n;
int Convert_IntP_to_LongIntC(t,i)
adr t;
long int* i;
adr Convert_DoubleC_to_NumP(f)
double f;
int Convert_NumP_to_DoubleC(t,f)
adr t;
double* f;
Convert_StringC_to_StringP(buf)
Transforms the C string (ending in zero) pointed by buf into a Prolog III
string. Returns the address of the term thus constructed, or NULL if the
transformation could not be performed.
Convert_StringP_to_StringC(t,buf,size_buf)
Opposite transformation to the above: t must be the address of a Prolog III
character string term. buf is the address of a space which has a size of at least
size_buf characters. This function transforms the Prolog string pointed by t
into a C string ending in zero, stored according to the address buf. If the
size of the Prolog string exceeds the value size_buf, the string is truncated.
Convert_LongIntC_to_IntP(n)
Transforms the long integer n into a Prolog III number and returns the
address of the term thus constructed, or NULL if the transformation could
not be performed.
Convert_IntP_to_LongIntC(t,i)
© PrologIA 1017
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
Convert_DoubleC_to_NumP(f)
Transforms the double f into a Prolog III number and returns the address of
the term thus constructed, or NULL if the transformation could not be
performed.
Convert_NumP_to_DoubleC(t,f)
Opposite transformation to the above; t must the address of a Prolog III
numeric term. This function puts the value of this number in the double
variable pointed by f. An error occurs if the transformation cannot be
performed. The functions returns 0 (FALSE) for an error, a non zero value
(TRUE) otherwise.
In the second system, each authorized data type (integers, reals, strings) has
an associated function for transfer from Prolog to the external program, and
another for transfer from the external program to Prolog. For each
argument of the external rule (i.e. of the goal to execute), the relevant
function must be called with the rank of this argument as its parameter.
These functions are called by the external program to obtain the actual
values of the arguments of the external rule. A specific function is associated
with each data type.
If the type of the actual argument is not the expected one, the
communication function sends back an error and forces the program to
backtrack. In this case it is absolutely essential to leave the external
function immediately.
1018 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
get_integer(no_arg,value,err)
long int no_arg;
long int *value;
int *err
get_real(no_arg,value,err)
long int no_arg;
float *value;
int *err;
get_string(no_arg,value,err)
long int no_arg;
char *value;
int *err;
no_arg is an integer giving the rank of the argument chosen in the
call to the external rule. The first argument of the external rule
has rank 1, the second rank 2, and so on. If the actual value of
no_arg does not correspond to an actual argument in the
external rule, an error occurs.
value is the address of the variable which is the argument of rank
no_arg in the external rule. If its (Prolog) type does not
correspond to that required by the function, backtracking is
automatically generated. For string type parameters, value
must be the address of an array defined in the external
program, of sufficient size to contain the string.
err is the address of a variable set at 1 if an error has occurred or a
backtracking has been generated. The external program is not
authorized to recover this type of error. To obtain correct
behavior of the error management system, you must leave the
external program immediately if err is not zero.
These functions return a value which is the opposite of the err argument in
boolean terms.
get_integer(no_arg,value,err)
Verifies that the argument of rank no_arg is an integer (can be contained in a
C long int) and transfers it into the variable (or memory zone) whose
address is value.
© PrologIA 1019
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
get_real(no_arg,value,err)
Verifies that the argument of rank no_arg is a floating number, and transfers
it into the variable (or memory zone) whose address is value.
get_string(no_arg,value,err)
Copies the original character string (from Prolog's work memory) into a
variable (or memory zone) defined in the external program. A null
character indicates the end of the string.
The receiving zone must have sufficient capacity to contain the characters
and the null character.
These functions are called by the external program to unify a value with an
argument from the external rule. If unification fails, backtracking is
automatically generated by the communication function. Here are the
available functions:
put_integer(no_arg,value,err)
long int no_arg;
long value;
int *err
put_real(no_arg,value,err)
long int no_arg;
float value;
int *err;
put_string(no_arg,value,err)
long int no_arg;
char *value;
int *err;
1020 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
put_integer(no_arg,value,err)
Unifies the argument of rank no_arg with the integer contained in value.
put_real(no_arg,value,err)
Unifies the argument of rank no_arg with the floating number contained in
value.
put_string(no_arg,value,err)
opies the character string pointed by value into Prolog's work memory and
unifies it with the argument of rank no_arg .
Please note that a null character must indicate the end of the original string.
These three functions return a value which is the opposite of the err
argument in boolean terms. The function can therefore be considered to be
evaluated as TRUE when there is no error, and as FALSE when an error
occurs. This makes the following two forms of call equivalent:
...
put_integer(n,v,err);
if (*err)
return;
...
and
...
if ( ! put_integer(n,v,err))
return;
...
© PrologIA 1021
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
A complete example
Let us suppose that you are programming in C and that you want to add the
predefined rule roots(a, b, c, x, y) which calculates the two real roots x and y
of the equation: ax 2 + bx + c = 0 if they exist and produces backtracking
otherwise.
The following method should be used, step by step (remember that the
rmUser.c file replaces the UserRule.c file when you are working in real
mode):
if (a == 0 || (d = b * b - 4 * a * c) < 0)
return 0;
else
{
*x = (-b + sqrt(d)) / (2 * a);
*y = -b / a - *x;
return 1;
}
}
2. Modify the UserRule function in the UserRule.c file by adding the call to
the new external program. For example, give the new rule the number 504
(use the number 20004 if you are using the rmUser.c file):
1022 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
return ( ! ((t = GetArg(1, Ptr_to_BIP))
&& Convert_NumP_to_DoubleC(t, &a)
&& (t = GetArg(2, Ptr_to_BIP))
&& Convert_NumP_to_DoubleC(t, &b)
&& (t = GetArg(3, Ptr_to_BIP))
&& Convert_NumP_to_DoubleC(t, &c)
&& (t = Convert_DoubleC_to_NumP(x))
&& PutArg(4, Ptr_to_BIP, t)
&& (t = Convert_DoubleC_to_NumP(y))
&& PutArg(5, Ptr_to_BIP, t)))
? FALSE : TRUE;
}
...
}
}
3. Start compiling and editing the link to reconstruct the executable in one of
the following ways according to whether UserRule.c or rmUser.c is being
used:
For real mode (rmUser.c file), the executable to reconstruct is
rmprolog.exe. This is done using one of the rmMAKE•.bat commands,
where • is the string me or lh according to whether the medium or
large/huge memory model is to be used (please consult MicroSoft
documentation concerning this subject). In this example the medium
model is sufficient. The file produced, rmProlog.exe, must if necessary
be copied into the directory containing prolog3.exe .
C> rmMAKEme
4. Start a Prolog III session using the new executable and the previous inital
state, define the name of the new primitive (for example roots) using the
set_ident rule. This rule establishes a link between a Prolog identifier and
the internal number of the C primitive which in this case is 504 (or 20004 if
you are working in real mode). Add this new name to the closed part of the
"sys" family (so that subsequently the user only has to type roots instead of
sys:roots) :
© PrologIA 1023
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
> roots(1,-5,6,x,y);
{x=2, y=3}
> roots(1,4,8,x,y);
>
6. Leave Prolog III using exit to save the current state. This now becomes
the initial state for future Prolog III sessions.
> exit("initial3.psv");
If quit is used instead of exit, point 4 must be carried out for each session.
1024 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
Introduction
It is easy to call Prolog III from C. Two C functions authorize this operation.
Since Prolog III needs to allocate and initialize its own data, and
communicate with the real mode, it can only be called during the call to the
Pro3Session function. This function takes as its argument a C function
described by the user, containing calls to Prolog III. The calls are performed
by means of the generic function Pro3Goal, which sends a command to
Prolog III in the form of a character string. Once the call to the Pro3Session
function has ended it is no longer possible to call Prolog III, except by
restarting the process using Pro3Session once more, etc. etc.
Initialization
© PrologIA 1025
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
Call
int Pro3Goal(g)
char *g;
Pro3Goal(g)
Prolog III is called by means of this single function. Its argument g is a C
character string ( terminated by '\0') containing a Prolog III query. It should
be noted that in this version, data are only passed from C to Prolog III, and
the latter gives its results on the Prolog III current output (which can be
modified).
The Pro3Goal function can only be used successfully if Prolog III has been
correctly initialized, i.e. if Pro3Goal is indeed used within a userprog procedure
passed in Pro3Session.
1026 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
{x = 1}
{x = 2}
{x = 3}
A small example
main1( )
{
Pro3Goal("out(c), {c=1/2};");
...work....
Pro3Goal("out(c) line, {c=1/4};");
return 0;
}
main2( )
{
Pro3Goal("out(c), {c=1};");
© PrologIA 1027
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
...work....
Pro3Goal("outl(c) fail, {c=2};");
return 0;
}
main()
{
...work....
Pro3Session(0, NULL, PROCALL, main1);
...work....
...work....
Pro3Session(0, NULL, PROCALL, main2);
...work....
}
Assuming that the ...work.... lines are empty, we now compile this file by
linking it to Prolog III. We will produce the executable called myprog:
To edit the link we must modify the prolink3.lnk and prolink3.bat files by
replacing promain by myProg, and then prolog3.exe by myProg.exe :
C> prolink3
Let's start myProg and see the results displayed in the console:
1/2{c = 1/2}
1/4
{c = 1/4}
1{c = 1}
2
1028 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
The Pro3Session function is rarely used more than once. The above example
can be programmed more simply as follows, with a main function consisting
of a simple call to Pro3Session :
/* file myprog.c */
#include "macuser.h"
main_bis( )
{
Pro3Goal("out(c), {c=1/2};");
...work....
Pro3Goal("out(c) line, {c=1/4};");
...work....
Pro3Goal("out(c), {c=1};");
...work....
Pro3Goal("outl(c) fail, {c=2};");
return 0;
}
main()
{
Pro3Session(0, NULL, PROCALL, main_bis);
}
Listings
#include "rmacuser.h"
default:
printf("User Rule (%ld) Not Defined.\n",
Ident_num_of_BIP);
return FALSE;
}
}
© PrologIA 1029
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
default:
ProPrintf(sorerr,
"User Rule (%ld) Not Defined.\n",
Ident_num_of_BIP);
return FALSE;
}
}
Appendix D
Information about protected mode
1030 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
Prolog loader
Prolog III
rmUserRule (real mode)
1 Mb
Zone available
for DOS tasks UserRule (protected mode)
© PrologIA 1031
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
Zone executed
in real mode Zone executed in protecte d mode
1 Mb
UserRule(protected mode)
1 Mb
TSR
program
1 E.g. the EMS QEMM simulator, and DESQview 386 from QuarterDeck Office Systems
1032 © PrologIA
Prolog
Aociation
HERITAGE
Using Prolog III on PC (MS-DOS)
Syntax:
-MINREAL n
-MAXREAL n
These parameters define the number of paragraphs (16 byte units) of
DOS memory (i.e. less than 640K) that the protected mode Prolog task
will leave available. MINREAL indicates the minimum size to be left free.
Below this value Prolog will refuse to start (default value 0). MAXREAL
indicates the maximum size to be left free (default value FFFFh, i.e. the
640 K are left free). Prolog guarantees that at least MINREAL
paragraphs of DOS memory are left free, and that as far as possible up to
MAXREAL paragraphs of DOS memory will be left free.
The following parameters are used to restrict the extended memory (i.e.
greater than 1 Mb) used by Prolog. Prolog normally adapts these values at
start-up if this memory is already partly used by disk RAMs or EMS
simulators. However these parameters may be necessary to function with
programs that use the extended memory and do not use the VDISK or
RAMDRIVE allocation standards, or the call INT 15h, a 88h function of the
BIOS.
-EXTLOW n
n specifies the minimum physical address for extended memory
implementation - default value 100000h (one Mega-byte).
© PrologIA 1033
Prolog
Using Prolog III on PC (MS-DOS) Aociation
HERITAGE
-EXTHIGH n
n speficies the maximum physical address for extended memory
implementation - default value FFFFFFFFh (4 Giga-bytes).
-CALLBUFS n
Specifies the size (in Kb) of the inter-task communication buffers
(default value 1).
-NISTACK n
n specifies the depth of the recursion stacks for cross-calls between
protected mode and real mode - default value 10.
1034 © PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Prolog
Aociation
HERITAGE
General Index
General Index
© PrologIA 1037
Prolog
General Index Aociation
HERITAGE
1038 © PrologIA
Prolog
Aociation
HERITAGE
General Index
© PrologIA 1039
Prolog
General Index Aociation
HERITAGE
1040 © PrologIA
Prolog
Aociation
HERITAGE
General Index
© PrologIA 1041
Prolog
General Index Aociation
HERITAGE
1042 © PrologIA
Prolog
Aociation
HERITAGE
General Index
© PrologIA 1043
Prolog
General Index Aociation
HERITAGE
Q restore_menubar 492
restrictions
Q(uit 1009 concatenation 75
qualifier 24 integers 100
queries 59 linearity 100
query (syntax) 438; 454 size 74
quit 8; 11; 196; 318 resume_trace 329
retract 188; 330; 397
retractall 398
R rmprolog.exe 1004
rule 187; 331
rad 170; 368
rule (syntax) 437; 454
radio button 495
rule head 58
rational 104; 320
rule_nb 334
read 396
rules 58
reading-writing context 24; 177
predefined
real 104; 321
boolean 126
real mode 1002; 1003; 1004; 1005; 1012;
numeric 102
1013; 1025
tuples 78
real number(syntax) 426
REALMODE 1005
recap S
boolean operations and relations 121
operations and relations defined on save 190; 335
trees and tuples 77 "SAVE" 466;468
redef_array 322 save_menubar 492
refreshing the graphics window 470 save_window 467
refreshment bitmap 466 saving a module 11
reinsert 185; 186; 323 saving modules (save) 190
relational symbols see 399
boolean 118 seen 400
numeric 98 semantics 60
1044 © PrologIA
Prolog
Aociation
HERITAGE
General Index
© PrologIA 1045
Prolog
General Index Aociation
HERITAGE
V
val 167; 365
abs 368
add 366
atan(t) 368
cos 368
div 366
eql 367
exp 368
if 367
inf 367
infe 367
ln 368
mod 367
mul 366
rad 368
sin 368
sqrt 368
sub 366
sup 367
supe 367
1046 © PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Prolog III
Version 1.3
Debugger Manual
HERITAGE
Copyright
This manual and the software it describes are protected by copyright. According
to the legislation dealing with these rights, this manual and software must not
be copied or adapated either wholly or in part, without the written consent of
PrologIA except within the normal bounds of use or to create a back-up copy.
However these exceptions do not authorise the user to create copies to be used by
a third party, regardless of whether or not they are to be sold.
Prolog III is a registred trademark of PrologIA.
HERITAGE
1. Introduction
2. Sources of errors in a program
3. Overview of the box model
4. The debug mode
5. Basic commands
6. More commands
7. Predefined rules
8. Advanced debugging
9. The trace mode
Even if a program is written in Prolog III, it can still be wrong. There is no such
thing as a programming language which enables you to enter the "algorithm I have
in my head" without letting errors creep in — whether they be design faults or
typing errors. This chapter describes the tools available in the Prolog III
environment for analyzing and debugging your programs.
We will also see that these tools provide more than simple error correction. By
analyzing the execution of a program a user can better understand the algorithm he
has written and thus improve it.
HERITAGE
1 . Introduction
Prolog III's debug mode is designed to fulfill this need for bug detection. But
there is nothing to stop you using it to simply learn about constraint
programming!
In this case, an error has been detected at line 1 of the current input unit.
More precisely, the error has been spotted before the end of the first line 1,
at column 4 in the text of the rule or query read in.
2002 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
The errors in the second category can be dealt with by the debugger.
Breakdowns and termination failures can be caused by many different types
of bugs, which are often trivial but are always difficult to find and get rid of.
The bug may be an incorrect piece of code or a failure to comply with
conditions for use of a primitive; it might be a test that has been omitted or a
failed link between variables. To find out exactly where and when these
bugs occur, it is necessary to observe the operation of the Prolog III
machine.
Debugging modes
The Prolog III debugging environment offers two modes which allow you
to view the film of a program execution; the trace mode is economic but
non-interactive, while the debug mode is enriched so that the re-running of
a program is easier to understand. In particular, the debugger can pause on
each entry or exit of a sub-program. The user is thus able to check that after
a call, the arguments of the executed goal are in the expected logical relation.
From an operational point of view, this additional control facility manifests
itself by parenthesizing (or nesting) the different call levels.
1To prevent this type of error, by default Prolog III is put into "warning" mode (see the
© PrologIA 2003
Prolog
Debugging Prolog III programs Aociation
HERITAGE
The Prolog III debugger is based on the box model which is used in standard
existing Prologs. The key point about this model is that each call can be
considered as a box. The box can be opaque or transparent, depending on
how detailed the user wants the execution trace to be. In general this
model's boxes have 4 openings called ports. In fact, as we will see, Prolog III
provides the user with more than 4 ports.
CALL EXIT
FAIL REDO
The direction of the arrows in the figure indicates the direction of control
flow in the program. Left to right corresponds to normal progression in a
forward direction. The opposite direction indicates that a failure has
occurred and that backtracking is taking place. The input ports (CALL, REDO)
are differentiated from the output ports (EXIT, FAIL). Only one port can be
active at any time.
2004 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
An example
olympic_city(Albertville) -> ;
olympic_city(Barcelona) ->;
and observe the reactions of the box created when the following call is
made:
> olympic_city(X);
In the first step the CALL port is activated (the other ports are locked):
CALL
{} olympic_city(X)
In the second step, the EXIT port is activated and produces the first
solution:
© PrologIA 2005
Prolog
Debugging Prolog III programs Aociation
HERITAGE
EXIT
olympic_city(X) {X = Albertville}
olympic_city(X) {X = Albertville}
REDO
Finally the fourth step; the EXIT port is activated again, producing the
second and final solution:
EXIT
olympic_city(X) {X = Barcelona}
Let's now start again the operation with the following goal:
> olympic_city(New_York) ;
2006 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
{X = New_York} olympic_city(X)
Second step: the FAIL port is activated, thus indicating the failure of the
query.
{X = New_York} olympic_city(X)
FAIL
Internal ports
© PrologIA 2007
Prolog
Debugging Prolog III programs Aociation
HERITAGE
RULE
OK
NO
This figure represents a test to see whether the conditions for application of
a rule exist. The selected rule is identified by its rank in the group (triangular
marker). The box uses this number as a counter, and it is incremented each
time a rule is tried. We consider that for as long as the last rule in the
procedure has not been fired, as far as the box is concerned there are still
choices pending.
Let's take another look at the example above, and now display what
happens internally, i.e. the box's management of the apparent non-
determinism, and the setting and solving of new constraint systems.
For the first query, rule 1 is selected and applied between CALL and EXIT.
This gives the sequence:
olympic_city(X)
a)
RULE
?
{X = Albertville}
b) olympic_city(X)
OK
1
{X = Albertville}
2008 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
The behavior between REDO and EXIT is similar (rule 2 from the procedure
is applied) :
olympic_city(X)
a)
RULE
?
{X = Barcelona}
b) olympic_city(X)
OK
2
{X = Barcelona}
If we now follow what happens for the next query between entry into the
box and exit (via FAIL), we observe that the failure is caused by the union of
contradictory constraint systems, and that in fact none of the base's rules can
be applied:
olympic_city(X) olympic_city(X)
a) c)
RULE RULE
1 2
? ?
{X = New_York} {X = New_York}
{X = Albertville} {X = Barcelona}
b) olympic_city(X) d) olympic_city(X)
NO 1 NO 2
{X = New_York} {X = New_York}
© PrologIA 2009
Prolog
Debugging Prolog III programs Aociation
HERITAGE
Nested boxes
In general, when a rule is applied to the current box new boxes are created.
They are created in the image of the sub-goals of the goal constituting the
rule's body, and are placed in the current box. This box can itself be
contained in other boxes and so on, as if they were Russian dolls.
To nest some boxes, let's complete the program above while representing
each Prolog III procedure as a box:
olympic_city :
11 olympic_city(Albertville) -> ;
21 olympic_city(Barcelona) -> ;
capital :
11 capital(Barcelona) -> ;
olympic_capital :
11 olympic_capital(X) ->
olympic_city(X) capital(X) ;
2010 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
Now let's see what happens when we enter the following query:
> olympic_capital(X) ;
Here's the film of the various events. All the boxes are transparent, and
only the external ports are visible.
CALL
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
olympic_capital(X)
{}
CALL
olympic_city(X) capital(X)
{}
© PrologIA 2011
Prolog
Debugging Prolog III programs Aociation
HERITAGE
EXIT
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
{X = Albertville}
CALL
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
{X = Albertville}
olympic_city(X)
olympic_city(X) FAIL capital(X)
capital(X)
{X = Albertville}
2012 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
REDO
{X = Albertville}
EXIT
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
{X = Barcelona}
CALL
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
{X = Barcelona}
© PrologIA 2013
Prolog
Debugging Prolog III programs Aociation
HERITAGE
EXIT
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
{X = Barcelona}
EXIT
olympic_city(X)
olympic_city(X) capital(X)
capital(X)
olympic_capital(X)
{X = Barcelona}
The state of the constraint system at the EXIT port gives the answer to the
question that was asked.
Start up
> debug;
2014 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
This execution mode functions as described above, and enables you to:
• advance step by step in program code,
• locate your exact current position,
• recap on the current proof,
When a user sets a query, the debug mode may produce a considerable
amount of printing on the screen before any answer is obtained. However,
since the displayed information is just a written translation of the diagrams
above, it's quite easy to find your way around. First of all, we'll explain how
to read and interpret the Prolog III debugger's messages.
By default, the debugger stops at the first detected port and displays
information relating to the state of the program. A message ending in
(DBG) indicates that the debugger is waiting for a command from the user.
To debug step by step, simply answer each prompt by hitting <RETURN>,
which repeats the previous command (in this case step).
Below we show what the example in the previous section would produce
(again, only the external ports are shown):
© PrologIA 2015
Prolog
Debugging Prolog III programs Aociation
HERITAGE
> olympic_capital(X) ;
--------new query--------
1[1]CALL : olympic_capital(X) (DBG)
2[2]CALL : olympic_city(X) (DBG)
2[2]EXIT(r1): olympic_city(Albertville) (DBG)
3[2]CALL : capital(Albertville) (DBG)
3[2]FAIL(r1*): capital(Albertville) (DBG)
2[2]REDO(r1): olympic_city(X) (DBG)
2[2]EXIT(r2*): olympic_city(Barcelona) (DBG)
3[2]CALL : capital(Barcelona) (DBG)
3[2]EXIT(r1*): capital(Barcelona) (DBG)
1[1]EXIT(r1*): olympic_capital(Barcelona) (DBG)
0[0]EXIT(r1): $query$ (DBG)
{X = Barcelona}
>
We can see that most of the lines are constructed with the same structure.
Below we explain the names for the different elements in this structure:
This is the rank of the box (each box corresponds to a call) in the current
branch of the proof. This number increases when a call is executed
successfully, and decreases when the call fails. When built-in predicates are
2016 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
executed, variations greater than 1 may be produced. The depth of the call
to the first goal in the query1 is 1.
This number is used to give each living box a unique identification.
Call level
The level of a call is defined by the nesting level of the box corresponding to
this call. This number therefore fulfills the following two conditions:
• All the query's goals are at level 1.
• All the sub-goals of a goal are at the same level, which is one unit
greater than the previous level.
The indentation of the displayed message shows the call level.
2 3
olympic_city(X) capital(X)
1
olympic_capital(X)
[2]
[1]
[0]
© PrologIA 2017
Prolog
Debugging Prolog III programs Aociation
HERITAGE
Port name
This is one of the strings CALL, RULE, {ok}, {no}, EXIT, REDO, FAIL .
Goal called
For the CALL, {ok}, {no}, EXIT, REDO, and FAIL ports, the current goal is
displayed in its current state of instantiation.
When a rule is selected, the RULE port displays a constraint system to satisfy
(this system starts with an equality whose left-hand side is none other than
the goal called).
The loaded rules are verified, and then we go into debug mode. We then
start the goal: BalancedMeal(h, m, d) , {h radishes}.
2018 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
> list ;
BalancedMeal(h,m,d) ->
HorsDoeuvre(h,i)
MainCourse(m,j)
Dessert(d,k) ,
{ -k - j - i + 10 >= 0 ,
i >= 0 ,
j >= 0 ,
k >= 0 } ;
MainCourse(m,i) ->
Meat(m,i) ;
MainCourse(m,i) ->
Fish(m,i) ;
HorsDoeuvre(radishes,1) -> ;
HorsDoeuvre(pate,6) -> ;
Meat(beef,5) -> ;
Meat(pork,7) -> ;
Fish(sole,2) -> ;
Fish(tuna,4) -> ;
Dessert(fruit,2) -> ;
Dessert(ice_cream,6) -> ;
{}
> debug ;
{}
> BalancedMeal(h, m, d) , {h # radishes} ;
--------new query--------
1[1]CALL : BalancedMeal(h,m,d) (DBG) t3
(DBG) p
The first box created corresponds to the query's first and only term. This
term is displayed without the constraint applying to h (default display
mode). The command t3 is used to move to the display mode with
constraints ("tracemode" 3). By typing p, (equivalent to printbox), we
redisplay the current port.
© PrologIA 2019
Prolog
Debugging Prolog III programs Aociation
HERITAGE
1[1]CALL : BalancedMeal(h,m,d),
{ h # radishes } (DBG) p7
(DBG) s
p7 asks the debugger to stop at all detected ports (there are 3 internal ports
and 4 external ports). From this point, the step command (shorthand s) is
used to advance step by step. The next port is the internal port RULE.
(r1*) indicates that the selected rule is the first and only rule in the
BalancedMeal procedure. There is no constraint to add to the current system
(hence the empty set {}). The linking equations are satisfied easily. The
subsequent transition is a determinist rewrite in HorsDoeuvre, MainCourse,
Dessert. Provided nothing else is typed, each new carriage return will repeat
the step command.
2[2]CALL : HorsDoeuvre(h,i_1),
{ h # radishes, -k_1 - j_1 - i_1 + 10 >= 0 ,
i_1 >= 0 ,
k_1 >= 0 ,
j_1 >= 0 } (DBG) rs
HorsDoeuvre(h,i_1) MainCourse(m,j_1) Dessert(d,k_1) ;
The second numbered box corresponds to the first term of the resolvent, i.e.
HorsDoeuvre. MainCourse and Dessert are at the same level, which is now
level [2]. To verify this, we simply type rs to display the current resolvent.
2020 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
(DBG) s
2[2]RULE(r1): HorsDoeuvre(h,i_1) = HorsDoeuvre(radishes,1),
{ h # radishes, -k_1 - j_1 - i_1 + 10 >= 0 ,
i_1 >= 0 ,
k_1 >= 0 ,
j_1 >= 0 } U
{ } (DBG)
2[2]{no}(r1): HorsDoeuvre(radishes,1) (DBG)
2[2]RULE(r2*): HorsDoeuvre(h,i_1) = HorsDoeuvre(pate,6),
{ h # radishes, -k_1 - j_1 - i_1 + 10 >= 0 ,
i_1 >= 0 ,
k_1 >= 0 ,
j_1 >= 0 } U
{ } (DBG)
2[2]{ok}(r2*): HorsDoeuvre(pate,6) (DBG)
2[2]EXIT(r2*): HorsDoeuvre(pate,6) (DBG)
After the first unsuccessful attempt (because the constraints h radishes and
h = radishes are incompatible), there is no alternative but to choose pâté. We
leave box 2 successfully with the simplified system {h = pate, i1 = 6}. While
staying at the same level, we then go to box 3. We start by checking that we
haven't left any remaining choices behind us (chpt command).
3[2]CALL : MainCourse(m,j_1),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } (DBG) chpt
--\/ CHOICE POINTS (new)\/--
__/\ CHOICE POINTS (old)/\__
(DBG) s
3[2]RULE(r1): MainCourse(m,j_1) = MainCourse(m_3,i_3),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } U
{ } (DBG)
3[2]{ok}(r1): MainCourse(m,j_1),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } (DBG)
© PrologIA 2021
Prolog
Debugging Prolog III programs Aociation
HERITAGE
4[3]CALL : Meat(m,j_1),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } (DBG)
4[3]RULE(r1): Meat(m,j_1) = Meat(beef,5),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } U
{ } (DBG)
4[3]{no}(r1): Meat(beef,5) (DBG)
4[3]RULE(r2*): Meat(m,j_1) = Meat(pork,7),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } U
{ } (DBG)
4[3]{no}(r2*): Meat(pork,7) (DBG)
4[3]FAIL(r2*): Meat(m,j_1),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } (DBG) chpt
If we choose pâté as the starter, we don't have much choice if we want to eat
a balanced meal (we have a margin of 4 points). The meat dishes on the
menu are eliminated (5 and 7 points), and so we must find a less fattening
dish...
When Meat fails, this causes backtracking as far as the last choice point. We
go down one level to level [2], inside box 3 which we hadn't left.
2022 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
(DBG) s
4[3]CALL : Fish(m,j_1),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } (DBG)
4[3]RULE(r1): Fish(m,j_1) = Fish(sole,2),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } U
{ } (DBG)
4[3]{ok}(r1): Fish(sole,2) (DBG)
4[3]EXIT(r1): Fish(sole,2) (DBG)
3[2]EXIT(r2*): MainCourse(sole,2) (DBG)
As we carry on, we leave box 2 for the first time, with {p = sole, j1 = 2}. We
now have to choose a dessert for 2 points. The answer is given by the fifth
and last box.
5[2]CALL : Dessert(d,k_1),
{ -k_1 + 2 >= 0 ,
k_1 >= 0 } (DBG)
5[2]RULE(r1): Dessert(d,k_1) = Dessert(fruit,2),
{ -k_1 + 2 >= 0 ,
k_1 >= 0 } U
{ } (DBG)
5[2]{ok}(r1): Dessert(fruit,2) (DBG)
5[2]EXIT(r1): Dessert(fruit,2) (DBG)
1[1]EXIT(r1*): BalancedMeal(pate,sole,fruit) (DBG)
0[0]EXIT(r1): $query$ (DBG)
{h = pate, p = sole, d = fruit}
© PrologIA 2023
Prolog
Debugging Prolog III programs Aociation
HERITAGE
So we've now obtained our first solution. Are there any others? The chpt
command tells us that two choice points are left, and the most recent one is
on Dessert. The control will therefore go up the boxes it has just left in the
opposite direction, to get information from box 5 which is still living.
2024 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
3[2]REDO(r2*): MainCourse(m,j_1),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } (DBG) n
3[2]EXIT(r2*): MainCourse(tuna,4)
(DBG)
5[2]CALL : Dessert(d,0)
(DBG) p4
(DBG) s
5[2]FAIL(r2*): Dessert(ice_cream,0)
(DBG)
1[1]FAIL(r1*): BalancedMeal(pate,tuna,ice_cream)
(DBG)
0[0]FAIL(r1): $query$
(DBG)
>
The next command n is used to skip directly to the new result for box 3 {p
= tuna, j1 = 4} (nothing is shown from level [3]).
The p4 command is then used to ignore the internal ports so that the trace is
lightened. There is no alternative to tuna and k1 = 0, which means we don't
get any dessert! In the end we leave all the nested boxes without any other
solution.
© PrologIA 2025
Prolog
Debugging Prolog III programs Aociation
HERITAGE
5 . Basic commands
kill
Syntax:
kill
Description:
no_debug
Syntax:
no_debug
Description:
This command turns off the debugger and continues execution of the
current program. Break points or spy points will no longer be able to
make themselves known, (unless the built-in predicates debug or break
are used in the program).
Note:
A Prolog III primitive is also called no_debug .
2026 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
step
Syntax :
step
Description :
step is the basic command for following interpreter execution step by
step. s is an alias and a short-cut for step.
Only ports described by the printport option are printing points as well
as break points for step.
If the print option is set to 0, then step takes one big jump, and can only
be stopped by a break point.
next, n, N
Syntax :
next
n
N
Description :
This command enables the interpreter to progress in larger steps than
using step. In particular, unlike step, next cannot stop at a port if its
level is greater than the level of the current port (see figure 1 below).
The n command behaves like next except that none of the ports of the
inner boxes are shown.
The N command behaves like n except that break points are not active.
© PrologIA 2027
Prolog
Debugging Prolog III programs Aociation
HERITAGE
The value of the print option determines whether the intermediate ports
are displayed or not. The value of the break option determines whether
encountered break points are active or not.
Only ports described by the breakport option are suitable targets for
next. N and n are aliases defined with next.
step
next
nextp
Syntax:
nextp
Description:
This variant of next is used to move to the next port of the current box
that interests us. In particular, it can be used to skip from an EXIT port
to a REDO port, if the same box is revisited. When the box cannot be
reentered — and this is the case when we leave the FAIL port or the last
EXIT port of the box, the behaviour of nextp is stipulated by the
warnnext option.
When this option is set to 1, an error message is displayed and no action
takes place. If warnnext is set to 0, then nextp acts as step.
2028 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
cont, C
Syntax:
cont
C
Description:
These commands are generally used in conjuction with spypoints.
cont causes the interpreter to run in a non-interactive mode until an
active break point is reached. The print and printport options determine
whether or not the ports are displayed.
C is an alias which behaves like cont, except that there is no display and
that it makes the break points active.
In debug mode, you can tell the system to print information about the
program being executed. For instance, you can recall the current port, view
the resolvent or current proof or indicates the retry points for other proofs.
printbox
Syntax:
printbox
Description:
Refreshes the status of the current port.
p is an alias and a short-cut for printbox.
© PrologIA 2029
Prolog
Debugging Prolog III programs Aociation
HERITAGE
chpt
Syntax:
chpt
Description:
Displays the pending choice points , from youngest to oldest (top to
bottom). The information is printed in the following format:
The numbers are used to identify the box that has the choice point. They
correspond respectively to the depth, the level of the box and the
number of the rule to use as an alternative. The printed terms
correspond to the rule heads waiting to be tried. This example shows
that rule #3 (* indicates that it is the last one) from the Dessert procedure
will be tried first when backtracking.
Note:
locus, ls
Syntax:
locus
locus nb_level
ls
Description:
This command gives a snapshot of the state of the current proof in the
form of a sequence of rules whose heads are ancestors of the current
goals.
2030 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
--------new query--------
1[1]CALL : aa(u) (DBG) s
1[1]RULE(r1*): aa(u) = aa(x_1) (DBG)
1[1]{ok}(r1*): aa(u) (DBG)
2[2]CALL : bb(u) (DBG)
2[2]RULE(r1*): bb(u) = bb(x_2) (DBG)
2[2]{ok}(r1*): bb(u) (DBG)
3[3]CALL : eq(u,1) (DBG)
3[3]EXIT(r1*): eq(1,1) (DBG) locus
[3] bb(1) -> eq(1,1) •
(DBG) locus 10
[3] bb(1) -> eq(1,1) •;
[2] aa(1) -> bb(1) •cc(1) ;
[1] aa(1) •;
[0] $query$ •
(DBG)
Notes:
• If you are not in debug mode when the query is started, locus cannot
give complete information about the proof carried out upstream of the
change to debug mode.
© PrologIA 2031
Prolog
Debugging Prolog III programs Aociation
HERITAGE
resol, rs
Syntax:
resol
resol nb_resolvents
rs
Description:
This command is fairly similar to locus, and is used to show the local
resolvents (remains of rule bodies) at each level. These resolvents
correspond to the literals that remain to be executed. The printing
corresponds approximately to the goals located to the right of the @
character that is displayed using the locus command.
When a number is given as an argument, it indicates the number of
levels to print, starting from the bottom of the proof tree (in the order of
decreasing levels).
The rs command is short-hand to indicate that we want to display the
current resolvent in full, i.e. with no restriction on levels.
--------new query--------
1[1]CALL : aa(u) (DBG) s
1[1]RULE(r1*): aa(u) = aa(x_1) (DBG)
1[1]{ok}(r1*): aa(u) (DBG)
2[2]CALL : bb(u) (DBG)
2[2]RULE(r1*): bb(u) = bb(x_2) (DBG)
2[2]{ok}(r1*): bb(u) (DBG)
3[3]CALL : eq(u,1) (DBG) resol
eq(u,1) ;
(DBG) resol 10
eq(u,1) ;
cc(u) ;
(DBG)
2032 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
sol
Syntax:
sol
Description:
sol displays the current state of the system of constraints applying to the
variables in the query. The same format is used when solutions are
printed out by Prolog III.
When the current proof is in a dead end with no alternative left, the
string "none" is displayed instead of the system, meaning that it is
unsatisfiable (this can happen on a FAIL or {no} port).
These commands enable you to quickly switch from one trace mode to
another or to restrict interactions when the external ports are displayed
(equivalent to set_config).
p4, p7
Syntax:
p4
p7
Description:
p4 sets the breakport and printport options so that only the four
“standard” ports CALL, EXIT, REDO, FAIL are taken into account.
p7 sets the same options so that all ports, external and internal, become
visible.
Both commands are defined by aliases.
© PrologIA 2033
Prolog
Debugging Prolog III programs Aociation
HERITAGE
t1, t2, t3
Syntax:
t1
t2
t3
Description:
The effect of t1, t2 or t3 is to set the tracemode option to 1, 2 or 3,
respectively. Please refer to the tracemode option and other trace modes
for more details.
All these commands are defined by aliases.
6 . More commands
2034 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
© PrologIA 2035
Prolog
Debugging Prolog III programs Aociation
HERITAGE
RULE
Syntax:
RULE #rule
Description;
The RULE command (according to the port name) is used to select the
rule to use when we are on the RULE port.
Note:
When the number provided does not correspond to any rule in the
procedure, no action is taken.
changechpt
Syntax:
Changes the number of the next rule contained in the choice point of box
number #box, to rule number #rule .
2036 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
© PrologIA 2037
Prolog
Debugging Prolog III programs Aociation
HERITAGE
Notes:
• Only when we get to the {ok} port can the choice point induced by the
RULE port be installed and exploited using the chpt and changechpt
commands. This can only be done provided that the creation of a
choice point is justified (there is no choice when the last rule of a group
is executed).
• It is not possible to modify a choice point attached to a built-in
predicate written in C (like enum) .
• A choice point is likely to disappear if a call to cut or garbage collector is
made before we return to this alternative.
fail
Syntax:
fail
Description;
The fail command causes the current action (therefore dependent on
the current port) to fail. This command can be considered as immediate
execution of the built-in predicate fail. It acts in the same way as step
when backtracking occurs.
2038 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
FAIL
Syntax:
FAIL
Description;
The FAIL command (according to the port name) takes us immediately
to the FAIL port of the current box. It does step if we were already at
the FAIL port (it continues the backtracking). This FAIL command is
more "energetic" than the fail command, which is more precise.
By default, each time a port is used its status is printed. In step by step mode
(step), this printing point is also a break point, where commands will be
read and executed.
There are two types of break point, depending on whether you want to
debug an individual call or all the calls to a procedure. To debug a given
box, you must use the breakat command, whereas to debug all the calls to
a procedure the spy command is used. The difference between these
commands is that breakat places a break point on a living box in the
current proof, whereas spy places a break point on all the boxes which are
© PrologIA 2039
Prolog
Debugging Prolog III programs Aociation
HERITAGE
instances of the procedure (which perhaps will only exist later on in the
proof).
Spy points are installed using spy and removed with nospy. Break points,
which are installed in the proof, are installed using breakat and removed
with unbreak.
spy
Syntax:
spy
spy identifier arity
Description:
It is also possible to add spy points, using the Prolog III primitive spy .
nospy
Syntax:
nospy
nospy identifier arity
Description:
This command is used to remove all calls to a group of rules. Without
any arguments, the name and arity of the group of rules correspond to
those of the current box. With arguments, it describes the group
described by the identifier arity pair.
2040 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
It is also possible to remove spy points, using the Prolog III primitive
no_spy .
breakat
Syntax:
breakat
breakat # box
breakat level # literal
Description:
This command is used to monitor a call in the current proof and install a
break point on it. Without any arguments, it puts a break point on the
current box. If it has one argument, it puts a break point on box #box.
The two argument form describes the call by giving its localization in the
display produced by the ls or l o c u s command, in “Cartesian
coordinates”. In this display, the described level is the number
indicated at the start of each line, and #literal is the number of terms,
counting from the left and with the rule head if present at position 1. The
value of the breakport 1 option when the break point is installed defines
the set of ports at which the break point will stop.
A break point installed by breakat appears in the form of the *
character in the display produced by the ls or locus command. The
break points are deactivated by putting the break option to 0. If the
break option is at 1, a cont or C command will stop on this break point2
for the ports selected at installation-time.
© PrologIA 2041
Prolog
Debugging Prolog III programs Aociation
HERITAGE
unbreak
Syntax:
unbreakat
unbreakat #box
unbreakat level #literal
Description:
This command has similar syntax to breakat, and is used to remove break
points from the current proof. In contrast to breakat, all the ports are
concerned, regardless of the value of the breakport option.
The set and show commands allow the user to display and modify the
debugger options.
2042 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
set
Syntax:
set name
set name value
Description:
Gives the value value to the option name. The one argument form sets
the option to its default value.
show
Syntax:
show
show name
Description:
The one argument form prints a list of all the options together with their
values in a re-usable format The two argument form is used to obtain
information about the option name only.
These are the options that can be printed with the show command, and
modified using the set command. They are used to parameterize the
debugger and modify its behaviour, e.g. regarding the amount of
information displayed.
© PrologIA 2043
Prolog
Debugging Prolog III programs Aociation
HERITAGE
2044 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
break point for step, if this option is set to 0, step can no longer stop1.
Similarly, during execution of next none of the ports corresponding to the
internal boxes is printed.
This option is used to restrict printing of the ports that takes place
during execution of a program, whether by step, next or cont. This
option takes as its value a set of ports each described by a letter, thus
producing a word like cerfRYN. Ports can be added or removed from this
option using the signs + or - . Here are some examples:
This option has a direct effect on the functioning of step. It is only used
when the print option is set to 1 .
Indicates at which ports the next command can stop its progression.
The syntax is the same as for the printport option. This option can also be
used in relation to break points; the value of breakport when a break point
is installed by breakat indicates at which ports this break point can "wake
up". Remember that the break points can only wake up if the break option
is set to 1 .
© PrologIA 2045
Prolog
Debugging Prolog III programs Aociation
HERITAGE
This option contains the prompt used by the debugger. The string
must be parenthesized by ( and ) if it contains blanks or semi-colons, as
shown in the example below:
1 The commands fail and FAIL are not active at this particular port.
2046 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
Additional commands
alias
Syntax:
alias
alias name
alias new_name (definition)
alias new_name (definition) (help)
Description:
The alias mechanism allows you to rename a sequence of commands.
The one argument form is used to list the currently defined names. The
two argument form displays the definition of the alias called name. The
three argument form is used to define new_name with the definition
definition which is a sequence of one or more commands separated
by a semi-colon. The four argument form is equivalent to the three
argument form, and in addition makes it possible to add a help line that
can be displayed using the help command.
An alias is useful because it enables us to use a shorter (or better) name
instead of a command's official name, and also enables us to define a new
command by combining other more basic commands.
Notes:
© PrologIA 2047
Prolog
Debugging Prolog III programs Aociation
HERITAGE
eof
Syntax:
eof
eof all
Description:
eof terminates the reading and execution of the debugger commands
read in the file containing this command.
eof all closes all the command files.
Note:
help
Syntax:
help
help command_name
Description:
help is simply used to display the list of commands. With an argument,
help prints some information about command_name if it exists. Aliases
can be documented (see alias).
source
Syntax:
source file_name
Description:
This command is used to open and read a file containing Prolog III
debugger commands. The commands are read up to the end of the file,
as the debugger requires them. The file therefore temporarily replaces
2048 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
the console. This command is mainly used to load aliases and position
certain options.
Notes:
7 . Predefined rules
Prolog III's built-in predicates for debugging are described in the chapter
entitled "Predefined rules and external procedures". Definitions and uses are
recalled in this section for convenience.
trace
no_trace
Activate and deactivate trace mode. See the trace mode section in this
chapter (section 9) or the Reference Manual for more details.
debug
no_debug
© PrologIA 2049
Prolog
Debugging Prolog III programs Aociation
HERITAGE
Break points
Spy points can also be set or removed by program. Here are the Prolog III
primitives for doing so.
spy(<I,A>)
spy("module_name")
no_spy(<I,A>)
no_spy("module_name")
For each of these primitives, there are two ways to identify the
procedures you want to spy on, namely:
• a pair <I, A> where I is the name and A the arity of the procedure. (at
least one of the two parameters must be known).
• a string corresponding to the name of a module, in which case all the
procedures defined in the module are spied.
break
break(message)
break(message, command)
The effect of this primitive is twofold since it activates the debugger and
then, if arguments are present, it displays the string message on the trace
output and executes the debugger command command.
By placing calls to break in a Prolog III program, spy points can be
installed in much more precise locations than is possible using the spy
command or the Prolog primitive spy to place them globally on a
procedure. Also, the ability to pass on a command to the debugger via
the command argument allows for some automation.
2050 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
8 . Advanced debugging
Retrying a proof
At present the debugger does not enable you to retry automatically, but
supplies the means required to perform a manual "retry". The commands
you will need for this are described earlier in the chapter; they are
changechpt, fail, FAIL, RULE .
The choice points are natural landmarks in any non-determinist proof, and
are ready-made candidates for retrying an execution 1 . The following
operations are required to retry a branch segment:
• identify the choice point that is closest to the incorrect point, making
sure you are upstream (in the past), using the chpt command,
• carry out a sequence of fail or FAIL commands to return to the
relevant boxes, and go to the RULE port corresponding to the choice
point's box.
• select the rule to use2 with the RULE command, in order to retry the
execution.
The continuation of the execution will regenerate this branch. Below we use
the "menu.p3" program to make this clearer, minus the second rule for
MainCourse:
© PrologIA 2051
Prolog
Debugging Prolog III programs Aociation
HERITAGE
--------new query--------
1[1]CALL : BalancedMeal(h,m,d) (DBG) p4 ; s
2[2]CALL : HorsDoeuvre(h,i_1) (DBG) n
2[2]EXIT(r1): HorsDoeuvre(radishes,1) (DBG)
3[2]CALL : MainCourse(m,j_1) (DBG)
3[2]EXIT(r1*): MainCourse(pork,7) (DBG) chpt
We have just left MainCourse. Let us suppose that we now want to have
details of the execution of the MainCourse rule, starting from the CALL port.
To do this there must be choice points pending. The chpt command
displays them.
Box #3 has no choice points but box #2 does have one, which we can modify
using the changechpt command:
We can now simply force MainCourse to fail and thus return to box #2.
2052 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
It is not always easy to spot the origin of an execution error, even if it has
been caught using a block mechanism. To help you to get to the root of a
user or system-defined error, the catcherror option will cause the debugger
to break precisely where the error takes place.
> minimize(X);
--------new query--------
1[1]CALL : minimize(X) (DBG) c
** 1[1]: error (59) goes up to box 0[0]
1[1]EXIT(r1): minimize(X_1) (DBG) c
Err 59: Unbounded expression for an extremum calculation
>
Please refer to the catcherror option for more details on error recovery.
Also, note that the general block mechanism can be traced using the same
method.
© PrologIA 2053
Prolog
Debugging Prolog III programs Aociation
HERITAGE
Start-up
> trace;
This mode is not interactive and is thus less flexible than the debug mode.
It is deactivated by no_trace.
You can also enter and leave this mode dynamically by calling specific
predicates1. You can modify the tracing options by interrupting the current
execution, changing the options, and then resuming execution. It is thus
possible to select strategically important sections of a program.
Display
2054 © PrologIA
Prolog
Aociation
HERITAGE
Debugging Prolog III programs
ststs
© PrologIA 2055
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Appendix
1. Summary of commands
2. Summary of options.
1. Summary of commands
HERITAGE
2058 © PrologIA
Prolog
Aociation
HERITAGE
Appendices
2. Summary of options
© PrologIA 2059
Prolog
Appendices Aociation
HERITAGE
2060 © PrologIA