Professional Documents
Culture Documents
Documentation PrologII Manual PdfA
Documentation PrologII Manual PdfA
$%"!$"!%&$'&$" $"" +%$(%$"'%)&$!%$$&"&
%%"&"!!' $)(&""!%'&&"!"!&!&$!&!%#$!
*
"!&&%%"&"!#$""$&"$
Aociation Prolog
HERITAGE
PROLOG II+
REFERENCE MANUAL
© PrologIA
Aociation Prolog
2 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 3
Contents
Contents.............................................................................................................3
Introduction ......................................................................................................9
Standardization..................................................................................9
Performances ....................................................................................9
Modularity ......................................................................................10
Communication with the outside world ...........................................10
Programming environment..............................................................10
Graphics interface ...........................................................................10
© PrologIA
Aociation Prolog
4 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 5
3.6.1 Identifiers...................................................................R 3 - 17
3.6.2 Abbreviated notation and contexts..............................R 3 - 18
3.6.3 Modules.....................................................................R 3 - 19
3.7 Adding, deleting and searching for rules.................................R 3 - 20
3.8 Manipulation of compiled modules.........................................R 3 - 31
6. The environment..................................................................................R 6 - 1
6.1 How to leave Prolog..................................................................R 6 - 1
6.2 Automatic start-up of a Prolog program....................................R 6 - 1
6.3 Program editing ........................................................................R 6 - 2
6.3.1 Modifying groups of rules...........................................R 6 - 2
6.3.2 Editing and recompiling a source module.....................R 6 - 3
6.3.3 Editing any type of text file ..........................................R 6 - 4
6.4 Date, time and measurements....................................................R 6 - 4
6.5 Link to the system.....................................................................R 6 - 5
6.6 Program debugger ....................................................................R 6 - 6
6.6.1 Trace mode...................................................................R 6 - 6
6.6.2 Interactive mode ...........................................................R 6 - 7
6.6.2.1 Break points.....................................................R 6 - 7
6.6.2.2 Advancing in the code ......................................R 6 - 8
6.6.2.3 Ending execution..............................................R 6 - 9
6.6.2.4 Displaying information ....................................R 6 - 9
© PrologIA
Aociation Prolog
6 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 7
9. Interruptions........................................................................................R 9 - 1
9.1 Concepts...................................................................................R 9 - 1
9.2 Description of the interfaces .....................................................R 9 - 2
9.3 Complete example.....................................................................R 9 - 3
© PrologIA
Aociation Prolog
8 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 9
Introduction
In response to these demands, PrologIA offers you a new system: Prolog II+.
While maintaining the features which have made Prolog II such a success, this
product offers the following new features:
• performance levels
• modularity
• standardization
• open to the external environment
• programming environment
• graphics interface
Standardization
Performances
© PrologIA
Aociation Prolog
10 Reference Manual HERITAGE
Modularity
• Two-way links with other languages: Calls can be written in Prolog to sub-
programs written in other languages. A Prolog program can be called from any
other program (even when different solutions are obtained in succession). All the
possible cross-call situations have now been provided for.
• Completely open data structures, with the interface needed for inter-language
communication, using all data types, with no restriction on the type of term (which,
for example, can include both variables and identifiers). It is possible to share
common zones (arrays) with other programs.
Programming environment
Graphics interface
© PrologIA
Aociation Prolog
HERITAGE Introduction 11
• Drawing composition.
• Dialog management.
© PrologIA
Aociation Prolog
12 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 13
Prolog II+ documentation is contained in two volumes. The first is the Reference
Manual, which gives a precise description of the language and its uses. It applies to
all implementationsof Prolog II+ (except where specifically noted). The second
volume is the User's Manual, describing all the features which are specific to a
particular computer and its operating system. Each type of machine therefore has
its own user's manual.
To install Prolog II+ and use it, please refer to Chapters 1 and 2 of the User's
Manual.
The Reference Manual starts with an elementary introduction to Prolog and its
practical uses. The second chapter then gives a more advanced theoretical
introduction to Prolog. The following chapters deal with predefined rules
concerning program control, rule manipulation, data operations, input-output, the
environment, the debugger and the editor. The following chapters concern Prolog
II+ and communication with the external environment. We explain how to add
predefined rules written by the user, how to make cross-calls or declare shared data
zones for use by Prolog and other languges, and how to intercept interruptions and
activate a Prolog process. Finally, the last chapter describes the library of primitives
specific to the Edinburgh syntax.
As a supplement to this manual we have added some Appendices, which also apply
to all implementations. They give details about some of the topics discussed in the
Reference Manual. In particular, you will find details of the differences between the
Prolog II interpreter and the Prolog II+ compiler, and some example programs to
illustrate how Prolog can be used.
The User's Manual specifies in detail how your computer performs certain
functions described in the Reference Manual. It deals with file name structure,
saved state management, the use of the memory, and explains how to start Prolog.
The second part of this manual describes all the features which are specific to this
version; everything that has been added or removed in comparison with the basic
version, and the boundary values for constants.
The following texts are also well worth consulting:
Prolog, theoretical principles and current trends.
A. Colmerauer, H. Kanoui, M. Van Caneghem,
TSI vol 2, number 4, 1983.
Prolog
F. Giannesini, H. Kanoui, R. Pasero, M. Van Caneghem,
Addison-Wesley, 1986.
In addition, for programming in Edinburgh syntax:
Prolog Programming for Artificial Intelligence
Ivan Bratko, Addison-Wesley, International Computer Science Series, 1986.
© PrologIA
Aociation Prolog
14 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 15
PrologIA offers no guarantee, tacit or explicit, concerning either this manual or the
software described, its qualities, performance or its suitability for any application
whatsoever.
PrologIA cannot be made liable for damage of any sort, whether direct or indirect,
resulting from a fault in the program or the manual, even if the company has been
advised that such damage might occur. In particular, PrologIA cannot take
responsibility for data memorized 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, notwithstanding any
exclusions or limitations.
Copyright
This manual and the software it describes are protected by copyright. According to
the legislation concerning these rights, this manual and software must not be copied
or adapted, either wholly or in part, without the written consent of PrologIA, except
within the bounds of normal use or to create a back-up copy. However, these
exceptions do not authorize the user to create copies to be used by a third party,
regardless of whether or not they are to be sold.
© PrologIA
Aociation Prolog
16 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
0. Getting started
which starts Prolog with an initial (empty) state called initial.po. The character "$"
is the system prompt. The character ">" is the Prolog prompt. The various
different ways of starting Prolog are described in the User's Manual.
The character ">" informs you that you are in the Prolog environment and that the
interpreter is waiting for a command.
To get started, let us try a simple command, to print the message "Hello World":
> out("Hello World") line;
"Hello World"
{}
>
Now, let us try our first small program. To do this, we first get into insertion mode
( insert command). The system is now ready to read rules (or comments) and will
compile them in memory as they are read.Here, we enter three rules asserting that
Peter, John and Mary live respectively in Paris, Marseille and Paris :
> insert;
live_in(Peter,Paris) ->;
live_in(John,Marseille) ->;
live_in(Mary,Paris) ->;;
{ }
>
Aociation Prolog
R 0 - 2 Reference Manual HERITAGE
Note that every rule is terminated by the character ";" and that the insertion is
terminated by an additional ";". Rules are inserted in the order they are entered.
This can be checked by typing the command list (which displays rules in the current
module).
> list;
live_in(Peter,Paris) ->;
live_in(John,Marseille) ->;
live_in(Mary,Paris) ->;
{ }
>
Every time, the system's answer is the set of values to be given to the variables
appearing in the question in order to satisfy the corresponding relation. To
terminate the session, type the command :
>quit;
Bye......
$
This example uses the menu.p2 program frequently described in Prolog literature.
This program is in the examples directory of your Prolog II+ Kit. For this lesson,
you must first copy menu.p2 into your current directory. Then start Prolog as
explained in the previous section, and insert menu.p2 by typing:
$ prolog
PROLOG II+ ...
© PrologIA
Aociation Prolog
insert reads rules on the file specified, and inserts them in the current module.
When the input file has been read, the current input switches back to the keyboard,
which is the default input unit. The echo primitive displays the rules at the console
as the file is read:
" the menu "
hors_d_oeuvre(Artichauts_Melanie) ->;
hors_d_oeuvre(Truffes_sous_le_sel) ->;
hors_d_oeuvre(Cresson_oeuf_poche) ->;
meat(Grillade_de_boeuf) ->;
meat(Poulet_au_tilleul) ->;
fish(Bar_aux_algues) ->;
fish(Chapon_farci) ->;
dessert(Sorbet_aux_poires) ->;
dessert(Fraises_chantilly) ->;
dessert(Melon_en_surprise) ->;
" main_course "
main_course(p) ->meat(p);
main_course(p) ->fish(p);
" composition of a meal "
meal(e,p,d) ->hors_d_oeuvre(e)
main_course(p) dessert(d);
" calorific value for a portion "
calories(Artichauts_Melanie,150) ->;
calories(Cresson_oeuf_poche,202) ->;
calories(Truffes_sous_le_sel,212) ->;
calories(Grillade_de_boeuf,532) ->;
calories(Poulet_au_tilleul,400) ->;
calories(Bar_aux_algues,292) ->;
calories(Chapon_farci,254) ->;
calories(Sorbet_aux_poires,223) ->;
calories(Fraises_chantilly,289) ->;
calories(Melon_en_surprise,122) ->;
" calorific value of a meal "
value(e,p,d,v) ->
calories(e,x)
calories(p,y)
calories(d,z)
sumof(x,y,z,v);
" balanced meal "
balanced_meal(e,p,d) ->
meal(e,p,d)
value(e,p,d,v)
smaller(v,800);
" miscellaneous "
sumof(a,b,c,d) ->
val(add(a,add(b,c)),d);
smaller(x,y) ->val(inf(x,y),1); ;
{ }
>
© PrologIA
Aociation Prolog
R 0 - 4 Reference Manual HERITAGE
Let's try this program out: what are the main courses ?
> main_course(p);
{ p=Grillade_de_boeuf}
{ p=Poulet_au_tilleul}
{ p=Bar_aux_algues}
{ p=Chapon_farci}
This lesson stops here and we save the current module "" (module with the prefix
""), by typing:
> save([""],"menu.mo") quit;
Bye........
The purpose of this lesson is to show how to use Prolog's built-in editor very
simply, to manipulate a group of rules. On machines which have a window
environment and a mouse, copy/paste, may be easier.
First, start Prolog and load the saved module containing the menu.p2 program,
assuming it has been saved with save:
...
> load("menu.mo");
{}
>
If exit was used to leave the file, Prolog is started with the saved state containing the
menu.p2 program, as we left it at the end of the previous lesson:
....
>
Let us suppose we want to change the menu, and replace the rules below:
a meat(Grillade_de_boeuf) ->;
b meat(Poulet_au_tilleul) ->;
with:
c meat(Veau_marengo) ->;
d meat(Poulet_roti) ->;
© PrologIA
Aociation Prolog
where the notation meat/1 denotes the group of rules concerning the relation meat
applying to 1 argument.
This activates the editor, which displays the rules that define the meat relation. You
can now perform the modifications as desired, and leave the editor. You should
check that Prolog has re-read the new definitions:
> list(meat/1);
meat(Veau_marengo) -> ;
meat(Poulet_roti) -> ;
{}
You can now execute the modified program, and we end with quit since we do not
want to keep the current state.
> meat(p);
{ p=Veau-Marengo}
{ p=Poulet-roti}
> main-course(p);
{ p=Veau-Marengo}
{ p=Poulet-roti}
{ p=Bar-aux-algues}
{ p=Chapon-farci}
> quit ;
Bye .......
This section explains some of the most frequent errors which may occur when
using Prolog II+.
CODE OVERFLOW
Prolog must be re-started with more space for the code (option -c on the command
line). If the automatic reallocation system is not deactivated when Prolog starts, a
certain number of reallocations will occur before overflow, and the code will then
take up all the space available on the Prolog machine. In this case, you must if
possible increase Prolog’s total memory, or else verify the functioning of the
program, which is doubtless abnormal.
0.4.2 Interruption.
© PrologIA
Aociation Prolog
R 0 - 6 Reference Manual HERITAGE
> insert;
rr -> rr;;
{}
> rr;
<Ctrl-C>
USER INTERRUPT
{}
>
This error occurs because the user has violated the following principle: all rules
having the same name and arity must be consecutive (two rules having the same
name/arity cannot be separated by a comment or a rule with a different name/arity).
The configurations given below are therefore incorrect .
qq(x) -> ;
rr(y) -> ;
qq(z) -> ;
The meanings of most of the syntax error messages are clear. If necessary, please
refer to the syntax specifications in Chapter 1 for additional explanations.
Explanations of some of these messages are given below.
© PrologIA
Aociation Prolog
This error message shows where the syntax was not respected. In this case, an
argument is missing.
A string must be contained on one line only, if the line is not hidden. Remember
that a string starts and finishes with the character ("). If (") is part of a string, it
must be doubled.
The only correct access to a rule is an identifier starting with two letters in Prolog II
syntax. Therefore, the head cannot be a variable (whose name starts with only one
letter) a number or a string.
If the first word of the name starts with at least two letters, it is the name of a relation
or a constant (this is called an identifier in the Prolog II syntax) and it is a correct
access to a rule. If not, it is the name of a variable. For example :
© PrologIA
Aociation Prolog
R 0 - 8 Reference Manual HERITAGE
There are several possible results, defined by a flag in the Prolog start-up command,
when execution of an undefined predicate is attempted:
uW : displays a warning and continues program execution,
uF : fails,
uE : generates the error.
The other execution error messages related to the use of block, block_exit, and val
need no explanation.
We recommend that you start Prolog with the -f uE option, which provides a precise
diagnosis when an incorrect call is made to a rule which does not exist (caused by a
typing error for example). If you want to call a rule, and cause a failure if it does
not exist, first test that it is present, with current_predicate.
© PrologIA
Aociation Prolog
HERITAGE
1.1 Notation
In this manual, context free rules will be used to describe the syntax of the formulas
occurring in Prolog. The notation used here is the same as that adopted by the
Prolog standardization commission:
• The symbol "=" is used as the rewrite symbol, and a rule ends with a ";". The
elements of the right member of a rule are separated by ",".
• Elements enclosed by curly brackets {…} may occur any number of times
(including zero).
• A vertical bar …|… signifies that the two elements it separates are alternatives.
When brackets are used (…|…), this means that the result of the alternative
appears in a list of symbols.
• The functioning of some re-writing rules depends on which syntax options have
been selected: rule whose first member is indexed by P are only activated if the
Prolog II syntax is selected (for example separator P ). Rules whose first
member is indexed by E are only activated if the Edinburgh syntax is selected
(for example graphic_charE).
• Other rules indexed by letters control options chosen at start-up, and are only
valid in certain cases.
©PrologIA
Aociation Prolog
R1-2 Reference Manual HERITAGE
The complete Prolog syntax is given at the end of this chapter. The following pages
contain some fairly simple extracts from this syntax, with explanatory comments.
©PrologIA
Aociation Prolog
There are several ways of inserting comments into a program. From the syntactical
point of view, a comment is identical to a space, and can be inserted anywhere a
space is permitted:
• The character "%" indicates the beginning of a comment which starts at the "%"
and finishes at the end of the same line.
• The symbols "|*", "*|" and "/*", "*/" are also used to denote a comment, which
consists of these symbols and the characters they enclose.
These symbols are not interchangeable. If a comment starts with a "|*" it must end
with a "*|" and if it starts with a "*/" it must end with a "/*". In addition, these
comments can be nested: for example the following text is regarded as being a
single comment:
• A character string written at the higher level, i.e. where a rule is expected, is also
taken to have the value of a comment.
1 . 3 Variables
Variables are used to denote constants as well as more complex entities. Here is
their syntax:
So, for variables, there is a basic syntax and an extended syntax, of which there are
two: Prolog II or Edinburgh. When starting Prolog II+ you must indicate whether
you wish to use a different syntax from the extended Prolog II syntax. In addition,
since these two syntaxes are incompatible,2 it is not possible to have both extensions
at the same time.
2In Prolog II, the expression x is a variable, but not in Edinburgh Prolog. Similarly, the name
Pierre is not a variable in Prolog II, but it is in Edinburgh!
©PrologIA
Aociation Prolog
R1-4 Reference Manual HERITAGE
1 . 4 Constants
The simplest data items are constants. There are four types: identifiers, integers, real
numbers and character strings.
prefix_limit = ":" ;
prefix = [ name , { prefix_limit , name } ] ;
integer_number = digits ;
integer_number = "0b", binary_number ;
integer_number = "0o", octal_number ;
integer_number = "0x", hex_number ;
integer_number = "0'", character ;
©PrologIA
Aociation Prolog
Identifiers
The presence of the character ":" indicates that the representation of the identifier is
complete. This character can be redefined and replaced by a graphic character, as
described in Chapter 3.
The following complete identifiers are correct and all represent different identifiers:
data:peter grammar:singular
x:peter lexicon:name
sys:write sys:env:files
:peter grammar:plural
Please note: the empty string is a valid prefix, and thus the identifier :peter is
syntactically correct.
©PrologIA
Aociation Prolog
R1-6 Reference Manual HERITAGE
The syntaxes for abbreviated representation of identifiers and for variables are very
similar, and together they define what is referred to as an "identifier" in many other
programming languages. To help distinguish between them, it is useful to
remember that in the Prolog II syntax, variables start with one letter or the character
"_", whereas the abbreviated representations of identifiers start with at least two
letters. In the Edinburgh syntax they are differentiated by the first character; for
variables it must be upper-case or the "_" character, and for abbreviated
representations of identifiers it must be lower-case.
Numbers
The syntax for numbers in Prolog II+ is virtually the same as in most other
programming languages.
Integers are signed and are normally used to represent any value. Prolog II+ accepts
several integer syntaxes.
An integer can be expressed in the following bases: 2, 8, 10, 16. To do this, the
integer mantissa must be preceded by 0b, 0o, 0, 0x respectively. A non-prefixed
mantissa will be considered as decimal base by default. Small integers less than
256 can also be expressed using the prefix 0' followed by a character, and the
integer value will then be the character code3 . For example, the following
expressions represent integers:
3 Be careful with extended characters. Their value depends on the chosen mode: ISO 8859-1 or
the host machine code.
©PrologIA
Aociation Prolog
Expression: Value:
0b110 6
0o110 72
0110 110
0x110 272
0'A 65
It should be noted, that in contrast to other languages, real numbers must include an
explicit exponent. Therefore the expression -12.34 does not define a real number,
but a pointed pair formed by the integers -12 and 34. On the other hand, 12.34e0 is
a correct real. This is the default choice in Prolog II syntax, but it can be modified
via an option on the command line at start-up, to obtain a standard syntax (see
section 2.3 of the User's Manual).
Reals are encoded in double precision, corresponding to the double type in the IEEE
64 bits standard. The letter introducing the exponent can be e, E, d or D, but e and E
are preferable.
Character strings
Character strings are enclosed by double quotes """. All the printable characters
can appear in a string without any special precautions, except for the """ character
which must be doubled, and if appropriate the "\" character which must be doubled
if interpretation of "\" is active (see the behavior options in section U 2.3.). For
example, the string below is correct:
In general, the "\" does not necessarily have to be doubled. When interpretation of
"\" is active (see section 2.3 of the user's manual), it must be doubled if it forms an
expression (escape sequence) representing another character, with the characters that
follow it. In all other cases there is no need to do so.
"Use \ followed by RETURN to ignore an end of line
"Hexadecimal codes must start with \\x"
\f form feed
\n newline. When this character is written, if necessary it is replaced by the
character(s) required to produce a new line on the output unit.
\r carriage return
\t tabulation
©PrologIA
Aociation Prolog
R1-8 Reference Manual HERITAGE
Other expressions can be used to represent characters not existing on the host
machine (see section 1.9.5).
Any character in a string can be specified by means of the number which is its
internal code. For example, the expressions "\033" and "\x1B" both define a string
consisting of a single character whose code is 27. The null character (i.e. the
character whose internal code is the number 0) must not appear in character strings.
A character string can take up several lines. To do this, the last character on each
relevant line except the last one must be "\". The "\" and the end of line character
will be ignored. For example, the expression:
"this is a stri\
ng on two lines"
Please note: When writing a Prolog program, a symbolic data item can be
represented either by a character string, or by an identifier. Since identifiers are
themselves coded as atomic objects, it is generally agreed that they constitute a more
efficient representation of symbolic objects than strings.
• or by the character "period" in which case there are exactly two sons,
• or by " <>" or "<->" or " <-\ ->" or " <-\ -\ ->" or … where the number of dashes
corresponds to the number of sons.
• <--->
/ \ / | \
"a" • ___/ | \____
/ \ / | \
"b" • plus <---> <--->
/ \ / | \ / | \
"c" nil times 5 8 times 5 8
Figure 1.1
©PrologIA
Aociation Prolog
<--->
/ | \
or "c" <--->
/ | \
and "a" <--->
/ | \
and <---> "b"
/ | \
or "c" <--->
/ | \
and "a" <--->
/ | \
and <---> "b"
/ | \
or "c" <--->
/ | \
and "a" <--->
/ | \
and <---> "b"
/ | \
Figure 1.2
Of course, this simplification presupposes that n is not zero. The last two trees can
therefore be represented in standard form as:
plus or
/ \ / \
times times "c" and
/ \ / \ / \
5 8 5 8 "a" and
/ \
or "b"
/ \
"c" and
/ \
"a" and
/ \
or "b"
/ \
"c" and
/ \
"a" and
/ \
or "b"
/ \
Figure 1.4
©PrologIA
Aociation Prolog
R 1 - 10 Reference Manual HERITAGE
The notion of an infinite tree is sufficiently new (and therefore unfamiliar) to justify
spending some time clarifying this concept. Basically, a tree is infinite if it
possesses an infinite branch. We are especially interested in those infinite trees
which, together with finite trees, form the set of rational trees, that is trees whose
set of subtrees is finite. Look again at the last two examples in figure 1.4. The set
of their subtrees is given in figure 1.5.
These sets are finite and so the trees in figure 1.4 are rational trees. Since a rational
tree contains a finite set of subtrees we can represent it using a finite diagram:
which merges all the nodes which produce the same subtrees (figure 1.6).
Figure 1.6
©PrologIA
Aociation Prolog
Figure 1.7
We must therefore be very careful, because different diagrams can represent the
same tree.
In order to represent trees we use formulas called terms. First, let us examine the
concept of a strict term:
Strict terms are "true" terms. However, for the sake of convenience, we will extend
the syntax of strict terms (without altering their meaning) by permitting:
©PrologIA
Aociation Prolog
R 1 - 12 Reference Manual HERITAGE
To transform a term into a tree, it is necessary to assign trees to its variables. This
operation is called tree assignment, which is a set X of the form:
X={x1:=x1, x2:=x2, …}
where the xi's are distinct variables and the ri's are trees. We also introduce the
following notations: if x1,x2 are two trees and if ri,r2,…,rn is a sequence of n trees
then (x1.x2) and <ri,r2,…,rn> denote respectively the trees:
If t is a strict term containing a subset of the set of variables of the tree assignment X
= {x1:=r i, x2:=r 2, …} then the expression t/X will denote the tree obtained by
replacing the variables xi by the corresponding trees ri. More precisely:
- t/X = ri if t = xi ;
if X contains the same variable as S and if X is such that the trees pi/X are
respectively equal to the trees qi/X and that the trees si/X are respectively different
from the trees ti/X.
Using these concepts it is now possible to represent the first tree in figure 1.1 by:
plus(times(l2,l1),times(l2,l1)) /{} or
©PrologIA
Aociation Prolog
1 . 6 Operators
The operators represent a clear and flexible way of expressing certain trees.
©PrologIA
Aociation Prolog
R 1 - 14 Reference Manual HERITAGE
The term which is the first member of a rule (rule head) must be:
- either an identifier
or
- a tuple whose first argument is an identifier
For example, the terms: go,father_of(x,y) or <father_of, x, y> can be correct rule
heads, while - contrary to what happens in Prolog II - terms such as <<father_of,
x>, y> or <masc.sing, x, y> cannot.
For the moment, we will ignore the concept of a parasite which, as we will see later,
is an ad hoc way of calling subprograms not written in Prolog.
4The complete rule syntax is given in the last section of this chapter.
©PrologIA
Aociation Prolog
generate a set (usually infinite) of particular rules which operate on the following
trees:
t0/X t1/X … tn/X
These rules are obtained by considering all possible tree assignment containing the
variables of the generating rule:
X = {x1:=s1,… ,xm:=sm}
Definition 1: The specified facts are the trees that can be executed in one or more
steps by means of the rewrite rules.
Definition 2: The set of specified facts is the smallest subset A of trees which
satisfy the logical implications.
It can be shown that the smallest set of Definition 2 exists and that Definitions 1
and 2 are equivalent.
©PrologIA
Aociation Prolog
R 1 - 16 Reference Manual HERITAGE
Find all the tree assignments X={x1:=ri,… ,xm:=rm} for which the trees t1/X,…
,tn/X are facts.
To solve this problem the computer produces all the derivations of the form:
The Ti's are sequences of terms called goals and the Si's are systems of equations
and inequations having at least one solution. S0 is the empty system: { }. The
derivation (Ti,Si) (Ti + 1,Si + 1), is best explained by the following three lines:
(1) (q0 q1 … qn , S)
(2) p0 -> p1 … pm
The first line represents the form of the current pair (Ti,Si), the second, the rule
which is applied and the third, the resulting pair (Ti + 1,Si + 1). Before applying the
rule it is necessary to rename its variables so that none of them occur in (Ti,Si). It
is also necessary to check that the new system Si + 1, which is obtained by adding
the equation {q 0 =p 0 } to S i', has at least one solution. This check is called
unification of q0 with p0.
The purpose of the previously defined derivations is to compute the pairs (Tj,Sj)
whose Tj sequence is empty and which can therefore be derived from (T0,{}). It
can be shown that the tree assignments X which solve Sj are the answers to our
problem. The result printed by the computer is a simplified form of the system Sj in
which inequations are omitted.
It can be shown that Prolog II+ checks perfectly whether a system of equations and
inequations has at least one solution.
From a more practical point of view, when Prolog is called, the computer displays
the prompt ">", meaning that Prolog is waiting for a sequence of goals T0=t1 … tn.
It will try to execute these goals in every possible way ((T0,{}) … (Tj,Sj)with Tj
empty), and will then print the corresponding systems S j. Just as we have a
constraint on rules, we also have the following constraint on goals.
At each step, the leftmost branches of the trees representing the goal to be
executed must be represented by an identifier.
©PrologIA
Aociation Prolog
Parasites provide Prolog with the use of external subprograms. To explain how
these subprograms are called we have to go back to the first of the three lines which
describe the general mechanism of Prolog: if q0 is a parasite, then instead of trying
to apply a rule, the system will execute the corresponding subprogram. Some
parasites appear in the predefined rules which create the interface between external
sub-programs and Prolog rules. This set of predefined rules constitutes a complete
programming environment allowing the user to perform the tasks described below.
• To structure and modify the set of rules which constitutes the current Prolog
program (see Chapter 3 - Structuring and modifying rules);
The programmer can also introduce an additional set of predefined rules referring to
his own parasites written in a language other than Prolog (C, Fortran, Pascal, …).
(see chapter 7 "Extension with external languages" or Appendix D "Adding external
rules (parasite method)".
Two predefined rules are directly related to the fundamental mechanism of Prolog:
dif and eq.
dif is the most important one. It introduces an inequation into a system of equations
and inequations. More precisely, the execution of dif(x,y) adds the inequation x y
to Si and checks that this new system Si +1 still has a solution.
eq(x,x) ->;
The following rules are not exactly predefined rules, but the Prolog system behaves
as if these rules exist. They are use to transform a list of goal into a single goal.
p.q-> p q ;
nil -> ;
©PrologIA
Aociation Prolog
R 1 - 18 Reference Manual HERITAGE
Notes:
2. exprn represents the sequence of rules expr1 ... expr1000 in Prolog II syntax,
and expr1 ... expr1200 in Edinburgh syntax.
4. Rules 7.3 and 7.4 define two alternative tuple syntaxes. In Edinburgh syntax,
only the second syntax is available. The equivalences are as follows:
<x,y> x , y )
©PrologIA
Aociation Prolog
6. In Prolog II syntax, rule 4 and rules 7.6, 8.1 and 8.2 define two alternative
syntaxes for list notation. The equivalences are as follows:
[a|b] a.b
[a,b] a . b . nil
[a,b,c,d] a . b . c . d . nil
[a,b,c|d] a.b.c.d
In Prolog II syntax, the two list syntaxes can still be used together in the same
program
[ a , b | c.d.nil] a . [b , c , d]
It should be noted that in Prolog II syntax, the operators are not authorized at the
first level of terms in the rule body, and that the expression must be bracketed in
such a case. In Edinburgh syntax, there is no restriction.
The following table describes the operators in Prolog II+ syntax. The table
indicates the syntactic term constructed corresponding to each operator.
©PrologIA
Aociation Prolog
R 1 - 20 Reference Manual HERITAGE
Note 1 : The trees corresponding to the unary operators + and - are evaluated when
analyzed if their argument is an integer constant.
Note 2 : Operators can be written with single quotes. Their only function, in
Prolog II+, is to extend identifier syntax. Therefore the only functional
notation for a functor declared as an operator is the tuple notation. If you
are unsure about the constructed term, it can always be tested by splitting
the term:
> eq(F(X,Y),1'<'2);
{F=inf, X=1, Y=2}
©PrologIA
Aociation Prolog
Notes :
1. Rule L4 defines the basic syntax for variables; two extensions to this syntax
are given by rule L5.P (Prolog II syntax) and rule L5.E (Edinburgh syntax).
In both cases the extension is the same: a sub-set of names, which would have
been abbreviated representations of identifiers in the basic syntax, is added to
the set of variables.
These two extensions are optional and are mutually incompatible. It is the
user who chooses the syntax when starting a Prolog session: please refer to
the User's Manual.
3. A command line option can make the exponent optional, but this creates an
ambiguity with lists in Prolog II syntax: 1.2 is read as a real in input. This
rule is only valid if this option is chosen. Please refer to the User's Manual,
section 2.3.
4. Rules L2.1 and L2.2 define the basic identifier syntax. Rules L2.3 and L2.4
define the extension for the Edinburgh syntax.
©PrologIA
Aociation Prolog
R 1 - 22 Reference Manual HERITAGE
L8 integer_number = digits ;
©PrologIA
Aociation Prolog
A description adapted to the host machine character set will be given in the User's
Manual in section 3.3.
Rule C6.2 represents the same set of characters as rules C7.2 and C8.1, but the
three rules are not all valid simultaneously. C6.2 with a P index is valid in
Marseilles syntax, C7.2 and C8.1 with an E index are valid in Edinburgh syntax.
When the syntax changes these characters act differently.
Rule C5 is valid if the character delimiting the prefix and suffix in the complete
identifiers has not been redefined. It can then have the value of a graphic character.
©PrologIA
Aociation Prolog
R 1 - 24 Reference Manual HERITAGE
C123 accent = " ` " | " ' " | "^ " | ": " ;
The following notes only apply when interpretation of the "\" is active.
Notes :
1. Prolog II+ has an execution mode (see U2.3) in which accent_escape is not
authorized and is replaced by format_escape. In this mode, these rules (C2.2,
C10.3, C11) are not valid. In all other cases, accent_escape can be used as
input to specify accented characters. For output, Prolog uses an
accent_escape for the accented characters in the ISO set 8859-1 that do not
exist in the host system character set.
©PrologIA
Aociation Prolog
Example:
Table 1
Accented characters in the ISO code 8859-1
The table below shows the accented characters and their corresponding expression
in the form of accent_escape . For example, you can observe that the following two
character strings:
are equivalent.
©PrologIA
Aociation Prolog
R 1 - 26 Reference Manual HERITAGE
set_alias(i,t)
Defines an alias.
From the place where and moment when this directive is detected, the reader
replaces certain occurrences of the identifier i (called an alias) with the term t
(called value). This definition is deactivated at the end of compiling of the
highest level of nesting.
The value t must be an integer, real or character string.
The alias i must be an identifier.
Only identifiers positioned as arguments (not rule heads) and not explicitly
prefixed in the text are replaced by the alias value. It is therefore possible to
conserve an identifier with the same abbreviated name as an alias, by prefixing
it explicitly in the text. It is therefore also logical that the prefix of the alias
should be ignored in the directive. Nevertheless, if this alias is already
defined, reading of a directive with an alias explicitly prefixed in the text will
prevent it being replaced, and will therefore allow it to be redefined
(accompanied by a warning message).
©PrologIA
Aociation Prolog
The val/1 predicates makes it possible to define an alias using another alias.
Examples with comments:
> insert;
set_alias(foo,44);
set_alias(foo,55); 44 is redefined as 55
-> set_alias(44,55) : BAD ARGUMENT TYPE
> insert;
set_alias(macro1,22);
set_alias(aa:macro1, 44); Here the prefixing is the means of redefinition
WARNING: macro1 ALREADY DEFINED, NEW VALUE TAKEN INTO ACCOUNT
rg1(macro1)->;
rg1(aa:macro1)->;
-> insert; Here, 2nd level of compiling nesting
set_alias(macro2,val(2 * macro1)); Definition using another macro
rg2(macro2)->;
rg2(macro1)->;
; We return to the 2nd compiling level
macro1(macro2)->; Automatic protection of rule heads
macro1(macro1)->;
;
{}
> rg1(I);
{I=44} Here the new value is taken into account
{I=aa:macro1} Here, no replacement of prefixed identifier
> rg2(I);
{I=88}
{I=44} The macro defined at the 1st compiling level
has been taken into account in the 2nd level
> macro1(I);
{I=88} The macro defined in the 2nd compiling level
has been taken into account in the first level
{I=44}
> insert; Here a new compiling operation starts
rg(macro1)->;
rg(macro2)->;
;
{}
> rg(I);
{I=macro1} The definitions have been cancelled
{I=macro2}
©PrologIA
Aociation Prolog
R 1 - 28 Reference Manual HERITAGE
©PrologIA
Aociation Prolog
HERITAGE
2.1 Control
2.2 Freeze
2.3 Infinite trees
2.4 Some advice about recursive programming
2.5 Metastructures
2.1 Control
At each stage in program execution, the Prolog interpreter must make two choices:
(1) It selects one goal in a sequence of goals to be executed. The first element of
the sequence is always chosen, i.e. to execute the sequence q0 q1 … qn it
selects q0, and then processes the remaining ones.
(2) To execute a goal, a rule must be selected whose head unifies with the goal to
be executed. Here also, the first candidate rule is chosen.
where rule(t,q) is a predefined rule (see Chapter 3) which matches successively with
all the rules of the program whose head matches t and whose body matches q.
using the program below, the original goal will be generated. The program loops
and ends in a stack overflow or a user interrupt. The program can be written
correctly by removing the "left recursivity".
taller(Michel,Alain) ->;
taller(Alain,Henry) ->;
taller(x,y) -> taller(x,z) taller(z,y);
>taller(Michel,x);
{x=Alain}
{x=Henry}
© PrologIA
R2-2 Reference Manual Aociation Prolog
HERITAGE
taller'(Michel,Alain) ->;
taller'(Alain,Henry) ->;
taller_or_equal(x,x) ->;
taller_or_equal(x,y) -> taller(x,y);
Example 2:
This example enumerates all the lists constructed with 1. If we keep the same
(wrong) order of rules, the infinite list will be computed first. By changing their
order, we can obtain the correct solution.
number(1.x) -> number(x);
number(nil) ->;
>number(x);
LOCAL STACK OVERFLOW
- rules having the same head as the rule containing the "!";
- rules which could have been used to execute the terms between the start
of the body and the "!".
The use of this parasite is illustrated by the example below.
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);
1If the automatic reallocation system is not deactivated when Prolog starts, a certain number of
reallocations will occur before overflow.
© PrologIA
Aociation Prolog Control of program execution R2-3
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) !;
{u=red.big}
"Not"
not(p) -> p ! fail;
not(p) ->;
> woman(Cristina);
{}
> woman(Michel);
> woman(x) eq(x,Cristina);
>
^(X,Y)
X must be a variable and Y can be any term.
© PrologIA
R2-4 Reference Manual Aociation Prolog
HERITAGE
^(X, Y) means "there exists X such that Y is true", and is equivalent to a call to
Y. It only makes sense to use this predicate (which is also an operator) in the
predicates bagof/3 and setof/3, to indicate the existential variables and remove
them from the set of free variables.
bagof(x, p, l)
For each different instantiation of the set of goal p's free variables, bagof(x, p,
l) unifies l with the list of all the solutions x when p is executed. These
variables are non existential and do not occur in the term x. Each list l is
constructed according to the order of the solutions found. E.g.:
aa(2,1) -> ;
aa(1,2) -> ;
aa(1,1) -> ;
aa(2,2) -> ;
aa(2,1) -> ;
>bagof(X, aa(X,Y),L);
{Y=1, L= 2.1.2.nil}
{Y=2, L= 1.2.nil}
> bagof(X,Y^aa(X,Y),L);
{L=2.1.1.2.2.nil}
>
block(e,b), block_exit(e)
block is a predefined rule which immediately ends the execution of a goal b.
In most cases, it is used for error recovery. We can state that:
© PrologIA
Aociation Prolog Control of program execution R2-5
HERITAGE
block(end_command,always(read_and_exec));
repeat ->;
repeat -> repeat;
© PrologIA
R2-6 Reference Manual Aociation Prolog
HERITAGE
Interruption
A Prolog program can be interrupted at any time by typing a certain key,
depending on the system used (for example <Ctrl-C>). This interruption is
processed by the Prolog error management system and corresponds to error
16. So this interruption can be recovered by the user. Otherwise, the Prolog
command level is reached and the message: USER INTERRUPT is
displayed.
bound(x)
bound(x) is executed if x is bound and fails otherwise. A variable is
considered bound if it has been unified:
dif(t1,t2)
all_different(nil) ->;
© PrologIA
Aociation Prolog Control of program execution R2-7
HERITAGE
Using these two primitives, the user can write a program to calculate
permutations. Simply assert that a list of integers is considered and that each
integer appears only once in the list.
permutation(x1,x2,x3,x4) fl
all_different(x1.x2.x3.x4.nil)
digit(x1) digit(x2) digit(x3) digit(x4);
digit(1) ->;
digit(2) ->;
digit(3) ->;
digit(4) ->;
It is clear in this example that Prolog first introduces all the inequalities before
executing the standard non-deterministic program. This results in a much
clearer and more efficient program.
The use of dif also makes it possible to write programs which would behave
incorrectly if they were defined using the cut. For example, the definition of
the relation "x is an element of l with a value of v" can be written as follows:
element(x,nil,false) ->;
element(x,x.l,true) ->;
element(x,y.l,v) -> dif(x,y) element(x,l,v);
> element(x,1.2.nil,v);
{x=1, v=true}
{x=2, v=true}
{x#1, x#2, v=false}
> element(x,1.2.nil,v);
{x=1, v=true} % a single solution !!
> element(2,4.2.3.nil,false);
{} % success !!
default(t1, t2)
The predefined rule default enables the following check to be performed: if t1
can be executed then it will be executed in all possible ways, otherwise t2 is
executed. At first sight, it is easy to think that this primitive could be
performed using '!', but in fact this is impossible.
Here is an example of how to use this rule:
answer(p) -> default(p,outml("nobody"));
man(john) ->;
man(peter) ->;
© PrologIA
R2-8 Reference Manual Aociation Prolog
HERITAGE
> answer(man(x));
{x=john}
{x=peter}
> answer(woman(x));
nobody
{}
eq(t1, t2)
Unification of t1 and t2: simply corresponds to the rule eq(x,x) ->;
fail
Predefined rule which always causes a failure (backtrack).
findall(x, p, l)
Unifies l with the list of all solutions x when p is executed.
free(x)
Is executed if x is not bound.
list_of(x, y, p, l)
Provides a sorted list, with no repetitions, of all individuals that fulfill a certain
requirement.
x is a variable.
y is a list of variables.
p is a Prolog term containing at least all these variables.
For each set of values of y, this primitive unifies l with the list of values of x so
that p is true (i.e. so that p executes).
The order of the list l is identical to the order defined on terms (see
term_cmp/3).
Example: Prolog containing the following data base:
man(big, michel, 184) ->;
man(big, alain, 183) ->;
man(big, henry, 192) ->;
man(small, nicolas, 175) ->;
man(small, julien, 176) ->;
man(small, gilles, 120) ->;
> list_of(x,t.nil,man(t,x,h),l);
{t=big, l=alain.henry.michel.nil}
{t=small, l=gilles.julien.nicolas.nil}
not(X)
Is described by the following rules :
not(X) :- X,!,fail.
not(X).
repeat
Is described by the following rules :
repeat ->;
repeat -> repeat;
© PrologIA
Aociation Prolog Control of program execution R2-9
HERITAGE
setof(x, p, l)
For each different instantiation of the set of goal p's free variables, setof(x, p,
l) unifies l with the list of all the solutions x when p is executed. The variables
are non existential and do not occur in the term x. Each list l is sorted and
contains no repetitions. Its order is identical to the order defined on the terms
(see term_cmp/3).
Example:
aa(2,1) -> ;
aa(1,2) -> ;
aa(1,1) -> ;
aa(2,2) -> ;
aa(2,1) -> ;
>setof(X, aa(X,Y),L);
{Y=1, L= 1.2.nil}
{Y=2, L= 1.2.nil}
> setof(X,Y^aa(X,Y),L);
{L=1.2.nil}
>
or(x,y)
Defines a logical "or", transparent to the cut. Example:
> op(900,xfy,or);
{}
> enum(i,4) (eq(i,1) or eq(i,2));
{i=1}
{i=2}
> enum(i,4) ([eq(i,3),'!'] or [outl(no),fail]);
no
no
{i=3}
>
2.2 Freeze
This predefined rule efficiently solves a problem which often occurs in Prolog: the
need to postpone certain decisions for as long as possible. In concrete terms, freeze
gives the user the ability to delay program execution until sufficient information is
available, or to wait for a given variable to be assigned a value before continuing.
This feature combines the advantages of declarative programming with efficient
execution.
freeze(x,q)
The purpose of this rule is to postpone the execution of q as long as x is
unknown. To be more precise,
© PrologIA
R 2 - 10 Reference Manual Aociation Prolog
HERITAGE
length'(nil,n) -> ;
length'(e.l,n) ->
dif(n,0) val(sub(n,1),n') length(l,n');
© PrologIA
Aociation Prolog Control of program execution R 2 - 11
HERITAGE
infinite
no_infinite
These rules are used to define the way in which the result will be printed: the
infinite option must be activated if you want to print solutions containing
infinite trees.
The following program uses freeze to check that a tree represents and will
always represent a finite tree. It is an indirect way of implementing the
occur_check test. It checks that a tree does not have two identical subtrees in
the same branch.
finite_tree(x) -> finite_branch(x,nil);
finite_branch'(x,l) ->
out_of(x,l) dominates(x,l') finite_branches(l',x.l);
finite_branches(nil,l) ->;
finite_branches(x.l',l) ->
finite_branch(x,l) finite_branches(l',l);
dominates(x1.x2,x1.x2.nil) -> !;
dominates(x,x') -> tuple(x) ! split(x,x');
dominates(x,nil) ->;
infinite_flag
The value of this symbol (0 or 1) indicates whether infinite or no_infinite is
active. This value can be tested using the predefined rule val.
© PrologIA
R 2 - 12 Reference Manual Aociation Prolog
HERITAGE
equations(t,t',l)
This predefined rule is used to transform a finite or infinite tree t into a list of
equations l which has the solution t. t' indicates the variable which has the
solution t. This is the primitive that is used to print solutions when the infinite
option is active. Let us see how it could be used in an example:
> infinite eq(x,ff(ff(x))) equations(x,t',l) out(t')
outm(" : ") outl(l) ;
v131 : eq(v131,ff(v131)).nil
However, one of the main uses of this rule is to add infinite trees. The assert
primitive is used (see next chapter) to add a rule.
add_infinite_tree(t) ->
equations(t,t',l)
assert(my_tree(t'),l) ;
The program above will run endlessly without overflowing, because the recursion
operates on the last literal in the rule. In contrast, the program below will overflow,
because the recursion will accumulate the literals to be executed (non terminal
recursion):
repeat -> out(1) repeat out(2);
© PrologIA
Aociation Prolog Control of program execution R 2 - 13
HERITAGE
> repeat ;
11111111111111111111111...
-> RECURSION STACK OVERFLOW1
>
Also, the information to be stored will accumulate because certain choices remain
for the executed rule. The execution of the goal using the following definition will
generate an overflow error by accumulation of choice points.
> insert;
repeat -> repeat ;
repeat ->;;
{}
> repeat fail;
-> RECURSION STACK OVERFLOW2
>
In contrast, the following program will run indefinitely (fortunately, we can interrupt
it with Control-C!):
repeat -> ;
repeat -> repeat;
The choice cut "!" enables the garbage collector to recover extra space, by removing
the choice points. It should be noted however, that if the "!" is placed at the end of a
rule, we lose the terminal recursivity.
repeat -> out(1) repeat !;
repeat ->;
The above program will generate an overflow error (the "!" is a literal to be
executed), while the program below will run indefinitely:
repeat -> out(1) ! repeat ;
repeat ->;
2.5 Metastructures
2.5.1 Creation
In PrologII+ you can attach a variable to a list of terms. This is called a meta-
structure or an allocated variable and allocated terms.
The special feature of these variables is that unification with a known term or with
another allocated variable is replaced by calls to user predicates.
1If the automatic reallocation system is not deactivated when Prolog starts, a certain number of
reallocations will occur before overflow.
2If the automatic reallocation system is not deactivated when Prolog starts, a certain number of
reallocations will occur before overflow.
© PrologIA
R 2 - 14 Reference Manual Aociation Prolog
HERITAGE
The parameters for each predicate are imposed. The first parameter will be the
allocated variable itself, the second parameter will be the term we are trying to unify
it with, and the third parameter will be the corresponding allocated term in the list.
A term can be linked to a variable using two built-in predicates: new_tlv/3 and
add_tlv/3 (TLV: Term Linked to Variable).
new_tlv(v, t, i)
Attaches term t to variable v. The list of terms allocated to variable v will
therefore be reduced to a single item: the term t. If v was already an allocated
variable, the previous list is lost. If v is not a variable an error is generated.
The third argument i must be an identifier. It is the name of the user rule
described above (arity 3) that will be called when an attempt is made to unify
variable v with a known term or with another allocated variable.
add_tlv(v, t, i)
Adds term t to the variable v. The list of terms allocated to variable v will
therefore be increased by one item: term t. If v was not already an allocated
variable, this predicate has the same effect as the previous one. If v is not a
variable an error is generated. The third argument i has the same meaning as
in the previous predicate.
The order in which the user predicates will be called is not specified.
Example:
> insert;
rule1(V,T,A) -> outm("Rule1 ") out(T) outm(" ") outl(A);
rule2(V,T,A) -> outm("Rule2 ") out(T) outm(" ") outl(A);
rule3(V,T,A) -> outm("Rule3 ") out(T) outm(" ") outl(A);
;
{}
> new_tlv(V,1.2.nil, rule1) add_tlv(V,3.4.nil,rule2)
add_tlv(V,5.6.nil,rule3) eq(V,foo);
Rule1 foo 1.2.nil
Rule2 foo 3.4.nil
Rule3 foo 5.6.nil
{V@rule1(1.2.nil).rule2(3.4.nil).rule3(5.6.nil).nil}
set_tlv(v, l)
where l must be a list of elements having the form i(t), i and t having the same
signification that in the two last predicates. If the list l has N elements, the call
of this predicate is equivalent to a first call to new_tlv/3, followed by N-1 calls
to add_tlv/3.
© PrologIA
Aociation Prolog Control of program execution R 2 - 15
HERITAGE
Example:
> set_tlv(X,foo(1).aa(2).nil);
{X@foo(1).aa(2).nil}
2.5.2 Recovery
The list of terms allocated to a variable can be obtained by means of the following
predicate:
get_tlv(v, l)
Unifies l with the list formed by the terms allocated to variable v. Each of
these terms is encapsulated by the user predicate called when an attempt is
made to unify this variable with another allocated variable or a known term.
This list l therefore takes the form: id1(t1).id2(t2)....nil in which each
identifier id (user predicate) is associated with the corresponding term. If v is
not a variable, l is unified with nil.
Example:
> new_tlv(V,1.2.nil, rule1) add_tlv(V,3.4.nil,rule2)
add_tlv(V,5.6.nil,rule3) get_tlv(V,T);
{V@rule1(1.2.nil).rule2(3.4.nil).rule3(5.6.nil).nil,
T=rule1(1.2.nil).rule2(3.4.nil).rule3(5.6.nil).nil}
unify_tlv(t1, t2)
Performs normal unification between the two terms t1 and t2. Let's look at all
the possible cases:
- If t1 and t2 are not allocated variables the predicate is equivalent to eq/2.
- If t1 is an allocated variable:
- If t2 is an ordinary variable, it will therefore become an allocated
variable when it is unified with t1.
- If t2 is a known term, t1 will therefore become this known term when
it is unified with t2 (the list of allocated terms will then be lost).
- If t2 is also an allocated variable, when t1 and t2 have unified they will
designate an allocated variable whose list of allocated terms is the
concatenation of the two initial lists from t1 and t2.
Example:
> new_tlv(V,1.2.nil,foo) unify_tlv(V,3);
{V=3}
> new_tlv(V,1.2.nil,foo) unify_tlv(Z,V);
{V=Z,V@foo(1.2.nil).nil,Z@foo(1.2.nil).nil}
© PrologIA
R 2 - 16 Reference Manual Aociation Prolog
HERITAGE
2.5.4 Output
The term after @ is the list of terms allocated to the variable, presented in an
identical manner to the get_tlv/2 predicate.
Example:
> new_tlv(x,zz,foo);
{x@foo(zz).nil}
2.5.5 Example
This program attaches a variable to the set of its possible values. If there is only one
value left, it is assigned to the variable.
insert;
% If X is a new variable, attaches the set of
% values L to it, otherwise attaches the intersection
be_in(X,L) -> get_tlv(X,L1) be_in(L1, X, L);
be_in(nil,X,L) -> ! new_set(X,L);
be_in(L1,X,L) -> get_values(L1, L2) inters(L,L2,L3)
attach_or_affect(X, L3);
get_values([],[])->!;
get_values(t_ag(L1).L2, L)-> get_values(L2,L3)
conc(L1,L3,L);
% Concatenation of 2 lists
conc(nil,L,L)->;
conc(X.L1,L2,X.L3) -> conc(L1,L2,L3);
attach_or_affect(X,[F]) -> !
unify_tlv(X,F); %only one value possible ==> we assign
attach_or_affect(X,L) -> dif(L,nil)
new_set(X,L); % new set possible
% User predicate
verify_in(V_arlibc, T_unifie, T_att) ->
member(T_unifie,T_att)
unify_tlv(V_arlibc, T_unifie);
; % End of insertion
{}
© PrologIA
Aociation Prolog Control of program execution R 2 - 17
HERITAGE
© PrologIA
R 2 - 18 Reference Manual Aociation Prolog
HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
3.1 Introduction
3.2 Terminology
3.3 Identifier syntax
3.4 Reading and writing context
3.5 Modules
3.6 Summary of how to use identifiers, contexts and modules
3.7 Adding, deleting and searching for rules
3.8 Manipulation of compiled modules
This chapter deals with the concepts of module, identifier family, and
reading/writing context, which have been introduced with two aims in mind:
• The ability to manage Prolog programs containing a very large number of rules.
This has been achieved by dividing the set of rules into different modules.
3.1 Introduction
The concept of a module results from the need to partition the rules in a large
program into functional groups which we call modules.
The simplest method is to extend the rule names by systematically prefixing them
with the module name. In this way, we implicitly partition the rules by partitioning
the rule names; semantically, the situation is exactly the same as a Prolog without
modules. We will call this prefix a qualifier.
<rule name> ::= <prefix> : <suffix>
<prefix> ::= <letter> <alpha num>
<suffix> ::= <letter> <alpha num>
Examples :
lexicon:data(1) ->;
lexicon:data(2) ->;
lexicon:pn(X) -> ...
...
...
The rule names of different modules are different by definition, since they have
different qualifiers (it is important to emphasise that the prefix+suffix sequence is
not a structure, but an indivisible identifier).
The basic concept is therefore a partitioning of rule symbols (or rule names), which
results in a partitioning of the corresponding rules. Each partition is called a
module. This concept is completely dynamic: when a rule is created with a rule
name belonging to an unused partition, this corresponds to the creation of a new
module.
All the modules are on the same level, and the concept of nested modules does not
exist.
Please note.
To be compatible with the Prolog II interpreter, the prefix syntax has been extended
to simulate inclusion, using ":" inside the prefix. For example, Base:Normal:data
is an identifier whose prefix is "Base:Normal", and whose suffix is "data".
To maintain the symmetry between data and programs, the same partitioning is used
for rule symbols and functor symbols. Functor qualification also makes it possible
to guarantee that certain names will not interfere with other modules (designation of
a temporary file, opaque data type, etc.).
To clarify notation, a specific notation has been created for certain functors called
generics. These functors can be used as "global" symbolic names (in the sense that
they are identical in all modules).
<functor name> ::= <rule name> | <generic name>
Generic identifiers correspond to those used by default for user names when no
module declaration is made.
The previous example can thus be written as follows in the source text:
© PrologIA
Aociation Prolog
module("lexicon");
data(1) ->;
data(2) ->;
pn(X) -> ...
end_module("lexicon");
module("grammar");
sentence(X) -> lexicon:pn(X1) sv(X2)...
error_message(M) -> sys:write(M);
data(8)...
end_module("grammar");
Any identifier written without the ":" character is said to be written in simplified (or
non qualified) notation. In the source text, it is represented by its suffix only.
The only convention is that if the qualifier is different from the module qualifier, the
complete (i.e. qualified) form of the rule identifier must be specified. In the
subsequent sections we describe other directives which are used to simplify notation
further.
By default, the qualification rule is the same for rule names and functor names.
One simple way to use the modules is to use generic names to write the same data in
several modules, and to prefix all rule call names which are not in the current
module or the system module. For example:
> insert;
module("lexicon");
np(:john) ->;
np(:marie) ->;
....
end_module("lexicon");
module("grammar");
proper_name(X) -> lexicon:np(X);
...
end_module("grammar");
;
> grammar:proper_name(X);
{X=john}
© PrologIA
Aociation Prolog
R3-4 Reference Manual HERITAGE
....
If you are not sure about the qualifier that has been created for an identifier, you can
use the predefined rule string_ident/3 to discover the associated prefix.
External names can be specified in the module heading, which avoids having to
qualify them, and is similar to an import declaration in a standard programming
language. However this does not prevent you from using other names, provided
they are explicitly qualified.
The example above can thus be written:
module("grammar",["lexicon",["np"]]);
proper_name(X) -> np(X);
...
end_module("grammar");
When Prolog is started without specifying the initial state the standard initial state
(file initial.po) is loaded in the working memory.
- The module containing the predefined rules, corresponding to the "sys" prefix.
- The modules constituting the supervisor, whose prefixes have the reserved form
"sys: ...".
- The default module for the user's programs, corresponding to the empty prefix
"".
3.2 Terminology
A large number of misunderstandings have arisen in the past because the same word
has been used to denote both a Prolog object and the character string which
represents it, and so here we will attempt to define a precise terminology. Although
this ambiguity is not particularly troublesome in normal Prolog, it leads to extreme
confusion when dealing with modules: a sequence of alphanumerical characters in a
module M1, may not represent the same object as that denoted by the same
character sequence in a module M2 (in other words the corresponding objects
cannot be unified).
Identifier
An identifier is an element of the set of non-structured objects, whose external
representation complies with identifier syntax.
© PrologIA
Aociation Prolog
Identifier family
A family "p" will be the set of all identifiers having the prefix "p". A family
will be denoted by the string corresponding to the prefix attached to the names
it contains.
Thus, sys:out, sys:in belong to the family "sys".
In the same way, sys:env:files belongs to the family "sys:env", :peter belongs
to the family "".
Module "p"
In a program, this module consists of all rules and facts whose access
identifier has the prefix "p" (here, the Prolog arrays are treated as facts). This
is therefore a dynamic concept: the modules evolve according to the state of
the program. The concept of a module is thus defined as the grouping
together of rules and facts whose access identifiers belong to the same family.
The syntax of the identifiers is extended so that they can be grouped by prefix. The
syntax of a complete identifier is thus:
© PrologIA
Aociation Prolog
R3-6 Reference Manual HERITAGE
Therefore the following complete identifiers are correct and all represent different
identifiers:
:peter grammar:plural
data:peter grammar:singular
sys:write lexicon:name
sys:env:files
It should also be emphasised that the ":" is NOT an operator: the name does not
represent a divisible object, only the character string representing it can be
decomposed. When we refer to an abbreviated name, we are therefore referring to
the corresponding character string, and it is the reading context alone which enables
us to determine which Prolog object is concerned:
Standard Prologs can easily be integrated into this structure: identifier syntax
corresponds to the abbreviated notation, and the convention for their extension is to
prefix them with"". This is the default convention when Prolog II+ starts.
Until now, and in the remainder of this manual, the character separating the suffix
from the prefix in the representation of a complete identifier has always been shown
as the character ":". This character is chosen by default to fulfill this purpose.
However, you can replace it with a graphic character by executing the built-in
predicate set_prefix_limit/1.
set_prefix_limit(s)
s must be a string comprising one graphic character. It becomes the character
separating the prefix from the suffix when a complete identifier is written.
Example:
> set_prefix_limit("$");
{}
> ident(sys$ident);
{}
> string_ident(x,y,a$a$ident);
{x="a$a",y="ident"}
© PrologIA
Aociation Prolog
prefix_limit(s)
Unifies s with the character separating the prefix from the suffix when a
complete identifier is written. Example:
> prefix_limit(x) set_prefix_limit("$") prefix_limit(y);
{x=":", y="$"}
When you change the way complete identifiers are written, you must take great care
and be aware of the consequences. If the separating character is defined
dynamically, you must take account of the representations of identifiers that appear
statically in the data of Prolog or C programs. In addition, when nested prefix
notation is used for a module ("Base:Normal:Data"), the name of the module may
change if this primitive has been used.
3.4.1 Reading
When an abbreviated identifier is read, it is identified with the first identifier in the
sequence having the same abbreviation. If no such identifier exists, it is extended by
the default prefix.
1The precise notation for these specifications in Prolog II+ is given below: see Section 3.4.4
© PrologIA
Aociation Prolog
R3-8 Reference Manual HERITAGE
3.4.2 Writing
The names are written in the most abbreviated form allowed by the context. If we
want to write an identifier having the prefix p and the abbreviation a, the abbreviated
representation is written a
1. if the identifier appears in the identifier sequence and is the first in the
sequence to have the abbreviation a,
Most programs use predefined rules, which means that to use the abbreviated
representation of their names, these names must all be listed explicitly in the
definition of the context. In order to simplify context definition, we will use the
concepts of an explicit sequence and an implicit sequence. The notation of the
sequence is lightened by allowing a set of identifiers in the sequence to be denoted
implicitly by their prefix.
in which the implicit sequence represents the identifier families in the program,
denoted by their prefix. A context can now be described in abstract form by the
following structure:
© PrologIA
Aociation Prolog
To solve this problem, we use the concept of an identifier family which is closed for
the context. This identifier family is a sub-set of a given name family, and is locked
by a special declaration (close_context_dictionary/1) which can only be modified by
ad hoc primitives (add_implicit/2, remove_implicit/2).
in others
out. ...
.
- either the locked sub-set, if the family is closed for the context,
- or otherwise the set of identifiers for the complete set. This set consists of all
the identifiers which have appeared in the program history with the relevant
prefix.
An example of an identifier family closed for the context is the family "sys". The
locked sub-set contains the set of identifiers for the rules and predefined functions
in Prolog II+.
We will use the term good context, to refer to a context in which all the implicit
sequences are closed for the context. A good context guarantees that the reading
and writing operations are repeatable and reversible.
An example will help to understand these concepts. Let us suppose we have the
following abstract context:
Reading of an abbreviated identifier out will produce m1:out, since the first
identifier in the explicit sequence has the same abbreviation.
© PrologIA
Aociation Prolog
R 3 - 10 Reference Manual HERITAGE
Reading of an abbreviated identifier nil will produce sys:nil since this identifier is
part of the locked sub-set of the family "sys" closed for the context .
Writing of sys:out will produce sys:out, since the first identifier in the sequence
having the abbreviation out has a different prefix.
Thus the explicit sequence "m1:out" "m1:outm" "jf:init" "m2:toto" "m2:peter" will
be represented as follows in infixed notation:
"m1".("out"."outm".nil)
."jf".("init".nil)
."m2".("toto"."peter".nil)
.nil
When a new context is activated, the old one is no longer taken into account.
The argument identification must be an identifier or a string. The second
argument must be an alternating list as described in the previous section. The
third argument is a list of strings representing prefixes, and the fourth
argument is a string defining the default prefix.
© PrologIA
Aociation Prolog
When Prolog starts, the current reading/writing context is the good context
defined by the following command:
set_context("user", [ ], ["sys"], "")
As another example, the second abstract context defined in section 3.4.3 above
will be defined and activated by the command:
> set_context(No2, ["m1",["out"],"m2",["peter"]],
["sys"], "a:b");
set_context(Identification)
Reactivates a context by giving its identification, once it has been defined.
Note 1:
When defining contexts which do not contain the family "sys" in the
implicit sequence, it is important to bear in mind that nil does not
generally represent the end of list marker sys:nil : it is the default prefix
and the explicit sequence which perform this function. Consequently,
errors may result when using predefined rules which take these values as
an argument. In this situation, it is recommended to use the complete
name sys:nil, or the equivalent notation [ ].
Note 2:
When a rule contains a context declaration, it comes into effect as soon as
the rule is executed, (and not when the rule is read). In the example
below, the context is not modified, and the abbreviated identifier "peach"
is identified with ":peach", since the reading context when the rule is read
is "user".
Prolog II+, ...
>insert;
apple ->
set_context("new",["other",["peach"]],[],"def");
peach;
peach ->;;
{}
>
current_context(t0)
current_context(t0, t1, t2, t3)
Unifies t0 with the term identifying the current reading/writing context, and
unifies t1, t2, t3 with, respectively, the term defining the explicit sequence, the
term defining the implicit sequence, and the context's default prefix.
close_context_dictionary(s)
Closes the identifier family s for context operations. From the moment this
command is executed, s remains in the same state, ie, no new identifier
belonging to this family will be taken into account for context operations.
© PrologIA
Aociation Prolog
R 3 - 12 Reference Manual HERITAGE
dictionary
The abbreviated form of accesses in the family having the same prefix as the
reading/writing context's default prefix is written on the current output.
dictionary (s1)
Unifies s1 with the list of prefixes of user modules present in memory.
dictionary (s1,t0)
Unifies t0 withthe list of access identifier/arity forms of rules in the module
s1. Example:
> insert;
aa:bb(1) ->;
aa:cc(1,2) ->;;
> dictionary("aa",L);
{L=aa:bb/1.aa:cc/2.nil}
file_dictionary(f, l_pref)
Unifies l_pref with the list of prefixes of the modules (containing rules)
present in file f. This file must contain compiled prolog code, and is therefore
an object module or a binary state for start-up. It is obtained using one of the
save predicates exit, save_state, save.
© PrologIA
Aociation Prolog
3.5 Modules
A definition of modules in Prolog must be able to deal efficiently with situations as
varied as those that can be found, for example, in a natural language system. In
such a system, there are essentially two modules: the first is a lexicon containing
many names from the data base and the grammar, and few rule names. The second
is the grammar, containing mainly its own names, and calls to the lexicon. Let us
look at the following example:
lexicon:pn(data:Peter, grammar:singular ) -> ;
lexicon:pn(data:John, grammar:singular ) -> ;
...
lexicon:verbø(data:smiles, grammar:singular ) -> ;
...
lexicon:adj(data:plural, grammar:plural ) -> ;
...
The fundamental reason for creating the reading context system described in the
previous sections was to define conventions that would make it possible to simplify
the writing of identifiers in such extreme situations as this one.
It is easy to construct a context which will allow us to write the lexicon module
using only abbreviated identifiers. The prefix which covers the greatest number of
identifiers is taken as the default prefix, and the rule names are represented in the
explicit sequence as follows:
set_context(:lex
, ["grammar", ["singular", "plural"],
"lexicon", ["pn", "verbø", "adj"] ]
,[]
,"data" )
A module "p" is a grouping together of all the rules, facts, evaluable functions,
assigned identifiers (using assign) and arrays whose access identifier belongs to the
family "p" (ie have the prefix "p"), in a given program, and at a given time.
Identifiers from the family "p" can appear in other modules, but not as access
identifiers (ie head predicate names). This concept of a module is dynamic: when a
rule is deleted or created the module which corresponds to its access identifier is
modified accordingly.
More simplistically, we can say that a module is a grouping together of all rules and
facts whose access identifiers have the same prefix.
A module can exist in text form (before reading), or in internal form (after reading).
We will refer to a source module for the first case, and an object module for the
second.
© PrologIA
Aociation Prolog
R 3 - 14 Reference Manual HERITAGE
In a source module, the heading of the module defines the context for reading its
rules. Once a module has been read, the current reading/writing context, which was
in effect before reading, is restored.
The context is used to read the source module when it is compiled. It is also used
for reading when the module is decompiled (using the list or editm primitives).
Note. If the source module has not been constructed in this way (e.g. the rules have
been compiled using insert or assert, in any order), the editm primitive can be used
to reconstruct it in this form.
The declarations module and end_module are to be used in the Prolog rule insertion
mode (see insert paragraph 3.6). Consequently, the Prolog elements enclosed by
these two directives must be rules (or comments, which are ignored). The module
declaration begins the definition of a module, and end_module ends it.
The argument denoting the access 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 convention
prevents naming errors during reading.
In simple terms, the module directive means "ihe following rules must be inserted
with the writing context defined here, checking that the rules to be read possess (or
acquire) the desired prefix".
2 If the module is modified, i.e. part of the module is recompiled (using reinsert or insertz) or
reloaded (using reload), the initialization rule is only executed if it is one of the modified rules.
© PrologIA
Aociation Prolog
The complete version of the directive module includes a definition of the module's
reading context (see the description of contexts, section 3.4):
sys:module( access_prefix,
explicit_sequence,
implicit_sequence,
default_prefix)
If all the arguments are not given, the following default values apply (we will assume
that the reading context of the directive sys:module, allows abbreviation):
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 module's header is used to read the rest of the
module, including the sys:end_module directive. The context existing before
reading is then restored.
If, when the module is read, a rule or a fact is created with an access identifier whose
prefix differs from that of the module, an error is generated.
The two example modules at the beginning of section 3.5 can thus be written in
different ways:
1st example
module("grammar");
sentence(x,z) -> sn(x,y,g) vp(y,z,g);
sn(x.l,l,g) -> lexicon:pn(x,g);
...
end_module("grammar");
2nd example
module("grammar", ["lexicon",["pn","verbø", ...]]);
sentence(x,z) -> sn(x,y,g) vp(y,z,g);
sn(x.l,l,g) -> pn(x,g);
...
end_module("grammar");
3rd example
module( "lexicon"
, ["lexicon", ["pn", "verbø", "adj"],
"grammar", ["singular", "plural" ]]
, [ ]
, "data");
pn(Peter,singular) ->;
pn(John,singular) ->;
...
verbø(smiles,singular ) ->
© PrologIA
Aociation Prolog
R 3 - 16 Reference Manual HERITAGE
...
adj(data:plural,plural) ->;
...
end_module("lexicon");
Words entered by the user will be read with the context defined by:
set_context( :my_entry, [ ], [ ], "data" ) ;
Using the concept of a reading context for the module, we can redefine more clearly
certain primitives used within a module:
module("example", ["example", ["out"]] ) ;
out(x) -> nicer(x,y) sys:out(y);
...
explain(x) -> out(x) TellSomethingAbout(x);
end_module("example");
In the example below, the initialization part of the module is used to add the relevant
rule to the module as a Prolog built-in predicate. It will also be used to call this rule
using the abbreviated identifier, if the current context contains the sys module of
predefined rules:
module("parser");
ini_module ->
assert(sys:parse(x),parse(x,nil).nil)
add_implicit("sys","parse");
parse(l1,l2) -> sentence(l1,l2);
...
end_module("parser");
The load and save primitives are used to load and save several object modules.
When an object module is saved on file, it is saved with a dictionary which makes it
possible to rename the prefixes when loading. It is thus possible to solve name
conflict problems, whatever they may be, and to construct programs which do not
interfere with the data they manipulate; or on the contrary, to define data base and
lexicon type programs, whose names can be merged.
© PrologIA
Aociation Prolog
3.6.1 Identifiers
Identifiers are Prolog objects that are used to construct other Prolog objects. They
can be used in two different ways:
- as predicates to define a rule (section 3.1.1.)
- as functors to be used as data (section 3.1.2.)
Prolog identifiers (see section 3.3) always have the same syntax:
prefix:suffix
The prefix and suffix are character sequences conforming to the chosen syntax
(Prolog II or Edinburgh). ":" can be replaced by a graphic character (see
set_prefix_limit).
The advantage of this syntax is that a large set of identifiers can be identified simply
from a specific part of their name.
The term identifier family prefixed "wotsit", refers to all identifiers (predicates and
functors) whose name is written wotsit:suffix (section 3.2.).
The term module prefixed "wotsit", or module "wotsit", refers to all rules and/or
arrays and/or static variables whose access identifier is written wotsit:suffix
(section 3.2.).
Advice. If you want to have an invariable identifier for all programs that is easy to
write and remember, choose the empty prefix for this identifier. In the sections
above (section 3.1.2) it is called the generic functor.
Very often a situation arises where the vast majority of the identifiers to process are
all written with the same prefix. To avoid having to repeat this prefix continually, we
need to have an abbreviated form of identifier representation.
To achieve this goal, and thus simplify program implementation and legibility, we
have conventions for simplified representation of identifiers, which determine each
individual Prolog data item. These conventions are called reading/writing contexts
(see section 3.4).
Conversion between the internal encoding of the data item and its external
representation is only carried out during reading and writing operations.
© PrologIA
Aociation Prolog
R 3 - 18 Reference Manual HERITAGE
Properties:
• The list of explicit attributions is processed from left to right.
• If an abbreviated representation appears several times in the list, it is given the
first associated prefix (i.e. the leftmost prefix).
• The strings declared in the context do not all need to correspond to existing
identifiers. If Prolog has to create or read an identifier, it will consult this list of
potential representations.
Writing can be further shortened in the definition of the context. When you want to
include a whole identifier family in the explicit list, instead of giving an exhaustive
list you can simply specify the family's name. This is considered to be an implicit
attribution, equivalent to calculating the explicit list which stems from it and
inserting it in the existing list, each time a prefix is attributed.
This context now becomes dependent on time, since the families designated for an
implicit attribution may grow over a period of time.
To re-establish a healthy context, and remove this unknown part in the case of
implicit attributions, the family must be "closed". This means that when the family
is closed, the explicit list it represents is calculated and memorized once and for all.
The context is once more completely defined and invariable.
3.6.3 Modules
Since Prolog is incremental, with no data types, there is no constraint on the order of
rule insertion.
© PrologIA
Aociation Prolog
However, you can group together all the rules of a single module and define them at
the same time. You can also define different reading conventions for this group,
compared to those of the execution context. Provided the context is healthy, it is
thus possible to make the module definition autonomous.
A module can be defined using the module or omodule declaration (section 3.5.2):
insert; insert;
module(p,e,i,d); equivalent to ->set_context(p,e,i,d)
->prefix_verif_mode(p)
rules… rules…
end_module(p); ->exec(p:ini_module);
->restore_context;
… …
; ;
This means that although there are no order constraints on the groups of rules,
constraints may apply to the order in which the modules are compiled or loaded.
It is very important to mention that the notions of files and modules are fully
independent. A source file can include several modules, and the same module name
can appear in several files loaded simultaneously.
The Prolog II+ system comprises a compiler which translates your Prolog source
programs into an object language whose "level" (ie proximity to the host machine)
varies from one machine to another. Nevertheless, in all circumstances it is much
more efficient than simple interpretation of the Prolog source code. On the other
end, it is difficult to restore the exact source text of certain rules because variable
names disappear.
The Prolog II+ compiler is incremental (translation is performed rule by rule), and
transparent (rules are compiled and indexed as soon as they are written, without
having to give any particular command).
© PrologIA
Aociation Prolog
R 3 - 20 Reference Manual HERITAGE
To minimise the time required to choose a rule that can be used to execute a specific
goal, when Prolog II+ compiles a group of rules it creates an image of the group. It
puts in this group all the rules whose first argument or value are identical. In this
way it creates several separate groups of rules, and to execute any single goal either
all or none of the rules in any one group will be chosen. This type of processing is
called indexing. If indexing is removed, this is the same as leaving all the group’s
rules available as valid choices.
In the text and programs that follow, the term identifier/integer denotes a group of
rules for which the access identifier of the head is identifier, and the number of
arguments is integer.
Before we go on to describe the primitives, the reader should take note of two very
important consequences of rule group modifications, which will affect the program's
execution.
1. When a group of compiled rules is modified (rules are added or deleted), its
indexation is deleted, and so the index primitive must be used to restablish it.
2. If a group of rules is modified while one of its rules is being executed (the choice
is still on standby), the behavior of the execution (for backtracking or a subsequent
call), depends to a very great extent on the configuration of the rules (determined by
the group's structure, the current rule, the modified rule).
As far as possible, it is preferable either to exhaust the choices before modifying the
rules, or otherwise to delete the indexation before the rules are executed and
modified.
Another technique to improve performance is has been introduced into Prolog II+; a
new type of rule called “non compiled facts”. The aim of this technique is to
optimize management of problems by handling facts dynamically. To verify a fact,
there is no point in optimizing the execution of the rule body since it is non existent,
but on the other hand it is important to improve accesses to the arguments.
For the “non compiled facts”, Prolog II+ will install an indexing process based on
all the fact’s arguments, so that at execution time access to the relevant facts is
virtually instantaneous. It is not possible to delete the indexing installed on “non
compiled facts”.
© PrologIA
Aociation Prolog
assert(t, q)
asserta(t,q)
Compiles and adds a rule at the beginning of a group.
t must be a term capable of being a rule head, that is, an identifier or a tuple
whose first argument is an identifier (eg <ident, arg1, … argn> or ident(arg1,
… argn), these two notations are equivalent). q must be a list of terms.
The execution of assert(t,q) compiles and adds the rule above the group of
rules having the same "name" as t, that is at the beginning of the group
corresponding to t. For example, the following two commands
assert(conc(e.x, y, e.z), conc(x, y, z).nil);
assert(conc(nil, y, y), nil);
Do not allow the adding of rules containing infinite trees: however this can be
achieved with the predefined rule equations (see section 2.3).
assert''(t,q)
assertz(t,q)
Compiles and adds a rule at the end of a group.
Function in the same way as assert, but the rule is added below the group
corresponding to t, and not above. Example: the two following commands, in
the order shown, produce the insertion of the same conc program as above:
assert''(conc(nil, y, y), nil);
assert''(conc(e.x, y, e.z), conc(x, y, z).nil);
Do not allow the adding of rules containing infinite trees: however this can be
achieved with the predefined rule equations (see section 2.3).
assertn(t, q, n)
Compiles and adds a rule at the n-th position in the group.
Functions in the same way as assert, but the rule is added at the n-th position
in the group corresponding to t. Example:
assert(myrule(2), nil);
assertn(myrule(0),nil,1);
assertn(myrule(1),nil,2);
typed in this order, have the effect of adding the following program:
myrule(0) ->;
myrule(1) ->;
myrule(2) ->;
Cannot be used to add rules containing infinite trees; this is done using the
predefined rule equations (See section 2.3).
© PrologIA
Aociation Prolog
R 3 - 22 Reference Manual HERITAGE
current_predicate(i/a)
Tests for 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, this primitive lists in succession all the values of a
corresponding to a rule with access i. If i is not known (i.e. is a variable), the
rule unifies the argument in sucession with all the i/a forms of the rules in the
module specified by the default prefix of the current context. i and a cannot
be free variables at the same time.
discontiguous(i/a)
Enables a rule group to be discontiguous.
When a rule with access identifier i and arity a is compiled using the insert
predicate, it will be added at the end of its group. This directive makes it
possible to split rule groups within one or several files. Note that this
directive does not have any effect on compiling performed using the reinsert
predicate, which will overwrite the existing rule group with the newly detected
group. This is a compiling directive, not a predicate. This means it can appear
in the middle of a source you are compiling but cannot be located in a rule
body.
dynamic(i/a)
Declares a group of dynamic rules.
All Prolog II+ rule groups are dynamic, i.e. they can be modified. This
directive therefore has no effect and only exists to ensure compatibility with
the Prolog standard. This is a compiling directive, not a predicate. This
means it can appear in the middle of a source you are compiling but cannot be
located in a rule body.
ensure_loaded(f)
Ensures compiling of a file is performed once only.
Compiles file f at the location of the directive if this file has not already been
compiled during this same compiling phase, otherwise does nothing. At the
end of compiling the highest nesting level, and therefore for a new compiling
phase, the file is no longer considered to have been compiled. The file f is
compiled using the same mode as the mode used by the higher level
compiling predicate (insert, reinsert, insertz).
This is a compiling directive, not a predicate. This means it can appear in the
middle of a source you are compiling but cannot be located in a rule body.
fasserta(t)
fassertz(t)
Adds an uncompiled fact.
© PrologIA
Aociation Prolog
These rules add an uncompiled fact, at the start (fasserta) or end (fassertz) of
its group. Assertion is extremely fast and enables you to manage very large
fact bases. In addition, since these facts are indexed through a preliminary
call to the init_fassert primitive, they can be accessed with good
performances. The term t must have the form of a rule head, i.e. a tuple whose
first element is an identifier. You cannot mix compiled rules (assert, insert)
and uncompiled facts (fassert) in the same group. Here is an example:
> fasserta(myrule(1,2,3,4.nil,<44,"abc">,6,1.2.2e0.nil));
fretract(t)
Rapid deletion of an uncompiled fact.
Deletes the uncompiled facts that unify with t in a very efficient way. The
search for these facts is very fast and benefits from the optimizations
implemented for access to non compiled facts. These facts must be created
using either the fasserta or the fassertz predicate. As soon as a fact unifying
with t is found, it is deleted.
If a suitable fact is invisible at decompiling time it is deleted, and the primitive
executes without unifying t's free variables.
Here is an example:
> fretract(myrule(1,2,3,x,y,z,t));
fretractall(t)
Rapidly deletes all the non compiled facts corresponding to a pattern.
Very efficiently deletes in a single operation all the facts unifying with t.
These facts must be non compiled, and created by one of the two predicates
fasserta and fassertz. t must make it possible to identify an index for this fact
base using the following method: all arguments of the goal that are not free
must be atoms, and must denote a combination of arguments corresponding to
an indexing combination defined for this fact base. If this is not the case an
error is generated. Example:
> init_fassert(bb/3,(1.2.3).(1.2).nil);
{}
> fasserta(bb(1,2,3));
{}
© PrologIA
Aociation Prolog
R 3 - 24 Reference Manual HERITAGE
> fasserta(bb(1,2,x));
{}
> fasserta(bb(1,2,1.2));
{}
> fasserta(bb(1,1,1.1));
{}
> fretractall(bb(1,x,3));
> fretractall(bb(1.2,2,x));
> fretractall(bb(1,2,x));
{}
> list(bb/3);
bb(1,1,1.1) -> ;
{}
hidden_rule(x)
Hides rules for decompilation.
Makes rules "non visible for rule". If x is in the form i/a where i is an
identifier and a is an integer, this primitive concerns the group of rules with
access i and arity a. If x is a string, it concerns all rules in the module x. "Not
visible for rule" means that it is not decompilable, i.e. it cannot be
reconstructed as a Prolog source. Therefore, none of the primitives to
decompile or print these rules will have any effect.
hidden_debug(x)
Hides the accesses to rules.
Makes rules "non visible for debug'. If x is in the form i/a, where i is an
identifier and a is an integer, this primitive concerns the group of rules with
access i and arity a. If x is a string, it concerns all rules in the module x. "Not
visible for debug" means that the access is hidden. The debugger will not
show the calls to this group of rules, or the calls made in the body of rules in
this group. If a visible rule is called in the body of a non visible rule, only the
body of the visible rule will be displayed. Predefined rules that return rule
accesses (e.g. dictionary), ignore these "hidden for debug" rules. It should be
noted that to decompile these rules, you must use built-in predicates that
decompile rules according to their access identifier and arity, and not global
decompiling rules (i.e. that only require a module name).
hidden(x)
Hides rules.
© PrologIA
Aociation Prolog
include(f)
Includes the compiling of a file.
Compiles file f at the location of the directive. Everything therefore takes
place as if the directive was replaced by the content of file f. File f is compiled
using the same mode as the mode used by the higher level compiling predicate
(insert, reinsert, insertz).
This is a compiling directive, not a predicate. This means it can appear in the
middle of a source you are compiling but cannot be located in a rule body.
init_fassert(i/a, l)
Describes the indexing for a group of uncompiled facts.
Initializes a group of uncompiled facts with access identifier i and arity a.
Argument l is a list (terminated by nil) indicating the indexing combination
chosen for these facts' arguments. This list is arranged according to the
indexing priority. Each element in this list indicates a combination and must
have one of the following values:
- either a list of integers (possibly terminated by nil) indicating a combination
of the arguments to index or one integer if there is only one argument in the
combination. The corresponding hash-code table will then have a default size
(512 entries).
- or a 2-element tuple, formed by:
- in the first argument, the list described above.
- in the second argument, an integer indicating the size of the hash-
code table for this combination.
This predicate must be called before fasserta or fassertz. It can be called
several times for the same rule group, provided the argument l is the same for
the different calls. Here is an example:
> init_fassert(myrule/7, (1.2.3). (4.5.nil). 5. <6,200>.
<2.6,300>. nil);
In this example we choose :
- as a first choice, multiple indexing on the combination of arguments 1, 2 and
3,
- another mutiple indexing on the combined arguments 4 and 5,
- an indexing on argument 5 by itself,
- an indexing on argument 6 alone, with a 200-entries hash-code table,
- and finally an indexing on the combined arguments 2 and 6, with a 300-
entries hash-code table.
© PrologIA
Aociation Prolog
R 3 - 26 Reference Manual HERITAGE
initialization(B)
Initializes a rule group.
Includes goal B in the list of goals that will be executed as soon as compiling
of the file that contains this directive has finished. This is a compiling
directive not a predicate. This means that it can appear in the middle of a
source you are compiling, but cannot be located in a rule body. This list of
goals will be executed provided no errors have been detected during
compiling.
insert
insertz
reinsert
Inserts rules.
This predefined rule switches the system into a mode in which statements
(rules) are added in the order they are read on the current input unit. The
directives and declarations are executed and taken into account respectively
immediately they are detected. The insert mode ends either when an empty
statement is found (finds a ";;" in Prolog II syntax) or if the end of the input
file is reached.
Example:
>insert;
conc(nil, y, y) ->;
conc(e.x, y, e.z) -> conc(x, y, z); ;
{}
© PrologIA
Aociation Prolog
Depending on the warning mode chosen at Prolog start-up, when the rules are
read a warning is displayed if a singleton variable appears. A singleton
variable is a variable only appearing once in the rule, and is therefore
theoretically of no use. The warning is not displayed for the anonymous
variable _ .
insert is used to define groups of rules, reinsert is used to redefine groups of
rules, and insertz is used to complete groups of rules by adding alternatives at
the end.
insert causes an error when a group which already exists and has not been
declared discontiguous (predicate discontiguous/1) is read, whereas insertz
appends the new rules at the end of the existing group and reinsert replaces
the previous group with the new definition .
Warning.
This can be dangerous. If an error is made concerning the number of
arguments in a rule inside a group, use of reinsert will cause the previous rules
to be erased when reading of the group continues. In the same way, because
insertz is used to define a group of rules in several pieces (i.e. mixed with
other rules), errors concerning the number of arguments or mix-ups with very
similar predicate names will not be visible.
When a module m is read, the context defined by the module heading is
memorized in the module in the form of a rule
m:module_context(A1,A2,A3,A4) where A1, A2, A3, A4 have values defining
the module's reading context (this rule is used by module editing primitives
such as editm).
insert(f)
insertz(f)
reinsert(f)
Inserts rules from a file.
Function in the same way as insert, but the statements are read on the file
indicated. If the echo mode has been activated (see echo rule), the rules are
displayed on the console as they are read.
When a module m is read, the name of the module's source file is memorized
in the module in the form of a rule m:module_file(s) where s is a string
representing the file name (this rule is used by module editing primitives such
as editm).
is_uncompiled(i/a)
Successes if the rules constituting the group named i of arity (number of
arguments) a. is a set of uncompiled facts, else fails.
list
Lists the current module.
Lists all the rules in the module specified by the default prefix of the current
context.
© PrologIA
Aociation Prolog
R 3 - 28 Reference Manual HERITAGE
list(t)
Lists the group(s) of rules indicated by t, on the current output.
t can be a sequence of one or more terms, having the following forms (i
denotes an identifier, a an integer, and v a variable).
i/a All rules constituting the group named i of arity (number of arguments) a.
i/v All rules whose access is i, whatever their arity.
v/a All rules whose arity is a.
i Equivalent to i/v.
Example:
> list(num.bin/2);
list(s)
Lists a module.
s must be a character string. All rules prefixed by s are listed on the current
output.
list(i/a,n)
Lists one rule.
i must be an identifier, and a an integer. Rule number n in the group named i
and with arity (number of arguments) a is listed on the current output.
multifile(i/a)
Enables a rule group to be discontiguous.
Compiling directive identical to the discontiguous/1 directive.
not_defined(s,l)
Finds the accesses of a module that are not defined.
Unifies l with the list of accesses belonging to module s that are not defined.
The accesses are written i/a, where i is the access identifier and a is its arity.
Note: this predefined rule activates the garbage collector on the dictionary
before providing the result.
Example:
> insert;
module("agency");
travel(v,d,h,s) -> transport(v,t)
stay(v,h,n)
duration(d)
multiply(n,d,p)
add(p,t,s);
transport(Rome,1200) ->;
transport(London,800) ->;
transport(Tunis,2000) ->;
end_module("agency");
;
{}
> dictionary("agency",l);
{l=agency:module_context / 4.agency:transport / 2.
agency:voyage / 4.nil}
> not_defined("agency",l);
{l=agency:add / 3.agency:duration / 1. agency:multiply / 3.
agency:stay / 3.nil}
© PrologIA
Aociation Prolog
predefined(t)
Tests whether a pattern corresponds to a predefined rule.
Executes successfully if t is a term corresponding to a predefined rule call.
rule(t,q)
Searches for rules corresponding to a given pattern.
This primitive is executed as many times as there are rules whose head unifies
with t and the body with q. If no such rule exists, rule(t,q) fails. t must be
either an identifier or a tuple whose first argument is a known identifier.
The rule primitive uses the rule indexation when possible (see no_index).
Example of use of rule (applying to the conc program given above):
>rule(conc(x,y,z),q);
{x=nil,z=y,q=nil}
{x=v149.v150,z=v149.v151,q=conc(v150,y,v151).nil}
>
rule(n,t,q)
Searches for rules corresponding to a given pattern.
Functions in the same way as rule(t,q) but, in addition, n is unified with the
rank of the rule in its group.
Example:
>rule(n,conc(x,y,z),q);
{n=1,x=nil,z=y,q=nil}
{n=2,x=v172.v173,z=v172.v174,q=conc(v173,y,v174).nil}
>rule(n,conc(x,y,z),conc(x',y',z').l);
{n=2,x=v263.x',z=v263.z',y'=y,l=nil}
>rule(1,conc(x,y,z),q);
{x=nil,z=y,q=nil}
>
rule(n,a,t,q)
Searches for rules having a given name.
a must be an identifier, or a tuple whose first argument is an identifier. For
each rule with access identifier a, this primitive executes by unifying n with
the rank of the rule in its group, t with the rule head, and q with the rule body.
This version of rule provides a means of searching for rules whose names are
known, but not their pattern.
Example:
conc(nil,x2,x2) ->;
conc(e.x1,x2,e.r) -> conc(x1,x2,r);
conc(x1,x2,x3,r) -> conc(x1,x2,u) conc(u,x3,r);;
> rule(n,conc,t,q);
{n=1,t=conc(v124,v125,v126,v127),
q=conc(v124,v125,v128).conc(v128,v126,v127).nil}
{n=1,t=conc(nil,v125,v125),q=nil}
{n=2,t=conc(v127.v128,v125,v127.v129),
q=conc(v128,v125,v129).nil}
rule_nb(i/a,n)
rule_nb(i,n)
Counts the number of rules in a group.
© PrologIA
Aociation Prolog
R 3 - 30 Reference Manual HERITAGE
retract(t,q)
Searches for and deletes 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. It uses rule indexation if possible, or
otherwise tries each rule in successive order. If such a rule does not exist,
retract(t,q) fails. t must either be an identifier, or a tuple whose first argument
is a known identifier.
If a matching rule is invisible for decompilation, the rule is deleted and the
primitive executes without unifying the free variables of t and q.
suppress(i/a)
Deletes a whole group of rules. i must be an identifier, and a an integer. All
the rules in the group named i and with arity (number of arguments) a are
deleted. If there is no rule, when the predicate executes it may3 print a
warning.
Here is an example:
data(1) ->;
data(2) ->;
data(3) ->;;
>data(x);
{x=1}
{x=2}
{x=3}
>suppress(data/1);
{}
>data(x);
WARNING : call to undefined rule
>
suppress(i/a,n)
Deletes one rule.
i must be an identifier, and a and n are two integers. The nth rule in the group
having the name i and the arity (number of arguments) a is deleted. If there is
no such rule, when the predicate executes it may4 print a warning.
Example:
data(1) ->;
data(2) ->;
data(3) ->;;
© PrologIA
Aociation Prolog
>data(x);
{x=1}
{x=2}
{x=3}
>suppress(data/1, 2);
{}
>data(x);
{x=1}
{x=3}
>
index(i/a)
Indexes a group of compiled rules.
Indexes the first argument in the group of compiled rules whose access
identifier is i and whose arity is a. If the rule is already indexed, nothing
happens. This rule can be used to accelerate the execution speed of rules
created using assert, which are not automatically indexed unlike rules created
using insert. It has no effect on the non compiled facts.
kill_module(s)
Deletes module.
s must be a string or a list of strings. All the rules in each module denoted in
s are deleted, its arrays are de-allocated and its identifier assignments are
undone. If a module does not exist, a message may5 be displayed and the
processing continues.
load(f,l)
load(f)
Loading saved modules.
f is a file name (character string) and l is a substitutory list of prefixes. This
command loads the saved modules in the file f, which must have been created
using the command save. If the module initialization rules exist they are
executed.
l is a list having the form <pref1 . subs1> . … . <prefk . subsk> . nil which
specifies the renaming of the loaded modules: pref1 will be substituted by
subs1, pref2 by subs2, etc. If a module to rename is not present, the system
ignores the substitution and a message may6 be displayed.
Example:
>load("myfile.mo", <"data"."donnees">.nil);
{}
© PrologIA
Aociation Prolog
R 3 - 32 Reference Manual HERITAGE
no_index(i/a)
Removes indexation from a compiled rule group.
Removes indexation from the group of compiled rules whose access identifier
is i, and whose arity is a. If the rule is not indexed, nothing happens. It is
advisable to use this rule before dynamically handling rules read by insert, so
that the modifications will always be taken into account in the same way. It
has no effect on the non compiled facts.
reload(f)
reload(f,l)
Loading saved modules.
Functions in the same way as load, except that when an element is redefined,
the version found in the file replaces the one in memory, without producing an
error.
save(l,f)
Saving modules.
f is a file name (character string) and l is a list of prefixes (character strings).
This command saves all the elements (rules, static variables and arrays) from
the modules corresponding to the specified prefixes, in the file f. If a module
does not exist, a message may7 be displayed, and the save continues.
Example:
>save(""."data"."dict".nil, "myfile.mo");
{}
The file produced is an object code file. This code can only be exploited by a
Prolog machine. By memorizing programs in this way, it is possible to
achieve faster reloading than from the source files.
save_state(s)
Saves a start-up state.
Saves the whole program (rules, arrays, assigned identifiers, including the
Prolog II+ supervisor) in a file named s (where s is a string) which can then
be used as a start-up file. This primitive has the same effect as exit(s) but
without leaving Prolog.
© PrologIA
Aociation Prolog
© PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
These rules are used to determine an object's type. If the argument is a free variable,
the rules make no sense and thus fail.
ident(t)
Checks that t is an identifier.
integer(t)
Checks that t is an integer.
real(t)
Checks that t is a real.
double(t)
Identical with real(t).
dot(t)
Checks whether t has the form t1.t2 or [ t1 | t2 ].
string(t)
Checks whether t is a string.
tuple(t)
Checks whether t is a term having the form(t1 … tn) or <t1 … tn>.
The following primitives concern the "state" of the variables, and thus operate in a
similar way to the type testing rules.
©PrologIA
Aociation Prolog
R4-2 Manuel de Référence HERITAGE
bound(x)
bound(x) is executed if x is bound and fails otherwise. A variable is
considered bound if it has been unified:
free(x)
Is executed if x is not bound, and fails otherwise.
var_time(x,n)
A variable's creation date
x must be an unbound variable. This predefined rule unifies n with a certain
"creation date" of a variable x. n is an integer which identifies a unique
variable; two variables have the same date if, and only if, they are linked to
each other (the compiler uses this same number to print unbound variables -
see example below).
Example:
>eq(x,y) var_time(x,_tx) var_time(y,_ty) var_time(z,_tz)
out(x.y.z) line;
v35.v35.v172
{y=x,_tx=35,_ty=35,_tz=172}
>
Warning. The value of variables' creation dates may be affected when the
garbage collector compacts the stack space.
An expression is evaluated using the predefined rule val. The result is either an
integer, a real, an identifier or a string. Booleans are represented by the integers 0
and 1.
©PrologIA
Aociation Prolog
val(t1, t2)
tval(t1, t2)
Evaluate the expression t1 and produces the result t2. The expression to be
evaluated is constructed recursively from constants, identifiers and evaluable
functions. When decompiling or debugging, the optimizations (provided they
are not deactivated when Prolog starts) of the code generated for the call to the
val predicate do not make it possible to reconstitute the original term, but
rather an equivalent term. In addition, they momentarily suspend the
automatic space and stack management mechanism. However the tval
predicate is not optimized. You may prefer to use it instead of val when using
memory intensive programs in which val frequently handles complex terms.
In this way you will avoid having to manage the memory "by hand".
Examples:
>val(add(mul(2, add(3, 4)), 1000), x);
{x=1014}
>val(add(mul(2e0, add(3, 4e0)), 1000), x);
{x=1.014000000000000e+03}
>val(2 * (3 + 4) + 1000, x);
{x=1014}
The arithmetical functions can have different types of arguments: they are
automaticaly converted to the most general type (the types are as follows, in
decreasing order: real, integer). If a function to be evaluated has an incorrect
number of arguments or if any of its arguments are of the wrong type, val
generates an error. This error can be recovered with the predefined rule block.
• The value of a number or string is equal to that number or string.
(1) If a term t has been assigned to term i(using the rule assign described
in the next section) then the value of i is t;
Example:
>assign(un, 1);
{}
>val(un, x) val(deux, y);
{x=1,y=deux}
Certain evaluable functions can also be expressed using operators. The evaluable
functions are:
©PrologIA
Aociation Prolog
R4-4 Manuel de Référence HERITAGE
add(t1, t2) or t1 + t2
value( add(t1,t2)) = value(t1 + value( t2)
The value of t1 and t2 must be an integer or real number value.
sub(t1, t2) or t1 - t2
value( sub(t1,t2)) = value(t1) - value( t2)
The value of t1 and t2 must be an integer or real number value
mul(t1, t2) or t1 * t2
value(mul(t1,t2)) = value( t1) x value( t2)
The value of t1 and t2 must be an integer or real number value.
div(t1, t2) or t1 / t2
value(div(t1,t2)) = value( t1) / value( t2)
The values of t1 and t2 must be an integer or real number value.
©PrologIA
Aociation Prolog
sign(t)
value(sign(t))= if value(t) = 0 then 0, if value(t) < 0 then -1, else 1.
The value of t must be an integer or a real number.
ceiling(t)
value(ceiling(t))= - (floor(-value(t))) .
The value of t must be an integer or a real number. The result is an integer.
floor(t)
value(floor(t)) = floor(value(t)) .
The value of t must be an integer or a real number. The result is an integer.
round(t)
value(round(t))= integer part (value(t)+0.5).
The value of t must be an integer or a real number. The result is an integer.
trunc(t)
value( trunc(t)) = the value of t is converted into an integer.
The value of t must be an integer or a real number.
float(t)
value( float(t)) = the value of t is converted into a real number.
The value of t must be an integer or a real number.
double(t)
value( double(t)) = the value of t is converted into a real number.
The value of t must be an integer or a real number.
abs(t)
value( abs(t)) = absolute value(value( t)).
The value of t must be an integer or a real number.
The following functions must be applied to integer arguments. They give an integer
result.
'/\'(t1,t2)
value('/\'(t1,t2)) = bit by bit 'and' between t1 and t2.
The values of t1 and t2 must be integers.
©PrologIA
Aociation Prolog
R4-6 Manuel de Référence HERITAGE
'\/'(t1,t2)
value('\/'(t1,t2)) = bit by bit 'or' between t1 and t2.
The values of t1 and t2 must be integers.
'<<'(t1,t2)
value('<<'(t1,t2)) = t1 offset by t2 bits to the left.
The values of t1 and t2must be integers.
'>>'(t1,t2)
value('>>'(t1,t2)) = t1 offset t2 bits to the right.
The values of t1 and t2must be integers.
'~'(t)
value('~'(t)) = bit by bit complement of t.
The value of t must be an integer.
The following functions give a real number result, and must be applied to integer or
real number arguments. The trigonometric functions work with angles expressed in
radian units.
atan(t)
value( atan(t)) = arc tangent(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)).
Converts degrees to radians.
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)).
t1 ** t2
value(t1 ** t2) = value(t1) to the power value(t2).
©PrologIA
Aociation Prolog
4.3 Assignment
assign(i, t)
tassign(i, t)
cassign(i, t)
Assign the term t to identifier i. t can be any Prolog term. The rule functions
as if i were becoming the name of a variable which is "global" (subsequently
accessible during the execution of any goal), "static" (resists backtracking)
and has the value t. Therefore, this is standard assignment, as it occurs in
Fortran, Pascal, etc … The optimizations of the code generated for the call to
the assign predicate momentarily suspend the automatic space and stack
management mechanism (provided they are not deactivated when Prolog
starts). However the tassign predicate is not optimized. You may prefer to use
it instead of assign when using memory intensive programs in which assign
frequently handles complex terms. In this way you will avoid having to
manage the memory "by hand". The cassign predicate is similar to tassign but
allows to keep the constraints (dif, freeze) and the attributes (metastructures)
linked to the variables of t.
Example:
>assign(file_name, "myfile.txt");
{}
>val(file_name,x)
{x="myfile.txt"}
>
©PrologIA
Aociation Prolog
R4-8 Manuel de Référence HERITAGE
assign(tab(i), t) or assign(tab[i], t)
assign(tab(i), t) or tassign(tab[i], t)
Assigns the term t to the element of rank i in the array tab, which must have
been previously defined as an array with def_array.
To obtain access to array elements (in val), the notations tab(i) and tab[i] are
equivalent. However, they are not represented by the same Prolog terms, and
use of the notation tab[i] enables the compiler to optimize access to the array.
In practice, the notation tab[i] will only be used to denote elements in an
array. The same applies to these predicates as above: assign is optimized,
tassign is not.
backtrack_term
Predefined array in the sys module, with a length of 100 (possible indices
between 1 and 100) that can be manipulated using built-in predicates val or
tval and assign or tassign. The values it is assigned are lost during
backtracking. Each array element is set to 0. Example:
> insert;
test(i) -> assign(backtrack_term[1],111)
val(backtrack_term[1],i);
test(i) -> val(backtrack_term[1],i);
;
{}
> test(i);
{i=111}
{i=0}
def_array(i, n)
Dynamically defines a Prolog term array named i of size n. This array will
behave like a variable which is "global" (subsequently accessible during
execution of any goal), and "static" (resists backtracking). Each array element
is set to the integer 0. Legal values for the index are between 1 and n.
If an array with the same name already exists:
- if the arrays are the same size, nothing happens
- if the sizes are different, an error is generated.
Access and assignment work in the same way as in arrays in other
programming languages (see above; val for access and assign for
assignment). The array is deallocated when you kill the module it belongs to
(i.e. the rules with the same prefix), or when you execute the kill_array
predicate.
"stack management "
push(v) ->
inc(pointer)
val(inf(pointer,100),1)
©PrologIA
Aociation Prolog
!
val(pointer,p)
assign(stack(p),v);
push(v) -> outm("stack overflow") line fail;
pop(v) ->
val(eql(pointer,0),0)
!
val(stack(pointer),v)
dec(pointer);
pop(v) -> outm("stack error") line fail;
> initialize;
{}
> push(12345);
{}
> push(23456);
{}
> pop(x);
{x=23456}
> pop(x);
{x=12345}
> pop(x);
stack error
redef_array(i, n)
Similar to def_array, but if the array i already exists, this predicate redefines
its size with the value n, It conserves existing assignments for the valid indices,
and initializes the new elements if necessary.
is_array(i,t)
Checks that the identifier i effectively denotes an array, and unifies t with its
size.
kill_array(i)
Deletes array i. If the array is not defined, when the predicate executes a
warning may1 be printed.
©PrologIA
Aociation Prolog
R 4 - 10 Manuel de Référence HERITAGE
conc_string(s1,s2,s3)
Lists all the triplets of strings s1, s2, s3 such that s3 is the concatenation of s1
and s2. s1, s2, and s3 must be sufficiently known to produce finite sets of
triplets, i.e. either the third known argument, or two of the three known
strings.
Example:
>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=""}
substring(s1,i,j,s2)
Extracts a substring of length j from the string s1 beginning at position i, and
attempts to unify it with s2.
Example:
>substring("1234567890", 3, 4, x);
{x="3456"}
find_pattern(s1,s2,n)
Unifies n with the position of the start of string s2 within string s1. If s2 is
not found, find_pattern fails.
Example:
>find_pattern("1234567890", "3456", p);
{p=3}
>find_pattern("1234567890", "abcd", p);
>
2This is the ISO code 8859-1 (see table at the end of section 1.9). This character set is the 8 bit
extended American ASCII set with accented characters
©PrologIA
Aociation Prolog
conc_list_string(l, s)
Concatenates the strings in list l to create string s.
©PrologIA
Aociation Prolog
R 4 - 12 Manuel de Référence HERITAGE
Example :
>conc_list_string("How "."are "."you "."?".nil, x);
{x="How are you ?"}
copy_term(t1, t2)
Makes a copy of the term t1 in which each free variable (constrained or not) is
replaced by a new variable without constraints, and unifies this copy with t2.
This means the two terms are represented by the same tree, apart from the
variable names. t1 is any prolog term, even an infinite one.
Example :
>copy_term(one(2.x,y), t);
{t=one(2.v33,v31)}
copy_term_with_constraints(t1, t2)
Identical to the predicate copy_term/2 but copies the constraints onto the
variables.
enum(i,k1, k2)
enum(i,k2)
k1 and k2 must be known integers. If k1 > k2 the rule fails. By definition, this
rule can be executed in k2 - k1 + 1 ways. The first way is to unify i and k1;
the second is to unify i and k1 +1, etc …; the final way is to unify i and k2.
Example:
>enum(i,5,9);
{i=5}
{i=6}
{i=7}
{i=8}
{i=9}
gensymbol(i)
Creates a new identifier in the form idn where n is an integer, and unifies it
with i.
list_string(l, s )
Creates a string s from the list of characters l.
Example:
>list_string("H"."e"."l"."l"."o".nil, x);
{x="Hello"}
list_tuple(l, t )
Composes a tuple t from the list of arguments l.
Example:
>list_tuple(111.aaa.222."Hello".nil,x);
{x=<111,aaa,222,"Hello">}
©PrologIA
Aociation Prolog
member(x,l)
Unifies x with item in list l in succession. Is described by the following rules:
member(x, x.l) ->;
member(x, _.l) -> member(x, l);
split(t, l )
Splits a string or a tuple into a list of its components. When split(t, l ) is
executed t must be known; we then have the following:
string_ident(s1,s2,i)
string_ident(s,i)
Defines the link between an identifier and its representation as a string. If the
identifier does not exist it is created. In the first version, the identifier which
has the prefix s1 and the abbreviated representation s2 is made to correspond
to strings s1 and s2, and vice-versa.
Example:
> string_ident(p, i, guests:john);
{ p="guests", i="john"}
> string_ident("guests", "John", x)
{ x=guests:John}
>
In the second version, the current reading/writing context is used, to define the
link between identifier i and its representation s. s can be a complete or
abbreviated representation.
Example (in the standard context):
>string_ident(s,sys:outm);
{s="outm"}
©PrologIA
Aociation Prolog
R 4 - 14 Manuel de Référence HERITAGE
string_integer(s,n)
Makes string s correspond to integer n and vice versa.
Example:
>string_integer(s,123);
{s="123"}
>string_integer("-0123",n);
{n=-123}
string_real(s,r)
Makes string s correspond to real r and vice versa.
Example:
>string_real(s,12.34e5) string_real(s,x);
{s="1.234000000000000e+06",x=1.234000000000000e+06}
>string_real(s,1d110) string_real(s,x);
{s="1.000000000000000e+110",x=1.000000000000000e+110}
string_double(s, d)
Identical with string_real(s,d).
string_term(s, t, s',n)
string_term(s, t, s')
string_term(s, t)
Attempts to read from the string s a Prolog term that will be unified with t. s'
is the unused part of string s. If a variable appears in the string s, a free
Prolog variable is created.
Conversely, if s is not known, it is unified with a string corresponding to the
term t, as out(t) would output it. The argument n is used to specify the
maximum size of the string, if it is more than 400 (400 < n < 32768). An error
occurs if the string becomes longer than this maximum size. If n is not
specified, a default value of 400 is used. When string_term is used this way,
s' is ignored and t can be any term at all, and can even contain variables and
complex structures.
>string_term(s,myterm(x,1.2e0),s') string_term(s,x,s');
{s="myterm(v14,1.200000000000000e+00)",x=myterm(v15,1.2000
00000000000e+00),
s'=""}
>string_term("1.2,3)",t,s') string_term(s,t,s');
{t=1.2,s'=",3)",s="1.2"}
term_vars(t, l)
Unifies l with the list of free variables in t, including constraints if any, t is any
Prolog term, even an infinite one.
Example :
>term_vars(one(2.x,y,y), t);
{t=x.y.nil}
©PrologIA
Aociation Prolog
It is possible to compare any two Prolog terms. To do this, the following increasing
order has been defined:
- variables
- reals
- integers
- identifiers
- character strings
- tuples with length < 2.
- lists
- tuples with length >= 2.
For two variables, the system compares their memory location. For two integers or
reals it compares their values. For two character strings or two atoms it compares
their alphanumeric order. For two lists it compares the first two items found that are
different. For two tuples it first compares their lengths and if they are of equal
length it compares the first two items found that are different. The comparison
predicate is as follows:
term_cmp(X, Y,V)
Compares terms X and Y, unifies V with the integer -1 if X precedes Y, 1 if Y
precedes X, 0 if the terms X and Y are formally equal. Here are some
examples:
> term_cmp(1e0,1,V);
{V=-1}
> term_cmp(foo,zebra,V);
{V=-1}
> term_cmp(short,short,V);
{V=0}
> term_cmp(shorter,short,V);
{V=1}
> term_cmp(foo(a),foo(b),V);
{V=-1}
> term_cmp(foo(aa),foo(bb),V);
{V=-1}
> term_cmp(X,X,V);
{V=0}
> term_cmp(Y,X,V);
{V=-1}
> term_cmp(_,_,V);
{V=-1}
> term_cmp("foo",foo,V);
{V=1}
> term_cmp(1.2.3.nil,1.1.3.4.nil,V);
{V=1}
> term_cmp(1.2.nil,<1,2>,V);
{V=-1}
> term_cmp(1.2.nil,<X>,V);
{V=1}
term_cmpv(X, Y, V)
Compares X and Y in the same way as term_cmp, but without taking account
of the variables appearing in terms X and Y. For the term_cmpv predicate, two
distinct variables are considered identical. Example:
©PrologIA
Aociation Prolog
R 4 - 16 Manuel de Référence HERITAGE
Example:
> term_cmpv(foo(V1),foo(V2),V);
{V=0}
Two list sorting predicates are provided: sort/2 and keysort/2. To perform sorting,
they use the term_cmp/3 predicate described above internally.
sort(L1, L2)
L2 is unified with the list of items in L1 sorted in increasing order. In this list,
multiple items are only kept once. Example:
> sort(4.7.foo.3.4.1.nil,L);
{L=1.3.4.7.foo.nil}
keysort(L1, L2)
L2 is unified with the list of items in L1 sorted in increasing order. In this list,
multiple items are kept. Example:
> keysort(4.7.foo.3.4.1.nil,L);
{L=1.3.4.4.7.foo.nil}
These same predicates allow you to insert an additional argument to indicate the
user predicate employed to compare terms. This user predicate's arity must be equal
to 3. The first two arguments will receive the terms to compare, while the 3rd will
return the result of the comparison (-1, 0 or 1).
©PrologIA
Aociation Prolog
HERITAGE
The input/output devices used by a Prolog II+ program (keyboard, screen, files,
etc.) are represented by objects called input/output units. These units are represented
in written form by a character string1. If necessary, this string also represents
information which identifies the unit in relation to the operating system: file-name
etc.
At any given moment, the Prolog II+ system "knows" a certain number of
input/output units: these are units which were opened previously, and have not yet
been closed. The descriptors for these units are stored in a type of stack: the unit at
the top of the stack is called the current unit. In principle, all input/output operations
are performed using the corresponding current unit. At start-up, the system
automatically opens an input unit and an output unit, (both called console) which are
the current units. Usually, these units are associated with the keyboard and the
screen of the computer or terminal which Prolog has been started from.
Changing the unit (i.e. executing input(f) or output(f)) does not close the current
unit or change its state. Instead, a new unit is opened, if necessary, and is placed at
the top of the stack, above the previous current unit. In this way, the latter can be
restored to its previous status when the new current unit is closed.
The number of units which can be open simultaneously depends on the host
machine.
Each created input/output unit is of a specific type and has a specific opening mode.
The different possible types are:
- :console: unit type Prolog creates automatically at start-up.
- :text: text format disk file.
- :binary: binary format disk file.
- :memory_file: memory file described below.
- :unix_pipe: Inter-process communication pipe (UNIX).
© PrologIA
Aociation Prolog
R5-2 Reference Manual HERITAGE
The following types of unit can be opened for both reading and writing: :console,
:tty_area , :edit_area, and :memory_file.
memory_file(s)
memory_file(s,n)
Creates a "memory file" unit called s. In the first version of the predicate, the
character buffer is 400 characters long. In the second version, the buffer has
the length n or the nearest value to it, given that the minimum allocated size is
400 characters, and the maximum allocated size is 32K characters. This unit
can be used as input and output. It can be the current input unit and the
current output unit simultaneously. If the buffer is too small for the writing
operations performed in it, it automatically doubles its size, although it never
exceeds 32K characters. The unit will be physically closed when it is closed
for both reading and writing. This unit can be used in the same way as the
files.
The unit types and opening modes can be obtained using the following predicate:
current_file(x)
current_file(x,t,m)
Unifies x in succession with the names of the units open for reading and/or
writing. Unifies t with the unit's type, and m with the opening mode.
5.1 Input
The standard character buffer provided by Prolog for an input unit is limited to 400
characters. If a line is longer than this, Prolog behaves as if there were a space after
the 400th character. The rest of the line is read once the 400 previous characters
have been exhausted.
© PrologIA
Aociation Prolog
eol
Tests for an end of line in input.
Tests whether an end of line has been reached. To be more precise; if the next
character to be read is an end-of-line mark, eol executes, otherwise its
execution fails.
Example:
> in_char'(c) eol;
a<CR>
{c="a"}
> in_char'(c) eol;
a<space><CR>
>
eof
Tests for an end of input.
Tests whether any characters are left to input on the current unit, i.e. tests
whether the next read will cause error 104: END OF FILE. If this is not the
case, execution of eof fails. Obviously this primitive cannot execute on the
console or in a TTY window, since these are terminal mode units, which
always have characters, sometimes as a result of user input.
Example :
> input("empty_file") eof input("console");
{}
>
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. The end of a line is considered as a space character.
Note: although the end of line character is treated as a space by other
primitives that analyze the read characters, for this primitive it will have the
value "\n".
Please note: all commands (goal sequence) end at the ";". When in_char is
launched on the command line, the first character to be read is the one
immediately after ";". This is often "end-of-line".
Example:
> in_char(c);
{c="\n"}
> clear_input in_char(c);
a<CR>
{c="a"}
© PrologIA
Aociation Prolog
R5-4 Reference Manual HERITAGE
in_char'(t)
Reads a non-blank character.
Reads all blank characters and then behaves like in_char(t).
Example:
>in_char'(x) in_char(y) in_char'(z) in_char(t);
ab c d
{x="a",y="b",z="c",t=" "}
next_char(t)
Attempts to unify the next input character with t without actually reading it.
next_char'(t)
Reads all blank characters, if any, and then behaves like next_char(t).
Example:
>next_char'(x) in_char(y);
abc
{x="a",y="a"}
inl(s)
inl(s, n)
Reads one line.
Reads all the end of the current line and unifies it as a character string with s.
n is unified with the rank of the read line in its unit. n is much more useful for
files and for EDIT windows. In the console or TTY windows, the lines are
divided into two groups; input and output lines. n then corresponds to the
rank within these groups.
Example:
> clear_input inl(s);
Maitre corbeau, sur un arbre perche
{s="Maitre corbeau, sur un arbre perche"}
in(t, c)
in(t, D, c)
Reads a Prolog term.
Reads the longest character sequence x which is a term or the beginning of a
term. If x is the expression of a term, unification of x with t is attempted. If x is
not a term, an error occurs. All blank characters following x are read. c unifies
with the first lexical unit read that does not belong to x. D is unified with
variable dictionary of the term, i.e. a list of pairs corresponding to t's
variables. Each pair contains the character string that is the original name of
the variable, and the relevant variable.
Example:
>in(t, c);
this is a term;
{t=this is a term, c=";"}
>in(t, D, c);
aa(x, bb(y_n1',x));
{t=aa(v129, bb(v163,v129)),
D=<"x", v129>.<"y_n1'",v163>.nil, c=";"}
© PrologIA
Aociation Prolog
Please note: in this case, it is essential to read one unit in advance because of
the operators.
in_integer(t)
First reads all blank characters, and then attempts to read an integer on the
current unit. If the object does not have integer syntax, nothing is read and
in_integer fails. Otherwise t is unified with the integer which has been read.
Example:
> in_integer(i) in_char(c) in_integer(j);
-123+456
{i=-123,c="+",j=456}
Warning: since integers and reals can be written on several lines using
"\<return>" (if the option for interpretation of '\' is active (see section U2.3.)),
if the object is written on several lines it is not possible to restore the lines
before the last line if the object is not an integer (in this case it is a real).
in_real(t)
First reads all blank characters, and then attempts to read a real on the current
unit. If the object does not have real syntax (defined by the current option),
nothing is read and in_real fails. Otherwise t is unified with the real that has
been read.
> in_real(x) in_char(c) in_real(y);
-123e+4,54.63d0
{x=-1.230000000000000e+06, c=",", y=5.463000000000000e+01}
Warning: since integers and reals can be written on several lines using
"\<return>" (if the option for interpretation of '\' is active (see section U2.3.)),
if the object is written on several lines it is not possible to restore the lines
before the last line if the object is not an integer (in this case it is a real).
in_double(t)
Identical with in_real(t).
in_string(t)
First reads all blank characters, and then attempts to read a Prolog string. If
the object does not have string syntax, nothing is read, and in_string fails.
Otherwise, t is unified with the read string.
Warning. this is a string type Prolog term (i.e. with quote marks) and not
"anything, considered as a string".
Example:
> in_string(s) in_char(c);
"Hello !";
{s="Hello !", c=";"}
in_ident(t)
First reads all blank characters, and then attempts to read a Prolog identifier. If
the object does not have identifier syntax (defined by the current option),
nothing is read, and in_ident fails. Otherwise, t is unified with the read
identifier. Example:
read(integer(n)) -> in_integer(n) !;
read(ident(i)) -> in_ident(i) !;
© PrologIA
Aociation Prolog
R5-6 Reference Manual HERITAGE
in_word(t1,t2)
Reads all blank characters, then reads the largest word, transforms it into a
string and tries to unify this string with t1. A word is either:
in_sentence(t1,t2)
Reads a sentence ending with ".", "?", "!" or any other character defined as a
terminator, and builds two lists out of it. t1 is the list of lexical units
constituting the sentence (words in the in_word sense), and t2 is the list of
corresponding atoms, as for in_word. The list of sentence terminators can be
modified by the predicates a d d _ s e n t e n c e _ t e r m i n a t o r / 1 and
remove_sentence_terminator/1.
>in_sentence(x, y);
this is a string.
{x="this"."is"."a"."string".".".nil,
y=nil.nil.nil.string.".".nil}
>in_sentence(x, y);
sum := 052345;.
{x="sum".":"."="."052345".";".".".nil,
y=nil.":"."=".52345.";".".".nil}
add_sentence_terminator(C)
Adds the character C to the list of sentence terminators (initially containing the
characters ".", "?", and "!").
© PrologIA
Aociation Prolog
remove_sentence_terminator(C)
Removes the character C from the list of sentence terminators. Causes a
failure if the list does not contain this character.
read_unit(t, u)
Reads a lexical unit.
Reads a lexical unit, unifies t with its type (identifier, number etc.) in the form
of a number, and u with its value.
Prolog II+'s lexical units are defined by the grammar in section 1.9. The
numbers given by t in read_unit correspond to the following notations from
this grammar:
value of t lexical category value of u
1 identifier the identifier
2 separator2 the corresponding string
3 variable the corresponding string
4 constant the constant
5 graphic_symbol the corresponding string
Example:
> read_unit(t1,u1) read_unit(t2,u2) read_unit(t3,u3)
read_unit(t4,u4);
x12 + :pi ,
{t1=3,u1="x12",t2=5,u2="+",t3=1,u3=pi,t4=2,u4=","}
> read_unit(t,u);
123
{t=4,u=123}
read_rule(t1, t2)
Reads a Prolog rule on the current input unit, and unifies t1 with the head and
t2 with the list of terms in the body.
Example:
> read_rule(t1,q1) read_rule(t2,q2);
tt(1,x) -> outl(x) fail;
tt(2,x) -> !;
{t1=tt(1,v118),q1=outl(v118).fail.nil,
t2=tt(1,v228),q2='!'.nil}
>
sscanf
The C function sscanf is accessible from Prolog via the callC primitive (see
section 6.6 of this manual).
Example:
> callC(sscanf("123","%f",<"R",y>));
{y=1.23000e+02}
> eq(f,"%x %o") callC(sscanf("12 12",f,<"I",x>,<"I",y>));
{x=18, y=10}
>
© PrologIA
Aociation Prolog
R5-8 Reference Manual HERITAGE
The names for the input units can be Prolog strings or Prolog identifiers or integers.
Files and predefined windows can only be represented by strings.
input(u)
input(u,n)
The unit named u becomes the current input unit. If this unit is not one of the
open units, its descriptor is created and added to the stack of open input units.
If it is a new unit, a file is found and opened. A command file opened by input
can itself contain an input command. The new current unit is stacked above
the previous one. In the two argument version, n expresses the size of the
unit's buffer by the number of characters. It must be between 400 and 32K.
If n is not in this interval the buffer size will be the nearest value.
input_is(u)
Gives in u the name of the current input unit.
close_input
Closes the current unit (unless it is the console or a window) and removes its
descriptor from the top of the stack of units. The previous unit again becomes
the current unit.
close_input(u)
u is the name of a unit which must be included in the list of open input units.
Closes this unit (unless it is the console or a window) and removes its
descriptor from this list.
clear_input
Ignores characters remaining unread in the current input line.
5.2 Output
Prolog maintains a line pointer for each output unit, by means of the out, outm and
line primitives. It is reset by executing the line primitive. This pointer is used to
maintain within the system a representation of events on the unit's current line. In
particular, it can be used to find out how much space is left on the line (the line
length is defined by set_line_width) and then set a new carriage return.
Use of set_cursor does not affect this line pointer, and so Prolog's representation of
the line is no longer accurate. New carriage returns that are set (\<return>) may be
unwanted. To avoid this, it is recommended to use the outl and outml primitives with
set_cursor, instead of the out and out primitives. In this way, the pointer is
constantly reset, and management of presentation is left entirely to set_cursor. It
should be noted that the same behavior is obtained by making use of external rules
(C, Pascal, …) which manage screen presentation.
© PrologIA
Aociation Prolog
beep
Generates a warning beep.
flush
Empties the current output unit's character buffer, by sending all the characters
waiting to be written to the associated physical unit.
out(t)
outl(t)
Writes the term t on the current unit. Any term written with out can be re-read
with in if the option for interpretation of «\» is active (see section 2.3. of the
user's manual). If a term is longer than the remaining length of the line, a
carriage return is inserted, in accordance with the following rules.
(1) Strings are cut in the required place, by insertion of a masked carriage
return (i.e. preceded by the character "\").
(2) Numbers are not cut, unless a single number is longer than a whole
line, in which case it is cut in the same way as a string.
(3) Identifiers are not cut, unless a single identifier is longer than a whole
line, in which case it is cut in the same way as a string.
The term is written in conformity with the following conventions:
(1) Lists are printed with period notation for Prolog II syntax and with
square brackets for Edinburgh syntax or if the option "standard
notation for reals" is active.
(3) Any identifier which does not correspond to identifier syntax is written
with quote marks.
outl(t) is equivalent to the goal sequence out(t) line; when the term t is written,
the system goes to the next line.
Example:
>out(1.Peter."Hi!".nil);
1.Peter."Hi!".nil{}
>
© PrologIA
Aociation Prolog
R 5 - 10 Reference Manual HERITAGE
Please note: the braces printed after the term indicate that the goal
>out(1.Peter."Hi!".nil); has been successfully executed. One way of avoiding
this print-out is to make this execution fail artificially:
>out(1.Peter."Hi!".nil) line fail;
1.Peter."Hi!".nil
>
outm(s)
outml(s)
Writes the string s on the active output unit without the quote marks, and with
correct interpretation of formatting characters which s may contain (for
example: \n). A string longer than the remaining space on a line is truncated
by a "masked" carriage return. Characters corresponding to a non-printable
ISO 8859-1 code are sent to the current output unit without being
transformed.
Example:
>out(" \tHello! ") line fail;
"\tHello!"
>outm("\tHello!") line fail;
Hello!
>
outm(s,n)
Writes the string s n times, with the same conventions as above.
Example:
>outm("-",40) line fail;
----------------------------------------
>
out_equ(t)
Writes the minimal system of equations for the term t . This rule is much
slower than out, but it factorizes the sub-trees and thus produces a more
compact representation, when this is possible.
line
Outputs a new line.
page
Goes to the next page. On the "console" unit, the screen is cleared and the
cursor is positioned at the top left hand corner of the screen. It has no effect in
the graphics environment.
paper
Writes a copy of console activity into a log file (default: prolog.log ).
© PrologIA
Aociation Prolog
no_paper
Cancels paper. The log file is only closed at the end of the session. A
subsequent call to paper will add information at the end of the file.
set_cursor(n1,n2)
The cursor is positioned at (n1,n2) on the screen, where n1 is the column
coordinate and n2 is the line coordinate. (1,1) corresponds to the top left hand
corner of the screen. The following conditions must be fulfilled:
1 n1 line width, and 1 n2 lines on the screen.
It has no effect in the graphics environment.
set_line_cursor(n)
Positions the current character pointer at n on the current line. This provides a
type of tabulation. set_line_cursor does not work backwards from the current
character pointer. The first character position is 1.
sprintf
The C function sprintf is accessible from Prolog via the callC primitive (see
section 6.6 of this manual).
Example:
> callC(sprintf(<"",x,80>,"value: %ld",200));
{x="value: 200"}
To use the following primitives, it is necessary to first load the tree drawing module
(see section 5.3).
draw_equ(t)
Draws the minimal system of equations representing a finite or infinite tree t.
The tree-drawing module must be loaded in order to use this primitive.
> ... draw_equ(aa(bb(cc,dd),bb(cc,dd))) ...
aa
+--^--+
v1026 v1026
v1026 = bb
+^-+
cc dd
{}
draw_tree(t)
Draws the finite tree t on the screen (if the terminal has graphics facilities,
semi-graphic symbols are used). The tree-drawing module must be loaded in
order to use this primitive.
> ... draw_tree(aa(bb(cc,dd),bb(cc,dd))) ...
aa
+--^---+
bb bb
+^-+ +^-+
cc dd cc dd
{}
© PrologIA
Aociation Prolog
R 5 - 12 Reference Manual HERITAGE
draw_mode(x)
The following two primitives control the way trees are drawn. Depending on
the type of screen, some semi-graphic characters can be used to produce better
drawings. draw_mode(x) gives a character string x, which indicates the type of
screen used. The possible values for x depend on the machine: they are
"VT100", "GRAPHICS" and "TTY". "TTY" is for terminals without graphics
facilities, and is available on all machines. The tree-drawing module must be
loaded in order to use this primitive.
set_draw_mode(x)
Makes it possible to choose the type of screen to be used for tree drawing.
The values for x are the same as before. If you want to print trees on a
standard printer, the "TTY" mode must be used. The tree-drawing module
must be loaded in order to use this primitive.
The names for the output units can be Prolog strings or Prolog identifiers or
integers. Files and predefined windows can only be represented by strings.
output(u)
output(u,n)
The unit called u becomes the current output unit. If the unit designated by u
is not already in the list of open output units, then the unit is allocated a
descriptor, and a file may be created with the name u. In the two argument
version, n expresses the size of the unit's buffer by the number of characters.
It must be between 400 and 32K. If n is not in this interval, the buffer size will
be the nearest value. In the one argument version the buffer size will be 400
characters.
This primitive can never be used to create a window or a memory file; to do
that please use the relevant primitives. If u is a character string ending with the
sign "+", the file with the same name apart from this sign is then opened in
append mode, i.e. if the file already exists on the disk, subsequent output will
be added to it.
output_is(u)
Gives in u the name of the current output unit.
close_output
The current unit is removed from the top of the stack of open output units. If
this corresponds to a file, the file is closed.
close_output(u)
u is the name of unit which must be included in the list of open output units.
If it is a file it is closed. The unit's descriptor is removed from this list and
deleted. This primitive can never be used to close a window; to do that please
use the relevant primitives
© PrologIA
Aociation Prolog
line_width(n)
Returns in n the maximum current width of the current unit's lines, defined by
set_line_width.
set_line_width(n)
Is used to define the maximum line width in the current output unit. n
becomes the unit's new line width. The default line width is 80 characters. The
maximum possible width is 400 characters. If no carriage return is requested
before the maximum line length is reached, Prolog inserts one: either
<carriage return> is inserted between two lexical units, or the sequence
<\><carriage return> is inserted inside a unit.
echo
Activates the option which produces a display on the "console" unit of
characters written or read by another file type unit.
no_echo
Cancels the effect of echo.
The Dessin module is not included in the initial state we supply. You can add it to
your Prolog system by loading the binary file:
>load("dessin.mo");
This file creates a new module called Dessin containing the program for drawing
trees and equations. This makes the following rules available (see section 5.2.1):
draw_equ
draw_tree
draw_mode
set_draw_mode
gr_tree_click if graphic mode is active.
© PrologIA
Aociation Prolog
R 5 - 14 Reference Manual HERITAGE
Some configurations are already defined: vt100, tty, etc. It is up to you to add to
dessin.m2 the configurations required by the terminals you use.
termi(external_name,internal_name) —>;
Note that the end-user should only know the external name.
2. Add two new definitions of the en-graphique and hors-graphique rules which
control the terminal's transition from character mode to semi-graphic mode,
and vice versa.
3. Add a new config rule to define the character strings which, when in graphic
mode, display the graphics indicated.
Please note
In all cases, the "TTY" mode can be used to obtain basic drawings without having to
use any of the terminal's graphic possibilities. This can be useful for example if you
want to print tree diagrams on a standard printer.
The operators make it possible to write functional terms having one or two
arguments, without using brackets. The functional symbol is replaced by an
operator placed as follows:
© PrologIA
Aociation Prolog
op(n,i1,s)
op(n,i1,s,i2)
Declares the operator s with precedence n(0 <= n <= 1200) and bracketing
type i1. s is an identifier, or a string representing a graphic symbol. In the 3-
argument form, s can be a list, and the declaration then applies to each list
element. The 3 argument version is also a compiling directive. This means
that an operator can also be declared in the middle of a source you are
compiling. The functional symbol represented by s is i2 if the latter has been
defined, otherwise it is the symbol s given. The associativity il is defined by
an identifier combining two or three letters f, x, y; with the following
conventions:
f represents the operator
x represents an expression with an order of precedence less than f
y represents an expression with an order of precedence less than or equal
to f.
The possible combinations are:
fx operator prefixed with operand of lesser precedence
fy operator prefixed with operand of lesser or equal precedence
xf operator postfixed with operand of lesser precedence
yf operator postfixed with operand of lesser or equal precedence
xfx operator infixed with operands of lesser precedence
yfx operator infixed on the left with an operand of the same precedence, with
left right bracketing
xfy operator infixed on the right with an operand of the same precedence,
with right left bracketing
Example:
> insert;
op(900,fy,not) op(700,xfx,"=",eq);
not x -> x ! fail;
not x ->; ;
{}
> (not 1=2)3;
{}
> split(1=2,L);
{L=eq.1.2.nil}
3Remember that in Prolog II syntax, the operators must be bracketed at the first level of a rule
body.
© PrologIA
Aociation Prolog
R 5 - 16 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
6. The environment
This chapter describes the predefined rules which provide communication with the
operating system, and which function regardless of which particular system is used.
Those rules which depend on the implementation used are described in the user's
manual.
exit(s)
exit
Leaves Prolog, and saves all the currently known programs, including those
which constitute the Prolog II+ supervisor. The current state is saved in a file
called s. The second form, exit, is equivalent to exit(prolog.po).
Note: it is possible to just save the modules you have created or modified
during the session (command save -see section 3.7) and leave Prolog using
the quit command.
quit(n)
quit
Leaves Prolog without saving anything. The value n is sent to the operating
system as a "termination status". Whatever the system, if n=0 the value sent
corresponds to "no error" (this value does not have to be nil).
The second form, quit, is equivalent to quit(0).
If the binary state used to start Prolog contains modules that have an ini_module
rule, each of these rules is executed (in an order defined by Prolog), as soon as
initialization terminates. Prolog then attempts to execute the goal :to_begin.
The :to_begin rule is not defined in the initial state. If you want the program to start
automatically, you should add the following rule:
© PrologIA
Aociation Prolog
R6-2 Reference Manual HERITAGE
where xxxx is the initial goal to be executed from the application program. You must
then save this state. When you call Prolog later on with this new state, xxxx will be
executed immediately.
Since Prolog II+ is an incremental compiler, it enables you to edit rules without
leaving Prolog, using an editor that we will call a host editor.
There are several versions of this command, depending on what you want to do:
There are some important things you should know about editing in Prolog:
- rules are deleted from the Prolog code space so that they can be written in the
text file used for editing. At the end of editing the file is reinserted.
- editing compiles, and therefore when non compiled facts are edited they will
be transformed into compiled rules.
- at any particular time there is only one copy of the rules; either as Prolog code
or as Prolog source.
- when a user interrupt occurs the code space will however be modified, in a
variety of ways depending on when the interruption occurs.
- when non visible rules are edited they are deleted, but are not provided in
source format!
This command is used to edit groups of rules, listed as arguments. When editing is
finished, these groups are re-inserted in place of the original groups. The groups
can belong to several different modules, in which case it is the reading/writing
context of the first group's module which is used.
© PrologIA
Aociation Prolog
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 .
l is a sequence of ident/arity elements (may or may not end in nil).
When Prolog returns from a host editor call it may detect a syntax error in the rules
that you have just edited. If so it will display the number and contents of the line
containing the error, the corresponding diagnosis, and will ask you if you wish to
re-start the editing-compiling cycle, or abandon the attempt.
If you abandon the attempt the system brings you back to Prolog, and the non-
inserted rules are deleted.
By pressing the carriage-return key you can restart the host editor, and correct the
error. By pressing q <RETURN> you return to Prolog, and the non-inserted rules
are deleted.
Please note
It is possible that the text you have edited contains an error which Prolog
cannot detect immediately.
Remember that when the host editor is used, a file called PROEDIT.PRO
is created in the current directory, which contains the edited rules in their
final state. You will find yourself back in Prolog, without the edited rules
which have not been read. Save this program, and once you have left
Prolog, use a text editor to analyze the missing piece from
PROEDIT.PRO.
This function is used to modify and recompile the source text of a loaded module.
Editing will be carried out on the original form:
editm(m)
m is a string. Deletes all rules in the module m and starts editing of the
corresponding source file. The edited version is recompiled and replaces the
previous version.
If the source file cannot be found, editing is performed on a source created by
decompiling the module. This source file is called PROEDIT.Mx where x is
a number generated by Prolog having a different value for each module with a
different name.
Please note: any rules which may have been added to the module using
insert or assert during execution are executed before the module is
reloaded.
© PrologIA
Aociation Prolog
R6-4 Reference Manual HERITAGE
edit(s)
s is a string. Enables editing the file of name s.
reset_cpu_time, cpu_time(x)
cpu_time unifies x with the cpu time in milliseconds elapsed since the last
reset_cpu_time.
date(j,m,a,s)
Calculates the arguments j,m,a,s for the current date. The four arguments
correspond to the day of the month, the month, the year, and the number of the
day in the week (Sunday = 0, Monday = 1, ...).
date_string(s)
Calculates the current date in English and unifies the corresponding character
string with s.
date_stringF(s)
Calculates the current date in French and unifies the corresponding character
string with s.
week(n,s)
Returns in s the string corresponding to the day in the week whose rank is n,
and vice-versa.
month(n,s)
Returns in s the string corresponding to the month whose rank is n and vice
versa.
delay(n)
Generates a delay of n milliseconds
time(x)
Gives an absolute time in seconds. The origin of this time varies from one
machine to another.
© PrologIA
Aociation Prolog
time(h,m,s)
Calculates arguments h, m, s of the current time, representing hours, minutes
and seconds.
sys_command
Executes an operating system command represented by the string s. When
the command called causes an error, sys_command generates a "SYSTEM
ERROR" and provides an error complement; the status returned by the
operating system.
On some systems (especially those running UNIX), this predicate may
consume a large amount of memory. This can be avoided by redefining it
with a coprocess (on these systems, refer to the chapter on coprocesses).
getenv(s,x)
Unifies x with the string representing the value of the environment system
variable whose name is defined in the string s. If the variable is not defined, x
is unified with an empty string.
set_import_dir(s)
Defines a reference directory that is consulted after the current directory, when
files have not been found by primitives manipulating files for reading, such as
input, insert, load. The character string s concatenated to a file name must
define a complete name the operating system can understand.
lkload(s,x)
This primitive is only available on certain operating systems, so please refer to
the User's Manual. When present, it enables dynamic linking and loading of
external programs.
ms_err(n,s)
Unifies s with the text of error number n. To do this, Prolog searches in the
error file err.txt which must consist of a sequence of lines in the following
format:
integer space character sequence constituting the text of the error.
You can add messages to this file, provided you comply with the indicated
format. We recommend you message numbers greater than 1000.
© PrologIA
Aociation Prolog
R6-6 Reference Manual HERITAGE
When you have executed the program with the debugger enabled, the built-in
predicate statistics may help to configure the Prolog spaces.
To begin with, before you plunge into the detail of the interactive mode commands,
the trace mode enables you to display all the information required to understand the
program.
The trace mode is a simple and quick way of understanding how a program
executes.
Each executed goal is displayed with its unified arguments on the rule chosen for
the current execution. The backtrackings are shown and the system specifies the
predicate where choices remained and the new rule's rank in the group.
If you load the example program menu.p2 and activate trace mode, the following
sequence shows how this information is presented:
> meal(e,Chapon_farci,d);
hors_d_oeuvre( Artichauts_Melanie)
main_course( Chapon_farci)
RECALL(2): main_course/ 1
main_course( Chapon_farci)
fish( Chapon_farci)
dessert( Sorbet_aux_poires)
{e=Artichauts_Melanie,d=Sorbet_aux_poires}
RECALL(2): dessert / 1
dessert( Fraises_chantilly)
{e=Artichauts_Melanie,d=Fraises_chantilly}
RECALL(3): dessert / 1
dessert( Melon_en_surprise)
{e=Artichauts_Melanie,d=Melon_en_surprise}
© PrologIA
Aociation Prolog
To make the information provided by the trace easier to read (when executing
programs that write on the current output), it can be redirected into a file.
Activation, deactivation
Trace mode is activated by executing one of the built-in predicates trace/0 or
trace/1. It is deactivated by executing the built-in predicate no_trace/0.
trace
Activates the trace.
trace(f)
Activates the trace. It redirects all trace output into the file called f (Prolog
string). The file is closed when a predicate to close the debugger is executed.
If the debugging output was already redirected, the previous file is closed and
replaced by f.
no_trace
Deactivates the trace.
Although the trace is simple to activate, it can rapidly produce a considerable flow of
information where it is easy to get lost. This is where the interactive mode becomes
extremely useful, because it enables you to go straight to the most important
information. Its advantages are:
Interactive mode enables you to choose the information you want to extract from the
program, in the appropriate format, without modifying the program, and only in
designated sections of the code. Above all, it enables you to take control whenever
you want, to start actions.
© PrologIA
Aociation Prolog
R6-8 Reference Manual HERITAGE
• temporary break points that are only valid during a command, which in fact
defines the next check point for the debugger.
When a break point is defined on a predicate the debugger stops as soon as the
current program calls this predicate. The Prolog machine will therefore stop at the
moment when the goal is to be erased, before unification with the head of the chosen
rule has taken place.
There are specific commands and built-in predicates to define fixed break points.
The temporary break points are defined implicitly by an advance command or when
the debugger is activated.
When the Prolog machine is running with the debugger enabled, a user interrupt
posts a temporary break point on the current goal and the interactive mode is re-
enabled. This means user interrupts are intercepted and do not produce an error.
See the debugger commands +, -, b and the predefined rules spy, no_spy,
show_spy.
There are three scales of advance. You will use different scales depending on how
"close" the error is and the type of information you want to extract from a section of
the program.
Starting from a break point, there are three ways of advancing (jumps):
1) You know where the problem is in a program, and you want to get there directly
and quickly.
Answer: (go to spy) goes to the next fixed break point, which can be
anywhere in the code.
2) You want to have a "close look" at the execution of the function, without going
down into the low levels of its "sub-programs".
Answer: (next) goes to the next goal of the same level or upper level. It
ignores the lower levels1, i.e. ignores the body of the current rule.
3) You want to see the whole execution of the function precisely, without omitting
any instructions.
1 Definition of a goal's level. Let's suppose a goal of the question is on level 0. If a goal is on
level n, the goals appearing in the body of its rule are all on the same level, equal to n+1.
© PrologIA
Aociation Prolog
On our example of a menu, let's represent the possible advance jumps using next
and step:
meal ...
step
next
meat
Note that on the specified facts step and next have the same effect.
The commands for advancing in the code enable you to define the next break point
and the information that must be obtained in the meantime. Each time you advance
you can choose whether or not to display information about the execution of the
program section.
- (go to end) continue to the end of the program: by printing all the information, by
printing just the information concerning the fixed break points, or by leaving debug
mode and continuing normally.
© PrologIA
Aociation Prolog
R 6 - 10 Reference Manual HERITAGE
When?
A backtracking is generated:
The number of the rule to try again is written in brackets (2). A break point is
inserted on the new call to the goal
main_course( Chapon_farci)
On this other alternative we then have access to all the functions of the debugger.
The break points are not modified. The error message is displayed, even if the error
is recovered by a block, together with the resolution branch, when the error occurs.
For example, on the following execution:
> insert;
toto(x,y) -> block(x,titi(y)) outl(x);
titi(y) -> string_ident(y,z) outl(z);
© PrologIA
Aociation Prolog
;
{}
> debug toto(x,12);
CALL: toto( v156, 12)
DBG:
block
CALL: titi( 12)
DBG:
CALL: string_ident( 12, v360)
DBG:
BAD ARGUMENT TYPE
^^^^^^^^^^^^^^^^TOP^^^^^^^^^^^^^^^^^^
^^^^^^^^ titi / 1, rule number 1
^^^^^^^^ toto / 2, rule number 1
^^^^^^^^^^^^^^^BOTTOM^^^^^^^^^^^^^^^^
CALL: outl( 253)
DBG:
You can cancel display of this information about errors during a debugging session,
using the debugger command s.
This mechanism does not show up the errors block_exit produces in Prolog. The
predefined rule block_exit is treated as an ordinary predicate. To obtain a warning
about this type of error, simply put a break point on block_exit/1 and block_exit/2.
Goals can be printed on two occasions, which we will call "before unification" and
"after unification". See the debugger commands p, P.
Goals can be printed before unification, i.e. the goal is displayed as it appears in the
current list of goals before it is unified with rule head chosen for its erasure.
They can be printed after unification, i.e. the goal is displayed after the rule has been
chosen and just before the next break point. Therefore we can obtain different
results from one execution to another for different advance jumps. For example, if
the advance jump in the debugger is a step for a specific goal, the Prolog machine
will have simply unified the goal with the rule head. However, if the jump is next the
Prolog machine will have executed the body of the rule where the unifications have
taken place, and the goal's arguments will not necessarily have the same values as
before.
Let's look at the value of the arguments for our example, using both types of
advance:
> meal(e,p,d);
CALL: meal( v156, v191, v226)
DBG: P1 (validates display after unification)
© PrologIA
Aociation Prolog
R 6 - 12 Reference Manual HERITAGE
DBG:
CALL: hors_d_oeuvre( v156)
DBG:
hors_d_oeuvre( Artichauts_Melanie)
CALL: main_course( v191)
DBG:
main_course( v191)
CALL: meat( v191)
DBG:
meat( Grillade_de_boeuf)
CALL: dessert( v226)
DBG: g (go to spy)
{e=Artichauts_Melanie,p=Grillade_de_boeuf,d=Sorbet_aux_poires
}
…
> meal(e,p,d);
CALL: meal( v156, v191, v226)
DBG: P1
DBG:
CALL: hors_d_oeuvre( v156)
DBG:
hors_d_oeuvre( Artichauts_Melanie)
CALL: main_course( v191)
DBG: n (next)
main_course( Grillade_de_boeuf)
CALL: dessert( v226)
DBG: g
{e=Artichauts_Melanie,p=Grillade_de_boeuf,d=Sorbet_aux_poires
}
…
How?
Presentation
You can define a margin (number of characters) for debugger display, to make the
debugging session easier to read and differentiate between messages from the
program and the debugger. All messages transmitted by the debugger will be
indented the defined number of characters from the margin when displayed.
> meal(e,p,d);
CALL: meal( v156, v191, v226)
DBG:
CALL: hors_d_oeuvre( v156)
DBG:
CALL: main_course( v191)
DBG: n (next)
CALL: dessert( v226)
DBG:
{e=Artichauts_Melanie,p=Grillade_de_boeuf,d=Sorbet_aux_poires
}
RECALL(2): dessert(v190)
DBG:
{e=Artichauts_Melanie,p=Grillade_de_boeuf,d=Fraises_chantilly
}
RECALL(3): dessert(v190)
DBG:
{e=Artichauts_Melanie,p=Grillade_de_boeuf,d=Melon_en_surprise
}
© PrologIA
Aociation Prolog
RECALL(2): meat(v165)
DBG:
CALL: dessert( v226)
DBG:
Another alternative is to redirect the debugger's messages into a file. In this case,
only the prompt sequence will be displayed in the trace unit.
See the debugger command i, or the predefined rules debug(f) and debug(n,f).
Precision
You can configure the precision of the goal display, according to the amount of
information you want. There are three modes:
- The debugger prints the predicates without their arguments and specifies
their arity in the form identifier/arity.
- The debugger prints the predicates and their arguments in the form of a
tree using the Dessin:draw_tree predicate. To use this mode the tree
drawing module must be loaded. The Dessin:draw_tree rule can be
modified to redefine what the debugger prints.
Each atom of the term to print is assigned a depth. Only atoms with a depth less
than the defined limit will be displayed.
The system counts recursively starting from the goal to display, and starts at 1. The
depth increments when the system goes from a term to a sub-term, as follows:
If a functional term f(a1, t2, …, as) appears in a term with depth n then the
functor f has a depth of n, and its arguments a1, …, as have the depth n+1.
If a tuple <t1, t2, …, ts> (t1 is not an identifier) appears in a term with depth
n then the atom <> has a depth of n and the arguments of tuple t1, t2, …, ts
have a depth of n+1.
If a list x.y appears in a term with depth n, then x has the depth n and y has
the depth n+1.
For example, this is how the depths of the atoms are defined for the following term:
© PrologIA
Aociation Prolog
R 6 - 14 Reference Manual HERITAGE
Parts of the program have already been proved and do not need to be verified. In
interactive mode you can use the next advance jump to avoid developing the body of
a predicate. The same possibility is available in trace mode (total trace or printing of
information between two break points).
instead of:
> meal(e,p,d) !;
hors_d_oeuvre( Artichauts_Melanie)
main_course( v191)
meat( Grillade_de_boeuf)
dessert( Sorbet_aux_poires)
{e=Artichauts_Melanie,p=Grillade_de_boeuf,d=Sorbet_aux_poires
}
…
On each break point, the debugger enables you to locate the goal called in relation to
the resolution tree and the rule base.
In fact the current resolution branch is given by the state of the recursion stack.
Because the Prolog machine optimizes the terminal call, it is not possible to view the
rules in which the currently executing goal is the last in the rule body. For example:
> meal(e,p,d);
© PrologIA
Aociation Prolog
Finally, to have access to the maximum amount of information, you can open a
Prolog session. This enables you to check for the program's side effects, restart
part of the program, start an additional program, verify the rule base, check the status
of the stacks, etc.
When the session opens, the command line prompt is displayed in the console and
you can enter any Prolog goal. When you close the session (e.g. by executing quit)
the debugger continues from where it was. It should be noted that the session's side
effects are kept: assignments, addition/suppression of rules, opening/closing of files,
etc.
© PrologIA
Aociation Prolog
R 6 - 16 Reference Manual HERITAGE
meat(Poulet_au_tilleul) -> ;
6.6.2.6 Configuration
As we have already seen, it is possible to define the debugger's behavior. The set of
behavior parameters is called the configuration.
Some configuration parameters can be specified when the debugger starts. They
will be valid during throughout the debugging session (i.e. for as long as the
debugger has not been disabled or reactivated with different parameters) unless a
command modifies them.
There are debugger tools enabling you to ascertain its configuration, and obtain
other information about the debugging:
the state of the options,
the list of active break points,
the list of predicates not developed in the trace,
the list of debugger commands.
© PrologIA
Aociation Prolog
The debugger is activated as soon as one of the built-in predicates trace/0, trace/1,
debug/0, debug/1 or debug/2 is executed. It is deactivated by executing one of the
built-in predicates no_trace/0 or no_debug/0.
A flag defines the configuration at the beginning. It is the sum of the values chosen
from:
1 break on the first call to a goal.
2 break on the first fixed break point.
8 Option to print after unification confirmed.
16 Option to print before unification confirmed.
debug(n) or
debug(n, f)
are the general predicates for activating the debugger. n must be a known
integer when the call is made. It specifies the starting configuration as it has
been defined above. An n value of 0 specifies the predefined standard
configuration. f is the name of the file containing the redirected debugger
display. The file is closed when a debugger deactivation predicate is executed.
If the debugger display was already redirected to a file, this file is closed and f
replaces it.
debug or
debug(f)
are the debugger's reactivation predicates. They do not modify the current
configuration. f is the name of the file that will contain the redirected
debugger display. The file is closed when a debugger deactivation predicate is
executed. If the debugger display was already redirected to a file, this file is
closed and f replaces it.
trace or
trace(f)
are the debugger's special predicates. They activate it in trace mode,
represented by the flag 19. f is the name of the file that will contain the
redirected debugger display. The file is closed when a debugger deactivation
predicate is executed. If the debugger display was already redirected to a file,
this file is closed and f replaces it.
no_trace or
no_debug
are the debugger's deactivation predicates. They function regardless of the
mode, and do not modify the current configuration.
© PrologIA
Aociation Prolog
R 6 - 18 Reference Manual HERITAGE
The break points are managed using the following predefined rules:
spy(i/a)
Places a break point on the rule with name i and arity a. The break point is
only taken into account if the debugger is activated with an appropriate mode.
no_spy(i/a)
Removes any break point placed on the rule with name i and arity a.
show_spy(l)
Unifies l with the list of primitives that have an active break point. The
primitives are shown in the normal way: i/a where i is its access identifier and
a is its arity.
At each break point, the debugger prints the prompt sequence "DBG:" indicating
that it is waiting for a user command. A carriage return, written CR in this section,
corresponds to the default command step in interactive mode. The other commands
end in a carriage return.
b (breakpoints) Displays the active break points. See also the show_spy
predicate.
e (end debugging and go) Ends debugging mode and continues execution.
g (go to spy) Continues to the next fixed break point without displaying
anything.
G integer
(Go to end) Continues to the end of the program. If integer is 0 it prints the
fixed break points only. If integer is not 0 it also prints the goals appearing in
the rule body of fixed break points.
© PrologIA
Aociation Prolog
i integer
(indent) The value of integer defines the number of characters for the display
margin.
j
(jump) Gives the list of rules whose bodies are ignored in trace mode.
l integer
(length) The value of integer defines the length of the line for output.
m integer
(mode) The value of integer defines the mode for displaying Prolog goals:
0 Display in the form identifier/arity.
1 Display by the tree drawing program.
[2, 1000] Display with depth limited by integer.
> 1000 Display of the complete term.
N (Next while tracing) Stops on the next goal that is not a sub-goal and prints
information about execution of the section of program, according to the
current options chosen. In this case the effect of the > command is ignored.
p boolean
(print before unification) Printing of goals before unification is activated if
boolean is 1, and deactivated if boolean is 0. If boolean is not mentioned it is
equivalent to 0.
P boolean
(Print after unification) Printing of goals after unification is activated if
boolean is 1, and deactivated if boolean is 0. If boolean is not mentioned it is
equivalent to 0.
s0 Cancels printing of the message and the Prolog stack when an error occurs. s
1 restores it.
t (trace to spy) Continues to the next fixed break point and prints the
information about execution of the section of program, according to the
current options chosen.
T (Trace to end) Continues to the end of the program and prints the execution
information according to the current options chosen.
© PrologIA
Aociation Prolog
R 6 - 20 Reference Manual HERITAGE
+ ident/arity
Puts a break point on the group of rules with access identifier ident and arity
arity. See also the spy predicate.
- ident/arity
Removes all break points from the group of rules with access identifier ident
and arity arity. See also the no_spy predicate
> ident/arity
Indicates that the predicate with access identifier ident and arity arity must not
be developed in the trace.
< ident/arity
Cancels the effect of the opposite command (>) on the predicate with access
identifier ident and arity arity.
< a Cancels the effect of all the opposite commands (>) that have been applied to
predicates.
The fixed break points, predicates not to be developed in the trace, the display mode
and the margin definition are permanent. They are not modified by a specific or
default activation of the debugger. They can only be modified or removed
explicitly.
6.6.6 Example
Let's look at the example program about menus, supplied in the kit. The comments
about execution are shown in italics.
We verify the loaded rules and go into debug mode. Then we launch the goal
dif(d, Sorbet_aux_poires) balanced_meal( Truffes_sous_le_sel, p,
d).
User input is shown in bold. The lines entered by the user must end with a carriage
return, which is not shown here, except when there is an empty line, where it is
written CR.
> dictionary;
DICTIONARY CONTENT OF ""
balanced_meal / 3
calories / 2
dessert / 1
fish / 1
hors_d_oeuvre / 1
main_course / 1
meal / 3
meat / 1
smaller / 2
sumof / 4
value / 4
© PrologIA
Aociation Prolog
{}
> debug dif(d, Sorbet_aux_poires)
balanced_meal(Truffes_sous_le_sel,p,d);
CALL: dif( v254, Sorbet_aux_poires)
DBG: CR
CALL: balanced_meal( Truffes_sous_le_sel, v623, v743)
We add display after unification and indentation to the
default configuration.
DBG: P1
DBG: i5
We verify the current options.
DBG: S
Print after unification
Print before unification
Print mode = out, depth: 4
Errors are printed
Indentation= 5
We continue.
DBG: CR
CALL: meal( Truffes_sous_le_sel, v623, v743)
This is an important predicate. We put a fixed break point
on it and check the active fixed break points.
DBG: +meal/3
DBG: b
meal/3
We continue.
DBG: CR
meal( Truffes_sous_le_sel, v623, v743)
CALL: hors_d_oeuvre( Truffes_sous_le_sel)
DBG: CR
hors_d_oeuvre( Truffes_sous_le_sel)
CALL: main_course( v623)
This is an important predicate. We put a fixed break point
on it and check the active fixed break points.
DBG: +main_course/1
DBG: b
main_course/1
meal/3
We continue.
DBG: CR
main_course( v623)
CALL: meat( v623)
DBG: CR
meat( Grillade_de_boeuf)
CALL: dessert( v743)
DBG: CR
RECALL(2): dessert( v743)
DBG: CR
dessert( Fraises_chantilly)
CALL: value( Truffes_sous_le_sel, Grillade_de_boeuf,
Fraises_chantilly, v817)
We don't want to stop in this predicate, we just want to see
what is happening in it.
DBG: N
value( Truffes_sous_le_sel, Grillade_de_boeuf,
Fraises_chantilly, v817)
CALL: calories( Truffes_sous_le_sel, v828)
calories( Truffes_sous_le_sel, 212)
© PrologIA
Aociation Prolog
R 6 - 22 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
main_course/1
meal/3
meat/1
DBG: G
main_course( v623)
CALL: fish( v623)
fish( Bar_aux_algues)
{d=Fraises_chantilly,p=Bar_aux_algues}
{d=Melon_en_surprise,p=Bar_aux_algues}
RECALL(2): fish( v623)
fish( Chapon_farci)
{d=Fraises_chantilly,p=Chapon_farci}
{d=Melon_en_surprise,p=Chapon_farci}
>
alloc
alloc / 12
Describes the state of the Prolog stacks. The version with no argument writes
the current values on the current output. If the second version is used, the first
argument is unified with the space occupied, the second with the space
available, as follows:
1,2 : code space
3,4 : structure copy stack (heap)
5,6 : local stack (local environments and variables)
7,8 : restoration stack
9,10 : dictionary space
11,12 : none
edinburgh
This primitive is used to go into Edinburgh mode from Prolog II mode. It
loads the edinburg.mo module; and also changes the syntax, adds built-in
primitives, adds and modifies operators.
get_option(o,x)
Obtains the value of a behavior option in the session. o must be a character
string of one character representing the option. x is unified with a character
string of one character representing the option's value. The meaning of the
characters is defined by the conventions of the command line option -f (see
chapter U2.3). For example, to find out the real syntax chosen for the session:
> get_option("r",x);
{x="P"}
prologII
This primitive is used to go into Prolog II mode from Edinburgh mode. It
changes the syntax, modifies the operators, deletes the specific Edinburgh
built-in primitives.
© PrologIA
Aociation Prolog
R 6 - 24 Reference Manual HERITAGE
prologIIE
This primitive is used to go into Prolog II mode from Edinburgh mode. It
keeps the Edinburgh-specific predefined rules: changes the syntax and
modifies the operators.
state
Displays the current state of the stacks, and the name of the modules that are
in memory.
statistics
statistics/12
This primitve is used to display the maximum values reached in Prolog spaces
during a session. These values are only memorized in debug mode. If debug
has never been executed and statistics is called, the values displayed will be
meaningless. Arguments are the same that in alloc predicate.
set_options(o)
This primitive is used to change the options defined at start-up by the -f
command line option, without having to leave Prolog. o is a characer string.
In the example below, the user goes to edinburgh variable syntax and standard
reals syntax:
> set_options("vErS");
version(o)
This primitive gives you the current version of Prolog. For example, if the
current version is 3.1,
> version(o);
{o=301}
- the copy stack (heap), containing a copy of the current proof's structures;
- the restoration stack (trail), containing a record of the arguments' values,
for backtracking;
© PrologIA
Aociation Prolog
- the dictionary space, containing all the identifiers and rule accesses created
during the session.
The Prolog II+ system comprises a garbage collection and packing mechanism for
the stacks and spaces, and a reallocation mechanism.
During operations that make use of the stacks or spaces (assert, insert, def_array,
non terminal recursivity …), these stacks or spaces may become saturated. The
garbage collection and packing mechanism is then activated automatically. If there
is still not enough free memory space, the reallocation mechanism is automatically
activated in turn. It's purpose is to increase the allocation to the relevant stack or
space by 25%. This is the default percentage, and it can be modified using a
command line option when Prolog starts (see U2.3).
You can explicitly request either of these two mechanisms on a stack or space, using
the gc and realloc predicates.
gc(x)
activates garbage collection and packing on the memory space denoted by x. x
can take one of the following values:
:code for the code space
:dictionary for the dictionary space,
:stacks for the stacks (they cannot be separated for this
operation)
N.B.: When code space garbage collection is activated, the system considers that all
the rules being used in the current execution must be conserved, even if they have
previously been deleted and are therefore inaccessible for a new execution.
N.B.: The garbage collector must determine which objects are unnecessary, so that
their space can be used again. The structures likely to be manipulated by an
external language, and where the garbage collector can function are the Prolog
identifiers. To avoid confusion, users must tell Prolog whether or not they are using
a particular identifier from the outside, so that Prolog knows whether an identifier is
still necessary, and so that the garbage collector does not delete it. This can be done
using the set_permanent_symbol and reset_permanent_symbol functions (cf.
Chapter 7 of this manual).
realloc R(x,y)
activates reallocation of the space denoted by x, with a size redefined by the
factor y. x can take the values :code, :dictionary, :stack, :heap, :trail,
depending on whether the space is in the code, the dictionary, the stack, the
heap or the trail. y is an integer indicating the percentage of increase (if it is
positive) or decrease (if it is negative) of the previous size.
© PrologIA
Aociation Prolog
R 6 - 26 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
This chapter explains how to make links with external objects and how to add new
predefined rules written in C or a compatible language. The examples described in
this chapter can be found in the kit's expredef.c file. A Fortran equivalent is
provided in the kit's fprouser.eg file.
To extend Prolog with functions from other languages, you must have a
communication module to:
- create a link between the Prolog predicate and the external function,
- transform the data transferred between the Prolog structure and the
external structure.
To extend Prolog with certain types of data, which Prolog and C will then share, it is
sufficient to:
- create a link between the Prolog term and the external data item, using the
descriptor method.
© PrologIA
Aociation Prolog
R7-2 Reference Manual HERITAGE
In sections 7.2 and 7.3 we are going to describe the transfer functions you can use
when a procedure in an external language needs to know the value of an argument in
the Prolog predicate linked to the procedure, or needs to assign it a value.
Below we define some principles that are common to all these functions.
Because languages differ in the way they pass an argument, one set of procedures is
provided for the C language, and another set for the FORTRAN language. The
FORTRAN routines have exactly the same arguments, but they are passed by their
address. Their names start with the letter "f" and do not contain a "_" sign. The
FORTRAN routines can also be used for PASCAL programs, by declaring all
arguments as var.
In every case a data item must be transmitted between Prolog and an external
language. Therefore, when the transfer function is called it is necessary to specify
the rank of the Prolog predicate's argument and the structure of the associated
external data item. Then, depending on the direction of transfer, either the Prolog
argument is "copied" into the external structure, or the term represented by the
external structure is constructed in the Prolog stacks and unified with the
associated predicate's argument.
On the other hand, it may be that the transfer cannot take place, in which case you
need to be informed. To do this, the transfer functions have an argument which
serves as an indicator. It is at zero when the function has been successful, strictly
positive when an error must be generated, and equal to -1 when a backtracking
must be generated.
Prolog's error management system requires that you leave the external program
immediately as soon as the *err flag - i.e. indicator - is not at zero. This is because
when the indicator is not at zero the situation is abnormal and requires a
backtracking or error in the Prolog program, which can only be performed once the
Prolog machine has been restarted, i.e. once the external program has terminated. It
may also be a more serious error, causing the Prolog machine to stop.
© PrologIA
Aociation Prolog
For each type of data there is one procedure for transfers from Prolog to external
procedures, and another for transfers from external procedures to Prolog1.
The get_arg_type function is used to test the type and size of a Prolog argument, in
order to choose the appropriate transfer procedure to recover its value. This
function also enables you to obtain the size to allocate to recover a string. This
function does not return an error except when no argument exists with the defined
rank.
get_arg_type(no_arg, value, lgPtr, err)
int no_arg;
char *value;
int *lgPtr;
int *err;
integer*4 function fgetargtype(no_arg, value, lgPtr, err)
integer*4 no_arg,lgPtr,err;
character** value;
no_arg
This is an integer which gives the rank of the argument chosen in the Prolog
predicate. The first argument of the interface rule has the rank 1, the second
has the rank 2, and so on.
value
Address of a character type variable in which the "code" of the argument type
will be written. The returned characters have the following meanings:
"code" type
'I' integer
'R' real
'S' string
'N' identifier
'E' nil
'V' free variable
'D' list
'T' tuple
The type codes are the same as for the get_term, put_term procedures (see
section 7.2.1), except for the nil identifier whose code is 'E'.
© PrologIA
Aociation Prolog
R7-4 Reference Manual HERITAGE
lgPtr
Address of an integer variable in which the size in bytes occupied by a
constant will be written. When the argument is not a simple term, i.e. when it
is a list or tuple, the size is not specified.
err
The pointed variable is not 0 if an error occurs, otherwise it is equal to 0.
The external program calls these functions to obtain the effective values of the
Prolog predicate.
If the effective argument type is not the expected one, or if there is no argument of
the required rank, the transfer function signals an error by assigning the err
indicator a non null value. If the value of an integer argument cannot be represented
in the associated external type, an error is signaled in the same way.
C Interface:
int get_integer(no_arg, value, err)
int no_arg;
long *value;
int *err;
int get_real(no_arg, value, err)
int no_arg;
float *value;
int *err;
int get_double(no_arg, value, err)
int no_arg;
double *value;
int *err;
int get_string(no_arg, value, err)
int no_arg;
char *value;
int *err;
int get_max_string(no_arg, lg_max, value, in_external_code,
err)
int no_arg;
int lg_max;
char *value;
int in_external_code;
int *err;
© PrologIA
Aociation Prolog
Fortran interface:
integer*4 function fgetinteger(no_arg, value, err)
integer*4 no_arg,value,err
integer*4 function fgetreal(no_arg, value, err)
integer*4 no_arg,err
real*4 value
integer*4 function fgetdouble(no_arg, value, err)
integer*4 no_arg,err
real*8 value
integer*4 function fgetstring(no_arg, lg, value, err)
integer*4 no_arg,lg,err
character** value
integer*4 function fgetmaxstring(no_arg, lg_max, lg, value,
in_external_code, err)
integer*4 no_arg,lg_max,lg,in_external_code,err
character** value
no_arg
This is an integer which gives the rank of the argument chosen in the Prolog
predicate. The first argument of the interface rule has the rank 1, the second
has the rank 2, and so on.
value
Address of the data item that must receive the value of the argument with rank
no_arg in the Prolog predicate.
lg
Integer used in Fortran functions manipulating strings, which must receive the
effective length of the character string.
lg_max
This is the size of the character zone.
in_external_code
This is a boolean, indicating whether the string must be encoded in external
character code (this is useful when the ISO character option is active and
characters are being used that are not present in the first half of the ISO set:
see Appendix E). If the value is 0, no transformation is performed on the
Prolog string.
err
The pointed variable is different from 0 if an error or a backtracking is
requested.
These functions return zero when an error has occurred or a non null value when no
error has occurred.
© PrologIA
Aociation Prolog
R7-6 Reference Manual HERITAGE
get_max_string copies the original character string from Prolog's working memory
into a zone that value points to, with a size of lg_max characters, defined in the
external program. A NULL character indicates the end of the string. An error is
generated if the size of the character zone defined by lg_max is insufficient to
recover the string.
get_string performs the same operation as get_max_string but does not test for
overflow. The size of the array value points to must therefore be sufficient to
contain the string. To prevent the risk of memory overwrite it is better to use
get_max_string.
The external program calls these procedures in order to unify a value with an
argument in the associated Prolog predicate. If the unification fails, backtracking is
announced by the transfer procedure.
If the effective type of the argument is not the expected one, or if there is no
argument of the required rank, the transfer function signals an error by assigning
the err identifier a non null value.
C Interface:
int put_integer(no_arg, value, err)
int no_arg;
long value;
int *err;
int put_real(no_arg, value, err)
int no_arg;
float value;
int *err;
int put_double(no_arg, value, err)
int no_arg;
double value;
int *err;
int put_string(no_arg, value, err)
int no_arg;
char *value;
int *err;
Fortran Interface:
integer*4 function fputinteger(no_arg, value, err)
integer*4 no_arg,value,err
integer*4 function fputreal(no_arg, value, err)
integer*4 no_arg,err
© PrologIA
Aociation Prolog
real*4 value
integer*4 function fputdouble(no_arg, value, err)
integer*4 no_arg,err
real*8 value
integer*4 function fputstring(no_arg, lg, value, err)
integer*4 no_arg,lg,err
character** value
no_arg
This is an integer which gives the rank of the argument chosen in the Prolog
predicate. The first argument of the interface rule has the rank 1, the second
has the rank 2, and so on.
value
This is the value which will be unified with the argument having rank no_arg
in the associated Prolog predicate. For character string parameters, value is
the address of a string ending in zero and defined by the external program.
put_string copies this character string into Prolog's working memory and then
unifies the value with the argument in the interface rule.
err
The pointed variable is not 0 if an error or backtracking has been requested.
These functions return zero when an error is generated, or a non null value if there is
no error.
© PrologIA
Aociation Prolog
R7-8 Reference Manual HERITAGE
The functions described here are simple and easy to put into operation. They can be
used for instance the first time you create an interface between Prolog and other
languages.
They are much less efficient than the method using array structures, which is
described in the next section. They offer less possibilities for using the arguments,
and they are also restricted in their manipulation of variables. It is not possible for
several arguments in the predicate linked to the external procedure to use the same
free variable. The dictionary of variables is local for the communication procedure,
i.e. local for an argument and not for the rule.
C Interface:
get_strterm(no_arg, lg_max, value, in_external_code, err)
int no_arg;
int lg_max;
char *value;
int in_external_code;
int *err;
Fortran Interface:
integer*4 function fgetstrterm(no_arg, lg_max, lg, value,
in_external_code, err)
integer*4 no_arg,lg_max,lg,in_external_code,err
character** value
integer*4 function fputstrterm(no_arg, lg, value,
in_external_code, err)
integer*4 no_arg,lg_max,in_external_code,err
character** value
no_arg
This is an integer which gives the rank of the argument chosen in the Prolog
predicate. The first argument of the interface rule has the rank 1, the second
has the rank 2, and so on. If there is no argument of this rank, an error is
signaled.
value
is the address of a zone of characters.
lg_max
is the size of this zone.
© PrologIA
Aociation Prolog
in_external_code
is a boolean, indicating whether the string is (put_strterm), or must be
(get_strterm) in external character code (this is useful when the ISO character
option is active, and characters are being used that are not present in the first
half of the ISO set: see Appendix E).
err
indicates whether an error has occurred or not or whether a backtracking must
be generated.
When transferring from Prolog to the other language, the character zone value
points to must be big enough to contain the resulting string. Prolog transforms the
argument of rank no_arg (in the same way as the out predicate) into a string that
it copies to the value address. If the string to copy is greater than lg_max an error is
signaled.
When transferring from the other language to Prolog, Prolog analyzes the string
contained in value, constructs the Prolog term it represents (in the same way as the
in predicate), and unifies it with the argument of rank no_arg.
For example, in an external rule to unify the third argument with a list of 5 integers,
the following will be written:
put_strterm( 3, "[1,2,3,4,5]", 0, &err);
Below is a small example comprising a section in C to add into Prolog after the
external predicate declaration is added and a section in Prolog which tests it. We
assume that the link between the Prolog predicate and the C function has been
declared.
int test_ccom()
{ int err; char s[80];
get_strterm(1,80,s,1,&err);
if (err) return err;
fprintf(stderr,">>>>%s\n",s);
put_strterm(2,s,1,&err);
if (err) return err;
return 0;
}
> test_ccom(term(1.2.x,"string",[]),z);
>>>>term(1.2.v64,"string",nil)
{z=term(1.2.v150,"string",nil)}
>
The two term transfer functions described here, get_term and put_term, are the most
general functions for transferring data.
Since the functions for transferring simple terms use data types, this interface can
also be used when the type of the argument to process is not known in advance.
© PrologIA
Aociation Prolog
R 7 - 10 Reference Manual HERITAGE
When transferring data from the other language to Prolog, the aim is to unify the
proposed term with the argument of the associated Prolog predicate. If unification
fails, the transfer function signals a backtracking.
Two arrays to code the type and value of a term and its sub-terms;
- one character array for the types (or "tags") of terms/sub-terms.
- one array of long integers for the values of terms/sub-terms. The meaning
of each item is given by the content of the item with the same index in the type
array.
The term corresponding to the no_arg argument is coded in the first box of both the
type array and the value array:
tag_tab[0], val_tab[0]
© PrologIA
Aociation Prolog
There are two equivalent representations of the term 1.2.3.nil; one is in vectorised
form, the second is a pointed pair (a pair here is represented by three entries).
Prolog always produces data in the first form, which is more compact, while the
second is useful for the construction of lists whose length is unknown when
construction begins.
© PrologIA
Aociation Prolog
R 7 - 12 Reference Manual HERITAGE
The pair ('N',0) represents the identifier nil. (in the array below, "-" represents
undefined values)
01 'I' 1 'I' 1
02 'I' 2 'F' -
03 'I' 3 'D' 4
04 'E' - 'I' 2
05 'F' -
06 'D' 7
07 'I' 3
08 'F' -
09 'N' 0
Example:
© PrologIA
Aociation Prolog
7.3.2.2 Identifiers
In the array structures an identifier is encoded by a key (normally an integer) in the
Prolog dictionary. When the data is transformed by the interface functions
(get_term, put_term), conversion functions between the key and the identifier
representation (character string) may be necessary.
The character chosen to separate the prefix and suffix in the complete representation
of an identifier can be modified in Prolog. The following function is therefore used
to ascertain the character currently used:
char prefix_limit();
character*1 function fprefixlimit();
© PrologIA
Aociation Prolog
R 7 - 14 Reference Manual HERITAGE
set_permanent_symbol(key)
long key;
reset_permanent_symbol(key)
long key;
integer*4 function fsetpermanentsymbol(key)
integer*4 key
integer*4 function fresetpermanentsymbol(key)
integer*4 key
- The arrays used to encode the term: tag_tab, val_tab, str_tab, real_tab. When
an array is not referenced (for example if it has neither strings, nor reals), it can
be replaced by NULL. An error is indicated when one of the arrays is not big
enough to encode the term.
- An integer which indicates the last box used to code the term in the arrays:
tag_tab and val_tab: max_used.
© PrologIA
Aociation Prolog
err );
integer*4 function fputterm(no_arg, tabsize, strtabsize,
realtabsize,
tagtab, valtab, strtab, realtab, maxused,
err );
Examples of how to use these interface procedures can be found in the "expredef.c"
kit's file or the "fprouser.eg" kit's file.
The descriptor method is used to define Prolog relay objects and their link with an
external object. It can be used for external functions and shared data. In this
method the objects and links are declared in C.
First we will determine the elements that need to be described in C to create this
definition, and then we will describe the two ways of declaring them: statically or
dynamically.
name
Identifies the Prolog term associated with the external object. It is a pointer to
a C type string containing the representation of a complete Prolog identifier.
In the case of a SYMBOL_ARRAY object it has a different meaning, since it only
represents the module that the array's identifiers belong to. It therefore
contains the representation of these symbols' prefix.
type
Defines the type of the declared external object. The possible values are as
follows:
I N T _ A R R A Y for an integer array, C H A R _ A R R A Y for a character array,
STRING_ARRAY for a string array SINGLE_FLOAT_ARRAY for an array of single
precision reals, DOUBLE_ARRAY for an array of double precision reals,
SYMBOL_ARRAY for an identifier array, C_FUNCTION or C_FUNCTION_PROTECTED
for an external function, C _ F U N C T I O N _ B A C K T R A C K or
C_FUNCTION_BACKTRACK_PROTECTED for a non-determinist external function,
DIRECT_C_FUNCTION for a direct-call external function. For data arrays, it is
© PrologIA
Aociation Prolog
R 7 - 16 Reference Manual HERITAGE
size
In the case of an external function, defines the rule's arity. In the case of a
shared data item, defines the size of the array. Has no meaning in the case of
SYMBOL_ARRAY.
adresse
Defines the effective address of the declared C object (or of a sub-array of
descriptors in the case of SYMBOL_ARRAY).
The external objects and associated Prolog objects can be declared statically by
descriptor tables that Prolog scans at initialization time. When you load Prolog
these tables will create the necessary links and declarations. The Prolog objects
created in this way, and their links with the external object, are permanent
throughout the session. They are not deleted by the predefined rules kill_module,
kill_array, suppress etc.
To add these objects to Prolog, the Prolog machine must be extended by one or
more external modules containing the declaration of these descriptors. A descriptor
must be assigned to a descriptor table, which the general array PRO_EXTERNAL
must point to. The prolink linking program automatically constructs this
PRO_EXTERNAL array in the prodesc module and then reconstructs the Prolog
machine.
Descriptor table
A descriptor table is an array of descriptors ending in a descriptor containing 0 in
the name field. For example:
EXTERNAL_DESCRIPTOR sample_desc[] =
© PrologIA
Aociation Prolog
{
{":term_vars", C_FUNCTION, 2, (POINTER) term_vars},
{":qsort", DIRECT_C_FUNCTION, 1, (POINTER) quicksort},
{":enumerate", C_FUNCTION_BACKTRACK,3,(POINTER)enumerate},
{ 0, 0, 0, 0}
};
You can create as many tables as you like. Normally you should create one for each
external file.
In the same way as a static declaration, the Prolog objects created in this way and
their link with the external object are permanent throughout the session. Once the
declaration has been made, you cannot cancel its effect.
The following example allocates a zone of 1000 reals shared by Prolog and C, and
accessible in Prolog using the name mymodule:data.
#include <malloc.h>
#include "proext.h"
...
double *t;
t = (double *) malloc( 1000*sizeof(double));
PRO_BIND( "mymodule:data"
, DOUBLE_ARRAY
, 1000
, (POINTER) t);
Once this sequence has been executed, the following Prolog program executes
without errors, and references the data zone t[4]:
assign(mymodule:data(5), 1.5e );
In the following sections we describe the different types of object that can be
accessed using the descriptor method. The examples are described with static
declarations, but obviously they can also be declared dynamically.
© PrologIA
Aociation Prolog
R 7 - 18 Reference Manual HERITAGE
Prolog can be extended by one or more zones of shared data. These data zones are
treated as arrays and processed as arrays by both languages.
The shared data is defined by declaring a descriptor whose type field will have one
of the following values: INT_ARRAY , SINGLE_FLOAT_ARRAY , DOUBLE_ARRAY,
CHAR_ARRAY, STRING_ARRAY, SYMBOL_ARRAY. In addition, OFFSET_ZERO_BASED can be
added to any of these values.
The name field will be Prolog's representation of the array. The def_array primitive
must not be used to define this array. The size field indicates the number of items
in the array.
The adresse field is the address of the memory zone reserved for this array in C.
Depending on the object's type, it will be:
INT_ARRAY
the address of a static integer zone (int type in C).
CHAR_ARRAY
the address of a character zone2 (1 byte per character).
STRING_ARRAY
the address of an array of pointers to strings3 ending with the null character.
It can be declared in the form: char *tab[size];
Warning. There is no overflow test on the size of the strings the interface
manipulates. Don't forget to allocate the space for the strings, and to
initialize the pointer array.
SINGLE_FLOAT_ARRAY
the address of a zone of IEEE 32 bit reals.
DOUBLE_ARRAY
the address of a zone of IEEE 64 bit reals.
2Are you sure about the character encoding mode? See appendix E.
3Are you sure about the string encoding mode? See appendix E.
© PrologIA
Aociation Prolog
SYMBOL_ARRAY
the address of a sub-table of associations (identifier string, internal
representation). The programmer initializes the string part, and Prolog
initializes the international representation part.
For this type of descriptor, the name field defines the default prefix for the
table's symbols (i.e. if the string id_name corresponds to an abbreviated name,
this is the default prefix to be used).
This type of object makes it possible to construct automatically a table of the
internal values of the Prolog identifiers we want to manipulate. All the table's
identifiers are permanent (see set_permanent_symbol) be default.
Here, we declare two arrays shared by C and Prolog. The first is an array of 100
integers, called com in C and :com in Prolog. The second is an array of 3 strings of
no more than 10 characters, called m:str in Prolog, and str in C.
#include "proext.h"
int com[100];
char *str[3] =
{
"0123456789",
" ",
" "
};
EXTERNAL_DESCRIPTOR my_desc_table1 [] =
{{":com", INT_ARRAY+OFFSET_ZERO_BASED, 100, (POINTER)com},
{"m:str", STRING_ARRAY, 3, (POINTER) str },
{ 0, 0, 0, 0 }
};
Supposing these declarations are contained in a file called table.c, it can be linked to
Prolog once it has been compiled, by executing prolink to link it to table's object
module and the descriptor descTable1. (See User's Manual section 2.8).
When it is loaded, Prolog will automatically create a link with the C array. It will be
possible to modify and consult this array by means of the standard Prolog
commands assign and val. It should be noted that for shared data declared with
OFFSET_ZERO_BASED the Prolog indices start at 0, for the other arrays they start at 1,
and that the C indices start at 0. The following commands in C and Prolog have
exactly the same effect and work on the same memory zone:
Prolog C
assign(:com[4], 100); com[4] = 100;
val(:com[4],_x) outl(_x); printf("%ld\n",com[4]);
val(m:str[1],_x) outm(_x); printf("%s",str[0]);
assign(m:str[2],"abc"); strcpy(str[1],"abc");
© PrologIA
Aociation Prolog
R 7 - 20 Reference Manual HERITAGE
- functions that carry out one process and stop. The value of the
descriptor's type field will then be C_FUNCTION or DIRECT_C_FUNCTION.
We will describe DIRECT_C_FUNCTION type objects in section 7.7.
C_FUNCTION
By declaring this type of object you automatically create a Prolog relay rule
called name with an arity of size. This Prolog rule will be executed by calling
the C function whose address is in the adresse field. The rule's arguments
can be accessed from the C function using the standard data transfer functions
get_... and put_... . The C function adresse points to must be declared as the
int type and is called by Prolog without any parameters. It must return the
termination condition (-1 for FAIL, 0 for SUCCESS, > 0 for ERROR).
This is a simpler way of constructing external predefined rules than by
directly using parasites (/?n) and the relay procedure user_rule (see Appendix
D).
C_FUNCTION_BACKTRACK
By declaring this type of object you automatically create a Prolog relay rule
called name with an arity of size. This Prolog rule will be executed by calling
the C function whose address is in the adresse field. The rule's arguments
can be accessed from the C function using the standard data transfer functions
get_... and put_... . The function must be declared as the int type. It is called
by Prolog with a single long type parameter indicating the number of the
current call. It must return the termination condition (FAIL for a failure,
SUCCESS for a success, > 0 for an error,
SUCCESS_END_OF_C_BACKTRACK to indicate the success of the last
call, or FAIL_END_OF_C_BACKTRACK to indicate failure of the last call).
In the event of a cut, an additional call to this function will be made using the
conventional value CUT_OF_C_BACKTRACK as the argument. This aim
of this call is not to find another solution, but to signal that there will not be
any more calls, and in this way make it possible to terminate the processes in
progress (e.g. freeing of allocated memory, closing files, etc.). During a call
to this function, an integer value can be stored in Prolog's space using the
function store_C_backtrack_data(long ptr), or can be recovered by the return
© PrologIA
Aociation Prolog
When linked to Prolog, the following file automatically produces two new built-in
predicates: sys:reverse(s1,s2) that unifies s2 with the inverted string s1; and
sys:enumerate(x,b,e) that unifies x in succession with the integers between b and e.
If you want to use the abbreviated name, you must add the name in the closed
context "sys" by executing the following command:
> add_implicit("sys","reverse")
add_implicit("sys","enumerate");
#include "proext.h"
#include <stdio.h>
#include <string.h>
#define MAX_STRING 512
int reverse();
EXTERNAL_DESCRIPTOR descTable2[] =
{{"sys:reverse", C_FUNCTION, 2, (POINTER) reverse},
{"sys:enumerate", C_FUNCTION_BACKTRACK, 3,
(POINTER) enumerate},
{ 0, 0, 0, 0 }
};
reverse()
{
int err, i, j, lg;
char c1, c[MAX_STRING];
if ( ! get_string(1,c,&err) )
return err;
lg = strlen(c);
for (i=0; i<lg/2; i++)
{
j = lg -1 -i;
c1 = c[i];
c[i] = c[j];
c[j] = c1;
}
if ( ! put_string(2,c,&err) )
return err;
return 0;
}
typedef struct {
int direction, current, start, end;
} enumRecord, *EnumMemory;
int enumerate(call)
long call;
{
EnumMemory mem;
int err;
if (call==CUT_OF_C_BACKTRACK) /* cut */
© PrologIA
Aociation Prolog
R 7 - 22 Reference Manual HERITAGE
{
mem = (EnumMemory) restore_C_backtrack_data();
free(mem);
return;
}
store_C_backtrack_data(mem);
}
if (mem->current == mem->end)
{
/* it's finished, it must be freed */
free(mem);
return END_OF_C_BACKTRACK;
}
else
/* the counter is incremented */
mem->current += mem->direction;
return err;
}
The above file must now be compiled, linked (see User's Manual section 2.8), and
the new Prolog must be activated to obtain:
Prolog II+, ..
...
>sys:reverse("0123456",x);
{x="6543210"}
>sys:enumerate(x,-2,2);
{x=-2}
{x=-1}
{x=0}
{x=1}
{x=2}
>
© PrologIA
Aociation Prolog
This method therefore makes it possible to transfer types of data common to both
languages, i.e. integers, reals, character strings and homogeneous arrays of these
data types.
A direct call external function is declared by declaring a descriptor whose type field
has the value DIRECT_C_FUNCTION.
DIRECT_C_FUNCTION
By declaring this type of object you automatically create a Prolog relay rule
called name with an arity of size that can only be executed using the callC
primitive. The execution of callC consists in calling the C function pointed by
the descriptor's adresse field.
This C function must not have more than 20 arguments. If the descriptor's
size field has the value -1, the type and number of arguments vary depending
on the call. For example it is possible to call sprintf (see section 5.2 of this
manual).
When the call is made, the predefined primitive callC determines the way in which
the arguments are passed to the C function, their type and the type of the return
value, according to the effective arguments of the Prolog predicate, and in
compliance with the various conventions described in the next section. This makes
it possible to call functions with varying types and numbers of arguments.
callC(t1)
callC(t1,t2)
t1 is a term representing the call to the Prolog predicate with its parameters in
compliance with the chosen conventions. t2 is a term representing the result.
If t2 is nil the function's result is ignored. The single argument version
callC(t1) is equivalent to callC(t1,nil).
This function makes it possible to call functions you have described with a
DIRECT_C_FUNCTION descriptor, as well as the sprintf and sscanf functions
which are pre-declared.
© PrologIA
Aociation Prolog
R 7 - 24 Reference Manual HERITAGE
If you are using a system that allows implementation of the lkload primitive, it
is possible to call functions existing in the Prolog environment without
declaring them. The callC primitive then creates the link dynamically when
the first call is made. To do this the runnable file prolog must be in the
current directory.
Examples:
> callC(sscanf("123","%lf",<"R",y>));
{y=1.230000000000000e+02}
> eq(x,"123") callC(sscanf(x,"%2f",<"R",y>));
{x="123", y=1.200000000000000e+01}
> eq(f,"%x %o") callC(sscanf("12 12",f,<"I",x>,<"I",y>));
{x=18, y=10}
> callC(sprintf(<"",x,80>,"value: %ld",200));
{x="valeur: 200"}
Our aim here is to be able to express in Prolog all the information needed to call a C
function, concerning its arguments and return value. We will therefore examine:
- the way in which the arguments are passed,
- the type of the function's arguments and return value,
- the initial value of the arguments,
- the resulting value of the arguments and the function,
- other technical information connected with the object's type.
The most crucial aspect here is not the passage of data, but rather the role of the data
, i.e. whether it is input and/or output data.
In Prolog, once data has been assigned a value this value cannot change (except by
backtracking, but when comparing it with C this can be regarded as another
execution). If a Prolog procedure had to accept a value as input and a result as
output, it would have to use two data items. This is the fundamental difference
between Prolog and C, and so it is important to know whether a data item (initialized
or not) has to change value during execution of the C function. In the rest of this
section, we will therefore differentiate between an argument with a return value and
an argument without a return value. From this it will be deduced automatically
whether the data is passing by address or by value.
© PrologIA
Aociation Prolog
Now let's take a look at the conventions. To illustrate them with examples, we will
assume that a link has been declared between the predicate prologRelay and the
function functionC.
Strings and arrays are always passed by their address in accordance with the normal
C convention. In any case Prolog makes a copy of the arguments in an intermediate
zone whose size can be configured on the command line (see Chapter 2 of the
User's Manual).
We differentiate between the types of data: simple types and types requiring
allocation of a memory zone.
© PrologIA
Aociation Prolog
R 7 - 26 Reference Manual HERITAGE
Note. Some conventions with return values specify memory zone sizes to
allocate, for storage of the results of the called C functions. Therefore it
is very important to ensure that the zones are sufficient for the expected
results. You must also ensure that the argument types are consistent with
the declarations made in C.
The convention for simple data types, i.e. integers and reals, is as follows:
followed by the assignments to variables x and y of the new values for arg1
and arg2.
The convention for data requiring a memory zone depends on the data type:
For a character string, you must have a character zone, whose size you must
define, big enough to contain the initial string first and then the result string.
For an array of integers or of reals, you must have a zone of integers or reals
acting as an array. You must define the number of items in it, and it must be big
enough to contain the input array items first, and then the output array items.
© PrologIA
Aociation Prolog
followed by the assignments to variables x and y of the new values for arg1
and arg2.
For an array of character strings, you must have a zone of pointers to represent
the array. You must define the number of items in this zone. You may also need to
define a character zone to store all the characters in all the array's strings, and define
its size also.
Example:
:prologRelay(<"once"."upon"."a"."time",x,100,5>)
is equivalent to the following C instructions:
{ char * arg1[5]; char buffer[100];
© PrologIA
Aociation Prolog
R 7 - 28 Reference Manual HERITAGE
followed by the assignment to the variable x of the new values for arg1.
© PrologIA
Aociation Prolog
{
strcpy(tso1[0],"Zone1"); /*first pointer(tso1[0])*/
/*initialized by Prolog */
tso1[1] = tso1[0]+6; /*others pointers initialized*/
/*by the user */
strcpy(tso1[1],"Zone2");
tso1[2] = NULL; /*end of array */
}
else /*space for strings reserved by the user */
{
tso1[0] = "Zone1";
tso1[1] = (char *) malloc(10);
strcpy(tso1[1],"Zone2");
tso1[2] = NULL;
}
return 1234.; /*returned value */
}
static mystrcmp(a1,a2)/*
------------------------*/
char **a1,**a2;
{
return strcmp(*a1,*a2);
}
static quicksort(tab_in,tab_out)/*
-------------------------------*/
char **tab_in, **tab_out;
{
int i,nbr;
for (nbr=0;tab_in[nbr];nbr++)
tab_out[nbr] = tab_in[nbr];
tab_out[nbr] = NULL;
qsort(tab_out,nbr,sizeof(char *),mystrcmp);
}
static reverse(str)/*
------------------------*/
char *str;
{
char c;
INTEGER i,len;
len = strlen(str);
for (i=0;i<len/2;i++)
{
c = str[i];
str[i] = str[len - (i+1)];
str[len - (i+1) ] = c;
}
}
© PrologIA
Aociation Prolog
R 7 - 30 Reference Manual HERITAGE
EXTERNAL_DESCRIPTOR calld_desc[] =
{
{":complete_example", DIRECT_C_FUNCTION, 13, (POINTER)
complete_example},
{":average", DIRECT_C_FUNCTION, -1, (POINTER) average},
{":reverse", DIRECT_C_FUNCTION, 1, (POINTER) reverse},
{":qsort", DIRECT_C_FUNCTION, 2, (POINTER) quicksort},
{0, 0, 0, 0}
};
Let's assume the above file is called callc.c. We must now compile it, create the
links (see the User's Manual Chapter 2.8), and then activate the new Prolog to
obtain:
Prolog II+, ..
...
> eq(r_eserved,30)
callC(complete_example
(
11, /*integer in input */
<155,i>, /* integer in output with initialization*/
+13.0e0, /* real in input*/
<+222.0e0,r>,/* real in output with initialization*/
"str_input", /* string in input*/
<"ee",s,10>, /* string in output with initialization*/
123.456.nil, /*array of integers in input */
14.0e0.15.0e0.nil, /*array of reals in input */
<11.22.33,w,5,20>, /*array of integers in output
/*with initialization*/
<+44.0e0.+55.0e0.+66.0e0,t1,5,20>, /*array of reals in
output with initialization*/
"list_str_in1"."list_str_in2".nil, /*array of STRINGS*/
/*in input */
<"list_str_out1"."list_str_out2"."list_str_out3".nil,
T_S,r_eserved,5>,
r_eserved /*integer in input */
),
<"R",m>) /*result */
;
ii1= 11
io1= 155
ri1= 13
ro1= 222
si1= str_input
so1= ee
tii1[0]= 123
tii1[1]= 456
tri1[0]= 14
tri1[1]= 15
tio1[0]= 11
tio1[1]= 22
tio1[2]= 33
tsi1[0]= list_str_in1
tsi1[1]= list_str_in2
tro1[0]= 44
tro1[1]= 55
tro1[2]= 66
strin(0)=list_str_out1
strin(1)=list_str_out2
{r_eserved=30,i=3333,
© PrologIA
Aociation Prolog
r=-8.888000000000000e+03,
s="bonjour",
w=200.201.202.203.204.nil,
t1=2.000000000000e+02.2.010000000000e+02.2.020000000000e+02.
2.030000000000e+02.2.040000000000e+02.nil,
T_S="Zone1" ."Zone2".nil,
m=1.234000000000e+03
}
> callC(average(1.3.5.nil,3),<"R",x>);
{x=3.000000000000e+00}
> callC(reverse(<"abcde",s,20>));
{s="edcba"}
> callC(reverse(<"abcdef",s,20>));
{s="fedcba"}
> callC(qsort("qqq"."zzz"."aaa"."iii".nil,<"".nil,s,0,50>));
/*0 because strings not created (already exist)*/
{s="aaa"."iii"."qqq"."zzz".nil}
© PrologIA
Aociation Prolog
R 7 - 32 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
This chapter assumes that the reader is fully conversant with Chapter 7. If this is
not yet the case, this chapter can be skipped.
A C program can only be called by a predefined rule, apart from when the Prolog
machine is at a stopping point. This rule can either stack a new goal or cause an
error.
When the Prolog machine is at a stopping point, a C program can do the following:
stack a new goal, reactivate the machine up to the next stopping point to get another
solution, or cause abandonment of the current goal and a return to the previous state.
8 . 1 Basic theory
When a Prolog machine is in a "normal state", this means that it is executing a
series of goals (see Chapter 2 of this manual). This process is sometimes called the
Prolog clock. When the machine is in this situation, we refer to it as being active.
When the Prolog machine is activated, it already has an initial sequence of goals to
execute. The execution process (choice of a rule, unification of the head, etc ...) will
last for as long as the current sequence of goals is not empty. When this sequence
is empty, the machine reaches a stopping point.
In this section, we define the various states the Prolog machine can be in when it is
not active, from the point of view of a C programmer (or a Pascal programmer,
etc...). These states are called stopping points. We also describe the procedures
which make the machine pass from one stopping point to another.
© PrologIA
Aociation Prolog
R8-2 Reference Manual HERITAGE
0. Machine not initialized. In fact, this is not the state of the machine, but rather
the situation we are in before it has been initialized (space allocation, etc ...).
The ProStart(…) procedure, which is called once per session, takes us to the
next state:
1. Nothing to execute (NO_GOAL). The machine has been initialized, but the
sequence of goals to execute is empty.
The machine also arrives at this state during normal functioning, when there
are no more possible ways of executing the current goal sequence, i.e. when
all the solutions to the current problem have already been obtained. When in
this state, any activation of the machine (using next_solution()) immediately
brings it back to the same NO_GOAL state.
5. Error encountered (ERROR). The machine is put in this state when an error
has made its normal functioning abort. An activation (by next_solution() )
will transfer it to the NO_GOAL state.
In any of the states 1 to 4 above, the procedure new_goal() can be called to install a
new problem above the current one. The latter is retained in exactly the same state,
so that subsequently it will be possible to continue to obtain its solutions.
© PrologIA
Aociation Prolog
In the same way, in states 2 to 5 we can call the procedure kill_goal(), which causes
abandonment of the current problem and a return to the previous problem, which is
in exactly the same state as when new_goal() was called.
The functions which activate the Prolog machine (i.e. which transfer it to another
state) are:
ProStart(..)
Function used to initialize the Prolog machine. This function must be called
once before any other call concerning Prolog. Initializes the machine in state
1.
ProFinal(..)
Function making it possible to terminate and clear the Prolog machine and
environment. It has an integer argument that specifies Prolog’s termination
status.
new_goal()
Memorizes the current state of the machine, and transfers it to state 2 (goal
ready to be executed). State 2 is initialized with the call exec(_b,_s) whose
variables must be instantiated by the calling program AFTER the new_goal
call.
This procedure stacks the activations of goals _b up to a depth which is only
limited by the size of the Prolog stacks.
kill_goal()
Returns to exactly the same state the machine was in before the last new_goal
call. new_goal and kill_goal function as parentheses bracketing the execution
of a new Prolog goal.
next_solution()
This is an activation function of the machine, which transfers it to the next
stopping point (1, 4, or 5). The value of the function is the new state of the
Prolog machine: SOLUTION_EXISTS (0), NO_GOAL (-1), ERROR (>0).
© PrologIA
Aociation Prolog
R8-4 Reference Manual HERITAGE
The following diagram defines the possible transitions for any Prolog state, apart
from the non-initialized state:
8 . 2 Initializing Prolog
When an application starts up, Prolog is in a non-initialized state. The ProStart
function initializes Prolog with a configuration (stack sizes, input file,…), defined in
the character string passed as the parameter. This string represents the Prolog start-
up options (stack sizes, input file, etc.). The function returns 0 if everything is OK,
or a non null positive number corresponding to an error number if an error has
occurred and initialization has not taken place.
© PrologIA
Aociation Prolog
int ProStart(params)
char *params;
When you have finished using Prolog, the ProFinal function enables you to clear
the structures and terminate Prolog. The function has no return value, but instead an
argument that specifies Prolog’s termination status and determines a message
printed by ProFinal . This message must be defined in the Prolog error file. The
status value must be 0 for a normal termination, or a strictly positive number for an
error status. This error status could be for example the error returned by one of the
following functions: new_goal, next_solution or kill_goal.
When ProFinal has been executed, Prolog is once more in a non-initialized state.
Here is an example:
my_prolog_initialization()
{
int err;
if ((err = ProStart("-c 400 -f cM prolog.po")) == 0)
fprintf(stderr,"initialization succeeded");
else
{ fprintf(stderr,"initialization failed, bye!");
exit(err);}
}
my_prolog_termination(condition)
int condition;
{
if (my_error(condition))
{ my_error_message(condition);
ProFinal(0);
}
else
ProFinal(condition);
}
Use of the Prolog machine is started and terminated by calling the ProStart and
ProFinal functions.
© PrologIA
Aociation Prolog
R8-6 Reference Manual HERITAGE
When new_goal has been called, the call exec(_b,_s) is ready to be executed. The
standard routines can be used to instantiate the arguments (put_term(1,..) to
instantiate _b, and put_term(2,..) to define the variables corresponding to the
interesting solution).
A call to the function next_solution transfers the machine to one of the states 1,4 or
5. The value returned by this function is the state which has been reached:
NO_GOAL (-1), ERROR (>0), or SOLUTION_EXISTS (0).
exec(_b,_s) ->
block(_e,_b)
condition(_e,_k)
stopping_point1(_k,_s)
fail ;
exec(_b,_s) -> stopping_point2(NO_GOAL,nil);
Everything happens as if the user were in the rule stopping_point. Because of the
way exec is written, the value of the first argument (obtained by get_integer(1,..))
also contains the state which has been reached. If this state is
SOLUTION_EXISTS, the second argument (obtained by get_term(2,..)) contains
the term defining the interesting solution.
© PrologIA
Aociation Prolog
8 . 4 Programming
The file proext.h contains the declarations for the interface procedures and
structures. An #include from this file must be placed at the start of the modules
using these procedures.
EXTERNAL_DESCRIPTOR prouser_desc[] =
{{":example", C_FUNCTION, 0, (POINTER)example},
{0,0,0,0}};
© PrologIA
Aociation Prolog
R8-8 Reference Manual HERITAGE
This method consists in specifying the structure of the goal's arguments and their
interesting values when the goal is installed, so that they can be named when a
solution is obtained, instead of having to perform an algorithmic search for the
required sub-terms of the solution.
The called goal's arguments can be any term (except infinite) and the values to
extract are simple terms such as integers, reals, doubles, identifiers, or strings.
8.5.1. Description
int new_pattern(char * goal)
is a function with a single argument; a character string representing a Prolog
term that is the goal to execute, and where the interesting results are
represented by formats. The function returns 0 if everything is OK, or an
error number if an error occurs.
The following formats are accepted:
%d for integers
%s for character strings
%f for single reals
%F for double reals
%i for identifiers in the form of an integer
%I for identifiers in the form of a character string
© PrologIA
Aociation Prolog
The get_formats function will load the integer i with the value associated with
the first format (the integer -2 in our example). It should be noted that this
call is exactly equivalent to:
error = get_formats(1, &i);
8.5.2. Example
Here is an example of how to use the new_pattern and get_formats functions:
int example2()
{
int error;
long i;
char s[100];
float f;
© PrologIA
Aociation Prolog
R 8 - 10 Reference Manual HERITAGE
error = new_pattern("test_rules(%i,%s,%f)");
if (error) return error;
while (next_solution() == SOLUTION_EXISTS)
{
error = get_formats(0, &i, s, 100, &f);
if (error) goto error;
printf("%d %s %f\n",i,s,f);
}
kill_goal();
return 0;
error:
printf("error\n");
kill_goal();
return error;
}
8 . 6 Other functions
ConnectDescriptors( EXTERNAL_DESCRIPTOR * paD[] )
This routine is used to declare the descriptor array paD in the application
code. The array is written in the same way as a direct C extension and must
be persistent throughout the whole of the Prolog session that uses it (e.g.
qualified as static if it is positioned as a local variable). The declaration must
be made before the start of the session (before the call of ProStart() ).
If the argument is NULL, the descriptors will be deleted in the next session.
If the routine is called several times, the last array will be taken. The routine
returns 0 if it succeeds, -1 if it fails (session already started).
© PrologIA
Aociation Prolog
© PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
9. Interruptions
9.1 Concepts
9.2 Description of the interfaces
9.3 Complete example
This mechanism therefore makes it possible to suspend the current execution, and
stack the activation of a new Prolog machine which will process the interruption.
9.1 Concepts
The Prolog machine has a vector of external event bits. The first eight bits (0 to 7)
are reserved for events defined by the user. Each bit must be associated with a C
function to construct the arguments and call a Prolog goal. This C function is
installed by the user by calling the pro_signal procedure.
2. Write a function (e.g. myHandler) which will be used to activate the Prolog
program handling the interruption.
3. In the Prolog environment, associate the event myEvent with the function that
processes it by calling the function:
pro_signal(myEvent,myHandler).
© PrologIA
Aociation Prolog
R9-2 Reference Manual HERITAGE
4. In the routine called at interruption, send the event to Prolog by calling the
function:
send_prolog_interrupt(myEvent ).
P
myHandler()
R
{
O
new_goal();...
C
next_solution();
E
kill_goal();
S
} Prolog machine
S
I
N
new_goal() next_solution() kill_goal()
T
E (*myHandler)()
R
R
U
P
T
I reset myEvent flag
O
prolog_event_handler(myEvent)
N
asynchronous user
interruption
Prolog machine ...
myAsynchronousHandler()
{
send_prolog_interrupt(myEvent); set myEvent flag
}
The functions defined here are used to link Prolog II+ with interruption procedures.
The prototypes for these functions are given at the end of this chapter.
pro_signal(event_mask,event_handler)
Associates the event event_mask with the activation function event_handler.
This function returns -1L if there is an error (in particular if a function is
already associated with event_mask), NULL otherwise. If the second
argument is NULL the activation function associated with the first argument is
deleted, and its value is returned as the function result. The event_mask
argument must be one of the following values: 1, 2, 4, 8, 16, 32, 64, 128.
© PrologIA
Aociation Prolog
When the event_handler function is called and its result n is greater than 0 the
corresponding Prolog error is activated.
send_prolog_interrupt(event_mask)
Activates the process associated with the interruption event_mask, as soon as
this is allowed by the Prolog machine.
This function must return an integer which is interpreted as a Prolog error code if
this integer is positive.
When several interruptions are on stand-by, they are processed in the order defined
by the bit numbers (bit 0 first).
We recommend not to use the functions get/put_strterm if the time factor is critical,
since these functions are relatively slow to execute.
1. Write the Prolog extension to react to the SIGUSR11 signal: 30 and associate
with it the rule message in the file test.c.
#include <signal.h>
#include "proext.h"
#define MYEVENT 8
1This is an asynchronous signal which can be generated from outside Prolog from another UNIX
process. UNIX is a multi-task system, in which all executing programs are processes.
© PrologIA
Aociation Prolog
R9-4 Reference Manual HERITAGE
new_goal();
put_strterm(1,":message",&err);
if (!err)
err = next_solution();
kill_goal();
return err>0 ? err : 0 ;
}
EXTERNAL_DESCRIPTOR testTable[] =
{{":install_handler", C_FUNCTION, 0, (POINTER)
install_handler},
{ 0, 0, 0, 0 }
};
2. Compile test.c and link with Prolog1. In Prolog add the interruption handling
program.
$ cc -c test.c2
$ prolink test.o testTable
$ prolog
...
> insert;
message -> val(counter,n) outl(n);
count(N) -> val(mod(N+1,1000000),N1) assign(counter,N1)
count(N1);
;
> install_handler count(0);
1Please refer to section 2.8 of the User's Manual for instructions on how to compile and link in
Prolog, using your system.
© PrologIA
Aociation Prolog
1 This command transmits the SIGUSR1 signal (which Prolog must react to) to the Prolog
process.
© PrologIA
Aociation Prolog
R9-6 Reference Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
10.1 Syntax
10.2 Control
10.3 Manipulation of rules
10.4 Predefined data operations
10.5 Input and output
10.6 The environment
10.7 Translation of DCG
This chapter describes the additional rules made available when the Edinburgh
module is loaded.
It is organized in the same way as the reference manual, and describes the features
specific to Edinburgh mode for each topic.
A certain number of predefined rules are identical to the Prolog II+ predefined
rules, but with different names.
IMPORTANT: In this chapter, all atoms given in the argument position have an
empty prefix (""). The examples shown are written assuming the option
corresponding to "all atoms in the argument position not explicitly prefixed have an
empty prefix" is active. This option is described in appendix A. If it is not active,
you must bear in mind that atoms whose abbreviated representation is already
known to the system must be explicitly prefixed with the empty prefix, otherwise the
sys prefix will be used by default (at least in the user context). This applies in
particular to the following atoms: debug, string, fail (used in the predicate
set_prolog_flag/2), true, false (used for example in the predicate write_term/2), and
input, output, read, write (used for stream_property/2 or open/4).
10.1 Syntax
©PrologIA
Aociation Prolog
R 10 - 2 Reference Manual HERITAGE
The exact syntax is described in Chapter 1 using the E variant of the syntactic rules.
The main differences compared to the Edinburgh syntax described in the ISO/IEC
standard are described in appendix A.
When the first term encountered on the command line or in a directive is a list, it is
interpreted as a list of files to be consulted. user is equivalent to "console".
10.1.2 Operators
©PrologIA
Aociation Prolog
current_op(P,M,O)
Unifies the arguments P, M and O with the precedence, the type of parenthesis
and the operator respectively. Example:
?- current_op(1200,M,O).
{M=fx,O=?-}
{M=fx,O=:-}
{M=xfx,O=:-}
{M=xfx,O=-->}
10.2 control
\+ X or \+(X)
Equivalent to not(X).
X=Y or =(X,Y)
Succeeds if X can be unified with Y, fails otherwise. Defined by the rule:
X = X.
X \= Y or \=(X,Y)
Succeeds if X cannot be unified with Y, fails otherwise. Examples:
?- 1 \= 1.
?- X \= 1.
?- X \= Y.
?- 1 \= 1.0.
{}
X -> Y or ->(X,Y)
"If-then". Is defined by the rule (the parentheses are just to make it more
legible):
(X -> Y) :- X,!,Y.
X,Y
Propositional "and". X is executed, then Y.
©PrologIA
Aociation Prolog
R 10 - 4 Reference Manual HERITAGE
X;Y
Propositional "or". Is defined by the following rules (Please note: in
Prolog II the cut is transparent):
X;Y :- X.
X;Y :- Y.
call(X)
Is defined by the rule:
call(X) :- X.
catch(G,C,R)
Starts execution of goal G. Succeeds in two cases:
- execution of G succeeds with a "throw" interruption,
- a "throw" interruption occurs whose argument unifies with the
argument C and execution of goal R succeeds. If unification fails, the
interruption spreads via the block/block_exit mechanism.
Examples:
reconsult(user).
foo(X) :- Y is X*2, throw(test(Y)).
bar(X) :- X=Y, throw(Y).
coo(X) :- throw(X).
car(X) :- X=1, throw(X).
g :- catch(p, B, write(h2)), coo(c).
p.
p :- throw(b). .
{}
?- catch(foo(5),test(Y),true).
{Y=10}
?- catch(bar(3),Z,true).
{Z=3}
?- catch(true,C,write(foo)), throw(bla).
-> bla([]) 'block_exit' NO 'block' CORRESPONDENT
?- catch(coo(X),Y,true).
{}
?- catch(car(X),Y,true).
{X=1,Y=1}
?- catch(g, C, write(h1)).
h1{C=c}
fail_if(X)
Equivalent to call to not(call(X)).
?- fail_if(true).
?- fail_if(4=5).
{}
once(G)
Executes goal G in the first way possible. Defined by the rule:
once(G) :- G, ! .
throw(X)
Equivalent to a call to block_exit(X1) , where X1 is a copy of the term X
(renaming of variables).
©PrologIA
Aociation Prolog
true
Always executes successfully.
unify_with_occurs_check(X, Y)
Attempts to unify terms X and Y with a check for non production of infinite
trees. Fails if the unification fails or if it generates an infinite tree. Examples:
?- unify_with_occurs_check(1,1).
{}
?- unify_with_occurs_check(1,2).
?- unify_with_occurs_check(X,1).
{X=1}
?- unify_with_occurs_check(X,a(X)).
?- unify_with_occurs_check(X,[1|X]).
?- unify_with_occurs_check(X,[X|1]).
?-
assert(X)
assertz(X)
Adds the rule or fact X at the end of a group of rules. Please refer to the
description of assert in Prolog II.
Warning. In Edinburgh syntax, the comma is both a separator and an
operator, and the argument must therefore be bracketed in these rules:
?- assert(a).
{}
?- assert((a :- b,c)).
{}
asserta(X)
Adds the rule or fact X at the beginning of a group of rules. Please refer to
the description of asserta in Prolog II.
clause(T,Q)
T must not be a free variable. Unifies T and Q with the head and body
respectively of all clauses whose access is defined by T. Behaves like rule
except that an empty body is represented by true, and a non-empty body is
represented by a structure with the node ','.
consult(F)
reconsult(F)
Equivalent to insert and reinsert respectively. If F is an identifier, the string
corresponding to its abbreviation is taken as the file name (i.e. the prefix is
ignored). If the value of F is user or "user", it reads on the current reading
unit.
©PrologIA
Aociation Prolog
R 10 - 6 Reference Manual HERITAGE
listing
listing(X)
Equivalent to list and list(X).
retract(X)
Same behavior as retract with two arguments. X must be a fact or rule whose
head predicate is instantiated.
retract((T:- true)) is equivalent to retract(T),
retract(T) is equivalent to retract(T,[]), if T does not unify with :- (T1,T2),
retract((T :- Q)) is equivalent to retract(T,Q).
retractall(X)
Retracts all rules whose heads unify with X (without unification of X or
backtracking). X must have the pattern of a rule head, otherwise the predicate
will have no effect. Always results in a success.
atom(X)
Succeeds if X is an identifier, fails otherwise. Equivalent to ident(X).
atomic(X)
Succeeds if X is a constant, fails otherwise.
compound(X)
Succeeds if X is a list or tuple, fails otherwise.
float(X)
Is equivalent to real(X).
nonvar(X)
Is equivalent to bound(X).
number(X)
Succeeds if X is an integer or a real, and fails otherwise.
var(X)
Succeeds if X is a free variable and fails otherwise. Is equivalent to free(X).
©PrologIA
Aociation Prolog
An expression is evaluated using the predefined rule val. Certain expressions can
be used directly in Edinburgh syntax as terms to erase.
The following terms can be erased with using the val predicate.
X =:= Y or =:=(X,Y)
Is equivalent to val(eql(X,Y),1).
X < Y or <(X,Y)
X =< Y or =<(X,Y)
X > Y or >(X,Y)
X >= Y or >=(X,Y)
Are equivalent respectively to:
val('<'(X,Y),1)
val('=<'(X,Y),1)
val('>'(X,Y),1)
val('>='(X,Y),1)
X is Y or is(X,Y)
Is equivalent to val(Y,X).
The following functions are specific to Edinburgh mode. They are evaluated by the
predefined rules val, tval and is. They must be applied to integer or real number
arguments.
\X or \(X)
value (\X) = value ('~'(X)) = bit by bit complement of X.
The value of X must be an integer. The result is an integer.
X // Y or //(X,Y)
value (//(X, Y)) = integer division of value (X) by value (Y).
The result is an integer.
log(t)
value (log(t)) = value (ln(t)) = Napierian logarithm(value(t)).
The result is a real.
truncate(t)
value (truncate(t)) = value (trunc(t)) = the value of t is converted into an
integer.
The result is an integer.
©PrologIA
Aociation Prolog
R 10 - 8 Reference Manual HERITAGE
X =.. Y or =..(X,Y)
If X is instantiated, Y is unified with a list in which the first element is the
functor of X, and the subsequent elements are possible arguments in their
order.
If X is free, Y must be instantiated with a list in which the first element is
atomic. X is then unified with a term constructed using the first element in the
list as functor, and the other elements as arguments.
An atomic element is a list constituted by this single element. Examples:
?- '=..'(foo(a,b),[foo,a,b]).
{}
?- '=..'(X,[foo,a,b]).
{X=foo(a,b)}
?- '=..'(foo(a,b),L).
{L=[foo,a,b]}
?- '=..'(foo(X,b),[foo,a,Y]).
{X=a,Y=b}
?- '=..'(1,[1]).
{}
?- '=..'(foo(a,b),[foo,b,a]).
?- '=..'(f(X),[f,u(X)]).
{X=_714, _714=u(_714)}
arg(N,T,X)
X returns the Nth element of the term T. N is an integer, and T a tuple or
pointed pair. Both must be known when the rule is made.
If T is a pointed pair, then if;
N=1, X is unified with the first element of the pair.
N=2, X is unified with the second element of the pair.
If N is an integer, and T is a tuple whose size is M>1, then if:
0<N<M, X is unified with argument N+1 of the tuple T.
(i.e. with argument N of T=f(a1,...,an,...,aM)).
Fails otherwise.
Example :
?- arg(1,eq(john,fred), X).
{X=john}
?- arg(0,eq(john,fred), Y).
?-
atom_chars(A,L)
Associates the list L of characters with the identifier A it constitutes and vice-
versa. The prefix of identifier A is ignored (as input) or equal to "" (as
output). Examples:
?- atom_chars('',L).
{L=[]}
?- atom_chars('''', L).
{L=['''']}
?- atom_chars('ant',L).
{L=[a,n,t]}
?- atom_chars(Str, ['s', 'o', 'p']).
{Str=sop}
©PrologIA
Aociation Prolog
atom_codes(A,L)
Associates the list L of internal codes (ISO codes or host machine codes) with
the identifier A it constitutes and vice-versa. The prefix of identifier A is
ignored (as input) or equal to "" (as output).
atom_concat(A1,A2,A3)
Manipulates identifiers in the same way as conc_string manipulates character
strings. The prefixes of identifiers A1, A2, A3 are ignored (as input) or equal
to "" (as output). Examples:
?- atom_concat('hello',' world',S3).
{S3='hello world'}
?- atom_concat(T,' world','small world').
{T=small}
?- atom_concat(T1,T2,'hello').
{T1='',T2=hello}
{T1=h,T2=ello}
{T1=he,T2=llo}
{T1=hel,T2=lo}
{T1=hell,T2=o}
{T1=hello,T2=''}
atom_length(A,N)
Unifies N with the length of identifier A. The prefix of identifier A is ignored.
Examples:
?- atom_length('enchanted evening',N).
{N=17}
?- atom_length('',N).
{N=0}
functor(T,F,N)
Associates tree T with its functor F and arity N, and vice versa.
?- functor(foo(a,b,c),X,Y).
{X=foo,Y=3}
?- functor(X,foo,3).
{X=foo(_515,_516,_517)}
?- functor(X,foo,0).
{X=foo}
?- functor(foo(a),foo,2).
?- functor(foo(a),fo,1).
?- functor(1,X,Y).
{X=1,Y=0}
?- functor(X,1.1,0).
{X=1.1}
?- functor([_|_],'.',2).
{}
?- functor([],[],0).
{}
name(X,L)
If X is an identifier or number, L is unified with the list of internal codes (ISO
codes or host machine codes) of the characters constituting the representation
of identifier X.
If L is a list of the internal codes of an identifier's letters, X is instantiated with
the identifier determined by the current prefixing conventions.
©PrologIA
Aociation Prolog
R 10 - 10 Reference Manual HERITAGE
?-name(abc:def,L).
{L=[97,98,99,58,100,101,102]}
?- name(123,L).
{L=[49,50,51]}
?- name(X,[65,66|4]).
?- name("asd",X).
?- name(Y,X).
?- name(ab:'cd',L).
{L=[97,98,58,99,100]}
?- name(ab:' %',L).
{L=[97,98,58,39,32,37,39]}
?- name(I,[97,98,58,99,100]).
{I=ab:cd}
?- name(M,[97,98,58,39,32,37,39]).
{M=ab:' %'}
?-
number_chars(N,L)
Associates the list L of characters with the number N it constitutes.
Conversely, considers L as input and associates the number N with it (printed
in decimal form). Examples:
?- number_chars(33, L).
{L=['3','3']}
?- number_chars(33.0, L).
{L=['3','3','.','0']}
?- number_chars(X, ['3', '.', '3', 'E', '+', '0']).
{X=3.3}
?- number_chars(3.3, ['3', '.', '3', 'E', '+', '0']).
{}
?- number_chars(A, ['-', '2', '5']).
{A=-25}
?- number_chars(A, [' ', '3']).
{A=3}
?- number_chars(A, ['0', 'x', 'f']).
{A=15}
?- number_chars(A, ['0', '''', 'a']).
{A=97}
?- number_chars(A, ['4', '.', '2']).
{A=4.2}
?- number_chars(A, ['4', '2', '.', '0', 'e', '-', '1']).
{A=4.2}
number_codes(N,L)
Same description as number_chars/2 but L is a list of internal codes (ISO
codes or host machine codes).
phrase(X,Y)
phrase(X,Y,Z)
Attempts to split the list Y into a sentence of the grammar and a remainder. X
must be a grammar rule head, Y and Z can be free variables or lists.
Enumerates the possible solutions and unifies the remainder with Z. The two-
argument version phrase(X,Y) is equivalent to phrase(X,Y,[]).
Note: If Y or Z are character strings, they are first transformed into lists of
characters before the call is performed: phrase(sum(X),"1+2+3") is
automatically transformed in the call phrase(sum(X), ["1","+","2","+","3"]).
©PrologIA
Aociation Prolog
sub_atom(A1,N1,N2,N3,A2)
Results in a success if identifier A1, which must be known when the call is
made, can be seen as the concatenation of three parts such that N1 is the
length of the first part, N2 the length of the second part, which is simply the
identifier A2, and N3 the length of the third part. The prefixes of identifiers
A1 and A2 are ignored (as input) or equal to "" (as output). Examples:
?- sub_atom(abracadabra, 0, 5, A, S2).
{A=6,S2=abrac}
?- sub_atom(abracadabra, _, 5, 0, S2).
{S2=dabra}
?- sub_atom(abracadabra, 3, L, 3, S2).
{L=5,S2=acada}
?- sub_atom(abracadabra, B, 2, A, ab).
{B=0,A=9}
{B=7,A=2}
?- sub_atom('Banana', 3, 2, A, S2).
{A=1,S2=an}
?- sub_atom('charity', B, 3, A, S2).
{B=0,A=4,S2=cha}
{B=1,A=3,S2=har}
{B=2,A=2,S2=ari}
{B=3,A=1,S2=rit}
{B=4,A=0,S2=ity}
?- sub_atom('ab', Start, Length, A, Sub_atom).
{Start=0,Length=0,A=2,Sub_atom=''}
{Start=0,Length=1,A=1,Sub_atom=a}
{Start=0,Length=2,A=0,Sub_atom=ab}
{Start=1,Length=0,A=1,Sub_atom=''}
{Start=1,Length=1,A=0,Sub_atom=b}
{Start=2,Length=0,A=0,Sub_atom=''}
X == Y or ==(X,Y)
Succeeds if X is formally equal to Y, fails otherwise. Examples:
?- 1 == 1.
{}
?- X == X.
{}
?- 1 == 2.
?- X == 1.
?- X == Y.
?- _ == 1.
?- _ == _.
?-
©PrologIA
Aociation Prolog
R 10 - 12 Reference Manual HERITAGE
X @< Y
Compares terms X and Y, and succeeds if X precedes Y. Fails otherwise.
X @> Y
Compares terms X and Y and succeeds if Y precedes X. Fails otherwise
X @>= Y
Compares terms X and Y and succeeds if Y precedes or is formally equal to X.
Fails otherwise.
X @=< Y
Compares terms X and Y and succeeds if X precedes or is formally equal to Y.
Fails otherwise. Some examples:
?- 1.0 @< 1.
{}
?- @<(aardvark,zebra).
{}
?- @<(short,short).
?- short @< shorter.
{}
?- @<(foo(a),foo(b)).
{}
?- @<(foo(a,b),north(a)).
?- @<(X,X).
?- Y @< X.
{}
?- @<(_,_).
{}
?- @<(foo(X,a),foo(Y,b)).
{}
?- "foo" @> foo.
{}
?- [1,2,3] @> [1,1,3,4].
{}
?- [1,2] @> <>(1,2).
?- [1,2] @> <>(X).
{}
10.5.1 Introduction
©PrologIA
Aociation Prolog
close(C,O), close(C)
Closes the unit associated with channel C. If argument O exists, it must be a
list of options taken from among:
force(true): if a unit closing error occurs it will be generated.
force(false): if a unit closing error occurs it will be ignored.
open(S,M,C,O), open(S,M,C)
Opens the unit whose name is the atom S in mode M, and returns the
associated channel C. If argument O exists, it must be a list of options taken
from among:
- alias(A) where A must be an identifier and will indicate an alias to be
used as the unit's name in the predicates.
- eof_action(A) which indicates the action to perform on an end of file
according to the value of A:
- error: an error is generated (default).
- eof_code: a special code determined by the reading predicate
is returned upon each attempt to access the file (see reading
predicates).
- reset: the same code as for eof_code is returned and reading
of the end of file is canceled. The value of the end_of_stream
property remains at. This is useful for terminals.
- lg_buffer(L) where L must be an integer and indicates the size of the
buffer associated to the unit.
- reposition(B) where B can take the value true or false and indicates
whether the reading (or writing) index can be re-positioned (call to the
primitive set_stream_position/2). Default: true.
- type(T) where T denotes the unit type.
Channel C associated with the unit must be a free variable when the call is
made, and is unified with a negative integer value (transparent for the user).
Example:
?- open(bfile,write,X,[alias(bfile),type(binary)]).
{X=-7}
set_stream_position(C,N)
Positions the reading or writing cursor of the unit associated with channel C at
the Nth byte. N must be an integer and the unit must be a disk file.
stream_property(C,P)
Succeeds if the unit associated with channel C has the property P. C can be a
free variable, in which case all channels possessing property P will be unified
with C. P can either be free or indicate one of the following properties:
- alias(A) where A will be unified with the unit's alias.
- file_name(S) where S will be unified with the unit's name.
- input which will be true if the unit is an input unit.
- mode(M) where M will be unified with the unit opening mode.
- output which will be true if the unit is an output unit.
©PrologIA
Aociation Prolog
R 10 - 14 Reference Manual HERITAGE
10.5.2 Input
Examples:
?- set_prolog_flag(double_quotes,string), read(R).
©PrologIA
Aociation Prolog
"hello world".
{R="hello world"}
?- set_prolog_flag(double_quotes,chars), read(R).
"hello world".
{R=[h,e,l,l,o,' ',w,o,r,l,d]}
?- set_prolog_flag(double_quotes,codes), read(R).
"hello world".
{R=[104,101,108,108,111,32,119,111,114,108,100]}
?- set_prolog_flag(double_quotes,atom), read(R).
"hello world".
{R='hello world'}
?-
10.5.2.2 Predicates
If the argument denoting the input unit is an input argument, you can use either the
channel number or the alias associated with the unit. Otherwise (i.e. the predicate
current_input/1), the channel number will be returned.
Most input predicates can be used either on the unit specified in the argument
(channel number, alias), or on the current input unit, in which case the argument
indicating the unit is absent.
The behavior of reading predicates when an end of file is detected complies with the
eof_action option chosen when the reading unit was opened.
at_end_of_stream(C), at_end_of_stream
Succeeds if reading on channel C has already indicated an end of file, fails
otherwise. Unlike the eof predicate, this predicate does not attempt to read
channel C again. Instead it just examines the status of the previous reading.
current_input(C)
C is unified with the channel associated with the current input unit. Warning:
C will not be an alias.
get(C,X), get(X)
X is unified with the integer equal to the internal code (ISO code or host
machine code) of the first non blank character read on the input unit
associated with channel C. If an end of file is reached and if unit has been
opened with eof_action(eof_code) option X is unified with -1.
get_byte(C,X), get_byte(B)
X is unified with the first byte (integer >= 0) read on the input unit associated
with channel C. This unit must be the :binary type. If an end of file is
reached and if unit has been opened with eof_action(eof_code) option X is
unified with -1.
get_char(C,X), get_char(X)
X is unified with the first character read on the input unit associated with
channel C. If an end of file is reached and if unit has been opened with
eof_action(eof_code) option X is unified with end_of_file.
©PrologIA
Aociation Prolog
R 10 - 16 Reference Manual HERITAGE
get_code(C,X), get_code(X)
X is unified with the integer equal to the internal code (ISO code or host
machine code) of the first character read on the input unit associated with
channel C. If an end of file is reached and if unit has been opened with
eof_action(eof_code) option X is unified with -1.
get0(X)
Identical to get_code/1.
peek_byte(C,X), peek_byte(X)
Attempts to unify X with the first byte (integer >= 0) input on the unit
associated with channel C. This unit must be the :binary type. The byte is
not read. Therefore this predicate does not modify the unit's properties
position and end_of_stream. If an end of file is reached and if the unit has
been opened with eof_action(eof_code) option X is unified with -1.
peek_char(C,X), peek_char(X)
Attempts to unify X with the first character input on the unit associated with
channel C. The character is not read. Therefore this predicate does not
modify the unit's properties position and end_of_stream. If an end of file is
reached and if the unit has been opened with eof_action(eof_code) option X is
unified with end_of_file.
peek_code(C,X), peek_code(X)
Attempts to unify X with the integer equal to the internal code (ISO code or
host machine code) of the first character input on the unit associated with
channel C. The character is not read. Therefore this predicate does not
modify the unit's properties position and end_of_stream. If an end of file is
reached and if unit has been opened with eof_action(eof_code) option X is
unified with -1.
read(C,X), read(X)
Reads the next term on the unit associated with channel C, followed by the
first subsequent non blank character. Equivalent to in(X,_) on unit C. If an
end of file is reached and if unit has been opened with eof_action(eof_code)
option X is unified with end_of_file.
> read(X).
[1,2].
{X=[1,2]}
read_term(C,X,O), read_term(X,O)
Similar to the read predicate, but in addition you can obtain the following list
of options:
- variables(L_V) where L_V will be the list of variables of term X.
©PrologIA
Aociation Prolog
see(F)
Is equivalent to input(F). If F is an identifier, the string corresponding to its
abbreviation is taken as the file name (i.e. the prefix is ignored).
seeing(F)
Is equivalent to input_is(F). If F is an identifier, the string corresponding to
its abbreviation is taken as the file name (i.e. the prefix is ignored).
seen
Is equivalent to close_input.
set_input(C)
Redirects current input to the unit associated with channel C.
10.5.3 Output
If the argument denoting the output unit is an input argument, you can use either the
channel number or the alias associated with this unit. Otherwise, (i.e. the predicate
current_output/1), it is the channel number that will be returned.
Most of the output predicates can be used either on the unit specified in the
argument (channel number, alias), or on the current output unit, in which case the
argument indicating the unit is absent.
current_output(C)
C is unified with the channel associated with the current output unit.
Warning: C will not be an alias.
flush_output(C), flush_output
Equivalent to the predicate flush/0 for the output unit associated with channel
C.
©PrologIA
Aociation Prolog
R 10 - 18 Reference Manual HERITAGE
nl(C), nl
Equivalent to line/0 for the output unit associated with channel C.
put(X)
Equivalent to put_code/1.
put_byte(C,X), put_byte(X)
The byte X (integer >= 0) is sent to the output unit associated with channel C.
This unit must be the :binary type.
put_char(C,X), put_char(X)
The character X is sent to the output unit associated with channel C.
put_code(C,X), put_code(X)
The internal code of character X is sent to the output unit associated with
channel C.
set_output(C)
Redirects the current output to the unit associated with channel C.
tab(N)
Sends N blanks to the current output unit.
tell(F)
Is equivalent to output(F). If F is an identifier, the string corresponding to its
abbreviation is taken as the file name (i.e. the prefix is ignored).
telling(F)
Is equivalent to output_is(F). If F is an identifier, the string corresponding to
its abbreviation is taken as the file name (i.e. the prefix is ignored).
told
Is equivalent to close_output.
write(C,X), write(X)
Is equivalent to w r i t e _ t e r m with the options [ q u o t e d ( f a l s e ) ,
numbervars(true), ignore_ops(false)].
writeq(C,X), writeq(X)
Is equivalent to write_term with the options [quoted(true), numbervars(true),
ignore_ops(false)].
write_canonical(C,X), write_canonical(X)
Is equivalent to w r i t e _ t e r m with the options [ q u o t e d ( t r u e ) ,
numbervars(false), ignore_ops(true)].
©PrologIA
Aociation Prolog
write_term(C,X,O), write_term(X,O)
Writes the term X on the output unit associated with channel C, taking account
of the list of options O selected from the following:
- quoted(true) or quoted(false): indicates whether or not the string and
identifier constants in X must be written in quoted form.
- ignore_ops(true) or ignore_ops(false): indicates whether or not the
current operator declarations should be ignored.
- numbervars(true) or numbervars(false): indicates whether or not the
terms in the form '$VAR'(N), (where N is a positive integer) must be
written as a variable consisting of an upper-case letter followed by an
integer. The letter is the (i+1)th letter of the alphabet, and the integer is
j, such that:
i = N modulo 26
j = N / 26 (integer division).
If an option is not specified, its default value is :false.
Examples:
?- write_term(['quoted atom', "string", 1+2,
'$VAR'(35)],[]).
[quoted atom,string,1 + 2,'$VAR'(35)]{}
?- write_term(['quoted atom', "string", 1+2,
'$VAR'(35)],[quoted(:true),numbervars(true),
ignore_ops(true)]).
['quoted atom',"string",+(1,2),J1]{}
?-
©PrologIA
Aociation Prolog
R 10 - 20 Reference Manual HERITAGE
current_prolog_flag(X,Y)
Gives information about the current values of the environment status variables.
The status variables max_integer and min_integer always cause a failure
because integer arithmetic is not bounded. For example: We want to know
the values of all the status variables:
?- current_prolog_flag(F, V).
{F=bounded,V=false}
{F=integer_rounding_function,V=toward_zero}
{F=char_conversion,V=off}
{F=max_arity,V=8388607}
{F=:debug,V=off}
{F=unknown,V=warning}
{F=double_quotes,V=:string}
halt(X), halt
Equivalent to quit(X) and quit respectively
set_prolog_flag(X,Y)
Sets the environment status variable X to the value Y. This predicate is also a
compiling directive, i.e. the environment variables may be modified in the
middle of a source you are compiling. Examples:
?- consult.
set_prolog_flag(double_quotes, codes).
foo :- myrule("abc").
.
{}
?- set_prolog_flag(debug, on).
{}
A --> B.
Where A is a term and B is a sequence of terms. For each term in the sequence B:
©PrologIA
Aociation Prolog
To translate the grammar rule into a Prolog rule, Prolog will call the predicate
:term_expansion/2 if it has been defined. If not it will use its own transformation
program. It is thus possible to perform automatic transformations of terms having
the form (A --> B). To define a transformation program, the following rule must be
defined:
term_expansion(X,Y)
When this rule is called, X is the term Prolog has just read and Y is a free
variable. X has the form (A --> B).
After the call, Y must represent the Prolog rule, which must be associated with
rewriting rule X (i.e. the Prolog rule that will be asserted).
Example 1
?- [user].
sum(Z) --> digit(Z).
sum(X+Y) --> digit(X), "+", sum(Y).
digit(1) --> "1".
...
digit(9) --> "9".
.
{}
?- list.
sum(_53,_54,_55) :-
digit(_53,_54,_55).
sum(_57 + _58,_54,_55) :-
digit(_57,_54,["+" | _59]),
sum(_58,_59,_55).
digit(1,["1"|_54],_54).
...
digit(9,["9"|_54],_54).
{}
?- phrase(sum(Z),"1+2+3").
{Z=1 + (2 + 3)}
?- phrase(sum(1+(2+9)),L).
{L=["1","+","2","+","9"]}
Example 2
?- [user].
sum(Z) --> digit(Z).
©PrologIA
Aociation Prolog
R 10 - 22 Reference Manual HERITAGE
©PrologIA
Aociation Prolog
HERITAGE
Appendix A
Differences between Prolog II+ and
the standard
In Prolog II+ the cut in a meta-call has a greater range than in the standard. For
example this means that there are the following differences in operation, compared
to the standard:
?- insert.
a(1).
a(2).
.
?- call( (Z=!, a(X), Z) ).
{Z=!,X=1} /* a single solution instead of 2 */
Prolog II+ has an extra option compared to the standard definition, making it
possible to classify "in double quotes" in a type of its own which is the "character
string" type. This option is active by default at Prolog start-up.
Identifier prefixing
In Prolog II+, when identifiers are read they are always assigned a prefix in
accordance with the current context, whether they are positioned as
arguments(functors) or goals (rule head or body). However we also make it
possible to automatically assign non-prefixed identifiers the empty prefix ("") when
they are positioned as arguments. To do this, simply start Prolog with "-f a0"
option.
For example, when the system reads call(nl) in this mode it will call a rule that is
doubtless not defined (:nl), whereas call(sys:nl) will print a line feed. .
©PrologIA
Aociation Prolog
A-2 Appendix A HERITAGE
?- set_options("a1").
The only times when the behavior may be different from an immediate process is
when a rule is suppressed in a group where there still remain alternatives to execute.
The enumeration of all the possibilities is then quite complex. The complexity
depends on whether or not the group of rules in question is indexed, on the position
of the modified rule in relation to the rule of the same group that is being executed,
on the type of the goals' first argument (variable, constant, etc.).
The tuples
The tuple type is not defined in the Prolog standard. To define an equivalence, we
can say that the term f(a1, a2, ..., an) where f is an atom, is equivalent to the tuple
<>(f, a1, a2, ..., an), except when n=0 (f is not equivalent to <>(f) ).
Only the :off value is taken into account for the second parameter of the compiling
directive and primitive set_prolog_flag/2 when the value of the first parameter is
:char_conversion.
©PrologIA
Aociation Prolog
©PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Appendix B
List of predefined directives and
predicates
©PrologIA
Aociation Prolog
B-2 Reference manual HERITAGE
B.2 Predicates
A
abolish( @t) abolish(myrule/2)
abs( +m) val(abs(-1.5e0),1.5e)
add( +m1, +m2) val(add(2.3E0,3.1E1),3.33E1)
add_implicit( +s1, +s2) add_implicit("sys","outml")
add_tlv( -v, ?t, +i) add_tlv(V, 33, foo)
alloc
alloc( ?n1, ?n2, ?n3, ?n4, ?n5, ?n6, ?n7, ?n8, ?n9, ?n10, ?n11, ?n12)
arg( +n, +t1, ?t2) arg(0,<>(aa,bb),aa)
arg2( +n, +t1, ?t2) arg2(2,<>(aa,bb),bb)
assert( +t) assert(brother(jean,paul))
assert( +t1, +t2) assert(pp(X),[qq(X),rr(X)])
assert''( +t1, +t2) assert''(pp(X),[qq(X),rr(X)])
asserta( +t) asserta(brother(jean,paul))
asserta( +t1, +t2) asserta(pp(X),[qq(X),rr(X)])
assertn( +t1, +t2, +n) assertn(pp(x),[qq(X),rr(X)],2)
assertz( +t1, +t2) assertz(pp(x),[qq(X),rr(X)])
assertz( +t) assertz(brother(X,Y):-son(X,Z),son(Y,Z))
assign( +i, @t) assign(fo,term(3,[1,2,x],tab[5],"str"))
at_end_of_stream
at_end_of_stream( +h) at_end_of_stream(alias1)
atan( +m) val(atan(1),X)
atom( @t) atom(foo)
atom_chars( +i, ?l) atom_chars(foo,X)
atom_chars( -i, +l) atom_chars(X,["a","b"])
atom_codes( +i, ?l) atom_codes(foo,X)
atom_codes( -i, +l) atom_codes(X,[65,66])
atom_concat( ?i1, ?i2, +i) atom_concat(X,Y,foo)
atom_concat( +i1, +i2, -l) atom_concat(fo1,fo2,X)
atom_length( +i, ?n) atom_length(foo,X)
atomic( @T) atomic(1)
B
bagof( ?v, +t, ?l) bagof(X,frere(X,Y),L)
beep
block( ?t1, +t2) block(edit,call_editor)
block( ?t1, ?t2, +t3) block(edit,_info,call_editor)
block_exit( @t) block_exit(edit)
block_exit( @t1, @t2) block_exit(edit, "this error")
bound( @t) bound(X)
C
call( +t) call(outml("Hello"))
callC( +t1) callC(sscanf("12.","%f",<>("R",X)))
callC( +t1, ?t2) callC(open("myfile"),<>("I",X))
catch( +t1, ?t2, +t3) catch(foo(5),test(Y),outml("Hello"))
©PrologIA
Aociation Prolog
D
date( ?v1, ?v2, ?v3, ?v4) date(J,M,A,S)
date_string( ?v)
date_stringF( ?v)
debug
debug( +u) debug("echodebug.dat")
debug( +n) debug(3)
debug( +n, +u) debug(3, "echodebug.dat")
def_array( +i, +n) def_array(stack,100)
default( +t1, +t2) default(man(X),eq(x,[]))
delay( +n) delay(5000)
dictionary
dictionary( ?l)
dictionary( +s, ?l) dictionary("sys",X)
dif( ?t1, ?t2) dif(X,toto)
©PrologIA
Aociation Prolog
B-4 Reference manual HERITAGE
E
echo
edinburgh
edit( +i/+n) edit(hors_d_oeuvre/1)
edit( +l) edit([meat/1,fish/1])
edit( +s) edit("file.dat")
editm( +s) editm("my_module")
enum( ?v, +n) enum(X,10)
enum( ?v, +n1, +n2) enum(X,10,20)
eof
eol
eq( ?t1, ?t2) eq(X,father(john,mary))
eql( +a1, +a2) val(eql(3,3),1)
equations( +t1, ?t2, ?l) equations(X,T,l)
exit
exit( +s) exit("myfile.psv")
exp( +m) val(exp(+1.0e0),X)
FGH
fail
fail_if( +t) fail_if(fail)
fasserta( +t) fasserta(town("Marseille",13))
fassertz( +t) fassertz(town("Marignane",13))
file_dictionary( +s, ?l) file_dictionary("foo.mo",X)
find_pattern( +s1, +s2, ?n) find_pattern("abcdef","de",4)
findall( ?V, +T, ?L) findall (X,brother(X,Y),L)
float( +m) val(float(5),+5.0e0)
flush
flush_output
flush_output( +h) flush_output(alias1)
free( @t) free(X)
freeze( -v, +t) freeze(X,list(X))
freplace( +t, +n, +t') freplace(old(X,Y),1,"010180")
freplace( +i/+a, +n1, +n2, +t) freplace(old/2,10,2,"011293")
fretract( +t) fretract(town(X,83))
fretractall( @t) fretractall(town(X,83))
functor( -t, +i, +n) functor(X,aa,2)
functor( +t, ?i, ?n) functor(aa(bb(X),bb(cc)),aa,X)
gc( +i) gc(:dictionary)
gensymbol( -v) gensymbol(X)
get( ?n) char_code(";",C), get(C)
©PrologIA
Aociation Prolog
IK
ident( @t) ident(toto)
if( +b, +a1, +a2) val(if(inf(1,5),add(1,1),3),2)
import_dir( ?s)
in( ?t , ?c) in(X,C)
in( ?t , ?l, ?c) in(X,D,C)
in_char( ?c) in_char(X)
in_char'( ?c) in_char'(X)
in_double( ?d) in_double(X)
in_ident( ?i) in_ident(X)
in_integer( ?n) in_integer(X)
in_real( ?r) in_real(X)
in_sentence( ?t1, ?t2) in_sentence(X,Y)
in_string( ?s) in_string(X)
in_word( ?s, ?a) in_word(X,Y)
include( +s) include("myfile")
index( +i/+n) index(database/1)
inf( +a1, +a2) val(inf("to","zou"),1)
infe( +a1, +a2) val(infe("to","zou"),1)
infinite
infinite_flag val(infinite_flag,X)
init_fassert( +i/+a, +l) init_fassert(town/2,[[1,2],1,2])
inl( ?v) inl(X)
inl( ?v1, ?v2) inl(X,Y)
input( +u) input("console")
input( +u , +n) input("myfile", 1000)
input_is( ?u) input_is("console")
insert
©PrologIA
Aociation Prolog
B-6 Reference manual HERITAGE
L
line
line_width( ?n) line_width(X)
list
list( +i/+n) list(foo/2)
list( +i/+n, n) list(foo/2,4)
list( +s) list("mymodule")
list_of( ?v, +l1, +t, ?l2) list_of(X,[],data(X),L)
list_string( +l, ?s) list_string(["a","b"],X)
list_tuple( +l, ?t) list_tuple([aa,bb,cc],x)
listing
listing( +s) listing("mymodule")
lkload( +s1, +s2) lkload("my_file","my_table")
ln( +m) val(ln(1.0e0),0.0e0)
log( +m) val(log(1.0e0),0.0e0)
load( +s) load("myfile")
load( +s, +l) load("myfile", [<>("aa","bb")])
MN
member( ?t, ?l) member(1,[1,2,3,4])
memory_file( +s) memory_file("non-terminal")
memory_file( +s, +n) memory_file("lexical",32000)
mod( +n1, +n2) val(mod(7,3),1)
month( ?i, ?s) month(5,"may")
ms_err( +i, ?s) ms_err(104,X)
mul( +m1, +m2) val(mul(add(3.1e0,0.077d0),5),X)
name( +f, ?l) name(toto,X)
name( -f, +l) name(X,[116,111,116,111])
new_tlv( -v, ?t, +i) new_tlv(V, 33, foo)
next_char( ?c) next_char(",")
next_char'( ?c) next_char'(X)
nil
nl
nl( +h) nl(alias1)
no_debug
no_echo
no_index( +i/+a) no_index(foo/2)
©PrologIA
Aociation Prolog
no_infinite
no_paper
no_spy( +i/+n) no_spy(foo/2)
no_trace
nonvar( @t) nonvar([1|X])
not( @t) not(true)
not_defined( ?l)
number( @t) number(10)
number_chars( +n, ?l) number_chars(123,X)
number_chars( -n, +l) number_chars(X,["1","2","3"])
number_codes( +n, ?l) number_codes(123,X)
number_codes(- n, +l) number_codes(X,[49,50,51])
OPQ
once( +t) once(out(foo))
op( ?n, ?i1, ?i2) op(900,fy,not)
op( +n, +i1, +i2, +i3) op(700,xfx,"=",eq)
open( +s, +i, -v) open("file",:read,X)
open( +s, +i, -v, +l) open("file",:read,X,[alias(alias1))
or( +t1, +t2) or(eq(X,3),outl(X).fail)
out( @t) out([a,b])
out_equ( @t) out_equ(aa(bb))
outl( @t) outl([a,b])
outm( +s) outm("bonjour")
outm( +s, +n) outm("_",30)
outml( +s) outml("The cat and the dog")
output( +s) output("myfile.pro")
output( +u , +n) output ("myfile", 1000)
output_is( ?s) output_is("myfile.pro")
page
paper
peek_byte( ?n)
peek_byte( +h, ?n) peek_byte(alias1,X)
peek_char( ?c)
peek_char( h, ?c) peek_char(alias1,X)
peek_code( ?n)
peek_code( +h, ?n) peek_code(alias1,X)
phrase( ?t1, ?t2) phrase(somme(X),"1+2+3")
phrase( ?t1, ?t2 , ?t3) phrase(somme(X),"1+2+3",Y)
predefined( +t) predefined(outm("Ok"))
prefix_limit( ?c) prefix_limit(X)
prologII
prologIIE
put( +n) char_code("!",C), put(C)
put_byte( +n) put_byte(12)
put_byte( +h, +n) put_byte(alias1,12)
put_char( +c) put_char("e")
put_char( +h, +c) put_char(alias1,"e")
©PrologIA
Aociation Prolog
B-8 Reference manual HERITAGE
R
rad( +m) val(rad(+90.0e0),X)
read( ?t) read(X)
read( +h, ?t) read(alias1,X)
read_rule( ?v1, ?v2) read_rule(T,Q)
read_term( ?t, +l) read_term(X,[variables(L)])
read_term( +h, ?t, +l) read_term(alias1,X,[variables(L)])
read_unit( ?v1, ?v2) read_unit(_type,_valeur)
real( @t) real(-5.9e0)
realloc( +i, +n) realloc(:code,50)
reconsult( +f) reconsult("prog1.p2E")
recv_double( +n1, ?v2) recv_double(5,D)
recv_integer( +n1, ?v2) recv_integer(5,N)
recv_real( +n1, ?v2) recv_real(5,R)
recv_string( +n1, ?v2) recv_string(5,S)
redef_array( +i, +n) redef_array(foo,1000)
reinsert
reinsert( +u) reinsert("prog.p2")
reload( +s) reload("myfile")
reload( +s, +l) reload("myfile", [<>("aa","bb")])
remove_implicit( +s1, +s2) remove_implicit("sys","outml")
remove_sentence_terminator(+c) remove_sentence_terminator(";")
repeat
reset_chrono
reset_cpu_time
retract( +t1, ?t2) retract(father(john,X),Y)
retract( +t) retract(brother(X,Y):- true)
retractall( @T) retractall(father(john,X))
rule( +t1, ?t2) rule(father(john,x),Y)
rule( +n, +t1, ?t2) rule(r,father(john,X),Y)
rule( +n, +i, +t1, ?t2) rule(5,father,T,Q)
rule_nb( +i/+n, ?v) rule_nb(foo/2,X)
S
save( +l, +s) save(["aa","bb"], "myfile")
save_state( +s) save_state("myfile")
see( +f) see(filei)
seeing( +f) seeing(filei)
seen
send_double( +n, +d) send_double(5,12d0)
send_integer( +n1, +n2) send_integer(5,1000)
send_real( +n, +r) send_real(5,3.14e0)
send_string( +n, +s) send_string(5,"error")
©PrologIA
Aociation Prolog
©PrologIA
Aociation Prolog
B - 10 Reference manual HERITAGE
TUVW
tab( +n) tab(10)
tan( +m) val(tan(-3.14e0),X)
tassign( +i, @t) tassign(aa,term(3,[1,X],tab[5],"str"))
tassign( +i[+n], @t) tassign(tab[1],123)
tell( +f) tell(file)
telling( +f) telling(file)
term_cmp( @t1, @t2, ?n) term_cmp(1,"foo",X)
term_cmpv(@t1, @t2, ?n) term_cmpv(1,"foo",X)
term_vars(@t1, ?l) term_vars(one(2.X,Y,Y),L)
throw( @t) throw(12)
time( ?n)
time( ?n1, ?n2, ?n3)
told
trace
trace( +s) trace("debug.dat")
true
trunc( +m) val(trunc(+3.8e0),3)
truncate( +m) val(truncate(+3.8e0),3)
tuple( @t) tuple(ff(a))
tval( @t1, ?t2) tval(1+2*3+pile[1],X)
unify_tlv( -v, ?t2) unify_tlv(V, 22)
unify_with_occurs_check( ?t1, ?t2) unify_with_occurs_check(X,1)
val( @t1, ?t 2) val(3,3)
var( @t) var(X)
var_time( -v, ?n) var_time(X,Y)
version( ?n) version(X)
week( ?n, ?s) week(0,"sunday")
write( @t) write("Hello world!")
write( +h, @t) write(alias1,"Hello world!")
write_canonical( @t) write_canonical ("Hello world!")
write_canonical( +h, @t) write_canonical (alias1,"Hello world!")
write_term( @t , +l) write_term("foo",[quoted(:true)])
write_term( +h, @t , +l) write_term (alias1,"f",[quoted(:false)])
writeq( @t) writeq(foo(1,2,3)
writeq( +h, @t) writeq(alias1,foo(1,2,3)
Autres
\( +n) val(\(4),X)
~( +n) val(~(4),X)
+m1 * +m2 val(-3.14e0 * 0.5e,X)
+m1 + +m2 val(1+2,X)
©PrologIA
Aociation Prolog
©PrologIA
Aociation Prolog
B - 12 Reference manual HERITAGE
©PrologIA
Aociation Prolog
HERITAGE
Appendix C.
Some examples of Prolog II+
programs
C.1 Grammars
C.2 Formal derivation
C.3 Mutants
C.4 Database consultation by evaluating a logic formula
C.5 A brain teaser
C.6 Construction of a path
C.7 Infinite trees
C.1 Grammars
Describing the problem
<primary>
(3) ::= <number>
(4) ::= ( <expression> )
<rest of sum>
(5) ::= <op add> <product> <rest of sum>
(6) ::= <empty>
<rest of product>
(7) ::= <op mul> <primary> <rest of product>
(8) ::= <empty>
© PrologIA
Aociation Prolog
C - 2 Reference Manual HERITAGE
<op add>
(10) ::= +
(11) ::= -
<number>
(12) ::= 0
(13) ::= 1
(14) ::= 2
(...)
How can Prolog be used to construct this analyzer? Let's suppose that the input
string is a graph: the first peak in the graph is placed at the beginning of the
sentence, and a peak is added at the end of each word in the sentence. Thus, each
word labels the arc joining the two nodes on each side of it. In our example, we
obtain:
2 * 3 + 6
• -----> • -----> • -----> • -----> • -----> •
a b c d e f
<expr>
|
|
<sum>
__/ \__
___/ \__
/ \
<prod> <r-o-s->
/ \ / | \
/ \ / | \
<prim> <r-o-p> <op-a> <prod> <r-o-s>
| / | \ | / \ |
| / | \ | / \ |
<nb> <op-m> <prim> <r-o-p> | <prim> <r-o-p> |
| | | | | | | |
| | | | | | | |
| | <nb> <empty> | <nb> <empty> <empty>
| | | | |
| | | | |
2 * 3 + 6
Figure C.1
© PrologIA
Aociation Prolog
The rules of the grammar can therefore be seen as instructions which allow this
graph to be completed. A rule such as (21) is to be interpreted as: "if there is an arc
labeled "9" between node x and node y of the graph, add an arc labeled "number"
between x and y".
A rule such as (1) gives the following: "if there is an arc labeled product between
nodes x and y and an arc labeled rest of sum between nodes y and z, add an arc
labeled expression between x and z". To analyze a sentence using these
conventions, we search for an arc labeled expression between the first and the last
peak of the associated graph. If we succeed, the sentence will be accepted, if not it
will be rejected.
Let's now write the corresponding Prolog program: each non-terminal symbol N in
the grammar is associated with a predicate of the same name N(<x,y>); which will
be interpreted as: "there is an arc labeled N between the nodes x and y of the graph".
Going back to the graph, it can be represented simply by the list of words
constituting the input sentence:
• peak a
/ \
2 • peak b
/ \
* • peak c
/ \
3 • peak d
/ \
+ • peak e
/ \
6 nil peak f
Each peak in the graph corresponds to a subtree of the tree in figure C.1. If we use
this representation for N(<x,y>), x represents the input string before the execution
of N, and y represents the string remaining to be analysed after N has been
executed. Moreover, this representation makes it possible to express terminal rules
such as (12) and (13) etc, in the form:
number(<x,y>) -> word(n,<x,y>) integer(n) ;
and the predefined rule integer. Finally, recognizing whether or not a sentence
belongs to the language defined by our grammar is equivalent to executing:
expression(<p,nil>)
© PrologIA
Aociation Prolog
C - 4 Reference Manual HERITAGE
We have now reached the point where we know how to translate a grammar into a
set of rules telling us whether or not a sentence belongs to a language. We can go
further, and complete the set of relations to give the tree constructed by parsing ,
e.g. for the previous example:
add
/ \
mul 6
/ \
2 3
To do this, we only need to add an argument to the predicates associated with the
non-terminals of the grammar. This argument will express the way in which a
sentence is constructed from sub-sentences. We therefore obtain:
number(n,<x,y>) -> word(n,<x,y>) ;
primary(n,<x,y>) -> number(n,<x,y>) ;
where e represents the tree associated with the expression analyzed. Here is the
complete program:
" grammar of expressions "
sum(e,<x,y>) ->
product(p,<x,z>) rest_of_sum(p,e,<z,y>) ;
product(p,<x,y>) ->
primary(f,<x,z>) rest_of_product(f,p,<z,y>) ;
primary(n,<x,y>) ->
word(n,<x,y>) integer(n) ;
primary(e,<x,y>) ->
word("(",<x,z>)
expression(e,<z,t>)
word(")",<t,y>) ;
rest_of_sum(p,e,<x,y>) ->
word(o,<x,z>)
op_add(o,o_a)
product(p',<z,t>)
rest_of_sum(<o_a,p,p'>,e,<t,y>) ;
rest_of_sum(e,e,<x,x>) -> ;
rest_of_product(f,p,<x,y>) ->
word(o,<x,z>)
op_mul(o,o_m)
primary(f',<z,t>)
rest_of_product(<o_m,f,f'>,p,<t,y>) ;
rest_of_product(f,f,<x,x>) -> ;
© PrologIA
Aociation Prolog
word(a,<a.x,x>) -> ;
op_add("+",add) -> ;
op_add("-",sub) -> ;
op_mul("*",mul) -> ;
run ->
outm("the expression ")
read(p)
analyze(p,e)
val(e,f)
outm(" evaluates to ")
outl(f);
We use the predicate read which reads a sentence ending with "." and transforms it
into a list of words. For example:
>read(p) ;
12+(23-4)*5+210-34-43.
{ p=12."+"."(".23."-".4.")"."*".5."+".210."-".34."-".
43.nil}
The predicate expression constructs a syntax tree from the sentence which it has
read (if it belongs to the language). We can now communicate this tree to the
predefined rule val which calculates and prints out its value. All this is done by:
>run;
The expression 12+(23-4)*5+210-34-43.
evaluates to 240
© PrologIA
Aociation Prolog
C - 6 Reference Manual HERITAGE
sum(e,<x,y>) ->
product(p,<x,z>) rest_of_sum(p,e,<z,y>);
product(p,<x,y>) ->
factor(f,<x,z>) rest_of_product(f,p,<z,y>);
factor(f,<x,y>) ->
primary(p,<x,z>) rest_of_factor(p,f,<z,y>);
rest_of_sum(p,e,<x,y>) ->
word(o,<x,z>)
op_add(o,o_a)
product(p',<z,t>)
rest_of_sum(<o_a,p,p'>,e,<t,y>);
rest_of_sum(e,e,<x,x>) ->;
rest_of_product(f,p,<x,y>) ->
word(o,<x,z>)
op_mul(o,o_m)
factor(f',<z,t>)
rest_of_product(<o_m,f,f'>,p,<t,y>);
rest_of_product(f,f,<x,x>) ->;
rest_of_factor(p,f,<x,y>) ->
word(o,<x,z>)
op_exp(o,o_e)
primary(p',<z,t>)
rest_of_factor(<o_e,p,p'>,f,<t,y>);
rest_of_factor(f,f,<x,x>) ->;
word(a,<a.x,x>) ->;
op_add("+",plus) ->;
op_add("-",minus) ->;
op_mul("*",mult) ->;
op_exp("E",exp) ->;
op_un("-",minus) ->;
op_un(sin,sin) ->;
op_un(cos,cos) ->;
derivative(x,x,1) -> ;
derivative(n,x,0) -> integer(n) ;
derivative(plus(u,v),x,plus(u',v')) ->
derivative(u,x,u')
derivative(v,x,v');
© PrologIA
Aociation Prolog
derivative(minus(u,v),x,minus(u',v')) ->
derivative(u,x,u')
derivative(v,x,v');
derivative(mult(u,v),x,plus(mult(u,v'),mult(v,u'))) ->
derivative(u,x,u')
derivative(v,x,v');
derivative(exp(u,n),x,mult(n,mult(u',exp(u,minus(n,1))))) ->
derivative(u,x,u');
derivative(minus(u),x,minus(u')) -> derivative(u,x,u');
derivative(sin(u),x,mult(u',cos(u))) -> derivative(u,x,u');
derivative(cos(u),x,minus(mult(u',sin(u)))) ->
derivative(u,x,u');
simplify(<o_b,x,y>,u) ->
simplify(x,x')
simplify(y,y')
simp(o_b,x',y',u);
simplify(<o_u,x>,u) ->
simplify(x,x')
simp(o_u,x',u);
simplify(x,x) ;
simp(plus,0,x,x) -> ;
simp(plus,x,0,x) -> ;
simp(minus,x,0,x) -> ;
simp(minus,0,x,y) -> simp(minus,x,y);
simp(mult,0,x,0) -> ;
simp(mult,x,0,0) -> ;
simp(mult,1,x,x) -> ;
simp(mult,x,1,x) -> ;
simp(exp,x,0,1) -> ;
simp(mult,minus(x),y,u) ->
simp(mult,x,y,v)
simp(minus,v,u);
simp(mult,x,minus(y),u) ->
simp(mult,x,y,v)
simp(minus,v,u);
simp(exp,x,1,x) -> ;
simp(exp,0,x,0) -> ;
simp(exp,1,x,1) -> ;
simp(o_b,x,y,u) ->
dif(o_b,exp)
integer(x)
integer(y)
evalCst(<o_b,x,y>,u);
simp(o_b,x,<o_b,u,v>,t) -> simp(o_b,x,u,z) simp(o_b,z,v,t);
simp(o_b,x,y,<o_b,x,y>) ->;
simp(minus,0,0) -> ;
simp(minus,minus(x),x) -> ;
simp(sin,0,0) -> ;
simp(cos,0,1) -> ;
simp(o_u,x,<o_u,x>) -> ;
© PrologIA
Aociation Prolog
C - 8 Reference Manual HERITAGE
"reading"
"writing"
write(<o_b,x,y>) ->
!
op_bin(o,o_b)
outm("(")
write(x)
outm(o)
write(y)
outm(")");
write(minus(x)) -> ! outm("-") write(x);
write(<o_u,x>) -> ! op_un(o,o_u) out(o) write(x);
write(x) -> string(x) ! outm(x) ;
write(x) -> out(x);
run ->
outm("the expression ")
read(p)
analyze(p,e)
derivative(e,"x",e')
simplify(e',f)
outm("has for derivative ")
write(f)
line
!;
Next we define the differentiation relation derivative(f,x,f') which means: f' is the
derivative of f with respect to x.
© PrologIA
Aociation Prolog
Since this relation gives one rule for each operator or function symbol, it can be
expressed quite naturally. For example, the derivative of the preceding expression is
given by:
> read(p) expression(e, <p, nil>) derivee(e, "x", e');
3*x2^+6*x+5.
...,
e'=plus(plus(plus(mult(3,mult(2,mult(1,exp("x",minus(2,1)))))
,
mult(exp("x",2),0)),plus(mult(6,1),mult("x",0))),0)}
Clearly, the result is still far from simple! We have therefore added a (very
incomplete) simplification program, which produces a more condensed result. This
is accomplished by the predicate run. Here is an example of its use:
>run;
the expression 3*x^2+6*x+5.
has the derivative ((6*x)+6)
>run;
the expression cos(-3*x^2+2).
has the derivative ((6*x)*sin(-(3*(x^2))+2))
C.3 Mutants
In this example we are breeding mutants, hybrid offspring of animal names. The
animals are known by their names (in French), represented as character strings.
Two animals give birth to a mutant if the end of the name of the first animal is
identical to the beginning of the name of the second.The interesting aspect of this
program is that the same relation append is used in two different ways: firstly to
join together two lists, and secondly to break up a list into two sublists.
On the next page are the results produced by the following set of animals: alligator,
tortue, caribou, ours, cheval, vache, lapin, pintade, hibou, bouquetin and chèvre.
>pretty_mutant;
alligatortue
caribours
caribouquetin
chevalligator
chevalapin
vacheval
vachevre
lapintade
hibours
hibouquetin
>
© PrologIA
Aociation Prolog
C - 10 Reference Manual HERITAGE
mutant(z) ->
animal(x)
animal(y)
append(a,b,x)
dif(b,nil)
append(b,c,y)
dif(c,nil)
append(x,c,z);
append(nil,y,y) ->;
append(e.x,y,e.z) -> append(x,y,z);
animal("a"."l"."l"."i"."g"."a"."t"."o"."r".nil) ->;
animal("t"."o"."r"."t"."u"."e".nil) ->;
animal("c"."a"."r"."i"."b"."o"."u".nil) ->;
animal("o"."u"."r"."s".nil) ->;
animal("c"."h"."e"."v"."a"."l".nil) ->;
animal("v"."a"."c"."h"."e".nil) ->;
animal("l"."a"."p"."i"."n".nil) ->;
animal("p"."i"."n"."t"."a"."d"."e".nil) ->;
animal("h"."i"."b"."o"."u".nil) ->;
animal("b"."o"."u"."q"."u"."e"."t"."i"."n".nil) ->;
animal("c"."h"."e"."v"."r"."e".nil) ->;
which indicates that the individual named Candide is 20 years old, that he was born
in Constantinople and that he doesn't wear glasses. In addition, elementary relations
(atomic formulas) can be defined from this data.
The program evaluates a logical formula which is made up of atomic formulas, the
connectors "and" and "or" and existential and universal quantifiers which apply to
typed variables. A typed variable is one that has a specific domain of values. The
type of question we can ask is:
"what are the values of x belonging to the domain D for which the property P
is true?"
© PrologIA
Aociation Prolog
For example, the question: (1) What city does mimosa live in ? is translated by the
formula:
element(x,set(x,city,lives_in(mimosa,x)))) ,
in the same way: (2) Does olive wear glasses ? is translated by:
element(x,set(x,boolean,glasses(olive,x))))
and finally: (3) What are the cities having at least one inhabitant less than 20 years
old who wears glasses ? corresponds to:
element(x,set(x,city,exist(y,name,and(lives_in(y,x),
and(years_old(y,a),
and(inferior(a,20),
glasses(y,yes)))))))).
These three questions have already been entered and can now be activated by
respond_to_all which writes the question in natural language followed by the
answers. The result is as follows (the answers computed by the machine are
preceded by " -->"):
>respond_to_all;
which city does mimosa live in ?
--> aspres_sur_buech
does olive wear glasses?
--> no
what are the cities having at least one inhabitant at least
20 years old who wears glasses ?
--> aspres_sur_buech
--> severac_le_chateau
individu(candide,20,constantinople,no) -> ;
individu(cunegonde,20,constantinople,yes) -> ;
individu(gontran,94,aspres_sur_buech,no) -> ;
individu(casimir,2,severac_le_chateau,yes) -> ;
individu(clementine,1,cucugnan,no) -> ;
individu(popeye,99,aspres_sur_buech,yes) -> ;
individu(olive,99,aspres_sur_buech,no) -> ;
individu(mimosa,1,aspres_sur_buech,yes) -> ;
individu(bip,15,pampelune,no) -> ;
individu(ignace,114,loyola,yes) -> ;
individu(balthazar,87,jerusalem,no) -> ;
individu(gaspard,96,smyrna,yes) -> ;
individu(melchior,34,kartoum,no) -> ;
© PrologIA
Aociation Prolog
C - 12 Reference Manual HERITAGE
name(candide) -> ;
name(cunegonde) -> ;
name(gontran) -> ;
name(casimir) -> ;
name(clementine) -> ;
name(popeye) -> ;
name(olive) -> ;
name(mimosa) -> ;
name(bip) -> ;
name(ignace) -> ;
name(balthazar) -> ;
name(gaspard) -> ;
name(melchior) -> ;
age(20) -> ;
age(94) -> ;
age(2) -> ;
age(1) -> ;
age(99) -> ;
age(15) -> ;
age(114) -> ;
age(87) -> ;
age(96) -> ;
age(34) -> ;
city(constantinople) -> ;
city(aspres_sur_buech) -> ;
city(severac_le_chateau) -> ;
city(cucugnan) -> ;
city(pampelune) -> ;
city(loyola) -> ;
city(jerusalem) -> ;
city(smyrna) -> ;
city(kartoum) -> ;
boolean(yes) -> ;
boolean(no) -> ;
atomic(lives_in(x,y)) -> ;
atomic(years_old(x,y)) -> ;
atomic(glasses(x,y)) -> ;
atomic(older_than(x,y)) -> ;
atomic(inferior(x,y)) -> ;
atomic(different(x,y)) -> ;
older_than(x,y) ->
individu(x,a,v,b)
individu(y,a',v',b')
val(inf(a',a),1);
© PrologIA
Aociation Prolog
true(p) ->
atomic(p)
p;
true(no(p)) ->
no(true(p));
true(and(p,q)) ->
true(p)
true(q);
true(or(p,q)) ->
true(p) ;
true(or(p,q)) ->
true(q) ;
true(exist(x,t,p)) ->
type(x,t)
true(p);
true(all(x,t,p)) ->
no(true(exist(x,t,no(p))));
no(p) ->
p
!
fail;
no(p) -> ;
respond_to_all ->
question(i,q)
element(y,q)
line
outm("---> ")
out(y)
line;
element(x,set(x,t,p)) ->
type(x,t)
true(p);
question(1,set(x,city,lives_in(mimosa,x))) ->
outm("(1) what city does mimosa live in ?");
question(2,set(x,boolean,glasses(olive,x))) ->
outm("(2) does olive wear glasses ?");
© PrologIA
Aociation Prolog
C - 14 Reference Manual HERITAGE
question(3,set(x,city,exist(y,name,and(lives_in(y,x),
and(years_old(y,a),and(inferior(a,20),glasses(y,yes))))))) ->
outm("(3) what are the cities having at least one
inhabitant")
outm("at least 20 years of age who wears glasses ?");
C.5 A brain-teaser
In this example, we have designed a program which solves a well-known
cryptarithmetic problem: how to replace each of the letters s,e,n,d,m,o,r,y by a
different digit, so that:
SEND
+ MORE
------
MONEY
9567
+1085
-----
10652
{}
solution(s.e.n.d.m.o.r.y) ->
different(s.e.n.d.m.o.r.y.nil)
sum(r1,0,0,m,0)
sum(r2,s,m,o,r1)
sum(r3,e,o,n,r2)
sum(r4,n,r,e,r3)
sum( 0,d,e,y,r4);
© PrologIA
Aociation Prolog
digit(0) -> ;
digit(1) -> ;
digit(2) -> ;
digit(3) -> ;
digit(4) -> ;
digit(5) -> ;
digit(6) -> ;
digit(7) -> ;
digit(8) -> ;
digit(9) -> ;
remainder(1) -> ;
remainder(0) -> ;
different(nil) -> ;
different(x.l) -> out_of(x,l) different(l);
out_of(x,nil) -> ;
out_of(x,a.l) -> dif(x,a) out_of(x,l);
pretty_output(s.e.n.d.m.o.r.y) ->
outm(" ") out(s) out(e) out(n) out(d) line
outm("+") out(m) out(o) out(r) out(e) line
outm("-----") line
out(m) out(o) out(n) out(e) out(y) line;
© PrologIA
Aociation Prolog
C - 16 Reference Manual HERITAGE
{l=LosAngeles.Marseille.nil}
{l=LosAngeles.Marseille.London.nil}
{l=LosAngeles.London.nil}
{l=LosAngeles.London.Marseille.nil}
>
town(Marseille) -> ;
town(London) -> ;
town(LosAngeles) -> ;
good_list'(nil) -> ;
good_list'(x.l) -> out_of(x,l) good_list(l);
out_of'(x,nil) -> ;
out_of'(x,x'.l) -> dif(x,x') out_of(x,l);
© PrologIA
Aociation Prolog
x = final
/ \
aa bb
| |
y z
y = non_final
/ \
aa bb
| |
z x
z = non_final
/ \
aa bb
| |
x y
The term fail causes backtracking, to avoid the final print-out. Here is the complete
program behind all this. It must be noted that the goals accepts(s,x) and rejects(s,x)
are achieved in a completely deterministic way. This is why, to obtain the minimal
automaton, it is not necessary to have Peano_integer(n) as the first goal in the
sequence of preceding goals (to be executed).
"Acceptance"
final_state(<final,aa(s1),bb(s2)>) -> ;
non_final_state(<non_final,aa(s1),bb(s2)>) -> ;
arrow(<f,aa(s1),bb(s2)>,"a",s1) -> ;
arrow(<f,aa(s1),bb(s2)>,"b",s2) -> ;
automata_of_size(nil,0,l) -> ;
automata_of_size(s.l,n,l') ->
element_of(s,l')
automata_of_size(l,n,l');
automata_of_size(s.l,suc(n),l') ->
not_element_of(s,l')
arrow(s,"a",s1)
arrow(s,"b",s2)
automata_of_size(s1.s2.l,n,s.l');
element_of(s,s.l) -> ;
element_of(s,s'.l) -> dif(s,s') element_of(s,l);
not_element_of(s,nil) -> ;
not_element_of(s,s'.l) -> dif(s,s') not_element_of(s,l);
© PrologIA
Aociation Prolog
C - 18 Reference Manual HERITAGE
Peano_integer(0) -> ;
Peano_integer(suc(n)) -> Peano_integer(n);
© PrologIA
Aociation Prolog
HERITAGE
Appendix D
Adding predefined rules
(parasite method)
This chapter explains how to add new predefined rules to the standard set, and
describes the interface procedures. The method described is the only one working
in 16 bits mode on PC. Otherwise, a simpler method using descriptors can also be
used for the compiler (see Chapter 7 of the Reference Manual).
The external procedure may either cause backtracking, send back an error which
will then be processed by the block mechanism, or display a message defined by the
user.
The user module prouser acts as a link between Prolog and user routines written in
C. The user module fprouser links Prolog and user routines written in Fortran. It
is thus possible to use simultanesously predefined rules written in both languages.
The corresponding source files are included in the distribution volume.
Remember that there are two ways of calling an external function defined in C from
Prolog:
1. Using the descriptor method (see Reference Manual section 7.6). This is
direct calling, in which the Prolog calling rule is automatically generated.
2. Using a parasite via a linking procedure defined in the user module supplied
in the kit.
When Prolog is started without specifying the initial state, the standard initial state
(file initial.po) is loaded. To add new predefined rules written in another language,
using the parasite method described here, you must:
1. Define Prolog's call to these rules in Prolog, and include it in an initial state
(in the descriptor method this step is performed automatically).
©PrologIA
Aociation Prolog
D-2 Reference Manual HERITAGE
switch(nb) {
...
case 300:
prouser.c my_rule(...);
break;
...}
Let's use an example to explain the method. The first step when adding a new
predefined rule, is to decide which module to define it in. We could use a module
specially reserved for this purpose, called "Interface" for example. In the example
below, we define a new predefined rule in just such a module.
This can be done either in a seperate source module, or directly on the Prolog
command line. You can save this module using the command:
save( ["Interface"], "Interface.mo");
This module can now be reloaded in any initial state, using the command load.
You can also directly create a new initial state using the command:
exit("new_state.po");.
In what follows, we will assume that a new initial state has been created.
new_state.po is a file containing an initial state enlarged by the calling rule
compiled by Prolog.
©PrologIA
Aociation Prolog
- Up-date the prouser user module (see Section D.3.) and compile it.
- Re-link the new modules with the modules constituting Prolog (see section 2.7
of the User's Manual for the exact commands to be used on your machine).
The new prolog Machine can now be used, with the initial state enlarged by the new
predefined rule.
When you call an external procedure from Prolog, the rule used has to satisfy the
following conditions:
- the rule head must be an identifier followed by arguments which are free
variables
- the rule body must contain a parasite represented by a number preceded by /?.
The number selects the relevant external procedure (see the user_rule procedure in
the prouser.c module). For each number there is a call to a corresponding external
procedure in the C function user_rule and the Fortran function fuserrule.
Please note
Numbers less than 250 are reserved for the system (this is not checked). Numbers
greater than 250 are available to the user. We recommend using numbers between
250 and 9999 for C routines whose call is in the prouser module, numbers between
10000 and 20000 for Fortran routines (or other Fortran type languages) whose call
is in the fprouser module, and numbers greater than 20000 for 16 bits mode
routines for DOS/WINDOWS3 whose call is in the prowuser module.
An external program can only be called from Prolog using the parasite method, if
the associated number and call command have been added to the user_rule
procedure in the prouser C module (or the fuserrule procedure in the fprouser
Fortran module).
©PrologIA
Aociation Prolog
D-4 Reference Manual HERITAGE
*err = FALSE;
*err_nb = 0;
switch (class(num))
{
case FORTRAN_FUNCTION:
fuserrule_(&num, err, err_nb);
break;
case REAL_MODE_FUNCTION:
real_mode_user_rule(num, err, err_nb);
break;
case NORMAL_FUNCTION:
switch (nb)
{
case 201:
find_pattern(err, err_nb);
break;
...
/* add procedure calls here */
default:
*err = TRUE;
*err_nb = 500;
}
}
}
Depending on the nature of the external program, you can either insert it directly
into the prouser module, or write it in a separate file.
If you have written the external rules in modules other than prouser or fprouser,
you will have to compile these modules and add their names to the prolink linking
program.
As supplied to you, the prouser module establishes the call links between the
Prolog compiler and the external procedure find_pattern. This is given as an
example of how to write external rules.
©PrologIA
Aociation Prolog
Important note:
From version 4.1 onwards, the err parameter has no meaning, and Prolog ignores it.
However bottom-up compatibility between the versions is still guaranteed.
If err_nb is set to a value greater than zero, a command equivalent to the Prolog
command block_exit(err_nb) is executed. To associate a message with it, add the
corresponding line in the err.txt file, in the following form
Number Text_describing_the_error
The predefined rule ms_err gives access to the message associated with a given
number in the Interface world. Error numbers less than 1000 are reserved for
Prolog, and numbers greater than 1000 are available to the user. Below is a list of
some of the error messages concerning external modules:
500 ERROR IN USER PREDEFINED RULE
501 WRONG ARGUMENT NB IN USER MODULE
502 VALUE OUT OF RANGE IN USER MODULE
503 STRING TOO LONG IN USER MODULE
520 GET-TERM : VALUE ARRAY NOT BIG ENOUGH TO CODE THE TERM
521 GET-TERM : STRING ARRAY NOT BIG ENOUGH TO CODE THE TERM
522 GET-TERM : REAL ARRAY NOT BIG ENOUGH TO CODE THE TERM
523 PUT-TERM : VALUE ARRAY INDEX OUT OF RANGE
Indicates that a value outside the possible indexes for the val_tab array corresponds
to a 'T' or 'D' type tag .
524 PUT-TERM : STRING ARRAY INDEX OUT OF RANGE
Indicates that a value outside the possible indexes for the string array corresponds
to an 'S' type tag .
525 PUT-TERM : REAL ARRAY INDEX OUT OF RANGE
Indicates that a value outside the possible indexes for the real array corresponds to
an 'R' type tag .
526 PUT-TERM : WRONG TUPLE CODING
A tuple index refers to a sequence whose first element is not an integer.
527 PUT-TERM : INVALID TYPE IN TAG ARRAY
528 PUT-TERM : PROLOG ARGUMENT IS NOT A FREE VARIABLE
Backtracking is caused when you return to Prolog with err_nb set to a negative
integer.
©PrologIA
Aociation Prolog
D-6 Reference Manual HERITAGE
©PrologIA
Aociation Prolog
HERITAGE
Appendix E
Prolog II+ characters
E.1. Presentation
E.2. ISO set: advantages and disadvantages
E.3. Host set: advantages and disadvantages
E.4 Remarks
E.5 Conventions
E.1. Presentation
Two sets of characters can be used in Prolog II+ :
The set is chosen at the start of the Prolog session, and this choice remains valid
until the end of the session (see User's Manual section 2.3).
There are two sets of characters, and therefore there are two internal coding modes
for these characters:
• One mode in which whatever host system is used, the internal coding is the same:
ISO 8859-1.
• A second mode in which the internal coding used is that of the host system.
To have two internal coding modes we must also have two types of binary file:
• Files than contain strings encoded with with host system characters.
When saving is performed, the coding chosen for the session is memorized in the
file that is created: a warning message will be displayed when a file is loaded if the
coding memorized in the binary file is not the same as the coding chosen for the
current session.
©PrologIA
Aociation Prolog
E - 2 Reference Manual HERITAGE
In addition, in ISO mode, since Prolog handles data (characters) which may not
exist on the host machine, these data must be associated with an external
representation1 (character sequence) in order to be displayed. There are two modes
for representation of accented characters not belongning to the host set:
This mode is chosen at the start of the Prolog session, and remains valid throughout
the session (see User's Manual section 2.3).
From now on, we will distinguish between an internal representation (binary string),
which is a value in memory, and display of this data (print string), i.e. its
representation in character form on an input or output channel.
The disadvantage of using ISO with an extremely open language such as Prolog
which performs many data transfer and sharing operations, is the difference in
internal coding of certain data (strings) between Prolog and the external
environment. This means that a transformation has to be performed for each
external communication. In fact, the user does not always need to do this,
depending on the operation that will be performed on these data. The data may be
required:
• in ISO code.
For instance, string-handling procedures that don't need to know their meaning,
such as find_pattern which compares them, or substring which splits them,
operate independently of any particular code and thus do not need these
transformations. However, procedures that call the host system will need them.
1 The display function is an external representation (outside Prolog) and must therefore be
encoded by the host system. Prolog only handles data, i.e. the ISO codes. It is the input/output
that makes the transformation between graphic representation and internal coding.
©PrologIA
Aociation Prolog
To sum up, this set is satisfactory provided that procedures to transform strings
between the ISO coding and the host coding are available, and that the type of
coding assumed in Prolog communication procedures is known.
The disadvantage of this choice is that the ASCII set is relatively restricted, and that
extended characters are not standardized on all machines, thus making the programs
non portable.
E.4. Remarks
•If the same coding is used as that of the host machine, the data element and its
representation merge, whereas if ISO coding is used the data element and its
representation may be different and the external representation may take up more
bytes in memory than the data element.
•The first half of the ISO code table is identical to the US ASCII table. If a Prolog
program does not contain extended characters, there is no point in performing
transformations between ISO and host sets.
•If the user wishes to use characters not existing on the host machine, not only must
the ISO mode be chosen, but also, for communications purposes they must be either
be transmitted in ISO or in printable form (print string).
•The ISO mode without accent_escape is like the host mode in that it reduces the
number of characters that can create ambiguity if they are preceded by the '\'
character. This mode can therefore be used in programs that contain numerous '\'
characters, to avoid having to mask them (useful for Edinburgh programs which
frequently handle identifiers or graphic_symbol contain '\' characters).
The PRO_BIND function, used to create shared data zones dynamically, references
data which must be encoded in ISO. However its first argument which is the Prolog
name for the data zone is a host string.
©PrologIA
Aociation Prolog
E - 4 Reference Manual HERITAGE
For data transfers between Prolog and external languages or vice versa, the
following conventions apply:
get_O_string, put_O_string:
have the same arguments as get_string and put_string respectively, and
function in the same way, but send and receive host strings in printable form.
bin_str_iso_to_host(source,dest)2
bin_str_host_to_iso(source,dest)2
convert an ISO string into a host string and vice versa, by assimilating strings
to data (binary string). The lengths are conserved, there may be non printable
characters and the characters in the input string not existing in the output set
are replaced by '?'.
print_str_iso_to_host(source,dest)2
print_str_host_to_iso(source,dest)2
convert an ISO string into a host string and vice versa, when the host string is
the representation (printable string) of the ISO string. The lengths of the two
strings is not necessarily the same, and a character can be represented by a
four character string.
2source is the address of a memory zone containing the reference string terminated by the null
character. dest is the address of the memory zone into which Prolog will copy the resulting
string. It is up to the user to reserve the necessary space.
©PrologIA
Aociation Prolog
HERITAGE
Appendix F
Table ISO 8859-1
0 1 2 3 4 5 6 7
SP 0 @ P p
0 `
1 ! 1 A Q a q
2 " 2 B R b r
3 # 3 C S c s
4 $ 4 D T d t
5 % 5 E U e u
6 & 6 F V f v
7 ' 7 G W g w
8 ( 8 H X h x
9 ) 9 I Y i y
A * : J Z j z
B + ; K [ k {
C , < L \ l |
D - = M ] m }
E . > N ^ n ~
F / ? O _ o
8 9 A B C D E F
NBSP ° À –
D à
0
1 ¡ ± ’
A Ñ á ñ
2 ¢ 2 Â Ò â ò
3 £ 3 Ã Ó ã ó
4 ´ Ä Ô ä ô
5 µ °
A Õ °a õ
Y-
6 ¶ Æ Ö æ ö
7 § · Ç ç ÷
8 ¨ , È Ø è ø
9 ı É Ù é ù
©
A ^
ª º E U’ ê ú
B » Ë ^ ë û
« U
C ¬ 1/4 Ì Ü `i ü
D SHY 1/2 I’ Y’ í y’
^
E ® 3/4 I î
F – ¿ Ï ß ï ÿ
©PrologIA
Aociation Prolog
F - 2 Reference Manual HERITAGE
©PrologIA
Aociation Prolog
HERITAGE
PROLOG II+
Windows
USER'S MANUAL
© PrologIA
Aociation Prolog
2 Windows 3 User's Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 3
Contents
Contents.............................................................................................................3
Foreword............................................................................................................7
© PrologIA
Aociation Prolog
4 Windows 3 User's Manual HERITAGE
5. Graphics Primitives............................................................................ U 5 - 1
5.1 Description of the graphics system .......................................... U 5 - 2
5.1.1 Events..........................................................................U 5 - 2
5.1.2 Graphics objects..........................................................U 5 - 2
5.1.3 Configuration of Prolog II+ graphics at start-up......... U 5 - 5
5.1.4 Conventions used in this chapter ................................. U 5 - 6
5.2 Window management primitives .............................................. U 5 - 7
5.2.1 Creation and deletion of a window...............................U 5 - 7
5.2.2 Configuration and manipulation of a window.............. U 5 - 9
5.2.3 Refreshing of graphics units......................................U 5 - 12
5.3 Elementary primitives for management of objects attached to ..............
a window................................................................................ U 5 - 12
5.3.1 Creation and deletion of objects................................. U 5 - 12
5.3.2 Configuration of objects............................................U 5 - 16
5.3.3 Event management.....................................................U 5 - 19
© PrologIA
Aociation Prolog
HERITAGE Introduction 5
© PrologIA
Aociation Prolog
6 Windows 3 User's Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE Introduction 7
Foreword
- the Reference Manual gives a precise description of the language and its uses,
which applies to all implementations of Prolog II+.
The user's manual explains how to carry out, on your machine, the functions
described in the reference manual.
The second chapter concerns Prolog start-up, saved state management and the file
name structure.
The third chapter describes the features which are specific to this particular version,
i.e. everything that has been added or removed in comparison with the basic version,
and also the boundary values for constants.
The fourth chapter describes how to communicate with an application, using DDE
protocol.
The last chapter describes the library of graphics primitives, which is specific to
each implementation.
© PrologIA
Aociation Prolog
8 Windows 3 User's Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
1. Installation Guide
1.0 Foreword
1.1 Necessary equipment and software
1.2 Contents of the installation kit
1.3 Installation procedure
1.4 Modification of the execution environment
This chapter describes how to install the Prolog II+ compiler as an application in
the Windows environment. We recommend you read the whole chapter before
installing the system.
1.0 Foreword
Prolog II+ for Windows is now a true 32 bit application running on Windows NT,
Windows 3.1 extended with the Win32s kit, and Windows 95.
If you are using Windows 3, Prolog II+ still makes it possible to add 16 bit
extensions in C, which are now located in a separate DLL, and therefore only
require the standard 16 bit SDK.
If you are using 32 bit code you can use all the different resources for adding
Prolog extensions. The recommended development tool is "MicroSoft Visual C++
version 2.xx". You can also use any other compatible SDK.
© PrologIA
Aociation Prolog
U1-2 Windows User's Manual HERITAGE
Only Windows 3 users can add extensions in 16 bit code, since Windows NT and
Windows 95 do not recognize the extension DLL. The only method available here
is the parasite method described in the appendix. The extension code is placed in a
DLL that Prolog loads automatically. To construct this DLL we provide a static
library containing the communication functions (get_integer etc.). It is compiled
with the "CL version 8.00" of the "MicroSoft Visual C++ version 1". You can use
any other compatible SDK.
This DLL has access to the whole of the Windows 16 bit API.
To create and distribute applications, you must order the following kit:
Run Time Prolog II+ for Windows. For Windows 3, you must also redistribute
the Win32s kit.
If you are using Windows 3, the first thing to do is install the supplied Win32s kit.
It has its own autonomous installation procedure, and must be redistributed "as is"
to your own customers who are use Windows 3. The "FreeCall" set supplied with
this kit will enable you to check it functions correctly.
The kit to install Prolog II+ on Windows consists of one volume containing the
following files:
err.txt
File containing error messages in English, consulted by Prolog when the
ms_err rule is called, if the -r option has not been used to choose a different
one. To obtain messages in French, choose the file called fr_err.txt.
fonts.usr
File defining the fonts that Prolog II+ uses in the graphics environment. The
user can modify this file before start-up, to define fonts called :ft(1), :ft(2) etc.
These fonts will be used for example by the gr_font predicate.
initial.po
File containing the supervisor's saved code.
© PrologIA
Aociation Prolog
prolog.exe
Runnable file for the Prolog II+ development version.
customiz.dl_
DLL containing Prolog II+ customization resources, automatically recognized
if renamed as customiz.dll.
dde.mo
Prolog object module which must be loaded to write a client or a server
application using DDE protocol.
dessin.m2, dessin.mo
Source and object files containing the tree drawing module.
edinburg.mo
A Prolog object module which is loaded automatically when the Edinburgh
syntax is selected. It contains all built-in predicates specific to the Edinburgh
syntax.
fr_err.txt
File containing the error messages in French.
graphic.mo
Prolog object module containing all graphics primitives. This file must be
loaded to start Prolog's graphics environment.
graphstr.mo
Prolog object module which is loaded automatically by graphic environment
according to selected configuration when starting.
obdialog.mo
Prolog object module which must be loaded to use the primitive for
management of structured graphics objects: gr_dialog. Automatically loaded
by loading graphic.mo file.
prolog2.pre
Text file containing the Prolog II+ command line. Assuming this file exists,
the options it specifies replace the default options. This file is first searched
for in the current directory, and then in the directory defined in PrologDir2
environment variable. It can be edited using any text editor.
tools
Directory of tools as:
© PrologIA
Aociation Prolog
U1-4 Windows User's Manual HERITAGE
dbgbase.mo
Object module which must be reloaded, and which provides more detailed
error messages about Prolog II syntax built-in predicates.
dbgedin.mo
Object module which must be reloaded, and which provides more detailed
error messages about Edinburgh syntax built-in predicates. Can be loaded
instead of edinburg.mo.
dbggraph.mo
Object module which must be reloaded, and which provides more detailed
error messages about graphics built-in predicates. Can be loaded instead
of graphic.mo.
int_edit.mo
Prolog object module which must be reloaded (reload predicate) to be able
to use the integrated editor instead of host editor defined in PrologEdit
environment variable.
All the files listed below are used to reconstruct Prolog II+. The object files and the
library are essential, and constitute the final runnable: prolog32.exe.
princip.c, princip.obj
Source and object files containing the way to run the initial goal of Prolog.
proentry.c, proentry.obj
Source and object files containing the main program (WinMain). The
proentry.obj file can be replaced by a user program that uses Prolog as a sub-
program.
proext.h
C source file containing declarations of macros and structures, to be included
in user modules written in C.
prolink.bat
Command file to re-edit the Prolog II+ links to construct the runnable file. It
can be modified by the user.
prolog.def
Module description file used when linking. You must add to it the names of
any Callbacks you want to export (see SDK Windows).
prolog.lib
Library file containing the Prolog functions.
© PrologIA
Aociation Prolog
prolog.res
Compiled file of Prolog resources.
prouser.c, prouser.obj
Source and object files for the C external interface.
use_win.h
Source file that must be included in user modules written in C, to ensure they
are compatible with the Support.
The DLL must be in the same place as Prolog's 32 bit runnable, and it must have
the same name except for the last character, which is replaced by '-', and the
suffix which is ".DLL".
When using communication primitives with Prolog, it is useful to know that when
pointers are passed they are converted, but the pointed data is not copied. The
operation is therefore relatively efficient.
callpro.h
File providing the prototypes for the communication primitives to include.
callpros.lib, callprol.lib
Static library providing the link code to Prolog, available in a Small model
(callpros) and a Large model (callprol). One of the two versions must be
linked to your code.
© PrologIA
Aociation Prolog
U1-6 Windows User's Manual HERITAGE
callpro.def
File defining the DLL's standard module used by the linker. You may need to
modify this file's parameters and add your own exports. The rank numbers
do not matter, since the connection functions are recognized by their name.
userdll.mak
Example of a makefile for the DLL, to be adapted.
The examples are located in the sub-directory examples in the Prolog Kit.
Other examples:
Other examples using graphic environment are given, and also self documented
sample files to add external predicates.
© PrologIA
Aociation Prolog
The following conventions are used to indicate the type of file and its meaning:
.m2 The file contains a Prolog II+ source module written in Prolog II
syntax.
.m2E The file contains a Prolog II+ source module written in Edinburgh
syntax.
.mo The file contains the code for a compiled Prolog module (be careful,
these files are not compatible with the system link editor, only Prolog
can use them).
.po Same as above, but these files contain a complete state (files saved
using the command exit). These are the only files that can be used as
the initial state for Prolog start-up.
.p2 This is a source file containing Prolog II+ rules written in Prolog II
syntax. It is loaded with the insert command when the current syntax
is Prolog II syntax.
.p2E This is a source file containing Prolog II+ rules written in Edinburgh
syntax. It is loaded with the consult command when the current
syntax is Edinburgh syntax.
The files whose names end in .p2 contain the source texts for the programs given
as examples in the Appendix.
The Prolog II+ distribution volume was generated by compressing a tree structure.
As soon as you are in the directory in which you wish to place the files, the loading
command can be executed as indicated in the information sheet accompanying the
distribution kit.
© PrologIA
Aociation Prolog
U1-8 Windows User's Manual HERITAGE
We recommend you create a directory reserved for Prolog, called for example
c:\prolog, and install the kit's files in it. You must then define the environment
variable used by Prolog to access these files (see section 1.4).
The most convenient way to use Prolog is to define the following variables in your
execution environment (autoexec.bat):
PrologDir2
This is the path used by Prolog if the following files have not been defined in
the current directory: initial.po, edinburg.mo, err.txt. The variable
concatenated to the file name must specify its complete path.
PrologEdit
Name of your command file that will start the text editor to be used by Prolog
(using the edit and editm predicates) when editing with a host machine editor.
The following command must be comprehensible for the command
interpreter:
%PrologEdit% file-name
There is no default value for this variable.
Note: In Windows3 your command file must also create at the end a file
called file.end in a directory defined by the environment variable called TEMP,
to indicate the end of editing. For example, if you want to use the DOS editor
edlin, you must write the following command file (myedit.bat):
rem begin
edlin %1
echo >> file.end
rem end
However, if you want to use the built-in editor instead of an external editor,
you must execute the following predicate:
> reload("int_edit.mo");
© PrologIA
Aociation Prolog
© PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
Prolog II+ is the compiler for an advanced version of the Prolog language. The
Windows Prolog II+ compiler enables you to load, execute, extend or interactively
modify a Prolog program.
The compiler starts with an initial state. When you leave Prolog using the command
exit, the current state of the progam is saved in a binary code file, which can be used
later as a new initial state. The initial.po file we supply is a new initial state; i.e. it
contains just a supervisor and predefined rules.
This chapter describes how to start the Windows Prolog II+ compiler, create a
program and then leave the system.
This chapter also explains how to use the other runnables in the Prolog II+ kit.
To end a session, type one of these Prolog goals: quit or exit. You can also use the
Quit option in the main menu.
© PrologIA
Aociation Prolog
U2-2 Windows User's Manual HERITAGE
If no file name is given for the initial state file, the default file name is initial.po.
Below are two examples
win prolog
This command starts the compiler with an initial state initial.po, which is sought,
first using the current directory, and then using the path indicated by the
environment variable PrologDir2. An error occurs if such a file does not already
exist. The Prolog command exit saves the state of the program in the file called
prolog.po in the current directory.
This command starts the compiler with the initial state myfile.po. An error occurs if
such a file does not already exist.
When it starts, Prolog creates the Application window and the Console window. It
then displays its title line with some information about its configuration, and loads
the binary start-up state.
Once loading is over, Prolog waits for a command. It displays a prompt and waits
for a sequence of goals that it can execute. Prolog will function in this way until the
session is terminated using quit or exit.
If you use the predefined rule quit or a menu to leave Prolog, no state will be saved.
If you use the predefined rule exit to leave Prolog, the current state is saved under
the name prolog.po.
If you use the predefined rule exit("file_name") to leave Prolog, this file-name will
always be used for the resulting saved state.
Prolog's work space is divided into different spaces, to which is added the name
dictionary space, designed as an independent external module. By default, the sizes
of these spaces are read in the initial binary file, unless the command line option is
used which enables the method for determining these values to be changed. Here
are the most important spaces:
© PrologIA
Aociation Prolog
code space
This is the space where the initial state and the code generated by the compiler
are loaded. The default size is 500 Kb. There is no limit on module size,
except that the total of all the module sizes must be less than the total space
for the code.
When rules (thus modules) are deleted, the space is automatically collected for
the rules which are not being used.
dictionary space
Dictionary of Prolog identifiers. Default size: 200Kb.
These default sizes can be modified, using the options on the command line or in
the prolog2.pre file.
All the syntactic descriptions in this manual use square brackets [ ] for optional
elements, and curly brackets {} for elements which can be repeated any number of
times - including zero.
© PrologIA
Aociation Prolog
U2-4 Windows User's Manual HERITAGE
The file name initial_state, written in host system syntax, denotes the state file which
is to be used to start the Prolog session. If nothing is specified, initial.po is the
default name which will be used for this file.
The parameters can be specified in any order. They modify the compiler's default
sizes and options. The list of possible parameters is as follows:
[-H] [-c n] [-C file] [-d n] [-E] [-f fv{fv}] [-h n] [-i file] [-
j file] {-m file} [-M n] [-o file] [-P parameter] [-q n] [-Q] [-r
file] [-R n] [-s n] [-t n]
-H
(Help) This command line help facility displays the default configuration.
-c integer
(code) Defines the amount of space used (in Kb) for rules, static variables
and Prolog arrays.
-C file
(Compile) Compiles the source file called file, generates an object file and
leaves Prolog. The name of the object file is determined following these rules
If the option -o is simultaneously used, the name used in this option is
used;
If the source file does not contain any module, the name empty.mo is used;
If the source file contains only one module, this name of module suffixed
with .mo is used (if this module is the empty one, the name user.mo is
used;
If the source file contains several modules, the name of the source file
suffixed with .mo. is used.
-d integer
(dict.) Defines the amount of space used, in Kb, for the dictionary.
-E
(Edinburgh) activates Prolog in Edinburgh mode (see Chapter 10 of the
Reference Manual) and is equivalent to the -m edinburg.mo option.
It changes the syntax and loads the new predefined rules specific to the
Edinburgh mode. The Edinburgh mode assumes that the variable syntax is
not the Prolog syntax, and that the real number syntax is the standard syntax.
So when this option is used it modifies the values of the s, v, and r flags which
will have the respective values E, E or U, and S. This option is the last to be
processed. Therefore, if the flags s and r are specified by the -f option they
will be ignored, as will the v flag defined at P.
© PrologIA
Aociation Prolog
-f fv{fv}
(flags) Defines the values of various behavior options. A sequence of
character pairs defining the values of various default options. The default
option values are equivalent to the following parameter:
-f a1A0cIe0g1G0i1o1rPsSuWvPw1zU
fv{fv} is a sequence of character pairs where in each pair, the first character
defines the option, the second its value. The available options are as follows:
a: (atoms)
Determines whether the empty prefix ("") must be automatically
assigned to non-prefixed atoms when they are positioned as
arguments:
A: (reallocation)
Determines whether reallocation of the relevant space must be
prohibited or permitted:
1 All reallocations are prohibited
© PrologIA
Aociation Prolog
U2-6 Windows User's Manual HERITAGE
c: (character coding)
Determines the type of internal character coding:
e: (escape mode)
Determines the mode for printing accented characters not belonging
to the host machine set. This flag only has a meaning in the ISO
coding mode. The possible values are:
G: (garbage collector)
Determines whether gargabe collection in the relevant space must be
prohibited or permitted:
1 All garbage collection is prohibited.
© PrologIA
Aociation Prolog
o: (optimization)
Determines whether or not the generated code (arithmetical
instructions, comparison instructions, type tests, block, val, assign...)
is optimized. When optimization is selected, and a rule is decompiled
(for example using rule), arithmetical operations may produce a
sequence of terms which is different from the original sequence. In
the same way, when decompiling a rule using the block predicate, an
equivalent term will be shown instead of the original one. Also, the
debugger may not display certain arithmetical operations, or certain
type tests, or arguments of predicates such as val, assign and block.
The possible values are:
0 (no optimization) The program appears in its original form
when rule or the debugger are used.
1 (optimization) This is the default value. It applies to any
code produced by insert, module or assert.
r: (reals)
Determines the syntax used for reals.
P Prolog II notation. It allows simultaneous use with infixed
list notation.
S Standard notation. Reals are written in abbreviated form, and
the lists are written in square bracket notation, e.g. [1, 2, 3].
s: (string)
This option only takes effect in Edinburgh mode. The value defines
the syntactical interpretation of the lexical unit string described in
section 1.4 of the Reference Manual.
© PrologIA
Aociation Prolog
U2-8 Windows User's Manual HERITAGE
u: (undefined)
Defines the result of an attempt to execute a non-defined rule. The
possible values are:
E (Error) The goal is printed, and the system stops.
F (Fail) Same behavior as the interpreter: failure.
W (Warning) A message is printed and the goal fails.
v: (variables)
Determines the syntax used for variables and identifiers.
E (Edinburgh) Edinburgh notation
P (Prolog II+) Prolog II+ notation
w: (warning)
Defines the warning for certain surprising configurations. Does not
function on messages resulting from the uW option when a called
predicate is not defined.
0 no message is given.
1 during execution, warning is given when the following
primitives are erased:
- block_exit/1 or block_exit/2 with a free variable instead of
the error number,
- load/2 or reload/2 with a demand for replacement of a non-
existent prefix,
- save/2 or kill_module/1 for a non-existent module,
- suppress/1 or suppress/2 for a non-existent rule,
- kill_array/1 for an undefined array.
2 gives the same warnings as in mode 1, and in addition
indicates:
- during compiling, the non anonymous variables which only
have one occurrence in the rule (likely to be caused by a
typing error).
U the sizes of the spaces are read in the initial binary file
-h integer
(heap) Defines the amount of space, in Kb, reserved for the copy stack.
© PrologIA
Aociation Prolog
-i file
(Input) Defines the name of the file which the current reading unit is directed
to at start-up. By default reading is performed at the console.
-j file
Defines the name of log file created by the Prolog paper primitive (default:
"prolog.log").
-m file
(Module) Loads at start-up, after the binary state, the Prolog object module
whose name is file. If the file is not found in the current directory, the system
looks for it in the directory defined by the PrologDir2 environment variable.
If several of these options (up to 20) are used, they are processed in order of
appearance.
-M integer
Maximum response time in milliseconds for a DDE exchange, after which an
error is signaled.
-o file
(Output) Defines the name of the file which the current output unit is directed
to at start-up. By default writing is performed at the "console". The Prolog
title line still appears in the console.
-P parameter
Passes a parameter on the command line. This parameter can be recovered
from Prolog in the predefined table of character strings tab_user_param. If
an empty string is returned this means there are no more parameters to
recover. A maximum of 20 parameters can be transmitted on the command
line. Example:
prolog -P 1 -P foo
> val(tab_user_param[1], V);
{V = "1"}
> val(tab_user_param[2], V);
{V = "foo"}
> val(tab_user_param[3], V);
{V = ""}
-q integer
Defines the amount of space, in Kb, reserved for encoding the arguments of
direct calls to C procedures.
-Q
Starts Prolog in an iconic state (Quiet).
-r file
Defines the name of the error file used by Prolog (default: "err.txt"). To
obtain error messages in French, choose the file called fr_err.txt.
© PrologIA
Aociation Prolog
U 2 - 10 Windows User's Manual HERITAGE
-R integer
(Realloc) Defines the percentage size increase for automatic reallocation
(default 25).
-s integer
(stack) Defines the amount of space, in Kb, reserved for the recursion and
local variables stack.
-t integer
(trail) Defines the amount of space, in Kb, reserved for the restoration stack,
(variables restored after backtracking).
{x=Jean, y=Marie}
{x=Jean, y=Pierre}
>exit; A new binary start-up state is saved,
containing the user program.
Bye......
$
The prolog.po file has now been created, and contains a new state (built-in
predicates and your program). To start with the previous state, start Prolog again by
entering the name of the corresponding file:
$ win prolog prolog.po
PROLOG II+ ...
... PrologIA Prolog now knows the built-in
predicates and your program.
>father(Jean,y); You can start an execution.
{y=Marie}
{y=Pierre}
>quit; You now leave Prolog without
saving.
Bye......
© PrologIA
Aociation Prolog
To save the state with another file name, use the command exit("file-name").
After choosing options in the control panel, you should save current state to avoid
doing it again every time you run Prolog:
> save_state("myini.po");
prolink.bat
The prolink.bat program is used to reconstruct a Prolog runnable file that has been
modified or to which modules have been added that may contain descriptors for
external data. The prolink command has the form:
prolink ['object_modules_list'] ['descriptors_list']
object_modules_list
is a series of names of compiled object modules. These modules must be
included in the final runnable.
© PrologIA
Aociation Prolog
U 2 - 12 Windows User's Manual HERITAGE
descriptors_list
is a series of names of descriptor arrays (see Chapter 7 of the Reference
Manual) located in the object modules given as the first argument. If no
descriptor arrays have been created, the second argument can be left out.
© PrologIA
Aociation Prolog
© PrologIA
Aociation Prolog
HERITAGE
Aociation Prolog
HERITAGE
3. Special features of
the Windows version
The reals manipulated in Prolog correspond to the double type in C (IEEE 64 bits).
The range of values for doubles is from -1.79e308 to +1.79e308; their biggest
negative value is -2.2e-308 and the smallest positive value is +2.2e-308. Some
communication functions only accept single precision reals. The range of values for
single precision reals is from -3.4e38 to +3.4e38; their biggest negative value is
-1.2e-38 and their smallest positive value is +1.2e-38. This corresponds to the float
type in C (IEEE 32 bits).
Throughout the first chapter of the Reference Manual, the syntax described applies
more especially to the ISO set. This chapter describes a part of the syntax relating
to characters, adapted for the Windows systems. It is valid for each Prolog session
which uses the host machine's character set.
It should be noted that whereas MS-DOS uses the OEM character set, Windows
uses the ANSI set, which is virtually identical to the ISO set. So when files written
in MS-DOS containing accented characters are displayed in a window, these
characters may be replaced by black rectangles. We therefore recommend you
create text files with an editor in Windows.
© PrologIA
Aociation Prolog
U3-2 Windows User's Manual HERITAGE
At initialization time, the system searches for the DLL customiz.dll and loads it if it
exists in the directory which contains the executable file of Prolog. This DLL does
not contain any executable code. The purpose of this DLL is to support User
resources. The user resources will therefore be linked to this module using a
provided makefile.
The system will search for the following resources at initialization time, and if they
exist they replace the corresponding original resources:
10
is an icon resource that will be used instead of Prolog's "Column" icon to
represent the application's main window. You can also use it to represent the
application in the Application Manager window: just search for it in the
customiz.dll module instead of prolog.exe.
1, in a STRINGTABLE resource
is a character string resource that will be used as the initial title of Prolog's
main window instead of "Prolog II+". Caution, remember that in a resource
the final '\0' character must be explicit.
© PrologIA
Aociation Prolog
100
is a dialog box description resource, that can be written either by hand or
using the SDK Dialog Editor. If it is found, the "About Prolog" item in the
Application menu disappears and the "About the Application" item is enabled,
causing this "About Box" to open. It can represent whatever you like but only
one button will be recognized, and it must have the identifier 1 (IDOK).
Other user resources can be supplied, but they will not be generated automatically.
Please follow the standard Windows procedure. Two important points must always
be borne in mind:
- Your dialog function must also be exported by the Application, so make sure you
declare it in the prolog.def module,
In the case of Windows 3 and to use resources via 16 bit extensions, it is more
suitable to link these resources directly to the extension DLL.
The proentry.c file contains the source for the main routine of Prolog as an
application. The routine is commented in detail and calls the following functions:
- InitializeProlog (hInstance, hPrevInstance, lpCmdLine, nCmdShow) which
will perform the initializations required to start Prolog. This function returns
0 if the initializations succeed, or an error number if an error has occurred. Its
parameters are those of the WinMain function application. It replaces the
ProStart function mentioned in Chapter 8 of the reference manual.
© PrologIA
Aociation Prolog
U3-4 Windows User's Manual HERITAGE
- StartPrologMainGoal() which will start the Prolog main goal, by calling the
promain() function from the princip.c file, whose source is already provided.
This function returns 0 if everything is OK, or an error number if an error has
occurred. The call to the StartPrologMainGoal function is not obligatory in
order to use the Prolog machine. It can be replaced by calling a user
procedure that installs its own goal and thus uses Prolog as a runtime.
However, if you feel intuitively that this procedure's task will be too long, it
must be started as described in the file, to avoid paralyzing the machine.
This file also provides the function Prolog uses to distribute each Windows
message that has been read.
External procedures can only be added using the parasite method described in
Appendix D.
In the parasite linking method, a user module acts as a link between Prolog and the
user routines written in C. The parasite numbers from 20000 to 29999 are reserved
for C routines linked to this interface. This module can be developed like a standard
Windows 3 Application. Switching and control transfer are very rapid and
everything happens as if the extension was directly linked to the 32 bit application.
Here is a complete example describing all the operations needed to create a new
built-in predicate, implemented by an external routine in 16 bit code.
Let us suppose that you are programming in C and that you want to add a built-in
predicate roots(a,b,c,x,y) to calculate the two real roots x and y of the equation
ax2 + bx + c = 0, if they exist, and which causes backtracking if not.
Here is the step-by-step sequence you should follow:
© PrologIA
Aociation Prolog
#include <math.h>
then
real_roots(perr_nb)
int *perr_nb;
{
float a, b, c, d, x1;
if ( !get_real(1, &a, perr_nb)
|| !get_real(2, &b, perr_nb)
|| !get_real(3, &c, perr_nb))
return;
if ( a == 0.)
*perr_nb = -1; /*backtrack*/
else if ( (d = b * b - 4 * a * c) < 0.)
*perr_nb = -1; /*backtrack*/
else
{
x1 = (-b + sqrt(d)) / (2 * a);
if ( ! put_real(4, x1, perr_nb) )
return;
put_real(5, -b/a - x1, perr_nb);
}
}
2. Modify the user_rule function of the roots.c file by adding the call to the new
external program. For example, give the new rule the number 20001:
user_rule(nb, err, err_nb)
int nb, *err, *err_nb;
{
*err = *err_nb = 0;
switch (nb)
{
...
case 20001:
real_roots(err_nb);
break;
...
}
}
4. Rename the roots.dll file as prolo-.dll and copy it into the same place as the
Prolog runnable:
$ copy roots.dll c:\prolog\prolo-.dll
© PrologIA
Aociation Prolog
U3-6 Windows User's Manual HERITAGE
>
It should be noted that all these routines are exported by the DLL using the cdecl
protocol. Use of the import library (file prodll.lib) and the definition of prototypes
(file exportsw.h ) will enable you to avoid any problems in this area.
© PrologIA
Aociation Prolog
InterruptProlog( )
This routine with no argument is used to activate a user interrupt in the Prolog
session currently being executed. It can be called at any time. The example
provided with the DLL shows how to use it to stop execution of the Prolog
predicate enum.
© PrologIA
Aociation Prolog
U3-8 Windows User's Manual HERITAGE
© PrologIA
Aociation Prolog
HERITAGE
The Prolog II+ environment supports the DDE protocol and ensures portability
between Windows 32 and OS/2-PM. These new functionalities enable you to carry
out two types of operation.
- You can launch Prolog goals and recover the results from an external Client
application program, without writing any interface code.
- By loading a specific Prolog module, you can obtain a complete set of primitives
enabling you to write a DDE Client or Server application without any C extension.
This is just a very brief presentation of the DDE protocol. For more detailed
information, please refer to the chosen host system's documentation.
© PrologIA
Aociation Prolog
U4-2 Windows User's Manual HERITAGE
Service identifies a logical Server. In practice it is usually the generic name of the
Server application itself ("EXCEL", "WORD", "CLOCK", etc.). However there is
nothing to stop the Server declaring several Services, if it is capable of managing
them.
The name of Item indicates a given specific object relatively to a conversation taking
place on a given Topic. Therefore in practice it is often a specific "paragraph" of the
open "document" (e.g. range "E7-K9" of the above-mentioned spreadsheet).
However it can be any entity subordinate to the Topic and compatible with the DDE
operations to be performed on it (e.g. a "Reset" signal obviously accessed for a
"Poke" operation, in a conversation on the Topic "Time" with "CLOCK").
© PrologIA
Aociation Prolog
"Service"
TEXT only
for Prolog
(currently) "Topic 1"
Some Data
One-Way Conversation (+ Format)
"Topic 2"
Execute( Order)
"Item 1"
RequestData
HotLinkData "Item 2"
WarmLinkData
PokeData( Data) Some Other
"Item z" Data
Data for RequestData,
else Boolean ACK
"Topic n"
To comply with the standard programming model for Prolog II+, the general DDE
protocol has been adapted as follows:
- All exchanges take place by means of calls to primitives or else automatic calls to
goals by the system. From now on these goals will be called "callback goals". A
primitive's return value corresponds to the end of a transaction and provides the
associated status.
- The capacities of the Prolog DDE are limited to "Standard Text String" data.
- When the potential Client does not specify the Service or the Topic, there should
be a negotiation stage where the Server describes what it has on offer. This sub-
protocol cannot be implemented in the form of an extendable skeleton in Prolog.
It has therefore been decided that Prolog will only accept "Wild
Connections" with a specified Topic.
© PrologIA
Aociation Prolog
U4-4 Windows User's Manual HERITAGE
- The callback goals participate in system mechanisms and therefore cause the
classic problems one would expect. This means they must be debugged in a
simulation context before they are connected, instead of "on site". Similarly the
processes they generate must be of a "reasonable" duration (to be judged
intuitively by users).
To use Prolog II+ as a DDE Server you must have a Client application program
capable of formulating requests that can be configured in the "Pure Text" format.
There are several ways of testing this out:
- you already have such an application program, even if it seems too big to be used
in this way,
- you can use a "Sample DDE Client" supplied with the Software Development Kit
for the host platform (e.g. the SDK from MicroSoft for Windows),
To validate the DDE Service you must call the following primitive:
ddePublishExternalEvent( _bActivate)
Activates the Service (_bActivate is 1) or deactivates it (_bActivate is 0).
Deactivation of the Service prevents any future connection, but does not
dismiss any Clients already connected. However they will be dismissed
correctly if Prolog II+ terminates prematurely.
Once Prolog II+ is validated it publishes a Service (or application name) entitled
Prolog2 under which it recognizes the Topic ExternalEvent. If a "Wild
Connection" has no Service but specifies this Topic it will also be accepted. Any
number of Clients can connect up (each using its own method) within the system's
limits.
It should be noted that when connection or any subsequent operation takes place the
Prolog II+ console does not react in any way, except in the case of an explicit
writing operation.
Once the Client has connected it is free to use standard DDE requests using the
semantics described below.
© PrologIA
Aociation Prolog
- You can send a Poke request to an Item called "anytext" without any additional
data (it will be ignored if present). An extern_event( "anytext", 0, 0) event is
placed in the Prolog II+ event queue, which can be read by the graphic module's
get_event/3 predicate.
- You can send an Execute request (the Item parameter does not exist) with a
prolog_goal. The transmitted goal is placed in Prolog II+'s execution queue and
will be launched in an asynchronous manner by the machine. When the request
succeeds this means the transmission has succeeded, not the transmitted
goal. Here we do not consider the recovery of solutions.
Any Prolog error messages are shown in the current output unit (by default the
console), and are not transmitted to the Client. The unification of the transmitted
goal's variables does not produce any trace. Only explicit writing will be visible.
Limit. The prolog_goal data item is limited to 32,767 characters and must take the
form of a unique goal (not a sequence or list of goals), complying with the current
syntax, otherwise an error is generated.
- Poke request on the Item "Lily was here" with the data item "You won't see me":
> get_event( 0, x, y);
{ x=extern_event( "Lily was here", 0, 0), y=0 }
>
The data item transmitted by the Execute request accepts a second syntax, which can
be described as follows:
© PrologIA
Aociation Prolog
U4-6 Windows User's Manual HERITAGE
identifier has the syntax of an abbreviated Prolog identifier (no prefix) and will
designate the solution.
When the goal executes the value assigned to the designated argument will be
converted into a character string and associated with its identifier. If the goal fails or
generates an error, the value assigned to the solution will be "*Failure" or "*Error
nnn" respectively, where nnn is the Prolog error code. The Client can recover the
solution(s) in two ways:
- By sending a Request request to the Identifier Item after execution of the goal.
The returned value is that of the last current solution of the goal the identifier is
associated with, in the previously described conditions. The problem is that there
is no method of automatic synchronization making it possible to find out whether
the goal has been executed. If it has not been executed the request fails, unless
the identifier used already contains the solution for another goal launched
beforehand. The second problem is that only the last solution is recovered.
Remarks
- If the Prolog II+ Server is requested by several Clients, the transmitted goals are
stocked in chronological order, and their only link with their author is the
specified identifier. This characteristic makes it possible to share data between
Clients, with or without their consent. When an application is based on several
application programs, it is advisable to choose with care the identifiers used.
- If one of the Clients transmits the goal quit or any goal that has a side effect,
Prolog II+ executes it without considering the interests of the other Clients. For
example, a tool that periodically attempts to connect with Prolog II+ to launch a
Execute( quit) request on it would constitute a veritable anti-Prolog vaccine.
© PrologIA
Aociation Prolog
This diagram should be compared with the more general diagram given above.
Logic Server:
Logic Client The "PROLOG" DDE Service Automatic Service
"Prolog2"
HotLinkData "AnyResultNumber"
Execute
PokeData() "Anything"
Data for RequestData, ExternEvent( "Anything")
else Boolean ACK
Events
Queue
get_event()
4.2.5 Examples
- The Execute request with the data item 'eq(production, x), 2, my_var' succeeds
and associates the value of x (here production) with the identifier my_var in the
interface.
- The Execute request with the data item 'eq(production, x), 1, my_atom' succeeds.
- The Request request for the Item my_var succeeds and returns production
- The Request request for the Item my_atom' succeeds and returns production (1st
argument).
- The Execute request with the data item 'arg2( X, Y, Z), 3, my_arg' succeeds, but
the message:
-> <v33> : BAD ARGUMENT TYPE
is displayed in the Prolog II+ console
- The Request request for the Item my_arg succeeds and returns *Error 253
- The request Advise (or HotLinkData) for the Item enumerate succeeds.
© PrologIA
Aociation Prolog
U4-8 Windows User's Manual HERITAGE
- The Execute request with the data item 'enum( i, 5), 1, enumerate ' succeeds and
the Client receives 1, 2, 3, 4, 5 in succession.
- The Request request for the Item enumerate succeeds and returns 5.
In both cases you must load the "dde.mo" module, which installs the DDE
primitives. To cancel installation call the following primitive:
ddeCleanup/0
Terminates all the conversations and Services in progress and removes all the
Prolog primitives relating to the DDE. This primitive is not the right way to
end the DDE activity of a Client or Server application program. It should only
be used afterwards.
The following sections examine the two modes separately, but there is nothing to
stop an application from being a Client and Server simultaneously, in different
conversations. However when writing it you must take great care with management
of conversation numbers and with the DDE identifiers used. The following primitive
will be of great assistance in this task:
ddeRememberDatabase( _xData)
Enumerates the current Services and conversations and unifies them with the
argument _xData. It has the following format:
dde_I_serve(_tService) for Services (therefore the Server only),
dde_I_am_Client(_hConversation, _tTopic) or
dde_I_am_Server(_hConversation, _tTopic,) for the conversations.
DDE transactions are initiated by the Client, but some of them also take the form of
asynchronous notifications from the Server. The system assumes the Client takes
account of them and adapts its behavior accordingly. Similarly, the system assumes
the Client knows how to use the Server it wants to use. It may also be necessary for
the Client to start the required Server application program.
© PrologIA
Aociation Prolog
ddeEndConversation( _hConversation)
Ends the conversation designated by_hConversation by dismissing the
Server. If _hConversation is a free variable, ends by enumerating
(backtracking) all the current conversations by unifying _hConversation with
the relevant conversation. If the designated conversation does not exist, the
unification fails. Use of this primitive is natural for the Client.
© PrologIA
Aociation Prolog
U 4 - 10 Windows User's Manual HERITAGE
Callback goals
The callback goals (predefined names) are in the global module and have the prefix
"". The user writes them and the system calls them. They are therefore subject to
constraints depending on the system programming. The following rules should be
borne in mind:
- Callback goals can perform backtracking, but the transmitted request will be
validated (assuming it requires validation) if there is at least one solution.
- Callback goals should not execute abnormally large processes (to be judged by the
user), and certainly not processes interacting with the user including modal
stages. There is a risk of a time-out, or even of a defensive reaction from the
system.
- This means that the callback goals cannot be debugged on site. They must be
debugged using a simulator.
:ddeCbServerClosing( _hConversation)
Indicates that the Server has prematurely terminated the conversation
_hConversation for whatever reason. The termination status of its processing
does not affect the result transmitted to the server. The value of
_hConversation must from now on be considered invalid and recyclable
(therefore ddeEndConversation( _hConversation) will fail if it is attempted).
Example
© PrologIA
Aociation Prolog
{ _t="15:20:33" }
> ddeTransmitRequest( 1, ddePokeData("Now", "23:59:30"));
{}
> ddeTransmitRequest( 1, ddeHotLinkData("Now", ddeOpen));
{}
It is 23:59:55
It is 23:59:56
It is 23:59:57
It is 23:59:58
It is 23:59:59
End !
> ddeEndConversation( 1); % Failure, number 1 is out-of date
>
There are more restrictions on this mode, because a Server must be at the complete
disposal of Clients, and also avoid any conflicts of interest with other Servers. So
the first and most important step is to formally define all the commands it can
receive, and give them appropriate names. The instructions on how to use it must be
very comprehensive.
Declaration primitive
ddeEndConversation( _hConversation)
Terminates the _hConversation by dismissing the Client. If _hConversation
is a free variable this primitive terminates all the current conversations by
enumeration and unifies _hConversation with the relevant conversations. Use
of this primitive is natural for the Client. Although the Server can use this
primitive it is not recommended. It would only be necessary to use if a
problem arises.
© PrologIA
Aociation Prolog
U 4 - 12 Windows User's Manual HERITAGE
Callback goals
© PrologIA
Aociation Prolog
- ddeHotLinkData(_tItem, ddeOpen) or
ddeHotLinkData(_tItem, ddeClose): advises a standard Advise request for
the data item named by the string _tItem, requesting a subscription to
automatic update of this data item (hot link) or cancellation of this
subscription. The system assumes that Server records this information to
modify its subsequent behavior,
- ddePokeData(_tItem, _xValue): advises a standard Poke request for the Item
named by the string _tItem, therefore sending the data item _xValue
(Prolog text string) to the Server, or else a simple signal without any
attached data. In this case the value of _xValue is nil,
- ddeExecute(_xArgument): advises a standard Execute request to the Server
passing it a pre-agreed text message contained in the string _xArgument,
that the system assumes the Server understands and executes in a
synchronous manner. Its status must determine whether or not the
message succeeds,
- ddeClose: advises of the disconnection of the Client. The internal data base
is automatically updated and the system assumes that the Server updates
its own data, if any. This notification takes place after the event, and the
goal's termination status has no effect.
Example
Let's imagine that the Server is the fridge in a restaurant. It has to manage the stock
of different dishes, eaten in a random manner. It has to communicate the quantity of
each dish that is available and subtract the quantity eaten. It must warn the
restaurant when stocks run low and then be able to produce on request a list of the
dishes to be restocked. Finally, its must be able to record a delivery.
The items will be the names of the dishes associated with an available quantity, in an
internal data base. An item called "Rupture" that only the Boss can access enables
him to obtain the list of dishes with a stock of less than 5. The boss can interrogate
it using Request and/or subscribe to it. He will then receive the up-to-date list each
time a dish is eaten in the restaurant. Only the boss is authorized to supply the
Fridge with an Execute request passing a list of figures. He also has access to all
the authorized operations for the waiters in the restaurant.
The program for this example is given in the file called ddefrigo.p2 of the kit. You
will notice that it is much bigger than the previous one. To use it in an interesting
way, it is best to have several Client application programs (approximately 3) that can
(easily) use random DDE Identifiers. If other Prolog instances are used as Clients,
a file called ddecligo.p2 in the kit provides simplified commands adapted for this
example. In all cases, launch the to_begin rule to start these programs. They then
list their instructions for use.
© PrologIA
Aociation Prolog
U 4 - 14 Windows User's Manual HERITAGE
- First of all fill the fridge, initially empty. For example the boss launches an
Execute request for the string : "4 Rabbit, 15 Chicken, 7 Apple Crumble, end" ,
- Try to connect a second boss, especially if the first one is already subscribed to
Rupture,
- Try to obtain a dish that is not available, e.g. Poke request of "dish name, -1",
- ...
© PrologIA
Aociation Prolog
HERITAGE
5. Graphics Primitives
The Prolog II+ graphics primitives also enable you to create panels, which act as
supports for other types of graphics object. The primitives to create and manipulate
objects only act upon Prolog objects. All these objects must be created by means of
Prolog predicates only, without using external tools (e.g. a screen generator).
However, the event management primitives can also manipulate events affecting
objects outside Prolog.
A s sign indicates new primitives now available under Window3, OS/2-PM and
Motif1 . These primitives are not yet implemented on Macintosh.
If you want to port your programs to other configurations, you should not use these
marked rules, which are specific to a machine or environment.
1 Prolog II+ graphics under the Motif environment were developed in collaboration with
Digital Equipment Corporation.
Aociation Prolog
U5-2 Windows User's Manual HERITAGE
From the point of view of Prolog, all the graphics effects produced must be
considered as side effects. In particular, a drawn object is never erased in
backtracking. Similarly, the position of the writing point is a global variable.
5.1.1 Events
Some Prolog graphics objects are sensitive to events, and transmit them to the
Prolog programmer who can choose between three different processes:
- immediate processing by attaching a Prolog program to the object;
- automatic addition to the Prolog events queue, for subsequent processing;
- nothing.
First, let's look at the main graphics objects; windows. Windows may or may not
have a frame, a title bar and menus. They can be re-sized, given icons and made
invisible. Text windows can have horizontal or vertical scroll bars, and their
contents can be saved.
There are four types of window, with different characteristics and functions.
EDIT windows
These are text windows for text editing. Their contents can be modified
directly using the keyboard, the mouse and the menus, and also by program
using Prolog input/output. The writing point is at the end of the text. The
reading point is initially at the top of the window, and is then at the last read
position. It should be noted that when reading is requested, Prolog copies a
whole line into a buffer.
These windows have limited capacity. Manipulations that increase the size of
the text beyond this limit will be ignored.
© PrologIA
Aociation Prolog
FRAMEPANEL windows
These windows are empty. Their only function is to receive objects. They do
not have a drawable or editable part.
GRAPHICS windows
These windows are for drawings. They are affected by keyboard and mouse
actions, and can receive objects. Standard methods can be used to insert text
into them. By default, the bitmap image is not saved and so refreshing is not
guaranteed. They can receive a bitmap to enable automatic redrawing.
To maintain compatibility, the MODAL type still exists, as a sub-set of the
GRAPHICS type, and denotes GRAPHICS windows that have the MODAL
attribute. This attribute gives the window input focus, which restricts user
events to this window only and makes input in this window mandatory.
By convention, primitives which only have an effect in a GRAPHICS window
have the prefix gr_.
TTY windows
These are text windows operating in write and read modes, always at the end
of the window. They produce a trace or listing and function like terminals, i.e.
everything displayed is non modifiable and input is in line mode, so that
provided the input line has not been finished it can be modified.
These windows have a limited capacity. If necessary, automatic truncation is
performed at the top of the window.
Let's now look at the other objects. They are designed to be placed on a window,
called the parent window. They move with their parent and cannot exist once it has
been deleted. Their size and position are defined by coordinates relating to the top
inner left-hand corner of the parent.
To determine the behavior of an object when the size of its parent changes, we can
define the attachment of the object to an edge of the parent window:
When an object is attached to one edge of the parent, this means that the
distance (defined when the attachment is created) between the edge and the
object is constant regardless of the changes in the parent's size.
© PrologIA
Aociation Prolog
U5-4 Windows User's Manual HERITAGE
Check button:
Two-state button. When activated it changes state and generates an event .
Push button:
Push button which generates an event when activated.
Radio button:
Exclusive two-state choice button. Radio buttons are organized in groups,
only one of which can be selected at a time. In particular, as soon as a button
in the group is activated it generates an event, and deselects the previously
selected button. When created, by default the first button in the group is
selected.
Drawing area:
Graphics zone designed for drawing, sensitive to keyboard and mouse
actions. It can contain text, entered by means of the normal writing methods.
By default the bitmap image is not saved, but the zone can be equipped with a
bitmap to provide automatic redrawing. The primitives prefixed by gr_ take
effect in this zone if it has been defined beforehand as the current graphics
zone (see gr_window).
Editfield:
Single or multi-line editing field. It generates an event when a character is
typed or when input focus is lost or obtained.
Label:
Non editable text zone, not affected by events. Is used only to display a text
whose redrawing is managed automatically.
Listbox:
List of items written in a rectangle, with a vertical scroll bar. Each item can
take two values: selected or not selected. Each time an item in the list box is
selected, an event is generated.
Popup menu:
Pulldown menu:
A menu groups a series of vertically arranged items. An item can either be a
terminal or a menu, in which case it is called a hierarchical menu. When a
terminal item is selected in the menu, an event is generated and the menu
disappears. There are two separate types of menu which differ because of the
way they are activated and the characteristics of the windows they can be
attached to.
© PrologIA
Aociation Prolog
Scrollbar:
Scroll bar with a scroll box (rectangle that moves in the bar) whose position
represents a location comprised in the range represented by the scroll bar. It
can be used as a gauge. Each time the scroll bar is activated, it generates an
event.
When Prolog starts, it has a menu bar and three predefined windows, one of which
is visible.
The visible window is the TTY type console window, which is by default the
current reading and writing unit. The reading and writing units can be
changed by the input and output primitives respectively.
init_screen
initializes graphics mode. This predicate is automatically started when the
graphic.mo module is loaded.
© PrologIA
Aociation Prolog
U5-6 Windows User's Manual HERITAGE
end_screen
de-installs graphics mode, i.e. it closes the windows, cancels the menus and
suppresses access to the graphics predicates.
get_screen(x,y)
get_screen(x,y,N)
x and y are unified with the width and height of the screenr espectively, in
pixels. In the three argument version, N is unfied with 1 if the screen only has
two colors (black and white), or otherwise with a higher number.
graphic_system(s)
Unifies s with a character string that varies depending on the host graphics
system:"M" for Motif, "W" for Windows3, "P" for Presentation Manager.
The file int_edit.mo enables you to use the built-in editor by means of the edit and
editm predicates, instead of the editor defined by the environment variable
PrologEdit. To do this, you must execute the following goals:
> reload("int_edit.mo");
> exit("initial.po"); (if you want to avoid having to repeat the
previous command the next time Prolog starts).
In all the following rules, x and y stand for horizontal (x) and vertical (y)
coordinates. The direction of the x's positive axis is to the right. The direction of
the y's positive axis is downwards. Remember that the default origin (i.e. x=0, y=0)
coincides with the top inside left-hand corner of the reference element. The
reference element is the current graphics window for drawing, the parent window for
an object which is not a window, and the screen for a window.
Variables starting with r will represent trees defining a rectangle. These trees must
have one of the following forms:
<x1,y1>.<x2,y2> or <x1,y1,x2,y2>
where x1,y1 are the coordinates of the top left-hand corner, and x2,y2 are those of
the bottom right-hand corner.
The term boolean will refer to an integer that takes the values 0 or 1 and is used as a
truth value for a property (object visibility etc.).
© PrologIA
Aociation Prolog
You can name an object using a string, and this identification can be used for all the
primitives used to create and manage objects. You can also allow Prolog to assign
the object a default identification (this will be an integer) when it is created (leaving
one free variable). This identification can be used subsequently for all the object
management primitives. Or else, for objects that are not windows you can name
them using an identifier that will be valid for all the primitives affecting these
objects.
new_window(s,t)
s new_window(s,t,s')
new_window(s,t,v,r)
s new_window(s,t,v,s',r)
new_window(s,t,v,x1,y1,x2,y2)
s new_window(s,t,v,s',x1,y1,x2,y2)
These rules create a new window, and a new I/O unit called s of type t. The
name must not have been used already for existing units, and it can be a
string. If s is a free variable when the call is made, it will be unified with a
window identification provided by Prolog.
The character string s' is displayed in title bar of the window. If s' is not
specified, s is displayed.
v is a boolean (1 or 0) indicating whether or not the window is visible. By
default the window is visible.
x1,y1 are the new coordinates of the top inside left-hand corner of the window,
in relation to the screen.
x2,y2 are the coordinates of the bottom inside right-hand corner of the new
window. The origin is the top left-hand corner of the screen.
t has the form type, or type.attributes_list where type determines the type of
window and therefore the type of operations that can be applied to it.
The possible values for type are:
"EDIT" or :edit
to create an EDIT window.
s "FRAMEPANEL" or :framepanel
to create a FRAMEPANEL window.
"GRAPHICS" or :graphics
to create a GRAPHICS window.
"MODAL" or :modal
to create a GRAPHICS window with the MODAL attribute.
"TTY" or :tty
to create a TTY window.
© PrologIA
Aociation Prolog
U5-8 Windows User's Manual HERITAGE
© PrologIA
Aociation Prolog
create_window(s,t,s',r1)
create_window(s,t,v,s',r1)
create_window(s,t,v,s',r1,r2)
Similar to new_window, but can be used 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 section of the window in a screen [0,1] *
[0,1].
r2 has the form <x1,y1,x2,y2> where x1,y1,x2,y2 are integers defining a
user's local coordinate system. This parameter is only to be specified for
GRAPHICS and FRAMEPANEL windows. If parameter r2 is not
specified, the graphics coordinates in the window will be given in pixels.
For example, if a window is created by the following call:
> create_window("mywindow", "GRAPHICS", 1, "mywindow",
<0.1E0,0.1E0,0.6E0,0.7E0>, <0,0,100,100>);
kill_window(s)
Deletes the window s, which must not be a predefined window (i.e. it must
have been created by new_window or create_window). If the deleted window
was the current input or output, the previously active input or output unit
becomes active again. If the deleted window was the current graphics window,
the predefined "graphic" window becomes the current graphics unit. For
more information please refer to the kill_object predicate.
clear_window(s)
Erases the contents of the window s. It does not modify any of the window's
objects or delete events linked to the window that are in the Prolog queue. It
is valid for any type of window (but has no effect on a FRAMEPANEL
window).
file_window(s1)
file_window(s1,s2)
Create an EDIT 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).
© PrologIA
Aociation Prolog
U 5 - 10 Windows User's Manual HERITAGE
front_window(s)
Unifies s with the name of the Prolog window that is on top and has the input
focus.
get_window(s,v)
get_window(s,v,x1,y1,x2,y2)
s get_window(s,t,v,x1,y1,x2,y2)
Gives information about the type, attributes, visibility and coordinates of
window s. The two argument version just gives information about visibility.
By backtracking, unifies the parameters s,t,v,x1,y1,x2,y2 in sucession with the
values corresponding to each window. Please refer to the
new_window(s,t,v,x1,y1,x2,y2) primitive for the meaning of the parameters.
The type and attributes are given in identifier form. The value of the :distance
attribute is now given in pixels, instead of a percentage of the drawable part as
previously.
gr_window(s)
The graphics window s becomes the current graphics unit.
gr_window_is(s)
Unifies s with the name of the current graphics unit.
print_window(s)
print_window(s,f,t)
Prints the contents of text window s with the font f of size t. The same
conventions apply as for gr_text(f,t,l) (See 5.5. Drawing and writing mode).
The one argument version prints the window with its current font.
gr_print(s)
gr_print(s,_rx,_ry,x0,y0)
gr_print(s,r1,r2)
Prints the contents of the graphics window s. The zone to print can be
specified by means of the third version. It is the contents of rectangle r1, and
the result on paper is located in rectangle r2. Any reductions and translations
are automatically performed. The single argument version prints the window
without modifying the format.
The 5 argument version is used to specify the reduction according to the X
and Y axes, in the form of two numbers _rx and _ry between 0e0 and 1e0.
The position of the printing origin on paper can be entered in x0 and y0.
© PrologIA
Aociation Prolog
> gr_print("graphic",0.5e0,0.5e0,0,0);
reset_window(s)
Repositions the cursor at the beginning of the EDIT window called s. The
rule fails is s is not an EDIT window created by new _w indow or
create_window. The point of writing is still the end of the text.
save_window(s1)
save_window(s1, s2)
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)
This rule enables you to modify the attributes and visibility of a window. s
identifies the window, b can either be an attribute (see new_window) or a
boolean indicating whether the window will be visible (1) or invisible (0).
The possible attributes for graphics and modal windows are as follows:
<"SAVE", v > when v is a boolean
This predicate can also be used with this attribute for a drawing area.
It's identification is then s.
If v =1, the system creates a refreshment bitmap for the size of the
object.
<"SAVE", r > where r is a rectangle.
For a text window:
<"FONT", n >
<"FONTSIZE", n >
Example:
> set_window("console",<"FONTSIZE",12>);
set_window(s,b,x1,y1,x2,y2)
This rule is used to modify the visibility, size and position of windows.
s window name (character string or integer), such as "console", "graphic"
or "trace" for the predefined windows.
b boolean flag indicating whether the window will be visible (1) or
invisible (0).
x1,y1 new coordinates of the top inside left-hand corner of the window, in
relation to the screen.
x2,y2 new coordinates of the bottom inside right-hand corner of the window.
The origin is the top left-hand corner of the screen.
Example:
> set_window("graphic",1,50,50,300,300);
© PrologIA
Aociation Prolog
U 5 - 12 Windows User's Manual HERITAGE
If this method is not used, a graphics units coroutine is available which is activated
whenever these units require graphics refreshing. This coroutine is:
exec(:gr_update(u))
where u represents the name of the unit. The :gr_update rule is not defined in the
standard environment, and is not started if the user does not define it. By writing a
:gr_update/1 rule, the user can therefore define the refreshing of the graphics units,
without using an auxiliary bitmap.
These primitives are not sufficient to manipulate and configure menus completely.
The menu primitives that do this are described in 5.4.
You can modify the default attachments of objects by adding the attributes
:top_attach, :left_attach, :bottom_attach, :right_attach to the list of creation
options. Use the :top_attach and/or :bottom_attach attributes to modify the vertical
attachment, and the :left_attach and/or :right_attach attributes to redefine the
horizontal attachment.
© PrologIA
Aociation Prolog
A Prolog program can be linked to the events (if any) occurring on the created
object. As soon as the events take place, the current Prolog program is suspended
and the predicate associated with the object is started. The predicate's first argument
is the identification of the object, and a possible second argument may be additional
information (character typed, etc). When the predicate terminates, the suspended
proof carries on as normal. In this way it is possible to manage graphics screen
input "live".
It is also possible to delay the processing of entered data or events, by simply
specifying sys:get_event instead of the predicate. The event will be put into the
Prolog events queue (it can be monitored using get_event or cleared using
clear_events).
It is also quite possible to do nothing. Simply specify nil to replace the predicate,
and the object's events will be ignored.
s kill_object(o)
Deletes object o. Is valid for any object.
s new_check_button(o,p,v,s,b,<x1,y1,x2,y2>)
Creates a check button identified by o, containing a text s. The button and text
will be written in a rectangle with coordinates x1, y1, x2, y2 in the parent
window p. Visibility is determined by the value of v.
x2 and y2 must be free. They are unified with the coordinates of the bottom
inside right-hand corner of the object when it has been created.
b can be nil, sys:get_event or a rule identifier. In this last case, each time the
button is activated, the goal b(o) is started.
s new_drawing_area(o,p,v,<x1,y1,x2,y2>,r2,l)
s new_drawing_area(o,p,v,<x1,y1,x2,y2>,l)
Creates a graphics area identified by o. It is drawn in a rectangle whose
coordinates are x1, y1, x2, y2 in the parent window p. Its visibility will depend
on the value of v. r2 has the same meaning as in the create_window
predicate (local coordinate system). l is a possibly empty (nil) list of options
formed by the identifiers:
:no_border if you don't want a border around the area.
:save to have a save bitmap.
:top_attach, :left_attach, :right_attach, :bottom_attach
s new_push_button(o,p,v,s,b,<x1,y1,x2,y2>)
s new_push_button(o,p,v,s,b,<x1,y1,x2,y2>,l)
Creates a push button identified by o, containing a text s, whose coordinates
are x1, y1, x2, y2 in the parent window p. Visibility is determined by the value
of v.
If x2 and y2 are free they are unified with the coordinates of the bottom right-
hand corner of the object, when it has been created.
© PrologIA
Aociation Prolog
U 5 - 14 Windows User's Manual HERITAGE
b can be nil, sys:get_event or a rule identifier. In this last case, each time the
button is activated, the goal b(o) is started. l is a possibly empty (nil) list of
options formed from the identifiers:
:buttonD is used to define it as the "default button", i.e.any carriage
returns not detected by another object will activate this button. These buttons
are designed so that there is one for each window. If this is not the case,
behavior is not guaranteed, and depends on the host system.
:top_attach, :left_attach, :right_attach, :bottom_attach
s new_radio_button(o,g,p,v,s,b,<x1,y1,x2,y2>)
Creates a radio button identified by o, containing a text s. g is a Prolog
identifier representing the group comprising the button. The button and text
are written in a rectangle with coordinates x1, y1, x2, y2 in the parent window
p. Visibility is determined by the value of v.
x2 and y2 must be free. They are unified with the coordinates of the bottom
inside right-hand corner of the object when it has been created.
b can be nil, sys:get_event or a rule identifier. In this last case, each time the
button is activated, the goal b(o) is started.
s new_label(o,p,v,s,<x1,y1,x2,y2>,l)
Creates a label identified by o, containing a text s, written in a rectangle with
coordinates x1, y1, x2, y2 in the parent window p. Visibility will be determined
by the value of v.
If x2 and y2 are free they are unified with the coordinates of the bottom inside
right-hand corner of the object, when it has been created.
l is a list of options, which may possibly be empty (nil), formed by the
following identifiers:
:left for left-aligned text in the rectangle.
:right for right-aligned text in the rectangle.
© PrologIA
Aociation Prolog
s new_popup_menu(o,p)
Creates a popup menu support identified by o, attached to the window p. No
item is created. To create an item use the set_menu primitive.
Note: it is not necessary to create a popup menu support before using the
set_menu primitive. If set_menu is used with the name of a window, it refers
to that window's popup menu. If the menu does not exist, set_menu creates it,
but its identification is not known.
s new_pulldown_menu(o,p,s)
Creates a pulldown menu identified by o, with the name s (character string),
and attached to the window p. Its items will then be created by the set_menu
primitive. Is not valid for frame shaped windows.
The sequence of goals below creates a customized titled popup menu
consisting of the list of items: "myColor", "myMode", "myFont", "myPen".
The procedures myColor/1, myMode/1, myFont/1, myPen/1 are attached to
each item respectively.
> new_pulldown_menu(mymenu,mygraph,"custom");
© PrologIA
Aociation Prolog
U 5 - 16 Windows User's Manual HERITAGE
> set_menu(mymenu,nil,myColor.myMode.myFont.miPen.nil);
> set_menu(mymenu,"miPen".nil,myPen);
s new_scrollbar(o,p,v,b,<x1,y1,x2,y2>,l)
Creates a scrollbar identified by o, with coordinates x1, y1, x2, y2 in the
parent window p. Visibility is determined by the value of v.
If x2 and y2 are free they are unified with the coordinates of the bottom inside
right-hand corner of the object, when it has been created.
b can be nil, sys:get_event or a rule identifier. In this last case, each time the
scrollbar is activated, the goal b(o,n) is started.
l is a list of options, which may possibly be empty (nil), formed by the
following identifiers:
:vscroll for a vertical scrollbar.
:hscroll for a horizontal scrollbar.
:top_attach, :left_attach, :right_attach, :bottom_attach
The default orientation is determined by the coordinates, given that the length
of a bar is greater than its width.
s get_attribute(o,a,v)
Supplies information about the state or properties of objects.
o is the object identification.
a is the attribute identification.
v will be unified with the value of the queried attribute.
The possible attributes are the same as for the set_attribute primitive, except
for the focus and customColor attributes. The following attributes which are
added are properties of non-modifiable creation:
:parent: v is unified with the identification of the parent of object o.
:type: v is unified with an identifier representing the type of the object o. The
possible values are: :graphics, :tty, :edit, :framepanel, :label,
:push_button, :check_button, :radio_button, :scrollbar, :edit_field,
:popup_menu, :pulldown_menu, :listbox
:fontheight: v is the height in pixels of the font used by the object. The font
height is the height of the rectangle containing the characters (including
the line space).
:group: v is unified with the identifier of radio button group o.
:items_nb: v is unified with the number of items in the list box o.
s set_attribute(o,a,v)
Is used to modify or specify the configuration of objects .
o is the object identification.
a is the attribute identification.
v is the attribute value.
© PrologIA
Aociation Prolog
The possible attributes are determined by the type of object. The general
attributes are as follows:
:activity: indicates whether the object or menu item reacts to events or not. v's
value is 1 or 0 respectively. Is not valid for labels.
:background: concerns the background color of the object. v is an integer or
identifier and complies with the same conventions as those applying in the
gr_color2 primitve (see 5.5. Drawing and writing mode).
:bottom_right: concerns the position of the outside bottom right-hand corner
of the object. v has the form <p1, p2> where p1 is the abscissa and p2 is
the ordinate. It resizes the object. Is not valid for menus.
:cursor: concerns the mouse pointer shape when it is inside window o. v is
one of the following identifiers: :default, :wait, :cross. For set_attribute,
if the value of o is nil, the definition is valid for all the windows.
:customColor: defines the user color for object o. v has the form <_r, _g,
_b> where _r, _g _b are integers or reals and represent the color in red,
green and blue components, as defined in the gr_color3 primitive (see
5.5. Drawing and writing mode). This attribute is not valid for the
get_attribute primitve.
:focus: gives the input focus to the object o. v is ignored. This attribute is not
valid for the get_attribute primitive.
:font: concerns the font used by the object. v is an identifier that has the same
meaning as in the gr_font primitive (see 5.5. Drawing and writing mode).
The font defines the style and the size. The size can be obtained using the
get_attribute primitive with the fontheight attribute.
:foreground: concerns the color for drawing an object (text or drawing). v is
an integer or identifier and complies with the same conventions as in the
gr_color2 primitve (see 5.5. Drawing and writing mode).
:predicate: v is the Prolog predicate attached to the object. It is not valid for
labels (they are not sensitive) or menus and their items (please refer to the
set_menu primitive for more information).
Note: it can be used for graphics units. It then corresponds to the
predicate that must be started when an expose event occurs (it is
necessary to redraw part of the unit) and the unit does not have a bitmap.
The default value assigned is gr_update.
Note: take care not to confuse this predicate with the predicate that starts
on a click event. This predicate is linked to an area of the unit (please
refer to the gr_sensitive predicate for more details), and cannot be
modified by set_attribute.
:protected allows to disable close option in the default menu of a window.
:rank: concerns the numbering of the objects in their parent. v is the local
rank of the object in its parent. This number is unique for any given
parent, and it is implicitly the creation order number. This attribute is not
valid for windows.
:state: concerns the state of the selected or unselected object. The value of v is
1 or 0 respectively. Is only valid for check buttons and radio buttons.
© PrologIA
Aociation Prolog
U 5 - 18 Windows User's Manual HERITAGE
:text: concerns the text of an editing field, a title bar, the label of a button type
object or label. In general, v is a character string. For an editing field, v
can take the form <s, 1> signifying that the character string s must be
added (append mode) to the content of the editing field.
:text_selection: concerns selection in an editing field. v has the form <p1,
p2> where p1 is the index of the first selected character (starts at 0), p2 is
the index folowing the last selected character, and p2 >= p1.
:top_left: concerns the position of the top left-hand corner of the object. v has
the form <p1, p2> where p1 is the abscissa, and p2 is the ordinate. It
moves the object. Is not valid for menus.
:user_field: concerns the user field, which Prolog does not manage at all. v is
an integer. The programmer can use it for example as a global variable
associated with the object.
:visibility: concerns the visibility of the object. The value of v is 0 if the object
is invisible, 1 if it is visible, or 2 if the object is an iconized window. Is
not valid for menus.
:width_height: v has the form <p1, p2> where p1 is the width of the object
and p2 is its height. Is not valid for menus.
The following attributes are specific to listbox:
:items: concerns the list of list box items. v is a list of Prolog strings that
describes all the list box items by their text, in the same order.
:selected_items: concerns the list of selected items in a list box. v is the list of
ranks of the selected items. If more than one rank is given for a list box
in simple selection mode, the last selection will be taken into account.
:state(i): concerns the state of a selected or unselected list box item. v has the
value 1 or 0 respectively. i is an integer for the number of the relevant
item in the list box. The first list box item is represented by the integer 1.
:text(i): concerns the text of a list box item. i is an integer for the number of
the relevant item in the list box. The first list box item is represented by
the integer 1. v can have different values, determined by the following
circumstances:
– Query on the text of an item. v is a character string. If the item does
not exist, v is the empty string.
– Modification of an item's text. i is an existing item number, and v is a
non empty character string.
– Deletion of the item. i is an existing item number, v is the character
string.
– Creation of the item. i is a non-existent item number and v is a
possibly empty character string.
– Insertion of the item. v has the form <p1, 1> where p1 is any
character string for the text of the item created at the position denoted
by i.
:toplist: v is the number of the first visible item in the list box.
© PrologIA
Aociation Prolog
s get_local_object(p, n, o)
Unifies o with the identification of the object whose parent is p and has a local
rank of n in p.
s get_objects(p,l_o)
Unifies l_o with the list of objects whose parent is p.
s get_event(b,e,o)
Tests whether an event whose type is defined by e concerning object o is
present in the Prolog events queue. If it is present, the first corresponding
event (the oldest one) is read and therefore deleted from the queue, and the
system attemps to unify the arguments. Otherwise get_event acts according to
the value of b, which must be known when the call is made.
If the value of b is 0, get_event does not block, and generates backtracking.
If the value of b is 1, get_event blocks. The system waits for the event, reads it
and finally attempts unification.
o is either the identification of an object, or a free variable. In the latter case,
all the objects are concerned.
e is either a free variable, in which case all events are concerned, or has the
form:
:char(c): for editing fields and GRAPHICS windows, where c is the character
code.
:click: for a button (push, check or radio) or a scrollbar. No result is
transmitted, only a success or a failure.
:click(i,m): for the menus or list boxes, where i is the number of the selected
item and m specifies the state of the main modification keys. m is the
sum of the following values:
1 if the SHIFT key is pressed,
© PrologIA
Aociation Prolog
U 5 - 20 Windows User's Manual HERITAGE
s peek_event(b,e,o)
Same method and values as the get_event(b,e,o) primitive, but just consults the
event queue without modifying it. The event e for object o is not deleted from
the queue.
s clear_events(e,o)
Clears all events defined by e concerning the object o without any unification.
This predicate never fails. e complies with the same conventions as for
get_event(b,e,o).
All menus are attached to a window, whether they are popup or pulldown. A special
support for general application menus does exist however, called the Prolog menu
bar.
© PrologIA
Aociation Prolog
clear_menubar
Calls save_menubar and then erases the standard menu bar. This primitive is
used to redefine the menu bar completely.
clear_menubar(w)
Clears the menu bar in window w.
s restore_sysmenus(s,f,e)
Adds the "File" and "Edit" system menus to the menu bar of window s and
unifies their names with f and e. The variable remains free if the menu does
not exist.
save_menubar
Memorizes the current menu bar. This rule can only be called once.
restore_menubar
Restores the menu bar saved using save_menubar.
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 insert the Apple menu
"file" : to insert the File menu
"edit" : to insert the Edit menu
"find" : to insert the Find menu
"control" : to insert the Control menu
"window" : to insert the Window menu
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 called u.
The meanings of each argument are as follows:
u (unit) Represents the relevant menu. 0 for a menu in the menu bar,
the identification of a window for the popup menu associated with it, or the
identification of a menu (popup or pulldown).
© PrologIA
Aociation Prolog
U 5 - 22 Windows User's Manual HERITAGE
v (value) Tree describing the value which replaces the item at the
position indicated by p, in the menu u. This value can either be a leaf, or a
hierarchy.
When the menu is selected, the current program is suspended, and the goal
Identifier(u) is immediately activated. If the goal terminates without any
errors, the program continues as normal, otherwise the error is propagated by
the block_exit mechanism.
Example: let us suppose that an editing window "menu.p2" is open:
> set_menu( 0
, ["Control","Compile the window"]
,<"Compile the window",compiling_win>)
set_menu( "menu.p2"
, ["Compile"]
,<"Compile",compiling_win>);
{}
>
insert;
compiling_win(0) -> front_window(u) reinsert(u);
compiling_win(u) -> string(u) reinsert(u);;
{}
>
© PrologIA
Aociation Prolog
File
Do
Size 1
2
3
File
Do goal1
Size Stop
When set_menu is used for the menu bar, i.e. with u equal to 0, the menu
created on the bar is a pulldown menu. The title of the pulldown menu is
represented by the first string in the path p, or if the value of p is null, the first
string whose value is v. This menu's identification is a string; the title string
when the menu is created. Subsequent modifications of the title do not
modify the menu's identification. This identification can be useful for other
primitives, such as kill_object, get_attribute…
Example:
> set_menu(0,"new".nil,<"colors",black.grey.white.nil>);
The identification of the menu created by this call is "new", and its title is
"colors".
> set_menu(0,nil,colors.black.grey.white.nil);
The identification of the menu created by this call is "colors", and its title is
"colors".
> set_menu(0,"colors"."black"."white"."else".nil,else);
The identification of the menu created by this call is "colors", and its title is
"colors".
© PrologIA
Aociation Prolog
U 5 - 24 Windows User's Manual HERITAGE
In the primitives below, the first and second arguments comply with the same
conventions as for set_menu :
check_item(u,p,v)
This primitive checks an item or removes the check, depending on the value of
v: 0 = not checked, 1 = checked with the standard checking mark.
If v is an integer greater than 1, the host machine character whose code v is
used as the checking mark.
Example:
> check_item(0,"Windows"."trace".nil,1);
command_menu(u,p,v)
v is the code of the character used with the command key ( ) as a keyboard
equivalent to activate the item specified by the first two arguments.
Example of how to create the keyboard equivalent T to activate the Prolog
trace.
> char_code("T",n)
command_menu(0,"Control"."trace".nil,n);
s The character used as a keyboard abbreviation is a character belonging
to the menu item’s text. It is denoted when the menu or item is defined.
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".nil,0);
style_menu(u,p,v)
Specifies the style of a menu. v is an integer in which each bit represents one
of the styles specified in the order defined 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,"Windows"."trace".nil,6);
The set of primitives described in this section affect the properties of the current
graphics unit (which can be either a GRAPHICS window or a drawing area).
© PrologIA
Aociation Prolog
gr_color3(r,g,b)
Defines the color of the current graphics unit in components: r red, g green, b
blue. If the values are reals, they correspond to percentages of intensity for
each component. They must be between 0e0 and 1e0, and can be ported from
one machine to another. If the values are integers, they must be between 0 and
65535. This color is memorized as the customColor of the current graphics
unit.
gr_color(d,c)
Defines the color of the background (if d= 0) or of the pen (if d=1) in the
current graphics unit. The argument p is an integer representing one of the
following 8 colors: 33:black, 30:white, 205:red, 341:green, 409:blue 273:cyan,
137:magenta, 69:yellow.
s gr_color1(d,c)
Defines the color of the background (if d= 0) or of the pen (if d=1) in the
current graphics unit. The argument c represents a color, using the same
conventions as the gr_color2 primitive.
gr_color2(b,p)
Defines the color of the background b and of the pen p in the current graphics
unit. The arguments b and p are integers or identifiers representing one of the
following colors:
0 :white
1 :red
2 :green
3 :blue
4 :pink
5 :orange
6 :brown
7 :magenta
8 :purple
9 :cyan
10 :yellow
11 :lightGrey
12 :darkGrey
13 :black
14 :defaultColor (system color)
15 :customColor (user color defined by gr_color3).
Note: the integer form is less explicit than the identifier form. In the
configuration query primitives (get_attribute(ob1, :background, x)), Prolog
returns the values in the identifier form.
© PrologIA
Aociation Prolog
U 5 - 26 Windows User's Manual HERITAGE
gr_choosecolor(p,s,i,f)
Displays the color selection dialog at point p (in the form <x,y>) on the
screen. s is a string that will be displayed in the dialog. i and f are integer
triples between 0 and 65535 in the form <r, g, b> representing a color in
components of r: red, g: green and b: blue. i is the initial dialog color and
must be known when the call is made, f will be unified with the chosen color.
Fails if the user clicks the Cancel button.
gr_pen(w,p)
gr_pen(w,h,p)
Defines the size in pixels and the pattern of the pen in the current graphics
unit.
w = width,
h = height,
p = pattern, which is an integer or an identifier.
p p
0 :clear
1 :solid
2 :halfPattern
3 :lightPattern
4 :darkPattern
Note: the integer form is less explicit than the identifier form. In the
configuration query primitives (gr_get_pen(l, h, m)), Prolog returns the values
in the identifier form.
s gr_get_pen(w,p)
s gr_get_pen(w,h,p)
Indicates the size and pattern of the pen in the current graphics unit. w,h,p
have the same meaning as in the primitive gr_pen(w,h,p). Prolog returns an
identifier for the pen pattern.
gr_stringwidth(s,n)
Unifies n with the length of the string s according to the current font, size, and
style defined for the current graphics unit.
gr_mode(b,p)
Defines the pattern application mode on the background, for the current
graphics unit.
b=0 Concerns drawing, and therefore the pen pattern.
b=1 Concerns text, and therefore the pattern corresponding to each
character.
There are four basic operations: Copy, Or, Xor and Bic.
The Copy operation simply replaces the target pixels with the pixels in the
pattern or source. The target pixels are "painted over" without regard to their
initial state.
© PrologIA
Aociation Prolog
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 (adds) replaces them with black pixels.
Xor (inverts) inverts them.
Bic (deletes) replaces them with white pixels.
Depending on the mode, the operation is either performed on the pattern itself
(src) or on its inversion (notSrc).
For color machines, the white part of the pattern corresponds to the
background color part, the black part of the pattern corresponds to the
pen color part, and the inverted color is determined by the machine.
Here are the values of p for the different modes.
p p application modes
0 :srcCopy srcCopy
1 :srcOr srcOr
2 :srcXor srcXor
3 :srcBic srcBic
4 :notSrcCopy notSrcCopy
5 :notSrcOr notSrcOr
6 :notSrcXor notSrcXor
7 :notSrcBic notSrcBic
Note: the integer form is less explicit than the identifier form. In the
configuration query primitives (gr_get_mode(1, x)), Prolog returns the values
in the identifier form.
s gr_get_mode(b,p)
Indicates the pattern application mode in the current graphics unit. b, p have
the same meaning as in gr_mode(b,p). Prolog returns the mode as an
identifier.
gr_text(f,s,l)
Defines the font, size and style of output in the current graphics unit. f = font
number; s = font size; l = 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 |
© PrologIA
Aociation Prolog
U 5 - 28 Windows User's Manual HERITAGE
...
The empty list represents normal text. The default combination is
gr_text(4,12,nil).
For example gr_text(3,18,1.3.4.nil) 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.nil)
output("graphic") outm("Hello") output("console");
s gr_font(f)
Loads the font represented by f for the current graphics unit. The basic font is
the font proposed automatically by the system and is denoted by :ftdefault .
The other available fonts take the form :ft(i) or i, where i is an integer between
1 and 50. The correspondances between the integer and the name of the host
system's font is defined in the fonts.usr file. You can take a look at all the
available fonts, when Prolog has been started for the first time, in the fonts.all
file (created when graphics starts up).
Example:
> gr_font(:ft(2));
gr_setorigin(x,y)
Changes the origin of the axes so that x,y represent the coordinates of the top
inside left-hand corner of the current graphics unit. The window's appearance
is not modified.
s gr_getorigin(x,y)
Indicates the coordinates of the top inside left-hand corner of the current
graphics window installed by gr_setorigin
gr_penloc(x,y)
Returns the integer coordinates of the pen position in the current graphics
unit.
© PrologIA
Aociation Prolog
gr_penlocr(x,y)
Identical to gr_penloc(x,y) but gives a real number result.
gr_erase
Erases the contents of the current graphics unit, positions the pen in the top
left-hand corner and deletes all events linked to the unit and its objects.
gr_move(x,y)
Moves the pen position x horizontal pixels and y vertical pixels from its
current position.
gr_moveto(x,y)
Positions the writing point (pen) in the current graphics unit at x,y.
gr_line(x,y)
Draws a line from the current pen position to a new position x pixels away
horizontally and y pixels away vertically.
gr_lineto(x,y)
Draws a line by moving the pen from the current position to point (x,y).
gr_rect(n,r)
gr_rect(n,x1,y1,x2,y2)
Produce calls to the basic routines for drawing in a rectangle.
r is the tree denoting the rectangle. x1,y1 are the coordinates of the top left-
hand corner, and x2,y2 are those of the bottom right-hand corner of the
rectangle.
The first argument n, which is an identifier or integer, determines which
procedure is called:
0, :frameRect, :frame
Draws the perimeter of the rectangle.
1, :paintRect, :paint
Fills the rectangle with current pen-pattern.
2, :eraseRect, :erase
Erases the contents of the rectangle.
3, :invertRect, :invert
Inverts the color of each point inside the rectangle. If the rectangle
contains colors other than black and white, the results depends on the
machine.
4, :frameOval
Draws the oval in the rectangle.
© PrologIA
Aociation Prolog
U 5 - 30 Windows User's Manual HERITAGE
5, :paintOval
Fills the oval with current pen-pattern.
6, :eraseOval
Erases the contents and perimiter of the oval.
7, :invertOval
Inverts the bits of the oval. If it contains colors other than black and
white, the result depends on the machine.
8, :frameRoundRect
Same as :frameRect but with rounded corners.
9, :paintRoundRect
Same as :paintRect but with rounded corners.
10, :eraseRoundRect
Same as :eraseRect but with rounded corners.
11, :invertRoundRect
Same as :invertRect but with rounded corners.
12, :clipRect
Subsequent drawings will only be drawn inside the rectangle, i.e. a
visibility rectangle is defined for all future drawings. To cancel this
action, repeat it with the coordinates of the screen.
gr_polygon(n,L)
Draws a polygon in the current graphics unit. L is a list of <x,y> (or <> (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 the current pen-pattern.
2, :erase
Erases the contents of the polygon (some broken lines forming the
polygon contour may remain).
3, :invert
Inverts the color of each point inside the polygon. If the polygon
contains colors other than black and white, the result depends on the
machine.
gr_arc(n,r,a1,a2)
gr_arc(n,x1,y1,x2,y2,a1,a2)
Draws an elliptical arc inside the rectangle r between the angles a1 and a2.
Angles a1 and a2 are given in degrees.
The first argument n, which is an integer or identifier, determines which
procedure is called:
© PrologIA
Aociation Prolog
0, :frame
Draws the elliptical arc.
1, :paint
Fills the sector defined by the elliptical arc with the pen pattern.
2, :erase
Erases the arc and the sector.
3, :invert
Inverts the color of each point inside the elliptical sector. If it contains
colors other than black and white, the result depends on the machine.
> 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 in the rectangle r between the angles a1 and a2. a1
and a2 are given in degrees. The arguments are the same as for gr_arc but
the origin is on the vertical axis, a2 is relative to the position a1, and the
positive direction is clockwise.
> gr_arc'(:frame,100,100,200,170,20,30);
© PrologIA
Aociation Prolog
U 5 - 32 Windows User's Manual 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 specified rectangle. The software first
searches for this resource in the Prolog II+ executable file, and then in the
system file. The system always contains the following icons:
0 Stop.
1 Note.
2 Caution.
The best results are obtained by giving a square with equal sides of 32 as the
rectangle.
gr_load(s)
Draws the contents of graphics file s in the current graphics unit. This
graphics file is a non-Prolog II+ file and is created using any graphics editor
from the host system. It is possible to draw selected parts of a file in different
locations, using the primitives gr_setorigin and gr_rect(:clipRect,..).
© PrologIA
Aociation Prolog
gr_click(b,x,y)
Tests whether a mouse button has been pressed since the last call to gr_erase
or gr_click. If a click has indeed occurred, x and y are unified with the
coordinates of the click position in the current graphics unit. Otherwise, the
primitive is controlled by b, a boolean value which must be known when the
call is made and has the following meanings:
b=1 The system waits for a click in the current graphics unit.
b=0 The system doesn't wait, and performs backtracking.
s gr_click(b,x,y)
Tests whether a click event in the current graphics unit is present in the event
queue. If it is, x and y are unified with the click coordinates in the current
graphics unit, and the event is removed from the queue. Otherwise the
primitive is controlled by b, a boolean value which must be known when the
call is made and has the following meanings:
b=1 The system waits for a click in the current graphics unit.
b=0 The system doesn't wait, and performs backtracking.
Please refer also to the get_event primitive.
gr_click(b,x,y,m)
Identical to gr_click(b,x,y) but also indicates the state of the main modification
keys, by unifying m with the sum of the following values:
1 The SHIFT key is pressed.
2 The CONTROL1 key is pressed.
4 An option key is pressed (OPTION on Mac).
8 The COMMAND key is pressed.
16 The SHIFT-LOCK key is kept down.
s 32 A DOUBLE_CLICK is carried out.
gr_clickr(b,x,y)
Identical to gr_click(b,x,y) but xand y are reals.
© PrologIA
Aociation Prolog
U 5 - 34 Windows User's Manual HERITAGE
s gr_sensitive(x1,y1,x2,y2,p)
Defines the rectangle with coordinates x1,y1,x2,y2 in the current graphics unit f
as a click-sensitive zone, to which the predicate p is attached. If p is not the nil
or get_event identifier, each time a click occurs inside the rectangle, the goal
p(f) will be launched. By default, all the zones are defined with get_event, and
so all clicks in the unit are sent to the Prolog event queue.
gr_sensitive(x,y,x',y',nil) is used to ignore the clicks in the defined zone.
The various defined rectangles must be disjoined. If this is not the case, and a
click occurs in a common zone, the result cannot be guaranteed. One of the
zones will sense the click, but it is not possible to know which one.
gr_getmouse(x,y)
gr_getmouse(x,y,b)
Gives the current mouse position in the current graphics unit, in integer
coordinates relative to the unit origin. b=0 if the mouse button(s) is/are not
pressed, otherwise b equals the number of the pressed button, starting from
the left for a multi-button mouse (the first button is number 1).
gr_getmouser(x,y)
Identifcal to gr_getmouse(x,y) but produces a real number result.
To use the two primitives described below, you must first load the drawing module
dessin.mo.
gr_draw_buttons(b)
Draws all the buttons of the database whose access identifier is b. The button
database is constructed by the user. It will assign a rule name to each group
of buttons. The rules must have three arguments:
- the rectangle the button is written in.
- the string displayed in the button.
- a term to associate with the button.
For example, the following user-defined buttons:
wtButton(<5,160>.<50,175>,"Edit",edit)->;
wtButton(<5,180>.<50,195>,"Set",nil)->;
are drawn by launching the following goal:
> gr_draw_buttons(wtButton);
© PrologIA
Aociation Prolog
gr_button_hit(b,<x,y>,t)
b is the access identifier for the button database. This rule succeeds if x,y are
the coordinates of a point inside one of the buttons in database b. t is then
unified with the third argument of the rule for the relevant button.
By combining the gr_click and gr_button_hit primitives, it is easy to write a
button monitoring loop.
s message_box(t,s,m,b,x)
Creates a modal graphics window to display a message. When the user has
pressed one of the buttons, the window is deleted and x is unified with the
number of the button. The window comprises:
- a title given by the character string s,
- an icon defined by the identifier t: :warning, :info, :question, :wait, :error.
The way the icon is drawn depends on the machine's graphics environment.
- a message given by the character string m,
- a line of buttons (maximum of 3), such that:
if b is an integer, there will be b buttons containing texts that depend on the
number of buttons, the type of icon and the machine's graphics environment.
if b is a list of strings, each string defines the text of a button.
gr_editf(<s1,p1,p2>,r,s,k)
gr_editf(<s1,p1,p2>,x1,y1,x2,y2,s,k)
These primitives create an editing field in the current graphics unit, which
must be a window. If the unit is a drawing area, an error is generated. To end
editing, hit the return key or a tab key, or click in the window outside the
editing field, but not on an object. If k is not a variable, the field and its text
are only drawn, without editing.
s1 is the initial string to place in the editor.
p1, p2 are integers defining the indices of the characters that start
(included) and end (not included) the text selection indicated by
highlighting. The first index is 0. Initialization of an empty field
corresponds to the values <"",0,0>.
r defines the position of the enclosing rectangle. Text is left-aligned.
x1,y1,x2,y2 are the coordinates of the top left-hand and bottom right-hand
corners of the rectangle in the window.
s is the variable that will be unified with the edited string.
© PrologIA
Aociation Prolog
U 5 - 36 Windows User's Manual HERITAGE
get_key(c)
get_key(a,t,m)
This primitive takes a character. There is no echo of this character in any
window, and so this primitive can be used to enter a pass word. Its operation
is described in detail in the paragraph about stty below.
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 primitve.
t=0
Default mode, in which get_key always fails. The characters typed are
inserted in the text windows if appropriate. In this mode, the user can edit text
windows while Prolog II+ is working.
t<0
get_key takes a character which cannot be older than t ticks (1 s = 60 ticks)
before the call. Fails if no character is available when the call is made, or if the
character is too "old".
t>0
© PrologIA
Aociation Prolog
get_key will wait for a character for no more than t ticks. It fails if no
character is found after this time. get_key doesn't wait for the time period to
end before executing, if a character is provided in time. A character can be
typed in advance. This mode makes it possible to enter a pass word in a
specified 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.
> 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. It is possible to type the character in advance.
get_key will succeed as soon as the character is obtained, without waiting for
the five seconds to elapse.
stty("FLUSH")
Removes all characters from the event queue. They are no longer available to
get_key. This 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
Aociation Prolog
U 5 - 38 Windows User's Manual HERITAGE
o
Describes one of the four following operations to perform:
<0> Draws only (no user input possible).
<1,k> Draws and takes control until a character input or click event
occurs in the window but outside the list. NEITHER THE CLICK
NOR THE CHARACTER ARE READ. Returns the following for
k:
0 : carriage return typed
1 : click outside the list
2 : TAB typed
<2,x,y,m>
Draws the list and processes the click x,y,m (given for example by
gr_click(?,x,y,m) ). Exits immediately afterwards.
<3,x,y,m,k>
Draws, processes the click (given for example by gr_click(?,x,y,m))
and takes control until a character input or click event occurs in the
window but outside the rectangle. Neither the click nor the character
are read.
Returns the following for k:
0 : carriage return typed
1 : click outside the list
2 : TAB typed
The click to end selection can be read by gr_click(0,x,y).
s Note: this function can also be carried out using the primitives to create and
handle listbox objects.
gr_popupItem(r,L,n1)
gr_popupItem(r,L,n1,n2)
Create popup menu items.
L is a list of constants. r is the rectangle in which item number n1 from list L
is displayed. If n2 is missing, the item is simply drawn. If n2 is present, a
menu presenting the list of choices L partially covers the item, and the
inversion of the fields is continued 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 its number (n1 if
no field is selected).
Example. Make the graphics window visible and type in the following
example:
> 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);
© PrologIA
Aociation Prolog
When you click in the window and keep the button pressed:
aa
bb
cc
dd
3
4
input(x)
output(x)
This facility is added to the input and output primitives, with x as a free
variable when the call is made. This facility asks the user for the file name
using a dialog box. The input or output unit is then changed as normal (see
input output), and the file is opened, if appropriate. In output, unifies x with
the complete file name. If the Cancel button is clicked in the file selection
dialog, the primitive fails and no action is performed.
sfgetfile(s)
s sfgetfile(s,Filter,InitialName,Point)
Displays a dialog area to enable you to view the names of those files on the
disk(s) that are filtered by Filter, and select one of them.
Point is a point in <x,y> format indicating the location of the dialog display.
This dialog comprises a list of choices for the proposed files, and an editing
field initialized with the string InitialName.
Unifies s with the user's selection. s is the complete file name (including the
access path and the selected name). The file is not opened. This rule fails if
the Cancel button is clicked.
sfgetfile(Point,Ltypes,Filter,S)
Displays a dialog area to enable you to view the names of those files on the
disk(s) whose type belongs to the list of types Ltypes, and to select one of
them.
Point is a point in <x,y> format indicating the location of the dialog display.
Ltypes is a list of file types which must be displayed. A type is a 4 character
string as defined in Inside Macintosh. For example: "TEXT"."APPL".nil
selects all text only or application files.
Filter is a filtering procedure to manage acceptance of the selected files. This
must be nil for the moment.
© PrologIA
Aociation Prolog
U 5 - 40 Windows User's Manual HERITAGE
S is unified with the user's selection. It has the form: <C,T,N> where C is the
creator (4 character string), T is the file type (4 characer string), and N is a
string indicating the access path and name of the selected file (the file is not
opened).
The rule fails if the Cancel button is pressed.
sfputfile(s)
Displays a dialog box to choose the name of a file to create, and unifies s with
the name and path of this file. The file is not opened. The rule fails if the
Cancel button is pressed.
sfputfile(Point,Prompt,InitialName,s)
Displays a dialog box to enable the user to choose a name, volume and
directory for a file.
The file name is entered at the keyboard in an editing field initialized with the
possibly empty string InitialName which must be a filename without a path.
If the user enters an existing filename, an alert gives a warning. The file is not
created or opened.
s is unified with the name and path confirmed by the user.
Point is a point in <x,y> format, indicating the location of dialog display.
Prompt is a possibly empty string, containing a message for the user at the
top of the dialog box.
The rule fails if the Cancel button is pressed.
gr_tree_click(t,l,n)
To use this primitive, you must load the drawing module dessin.mo.
Draws the tree t in the current graphics unit, and waits for the user to click on
one of the tree nodes. When this is done, l is unified with the path leading to
the node and n is unified with the node. The path is a list of the numbers of
the sons to pass through, starting from the root, e.g. node dd in the tree
aa(bb,cc(ee(dd),ff)) is represented by the path 2.1.1.nil.
gendialog(D,l1,l2)
gendialog(P,D,l1,l2)
To use this primitive, you must first load the obdialog.mo module. This
primitive gives the user a very quick way of creating graphics screen sources,
that can then be integrated into applications.
P, D and l1 have the same meaning as in the gr_dialog primitive described
below.
© PrologIA
Aociation Prolog
In l2 this primitive generates a list of goals that make it possible to create the
dialog screen defined by D.
gendialog(<100,100>.3.nil,"Hello".buttonD,nil,g_oals) g_oals;
will unify g_oals with the list of goals to perform to create this dialog and
then execute these goals.
gr_dialog(D,l1,l2)
gr_dialog(P,D,l1,l2)
To use this primitive, you must first load the obdialog.mo module. This
module contains the Prolog II+ dialog manager which is used to create and
activate the dialogs described by D.
In the second version of this primitive, the additional argument P takes the
form of a list formed by one of the following:
- a pair <x,y> to determine the position of the top left-hand corner of the
dialog.
- an integer i to choose the font of the dialog's text. i is as specirfied in the
gr_font primitive.
- the term :title(s) where s is a string which represents the title of the dialog
window.
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)
This list is used to define or redefine the contents of the zones. 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.
A dialog is described with primitive objects (text areas, editing fields, 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:
> load("obdialog.mo");
> gr_dialog("Hello".buttonD("OK"),nil,L);
© PrologIA
Aociation Prolog
U 5 - 42 Windows User's Manual HERITAGE
© PrologIA
Aociation Prolog
:button(s,i)
Describes a button labeled s associated with an action i. When the
button is pressed, an action is performed:
- If i is fail, the dialog terminates and gr_dialog fails.
- If i is nil, nothing happens.
- Otherwise, the goal i(l) is activated, in which l is the list of
name.value pairs in the dialog zones when the button is clicked.
When the goal i has been executed, the dialog management continues as
before. To stop the current dialog, the user can program a
block_exit(<fail,L>) in i to cause backtracking of gr_dialog, or a
block_exit(<nil,L>) which results in normal termination, since l2 is
constructed from the list of name.value pairs indicated by L.
:button2(s,i)
This item behaves in the same way as the :button item, except that the i
rule is called with two arguments. The first is a list describing the state
of the dialog items. 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. Normally, s is the string "OK", and i is nil. This button can be
activated by mouse-clicking or by entering a Return.
glist(Lines,Columns,Identifier,ValueList)
Defines an item which is a list of values, with a scroll bar. The
meanings of the arguments are as follows:
Lines
Integer representing the number of items visible. The height of the
rectangle is automatically calculated according to this parameter.
Columns
Integer representing the number of characters visible for an item. The
width of the rectangle is automatically calculated according to this
parameter.
Identifier
Identifier giving the manager an internal name. It is used to give the
output result.
ValueList
Any list of constants (strings, identifiers, numbers) which represents the
list of values presented, or else a triple describing the initial state of the
manager. This triple must have the following form:
<ValueList, ListOfSelectedNbs, TopNumber>
The first argument is any list of constants (strings, identifiers,
numbers).
© PrologIA
Aociation Prolog
U 5 - 44 Windows User's Manual HERITAGE
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.
The result is given in output, therefore in l2, in the normal form of a
pair:
(identifier.ListOfSelectedItems)
In the internal representation, the state of the manager is represented by
the triple described above. In the programs linked to buttons, the value
of the glist must be handled in this form, i.e. in the lists handled by
these programs, it is the pair (identifier . < ValueList,
ListOfSelectedNbs, TopNumber>) which must appear.
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 series, the primitive calculates the size of each element 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 series 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 series, the
primitive calculates the size of each element, and constitutes a row of
elements arranged side by side, aligned to their top edges.
:crow(l)
Describes a row of objects described by l and centered horizontally, i.e.
arranged so that their median points are aligned on the same horizontal
axis.
: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.
© PrologIA
Aociation Prolog
:group(identifier.value,ItemDescription)
Enables an identifier 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 grey-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( ccol("Do you want to re-start the test?"
.buttonD
.button("Cancel",fail))
, nil
, L);
© PrologIA
Aociation Prolog
U 5 - 46 Windows User's Manual HERITAGE
.:buttonD("OK",nil)
.:button("Cancel",fail)
."HELLO WORLD"
)
."ijklmnopq"
)
, nil,l);
> insert;
enable( l1, l3 ) ->
set_item(l1, zone1, 1, l2)
set_item(l2, zone2, 0, l3);
© PrologIA
Aociation Prolog
{L=(color.green).(ed1."aa").nil}
This feature enables you to make this object communicate with Prolog, using the
events principle.
send_external_event(no,str,bool,int1,int2)
sends an event to Prolog.
© PrologIA
Aociation Prolog
U 5 - 48 Windows User's Manual HERITAGE
Both event management modes can be used; you can process the event
immediately, or put it in the event queue.
The arguments have the following meaning:
bool is the int type with a boolean value, and indicates the required processing
mode:
© PrologIA
Aociation Prolog
HERITAGE
Index
^ R 1 - 20 =< R 10 - 2; 7
^R2-4 == R 10 - 2; 11
~R4-6 =\= R 4 - 4
^ R 10 - 3 =\= R 10 - 20; 2; 7
* R 1 - 20 > R 1 - 20
* R 10 - 3 > R 10 - 2; 7
** R 1 - 20 >= R 1 - 20
** R 4 - 6 >= R 10 - 2; 7
** R 10 - 3 >> R 1 - 20
+ R 1 - 20 >> R 4 - 6
+ R 10 - 2; 3 >> R 10 - 3
, R 10 - 2; 3 ?- R 10 - 2
- R 1 - 20 @< R 10 - 2; 12
- R 10 - 2; 3 @=< R 10 - 2; 12
--> R 10 - 2 @> R 10 - 2; 12
-> R 10 - 2; 3 @>= R 10 - 2; 12
/ R 1 - 20 abolish R 10 - 5
/ R 10 - 3 abs R 4 - 5
// R 10 - 3; 7 access R 0 - 7
/\ R 1 - 20 activity U 5 - 17
/\ R 4 - 5 add R 4 - 4
/\ R 10 - 2 add_implicit R 3 - 12
:- R 10 - 2 add_sentence_terminator R 5 - 6
< R 1 - 20 add_stdmenu U 5 - 21
< R 10 - 2; 7 add_tlv R 2 - 14
<< R 1 - 20 alias R 10 - 13
<< R 4 - 6 alloc / 12 R 6 - 23
<< R 10 - 3 alloc R 6 - 23
= R 10 - 2; 3 append R 5 - 2
=.. R 10 - 2; 8 arg R 4 - 11
=:= R 1 - 20 arg R 10 - 8
=:= R 10 - 2; 7 arg2 R 4 - 10
=< R 1 - 20 assert R 2 - 12
© PrologIA
Aociation Prolog
I-2 Prolog II+ Windows Index HERITAGE
assert R 3 - 21 bounded R 10 - 19
assert R 10 - 5 break point R 6 - 7
assert U 2 - 7 buttonD U 5 - 14
assert'' R 3 - 21 call R 10 - 4
asserta R 3 - 21 callC R 7 - 23
asserta R 10 - 5 callpro.def U 1 - 6
assertn R 3 - 22 callpro.h U 1 - 5
assertz R 3 - 21 callprol.lib U 1 - 5
assertz R 10 - 5 callpros.lib U 1 - 5
assign R 3 - 20 cassign R 4 - 7
assign R 4 - 7 catch R 10 - 4
assign U 2 - 7 ceiling R 4 - 5
at R 10 - 14 char U 5 - 20
atan R 4 - 6 characters R 1 - 2
atom R 10 - 6 chars_nb U 5 - 14
atomic R 10 - 6 CHAR_ARRAY R 7 - 15; 18
atom_chars R 10 - 8 char_code R 4 - 9
atom_codes R 10 - 9 char_conversion R 10 - 19
atom_concat R 10 - 9 Check button U 5 - 4
atom_length R 10 - 9 check_button U 5 - 16
at_end_of_stream R 10 - 15 check_item U 5 - 24
background U 5 - 17 chrono R 6 - 4
backtrack_term R 4 - 8 clause R 10 - 5
bagof R 2 - 4 clear_events U 5 - 20
beep R 5 - 9 clear_input R 5 - 8
binary R 5 - 1 clear_menubar U 5 - 21
block R 2 - 4; 5 clear_window U 5 - 9
block R 3 - 20 click U 5 - 20
block U 2 - 7 click_down U 5 - 20
block_exit R 2 - 4; 5 click_up U 5 - 20
block_exit U 2 - 8 close R 10 - 13
bottom_attach U 5 - 13 close_context_dictionary R 3 - 12
bottom_right U 5 - 17 close_input R 5 - 8
bound R 2 - 6 close_output R 5 - 12
bound R 4 - 2 code R 6 - 25
© PrologIA
Aociation Prolog
command_menu U 5 - 24 C_FUNCTION_BACKTRACK_PROTECTE
Composition and decomposition of D R 7 - 15; 20
objects R 4 - 10 C_FUNCTION_PROTECTED R 7 - 15; 20
compound R 10 - 6 date R 6 - 4
conc_list_string R 4 - 11 date_string R 6 - 4
conc_string R 4 - 10 date_stringF R 6 - 4
ConnectDescriptors R 8 - 10 dbgbase.mo R 2 - 6
ConnectInString R 8 - 11 dbgbase.mo U 1 - 4
ConnectOutString R 8 - 11 dbgedin.mo R 2 - 6
console R 5 - 1 dbgedin.mo U 1 - 4
constant R 1 - 4 dbggraph.mo R 2 - 6
consult R 10 - 5 dbggraph.mo U 1 - 4
consult U 1 - 7 dde.mo U 1 - 3
copy_term R 4 - 11 ddeCbServerClosing U 4 - 10
copy_term_with_constraints R 4 - 11 ddeCbServerUpdate U 4 - 10
cos R 4 - 6 ddePublishExternalEvent U 4 - 4
cpu_time R 6 - 4 debug R 3 - 20
create_window U 5 - 9 debug R 6 - 17
cross U 5 - 17 debug R 10 - 19
current_context R 3 - 12 debugger R 6 - 6
current_file R 5 - 2 Declaration of operators R 5 - 14
current_input R 10 - 15 default R 2 - 7
current_op R 10 - 3 default U 5 - 17
current_output R 10 - 17 def_array R 4 - 8
current_predicate R 3 - 22 delay R 6 - 4
current_prolog_flag R 10 - 20 descriptor R 7 - 16
cursor U 5 - 17 Dessin R 5 - 13
customColor U 5 - 17 dessin.m2 R 5 - 13
customiz.dll U 1 - 3 dessin.m2 U 1 - 3
customiz.dll U 3 - 2 dessin.mo U 1 - 3
customiz.dl_ U 1 - 3 dictionary R 3 - 13
customiz.dl_ U 3 - 3 dictionary R 3 - 13
C_FUNCTION R 7 - 15; 20 dictionary R 3 - 25
C_FUNCTION_BACKTRACK R 7 - 15; 20 dictionary R 6 - 25
dif R 2 - 6
© PrologIA
Aociation Prolog
I-4 Prolog II+ Windows Index HERITAGE
© PrologIA
Aociation Prolog
file_window U 5 - 9 freeze R 3 - 20
findall R 2 - 8 freplace R 3 - 23
find_pattern R 4 - 10 frequent errors R 0 - 5
float R 4 - 5 fresetpermanentsymbol R 7 - 14
float R 10 - 6 fretract R 3 - 23
floor R 4 - 5 fretractall R 3 - 24
flush R 5 - 9 front_window U 5 - 10
flush_output R 10 - 17 fr_err.txt U 1 - 2; 3
focus U 5 - 17 fr_err.txt U 2 - 9
focus_in U 5 - 20 fsetpermanentsymbol R 7 - 14
focus_out U 5 - 20 fsymbolstring R 7 - 13
FONT U 5 - 8 functor R 10 - 9
font U 5 - 8; 17 gc R 6 - 25
fontheight U 5 - 17 gendialog U 5 - 40
fonts.all U 5 - 28 gensymbol R 4 - 12
fonts.usr U 1 - 2 get R 10 - 15
fonts.usr U 5 - 28 get0 R 10 - 16
FONTSIZE U 5 - 8 getenv R 6 - 5
fontsize U 5 - 8 get_arg_type R 7 - 3
force R 10 - 13 get_attribute U 5 - 16
foreground U 5 - 17 get_byte R 10 - 15
fprefixlimit R 7 - 13 get_char R 10 - 15
fprosymbol R 7 - 13 get_code R 10 - 16
fprouser.eg R 7 - 1 get_double R 7 - 4
fputdouble R 7 - 7 get_error_complement R 8 - 11
fputinteger R 7 - 6 get_event U 5 - 13
fputreal R 7 - 7 get_event U 5 - 19
fputstring R 7 - 7 get_formats R 8 - 8; 9
fputstrterm R 7 - 8 get_integer R 7 - 4
fputterm R 7 - 15 get_key U 5 - 36
FRAMEPANEL U 5 - 3; 7 get_local_object U 5 - 19
framepanel U 5 - 7; 16 get_max_string R 7 - 4
free R 2 - 8 get_objects U 5 - 19
free R 4 - 2 get_option R 6 - 23
Freeze R 2 - 9 get_real R 7 - 4
© PrologIA
Aociation Prolog
I-6 Prolog II+ Windows Index HERITAGE
get_screen U 5 - 6 gr_get_pen U 5 - 26
get_string R 7 - 4 gr_icon U 5 - 32
get_strterm R 7 - 8 gr_line U 5 - 29
get_term R 7 - 14 gr_lineto U 5 - 29
get_tlv R 2 - 15 gr_list U 5 - 37
get_window U 5 - 10 gr_load U 5 - 32
graphic.mo U 1 - 3 gr_mode U 5 - 26
graphic.mo U 5 - 5 gr_move U 5 - 29
GRAPHICS U 5 - 3; 7 gr_moveto U 5 - 29
graphics U 5 - 7; 16 gr_pen U 5 - 26
graphic_area R 5 - 2 gr_penloc U 5 - 29
graphic_system U 5 - 6 gr_penlocr U 5 - 29
graphstr.mo U 1 - 3 gr_polygon U 5 - 30
group U 5 - 17 gr_popupItem U 5 - 38
gr_arc U 5 - 31 gr_print U 5 - 10
gr_arc' U 5 - 31 gr_rect U 5 - 29
gr_button_hit U 5 - 35 gr_sensitive U 5 - 34
gr_choosecolor U 5 - 26 gr_setorigin U 5 - 28
gr_click U 5 - 33 gr_stringwidth U 5 - 26
gr_clickr U 5 - 33 gr_text U 5 - 27
gr_color U 5 - 25 gr_tree_click U 5 - 40
gr_color1 U 5 - 25 gr_window U 5 - 10
gr_color2 U 5 - 25 gr_window_is U 5 - 10
gr_color3 U 5 - 25 gtty U 5 - 37
gr_dialog U 1 - 3 halt R 10 - 20
gr_dialog U 5 - 41 heap R 6 - 25
gr_draw_buttons U 5 - 34 hidden R 3 - 25
gr_editf U 5 - 35 hidden_debug R 3 - 25
gr_erase U 5 - 29 hidden_rule R 3 - 24
gr_font U 1 - 2 hscroll U 5 - 14; 15; 16
gr_font U 5 - 28 ident R 4 - 1
gr_getmouse U 5 - 34 if R 4 - 5
gr_getmouser U 5 - 34 ignore_ops R 10 - 19
gr_getorigin U 5 - 29 in R 5 - 4
gr_get_mode U 5 - 27 include R 3 - 25
© PrologIA
Aociation Prolog
index R 3 - 20 int_edit.moU 5 - 6
index R 3 - 31 in_char R 5 - 3
indexing R 3 - 20 in_char' R 5 - 4
inequation R 1 - 12 in_double R 5 - 5
inf R 4 - 4 in_ident R 5 - 5
infe R 4 - 4 in_integer R 5 - 5
Infinite trees R 2 - 11 in_real R 5 - 5
infinite R 2 - 11 in_sentence R 5 - 6
infinite_flag R 2- 12 in_string R 5 - 5
initial.po R 3 - 4 in_word R 5 - 6
initial.po U 1 - 2; 8 is R 10 - 2; 7
initial.po U 2 - 2 is_array R 4 - 9
initialization R 3 - 26 is_uncompiled R 3 - 28
InitializeProlog U 3 - 3 items U 5 - 18
init_fassert R 3 - 25 items_nb U 5 - 17
init_screen U 5 - 5 keysort R 4 - 15; 16
ini_module R 3 - 14 kill_array R 4 - 9
ini_module R 3 - 17 kill_array R 7 - 16
inl R 5 - 4 kill_array U 2 - 8
Input R 5 - 2; 8 kill_goal R 8 - 3
input R 10 - 13 kill_module R 3 - 31
input U 1 - 7 kill_module R 7 - 16
input U 5 - 39 kill_module U 2 - 8
input_is R 5 - 8 kill_object U 5 - 13
insert R 3 - 26; 27 kill_window U 5 - 9
insert R 3 - 32 Label U 5 - 4
insert U 1 - 7 label U 5 - 16
insert U 2 - 7 left U 5 - 15
insertz R 3 - 26; 27 left_attach U 5 - 13
integer R 4 - 1 lg_buffer R 10 - 13
integer_rounding_function R 10 - 20 line R 5 - 10
Interruption R 2 - 6 line_width R 5 - 13
interruption R 0 - 5 list R 3 - 14
INT_ARRAY R 7 - 15; 18 list R 3 - 28
int_edit.mo U 1 - 4 Listbox U 5 - 4
© PrologIA
Aociation Prolog
I-8 Prolog II+ Windows Index HERITAGE
listbox U 5 - 16 new_drawing_area U 5 - 13
listing R 10 - 6 new_edit_field U 5 - 14
list_of R 2 - 8 new_goal R 8 - 3
list_string R 4 - 12 new_label U 5 - 15
list_tuple R 4 - 12 new_listbox U 5 - 15
lkload R 6 - 5 new_pattern R 8 - 8
lkload R 7 - 24 new_popup_menu U 5 - 15
ln R 4 - 6 new_pulldown_menu U 5 - 16
load R 3 - 31 new_push_button U 5 - 14
load U 2 - 8 new_radio_button U 5 - 14
log R 10 - 7 new_scrollbar U 5 - 16
max_arity R 10 - 19 new_tlv R 2 - 14
member R 4 - 12 new_window U 5 - 7
memory_file R 5 - 1 next_char R 5 - 4
memory_file R 5 - 2 next_char' R 5 - 4
message_box U 5 - 35 next_solution R 8 - 3
mod R 1 - 20 nl R 10 - 17
mod R 4 - 4 nonvar R 10 - 6
mod R 10 - 2 not R 2 - 8
MODAL U 5 - 7; 8 not R 10 - 14
modal U 5 - 7; 8 not_defined R 3 - 28
mode R 10 - 13 no_border U 5 - 13; 15
module R 3 - 15 no_debug R 6 - 17
module R 3 - 19 no_echo R 5 - 13
module U 2 - 7 NO_GOAL R 8 - 2
module_context R 3 - 27 no_index R 3 - 32
module_file R 3 - 27 no_infinite R 2 - 11
month R 6 - 4 no_paper R 5 - 11
"MPW" U 5 - 37 NO_RESIZE U 5 - 8
ms_err R 6 - 5 no_resize U 5 - 8
mul R 4 - 4 no_spy R 6 - 18
multifile R 3 - 28 no_trace R 6 - 7; 17
multiple U 5 - 14; 15 number R 10 - 6
name R 10 - 9 numbervars R 10 - 19
new_check_button U 5 - 13 number_chars R 10 - 10
© PrologIA
Aociation Prolog
number_codes R 10 - 10 phrase R 10 - 10
obdialog.mo U 1 - 3 Popup menu U 5 - 4
OFFSET_ZERO_BASED R 7 - 16 popup_menu U 5 - 16
omodule R 3 - 15 position R 10 - 13
omodule R 3 - 19 predefined R 3 - 29
once R 10 - 4 predicate U 5 - 17
op R 5 - 15 prefix_limit R 3 - 7
open R 10 - 13 prefix_limit R 7 - 13
operators R 1 - 13; 19 princip.c U 1 - 4
operators R 5 - 14 princip.c U 3 - 4
optimization U 2 - 7 princip.obj U 1 - 4
optimizations R 2 - 5; 11 print_window U 5 - 10
optimizations R 4 - 3; 7 proentry.c U 1 - 4
optimizations R 6 - 6 proentry.c U 3 - 3
optimizations R3 - 20 proentry.obj U 1 - 4
option U 5 - 10 proext.h R 7 - 16
or R 2 - 9 proext.h U 1 - 4
out R 5 - 9 ProFinal R 8 - 3; 5
outl R 5 - 9 ProFinal U 3 - 4
outm R 5 - 10 prolink R 7 - 16
outml R 5 - 10 prolink.bat U 1 - 4
Output R 5 - 9; 12 prolink.bat U 2 - 11
output R 10 - 13 prolog U 5 - 21
output U 5 - 39 prolog.def U 1 - 4
output_is R 5 - 12 prolog.def U 3 - 3
out_equ R 5 - 10 prolog.exe U 1 - 3
page R 5 - 10 prolog.exe U 3 - 2
paper R 5 - 10 prolog.lib U 1 - 4
parasite R 1 - 17 prolog.log U 2 - 8
parent U 5 - 16 prolog.po U 2 - 2; 10
past R 10 - 14 prolog.res U 1 - 5
peek_byte R 10 - 16 prolog2.pre U 1 - 3
peek_char R 10 - 16 prolog2.pre U 2 - 3
peek_code R 10 - 16 prolog32.exe U 1 - 4
peek_event U 5 - 20 PrologDir2 U 1 - 3; 8
© PrologIA
Aociation Prolog
I - 10 Prolog II+ Windows Index HERITAGE
PrologDir2 U 2 - 2; 9 radio_button U 5 - 16
PrologEdit U 1 - 4; 8 rank U 5 - 18
PrologEdit U 5 - 6 read R 5 - 2
prologII R 6 - 24 read R 10 - 16
prologIIE R 6 - 24 read_line R 10 - 16
ProStart R 8 - 3; 5 read_rule R 5 - 7
ProStart U 3 - 3 read_term R 10 - 16
protected U 5 - 18 read_unit R 5 - 7
prouser.c R 4 - 10 real R 4 - 1
prouser.c U 1 - 5 realloc R 6 - 25
prouser.c U 2 - 11 reconsult R 10 - 5
prouser.c U 3 - 3 redef_array R 4 - 9
prouser.obj U 1 - 5 reinsert R 3 - 26; 27
pro_signal R 9 - 2 reload R 3 - 32
pro_symbol R 7 - 13 reload U 2 - 8
Pulldown menu U 5 - 4 rem R 1 - 20
pulldown_menu U 5 - 16 rem R 4 - 4
Push button U 5 - 4 rem R 10 - 2
push_button U 5 - 16 remove_implicit R 3 - 12
put R 10 - 18 remove_sentence_terminator R 5 - 7
put_byte R 10 - 18 repeat R 2 - 9
put_char R 10 - 18 reposition R 10- 13
put_code R 10 - 18 reposition R 10 - 14
put_double R 7 - 6 reset R 10 - 13
put_integer R 7 - 6 reset_chrono R 6 - 4
put_real R 7 - 6 reset_cpu_time R 6 - 4
put_string R 7 - 6 reset_permanent_symbol R 6 - 25
put_strterm R 7 - 8 reset_permanent_symbol R 7 - 14
put_term R 7 - 14 reset_window U 5 - 11
quit R 0 - 5 restore_C_backtrack_data R 7 - 21
quit R 6 - 1 restore_menubar U 5 - 21
quit U 2 - 2 restore_sysmenus U 5 - 21
quoted R 10 - 19 retract R 3 - 30
rad R 4 - 6 retract R 10 - 6
Radio button U 5 - 4 retractall R 10 - 6
© PrologIA
Aociation Prolog
right U 5 - 15 set_input R 10 - 17
right_attach U 5 - 13 set_line_cursor R 5 - 11
round R 4 - 5 set_line_width R 5 - 13
rule R 1 - 13 set_menu U 5 - 22
rule R 3 - 20 set_options R 6 - 24
rule R 3 - 29 set_output R 10 - 18
rule U 2 - 7 set_permanent_symbol R 6 - 25
rule_nb R 3 - 30 set_permanent_symbol R 7 - 14; 19
SAVE U 5 - 8 set_prefix_limit R 3 - 7; 17
save R 3 - 32 set_prolog_flag R 10 - 20
save U 2 - 8 set_stream_position R 10 - 13
save U 5 - 8; 13 set_tlv R 2 - 15
save_menubar U 5 - 21 set_window U 5 - 11
save_state R 3 - 32 sfgetfile U 5 - 39
save_window U 5 - 11 sfputfile U 5 - 40
Scrollbar U 5 - 5 SHAPE U 5 - 8
scrollbar U 5 - 16 shape U 5 - 8
scrollb_page U 5 - 19 show_spy R 6 - 18
scrollb_pos U 5 - 19 sign R 4 - 5
scrollb_range U 5 - 19 sin R 4 - 6
scrollb_step U 5 - 19 singleton R 3 - 27
see R 10 - 17 singletons R 10 - 17
seeing R 10 - 17 SINGLE_FLOAT_ARRAY R 7 - 15; 18
seen R 10 - 17 SOLUTION_EXISTS R 8 - 2
selected_items U 5 - 18 sort R 4 - 15; 16
send_external_event U 5 - 47 specified fact R 1 - 13; 15
send_prolog_interrupt R 9 - 3 split R 4 - 13
setarg R 4 - 12 sprintf R 5 - 11
setof R 2 - 9 sprintf R 7 - 23
set_alias R 1 - 26 spy R 6 - 18
set_attribute U 5 - 17 sqrt R 4 - 6
set_context R 3 - 11 sscanf R 5 - 7
set_cursor R 5 - 11 sscanf R 7 - 23
set_draw_mode R 5 - 12 stack R 6 - 25
set_import_dir R 6 - 5 stacks R 6 - 25
© PrologIA
Aociation Prolog
I - 12 Prolog II+ Windows Index HERITAGE
StartPrologMainGoal U 3 - 4 TerminateProlog U 3 - 4
state R 6 - 24 terms R 1 - 11
state U 5 - 18 term_cmp R 2 - 8; 9
statistics R 6 - 24 term_cmp R 4 - 15
store_C_backtrack_data R 7 - 20 term_cmpv R 4 - 15
stream_property R 10 - 13 term_expansion R 10 - 21
String operations R 4 - 9 term_vars R 4 - 14
string R 4 - 1 text R 5 - 1
STRING_ARRAY R 7 - 15; 18 text U 5 - 18
string_double R 4 - 13 text_selection U 5 - 18
string_ident R 4 - 13 The cut "!" R 2 - 2
string_integer R 4 - 13 throw R 10 - 4
string_real R 4 - 13 time R 6 - 4; 5
string_term R 4 - 14 told R 10 - 18
stty U 5 - 36 toplist U 5 - 19
style_menu U 5 - 24 top_attach U 5 - 13
sub R 4 - 4 top_left U 5 - 18
substring R 4 - 10 trace R 6 - 7; 17
sub_atom R 10 - 11 trail R 6 - 25
sup R 4 - 5 tree R 1 - 8
supe R 4 - 5 true R 10 - 5
suppress R 3 - 30 trunc R 4 - 5
suppress R 7 - 16 truncate R 10 - 7
suppress U 2 - 8 TTY U 5 - 3; 7
SYMBOL_ARRAY R 7 - 15; 19 "TTY" U 5 - 37
symbol_string R 7 - 13 tty U 5 - 7; 16
sys_command R 6 - 5 tty_area R 5 - 2
tab R 10 - 18 tuple R 4 - 1
tab_user_param U 2 - 9 tval R 4 - 3
tan R 4 - 6 Type testing rules R 4 - 1
tassign R 4 - 7 type R 10 - 13; 14
tell R 10 - 18 type U 5 - 16
telling R 10 - 18 unification R 1 - 16
TEMP U 1 - 8 unify_tlv R 2 - 15
term R 1 - 8 unify_with_occurs_check R 10 - 5
© PrologIA
Aociation Prolog
unix_pipe R 5 - 1
unknown R 10 - 19
update U 5 - 20
userdll.mak U 1 - 6
usermpty.c U 1 - 5
userrsc.rc U 3 - 3
user_field U 5 - 18
use_win.h U 1 - 5
val R 3 - 20
val R 4 - 3
val U 2 - 7
var R 10 - 6
variable R 1 - 3
variables R 10 - 16
variable_names R 10 - 16
var_time R 4 - 2
version R 6 - 24
visibility U 5 - 18
vscroll U 5 - 14; 16
wait U 5 - 17
week R 6 - 4
width_height U 5 - 18
write R 5 - 2
write R 10 - 18
writeq R 10 - 18
write_canonical R 10 - 18
write_term R 10 - 18
\ R 10 - 3; 7
\+ R 10 - 2; 3
\/ R 1 - 20
\/ R 4 - 6
\/ R 10 - 2
\= R 10 - 2; 3
\== R 10 - 2; 11
© PrologIA
Aociation Prolog
I - 14 Prolog II+ Windows Index HERITAGE
© PrologIA