Download as pdf or txt
Download as pdf or txt
You are on page 1of 686



    
$%"!$"!%&$'&$" $"" +%$(%$"'%)&$!%$$&"&  
%%"&"!!' $)(&""!%'&&"!"!&!&$!&!%#$!
*   

"!&&%%"&"!#$""$&"$
Aociation Prolog

HERITAGE

Prolog III
Version 1.3

December 1991 © PrologIA


Aociation Prolog

HERITAGE

Guarantee and liabilities


PrologIA offers no guarantee, tacit or explicit concerning either this manual or
the software herein described, its qualitiy, performance or its suitability for any
application whatsoever.
PrologIA cannot be held liable for damage of any sort, whether direct or indirect
resulting from a fault in the manual or program, even if the company has been
advized that such damage might occur. In particular, PrologIA cannot take
responsibility for data stored or used; this includes costs of recovery or
duplication of such data.
Nevertheless the purchaser is entitled to the statutory guarantee in such cases
and to the extent to which the statutory guarantee is applicable not
withstanding any exclusions or limitations.

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.

December 1991 © PrologIA


Aociation Prolog

HERITAGE

Foreword

Congratulations ! You are holding in your hands the leading product in a


new generation of logic programming languages: Prolog III. This language
is based on the new concept of constraint logic programming. While the
general principles which have made Prolog the leading light of Artificial
Intelligence programming still remain, Prolog III represents above all a total
reworking of the very core of the language, unification. This is embodied
not only by more refined manipulation of infinite and finite trees which are
still the main objects manipulated by the language, but also by the
generalization of the fundamental concept of constraint solving, which was
only sketched out in Prolog II. This concept has enabled us to produce an
approach to the processing of numbers, and of Boolean algebra which is
fundamentally different from the attempts which have already been made.
These attemps consisted in the addition of a large number of built-in
predicates, and were far removed from the basic Prolog philosophy. Prolog
III thus makes it possible to write systems of equations and inequations
manipulating reals or perfect precision rational numbers, to process formulæ
in complete propositional logic and to solve certain constraints applying to
trees and lists.

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.

We look forward to hearing your criticisms and remarks and we hope


that Prolog III brings you much satisfaction.

The authors.
Aociation Prolog

HERITAGE

Differences between the 1.2 version


and the 1.3 version

This new version of Prolog III makes a certain number of modifications to


the previous version. Of course, all the known bugs have been corrected,
and we have remedied certain deficiencies in the documentation. We would
like to thank the many people who were kind enough to inform us of these
imperfections. However the main reason we are releasing this new version
is to implement a symbolic debugger.
This version also features some new numeric primitives.
In addition, it is now possible to recover and process all errors that occur
during program execution, by extending the block and block_exit primitives.

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:

'!' lower_bound(R1,R2) no_spy(<I,A>)


block(...) maximize(R) no_spy(S)
block_exit(...) maximum(R1,R2) set_config(S,N)
break(S1) minimize(R) spy(<I,A>)
break(S1,S2) minimum(R1,R2) spy(S)
debug no_debug upper_bound(R1,R2)
Aociation Prolog

HERITAGE

The minimize and maximize primitives have been introduced to allow


more efficient processing of linear optimization problems. The min_value
and max_value primitives are now obsolete1 and are replaced by: minimum,
lower_bound, maximum, upper_bound .

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 programmer should note that by default, attempts to execute an


undefined rule or a non-executable goal cause a warning to be sent on the
console. The "undefined_rule" option of the set_config predicate is now set to
"warning".

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.

We end this foreword by reminding readers that we are always willing to


consider any comments you may wish to make about the software or this
documentation. We will do our utmost to respond to any suggestions or
criticisms.

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

1 They will be removed in version 1.4.


Aociation Prolog

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

December 1990 © PrologIA


Prolog
General Contents Aociation

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

4. Predefined rules on tuples ................................................................. 78


Sizes and concatenations......................................................................78
Miscellaneous......................................................................................79
Example of a program on tuples............................................................79
5. Lists........................................................................................................81
List primitives....................................................................................82
6. Strings ................................................................................................... 83
Primitives on strings............................................................................83
7. Examples...............................................................................................85
Calculation of leaves on a tree .............................................................85
Quick sort............................................................................................86
A periodic sequence..............................................................................87
Eratosthene's sieve..............................................................................88
Numeric constraints............................................................................................ 91
1. Introduction ......................................................................................... 92
2. General definitions.............................................................................. 92
Numbers.............................................................................................. 92
Numeric expressions ............................................................................95
Numeric constants .........................................................................95
Numeric operators.........................................................................96
Priorities of the numeric operators.................................................96
Relations ............................................................................................ 98
Unary relations.............................................................................98
Binary relations............................................................................ 99
Numeric constraints.............................................................................99
Examples of numeric constraints ...........................................................99
Restrictions....................................................................................... 100
Normal form ..................................................................................... 100
The equations.............................................................................. 100
Inequations ................................................................................. 101
3. Predefined rules and specific external procedures....................... 102
Type verification........................................................................ 103
Miscellaneous ............................................................................. 104
4. Delay of non-linear constraints....................................................... 104
5. Input-Output formats....................................................................... 105
6. Example programs............................................................................ 106
Banking calculation........................................................................... 106
Crypto-arithmetic ............................................................................ 107
Filling a rectangle with squares......................................................... 108
Boolean constraints.......................................................................................... 115
1. Introduction ....................................................................................... 116
2. Some definitions and remarks ........................................................ 116
Boolean expressions........................................................................... 117
Boolean operator priorities................................................................ 117
Boolean constraints............................................................................ 118

© 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

Edinburgh Predefined Rules.......................................................................... 373


Identifier - Arity ........................................................................ 374
Rules in the form of terms ............................................................ 374
Index of predefined rules for Edinburgh syntax................................. 419
The Prolog III syntaxes................................................................................... 421
1. Introduction ....................................................................................... 422
Choice of syntax mode ....................................................................... 422
Common points, differences................................................................ 422
Grammatical conventions................................................................... 423
Set of characters................................................................................ 424
Constants .......................................................................................... 425
2. Basic syntax ........................................................................................ 430
Variables.......................................................................................... 430
Identifiers......................................................................................... 431
Terms................................................................................................ 432
Numeric expressions.................................................................... 434
Boolean expressions..................................................................... 435
Trees and Terms........................................................................... 435
Constraints........................................................................................ 436
Rules and queries............................................................................... 437
Some remarks.................................................................................... 439
Space character. ......................................................................... 439
Line continuation......................................................................... 439
The different comments ............................................................... 440
3. Edinburgh syntax.............................................................................. 440
Variables.......................................................................................... 440
Identifiers......................................................................................... 441
Terms................................................................................................ 442
Operators ................................................................................... 442
The terms.................................................................................... 444
Numeric expressions.................................................................... 449
Boolean expressions..................................................................... 449
Trees and Terms........................................................................... 450
Constraints........................................................................................ 451
Rules and queries............................................................................... 454
Some remarks.................................................................................... 456
Space character. ......................................................................... 456
Line continuation......................................................................... 456
The different comments ............................................................... 457
Edinburgh operators.................................................................... 457
Peculiarities............................................................................... 457
4. General remarks................................................................................ 458
Differences between the modes .................................................... 458
Cohabitation of the two syntaxes ................................................ 459
Graphics Primitives .......................................................................................... 461
1. Introduction and conventions......................................................... 462
2. Window management primitives................................................... 464
Refreshing the graphics window........................................................ 470

© PrologIA ix
Prolog
General Contents Aociation

HERITAGE

3. Drawing and coordinate setting......................................................470


4. Using the mouse................................................................................475
Rules for handling of windows using the keyboard and mouse ..............475
Locating the mouse.............................................................................476
5. Drawing and writing modes............................................................477
6. Special primitives for keyboard and mouse input/output.........481
Button simulation ..............................................................................481
Entering text......................................................................................482
Choice boxes......................................................................................485
Printing windows...............................................................................488
7. Menu description primitive..............................................................488
8. Dialog box management..................................................................493
Definition of a standard dialog..........................................................493
User extensions ..................................................................................504
9. Active buttons....................................................................................509
10. File manipulation primitives............................................................509
Index of graphics primitives ...................................................................513
Appendices .........................................................................................................517
A. List of Prolog III error messages..........................................................517
B. List of predefined rules with classification........................................521
Prolog III predefined rules .................................................................521
Trees, lists, strings and tuples.......................................................521
Control........................................................................................521
Numeric constraints.....................................................................522
Conversion ..................................................................................522
Environment................................................................................522
Input/Output...............................................................................523
Rule and identifier management ..................................................524
Type verification ........................................................................524
Edinburgh predefined rules ................................................................525
Trees, lists, strings and tuples.......................................................525
Control........................................................................................525
Evaluation of predefined functions...............................................525
Input / Output .............................................................................526
Rule and identifier management ..................................................526
Type verification ........................................................................526
C. Some Prolog III Programs..........................................................................527
1. A Sample Example: menu.p3e............................................................528
The program:...............................................................................528
Query:.........................................................................................528
2. Big Numbers Calculations: fact.p3e...................................................529
The factorial program: ................................................................529
Queries .......................................................................................529
3. Banking Calculation: bank.p3e...........................................................530
The program:...............................................................................530
Some queries with integer or floating-point numbers .....................530
4. Tree Handling: leaves.p3e...................................................................531

x © PrologIA
Prolog
Aociation

HERITAGE
General Contents

The program: .............................................................................. 531


Queries:...................................................................................... 531
5. Logical Calculus: god.p3e.................................................................... 532
The program: .............................................................................. 532
Query: ........................................................................................ 532
6. A Lewis Caroll Boolean Problem: lewis.p3e .................................... 533
The program: .............................................................................. 533
Some possibles queries:................................................................ 534
7. Fault detection in an adder: circuit.p3e ............................................. 535
The program: .............................................................................. 535
First Set of queries:...................................................................... 535
Second set of queries: ................................................................... 536
8. A Numeric Puzzle: send.p3e...............................................................537
The program: .............................................................................. 537
The query:................................................................................... 537
9. A Tiling Problem: rectangle.p3e......................................................... 538
The program: .............................................................................. 538
A query : ..................................................................................... 538

User's Manual

Using Prolog III.............................................................................................. 1001


1. Installing Prolog III ......................................................................... 1002
Necessary equipment and software................................................... 1002
To start Prolog III...................................................................... 1002
To add external programs .......................................................... 1002
Contents of installation kit.............................................................. 1004
Essential files........................................................................... 1004
Additional files........................................................................ 1005
Installation procedure ..................................................................... 1006
2. Using Prolog III ............................................................................... 1007
Activating Prolog III....................................................................... 1007
Parameterization of the Prolog III interpreter.................................. 1007
Program interruption ....................................................................... 1009
3. Particular characteristics of Prolog III on PC .............................. 1010
Boundary values of arithmetical constants....................................... 1010
Default spaces and sizes .................................................................. 1010
4. The Prolog III environment on PC............................................... 1011
Using a host editor .......................................................................... 1011
Modifying groups of rules........................................................... 1011
5. Adding predefined rules ................................................................ 1012
Method........................................................................................... 1013
Calling an external rule................................................................... 1014
Data transfer procedures.................................................................. 1015
First data transfer protocol........................................................ 1016
Second data transfer protocol..................................................... 1019

© PrologIA xi
Prolog
General Contents Aociation

HERITAGE

Transfer of simple data from Prolog to C..................................... 1019


Transfer of simple data from C to Prolog . ................................... 1021
A complete example......................................................................... 1023
6. Calling Prolog III from the C language .......................................1026
Introduction..................................................................................... 1026
Description of the functions.............................................................. 1026
Initialization............................................................................ 1026
C a l l.......................................................................................... 1027
A small example.............................................................................. 1029
Listings ........................................................................................... 1031
Appendix D ......................................................................................................1032
D1. Operation in protected mode ........................................................1032
D2. Modification of the implementation with CFIG386 ...................1034
General Index..................................................................................................1036

Debugger Manual

Debugging Prolog III programs..................................................................2001


1. Introduction......................................................................................2002
2. Sources of errors in a program .....................................................2003
Debugging modes.............................................................................. 2003
3. Overview of the box model...........................................................2004
The four external ports..................................................................... 2004
An example ..................................................................................... 2005
Internal ports................................................................................... 2007
Nested boxes.................................................................................... 2010
4. The debug mode..............................................................................2014
Start up........................................................................................... 2014
Line describing a port ...................................................................... 2015
Display of terms and literals ........................................................... 2018
5. Basic commands...............................................................................2026
Leaving the debugger....................................................................... 2026
Stepping from port to port ................................................................ 2027
Getting more information ................................................................. 2029
Switching modes and filtering ports ................................................. 2033
6. More commands..............................................................................2034
Classification of the commands........................................................ 2035
The command language .................................................................... 2035
Modifying the execution................................................................... 2035
Installing break points..................................................................... 2039
Management of the debugger options................................................. 2042
Available debugger options.............................................................. 2043
Additional commands...................................................................... 2047
7. Predefined rules...............................................................................2049
Trace, debug and normal modes......................................................... 2049

xii © PrologIA
Prolog
Aociation

HERITAGE
General Contents

Break points................................................................................... 2050


8. Advanced debugging ..................................................................... 2051
Retrying a proof .............................................................................. 2051
Recovering an error at source ............................................................ 2053
9. The trace mode................................................................................ 2054
Start-up.......................................................................................... 2054
Display .......................................................................................... 2054
Appendix E....................................................................................................... 2057
1. Summary of commands................................................................. 2057
2. Summary of options....................................................................... 2059

© PrologIA xiii
Aociation Prolog

HERITAGE
Aociation Prolog

HERITAGE

Prolog III
Version 1.3

Reference Manual

December 1991 © PrologIA


Aociation Prolog

HERITAGE

Guarantee and liabilities


PrologIA offers no guarantee, tacit or explicit concerning either this manual or
the software herein described, its qualitiy, performance or its suitability for any
application whatsoever.
PrologIA cannot be held liable for damage of any sort, whether direct or indirect
resulting from a fault in the manual or program, even if the company has been
advized that such damage might occur. In particular, PrologIA cannot take
responsibility for data stored or used; this includes costs of recovery or
duplication of such data.
Nevertheless the purchaser is entitled to the statutory guarantee in such cases
and to the extent to which the statutory guarantee is applicable not
withstanding any exclusions or limitations.

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.

December 1991 © PrologIA


Aociation Prolog

HERITAGE

Introduction

The purpose of this manual is to give a programmer the information he


or she needs in order to use Prolog III. The amount of information required
is considerable, since some of the commonly-used concepts cannot be found
in any other language. So this manual not only presents the purely syntactic
characteristics that describe the programs, but also explains some
occasionally more complex concepts. These concepts help the user to
comprehend the underlying mechanisms which govern unification, and thus
make it possible to program better, more clearly, more efficiently. You
could say they simply make it possible to program, period. With this aim in
mind, numerous examples are provided and developed as the user
encounters these concepts.

Prolog III - like its predecessor Prolog II - is remarkable in that it has a


complete theoretical model, which justifies the fact that any program
complying with Prolog III syntax is executed in a unique and foreseeable
way. The reader interested in theoretical aspects of this question can refer to
the numerous articles and papers published on this subject. In this manual
for reasons of clarity we prefer to take a relatively informal view of things,
which should also prove to be more accessible. We hope that enthusiasts for
theoretical presentations will not hold this against us.

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.

Here again a certain number of publications - especially "Prolog"


published by Addison-Wesley - will enable you to come to grips with the
basic concepts of logic programming.

December 1991 © PrologIA


Aociation 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.

The Reference Manual.

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 manual then continues with a description of everything that is useful


for the programmer; control, environment, input/output etc.

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

Finally, the "Graphics Primitives" chapter gives a detailed description of


the environment primitives used to manage not only graphics, windows,
and pull-down menus, but also mouse interruptions and structured objects.

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.

The User's Manual

The User's Manual presents the different specific characteristics of Prolog


III on the machine you are using. You will also find instructions on how to
install Prolog III on your machine, an explanation of how to add predefined
rules, and information concerning external calls.

At the end of this booklet is a general index covering the Reference and
User's Manuals.

The debugger manual

This manual describes the command language and primitives of the


Prolog III debugger. Its model is presented at the beginning of the chapter.
Selected examples gradually introduce a more detailed description of its
operation and of increasingly complex commands.

ststs

© PrologIA 3
Aociation Prolog

HERITAGE

4 © PrologIA
Aociation Prolog

HERITAGE

Getting started with Prolog III

1. Starting a Prolog III session


2. Using an example program
- Loading a program
- Deleting, editing, saving
3. Some small examples
- Tuples and character strings
- Arithmetic and numeric constraints
- Booleans and formulæ

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Getting started with Prolog III Aociation

HERITAGE

1 . Starting a Prolog III session

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 :

PROLOG III, Version V1.2 December 1989,1990

>

On Macintosh, you must find the file containing the Prolog


III software and open it. To do this, double-click on the icon
shown opposite. Prolog III takes a moment to activate, after
which a window called console opens containing the
following text:

PROLOG III, Version V1.2 December 1989,1990

>

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:

> lives_in(Jacques,Paris) ->;


> lives_in(Annie,Marseille) ->;
> lives_in(Remi,Paris) ->;
>

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) ->;
{}
>

Let's try this program out: where does Jacques live?

> lives_in(Jacques,x);
{ x=Paris }
>

Who lives in Paris?

> lives_in(x,Paris);
{ x=Jacques }
{ x=Remi }
>

© PrologIA 7
Prolog
Getting started with Prolog III Aociation

HERITAGE

Who lives where?

> 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;
$

and we go back to the command interpreter of the operating system.

2 . Using an example program

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) ->;

MainCourse(m,i) -> Meat(m,i);


MainCourse(m,i) -> Fish(m,i);

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 }
>

Deleting, editing, saving

If we want to change our menu by replacing the rules below:

Meat(beef,5) -> ;
Meat(pork,7) -> ;

with the following rules:

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

>

Now we can execute the program again:

> 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 }
>

If we want to save our modifications in a file, for example menub.p3, we


must type the following commands:

> output("menub.p3") list c l o s e _ o u t p u t ;


{}
>

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.

3 . Some small examples

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("");
{}
>

Tuples and character strings

A tuple is a sequence of Prolog objects. The tuple which is written<a1,a2,a3>


represents a sequence of length 3 formed by the elements a 1 , a 2 , a 3 ,
whatever the nature of these elements. The empty tuple is naturally written
<>. To indicate that a variable x is a tuple we add the constraint x !tuple. We
can also constrain x to be a tuple of length n given by x :: n . The basic
operation on tuples is concatenation, written . (period). Let's look at the
following examples:

> {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

If we wish to obtain the first element x of a tuple l, we simply unify it with a


term having the form <x>.r , signifying the concatenation of a single element
tuple <x> and any tuple r. This enables us to write the two element_of rules
in Prolog III:

> element_of(x,<x>.r) - > ;


> element_of(x,<y>.r) -> element_of(x,r) , { x # y } ;
>

and we can then ask:

> element_of(1, <3,5,1>);


{}
> element_of(x, <3,5,1>);
{ x=3 }
{ x=5 }
{ x=1 }
> element_of(9, <3,5,1>);
>

Character strings are tuples whose elements are characters. The string
written "abc" is the tuple of characters <'a','b','c'> .

Strings and tuples can be mixed, in particular using the concatenation


operator. A string type variable can be constrained to have a known length
n (number of characters) by installing the constraint x :: n .

> {x=y.<`-`>."at-".<`h`,`o`,`m`,`e`>, y="stay"};


{ x="stay-at-home", y="stay" }
>

Arithmetic and numeric constraints

Let's examine the following problem: we have a certain number of cats,


birds, and the numbers of heads and legs, and we are asked to express the
relations linking these numbers. If we call the number of cats c, the number
of birds b, the number of heads h and the number of legs l, the relations are
as follows:

© PrologIA 13
Prolog
Getting started with Prolog III Aociation

HERITAGE

h= c + b and l = 4c + 2b

and can be expressed naturally in Prolog III:

> {h=c+b, l=4c+2b};


{ h=b+c, l=2b+4c }
>

Prolog replies with a system of equations, meaning that the system is


solvable. We can go a little further and give values to certain variables.
Since the system comprises two equations with four unknowns, we set the
values of two of the variables, to obtain the values of the two others. We set
the number of legs at 14 and the number of heads at 5:

> {h=c+b, l=4c+2b, l=14, h=5};


{ h=5,c=2,b=3,l=14 }
>

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:

> CatsBirds(c,b,l,h) -> , {h=c+b, l = 4 c + 2 b } ;


>

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 then we write the new relation:

> CatsBirds(c,b,l,h) ->,


{h=c+b, l=4c+2b, c>=0, b>=0, l>=0, h>=0};
>

and ask:

> CatsBirds(c,b,6,4);
>

Prolog tells us that there is no solution to this query, which is what we


wanted. But what happens if we give a number of legs and heads such that
there is no integer solution?

> 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

Booleans and formulæ

Prolog also manipulates boolean constraint systems and formulæ. At any


moment it verifies their consistency and gives a "simplified" system as a
solution. For the moment we will not expand on the notion of
"simplification"; suffice it to say that the system which is a solution is
equivalent to the one provided as input. For example, take a look at these
three relations on the three variables a, b, c :

> {a=>b, b=>c, c=>a};


{ b=>c, c=>a, a=>b }
>

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".

We now constrain one of the three variables a or b or c to be true. To do


this, we add the equation a|b|c = 1' to the previous system, signifying that
the formula «a or b or c » is true ( 1' is the Prolog constant true, and 0' the
constant false).

16 © PrologIA
Prolog
Aociation

HERITAGE
Getting started with Prolog III

> {a=>b, b=>c, c=>a, a|b|c = 1'};


{ a=1',b=1',c=1' }
>

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 is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Basic concepts Aociation

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:

ALL THE OBJECTS MANIPULATED BY PROLOG III ARE TREES.

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.

This hierarchy is embodied by a set of positions, or nodes, and a set of arrows


which link these positions. Nodes located at the end of an arrow starting at
the node n are referred to as the sons of n. The set of sons of a given node is
always ordered, even if this is only the order in which the nodes are
practically represented. The node at the summit of the hierarchy is called the
root or initial node of the tree.

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 TREE COMPRISES A LABEL AND A FINITE SEQUENCE OF SUB-TREES.

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 <>

Here is a Prolog III tree:

name_married_weight

<> 1' 755/10

`D` `u` `p` `o` `n` `t`

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”

Because of the powerful operator which equips them, expressing


concatenation of finite sequences, tuples represent a flexible and powerful
tool for defining many data structures, combining the generality of lists and
the efficiency of vectors. They can therefore replace to great advantage the
usual concept of a list as it exists in Lisp or other Prologs.

Nevertheless these standard lists, defined by means of the concept of a


pointed pair, can also be used in Prolog III, and can be expressed in their
usual syntax, Edinburgh.

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.

A leaf is not necessarily a constant: a tree reduced to a single fractional


number such as 755/10 is a leaf, but it does not have a specific name and
can only be expressed by means of the division which produced it. Of
course 151/2 is another way of specifying the same rational number

Conversely, not all constants necessarily represent leaves. Thus a sequence


of characters such as:

<>

`D` `u` `p` `o` `n` `t`

is certainly not atomic: however Prolog III considers it to be a constant; since


a special string notation will be used thus "Dupont" . Of course the same
tree can be represented by <`D`,`u`,`p`,`o`,`n`,`t`> .

The known constants are described in the next few sections.

Identifiers

Identifiers are symbolic constants such as:

pierre
light_meal
calcul12

© PrologIA 23
Prolog
Basic concepts Aociation

HERITAGE

An identifier is a sequence containing letters, digits and the two characters


quote ( ' ) and underline ( _ ), and does not have the syntax of a variable
name, i.e. it starts with at least two letters. A more precise description of
identifier syntax is given in the chapter " Prolog III syntaxes".

In fact identifier syntax is much more complex than is shown by the


examples above, since the complete concept of an identifier comprises a
qualifier (or prefix) to indicate the module to which it belongs. The role of
modules in a Prolog III program is to partition name space, thus allowing it
to be gigantic while remaining relatively easy for the programmer to
comprehend. Nevertheless, the existence in addition of a reading-writing
context usually makes it possible to use only simple notation for identifiers.

The concepts of module, qualifier, and reading-writing context are explained in


the chapter "Program control and environment"

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" :

`A` , `a` , `<`

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:

`\`` indicates the character `


`\n` indicates the "new line" character
` \ x 4 1 ` indicates the character A (ASCII code 41 in
hexadecimal)
` \ 1 0 1 ` indicates the character A (ASCII code 101 in octal)
`\\` indicates the character \ itself

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.

Non negative integers

0
1
2
1991
815915283247897734345611269596115894272000000000

Negative integers are not considered to be constants, because they can be


expressed as the result of a sign change operation, applied to a positive or
zero integer. In the same way, fractional numbers are not constants either;
they are represented using division and sign change operations, applied to
integers.

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 internal representation of floating numbers, and thus their precision


and extent, are determined by the characteristics of your machine. Their
syntax coincides with that used in most languages manipulating this type of
numeric data. It is given in detail in "Prolog III syntaxes".

The empty tuple

<>

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

The normal way of writing character strings, in inverted commas:

"Oh boy"

26 © PrologIA
Prolog
Aociation

HERITAGE
Basic concepts

is in fact a second way of writing the tree below:

<>

`O` `h` ` ` `b` `o` `y`

In Prolog III, a character string is always structured, because it is a character


tuple. Strings are only atomic entities when regarded as syntactic objects,
and even then only when constant-string notation is used "Oh boy".

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 :

f : (a1, … an)  f (a1, … an)

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.

We have three types of operation: boolean, arithmetical and tree


construction. An essential point here is that the boolean and arithmetical
operations have their usual mathematical meaning.

1 In mathematical jargon, an operation is thus a mapping


f : D'  D , with D'  Dn

© 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.

In Prolog III however, boolean and arithmetical operations are known as


such by the core of the language, which gives them their usual logical or
arithmetical meaning. It follows from this that a tree represented by the
formula 2 + 3 is simply a leaf reduced to the number 5, the result of the
operation.

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.

(1) The unary operation not

a1  ~ a1

(2) The binary operation and


(a1, a2)  a1 & a2

(3) The binary operation or (non exclusive)


(a1, a2)  a1 | a2

(4) The binary operation implies

28 © PrologIA
Prolog
Aociation

HERITAGE
Basic concepts

(a1, a2)  a1 => a2

(5) The binary operation equivalent


(a1, a2)  a1 <=> a2

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'

In section 5 we give examples of correct terms that express boolean


operations, and errors to be avoided.

Arithmetical operations

Arithmetical operations are only defined if the operands are numeric values,
i.e. leaves labeled by numbers.

If none of the numbers are floating numbers, the operation is considered to


be an exact operation on rational numbers. If at least one of the operands is
floating, then the other is transformed into a floating number also, unless it
already was one, and the operation is considered to be the corresponding
operation on floating numbers.

The arithmetical operations are:

(1) The unary operation “neutral”


a1  + a1

© PrologIA 29
Prolog
Basic concepts Aociation

HERITAGE

(2) The unary operation of sign change


a1  - a1

(3) The binary operation addition


(a1, a2)  a1 + a2

(4) The binary operation subtraction


(a1, a2)  a1 - a2

(5) The binary operation multiplication


(a1, a2)  a1 * a2

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.

(6) The binary operation division


(a1, a2)  a1 / a2

Division is only defined if a2 is not zero.

In section 5, we give correct terms that express arithmetical operations, and


errors to be avoided.

Tree construction operations

These operations are used to construct trees not reduced to leaves. These
are:

(1) The tree construction operation


(a1, a2, … an)  a1(a2, … an)

30 © PrologIA
Prolog
Aociation

HERITAGE
Basic concepts

This operation is only defined if n  2 and a1 is a leaf. It results in the tree


labeled by 1 a1 whose sons are a2, … an.

(2) The tuple construction operation


(a1, … an)  < a1, … an >

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:

<a1, … an> = <>(a1, … an)

(3) The binary operation of general tree construction.


(a1, a2)  a1[a2]

This operation is only defined if a1 is a leaf and a2 is a tuple. It results in the


tree which is labeled by a1 and whose sequence of sons is a2. By definition
we therefore have the following equality:

a1[<b1, … bm>] = a1(b1, … bm)

(4) The binary tuple concatenation operation.


(a1, a2)  a1 . a2

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:

<b1, … bm>.<c1, … ck> = <b1, … bm, c1, … ck>

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 ]

It is important to understand that this not a tree construction operation


specifically taken into account by Prolog III, but simply another syntactic
way of expressing certain trees: the pointed pair and the famous nil. To this
end we give the double sign [] identifier status and we code the basic pair
[e1|e2] by the tree [](e1,e2). Consequently, the expressions above specify
the following trees
[]
[]( e 1 ,[]( e 2 , … []( e n ,[]) … ) )
[]( e 1 ,[]( e 2 , … []( e n , q ) … ) )

Even though Prolog III tuples are an indisputable improvement on standard


lists, all the Prolog III predefined rules inherited from Prolog II only use the
latter, so that their behavior does not change.

1 Here we refer to "standard lists" as opposed to the "new" lists ccorresponding to


tuples, but from now on we will simply call the standard lists "lists", or else "binary lists".
2 These lists cannot be expressed in Prolog III with the syntax they have in Prolog II,
i.e. " a 1 .a 2 . … . a n ", since here the dot has a totally different syntactic role (it expresses
concatenation).

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.

From the syntactic point of view, the main distinguishing feature of a


variable is that its name is a sequence of letters, digits, and two characters -
quote ( ' ) and underline ( _ ) - starting with one letter, and whose second
character if any is not a letter. The following formulæ are variable names1:

X
Y'
Z2
V_ariable

There is a profound difference between the meaning of variables in most


standard languages and what they represent in Prolog III. In standard
languages, a value is attached to each variable. When a program executes, it
produces many types of modification in these values, and obtains the
solution to the problem in the form of final values for these variables. In
these languages, a variable always denotes a completely known object, or
else the use of a variable is illegal.

IN PROLOG III, VARIABLES REPRESENT UNKNOWN TREES.

A Prolog III variable is the opposite: it denotes an unknown tree in exactly


the same way that an unknown in a mathematical equation denotes an
unknown number, for example X in

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

Having introduced the reader to constants, operations and variables, we


now have all that we need to define terms in all their generality. As we
stated before: terms are formulæ that represent trees in a program.

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

One important point immediately becomes clear: the expressions which we


used to define trees and tree operations are terms. In fact, to explain the
constants and operations we had no choice but to define implicitly the syntax
of terms without variables. Let us consider these formulæ to be established;
we now add the possibility of putting variables into them. To be more
precise, from now on it is possible to write a variable anywhere in a term-
without-variable where the expression of a tree could appear.

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.

The first concerns terms headed by an arithmetical operator: the arithmetical


expressions must be linear.

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.

The second restriction concerns the concatenation operation: in a


concatenation, the length of the left-hand operand must be known.

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

Here is a series of correct terms and incorrect expressions which illustrate


term syntax and require a certain amount of additional information and
warnings.

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

Incorrect floating numbers

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

"Pinocchio goes to school" (1)


"Pinocchio goes \
to school" (2)
"This string contains\na carriage return" (3)
"The brackets \"[\" and \"]\" indicate…" (4)
"" (5)
"A\tB" (6)
"A\x09B" (7)
"A\x7B" (8)

© 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{

Incorrect character strings

""" (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:

" 1 1 \ 01112” (or "11\ t 1 2 ” )

Numeric expressions

A numeric expression is any term constituted by applying an arithmetical


operator to one or more operands. Here are some examples:

-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

Expression (1) indicates the sign change operation, applied to an unknown


number X (in example (2) the "neutral" operation). Both of them only have
a meaning for numbers: they constrain X to represent a numeric value.
Moreover their result is a number by definition. Like the other arithmetical
operations, they therefore have many more consequences than the simple
transformation of the value of their operand: they impose type constraints
on their operands and on the expressions in which they appear. The concept
of a constraint is explained in detail in section 7.

Example (4) shows various cases where the Prolog III syntax enables the
operator * to be omitted. An equivalent notation of this expression is :

X + 3*Y + 5*Z/4 + (14+9/17)*T

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.

Incorrect numeric expressions

5(X + Y) (1)
4/5X (2)
X5 (3)
XY (4)
3*-X (5)

5(X + Y) is incorrect as an arithmetical expression. However this term is


the correct notation for a tree having the label 5 and the number resulting
from the addition X + Y as its only son.

The example 4/5X is syntactically incorrect. The correct notation to


indicate four fifths of the value represented by X is (4/5)X.

The expression X5 is not incorrect, but it does not represent a mathematical


expression, only a variable having this name. In the same way, XY is an
identifier, not a product.

Finally, the expression 3*-X must be rewritten as 3*(-X)

© 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)

"MIxed" arithmetico-boolean expressions

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

Expressions like the one below are thus fundamentally incorrect:

(0 < X) & (X < 9)

But if this is the case, what status do equality, inequality, numeric


comparisons etc. have in Prolog III? The following must be borne in mind:
= , # , < , <= , > , >= are not operators.
These symbols are used to express
relations, which are themselves used to write constraints. The distinctive
feature of a constraint is to be or not to be verified, and in practice we will
use the terms true and false. But these are not the boolean values of the
Prolog III domain; 0' and 1' . A constraint is not a term, and cannot be
regarded as expressing an operation.

Other terms

measurement(pierre, <180/100, meters>, 1') (1)


measurement[<pierre, <180/100, meters>, 1'>] (2)

<measurement, pierre, <180/100, meters>, 1'> (3)


<>(measurement, pierre, <180/100, meters>, 1') ( 4 )

4(X + Y) (5)

(4z+y)(character(`c`, "character `c`")) (6)

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

triplet (X,Y,Z) (1)


ff(X,Y)(Z,T) (2)
aLeaf() (3)

Example(1) reminds us of one of the (rare) occasions on which the syntax


does not allow a space to be inserted: between the label of a tree and the
opening parenthesis which precedes the sons.

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.

What do terms represent ?

Terms represent trees in Prolog III programs. This can be understood in


two different ways:

• A term denotes a partially unknown tree. We have already explained that a


variable, as a special type of term, represents an unknown tree which it is
the aim of a Prolog III program to determine. In a similar way, a term
generally represents a tree in which only certain components are known,
and the aim of the program is to reveal the other components. The
unknown parts have to be sub-trees, the known parts may be sub-trees or
elements that define the tree skeleton. For example, the term

< P + L, 2P + 4L >

44 © PrologIA
Prolog
Aociation

HERITAGE
Basic concepts

represents a tuple whose skeleton is known (it is a tuple of length 2) while


the sub-trees that constitute it are unknown numbers resulting from the
operations P + L and 2P + 4L.

• 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

Let t be a term; each assignment A of the set of variables appearing in t


enables t to be transformed into a tree a = t /A . Roughly speaking, it is
sufficient to " replace each variable of t with its value in A". If we wanted to be
more strict, we would need to define t /A for each model of term t, as
follows:
- if t reduces to a constant k, then a is the tree k

- if t reduces to a variable x, then a is the tree given as a value to x in the


assignment A
- if t has the form < t1, t2, … tn > and if a1, a2, … an are the trees t1/A, t2/A,
… tn/A then a is the tree < a1, a2, … an >

- 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…

For example, the assignment { P  2, L  3 } transforms the term


< P + L, 2P + 4L > into the tree < 2 + 3, 2*2 + 4*3 > that is < 5,
16 > .

Particularly subtle terms …

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.

This sub-set can be denoted by the term:

1*X

or in a more "economical" way by the term:

+X

since the arithmetical operation unary + constrains its operand to be a


number and produces this number as its result. We should note here that
although it is described as a neutral operation it would be quite wrong to
perceive the unary + as an operation having no effect.

Of course, all these considerations apply equally to boolean expressions.


Thus, the terms

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

In Prolog III, binary and unary relations express conditions applying to


trees, such as " <aa,bb,cc> is different from aa(bb,cc) " or " 1 is greater than
0". There are completely general relations such as equality between trees,
and also specific relations which only make sense for a special category of
trees, such as relations of order for numbers or of implication between
booleans.

Relations are not operations1. The distinctive feature of an operation applied


to a tuple of trees is to produce a tree as a result; the distinctive feature of a
relation applied to a tuple of trees is to be or not to be verified. Although it
is defined on trees or pairs of trees, a relation does not associate with them
elements from the Prolog III domain, and even if in everyday language we
say that a relation is "true" or "false" this should not be seen as referring to
the boolean values 1' and 0' of the Prolog III domain.

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.

There are seven binary relations:

Equality and Inequality

The condition
a1 = a2

reads as " trees a1 and a2 are equal".

1 Remember that from a mathematical point of view, to define a binary relation on


a set D is to choose a sub-set B of the set D  D of pairs of elements from D; the pairs
belonging to B are said to verify the relation. In the same way, to define a unary relation
on D is to choose the sub-set U of D of elements for which the relation is verified.

48 © PrologIA
Prolog
Aociation

HERITAGE
Basic concepts

The condition

a1 # a2

reads as " trees a1 and a2 are not equal"

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

- a1 and a2 have the same number n of sons


- (if n  0) the first son of a1 is equal to the first son of a2, the second son
of a1 is equal to the second son of a2, etc… up to the n-th son of a1 which
is equal to the n-th son of a2.

Of course, this assumes that we have previously defined label-equality. For


two labels to be equal they must be
- of the same type (two identifiers, two numbers, two characters, etc.),

- equal as concerns the equality criteria corresponding to their type.

Essentially, these criteria are as follows:


- identifiers: two identifiers are equal if their non-abbreviated forms are
spelt in exactly the same way. An important point to be observed is
that lower-case and upper-case letters cannot be equal. The "non-
abbreviated form" of identifiers is explained in the chapter "Program
control and environment".
- characters: two international printable characters are equal if their written
form is the same, i.e. if they have the same internal representation
(ASCII code). For national or non printable characters, please refer to
the documentation about the particular Prolog III system you are using.
- rational numbers. Equality between integers is a primitive notion
inherited from mathematics, which does not pose any problem.
Concerning fractional numbers, we know that Prolog III stores them
with infinite precision in their irreducible form, so again equality poses
no problem.

© PrologIA 49
Prolog
Basic concepts Aociation

HERITAGE

- floating numbers. Equality between two floating numbers x and y , or


between two numbers x and y one of which is floating, is defined by a
relation having the form |x - y|  , where  is a threshold taking
into account the absolute values of x and y , the special features of
floating number representation in the machine used, and if necessary an
estimation of the error occuring in the expression where x and y
appear.
- the other cases, i.e. the two booleans 0' and 1', and the empty tuple <>
are easily dealt with: each of these values is different from the others.

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:

a1 a2 Is the constraint a 1 => a 2 satisfied ?


0' 0' yes
0' 1' yes
1' 0' no
1' 1' yes

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:

a !num is equivalent to a !numt and a ::0


a !char is equivalent to a ! c h a r t and a ::0
a !bool is equivalent to a ! b o o l t and a ::0
a !id is equivalent to a !idt and a ::0

© 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

In Prolog III programs, constraints are always expressed within constraint


systems. A constraint system is a finite sequence of constraints which are
separated by commas and enclosed by braces:

<constraint system>
::= { }
::= { <constraint> {, <constraint> } }

<constraint>
::= <term> = <term>
::= <term> # <term>
::= <term> => <term>
::= <type constraint>
::= <Sup constraint>
::= <Inf constraint>

1 When explaining the conditions on trees we had no choice but to simultaneously


define the symbols which define the relations: we have therefore provided the essential
part of constraint syntax. Of course a constraint on terms without a variable is simply the
written expression of a condition on trees.

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

Here are some syntactically correct constraints:

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

and formulæ which are not correct constraints:

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.

8 . Solving constraint systems

A condition that applies to trees generally expresses a statement which is


implicitly held to be true, such as "a is equal to b". The same can be said of a
constraint that applies to terms without variables, since such terms
unambiguously represent single trees. We must now define what is meant
by "verification" of a constraint that applies to terms with variables.

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.

For example, the constraint system

{ P  0, L  0, P + L = 16 }

is solvable because amongst others, the assignment

54 © PrologIA
Prolog
Aociation

HERITAGE
Basic concepts

{ P  8, L  8 }

transforms it into the following set of conditions:

{ 8  0, 8  0, 8 + 8 = 16 }

In everyday language, we can say that wherever constraints appear in a


Prolog III program they "ask" to be verified. A major part of the Prolog III
machine's work consists in ensuring that the system of all considered
constraints is constantly solvable. But this does not satisfy us: we still want
to obtain the values which must be assigned to the constraint system's
variables, or some of them, so that it is transformed into a set of true
conditions: this is often the main purpose of the program in question.

For example, the constraint system

{ P  0, L  0, P + L = 16, 2P + 4L = 44 }

is also solvable, since the assignment

{ P  10, L  6 }

transforms it into a set of true conditions. But in addition, it is the only


assignment that does so; the values that it contains are thus the system's
unique solution, which would no doubt be of great interest to the program
writer.

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.

For example, 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.

Below we examine some examples of other constraints of the same ilk:

{ 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)

System (1) is equivalent to { X !num , Y !bool }. The operators used


constrain variables X and Y to take these types and the relation # does not
add anything since for any number n and any boolean b we have n # b. For
the same reason, system (2) is insolvable.

Finally, we should point out that the expressions

{ +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.

9 . Rules and queries

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>

Here are some examples of correct rules:

m e a l (X,Y,Z) -> h ors_d_ o e u v r e ( X ) m a i n _ c o u r s e ( Y )


dessert(Z);

sum(<X>.L,S) -> sum(L,S0) , { S = S0 + X } ;

hens_rabbits(P, L, P + L, 2P + 4L) -> ;

To activate a program we must compose a query. A query is the same thing


as a rule body. Here are some examples of correct queries:

h o r s _d_oeuvre(X) m ain _ c o u r s e ( Y ) d e s s e r t ( Z ) ;

meal(H, sole, D) , { H # salad } ;

h e n s _rabbits(P, L, 1 6, 4 4 ) ;

circuit(A,B,C) / , { C|A&~B = 0', D=>C, D#B } ;

58 © PrologIA
Prolog
Aociation

HERITAGE
Basic concepts

Meaning of a Prolog III program

If we examine a Prolog III program, we discover that it has a double


meaning. On the one hand it constitutes the recursive definition of a set of
trees which are considered by the programmer to be true facts; this is called
the declarative semantics of the language. On the other hand, for the
Prolog III interpreter, the program manifests itself as a series of actions to be
executed of which there are two sorts: constraint system solving and
procedure calls. This we will call the operational semantics of Prolog III.

The set of facts defined by a Prolog III program.

A program consists of rules in the following form:

t0  t1 t2 … tn , S ; (1)

where t0 is a term, t1 … tn are terms1 and S is a set of constraints. We know


that each assignment A of the set of variables of this rule transforms the
terms ti into trees ai = ti/A and the set S of constraints into a set C = S /A of
conditions applying to these trees. Therefore, a rule such as (1) generates a
whole set of rules acting upon these trees, one rule for each assignment A that
makes the conditions C = S/A true, in the following form:

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".

When n = 0 the rule has no body:

a0  ; (3)

the corresponding logical property is simply "a0 is a fact".

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.

For example, let us look at the following very simple program:

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. "

This problem will be submitted to the machine in the form of a query

t1 t2 … tn , S

There are two particularly significant possibilities:

- if the sequence t1 t2 … tn is empty, then the query amounts to a request to


solve the the system 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).

Each time it reaches a state having the form


( W, , S )

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

For example, starting from the very simple query

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 ) , { } ;

use of the rule cheap_present(X) -> etc…:

{X}, present(X') price(X',P') ,

{P100,cheap_present(X)=cheap_present(X')};

which simplifies to:

{ X } , present(X') price(X',P') , { P  1 0 0 , X = X ' } ;

use of the rule present(chocolates) ->; :

{X}, price(X',P') ,

{P'100,X=X',present(X')=present(chocolates)};

which simplifies in its turn to:

{X}, price(X',P') ,
{P'100,X=X',X'=chocolates};

use of the rule price(chocolates,90) ->; :

{X}, , {P'100,X=X',X'=chocolates,

price(X',P')=price(chocolates,90)};

© PrologIA 63
Prolog
Basic concepts Aociation

HERITAGE

which simplifies to:

{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 }

is displayed shortly afterwards.

ststs

64 © PrologIA
Aociation Prolog

HERITAGE

Trees, tuples, strings and lists

1. Introduction
2. Trees
3. Tuples
4. Predefined rules on the tuples
5. Lists
6. Strings
7. Examples

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Trees, tuples strings and lists Aociation

HERITAGE

1 . Introduction

Prolog III considerably improves tree processing, by introducing an


operator that allows a tree to be represented in a totally generic way,
independent of its arity. The improvement represented by Prolog III as far
as concerns lists - basic data structures in Prolog programs - is fundamental,
and introduces a new object: the tuple. This evolution has come about
because of two observations. Firstly, the very structure of a list; a tree
constructed by means of a binary functional symbol, makes concatenation
operations extremely costly. Secondly, any access to the n-th element of a
list (this also applies to concatenation programmed in Prolog) can only be
gained via a sequential path. These two disadvantages are now removed
by introducing constraints on tuples, equipped with a concatenation
operation whose properties correspond to what the user has a right to
expect.

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.

These trees consists of nodes labeled by:


• identifiers,
• characters,
• the boolean values 0' and 1',
• numeric values ,
• the special sign <>

Particular care must be taken not to confuse trees and terms.


{ Trees are elements in the Prolog III domain; terms are syntactic
constructions.

68 © PrologIA
Prolog
Aociation

HERITAGE
Trees, tuples, strings and lists

Here is an example of a tree:

maple

<> leaves

`a` `c` `e` `r` lobes deciduous

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.

NOTATION: In Prolog III, strings are represented enclosed by


{ inverted commas as a rule (for example: "A horse, a horse,
my kingdom for a horse" ) and tuples enclosed by corner
brackets (for example <Hastings, 1066, 1'>).

Operations on trees

The operations defined on trees are the construction operations. As in


Prolog II we thus find the tree constructor, but there also two new
constructors, the tuple constructor and the general tree constructor, which is
used to denote any tree in a totally generic way, regardless of the number of
its sons. Below are diagrams to illustrate these operations:

© PrologIA 69
Prolog
Trees, tuples strings and lists Aociation

HERITAGE

x (x … x ) = x
0 1 n 0

x1 … x
n

The tree constructor

<x0 … xn > = <>

x0 … xn

The tuple constructor

x0 ( <> ) = x
0

x1 … x x … x
n 1 n

The general tree constructor

The general tree constructor can be used to represent any tree using just its
initial label and the tuple formed by its immediate sons.

W ARNING. Spaces cannot be inserted between the term


representing the tree label and the opening parenthesis of the
{ constructor. This is one of the rare occasions in Prolog III in which
spaces are prohibited.

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

Finally, below is an example of the same type concerning a character string:

"123" <>
<>(`1`,`2`,`3`)
<>["123"]
<>[<`1`,`2`,`3`>]
`1` `2` `3`

© PrologIA 71
Prolog
Trees, tuples strings and lists Aociation

HERITAGE

Constraints on trees

Constraints are constructed by means of relations. The relations used on


trees are:

• 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

Here are some examples of constraints on trees,

{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 # <>}

This constraint constrains the variable X to represent a tree which is not a


tuple.

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

> {E[U] = example(1,2,3)};


{ E = example, U = <1,2,3> }

> {E[U] = <1,2,3>};


{ E = <>, U = <1,2,3> }

> {E[U] = example(<1,2,3>)};


{ E = example, U = <<1,2,3>> }

> {E[U] = "123"};


{ E = <>, U = "123" }

> {E[U] = 121/3};


{ E = 121/3, U = <> }
>

The following examples clearly show how certain equations on trees are
simplified:

> {X(Y) = Y(X) };


{ Y = X, X::0 }

> {<X> = X[Y]};


{ X = <>, Y = <<>> }

> {Y[X] = X[Y] };


{ Y = <>, X = <> }
>

Finally, these examples show constraints whose solutions are infinite trees:

> {X(Y) = X[Y]};


{ Y = <Y>, X::0 }

> {X(Y) = <<X,Y>>};


{ X = <>, Y = <<>,Y> }
>

© PrologIA 73
Prolog
Trees, tuples strings and lists Aociation

HERITAGE

Restrictions on the size constraint

In Prolog III we can only constrain a tree to have a certain number of


immediate sons if this number is a constant, i.e. a positive integer.
However, to make programming easier, if this number is represented by a
term containing variables, a delay mechanism is installed by Prolog III. We
will return to this mechanism in the chapter "Delay Techniques".

{E[<X, ff(Y)>. Z] :: 13};

In a size constraint, the number of immediate sons must be known explicitly.

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

The only operation defined on tuples is the concatenation operation, denoted


by a dot (“.”). This operation uses two tuples T1 and T2 whose respective
sizes are n and m to construct the tuple T1.T of size m+n, in which the first n
sons are those of T1, and the subsequent m sons those of T2.

74 © PrologIA
Prolog
Aociation

HERITAGE
Trees, tuples, strings and lists

This can be illustrated by the following diagram:

<> • <> = <>

x1 … xn y1 … ym x1 …xn y1 …ym

Concatenation of two tuples

Relations

The relations which enable constraints to be constructed on tuples are the


same as those used for trees, i.e. equaltiy, inequality, and the unary relation
which enables a tuple to be associated with the number of its elements. In
this last case, we have not only the size relation on trees, but also a unary
relation which constrains a term T to represent a tuple (T !tuple).

Restrictions concerning tuples

To achieve a good compromise between the complexity of the processed


constraints and considerations of efficiency associated with the creation of a
programming language, Prolog III imposes a certain number of restrictions
on these constraints. As far as concerns tuples, the main restriction is that the
size of any tuple appearing in the left-hand member of a concatenation operation
must be explicitly known. The second restriction follows on logically from that
imposed on trees, i.e. that for any size constraint applying to a tuple the
number that represents it must be known. If these restrictions are not
obeyed a delay mechanism is installed, which we will describe in detail later
(please refer to the chapter dealing solely with delay).

{ 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

Examples of constraints on tuples

Here are some constraint systems applying to tuples:

{<1,2,3>.V = Z}

{<E>.U = V}

{U.V = W,U :: 100}

{U.<E,F>.V = W, U :: 4}

{(U.V).W = T,U :: 2,V :: 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:

> {<0>.U = U.<0>, U :: 10};


{ U = <0,0,0,0,0,0,0,0,0,0> }

> {Z :: 10, <1,2,3>.Z = Z.<2,3,1>};


{ Z = <1,2,3,1,2,3,1,2,3,1> }
>

A recap on operations and relations

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 and relations defined on trees

operations

tree constructor x 0 (x 1 , ..., xn )

general tree constructor x 0 [<x 1 , ..., xn > ]

relations

equality x = y

inequality x # y

size x :: n

Operations and relations defined on tuples

operations

tuple constructor <x 0 , x1 , ..., xn>

concatenation u.v

relations

equality u = v

inequality u # v

size u :: n

type u !tuple

4 . Predefined rules on tuples

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".

Sizes and concatenations

bound_size(T,N). Sets the constraint {T :: N} when N is a known


positive integer, or {N = k} if k is the size of T. Fails if the size of T is not
known, or if N is unknown or does not represent a positive integer value.

size(U,N). Sets the constraint {U :: N},with possible delay if N and the


size of U are not known. Fails if N is known but does not represent a positive
integer value.

bound_conc(U1,U2,U3). Sets the constraint {U3 = U1.U2}. Fails if the


size of the tuple U1 is not known.

c o n c 3 ( U 1 , U 2 , U 3 ) . Sets the following set of constraints:


{U3 = U1.U2,U1 :: N1,U2 :: N2,U3 :: N3,N3 = N1+N2,
N1 >= 0, N2 >= 0}, with possible delay if N1, N2 or N3 are not known.

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.

known_part(U1,U2,U3). Sets the constraint {U1 = U2.U3}, where U2 is


a tuple formed from the biggest known sequence of the first elements of U1.

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.

tuple(U). Executes successfully if U represents an entirely known tuple


(see bound predicate). Fails in all other cases.

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.

Example of a program on tuples

In this first example program, we intend to consider the reversal (or


inversion) of a tuple. We will first examine the method usually followed in
Prolog, then show how to program the problem in Prolog III, and end by
examining a program which uses delayed constraints.

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

respective semantics of the . (dot) remain fundamentally different. Also in


this program, we find our old friend the ever famous conc predicate.

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') ->
naive_reverse(X,X'')
bound_conc(X'',<E>,X') ;

Finally here is a third program, which installs the concatenations before


execution of naive_reverse. Delayed constraints are then installed (see
chapter on delay). If the program provides the expected results, execution
times will be greater than in the above program, because of the delay
management.

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 [].

Syntactically, the following forms are permitted:

[U|L] representing a list with head U and tail L

[U1,U2,...,Un] representing a list formed by the elements


U1,U2,...,Un

[U1,U2,...,Un|L] representing a list whose first elements are


U1,U2,...,Un and whose tail is L

Although the syntax is unambiguous, you must be careful not to


confuse the binary operator used for lists and represented by
{ square brackets (for example [U] for a list reduced to one element),
with the n-ary general tree construction operator, represented by
the same symbol (for example E[U]).

W ARNING . There is real ambiguity in the following: how do we


distinguish between a list having the head A and the tail B which
must be written [A|B] , and a list reduced to a single boolean
{ resulting from the disjunction of the booleans A and B which should
also be written [A|B]? This ambiguity is removed by creating the
convention that in the second case the boolean expression is
parenthesized: [(A|B)]

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.

Here are some executions involving lists:

> {E[U] = [A,B,C|L]};


{E = '[]', U = <A,[B,C | L]>}

> {E(X,Y) = [A,B,C|L]};


{E = '[]', Y = [B,C | L], A = X}

> {[A,B,C|L] = [A'|L']};


{A' = A, L' = [B,C | L]}

> is_ident([]);
{}

List primitives

arg2(N,L,T). If N is null, sets the constraint {T = N'}, where N '


represents the number of elements in list L . If N is not null, sets the
constraint {T = N'}, where N' is the Nth argument in list L. Fails if N is not
a known positive integer, or if list L is not sufficiently known.

list_tuple(L,U) : Sets the constraint {U = U'}, where U' is the tuple


consisting of the elements forming list L (please refer to a later section in this
chapter concering lists). Fails when list L is not entirely known.

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.

Here are some examples of constraints on strings:

> {X."a" = "a".X, X :: 10};


{X = "aaaaaaaaaa"}

> {X = Y." une concatenation ".<`d`,`e`,` `>.Z,


Y = <>(`V`,`o`,`i`,`c`,`i`), Z = U["chaine"]};
{X = "Voici une concatenation de chaine",
Y = "Voici",
Z = "chaine", U = <>}

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

conc_string(S1,S2,S3). This predefined rule has the same effect as its


Prolog II counterpart. It enumerates all the triples S1,S2,S3 of strings such
that S3 is the concatenation of S1 and S2. This predicate only succeeds if
either strings S1 and S2, or string S3, are completely known.

find_pattern(S1,S2,N). Sets the constraint {N = D} where D is the


position of the start of string S2 in string S1. If string S2 is not found, or if
S1 and S2 are not completely known, then find_pattern fails.

© PrologIA 83
Prolog
Trees, tuples strings and lists Aociation

HERITAGE

substring(S1,N1,N2,S2). Sets the constraint {S2 = S1'}, where S1'


is the sub-string of S1 starting at position N1, of length N2. It fails if such a
sub-string does not exist, or if S1 is not known.

String conversions

list_string(L,S). Sets the constraint {S = L'}, where L' is a string


consisting of characters that form the list L. Fails if the list is not completely
known.

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

string(S). Executes successfully if S represents an entirely known string.


Fails in all other cases.

7 . Examples

Here we give some example programs concerning tuples in particular,


which show the possible ways in which they can be used. Since some of
these examples use delayed constraints, it is recommended to refer to the
corresponding chapter if you want to examine them in detail.

Calculation of leaves on a tree

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);

Here is an execution of this program:

> 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};

There exist several possible executions of this program. In the first an


entirely known tuple is sorted:

> 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> }
>

Of course this execution provides all the permutations of n elements.

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 }
>

The step variables introduced have been renamed X1 and X2.

A periodic sequence

The aim of this program is show that the sequence defined by:

X i+2 = |Xi+1| - Xi

is periodic with a step of 9


Here is the program:

© 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 };

This program limits itself to describing the construction of a tuple whose


elements constitute a sequence of elements from the previously defined
sequence.

To prove that this periodic sequence has a step of 9, subtle programming is


required in order to set a query that corresponds to the following question:

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};

sieves(N, <>, <>) ->;


sieves(N, <0'>.X, <0'>.Z) ->
sieves(N+1, X, Z);
sieves(N, <1'>.X, <1'>.Z) ->
sieves(N, X, Y)
sieves(N+1, Y, Z);

sieve(N, X, X) -> {X :: M, N > M};


sieve(N, X, Y) ->
Sieve(N, X', Y')
{ X :: M, N <= M,
X = U.<E>.X',
Y = U.<0'>.Y',
U :: N-1 };

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:

> prime_numbers(Y), {Y :: 12};


{ Y = <1',1',1',0',1',0',1',0',0',0',1',0'> }
>

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

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Numeric constraints Aociation

HERITAGE

1 . Introduction

Prolog has always been considered, quite rightly, to be a powerful symbolic


language, unsuitable for number processing. To a large extent, this image is
linked to historical considerations, and many of the language's interpreters
and compilers have until now limited themselves to adding layers to cover
unification, and to enable certain numeric expressions to be manipulated.
These processes in fact evaluate numeric expressions by performing
calculations on variables whose values are known at unification. Prolog III
offers an approach which goes way beyound this simple "syntactic icing",
since variables representing numbers are processed in the same way as all
other Prolog III variables, i.e. they are objects whose value can be
completely unknown. Numeric expressions are therefore not evaluated in
general (since not enough variable values are known), but instead form the
main components of the numeric constraints which are processed by the
language at the unification level. This processing consists basically in
verifying whether or not the addition of these constraints makes the system
unsolvable, and in performing certain other processes which will be
explained in detail later on.

2 . General definitions

Numbers

Prolog III numeric constraints apply to two types of object: rational numbers
and floating numbers.

Rational numbers are represented in the machine in perfect precision, i.e.


with as many digits as is required to express them exactly. All rational
numbers are encoded in the form of an irreducible fractional number: a pair
of perfect precision integers representing its numerator and denominator.
Prolog III thus ensures that any representation of a rational number is
unique (the numbers 3/9, 2/6 and 1/3 represent the same rational
number and are encoded in the form (1,3) ). To conserve this unicity of

92 © PrologIA
Prolog
Aociation

HERITAGE
Numeric constraints

representation, a perfect precision arithmetic module has been included in


Prolog III.

As far as concerns floating numbers, their internal representation, and thus


their precision and extent, are determined by the characteristics of your
computer. Their syntax is the same as that used in most languages that
include this type of numeric data. It is given in detail in the chapter devoted
to syntax.

Although floating numbers can be very useful, even indispensable, when


solving many problems, they can also be considered to have harmful effects,
especially on the exactness of the calculations they are involved in. In
addition, their status among the other objects that constitute the Prolog III
domain may at first seem rather unclear. It will therefore be useful to give
some explanations straight away, beginning with a definition of what
floating numbers are not:

• Floating numbers are not an alternative notation for rational numbers.


75.5 should not be taken as another way of writing 755/10. Even though
such an operation may be correct under certain circumstances, the nature of
the calculations that are implemented to convert a floating number into a
rational mean that a generally satisfactory result cannot be guaranteed. In
addition, the systematic use of such conversions goes against the very spirit
of floating numbers, since it gives them a precision which they never had,
and never even demanded.

• Floating numbers do not constitute a separate numeric domain, disjoined


from rational numbers. In other words, it is perfectly reasonable to wonder
whether the constraint 75.5 = 755/10 is satisfied or not. Further, not
only does such a constraint have a meaning, but also it is important to
realize that Prolog III endeavours to process it as precisely as possible.
Therefore two numbers - one of which at least is floating - are found to be
equal if the difference between them is less than a certain threshold. This
threshold takes into account the relevant numbers, the coding characteristics
of floating numbers on the host system, and a sophisticated error
calculation. Moreover, the inequality constraint ( ) is processed in a way
which is totally consistent with the constraint described above.

© PrologIA 93
Prolog
Numeric constraints Aociation

HERITAGE

The following points indicate the correct way to view the sets of numbers
processed by Prolog III:

1. The numeric domain consists of the set of real numbers in the


mathematical sense, including rational numbers, algebraic numbers and
transcendental numbers, even though some of these number families are
not in fact accessible.

2. Numbers which have been expressed in the rational number syntax


represent precise data for the user. The four arithmetical operations (+, -
, *, /) are also considered to be precise. The results of precise operations on
precise numbers are precise. Finally, the syntax which expresses precisely the
value of precise numbers is the rational number syntax.

3. For the sake of efficiency and in order to be open to other application


domains, a syntax exists which enables imprecise numbers to be expressed:
the floating number syntax. Since imprecision is thus permitted, we also
have a number of imprecise operations such as the square root and the
trigonometric and logarithmic operations, whose usefulness is self evident.

4. Imprecision is contagious: the result of an imprecise operation or of a


precise operation on imprecise numbers is imprecise.

5. It is not a crime to be imprecise. Prolog III endeavours to work with


imprecise numbers as precisely as possible, as we have already shown when
dealing with x = y and x  y when x or y are floating numbers.

Numeric expressions

Numeric expressions are terms constructed from Prolog III variables,


numeric constants and numeric operators.

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

Positive or zero integers.


Here are some examples:

0
1
2
1789
815915283247897734345611269596115894272000000000 1

Neither negative integers nor fractional numbers are considered


{ to be constant. However they can be expressed as the results of
operations on non negative integers.

Positive or zero floating numbers.

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

These are as follows:

+ : 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

Syntactically, Prolog III conserves a certain philosophy of


mathematical notation since it allows the multiplication sign
to be omitted when this does not cause ambiguity. For
example the constraint system {X+2Y = 1,3Z-2T < 5} is
{ perfectly correct. On the other hand, the constraint
{(X+Y)(X-Y) # 0 } is also correct, but means that the
tree labeled by the value X+Y whose only son is the
numeric value X-Y is different from the tree reduced to the
leaf 0, something which moreover is always verified.

Priorities of the numeric operators

In order to enable parentheses to be omitted in certain cases, an order of


priority is introduced on the numeric operators:

• The operators * and / have priority over the operators + and -

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:

((x*y)/z)+(x*(y/z)) written more simply is: x*y/z+x*(y/z)

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

and here are some incorrect ones:

(7) 2(X)

96 © PrologIA
Prolog
Aociation

HERITAGE
Numeric constraints

(8) X2

(9) 3+-X

(10) 3 / 2 X

(11) X = 2Y+1

The following remarks can be made:

(2) is a numeric expression which simply constrains X to represent a numeric


value. The term X is not a numeric expression, since the variable X
represents any tree.

(3) The expression is parenthesized and does not allow parentheses to be


omitted (see example (10) and the chapter concerning numeric expression
syntax, especially on the possible omission of the multiplication operator.
We remind the reader that this operator can only be omitted in expressions
of the type Constant*Variable and (Numeric Expression)*Variable.

(6) is a correct numeric expression, but it is non-linear. There is a special type


of processing for such expressions, and in particular for constraints involving
such expressions, which is given in detail in the subsequent chapters.

(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.

(9) and (10) require parentheses (see Syntax chapter)

(11) is not a numeric expression, or even a Prolog III term. It is however a


syntactic object in the language, since it is a numeric constraint. We must be
careful not to confuse these two types of object.

© 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.

X !numt constrains the variable X to represent a tree labeled by a real or


rational number. (Syntactically, we should note that as in all unary typing
relations, it is not permitted to insert a space between the ! and numt).

X !num which is equivalent to the association of the two constraints X


!numt and X :: 0.

Binary relations.

= : equality
# : inequality
< : strictly less than
> : strictly greater than
<= : less than or equal to
>= : greater than or equal to

Numeric constraints

Numeric constraints are syntactic objects which, in the case of binary


relations, express the relationship between two numeric expressions. Unary
constraints lead to the typing of the variables considered.

Concerning types, the following property must be noted:

98 © PrologIA
Prolog
Aociation

HERITAGE
Numeric constraints

{ The mere presence of a variable in a numeric expression constrains


the variable to represent a numeric value.

For example the constraint {X = Y+2Z} is in fact encoded as follows: { Y


!num, Z !num, X = Y+2Z}. Since the term appearing to the left of the
equality, X, is not a numeric expression, typing is performed, and therefore
from the typing point of view the variable X represents any tree, even if X is
constrained to represent a number in order to verify this equality.

Examples of numeric constraints

Here are some examples of correct numeric constraints:

• 2X-3 = 0

• X+5 = 3*(2X-1)+2

• X # 1+Y

• X > Y

• 1 <= 4X-1 <= 9

Restrictions

The main restriction applying to numeric constraints is that, for obvious


reasons of efficiency, only linear equations and inequations are taken into
account by Prolog III's solving algorithms. It follows from this that the
processing of any constraint containing the multiplication of two variables or
division by a variable is delayed until the number of known variables
becomes sufficient to make the constraint linear. In most cases this linearity
is obtained immediately upon unification. The process installed in other
cases is examined in detail in a chapter specially devoted to this topic.

© PrologIA 99
Prolog
Numeric constraints Aociation

HERITAGE

Another important restriction is that in Prolog III it is not possible to


constrain a term to represent an integer value. One way of processing
integers is to define the sets of constraints applying to rational numbers, and
at the end of the process to perform a complete enumeration of the possible
values of these variables by means of the predefined rule enum (see the
chapter "Predefined rules and external procedures")

Normal form

Here we describe the normal form used to encode numeric constraints, in


order to clarify somewhat the expressions encountered as output (when the
built-in predicate list is used for example).

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).

To visualize this normal form, we can question the interpreter:

> { 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 }

> { 1X = (1/2)Y+2Z-4,Z >= 0 };


{ Y = 2X-4Z+8, Z >=0 }
>

100 © PrologIA
Prolog
Aociation

HERITAGE
Numeric constraints

In the first example, the three variables X, Y and Z are non-constrained


numeric variables.

In the second example, X is any tree type variable, and the two variables Y
and Z are non-constrained numeric variables.

In the third example, Z is a numeric variable constrained to represent a


positive or zero value, and the two variables X and Y are non-constrained
numeric variables.

Inequations

The inequations are transformed as follows, by introducing an additional


variable , called a step variable .

X>Y is transformed into X-Y = ,  > 0


XY " " " X-Y = ,  >= 0
X<Y " " " Y-X=  ,  > 0
XY " " " Y-X =  ,  >=
0

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:

> { X+3Y >= Z+2T };


{ T = -(1/2)Z+(3/2)Y+(1/2)X-(1/2)X', X' >= 0 }

> {0 <= (7/11)X+(4/6)Y};


{ Y = -(21/22)X+(3/2)X', X' >=0 }
>

The step variables created by Prolog III have been renamed, for increased
clarity.

© PrologIA 101
Prolog
Numeric constraints Aociation

HERITAGE

3 . Predefined rules and specific external


procedures

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.

Warning. The order of variable enumeration is very important,


since it can cause huge differences in performance. In general, the
{ most constrained variables should be enumerated first. If the
constraints are identical, the variables with the highest coefficients,
or those which are used most frequently in the constraint system
should be chosen first.

As an example, we can examine the cryptarithm SEND+MORE = MONEY,


further on in this chapter.

max_value(R1,R2)
min_value(R1,R2)

These double-argument external procedures calculate the maximum and


minimum values of a numeric expression R1 . To be more precise, for
max_value the value calculated is the smallest majorant, and for min_value it
is the biggest minorant. This implies that the maximum (for max_value) or
minimum (for min_value) calculated is not necessarily attained, since this
calculation does not take account of  type inequality constraints, and strict
inequality constraints (<, >).

particular_value(R1, R2). Sets the constraint {R2 = R1'}, where


R1' is any value of the term R1 that satisfies the current set of constraints.
For further details concerning this primitive, please refer to the chapter
devoted to predefined rules and external procedures.

102 © PrologIA
Prolog
Aociation

HERITAGE
Numeric constraints

mult(R1,R2,R3) sets the constraint {R3 = R1*R2} with the necessary


delays if required.

bound_mult(R1, R2, R3) sets the constraint {R3 = R1*R2}, provided


that the value of R1 or R2 is known. Fails otherwise.

Type verification

integer(I) verifies that the term I represents a known integer value

num(R) verifies that the term R represents a known numeric value

rational(R) verifies that the term R represents a known rational numeric


value

real(R) verifies that the term R represents a known numeric value


encoded as a floating number

is_num(T) verifies that the term T is constrained to represent a numeric


value, or that the constraint {T !num} belongs to the current constraint
system

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.

div(N1,N2,N3) sets the constraint {N3 = E} where E is the result of the


integer division of N1 by N2 . Only the absolute values of N1 and N2 are
considered for the calculation of E. Fails if N1 or N2 is not a known integer
value.

mod(N1,N2,N3) sets the constraint {N3 = R} where R is the remainder of


the integer division of N1 by N2. Only the absolute values of N1 and N2 are
considered for the calculation of R. Fails if N1 or N2 is not a known integer
value.

© PrologIA 103
Prolog
Numeric constraints Aociation

HERITAGE

4 . Delay of non-linear constraints

The delay of non-linear numeric constraints will be examined in detail in the


chapter completely devoted to delay. For the moment, we can nonetheless
make one observation: Prolog III allows non-linear constraints to be written.
As a first step, let's just note that Prolog III adds to the system of numeric
constraints any constraint which is linear when it is processed. In other
words, any syntactically non-linear constraint is processed perfectly
normally if the values of a sufficient number of variables are known at
execution time.

Here is an example:

> calculate(X,Y,Z) ->


{Z = (3X-Y)/Z, X+Y-2Z =0};
{}
> calculate(X,Y,2);
{ X = 2, Y = 2 }
> calculate(1,Y,Z);
{ Y = Y1, Z = (1/2)Y1+1/2,
((1/2)Y1+1/2)*((1/2)Y1+1/2) = -Y1+3,
(1/2)Y1+1/2 # 0 }
>

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).

The first parameter must be a string. As far as concerns numeric output


formats, S must be equal to "format_out_num". The possible values for the
second parameter T are then:

• "Fnormal" : displays rationals with infinite precision, floating numbers


in scientific notation
• "Fexact" : displays rationals with infinite precision, floating numbers
are converted
• "Fdecimal" : display in decimal form
• "Ffloat" : display in scientific notation
• "Fint+fract": display in the form: integer part + fractional part

Examples of how to use set_config can be found in its description in the


chapter "Predefined rules and built-in predicates".

6 . Example programs

Banking calculation

In this example, the task set is the calculation of a series of successive


instalments which have to be made to repay capital borrowed from a bank.
We will assume that the same time period elapses between two instalments,
and that during this period the interest imposed by the bank is 10%. The set
of facts defined by the program will be the set of trees:
instalment_capital(X,C)

where x represents the list of instalments necessary to repay the capital c


with an interest rate of 10% between two instalments. The program itself
can be summarized by two rules:

© 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

The problem posed is how to assign different digits to the 8 letters


s,e,n,d,m,o,r,y so that the sum send+more=money is correct. The first way of
attacking the problem is to make use of the fact that addition, subtraction,
multiplication by a constant and the relations =,,<,,,> are completely
known at the level of rational numbers.

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

Here is the program:

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};

If we write the query

> solution(I,J,K);
{ I=9567, J=1085, K=10652 }
>

Filling a rectangle with squares

The following is a problem taken from an article by Alain Colmerauer


"Introduction to Prolog III" which underlines the value of the numeric part of
Prolog III. Given an integer N , we want to know whether it is possible to

© PrologIA 107
Prolog
Numeric constraints Aociation

HERITAGE

have N squares of different sizes which can be assembled to form a


rectangle. If this is possible, we would naturally like to find out the sizes of
these squares, their positions, and the size of the rectangle formed. For
example, here are two solutions to this problem, where N=9.

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

(1) place a square in the lower left-hand corner of the rectangle,


(2) fill zone A with squares if it is not empty,
(3) fill zone B with squares if it is not empty.

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'

A zone's boundaries are marked by a lower jagged line L joining P to Q and


by an upper jagged line L' joining the same point P to the same point Q .
Point P is placed anywhere in the rectangle to be filled whereas point Q
denotes the upper right-hand corner of the rectangle. These jagged lines are
represented by alternating sequences of vertical and horizontal segments

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.

If these conventions are applied to the whole of the rectangle (diagram on


the right above) the lower line L can be represented by the sequence 1,a,1
and the upper line L' by a sequence having the form 0, h 1 ,0,..., h n ,0,
with h1+...+hn = a, where all the hi's are positive.

110 © PrologIA
Prolog
Aociation

HERITAGE
Numeric constraints

The core of the program will be the procedure

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

The program itself consists of the following ten rules:

© 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};

make_distinct(B, <>) ->;


make_distinct(B, <B'>.C) ->
make_distinct(B, C),
{B # B'};

fill_zone(<V>.L, <V>.L, C, C) ->,


{V >= 0};
fill_zone(<V>.L, L''', <B>.C, C'') ->
place_square(B, L, L')
fill_zone(L', L'', C, C')
fill_zone(<V+B, B>.L'', L''', C', C''),
{V < 0};

place_square(B, <H, 0, H'>.L, L') ->


place_square(B, <H+H'>.L, L'),
{B > H};
place_square(B, <H,V>.L, <-B+V>.L) ->,
{B = H};
place_square(B, <H>.L, <-B, H-B>.L) ->,
{B < H};

The general call is performed by the query

> fill_rectangle(a, C), {C::n};

where n will be the number of squares we want to place in a rectangle. The


program calculates the size 1 x a of the rectangle (a  1 ) and the list C of
sizes of the n squares. This calculation starts with the execution of the first
rule, which simultaneously constrains a to be greater than or equal to 1 ,
creates n squares (of unknown sizes) all distinct and starts the filling of the
zone constituted by the whole of the rectangle. Line L constituting the

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 :

> fill_rectangle(a, C), {C::9};

we obtain 8 answers. The first two are as follows:

{ 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>
}

corresponding to the two diagrams we have drawn above. The other 6


answers describe diagrams which are symmetrical to these two.

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

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Boolean constraints Aociation

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.

After a brief recapitulation concerning boolean constraints, we will


describe the specifications of the language with regard to this domain, and
then go on to present a certain number of example programs intended to
illustrate how this type of constraint can be used.

2 . Some definitions and remarks

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

• Let V be the sub-set of variables that represent boolean values.


• Let B = {0', 1'} be the set of values that elements of V can take. They are
the representations of the constants false and true in Prolog III.
• Finally, let us consider the following operations:
~ (not)
& (and)
| (or)
=> (implies)
<=> (equivalent)

Boolean expressions are defined as follows:


• 0' and 1' are boolean expressions,
• boolean variables are boolean expressions,
• if f and g are boolean expressions, then:

~(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. .

Boolean operator priorities

In order to dispense with a certain number of parentheses an order of


priority is introduced for boolean operators:
• The operator ~ has priority over | => and<=>
• The operators | have priority over => and <=>

© 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

Below are some more examples of correct boolean expressions:


• 1'
• b if b is a boolean typed variable
• ~~a|1'
• a&~b' <=> ~a'|b
• (a|b)&(a'<=>(b&(a'|0')))

Boolean constraints

To represent boolean constraints, we also have the following relational


symbols:
Binary relations:

= (equals)
# (different)
=> (implies)

It should be noted that implies is also a relation in Prolog III. As an


operation it often enables expressions to be written more simply,
{ but care must be taken to differentiate it from the implies relation.

We can also constrain a tree b to be labeled by a boolean value, by means of


the following unary constraint:

b !boolt

Finally, we can constrain a tree b to be reduced to a leaf and be labeled by a


boolean value, by means of the following unary constraint:

b !bool

118 © PrologIA
Prolog
Aociation

HERITAGE
Boolean constraints

A boolean constraint is: either the unary relation which constrains a


{ variable to represent a tree labeled by a boolean; or a relation
between two boolean expressions.

Important remarks

Firstly, it must be noted that by definition a constraint is either verified or


not, and that in particular it does not send back a boolean value. We must
therefore be very careful not to use expressions for constraints, and vice-
versa. Therefore, the expression a b is not a constraint, nor is it correct to
write (a>0) (b>0)=1'. This is one of the restrictions of Prolog III, in that it
does not enable different algebræ to be mixed. It must be borne in mind
that a boolean constraint is only valid if it contains exactly one relational
symbol.

Although strictly speaking the concept of a type does not exist in


Prolog III, it is important to note that there are four ways of constraining a
variable b to be boolean (i.e. to represent a tree labeled by a boolean and
reduced to a leaf) without any restriction:
• by setting the constraint b !bool
• by setting the two constraints b !boolt, and b :: 0 (the latter adds
the constraint that b is a leaf)
• by having this variable appear in a boolean expression. It can appear in a
constraint, as in {b|~b=1'}1, or in a term, for example, boolean (b|0')2.
• by having this variable appear as an expression in a => type constraint. In
this case the two terms that are in relation are constrained to be boolean
expressions. One way of writing them is : 0'=>b 3 , where the only
constraint applied to the variable b is that it represents a boolean value.

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

Similarly, it should be noted that if a is a boolean variable, the constraint a#b


(the tree represented by the variable a is different from that represented by
the variable b) under no circumstances constrains b to represent a boolean
value. In particular, the simple fact that it does not belong to the boolean
domain is sufficient to verify the constraint.

Sets of boolean constraints

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 = 1 ' , b = 1 ' , c = 1 ' } or {a&b&c = 1'}


• {a => c, c # a|b} or {(~a|c)&~(c<=>a|b) = 1'}

However, for the sake of efficiency (i.e. in order to avoid pre-processing


which is too costly), it will often be beneficial to use large sets of simple
constraints rather than systems consisting of a few complex constraints.

Examples of boolean constraints

Here are some examples of correct boolean constraints, and sets of


constraints which 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}, …

a&b&c => a'|b'


The distinctive characteristic of this constraint, which can easily be
assimilated to a propositional clause or even a production rule in an
expert system, is that it comprises an or to the right of the
implication, a feature which is normally illegal in standard provers.
Equivalent sets of constraints:
{~a|~b|~c|a'|b'=1'},
{~a'&~b' => ~a|~b|~c}, …

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

Normal conjunctive form

Initially the normal form used to encode boolean constraints in the


interpreter does not seem to concern the user of Prolog III at all. However
we believe it is important to mention it for two main reasons.

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.

The normal conjunctive form, or clausal form, of a formula is an equivalent


formula written in the form of conjunctions of disjunctions of literals, as
below:

(l1 or l2 or… ln) and… (l'1 or l'2 or… l'p)

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.

Whenever possible, it is in the programmer's interest to write constraints


which are close to this formalism, so that exponentially costly
transformations are avoided. A typical example of a constraint which is very
costly to transform is the representation of a formula in normal disjunctive
form, such as the following:

{(a&b&c)|(a'&b'&c')|(a''&b'')}

the normal conjunctive form of which is:

{ a|a'|a'' = 1', a|a'|b'' = 1',


a|b'|a'' = 1', a|b'|b'' = 1',
a|c'|a'' = 1', a|c'|b'' = 1',
b|a'|a'' = 1', b|a'|b'' = 1',
b|b'|a'' = 1', b|b'|b'' = 1',
b|c'|a'' = 1', b|c'|b'' = 1',
c|a'|a'' = 1', c|a'|b'' = 1',
c|b'|a'' = 1', c|b'|b'' = 1',
c|c'|a'' = 1', c|c'|b'' = 1' }

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:

> {a<=>b = 1'};


{ a => b, b => a }
>

The interpreter analyzes the initial set of constraints, encodes it in clausal


form, verifies its solvability and prints it in its encoded form, once it has been
simplified. These concepts of solvability and simplification will be examined
in the sub-chapters below.

Here are some other examples of how sets of constraints are put into
normal conjunctive form, which you can also test on your interpreter:

• {(a&~b)|(c&~d)=1'} becomes {a|c=1',d=>a,b=>c,b&d=0'}


• {a|b#c,c !boolt,c::0} " {a&c=0',b&c=0',a|b|c=1'}

Boolean assignments

Here is a definition of boolean assignment which can be assimilated to the


concept of interpretation in propositional logic. In general, we can consider
that all the variables of V are assigned a value in {0', 1'}.

A boolean assignment is a set X= {x1 := a1, x2 := a2,…} where a value ai taken


from the set {0', 1'} is associated with any boolean variable xi

© PrologIA 123
Prolog
Boolean constraints Aociation

HERITAGE

By means of these assignments we can define the value of a boolean


expression for an assignment X in the following way:

Let v be a variable from V, and f and g two boolean expressions, then:

• 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.

Solution of a boolean constraint system

A boolean assignment is a solution of a set of constraints if and only if all the


constraints in this set are verified when the expressions it contains have been
replaced with their values in this assignment.

Similarly, a boolean constraint system is solvable if it allows at least one


boolean assignment which is a solution of it, unsolvable otherwise.

Examples :

• The system {a=>b,b=>c,c=>a} is solvable and allows the following


two solutions: X={a:=1', b:=1', c:=1'}
and X'={a:=0', b:=0', c:=0'}

124 © PrologIA
Prolog
Aociation

HERITAGE
Boolean constraints

• The system {~a|b=1',a|c=1',a#b,b#c} does not allow any solution,


and is thus unsolvable.

Simplification of constraint systems

When we refer to simplification of constraints, this generally covers two


very different aspects. The first aspect of simplification is that it makes the
considered system as readable as possible, by means of a convenient normal
form but above all because it removes the largest possible number of
redundancies, mainly in order to reduce its size. The second aspect concerns
elimination of unnecessary variables.

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:

> {a|b|c = 1',a => b,b => c};


{c = 1', a => b}

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.

Now let us examine the mechanism used to remove unnecessary variables.


First here is the definition of equivalence on a sub-set of variables.

Two constraint systems are equivalent on a sub-set of variables V if and only if


for any solution X of one, there exists a solution X' of the other which
coincides with X on V, and vice-versa.

© PrologIA 125
Prolog
Boolean constraints Aociation

HERITAGE

In particular, for output we will seek to produce an equivalent system on a


sub-set V, in general the set of variables appearing in the query, which only
contains variables from V. We will sometimes refer to this as projection on a
sub-vocabulary. The constraints present in this system will provide the links
which unite the considered variables in the current system.

126 © PrologIA
Prolog
Aociation

HERITAGE
Boolean constraints

This functionality is necessary for two reasons. Firstly, in some situations,


and we will see examples of this, we are only interested in the links that
unite some of the variables to which we have applied constraints (e.g., in a
fault diagnosis expert system, what are the links between the different
possible faults in a given configuration). Secondly the interpreter is
constantly creating new variables, a process which is transparent to the user.
It would be unfortunate if these variables appeared in constraints and
perturbed the clarity (if it could be termed as such) of the sets of resulting
constraints.

Finally, here are some examples of simplification of systems:

• The simplification of the system {a|x=1',a|~x=1'} on the sub-set {a}


gives the system {a=1'}

This example is relatively trivial since the initial system is already


equivalent to the system {a=1'}

• The simplification of {a|x=b|y,a&x#b&y} on {a, b, c} provides the


system {a|b=1'}

On this example it is worth noting that one of the two variables a or b


must be equal to 1 ' . In fact no solution of the initial system
simultaneously comprises the assignments a:=0' and b:=0'.
• Finally, the system {a=>b|x,x=a&c,y|b#x&c} when simplified on {a,
b, c} is equal to {a=>c|b,a&b&c=0'}

No particular comment is required, except that this example is difficult to


verify "by hand". Why not try it out?

Specific predefined rules

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).

bool(B). Verifies that the term B represents a known boolean value.

is_bool(B). Verifies that the term B represents a known boolean value,


or that the constraint {B !bool} belongs to the current constraint system.

© PrologIA 127
Prolog
Boolean constraints Aociation

HERITAGE

3 . Some simple example programs

In this section we examine some Prolog III programs which use boolean
constraints

An or on two variables

A first quite elementary predicate calculates the or of two variables, as


follows:

SimpleOr(b1, b2, b1|b2) ->;

A few executions give us a clearer idea of the processing performed when


this type of constraint is applied.

> SimpleOr(1',0',b);
{ b = 1'}
>

The result of or applied to true and false is true.

> 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' }
>

Finally, in order for the result of an or applied to two variables to be false,


both variables must represent the value false.,

An or on a list

The calculation of an or on a list of booleans is slightly more complicated. In


fact we want to express constraints equivalent to the expression "there is at
least one true element in the list" in which the second argument of the Or
predicate has the value of this expression.
Here is the program:

Or(<>, 0') ->;


Or(<b1>.L, b1|b2) ->
Or(L, b2);

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.

Here are some executions to make this a little clearer:

> 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'}
>

In this case, if there is to be at least one true element in a list consisting of


three times the same variable, of course this variable must represent the
value true.

> 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.

At most one true

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.

If we examine the problem with a bit more precision, we find ourselves


confronted by the following alternative:

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) };

Here are some executions:

> AtMostOneTrue(<1',b2,b3>,1');
{ b2 = 0', b3 = 0'}

> AtMostOneTrue(<b1,0',b2>,b);
{ b&b1&b2 = 0',
b|b1 = 1',
b|b2 = 1' }
>

There are no particular comments to be made about the first example. In


the second, the equivalent constraint system expresses the following
assertions:
• b1, b2 and b cannot be true at the same time (if they were,
AtMostOneTrue would send back the value 1' with two true elements
in the list)
• b1 or b is true (if not, AtMostOneTrue will send back the value 0' ,
whereas two of the elements in the list out of three are false).
• b2 or b is true (same reason as above)

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.

For example, if we consider a list of five elements we will have:

{
b1 & (b2|b3|b4|b5) = 0'
b2 & (b3|b4|b5) = 0'
b3 & (b4|b5) = 0'
b4 & b5 = 0'
}

So here is another possible notation :

AtMostOneTrue(L) -> OrOnAtMostOneTrue(L, b);

OrOnAtMostOneTrue(<>, 0') ->;


OrOnAtMostOneTrue(<b1>.L, b1|b2) ->
OrOnAtMostOneTrue(L, b2)
{b1 & b2 = 0');

Here are the same execution examples as in the previous example:

> AtMostOneTrue(<1',b2,b3>);
{ b2 = 0', b3 = 0' }
> AtMostOneTrue(<b1,0',b2>);
{ b1&b2 = 0' }
>

K true elements in a list of n booleans

Finally, here is the last example of constraint manipulation on lists of


booleans. In the following program, the predicate True(k,L,b) has been
constructed in such a way that the boolean value of b is the expression:

132 © PrologIA
Prolog
Aociation

HERITAGE
Boolean constraints

"the list L of booleans contains exactly k true elements"

True(k, <>, 0') ->


{k  0};
True(0, <>, 1') ->;

True(0, <b1>.L, ~b1&b2) ->


True(0, L, b2);

True(k, <b1>.L, b) ->


True(k-1, L, b2)
True(k, L, b3),
{k  0, b = (b1 & b2) | (~b1& b3)};

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

By using the parameter b it also possible to make this program entirely


deterministic if k and the size of the list L are known.

Here is an example of execution of this program:

> 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

It should be noted that the answer given, after simplification and


elimination of unnecessary variables in the final constraint system, results in
a different formulation of the problem posed, that can be expressed as
follows:

k booleans are true amongst n


if and only if
any disjunction of (n-k+1) elements is true,
and any conjunction of (k+1) elements is false.

It can also be observed that the execution of a question in which k is


unknown gives a set of answers corresponding to the possible values of k.

There is also a way of programming this example using a simple


recursive call, which makes it much more efficient. We leave it up to the
reader to write this program as an exercise.

4 . Other examples

In this section we present some slightly larger examples which make it


possible to appreciate how boolean constraints are used to solve a certain
number of problems.

Faults in a binary adder

We are trying to detect one or more defective components in an adding


circuit which calculates the binary sum of three bits x1,x2,x3, in the form
of a binary number composed of two bits y 1 ,y 2 . As you can see below,
the circuit is made up of 5 components numbered from 1 to 5: two and gates
(marked And), one or gate (marked Or) and two exclusive or gates (marked
Xor). We have also added three variables u1,u2,u3 to represent the output
from gates 1, 2 and 4.

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

Fig. 4.1 The circuit

A fault pi is associated with each gate i and we take the hypothesis of a


simple fault, i.e. two gates cannot be faulty at the same time.

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

In this example an implication is used instead of an equality (equivalence),


between the variables that represent the faults of a given gate and the
expressions that express its correct operation. This is in order to allow for
the fact that a gate can be faulty and still provide a correct response for a
certain set of data, (a typical example is a gate which always sends back the
same value). Therefore, the launch of a program with a correct set of data
does not provide the result 0' for all the variables that represent faults, since
these variables remain free.

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' }
>

Gate 4 (Xor) is faulty.

> circuit(<P1,P2,P3,P4,P5>,<1',0',1'>,<0',0'>);
{ P5=0',P4=0',P2=0',
P3&P1=0',
P3|P1=1' }
>

One of the gates 1 or 3 is faulty.

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')->;

We then launch the query and enumerate the solutions

© 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>);

Another possible solution is to work from a meta-level and use negation


by failure, since we want to know the data which on the one hand verify the
constraint system when P1 is true and do not verify it when P1 is false.

First of all, here is the not predicate, a standard Prolog predicate which
executes if the predicate P cannot execute:

not(P) -> P / fail;


not(P) ->;

We can thus pose our query as follows:

> 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>));

Here it should be noted that enumeration must occur before the


negation, otherwise problems will arise because the variables are not yet
instantiated (it is clear in this case that negation will systematically be
verified, since the constraint system before instantiation of the boolean
input-output variables is solvable in all cases). The problem here is that this
systematic instantiation "to the highest" is in fundamental opposition to the
Prolog III philosophy in which as many constraints as possible must be
installed before any enumeration occurs (see the chapter on numeric
constraints and the built-in predicate enum). Evidently, this solution is not
satisfactory.

Another possibility, still at a meta-level, but without using negation by


failure, is to use the built-in predicate known. We remind the reader that a
variable is known if and only if it represents a tree whose initial label is known
and whose number of sons is known to be zero or not.

© 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.

Here is this last query and the result it provides:

> 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);

{ X1 = 0', X2 = 0', X3 = 0', Y1 = 1', Y2 = 0',


P2 = 0', P3 = 0', P4 = 0', P5 = 0', P1 = 1' }

{ X1 = 0', X2 = 0', X3 = 1', Y1 = 1', Y2 = 1',


P2 = 0', P3 = 0', P4 = 0', P5 = 0', P1 = 1' }

{ X1 = 0', X2 = 1', X3 = 0', Y1 = 1', Y2 = 1',


P2 = 0', P3 = 0', P4 = 0', P5 = 0', P1 = 1' }

{ X1 = 1', X2 = 0', X3 = 0', Y1 = 1', Y2 = 1',


P2 = 0', P3 = 0', P4 = 0', P5 = 0', P1 = 1' }

{ X1 = 1', X2 = 0', X3 = 1', Y1 = 0', Y2 = 0',


P2 = 0', P3 = 0', P4 = 0', P5 = 0', P1 = 1' }

{ X1 = 1', X2 = 1', X3 = 1', Y1 = 0', Y2 = 1',


P2 = 0', P3 = 0', P4 = 0', P5 = 0', P1 = 1' }
>

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.

To do this, a parameter is added to the Circuit parameter and to


at_most_one_true , which sends back the boolean value that represents
the initial constraint system (we already noticed that it is always possible to
transform a boolean constraint system into an expression whose value is
true)..

140 © PrologIA
Prolog
Aociation

HERITAGE
Boolean constraints

Here is the new program. We use the three-argument version of


at_most_one_true which sends back the value b of the expression «There
is at least one true element in L». The result of Circuit is the conjunction of
b and the value of the newly constructed expression. We can also note in
passing that the original implications have been transformed into
disjunctions:

or(<>, 0') ->;


or(<B1>.L, B1|B2) ->
or(L, B2);

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:

> circuit(<1',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>, 1')


circuit(<0',P2,P3,P4,P5>,<X1,X2,X3>,<Y1,Y2>, 0')
booleans(<X1,X2,X3,Y1,Y2>);

Of course the result is identical to that given previously.

A logic puzzle

This logic brain-teaser proposed by Lewis Caroll is interesting in that it


consists of a series of sentences which can easily be formulated in the form
of propositional logic formulæ, and does not include any questions. Starting

© 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);

ElementOf(e, <e>.y) ->;


ElementOf(e, <e'>.y) ->
ElementOf(e,y), {e#e'};

© PrologIA 143
Prolog
Boolean constraints Aociation

HERITAGE

To calculate the possible relations which might exist between "clear-headed",


"popular" and "able to keep a secret", all that is needed is to write the
following query:

> 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

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Delay techniques Aociation

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

The definition of a known term is very precise in Prolog III:

A term is known when we know the label of the tree it represents


{ and we know whether or not the number of its sons is zero.

These terms are often reduced to one variable, and we then refer to them as
known variables.

The built-in predicates known, bound and free

The following three built-in predicates are directly involved with what we
know about a given term during the execution of a program:

known(T) executes successfully if T is a known term in the sense of the


above definition

bound(T) executes successfully if T is a term representing a tree whose:


• Initial label is known
• Number of sons is known

146 © PrologIA
Prolog
Aociation

HERITAGE
Delay techniques

free(T) executes successfully if we do not know the label of the tree


represented by the term T, and we do not know whether or not the number
of its sons is zero.

We note in passing that free(T) is not the negation of known(T). For


example, known(+x) fails because +x is not "known enough" (we know that
the label is a number, but we do not know its value), and free(+x) also
fails, because +x is "too known" (we know it is a leaf).

3 . Delay of goal execution

Prolog III enables goal execution to be delayed for as long as a term is


unknown (again, according to the definition above). As soon as it is known,
an attempt is made to execute the delayed goal. This delay operation is
performed by means of the built-in predicate freeze(X, P).

We can examine this processing on an example. Let us say that we want to


construct a predicate create(T1, T2, U) which delays the creation of a tuple U
formed by the two elements T1 and T2 for as long as the first element is not
known. Here are the corresponding rules:

create(T1, T2, U) ->


freeze(T1, create'(T1,T2,U));

create'(T1, T2, <T1, T2>)->;

We can examine an execution of create, to give an example of output


concerning frozen variables.

> 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.

These two predicates are shown below:

create_and(T1, T2, U) ->


freeze(T1, freeze(T2, create'(T1,T2,U)));

create_or(T1, T2, U) ->


freeze(T1, create'(T1, T2, U))
freeze(T2, create'(T1, T2, U));

create'(T1, T2, <T1, T2>) ->;

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:

• size constraints in which this size is not explicitly known


• constraints involving concatenation in which the size of the left-hand
operand is not known
• non linear numeric constraints, i.e. involving products of variables or
divisions by a variable.

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

Here is a first predicate, very close to the predicate size :

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 };

Two remarks can be made about this predicate in this connection:


• We use the fact that the size of a term is equal to that of the tuple
formed by its sons.
• We use any information about the start of this tuple in order to only
delay constraints applying to the unknown size part.

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

If everything really happened as we have just described, the two constraints


would be happy to remain frozen, and incoherence could never be detected
(remember that this is not resolution, but delay). However Prolog III enables
a certain amount of information to be communicated from the trees to the
numeric variables which represent their sizes. It is much more difficult to do
the same in the opposite direction (from sizes to trees), and this is not
performed in most cases.

Finally, let's examine an example where incoherence is not detected:

> { U :: N, 0 < N < 1 };


{ U = E[X],
X :: N,
-N+1 > 0,
N > 0 }
>

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.

In the same way as before, we can go a little further, by taking account of


the fact that the size of the resulting tuple is equal to the sum of the sizes of
the concatenated tuples. Here is a second predicate, written with this idea in
mind, which exactly reproduces the conc3 predicate:

delayed_conc2(U, V, W) ->
freeze(U, delayed_conc'(U,V,W))
size(U, N)
size(V, M)
size(W, N+M);

The delayed_conc' predicate is the same as the one shown previously.

Therefore, any constraint of the type W = U.V, where the size of U is


unknown, is replaced before the first literal of the rule containing this
constraint is processed, by a call to a predicate equivalent to delayed_conc2(U,
V, W).

Of course it is easy to see that this method in no way guarantees complete


processing in a case where the restrictions are not obeyed, but is rather a
palliative whose function is to relieve the programmer from having to
manage this type of delay.

Now here are some examples of delayed concatenation constraints. First of


all we examine very simple constraints, and the answers given by the
interpreter:

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 }
>

This is the most general case of a delayed constraint involving


concatenations. The concatenation is delayed, and a certain number of size
constraints and numeric constraints linking these sizes are added to the
current system. It should be remembered that these size constraints are also
delayed.

> { U :: N,
V :: M,
W :: P
W = U.V,
P # M+N };
>

> {U.X = V.X, U#V};


{ U :: N1,
U.X = X4,
U # V,
X :: N2,
V :: N1,
V.X = X4,
X4 :: N2+N1,
N1 >= 0,
N2 >= 0}
>

© PrologIA 153
Prolog
Delay techniques Aociation

HERITAGE

This example shows the limits of delayed constraints which involve


concatenation operations. In this case, the values represented by U and V
are not sufficiently known to enable the incoherence of this set of constraints
to be detected.

Delayed numeric constraints


Although only linear constraints are taken into account at the level of the
fundamental Prolog III algorithms, the language allows the programmer to
express non-linear constraints. In most cases this consists of a programming
feature to avoid use of the built-in predicate bound_mult, since the
expressions are linear at unification time, because a sufficient number of
variables present in these expressions are known. If this is not the case, the
addition of the constraint is delayed until it becomes linear.

The automatic delay process can also be programmed by means of freeze,


and as before we will explain how this functions by describing the Prolog III
rules which delay the constraints.

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_mult'(X, Y, Z, A)-> known(A) /;


delayed_mult'(X, Y, Z, 1')->
bound_mult(X, Y, Z);

delayed_divide(X, Y, Z)->
delayed_mult(Z, Y, X)
{ Y#0 };

In the case of multiplication, the processing of the constraint must be


delayed until one or other of the variables X and Y is known. We thus install
a double freeze on the two variables X and Y.

154 © PrologIA
Prolog
Aociation

HERITAGE
Delay techniques

The predicate delayed_mult' uses a communication variable A to make it


possible to avoid executing delayed_mult' twice if there is a stage where both
variables are known. The first execution of delayed_mult' will fail on the
first rule since A is not known and once the constraint is installed it will
assign A to 1', thereby forcing susbsequent calls to execute the first rule,
which does not install any constraint.
Division is constructed naturally using the predicate delayed_mult.

Concerning the delayed processing of non-linear numeric constraints, the


following informal definition should be taken:

In the processing of non-linear numeric expressions, everything happens as


if any constraint of the form Z = E*E', where E and E' are expressions
containing variables, is transformed into a call to the predicate
delayed_mult(E, E', Z). In a similar manner, any constraint of the form Z =
E/E', where E' is an expression containing variables, is replaced by a call to
delayed_divide(E, E', Z).

In particular, this method guarantees compliance with the rules


governing parentheses. For example the constraint systems
{X=A*(B+C)} and {X=A*B+A*C} are not processed in exactly the
{ same way. In the second case, if the value of A is unknown, the
fact that B or C is known unfreezes a part of the constraint,
whereas in the first case nothing happens for as long as their sum
is not known.

We can examine this delay process on an example:

non_linear(X,Y,Z,T,V) ->
{Z = X*Y+2T/(X+(3/2)V)};

The system considers this rule in the following way:

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

Here is an example of execution where a sufficient number of values are


known to make the system linear.

> non_linear(2,Y,Z,T,3);
{ Y = Y1, T = T1, Z = (4/13)T1+2Y1 }
>

Here is another where the constraints remain frozen:

> non_linear(X,3,Z,T,2);
{ X = X', Z = U'+3X', T = T',
X'+3 # 0,
U'*(X'+3) = 2T' }
>

As might be expected, a freeze remains in position on the division, since it


comprises unknown variables on the expression constituting the divisor.
The multiplication was linear when called and has been added to the
constraint system.

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.

Here are two examples of this:

{ 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

Programming control and


environment

1. Control
2. Expressions, static variables, arrays
3. Structuring, recording
4. Input/Output
5. Other elements of the environment

What is in this chapter ?

Everything …! This chapter describes in depth a series of very different concepts


which could be summarized under the title "how to program effectively in Prolog
III". It presents tools to control program execution in order to increase speed, such
as the famous /, and explains how to structure large programs into modules and use
directives so that they interface harmoniously. It also presents the practical methods
used to insert, delete and modify rules and shows how to save and restore them
using magnetic files. Following on from this, we deal with input/output and then all
the other features connected with the environment surrounding the Prolog III
system.

December 1990 © PrologIA


Prolog
The environment Aociation

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.

Since Prolog III is a fundamentally declarative language, the concept of


control is reduced to its simplest form, i.e. it consists in modifying or
restricting the above choices. The way Prolog makes these choices may
induce some programs to loop and thus not behave as planned. The two
following examples illustrate this problem.

Example 1. A typical case is transitivity. When trying to execute


greater_than(Jo,x) using the following program an instance of this same goal
is found. The program then starts to loop and ends in a stack overflow (or a
user interrupt).

> 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
>

The correct way to write this program is to remove the left-hand


recursitivity:

> 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 « / »

Normally, Prolog III attempts to execute a sequence of goals in all possible


ways. But if a rule containing a “/” (or cut1) is used to execute a goal q, the
execution of this “/” will delete all the rule choices which remain to be made
to execute q. This restricts the size of the search space; we could say that “/”
makes Prolog «forget» the other possible ways of executing q.

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 “/”

This topic is illustrated by the following examples:

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([x,y]) -> color(x) size(y);


choice1("that's all") ->;

choice2([x,y]) -> / color(x) size(y);


choice2("that's all") ->;

choice3([x,y]) -> color(x) / size(y);


choice3("that's all") ->;

choice4([x,y]) -> color(x) size(y) /;


choice4("that's all") ->;

{}
> 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] }
>

The cut can be regarded as a notation which is added to a correct program to


make it more efficient. Of course this is only justified if we are only
interested in the first solution provided by this program.

© PrologIA 163
Prolog
The environment Aociation

HERITAGE

Some standard uses of the “/” are show below:

« First solution only »


first_solution_only(b) -> b /;

« 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);
>

block(e, b), block_exit(e)


block is a predefined rule which is used to suddenly interrupt the execution of
a goal b. It can be assumed that:
- to execute block(e, b) b is executed having first created a pair of
imaginary parentheses around b, labeled by e.
- block_exit(e) immediately aborts the execution of all goals enclosed by
the parentheses labeled by e. Execution then continues normally, once
the environment has been restored to its state before execution of b.

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

- if there are several parentheses labeled by e, block_exit(e) stops at the


innermost pair of brackets.

- if block_exit(e) does not encounter any parentheses labeled by e, an


error is indicated.

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 ?

enablng the user to select a reponse in order to continue execution (C),


interrupt it (K), continue execution in trace mode (T) or quit the session (Q).

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.

2 . Expressions, static variables, arrays

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 }
>

Because arithmetic is an integral part of the core of Prolog III, evaluable


expressions often do not have the same meaning as in Prolog II, at least
when they are written in the right syntax. Below are the two terms which
were evaluated in the previous example.

> {t=add(mul(2,add(3,4)),1000)};
{ t = add(mul(2,add(3,4)),1000) }
> {t=2*(3+4)+1000};
{ t = 1014 }
>

When a function to be evaluated has an incorrect number of arguments, or


some of its arguments are of the wrong type, an error occurs. Each
evaluable function must have arguments of a precise type; there is no
automatic type conversion at evaluation.

• The value of a number or string is equal to this number or string.

© PrologIA 167
Prolog
The environment Aociation

HERITAGE

• The value of an indexed array is equal to the value of the


corresponding element of this array. For example:

> def_array(tab,100) assign(tab(50),3);


{}
> val(tab(50),x);
{ x = 3 }
>

• The value of an identifier i is defined as folows:


- if a constant k has been assigned to i (using the assign rule as in the
following paragraph), then the value of i is k.
- if no assignment has been performed on i, then the value of i is i
itself.
Example:

> assign(one,1);
{}
> val(one,x) val(two,y);
{ x = 1, y = two }
>

The evaluable functions are as follows:

add(t1, t2)
value(add(t1, t2)) = value(t1) + value(t2).

The values of t1 and t2 must be numeric and known.

sub(t1, t2)
value(sub(t1, t2)) = value(t1) - value(t2).

The values of t1 and t2 must be numeric and known.

mul(t1, t2)
value(mul(t1, t2)) = value(t1)  value(t2).

The values of t1 and t2 must be numeric and known.

168 © PrologIA
Prolog
Aociation

HERITAGE
The environment

div(t1, t2)
value(t1)
value(div(t1, t2)) =
value(t2)

This is the integer quotient by default of the absolute value of t1 by the


absolute value of t2.The values of t1 and t2 must be integers.

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.

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, 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.

if(t, t1, t2)


value(if(t, t1, t2)) = (value(t1) if (value(t)0) else value(t2)

trunc(t)
value(trunc(t)) = integer conversion of the value of t

abs(t)
value(abs(t)) = absolute value of value(t).

The value of t must be an integer or a floating number.

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" }
>

In Prolog these static variables can be regarded as a particularly efficient way


of writing specified facts (or rules without bodies). From the user's point of
view, the use of assign and val shown above can be considered to be
equivalent to:

> 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)

Dynamically defines an array of Prolog constants with name i and size n.


This array behaves like a global static variable. The authorized index values
are the elements 1, 2, … n.

If an array with the same name already exists:


- if it is an array of the same size, nothing happens
- if the sizes are different, an error occurs

Access and assignment of array components are similar to those in arrays in


other programming languages. The array is de-allocated when the module
it belongs to is deleted (using kill_module for example).

Example: stack management.

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);

initialize -> assign(pointer,1) def_array(stack,100);

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
>

3 . Structuring, recording and modifying


rules.

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

However, this situation no longer exists when we consider large programs


which are sufficiently complex to require splitting up into modules with
different functions, or even relatively simple programs which comprise a
large number of identifiers, regardless of whether or not they are rule
names. It quickly becomes clear that it would be very useful to have a way
of grouping together the identifiers according to "logical" criteria. These
groups provide a method for comfortably handling whole families of
identifiers by means of unique names, and also for regulating their visibility
i.e. for indicating which names defined in a "part of a program" (we will use
the term module) can be referenced in other parts.

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.

• a series of conventions which define reading/writing contexts make it


possible to write identifiers without their prefix conventions, and to
add this prefix to identifiers which are read without it.

Let's now examine all this in a little more detail.

Identifier families

Below is the complete syntax for identifiers:

<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 thus consists of a name preceded by a prefix, the two


being separated by a colon. An abbreviated identifier is what remains when
the prefix and separatorare removed from a complete identifier. The prefix
can be empty, can be a word, or can consist of several words separated by
colons.

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

The prefixes of these first three examples are " g r a m m a r " ,


"sys:env:screen" and "" (the empty prefix) respectively. The associated
abbreviated identifiers are plural , clear_screen and paul respectively.

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.

Closed part of a family

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

1 i.e. identifiers which are assigned a value by the assign primitive

176 © PrologIA
Prolog
Aociation

HERITAGE
The environment

Reading and writing context

A reading and writing context is a set of rules for the transformation of


abbreviated identifiers into complete identifiers and vice-versa. They
associate a unique complete identifier with every abbreviated identifier, and
conversely they define the set of identifiers which can be written in
abbreviated form. The internal coding of the identifiers always corresponds
to their complete form; the transformations discussed here only occur when
they are written or read.

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.

In formal terms, a reading and writing context is defined by writing a triplet

( explicit list , implicit list , default prefix )

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

• a complete identifier does not undergo any transformation


• an abbreviated identifier coinciding with the abbreviated form of an
element i of L is considered to represent this identifier, and is thus
completed with the prefix of i.
• the other abbreviated identifiers are completed with the indicated
default prefix.

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.

set_context(name, explicit-sequence, implicit-sequence, default-prefix)


This command is used to define a context, by giving it a name, and to install
it as the current reading and writing context.
• name is an identifier or string: it is the name of the newly defined
context.
• explicit-sequence is a list in the form

[ prefix1, list1, prefix2, list2, … prefixn, listn ]

which represents a sequence of complete identifiers "factorized" by


families. For example the list:
["m1",["aa","bb"],"m2",["cc"],"m3",["dd","ee","ff"]]
in fact represents the list of complete identifiers m1:aa, m1:bb, m2:cc,
m3:dd, m3:ee, m3:ff
• implicit_list is a list of prefixes given in the form of character strings.
Each prefix represents the closed part of the corresponding family, or
the whole of the family if closure has not been performed.

178 © PrologIA
Prolog
Aociation

HERITAGE
The environment

Given these conditions, the list L of identifiers defined by all these


elements is the concatenation, in the order they appear, of the
e x p l i c i t _ s e q u e n c e and the lists of identifiers defined by the
implicit_sequence. When this information is subsequently used, the
order of appearance of these elements is strictly maintained: searches
are first performed in the list deduced from explicit_sequence and this
list is scanned from start to finish, then in the list deduced from the first
element of implicit_sequence, then in the list deduced from its second
element, and so on.
• default_prefix is the prefix which will be attributed to each abbreviated
identifier provided it is not the abbreviated form of one of the
identifiers appearing in list L.

Note 1. When the command set_context(name, explicit_sequence,


implicit_sequence, default_prefix) is executed, it produces the memorization of
the context it describes in the form of a fact added to the environment
module:

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.

> apple ->


set_context("new",["fruits",["peach"]],["sys"],"
def")
peach;

© 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.

current_context(t0, t1, t2, t3)


current_context(t0)
Produce the name and definition of the current context:
t0 = name of the current context (identifier or string)
t1 = explicit-sequence
t2 = implicit-sequence
t3 = default-prefix.

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" }
>

When read, the abbreviated identifier dictionary becomes sys:dictionary (as


shown by the result of the built-in predicate string_ident), whereas when
written, the identifier sys:dictionary is abbreviated to dictionary. Given the
definition of the context, this shows that sys:dictionnary belongs to the closed
part of the "sys" family. This example continues below:

> remove_implicit("sys","dictionary");
{}

180 © PrologIA
Prolog
Aociation

HERITAGE
The environment

> string_ident(p,a,dictionary) outl(sys:dictionary);


sys:dictionary
{ p = <>, a = "dictionary" }
>

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

In a given program and at a given moment, module p is the grouping


together of all the facts and rules, evaluable functions, static variables (or
identifiers assigned by assign) and arrays whose name belongs to the same
family p. That is they possess the same prefix p which we will call the module
prefix. The identifiers from family p can appear in other modules, but not in
the position of access identifier (i.e. as a predicate name in a rule head). The
concept of a module is dynamic; when a new rule is created or deleted, the
module corresponding to its access identifier is modified accordingly.

© 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.

Source module. A source module is defined as the sequence of rules enclosed


by the two following directives:

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):

module(p)  module(p, [], ["sys"], p)


module(p,s)  module(p, s, ["sys"], p)
module(p,s,i)  module(p, s, i, p)

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

A module's reading context enables certain primitives used inside the


module to be redefined clearly. For example:

module("example", ["example", ["out"]] ) ;


...
out(x) -> embellish(x,y) s y s : o u t ( y ) ;
...
end_module("example");

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.

An object module can be saved in a magnetic file for subsequent reloading.


This is done using the load and save primitives. When an object module is
written in a file, it is stored in such a way that when the module is restored,
its identifiers can be renamed. It is thus possible to resolve name conflicts
whatever they may be, and to construct programs which do not interfere
with the data they manipulate.

Adding, deleting and searching for rules

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.

The execution of assert(t, [ q1, … qn ]) adds the rule t -> q1 … qn , { } above


the group of rules having the same "name" as t, i.e. at the start of the group
corresponding to t. If no group of rules has the same "name" as t, a new
group is created. For example, the following two commands:

© PrologIA 183
Prolog
The environment Aociation

HERITAGE

assert(conc([e|x],y,[e|z]),[conc(x,y,z)]);
assert(conc([],y,y),[]);

typed in this order, have the effect of adding the program

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);;
{}
>

If a syntax error is found, a warning is displayed and a certain number of


characters (in principle all the characters up to a " : " or up to the end of the
line on the console unit) are ignored.

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.

i must be an identifier and a must be an integer. Rule number n in the group


corresponding to name i and arity (number of arguments) a is listed on the
current output.

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

These primitives enumerate rules which satisfy the following constraints: n


= rank of the rule in its group, a = rule access identifier (name), t = rule head,
q = rule body. In the first version, a must be a known identifier. In the
second version t must be sufficiently known to enable the access identifier of
the relevant rules to be deduced.

Here is an example of how it is used, relating to the conc program given


above as an example:

> 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.

i must be an identifier, a and n must be integers. These primitives delete


rules as follows:
- first version: all rules having the access identifier (name) i,
- second version: all rules with name i and arity a.
- third version: the n-th rule from those which have name i and arity a.

© 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 }
>

Manipulation of object modules

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.

f is a file name (character string) and l is a prefix substitution list. This


command produces the loading of saved modules in the indicated file, which
must have been produced by the save command. If an element is redefined,
the version detected in the file replaces the version in memory, without
producing an error.

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.

f is a file name (character string) and l is a list of prefixes (character strings).


This command saves in the indicated file all the elements (rules, static
variables and arrays) from the modules corresponding to the prefixes given.

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

All the input/output devices (keyboard, screen, files, etc.) used by a


Prolog III program are represented by entities called input/output units. The
written representation of these units is a character string; if need be this
string also represents an item of information identifying the unit in relation
to the operating system: file name, etc.

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_char(c1) in_char(c2) in_char(c3);


ABC
{ c1 = `\12`, c2 = `A`, c3 = `B` }
>

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.

Reads the largest sequence of characters which constitute the written


expression (syntactically correct) of a sequence of Prolog III terms. Then
attempts to unify t with the first of the read terms. The blank characters
following the last term read are also read.

190 © PrologIA
Prolog
Aociation

HERITAGE
The environment

Example:

> in_term(t) in_char(c);


name_married_weight("Dupont",1',755/10) is a t e r m ;
{t = name_married_weight("Dupont",1',151/2) c = `\12` }
>

in_sentence(t1, t2, t3)


Reads a sentence ending in ".", "?" or "!" and puts it in the form of three lists,
unified with t 1 , t 2 and t 3 respectively. t 1 is the list of tokens (words,
numbers, special characters, etc.) which constitute the sentence. t3 is the list
obtained by replacing each upper-case letter appearing in an element of t1
with the corresponding lower-case letter. t 2 is the same as t 3 , but each
element of t 3 which corresponds to a known identifier in the family
corresponding to the default prefix of the current context has been replaced
by the conventional symbol <> to indicate this fact.

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.

Whatever the type of expression to be written, if its expression is longer


than the space remaining on the current line, then it is cut at the required
place by the insertion of a carriage-return hidden by a " \ " character. In
addition the writing of a term complies with the following conventions:
• Lists are printed in Edinburgh syntax (square brackets [ ] ).
• Any identifier which does not correspond to identifier syntax is put in
quotes.

• The current context determines the possible abbreviations for


identifiers.

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:

> out([1, Pierre, " H i ! " ] ) ;


[1, Pierre, "Hi!"]{}
>

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:

> out([1, Pierre, "Hi!"]) line fail;


[1, Pierre, "Hi!"]
>

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:

> out("\tHello!") line fail;


"\tHello!"
> outm("\tHello!") line fail;
Hello!
>

outc(t)
Writes the term t and the constraints that apply to it
Examples :

> outc(t) fail , { t ::num } ;


t,
{t::num }
> outc(t) fail , { t ::numt } ;
X3[X2],
{X3::num }
>

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.

5 . Other elements of the environment

Leaving Prolog III

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.

The second version quit, is equivalent to quit(0).

194 © PrologIA
Prolog
Aociation

HERITAGE
The environment

Time, other measurements

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

Predefined rules and


external procedures

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Predefined rules and external procedures Aociation

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:

Function briefly describes the predicate functionalities


Class specifies whether the predicate is an external
procedure, a built-in predicate or an evaluable
function, and defines its Prolog II and Edinburgh
compatibility.
Category refers to the chapter dealing with this type of
predicate, and often defines a sub-category.
Known parameters indicates the arguments which must be known, if
any, when the predicate is called.

Error message indicates whether or not incorrect use of the


primitive results in one or more error messages. It
should be noted that in certain cases it is preferable
for the primitive to fail, rather than print an error
message.

In addition, the arguments for each primitive correspond in most cases to


the required type (N for integer, S for string, T for term, R for rational, etc.)

We then give a more detailed description of the primitive, followed by


examples which make use of it, if necessary a number of remarks, and
finally a list of primitives with similar functions.

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : S1 and S2

Error message : if S1 is not the prefix of a family having a closed


part.

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

arg(N, T1, T2)


Function : Calculates the N-th argument of a term

Class : Prolog III predefined rule


Category : Trees, lists, tuples and strings
Known parameters : N, which must be a positive or zero intger

Error message : N is unknown, negative or greater than the


number of arguments in T1

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
>

> arg(3,U,T), {U :: tuple};


{ U = V.<T>.V',
V :: 2 }
> arg(2,[A,B,C],T);
{ T = [B,C] }

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

Class : Prolog II+ partial compatibility


Category : Trees, lists, tuples and strings
Known parameters : N, which must be a positive or zero integer

L which must be a sufficiently known list


Error message : N is unknown negative or greater than the
number of elements in T.
The list L is not sufficiently known

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

arg3(N, T1, T2)


Function : Calculates the N-th element of a tuple

Class : Prolog III predefined rule


Category : Trees, lists, tuples and strings
Known parameters : N, which must be a positive or zero integer

Error message : N is unknown negative or greater than the


number of arguments in T.

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : T and Q

Error message : - if Q is not a "standard" list


- if T is an incorrect rule head

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),[]);
{}

typed in this order, have the effect of adding the program

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)

Class : Prolog III predefined rule (Edinburgh)


Category : Rule and identifier management

Known parameters : T and Q


Error message : - if Q is not a "standard" list
- ifT is an incorrect rule head

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : T and Q

Error message : - if Q is not a "standard" list


- ifT is an incorrect rule head

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)

Class : Prolog III predefined rule (Edinburgh)

Category : Rule and identifier management


Known parameters : T and Q

Error message : - if Q is not a "standard" list


- ifT is an incorrect rule head

Identical to assert''.

206 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

assign(I, T)
Function : Assigns

Class : Prolog III predefined rule (II+)


Category : Control
Known parameters : T and I

Error message : If T does not represent an identifier, a number, a


character or a character string.

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:

> assign(file_name, "myfile.txt");


{}
> val(file_name,x);
{ x="myfile.txt" }
>

In Prolog, these static variables can be seen as a particularly efficient way of


writing specified facts (rules without bodies). From the user's point of view,
the way assign and val are used above is equivalent to:

> 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

Class : Prolog III predefined rule (II+)


Category : Control
Known parameters : tab(N) and T

Error message : Integer expected. Array already defined,


Undefined array, Array overflow.

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

block(E, C, B), block_exit(E, C)


Function : Aborts execution, Recovers errors

Class : Prolog III predefined rule (II+)


Category : Control
Known parameters : B

Error messages : Undefined block

Description:

The predefined rule block is used to terminate abruptly the execution of a


goal or list of goals B. This primitive is mainly used to recover errors or
control program execution.

We can consider that:

• to execute block(E, C, B), a pair of imaginary parentheses labeled by E


and possibly by C is created around the goal B, and B is then executed.

• the second parameter C in block(E C, B) is either a second label or


additional information that will be returned by block_exit(E, C). Some
predefined rules use this second parameter as additional information
by transmitting the argument that caused the error.

• block_exit(E, C) immediately aborts the execution of all goals enclosed


by the parentheses labeled by E and C. Execution then continues as if
block(E, C, B) had been executed, but no choice is left for the goal or
goals B that is/are waiting.

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

• If there are several parentheses labeled by E and C, block_exit(E, C)


stops at the innermost pair of parentheses.

• If block_exit(E, C) does not encounter any E and C parentheses, we


return to command level. If E is not an integer we obtain the error
message “Error 50: Undefined block”, but if E is an integer the
message corresponding to error E is obtained.

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);

execute(`t`) -> % program termination


block_exit(end_command, <>);
execute(`c`) ->
outml("continue");
execute(X) ->
block_exit(end_command, X),
{ X # `c` };

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);

reading_loop_continuation(X, D_ata, <D_ata>.L) ->


free(X) !
reading_loop(L);
reading_loop_continuation(17, _, <>) -> % end of file
close_input("file_to_read");

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

block(E, B), block_exit(E)


Function : Aborts execution. Recovers errors.

Class : Prolog III predefined rule (II+)


Category : Control
Known parameters : B

Error messages : Undefined block

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.

• block(E, B) is equivalent to block(E, _, B).


• block_exit(E) is equivalent to block_exit(E, <>).

When block_exit(E, C) is executed in an environment "parenthesized" by


block(E, B), block_exit(E, C) behaves in the same way as block_exit(E).
Conversely, when b l o c k _ e x i t ( E ) is executed in an environment
"parenthesized" by block(E, C, B), then block_exit(E) behaves in the same way
as block_exit(E, <>).

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

Class : Prolog III predefined rule


Category : Type verification
Known parameters : B

Error message : None

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

Known parameters : None


Error message : No

Description:
This predicate executes if T is a term representing a tree for which:

• the initial label is known


• the number of sons is known

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

bound_conc(U1, U2, U3)


Function : Concatenation

Class : Prolog III predefined rule


Category : Trees, lists, tuples and strings
Known parameters : See below

Error message : No

Description:
Sets the constraint {U3 = U1.U2}. Fails if the size of the tuple U1 is not
known.

Examples:

> bound_conc(<1,2>.X,Y,Z), { X::3 };


{ Z = <1,2>.X.Y, X::3 }
> bound_conc(X,Y,Z);
>

See also:
• conc3

214 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

bound_mult(N1, N2, N3)


Function : Linear multiplication

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : See below

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

Class : Prolog III predefined rule


Category : Trees, lists, tuples and strings
Known parameters : N or the size of T (see below)

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);
>

In this example we have renamed the intermediate variables created by


Prolog III.

216 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

bound_tree(T)
Function : Verifies that T represents a unique tree

Class : Prolog III predefined rule


Category : Trees, lists, tuples and strings
Known parameters : None

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

Known parameters : None


Error messages : No

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:

Fish(sole, 2) -> break("in Fish", "sol;p;C");


Fish(tuna, 4) ->;

© 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

Class : Prolog III predefined rule


Category : Type verification
Known parameters : C

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

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : C or N

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : S

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

Class : Prolog III predefined rule (II+)


Category : Input/Output
Known parameters : None

Error message : Impossible to close file

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

Class : Prolog III predefined rule (II+)


Category : Input/Output

Known parameters : F, which must be a character string


Error message : Impossible to close file

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

Class : Prolog III predefined rule (II+)


Category : Input/Output
Known parameters : None

Error message : Impossible to close file

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

Known parameters : F, which must be a character string


Error message : Impossible to close file

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

conc3(U1, U2, U3)


Function : Delayed concatenation of tuples with arithmetical
constraints on the sizes.
Class : Prolog III predefined rule
Category : Trees, lists, strings and tuples

Known parameters : See below


Error message : No

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:

• size, bound_size, bound_conc

224 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

conc_string(S1, S2, S3)


Function : String concatenation

Class : Prolog III predefined rule (II+)


Category : Trees, lists, strings and tuples
Known parameters : See below

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"

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : None

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : None

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : None

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

Class : Prolog III external procedure


Category : Control
Known parameters : None

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).

> color(red) ->;


> color(blue) ->;
> size(big) ->;
> size(small) ->;
> choice1(<X,Y>) -> color(X) size(Y);
> choice1("that's all") ->;
> choice2(<X,Y>) -> ! color(X) size(Y);
> choice2("that's all") ->;
> choice3(<X,Y>) -> color(X) / size(Y);
> choice3("that's all") ->;
> choice4(<X,Y>) -> color(X) size(Y) '!';
> choice4("that's all") ->;

© 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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : None

Error messages : No

Description:
Activates the debugger to debug a program execution.

Detailed information on how to use the debugger can be found in the


chapter “Debugging Prolog III programs”.

See also:

• no_debug, trace, no_trace


• set_config, set_configuration, get_config, get_configuration,

© PrologIA 229 ii
Prolog
Predefined rules and external procedures Aociation

HERITAGE

def_array(I, N)
Function : Array declaration

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : I and N

Error message : Identifier expected, Integer expected, Array


already defined

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.

If an array with the same name already exists:


• and it is an array of the same size, nothing happens
• and the sizes are different, an error occurs
Access and assignment are similar to those of arrays in other programming
languages. The array is de-allocated when the module it belongs to is killed
(i.e. the rules having the same prefix).

230 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

Examples:

> list;
inc(i) -> val(i,x) assign(i,x+1);

dec(i) -> val(i,x) assign(i,x-1);

initialize -> assign(pointer,1) def_array(stack,100);

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

Class : Prolog III external procedure (II+)


Category : Control
Known parameters : None

Causes of failure : T1 or T2 do not represent trees labeled by an


identifier.

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:

reply(p) -> default(p,outml("nobody"));

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : None

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

Class : Prolog III external procedure (II+)

Category : Rule and identifier management


Known parameters : None
Error message : No

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : M, which must be a string

Error message : If M is not a character string

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:

> aa:bb(1) ->;


aa:cc(1,2) ->;;
> dictionary("aa",L);
{ L = [aa:<bb,1>,aa:<cc,2>] }
>

234 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

dif(T1, T2)
Function : Inequality

Class : Prolog III external procedure (II+)


Category : Control
Known parameters : None

Error message : No

Description:
Sets the constraint {T1 #T2].

© PrologIA 235
Prolog
Predefined rules and external procedures Aociation

HERITAGE

div(N1, N2, N3)


Function : Integer division

Class : Prolog III external procedure


Category : Numeric constraints
Known parameters : N1 and N2, integers. N2 must not be zero.

Error message : Zero division

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

Class : Prolog III external procedure (II+)


Category : Type verification
Known parameters : T, which must represent a 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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

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

Class : Prolog III external procedure


Category : Environment
Known parameters : None

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

Class : Prolog III external procedure


Category : Environment
Known parameters : See below

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : P

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

Class : Prolog III external procedure (II+)


Category : Numeric constraints
Known parameters : None

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:

> enum(R),{-1.5 < R < 4};


{ R = 3 }
{ R = 2 }
{ R = 1 }
{ R = 0 }
{ R = -1 }
>

242 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

enum(R, R1)
Function : Integer enumeration with upper delimiter

Class : Prolog III external procedure (II+)


Category : Numeric constraints
Known parameters : R1

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.

enum(R, R1, R2)


Function : Integer enumeration between two delimiters

Class : Prolog III external procedure (II+)


Category : Numeric constraints

Known parameters : R1 and R2


Error message : No

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

Class : Prolog III external procedure (II+)


Category : Control
Known parameters : None

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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : None

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:

• exit(S), quit, quit(N)


• reload

© 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

Error message : String expected

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:

• exit, quit, quit(N)


• reload

246 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

fail
Function : Prolog failure

Class : Prolog III predefined rule (II+)


Category : Control
Known parameters : None

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

Class : Prolog III predefined rule


Category : Control
Known parameters : P

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

Class : Prolog III predefined rule (II+)


Category : Trees, tuples and lists
Known parameters : S1, S2

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

Known parameters : None


Error message : No

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:

• free_label, known, bound, bound_tree, bound_tree'

250 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

free_label(T)
Function : Verifies that the label of term T is not known.

Class : Prolog III predefined rule


Category : Control
Known parameters : None

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

• free, known, bound, bound_tree, bound_tree'

© PrologIA 251
Prolog
Predefined rules and external procedures Aociation

HERITAGE

freeze(T, P)
Function : Delays execution of a goal

Class : Prolog III external procedure (II+)


Category : Control
Known parameters : None

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

Class : Prolog III external procedure


Category : Environment
Known parameters : None

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

gcd(N1, N2, N3)


Function : Calculates the greatest common divisor

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : N1, N2

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

Class : Prolog III external procedure


Category : Environment
Known parameters : None

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

Class : Prolog III external procedure


Category : Environment
Known parameters : None

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:

• set_config, set_configuration, get_config

256 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

getenv(S1,S2)
Function : Obtains the value of an environment variable.

Class : Prolog III external procedure


Category : Environment
Known parameters : S1

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

Class : Prolog III external procedure


Category : Type verification
Known parameters : None

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

Error message : Unexpected end of file

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:

> in_char(X) in_char(Y);


a
{X=`\12`, Y=`a`}
> in_char(X);1
{X=`1`}
>

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

Known parameters : None


Error messages : Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

Error messages : Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

Error messages : Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/output
Known parameters : None

Error messages : Unexpected end of file

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:

• in_char, in_char', in_ident, in_integer, inl, in_sentence, in_string, in_term,


next_char, next_char'

© PrologIA 263
Prolog
Predefined rules and external procedures Aociation

HERITAGE

in_sentence(T1,T2,T3)
Function : Reads a sentence

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

Error message : Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

Error message : Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/output
Known parameters : None

Error messages : Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

Error message : Error in assert or in_term


Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/output
Known parameters : None

Error messages : Unexpected end of file

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : F, which must be a character string

Error message : Unexpected end of file


Impossible to open file

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:

• input_is, output, output_is

© PrologIA 269
Prolog
Predefined rules and external procedures Aociation

HERITAGE

input_is(F)
Function : Provides the current input unit

Class : Prolog III external procedure (II+)


Category : Input/output
Known parameters : None

Error messages : Unexpected end of file


Impossible to open the file

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None.

Error message : Syntax error. Group already exists.


Unexpected end of file.

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);;
{}
>

If a syntax error is encountered, a warning is dispalyed and a certain number


of characters (in principle all characters as far as the next " ; ", or up to the
end of the line on the console unit) are ignored.
insert causes an error when the group read already exists, whereas reinsert
replaces the old group with the new definition.
See also:
• insert(F), reinsert, reinsert(F)

© PrologIA 271
Prolog
Predefined rules and external procedures Aociation

HERITAGE

insert(F)
Function : Inserts rules from a file

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : F, which must be a string.

Error message : Unexpected end of file


Impossible to open file.
Syntax error. Group already exists.

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 ";"

If a syntax error is found, a warning is displayed and a certain number of


characters (all the characters up to the next ";" ) are ignored. Insertion then
starts again.

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.

Class : Prolog III external procedure (II+)


Category : Type verification
Known parameters : See below

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.

Class : Prolog III predefined rule


Category : Type verification
Known parameters : None

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

Class : Prolog III predefined rule


Category : Type verification
Known parameters : None

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:

• char, string, is_string

© PrologIA 275
Prolog
Predefined rules and external procedures Aociation

HERITAGE

is_ident(I)
Function : Verifies that I represents an identifier

Class : Prolog III predefined rule


Category : Type verification
Known parameters : None

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.

Class : Prolog III predefined rule


Category : Type verification
Known parameters : None

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

Class : Prolog III predefined rule


Category : Type verification
Known parameters : None

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

Class : Prolog III predefined rule


Category : Type verification
Known parameters : None

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

Known parameters : None


Error messages : No

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : S

Error messages : No identifier with this prefix

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:

> try1 ->;


> try2 ->;
> assign(try3,0);
{}
> list val(try3,X);
try1 -> ;
try2 -> ;
{ X = 0 }
> kill_module("");
{}
> list val(try3,X);
{ X = try3 }
>

See also:
• new

© PrologIA 281
Prolog
Predefined rules and external procedures Aociation

HERITAGE

known(T)
Function : Verifies that T represents a known tree.

Class : Prolog III predefined rule (II+)


Category : Control
Known parameters : T

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

known_part(U1, U2, U3)


Function : Extracts the known part of a tuple.

Class : Prolog III predefined rule


Category : Trees, tuples and lists
Known parameters : See below

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

> known_part(U1,U2,U3), {U1 =<1,2,3>.<4,X,6>};


{ U1 = <1,2,3,4,X,6>,
U2 = <1,2,3,4,X,6>,
U3 = <> }
> known_part(U1,U2,U3), {U1 =<1,2,3>.<X>.L};
{ U1 = <1,2,3,X>.L,
U2 = <1,2,3,X>,
U3 = L }
> known_part(U1,U2,U3), {U1
=<1,2,3>.<X>.L,L#<>};
{ U1 = <1,2,3,X>.L,
U2 = <1,2,3,X>.V1,
U3 = V2,
L = V1.V2,
V1::1 }
>

© PrologIA 283
Prolog
Predefined rules and external procedures Aociation

HERITAGE

lcm(N1, N2, N3)


Function : Calculates the lowest common multiple

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : N1, N2

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

Class : Prolog III predefined rule (II+)


Category : Input/Output
Known parameters : None

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : None

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : See below

Error message : Bad argument type, Non-existent rule

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : See below

Error message : Bad argument type, Non-existent rule

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

list([<I1, A1>, …, <In, An>])


Function : Prints rules

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : See below

Error messages : Bad argument type, Non-existent rule

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : See below

Error messages : Bad argument type, Non-existent rule

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

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : L

Error message : No

Description:
Sets the constraint {S = L'}, where L' is a string composed of characters
forming the list L.

Example:

> list_string([`H`,`e`,`l`,`l`,`o`], X);


{ X = "Hello" }
>

See also:
• split

© PrologIA 291
Prolog
Predefined rules and external procedures Aociation

HERITAGE

list_tuple(L, U)
Function : List/tuple conversion

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : L

Error message : No

Description:
Sets the constraint {S = U'}, where U' is a tuple composed from the elements
which form the list L.

Example:

> list_tuple([1/12,aaa,1',"rhino"], X);


{ X = <1/12,aaa,1',"rhino"> }
> list_tuple([1,[2,[3]]], X);
{ X = <1,[2,[3]]> }
>

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

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : R1

Error messages : Unbounded expression (Error 59)


Bad argument type (Error 60)

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:

> lower_bound(R,R'),{R = 2X+Y, X>=2, Y>3};


{ R' = 7, R = ... }
> lower_bound(R,R'),{R = 2X+Y, X>=2};
Err 59 : Unbounded expression for extremum calculation
> lower_bound(R,R),{R = 2X+Y, X>=2, Y>3};
>

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

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : R1

Error messages : Unbounded expression (Error 59)


Bad argument type (Error 60)

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:

> upper_bound(R,R'),{R = 2X+Y, X<=2, Y<3};


{ R' = 7, R = ... }
> upper_bound(R,R'),{R = 2X+Y, X<=2};
Err 59 : Unbounded expression for extremum calculation
> upper_bound(R,R),{R = 2X+Y, X<=2, Y<3};
>

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

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : R

Error messages : Unbounded expression (Error 59)


Bad argument type (Error 60)

Description:
Equivalent to (and more efficient than) maximum(R, R):

Calculates the maximum m of R and adds the constraint R = m to the current


constraint system.

Fails when R is bounded above and R cannot reach the maximum.


Causes an error when R cannot be numeric type (Error 60), or when the
numeric expression R is not bounded above (Error 59).

Examples:

> maximize(R),{R = 2X+Y, X<=2, Y<=3};


{ R = 7 , X = 2 , Y = 3 }
> maximize(R);
Err 59 : Unbounded expression for extremum calculation
> maximize(R),{R !numt, R::2};
Err 60 : Bad argument type for extremum calculation
> maximize(R),{R = 2X+Y, X<=2, Y<3};
>

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

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : R1

Error messages : Unbounded expression (Error 59)


Bad argument type (Error 60)

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:

> maximum(R,R'),{R = 2X+Y, X<=2, Y<=3};


{ R' = 7, R = ... }
> maximum(R,R'),{R = 2X+Y, X<=2};
Err 59 : Unbounded expression for extremum calculation
> maximum(R,R'),{R = 2X+Y, X<=2, Y<3};
>

Note:
Errors can be recovered in Prolog III using the block primitive.

See also:
• minimum, lower_bound, upper_bound, maximize, minimize

293 iii © PrologIA


Prolog
Aociation

HERITAGE
Règles prédéfinies et procédures externes

minimize(R)
Function : Minimizes a numeric expression

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : R

Error messages : Unbounded expression (Error 59)


Bad argument type (Error 60)

Description:
Equivalent to (and more efficient than) minimum(R, R)

Calculates the minimum m of R and adds the constraint R = m to the current


constraint system.

Fails when R is bounded below and R cannot reach the minimum.


Causes an error when R cannot be numeric type (Error 60), or when the
numeric expression R is not bounded below (Error 59).

Examples:

> minimize(R),{R = 2X+Y, X>=2, Y>=3};


{ R = 7 , X = 2 , Y = 3 }
> minimize(R);
Err 59 : Unbounded expression for extremum calculation
> minimize(R),{R !numt, R::2};
Err 60 : Bad argument type for extremum calculation
> minimize(R),{R = 2X+Y, X>=2, Y>3};
>

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

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : R1

Error messages : Unbounded expression (Error 59)


Bad argument type (Error 60)

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:

> minimum(R,R'),{R = 2X+Y, X>=2, Y>=3};


{ R' = 7, R = ... }
> maximum(R,R'),{R = 2X+Y, X>=2};
Err 59 : Unbounded expression for extremum calculation
> maximum(R,R'),{R = 2X+Y, X>=2, Y>3};
>

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

mod(N1, N2, N3)


Function : Modulo from integer division

Class : Prolog III external procedure


Category : Numeric constraints
Known parameters : N1 and N2 integers, N2 not zero

Error message : Zero division

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

module(P1, S1, S2, P2)


Function : Declares the start of a module

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : See below

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.

module(P) is equivalent to module(P, [], ["sys"], P)


module(P, S) is equivalent to module(P, S, ["sys"], P)
module(P, S, I) is equivalent to module(P, S, I, P)

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

mult(N1, N2, N3)


Function : Delayed multiplication

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : See below

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : None

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:

> try1 ->;


> try2 ->;
> assign(try3,10);
{}
> list val(try3,X);
try1 -> ;
try2 -> ;
{ X = 10 }
> new;
{}
> list val(try3,X);
{ X = 10 }
>

See also:
• kill_module

298 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

next_char(C)
Function : Reads a character in advance

Class : Prolog III external procedure (II+)


Category : Input/output
Known parameters : None

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:

• in_char, in_char', in_ident, in_integer, inl, in_real, in_sentence, in_string,


in_term, next_char'

© 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

Known parameters : None


Error messages : No

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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : None

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:

• debug, trace, no_trace,


• set_config, set_configuration, get_config, get_configuration

© PrologIA 301
Prolog
Predefined rules and external procedures Aociation

HERITAGE

no_echo
Function : Cancels echo on the console

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : S, and at least one from I and N

Error messages : Non existent prefix

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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : None

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:

• trace, debug, no_debug, suspend_trace, resume_trace


• set_config, set_configuration, get_config, get_configuration

302 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

not(T)
Function : Negation by failure

Class : Prolog III predefined rule (Edinburgh)


Category : Control
Known parameters : See below

Error message : No

Description:
Performs negation by failure. Here is the complete not(T) rule:

not(P) -> P ! fail;


not(P) ->;

And in Edinburgh syntax:

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.

Class : Prolog III predefined rule


Category : Type verification
Known parameters : R

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

numden(R, N1, N2)


Function : Calculates the numerator and denominator of a
rational number.
Class : Prolog III external procedure
Category : Numeric constraints

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

Class : Prolog III predefined rule


Category : Input/Output
Known parameters : None

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:

• outc, outl, outm, outml

306 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

outc(T)
Function : Writes terms with constraints

Class : Prolog III predefined rule


Category : Input/Output
Known parameters : None

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:

• out, outl, outm, outml

© PrologIA 307
Prolog
Predefined rules and external procedures Aociation

HERITAGE

outl(T)
Function : Writes terms with <CR>

Class : Prolog III predefined rule (II+)


Category : Input/Output
Known parameters : None

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:

• out, outc, outm, outml

308 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

outm(S1, S2, …, SN)


Function : Writes strings

Class : Prolog III predefined rule (II+)


Category : Input/Output
Known parameters : S1, S2, …, SN

Error message : Bad argument type

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:

• out, outc, outl, outml

© PrologIA 309
Prolog
Predefined rules and external procedures Aociation

HERITAGE

outml(S1, S2, …, SN)


Function : Writes strings with <CR>

Class : Prolog III predefined rule (II+)


Category : Input/Output
Known parameters : S1, S2, ..., SN

Error message : Bad argument type

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:

• out, outc, outl, outm

310 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

output(F)
Function : Definition of the current output unit

Class : Prolog III predefined rule (II+)


Category : Input/Output
Known parameters : F, which must be a string.

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

Class : Prolog III external procedure (II+)


Category : Input/output
Known parameters : None

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

Class : Prolog III external procedure


Category : Numeric constraints
Known parameters : None

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

> particular_value(X,Y) {X<=9,X>=9};


{ X = 9, Y = 9 }
> particular_value(X, Y),{X<9};
{ X = 9-S$1,
S$1 > 0,
Y = 9 }
> particular_value(X, X),{X<9};
>

Notes

Two cases may arise:


• The value of R1 which satisfies the current constraint system is unique.
R2 then represents this value.
• The set of possible values which satisfy the current constraint system is
infinite. The particular value is then chosen independently of the 
constraint and strict inequality constraints. However a value very
close to the one chosen is certain to exist.

© PrologIA 313
Prolog
Predefined rules and external procedures Aociation

HERITAGE

pgcd(N1, N2, N3)


Function : Calculates the greatest common divissor

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : N1, N2

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

ppcm(N1, N2, N3)


Function : Calculates the lowest common multiple

Class : Prolog III predefined rule


Category : Numeric constraints
Known parameters : N1, N2

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

Class : Prolog III external procedure


Category : Environment
Known parameters : None

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

Class : Prolog III predefined rule (II+)


Category : Environment
Known parameters : None

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

Class : Prolog III predefined rule (II+)


Category : Environment
Known parameters : N

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:

quit is equivalent to quit(0).

See also:

• quit

© PrologIA 319
Prolog
Predefined rules and external procedures Aociation

HERITAGE

rational(R)
Function : Verifies that R is a known rational number.

Class : Prolog III external procedure


Category : Type verification
Known parameters : See below

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.

Class : Prolog III external procedure (II+)


Category : Type verification
Known parameters : See below

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.

Class : Prolog III external procedure


Category : Rule and identifier management
Known parameters : I, N

Error messages : See below

Description:
Modifies the size allocated to an array created by the def_array primitive.

Examples:

> def_array(tab,100) assign(tab(50),3);


{}
> val(tab(50),X);
{ X = 3}
> redef_array(tab,200) assign(tab(154),2);
{}
> val(tab(154),X);
{ X = 2}
> redef_array(tab,40);
{}
> val(tab(50),X);
Error 246: Error in val
>

See also:

• assign, def_array,undef_array, val

322 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

reinsert
Function : Inserts rules from the input unit

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : None

Error message : See below

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);;
{}
>

If a syntax error is found, a warning is displayed and a certain number of


characters are ignored (in principle all characters up to the next " ; " or up to
the end of the line on the console unit). Unlike the insert primitive, reinsert
replaces an existing group with its new definition. Be very careful, this
operation can be dangerous. For example, when using reinsert a mistake on
a rule inside a group may cause the previous rules to be destroyed when
reading of the group continues.

See also:
• insert

© PrologIA 323
Prolog
Predefined rules and external procedures Aociation

HERITAGE

reinsert(F)
Function : Inserts rules from a file

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : F

Error message : See below

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

Class : Prolog III external procedure (II+)


Category : Input/Output
Known parameters : F, L

Error message : String expected, Bad argument type

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.

L ia list in the following form [ <pref1 , subs1> , … , <prefk , subsk> ] which


specifies the renaming of the loaded modules: pref1 will be replaced by subs1,
pref2 by subs2, etc…

Example:

> reload("myfile.mo",[<"data","donnees">]);
{}
>

If an attempt is made to load an element (rule or array) which is already


known, its previous version is replaced by the new one.

Notes:

If the user attempts to load an element (rule or arrays) which is already


known, the previous version will be replaced by the new one.

The modules are saved as object code.

© PrologIA 325
Prolog
Predefined rules and external procedures Aociation

HERITAGE

remove_implicit(S1, S2)
Function : Modifies the context

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : S1, S2

Error message : See below

Description:
Removes the identifier with the abbreviated name S2 from the closed part of
the family corresponding to prefix S1.

Please refer to « Structuring, recording and modifying rules, » in the chapter


entitled « Programming control and environment» for more details.

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

Class : Prolog III predefined rule (II+)


Category : Control
Known parameters : None

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

Class : Prolog III predefined rule (II+)


Category : Environment
Known parameters : None

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

Known parameters : None


Error messages : No

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.

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : See below

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

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : T

Error message : Non-existent rule

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:

T must be type !idt.

© PrologIA 331
Prolog
Predefined rules and external procedures Aociation

HERITAGE

rule(N,T,Q)
Function : Searches for rules

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : T

Error message : Non-existent rule

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:

T must be type !idt.

332 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

rule(N,A,T,Q)
Function : Searches for rules

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : A

Error message : Non-existent rule

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:

A must be type !idt.

© PrologIA 333
Prolog
Predefined rules and external procedures Aociation

HERITAGE

rule_nb(<I, A>, N)
Function : Counts the rules in a group

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : I, A

Error message : Non-existent rule

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

Class : Prolog III predefined rule (II+)


Category : Environment
Known parameters : None

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

Class : Prolog III predefined rule (II+)


Category : Environment
Known parameters : S

Error message : String expected

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

Class : Prolog III predefined rule (II+)


Category : Environment
Known parameters : L,S

Error message : String expected, End of list expected, Non-existent


prefix

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:

> save(["","data","dict"], "myfile.mo");


{}
>

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

Class : Prolog III external procedure


Category : Environment
Known parameters : S, V

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.

• the interpretation mode "machine_mode"


• the display of terms in debug or trace mode "tracemode"
• the echo "echo"
• execution of an undefined predicate "undefined_rule"
• the management of program interrupts "interrupt_is_error"
• the syntax used "syntax"
• maximum line length for display "tty_wrap"
• the numeric format for display "format_out_num"
• the display format for floating numbers "format_float"
• the number of digits after the decimal point "format_decimal"
• the relative error in floating number calculations "epsilon_float"
• execution statistics "statistics"

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

Class : Prolog III external procedure


Category : Environment
Known parameters :U

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

set_context (I, S, S', D)


Function : Describes and activates a context

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : I, S, S', D

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

When Prolog III is started, the current reading/writing context is defined by


the command:

> set_context("", [], ["sys"], "");


{}
>

© PrologIA 343
Prolog
Predefined rules and external procedures Aociation

HERITAGE

set_ident(I, N)
Function : Assigns an attribute to an identifier

Class : Prolog III predefined rule (II+)


Category : Rule and identifier management
Known parameters : I, N

Error messaages : Yes (please refer to the User's Manual)

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

Class : Prolog III predefined rule


Category : Trees, lists, tuples and strings
Known parameters : None

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

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : U

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] }

The intermediate variables created by Prolog III have been renamed.

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

Class : Prolog III (II+) external procedure


Category : Environment
Known parameters : S, and at least one from I and N

Error messages : Non existent prefix

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.

Class : Prolog III external procedure(II+)


Category : Environment
Known parameters : None

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

Class : Prolog III external procedure (II+)


Category : Type verification
Known parameters : See below

Error message : No

Description:
• Executes successfully if S represents an entirely known string. Fails in all
other cases.

Examples:

> string("let's go");


{}
> string(<`C`,`I`,`A`>);
{}
> string("debut".<A,B,C>);
>
string(`X`);
>
string(not_a_string);
>

348 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

string_bool(S, B)
Function : Converts a string into a boolean

Class : Prolog III predefined rule


Category : Type conversion
Known parameters : See below

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.

• If B is known sets the set of constraints {S = B'}, where B' is a string


formed by the characters which constitute the boolean B.

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

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : See below

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.

• If I is known it sets the set of constraints: {S = S'} where S' is a string


constituted by the characters of the of identifier I.

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

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : See below

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

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : See below

Error message : Integer expected

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.

• If N is known it sets the set of constraints {S = N'}, where N' is a string


formed by the characters which compose the integer N.

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

Class : Prolog III predefined rule (II+)


Category : Type conversion
Known parameters : See below

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

substring(S1, N1, N2, S2)


Function : Extracts sub-strings

Class : Prolog III predefined rule (II+)


Category : Trees, lists, tuples and strings
Known parameters : See below

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : I

Error message : None

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : I and A

Error message : None

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

Class : Prolog III external procedure (II+)


Category : Rule and identifier management
Known parameters : I, A, and N

Error messages : None

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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : None

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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : S

Error message : None

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

Class : Prolog III external procedure (II+)


Category : Environment
Known parameters : None

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.

This primitive is equivalent to the call:

set_config("machine_mode", 1)

The no_trace primitive allows you to exit from this mode.

See also:

• no_trace, debug, no_debug, trace_file, suspend_trace, resume_trace


• set_config, set_configuration, get_config, get_configuration,

360 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

trace_file(S)
Function : Redirects the trace

Class : Prolog III external procedure


Category : Environment
Known parameters : S

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

Class : Prolog III external procedure


Category : Numeric constraints
Known parameters : R

Error message : None

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.

Class : Prolog III external procedure


Category : Type verification
Known parameters : U

Error message : None

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

Class : Prolog III external procedure


Category : Rule and identifier management
Known parameters : I

Error messages : See belowd

Description:
De-allocates an array created by the def_array primitive, and recovers the
corresponding space.

Examples:

> def_array(tab,100) assign(tab(50),3);


{}
> val(tab(50),X);
{ X = 3 }
> undef_array(tab);
{}
> val(tab(50),X);
Error 246: Error in val
>
undef_array(X11);
Error 233: Identifier expected (2)
>

See also:

• assign, def_array, redef_array, val

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

Known parameters : See below


Error message : See below

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.

• The value of a number or string is equal to this number or string.


• The value of an indexed array (external or internal) is equal to the value of
the corresponding element in this array.

© PrologIA 365
Prolog
Predefined rules and external procedures Aociation

HERITAGE

Examples:

> def_array(tab,100) assign(tab[50],3);


{}
> val(tab[50],X);
{ X = 3 }
>

• The value of an identifier i is defined as follows:

(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:

> assign(one, 1);


{}
> val(one, x) val(two, y);
{ x=1,y=two }
>

Below we give all the evaluable functions:


add(t1, t2)
value(add(t1, t2)) = value(t1) + value(t2).
The values of t1 and t2 must be numeric.

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

Index of predefined rules and external procedures

abs 368 default 232


add 366 dictionary 233
add_implicit 200 dif 235
arg 201 div 236; 366
arg2 202 dot 237
arg3 203 echo 238; 339
assert 204 edinburgh 239
assert'' 206 edit 240
asserta 205 end_module 241
assertz 206 enum 242
assign 207 epsilon_float 340
atan 368 eq 244
block 210 eql 367
block_exit 210 exit 245
bool 212 exp 368
bound 213 fail 247
bound_conc 214 find_pattern 249
bound_mult 215 findall 248
bound_size 216 format_decimal 340
bound_tree 217 format_float 340
bound_tree' 218 format_out_num 339
char 219 Fdecimal 339
char_code 220 Fexact 339
close_context_dictionary 221 Ffloat 339
close_input 222 Fint+fract 339
close_output 223 Fnormal 339
conc3 224 free 250
conc_string 225 free_label 251
cos 368 freeze 252
cpu_time 226 garbage_collection 253
current_context 227 gcd 254
current_predicate 228 get_config 255
cut 229 get_configuration 256
def_array 230 getenv 257

© PrologIA 369
Prolog
Predefined rules and external procedures Aociation

HERITAGE

ident 258 mul 366


if 367 mult 297
in_char 259 new 298
in_char' 260 next_char 299
in_ident 261 next_char' 300
in_integer 262 no_echo 301
in_real 263 no_trace 302
in_sentence 264 not 303
in_sentence' 265 num 304
in_string 266 numden 305
in_term 267 out 306
inf 367 outc 307
infe 367 outl 308
inl 268 outm 309
input 269 outml 310
input_is 270 output 311
insert 271 output_is 312
integer 273 particular_value 313
is_bool 274 pgcd 314
is_char 275 ppcm 315
is_ident 276 predefined 316
is_leaf 277 prologIII 317
is_num 278 quit 318
is_tuple 279 rad 368
is_univ 280 rational 320
kill_module 281 real 321
known 282 redef_array 322
known_part 283 reinsert 323
lcm 284 reload 325
line 285 remove_implicit 326
list 286 repeat 327
list_string 291 reset_cpu_time 328
list_tuple 292 resume_trace 329
ln 368 retract 330
max_value 293 rule 331
min_value 294 rule_nb 334
mod 295; 367 save 335
module 296

370 © PrologIA
Prolog
Aociation

HERITAGE
Predefined rules and external procedures

set_config 338 tty_wrap 340


echo 339 tuple 363
epsilon_float 340 undef_array 364
format_decimal 340 undefined_rule 341
format_float 340 error 341
format_out_num 339 fail 341
statistics 340 warning 341
syntax 340 val 365
trace 338 abs 368
tty_wrap 340 add 366
undefined_rule 341 atan(t) 368
set_configuration 342 cos 368
set_context 343 div 366
set_ident 344 eql 367
sin 368 exp 368
size 345 if 367
split 346 inf 367
sqrt 368 infe 367
state 347 ln 368
string 348 mod 367
string_bool 349 mul 366
string_ident 350; 351 rad 368
string_integer 352 sin 368
string_real 353 sqrt 368
sub 366 sub 366
substring 354 sup 367
sup 367 supe 367
supe 367 tan 368
suppress 355 trunc 367
suspend_trace 358
syntax 340
Edinburgh 340
Prolog III 340
sys_command 359
tan 368
trace 338; 360
trace_file 361
trunc 362; 367

© PrologIA 371
Prolog
Predefined rules and external procedures Aociation

HERITAGE

372 © PrologIA
Aociation Prolog

HERITAGE

Edinburgh Predefined Rules

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Edinburgh Predefined Rules Aociation

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> .

Rules in the form of terms

Rules are sometimes manipulated as terms, mostly within rule management


primitives. In these cases, it is important to remember that Prolog III rules
have four possible forms,
head (1)
head { constraints } (2)
head :- goal, …, goal (3)
head :- goal, …, goal { constraints } (4)
and that the composite operator «{}» is the main operator in forms (2) and
(4) .

374 © PrologIA
Prolog
Aociation

HERITAGE
Edinburgh Predefined Rules

abolish(I)
abolish(<I, A>)
Function : Deletes a group of rules

Class : Edinburgh primitive


Category : Rule and identifier management
Known parameters : An argument which must be a known identifier or
a tuple <known ident, known arity>
Error message : None

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

Class : Edinburgh primitive


Category : Rule and identifier management
Known parameters : T
Error messages : If T is an incorrect rule

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) ).
{}

typed in the order shown, is to add the following program:

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( outside_of(X, [Y|Q]:- outside_of(X,Q) {X#Y}


).
{}
?- list.
outside_of(X,[Y | Q]) :-
outside_of(X, Q)
{X # Y }.
{}
?-

In a case where the rule passed as an argument contains goals separated by


one or more commas, the rule must be parenthesized to prevent any
ambiguity between the two types of comma (argument commas and rule
body comma).

?- 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

Error messages : If T is an incorrect rule

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:

?- asserta( conc([E|X],Y,[E|Z]):- conc(X,Y,Z) ).


{}
?- asserta(conc([],Y,Y),[]).
{}
?-

typed in the order shown, is to add the program below.

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

Error messages : 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

Error messages : 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

Error messages : None

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

Error messages : None

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

Error messages : Unexpected end of file, Impossible to open file

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).

If a syntax error is detected, a warning is displayed, and a certain number of


characters (in principle all characters up to a ".") are ignored. Insertion then
starts again.

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.

The call consult(S) is equivalent to insert(S), when S is a character string.


Consult("user") is equivalent to insert .

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

Error messages : 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}.

This constrains E to be a leaf, and N to be numeric (neither are necessarily


known at call time).

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

Error messages : End of input file

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

Error messages : End of input file

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

Class : Edinburgh primitive


Category : Evaluation of predefined functions
Known parameters : T
Error messages : Error in val

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

Error messages : Bad argument type, Non-existent rule

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

Error messages : 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

Error messages : This is not an identifier

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.

If L is a list of ASCII codes of the letters of an identifier, X is instantiated with


the identifier determined by the current prefixing conventions.

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:

• string_ident, string_integer, string_real, string_bool, ….

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

Error messages : None

Description:
Writes a carriage return on the current output unit. Behaves like the line
primitive.

See also:

• line, outl, outml

© 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

Error messages : 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:

• free, known, bound, var

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

Error messages : None

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:

• num, integer, real, rational

© PrologIA 393
Prolog
Edinburgh Predefined Rules Aociation

HERITAGE

op(N, I1, S)
op(N, I1, S, I2)
Function : Declares an operator

Class : Edinburgh primitive


Category : Trees, lists and tuples
Known parameters : N,I1,S,I2
Error messages : No

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

f represents the operator.


x represents an expression of precedence less than f
y represents an expression of precedence less than or equal to f

The possible combinations are as follows: f fx fy xf yf xfx yfx xfy . When N


is equal to 0, the effect of op is to delete the declaration existing for the
operator S.

Examples:

?- op(400, xfx, '@@').


{}
?- out(X @@ Y).
'@@'(X,Y){}
?-

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:

?- put(65), put(66), put(67), line.


ABC
{}
?-

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

Error messages : Various syntax errors

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

Error messages : None

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

Error messages : None

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:

• abolish, retract, suppress

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

Error messages : Unexpected end of file, Impossible to open file

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:

• input, close_input, seen

© PrologIA 399
Prolog
Edinburgh Predefined Rules Aociation

HERITAGE

seen
Function : Closes the current input unit
Class : Edinburgh primitive
Category : Input/output
Known parameters : None

Error messages : Impossible to close file

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

Error messages : Bad argument type

Description:
Sends N blanks to the current output unit. When N is not a known integer,
an error message is displayed.

See also:

• line, outm, put, writeq

© 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.

Error messages : None

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:

• output, close_output, told

402 © PrologIA
Prolog
Aociation

HERITAGE
Edinburgh Predefined Rules

told
Function : Closes the current output unit
Class : Edinburgh primitive
Category : Input/output
Known parameters : None

Error messages : Impossible to close file

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

Error messages : 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

Error messages : 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:

• free, bound, known, nonvar

© PrologIA 405
Prolog
Edinburgh Predefined Rules Aociation

HERITAGE

write(T)
Function : Prints terms without delimiters
Class : Edinburgh primitive
Category : Input/output
Known parameters : None

Error messages : 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:

• out, outm, writeq

406 © PrologIA
Prolog
Aociation

HERITAGE
Edinburgh Predefined Rules

writeq(T)
Function : Prints terms
Class : Edinburgh primitive
Category : Input/output
Known parameters : None

Error messages : 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

Error messages : None

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

Class : Edinburgh primitive


Category : Evaluation of predefined functions
Known parameters : X and Y
Error messages : Error in val

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:

X<Y :- val(inf(X,Y), 1).


X =< Y :- val(infe(X,Y), 1).
X>Y :- val(sup(X,Y), 1).
X >= Y :- val(supe(X,Y), 1).

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

Error messages : 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

Error messages : 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

Error messages : 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

Error messages : Error in val

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

Error messages : Error in val

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:

?- exp(1) =\= ln(1) .


{}
?- X =\= 2.
Error in val
?-

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

Error messages : None

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.

Error messages : None

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

Error messages : None

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

Error messages : None

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

Index of predefined rules, external procedures and


built-in predicates for Edinburgh syntax

, 416 put 395


-> 415 read 396
; 417 retract 397
< 409 retractall 398
= 410 see 399
=:= 413 seen 400
=.. 408 tab 401
=< 409 tell 402
== 411 told 403
=\= 414 true 404
> 409 var 405
>= 409 write 406
[] 418 writeq 407
\== 412
abolish 375
assert 376
asserta 378
assertz 376
atom 379
atomic 380
call 381
clause 382
consult 383
functor 384
get 385
get0 386
is 387
listing 388
member 389
name 390
nl 391
nonvar 392
number 393
op 394

© PrologIA 419
Prolog
Edinburgh Predefined Rules Aociation

HERITAGE

420 © PrologIA
Aociation Prolog

HERITAGE

The Prolog III syntaxes

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

What is in this chapter ?

You can program in Prolog III using two different syntaxes, which we call "basic
syntax" and "Edinburgh syntax". This chapter describes them both.

December 1990 © PrologIA


Prolog
Syntaxes Aociation

HERITAGE

1 . Introduction

Choice of syntax mode

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.
{}
>

Common points, differences

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.

• An element is any terminal or non terminal, or any sequence of


elements parenthesized by the signs "[" and "]" or else "{" and "}".

• When a sequence of elements is enclosed by the square brackets "["


and "]" this means that its presence is optional.
• When a sequence of elements is enclosed by the braces "{" and "}" this
means that it can be absent or can be repeated one or more times.

• The bar "|" denotes an alternative in a rule and avoids repetition.

• A comment is a text in italics.

In cases where the formal expression of a syntactic rule would be too


complex (and would thus be incomprehensible), we allow ourselves to
stretch the above rules by writing a simplified rule and a comment
concerning its validity or exceptions.

Set of characters

Here is the set of characters used by Prolog III :

<set of characters>
::= <special character>
::= <letter>
::= <digit>

1 These are characters whose ASCII code is between 0 and 32.

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,

• non-negative integers, non-negative reals ,


• booleans,

© Prolog IA 425
Prolog
Syntaxes Aociation

HERITAGE

• the empty list,


• character constants,
• character strings.

<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 »).

Some examples of correct integers:


1234 1_234_567
815915283247897734345611269596115894272000000000

Some examples of incorrect integers :


_27 variable
12 34 sequence of two integers
98.0 0. reals

Some valid reals :


1.e6 106
.5e6 0,5  106
3.14e-6 3,14  10-6
4. 4
.666 0,666

And some other reals which are not valid:


e10 this is the variable or the identifier e10
.e10 the mantissa must have at least one digit
1.2e exponent value absent
3e10 mantissa dot absent (3e10)

© Prolog IA 427
Prolog
Syntaxes Aociation

HERITAGE

We now introduce the escape character "\". It enables us to represent, within


a string or character type constant, certain characters which are sometimes
not available on the keyboard. It can also be used to mask certain unwanted
characters such as the carriage return which has to be typed to avoid
overflow of the keyboard buffer when a line is too long.

Here we introduce the definition of an escape sequence, which is very close to


the system used in the C language at this level.

<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>

If the "\" character is followed by:

- a carriage return , it is ignored (no character).


- an integer consisting of at most three decimal digits, the denoted
character represents the character whose ASCII code is this integer in
base 8.

- the letter x and an integer consisting of at most two hexadecimal digits,


the denoted character represents the character whose ASCII code is
this integer in base 16.

- one of the keyboard characters, then we have the following


correspondence between the denoted characters and the characters
they represent:

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

If c does not belong to the set of characters n , e , f , l , r , t , b , x the


sequence \ c denotes the character c . In particular \\ represents \ ,
and \" represents the character " , which enables them to be used
within strings. We can now define character constants and character
strings.

<character constant>
::= ` <constant character> ` this is the "grave accent"

<character string>
::= " { <constant character except"> | "" } "

<constant character>
::= <keyboard character except carriage return >
::= <denoted character>

Here are some examples of constant characters:


`a` represents the character a
`\\` represents the character \
`\n` represents the character newline
`\170` represents the character z

Here are some examples of character strings:


"Toto goes to school" (1)
"Toto goes \
to school" (2)
"This string contains\na carriage return" (3)
"The square brackets \"[\" and \"]\" indicate..." (4)

1 This code varies according to the machine, use\n instead of \012 or \r !

© 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...

The following character strings are incorrect


"""
"a"b"

2 . Basic syntax

Variables

The following characters can be used in a variable:

<extended alphanumeric>
::= <letter>
::= <digit>
::= ' quote
::= _ underline
::= $ dollar

In either syntax (basic or Edinburgh), a variable can always be written:

<variable>
::= _ { <extended alphanumeric> }

for example: _x _1 _toto' _F_F_ _'

A special case of a variable name is “_”. Each occurrence of this name


represents a new variable which we do not wish to name. Apart from this
exception, this notation is only used exceptionally, and the following form is
preferred, specific to the basic syntax:

<variable>
::= <letter> { <extended alphanumeric> }

430 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

with the restriction that the second character (if it


exists) must not be a letter.

Here are some examples of syntactically correct variables:


x X z' z''
p2c x78x m68000
x__y' u'2
a_
n_ew_variable' I'can

N.B. : We advise against using the character $; Prolog III uses it to name the
variables that it needs to create internally.

Identifiers

An identifier can be complete or abbreviated. It is complete if it has a prefix:

<prefix>
::= [ <name> { : <name> } ] orbis:lex

<name>
::= <letter> { <extended alphanumeric> }

<identifier>
::= <prefix> : <abbreviated identifier> sys:outm
::= <abbreviated identifier> outm

<abbreviated identifier>
::= <letter> <letter> { <extended alphanumeric> }

It can be noted that syntax of abbreviated identifiers is very similar to that of


variables. The important difference between them is that a variable starts
with at most one letter, whereas an identifier starts with at least two letters.

The form above is specific to the basic syntax. In both syntaxes an


abbreviated identifier can be written as follows:

© Prolog IA 431
Prolog
Syntaxes Aociation

HERITAGE

<abbreviated identifier>
::= ' { <all characters except ' > | '' } '

Here are some examples of correct identifiers:


apple apple'
xx'1 xx'2'
zZ44a_45b__c46'

and others which are incorrect (they are in fact variables):


t_iti I'm_happy B29

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

This syntax will enable us to construct numeric expressions using in


particular the four operators + - * / , boolean expressions using the
boolean operators | & ~ <=> =>, tuples using the tuple constructor < >
and the concatenation operator, and to form trees using parentheses () or
square brackets [] .

Numeric expressions

Prolog III numeric expressions are formed by means of numeric constants,


variables and the four operations +-*/. Here are some examples of correct
numeric expressions:
-x
355/113
-3/2 + (1000-1*2*3*4*5*6*7)y + (1-3/4)*(x+y-2z/5) + 4
-3x/4 - (14-22/7)x
(2x-1)y + (a-b)/(x-y)

and examples of incorrect ones:


5(x+y) is a tree labeled by 5
5/4x is syntactically incorrect
xy is an identifier, not x  y
3*-x should be written 3*(-x)

Boolean expressions

Boolean expressions are formed by means of variables, booleans and the


operators, in decreasing order of priority, not, and, or, equivalent and implies,
written as ~ & | <=> => respectively. The priorities can be modified by
parenthesization. Here are some examples of correct boolean expressions:
x
1'
x|y
~~y
x&~x
c&1'
(u3 & ( ~x1 <=> x3 )) | 0'

434 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

Trees and Terms

On a strictly syntactic level, a term is a pair consisting of a label and a list


(possibly empty) of sons. A tree is a term without variables. A leaf is a term
without sons which is assimilated to its label. Here are some examples of
correct terms:
(ff(x,y))(a,b,c)
(4z+y)(character(`c`, "character `c`"))
<1,2,A,B>.Z
E[<a,b,c>.R] the general tree constructor.
[1,2,3 | L] a “standard” list

- 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.

Here are some examples of syntactically incorrect terms:


toto(x,y)(z,t)
toto()

Constraints

Constraints are always expressed within a set enclosed by braces {} , called a


constraint system. There are four constraint families:
• general constraints concerning equality and difference between terms,
• constraints concerning term types,

• the numeric constraints less than and greater than (or equal),
• the boolean constraint implies .

Here is the syntax for constraint systems:

© 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>
::= > | >=

We can now give the syntax for type constraints:

<tree type>
::= !idt | !boolt | !numt | !chart | !tuple
::= !id | !bool | !num | !char

<type constraint>
::= <term> <tree type>
::= <term> :: <term>

436 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

The following constraint systems are equivalent:


{ t !id } and { t !idt, t::0 }
{ t !bool } and { t !boolt, t::0 }
{ t !num } and { t !numt, t::0 }
{ t !char } and { t !chart, t::0 }

Here are some examples of correct constraints :

{ x!num, f!idt, f::3, l::7n+u*v }


{ a # b(i,j), "toto"=z, a=>b&c, t < 3x/4+5y }

Rules and queries

<rule>
::= head> -> { <goal> } [ , <constraint system> ] ;

<query>
::= { <goal> } [ , <constraint system> ] ;

<goal>
::= / | ! slash or cut; mean the same
::= <term>

<head>
::= <term>

with the followng restrictions :


• the simple verficiation of constraints as they are written in the rule
must constrain the "head" term to:
- have a label which is a known identifier
- have a known number of sons
• a goal (when it is a term) must be of the !idt. type.
• when goals are present they must be separated by space characters.,

© 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.

Here are some examples of syntactically correct rules:


meal(x,y,z) -> hors_d_oeuvre(x) main_course(y)
dessert(z);
add(a,b,<a,b,c>) -> ,{l!tuple, b!num, c=a+b*b};
cats_birds_legs_heads(c, o, 4c+2o, c+o) ->;

and some examples of syntactically correct queries:


meal(salad,meat,d);
meal(h,sole,d) {h#salad};
add(a,b,c) add(c,d,e) ,{a<0', e>0};
circuit(c,a,b) / ,{c|a&~b = 456, d=>c, d#b};

Remember that a rule or query can be syntactically correct without being


valid and accepted by the Prolog III system. The semantic restrictions (by
type for example) greatly reduce the possible constructions authorized by
the syntax.

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.

Likewise space can be removed from anywhere except from inside a


constant and places where its removal would cause two tokens to become a
single token.

438 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

Line continuation.

The \<carriage-return> sequence is completely ignored during reading of


the term and rules. This solves presentation problems (string or number too
long). For example:

rule(123456\
78912) ->;

(where the 7 is really at the start of the line) is the same as:

rule(12345678912) ->;

The different comments

A comment is a sequence of characters parenthesized by the special groups


/* et */ . It can appear anywhere that a space character would have no
effect. Comments can also be parenthesized by means of groups formed by
repetition of /* to open and of */ to close, with the same number of
repetitions in each case. Comments can thus be nested. Here are some
examples:
/* this is a
comment taking up two lines*/

/*/* the text /* comment */ is included */*/

Another type of comment is introduced by the % character type and


terminates at the end of the current line.
text to comment on % comment

3 . Edinburgh syntax

Variables

The following characters can be used in a variable:

© Prolog IA 439
Prolog
Syntaxes Aociation

HERITAGE

<extended alphanumeric>
::= <letter>
::= <digit>
::= ' quote
::= _ underline
::= $ dollar

In either syntax (basic or Edinburgh), a variable can always be written:

<variable>
::= _ { <extended alphanumeric> } _underline

for example: _x _1 _toto' _F_F_ _'

A special case of a variable name is “_”. Each occurrence of this name


represents a new variable which we do not wish to name. Apart from this
exception, this notation is only used exceptionally, and the following form is
preferred, specific to the Edinburgh syntax:

<variable>
::= <upper-case> { <extended alphanumeric> }

Here are some examples of syntactically correct variables:


X W' Z''
P2c New_variable
X__y' U'2
A_ I'can

N.B. : We advise against using the character $; Prolog III uses it to name the
variables that is needs to create internally.

Identifiers

An identifier can be complete or abbreviated. It is complete if it has a prefix:

<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> }

It can be noted that syntax of abbreviated identifiers is very similar to that of


variables. The important difference between them is that a variable starts
with an upper-case letter, whereas an identifier starts with a lower-case
letter.

The form above is specific to the Edinburgh syntax. In both syntaxes, an


abbreviated identifier can also be written between simple quotes:

<abbreviated identifier>
::= ' { <constant character except ' > | '' } '

Here are some examples of correct identifiers:


apple apple a
x'1 xx'2' a_
zZ44a_45b__c46'

and others which are incorrect (they are in fact variables):


Titi I'm_happy B29

+ Identifiers between quotes are not character strings.

Terms

Operators

© Prolog IA 441
Prolog
Syntaxes Aociation

HERITAGE

Operators enable simple expression of trees and expressions. Their syntax is


as follows:

<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 /* .

The length of this sequence depends on the operator declarations that


Prolog III knows when reading. This sequence matches the longest
declaration.

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:

type f xf yf fx fy xfx xfy yfx


op. precedence n n n n n n n n
left op. preced. (l) n-1 n n-1 n-1 n
right op. preced. (r n-1 n n-1 n n-1

1 The predefined predicate op cannot be used to define these compound operators.

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>

<compound term, n>


::= <f. ,n,M> <term, M> <.f,n,M> (x)
::= <f. ,n,M> <term,M> <.fz,n,M,r> <term, r> (2+1)x
::= <term, l> <zf. , n,l,M> <term, M> <.f, n,M> f[x]

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.

We are now going to describe the operators by means of a table in which


each line contains the following:

© Prolog IA 443
Prolog
Syntaxes Aociation

HERITAGE

• the characters constituting the operator (unless we are dealing with a


family of operators, such as integer, in italics)

• an internal name which we will use to specify the object we have


constructed.
• the operator type .
• the operator precedence.
• the precedence provided (if the operator is to be paired with another
operator: in this case they must have the same provided precedence).
• one action from {push, pop, test, not test} which is used to manipulate
and test the current context 1 . In order for the operator to be
applicable, the action must succeed. The parameter for these actions is
a character; below we describe the effect of each one:
- push char establishes a new context char .
- pop char tests that a context is c h a r and
reconstitutes the previous context.
- test char tests that the context is char .
- not test char tests that the context is NOT char .

An action is successful if the test is verified (push always succeeds).

Operator Internal Name Type Prec. (a) Prec. (b) Action

{ CONTR xf. 1300 10001 push '{'


{ CONTR f. 1300 10001 push '{'
} CONTR .f 1300 10001 pop '}'
:- FLECHE xfx 1200
; PVIRG xfy 1100
, VLISTE xfy 1000 test '['
, VFONCT xfy 1010 test 'f'
, VTUPLE xfy 1010 test '<'
, VCONTR xfy 1010 test '{'
, VIRG xfy 1010
! CUT f 700

1 Here, the term context refers to the top of a stack of characters (empty at first).

444 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

Operator Internal Name Type Prec. (a) Prec. (b) Action

= EGAL xfx 650


# DIFF xfx 650
=> IMPLIQUE xfx 650
:: DEUXPTS xfx 650
!tuple TYPTUPLE xf 650
!boolt TYPBOOLT xf 650
!bool TYPBOOL xf 650
!numt TYPNUMT xf 650
!num TYPNUM xf 650
!chart TYPCHART xf 650
!char TYPCHAR xf 650
!idt TYPIDT xf 650
!id TYPID xf 650
!freeze( TYPFREEZE xf. 650 10002 push 'z'
) TYPFREEZE .f 650 10002 pop 'z'
< INF xfx 650
=< INFEG xfx 650
> SUP xfx 650
>= SUPEG xfx 650

<=> EQUIV yfx 600


| BARRE xfx 1002 test '['
| OU yfx 500 not test '['
+ ADD2 yfx 500
- SUB2 yfx 500
& ET yfx 400
* MULT yfx 400
/ DIV yfx 400
+ ADD1 fy 200
- SUB1 fy 200
~ NON fy 200
. CONC yfx 100
< TUPLE f. 50 10003 push '<'
> TUPLE .f 50 10003 pop '<'
[ GENERAL xf. 50 10004 push 'c'
] GENERAL .f 50 10004 pop 'c'
[ LISTE_ED f. 50 10005 push '['
] LISTE_ED .f 50 10005 pop '['
( FONCTION xf. 50 10006 push 'f'
) FONCTION .f 50 10006 pop 'f'
( PARENTH f. 2 10007 push '('
) PARENTH .fx 2 10007 pop '('
) PARENTH .f 2 10007 pop '('
integer NUMVAR fx 2

© 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

+ It should be noted that some operators appear twice,


with different types or precedences on each line .
For example, integer can be a prefixed operator (product
by default of a number and a variable on this occasion).

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

Prolog III numeric expressions are formed by means of numeric constants,


variables and the four operations +-*/. These expressions represent
numbers. Here are some examples of correct numeric expressions:
-X
355/113
-3/2 + (1000-1*2*3*4*5*6*7)Y + (1-3/4)*(X+Y-2Z/5) + 4
-3X/4 - (14-22/7)X
(2X-1)Y + (A-B)/(X-Y)

+ It is imporant to remember that a numeric expression


remains a leaf, and therefore does not form a tree with a
depth greater than zero.

and examples of incorrect ones:

5(X+Y) is a tree labeled by 5


5/4X is syntactically incorrect
XY is of course a variable, not X  Y

Boolean expressions

Boolean expressions are formed by means of variables, booleans and the


operators, in decreasing order of priority, not, and, or, equivalent and implies,
written as ~ & | <=> => respectively. The priorities can be modified by
parenthesization. All boolean expressions represent a boolean (known or
not). Here are some examples of correct boolean expressions:
X 1' X|Y
~~Y X&~X
C&1' => D

448 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

(U3 & ( ~X1 <=> X3 )) | 0'

+ Here again,any boolean expression remains a leaf, and


therefore does not form a tree with depth greater than
zero.

Trees and Terms

On a strictly syntactic level, a term is a pair consisting of a label and a list


(possibly empty) of sons. A tree is a term without variables. A leaf is a term
without sons which is assimilated to its label. Here are some examples of
correct terms:
(ff(X,Y))(A,B,C)
(4Z+Y)(character(`c`, "character `c`"))
<1,2,A,B>.Z
a(B,C) :- b, c {B=1}
{A<B, C = <1,2>}
E[<a,b,c>.R] the general tree constructor.
[1,2,3 | L] a “standard” list

- 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.

Here are some examples of syntactically incorrect terms:


toto(x,y)(z,t)
E[1,2]
(1,2)X
toto()
{C=<1,2>} = must be enclosed by space
characters

© Prolog IA 449
Prolog
Syntaxes Aociation

HERITAGE

Constraints

Constraints are always expressed within a set enclosed by braces {} , called a


constraint system. There are four constraint families:

• general constraints concerning equality and difference between terms,


• the numeric constraints less than and greater than (or equal),
• the boolean constraint implies .
• constraints concerning term types,

Although a constraint system can be expressed as a term, below we give a


more "targeted" description of its syntax.

<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

The following constraint systems are equivalent:

{ t !id } and { t !idt, t::0 }


{ t !bool } and { t !boolt, t::0 }
{ t !num } and { t !numt, t::0 }
{ t !char } and { t !chart, t::0 }

Here are some examples of correct constraints :

{ X!num, F!idt, F::3, L::7N+U*V }


{ A # B(I,J), "toto"=Z, A=>B&C, T < 3X/4+5Y }

Here are some examples of non valid constraints :


{ X<Y<Z } < cannot be nested
{ ff(1,2) } this is not a constraint

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

• t1 = t2 constructs the tree sys:'='(t1, t2)


• t1 # t2 " sys:'#'(t1, t2)

• t1 < t2 " sys:'<'(t1, t2)

• t1 =< t2 constructs the tree sys:'=<'(t1, t2)


• t1 > t2 " sys:'>'(t1, t2)

• t1 >= t2 " sys:'>='(t1, t2)


• t1 !tuple " sys:'!tuple'(t1)

• t1 !boolt " sys:'!boolt'(t1)

• …………… " ……………………


• t1 !freeze(t2) " sys:'!freeze'(t1, t2)

• t1 {t2} " sys:'{}'(t1, t2)


• {t1} " sys:'{}'(t1)

• {t1, t2} " sys:'{}'(sys:','(t1, t2))

• t1 => t2 calculates the term t1 => t2

+ It should be noted that the last line is an exception in the


general construction mechanism. In fact, implies is a
relation in a constraint and is an operation anywhere
else.

452 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

Rules and queries

<rule>
::= <term> <stop>

<query1>
::= [ ?- ] <term> <stop>

<stop>
::= . space

To be more pragmatic, rule and query have the following form:

<rule>
::= <term> [ <constraint system> ] <stop>
::= <term> :- <body> [ <constraint system> ] <stop>

<query>
::= [ ?- ] [ <body> ] [ <constraint system> ] <stop>

<body>
::= <term>
::= <term> , <body>

The following restrictions apply to all rules and queries:


• the simple verficiation of constraints as they are written in the rule
must constrain the "head" term to:
- have a label which is a known identifier
- have a known number of sons
• a goal (when it is a term) must be of the !idt. type.
• the rules are arranged in groups having the same access predicate
name (head identifier) and in sub-groups where predicates have the
same arity.

1 In this implementation,:- cannot be used to start a query .

© 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:

• t1 :- t2 constructs the tree sys:':-'(t1, t2)

• t1 , t2 " sys:','(t1, t2)


• t1 ; t2 " sys:';'(t1, t2)

Here are some examples of syntactically correct rules:


meal(X,Y,Z) :- hors_d_oeuvre(X), main_course(Y),
dessert(Z).
add(a,B,<A,B,B>) {L!tuple, B!num, C=A+B*B}.
cats_birds_legs_heads(C, O, 4C+2*O, c+O).

and some examples of syntactically correct queries:


meal(salad,meat,D).
meal(H,sole,D) {H#salad}.
?- sub(A,B,C), add(C,D,E) {A<0', E>0}.
circuit'(B, A,B), ! {C|A&~B = 456, D=>C, D#B}.

Remember that a rule or query can be syntactically correct without being


valid and accepted by the Prolog III system. The semantic restrictions (by
type for example) greatly reduce the possible constructions authorized by
the syntax.

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

Likewise space can be removed from anywhere except from inside a


constant and places where its removal would cause two tokens to become a
single token (the typical operator problem).

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.

The \<carriage-return> sequence is completely ignored during reading of


the term and rules. This solves presentation problems (string or number too
long). For example:

rule(123456\
78912) ->;

(where the 7 is really at the start of the line) is the same as:

rule(12345678912) ->;

The different comments

A comment is a sequence of characters parenthesized by the special groups


/* et */ . It can appear anywhere that a space character would have no
effect. Comments can also be parenthesized by means of groups formed by
repetition of /* to open and of */ to close, with the same number of
repetitions in each case. Comments can thus be nested. Here are some
examples:
/* this is a
comment taking up two lines*/

/*/* the text /* comment */ is included */*/

Another type of comment is introduced by the % character type and


terminates at the end of the current line.
text to comment on % comment

© 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:

Operator Type Precedence Construction

is xfx 700 sys:is(t1,t2)


== xfx 700 sys:'=='(t1,t2)
=\= xfx 700 sys:'=\='(t1,t2)
=:= xfx 700 sys:'=:='(t1,t2)
\== xfx 700 sys:'\=='(t1,t2)
-> xfx 700 sys:'->'(t1,t2)
=.. xfx 700 sys:'=..'(t1,t2)

Peculiarities

The term '+'(X,Y) causes a syntax error (type conflict), because it is


equivalent to +(X,Y) the unary+ operation applied to the term (X,Y) , and
this term cannot be numeric. If you wish to construct a term labeled by '+'
and having two arguments X and Y, you must write ('+')(X,Y).

The system will not understand the following goal correctly:


?- X is 3*4.

The digit 4 followed by . is understood by the system as a floating number;


the system waits for the rest of the goal (since it has not seen the stop). A
space must be inserted between the 4 and the final point.

This implementation is not ideal for writing terms with operators.


Therefore, functional notation is used for operators which are not those
manipulated by the core of Prolog III.
?- out(X is 3*4).
is(X,12).
{}

456 © PrologIA
Prolog
Aociation

HERITAGE
Syntaxes

4 . General remarks

Differences between the modes

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).

• In Edinburgh syntax, => (implies) has a priority inferior to <=>


(equivalent), whereas they are equal in basic syntax. .
• In basic syntax, rules can be entered directly. In Edinburgh mode,
because the syntax of some rules (facts) ressembles queries, it was
necessary to have a query mode and a rule insertion mode (see the
predicates insert and consult).

Cohabitation of the two syntaxes

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

titi(Var, Var) ->; % Var here seems to be an identifier;


{} % but remains a variable.
> titi(11, Q);
{Q=11}
>

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

1. Introduction and conventions


2. Window management primitives
3. Drawing and coordinate setting
4. Mouse and cursor position
5. Drawing and writing modes
6. Special primitives for keyboard and mouse input/output
7. Menu description primitive
8. Management of dialog boxes
9. Active buttons
10. File manipulation primitives

What is in this chapter ?

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.

December 1990 © PrologIA


Prolog
Graphics primitives Aociation

HERITAGE

1 . Introduction and conventions


This chapter describes a library of primitives that are available to a Prolog III
programmer who wants to create graphics interfaces. We assume that the
reader is accustomed to using multi-window graphics environments and
their tool-boxes.

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”.

Different types of object can be attached to a window: editing fields, choice


boxes, buttons (active or inactive), pop-up menus, texts and drawings, etc.
Dialog boxes (see gr_dialog) use “MODAL” type windows, with the result
that text must be typed in this window.

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.

By default, a window's bitmap image is not saved, meaning that window


refreshment is not provided. Refreshment can be obtained using the
<SAVE> option in the new_window and set_window primitives.

462 © PrologIA
Prolog
Aociation

HERITAGE
Graphics primitives

We will represent the coordinates of a point with abscissa X and ordinate Y


in the form of a pair of numbers <X, Y>. Similarly a rectangle will be
described by means of a quadruple of numbers 1 < X , Y , X ' , Y ' > ,
corresponding to the following diagram:
0 X X'
x
0

Y'

y
A group of rules with name Identifier and arity arity will be represented in
the form of an <Identifier, arity> pair.

Finally, primitives which only have an effect in a graphics window are


prefixed by gr_. These rules directly use the procedures of the host
machine's graphics system.

An  sign in the margin denotes a primitive or characteristic specific to Macintosh.


You should not use it if you wish to transfer your programs onto other machines. .

An X sign in the margin denotes a primitive or characteristic specific to the


XWindows or SunView environment

The descriptions of the various environments are described in a single


chapter, to make clear the discrepancies that still exist between them.

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

2 . Window management primitives

 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

The possible values of t are:


 "EDIT"
creates an editing window, in which the user can write, read, or
execute (i.e. directly manipulate the window independently of
Prolog I/O primitives). These windows function like files. Writing
is always done at the end of the text that already appears in the
window.
"GRAPHICS"
creates a window with the same capabilities as the "graphic"
window. The goal gr_window(s) is used to define it as the current
graphics unit.
 "TTY"
creates a window with the same capabilities as the "console"
window.
"MODAL"
creates a modal graphics window. This window stays above all
other windows, and all events outside the window are de-
activated (except for user interrupt). The external events are re-
activated when the window is killed. Modal windows can be
stacked.

The possible attributes depend on whether the window is a text


("EDIT", "TTY") or graphics ("GRAPHICS", "MODAL") window:
X <"DISTANCE",n>
n is an integer indicating the header space reserved for a button
creation zone, as a percentage in relation to the height of the
drawable part of the window. This attribute is valid for all types
of window.
X <"NLINES",n>
n is an integer indicating the number of lines to save when
scrolling in a "TTY" type window.
<"SHAPE",n>
n is an integer which determines the window format. The
standard shapes are: 0 - window with title and space for scrolling
bars; 1 - frame window. The default attribute for modal windows
is 1, and for text windows it is 0. This attribute is valide for all
types of window. It should be noted that graphics windows do
not have scrolling bars.

© 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.

v is an integer (1 or 0) indicating whether the window is to be visible (1)


or not (0).

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>]);

Restrictions: A maximum of 28 windows can be opened


simultaneously. Remember that in the XWindows or SunView
environments, a menu counts as one window, and an icon counts
double.

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.

Example of how to create a window:

> create_window("wind","GRAPHICS",1,

<0.1,0.1,0.6,0.7>,<0,0,100,100>);

Whatever the size of the screen, a rectangle drawn by gr_rect(1,0,0,100,100)


will fill it, gr_moveto(50,50) will position it at the center, etc.

 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

Erases the contents of the window s.

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

Refreshing the graphics window

Automatic refreshing of graphics windows by an auxiliary bitmap can be


obtained by creating these windows with the <"SAVE",1> attribute (see the
new_window primitive).
Prolog provides a coroutine associated with the graphics windows, which is
automatically activated as soon as these windows require refreshing. The
coroutine is as follows:

:gr_update(u)

where u represents the name of the refreshed window.

© PrologIA 469
Prolog
Graphics primitives Aociation

HERITAGE

The :gr_update rule is not defined in the standard environment. By writing


a <:gr_update,1> rule, the user can thus program the refreshing of the
graphics window u without using an auxilary bitmap.

3 . Drawing and coordinate setting

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.

The coordinates x or y can be expressed as integers, reals or rationals.

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.

1These twoprimitives are not yet available in SunView .

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.

4 . Using the mouse

Rules for handling of windows using the keyboard and mouse

X The following rules only concern XWindows orSunView users who


have a 3-button mouse.

474 © PrologIA
Prolog
Aociation

HERITAGE
Graphics primitives

Move window keep middle button pressed

Enlarge window SHIFT + CONTROL keys and keep middle button


pressed

or left-hand button in bottom right-hand corner of


the window

Menus click right-hand button to display menus


click left-hand button to validate your choice

Bring a window to the front


SHIFT key and click the middle button

Send a window to the back


CONTROL key and click the middle button

Locating the mouse

In this section, variables starting with x represent trees corresponding to


rectangles; i.e. having the form<x1,y1,x2,y2>.

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.

If m = 0 no modification key is pressed during the click.

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).

5 . Drawing and writing modes

 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)

1This key does not exist on the Macintosh Plus keyboard.

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

1Width does not have any effect in SunView .

© 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:

Or (addition) replaces them with black pixels.


Xor (inversion) replaces them with their opposite.
Bic (erasure) replaces them with white pixels.

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");

displays Hello in the graphics window.

© 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");

6 . Special primitives for keyboard and


mouse input/output

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:

wtButton(<5,160,50,175>, "Edit", edit) -> ;

wtButton(<5,180,50,195>, "Set", []) -> ;

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

1 for a mouse click inside the window1 (but outside the


editing field).
2 for a TAB character.
If k is input as a constant, it is output immediately after display
of the zone.
A simpler form of this rule can also be used for an empty initial string:
gr_editf(<>,x1,y1,x2,y2,s,k)

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".

1It's position can be obtained using gr_click (0,x,y).

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

gr_list(r, List, InSel, InTop, OutSel, OutTop, op)


The gr_list primitive manages a choice of elements in a list. This list is
displayed in the current graphics window. Below is a description of the
parameters:
r
The enclosing rectangle (scroll bars included) in the form
<x1,y1,x2,y2>.
List
The list of items. This is a binary list of possibly mixed constants
(string, integer, real, ident., etc).
InSel
This is the initial selection, in the form of a list of integers which
are the ranks (starting from 1) in List of the elements which we
want to select. Insert [] if this is not required.
InTop
This is the rank of the element which must appear at the top of
the display on the left (initial scroll). Put 1 for example.
OutSel
Outputs the list of ranks of the selected items (same convention as
for InSel).
OutTop
Outputs the rank of the first visible item.
op
Describes one of the four possible operations:
<0> Draws only (no recording possible).
<1,k> Draws and takes control until an event such as character
input or a click outside the list occurs. Neither the click nor the
character are read. Returns for k:
0 : carriage return typed
1 : click outside the list
2 : TAB has been typed
3 : a character other than RC or TAB has been typed
<2,x,y,m> Draws the list and processes the click x,y,m (given
for example by gr_click(b,x,y,m) ). Exits immediately afterwards.

484 © PrologIA
Prolog
Aociation

HERITAGE
Graphics primitives

<3,x,y,m,k> Draws, processes the click x ,y ,m (given for


example by gr_click(b,x,y,m) ) and takes control until a keyboard
event or a click outside the rectangle occurs. Neither the click nor
the character are read. Returns for k :
0 : carriage return typed
1 : click outside the list
2 : TAB has been typed
3 : a character other than RC or TAB has been typed.

 sys:gr:gr_list'(r, L, F, Sel, ISel, ITop, OSel, OTop, op)


is the basic primitive. Its 3rd argument is not used at present (it must be
free) and its 4th is the type of item selection. If you wish to modify the
type of selection by default you can replace the gr_list rule of "sys"
(using reinsert, or suppress followed by assert) with this one, in which
you will have replaced the 28 with the type of your choice:

gr_list(r, L, ISel, ITop, OSel, OTop, op) ->


sys:gr:gr_list'(r, L, _, 28, ISel, ITop,
OSel, OTop, op);

Here are some possible types of selection (Inside Macintosh IV-267):


0 shift and command
28 shift or command only (default value)
-128 one item at a time can be selected.

 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

If n2 is present, a menu showing the list of choices l covers up the item


and the field inversion is managed for as long as the mouse button
remains pressed. When the button is released, the selected field is
drawn in the rectangle in place of the previous one, and n2 is unified
with the number of the selected element (n1 if no field is selected).

Example when the graphics window is made visible:

> 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 :

> gr_print("graphic", 0.5, 0.5, 0, 0);

will print the "graphic" window reduced to a quarter of its original size (each
dimension is halved).

7 . Menu description primitive


A menu brings together a sequence of vertically arranged items. An item
can either be terminal or it can itself be a menu (referred to as a hierarchical
menu). A Prolog III goal is associated with each terminal item of a
hierarchical menu, and it is activated immediately the item is selected. This
suspends execution of the current program When the menu bar is used,
each item in this bar behaves like an item of a hierarchical menu.

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

A pop-up menu is activated either by pressing the right-hand button on a


multi-button mouse (inside the relevant window), or by simultaneously
pressing the option key and the mouse button if it is a single-button mouse.

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.

Simplified forms can be used:


either with a two argument tuple :
<"Item Name", Identifier>
( equivalent to: <"Item Name", Identifier, 0> ),
or simply with one identifier: Identifier
( equivalent to: <"Identifier", Identifier, 0> ).

488 © PrologIA
Prolog
Aociation

HERITAGE
Graphics primitives

For example, let us suppose that we have opened an editing window


"menu.p3":

> 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);

Hierarchy type value


A hierarchy is represented by a two argument tuple with the
following structure:
<"Item name", List_of_values>
Each element1 of List_of_values itself represents a leaf or hierarchy
value. A simplified form can be used:
List_of_values
In this case, the item name is indicated at the end of the path. This
is the same as inserting the hierarchy under the indicated item.

1On Sunview, each element in the list of values must be a leaf (a single level).

© PrologIA 489
Prolog
Graphics primitives Aociation

HERITAGE

Example :

> set_menu("graphic", [], [


<"File", [reinsert]>,
<"Do",
[goal1,<"Stop",goal2>]>,
<"Size", [ <"1",size1>,
<"2",size2,1>,
<"3",size3> ]> ] )
insert;
size1(u) -> gr_window(u) gr_text(1,10,[]);
size2(u) -> gr_window(u) gr_text(1,12,[]);
goal1(u) ->
...

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

8 . Dialog box management

Definition of a standard dialog

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

A dialog is described with primitive objects (text zones, edit zones,


buttons, etc) and primitives for formatting in columns or rows. These
primitives adjust the size of the zones dynamically, according to their
contents. Zones whose value can be modified are identified by a name,
so that their value can be redefined when they are called.

Example:

> reload("dial.mo3");
{}
> gr_dialog(["Hello"|buttonD("OK")],[],L);

> gr_dialog(<50,50>,

["Name:", editf(10,field1), buttonD("OK")],

[[field1|"John"]],

L);

The primitives to describe the objects are as follows:

: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).

:buttonD, :buttonD(s), :buttonD(s,i)


Describes a dialog termination button labeled s associated with an
action i defined as for :button(s,i). . Normally s is the string "OK",
and i is []. This button is activated by typing a carriage return.

: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.

This triple corresponds to the internal representation of the


manager's state. Thus the pair
[ Identifier | <InitList, SelectedNbs, TopNumber>]
appears in the list of values transmitted to the actions associated
with the buttons. The value returned by these actions to describe
a new state of the manager also has this form (see examples).

In dialog output, the result is given by a pair: [ Identifier |


ListOfSelectedItems ], where ListOfSelectedItems is formed from
InitList and SelectedNbs.

: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).

The formatting primitives are based on the notion of rectangle


combination, i.e. by placing two rectangles in a column, a new
rectangle is defined which encompasses the other two.

: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.

The following grouping primitive is used to manage the activation or


deactivation of entire zones during dialog input.

:group([ identifier | value ],DescriptionOfItems)


Enables an identificateur to be associated with a set of spatially and
semantically grouped items.
value indicates whether or not the group is active (0 for inactive, 1 for
active). When the group is inactive, it appears gray-colored and the
state of its items cannot be modified. the state of a group can only
be modified in the present version by the actions associated with
buttons. The state of a group is not given in the output list but it is
given in the list of states passed to the buttons, in the form of a pair
as follows:
[ identifier | value]

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

{ L = [[list1, yellow, black]] }


>

>
enable(l1, l3) ->
set_item(l1, zone1, 1, l2)
set_item(l2, zone2, 0, l3);

disable(l1, l3) ->


set_item(l1, zone1, 0, l2)
set_item(l2, zone2, 1, l3);

set_item([], i, b, []) ->


block_exit(816, ["set_item, absent: "|i]);
set_item([[i,_]|l], i, b, [[i,b]|l]) -> ! ;
set_item([e|l], i, b, [e|l']) ->
set_item(l, i, b, l') ;

© 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

A user_item is an elementary object appearing in a dialog box. Users can


define their own items.

502 © PrologIA
Prolog
Aociation

HERITAGE
Graphics primitives

To define a user_item you must give it a name (IdentifyingTerm), a sensitivity


(0, 1 or 2), its initial state value, and associated it with a group of rules with
an arity of 2. The 2 arguments will be the query and the returned value
respectively.
This <RuleIdentifier, 2> group is used to specify the following:
• the size of the enclosing rectangle (size query),
• the drawing corresponding to the object (draw query)
• the action associated with a click (click query)
• the response to character input (edit query)
• the information returned to the dialog manager when this item is
activated by a click or editing (extract query).

The sensitivity of the item is defined as follows:


Sensitivity Query
0 size, draw.
1 size, draw, clic, extract.
2 size, draw, clic, edit, extract.

The state of a user_item is a term structured by users according to their


requirements.

:userItem(IdentifyingTerm, RuleIdentifier, State, Sensitivity).


When the call is made, the first argument of the <RuleIdentifier, 2> rule
contains the query with the relevant parameters extracted from the
item, and the second argument is a free variable which must be
instantiated by the result of the query. If the rule fails, the operation is
ignored.

Below is a description of each query:

: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

Below is an example of creation of an item, which scrolls the various


elements in a list when it is clicked:

>
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), _) ;

max_width([], X, X+4) ->;


max_width([S|L], X, X') ->
gr_stringwidth(S, Y)
max(X, Y, X0)
max_width(L, X0, X');

maxof(X,Y, X) -> ! {X>Y};


maxof(X,Y, Y) -> ;

myItemDraw(<N,L>, r, _active) ->


arg2(N, L, S)
gr_moveto(x+2, y1+14)
gr_rect(:eraseRect, r)
gr_rect(:frameRect, r)
outItem(S, _active)
{r = <x1,y1,x2,y2>};

© PrologIA 505
Prolog
Graphics primitives Aociation

HERITAGE

outItem(S, 1) -> outml(S);


outItem(S, 0) ->;

> 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.

10. File manipulation primitives

 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:

"PNTG" (MacPaint) or "PICT" (MacDraw saved in PICT


format). It is possible to draw selected parts of a file at different
locations, by means of the primitives g r _ s e t o r i g i n and
gr_rect(:clipRect,..).

 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.

 sfputfile(point, prompt, initialName, s)


This rule is a parameterized version of the previous one.
point
is a point in the format <x,y> indicating the location at which the
dialog is displayed.
prompt
is a possibly empty string, containing a message for the user.
initialName
is a possibly empty string via which a file name can be proposed
in the editing field. This name must not include a path.
s
is unified with the path and name validated by the user (the file is
not open).
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

Index of 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

formatting primitives 498 "GRAPHICS" 465


front_window 464 group 495
get_key 483 grouping primitive 499
get_screen 464 gtty 484
get_window 464 hierarchical menu 488
gr_arc 473 horizontal space 499
gr_arc' 474 horizontalcoordinates 470
gr_button_hit 481 input 509
gr_choosecolor 478 keyboard equivalent 492
gr_click 476 kill_button 509
gr_color 477 kill_window 469
gr_color2 477 line of non-editable text 495
gr_color3 477 load_graphic 462
gr_dialog 493 MacDraw 510
gr_draw_buttons 481 MacPaint 510
gr_editf 482 "MODAL" 465
gr_erase 471 mouse 477
gr_font 480 "MPW" 484
gr_getmouse 477 new_window 464
gr_icon 475 "NLINES" 465
gr_line 471 option + closure 469
gr_lineto 470 output 510
gr_list 485 pattern 478
gr_load 510 pen 470; 471; 477; 478
gr_mode 478 pixels 464; 468; 471; 478; 499; 504
gr_move 471 pop-up menu 489
gr_moveto 470 print_window 469
gr_pen 478 radio button 495
gr_penloc 471 refreshing the graphics window 470
gr_polygon 472 refreshment bitmap 466
gr_popupItem 486 reset_window 469
gr_print 488 restore_menubar 492
gr_rect 471 "SAVE" 466; 468
gr_setorigin 471 save_menubar 492
gr_stringwidth 478 save_window 467
gr_text 479 set_menu 489
gr_window 469 set_window 467
gr_window_is 469 sfgetfile 510

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

A. List of Prolog III error messages


B. List of predefined rules with classification
C. Some Prolog III programs written in Edinburgh syntax.

A. List of Prolog III error messages

1: Copy stack overflow


2: Backtracking stack overflow
3: Auxiliary space overflow
4: Auxiliary space overflow
5: Auxiliary space overflow
6: Auxiliary space overflow
7: Auxiliary space overflow
8: Auxiliary space overflow
9: Rule space overflow
10 : Zero divide
11: Auxiliary space overflow
12: Real too large (1)
13: Real too large (2)
14: Undefined real (1)
15: Undefined real (2)
16: Non existent file
17: Unexpected end of file
18: Incorrect rule head
19: Marking stack overflow
20: Auxiliary space overflow (boolean)
21: Integer too long
22: Incorrect built-in predicate
23: Read error
24: Incorrect argument number in built-in predicate

December 1990 © PrologIA


Prolog
Appendices Aociation

HERITAGE

25: Tuple too large (2)


26: String too large
27: Identifier too long (1)
28: Problem assert
29: Incorrect character
30: Bip Rule conflict
31: Non arithmetical operand
32: Tuple too large (2)
33: File close error (1)
34: File open error
35: File close error (2)
36: No more input file
37: Too many files open
38: Too many output files
39: No more output files
40: Error in 'assert' or 'in_term'
41: Error in 'in_term'
41: Error in 'assert' (1)
42: Unknown insertion mode
46: Rule already defined
48: Auxiliary space overflow (simplex)
49: Error during rule space compacting
50: Undefined block
51: Memory saturated (1)
52: Prolog3.log file open error
53: Error in 'assert' (2)
54: Impossible to open file
55: Impossible to close file
56: Memory saturated (2)
100: Overflow during simplification (equations)
101: Overflow during simplification (inequations)
102: Overflow during simplification
103: Overflow during simplification (boolean)
200: Memory saturated (3)
201: End of list expected
202: This is an infinite list
203: String expected
204: Bad argument type
205: Prefix too long
206: Memory saturated (4)
207: Identifier too long (2)
208: Context already closed
209: Unknown identifier
210: Family not closed
211: Non existent rule (1)
212: Non existent rule (1)
213: Identifier expected (1)
214: Memory saturated (context closure)
215: This is not ident syntax
216: This is not prefix syntax
217: This is not an ident
218: Dictionary full
219: Strictly positive real expected

518 © PrologIA
Prolog
Aociation

HERITAGE
Appendices

220: Strictly positive or zero real expected


221: Unknown symbol
222: File open error (save)
223: Input/output error
224: Input/output error
225: Input/output error
226: Memory saturated (5)
227: Memory saturated (6)
228: Bad argument type
229: Undefined type
230: Dictionary full
231: Unknown length
232: Array too large
233: Identifier expected (2)
234: Integer expected
235: Array already defined
236: Undefined array
237: Array overflow
238: No ident with this prefix
239: Load file is not Prolog code
240: Load error
241: Non existent prefix
242: Load error (2)
243: Rule space overflow
244: Function not evaluable
245: Error in 'assign'
246: Error in 'val'
247: Error in 'string_ident'
248: Environment variable 'PrologEdit' undefined
249: Error in 'end_module'
250: Acces already defined (PRO_BIND)
251: Undefined Acces

400: Unknown configuration


422: Memory saturated (7)

500: No space left. PrologIII aborted ...


501: PrologIII booting aborted ...
502: Error file not found !
503: The constraint system of this query is unsolvable.
504: The constraint system of this rule is unsolvable.
505: Illegal character
506: Error while 'insert', 'assert' or 'in_term'
507: Internal error (1)
508: Internal error (2)
509: Not yet implemented (1)
510: Internal error (3)

1001: Exit program


1016: User interrupt
1026: Real too large.

1101: Error in opening file

© PrologIA 519
Prolog
Appendices Aociation

HERITAGE

1105: Eof or error on standard input


1111: Open error on output file
1115: File already open for another operation
1130: I/O unit already exists

1255: Doublet expected for 'gr_polygon'


1262: Arguments of first tuple should be between 0 and 1
1304: System error
1362: 'page' and 'set_cursor' disabled
1363: Warning: file 'termcap' not found
1364: Warning: terminal unknown for 'termcap'
1365: Warning: 'clear_screen' not available for this terminal
1366: Warning: variable 'term' not defined
1367: Warning: 'cursor_motion' not defined
1372: Incorrect graphic coordinates
1386: No window to attach the button
1387: Argument only allowed in a graphic window
1388: Inexistent or bad I/O unit type
1389: Predefined rule not implemented
1390: Screen not initialized for graphic operations
1391: Font not defined
1392: Window type not available
1393: Option not available for opening the window
1394: Too much items for this menu
1395: Level number allowed overflow
1396: This item does not exist
1436: Impossible to open a new I/O unit descriptor
1438: Too many i/o units
1462: Too many points for polygon
1471: 'string_term': string too long

1548: 'lkload' : descriptor is not in the file


1700: Read error in co_process
1701: Write error in co_process

1815: Internal fail in 'gr_dialog'


1816: Fail in a rule called by 'gr_dialog'
1817: Incorrect item in 'gr_dialog'
1818: 'gr_dialog' : internal error

520 © PrologIA
Prolog
Aociation

HERITAGE
Appendices

B. List of predefined rules with


classification

Prolog III predefined rules

Trees, lists, strings and tuples


arg(N, T1, T2)
arg2(N, L, T)
arg3(N, T1, T2)
bound_conc(U1, U2, U3)
bound_size(T, N)
bound_tree(T)
bound_tree'(T)
conc3(U1, U2, U3)
conc_string(S1, S2, S3)
find_pattern(S1, S2, N)
known_part(U1, U2, U3)
size(U, N)
substring(S1, N1, N2, S2)

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

Rule and identifier management


add_implicit(S1, S2)
assert(T, Q)
asserta(T, Q)
assertz(T, Q)
assert''(T,Q)
close_context_dictionary(S)
current_context(T0, T1, T2, T3)
current_context(T0)
current_predicate(<I, A>)
def_array(I, N)
dictionary
dictionary(L)
dictionary(M, L)
end_module
kill_module(S)
list
list(<I, A>)
list(<I, A>, N)
list([<I1,A1>,..., <In,An>])
list(T)
module
new
redef_array(tab, N)
remove_implicit(S1, S2)
retract(T, Q)
rule(N, A, T, Q)
rule(N, T, Q)
rule(T, Q)
rule_nb(<I, A>, N)
set_context (I, S, S', D)
set_ident(I, N)
suppress(I)
suppress(I, A)
suppress(I, A, N)
undef_array(I)

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)

Edinburgh predefined rules

Trees, lists, strings and tuples


'='(X, Y)
'=..'(X, Y)
'=='(X, Y)
'\=='(X, Y)
functor(T, E, N)
member(X, L)
name(X, L)
op(N, I1, S)
op(N, I1, S, I2)

Control
','(X, Y)
'->'(Y)
';'(X; Y)
'[]'(X, Y)
[]
[X|Y]
call(P)
nonvar(T)
true
var(T)

Evaluation of predefined functions


'<'(X, Y)
'=:='(X, Y)
'=<'(X, Y)
'=\='(X, Y)
'>'(X, Y)
'>='(X, Y)
is(X, 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)

Rule and identifier management


abolish(<I, A>)
abolish(I)
assert(T)
asserta(T)
assertz(T)
clause(T, Q)
listing
listing(<I, A>)
listing(I)
retract(X)
retractall(T)

Type verification
atom(T)
atomic(T)
number(R)

526 © PrologIA
Prolog
Aociation

HERITAGE
Appendices

C. Some Prolog III Programs


in “Edinburgh” Syntax

1. A Sample Example: menu.p3e


2. Big Number Calculations: fact.p3e
3. Banking Calculation: bank.p3e
4. Tree Handling: leaves.p3e
5. Logical Calculus: god.p3e
6. A Lewis Caroll Boolean Problem: lewis.p3e
7. Fault detection in an adder: circuit.p3e
8. A Numeric Puzzle: send.p3e
9. A Tiling Problem: rectangle.p3e

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

1. A Sample Example: menu.p3e

The program:

%%% The Famous Balanced Meal .

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

2. Big Numbers Calculations: fact.p3e

The factorial program:

%%% Factorial N! = N*(N-1)*(N-2)*....*2*1

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

3. Banking Calculation: bank.p3e

The program:

/* Banking calculation. interest rate is 10% */

instalmentsCapital(<>, 0).
instalmentsCapital(<I>.X, C) :-
instalmentsCapital(X, C+(10/100)C-I).

Some queries with integer or floating-point numbers

?- instalmentsCapital(<I, 2I, 3I>, 1000).

?- instalmentsCapital(<I, I, I>, 10000).

?- instalmentsCapital(<I, 2I, 3I>, 1000.0).

?- instalmentsCapital(<I, I, I>, 10000.0).

530 © PrologIA
Prolog
Aociation

HERITAGE
Appendices

4. Tree Handling: leaves.p3e

The program:

%%% Build the list of leaves of a tree.

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:

?- leavesOf(measures("Max", <1+75/100, metres>, 1'), X).

?- leavesOf(weighs("Max",<2 P + 1, kg>, male(1'),`o`,'H'),X).

© PrologIA 531
Prolog
Appendices Aociation

HERITAGE

5. Logical Calculus: god.p3e

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

6. A Lewis Caroll Boolean Problem:


lewis.p3e

The program:

%%%% A Problem from Lewis Carrol .

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

subPossibility(X) :- possibility(Y), subSet(X,Y).

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}.

Some possibles queries to discover links (if any) between


properties:

?- subPossibility(<<A,"clear_headed">,
<I,"popular">,
<N,"able to keep a secret">>).

?- subPossibility(<<N,"able to keep a secret">,


<F,"fit to be an M.P.">,
<P,"worth one's weight in gold">>).

?- subPossibility(<<K,"women">,
<F,"fit to be an M.P.">>) {K!bool,F!bool}.

534 © PrologIA
Prolog
Aociation

HERITAGE
Appendices

7. Fault detection in an adder: circuit.p3e

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'}.

%%% rules used only by the second set of queries:


booleans(<>).
booleans(<B>.L) :- boolean(B), booleans(L).

boolean(0').
boolean(1').

First Set of queries:

?- 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

Second set of queries:

?- 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

8. A Numeric Puzzle: send.p3e

The program:

/* An addition must be solved:

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

9. A Tiling Problem: rectangle.p3e

The program:

%%% Filling of a rectangle 1 x A with N different squares.

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}.

placeSquare(B, <H, 0, H'>.L, L') :-


placeSquare(B, <H + H'>.L, L')
{B > H}.
placeSquare(B, <H, V>.L, <-B + V>.L)
{B = H}.
placeSquare(B, <H>.L, <-B , H - B>.L)
{B < H}.

A query (How to fill an unknown rectangle with 9 unknown different


squares ?):

?- 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

Guarantee and liabilities


PrologIA offers no guarantee, tacit or explicit concerning either this manual or
the software herein described, its qualitiy, performance or its suitability for any
application whatsoever.
PrologIA cannot be held liable for damage of any sort, whether direct or indirect
resulting from a fault in the manual or program, even if the company has been
advized that such damage might occur. In particular, PrologIA cannot take
responsibility for data stored or used; this includes costs of recovery or
duplication of such data.
Nevertheless the purchaser is entitled to the statutory guarantee in such cases
and to the extent to which the statutory guarantee is applicable not
withstanding any exclusions or limitations.

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

Using Prolog III


on PC (MS-DOS)

1. Installing Prolog III


2. Using Prolog III
3. Particular characteristics of Prolog III PC
4. The environment
5. Adding predefined rules
6 Calling Prolog III from the C language

What is in this chapter ?

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.

March 1991 © PrologIA


Prolog
Using Prolog III on PC (MS-DOS) Aociation

HERITAGE

1 . Installing Prolog III

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 MS-DOS prompt will be represented by the string C>

Necessary equipment and software

To start Prolog III

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.

To add external programs

Either of the following two environments can be used to add external


programs:

1. To add external programs running in real mode:


Microsoft C compiler version 5.1 or later.
2. To add external programs running in protected mode:
• Metaware High C compiler version 1.4 or later.
• Phar Lap Software DOS-Extender development version 2.0 or later.
This package contains: 386|ASM/LINK (80386 protected mode linker
with extended addressing), and RUN386 (Protected mode loader and
manager).

1002 © PrologIA
Prolog
Aociation

HERITAGE
Using Prolog III on PC (MS-DOS)

The real mode environment enables Prolog to be extended using the


association method (by means of the Prolog primitive set_ident) and the C
data communication procedures (get_integer, GetArg,..). It finally enables
link editing with any library of programs available in DOS. However this
environment does not allow a Prolog goal to be started from a C program,
or the creation of shared zones1, or the use of descriptors1. Available space
is restricted to 640K of the DOS, minus approximately 280K for the DOS-
Extender and Prolog's real mode environment.

A HIGH C + DOS-Extender environment is the only configuration which


enables large programs and data zones to be used, as well as extensions by
means of the following: external linking by descriptors, creation of data
tables shared by C and Prolog and launching of Prolog goals from C.
However this environment is expensive and does not enable link editing
with existing libraries written in real mode.

Contents of installation kit

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.

1 Not yet documented

© 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.

If required, complete the environment variable PATH containing the access


paths of the various executables, so that Prolog III can be accessed from any
location. This is done in your autoexec.bat file, using the SET command. If
this variable is not updated, you will have to launch Prolog III with its
complete path.

Now position the environment variables PrologDir3 and PrologEdit


–respectively defining Prolog III's installation directory and access path to a
DOS editor – for example with edlin, m. These variables are positioned by
means of the SET command and can be declared in your autoexec.bat file. We
should point out that there is no need to define PrologDir3 if your work
directory contains Prolog III. Similarly, the PrologEdit variable is not
required if you do not use the editing predicate edit .
Here are some examples of definitions:

C> SET PrologDir3=C:\PIII\

© PrologIA 1005
Prolog
Using Prolog III on PC (MS-DOS) Aociation

HERITAGE

C> SET PrologEdit=C:\SOFT\EDLIN


Take special note of the \ character placed at the end of the PrologDir3 directory
name.
Remember that the machine must be re-started in order to take into account the
modifications in the autoexec.bat file.

2 . Using Prolog III

Activating Prolog III

To start a session, execute the following command:

C> prolog3

To end a session, execute the quit; query (while in Prolog III).

Parameterization of the Prolog III interpreter

If you want to redirect input/output when Prolog III is activated (this


assumes non-interactive use of Prolog III), or set execution parameters
which will rarely be modified, simply create a prolog3.prf file in the directory
containing the Prolog III application. This file must contain a line of text
which in fact has the syntax and meaning of a command which would
activate Prolog III in an MSDOS (or UNIX) environment.

Only the first line of the prolog3.prf file is taken into account. Here is a
relatively complex example:

Prolog3 c30000 u200 b2000 r100000 Ooutput.log


Iinput.log q

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.

O file specifies an output file which will replace the screen.

csize specifies the size of the copy stack (space for structure
construction) in 4-byte words. Minimum recommended
value: 10,000.

bsize specifies the size of the restoration (or backtracking) stack in


4-byte words. Minimum recommended value: 5,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.

usize specifies the size of the auxiliary algebra space in 4-byte


words. Minimum recommended value: 200.

msize specifies the size of the garbage collection stack in 4-byte


words. Minimum recommended value: 1,000

© 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.

-i size specifies the the size of the internal dictionary, in bytes


(linked to the number of groups of rules). Minimum
recommended value: 35,000

-e size specifies the size of the external dictionary, in bytes


(containing the names of all the identifiers). Minimum
recommended value: 32,000

q this option cancels the display of warnings and all other


messages apart from error messages.

Program interruption

On PC, a program is interrupted by simultaneously pressing the Control and


C keys.

Following this interruption, Prolog III poses the following question:

User Interrupt. C(ontinue, K(ill, T(race, Q(uit ?

You can then type one of the following characters:


C to continue as if the interruption had not occurred

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).

Q to leave the Prolog III session and return to the DOS.

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.

It should be noted that it is not possible to interrupt garbage collection or the


reading of a goal or rule at the console.

1008 © PrologIA
Prolog
Aociation

HERITAGE
Using Prolog III on PC (MS-DOS)

3 . Particular characteristics of Prolog III


on PC

Boundary values of arithmetical constants

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 !).

2. Floating numbers are implemented with the double type, encoded on 64


bits, with precision of 15 to 16 digits and an exponent between -307 and +308
.

Default spaces and sizes

• Main space 300,000 (option c )


• Backtracking stack 100,000 (option b )

• Secondary space 10,000 (option u )


• Code space 100,000 (option r )

• Garbage collection stack 10,000 (option m )


• Internal dictionary 36,000 (option -i)
• External dictionary 32,760 (option -e)

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

4 . The Prolog III environment on PC

Using a host editor

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.

Modifying 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.

5 . Adding predefined rules

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 .

In the description that follows, any operation performed in the UserRule.c


file can also be carried out in the rmUser.c file, unless we give instructions to
the contrary. To simplify the explanations, we will only describe the method
to be used for the UserRule.c file.

© 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.

• in the C universe, associate the link-number with the call of the


function which constitutes the actual implementation of the new rule.
This is done by adding a case to the switching array contained in the
UserRule.c module, and recompiling this module.

• define the external implementation of the rule in C (or Fortran or any


other compatible external language) and compile it.

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:

If you are working in real mode (rmUser.c file), the executable to


reconstruct is rmProlog.exe.
If you are working in protected mode (UserRule.c file), the executable to
reconstruct is prolog3.exe.

1012 © PrologIA
Prolog
Aociation

HERITAGE
Using Prolog III on PC (MS-DOS)

Calling an external rule

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:

long UserRule(Ptr_to_BIP, Ident_num_of_BIP)


char *Ptr_to_BIP;
long int Ident_num_of_BIP;

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.

Ident_num_of_BIP is an integer representing the relevant external


rule.

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.

The essential part of the UserRule function consists of a switching instruction


(switch) applying to the value Ident_num_of_BIP To add a new external rule
to Prolog III, you simply add a "case" to this switch, which corresponds to
the number chosen to represent the rule. In general, for a new external rule
you should add the following C instructions:

• first a certain number of calls to the GetArg function, to obtain pointers


to the arguments of the call to the external rule

© PrologIA 1013
Prolog
Using Prolog III on PC (MS-DOS) Aociation

HERITAGE

• in correspondence with the above, a certain number of calls to the


" Convert_PWotsit_to_CThing " conversion functions, so that the
argument values are coded according to C conventions
• next, a call to a C function written by you which constitutes the actual
implementation of the external rule
• on return from this function, a certain number of calls to
"Convert_CThing_to_PWotsit" conversion functions so that the results
are coded according to Prolog III internal conventions.
• finally, calls to the PutArg function to give these results as values to
certain arguments of the calling rule.
• Don't forget to specify the value (true or false) which must be returned
by the UserRule function as a report (success or failure) on the
execution of the external rule.

In the next few paragraphs we give several examples of how to implement


external rules.

Data transfer procedures

Only integers, reals and character strings can at present be exchanged


between a Prolog III program and external routines written in C or another
language. Two separate sets of data transfer procedures are provided,
corresponding to two slightly different ways of organizing the task.
• The first system is formed by the following C procedures:
GetArity
GetArg
PutArg
Convert_StringC_to_StringP
Convert_LongIntC_to_IntP
Convert_DoubleC_to_NumP
Convert_StringP_to_StringC
Convert_NumP_to_DoubleC
Convert_IntP_to_LongIntC

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

First data transfer protocol.

The first system consists of a set of general functions and conversion


functions. Two steps are therefore necessary.
To recover a data element from a Prolog structure, the corresponding
argument must be recovered (using the GetArg() function) and then
converted.
To add a data element to a Prolog structure, it must be converted into a
Prolog term and the corresponding argument must be instantiated (using
the PutArg() function).

General functions:

long int GetArity(term)


adr term;

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

term denotes the address1 of a term with an arity (GetArity) or son


(GetArg, PutArg) that interests us. In general, term will point to
the call to the external rule, obtained by means of the
Ptr_to_BIP argument of the call to UserRule. It should be noted
however that this is not mandatory, and that GetArity, GetArg
and even PutArg can be used to manipulate terms other than
that of the call to the external rule.
no_arg is an integer which when greater than or equal to 1
represents the rank of the previous term's son which interests
us, whether this is in order to obtain its value (GetArg) or
define it (PutArg).

value is the address of the internal representation of a Prolog III


term, generally originating from a call to one of the conversion
functions: Convert_StringC_to_StringP, C o n v e r t _ L o n g -
IntC_to_IntP, Convert_DoubleC_to_NumP.

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.

PutArg(no_arg, term, value)


Unifies the term pointed by value with the son of rank no_arg of the term
pointed by term. An error occurs if this son does not exist, or if this
unification is impossible.
In addition, PutArg(0,term,value) unifies the term pointed by value with 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

Opposite transformation to the above: t must be the address of a Prolog III


numeric (integer) term. This function puts the value of this number in the
integer variable pointed by i. An error occurs if the transformation cannot
be performed. The function returns 0 (FALSE) if there is an error, a non
zero value (TRUE) otherwise.

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.

Second data transfer protocol.

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.

Transfer of simple data from Prolog to C.

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)

Here are the functions available for simple data types:

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.

Transfer of simple data from C to Prolog .

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;

no_arg is an integer specifying the rank of the argument in the call to


the external rule. If the actual value of no_arg does not
correspond to an actual argument in the external rule, an error
occurs.

value is the value which must be unified on the argument of rank


no_arg in the interface rule.

1020 © PrologIA
Prolog
Aociation

HERITAGE
Using Prolog III on PC (MS-DOS)

For character string parameters, value is the address of a


character string ending in zero, defined by the external
program. put_string copies this character string into Prolog's
work memory before unifying the value with the argument of
the external rule.

err is a variable set at 1 if an error has occurred or if 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 immediately leave the
external program if err is not zero.

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

Here is a complete example describing the set of operations to perform to


create a new predefined rule implemented by an external program.

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):

1. Add the following function at the end of the UserRule.c file:


real_roots(a, b, c, x, y)
double a, b, c, *x, *y;
{
double d, sqrt();

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):

long int UserRule(Ptr_to_BIP, Ident_num_of_BIP)


adr Ptr_to_BIP;
long int Ident_num_of_BIP;
{
...
switch (Ident_num_of_BIP)
{
...
case 504 : /* 20004 if using real mode */
{
adr t;
double a, b, c, x, y;

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)

&& real_roots(a, b, c, &x, &y)

&& (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

For protected mde, (UserRule.c file), the executable to reconstruct is


prolog3.exe. This is done using the prolink3 command. The prolog3.exe
file should be copied into the directory containing the essential files.
C> prolink3

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

PROLOG III, v1.2 December 1990 (C) PrologIA 1989-90

> set_ident(sys:roots, 504 ) ; % 20004 if using


real mode
{}
> add_implicit("sys","roots");
{}
>

5. Try out the new rule:

> 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)

6 . Calling Prolog III from the C language

Introduction

This functionality is only available in protected mode.

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.

Description of the functions

Initialization

int Pro3Session(argc, argv, autoprolog, userprog)


int argc, autoprolog;
char *argv[];
int (*userprog)();
argc, argv have the same semantics as the main() function arguments
in any C program. They are used to pass options to Prolog III.
If this facility is not required, 0 can be passed for argc, and
NULL for argv. Remember that when a file called prolog3.prf
exists in the current directory (or in the directory contained in
the environment variable PrologDir3 if it is defined), its first line
is interpreted as a Unix command line, and the options on it are
read. In this case, the arguments argc and argv are ignored.

© PrologIA 1025
Prolog
Using Prolog III on PC (MS-DOS) Aociation

HERITAGE

autoprolog informs Prolog III that it is the main program, or that it is


only called from time to time. The possible values are:

PROMAIN if Prolog III is the main program


PROCALL if Prolog III is used as an external module
userprog is the name of a function provided by the programmer,
containing calls to Prolog III by means of the P r o 3 G o a l
primitive.

Pro3Session(argc, argv, autoprolog, userprog)


This function allocates and then initializes Prolog III. This initialization
includes Prolog III start-up. A fairly long delay may therefore occur before
it starts the user function userprog (depending on the size of the state to be
loaded). Once this userprog function has terminated, Prolog III frees the
memory space which it had allocated itself, and the Pro3Session call
terminates.
An error flag is returned; ERR3_NOERR for no error when Prolog III has
been able to allocate, load, initialize its space, start-up, etc.

All the constants PROMAIN, PROCALL, ERR3_NOERR are defined in the


header file macuser.h which must therefore be included.

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.

This function also returns an error flag. When there is no error,


ERR3_NOERR is returned. Otherwise it returns:

1026 © PrologIA
Prolog
Aociation

HERITAGE
Using Prolog III on PC (MS-DOS)

• a positive number corresponding to an error during execution of


Prolog III.

• ERR3_NOINI If Prolog III is not initialized.


• ERR3_ERRANA If there is syntax error in the command.

For example, the call:

err = Pro3Goal("enum(x), {0<x<4};");

produces the following display at execution:

{x = 1}
{x = 2}
{x = 3}

and the err variable will have the value ERR3_NOERR.

A small example

Here is a small example to illustrate and summarize the above. In this


example, Prolog III is assumed to be used "intensively" in two parts of the
program, and we wish to recover the Prolog III space between the two. We
will suppose that this source, containing the main() function, is called myprog.c
:
/* file myprog.c */
#include "macuser.h"

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:

C> hc386 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 :

We edit the links to produce myProg.exe by means of the script contained in


the command file prolink3.bat:

C> prolink3

Let's start myProg and see the results displayed in the console:

PROLOG III, v1.2 December 1990 (C) PrologIA 1989-90

1/2{c = 1/2}
1/4
{c = 1/4}

PROLOG III, v1.2 December 1990 (C) PrologIA 1989-90

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

rmUser.c file (for use in real mode):

#include "rmacuser.h"

long int UserRule(Ptr_to_BIP, Ident_num_of_BIP)


adr Ptr_to_BIP;
long int Ident_num_of_BIP;
{
switch (Ident_num_of_BIP) /* Use numbers */
{ /* greater than 20000 */

/* insert your own rules here */

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

UserRule.c file (for use in protected mode):


#include "macuser.h"

long int UserRule(Ptr_to_BIP, Ident_num_of_BIP)


adr Ptr_to_BIP;
long int Ident_num_of_BIP;
{

switch (Ident_num_of_BIP) /* Use numbers */


{ /* greater than 500 */

/* insert your own rules here */

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)

D1. Operation in protected mode

Prolog III MS-DOS/386 is an advanced version using 32 bit instructions and


the protected mode of the INTEL 80386 processor. This enables Prolog III
programs to use the whole of the available physical memory in a linear way
(16 Mb on present machines, 4 Gb maximum). Attached to the interpreter is
a protected mode loader/manager, enabling Prolog III to be used as an
ordinary MS-DOS task. This task contains a loader that initializes the
protected mode and loads the Prolog code into the available physical
memory. This memory may partly overlap the 640K DOS program zone, or
may leave it free so that DOS tasks can be activated from Prolog.

When it is started, Prolog activates in parallel a DOS task (rmProlog.exe)


operating in real mode, which can communicate with the Prolog programs.
The user can modify and extend this task using the customary DOS tools.

Below we have set out several different types of memory configuration.


The default configuration is described in the first diagram. The configuration
can be modified using the CFIG386 in the distribution kit (in the directory
386PMODE).

1. Reservation of space for DOS tasks (editor, etc.).

Zone executed in real mod e Zone executed in protecte d mode

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

2. Use of all the available space for Prolog.

Zone executed
in real mode Zone executed in protecte d mode

Prolog loader Prolog III


rmUserRule (real mode)

1 Mb

UserRule(protected mode)

3. Use with programs complying with the VDISK standard, BIOS


extended memory, or VCPI interface1:

Zone executed Zone executed in


in real mode VDISK zone protected mode

Prolog loader rmUserRule (real mode) Prolog III

1 Mb

TSR
program

UserRule protected mode

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)

D 2 . Modification of the memory


implementation with CFIG386

The CFIG386 utility is used to modify Prolog's memory implementation.


Since Prolog uses the paged mode, the memory used for protected mode is
not necessarily contiguous. The parameters below are used to delimit the
memory zones allocated to protected mode Prolog. Using the default
parameters, protected mode Prolog is implemented entirely above 1 Mb.

Syntax:

$ CFIG386 prolog3.exe [parameters]

If there are no parameters, the modifications of the default values are


displayed. The possible parameters are:

-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

! (cut) 162 :invert 472; 473


!bool 52; 118 :invertOval 472
!boolt 51; 118 :invertRect 472
!char 52 :invertRoundRect 472
!chart 51 :paint 471; 472; 473
!id 52 :paintOval 472
!idt 51 :paintRect 471
!num 52; 98 :paintRoundRect 472
!numt 51; 98 :rb 495
!tuple 51 :rb1 495
, 416 :row 499
-> 415 :text 495
/ (cut) 162 :userItem 498
386PMODE 1005 :vfill 499
:button 496 < 409
:button2 496 <> (empty tuple) 26
:buttonD 496 = 410
:cb 495 =.. 408
:ccol 498 =:= 413
:clipRect 472 =< 409
:col 498 == 411
:crow 499 =\= 414
:editf 496 > 409
:erase 471; 473 >= 409
:eraseOval 472 [ ] (empty list) 32
:eraseRect 471 [] 418
:eraseRoundRect 472 [] (functional symbol) 81
:frame 471; 472; 473 \== 412
:frameOval 472
:frameRect 471 A
:frameRoundRect 472
:glist 497 abbreviated identifier (syntax) 431
:group 499 abbreviated identifier(syntax) 441
:hfill 499 abolish 375

© PrologIA 1037
Prolog
General Index Aociation

HERITAGE

abortion of goal execution (block exit) 164


abs 170; 368 C
activate_button 509
add 168; 366 C external functions 1012
add_implicit 180; 200 C(ontinue 1009
add_stdmenu 493 call 381
adding a rule (assert) 184 cancellation
addition 30; 96 messages 1009
and 28; 117 carriage return 485; 496; 505
"apple" (menu) 493 carriage return key 482
arg 79; 201 char 219
arg2 82; 202 char_code 220
arg3 78; 203 character (syntax) 429
arithmetic 14 character string (syntax) 429
arrays (def_array) 172 character strings 13; 26; 69; 83
assert 184; 204; 376 characters 24
assert'' 185; 206 check box 495
asserta 184; 205; 378 check_item 491
assertz 185; 206; 376 clausal form 122
assign 171; 172; 207 clause 382
assignment 45 clear_menubar 492
assignment (assign) 171 clear_window 469
atan 170; 368 click 476; 482; 485; 486; 498; 504
atom 379 close_context_dictionary 180; 221
atomic 380 close_input 193; 222
close_output 11; 195; 223
B closed part of a family 176
command_menu 492
block 164; 210 comment 440; 457
block_exit 164; 210 conc3 78; 151; 224
bool 126; 212 conc_string 83; 225
boolean 116 concatenation 12; 74
boolean (syntax) 426 delayed 151
boolean assignment 123 configuration of Prolog III 1007
boolean values 25 console 6; 462
booleans 16 constants 23; 95
bound 146; 165; 213 boolean 117
bound_conc 78; 214 constraint (syntax) 436
bound_mult 103; 154; 215 constraint system (syntax) 436; 451
bound_size 78; 149; 216 constraint systems 53
bound_tree 217 constraints 52; 74
bound_tree' 218 boolean 16; 118
button 481; 496 examples 120
normal form 121
simplification 124

1038 © PrologIA
Prolog
Aociation

HERITAGE
General Index

delayed 149 dif 235


numeric 99 "DISTANCE" 465
delayed 154 div 104; 169; 236; 366
examples 99 division 30; 96
normal form 100 dot 237
constructor
general of trees 70 E
of trees 70
of tuples 70 echo 195; 238; 339
consult 383 edinburg.mo 1005
context definition (set_context) 178 edinburgh 239
control 160 edit 240; 1011
Control C 1009 "EDIT" 465
"control" (menu) 493 "edit" (menu) 493
Convert_DoubleC_to_NumP 1016; 1019 editable line of text 496
Convert_IntP_to_LongIntC 1016; 1019 empty list 82
Convert_LongIntC_to_IntP 1016; 1018 empty list (syntax) 426
Convert_NumP_to_DoubleC 1016; 1019 enable_menu 492
Convert_StringC_to_StringP 1016; 1018 end a session 1007
Convert_StringP_to_StringC 1016; 1018 end of session (quit) 11
cos 170; 368 end_module 182; 241
cpu_time 196; 226 enum 242
create_button 509 enum(N) 102
create_window 468 epsilon_float 340
current context 177 eq 244
current graphics window 470 eql 169; 367
current_context 180; 227 equality 48; 99
current_predicate 185; 228 characters 49
cut 162; 229 floating numbers 50
identifiers 49
D rational numbers 50
equivalence on a sub-vocabulary 125
data transfer protocol 1016; 1019 equivalent 29; 117
deactivate_button 509 evaluable functions 168
def_array 172; 230 example programs
default 165; 232 an or on 2 variables 127
delays an or on a list 128
concatenation 151 at most one true 129
freeze 147 banking calculation 106
non-linear constraints 104 binary adder 133
numeric constraints 154 CatsBirds 14
sizes 149 element_of 13
deleting rules (suppress) 10; 188 Eratosthene's sieve 88
description primitives 495 filling a rectangle 108
dictionary 181; 233 K true elements 131

© PrologIA 1039
Prolog
General Index Aociation

HERITAGE

leaf calculation 85 fail 247


LightMeal 9 family 175
logic puzzle 141 closed part 176
naive reverse 80 Fdecimal 106
periodic sequence 87 Fexact 106
Prolog III/C communications 1023 Ffloat 106
quick sort 86 "file" (menu) 493
SEND + MORE = MONEY 107 file selection dialog 509
examples file-name input dialog 510
boolean constraints 120 file_window 464
boolean expressions 42; 118 find_pattern 83; 249
characters 39 findall 248
constraints 54 "find" (menu) 493
constraints on strings 83 Fint+fract 106
constraints on trees 72 floating numbers 1010
constraints on tuples 76 Fnormal 106
constructors 71 font 466; 469; 478; 479; 480
floating numbers 38 "FONT" 468;466
freeze 147 font size 469; 478; 479; 480
identifiers 37 "FONTSIZE" 466;468
integers 38 format_decimal 340
lists 82 format_float 340
modules 183 format_out_num 105; 339
numeric constraints 99 Fdecimal 339
numeric expressions 40; 97 Fexact 339
queries 59 Ffloat 339
rules 59 Fint+fract 339
strings 39 Fnormal 339
terms 37; 43 formatting primitives 498
trees 69 free 147; 166; 250
use of the cut(/) 162 free_label 251
EXEMPLES 1005 freeze 154; 252
exit 195; 245 front_window 464
exp 170; 368 functor 384
expressions
boolean 42; 117 G
numeric 40; 95
maximum 103 garbage_collection 253
minimum 103 gcd 254
val predicate 166 get 385
external calls to Prolog III 1026 get0 386
get_config 255
F get_configuration 256
get_integer 1016; 1020; 1021
factual trees 69 get_key 483

1040 © PrologIA
Prolog
Aociation

HERITAGE
General Index

get_real 1016; 1020; 1021 gtty 484


get_screen 464
get_string 1016; 1020; 1021 H
get_window 464
GetArg 1016; 1017 hierarchical menu 488
GetArity 1016; 1017 horizontal space 499
getenv 257 horizontalcoordinates 470
goal(syntax) 438 host editor 1011
goals 58
"GRAPHICS" 465
gr_arc 473
I
gr_arc' 474
ident 258
gr_button_hit 481
identifier (syntax) 431; 441
gr_choosecolor 478
Identifiers 23
gr_click 476
abbreviated 175
gr_color 477
syntax 175
gr_color2 477
complete 175
gr_color3 477
separator 175
gr_dialog 493
syntax 175
gr_draw_buttons 481
if 170; 367
gr_editf 482
if_then_else 164
gr_erase 471
implies 29; 117
gr_font 480
implies (relation) 50; 118
gr_getmouse 477
in_char 191; 259
gr_icon 475
in_char' 260
gr_line 471
in_ident 261
gr_lineto 470
in_integer 262
gr_list 485
in_real 263
gr_load 510
in_sentence 192; 264
gr_mode 478
in_sentence' 265
gr_move 471
in_string 266
gr_moveto 470
in_term 191; 267
gr_pen 478
inequality 99
gr_penloc 471
inequality (relations)
gr_polygon 472
equality 48
gr_popupItem 486
inf 169; 367
gr_print 488
infe 169; 367
gr_rect 471
infinite trees 73
gr_setorigin 471
initial3.psv 1004
gr_stringwidth 478
inl 268
gr_text 479
input 8; 192; 269; 509
gr_window 469
input file 1008
gr_window_is 469
input-output 190
greater than or equal to 99
input-output formats 105
group 495
input.log 1007
grouping primitive 499

© PrologIA 1041
Prolog
General Index Aociation

HERITAGE

input/output units 190 loading a program(input) 8


input_is 270 looping 160
insert 185; 186; 271
installing Prolog III 1002 M
integer 103; 273
integer number (syntax) 426 MacDraw 510
interruption 165; 1009 MacPaint 510
of a program 1009 max_value 103; 293
is 387 maximum value of a numeric expression
is_bool 127; 274 103
is_char 275 member 389
is_ident 276 memory 1002
is_leaf 277 min_value 103; 294
is_num 104; 278 mod 104; 169; 295; 367
is_tuple 79; 279 "MODAL" 465
is_univ 280 modication of stack sizes 1007
module 24; 176; 183; 296
K module user 1012
module(directive) 182
K(ill 1009 modules
keyboard equivalent 492 examples 183
kill_button 509 mouse 477
kill_module 12; 189; 281 "MPW" 484
kill_window 469 mul 168; 366
known 146; 282 mult 103; 154; 156; 297
known term 146 multiplication 30; 96
known_part 79; 150; 283
N
L
naive_reverse 80
labels 21 name 390
lcm 284 new 298
leaf 21 new_window 464
less than or equal to 99 next_char 299
line 194; 285 next_char' 300
line of non-editable text 495 nil 32
list 7; 9; 11; 186; 187; 286 nl 391
list (t) 187 "NLINES" 465
list_string 84; 291 no_echo 195; 301
list_tuple 82; 292 no_trace 302
listing 388 nonvar 392
lists 32; 81 normal conjunctive form 121
literal 122 normal form
ln 170; 368 boolean constraints 121
load_graphic 462 numeric constraints 100

1042 © PrologIA
Prolog
Aociation

HERITAGE
General Index

not 28; 117; 303 output file 1008


num 103; 304 output.log 1007
number 393 output_is 312
numbers 14
floating 26; 92 P
fractional 92
integers 25 parameterization 1007
rationals 92 parasite 162
numbers limits particular_value 103; 313
floating-point 1010 pattern 478
integers 1010 pen 470; 471; 477; 478
numden 305 perfect precision 25; 92
numeric comparisons 51 pgcd 314
numeric constraints 14 pixels 464; 468; 471; 478; 499; 504
numeric equations 100 pointed pair 32; 81
numeric inequations 101 pop-up menu 489
ppcm 315
O predefined 187; 316
predefined rules
object module 183 adding new ones 1012
omission of the multiplication operator 97 prefix 24
op 394 syntax 174
operations 27 prefix (syntax) 431; 441
arithmetical 29 primitives
boolean 28 boolean 126
general tree construction 31; 69 numeric 102
tree construction 30; 69 string conversions 84
tuple concatenation 31; 74 tuples 78
tuple construction 31; 69 print_window 469
operators 96 priorities
boolean boolean operators 117
and 117 numeric operators 96
equivalent 117 Pro3Goal 1026; 1027; 1028
implies 117 Pro3Session 1026; 1027
not 117 program execution 62
or 117 projection on a sub-vocabulary 125
option + closure 469 Prolog III machine 63; 160
options 1008 prolog3.bst 1004
or 28; 117 prolog3.era 1005
out 193; 306 prolog3.erf 1005
outc 194; 307 prolog3.err 1004
outl 193; 308 prolog3.exe 1004
outm 194; 309 prolog3.lex 1004
outml 7; 194; 310 prolog3.prf 1004; 1008
output 11; 195; 311; 510 prolog3.sya 1005

© PrologIA 1043
Prolog
General Index Aociation

HERITAGE

prolog3.syf 1005 relations 48


prolog3.syn 1004 boolean 118
PrologDir3 1006; 1008 implication 50; 118
PrologEdit 1006; 1012 inequality 48
prologIII 317 number of sons 72
protected mde 1025 numeric 98
protected mode 1003; 1004; 1005; 1012; numeric comparisons 51
1013; 1026 of type 51
put 395 unary 51
put_integer 1016; 1022 reload 189; 325
put_real 1016; 1022 remove_implicit 180; 326
put_string 1016; 1022; 1023 repeat 327
PutArg 1016; 1017 reset_cpu_time 196; 328
reset_window 469

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

declarative 60 srcOr 479


operational 60 srcXor 479
terms 44 standard output 1007
separator 175 start a session 1007
set of characters 424 state 347
set of constraints strictly greater than 99
boolean 120 strictly less than 99
set_config 105; 338 string 85; 348
echo 339 string_bool 84; 349
epsilon_float 340 string_ident 84; 350; 351
format_decimal 340 string_integer 84; 352
format_float 340 string_real 84; 353
format_out_num 339 stty 483
statistics 340 style 478; 479; 492
syntax 340 style_menu 492
trace 338 sub 168; 366
tty_wrap 340 substring 84; 354
undefined_rule 341 subtraction 30; 96
set_configuration 342 sup 169; 367
set_context 178; 180; 343 supe 170; 367
set_ident 344; 1013 suppress 10; 15; 188; 355
set_menu 489 suspend_trace 358
set_window 467 syntax 340
sfgetfile 510 Edimbourg 340
sfputfile 511 Prolog III 340
"SHAPE" 465 sys_command 359
sign change 30
simplification T
boolean constraints 124
trees 73 T(race 1009
sin 170; 368 tab 401
size 78; 149; 345 tabulation 482; 485; 498; 505
sizes 74; 1010 tan 171; 368
auxiliary algebra space 1007 tell 402
copy stack 1007 term (syntax) 432; 444; 447
delayed 149 termination button 496
restoration stack 1007 terms 34
rule space 1007 known 146
solution of a constraint system 55 without variables 36
boolean 124 ticked item 489
solving constraint systems 55 ticking mark 491
source module 182 told 403
split 79; 346 trace 338; 360
sqrt 171; 368 trace_file 361
srcBic 479 transfer modes 479
srcCopy 479

© PrologIA 1045
Prolog
General Index Aociation

HERITAGE

Tree 68 tan 368


trees 20 trunc 367
true 404 var 405
true facts 60 variable (syntax) 430; 440
trunc 104; 170; 362; 367 Variables 33
"TTY" 484;465 step 101
tty_wrap 340 vertical coordinates 470
tuple 79; 363 vertical space 499
tuples 22; 69; 74
W
U
"window" (menu) 493
unary minus 96 write 406
unary plus 96 writeq 407
undef_array 364
undefined_rule 341
error 341
fail 341
warning 341
User Interrupt 1009
user_item 504
UserRule 1014; 1015; 1017; 1024

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

December 1991 © PrologIA


Aociation Prolog

HERITAGE

Guarantee and liabilities


PrologIA offers no guarantee, tacit or explicit concerning either this manual or
the software herein described, its qualitiy, performance or its suitability for any
application whatsoever.
PrologIA cannot be held liable for damage of any sort, whether direct or indirect
resulting from a fault in the manual or program, even if the company has been
advized that such damage might occur. In particular, PrologIA cannot take
responsibility for data stored or used; this includes costs of recovery or
duplication of such data.
Nevertheless the purchaser is entitled to the statutory guarantee in such cases
and to the extent to which the statutory guarantee is applicable not
withstanding any exclusions or limitations.

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.

December 1991 © PrologIA


Aociation Prolog

HERITAGE

Debugging Prolog III programs

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

What is in this chapter?

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.

November 1991 © PrologIA


Prolog
Debugging Prolog III programs Aociation

HERITAGE

1 . Introduction

The purpose of a debugging tool is to help us understand why a program


which in theory is right doesn't give the expected answer, or gives the
wrong answer to the question asked. However powerful the tools we
provide the programmer with, it's certainly true that they will never replace
the golden rule: always think before you program — and re-read your code
before you execute it.

However, in many cases detailed examination of how a program runs, and


interactive monitoring of its execution can give the programmer valuable
clues when confounded by that well-known phenomenon, a bug.

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!

2 . Sources of errors in a program

A program may be incorrect simply because of a "spelling" mistake. In this


case, the Prolog III parser refuses to load it (how could this be otherwise?),
and indicates a syntax error.

> Oh, hello your royal highness!


Oh, h
^
Line 1 (0,4): syntax error (skip to next ';')
;
>

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.

1 Hence the local line number 0.

2002 © PrologIA
Prolog
Aociation

HERITAGE
Debugging Prolog III programs

Mistakes that do not produce a syntax error can be classified in two


categories:

• Mistakes that can be detected statically, i.e. by examining the set of


rules that the program is likely to use.

• Mistakes that only appear when the program is executed.

In the first category we have mistakes caused by carelessness: undefined


rules 1 or rules defined with the wrong arity, isolated variables, etc. In
addition, we must ensure that no definition results from dynamic insertion
of rules due to an assert, insert, or reload. The best way of avoiding false
suppositions is to adopt a clear, documented programming style.

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

set_config primitive "undefined_rule" option).

© PrologIA 2003
Prolog
Debugging Prolog III programs Aociation

HERITAGE

3 . Overview of the box model

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.

The four external ports

These ports correspond to precise locations in the execution of a goal. They


represent:

• the activation of a group of rules (CALL),


• correct termination of one of the group's rules (EXIT),

• return to this group via backtracking (REDO),


• deactivation of this group when its choices are used up (FAIL).

CALL EXIT

FAIL REDO

Figure 1. An opaque box and its four ports.

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

Since a box's behavior is naturally non-deterministic, the same box may be


questioned several times, in order to provide different answers.
Sequentially, we first enter a box via CALL. We leave it successfully via EXIT
indicating that a solution has been found. When choices have been left
unused, we can return to the box and request an alternative solution via
REDO. If no (other) solution is present, this is indicated by FAIL which brings
about the final exit from the box.

An example

Let's take the following fact base as an example program:

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}

Third step; an internal failure has been generated downstream so that by


backtracking all solutions are listed, and the box is required again. The REDO
port is activated (all the other ports are locked):

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

First step: the CALL port is activated.

{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

In addition to the 4 external ports which allow macroscopic observation of a


program's behavior, the debugger's boxes also have 3 internal ports. These
ports describe down to the finest detail (i.e. state to state transitions) the
logical inferences performed by the Prolog III machine.

If we start with a state p p1…pn, S , these ports indicate the following:

• a rule q -> q1 …q m , T is selected from the group of rules and the


constraint system S  T  {p = q} is simultaneously set (RULE),
• the transition is accepted and the state becomes q 1 …q m p 1 …p n , S'
where S' is a solved system equivalent to S  T  {p = q} (OK),
• the transition is rejected — the attempt to unify with the selected rule's
head has failed (NO).

© PrologIA 2007
Prolog
Debugging Prolog III programs Aociation

HERITAGE

RULE
OK
NO

Figure 2. A box and its three internal ports

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.

4 . The debug mode

Start up

To switch from normal interpreting mode to debug mode, type in the


following goal:

> 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,

• print relevant information (or avoid unnecessary printing),


• retry or modify execution of a section from the program, ,
and many other things as well.

The debug mode is deactivated by no_debug.

Line describing a port

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:

2 [2] EXIT (r1) : olympic_city(Albertville) (DBG)

Goal called Prompt


Number of the
applied rule
Port name
Call level
Box number (call depth)

Box number (call depth)

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]

"Olympic" boxes: call numbers and nesting levels

1 Unless there are delayed constraints in the query.

© PrologIA 2017
Prolog
Debugging Prolog III programs Aociation

HERITAGE

Port name
This is one of the strings CALL, RULE, {ok}, {no}, EXIT, REDO, FAIL .

Number of the applied rule


This number is only displayed with the internal ports RULE, {ok}, {no}, and
the external port EXIT. If it is followed by a star *, this indicates that it is the
last rule in the group. Predefined rules written in C are indicated by (rC).

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).

Display of terms and literals

The level of detail displayed in trace or debug mode can be parameterized.


There are three modes for printing goals, depending on the amount of
information you want to see.

• mode 1 the names of the called predicates are printed, without


any arguments.
• mode 2 the calls are printed with their arguments.
• mode 3 : the calls are printed with their arguments, and also
constraints applying to the variables appearing in the
goal and/or the rule-head that is tried.
For an example of how constraint systems are displayed let's leave the
Olympic example to one side and turn to the balanced meal problem — as it
appears in the directory of Prolog III examples. This example will enable us
to introduce some of the most commonly used debugger commands.

The loaded rules are verified, and then we go into debug mode. We then
start the goal: BalancedMeal(h, m, d) , {h  radishes}.

User input is shown in bold.

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.

1[1]RULE(r1*): BalancedMeal(h,m,d) = BalancedMeal(h_1,m_1,d_1),


{ h # radishes } U
{ } (DBG)
1[1]{ok}(r1*): BalancedMeal(h,m,d),
{ h # radishes } (DBG)

(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.

--\/ CHOICE POINTS (new)\/--


3[2] (r2*): MainCourse(m,i)
__/\ CHOICE POINTS (old)/\__
(DBG) s
3[2]RULE(r2*): 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}(r2*): MainCourse(m,j_1),
{ -k_1 - j_1 + 4 >= 0 ,
j_1 >= 0 ,
k_1 >= 0 } (DBG) ls

2022 © PrologIA
Prolog
Aociation

HERITAGE
Debugging Prolog III programs

[3] MainCourse(m,j_1) -> @ Fish(m,j_1) ;


[2] BalancedMeal(pate,m,d) -> HorsDoeuvre(pate,6)
MainCourse(m,j_1) @ Dessert(d,k_1) ;
[1] BalancedMeal(pate,m,d) @ ;

We have no choice, it's going to be fish. Here, the ls command is used to


recap on the state of the proof. The @ symbol shows where we are in the
AND tree. To the right of this is what remains to be proved (the nested
resolvent).

(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.

0[0]REDO(r1): $query$ (DBG) chpt


--\/ CHOICE POINTS (new)\/--
5[2] (r2*): Dessert(ice_cream,6)
4[3] (r2*): Fish(tuna,4)
__/\ CHOICE POINTS (old)/\__
(DBG) s
1[1]REDO(r1*): BalancedMeal(pate,sole,d) (DBG)
5[2]REDO(r1): Dessert(d,k_1),
{ -k_1 + 2 >= 0 ,
k_1 >= 0 } (DBG)
5[2]RULE(r2*): Dessert(d,k_1) = Dessert(ice_cream,6),
{ -k_1 + 2 >= 0 ,
k_1 >= 0 } U
{ } (DBG)
5[2]{no}(r2*): Dessert(ice_cream,6) (DBG)
5[2]FAIL(r2*): Dessert(d,k_1),
{ -k_1 + 2 >= 0 ,
k_1 >= 0 } (DBG) chpt
--\/ CHOICE POINTS (new)\/--
4[3] (r2*): Fish(tuna,4)
__/\ CHOICE POINTS (old)/\__
(DBG) s

Obviously, this particular ice cream is too fattening!


We no longer have any alternative but to undo the proof as far as
MainCourse in order to re-examine the choice of sole.

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

This section describes some commands commonly used for debugging


programs.

Leaving the debugger


kill, no_debug

kill
Syntax:
kill
Description:

This command aborts execution of the current program and returns to


the Prolog III interpreter that is waiting for another goal. The debug
mode remains active.

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

Stepping from port to port

These commands allow you to go through a program using different sized


steps. Remember that in Prolog, depending on the direction of the control
flow, the depth of the port reached may either be greater or lower than the
depth of the port left.
step, next, n, N, nextp, cont, C

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

fig. 1 step versus 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.

Getting more information

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, chpt, locus, ls, resol, rs, sol

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:

--\/-- CHOICE POINTS (new)\/--


5[2] (r3*): Dessert(ice_cream,6)
4[3] (r2*): Meat(pork,7)
3[2] (r2*): MainCourse(m,i)
2[2] (r2): HorsDoeuvre(pate,6)
--/\-- CHOICE POINTS (old)/\--

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:

For built-in predicates, a question mark replaces unknown or hidden


information.

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

The current call's position inside a rule is indicated1 by the @ character. @


may appear before or after a call, depending on the port corresponding
to this call.
The level of a rule body is indicated in front of the rule head. Level [0]
denotes the virtual call of the $query$ goal, whose rule body would be
the query typed by the user.
When a number is given as an argument, it denotes the number of levels
we want to display line by line, starting from the bottom of the proof
tree (in the order of decreasing levels).
The ls command is short-hand to indicate that we want to display the
current proof, i.e. with no restriction on levels.

> aa(x) -> bb(x) cc(x);


> bb(x) -> eq(x,1);
> aa(u);

--------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.

1 This character varies according to the implementation.

© PrologIA 2031
Prolog
Debugging Prolog III programs Aociation

HERITAGE

• Break points (defined with breakat) are indicated by placing the *


character in front of the literal where they are installed.

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.

> aa(x) -> bb(x) cc(x);


> bb(x) -> eq(x,1);
> aa(u);

--------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).

Switching modes and filtering ports

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

Classification of the commands

The debugger commands can be classified as follows:

• Commands to close or kill a debugging session:


kill, no_debug
• Commands to make jumps of varying size between ports, when
following the control flow:
step, next, n, N, nextp, cont, C
• Commands to print information:
printbox, chpt, locus, ls, resol, rs, sol
• Commands to install or delete break points:
spy, nospy, breakat, unbreak
• Commands to modify the execution of a program:
RULE, changechpt, fail, FAIL

• Commands to manage the debugger's options:


set, show, p4, p7, t1, t2, t3
• Additional commands:

2034 © PrologIA
Prolog
Aociation

HERITAGE
Debugging Prolog III programs

alias, help, source, eof

The command language

The command language for Prolog III's debugger can be described as


follows:

• A command is a sequence of one or more words ending in an end-of-


line or a semi-colon.
• The words in this sequence are separated by spaces or tabs.
• The first word is the name of the command, and the other words are its
arguments.

• Words that contain spaces or tabs must be parenthesized.

• The names of the commands are case-sensitive.


• Semi-colons are used to separate commands on the same line
• By default, an empty line (only containing blanks and a carriage return)
repeats the line previously given to the debugger. This option can be
canceled using the following command:

(DBG) set nlrepeat 0

• An alias mechanism enables you to define new commands by


combining basic ones. Some commands are predefined using this
technique.

• The commands are executed at each break point. If no command is


waiting to be executed, the prompt is displayed, and the user has
control.

Modifying the execution

These commands are used to modify normal execution of a program, either


by prematurely pruning one or several branches or by replaying a
demonstration.

© PrologIA 2035
Prolog
Debugging Prolog III programs Aociation

HERITAGE

RULE, changechpt, fail, FAIL

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.

> dozen(12) -> ;


> dozen(24) -> ;
> dozen(36) -> ;
> dozen(x);
--------new query--------
1[1]CALL : dozen(x) (DBG) s
1[1]RULE(r1): dozen(x) = dozen(12) (DBG) RULE 3
1[1]RULE(r3*): dozen(x) = dozen(36) (DBG) s
1[1]{ok}(r3*): dozen(36) (DBG)
1[1]EXIT(r3*): dozen(36) (DBG)
0[0]EXIT(r1): $query$ (DBG)
{x = 36}
>

Note:

When the number provided does not correspond to any rule in the
procedure, no action is taken.

changechpt
Syntax:

changechpt #box #rule


Description;

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

This command is used to modify a choice point, and therefore modifies


the search tree which is traversed by the interpreter. This command
does not modify the searching of the current branch, since it modifies an
alternative situated in this branch's past (OR node).
changechpt is used to prune certain branches when we know they are
of no interest, or when we want to accelerate the search for an error. It is
also possible to re-execute certain branches which have already been
searched. This command uses the information displayed by the chpt
command.
Here is an example where we modify the choices that are pending.
First, we “repeat” the same solution twice:

> dozen(12) ->;


> dozen(24) ->;
> dozen(36) ->;
> dozen(x);
--------new query--------
1[1]CALL : dozen(x) (DBG) s
1[1]EXIT(r1): dozen(12) (DBG)
0[0]EXIT(r1): $query$ (DBG) chpt
--\/ CHOICE POINTS (new)\/--
1[1] (r2): dozen(24)
__/\ CHOICE POINTS (old)/\__
(DBG) changechpt 1 1
(DBG) chpt
--\/ CHOICE POINTS (new)\/--
1[1] (r1): dozen(12)
__/\ CHOICE POINTS (old)/\__
(DBG) s
{x = 12} the next solution will be 12 again
0[0]REDO(r1): $query$ (DBG)
1[1]REDO(r1): dozen(x) (DBG)
1[1]EXIT(r1): dozen(12) (DBG)
0[0]EXIT(r1): $query$ (DBG)
{x = 12}

Then, we “skip” a solution:

© PrologIA 2037
Prolog
Debugging Prolog III programs Aociation

HERITAGE

0[0]REDO(r1): $query$ (DBG) chpt


--\/ CHOICE POINTS (new)\/--
1[1] (r2): dozen(24)
__/\ CHOICE POINTS (old)/\__
(DBG) changechpt 1 3 ; chpt
--\/ CHOICE POINTS (new)\/--
1[1] (r3*): dozen(36)
__/\ CHOICE POINTS (old)/\__
(DBG) s and the next solution will be 36
1[1]REDO(r1): dozen(x) (DBG)
1[1]EXIT(r3*): dozen(36) (DBG)
0[0]EXIT(r1): $query$ (DBG)
{x = 36}
>

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.

The following table describes the changes in state due to fail:

2038 © PrologIA
Prolog
Aociation

HERITAGE
Debugging Prolog III programs

CALL goes to FAIL (leaves the box)


RULE goes to {no}

{ok} goes to {no}

EXIT goes to REDO or FAIL (depending on whether a choice point


is present or not)

{no} does step


REDO does step

FAIL does step

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.

Installing break points,

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:

This command is used to monitor all the calls to a procedure. It therefore


does not monitor an individual call like the breakat command. If there are
no arguments, the name and arity of the procedure correspond to those
of the current box. If there are arguments, it describes the identifier
arity group.

(DBG) spy Dessert 2

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.

(DBG) nospy Dessert 2

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.

1 Options are set using the set command.


2 If we get there! Backtracking may well occur in between…

© PrologIA 2041
Prolog
Debugging Prolog III programs Aociation

HERITAGE

> aa(x) -> bb(x) cc(x);


> bb(x) -> eq(x,1);
> cc(1) ->;
> aa(X);
--------new query--------
** 1[1]CALL : aa(X) (DBG) s
** 1[1]RULE(r1*): aa(X) = aa(x_1) (DBG)
** 1[1]{ok}(r1*): aa(X) (DBG) ls
[2] aa(X) -> @ bb(X) cc(X) ;
[1] aa(X) @;
[0] $query$ @
(DBG) breakat 2 3
(DBG) ls
[2] aa(X) -> @ bb(X) *cc(X) ; A break point on cc(X)
[1] aa(X) @;
[0] $query$ @
(DBG) C We go as far as the next break point
** 4[2]CALL : cc(1) (DBG) Break point is reached

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.

Management of the debugger options

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.

Available debugger options

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.

tracemode value: 1/2/3 default value: 2


This option indicates the precision of term printing (see trace), and
thus takes the value 1, 2 or 3.

maxlevel values:  -1 default value: -1

Indicates the maximum level for complete tree printing. The


maximum level of a tree is 0 when it is a leaf, or otherwise a greater integer,
e.g. if maxlevel is 0, the term eq(x, gg(y)) will be printed eq(...,...)

© PrologIA 2043
Prolog
Debugging Prolog III programs Aociation

HERITAGE

and if maxlevel is 1, it will be printed eq(x, gg(...)). Since this tree's


depth is 2, it will be printed completely if maxlevel is set to 2. A -1 value
indicates complete printing whatever the depth.

maxarg values:  -1 default value: -1

Indicates the maximum number of arguments to print, whether they


be functions or tuples. If maxarg is 0, the term eq(x, gg(y)) will be printed
eq(..(2)..)) indicating that two arguments are present and not printed. If
maxarg is 1, eq(x,..(1)..)) will be displayed where..(n).. indicates that there
remains a sequence of n non-printed arguments. A -1 value indicates that all
arguments are printed.

maxexpr values:  -1 default value: -1


Indicates the maximum number of monomials to print in a numeric
expression. This option functions somewhat like maxarg, and prints the rest
of the monomials in the form ..(nm).., where n is the remaining number
of monomials, e.g. if maxexpr is 1, the term eq(z+4y+(18/7)x-t, u) will be
printed eq(z..(3m)..,u) . A -1 value indicates that all the monomials are
printed.

maxstr values:  -1 default value: -1


Indicates the maximum number of characters to print in a character
string (not a tuple). This option functions like maxexpr and prints the rest of
the string in the form ..(nc).., where n is the remaining number of
characters, e.g. if maxstr is 10, the term eq(x, "this string is a bit too long") will
be printed: eq(x,"this strin..(25c).."). A -1 value indicates that the whole
string is printed.

print values: 0/1 default value: 1


This option controls the printing of the ports during execution of a
program, and therefore affects the functioning of the progression
commands, such as step, next and cont. Since any printing point is a

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.

printport values: [cerfRYN] default value: cerfRYN

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:

set printport cerf


set printport +YN
set printport -RYN

This option has a direct effect on the functioning of step. It is only used
when the print option is set to 1 .

break values: 0/1 default value: 1

This option indicates whether we allow a break point installed by the


breakat or spy commands to cause interruption of execution of the current
command. The next command is not affected by this option.

breakport values: [cerfRYN] default value: cerfRYN

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 .

echo values: 0/1 default value: 0


Prints the commands that are executed on the trace output.

prompt values: string of 19 char. max. default value: (DBG)

1 Unless a break point has been explicitly installed.

© 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:

set prompt ( (DBG) )

catcherror values: 0/1/2 default value: 2


This option is set at 1 or 2, and indicates whether the user wants to
localize errors or executions of the built-in predicate block_exit. If the
option's value is 0, the execution of the debugging session will not be
interrupted by error detection. If the option's value is 1, a message will be
printed indicating the error type (or the argument of block_exit) and the
number of the box where the error will be "caught" if applicable. If the
option's value is 2, the previous message is printed, and an EXIT port is
displayed, leaving control to the user1.

nlrepeat values: 0/1 default value: 1

When this option is set to 1, it indicates whether transmission of an


empty line (carriage return only) corresponds in fact to transmission of the
last non-empty line (containing one or more commands). This is very
useful, when you want to do the same sequence of commands, but is also
very dangerous, when you've entered a sequence of fail's, and have
forgotten to type step or n e x t to progress!. If the option is at 0,
transmission of an empty line has no effect.

warnnext values: 0/1 default value: 0


When the option's value is 1, it informs the user (if applicable) that it
has not been possible to execute the nextp command normally, in general
because backtracking has occurred, thus taking us out of the current box via
the FAIL port.

1 The commands fail and FAIL are not active at this particular port.

2046 © PrologIA
Prolog
Aociation

HERITAGE
Debugging Prolog III programs

Additional commands

This section describes a certain number of additional commands, some of


which can be used to customize the debugging environment.

alias, help, source, eof

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.

(DBG) alias x next

(DBG) alias nls (locus 10000;n)

Notes:

• Definitions or helps containing blanks or semi-colons must be


parenthesized.

• An alias is deleted by giving an empty definition using () .

© PrologIA 2047
Prolog
Debugging Prolog III programs Aociation

HERITAGE

• alias is not a general mechanism for defining macros.

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:

Please refer to the source command to read a command file.

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:

• source is recursive up to a depth of five calls.

• The eof command is used to terminate reading of a file.

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, debug and normal modes

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

debug switches to debug mode, whatever mode you were in previously.


Critical sections in a program can be enclosed within debug and no_debug,
but remember that information about the current proof will be limited if
the query was not started in debug mode. In addition Level [0] now
corresponds to the point in the program where debug is called, and is no
longer connected with the query.

Following a user interrupt, a dialog is displayed allowing you to enter or


exit the debug mode (the proposed option is a switch).

© 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

It is sometimes useful to be able to retry a proof without having to start


from the beginning, in particular when execution of the program to trace is
awkward because it takes a long time or because it is difficult to get to this
exact point in the 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:

1 This means that determinist programs cannot be retried.


2 This is often the one preceding the displayed rule.

© PrologIA 2051
Prolog
Debugging Prolog III programs Aociation

HERITAGE

> retract(MainCourse(m,i),[Fish(m,i)])list(MainCourse) debug;


MainCourse(m_15,i_15) ->
Meat(m_15,i_15);
{}

Here is the start of execution.

> BalancedMeal(h,m,d) {p # beef);

--------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.

--\/ CHOICE POINTS (new)\/--


2[2] (r2*): HorsDoeuvre(pate,6)
__/\ CHOICE POINTS (old)/\__

Box #3 has no choice points but box #2 does have one, which we can modify
using the changechpt command:

(DBG) changechpt 2 1 ; chpt


--\/ CHOICE POINTS (new)\/--
2[2] (r1): HorsDoeuvre(radishes,1)
__/\ CHOICE POINTS (old)/\__
(DBG) p

We can now simply force MainCourse to fail and thus return to box #2.

2052 © PrologIA
Prolog
Aociation

HERITAGE
Debugging Prolog III programs

3[2]EXIT(r1*): MainCourse(pork,7) (DBG) F


3[2]FAIL(r1*): MainCourse(pork,7) (DBG)
2[2]REDO(r1): HorsDoeuvre(h,i_1) (DBG) n
2[2]EXIT(r1): HorsDoeuvre(radishes,1) (DBG)
3[2]CALL : MainCourse(m,j_1) (DBG) s

We can now retry the execution as if nothing had happened.

4[3]CALL : Meat(m,j_1) (DBG) p7 ; s


4[3]RULE(r1) : Meat(m,j_1) (DBG) = Meat(beef,5) (DBG) s
4[3]{no}(r1) : Meat(beef,5) (DBG)
4[3]RULE(r2*): Meat(m,j_1) = Meat(pork,7) (DBG)
4[3]{ok}(r2*): Meat(pork,7) (DBG) C
{h = radishes, p = pork, d = fruit}

Recovering an error at source

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

9 . The trace mode

When a user is able to request information about the current program,


especially information not required by the interpreter, the amount of space
required by the debugging session in debug mode can become very large,
since garbage collection will no longer be as efficient.
When this cost becomes prohibitive, Prolog III offers the user a different
debugging mode: the trace mode

Start-up

The normal interpreting mode is switched to trace mode by the following


goal:

> 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

Basically, tracing consists in printing on the current trace output a sequence


of equality constraints between goals and rule heads before unification, with
indications of the backtracking points. The trace mode displays the
internal ports RULE and {no} in a different way, whose implementation
does not cause overcost at execution.

An execution in trace mode has the following form:

1 See trace, no_trace, suspend_trace, resume_trace, set_config, etc....

2054 © PrologIA
Prolog
Aociation

HERITAGE
Debugging Prolog III programs

goal = rule_head_to_try1 % indicates an attempt


<<<<<< % it fails
goal = rule_head_to_try2 % another attempt
another_goal = another_rule % execution of the previous
% goal succeeds

As in debug mode, the level of detail of the trace can be parameterized.


("tracemode" option from set_config), and enables the user to choose
between printing terms with or without arguments or an associated
constraint system.

ststs

© PrologIA 2055
Aociation Prolog

HERITAGE
Aociation Prolog

HERITAGE

Appendix

1. Summary of commands
2. Summary of options.

1. Summary of commands

• Leaving the debugger:


kill abandons the current query.
no_debug leaves the debugger and resumes execution.
• Stepping from port to port:
step jumps to the next port, going upwards.

next jumps to the next port, without going up a level.


n same as next, without printing.
N same as n, without breaking.
nextp jumps to the next port of the current box, without
going up a level.
cont continues till the next break point.
C same as cont, without printing.
• Printing information:
printbox displays the status of the current port.

chpt displays the choice points.


locus, ls display the current proof.

Decmber 1991 © PrologIA


Prolog
Appendices Aociation

HERITAGE

resol, rs display the current resolvent.


sol displays the constraints attached to variables of the
query.
• Installing or deleting break points:
spy, nospy set and remove a spy point (on code).
breakat sets a break point (on proof).
unbreak removes a break point (on proof).

• Modifying execution of a program:


RULE selects a rule in a procedure.
changechpt modifies choice points that are pending.
fail fails.
FAIL goes to the FAIL port of the current box.

• Managing the debugger's options:


set, show set and print the options.
p4, p7 select external ports / all ports.
t1, t2, t3 modify printing mode for literals.

• Customization and additional commands:


alias defines new aliases.

eof closes command files.


help provides on-line help.
source executes a command file.

2058 © PrologIA
Prolog
Aociation

HERITAGE
Appendices

2. Summary of options

Option Values Default Description


break 0/1 1 Enables/disables Breaks (not Nexts)
breakport [cerfRYN] cerfRYN Break and Next only at these ports
catcherror 0/1/2 2 0 = ignore, 1 = print, 2 = print & catch
echo 0/1 0 Echoes DBG commands before
executing
maxlevel >= -1 -1 (all) Max. level of full printing
maxarg >= -1 -1 (all) Max. number of arguments printed
maxexpr >= -1 -1 (all) Max. number of monomials printed
maxstr >= -1 -1 (all) Max. number of characters printed
nlrepeat 0/1 1 If set, <CR> performs the previous
command line
print 0/1 1 Enables/disables printing
printport [cerfRYN] cerfRYN Prints only specified ports
prompt < 19 char. ( (DBG) ) Prompt string
tracemode 1/2/3 2 Printing mode for literals
warnnext 0/1 0 Warns when nextp can't be done

© PrologIA 2059
Prolog
Appendices Aociation

HERITAGE

2060 © PrologIA

 

   

You might also like