GNU PROLOGA Native Prolog Compiler with Constraint Solving over Finite Domains
Edition 1.50, for GNU Prolog version 1.5.0
July 8, 2021

by Daniel Diaz

Copyright (C) 1999-2021 Daniel Diaz
Permission is granted to make and distribute verbatim copies of this manual provided the copyright noticeand this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions forverbatim copying, provided that the entire resulting derived work is distributed under the terms of apermission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under theabove conditions for modified versions, except that this permission notice may be stated in a translation
approved by the Free Software Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

CONTENTS

1

Contents
1 Acknowledgements

92 GNU Prolog License Conditions

11

3 Introduction

11

4 Using GNU Prolog
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 The GNU Prolog interactive interpreter . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1
Starting/exiting the interactive interpreter . . . . . . . . . . . . . . . . . . . . . .
4.2.2
The interactive interpreter read-execute-write loop . . . . . . . . . . . . . . . . .
4.2.3
Consulting a Prolog program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.4
Scripting Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.5
Interrupting a query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.6
The line editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Adjusting the size of Prolog data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4 The GNU Prolog compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.1
Different kinds of codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.2
Compilation scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.3
Using the compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.4
Running an executable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.5
Generating a new interactive interpreter . . . . . . . . . . . . . . . . . . . . . . .
4.4.6
The name mangling scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13
13
13
13
15
17
18
18
18
20
21
21
21
23
27
27
28

5 Debugging
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 The procedure box model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3 Debugging predicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.1
Running and stopping the debugger . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.2
Leashing ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.3
Spy-points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4 Debugging messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.5 Debugger commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.6 The WAM debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31
31
31
31
31
32
32
33
33
35

6 Format of definitions
6.1 General format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 Types and modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3 Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.1
General format and error context . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.2
Instantiation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.3
Uninstantiation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.4Type error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.5
Domain error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.6
Existence error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.7
Permission error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.8
Representation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.9
Evaluation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.10 Resource error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.11 Syntax error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.12 System error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37
37
37
39
39
39
40
40
40
41
41
41
42
42
42
42

7 Prolog directives and control constructs

45

2

CONTENTS

7.1

Prolog directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.2
dynamic/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.3
public/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.4
multifile/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.5
discontiguous/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.6
ensure linked/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.7
built in/0, built in/1, built in fd/0, built in fd/1 . . . . . . . . . . . . . .
7.1.8
include/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.9
if/1, else/0, endif/0, elif/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.10 ensure loaded/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.11 op/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.12 char conversion/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.13 set prolog flag/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.14 initialization/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.15 foreign/2, foreign/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Prolog control constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2.1
true/0, fail/0, !/0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2.2(’,’)/2 - conjunction, (;)/2 - disjunction, (->)/2 - if-then, (*->)/2 - soft-cut(soft if-then) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2.3
call/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2.4
catch/3, throw/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

45
45
45
45
46
46
47
47
48
48
49
49
49
50
50
50
51
51

8 Prolog built-in predicates
8.1 Type testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.1.1
var/1, nonvar/1, atom/1, integer/1, float/1, number/1, atomic/1,
compound/1, callable/1, ground/1, is list/1, list/1,
partial list/1, list or partial list/1 . . . . . . . . . . . . . . . . . . . . . .
8.2 Term unification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2.1(=)/2 - Prolog unification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2.2
unify with occurs check/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2.3(\=)/2 - not Prolog unifiable . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3 Term comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3.1
Standard total ordering of terms . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3.2(==)/2 - term identical, (\==)/2 - term not identical,(@<)/2 - term less than, (@=<)/2 - term less than or equal to,(@>)/2 - term greater than, (@>=)/2 - term greater than or equal to . . . . . . .
8.3.3
compare/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4 Term processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.1
functor/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.2
arg/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.3(=..)/2 - univ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.4
copy term/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.5
term variables/2, term variables/3 . . . . . . . . . . . . . . . . . . . . . . . .
8.4.6
subsumes term/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.7
acyclic term/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.8
term hash/4, term hash/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.9
setarg/4, setarg/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.5 Variable naming/numbering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.5.1
name singleton vars/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.5.2
name query vars/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.5.3
bind variables/2, numbervars/3, numbervars/1 . . . . . . . . . . . . . . . . . .
8.5.4
term ref/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.6 Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

55
55

7.2

51
52
53

55
56
56
56
57
57
57

57
58
59
59
59
60
60
61
61
61
62
63
63
63
64
64
65
66

CONTENTS

3

8.6.1
8.6.2
8.6.3

66
69

Evaluation of an arithmetic expression . . . . . . . . . . . . . . . . . . . . . . . .
(is)/2 - evaluate expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
(=:=)/2 - arithmetic equal, (=\=)/2 - arithmetic not equal,(<)/2 - arithmetic less than, (=<)/2 - arithmetic less than or equal to,(>)/2 - arithmetic greater than, (>=)/2 - arithmetic greater than or equal to . .
8.6.4
succ/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7 Dynamic clause management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7.1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7.2
asserta/1, assertz/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7.3
retract/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7.4
retractall/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7.5
clause/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7.6
abolish/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.8 Predicate information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.8.1
current predicate/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.8.2
predicate property/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.9 All solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.9.1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.9.2
findall/4, findall/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.9.3
bagof/3, setof/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10 Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.2 current input/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.3 current output/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.4 set input/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.5 set output/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.6 open/4, open/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.7 close/2, close/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.8 flush output/1, flush output/0 . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.9 current stream/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.10 stream property/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.11 at end of stream/1, at end of stream/0 . . . . . . . . . . . . . . . . . . . . . .
8.10.12 stream position/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.13 set stream position/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.14 seek/4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.15 character count/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.16 line count/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.17 line position/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.18 stream line column/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.19 set stream line column/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.20 add stream alias/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.21 current alias/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.22 add stream mirror/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.23 remove stream mirror/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.24 current mirror/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.25 set stream type/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.26 set stream eof action/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.10.27 set stream buffering/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.11 Constant term streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.11.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.11.2 open input atom stream/2, open input chars stream/2,
open input codes stream/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.11.3 close input atom stream/1, close input chars stream/1,
close input codes stream/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

69
70
70
70
71
72
72
73
73
74
74
75
76
76
76
77
78
78
79
79
80
80
81
82
83
83
84
85
85
86
86
87
88
88
89
89
90
90
91
91
92
92
93
93
94
94
94
95

4

CONTENTS

8.11.4open output atom stream/1, open output chars stream/1,
open output codes stream/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.11.5 close output atom stream/2, close output chars stream/2,
close output codes stream/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.12 Character input/output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.12.1 get char/2, get char/1, get code/1, get code/2 . . . . . . . . . . . . . . . . .
8.12.2 get key/2, get key/1 get key no echo/2, get key no echo/1 . . . . . . . . . .
8.12.3 peek char/2, peek char/1, peek code/1, peek code/2 . . . . . . . . . . . . . . .
8.12.4 unget char/2, unget char/1, unget code/2, unget code/1 . . . . . . . . . . . .
8.12.5 put char/2, put char/1, put code/1, put code/2, nl/1, nl/0 . . . . . . . . . .
8.13 Byte input/output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.13.1 get byte/2, get byte/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.13.2 peek byte/2, peek byte/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.13.3 unget byte/2, unget byte/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.13.4 put byte/2, put byte/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14 Term input/output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.1 read term/3, read term/2, read/2, read/1 . . . . . . . . . . . . . . . . . . . . .
8.14.2 read atom/2, read atom/1, read integer/2, read integer/1,
read number/2, read number/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.3 read token/2, read token/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.4 syntax error info/4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.5 last read start line column/2 . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.6 write term/3, write term/2, write/2, write/1, writeq/2, writeq/1,
write canonical/2, write canonical/1, display/2, display/1, print/2,
print/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.7 format/3, format/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.8 portray clause/2, portray clause/1 . . . . . . . . . . . . . . . . . . . . . . . .
8.14.9 get print stream/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.10 op/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.11 current op/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.12 char conversion/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.14.13 current char conversion/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.15 Input/output from/to constant terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.15.1 read term from atom/3, read from atom/2, read token from atom/2 . . . . . .
8.15.2 read term from chars/3, read from chars/2, read token from chars/2 . . . .
8.15.3 read term from codes/3, read from codes/2, read token from codes/2 . . . .
8.15.4 write term to atom/3, write to atom/2, writeq to atom/2,
write canonical to atom/2, display to atom/2, print to atom/2,
format to atom/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.15.5 write term to chars/3, write to chars/2, writeq to chars/2,
write canonical to chars/2, display to chars/2, print to chars/2,
format to chars/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.15.6 write term to codes/3, write to codes/2, writeq to codes/2,
write canonical to codes/2, display to codes/2, print to codes/2,
format to codes/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.16 DEC-10 compatibility input/output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.16.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.16.2 see/1, tell/1, append/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.16.3 seeing/1, telling/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.16.4 seen/0, told/0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.16.5 get0/1, get/1, skip/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.16.6 put/1, tab/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.17 Term expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.17.1 Definite clause grammars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

96
96
97
97
98
99
100
100
101
101
102
102
103
104
104
105
106
107
107

108
110
112
113
113
115
116
116
117
117
117
118

118

119

120
120
120
121
121
122
122
123
123
123

CONTENTS

5

8.17.2 expand term/2, term expansion/2 . . . . . . . . . . . . . . . . . . . . . . . . . . 124
8.17.3 phrase/3, phrase/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
8.18 Logic, control and exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
8.18.1 abort/0, stop/0, top level/0, break/0, halt/1, halt/0 . . . . . . . . . . . . . 126
8.18.2 false/0, once/1, (\+)/1 - not provable, call/2-11, call with args/1-11, call det/2,
forall/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
8.18.3 repeat/0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
8.18.4 between/3, for/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
8.19 Atomic term processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
8.19.1 atom length/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.19.2 atom concat/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.19.3 sub atom/5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.19.4 char code/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
8.19.5 lower upper/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
8.19.6 atom chars/2, atom codes/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
8.19.7 number atom/2, number chars/2, number codes/2 . . . . . . . . . . . . . . . . . 132
8.19.8 name/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
8.19.9 new atom/2, new atom/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
8.19.10 current atom/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
8.19.11 atom property/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
8.20 List processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
8.20.1 append/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
8.20.2 member/2, memberchk/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
8.20.3 reverse/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
8.20.4 delete/3, select/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
8.20.5 subtract/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
8.20.6 permutation/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
8.20.7 prefix/2, suffix/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
8.20.8 sublist/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
8.20.9 last/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
8.20.10 flatten/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
8.20.11 length/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
8.20.12 nth/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
8.20.13 max list/2, min list/2, sum list/2 . . . . . . . . . . . . . . . . . . . . . . . . . 139
8.20.14 maplist/2-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
8.20.15 sort/2, msort/2, keysort/2 sort/1, msort/1, keysort/1 . . . . . . . . . . . . . 140
8.21 Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
8.21.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
8.21.2 g assign/2, g assignb/2, g link/2 . . . . . . . . . . . . . . . . . . . . . . . . . 143
8.21.3 g read/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
8.21.4 g array size/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
8.21.5 g inc/3, g inc/2, g inco/2, g inc/1, g dec/3, g dec/2, g deco/2, g dec/1 . . . 144
8.21.6 g set bit/2, g reset bit/2, g test set bit/2, g test reset bit/2 . . . . . . 145
8.21.7 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
8.22 Prolog state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
8.22.1 set prolog flag/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
8.22.2 current prolog flag/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
8.22.3 set bip name/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
8.22.4 current bip name/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
8.22.5 write pl state file/1, read pl state file/1 . . . . . . . . . . . . . . . . . . . 152
8.23 Program state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
8.23.1 consult/1, ’.’/2 - program consult . . . . . . . . . . . . . . . . . . . . . . . . . 153
8.23.2 load/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
8.23.3 listing/1, listing/0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

6

CONTENTS

8.24 System statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.24.1 statistics/0, statistics/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.24.2 user time/1, system time/1, cpu time/1, real time/1 . . . . . . . . . . . . . .
8.25 Random number generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.25.1 set seed/1, randomize/0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.25.2 get seed/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.25.3 random/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.25.4 random/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.26 File name processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.26.1 absolute file name/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.26.2 is absolute file name/1, is relative file name/1 . . . . . . . . . . . . . . .
8.26.3 decompose file name/4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.26.4 prolog file name/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27 Operating system interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.1 argument counter/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.2 argument value/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.3 argument list/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.4 environ/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.5 make directory/1, delete directory/1, change directory/1 . . . . . . . . . .
8.27.6 working directory/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.7 directory files/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.8 rename file/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.9 delete file/1, unlink/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.10 file permission/2, file exists/1 . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.11 file property/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.12 temporary name/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.13 temporary file/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.14 date time/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.15 host name/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.16 os version/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.17 architecture/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.18 shell/2, shell/1, shell/0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.19 system/2, system/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.20 spawn/3, spawn/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.21 popen/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.22 exec/5, exec/4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.23 fork prolog/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.24 create pipe/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.25 wait/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.26 prolog pid/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.27 send signal/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.28 sleep/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.27.29 select/5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28 Sockets input/output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.2 socket/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.3 socket close/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.4 socket bind/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.5 socket connect/4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.6 socket listen/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.7 socket accept/4, socket accept/3 . . . . . . . . . . . . . . . . . . . . . . . . .
8.28.8 hostname address/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.29 Linedit management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.29.1 get linedit prompt/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

155
155
155
156
156
156
157
157
158
158
158
159
159
160
160
160
161
161
162
162
162
163
163
164
165
166
167
167
168
168
168
169
169
170
170
171
172
172
173
173
174
174
175
176
176
176
176
177
178
178
179
179
180
180

CONTENTS

7

8.29.2
8.29.38.29.4set linedit prompt/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
add linedit completion/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
find linedit completion/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

9 Finite domain solver and built-in predicates183
9.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
9.1.1
Finite Domain variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
9.2 FD variable parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
9.2.1
fd max integer/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
9.2.2
fd vector max/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
9.2.3
fd set vector max/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
9.3 Initial value constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
9.3.1
fd domain/3, fd domain bool/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
9.3.2
fd domain/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
9.4 Type testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
9.4.1
fd var/1, non fd var/1, generic var/1, non generic var/1 . . . . . . . . . . . 187
9.5 FD variable information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
9.5.1
fd min/2, fd max/2, fd size/2, fd dom/2 . . . . . . . . . . . . . . . . . . . . . . 187
9.5.2
fd has extra cstr/1, fd has vector/1, fd use vector/1 . . . . . . . . . . . . . 188
9.6 Arithmetic constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
9.6.1
FD arithmetic expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
9.6.2
Partial AC: (#=)/2 - constraint equal, (#\=)/2 - constraint not equal,(#<)/2 - constraint less than, (#=<)/2 - constraint less than or equal,(#>)/2 - constraint greater than, (#>=)/2 - constraint greater than or equal . . . 189
9.6.3
Full AC: (#=#)/2 - constraint equal, (#\=#)/2 - constraint not equal,(#<#)/2 - constraint less than, (#=<#)/2 - constraint less than or equal,(#>#)/2 - constraint greater than, (#>=#)/2 - constraint greater than or equal . . 190
9.6.4
fd prime/1, fd not prime/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
9.7 Boolean and reified constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
9.7.1
Boolean FD expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
9.7.2
fd reified in/4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
9.7.3(#\)/1 - constraint NOT, (#<=>)/2 - constraint equivalent,(#\<=>)/2 - constraint different, (##)/2 - constraint XOR,(#==>)/2 - constraint imply, (#\==>)/2 - constraint not imply,(#/\)/2 - constraint AND, (#\/\)/2 - constraint NAND,(#\/)/2 - constraint OR, (#\\/)/2 - constraint NOR . . . . . . . . . . . . . . . . 193
9.7.4
fd cardinality/2, fd cardinality/3, fd at least one/1, fd at most one/1,
fd only one/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
9.8 Symbolic constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
9.8.1
fd all different/1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
9.8.2
fd element/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
9.8.3
fd element var/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
9.8.4
fd atmost/3, fd atleast/3, fd exactly/3 . . . . . . . . . . . . . . . . . . . . . 196
9.8.5
fd relation/2, fd relationc/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
9.9 Labeling constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
9.9.1
fd labeling/2, fd labeling/1, fd labelingff/1 . . . . . . . . . . . . . . . . . 198
9.10 Optimization constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
9.10.1 fd minimize/2, fd maximize/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
10 Interfacing Prolog and C
201
10.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
10.2 Including and using gprolog.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
10.3 Calling C from Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
10.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
10.3.2 foreign/2 directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

8

CONTENTS

10.3.3 The C function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.3.4 Input arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.3.5 Output arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.3.6 Input/output arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.3.7 Writing non-deterministic C code . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.3.8 Example: input and output arguments . . . . . . . . . . . . . . . . . . . . . . . .
10.3.9 Example: non-deterministic code . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.3.10 Example: input/output arguments . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4 Manipulating Prolog terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.2 Managing Prolog atoms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.3 Reading Prolog terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.4 Unifying Prolog terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.5 Creating Prolog terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.6 Testing the type of Prolog terms . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.7 Comparing Prolog terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.8 Term processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.4.9 Comparing and evaluating arithmetic expressions . . . . . . . . . . . . . . . . . .
10.5 Raising Prolog errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.1 Managing the error context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.2 Instantiation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.3 Uninstantiation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.4 Type error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.5 Domain error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.6 Existence error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.7 Permission error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.8 Representation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.9 Evaluation error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.10 Resource error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.11 Syntax error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.5.12 System error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.6 Calling Prolog from C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.6.2 Example: my call/1 - a call/1 clone . . . . . . . . . . . . . . . . . . . . . . . . .
10.6.3 Example: recovering the list of all operators . . . . . . . . . . . . . . . . . . . . .
10.7 Defining a new C main() function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.7.1 Example: asking for ancestors . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

204
204
204
205
205
206
207
209
210
210
210
211
212
214
214
215
215
216
217
217
217
217
217
217
218
218
218
218
219
219
219
220
220
221
223
224
225

References

229

Index

231

9

1

Acknowledgements

I am grateful to the members of the Loco project at INRIA Rocquencourt for their encouragement. Theirinvolvement in this work led to useful feedback and exchange (1995).
Many thanks to all those people at GNU who helped me to finalize the GNU Prolog project (1999).
I would like to thank everybody who tested preliminary releases and helped me to put the finishing
touches to this system (1999).
I would particularly like to thank Jonathan Hodgson for the time and effort he put into the proofreadingof this manual. His suggestions, both regarding ISO technical aspects as well as the language in which it
was expressed, proved invaluable (1999-2017).
Thanks to Richard A. O’Keefe for his advice regarding the implementation of some Prolog built-in
predicates and for suggesting me the in-place installation feature (1999).
The on-line HTML version of this document was created using HEVEA developed by Luc Maranget who
kindly devoted so much of his time extending the capabilities of HEVEA in order to handle such a sizeable
manual (2000).
Jean-Christophe Aude kindly improved the visual aspect of both the illustrations and the GNU Prolog
web pages (2000).
Many thanks to the following contributors:• Clive Cox1 and Edmund Grimley Evans for their port to ix86/SCO (1999).
• Andreas Stolcke for his port to ix86/Solaris (1999).
• Alexander Diemand2 for his initial port to alpha/linux (2000).
• Nicolas Ollinger3 to for his port to ix86/FreeBSD (2000).
• Brook Milligan4 for his port to ix86/NetBSD and for general configuration improvements (2000).
• Lindsey Spratt5 for his port to powerpc/Darwin (MacOS X) (2002).
• Gwenolé Beauchesne6 for his port to x86 64/Linux (2002).
• Jason Beegan7 for his port to sparc/NetBSD and to powerpc/NetBSD (2003).
• Cesar Rabak8 for his initial port to ix86/MinGW (2004).
• Scott L. Burson9 for his port to x86 64/Solaris (2007).
• David Holland10 for his port to x86 64/BSD systems (2008).
• Ozaki Kiichi11 for his port to x86 64/Darwin (Mac OS X) (2012).
1 clive@laluna.demon.co.uk
2 ax@apax.net
3 nollinge@ens-lyon.fr
4 brook@nmsu.edu
5 spratt@alum.mit.edu
6 gbeauchesne@mandrakesoft.com
7 jtb@netbsd.org
8 csrabak@ig.com.br
9 Scott@coral8.com
10 dholland@netbsd.org
11 gclient.gaap@gmail.com

10

1

ACKNOWLEDGEMENTS• Jasper Taylor12 for his port to x86 64/MinGW64 (2011).
• Jasper Taylor13 for his ports to arm32/Linux and arm64/Linux (2021).
Many thanks to Paulo Moura for his continuous help (in particular about Darwin ports), for his ISO
Prolog unit tests and for including GNU Prolog in his logtalk system (2000-).
Many thanks to John Collins, the latexmk maintainer, who greatly helped me to simplify the building of
the documentation using latexmk (2021).

12 jasper@simulistics.com
13 jasper@simulistics.com

11

2

GNU Prolog License Conditions

GNU Prolog is free software. Since version 1.4.0, GNU Prolog distributed under a dual license: LGPLor GPL. So, you can redistribute it and/or modify it under the terms of either:– the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
or– the GNU General Public License (GPL) as published by the Free Software Foundation; either version
2 of the License, or (at your option) any later version.
or both in parallel (as here).
GNU Prolog is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; withouteven the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received copies of the GNU General Public License and the GNU Lesser General Public
License along with this program. If not, see http://www.gnu.org/licenses/.
Remark: versions of GNU Prolog prior to 1.4.0 were entirely released under the GNU General Public
License (GPL).

3

Introduction

GNU Prolog [5] is a free Prolog compiler with constraint solving over finite domains. For recent information about GNU Prolog please consult the GNU Prolog page.
GNU Prolog is a Prolog compiler based on the Warren Abstract Machine (WAM) [9, 1]. It first compiles
a Prolog program to a WAM file which is then translated to a low-level machine independent language
called mini-assembly specifically designed for GNU Prolog. The resulting file is then translated to theassembly language of the target machine (from which an object is obtained). This allows GNU Prolog
to produce a native stand alone executable from a Prolog source (similarly to what does a C compiler
from a C program). The main advantage of this compilation scheme is to produce native code and to be
fast. Another interesting feature is that executables are small. Indeed, the code of most unused built-in
predicates is not included in the executables at link-time.
A lot of work has been devoted to the ISO compatibility. Indeed, GNU Prolog is very close to the ISO
standard for Prolog [6].
GNU Prolog also offers various extensions very useful in practice (global variables, OS interface, sockets,...). In particular, GNU Prolog contains an efficient constraint solver over Finite Domains (FD). This
opens constraint logic programming to the user combining the power of constraint programming to thedeclarativity of logic programming. The key feature of the GNU Prolog solver is the use of a single (lowlevel) primitive to define all (high-level) FD constraints. There are many advantages of this approach:constraints can be compiled, the user can define his own constraints (in terms of the primitive), the solver
is open and extensible (as opposed to black-box solvers like CHIP),. . . Moreover, the GNU Prolog solver
is rather efficient, often more than commercial solvers.
GNU Prolog is inspired from two systems:

12

3

INTRODUCTION• wamcc: a Prolog to C compiler [3]. the key point of wamcc was its ability to produce stand alone
executables using an original compilation scheme: the translation of Prolog to C via the WAM.
Its drawback was the time needed by gcc to compile the produced sources. GNU Prolog can also
produce stand alone executables but using a faster compilation scheme.
• clp(FD): a constraint programming language over FD [4]. Its key feature was the use of a single
primitive to define FD constraints. GNU Prolog is based on the same idea but offers an extended
constraint definition language. In comparison to clp(FD), GNU Prolog offers new predefined constraints, new predefined heuristics, reified constraints,. . .
Here are some features of GNU Prolog:• Prolog system:– conforms to the ISO standard for Prolog (floating point numbers, streams, dynamic code,. . . ).
– a lot of extensions: global variables, definite clause grammars (DCG), sockets interface, operating system interface,. . .
– more than 300 Prolog built-in predicates.
– Prolog debugger and a low-level WAM debugger.
– line editing facility under the interactive interpreter with completion on atoms.
– powerful bidirectional interface between Prolog and C.
• Compiler:– native-code compiler producing stand alone executables.
– simple command-line compiler accepting a wide variety of files: Prolog files, C files, WAM
files,. . .
– direct generation of assembly code 15 times faster than wamcc + gcc.
– most of unused built-in predicates are not linked (to reduce the size of the executables).
– compiled predicates (native-code) as fast as wamcc on average.
– consulted predicates (byte-code) 5 times faster than wamcc.
• Constraint solver:– FD variables well integrated into the Prolog environment (full compatibility with Prolog variables and integers). No need for explicit FD declarations.
– very efficient FD solver (comparable to commercial solvers).
– high-level constraints can be described in terms of simple primitives.
– a lot of predefined constraints: arithmetic constraints, boolean constraints, symbolic constraints, reified constraints,. . .
– several predefined enumeration heuristics.
– the user can define his own new constraints.
– more than 50 FD built-in constraints/predicates.

13

4

Using GNU Prolog

4.1

Introduction

GNU Prolog offers two ways to execute a Prolog program:• interpreting it using the GNU Prolog interactive interpreter.
• compiling it to a (machine-dependent) executable using the GNU Prolog native-code compiler.
Running a program under the interactive interpreter allows the user to list it and to make full use of the
debugger on it (section 5, page 31). Compiling a program to native code makes it possible to obtain astand alone executable, with a reduced size and optimized for speed. Running a Prolog program compiled
to native-code is around 3-5 times faster than running it under the interpreter. However, it is not possible
to make full use of the debugger on a program compiled to native-code. Nor is it possible to list the
program. In general, it is preferable to run a program under the interpreter for debugging and thenuse the native-code compiler to produce an autonomous executable. It is also possible to combine these
two modes by producing an executable that contains some parts of the program (e.g. already debugged
predicates whose execution-time speed is crucial) and interpreting the other parts under this executable.
In that case, the executable has the same facilities as the GNU Prolog interpreter but also integrates
the native-code predicates. This way to define a new enriched interpreter is detailed later (section 4.4.5,
page 27).

4.2

The GNU Prolog interactive interpreter

4.2.1

Starting/exiting the interactive interpreter

GNU Prolog offers a classical Prolog interactive interpreter also called top-level. It allows the user to
execute queries, to consult Prolog programs, to list them, to execute them and to debug them. The
top-level can be invoked using the following command:% gprolog [OPTION ]. . .

(the % symbol is the operating system shell prompt)

Options:--init-goal GOAL--consult-file FILE--entry-goal GOAL--query-goal GOAL--help--version--

execute GOAL before entering the top-level
consult FILE inside the top-level
execute GOAL inside the top-level
execute GOAL as a query for the top-level
print a help and exit
print version number and exit
do not parse the rest of the command-line

The main role of the gprolog command is to execute the top-level itself, i.e. to execute the built-in
predicate top level/0 (section 8.18.1, page 126) which will produce something like:
GNU Prolog 1.5.0 (64 bits)
Compiled May 3 2021, 16:36:43 with gcc
Copyright (C) 1999-2021 Daniel Diaz
| ?The top-level is ready to execute your queries as explained in the next section.

14

4

USING GNU PROLOG

To quit the top-level type the end-of-file key sequence (Ctl-D) or its term representation: end of file.
It is also possible to use the built-in predicate halt/0 (section 8.18.1, page 126).
However, before entering the top-level itself, the command-line is processed to treat all known options(those listed above). All unrecognized arguments are collected together to form the argument list which
will be available using argument value/2 (section 8.27.2, page 160) or argument list/1 (section 8.27.3,
page 161). The -- option stops the parsing of the command-line, all remainding options are collected
into the argument list.
Several options are provided to execute a goal before entering the interaction with the user:• The --init-goal option executes the GOAL as soon as it is encountered (while the command-line
is processed). GOAL is thus executed before entering top level/0.
• The --consult-file option consults the FILE at the entry of top level/0 just after the banneris displayed. --consult-file options are handled before --consult-file options.
• The --entry-goal option executes the GOAL at the entry of top level/0 just after the banner isdisplayed.
• The --query-goal option executes the GOAL as if the user has typed in (under the top-level).
The above order is thus the order in which each kind of goal (init, entry, query) is executed. If there
are several goals of a same kind they are executed in the order of appearance. Thus, all init goals are
executed (in the order of appearance) before all entry goals and all entry goals are executed before all
query goals.
Each GOAL is passed as a shell argument (i.e. one shell string) and should not contain a terminal dot.
Example: --init-goal ’write(hello), nl’ under a sh-like. To be executed, a GOAL is transformed
into a term using read term from atom(Goal, Term, [end of term(eof)]). Respecting both the syntax of shell strings and of Prolog can be heavy. For instance, passing a backslash character \ can bedifficult since it introduces an escape sequence both in sh and inside Prolog quoted atoms. The use ofback quotes can then be useful since, by default, no escape sequence is processed inside back quotes (thisbehavior can be controlled using the back quotes Prolog flag (section 8.22.1, page 148)).
Since the Prolog argument list is created when the whole command-line is parsed, if a --init-goal option
uses argument value/2 or argument list/1 it will obtained the original command-line arguments (i.e.
including all recognized arguments).
Here is an example of using execution goal options:% gprolog --init-goal ’write(before), nl’ --entry-goal ’write(inside), nl’--query-goal ’append([a,b],[c,d],X)’
will produce the following:
beforeGNU Prolog 1.5.0 (64 bits)
Compiled May 3 2021, 16:36:43 with gcc
Copyright (C) 1999-2021 Daniel Diazinside| ?- append([a,b],[c,d],X).
X = [a,b,c,d]
yes
| ?-

4.2

The GNU Prolog interactive interpreter

15

NB: depending on the used shell it may be necessary to use other string delimiters (e.g. use " underWindows cmd.exe).

4.2.2

The interactive interpreter read-execute-write loop

The GNU Prolog top-level is built on a classical read-execute-write loop that also allows for re-executions(when the query is not deterministic) as follows:• display the prompt, i.e. ’| ?-’.
• read a query (i.e. a goal).
• execute the query.
• in case of success display the values of the variables of the query.
• if there are remaining alternatives (i.e. the query is not deterministic), display a ? and ask the user
who can use one of the following commands: RETURN to stop the execution, ; to compute the next
solution or a to compute all remaining solution.
Here is an example of execution of a query (“find the lists X and Y such that the concatenation of X and
Y is [a,b]”):| ?- append(X,Y,[a,b,c]).
X = []
Y = [a,b,c] ?
X = [a]Y = [b,c] ?

;a(here the user presses ; to compute another solution)(here the user presses a to compute all remaining solutions)

X = [a,b]
Y = [c](here the user is not asked and the next solution is computed)

X = [a,b,c]
Y = [](here the user is not asked and the next solution is computed)

no(no more solution)

In some cases the top-level can detect that the current solution is the last one (no more alternatives
remaining). In such a case it does not display the ? symbol (and does not ask the user). Example:| ?- (X=1 ; X=2).
X = 1 ?

;

X = 2

(here the user presses ; to compute another solution)(here the user is not prompted since there are no more alternatives)

yes
The user can stop the execution even if there are more alternatives by typing RETURN.
| ?- (X=1 ; X=2).
X = 1 ?
yes

(here the user presses RETURN to stop the execution)

16

4

USING GNU PROLOG

The top-level tries to display the values of the variables of the query in a readable manner. For instance,
when a variable is bound to a query variable, the name of this variable appears. When a variable is asingleton an underscore symbol is displayed ( is a generic name for a singleton variable, it is also called
an anonymous variable). Other variables are bound to new brand variable names. When a query variablename X appears as the value of another query variable Y it is because X is itself not instantiated otherwise
the value of X is displayed. In such a case, nothing is output for X itself (since it is a variable). Example:| ?- X=f(A,B, ,A), A=k.
A = k
X = f(k,B, ,k)(the value of A is displayed also in f/3 for X)(since B is a variable which is also a part of X, B is not displayed)| ?- functor(T,f,3), arg(1,T,X), arg(3,T,X).
T = f(X, ,X)(the 1st and 3rd args are equal to X, the 2nd is an anonymous variable)| ?- read from atom(’k(X,Y,X).’,T).
T = k(A, ,A)(the 1st and 3rd args are unified, a new variable name A is introduced)

The top-level uses variable binding predicates (section 8.5, page 63). To display the value of a variable,
the top-level calls write term/3 with the following option list: [quoted(true),numbervars(false),
namevars(true)] (section 8.14.6, page 108). A term of the form ’$VARNAME’(Name) where Name is
an atom is displayed as a variable name while a term of the form ’$VAR’(N) where N is an integer isdisplayed as a normal compound term (such a term could be output as a variable name by write term/3).
Example:| ?- X=’$VARNAME’(’Y’), Y=’$VAR’(1).
X = Y
Y = ’$VAR’(1)(the term ’$VARNAME’(’Y’) is displayed as Y)(the term ’$VAR’(1) is displayed as is)| ?- X=Y, Y=’$VAR’(1).
X = ’$VAR’(1)Y = ’$VAR’(1)In the first example, X is explicitly bound to ’$VARNAME’(’Y’) by the query so the top-level displays Y
as the value of X. Y is unified with ’$VAR’(1) so the top-level displays it as a normal compound term.
It should be clear that X is not bound to Y (whereas it is in the second query). This behavior should be
kept in mind when doing variable binding operations.
Finally, the top-level computes the user-time (section 8.24.2, page 155) taken by a query and displays it
when it is significant. Example:| ?- retractall(p( )), assertz(p(0)),
repeat,retract(p(X)),
Y is X + 1,
assertz(p(Y)),
X = 1000, !.
X = 1000
Y = 1001(180 ms) yes(the query took 180ms of user time)

4.2

The GNU Prolog interactive interpreter

4.2.3

17

Consulting a Prolog program

The top-level allows the user to consult Prolog source files. Consulted predicates can be listed, executedand debugged (while predicates compiled to native-code cannot). For more information about the difference between a native-code predicate and a consulted predicate refer to the introduction of this section(section 4.1, page 13) and to the part devoted to the compiler (section 4.4.1, page 21).
To consult a program use the built-in predicate consult/1 (section 8.23.1, page 153). The argumentof this predicate is a Prolog file name or user to specify the terminal. This allows the user to directly
input the predicates from the terminal. In that case the input shall be terminated by the end-of-file key
sequence (Ctl-D) or its term representation: end of file. A shorthand for consult(FILE ) is [FILE ].
Example:| ?- [user].
{compiling user for byte code...}even(0).
even(s(s(X))):even(X).
(here the user presses Ctl-D to end the input){user compiled, 3 lines read - 350 bytes written, 1180 ms}| ?- even(X).
X = 0 ?

(here the user presses ; to compute another solution);

X = s(s(0)) ?

;X = s(s(s(s(0)))) ?

(here the user presses ; to compute another solution)(here the user presses RETURN to stop the execution)

yes| ?- listing.
even(0).
even(s(s(A))) :even(A).
When consult/1 (section 8.23.1, page 153) is invoked on a Prolog file it first runs the GNU Prolog
compiler (section 4.4, page 21) as a child process to generate a temporary WAM file for byte-code. If
the compilation fails a message is displayed and nothing is loaded. If the compilation succeeds, theproduced file is loaded into memory using load/1 (section 8.23.2, page 153). Namely, the byte-code ofeach predicate is loaded. When a predicate P is loaded if there is a previous definition for P it is removed(i.e. all clauses defining P are erased). We say that P is redefined. Note that only consulted predicates
can be redefined. If P is a native-code predicate, trying to redefine it will produce an error at load-time:
the predicate redefinition will be ignored and the following message displayed:
native code procedure P cannot be redefinedFinally, an existing predicate will not be removed if it is not re-loaded. This means that if a predicate P
is loaded when consulting the file F , and if later the definition of P is removed from the file F , consulting
F again will not remove the previously loaded definition of P from the memory.
Consulted predicates can be debugged using the Prolog debugger. Use the debugger predicate trace/0
or debug/0 (section 5.3.1, page 31) to activate the debugger.

18

4.2.4

4

USING GNU PROLOG

Scripting Prolog

Since version 1.4.0 it is possible to use a Prolog source file as a Unix script-file (shebang support). A
PrologScript file should begin as follows:#!/usr/bin/gprolog --consult-file
GNU Prolog will be invoked as/usr/bin/gprolog --consult-file FILE
Then FILE will be consulted. In order to correctly deal with the #! first line, consult/1 treats as acomment a first line of a file which begins with # (if you want to use a predicate name starting with a #,simply skip a line before its definition).
Remark: it is almost never possible to pass additionnal parameters (e.g. query-goal) this way since inmost systems the shebang implementation deliver all arguments (following #!/usr/bin/gprolog) as asingle string (which cannot then correctly be recognized by gprolog).

4.2.5Interrupting a query

Under the top-level it is possible to interrupt the execution of a query by typing the interruption key(Ctl-C). This can be used to abort a query, to stop an infinite loop, to activate the debugger,. . . When aninterruption occurs the top-level displays the following message: Prolog interruption (h for help) ?
The user can then type one of the following commands:
Commandaebctdh or ?

4.2.6

Name
abort
exit
break
continue
trace
debug
help

Description
abort the current execution. Same as abort/0 (section 8.18.1, page 126)
quit the current Prolog process. Same as halt/0 (section 8.18.1, page 126)
invoke a recursive top-level. Same as break/0 (section 8.18.1, page 126)
resume the execution
start the debugger using trace/0 (section 5.3.1, page 31)
start the debugger using debug/0 (section 5.3.1, page 31)
display a summary of available commands

The line editor

The line editor (linedit) allows the user to build/update the current input line using a variety ofcommands. This facility is available if the linedit part of GNU Prolog has been installed. linedit is
implicitly called by any built-in predicate reading from a terminal (e.g. get char/1, read/1,. . . ). Thisis the case when the top-level reads a query.
Bindings: each command of linedit is activated using a key. For some commands another key is alsoavailable to invoke the command (on some terminals this other key may not work properly while theprimary key always works). Here is the list of available commands:

4.2

The GNU Prolog interactive interpreter

Key
Ctl-B
Ctl-F
Esc-B
Esc-F
Ctl-A
Ctl-E
Ctl-H
Ctl-D
Ctl-U
Ctl-K
Esc-L
Esc-U
Esc-C
Ctl-T
Ctl-V
Ctl-I
Esc-Ctl-I
Ctl-space
Esc-W
Ctl-W
Ctl-Y
Ctl-P
Ctl-N
Esc-P
Esc-N
Esc-<
Esc->
Ctl-C
Ctl-D
RETURN
Esc-?

Alternate key
←
→
Ctl-←
Ctl-→
Home
End
Backspace
DeleteCtl-Home
Ctl-EndInsertTab
Esc-Tab↑↓Page Up
Page Down

19

Description
go to the previous charactergo to the next charactergo to the previous word
go to the next word
go to the beginning of the line
go to the end of the line
delete the previous character
delete the current character
delete from beginning of the line to the current character
delete from the current character to the end of the line
lower case the next word
upper case the next word
capitalize the next word
exchange last two charactersswitch on/off the insert/replace mode
complete word (twice displays all possible completions)insert spaces to emulate a tabulation
mark beginning of the selection
copy (from the begin selection mark to the current character)cut (from the begin selection mark to the current character)
paste
recall previous history line
recall next history line
recall previous history line beginning with the current prefix
recall next history line beginning with the current prefix
recall first history line
recall last history line
generate an interrupt signal (section 4.2.5, page 18)
generate an end-of-file character (at the begin of the line)
validate a line
display a summary of available commands

History: when a line is entered (i.e. terminated by RETURN), linedit records it in an internal list called
history. It is later possible to recall history lines using appropriate commands (e.g. Ctl-P recall the lastentered line) and to modify them as needed. It is also possible to recall a history line beginning with agiven prefix. For instance to recall the previous line beginning with write simply type write followedby Esc-P. Another Esc-P will recall an earlier line beginning with write,. . .
Completion: another important feature of linedit is its completion facility. Indeed, linedit maintains
a list of known words and uses it to complete the prefix of a word. Initially this list contains all predefinedatoms and the atoms corresponding to available predicates. This list is dynamically updated when a new
atom appears in the system (whether read at the top-level, created with a built-in predicate, associatedwith a new consulted predicate,. . . ). When the completion key (Tab) is pressed linedit acts as follows:• use the current word as a prefix.
• collect all words of the list that begin with this prefix.
• complete the current word with the longest common part of all matching words.
• if more than one word matches emit a beep (a second Tab will display all possibilities).
Example:20

4| ?- argu| ?- argument
argument counter
argument list
argument value| ?- argument

USING GNU PROLOG(here the user presses Tab to complete the word)(linedit completes argu with argument and emits a beep)(the user presses again Tab to see all possible completions)(linedit shows 3 possible completions)(linedit redisplays the input line)| ?- argument c(to select argument counter the user presses c and Tab)
| ?- argument counter (linedit completes with argument counter)
Balancing: linedit allows the user to check that (square/curly) brackets are well balanced. For this,when a close bracket symbol, i.e. ), ] or }, is typed, linedit determines the associated open bracket,
i.e. (, [ or {, and temporarily repositions the cursor on it to show the match.
Customization: the behavior of linedit can be controlled via an environment variable called LINEDIT.
This variable can contain the following substrings:
noansi=noout=N
gui=nogui=silent
cp=N
oem put=no
oem get=no

4.3

do not activated linedit (should the only value of the variable)
do not use ANSI escape sequence (unix only)
use the file descriptor N for the output (unix only)
even if compiled with the GUI console run in text mode (windows)
if the GUI console is not found, silently run in text mode (windows)
use code page N (windows text console)
do not use Char→Oem conversion when emitting a char (windows text console)
do not use Oem→Char conversion when reading a char (windows text console)

Adjusting the size of Prolog data

GNU Prolog uses several stacks to execute a Prolog program. Each stack has a static size and cannot be
dynamically increased during the execution. For each stack there is a default size but the user can define
a new size by setting an environment variable. When a GNU Prolog program is run it first consults thesevariables and if they are not defined uses the default sizes. The following table presents each stack of
GNU Prolog with its default size and the name of its associated environment variable:
Since version 1.4.2, the size of the atom table (the table recording all atoms) is managed similarly tostacks. It is then included in the following table (even if actually it is not a stack but an hash table). In
this table, the associated name is atoms which is the key used in statistics (section 8.24.1, page 155). The
environment variable name is derived from the corresponding Prolog flag max atom, see (section 8.22.1,
page 148).
Stack
name
local
global
trail
cstr
atoms

Default
size (Kb)
16384
32768
16384
16384
32768

Environment
variable
LOCALSZGLOBALSZ
TRAILSZCSTRSZMAX ATOM

Description
control stack (environments and choice-points)
heap (compound terms)
conditional bindings (bindings to undo at backtracking)finite domain constraint stack (FD variables and constraints)
atom table

In addition, under Windows (since version 1.4.0), registry keys are consulted (key names are the same asenvironment names). The keys are stored in HKEY CURRENT USER\Software\GnuProlog\.
If the size of a stack is too small an overflow will occur during the execution. In that case GNU Prolog

4.4

The GNU Prolog compiler

21

emits the following error message before stopping:S stack overflow (size: N Kb, environment variable used: E )where S is the name of the stack, N is the current stack size in Kb and E the name of the associatedenvironment variable. When such a message occurs it is possible to (re)define the variable E with the
new size. For instance to allocate Kb to the local stack under a Unix shell use:
(under sh or bash)(under csh or tcsh)

LOCALSZ=32768; export LOCALSZ
setenv LOCALSZ 32768

This method allows the user to adjust the size of Prolog stacks. However, in some cases it is preferable
not to allow the user to modify these sizes. For instance, when providing a stand alone executable whose
behavior should be independent of the environment in which it is run. In that case the program should
not consult environment variables and the programmer should be able to define new default stack sizes.
The GNU Prolog compiler offers this facilities via several command-line options such as --local-sizeor --fixed-sizes (section 4.4.3, page 23).
Finally note that GNU Prolog stacks are virtually allocated (i.e. use virtual memory). This means thata physical memory page is allocated only when needed (i.e. when an attempt to read/write it occurs).
Thus it is possible to define very large stacks. At the execution, only the needed amount of space will bephysically allocated.

4.4

The GNU Prolog compiler

4.4.1

Different kinds of codes

One of the main advantages of GNU Prolog is its ability to produce stand alone executables. A Prolog
program can be compiled to native code to give rise to a machine-dependent executable using the GNU
Prolog compiler. However native-code predicates cannot be listed nor fully debugged. So there is analternative to native-code compilation: byte-code compilation. By default the GNU Prolog compiler
produces native-code but via a command-line option it can produce a file ready for byte-code loading.
This is exactly what consult/1 does as was explained above (section 4.2.3, page 17). GNU Prolog also
manages interpreted code using a Prolog interpreter written in Prolog. Obviously interpreted code isslower than byte-code but does not require the invocation of the GNU Prolog compiler. This interpreter
is used each time a meta-call is needed as by call/1 (section 7.2.3, page 52). This also the case of
dynamically asserted clauses. The following table summarizes these three kinds of codes:
Typeinterpreted-codebyte-code
native-code

4.4.2

Speed
slow
mediumfast

Debug ?
yes
yesno

For whatmeta-call and dynamically asserted clauses
consulted predicatescompiled predicatesCompilation scheme

Native-code compilation: a Prolog source is compiled in several stages to produce an object file thatis linked to the GNU Prolog libraries to produce an executable. The Prolog source is first compiled toobtain a WAM [9] file. For a detailed study of the WAM the interested reader can refer to “Warren’s
Abstract Machine: A Tutorial Reconstruction” [1]. The WAM file is translated to a machine-independent
language specifically designed for GNU Prolog. This language is close to a (universal) assembly language
and is based on a very reduced instruction set. For this reason this language is called mini-assembly(MA). The mini-assembly file is then mapped to the assembly language of the target machine. This

22

4

USING GNU PROLOG

assembly file is assembled to give rise to an object file which is then linked with the GNU Prolog libraries
to provide an executable. The compiler also takes into account Finite Domain constraint definition files.
It translates them to C and invoke the C compiler to obtain object files. The following figure presents
this compilation scheme:

Obviously all intermediate stages are hidden to the user who simply invokes the compiler on his Prolog
file(s) (plus other files: C,. . . ) and obtains an executable. However, it is also possible to stop thecompiler at any given stage. This can be useful, for instance, to see the WAM code produced (perhaps
when learning the WAM). Finally it is possible to give any kind of file to the compiler which will insert
it in the compilation chain at the stage corresponding to its type. The type of a file is determined using
the suffix of its file name. The following table presents all recognized types/suffixes:

4.4

The GNU Prolog compiler

23

Suffix of the file.pl, .pro, .prolog
.wam
.ma
.s
.c, .C, .CC, .cc, .cxx, .c++, .cpp.fd
any other suffix (.o, .a,. . . )Type of the file
Prolog source file
WAM source fileMini-assembly source file
Assembly source file
C or C++ source file
Finite Domain constraint source file
any other type (object, library,. . . )Handled by:pl2wamwam2mama2asmthe assembler
the C compiler
fd2c
the linker (C linker)

Byte-code compilation: the same compiler can be used to compile a source Prolog file for byte-code.
In that case the Prolog to WAM compiler is invoked using a specific option and produces a WAM forbyte-code source file (suffixed .wbc) that can be later loaded using load/1 (section 8.23.2, page 153).
Note that this is exactly what consult/1 (section 8.23.1, page 153) does as explained above (section 4.2.3,
page 17).

4.4.3

Using the compiler

The GNU Prolog compiler is a command-line compiler similar in spirit to a Unix C compiler like gcc.
To invoke the compiler use the gplc command as follows:% gplc [OPTION ]. . . FILE . . .

(the % symbol is the operating system shell prompt)

The arguments of gplc are file names that are dispatched in the compilation scheme depending on thetype determined from their suffix as was explained previously (section 4.4.2, page 21). All object files arethen linked to produce an executable. Note however that GNU Prolog has no module facility (since there
is not yet an ISO reference for Prolog modules) thus a predicate defined in a Prolog file is visible fromany other predicate defined in any other file. GNU Prolog allows the user to split a big Prolog source
into several files but does not offer any way to hide a predicate from others.
The simplest way to obtain an executable from a Prolog source file prog.pl is to use:
% gplc prog.pl
This will produce an native executable called prog which can be executed as follows:% progHowever, there are several options that can be used to control the compilation:
General options:-o FILE , --output FILE
-W, --wam-for-native-w, --wam-for-byte-code-M, --mini-assembly-S, --assembly-F, --fd-to-c-c, --object--temp-dir PATH--no-del-temp--no-demangling-v, --verbose-h, --help--version

use FILE as the name of the output filestop after producing WAM file(s)stop after producing WAM for byte-code file(s) (force --no-call-c)
stop after producing mini-assembly file(s)stop after producing assembly file(s)stop after producing C file(s) from FD constraint definition file(s)stop after producing object file(s)use PATH as directory for temporary files
do not delete temporary files
do not decode predicate names (name demangling)
print executed commands
print a help and exit
print version number and exit

24

4

USING GNU PROLOG

Prolog to WAM compiler options:--pl-state FILE--wam-comment COMMENT--no-susp-warn--no-singl-warn--no-redef-error--foreign-only--no-call-c--no-inline--no-reorder--no-reg-opt--min-reg-opt--no-opt-last-subterm--fast-math--keep-void-inst--compile-msg--statistics

read FILE to set the initial Prolog state
emit COMMENT as a comment in the WAM file
do not show warnings for suspicious predicates
do not show warnings for named singleton variables
do not show errors for built-in predicate redefinitions
only compile foreign/1-2 directives
do not allow the use of fd tell, ’$call c’,. . .
do not inline predicates
do not reorder predicate arguments
do not optimize registers
minimally optimize registers
do not optimize last subterm compilation
use fast mathematical mode (assume integer arithmetics)
keep void WAM instructions in the output file
print a compile message
print statistics information

WAM to mini-assembly translator options:--comment

include comments in the output fileMini-assembly to assembly translator options:--comment--picinclude comments in the output fileproduce position independent code (PIC)

C compiler options:--c-compiler FILE
-C OPTION

use FILE as C compiler/linker
pass OPTION to the C compiler

Assembler options:-A OPTION
Linker options:pass OPTION to the assembler

4.4

The GNU Prolog compiler--linker FILE--local-size N--global-size N--trail-size N--cstr-size N--max-atom N--fixed-sizes--gui-console--new-top-level--no-top-level--no-debugger--min-pl-bips--min-fd-bips--min-bips--min-size--no-fd-lib-s, --strip-L OPTION25

use FILE as linker
set default local stack size to N Kb
set default global stack size to N Kb
set default trail stack size to N Kb
set default constraint stack size to N Kb
set default atom table size to N atoms
do not consult environment variables at run-time (use default sizes)
link with the GUI console (windows only)
link the top-level main (to recognize top-level command-line options)do not link the top-level (force --no-debugger)
do not link the Prolog/WAM debugger
link only used Prolog built-in predicateslink only used FD solver built-in predicates
shorthand for: --no-top-level --min-pl-bips --min-fd-bips
shorthand for: --min-bips --strip
do not look for the FD library (maintenance only)
strip the executable
Pass OPTION to the linker

It is possible to only give the prefix of an option if there is no ambiguity.
The name of the output file is controlled via the -o FILE option. If present the output file produced will
be named FILE . If not specified, the output file name depends on the last stage reached by the compiler.
If the link is not done the output file name(s) is the input file name(s) with the suffix associated withthe last stage. If the link is done, the name of the executable is the name (without suffix) of the first filename encountered in the command-line. Note that if the link is not done -o has no sense in the presenceof multiple input file names. For this reason, several meta characters are available for substitution in
FILE :• %f is substitued by the whole input file name.
• %F is similar to %f but the directory part is omitted.
• %p is substitued by the whole prefix file name (omitting the suffix).
• %P is similar to %p but the directory part is omitted.
• %s is substitued by the file suffix (including the dot).
• %d is substitued by the directory part (empty if no directory is specified).
• %c is substitued by the value of an internal counter starting from 1 and auto-incremented.
By default the compiler runs in the native-code compilation scheme. To generate a WAM file for byte-code
use the --wam-for-byte-code option. The resulting file can then be loaded using load/1 (section 8.23.2,
page 153).
To execute the Prolog to WAM compiler in a given read environment (operator definitions, character
conversion table,. . . ) use --pl-state FILE . The state file should be produced by write pl state file/1(section 8.22.5, page 152).
By default the Prolog to WAM compiler inlines calls to some deterministic built-in predicates (e.g. arg/3
and functor/3). Namely a call to such a predicate will not yield a classical predicate call but a simple
C function call (which is obviously faster). It is possible to avoid this using --no-inline.
Another optimization performed by the Prolog to WAM compiler is unification reordering. The argumentsof a predicate are reordered to optimize unification. This can be deactivated using --no-reorder. The

26

4

USING GNU PROLOG

compiler also optimizes the unification/loading of nested compound terms. More precisely, the compiler
emits optimized instructions when the last subterm of a compound term is itself a compound term (e.g.
lists). This can be deactivated using --no-opt-last-subterm.
By default the Prolog to WAM compiler fully optimizes the allocation of registers to decrease both thenumber of instruction produced and the number of used registers. A good allocation will generate many
void instructions that are removed from the produced file except if --keep-void-inst is specified. To
prevent any optimization use --no-reg-opt while --min-reg-opt forces the compiler to only perform
simple register optimizations.
The Prolog to WAM compiler emits an error when a control construct or a built-in predicate is redefined.
This can be avoided using --no-redef-error. The compiler also emits warnings for suspicious predicate
definitions like -/2 since this often corresponds to an earlier syntax error (e.g. - instead of . This canbe deactivated by specifying --no-susp-warn. Finally, the compiler warns when a singleton variable has
a name (i.e. not the generic anonymous name ). This can be deactivated specifying --no-singl-warn.
Internally, predicate names are encoded to fit the syntax of (assembly) identifiers. For this GNU Prolog
uses it own name mangling scheme. This is explained in more detail later (section 4.4.6, page 28). By
default the error messages from the linker (e.g. multiple definitions for a given predicate, reference toan undefined predicate,. . . ) are filtered to replace an internal name representation by the real predicatename (demangling). Specifying the --no-demangling prevents gplc from filtering linker output messages(internal identifiers are then shown).
When producing an executable it is possible to specify default stack sizes (using --STACK NAME -size)
and to prevent it from consulting environment variables (using --fixed-sizes) as was explained above(section 4.3, page 20). By default the produced executable will include the top-level, the Prolog/WAM
debugger and all Prolog and FD built-in predicates. It is possible to avoid linking the top-level (section 4.2, page 13) by specifying --no-top-level. In this case, at least one initialization/1 directive(section 7.1.14, page 50) should be defined. The option --no-debugger does not link the debugger. To include only used built-in predicates that are actually used the options --no-pl-bips and/or --no-fd-bips
can be specified. For the smallest executable all these options should be specified. This can be abbreviated by using the shorthand option --min-bips. By default, executables are not stripped, i.e. theirsymbol table is not removed. This table is only useful for the C debugger (e.g. when interfacing Prolog
and C). To remove the symbol table (and then to reduce the size of the final executable) use --strip.
Finally --min-size is a shortcut for --min-bips and --strip, i.e. the produced executable is as small
as possible.
Example: compile and link two Prolog sources prog1.pl and prog2.pl. The resulting executable will
be named prog1 (since -o is not specified):% gplc prog1.pl prog2.pl
Example: compile the Prolog file prog.pl to study basic WAM code. The resulting file will be named
prog.wam:% gplc -W --no-inline --no-reorder --keep-void-inst prog.pl
Example: compile the Prolog file prog.pl and its C interface file utils.c to provide an autonomous
executable called mycommand. The executable is not stripped to allow the use of the C debugger:% gplc -o mycommand prog.pl utils.c
Example: detail all steps to compile the Prolog file prog.pl (the resulting executable is stripped). Allintermediate files are produced (prog.wam, prog.ma, prog.s, prog.o and the executable prog):% gplc -W prog.pl% gplc -M --comment prog.wam

4.4

The GNU Prolog compiler

27% gplc -S --comment prog.ma% gplc -c prog.s% gplc -o prog -s prog.o

4.4.4

Running an executable

In this section we explain what happens when running an executable produced by the GNU Prolog nativecode compiler. The default main function first starts the Prolog engine. This function collects all linked
objects (issued from the compilation of Prolog files) and initializes them. The initialization of a Prolog
object file consists in adding to appropriate tables new atoms, new predicates and executing its system
directives. A system directive is generated by the Prolog to WAM compiler to reflect a (user) directive
executed at compile-time such as op/3 (section 7.1.11, page 49). Indeed, when the compiler encounterssuch a directive it immediately executes it and also generates a system directive to execute it at thestart of the executable. When all system directives have been executed the Prolog engine executes all
initialization directives defined with initialization/1 (section 7.1.14, page 50). If several initialization
directives appear in the same file they are executed in the order of appearance. If several initialization
directives appear in different files the order in which they are executed is machine-dependant. However,on most machines the order will be the reverse order in which the associated files have been linked (thisis not true under native win32). When all initialization directives have been executed the default mainfunction looks for the GNU Prolog top-level. If present (i.e. it has been linked) it is called otherwise theprogram simply ends. Note that if the top-level is not linked and if there is no initialization directive theprogram is useless since it simply ends without doing any work. The default main function detects sucha behavior and emits a warning message.
Example: compile an empty file prog.pl without linking the top-level and execute it:% gplc --no-top-level prog.pl% progWarning: no initial goal executed
use a directive :- initialization(Goal)or remove the link option --no-top-level (or --min-bips or --min-size)

4.4.5

Generating a new interactive interpreterIn this section we show how to define a new top-level extending the GNU Prolog interactive interpreterwith new predicate definitions. The obtained top-level can then be considered as an enriched version of
the basic GNU Prolog top-level (section 4.2, page 13). Indeed, each added predicate can be viewed asa predefined predicate just like any other built-in predicate. This can be achieved by compiling thesepredicates and including the top-level at link-time.
The real question is: why would we include some predicates in a new top-level instead of simply consulting
them under the GNU Prolog top-level ? There are two reasons for this:• the predicate cannot be consulted. This is the case of a predicate calling foreign code, like a
predicate interfacing with C (section 10, page 201) or a predicate defining a new FD constraint.
• the performance of the predicate is crucial. Since it is compiled to native-code such a predicate will
be executed very quickly. Consulting will load it as byte-code. The gain is much more noticeable if
the program is run under the debugger. The included version will not be affected by the debugger
while the consulted version will be several times slower. Obviously, a predicate should be included
in a new top-level only when it is itself debugged since it is difficult to debug native-code.

28

4

USING GNU PROLOG

To define a new top-level simply compile the set of desired predicates and linking them with the GNU
Prolog top-level (this is the default) using gplc (section 4.4.3, page 23).
Example: let us define a new top-level called my top level including all predicates defined in prog.pl:% gplc -o my top level prog.pl
By the way, note that if prog.pl is an empty Prolog file the previous command will simply create a newinteractive interpreter similar to the GNU Prolog top-level.
Example: as before where some predicates of prog.pl call C functions defined in utils.c:% gplc -o my top level prog.pl utils.c
To obtain a fully extended executable, it is desirable to accept the same set of opions as the original
top-level, see (section 4.2, page 13), e.g. --init-goal. For this it is necessary to link main() functionused by the original top-level. This can be achieved passing the --new-top-level to gplc:% gplc --new-top-level -o my top level prog.pl utils.c
In conclusion, defining a particular top-level is nothing else but a particular case of the native-code
compilation. It is simple to do and very useful in practice.

4.4.6

The name mangling scheme

When the GNU Prolog compiler compiles a Prolog source to an object file it has to associate a symbol toeach predicate name. However, the syntax of symbols is restricted to identifiers: string containing only
letters, digits or underscore characters. On the other hand, predicate names (i.e. atoms) can contain any
character with quotes if necessary (e.g. ’x+y=z’ is a valid predicate name). The compiler may thus haveto encode predicate names respecting the syntax of identifiers. In addition, Prolog allows the user todefine several predicates with the same name and different arities, for this GNU Prolog encodes predicate
indicators (predicate name followed by the arity). Finally, to support modules in the future, the module
name is also encoded.
Since version 1.4.0, GNU Prolog adopts the following name mangling scheme. A predicate indicatorof the form [MODULE :]PRED /N (where the MODULE can be omitted) will give rise to an identifier of thefollowing form: XK [E(MODULE) ]E(PRED) aN where:
K is a digit in 0..5 storing coding information about MODULE and PRED . Possible values are:
• 0: no module present, PRED is not encoded• 1: no module present, PRED is encoded• 2: MODULE is not encoded, PRED is not encoded• 3: MODULE is not encoded, PRED is encoded• 4: MODULE is encoded, PRED is not encoded• 5: MODULE is encoded, PRED is encoded
E(STR) is a function to encode a string STR which returns:• STR itself (not encoded) if STR only contains letters, digits or but does not contain the substring and does not begin nor end with (i.e. regexp: [a-zA-Z0-9]([-]?[a-zA-Z0-9])*).
• an hexadecimal representation of each character of the string otherwise. For example: E( x+y=z)
returns 782B793D7A since 78 is the hexadecimal representation of the ASCII code of x, 2B ofthe code of +, etc.
Examples:4.4

The GNU Prolog compiler

29

Predicate indicator
father/2’x+y=z’/3
util:same/2
util:same 1/3

internal identifier
X0 father a2
X1 782B793D7A a3
X2 util same a2
X3 util 73616D655F5F31 a3

So, from the mini-assembly stage, each predicate indicator is handled via its name mangling identifier.
The knowledge of this scheme is normally not of interest for the user, i.e. the Prolog programmer. For thisreason the GNU Prolog compiler hides this mangling. When an error occurs on a predicate (undefinedpredicate, predicate with multiple definitions,. . . ) the compiler has to decode the symbol associatedwith the predicate indicator (name demangling). For this gplc filters each message emitted by thelinker to locate and decode eventual predicate indicators. This filtering can be deactivated specifying--no-demangling when invoking gplc (section 4.4.3, page 23).
This filter is provided as an utility that can be invoked using the hexgplc command as follows:% hexgplc [OPTION ]. . . FILE . . .

(the % symbol is the operating system shell prompt)

Options:--decode or --demangling--encode or --mangling--relax--printf FORMAT--aux-father--aux-father2--cmd-line-E or -M
-P or -D--help--version

decoding mode (this is the default mode)
encoding mode
decode also predicate names (not only predicate indicators)
pass encoded/decoded string to C printf(3) with FORMAT
decode an auxiliary predicate as its father
decode an auxiliary predicate as its father + auxiliary number
encode/decode each argument of the command-linesame as: --cmd-line --encode --relax
same as: --cmd-line --decode --relax --quote
print a help and exit
print version number and exit

It is possible to give a prefix of an option if there is no ambiguity.
Without arguments hexgplc runs in decoding mode reading its standard input and decoding (demangling)each symbol corresponding to a predicate indicator. To use hexgplc in the encoding (mangling) modethe --encode option must be specified. By default hexgplc only decodes predicate indicators, this canbe relaxed using --relax to also take into account simple predicate names (the arity can be omitted). It
is possible to format the output of an encoded/decoded string using --printf FORMAT in that case eachstring S is passed to the C printf(3) function as printf(FORMAT ,S ).
Auxiliary predicates are generated by the Prolog to WAM compiler when simplifying some control constructs like ’;’/2 present in the body of a clause. They are of the form ’$NAME /ARITY $auxN ’ where
NAME /ARITY is the predicate indicator of the simplified (i.e. father) predicate and N is a sequential number (a predicate can give rise to several auxiliary predicates). It is possible to force hexgplc to decode
an auxiliary predicate as its father predicate indicator using --aux-father or as its father predicate
indicator followed by the sequential number using --aux-father2.
If no file is specified, hexgplc processes its standard input otherwise each file is treated sequentially.
Specifying the --cmd-line option informs hexgplc that each argument is not a file name but a stringthat must be encoded (or decoded). This is useful to encode/decode a particular string. For this reason
the option -E (encode) and -D (decode) are provided as shorthand. Then, to obtain the mangling
representation of a predicate PRED use:
% hexgplc -E PRED

30

4USING GNU PROLOG

NB: if PRED is a complex atom it is necessary to quote it (the quotes must be passed to hexgplc). Hereis an example under bash:% hexgplc -E \’x+y=z\’/3
X1_782B793D7A__a3
Or even more safely (using bash quotes to prevent bash from interpreting special characters):% hexgplc -E \’’x+y=z’\’/3
X1_782B793D7A__a3

315

Debugging

5.1

Introduction

The GNU Prolog debugger provides information concerning the control flow of the program. The debugger
can be fully used on consulted predicates (i.e. byte-code). For native compiled code only the calls/exits
are traced, no internal behavior is shown. Under the debugger it is possible to exhaustively trace theexecution or to set spy-points to only debug a specific part of the program. Spy-points allow the user toindicate on which predicates the debugger has to stop to allow the user to interact with it. The debugger
uses the “procedure box control flow model”, also called the Byrd Box model since it is due to Lawrence
Byrd.

5.2

The procedure box model

The procedure box model of Prolog execution provides a simple way to show the control flow. Thismodel is very popular and has been adopted in many Prolog systems (e.g. SICStus Prolog, Quintus
Prolog,. . . ). A good introduction is the chapter 8 of “Programming in Prolog” of Clocksin & Mellish [2].
The debugger executes a program step by step tracing an invocation to a predicate (call) and thereturn from this predicate due to either a success (exit) or a failure (fail). When a failure occurs
the execution backtracks to the last predicate with an alternative clause. The predicate is then reinvoked (redo). Another source of change of the control flow is due to exceptions. When an exception israised from a predicate (exception) by throw/1 (section 7.2.4, page 53) the control is given back to themost recent predicate that has defined a handler to recover this exception using catch/3 (section 7.2.4,
page 53). The procedure box model shows these different changes in the control flow, as illustrated here:

Each arrow corresponds to a port. An arrow to the box indicates that the control is given to this predicate
while an arrow from the box indicates that the control is given back from the procedure. This modelvisualizes the control flow through these five ports and the connections between the boxes associated with
subgoals. Finally, it should be clear that a box is associated with one invocation of a given predicate. In
particular, a recursive predicate will give raise to a box for each invocation of the predicate with different
entries/exits in the control flow. Since this might get confusing for the user, the debugger associates witheach box a unique identifier (i.e. the invocation number).

5.3

Debugging predicates

5.3.1

Running and stopping the debugger

trace/0 activates the debugger. The next invocation of a predicate will be traced.
debug/0 activates the debugger. The next invocation of a predicate on which a spy-point has been set
will be traced.

32

5

DEBUGGING

It is important to understand that the information associated with the control flow is only available when
the debugger is on. For efficiency reasons, when the debugger is off the information concerning the control
flow (i.e. the boxes) is not retained. So, if the debugger is activated in the middle of a computation (bya call to debug/0 or trace/0 in the program or after the interrupt key sequence (Ctl-C) by choosing
trace or debug), information prior to this point is not available.
debugging/0: prints onto the terminal information about the current debugging state (whether the
debugger is switched on, what are the leashed ports, spy-points defined,. . . ).
notrace/0 or nodebug/0 switches the debugger off.
wam debug/0 invokes the sub-debugger devoted to the WAM data structures (section 5.6, page 35). It
can be also invoked using the W debugger command (section 5.5, page 33).

5.3.2

Leashing ports

leash(Ports) requests the debugger to prompt the user, as he creeps through the program, for every
port defined in the Ports list. Each element of Ports is an atom in call, exit, redo, fail, exception.
Ports can also be an atom defining a shorthand:• full: equivalent to [call, exit, redo, fail, exception]• half: equivalent to [call, redo]• loose: equivalent to [call]• none: equivalent to []• tight: equivalent to [call, redo, fail, exception]
When an unleashed port is encountered the debugger continues to show the associated goal but does notstop the execution to prompt the user.

5.3.3

Spy-points

When dealing with big sources it is not very practical to creep through the entire program. It is preferable
to define a set of spy-points on interesting predicates to be prompted when the debugger reaches one ofthese predicates. Spy-points can be added either using spy/1 (or spypoint condition/3) or dynamicallywhen prompted by the debugger using the + (or *) debugger command (section 5.5, page 33). The current
mode of leashing does not affect spy-points in the sense that user interaction is requested on every port.
spy(PredSpec) sets a spy-point on all the predicates given by PredSpec. PredSpec defines one or several
predicates and has one of the following forms:• [PredSpec1, PredSpec2,...]: set a spy-point for each element of the list.
• Name: set a spy-point for any predicate whose name is Name (whatever the arity).
• Name/Arity: set a spy-point for the predicate whose name is Name and arity is Arity.
• Name/A1-A2: set a spy-point for the each predicate whose name is Name and arity is between A1
and A2.

5.4

Debugging messages

33

It is not possible to set a spy-point on an undefined predicate.
The following predicate is used to remove one or several spy-points:
nospy(PredSpec) removes the spy-points from the specified predicates.
nospyall/0 removes all spy-points:
It is also possible to define conditional spy-points.
spypoint condition(Goal, Port, Test) sets a conditional spy-point on the predicate for Goal. Whenthe debugger reaches a conditional spy-point it only shows the associated goal if the following conditions
are verified:• the actual goal unifies with Goal.
• the actual port unifies with Port.
• the Prolog goal Test succeeds.

5.4

Debugging messages

We here described which information is displayed by the debugger when it shows a goal. The basic format
is as follows:
S N M Port : Goal ?
S is a spy-point indicator: if there is a spy-point on the current goal the + symbol is displayed else a spaceis displayed. N is the invocation number. This unique number can be used to correlate the trace messages
for the various ports, since it is unique for every invocation. M is an index number which represents thenumber of direct ancestors of the goal (i.e. the current depth of the goal). Port specifies the particular
port (call, exit, fail, redo, exception). Goal is the current goal (it is then possible to inspect its
current instantiation) which is displayed using write term/3 with quoted(true) and max depth(D )options (section 8.14.6, page 108). Initially D (the print depth) is set to 10 but can be redefined using
the < debugger command (section 5.5, page 33). The ? symbol is displayed when the debugger is waiting
a command from the user. (i.e. Port is a leashed port). If the port is unleashed, this symbol is not
displayed and the debugger continues the execution displaying the next goal.

5.5

Debugger commands

When the debugger reaches a leashed port it shows the current goal followed by the ? symbol. At thispoint there are many commands available. Typing RETURN will creep into the program. Continuing tocreep will show all the control flow. The debugger shows every port for every predicate encounteredduring the execution. It is possible to select the ports at which the debugger will prompt the user using
the built-in predicate leash/1 (section 5.3.2, page 32). Each command is only one character long:34

5Command
RET or c
l

Name
creep
leap

s

skip

G

go to

r

retry

f
w
d
p
e
g
A

fail
write
display
print
exception
ancestors
alternatives

u

unify

.

father filen=no debugdebugging+spy this-nospy this*spy conditionallyLlisting

a

abort

b

break

@
<

execute goal
set print depth

h or ?
W

help
WAM debugger

DEBUGGING

Description
single-step to the next port
continue the execution only stopping when a goal with a spy-pointis reachedskip over the entire execution of the current goal. No message will
be shown until control returns
ask for an invocation number and continue the execution until a port
is reached for that invocation number
try to restart the invocation of the current goal by failing until reaching the invocation of the goal. The state of execution is the sameas when the goal was initially invoked (except when using side-effectpredicates)
force the current goal to fail immediately
show the current goal using write/2 (section 8.14.6, page 108)
show the current goal using display/2 (section 8.14.6, page 108)
show the current goal using print/2 (section 8.14.6, page 108)
show the pending exception. Only applicable to an exception portshow the list of ancestors of the current goal
show the list of ancestors of the current goal combined with choicepoints
ask for a term and unify the current goal with this term. This isconvenient for getting a specific solution. Only available at a callportshow the Prolog file name and the line number where the current
predicate is definedswitch the debugger off. Same as nodebug/0 (section 5.3.1, page 31)
show debugger information. Same as debugging/0 (section 5.3.1,
page 31)
set a spy-point on the current goal. Uses spy/1 (section 5.3.3,
page 32)
remove a spy-point on the current goal. Uses nospy/1 (section 5.3.3,
page 32)
ask for a term Goal, Port, Test (terminated by a dot) and
set a conditional spy-point on the current predicate. Goal andthe current goal must have the same predicate indicator. Uses
spypoint condition/3 (section 5.3.3, page 32)
list all the clauses associated with the current predicate. Uses
listing/1 (section 8.23.3, page 154)
abort the current execution. Same as abort/0 (section 8.18.1,
page 126)
invoke a recursive top-level. Same as break/0 (section 8.18.1,
page 126)
ask for a goal and execute it
ask for an integer and set the print depth to this value (-1 for no
depth limit)
display a summary of available commands
invoke the low-level WAM debugger (section 5.6, page 35)

5.6

The WAM debugger

5.6

35

The WAM debugger

In some cases it is interesting to have access to the WAM data structures. This sub-debugger allows
the user to inspect/modify the contents of any stack or register of the WAM. The WAM debugger isinvoked using the built-in predicate wam debug/0 (section 5.3.1, page 31) or the W debugger command(section 5.5, page 33). The following table presents the specific commands of the WAM debugger:
Commandwrite A [N ]data A [N ]modify A [N ]where A
what RA
deref Aenvir [SA ]backtrack [SA ]backtrack all
quit
help

Description
write N terms starting at the address A using write/1 (section 8.14.6, page 108)
display N words starting at the address A
display and modify N words starting at the address A
display the real address corresponding to A
display what corresponds to the real address RA
display the dereferenced word starting at the address A
display the contents of the environment located at SA (or the current one)
display the contents of the choice-point located at SA (or the current one)
display all choice-points
quit the WAM debugger
display a summary of available commands

In the above table the following conventions apply:• elements between [ and ] are optional.
• N is an optional integer (defaults to 1).
• A is a WAM address, its syntax is: BANK NAME [ [ N ] ], i.e. a bank name possibly followed by anindex (defaults to 0). BANK NAME is either:– reg: WAM general register (stack pointers, continuation, ...).
– x: WAM X register (temporary variables, i.e. arguments).
– y: WAM Y register (permanent variables).
– ab: WAM X register saved in the current choice-point.
– STACK NAME : WAM stack (STACK NAME in local, global, trail, cstr).
• SA is a WAM stack address, i.e. STACK NAME [ [ N ] ] (special case of WAM addresses).
• RA is a real address, its syntax is the syntax of C integers (in particular the notation 0x... isrecognized).
It is possible to only use the first letters of a commands and bank names when there is no ambiguity. Also
the square brackets [ ] enclosing the index of a bank name can be omitted. For instance the following
command (showing the contents of 25 consecutive words of the global stack from the index 3): data
global[3] 25 can be abbreviated as: d g 3 25.

36

5

DEBUGGING

37

6

Format of definitions

6.1

General format

The definition of control constructs, directives and built-in predicates is presented as follows:
Templates
Specifies the types of the arguments and which of them shall be instantiated (mode). Types and modes
are described later (section 6.2, page 37).
Description
Describes the behavior (in the absence of any error conditions). It is explicitly mentioned when a builtin predicate is re-executable on backtracking. Predefined operators involved in the definition are alsomentioned.
Errors
Details the error conditions. Possible errors are detailed later (section 6.3, page 39). For directives, thispart is omitted.
Portability
Specifies whether the definition conforms to the ISO standard or is a GNU Prolog extension.

6.2

Types and modes

The templates part defines, for each argument of the concerned built-in predicate, its mode and type.
The mode specifies whether or not the argument must be instantiated when the built-in predicate iscalled. The mode is encoded with a symbol just before the type. Possible modes are:• +: the argument must be instantiated.
• -: the argument must be a variable (will be instantiated if the built-in predicate succeeds).
• ?: the argument can be instantiated or a variable.
The type of an argument is defined by the following table:

38

Type
TYPE list
TYPE1 or TYPE2
atom
atom property
booleanbytecallable term
charactercharacter codeclauseclose option
compound term
evaluable
fd bool evaluable
fd labeling option
fd evaluable
fd variable
flag
float
head
integer
in bytein characterin character code
io modelist
nonvarnumberoperator specifier
os file property
predicate indicatorpredicate property
read option
socket address
socket domain
source sinkstreamstream option
stream or alias
stream position
stream property
stream seek methodterm
var binding option
write option

6

FORMAT OF DEFINITIONS

Description
a list whose the type of each element is TYPE
a term whose type is either TYPE1 or TYPE2
an atoman atom property (section 8.19.11, page 134)
the atom true or false
an integer ≥ 0 and ≤ 255
an atom or a compound terma single character atom
an integer ≥ 1 and ≤ 255
a clause (fact or rule)a close option (section 8.10.7, page 82)
a compound term
an arithmetic expression (section 8.6.1, page 66)
a boolean FD expression (section 9.7.1, page 191)
an FD labeling option (section 9.9.1, page 198)an arithmetic FD expression (section 9.6.1, page 188)
an FD variable
a Prolog flag (section 8.22.1, page 148)
a floating point numbera head of a clause (atom or compound term)
an integer
an integer ≥ 0 and ≤ 255 or -1 (for the end-of-file)a single character atom or the atom end of file (for the end-of-file)an integer ≥ 1 and ≤ 255 or -1 (for the end-of-file)an atom in: read, write or append
the empty list [] or a non-empty list [ | ]any term that is not a variable
an integer or a floating point number
an operator specifier (section 8.14.10, page 113)
an operating system file property (section 8.27.11, page 165)
a term Name/Arity where Name is an atom and Arity an integer ≥ 0. A
callable term can be given if the strict iso Prolog flag is switched off(section 8.22.1, page 148)a predicate property (section 8.8.2, page 75)
a read option (section 8.14.1, page 104)a term of the form ’AF UNIX’(A) or ’AF INET’(A,N) where A is an atom
and N an integer
an atom in: ’AF UNIX’ or ’AF INET’an atom identifying a source or a sinka stream-term: a term of the form ’$stream’(N) where N is an integer ≥ 0
a stream option (section 8.10.6, page 81)
a stream-term or an alias (atom)
a stream position: a term ’$stream position’(I1, I2, I3, I4) where
I1, I2, I3 and I4 are integers
a stream property (section 8.10.10, page 84)
an atom in: bof, current or eof
any term
a variable binding option (section 8.5.3, page 64)
a write option (section 8.14.6, page 108)

6.3

Errors6.3

Errors

6.3.1

General format and error context

39

When an error occurs an exception of the form: error(ErrorTerm , Caller ) is raised. ErrorTerm isa term specifying the error (detailed in next sections) and Caller is a term specifying the context ofthe error. The context is either the predicate indicator of the last invoked built-in predicate or an atom
giving general context information.
Using exceptions allows the user both to recover an error using catch/3 (section 7.2.4, page 53) and toraise an error using throw/1 (section 7.2.4, page 53).
To illustrate how to write error cases, let us write a predicate my pred(X) where X must be an integer:
my_pred(X) :(nonvar(X) ->true;
throw(error(instantiation_error, my_pred/1)),),(
integer(X) ->true;
throw(error(type_error(integer, X), my_pred/1))),...
To help the user to write these error cases, a set of system predicates is provided to raise errors. These
predicates are of the form ’$pl err ...’ and they all refer to the implicit error context. The predicates
set bip name/2 (section 8.22.3, page 151) and current bip name/2 (section 8.22.4, page 151) are provided to set and recover the name and the arity associated with this context (an arity < 0 means that
only the atom corresponding to the functor is significant). Using these system predicates the user could
define the above predicate as follow:
my_pred(X) :set_bip_name(my_pred,1),(
nonvar(X) ->true;’$pl_err_instantiation’),(
integer(X) ->true;’$pl_err_type’(integer, X)),...
The following sections detail each kind of errors (and associated system predicates).

6.3.2

Instantiation error

An instantiation error occurs when an argument or one of its components is variable while an instantiatedargument was expected. ErrorTerm has the following form: instantiation error.
The system predicate ’$pl err instantiation’ raises this error in the current error context (section 6.3.1, page 39).

40

6

6.3.3

FORMAT OF DEFINITIONS

Uninstantiation error

An uninstantiation Error when an argument or one of its components is not a variable, and a variable or acomponent as variable is required. ErrorTerm has the following form: uninstantiation error(Culprit )where Culprit is the argument or one of its components which caused the error.
The system predicate ’$pl err uninstantiation’(Culprit) raises this error in the current error context (section 6.3.1, page 39).

6.3.4

Type error

A type error occurs when the type of an argument or one of its components is not the expected type(but not a variable). ErrorTerm has the following form: type error(Type , Culprit ) where Type isthe expected type and Culprit the argument which caused the error. Type is one of:• atom• evaluable• integer• atomic• fd bool evaluable• list• boolean• fd evaluable• number• byte• fd variable• pair• callable• float• predicate indicator• character• in byte• compound• in character

The system predicate ’$pl err type’(Type, Culprit) raises this error in the current error context(section 6.3.1, page 39).

6.3.5

Domain error

A domain error occurs when the type of an argument is correct but its value is outside the expecteddomain. ErrorTerm has the following form: domain error(Domain , Culprit ) where Domain is the
expected domain and Culprit the argument which caused the error. Domain is one of:• atom property• g array index• os path• buffering mode

• io mode• predicate property• character code list

• non empty list

• prolog flag

• close option• not less than zero• read option• date time

• operator priority• selectable item

• eof action• operator specifier• socket address• fd labeling option• order• socket domain• flag value• os file permission• source sink

• format control sequence• os file property• statistics key

6.3

Errors41• statistics value• stream position• term stream or alias• stream• stream property• var binding option• stream option• stream seek method• write option• stream or alias• stream typeThe system predicate ’$pl err domain’(Domain, Culprit) raises this error in the current error context(section 6.3.1, page 39).

6.3.6

Existence error

an existence error occurs when an object on which an operation is to be performed does not exist.
ErrorTerm has the following form: existence error(Object , Culprit ) where Object is the type ofthe object and Culprit the argument which caused the error. Object is one of:• procedure• source sink

• stream

The system predicate ’$pl err existence’(Object, Culprit) raises this error in the current error
context (section 6.3.1, page 39).

6.3.7

Permission error

A permission error occurs when an attempt to perform a prohibited operation is made. ErrorTermhas the following form: permission error(Operation , Permission , Culprit ) where Operation is
the operation which caused the error, Permission the type of the tried permission and Culprit theargument which caused the error. Operation is one of:• access• create• open• add alias• input• output• close• modify• reposition• binary stream• past end of stream• static procedure• flag• private procedure• stream• operator• source sink

• text stream

and Permission is one of:

The system predicate ’$pl err permission’(Operation, Permission, Culprit) raises this error in
the current error context (section 6.3.1, page 39).

6.3.8

Representation error

A representation error occurs when an implementation limit has been breached. ErrorTerm has thefollowing form: representation error(Limit ) where Limit is the name of the reached limit. Limit
is one of:42

6

FORMAT OF DEFINITIONS• character• max arity• integer 32bits• character code

• max integer• too many variables• in character code

• min integer

The errors max integer and min integer are not currently implemented.
The system predicate ’$pl err representation’(Limit) raises this error in the current error context(section 6.3.1, page 39).

6.3.9

Evaluation error

An evaluation error occurs when an arithmetic expression gives rise to an exceptional value. ErrorTermhas the following form: evaluation error(Error ) where Error is the name of the error. Error is oneof:• float overflow• undefined• int overflow• underflow• zero divisor

The errors float overflow, int overflow, undefined and underflow are not currently implemented.
The system predicate ’$pl err evaluation’(Error) raises this error in the current error context (section 6.3.1, page 39).

6.3.10Resource error

A resource error occurs when GNU Prolog does not have enough resources. ErrorTerm has the following
form: resource error(Resource ) where Resource is the name of the resource. Resource is one of:• print object not linked• too big fd constraint

The system predicate ’$pl err resource’(Resource) raises this error in the current error context (section 6.3.1, page 39).

6.3.11

Syntax error

A syntax error occurs when a sequence of character does not conform to the syntax of terms. ErrorTermhas the following form: syntax error(Error ) where Error is an atom explaining the error.
The system predicate ’$pl err syntax’(Error) raises this error in the current error context (section 6.3.1, page 39).

6.3.12

System error

A system error can occur at any stage. A system error is generally associated with an external component(e.g. operating system). ErrorTerm has the following form: system error(Error ) where Error is6.3

Errors43

an atom explaining the error. This is an extension to ISO which only defines system error without
arguments.
The system predicate ’$pl err system’(Error) raises this error in the current error context (section 6.3.1, page 39).

44

6

FORMAT OF DEFINITIONS

45

7

Prolog directives and control constructs

7.1

Prolog directives

7.1.1

Introduction

Prolog directives are annotations inserted in Prolog source files for the compiler. A Prolog directive isused to specify:• the properties of some procedures defined in the source file.
• the format and the syntax for read-terms in the source file (using changeable Prolog flags).
• included source files.
• a goal to be executed at run-time.

7.1.2

dynamic/1

Templates
dynamic(+predicate indicator)
dynamic(+predicate indicator list)
dynamic(+predicate indicator sequence)
Description
dynamic(Pred) specifies that the procedure whose predicate indicator is Pred is a dynamic procedure.
This directive makes it possible to alter the definition of Pred by adding or removing clauses. For more
information refer to the section about dynamic clause management (section 8.7.1, page 70).
This directive shall precede the definition of Pred in the source file.
If there is no clause for Pred in the source file, Pred exists however as an empty predicate (this meansthat current predicate(Pred) succeeds).
In order to allow multiple definitions, Pred can also be a list of predicate indicators or a sequence ofpredicate indicators using ’,’/2 as separator.
Portability
ISO directive.

7.1.3

public/1

Templates
public(+predicate indicator)
public(+predicate indicator list)
public(+predicate indicator sequence)

46

7

PROLOG DIRECTIVES AND CONTROL CONSTRUCTS

Description
public(Pred) specifies that the procedure whose predicate indicator is Pred is a public procedure. This
directive makes it possible to inspect the clauses of Pred. For more information refer to the section about
dynamic clause management (section 8.7.1, page 70).
This directive shall precede the definition of Pred in the source file. Since a dynamic procedure is also
public. It is useless (but correct) to define a public directive for a predicate already declared as dynamic.
In order to allow multiple definitions, Pred can also be a list of predicate indicators or a sequence ofpredicate indicators using ’,’/2 as separator.
Portability
GNU Prolog directive. The ISO reference does not define any directive to declare a predicate public
but it does distinguish public predicates. It is worth noting that in most Prolog systems the public/1
directive is as a visibility declaration. Indeed, declaring a predicate as public makes it visible from any
predicate defined in any other file (otherwise the predicate is only visible from predicates defined in thesame source file as itself). When a module system is incorporated in GNU Prolog a more general visibility
declaration shall be provided conforming to the ISO reference.

7.1.4

multifile/1

Templates
multifile(+predicate indicator)
multifile(+predicate indicator list)
multifile(+predicate indicator sequence)
Description
multifile(Pred) specifies that the procedure whose predicate indicator is Pred is a multifle procedure(the clauses of Pred can reside in several source files). This directive is only supported by GNU Prolog
since version 1.4.0.
The native compilation scheme of GNU Prolog requires that each Prolog source file refering to a multifile
predicate Pred must include a multifile(Pred) directive even if no clause are defined in this file forPred (i.e. Pred is only called by other predicates in this source file).
Portability
ISO directive.

7.1.5

discontiguous/1

Templates
discontiguous(+predicate indicator)
discontiguous(+predicate indicator list)
discontiguous(+predicate indicator sequence)
Description

7.1

Prolog directives

47

discontiguous(Pred) specifies that the procedure whose predicate indicator is Pred is a discontiguous
procedure. Namely, the clauses defining Pred are not restricted to be consecutive but can appear anywherein the source file.
This directive shall precede the definition of Pred in the source file.
In order to allow multiple definitions, Pred can also be a list of predicate indicators or a sequence ofpredicate indicators using ’,’/2 as separator.
A multifile predicate (declared with a multifile/1 directive) cannot be directly called from a file where it
is not declared as multifile (the native compiler must know the called predicate is multifile). Workarounds:
either call it via a meta-call (e.g. using call/1) or declare it as multifile in the calling source file). A
good habit is to encapsulate a multifile predicate in a monofile predicate which invokes it (external call
only invoke the monofile wrapper predicate).
Portability
ISO directive.

7.1.6

ensure linked/1

Templates
ensure linked(+predicate indicator)
ensure linked(+predicate indicator list)
ensure linked(+predicate indicator sequence)
Description
ensure linked(Pred) specifies that the procedure whose predicate indicator is Pred must be includedby the linker. This directive is useful when compiling to native code to force the linker to include the codeof a given predicate. Indeed, if the gplc is invoked with an option to reduce the size of the executable(section 4.4.3, page 23), the linker only includes the code of predicates that are statically referenced.
However, the linker cannot detect dynamically referenced predicates (used as data passed to a meta-callpredicate). The use of this directive prevents it to exclude the code of such predicates.
In order to allow multiple definitions, Pred can also be a list of predicate indicators or a sequence ofpredicate indicators using ’,’/2 as separator.
Portability
GNU Prolog directive.

7.1.7

built in/0, built in/1, built in fd/0, built in fd/1

Templates
built inbuilt in(+predicate indicator)
built in(+predicate indicator list)
built in(+predicate indicator sequence)
built in fd

48

7

PROLOG DIRECTIVES AND CONTROL CONSTRUCTS

built in fd(+predicate indicator)
built in fd(+predicate indicator list)
built in fd(+predicate indicator sequence)
Description
built in specifies that the procedures defined from now have the built in property (section 8.8.2,
page 75).
built in(Pred) is similar to built in/0 but only affects the procedure whose predicate indicator is
Pred.
This directive shall precede the definition of Pred in the source file.
In order to allow multiple definitions, Pred can also be a list of predicate indicators or a sequence ofpredicate indicators using ’,’/2 as separator.
built in fd (resp. built in fd(Pred)) is similar to built in (resp. built in(Pred)) but sets thebuilt in fd predicate property (section 8.8.2, page 75).
Portability
GNU Prolog directives.

7.1.8

include/1

Templates
include(+atom)
Description
include(File) specifies that the content of the Prolog source File shall be inserted. The resulting
Prolog text is identical to the Prolog text obtained by replacing the directive by the content of the Prolog
source File.
In case of File is a relative file name, it is searched in the current directory. If it is not found it is thensearched in each directory of parent includers.
See absolute file name/2 for information about the syntax of File (section 8.26.1, page 158).
Portability
ISO directive.

7.1.9

if/1, else/0, endif/0, elif/1

Templates
if(+callable term)
else
endif
elif(+callable term)

7.1

Prolog directives

49

Description
These directives are for conditional compilation.
if(Goal) compile subsequent code only if Goal succeeds. Goal is first processed by expand term/2(section 8.17.2, page 124). If Goal raises an exception it is printed and Goal fails.
else introduces the else part.
endif terminates a conditional compilation part.
elif(Goal) is a shorthand for :- else.

:- if(Goal).

. . . :- endif.

Portability
GNU Prolog directive. Also in SWI and YAP.

7.1.10ensure loaded/1

Templates
ensure loaded(+atom)
Description
ensure loaded(File) is not supported by GNU Prolog. When such a directive is encountered it issimply ignored.
Portability
ISO directive. Not supported.

7.1.11

op/3

Templates
op(+integer, +operator specifier, +atom or atom list)
Description
op(Priority, OpSpecifier, Operator) alters the operator table. This directive is executed as soon
as it is encountered by calling the built-in predicate op/3 (section 8.14.10, page 113). A system directiveis also generated to reflect the effect of this directive at run-time (section 4.4.4, page 27).
Portability
ISO directive.

7.1.12char conversion/2

Templates

50

7

PROLOG DIRECTIVES AND CONTROL CONSTRUCTS

char conversion(+character, +character)
Description
char conversion(InChar, OutChar) alters the character-conversion mapping. This directive is executed as soon as it is encountered by a call to the built-in predicate char conversion/2 (section 8.14.12,
page 116). A system directive is also generated to reflect the effect of this directive at run-time (section 4.4.4, page 27).
Portability
ISO directive.

7.1.13set prolog flag/2

Templates
set prolog flag(+flag, +term)
Description
set prolog flag(Flag, Value) sets the value of the Prolog flag Flag to Value. This directive is executed as soon as it is encountered by a call to the built-in predicate set prolog flag/2 (section 8.22.1,
page 148). A system directive is also generated to reflect the effect of this directive at run-time (section 4.4.4, page 27).
Portability
ISO directive.

7.1.14

initialization/1

Templates
initialization(+callable term)
Description
initialization(Goal) adds Goal to the set of goal which shall be executed at run-time. A user directive
is generated to execute Goal at run-time. If several initialization directives appear in the same file they
are executed in the order of appearance (section 4.4.4, page 27).
Portability
ISO directive.

7.1.15

foreign/2, foreign/1

Templates
foreign(+callable term, +foreign option list)
foreign(+callable term)

7.2

Prolog control constructs

51

Description
foreign(Template, Options) defines an interface predicate whose prototype is Template according tothe options given by Options. Refer to the foreign code interface for more information (section 10.3,
page 202).
foreign(Template) is equivalent to foreign(Template, []).
Portability
GNU Prolog directive.

7.2

Prolog control constructs

GNU Prolog follows the ISO notion of control constructs.

7.2.1

true/0, fail/0, !/0

Templates
true
fail
!
Description
true always succeeds.
fail always fails (enforces backtracking).
! always succeeds and the for side-effect of removing all choice-points created since the invocation of thepredicate activating it.
Errors
None.
Portability
ISO control constructs.

7.2.2(’,’)/2 - conjunction, (;)/2 - disjunction, (->)/2 - if-then, (*->)/2 - soft-cut (softif-then)Templates’,’(+callable term, +callable term);(+callable term, +callable term)->(+callable term, +callable term)*->(+callable term, +callable term)

52

7

PROLOG DIRECTIVES AND CONTROL CONSTRUCTS

Description
Goal1 , Goal2 executes Goal1 and, in case of success, executes Goal2.
Goal1 ; Goal2 first creates a choice-point and executes Goal1. On backtracking Goal2 is executed.
Goal1 -> Goal2 first executes Goal1 and, in case of success, removes all choice-points created by Goal1
and executes Goal2. This control construct acts like an if-then (Goal1 is the test part and Goal2 the thenpart). Note that if Goal1 fails ->/2 fails also. ->/2 is often combined with ;/2 to define an if-then-else
as follows: Goal1 -> Goal2 ; Goal3. Note that Goal1 -> Goal2 is the first argument of the (;)/2
and Goal3 (the else part) is the second argument. Such an if-then-else control construct first createsa choice-point for the else-part (intuitively associated with ;/2) and then executes Goal1. In case of
success, all choice-points created by Goal1 together with the choice-point for the else-part are removed
and Goal2 is executed. If Goal1 fails then Goal3 is executed.
Goal1 *-> Goal2 ; Goal3 implements the so-called soft-cut. It acts as the above if-then-else except that
if Goal1 succeeds only Goal3 is cut (the alternative solutions of Goal1 are preserved and can be foundby backtracking). Note that Goal1 *-> Goal2 alone (i.e. without an else branch Goal3) is equivalent to(Goal1 , Goal2).
’,’, ;, -> and *-> are predefined infix operators (section 8.14.10, page 113).
ErrorsGoal1 or Goal2 is a variable
Goal1 is neither a variable nor a callable term
Goal2 is neither a variable nor a callable term
The predicate indicator Pred of Goal1 or Goal2
does not correspond to an existing procedureand the value of the unknown Prolog flag iserror (section 8.22.1, page 148)

instantiation error
type error(callable, Goal1)
type error(callable, Goal2)
existence error(procedure, Pred)

Portability
ISO control constructs except (*->)/2 which is GNU Prolog specific.

7.2.3

call/1

Templatescall(+callable term)
Descriptioncall(Goal) executes Goal. call/1 succeeds if Goal represents a goal which is true. When Goal contains
a cut symbol ! (section 7.2.1, page 51) as a subgoal, the effect of ! does not extend outside Goal.
Errors7.2

Prolog control constructs

Goal is a variable
Goal is neither a variable nor a callable term
The predicate indicator Pred of Goal does notcorrespond to an existing procedure and thevalue of the unknown Prolog flag is error(section 8.22.1, page 148)

53

instantiation error
type error(callable, Goal)
existence error(procedure, Pred)

Portability
ISO control construct.

7.2.4

catch/3, throw/1

Templates
catch(?callable term, ?term, ?term)
throw(+nonvar)
Description
catch(Goal, Catcher, Recovery) is similar to call(Goal) (section 7.2.3, page 52). If this succeeds or
fails, so does the call to catch/3. If however, during the execution of Goal, there is a call to throw(Ball),the current flow of control is interrupted, and control returns to a call of catch/3 that is being executed.
This can happen in one of two ways:• implicitly, when an error condition for a built-in predicate is satisfied.
• explicitly, when the program executes a call of throw/1 because the program wishes to abandon
the current processing, and instead to take an alternative action.
throw(Ball) causes the normal flow of control to be transferred back to an existing call of catch/3.
When a call to throw(Ball) happens, Ball is copied and the stack is unwound back to the call tocatch/3, whereupon the copy of Ball is unified with Catcher. If this unification succeeds, then catch/3
executes the goal Recovery using call/1 (section 7.2.3, page 52) in order to determine the success or
failure of catch/3. Otherwise, in case the unification fails, the stack keeps unwinding, looking for an
earlier invocation of catch/3. Ball may be any non-variable term.
ErrorsBall is a variableinstantiation error

If Ball does not unify with the Catcher argument of any call of catch/3, a system error message isdisplayed and throw/1 fails.
When catch/3 calls Goal or Recovery it uses call/1 (section 7.2.3, page 52), an instantiation error,a type error or an existence error can then occur depending on Goal or Recovery.
Portability
ISO control constructs.

54

7

PROLOG DIRECTIVES AND CONTROL CONSTRUCTS

55

8

Prolog built-in predicates

8.1

Type testing

8.1.1

var/1, nonvar/1, atom/1, integer/1, float/1, number/1, atomic/1,
compound/1, callable/1, ground/1, is list/1, list/1,
partial list/1, list or partial list/1

Templatesvar(?term)
nonvar(?term)atom(?term)
integer(?term)
float(?term)
number(?term)
atomic(?term)compound(?term)
callable(?term)
ground(?term)
is list(?term)list(?term)
partial list(?term)
list or partial list(?term)

Description
var(Term) succeeds if Term is currently uninstantiated (which therefore has not been bound to anything,
except possibly another uninstantiated variable).
nonvar(Term) succeeds if Term is currently instantiated (opposite of var/1).
atom(Term) succeeds if Term is currently instantiated to an atom.
integer(Term) succeeds if Term is currently instantiated to an integer.
float(Term) succeeds if Term is currently instantiated to a floating point number.
number(Term) succeeds if Term is currently instantiated to an integer or a floating point number.
atomic(Term) succeeds if Term is currently instantiated to an atom, an integer or a floating point number.
compound(Term) succeeds if Term is currently instantiated to a compound term, i.e. a term of arity > 0(a list or a structure).
callable(Term) succeeds if Term is currently instantiated to a callable term, i.e. an atom or a compound
term.
ground(Term) succeeds if Term is a ground term.
list(Term) succeeds if Term is currently instantiated to a list, i.e. the atom [] (empty list) or a termwith principal functor ’.’/2 and with second argument (the tail) a list.
is list(Term) behaves like list(Term) (for compatibility purpose).
partial list(Term) succeeds if Term is currently instantiated to a partial list, i.e. a variable or a term
whose the main functor is ’.’/2 and the second argument (the tail) is a partial list.
list or partial list(Term) succeeds if Term is currently instantiated to a list or a partial list.

56

8

PROLOG BUILT-IN PREDICATES

Errors
None.
Portability
var/1, nonvar/1, atom/1, integer/1, float/1, number/1, atomic/1, compound/1 callable/1 andground/1 are ISO predicates.
list/1, partial list/1 and list or partial list/1 are GNU Prolog predicates.

8.2

Term unification

8.2.1(=)/2 - Prolog unification

Templates=(?term, ?term)
Description
Term1 = Term2 unifies Term1 and Term2. No occurs check is done, i.e. this predicate does not check if avariable is unified with a compound term containing this variable (this can lead to an infinite loop).
= is a predefined infix operator (section 8.14.10, page 113).
Errors
None.
Portability
ISO predicate.

8.2.2

unify with occurs check/2

Templates
unify with occurs check(?term, ?term)
Description
unify with occurs check(Term1, Term2) unifies Term1 and Term2. The occurs check test is done (i.e.
the unification fails if a variable is unified with a compound term containing this variable).
Errors
None.
Portability
ISO predicate.

8.3

Term comparison

8.2.3

57

(\=)/2 - not Prolog unifiable

Templates\=(?term, ?term)
Description
Term1 \= Term2 succeeds if Term1 and Term2 are not unifiable (no occurs check is done).
\= is a predefined infix operator (section 8.14.10, page 113).
Errors
None.
Portability
ISO predicate.

8.3

Term comparison

8.3.1

Standard total ordering of terms

The built-in predicates described in this section allows the user to compare Prolog terms. Prolog terms
are totally ordered according to the standard total ordering of terms which is as follows (from the smallest
term to the greatest):• variables, oldest first.
• finite domain variables (section 9.1.1, page 183), oldest first.
• floating point numbers, in numeric order.
• integers, in numeric order.
• atoms, in alphabetical (i.e. character code) order.
• compound terms, ordered first by arity, then by the name of the principal functor and by thearguments in left-to-right order.
A list is treated as a compound term (whose principal functor is ’.’/2).
The portability of the order of variables is not guaranteed (in the ISO reference the order of variables issystem dependent).

8.3.2(==)/2 - term identical, (\==)/2 - term not identical,(@<)/2 - term less than, (@=<)/2 - term less than or equal to,(@>)/2 - term greater than, (@>=)/2 - term greater than or equal toTemplates

58

8==(?term, ?term)\==(?term, ?term)@<(?term, ?term)

PROLOG BUILT-IN PREDICATES@=<(?term, ?term)@>(?term, ?term)@>=(?term, ?term)

Description
These predicates compare two terms according to the standard total ordering of terms (section 8.3.1,
page 57).
Term1 == Term2 succeeds if Term1 and Term2 are equal.
Term1 \== Term2 succeeds if Term1 and Term2 are different.
Term1 @< Term2 succeeds if Term1 is less than Term2.
Term1 @=< Term2 succeeds if Term1 is less than or equal to Term2.
Term1 @> Term2 succeeds if Term1 is greater than Term2.
Term1 @>= Term2 succeeds if Term1 is greater than or equal to Term2.
==, \==, @<, @=<, @> and @>= are predefined infix operators (section 8.14.10, page 113).
Errors
None.
Portability
ISO predicates.

8.3.3

compare/3

Templates
compare(?atom, +term, +term)
Description
compare(Order, Term1, Term2) compares Term1 and Term2 according to the standard (section 8.3.1,
page 57) and unifies Order with:• the atom < if Term1 is less than Term2.
• the atom = if Term1 and Term2 are equal.
• the atom > if Term1 is greater than Term2.
ErrorsOrder is neither a variable nor an atom
Order is an atom but not <, = or >Portability
ISO predicate.

type error(atom, Order)
domain error(order, Order)

8.4

Term processing

8.4

Term processing

8.4.1

functor/3

59

Templates
functor(+nonvar, ?atomic, ?integer)functor(-nonvar, +atomic, +integer)
Descriptionfunctor(Term, Name, Arity) succeeds if the principal functor of Term is Name and its arity is Arity.
This predicate can be used in two ways:• Term is not a variable: extract the name (an atom or a number if Term is a number) and the arityof Term (if Term is atomic Arity = 0).
• Term is a variable: unify Term with a general term whose principal functor is given by Name andarity is given by Arity.
ErrorsTerm and Name are both variables
Term and Arity are both variables
Term is a variable and Name is neither a variable
nor an atomic term
Term is a variable and Arity is neither a variable
nor an integer
Term is a variable, Name is a constant but not anatom and Arity is an integer > 0
Term is a variable and Arity is an integer >max arity flag (section 8.22.1, page 148)
Term is a variable and Arity is an integer < 0instantiation error
instantiation error
type error(atomic, Name)
type error(integer, Arity)
type error(atom, Name)
representation error(max arity)
domain error(not less than zero, Arity)

Portability
ISO predicate.

8.4.2

arg/3

Templatesarg(+integer, +compound term, ?term)
Descriptionarg(N, Term, Arg) succeeds if the Nth argument of Term is Arg.
ErrorsN is a variable
Term is a variable
N is neither a variable nor an integer
Term is neither a variable nor a compound term
N is an integer < 0instantiation error
instantiation error
type error(integer, N)
type error(compound, Term)domain error(not less than zero, N)

60

8

PROLOG BUILT-IN PREDICATES

Portability
ISO predicate.

8.4.3(=..)/2 - univ

Templates=..(+nonvar, ?list)=..(-nonvar, +list)
Description
Term =.. List succeeds if List is a list whose head is the atom corresponding to the principal functorof Term and whose tail is a list of the arguments of Term.
=.. is a predefined infix operator (section 8.14.10, page 113).
ErrorsTerm is a variable and List is a partial list
List is neither a partial list nor a list
Term is a variable and List is a list whose headis a variable
List is a list whose head H is neither an atom nor
a variable and whose tail is not the empty list
List is a list whose head H is a compound term
and whose tail is the empty list
Term is a variable and List is the empty list
Term is a variable and the tail of List has alength > max arity flag (section 8.22.1,
page 148)

instantiation error
type error(list, List)instantiation error
type error(atom, H)
type error(atomic, H)
domain error(non empty list, [])representation error(max arity)

Portability
ISO predicate.

8.4.4

copy term/2

Templates
copy term(?term, ?term)
Description
copy term(Term1, Term2) succeeds if Term2 unifies with a term T which is a renamed copy of Term1.
Errors
None.
Portability
ISO predicate.

8.4

Term processing

8.4.5

61

term variables/2, term variables/3

Templates
term variables(?term, ?list)
term variables(?term, ?list, ?list)
Description
term variables(Term, List) succeeds if List unifies with a list of variables (including FD variables),each sharing with a unique variable of Term. The variables in List are ordered in order of appearance
traversing Term depth-first and left-to-right.
term variables(Term, List, Tail) is a difference-list version of the above predicate, i.e. Tail is thetail of the variable-list List.
Errorsin term variables/2 List is neither a partial
list nor a list

type error(list, List)

Portability
term variables/2 is an ISO Predicate. term variables/3 is a GNU Prolog predicate.

8.4.6

subsumes term/2

Templates
subsumes term(?term, ?term)
Description
subsumes term(General, Specific) succeeds if General can be made equivalent to Specific by binding variables in General leaving Specific unaffected. The current implementation performs the unification (with occurs check) and ensures that the variable set of Specific is not changed by the unification(which is then undone). Note that this predicate fails in the presence of FD variables in Specific.
Errors
None.
Portability
ISO predicate.

8.4.7

acyclic term/1

Templates
acyclic term(?term)

62

8

PROLOG BUILT-IN PREDICATES

Description
acyclic term(Term) succeeds if Term does not contain a cyclic (sub-)term. In this case, Term may beprocessed safely. If acyclic term(Term) fails, Term contains a cycle and processing Term is not safe,
because GNU Prolog does not support the unification of cyclic terms but permits their creation. Cycles
can be safely undone by failing over their creation. The use of acyclic term/1 shall thus be reserved toprotect critical predicates against cyclic terms.
Errors
None.
Portability
ISO predicate.

8.4.8

term hash/4, term hash/2

Templates
term hash(?term, +integer, +integer, ?integer)term hash(?term, ?integer)
Description
term hash(Term, Depth, Range, Hash) succeeds if Hash is the hash code of Term. If Term is not ground(see ground/1 (section 8.1.1, page 55)), the predicate simply succeeds (Hash is not unified). Depth is thedepth limit to scan Term (starting from 1 for the top-level term). With Depth = 0 nothing is hashed,with 1 only atomic terms and the main functors/arity are hashed,... With Depth = -1 the full term isconsidered.
The hash code is as follows: 0 ≤ Hash < Range. If Range = 0 then Hash is not restricted (currently it is< 268435456).
term hash(Term, Hash) is equivalent to term hash(Term, -1, 0, Hash).
NB: the computed hash code is independent of any runtime context (i.e. it is constant across different
executions). It is also independent on the underlying machine.
These predicates are useful to implement hash tables or argument indexing.
ErrorsDepth is a variable
Depth is neither a variable nor an integer
Range is a variable
Range is neither a variable nor an integer
Range is an integer < 0Hash is neither a variable nor an integer
Portability
GNU Prolog predicate.

instantiation error
type error(integer, Depth)
instantiation error
type error(integer, Range)
domain error(not less than zero, Range)
type error(integer, Hash)8.5

Variable naming/numbering

8.4.9

63

setarg/4, setarg/3

Templates
setarg(+integer, +compound term, +term, +boolean)setarg(+integer, +compound term, +term)
Description
setarg(N, Term, NewValue, Undo) replaces destructively the Nth argument of Term with NewValue.
This assignment is undone on backtracking if Undo = true. This should only used if there is no further
use of the old value of the replaced argument. If Undo = false then NewValue must be either an atom
or an integer.
setarg(N, Term, NewValue) is equivalent to setarg(N, Term, NewValue, true).
ErrorsN is a variable
N is neither a variable nor an integer
N is an integer < 0Term is a variable
Term is neither a variable nor a compound term
NewValue is neither an atom nor an integer andUndo = false
Undo is a variable
Undo is neither a variable nor a boolean

instantiation error
type error(integer, N)
domain error(not less than zero, N)
instantiation error
type error(compound, Term)
type error(atomic, NewValue)
instantiation error
type error(boolean, Undo)

Portability
GNU Prolog predicate.

8.5

Variable naming/numbering

8.5.1

name singleton vars/1

Templatesname singleton vars(?term)
Description
name singleton vars(Term) binds each singleton variable appearing in Term with a term of the form’$VARNAME’(’ ’). Such a term can be output by write term/3 as a variable name (section 8.14.6,
page 108).
Errors
None.
Portability
GNU Prolog predicates.

64

8

8.5.2

PROLOG BUILT-IN PREDICATES

name query vars/2

Templatesname query vars(+list, ?list)
Description
name query vars(List, Rest) for each element of List of the form Name = Var where Name is anatom and Var a variable, binds Var with the term ’$VARNAME’(Name). Such a term can be output by
write term/3 as a variable name (section 8.14.6, page 108). Rest is unified with the list of elementsof List that have not given rise to a binding. This predicate is provided as a way to name the variable lists obtained returned by read term/3 with variable names(List) or singletons(List) options(section 8.14.1, page 104).
ErrorsList is a partial list
List is neither a partial list nor a list
Rest is neither a partial list nor a list

instantiation error
type error(list, List)
type error(list, Rest)

Portability
GNU Prolog predicate.

8.5.3

bind variables/2, numbervars/3, numbervars/1

Templatesbind variables(?term, +var binding option list)
numbervars(?term, +integer, ?integer)numbervars(?term)
Description
bind variables(Term, Options) binds each variable appearing in Term according to the options given
by Options.
Variable binding options: Options is a list of variable binding options. If this list contains contradictory options, the rightmost option is the one which applies. Possible options are:• numbervars: specifies that each variable appearing in Term should be bound to a term of the form’$VAR’(N) where N is an integer. Such a term can be output by write term/3 as a variable name(section 8.14.6, page 108). This is the default.
• namevars: specifies that each variables appearing in Term shall be bound to a term of the form’$VARNAME’(Name) where Name is the atom that would be output by write term/3 seeing a termof the ’$VAR’(N) where N is an integer. Such a term can be output by write term/3 as a variablename (section 8.14.6, page 108). This is the alternative to numbervars.
• from(From): the first integer N to use for number/name variables of Term is From. The default
value is 0.
• next(Next): when bind variables/2 succeeds, Next is unified with the (last integer N)+1 used tobind the variables of Term.

8.5

Variable naming/numbering

65• exclude(List): collects all variable names appearing in List to avoid a clash when binding avariable of Term. Precisely a number N ≥ From will not be used to bind a variable of Term if:– there is a sub-term of List of the form ’$VAR’(N) or ’$VARNAME’(Name) where Name is theconstant that would be output by write term/3 seeing a term of the ’$VAR’(N).
– an element of List is of the form Name = Var where Name is an atom that would be output
by write term/3 on seeing a term of the from ’$VAR’(N). This case allows for lists returned
by read term/3 (with variable names(List) or singletons(List) options) (section 8.14.1,
page 104) and by name query vars/2 (section 8.5.2, page 64).
numbervars(Term, From, Next) is equivalent to bind variables(Term, [from(From), next(Next)],
i.e. each variable of Term is bound to ’$VAR’(N) where From ≤ N < Next.
numbervars(Term) is equivalent to numbervars(Term, 0, ).
See also term variables (section 8.4.5, page 61) which returns the set of variables of a term.
Errors
Options is a partial list or a list with an element
E which is a variable
Options is neither a partial list nor a list
an element E of the Options list is neither avariable nor a variable binding option
From is a variable
From is neither a variable nor an integer
Next is neither a variable nor an integer
List is a partial list
List is neither a partial list nor a list

instantiation error
type error(list, Options)domain error(var binding option, E)
instantiation error
type error(integer, From)type error(integer, Next)
instantiation error
type error(list, List)

Portability
GNU Prolog predicates.

8.5.4

term ref/2

Templates
term ref(+term, ?integer)term ref(?term, +integer)
Description
term ref(Term, Ref) succeeds if the internal reference of Term is Ref. This predicate can be used either
to obtain the internal reference of a term or to obtain the term associated with a given reference. Notethat two identical terms can have different internal references. A good way to use this predicate is to
first record the internal reference of a given term and to later re-obtain the term via this reference.
ErrorsTerm and Ref are both variables
Ref is neither a variable nor an integer
Ref is an integer < 0
Portability

instantiation error
type error(integer, Ref)
domain error(not less than zero, Ref)

66

8

PROLOG BUILT-IN PREDICATES

GNU Prolog predicate.

8.6

Arithmetic

8.6.1

Evaluation of an arithmetic expression

An arithmetic expression is a Prolog term built from numbers, variables, and functors (or operators)
that represent arithmetic functions. When an expression is evaluated each variable must be bound toa non-variable expression. An expression evaluates to a number, which may be an integer or a floating
point number. The following table details the components of an arithmetic expression, how they areevaluated, the types expected/returned and if they are ISO or an extension:

8.6

Arithmetic

Expression
a variable
an integer number
a floating point numberpieepsilon+ E- E
inc(E)dec(E)
E1 + E2
E1 - E2
E1 * E2
E1 / E2
E1 // E2
E1 rem E2
E1 div E2
E1 mod E2
E1 /\ E2
E1 \/ E2
xor(E1,E2)\ E
E1 << E2
E1 >> E2
lsb(E)
msb(E)
popcount(E)abs(E)
sign(E)
min(E1,E2)
max(E1,E2)
gcd(E1,E2)
E1 ^ E2
E1 ** E2
sqrt(E)tan(E)
atan(E)
atan2(Y,X)
cos(E)
acos(E)sin(E)
asin(E)tanh(E)
atanh(E)cosh(E)
acosh(E)sinh(E)
asinh(E)
exp(E)

67

Result = eval (Expression)bound to an expression E, result is eval (E)this number
this number
the value of π = 3.141592...
the value of e = 2.718281...
difference between 1.0 and minimum float > 1.0
eval (E)- eval (E)eval (E) + 1
eval (E) - 1
eval (E1) + eval (E2)eval (E1) - eval (E2)eval (E1) * eval (E2)eval (E1) / eval (E2)rnd (eval (E1) / eval (E2))
eval (E1) - (rnd (eval (E1) / eval (E2)) * eval (E2))
b(eval (E1) - eval (E1) mod eval (E2)) / eval (E2)ceval (E1) - (beval (E1) / eval (E2)c * eval (E2))
eval (E1) bitwise and eval (E2)eval (E1) bitwise or eval (E2)eval (E1) bitwise xor eval (E2)bitwise not eval (E)eval (E1) integer shift left eval (E2)eval (E1) integer shift right eval (E2)
least significant bit (from 0) of eval (E) or -1
most significant bit (from 0) of eval (E) or -1
number of 1-bits in eval (E)absolute value of eval (E)sign of eval (E) (-1 if < 0, 0 if = 0, +1 if > 0)minimal value between eval (E1) and eval (E2)maximal value between eval (E1) and eval (E2)
greatest common divisor of eval (E1) andeval (E2)eval (E1) raised to the power of eval (E2)eval (E1) raised to the power of eval (E2)square root of eval (E)tangent of eval (E)arc tangent of eval (E)principal value of arc tangent of eval (Y) /eval (X) using both signs for the quadrant
cosine of eval (E)arc cosine of eval (E)sine of eval (E)arc sine of eval (E)hyperbolic tangent of eval (E)hyperbolic arc tangent of eval (E)hyperbolic cosine of eval (E)hyperbolic arc cosine of eval (E)hyperbolic sine of eval (E)hyperbolic arc sine of eval (E)e raised to the power of eval (E)Signature
IF → IFI
FF
FF
IF → IFIF → IFIF → IFIF → IFIF, IF → IF
IF, IF → IF
IF, IF → IF
IF, IF → F
I, I → I
I, I → I
I, I → I
I, I → I
I, I → I
I, I → I
I, I → I
I→I
I, I → I
I, I → I
I→I
I→I
I→I
IF → IFIF → IFIF, IF → ?
IF, IF → ?

ISO
Y
Y
Y
Y
N
N
Y
Y
N
N
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
N
N
N
Y
Y
Y
Y

I, I → I

N

IF, IF → IF
IF, IF → F
IF → F
IF → F
IF → FYYYYYIF → FYIF → FIF, IF → F
IF → F
IF → F
IF → F
IF → F
IF → FIF, IF → F
IF → F
IF → F
IF → F

Y
Y
Y
Y
N
N
N
N
N
N
Y

68

8

PROLOG BUILT-IN PREDICATES

Expression

Result = eval (Expression)

SignatureISOlog(E)
log10(E)log(R, E)
float(E)ceiling(E)floor(E)round(E)truncate(E)float fractional part(E)float integer part(E)natural logarithm of eval (E)base 10 logarithm of eval (E)base eval (R) logarithm of eval (E)the floating point number equal to eval (E)rounds eval (E) upward to the nearest integer
rounds eval (E) downward to the nearest integer
rounds eval (E) to the nearest integer
the integer value of eval (E)the float equal to the fractional part of eval (E)the float equal to the integer part of eval (E)IF → F
IF → F
F, IF → F
IF → F
F→I
F→I
F→I
F→I
F→F
F→F

Y
N
N
Y
Y
Y
Y
Y
Y
Y

The meaning of the signature field is as follows:• I → I: unary function, the operand must be an integer and the result is an integer.
• F → F: unary function, the operand must be a floating point number and the result is a floating
point number.
• F → I: unary function, the operand must be a floating point number and the result is an integer.
• IF → F: unary function, the operand can be an integer or a floating point number and the result
is a floating point number.
• IF → IF: unary function, the operand can be an integer or a floating point number and the result
has the same type as the operand.
• I, I → I: binary function: each operand must be an integer and the result is an integer.
• IF, IF → IF: binary function: each operand can be an integer or a floating point number andthe result is a floating point number if at least one operand is a floating point number, an integer
otherwise.
• IF, IF → ?: binary function: each operand can be an integer or a floating point number and theresult has the same type as the selected operand. This is used for min and max. Note that in caseof equality between an integer and a floating point number the result is an integer.
is, +, -, *, /, //, div, rem, mod, /\, \/, <<, >>, ** and ^ are predefined infix operators. +, - and \, arepredefined prefix operators (section 8.14.10, page 113).
Integer division rounding function: the integer division rounding function rnd (X) rounds the floating
point number X to an integer. There are two possible definitions (depending on the target machine) for
this function which differ on negative numbers:• rnd (X) = integer part of X, e.g. rnd (-1.5) = -1 (round toward 0)• rnd (X) = bXc, e.g. rnd (-1.5) = -2 (round toward −∞)The definition of this function determines the definition of the integer division and remainder ((//)/2
and (rem)/2). It is possible to test the value (toward zero or down) of the integer rounding function
Prolog flag to determine which function being used (section 8.22.1, page 148). Since rounding toward
zero is the most common case, two additional evaluable functors ((div)/2 and (mod)/2) are available
which consider rounding toward −∞.
Fast mathematical mode: in order to speed-up integer computations, the GNU Prolog compiler can
generate faster code when invoked with the --fast-math option (section 4.4.3, page 23). In this mode
only integer operations are allowed and a variable in an expression must be bound at evaluation time to
an integer. No type checking is done.

8.6

Arithmetic

69

Errorsa sub-expression E is a variable
a sub-expression E is neither a number nor an
evaluable functor
a sub-expression E is a floating point number
while an integer is expecteda sub-expression E is an integer while a floating
point number is expecteda division by zero occurs

instantiation error
type error(evaluable, E)
type error(integer, E)
type error(float, E)
evaluation error(zero divisor)

Portability
Refer to the above table to determine which evaluable functors are ISO and which are GNU Prolog
extensions. For efficiency reasons, GNU Prolog does not detect the following ISO arithmetic errors:
float overflow, int overflow, int underflow, and undefined.

8.6.2(is)/2 - evaluate expression

Templates
is(?term, +evaluable)
Description
Result is Expression succeeds if Result can be unified with eval (Expression). Refer to the evaluationof an arithmetic expression for the definition of the eval function (section 8.6.1, page 66).
is is a predefined infix operator (section 8.14.10, page 113).
ErrorsRefer to the evaluation of an arithmetic expression for possible errors (section 8.6.1, page 66).
Portability
ISO predicate.

8.6.3(=:=)/2 - arithmetic equal, (=\=)/2 - arithmetic not equal,(<)/2 - arithmetic less than, (=<)/2 - arithmetic less than or equal to,(>)/2 - arithmetic greater than, (>=)/2 - arithmetic greater than or equal toTemplates=:=(+evaluable, +evaluable)=\=(+evaluable, +evaluable)<(+evaluable, +evaluable)
Description
Expr1 =:= Expr2 succeeds if eval (Expr1) = eval (Expr2).

=<(+evaluable, +evaluable)>(+evaluable, +evaluable)>=(+evaluable, +evaluable)

70

8

PROLOG BUILT-IN PREDICATES

Expr1 =\= Expr2 succeeds if eval (Expr1) 6= eval (Expr2).
Expr1 < Expr2 succeeds if eval (Expr1) < eval (Expr2).
Expr1 =< Expr2 succeeds if eval (Expr1) ≤ eval (Expr2).
Expr1 > Expr2 succeeds if eval (Expr1) > eval (Expr2).
Expr1 >= Expr2 succeeds if eval (Expr1) ≥ eval (Expr2).
Refer to the evaluation of an arithmetic expression for the definition of the eval function (section 8.6.1,
page 66).
=:=, =\=, <, =<, > and >= are predefined infix operators (section 8.14.10, page 113).
ErrorsRefer to the evaluation of an arithmetic expression for possible errors (section 8.6.1, page 66).
Portability
ISO predicates.

8.6.4

succ/2

Templates
succ(+integer, ?integer)succ(-integer, +integer)
Description
succ(X, Y) is true iff Y is the successor of the non-negative integer X.
ErrorsX and Y are both variables
X is neither a variable nor an integer
Y is neither a variable nor an integer
X is an integer < 0
Y is an integer < 0instantiation error
type error(integer, X)
type error(integer, Y)
domain error(not less than zero, X)
domain error(not less than zero, Y)

Portability
GNU Prolog predicate.

8.7

Dynamic clause management

8.7.1

Introduction

Static and dynamic procedures: a procedure is either dynamic or static. All built-in predicates are
static. A user-defined procedure is static by default unless a dynamic/1 directive precedes its definition

8.7

Dynamic clause management

71(section 7.1.2, page 45). Adding a clause to a non-existent procedure creates a dynamic procedure. The
clauses of a dynamic procedure can be altered (e.g. using asserta/1), the clauses of a static procedure
cannot be altered.
Private and public procedures: each procedure is either public or private. A dynamic procedure isalways public. Each built-in predicate is private, and a static user-defined procedure is private by default
unless a public/1 directive precedes its definition (section 7.1.3, page 45). If a dynamic declaration
exists it is unnecessary to add a public declaration since a dynamic procedure is also public. A clauseof a public procedure can be inspected (e.g. using clause/2), a clause of a private procedure cannot be
inspected.
A logical database update view: any change in the database that occurs as the result of executing
a goal (e.g. when a sub-goal is a call of assertz/1 or retract/1) only affects subsequent activations.
The change does not affect any activation that is currently being executed. Thus the database is frozen
during the execution of a goal, and the list of clauses defining a predication is fixed at the moment of its
execution.

8.7.2

asserta/1, assertz/1

Templates
asserta(+clause)
assertz(+clause)
Description
asserta(Clause) first converts the term Clause to a clause and then adds it to the current internal
database. The predicate concerned must be dynamic (section 8.7.1, page 70) or undefined and the clauseis inserted before the first clause of the predicate. If the predicated is undefined it is created as a dynamic
procedure.
assertz(Clause) acts like asserta/1 except that the clause is added at the end of all existing clausesof the concerned predicate.
Converting a term Clause to a clause Clause1:• extract the head and the body of Clause: either Clause = (Head :- Body) or Clause = Head and
Body = true.
• Head must be a callable term (or else the conversion fails).
• convert Body to a body clause (i.e. a goal) Body1.
• the converted clause Clause1 = (Head :- Body1).
Converting a term T to a goal:• if T is a variable it is replaced by the term call(T).
• if T is a control construct (’,’)/2, (;)/2 or (->)/2 each argument of the control construct isrecursively converted to a goal.
• if T is a callable term it remains unchanged.
• otherwise the conversion fails (T is neither a variable nor a callable term).

72

8

PROLOG BUILT-IN PREDICATES

ErrorsHead is a variable
Head is neither a variable nor a callable term
Body cannot be converted to a goal
The predicate indicator Pred of Head is that of astatic procedure

instantiation error
type error(callable, Head)type error(callable, Body)
permission error(modify,
static procedure, Pred)

Portability
ISO predicates.

8.7.3

retract/1

Templates
retract(+clause)
Description
retract(Clause) erases the first clause of the database that unifies with Clause. The concerned predicate must be a dynamic procedure (section 8.7.1, page 70). Removing all clauses of a procedure does
not erase the procedure definition. To achieve this use abolish/1 (section 8.7.6, page 73). retract/1 is
re-executable on backtracking.
ErrorsHead is a variable
Head is neither a variable nor a callable term
The predicate indicator Pred of Head is that of astatic procedure

instantiation error
type error(callable, Head)permission error(modify,
static procedure, Pred)

Portability
ISO predicate. In the ISO reference, the operation associated with the permission error is accesswhile it is modify in GNU Prolog. This seems to be an error of the ISO reference since for asserta/1(which is similar in spirit to retract/1) the operation is also modify.

8.7.4

retractall/1

Templates
retractall(+head)
Description
retractall(Head) erases all clauses whose head unifies with Head. The concerned predicate must be a
dynamic procedure (section 8.7.1, page 70). The procedure definition is not removed so that it is foundby current predicate/1 (section 8.8.1, page 74). abolish/1 should be used to remove the procedure(section 8.7.6, page 73).
Errors8.7

Dynamic clause management

Head is a variable
Head is not a callable term
The predicate indicator Pred of Head is that of astatic procedure73

instantiation error
type error(callable, Head)permission error(modify,
static procedure, Pred)

Portability
ISO predicate.

8.7.5

clause/2

Templates
clause(+head, ?callable term)
Description
clause(Head, Body) succeeds if there exists a clause in the database that unifies with Head :- Body.
The predicate in question must be a public procedure (section 8.7.1, page 70). Clauses are delivered fromthe first to the last. This predicate is re-executable on backtracking.
ErrorsHead is a variable
Head is neither a variable nor a callable term
The predicate indicator Pred of Head is that of a
private procedure
Body is neither a variable nor a callable term

instantiation error
type error(callable, Head)permission error(access,private procedure, Pred)type error(callable, Body)

Portability
ISO predicate.

8.7.6

abolish/1

Templates
abolish(+predicate indicator)
Description
abolish(Pred) removes from the database the procedure whose predicate indicator is Pred. The concerned predicate must be a dynamic procedure (section 8.7.1, page 70).
Errors748Pred is a variable
Pred is a term Name/Arity and either Name orArity is a variable
Pred is neither a variable nor a predicate
indicator
Pred is a term Name/Arity and Arity is neither
a variable nor an integer
Pred is a term Name/Arity and Name is neither avariable nor an atom
Pred is a term Name/Arity and Arity is an
integer < 0
Pred is a term Name/Arity and Arity is an
integer > max arity flag (section 8.22.1,
page 148)
The predicate indicator Pred is that of a static
procedure

PROLOG BUILT-IN PREDICATES

instantiation error
instantiation error
type error(predicate indicator, Pred)type error(integer, Arity)
type error(atom, Name)
domain error(not less than zero, Arity)
representation error(max arity)
permission error(modify,
static procedure, Pred)

Portability
ISO predicate.

8.8

Predicate information

8.8.1

current predicate/1

Templates
current predicate(?predicate indicator)
Description
current predicate(Pred) succeeds if there exists a predicate indicator of a defined procedure thatunifies with Pred. All user defined procedures are found, whether static or dynamic. Internal systemprocedures whose name begins with ’$’ are not found. A user-defined procedure is found even when
it has no clauses. A user-defined procedure is not found if it has been abolished. To conform to the
ISO reference, built-in predicates are not found except if the strict iso Prolog flag is switched off(section 8.22.1, page 148). This predicate is re-executable on backtracking.
ErrorsPred is neither a variable nor a predicate
indicator
Pred is a term Name/Arity and Arity is neither
a variable nor an integer
Pred is a term Name/Arity and Name is neither avariable nor an atom
Pred is a term Name/Arity and Arity is an
integer < 0
Pred is a term Name/Arity and Arity is an
integer > max arity flag (section 8.22.1,
page 148)
Portability

type error(predicate indicator, Pred)type error(integer, Arity)
type error(atom, Name)
domain error(not less than zero, Arity)
representation error(max arity)

8.8

Predicate information

75

ISO predicate.

8.8.2

predicate property/2

Templates
predicate property(?callable, ?predicate property)
Description
predicate property(Head, Property) succeeds if Head refers to a predicate that has a property Property.
All user defined procedures and built-in predicates are found. Internal system procedures whose namebegins with ’$’ are not found. This predicate is re-executable on backtracking.
Since version 1.4.0, predicate property/2 no longer accepts a predicate indicator. Control constructs
are now returned. Properties built in fd and control construct now imply the property built in.
Predicate properties:• static: if the procedure is static.
• dynamic: if the procedure is dynamic.
• private: if the procedure is private.
• public: if the procedure is public.
• monofile: if the procedure is monofile.
• multifile: if the procedure is multifile.
• user: if the procedure is a user-defined procedure.
• built in: if the procedure is a built-in predicate or a control construct.
• built in fd: if the procedure is an FD built-in predicate.
• control construct: if the procedure is a control construct (section 7.2, page 51).
• native code: if the procedure is compiled in native code.
• prolog file(File): source file from which the procedure has been read.
• prolog line(Line): line number of the source file.
• meta predicate(Head): if the procedure is a meta-predicate unify Head with the head-pattern.
The head-pattern is a compound term with the same name and arity as the predicate where eachargument of the term is a meta argument specifier as follows:
integer N the argument is a term that is used to reference a predicate with N more arguments than
the given argument term (e.g. call(0)).
: the argument is module sensitive, but does not directly refer to a predicate (e.g. consult(:)).
- the argument is not module sensitive and unbound on entry.
? the argument is not module sensitive and the mode is unspecified.
+ the argument is not module sensitive and bound (i.e., nonvar) on entry.

76

8

PROLOG BUILT-IN PREDICATES

ErrorsHead is neither a variable nor a callable term
Property is neither a variable nor a predicate
property term
Property = prolog file(File) and File isneither a variable nor an atom
Property = prolog line(Line) and Line isneither a variable nor an integer

type error(callable, Head)domain error(predicate property,
Property)
type error(atom, File)type error(integer, Line)

Portability
GNU Prolog predicate.

8.9

All solutions

8.9.1

Introduction

It is sometimes useful to collect all solutions for a goal. This can be done by repeatedly backtracking andgradually building the list of solutions. The following built-in predicates are provided to automate thisprocess.
The built-in predicates described in this section invoke call/1 (section 7.2.3, page 52) on the argument
Goal. When efficiency is crucial and Goal is complex it is better to define an auxiliary predicate which
can then be compiled, and have Goal call this predicate.

8.9.2

findall/4, findall/3

Templates
findall(?term, +callable term, ?list, ?term) findall(?term, +callable term, ?list)
Description
findall(Template, Goal, Instances) succeeds if Instances unifies with the list of values to which
a variable X not occurring in Template or Goal would be instantiated by successive re-executions ofcall(Goal), X = Template after systematic replacement of all variables in X by new variables. Thus,
the order of the list Instances corresponds to the order in which the proofs are found.
findall(Template, Goal, Instances, Tail) is the difference list version of findall/3. The result
is the difference list Instances-Tail. Thus findall(Template, Goal, Instances) is equivalent tofindall(Template, Goal, Instances, []).
Errors

8.9

All solutions

Goal is a variable
Goal is neither a variable nor a callable term
The predicate indicator Pred of Goal does notcorrespond to an existing procedure and thevalue of the unknown Prolog flag is error(section 8.22.1, page 148)
Instances is neither a partial list nor a list
Tail is neither a partial list nor a list

77

instantiation error
type error(callable, Goal)
existence error(procedure, Pred)type error(list, Instances)type error(list, Tail)

Portability
findall/3 is an ISO predicate. findall/4 is a GNU Prolog predicate.

8.9.3

bagof/3, setof/3

Templates
bagof(?term, +callable term, ?list)
setof(?term, +callable term, ?list)
Description
bagof(Template, Goal, Instances) assembles as a list the set of solutions of Goal for each different
instantiation of the free variables in Goal. The elements of each list are in order of solution, but the orderin which each list is found is undefined. This predicate is re-executable on backtracking.
Free variable set: bagof/3 groups the solutions of Goal according to the free variables in Goal. Thisset corresponds to all variables occurring in Goal but not in Template. It is sometimes useful to exclude
some additional variables of Goal. For that, bagof/3 recognizes a goal of the form T^Goal and exclude all
variables occurring in T from the free variable set. (^)/2 can be viewed as an existential quantifier (thelogical reading of X^Goal being “there exists an X such that Goal is true”). The use of this existential
qualifier is superfluous outside bagof/3 (and setof/3) and then is not recognized.
(^)/2 is a predefined infix operator (section 8.14.10, page 113).
setof(Template, Goal, Instances) is equivalent to bagof(Template,Goal,I), sort(I,Instances).
Each list is then a sorted list (duplicate elements are removed).
From the implementation point of view setof/3 is as fast as bagof/3. Both predicates use an in-place(i.e. destructive) sort (section 8.20.15, page 140) and require the same amount of memory.
ErrorsGoal is a variable
Goal is neither a variable nor a callable term
The predicate indicator Pred of Goal does notcorrespond to an existing procedure and thevalue of the unknown Prolog flag is error(section 8.22.1, page 148)
Instances is neither a partial list nor a list
Portability
ISO predicates.

instantiation error
type error(callable, Goal)
existence error(procedure, Pred)type error(list, Instances)

78

8

8.10

Streams

8.10.1Introduction

PROLOG BUILT-IN PREDICATES

A stream provides a logical view of a source/sink.
Sources and sinks: a program can output results to a sink or input data from a source. A source/sinkmay be a file (regular file, terminal, device,. . . ), a constant term, a pipe, a socket,. . .
Associating a stream to a source/sink: to manipulate a source/sink it must be associated with astream. This provides a logical and uniform view of the source/sink whatever its type. Once this association has been established, i.e. a stream has been created, all subsequent references to the source/sinkare made by referring the stream. A stream is unidirectional: it is either an input stream or an output stream. For a classical file, the association is done by opening the file (whose name is specified as
an atom) with the open/4 (section 8.10.6, page 81). GNU Prolog makes it possible to treat a Prolog
constant term as a source/sink and provides built-in predicates to associate a stream to such a term (section 8.11, page 94). GNU Prolog provides operating system interface predicates defining pipes between
GNU Prolog and child processes with streams associated with these pipes, e.g. popen/3 (section 8.27.21,
page 170). Similarly, socket interface predicates associate streams to a socket to allow the communication,e.g. socket connect/4 (section 8.28.5, page 178).
Stream-term: a stream-term identifies a stream during a call of an input/output built-in predicate.
It is created as a result of associating a stream to a source/sink (section above). A stream-term is acompound term of the form ’$stream’(I) where I is an integer.
Stream aliases: any stream may be associated with a stream alias which is an atom which may be
used to refer to that stream. The association can be done at open time or using add stream alias/2(section 8.10.20, page 90). Such an association automatically ends when the stream is closed. A particularalias only refers to at most one stream at any one time. However, more than one alias can be associatedwith a stream. Most built-in predicates which have a stream-term as an input argument also accept astream alias as that argument. However, built-in predicates which return a stream-term do not accept astream alias.
Standard streams: three streams are predefined and open during the execution of every goal: thestandard input stream which has the alias user input, the standard output stream which has the alias
user output and the standard error stream which has the alias user error. A goal which attempts toclose either standard stream succeeds, but does not close the stream.
Current streams: during execution there is a current input stream and a current output stream. By
default, the current input and output streams are the standard input and output streams, but the builtin predicates set input/1 (section 8.10.4, page 80) and set output/1 (section 8.10.5, page 80) can beused to change them. When the current input stream is closed, the standard input stream becomes thecurrent input stream. When the current output stream is closed, the standard output stream becomesthe current output stream.
Text streams and binary streams: a text stream is a sequence of characters. A text stream is also
regarded as a sequence of lines where each line is a possibly empty sequence of characters followed bya new line character. GNU Prolog may add or remove space characters at the ends of lines in order
to conform to the conventions for representing text streams in the operating system. A binary stream
is a sequence of bytes. Only a few built-in predicates can deal with binary streams, e.g. get byte/2(section 8.13, page 101).
Stream positions: the stream position of a stream identifies an absolute position of the source/sink to8.10

Streams

79

which the stream is connected and defines where in the source/sink the next input or output will takeplace. A stream position is a ground term of the form ’$stream position’(I1, I2, I3, I4) where
I1, I2, I3 and I4 are integers. Stream positions are used to reposition a stream (when possible) using
for instance set stream position/2 (section 8.10.13, page 86).
The position end of stream: when all data of a stream S has been input S has a stream position
end-of-stream. At this stream position a goal to input more data will return a specific value to indicatethat end of stream has been reached (e.g. -1 for get code/2 or end of file for get char/2,. . . ). When
this terminating value has been input, the stream has a stream position past-end-of-stream.
Buffering mode: input/output on a stream can be buffered (line-buffered or block-buffered) or notbuffered at all. The buffering mode can be specified at open time or using set stream buffering/2(section 8.10.27, page 93). Line buffering is used on output streams, output data are only written to thesink when a new-line character is output (or at the close time). Block buffering is used on input or output.
On input streams, when an input is requested on the source, if the buffer is empty, all available characters
are read (within the limits of the size of the buffer), subsequent reads will first use the characters in thebuffer. On output streams, output data are stored in the buffer and only when the buffer is full is it
physically written on the sink. Thus, an output to a buffered stream may not be sent immediately to thesink connected to that stream. When it is necessary to be certain that output has been delivered, thebuilt-in predicate flush output/1 (section 8.10.8, page 83) should be used. Finally, it is also possible
to use non-buffered streams, in that case input/output are directly done on the connected source/sink.
This can be useful for communication purposes (e.g. sockets) or when a precise control is needed, e.g.
select/5 (section 8.27.25, page 173).
Stream mirrors: any stream may be associated with mirror streams specified at open time or using
add stream mirror/2 (section 8.10.22, page 91). Then, all characters/bytes read from/written to thestream are also written on each mirror stream. The association automatically ends when either the
stream or the mirror stream is closed. It is also possible to explicitly remove a mirror stream using
remove stream mirror/2 (section 8.10.23, page 91).

8.10.2current input/1

Templates
current input(?stream)
Description
current input(Stream) unifies Stream with the stream-term identifying the current input stream.
ErrorsStream is neither a variable nor a stream
Portability
ISO predicate.

8.10.3current output/1

Templates
current output(?stream)

domain error(stream, Stream)

80

8

PROLOG BUILT-IN PREDICATES

Description
current output(Stream) unifies Stream with the stream-term identifying the current output stream.
ErrorsStream is neither a variable nor a stream

domain error(stream, Stream)

Portability
ISO predicate.

8.10.4

set input/1

Templates
set input(+stream or alias)
Description
set input(SorA) sets the current input stream to be the stream associated with the stream-term or alias
SorA.
ErrorsSorA is a variable
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream

instantiation error
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)

Portability
ISO predicate.

8.10.5set output/1

Templates
set output(+stream or alias)
Description
set output(SorA) sets the current output stream to be the stream associated with the stream-term or
alias SorA.
ErrorsSorA is a variable
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an input stream

instantiation error
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(output, stream, SorA)

8.10

Streams

81

Portability
ISO predicate.

8.10.6

open/4, open/3

Templates
open(+source sink, +io mode, -stream, +stream option list)
open(+source sink, +io mode, -stream)
Description
open(SourceSink, Mode, Stream, Options) opens the source/sink SourceSink for input or output
as indicated by Mode and the list of stream-options Options and unifies Stream with the stream-term
which is associated with this stream. See absolute file name/2 for information about the syntax ofSourceSink (section 8.26.1, page 158).
Input/output modes: Mode is an atom which defines the input/output operations that may be performed the stream. Possible modes are:• read: the source/sink is a source and must already exist. Input starts at the beginning of thesource.
• write: the source/sink is a sink. If the sink already exists then it is emptied else an empty sink iscreated. Output starts at the beginning of that sink.
• append: the source/sink is a sink. If the sink does not exist it is created. Output starts at the endof that sink.
Stream options: Options is a list of stream options. If this list contains contradictory options, therightmost option is the one which applies. Possible options are:• type(text/binary): specifies whether the stream is a text stream or a binary stream. The default
value is text.
• reposition(true/false): specifies whether it is possible to reposition the stream. The default
value is true except if the stream cannot be repositioned (e.g. a terminal).
• eof action(error/eof code/reset): specifies the effect of attempting to input from a stream
whose stream position is past-end-of-stream:– error: a permission error is raised signifying that no more input exists in this stream.
– eof code: the result of input is as if the stream position is end-of-stream.
– reset: the stream position is reset so that it is not past-end-of-stream, and another attempt
is made to input from it (this is useful when inputting from a terminal).
The default value is eof code.
• alias(Alias): specifies that the atom Alias is to be an alias for the stream. By default no alias
is attached to the stream. Several aliases can be defined for a same stream.
• mirror(Mirror): specifies the stream associated with the stream-term or alias Mirror is a mirror
for the stream. By default no mirror is attached to the stream. Several mirrors can be defined fora same stream.
• buffering(none/line/block): specifies which type of buffering is used by input/output operations
on this stream:– none: no buffering.

82

8

PROLOG BUILT-IN PREDICATES– line: output operations buffer data emitted until a new-line occurs– block: input/output operations buffer data until a given number (implementation dependant)of characters/bytes have been treated.
The default value is line for a terminal (TTY), block otherwise.
open(SourceSink, Mode, Stream) is equivalent to open(SourceSink, Mode, Stream, []).
Errors
SourceSink is a variable
Mode is a variable
Options is a partial list or a list with an element
E which is a variable
Mode is neither a variable nor an atom
Options is neither a partial list nor a list
Stream is not a variable
SourceSink is neither a variable nor asource/sink
Mode is an atom but not an input/output mode
an element E of the Options list is neither avariable nor a stream-option
the source/sink specified by SourceSink does
not exist
the source/sink specified by SourceSink cannot
be opened
an element E of the Options list is alias(A) and
A is already associated with an open stream
an element E of the Options list is mirror(M)and M is not associated with an open stream
an element E of the Options list is mirror(M)and M is an input stream
an element E of the Options list is
reposition(true) and it is not possible toreposition this stream

instantiation error
instantiation error
instantiation error
type error(atom, Mode)type error(list, Options)uninstantiation error(Stream)
domain error(source sink, SourceSink)
domain error(io mode, Mode)domain error(stream option, E)
existence error(source sink, SourceSink)
permission error(open, source sink,
SourceSink)
permission error(open, source sink,alias(A))
existence error(stream, M)
permission error(output, stream, M)
permission error(open, source sink,
reposition(true))

Portability
ISO predicates. The mirror and buffering stream options are GNU Prolog extensions.

8.10.7close/2, close/1

Templates
close(+stream or alias, +close option list)
close(+stream or alias)
Description
close(SorA, Options) closes the stream associated with the stream-term or alias SorA. If SorA is
the standard input stream or the standard output stream close/2 simply succeeds else the associatedsource/sink is physically closed. If SorA is the current input stream the current input stream becomes
the standard input stream user input. If SorA is the current output stream the current output stream
becomes the standard output stream user output.

8.10

Streams

83

Close options: Options is a list of close options. For the moment only one option is available:• force(true/false): with false, if an error occurs when trying to close the source/sink, the stream
is not closed and an error (system error or resource error) is raised (but close/2 succeeds).
With true, if an error occurs it is ignored and the stream is closed. The purpose of force/1 option
is to allow an error handling routine to do its best to reclaim resources. The default value is false.
close(SorA) is equivalent to close(SorA, []).
ErrorsSorA is a variable
Options is a partial list or a list with an element
E which is a variable
Options is neither a partial list nor a list
SorA is neither a variable nor a stream-term oralias
an element E of the Options list is neither avariable nor a close-option
SorA is not associated with an open stream
SorA needs a special close (section 8.11, page 94)

instantiation error
instantiation error
type error(list, Options)domain error(stream or alias, SorA)
domain error(close option, E)
existence error(stream, SorA)
system error(needs special close)

Portability
ISO predicates. The system error(needs special close) is a GNU Prolog extension.

8.10.8flush output/1, flush output/0

Templates
flush output(+stream or alias)
flush output
Description
flush output(SorA) sends any buffered output characters/bytes to the stream.
flush output/0 applies to the current output stream.
ErrorsSorA is a variable
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an input stream
Portability
ISO predicates.

8.10.9current stream/1

Templates

instantiation error
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(output, stream, SorA)

84

8

PROLOG BUILT-IN PREDICATES

current stream(?stream)
Description
current stream(Stream) succeeds if there exists a stream-term that unifies with Stream. This predicate
is re-executable on backtracking.
ErrorsStream is neither a variable nor a stream-term

domain error(stream, Stream)

Portability
GNU Prolog predicate.

8.10.10stream property/2

Templates
stream property(?stream, ?stream property)
Description
stream property(Stream, Property) succeeds if current stream(Stream) succeeds (section 8.10.9,
page 83) and if Property unifies with one of the properties of the stream. This predicate is re-executableon backtracking.
Stream properties:• file name(F): the name of the connected source/sink.
• mode(M): M is the open mode (read, write, append).
• input: if it is an input stream.
• output: if it is an output stream.
• alias(A): A is an alias of the stream.
• mirror(M): M is a mirror stream of the stream.
• type(T): T is the type of the stream (text, binary).
• reposition(R): R is the reposition boolean (true, false).
• eof action(A): A is the end-of-file action (error, eof code, reset).
• buffering(B): B is the buffering mode (none, line, block).
• end of stream(E): E is the current end-of-stream status (not, at, past). If the stream position is
end-of-stream then E is unified with at else if the stream position is past-end-of-stream then E is
unified with past else E is unified with not.
• position(P): P is the stream-position term associated with the current position.

8.10

Streams

85

ErrorsStream is a variable
Stream is neither a variable nor a stream-term
Property is neither a variable nor a stream
property
Property = file name(E), mode(E), alias(E),end of stream(E), eof action(E),reposition(E), type(E) or buffering(E) and
E is neither a variable nor an atom

instantiation error
domain error(stream, Stream)
domain error(stream property, Property)

type error(atom, E)

Portability
ISO predicate. The buffering/1 property is a GNU Prolog extension.

8.10.11at end of stream/1, at end of stream/0

Templates
at end of stream(+stream or alias)
at end of stream
Description
at end of stream(SorA) succeeds if the stream associated with stream-term or alias SorA has a stream
position end-of-stream or past-end-of-stream. This predicate can be defined using stream property/2(section 8.10.10, page 84).
at end of stream/0 applies to the current input stream.
ErrorsSorA is a variable
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream

instantiation error
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)

Portability
ISO predicates. The permission error(input, stream, SorA) is a GNU Prolog extension.

8.10.12stream position/2

Templates
stream position(+stream or alias, ?stream position)
Description
stream position(SorA, Position) succeeds unifying Position with the stream-position term associated with the current position of the stream-term or alias SorA. This predicate can be defined using
stream property/2 (section 8.10.10, page 84).

86

8

PROLOG BUILT-IN PREDICATES

ErrorsSorA is a variable
SorA is neither a variable nor a stream-term or
alias
Position is neither a variable nor astream-position term
SorA is not associated with an open stream

instantiation error
domain error(stream or alias, SorA)
domain error(stream position, Position)
existence error(stream, SorA)

Portability
GNU Prolog predicate.

8.10.13

set stream position/2

Templates
set stream position(+stream or alias, +stream position)
Description
set stream position(SorA, Position) sets the position of the stream associated with the streamterm or alias SorA to Position. Position should have previously been returned by stream property/2(section 8.10.10, page 84) or by stream position/2 (section 8.10.12, page 85).
ErrorsSorA is a variable
Position is a variable
SorA is neither a variable nor a stream-term or
alias
Position is neither a variable nor astream-position term
SorA is not associated with an open stream
SorA has stream property reposition(false)

instantiation error
instantiation error
domain error(stream or alias, SorA)
domain error(stream position, Position)
existence error(stream, SorA)
permission error(reposition, stream,
SorA)

Portability
ISO predicate.

8.10.14seek/4

Templatesseek(+stream or alias, +stream seek method, +integer, ?integer)
Descriptionseek(SorA, Whence, Offset, NewOffset) sets the position of the stream associated with the streamterm or alias SorA to Offset according to Whence and unifies NewOffset with the new offset from the
beginning of the file. seek/4 can only be used on binary streams. Whence is an atom from:

8.10

Streams87• bof: the position is set relatively to the begin of the file (Offset should be ≥ 0).
• current: the position is set relatively to the current position (Offset can be ≥ 0 or ≤ 0).
• eof: the position is set relatively to the end of the file (Offset should be ≤ 0).
This predicate is an interface to the C Unix function lseek(2).
ErrorsSorA is a variable
Whence is a variable
Offset is a variable
SorA is neither a variable nor a stream-term or
alias
Whence is neither a variable nor an atom
Whence is an atom but not a valid stream seek
methodOffset is neither a variable nor an integer
NewOffset is neither a variable nor an integer
SorA is not associated with an open stream
SorA has stream property reposition(false)
SorA is associated with a text stream

instantiation error
instantiation error
instantiation error
domain error(stream or alias, SorA)
type error(atom, Whence)
domain error(stream seek method, Whence)
type error(integer, Offset)
type error(integer, NewOffset)
existence error(stream, SorA)
permission error(reposition, stream,
SorA)
permission error(reposition, text stream,
SorA)

Portability
GNU Prolog predicate.

8.10.15

character count/2

Templates
character count(+stream or alias, ?integer)
Description
character count(SorA, Count) unifies Count with the number of characters/bytes read/written on thestream associated with stream-term or alias SorA.
ErrorsSorA is a variable
Count is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
Portability
GNU Prolog predicate.

instantiation error
type error(integer, Count)domain error(stream or alias, SorA)
existence error(stream, SorA)

88

8

8.10.16

PROLOG BUILT-IN PREDICATES

line count/2

Templates
line count(+stream or alias, ?integer)
Description
line count(SorA, Count) unifies Count with the number of lines read/written on the stream associatedwith the stream-term or alias SorA. This predicate can only be used on text streams.
ErrorsSorA is a variable
Count is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is associated with a binary stream

instantiation error
type error(integer, Count)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(access, binary stream,
SorA)

Portability
GNU Prolog predicate.

8.10.17line position/2

Templates
line position(+stream or alias, ?integer)
Description
line position(SorA, Count) unifies Count with the number of characters read/written on the current
line of the stream associated with the stream-term or alias SorA. This predicate can only be used on text
streams.
ErrorsSorA is a variable
Count is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is associated with a binary stream
Portability
GNU Prolog predicate.

instantiation error
type error(integer, Count)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(access, binary stream,
SorA)

8.10

Streams

8.10.1889

stream line column/3

Templates
stream line column(+stream or alias, ?integer, ?integer)
Description
stream line column(SorA, Line, Column) unifies Line (resp. Column) with the current line number(resp. column number) of the stream associated with the stream-term or alias SorA. This predicate canonly be used on text streams. Note that Line corresponds to the value returned by line count/2 + 1(section 8.10.16, page 88) and Column to the value returned by line position/2 + 1 (section 8.10.17,
page 88).
ErrorsSorA is a variable
Line is neither a variable nor an integer
Column is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is associated with a binary stream

instantiation error
type error(integer, Line)
type error(integer, Column)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(access, binary stream,
SorA)

Portability
GNU Prolog predicate.

8.10.19

set stream line column/3

Templates
set stream line column(+stream or alias, +integer, +integer)
Description
set stream line column(SorA, Line, Column) sets the stream position of the stream associated withthe stream-term or alias SorA according to the line number Line and the column number Column. Thispredicate can only be used on text streams. It first repositions the stream to the beginning of the fileand then reads character by character until the required position is reached.
Errors90

8

SorA is a variable
Line is a variable
Column is a variable
Line is neither a variable nor an integer
Column is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is associated with a binary stream
SorA has stream property reposition(false)

PROLOG BUILT-IN PREDICATES

instantiation error
instantiation error
instantiation error
type error(integer, Line)
type error(integer, Column)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(reposition,
binary stream, SorA)
permission error(reposition, stream,
SorA)

Portability
GNU Prolog predicate.

8.10.20

add stream alias/2

Templates
add stream alias(+stream or alias, +atom)
Description
add stream alias(SorA, Alias) adds Alias as a new alias to the stream associated with the streamterm or alias SorA.
ErrorsSorA is a variable
Alias is a variable
Alias is neither a variable nor an atom
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
Alias is already associated with an open stream

instantiation error
instantiation error
type error(atom, Alias)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(add alias, source sink,alias(Alias))

Portability
GNU Prolog predicate.

8.10.21current alias/2

Templates
current alias(?stream, ?atom)
Description
current alias(Stream, Alias) succeeds if current stream(Stream) succeeds (section 8.10.9, page 83)

8.10

Streams91

and if Alias unifies with one of the aliases of the stream. It can be defined using stream property/2(section 8.10.10, page 84). This predicate is re-executable on backtracking.
ErrorsStream is neither a variable nor a stream-term
Alias is neither a variable nor an atom

domain error(stream, Stream)type error(atom, Alias)

Portability
GNU Prolog predicate.

8.10.22

add stream mirror/2

Templates
add stream mirror(+stream or alias, +stream or alias)
Description
add stream mirror(SorA, Mirror) adds the stream associated with the stream-term or alias Mirror asa new mirror to the stream associated with the stream-term or alias SorA. After this, all characters (orbytes) read from (or written to) SorA are also written to Mirror. This mirroring occurs until Mirror is
explicitly removed using remove stream mirror/2 (section 8.10.23, page 91) or implicitly when Mirror
is closed. Several mirror streams can be associated with a same stream. If Mirror represents the same
stream as SorA or if Mirror is already a mirror for SorA, no mirror is added.
ErrorsSorA is a variable
Mirror is a variable
SorA is neither a variable nor a stream-term or
alias
Mirror is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
Mirror is not associated with an open stream
Mirror is an input stream

instantiation error
instantiation error
domain error(stream or alias, SorA)
domain error(stream or alias, Mirror)
existence error(stream, SorA)
existence error(stream, Mirror)
permission error(output, stream, Mirror)

Portability
GNU Prolog predicate.

8.10.23

remove stream mirror/2

Templates
remove stream mirror(+stream or alias, +stream or alias)
Description
remove stream mirror(SorA, Mirror) removes the stream associated with the stream-term or alias
Mirror from the list of mirrors of the stream associated with the stream-term or alias SorA. This predicate
fails if Mirror is not a mirror stream for SorA.

92

8

PROLOG BUILT-IN PREDICATES

ErrorsSorA is a variable
Mirror is a variable
SorA is neither a variable nor a stream-term or
alias
Mirror is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
Mirror is not associated with an open stream

instantiation error
instantiation error
domain error(stream or alias, SorA)
domain error(stream or alias, Mirror)
existence error(stream, SorA)
existence error(stream, Mirror)

Portability
GNU Prolog predicate.

8.10.24current mirror/2

Templates
current mirror(?stream, ?stream)
Description
current mirror(Stream, M) succeeds if current stream(Stream) succeeds (section 8.10.9, page 83)
and if M unifies with one of the mirrors of the stream. It can be defined using stream property/2(section 8.10.10, page 84). This predicate is re-executable on backtracking.
ErrorsStream is neither a variable nor a stream-term
M is neither a variable nor a stream-term

domain error(stream, Stream)
domain error(stream, M)

Portability
GNU Prolog predicate.

8.10.25

set stream type/2

Templates
set stream type(+stream or alias, +atom)
Description
set stream type(SorA, Type) updates the type associated with stream-term or alias SorA. The valueof Type is an atom in text or binary as for open/4 (section 8.10.6, page 81). The type of a stream canonly be changed before any input/output operation is executed.
Errors8.10

Streams

SorA is a variable
Type is a variable
Type is neither a variable nor a valid type
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
An I/O operation has already been executed on
SorA

93

instantiation error
instantiation error
domain error(stream type, Type)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(modify, stream, SorA)

Portability
GNU Prolog predicate.

8.10.26

set stream eof action/2

Templates
set stream eof action(+stream or alias, +atom)
Description
set stream eof action(SorA, Action) updates the eof action option associated with the streamterm or alias SorA. The value of Action is one of the atoms error, eof code, reset as for open/4(section 8.10.6, page 81).
ErrorsSorA is a variable
Action is a variable
Action is neither a variable nor a valid eof action
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream

instantiation error
instantiation error
domain error(eof action, Action)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(modify, stream, SorA)

Portability
GNU Prolog predicate.

8.10.27

set stream buffering/2

Templates
set stream buffering(+stream or alias, +atom)
Description
set stream buffering(SorA, Buffering) updates the buffering mode associated with the stream-termor alias SorA. The value of Buffering is one of the atoms none, line or block as for open/4 (section 8.10.6, page 81). This predicate may only be used after opening a stream and before any otheroperations have been performed on it.
Errors94

8

SorA is a variable
Buffering is a variable
Buffering is neither a variable nor a valid
buffering mode
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream

PROLOG BUILT-IN PREDICATES

instantiation error
instantiation error
domain error(buffering mode, Buffering)domain error(stream or alias, SorA)
existence error(stream, SorA)

Portability
GNU Prolog predicate.

8.11

Constant term streams

8.11.1Introduction

Constant term streams allow the user to consider a constant term (atom, character list or character codelist) as a source/sink by associating to them a stream. Reading from a constant term stream will deliver
the characters of the constant term as if they had been read from a standard file. Characters written
on a constant term stream are stored to form the final constant term when the stream is closed. The
built-in predicates described in this section allow the user to open and close a constant term stream for
input or output. However, very often, a constant term stream is created to be only read or written once
and then closed. To avoid the creation and the destruction of such a stream, GNU Prolog offers several
built-in predicates to perform single input/output from/to constant terms (section 8.15, page 117).

8.11.2

open input atom stream/2, open input chars stream/2,
open input codes stream/2

Templates
open input atom stream(+atom, -stream)
open input chars stream(+character list, -stream)
open input codes stream(+character code list, -stream)
Description
open input atom stream(Atom, Stream) unifies Stream with the stream-term which is associated witha new input text-stream whose data are the characters of Atom.
open input chars stream(Chars, Stream) is similar to open input atom stream/2 except that data
are the content of the character list Chars.
open input codes stream(Codes, Stream) is similar to open input atom stream/2 except that data
are the content of the character code list Codes.
Errors8.11

Constant term streams

Stream is not a variable
Atom is a variable
Chars is a partial list or a list with an element E
which is a variable
Codes is a partial list or a list with an element E
which is a variable
Atom is neither a variable nor a an atom
Chars is neither a partial list nor a list
Codes is neither a partial list nor a list
an element E of the Chars list is neither avariable nor a character
an element E of the Codes list is neither avariable nor an integer
an element E of the Codes list is an integer but
not a character code95

uninstantiation error(Stream)
instantiation error
instantiation error
instantiation error
type error(atom, Atom)type error(list, Chars)
type error(list, Codes)
type error(character, E)
type error(integer, E)
representation error(character code)

Portability
GNU Prolog predicates.

8.11.3close input atom stream/1, close input chars stream/1,
close input codes stream/1

Templates
close input atom stream(+stream or alias)
close input chars stream(+stream or alias)
close input codes stream(+stream or alias)
Description
close input atom stream(SorA) closes the constant term stream associated with the stream-term or
alias SorA. SorA must a stream open with open input atom stream/2 (section 8.11.1, page 94).
close input chars stream(SorA) acts similarly for a character list stream.
close input codes stream(SorA) acts similarly for a character code list stream.
ErrorsSorA is a variable
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is a stream-term or alias but does not referto a constant term stream.
Portability
GNU Prolog predicates.

instantiation error
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(close, stream, SorA)
domain error(term stream or alias, SorA)

96

8

8.11.4

PROLOG BUILT-IN PREDICATES

open output atom stream/1, open output chars stream/1,
open output codes stream/1

Templates
open output atom stream(-stream)
open output chars stream(-stream)
open output codes stream(-stream)
Description
open output atom stream(Stream) unifies Stream with the stream-term which is associated with a new
output text-stream. All characters written to this stream are collected and will be returned as an atomwhen the stream is closed by close output atom stream/2 (section 8.11.5, page 96).
open output chars stream(Stream) is similar to open output atom stream/1 except that the result
will be a character list.
open output codes stream(Stream) is similar to open output atom stream/1 except that the result
will be a character code list.
ErrorsStream is not a variable

uninstantiation error(Stream)

Portability
GNU Prolog predicates.

8.11.5close output atom stream/2, close output chars stream/2,
close output codes stream/2

Templates
close output atom stream(+stream or alias, ?atom)
close output chars stream(+stream or alias, ?character list)
close output codes stream(+stream or alias, ?character code list)
Description
close output atom stream(SorA, Atom) closes the constant term stream associated with the streamterm or alias SorA. SorA must be associated with a stream open with open output atom stream/1(section 8.11.4, page 96). Atom is unified with an atom formed with all characters written on the stream.
close output chars stream(SorA, Chars) acts similarly for a character list stream.
close output codes stream(SorA, Codes) acts similarly for a character code list stream.
Errors8.12

Character input/output

SorA is a variable
Atom is neither a variable nor an atom
Chars is neither a partial list nor a list
Codes is neither a partial list nor a list
an element E of the Chars list is neither avariable nor a character
an element E of the Codes list is neither avariable nor an integer
an element E of the Codes list is an integer but
not a character code
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an input stream
SorA is a stream-term or alias but does not referto a constant term stream

97

instantiation error
type error(atom, Atom)type error(list, Chars)
type error(list, Codes)
type error(character, E)
type error(integer, E)
representation error(character code)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(close, stream, SorA)
domain error(term stream or alias, SorA)

Portability
GNU Prolog predicates.

8.12

Character input/output

These built-in predicates enable a single character or character code to be input from and output to atext stream. The atom end of file is returned as character to indicate the end-of-file. -1 is returned ascharacter code to indicate the end-of-file.

8.12.1

get char/2, get char/1, get code/1, get code/2

Templates
get char(+stream or alias, ?in character)get char(?in character)get code(+stream or alias, ?in character code)
get code(?in character code)
Description
get char(SorA, Char) succeeds if Char unifies with the next character read from the stream associatedwith the stream-term or alias SorA.
get code/2 is similar to get char/2 but deals with character codes.
get char/1 and get code/1 apply to the current input stream.
Errors98

8

SorA is a variable
Char is neither a variable nor an in-character
Code is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a binary stream
SorA has stream properties
end of stream(past) and eof action(error)
The entity input from the stream is not acharacter
Code is an integer but not an in-character code

PROLOG BUILT-IN PREDICATES

instantiation error
type error(in character, Char)type error(integer, Code)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, binary stream,
SorA)
permission error(input,
past end of stream, SorA)
representation error(character)
representation error(in character code)

Portability
ISO predicates.

8.12.2get key/2, get key/1 get key no echo/2, get key no echo/1

Templates
get key(+stream or alias, ?integer)
get key(?integer)
get key no echo(+stream or alias, ?integer)
get key no echo(?integer)
Description
get key(SorA, Code) succeeds if Code unifies with the character code of the next key read from thestream associated with the stream-term or alias SorA. It is intended to read a single key from the keyboard(thus SorA should refer to current input stream). No buffering is performed (a character is read as soon as
available) and function keys can also be read (in that case, Code is an integer > 255). The read characteris echoed if it is printable.
This facility is only possible if the linedit facility has been installed (section 4.2.6, page 18) otherwise
get key/2 behaves similarly to get code/2 (section 8.12.1, page 97) (the code of the first character isreturned) but also pumps remaining characters until a character < space (0x20) is read (in particular
RETURN). The same behavior occurs if SorA does not refer to the current input stream or if this stream
is not attached to a terminal.
get key no echo/2 behaves similarly to get key/2 except that the read character is not echoed.
get key/1 and get key no echo/1 apply to the current input stream.
Errors8.12

Character input/output

SorA is a variable
Code is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a binary stream
SorA has stream properties
end of stream(past) and eof action(error)

99

instantiation error
type error(integer, Code)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, binary stream,
SorA)
permission error(input,
past end of stream, SorA)

Portability
GNU Prolog predicates.

8.12.3peek char/2, peek char/1, peek code/1, peek code/2

Templates
peek char(+stream or alias, ?in character)peek char(?in character)peek code(+stream or alias, ?in character code)
peek code(?in character code)
Description
peek char(SorA, Char) succeeds if Char unifies with the next character that will be read from thestream associated with the stream-term or alias SorA. The character is not read.
peek code/2 is similar to peek char/2 but deals with character codes.
peek char/1 and peek code/1 apply to the current input stream.
ErrorsSorA is a variable
Char is neither a variable nor an in-character
Code is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a binary stream
SorA has stream properties
end of stream(past) and eof action(error)
The entity input from the stream is not acharacter
Code is an integer but not an in-character code
Portability
ISO predicates.

instantiation error
type error(in character, Char)type error(integer, Code)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, binary stream,
SorA)
permission error(input,
past end of stream, SorA)
representation error(character)
representation error(in character code)

100

8

8.12.4

PROLOG BUILT-IN PREDICATES

unget char/2, unget char/1, unget code/2, unget code/1

Templates
unget char(+stream or alias, +character)
unget char(+character)
unget code(+stream or alias, +character code)
unget code(+character code)
Description
unget char(SorA, Char) pushes back Char onto the stream associated with the stream-term or alias
SorA. Char will be the next character read by get char/2. The maximum number of characters that canbe cumulatively pushed back is given by the max unget Prolog flag (section 8.22.1, page 148).
unget code/2 is similar to unget char/2 but deals with character codes.
unget char/1 and unget code/1 apply to the current input stream.
ErrorsSorA is a variable
Char is a variable
Code is a variable
Char is neither a variable nor a character
Code is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a binary stream
Code is an integer but not a character code

instantiation error
instantiation error
instantiation error
type error(character, Char)type error(integer, Code)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, binary stream,
SorA)
representation error(character code)

Portability
GNU Prolog predicates.

8.12.5put char/2, put char/1, put code/1, put code/2, nl/1, nl/0

Templates
put char(+stream or alias, +character)put char(+character)put code(+stream or alias, +character code)
put code(+character code)nl(+stream or alias)nl
Description
put char(SorA, Char) writes Char onto the stream associated with the stream-term or alias SorA.
put code/2 is similar to put char/2 but deals with character codes.

8.13

Byte input/output

101

nl(SorA) writes a new-line character onto the stream associated with the stream-term or alias SorA.
This is equivalent to put char(SorA, ’\n’).
put char/1, put code/1 and nl/0 apply to the current output stream.
ErrorsSorA is a variable
Char is a variable
Code is a variable
Char is neither a variable nor a character
Code is neither a variable nor an integer
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an input stream
SorA is associated with a binary stream
Code is an integer but not a character code

instantiation error
instantiation error
instantiation error
type error(character, Char)type error(integer, Code)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(output, stream, SorA)
permission error(output, binary stream,
SorA)
representation error(character code)

Portability
ISO predicates.

8.13

Byte input/output

These built-in predicates enable a single byte to be input from and output to a binary stream. -1 isreturned to indicate the end-of-file.

8.13.1

get byte/2, get byte/1

Templates
get byte(+stream or alias, ?in byte)
get byte(?in byte)
Description
get byte(SorA, Byte) succeeds if Byte unifies with the next byte read from the stream associated withthe stream-term or alias SorA.
get byte/1 applies to the current input stream.
Errors102

8

SorA is a variable
Byte is neither a variable nor an in-byte
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a text stream
SorA has stream properties
end of stream(past) and eof action(error)

PROLOG BUILT-IN PREDICATES

instantiation error
type error(in byte, Byte)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, text stream,
SorA)
permission error(input,
past end of stream, SorA)

Portability
ISO predicates.

8.13.2peek byte/2, peek byte/1

Templates
peek byte(+stream or alias, ?in byte)
peek byte(?in byte)
Description
peek byte(SorA, Byte) succeeds if Byte unifies with the next byte that will be read from the stream
associated with the stream-term or alias SorA. The byte is not read.
peek byte/1 applies to the current input stream.
ErrorsSorA is a variable
Byte is neither a variable nor an in-byte
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a text stream
SorA has stream properties
end of stream(past) and eof action(error)
Portability
ISO predicates.

8.13.3

unget byte/2, unget byte/1

Templates
unget byte(+stream or alias, +byte)
unget byte(+byte)

instantiation error
type error(in byte, Byte)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, text stream,
SorA)
permission error(input,
past end of stream, SorA)

8.13

Byte input/output

103

Description
unget byte(SorA, Byte) pushes back Byte onto the stream associated with the stream-term or alias
SorA. Byte will be the next byte read by get byte/2. The maximum number of bytes that can be
successively pushed back is given by the max unget Prolog flag (section 8.22.1, page 148).
unget byte/1 applies to the current input stream.
ErrorsSorA is a variable
Byte is a variable
Byte is neither a variable nor a byte
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a text stream

instantiation error
instantiation error
type error(byte, Byte)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, text stream,
SorA)

Portability
GNU Prolog predicates.

8.13.4put byte/2, put byte/1

Templates
put byte(+stream or alias, +byte)
put byte(+byte)
Description
put byte(SorA, Byte) writes Byte onto the stream associated with the stream-term or alias SorA.
put byte/1 applies to the current output stream.
ErrorsSorA is a variable
Byte is a variable
Byte is neither a variable nor a byte
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a text stream
Portability
GNU Prolog predicates.

instantiation error
instantiation error
type error(byte, Byte)
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(output, stream, SorA)
permission error(output, text stream,
SorA)

104

8

8.14

PROLOG BUILT-IN PREDICATES

Term input/output

These built-in predicates enable a Prolog term to be input from or output to a text stream. The atom
end of file is returned as term to indicate the end-of-file. The syntax of such terms can also be alteredby changing the operators (section 8.14.10, page 113), and making some characters equivalent to others(section 8.14.12, page 116) if the char conversion Prolog flag is on (section 8.22.1, page 148). Double
quoted tokens will be returned as an atom or a character list or a character code list depending on thevalue of the double quotes Prolog flag (section 8.22.1, page 148). Similarly, back quoted tokens are
returned depending on the value of the back quotes Prolog flag.

8.14.1

read term/3, read term/2, read/2, read/1

Templates
read term(+stream or alias, ?term, +read option list)
read term(?term, +read option list)
read(+stream or alias, ?term)read(?term)
Description
read term(SorA, Term, Options) is true if Term unifies with the next term read from the stream
associated with the stream-term or alias SorA according to the options given by Options.
Read options: Options is a list of read options. If this list contains contradictory options, the rightmost
option is the one which applies. Possible options are:• variables(VL): VL is unified with the list of all variables of the input term, in left-to-right traversal
order. Anonymous variables are included in the list VL.
• variable names(VNL): VNL is unified with the list of pairs Name = Var where Var is a named
variable of the term and Name is the atom associated with the name of Var. Anonymous variables
are not included in the list VNL. The pairs appear in left-to-right traversal order of their Var in theterm.
• singletons(SL): SL is unified with the list of pairs Name = Var where Var is a named variable which
occurs only once in the term and Name is the atom associated to the name of Var. Anonymous
variables are not included in the list SL.
• syntax error(error/warning/fail): specifies the effect of a syntax error:– error: a syntax error is raised.
– warning: a warning message is displayed and the predicate fails.
– fail: the predicate quietly fails.
The default value is the value of the syntax error Prolog flag (section 8.22.1, page 148).
• end of term(dot/eof): specifies the end-of-term delimiter: dot is the classical full-stop delimiter(a dot followed with a layout character), eof is the end-of-file delimiter. This option is useful for
predicates like read term from atom/3 (section 8.15.1, page 117) to avoid to add a terminal dot at
the end of the atom. The default value is dot.
read(SorA, Term) is equivalent to read term(SorA, Term, []).
read term/2 and read/1 apply to the current input stream.
Errors8.14

Term input/output

SorA is a variable
Options is a partial list or a list with an element
E which is a variable
SorA is neither a variable nor a stream-term or
alias
Options is neither a partial list nor a list
an element E of the Options list is neither avariable nor a valid read option
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a binary stream
SorA has stream properties
end of stream(past) and eof action(error)
a syntax error occurs and the value of thesyntax error Prolog flag is error(section 8.22.1, page 148)

105

instantiation error
instantiation error
domain error(stream or alias, SorA)
type error(list, Options)domain error(read option, E)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, binary stream,
SorA)
permission error(input,
past end of stream, SorA)
syntax error(atom explaining the error )Portability
ISO predicates. The ISO reference raises a representation error(Flag) where Flag is max arity,
max integer, or min integer when the read term breaches an implementation defined limit specified
by Flag. GNU Prolog detects neither min integer nor max integer violation and treats a max arity
violation as a syntax error. The read options syntax error and end of term are GNU Prolog extensions.

8.14.2

read atom/2, read atom/1, read integer/2, read integer/1,
read number/2, read number/1

Templates
read atom(+stream or alias, ?atom)
read atom(?atom)
read integer(+stream or alias, ?integer)
read integer(?integer)
read number(+stream or alias, ?number)read number(?number)
Description
read atom(SorA, Atom) succeeds if Atom unifies with the next atom read from the stream associatedwith the stream-term or alias SorA.
read integer(SorA, Integer) succeeds if Integer unifies with the next integer read from the stream
associated with the stream-term or alias SorA.
read number(SorA, Number) succeeds if Number unifies with the next number (integer or floating point
number) read from the stream associated with the stream-term or alias SorA.
read atom/1, read integer/1 and read number/1 apply to the current input stream.
Errors106

8

SorA is a variable
Atom is neither a variable nor an atom
Integer is neither a variable nor an integer
Number is neither a variable nor a number
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a binary stream
SorA has stream properties
end of stream(past) and eof action(error)
a syntax error occurs and the value of thesyntax error Prolog flag is error(section 8.22.1, page 148)

PROLOG BUILT-IN PREDICATES

instantiation error
type error(atom, Atom)type error(integer, Integer)
type error(number, Number)domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, binary stream,
SorA)
permission error(input,
past end of stream, SorA)
syntax error(atom explaining the error )Portability
GNU Prolog predicates.

8.14.3

read token/2, read token/1

Templates
read token(+stream or alias, ?nonvar)
read token(?nonvar)
Description
read token(SorA, Token) succeeds if Token unifies with the encoding of the next Prolog token readfrom the stream associated with stream-term or alias SorA.
Token encoding:• var(A): a variable is read whose name is the atom A.
• an atom A: an atom A is read.
• integer N: an integer N is read.
• floating point number N: a floating point number N is read.
• string(A): a string (double quoted item) is read whose characters forms the atom A.
• punct(P): a punctuation character P is read (P is a one-character atom in ()[]{|}, the atom
full stop or the atom end of file).
• back quotes(A): a back quoted item is read whose characters forms the atom A.
• extended(A): an extended character A (an atom) is read.
As for read term/3, the behavior of read token/2 can be affected by some Prolog flags (section 8.14,
page 104).
read token/1 applies to the current input stream.
Errors8.14

Term input/output

SorA is a variable
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an output stream
SorA is associated with a binary stream
SorA has stream properties
end of stream(past) and eof action(error)
a syntax error occurs and the value of thesyntax error Prolog flag is error(section 8.22.1, page 148)

107

instantiation error
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(input, stream, SorA)
permission error(input, binary stream,
SorA)
permission error(input,
past end of stream, SorA)
syntax error(atom explaining the error )Portability
GNU Prolog predicates.

8.14.4syntax error info/4

Templates
syntax error info(?atom, ?integer, ?integer, ?atom)
Description
syntax error info(FileName, Line, Column, Error) returns the information associated with the last
syntax error. Line is the line number of the error, Column is the column number of the error and Error
is an atom explaining the error.
ErrorsFileName is neither a variable nor an atomLine is neither a variable nor an integer
Column is neither a variable nor an integer
Error is neither a variable nor an atom

type error(atom, FileName)
type error(integer, Line)
type error(integer, Column)
type error(atom, Error)

Portability
GNU Prolog predicate.

8.14.5last read start line column/2

Templates
last read start line column(?integer, ?integer)
Description
last read start line column(Line, Column) unifies Line and Column with the line number and thecolumn number associated with the start of the last read predicate. This predicate can be used after calling
one of the following predicates: read term/3, read term/2, read/2, read/1 (section 8.14.1, page 104),
read atom/2, read atom/1, read integer/2, read integer/1, read number/2, read number/1 (section 8.14.2, page 105) or read token/2, read token/1 (section 8.14.3, page 106).

108

8

PROLOG BUILT-IN PREDICATES

ErrorsLine is neither a variable nor an integer
Column is neither a variable nor an integer

type error(integer, Line)
type error(integer, Column)

Portability
GNU Prolog predicate.

8.14.6

write term/3, write term/2, write/2, write/1, writeq/2, writeq/1,
write canonical/2, write canonical/1, display/2, display/1, print/2,
print/1

Templates
write term(+stream or alias, ?term, +write option list)
write term(?term, +write option list)
write(+stream or alias, ?term)
write(?term)
writeq(+stream or alias, ?term)
writeq(?term)
write canonical(+stream or alias, ?term)
write canonical(?term)
display(+stream or alias, ?term)
display(?term)
print(+stream or alias, ?term)
print(?term)
Description
write term(SorA, Term, Options) writes Term to the stream associated with the stream-term or alias
SorA according to the options given by Options.
Write options: Options is a list of write options. If this list contains contradictory options, therightmost option is the one which applies. Possible options are:• quoted(true/false): if true each atom and functor is quoted if this would be necessary for theterm to be input by read term/3. If false no extra quotes are written. The default value is false.
• ignore ops(true/false): if true each compound term is output in functional notation (neither
operator notation nor list notation is used). If false operator and list notations are used. The
default value is false.
• numbervars(true/false): if true a term of the form ’$VAR’(N), where N is an integer, is output
as a variable name (see below). If false such a term is output normally (according to the otheroptions). The default value is false.
• namevars(true/false): if true a term of the form ’$VARNAME’(Name), where Name is an atom
respecting the syntax of variable names, is output as a variable name (see below). If false such aterm is output normally (according to the other options). The default value is false.
• variable names(VNL): VNL is a list of pairs Name = Var where Var is a variable and Name is theatom associated with the name of Var. Each variable Var is written as the atom Name (withquoted(false)) iff a term Name = Var is an element of the list VNL. If several pairs exist for thesame variable name the first one applies.

8.14

Term input/output

109• space args(true/false): if true an extra space character is emitted after each comma separating
the arguments of a compound term in functional notation or of a list. If false no extra space isemitted. The default value is false.
• portrayed(true/false): if true and if there exists a predicate portray/1, write term/3 acts
as follows: if Term is a variable it is simply written. If Term is non-variable then it is passed toportray/1. If this succeeds then it is assumed that Term has been output. Otherwise write term/3
outputs the principal functor of Term (Term itself if it is atomic) according to other options
and recursively calls portray/1 on the components of Term (if it is a compound term). With
ignore ops(false) a list is first passed to portray/1 and only if this call fails each element of thelist is passed to portray/1 (thus every sub-list is not passed). The default value is false.
• max depth(N): controls the depth of output for compound terms. N is an integer specifying thedepth. The output of a term whose depth is greater than N gives rise to the output of ... (3 dots).
By default there is no depth limit.
• priority(N): specifies the starting priority to output the term. This option controls if Term should
be enclosed in brackets. N is a positive integer ≤ 1200. By default N = 1200.
Variable numbering: when the numbervars(true) option is passed to write term/3 any term of theform ’$VAR’(N) where N is an integer is output as a variable name consisting of a capital letter possibly
followed by an integer. The capital letter is the (I+1)th letter of the alphabet and the integer is J, where
I = N mod 26 and J = N // 26. The integer J is omitted if it is zero. For example:’$VAR’(0) is written as A’$VAR’(1) is written as B...
’$VAR’(25) is written as Z’$VAR’(26) is written as A1’$VAR’(27) is written as B1
Variable naming: when the namevars(true) option is passed to write term/3 any term of the form’$VARNAME’(Name) where Name is an atom is output as a variable name consisting of the characters Name.
For example: ’$VARNAME’(’A’) is written as A (even in the presence of the quoted(true) option).
write(SorA, Term) is equivalent to write term(SorA, Term, [numbervars(true),
namevars(true)]).
writeq(SorA, Term) is equivalent to write term(SorA, Term, [quoted(true),
numbervars(true), namevars(true)]).
write canonical(SorA, Term) is equivalent to write term(SorA, Term, [quoted(true),
ignore ops(true), numbervars(false), namevars(false)]).
display(SorA, Term) is equivalent to write term(SorA, Term, [ignore ops(true),
numbervars(false), namevars(false)]).
print(SorA, Term) is equivalent to write term(SorA, Term, [numbervars(false),
portrayed(true)]).
write term/2, write/1, writeq/1, write canonical/1, display/1 and print/1 apply to the current
output stream.
Errors110

8

SorA is a variable
Options is a partial list or a list with an element
E which is a variable
Options is neither a partial list nor a list
SorA is neither a variable nor a stream-term oralias
an element E of the Options list is neither avariable nor a valid write-option
SorA is not associated with an open stream
SorA is an input stream
SorA is associated with a binary stream

PROLOG BUILT-IN PREDICATES

instantiation error
instantiation error
type error(list, Options)domain error(stream or alias, SorA)
domain error(write option, E)
existence error(stream, SorA)
permission error(output, stream, SorA)
permission error(output, binary stream,
SorA)

Portability
ISO predicates except display/1-2 and print/1-2 that are GNU Prolog predicates. namevars, variable names
space args, portrayed, max depth and priority options are GNU Prolog extensions.

8.14.7

format/3, format/2

Templates
format(+stream or alias, +character code list or atom, +list)
format(+character code list or atom, +list)
Description
format(SorA, Format, Arguments) writes the Format string replacing each format control sequence F
by the corresponding element of Arguments (formatted according to F) to the stream associated with thestream-term or alias SorA.
Format control sequences: the general format of a control sequence is ’~NC’. The character C determines the type of the control sequence. N is an optional numeric argument. An alternative form of N is’*’. ’*’ implies that the next argument Arg in Arguments should be used as a numeric argument in
the control sequence. The use of C printf() formatting sequence (beginning by the character %) is also
allowed. The following control sequences are available:

8.14

Term input/output

Formatsequence~Na

type of theargumentatom~Nccharacter code

~Nf
~Ne ~NE~Ng ~NGfloat expression~Ndinteger expression~ND

integer expression~Nrinteger expression

~NR
~Ns
~NS
~i
~k
~p
~q
~w
~~
~Nn
~N
~?

integer expression
character code list
character list
term
term
term
term
term
none
none
none
atom
atom, integer or
float expression

%F

111

Description
print the atom without quoting. N is minimal number of charactersto print using spaces on the right if needed (default: the length of
the atom)print the character associated with the code. N is the number oftimes to print the character (default: 1)
pass the argument Arg and N to the C printf() function as:
if N is not specified printf("%f",Arg) else printf("%.Nf",Arg).
Similarly for ~Ne, ~NE, ~Ng and ~NG
print the argument. N is the number of digits after the decimal point.
If N is 0 no decimal point is printed (default: 0)
identical to ~Nd except that ’,’ separates groups of three digits tothe left of the decimal point
print the argument according to the radix N. 2 ≤ N ≤ 36 (default: 8).
The letters a-z denote digits > 9
identical to ~Nr except that the letters A-Z denote digits > 9
print exactly N characters (default: the length of the list)
print exactly N characters (default: the length of the list)
ignore the current argument
pass the argument to write canonical/1 (section 8.14.6, page 108)
pass the argument to print/1 (section 8.14.6, page 108)
pass the argument to writeq/1 (section 8.14.6, page 108)
pass the argument to write/1 (section 8.14.6, page 108)
print the character ’~’
print N new-line characters (default: 1)
print a new-line character if not at the beginning of a line
use the argument as a nested format stringinterface to the C function printf(3) for outputting atoms (Cstring), integers and floating point numbers. * are also allowed.

format/2 applies to the current output stream.
Errors112

8

SorA is a variable
Format is a partial list or a list with an element
E which is a variable
Arguments is a partial list
Format is neither a partial list nor a list or an
atom
Arguments is neither a partial list nor a list
an element E of the Format list is neither avariable nor a character code
SorA is neither a variable nor a stream-term oralias
an element E of Format is not a valid format
control sequence
the Arguments list does not contain sufficientelements
an element E of the Arguments list is a variablewhile a non-variable term was expected
an element E of the Arguments list is neither
variable nor an atom while an atom was expected
an element E of the Arguments cannot be
evaluated as an arithmetic expression while an
integer or a floating point number was expected
an element E of the Arguments list is neither
variable nor character code while a charactercode was expected
SorA is not associated with an open stream
SorA is an input stream
SorA is associated with a binary stream

PROLOG BUILT-IN PREDICATES

instantiation error
instantiation error
instantiation error
type error(list, Format)
type error(list, Arguments)
representation error(character code, E)
domain error(stream or alias, SorA)
domain error(format control sequence, E)
domain error(non empty list, [])instantiation error
type error(atom, E)
an arithmetic error (section 8.6.1, page 66)

representation error(character code, E)
existence error(stream, SorA)
permission error(output, stream, SorA)
permission error(output, binary stream,
SorA)

Portability
GNU Prolog predicates.

8.14.8

portray clause/2, portray clause/1

Templates
portray clause(+stream or alias, +clause)
portray clause(+clause)
Description
portray clause(SorA, Clause) pretty prints Clause to the stream associated with the stream-termor alias SorA. portray clause/2 uses the variable binding predicates name singleton vars/1 (section 8.5.1, page 63) and numbervars/1 (section 8.5.3, page 64). This predicate is used by listing/1(section 8.23.3, page 154).
portray clause/1 applies to the current output stream.
Errors8.14

Term input/output

Clause is a variable
Clause is neither a variable nor a callable term
SorA is a variable
SorA is neither a variable nor a stream-term or
alias
SorA is not associated with an open stream
SorA is an input stream
SorA is associated with a binary stream

113

instantiation error
type error(callable, Clause)
instantiation error
domain error(stream or alias, SorA)
existence error(stream, SorA)
permission error(output, stream, SorA)
permission error(output, binary stream,
SorA)

Portability
GNU Prolog predicates.

8.14.9get print stream/1

Templates
get print stream(?stream)
Description
get print stream(Stream) unifies Stream with the stream-term associated with the output stream usedby print/2 (section 8.14.6, page 108). The purpose of this predicate is to allow a user-defined portray/1
predicate to identify the output stream in use.
ErrorsStream is neither a variable nor a stream-term

domain error(stream, Stream)

Portability
GNU Prolog predicate.

8.14.10

op/3

Templates
op(+integer, +operator specifier, +atom or atom list)
Description
op(Priority, OpSpecifier, Operator) alters the operator table. Operator is declared as an operator
with properties defined by specifier OpSpecifier and Priority. Priority must be an integer ≥ 0 and≤ 1200. If Priority is 0 then the operator properties of Operator (if any) are canceled. Operator may
also be a list of atoms in which case all of them are declared to be operators. In general, operators canbe removed from the operator table and their priority or specifier can be changed. However, it is anerror to attempt to change the ’,’ operator from its initial status. An atom can have multiple operator
definitions (e.g. prefix and infix like +) however an atom cannot have both an infix and a postfix operator
definitions.
Operator specifiers: the following specifiers are available:

114

8

Specifier
fx
fy
xf
yf
xfx
yfx
xfy

Type
prefixprefixpostfix
postfix
infix
infix
infix

PROLOG BUILT-IN PREDICATES

Associativity
no
yes
no
yes
no
left
right

Prolog predefined operators:
Priority
1200
1200
1105
1100
1050
1000
900

Specifier
xfx
fx
xfy
xfy
xfy
xfy
fy

700

xfx

600
500
400
200
200

xfy
yfx
yfx
xfx
fy

Operators:- -->:|;-> *->,\+= \= =..
== \== @< @=< @>> >=:+ - /\ \/* / // rem mod div << >>
** ^
+ - \

@>=

is

=:=

=\=

<

=<

#<#

#=<#

#>#

#>=#

FD predefined operators:
Priority
750
740
730
720
710
700
500
400
200
200
ErrorsSpecifier
xfy
xfy
xfy
yfx
fy
xfx
yfx
yfx
xfy
fy

Operators#<=> #\<=>#==> #\==>## #\/ #\\/#/\ #\/\#\#= #\= #< #=<+ * / // rem
**
+ -

#>

#>=

#=#

#\=#

8.14

Term input/output

Priority is a variable
OpSpecifier is a variable
Operator is a partial list or a list with anelement E which is a variable
Priority is neither a variable nor an integer
OpSpecifier is neither a variable nor an atom
Operator is neither a partial list nor a list nor
an atom
an element E of the Operator list is neither avariable nor an atom
Priority is an integer not ≥ 0 and ≤ 1200
OpSpecifier is not a valid operator specifier
Operator (or an element of the Operator list) is’,’
OpSpecifier is a specifier such that Operator
would have a postfix and an infix definition.
Operator (or an element of the Operator list) is| and it would have a prefix or a postfix
definition or its Priority would be ≤ 1100.
Operator (or an element of the Operator list) is[] or {}.

115

instantiation error
instantiation error
instantiation error
type error(integer, Priority)
type error(atom, OpSpecifier)
type error(list, Operator)
type error(atom, E)
domain error(operator priority, Priority)
domain error(operator specifier,
OpSpecifier)permission error(modify, operator, ’,’)
permission error(create, operator,
Operator)
permission error(create, operator, ’|’)
permission error(create, operator,
Operator)

Portability
ISO predicate.
The ISO reference implies that if a program calls current op/3, then modifies an operator definition bycalling op/3 and backtracks into the call to current op/3, then the changes are guaranteed not to affectthat current op/3 goal. This is not guaranteed by GNU Prolog.

8.14.11current op/3

Templates
current op(?integer, ?operator specifier, ?atom)
Description
current op(Priority, OpSpecifier, Operator) succeeds if Operator is an operator with properties
defined by specifier OpSpecifier and Priority. This predicate is re-executable on backtracking.
ErrorsPriority is neither a variable nor an operator
priority
OpSpecifier is neither a variable nor an
operator specifier
Operator is neither a variable nor an atom
Portability
ISO predicate.

domain error(operator priority, Priority)
domain error(operator specifier,
OpSpecifier)
type error(atom, Operator)

116

8

8.14.12PROLOG BUILT-IN PREDICATES

char conversion/2

Templateschar conversion(+character, +character)
Description
char conversion(InChar, OutChar) alters the character-conversion mapping. This mapping is used by
the following read predicates: read term/3 (section 8.14.1, page 104), read atom/2, read integer/2,
read number/2 (section 8.14.2, page 105) and read token/2 (section 8.14.3, page 106) to replace any
occurrence of a character InChar by OutChar. However the conversion mechanism should have beenpreviously activated by switching on the char conversion Prolog flag (section 8.22.1, page 148). When
InChar and OutChar are the same, the effect is to remove any conversion of a character InChar.
Note that the single character read predicates (e.g. get char/2) never do character conversion. Ifsuch behavior is required, it must be explicitly done using current char conversion/2 (section 8.14.13,
page 116).
Errors
InChar is a variable
OutChar is a variable
InChar is neither a variable nor a character
OutChar is neither a variable nor a characterinstantiation error
instantiation error
type error(character, InChar)type error(character, OutChar)

Portability
ISO predicate. The type error(character,...) is a GNU Prolog behavior, the ISO reference instead
defines a representation error(character) in this case. This seems to be an error of the ISO reference since, for many other built-in predicates accepting a character (e.g. char code/2, put char/2), a
type error is raised.
The ISO reference implies that if a program calls current char conversion/2, then modifies the character mapping by calling char conversion/2, and backtracks into the call to current char conversion/2
then the changes are guaranteed not to affect that current char conversion/2 goal. This is not guaranteed by GNU Prolog.

8.14.13current char conversion/2

Templates
current char conversion(?character, ?character)
Description
current char conversion(InChar, OutChar) succeeds if the conversion of InChar is OutChar according
to the character-conversion mapping. In that case, InChar and OutChar are different. This predicate is
re-executable on backtracking.
Errors
InChar is neither a variable nor a character
OutChar is neither a variable nor a character

type error(character, InChar)type error(character, OutChar)8.15

Input/output from/to constant terms

117

Portability
ISO predicate. Same remark as for char conversion/2 (section 8.14.12, page 116).

8.15

Input/output from/to constant terms

These built-in predicates enable a Prolog term to be input from or output to a Prolog constant term
(atom, character list or character code list). All these predicates can be defined using constant term
streams (section 8.11, page 94). They are however simpler to use.

8.15.1

read term from atom/3, read from atom/2, read token from atom/2

Templates
read term from atom(+atom ?term, +read option list)
read from atom(+atom, ?term)
read token from atom(+atom, ?nonvar)
Description
Like read term/3, read/2 (section 8.14.1, page 104) and read token/2 (section 8.14.3, page 106) exceptthat characters are not read from a text-stream but from Atom; the atom given as first argument.
ErrorsAtom is a variable
Atom is neither a variable nor an atom
see associated predicate errors

instantiation error
type error(atom, Atom)(section 8.14.1, page 104) and (section 8.14.3,
page 106)

Portability
GNU Prolog predicates.

8.15.2

read term from chars/3, read from chars/2, read token from chars/2

Templates
read term from chars(+character list ?term, +read option list)
read from chars(+character list, ?term)
read token from chars(+character list, ?nonvar)
Description
Like read term/3, read/2 (section 8.14.1, page 104) and read token/2 (section 8.14.3, page 106) exceptthat characters are not read from a text-stream but from Chars; the character list given as first argument.
Errors118

8Chars is a partial list or a list with an element E
which is a variable
Chars is neither a partial list nor a list
an element E of the Chars list is neither avariable nor a character
see associated predicate errors

PROLOG BUILT-IN PREDICATES

instantiation error
type error(list, Chars)
type error(character, E)(section 8.14.1, page 104) and (section 8.14.3,
page 106)

Portability
GNU Prolog predicates.

8.15.3

read term from codes/3, read from codes/2, read token from codes/2

Templates
read term from codes(+character code list ?term, +read option list)
read from codes(+character code list, ?term)
read token from codes(+character code list, ?nonvar)
Description
Like read term/3, read/2 (section 8.14.1, page 104) and read token/2 (section 8.14.3, page 106) exceptthat characters are not read from a text-stream but from Codes; the character code list given as firstargument.
ErrorsCodes is a partial list or a list with an element E
which is a variable
Codes is neither a partial list nor a list
an element E of the Codes list is neither avariable nor an integer
an element E of the Codes list is an integer but
not a character code
see associated predicate errors

instantiation error
type error(list, Codes)
type error(integer, E)
representation error(character code, E)(section 8.14.1, page 104) and (section 8.14.3,
page 106)

Portability
GNU Prolog predicates.

8.15.4

write term to atom/3, write to atom/2, writeq to atom/2,
write canonical to atom/2, display to atom/2, print to atom/2,
format to atom/3

Templates
write term to atom(?atom, ?term, +write option list)
write to atom(?atom, ?term)
writeq to atom(?atom, ?term)
write canonical to atom(?atom, ?term)

8.15

Input/output from/to constant terms

119display to atom(?atom, ?term)
print to atom(?atom, ?term)
format to atom(?atom, +character code list or atom, +list)
Description
Similar to write term/3, write/2, writeq/2, write canonical/2, display/2, print/2 (section 8.14.6,
page 108) and format/3 (section 8.14.7, page 110) except that characters are not written onto a textstream but are collected as an atom which is then unified with the first argument Atom.
ErrorsAtom is neither a variable nor an atom
see associated predicate errors

type error(atom, Atom)(section 8.14.6, page 108) and (section 8.14.7,
page 110)

Portability
GNU Prolog predicates.

8.15.5

write term to chars/3, write to chars/2, writeq to chars/2,
write canonical to chars/2, display to chars/2, print to chars/2,
format to chars/3

Templates
write term to chars(?character list, ?term, +write option list)
write to chars(?character list, ?term)
writeq to chars(?character list, ?term)
write canonical to chars(?character list, ?term)
display to chars(?character list, ?term)
print to chars(?character list, ?term)
format to chars(?character list, +character code list or atom, +list)
Description
Similar to write term/3, write/2, writeq/2, write canonical/2, display/2, print/2 (section 8.14.6,
page 108) and format/3 (section 8.14.7, page 110) except that characters are not written onto a textstream but are collected as a character list which is then unified with the first argument Chars.
ErrorsChars is neither a partial list nor a list
An element E of the list Chars is neither avariable nor a one-char atom
see associated predicate errors
Portability
GNU Prolog predicates.

type error(list, Chars)
type error(character, E)(section 8.14.6, page 108) and (section 8.14.7,
page 110)120

88.15.6

PROLOG BUILT-IN PREDICATES

write term to codes/3, write to codes/2, writeq to codes/2,
write canonical to codes/2, display to codes/2, print to codes/2,
format to codes/3

Templates
write term to codes(?character code list, ?term, +write option list)
write to codes(?character code list, ?term)
writeq to codes(?character code list, ?term)
write canonical to codes(?character code list, ?term)
display to codes(?character code list, ?term)
print to codes(?character code list, ?term)
format to codes(?character code list, +character code list or atom, +list)
Description
Similar to write term/3, write/2, writeq/2, write canonical/2, display/2, print/2 (section 8.14.6,
page 108) and format/3 (section 8.14.7, page 110) except that characters are not written onto a textstream but are collected as a character code list which is then unified with the first argument Codes.
ErrorsCodes is neither a partial list nor a list
An element E of the list Codes is neither avariable nor an integer
An element E of the list Codes is an integer but
not a character code
see associated predicate errors

type error(list, Codes)
type error(integer, E)
representation error(character code)(section 8.14.6, page 108) and (section 8.14.7,
page 110)

Portability
GNU Prolog predicates.

8.16

DEC-10 compatibility input/output

8.16.1Introduction

The DEC-10 Prolog I/O predicates manipulate streams implicitly since they only refer to current input/output streams (section 8.10.1, page 78). The current input and output streams are initially set
to user input and user output respectively. The predicate see/1 (resp. tell/1, append/1) can beused for setting the current input (resp. output) stream to newly opened streams for particular files.
The predicate seen/0 (resp. told/0) close the current input (resp. output) stream, and resets it to thestandard input (resp. output). The predicate seeing/1 (resp. telling/1) is used for retrieving thefile name associated with the current input (resp. output) stream. The file name user stands for the
standard input or output, depending on context (user input and user output can also be used). The
DEC-10 Prolog I/O predicates are only provided for compatibility, they are now obsolete and their use
is discouraged. The predicates for explicit stream manipulation should be used instead (section 8.10,
page 78).

8.16

DEC-10 compatibility input/output

8.16.2121

see/1, tell/1, append/1

Templatessee(+source sink)see(+stream)tell(+source sink)tell(+stream)
append(+source sink)append(+stream)
Descriptionsee(FileName) sets the current input stream to FileName. If there is a stream opened by see/1 associated with the same FileName already, then it becomes the current input stream. Otherwise, FileNameis opened for reading and becomes the current input stream.
tell(FileName) sets the current output stream to FileName. If there is a stream opened by tell/1
associated with the same FileName already, then it becomes the current output stream. Otherwise,
FileName is opened for writing and becomes the current output stream.
append(FileName) like tell/1 but FileName is opened for writing + append.
A stream-term (obtained with any other built-in predicate) can also be provided as FileName to thesepredicates.
ErrorsSee errors associated with open/4 (section 8.10.6, page 81).
Portability
GNU Prolog predicates. Deprecated.

8.16.3seeing/1, telling/1

Templates
seeing(?source sink)telling(?source sink)
Description
seeing(FileName) succeeds if FileName unifies with the name of the current input file, if it was opened
by see/1; else with the current input stream-term, if this is not user input, otherwise with user.
telling(FileName) succeeds if FileName unifies with the name of the current output file, if it was
opened by tell/1 or append/1; else with the current output stream-term, if this is not user output,
otherwise with user.
Errors
None.

122

8

PROLOG BUILT-IN PREDICATES

Portability
GNU Prolog predicates. Deprecated.

8.16.4seen/0, told/0

Templates
seen
told
Description
seen closes the current input, and resets it to user input.
told closes the current output, and resets it to user output.
Errors
None.
Portability
GNU Prolog predicates. Deprecated.

8.16.5

get0/1, get/1, skip/1

Templates
get0(?in character code)get(?in character code)skip(+character code)
Description
get0(Code) succeeds if Code unifies with the next character code read from the current input stream.
Thus it is equivalent to get code(Code) (section 8.12.1, page 97).
get(Code) succeeds if Code unifies with the next character code read from the current input stream thatis not a layout character.
skip(Code) skips just past the next character code Code from the current input stream.
ErrorsSee errors for get code/2 (section 8.12.1, page 97).
Portability
GNU Prolog predicates. Deprecated.

8.17

Term expansion

8.16.6123

put/1, tab/1

Templates
put(+character code)tab(+evaluable)
Description
put(Code) writes the character whose code is Code onto the current output stream. It is equivalent to
put code(Code) (section 8.12.5, page 100).
tab(N) writes N spaces onto the current output stream. N may be an arithmetic expression.
ErrorsSee errors for put code/2 (section 8.12.5, page 100) and for arithmetic expressions (section 8.6.1, page 66).
Portability
GNU Prolog predicates. Deprecated.

8.17

Term expansion

8.17.1

Definite clause grammars

Definite clause grammars are a useful notation to express grammar rules. However the ISO reference does
not include them, so they should be considered as a system dependent feature. Definite clause grammars
are an extension of context-free grammars. A grammar rule is of the form:
head --> body.
--> is a predefined infix operator (section 8.14.10, page 113).
Here are some features of definite clause grammars:• a non-terminal symbol may be any callable term.
• a terminal symbol may be any Prolog term and is written as a list. The empty list represents anempty sequence of terminals.
• a sequence is expressed using the Prolog conjunction operator ((’,’)/2).
• the head of a grammar rule consists of a non-terminal optionally followed by a sequence of terminals(i.e. a Prolog list).
• the body of a grammar rule consists of a sequence of non-terminals, terminals, predicate call,disjunction (using ;/2), if-then (using (->)/2) or cut (using !).
• a predicate call must be enclosed in curly brackets (using {}/1). This makes it possible to express
an extra condition.
A grammar rule is nothing but a “syntactic sugar” for a Prolog clause. Each grammar rule accepts as
input a list of terminals (tokens), parses a prefix of this list and gives as output the rest of this list
(possibly enlarged). This rest is generally parsed later. So, each a grammar rule is translated into a
Prolog clause that explicitly the manages the list. Two arguments are then added: the input list (Start)
and the output list (End). For instance:

124

8

PROLOG BUILT-IN PREDICATES

p --> q.
is translated into:p(Start, End) :- q(Start, End).
Extra arguments can be provided and the body of the rule can contain several non-terminals. Example:p(X, Y) -->q(X),r(X, Y),s(Y).
is translated into:p(X, Y, Start, End) :q(X, Start, A),r(X, Y, A, B),s(Y, B, End).
Terminals are translated using unification:
assign(X,Y) --> left(X), [:=], right(Y), [;].
is translated into:
assign(X,Y,Start,End) :left(X, Start, A),
A=[:=|B],
right(Y, B, C),
C=[;|End].
Terminals appearing on the left-hand side of a rule are connected to the output argument of the head.
It is possible to include a call to a prolog predicate enclosing it in curly brackets (to distinguish themfrom non-terminals):
assign(X,Y) --> left(X), [:=], right(Y0), {Y is Y0 }, [;].
is translated into:
assign(X,Y,Start,End) :left(X, Start, A),
A=[:=|B],
right(Y0, B, C),
Y is Y0,
C=[;|End].
Cut, disjunction and if-then(-else) are translated literally (and do not need to be enclosed in curly
brackets).

8.17.2

expand term/2, term expansion/2

Templates
expand term(?term, ?term)
term expansion(?term, ?term)

8.17Term expansion

125

Description
expand term(Term1, Term2) succeeds if Term2 is a transformation of Term1. The transformation steps
are as follows:• if Term1 is a variable, it is unified with Term2• if term expansion(Term1, Term2) succeeds Term2 is assumed to be the transformation of Term1.
• if Term1 is a DCG then Term2 is its translation (section 8.17.1, page 123).
• otherwise Term2 is unified with Term1.
term expansion(Term1, Term2) is a hook predicate allowing the user to define a specific transformation.
The GNU Prolog compiler (section 4.4, page 21) automatically calls expand term/2 on each Term1
read in. However, in the current release, only DCG transformation are done by the compiler (i.e.
term expansion/2 cannot be used). To use term expansion/2, it is necessary to call expand term/2
explicitly.
Errors
None.
Portability
GNU Prolog predicate.

8.17.3phrase/3, phrase/2

Templates
phrase(?term, ?list, ?list)
phrase(?term, ?list)
Description
phrase(Phrase, List, Remainder) succeeds if the list List is in the language defined by the grammar
rule body Phrase. Remainder is what remains of the list after a phrase has been found.
phrase(Phrase, List) is equivalent to phrase(Phrase, List, []).
ErrorsPhrase is a variable
Phrase is neither a variable nor a callable term
List is neither a list nor a partial list
Remainder is neither a list nor a partial list
Portability
GNU Prolog predicates.

instantiation error
type error(callable, Phrase)type error(list, List)
type error(list, Remainder)

126

8

PROLOG BUILT-IN PREDICATES

8.18

Logic, control and exceptions

8.18.1

abort/0, stop/0, top level/0, break/0, halt/1, halt/0

Templates
abort
stop
top level
breakhalt(+integer)
halt
Description
abort aborts the current execution. If this execution was initiated under a top-level the control is given
back to the top-level and the message {execution aborted} is displayed. Otherwise, e.g. execution
started by a initialization/1 directive (section 7.1.14, page 50), abort/0 is equivalent to halt(1)(see below).
stop stops the current execution. If this execution was initiated under a top-level the control is given
back to the top-level. Otherwise, stop/0 is equivalent to halt(0) (see below).
top level starts a new recursive top-level (including the banner display). To end this new top-level
simply type the end-of-file key sequence (Ctl-D) or its term representation: end of file.
break invokes a recursive top-level (no banner is displayed). To end this new level simply type theend-of-file key sequence (Ctl-D) or its term representation: end of file.
halt(Status) causes the GNU Prolog process to immediately exit back to the shell with the return code
Status.
halt is equivalent to halt(0).
ErrorsStatus is a variable
Status is neither a variable nor an integer

instantiation error
type error(integer, Status)

Portability
halt/1 and halt/0 are ISO predicates. abort/0, stop/0, top level/0 and break/0 are GNU Prolog
predicates.

8.18.2

false/0, once/1, (\+)/1 - not provable, call/2-11, call with args/1-11, call det/2,
forall/2

Templates
false
once(+callable term)\+(+callable term)call(+callable term, +term,..., +term)

8.18

Logic, control and exceptions

127

call with args(+atom, +term,..., +term)call det(+callable term, ?boolean)
forall(+callable term, +callable term)
Description
false always fails and enforces backtracking. It is equivalent to the fail/0 control construct (section 7.2.1, page 51).
once(Goal) succeeds if call(Goal) succeeds. However once/1 is not re-executable on backtracking since
all alternatives of Goal are cut. once(Goal) is equivalent to call(Goal), !.
\+ Goal succeeds if call(Goal) fails and fails otherwise. This built-in predicate gives negation by failure.
call(Closure, Arg1,..., ArgN) calls the goal call(Goal) where Goal is constructed by appending
Arg1,..., ArgN (1 ≤ N ≤ 10) additional arguments to the arguments (if any) of Closure.
call with args(Functor, Arg1,..., ArgN) calls the goal whose functor is Functor and whose arguments are Arg1,. . . , ArgN (0 ≤ N ≤ 10).
call det(Goal, Deterministic) succeeds if call(Goal) succeeds and unifies Deterministic withtrue if Goal has not created any choice-points, with false otherwise.
forall(Condition, Action) succeeds if for all alternative bindings of Condition, Action can be proven.
It is equivalent to \+ (Condition, \+ Action).
\+ is a predefined prefix operator (section 8.14.10, page 113).
ErrorsGoal (or Condition or Action) is a variable
Goal (or Condition or Action) is neither avariable nor a callable term
The predicate indicator Pred of Goal does notcorrespond to an existing procedure and thevalue of the unknown Prolog flag is error(section 8.22.1, page 148)
Functor is a variable
Functor is neither a variable nor an atom
Deterministic is neither a variable nor abooleanfor call/2-11 the resulting arity of Goal (arityof Closure + N) is an integer > max arity flag
(section 8.22.1, page 148)

instantiation error
type error(callable, Goal)

existence error(procedure, Pred)
instantiation error
type error(atom, Functor)
type error(boolean, Deterministic)
representation error(max arity)

Portability
false/0, call/2-8, once/1 and (\+)/1 are ISO predicates. call/9-11, call with args/1-11, call det/2
and forall/2 are GNU Prolog predicates.

8.18.3

repeat/0

Templates

128

8

PROLOG BUILT-IN PREDICATES

repeatDescription
repeat generates an infinite sequence of backtracking choices. The purpose is to repeatedly perform someaction on elements which are somehow generated, e.g. by reading them from a stream, until some test
becomes true. Repeat loops cannot contribute to the logic of the program. They are only meaningful
if the action involves side-effects. The only reason for using repeat loops instead of a more natural tailrecursive formulation is efficiency: when the test fails back, the Prolog engine immediately reclaims any
working storage consumed since the call to repeat/0.
Errors
None.
Portability
ISO predicate.

8.18.4

between/3, for/3

Templates
between(+integer, +integer, ?integer)
for(?integer, +integer, +integer)
Description
between(Lower, Upper, Counter) generates an sequence of backtracking choices instantiating Counterto the values Lower, Lower+1,. . . , Upper.
for(Counter, Lower, Upper) is equivalent to between(Lower, Upper, Counter). This predicate isdeprecated and new code should use between/3.
ErrorsCounter is neither a variable nor an integer
Lower is a variable
Lower is neither a variable nor an integer
Upper is a variable
Upper is neither a variable nor an integer

type error(integer, Counter)instantiation error
type error(integer, Lower)
instantiation error
type error(integer, Upper)

Portability
GNU Prolog predicate.

8.19

Atomic term processing

These built-in predicates enable atomic terms to be processed as a sequence of characters and charactercodes. Facilities exist to split and join atoms, to convert a single character to and from the corresponding
character code, and to convert a number to and from a list of characters and character codes.

8.19

Atomic term processing

8.19.1129

atom length/2

Templates
atom length(+atom, ?integer)
Description
atom length(Atom, Length) succeeds if Length unifies with the number of characters of the name ofAtom.
ErrorsAtom is a variable
Atom is neither a variable nor an atom
Length is neither a variable nor an integer
Length is an integer < 0instantiation error
type error(atom, Atom)type error(integer, Length)
domain error(not less than zero, Length)

Portability
ISO predicate.

8.19.2

atom concat/3

Templates
atom concat(+atom, +atom, ?atom)
atom concat(?atom, ?atom, +atom)
Description
atom concat(Atom1, Atom2, Atom12) succeeds if the name of Atom12 is the concatenation of the nameof Atom1 with the name of Atom1. This predicate is re-executable on backtracking (e.g. if Atom12 isinstantiated and both Atom1 and Atom2 are variables).
ErrorsAtom1 and Atom12 are variables
Atom2 and Atom12 are variables
Atom1 is neither a variable nor an atom
Atom2 is neither a variable nor an atom
Atom12 is neither a variable nor an atom

instantiation error
instantiation error
type error(atom, Atom1)
type error(atom, Atom2)
type error(atom, Atom12)

Portability
ISO predicate.

8.19.3sub atom/5

Templates
sub atom(+atom, ?integer, ?integer, ?integer, ?atom)

130

8

PROLOG BUILT-IN PREDICATES

Description
sub atom(Atom, Before, Length, After, SubAtom) succeeds if atom Atom can be split into threeatoms, AtomL, SubAtom and AtomR such that Before is the number of characters of the name of AtomL,
Length is the number of characters of the name of SubAtom and After is the number of characters of thename of AtomR. This predicate is re-executable on backtracking.
ErrorsAtom is a variable
Atom is neither a variable nor an atom
SubAtom is neither a variable nor an atom
Before is neither a variable nor an integer
Length is neither a variable nor an integer
After is neither a variable nor an integer
Before is an integer < 0Length is an integer < 0
After is an integer < 0instantiation error
type error(atom, Atom)type error(atom, SubAtom)type error(integer, Before)
type error(integer, Length)
type error(integer, After)
domain error(not less than zero, Before)
domain error(not less than zero, Length)
domain error(not less than zero, After)

Portability
ISO predicate.

8.19.4char code/2

Templateschar code(+character, ?character code)char code(-character, +character code)
Description
char code(Char, Code) succeeds if the character code for the one-char atom Char is Code.
ErrorsChar and Code are variables
Char is neither a variable nor a one-char atom
Code is neither a variable nor an integer
Code is an integer but not a character code
Portability
ISO predicate.

8.19.5lower upper/2

Templates
lower upper(+character, ?character)lower upper(-character, +character)
Description

instantiation error
type error(character, Char)type error(integer, Code)representation error(character code)

8.19

Atomic term processing

131

lower upper(Char1, Char2) succeeds if Char1 and Char2 are one-char atoms and if Char2 is the upper
conversion of Char1. If Char1 (resp. Char2) is a character that is not a lower (resp. upper) letter thenChar2 is equal to Char1.
ErrorsChar1 and Char2 are variables
Char1 is neither a variable nor a one-char atom
Char2 is neither a variable nor a one-char atom

instantiation error
type error(character, Char1)
type error(character, Char2)

Portability
GNU Prolog predicate.

8.19.6

atom chars/2, atom codes/2

Templates
atom chars(+atom, ?character list)
atom chars(-atom, +character list)
atom codes(+atom, ?character code list)
atom codes(-atom, +character code list)
Description
atom chars(Atom, Chars) succeeds if Chars is the list of one-char atoms whose names are the successive
characters of the name of Atom.
atom codes(Atom, Codes) is similar to atom chars/2 but deals with a list of character codes.
ErrorsAtom is a variable and Chars (or Codes) is apartial list or a list with an element which is avariable
Atom is neither a variable nor an atom
Chars is neither a list nor a partial list
Codes is neither a list nor a partial list
An element E of the list Chars is neither avariable nor a one-char atom
An element E of the list Codes is neither avariable nor an integer
An element E of the list Codes is an integer but
not a character code

instantiation error
type error(atom, Atom)type error(list, Chars)
type error(list, Codes)
type error(character, E)
type error(integer, E)
representation error(character code)

Portability
ISO predicates. The ISO reference only causes a type error(list, Chars) if Atom is a variable andChars is neither a list nor a partial list. GNU Prolog always checks if Chars is a list. Similarly for
Codes. The type error(integer, E) when an element E of the Codes is not an integer is a GNU Prolog
extension. This seems to be an omission in the ISO reference since this error is detected for many otherbuilt-in predicates accepting a character code (e.g. char code/2, put code/2).

132

8

8.19.7

PROLOG BUILT-IN PREDICATES

number atom/2, number chars/2, number codes/2

Templates
number atom(+number, ?atom)
number atom(-number, +atom)
number chars(+number, ?character list)
number chars(-number, +character list)
number codes(+number, ?character code list)
number codes(-number, +character code list)
Description
number atom(Number, Atom) succeeds if Atom is an atom whose name corresponds to the characters of
Number.
number chars(Number, Chars) is similar to number atom/2 but deals with a list of characters.
number codes(Number, Codes) is similar to number atom/2 but deals with a list of character codes.
ErrorsNumber and Atom are variables
Number is a variable and Chars (or Codes) is apartial list or a list with an element which is avariable
Number is neither a variable nor an number
Atom is neither a variable nor an atom
Chars is neither a list nor a partial list
Codes is neither a list nor a partial list
An element E of the list Chars is neither avariable nor a one-char atom
An element E of the list Codes is neither avariable nor an integer
An element E of the list Codes is an integer but
not a character code
Number is a variable, Atom (or Chars or Codes)
cannot be parsed as a number and the value ofthe syntax error Prolog flag is error(section 8.22.1, page 148)

instantiation error
instantiation error
type error(number, Number)
type error(atom, Atom)type error(list, Chars)
type error(list, Codes)
type error(character, E)
type error(integer, E)
representation error(character code)

syntax error(atom explaining the error )Portability
number atom/2 is a GNU Prolog predicate. number chars/2 and number codes/2 are ISO predicates.
GNU Prolog only raises an error about an element E of the Chars (or Codes) list when Number is avariable while the ISO reference always check this. This seems an error since the list itself is only checked
if Number is a variable.
The type error(integer, E) when an element E of the Codes is not an integer is a GNU Prolog
extension. This seems to be an omission in the ISO reference since this error is detected for many otherbuilt-in predicates accepting a character code (e.g. char code/2, put code/2).

8.19

Atomic term processing

8.19.8133

name/2

Templates
name(+atomic, ?character code list)
name(-atomic, +character code list)
Description
name(Constant, Codes) succeeds if Codes is a list whose elements are the character codes corresponding
to the successive characters of Constant (a number or an atom). However, there atoms are for which
name(Constant, Codes) is true, but which will not be constructed if name/2 is called with Constantuninstantiated, e.g. the atom ’1024’. For this reason the use of name/2 is discouraged and should
be limited to compatibility purposes. It is preferable to use atom codes/2 (section 8.19.6, page 131) or
number chars/2 (section 8.19.7, page 132).
ErrorsConstant is a variable and Codes is a partial list
or a list with an element which is a variable
Constant is neither a variable nor an atomic
termConstant is a variable and Codes is neither a list
nor a partial list
Constant is a variable and an element E of thelist Codes is neither a variable nor an integer
Constant is a variable and an element E of thelist Codes is an integer but not a character code

instantiation error
type error(atomic, Constant)
type error(list, Codes)
type error(integer, E)
representation error(character code)

Portability
GNU Prolog predicate.

8.19.9new atom/2, new atom/1

Templates
new atom(+atom, -atom)
new atom(-atom)
Description
new atom(Prefix, Atom) unifies Atom with a new atom whose name begins with the characters of thename of Prefix. This predicate is then a symbol generator. It is guaranteed that Atom does not exist
before the invocation of new atom/3. The characters appended to Prefix to form Atom are in: A-Z(capital letter), a-z (small letter) and 0-9 (digit).
new atom/1 is similar to new atom(term , Atom), i.e. the generated atom begins with term .
ErrorsPrefix is a variable
Prefix is neither a variable nor an atom
Atom is not a variableinstantiation error
type error(atom, Prefix)
uninstantiation error(Atom)

134

8

PROLOG BUILT-IN PREDICATES

Portability
GNU Prolog predicate.

8.19.10current atom/1

Templates
current atom(?atom)
Description
current atom(Atom) succeeds if there exists an atom that unifies with Atom. All atoms are found except
those beginning with a ’$’ (system atoms). This predicate is re-executable on backtracking.
ErrorsAtom is neither a variable nor an atom

type error(atom, Atom)Portability
GNU Prolog predicate.

8.19.11

atom property/2

Templates
atom property(?atom, ?atom property)
Description
atom property(Atom, Property) succeeds if current atom(Atom) succeeds (section 8.19.10, page 134)
and if Property unifies with one of the properties of the atom. This predicate is re-executable on
backtracking.
Atom properties:• length(Length): Length is the length of the name of the atom.
• hash(Hash): Hash is the hash code of the atom, see also term hash/2 (section 8.4.8, page 62).
• prefix op: if there is a prefix operator currently defined with this name.
• infix op: if there is an infix operator currently defined with this name.
• postfix op: if there is a postfix operator currently defined with this name.
• needs quotes: if the atom must be quoted to be read later.
• needs scan: if the atom must be scanned when output to be read later (e.g. contains special
characters that must be output with a \ escape sequence).
Errors8.20

List processing

Atom is neither a variable nor an atom
Property is neither a variable nor a n atom
property term
Property = length(E) or hash(E) and E isneither a variable nor an integer

135

type error(atom, Atom)domain error(atom property, Property)
type error(integer, E)

Portability
GNU Prolog predicate.

8.20

List processing

These predicates manipulate lists. They are bootstrapped predicates (i.e. written in Prolog) and noerror cases are tested (for the moment). However, since they are written in Prolog using other built-in
predicates, some errors can occur due to those built-in predicates.

8.20.1append/3

Templates
append(?list, ?list, ?list)
Description
append(List1, List2, List12) succeeds if the concatenation of the list List1 and the list List2 is
the list List12. This predicate is re-executable on backtracking (e.g. if List12 is instantiated and both
List1 and List2 are variable).
Errors
None.
Portability
GNU Prolog predicate.

8.20.2

member/2, memberchk/2

Templates
member(?term, ?list)
memberchk(?term, ?list)
Description
member(Element, List) succeeds if Element belongs to the List. This predicate is re-executable on
backtracking and can be thus used to enumerate the elements of List.
memberchk/2 is similar to member/2 but only succeeds once.
Errors136

8

PROLOG BUILT-IN PREDICATES

None.
Portability
GNU Prolog predicate.

8.20.3reverse/2

Templates
reverse(?list, ?list)
Description
reverse(List1, List2) succeeds if List2 unifies with the list List1 in reverse order.
Errors
None.
Portability
GNU Prolog predicate.

8.20.4delete/3, select/3

Templates
delete(?list, ?term, ?list)
select(?term, ?list, ?list)
Description
delete(List1, Element, List2) removes all occurrences of Element in List1 to provide List2. A
strict term equality is required, cf. (==)/2 (section 8.3.2, page 57).
select(Element, List1, List2) removes one occurrence of Element in List1 to provide List2. Thispredicate is re-executable on backtracking.
Errors
None.
Portability
GNU Prolog predicate.

8.20.5subtract/3

Templates
subtract(+list, +list, ?list)

8.20

List processing

137

Description
subtract(List1, List2, List3) removes all elements in List2 from List1 to provide List3. Membership is tested using memberchk/2 (section 8.20.2, page 135). The predicate runs in O(|List2| × |List1|).
Errors
None.
Portability
GNU Prolog predicate.

8.20.6

permutation/2

Templates
permutation(?list, ?list)
Description
permutation(List1, List2) succeeds if List2 is a permutation of the elements of List1. This predicate
is re-executable on backtracking.
Errors
None.
Portability
GNU Prolog predicate.

8.20.7

prefix/2, suffix/2

Templates
prefix(?list, ?list)
suffix(?list, ?list)
Description
prefix(Prefix, List) succeeds if Prefix is a prefix of List. This predicate is re-executable on backtracking.
suffix(Suffix, List) succeeds if Suffix is a suffix of List. This predicate is re-executable on backtracking.
Errors
None.
Portability
GNU Prolog predicate.

138

8

8.20.8PROLOG BUILT-IN PREDICATES

sublist/2

Templates
sublist(?list, ?list)
Description
sublist(List1, List2) succeeds if all elements of List1 appear in List2 in the same order. Thispredicate is re-executable on backtracking.
Errors
None.
Portability
GNU Prolog predicate.

8.20.9last/2

Templates
last(?list, ?term)
Description
last(List, Element) succeeds if Element is the last element of List.
Errors
None.
Portability
GNU Prolog predicate.

8.20.10flatten/2

Templates
flatten(?term, ?list)
Description
flat(List1, List2) succeeds if List2 is the flatten version of List1.
Errors
None.
Portability
GNU Prolog predicate.

8.20

List processing

8.20.11139

length/2

Templates
length(?list, ?integer)
Description
length(List, Length) succeeds if Length is the length of List.
ErrorsLength is an integer < 0domain error(not less than zero, Length)

GNU Prolog predicate.

8.20.12nth/3

Templates
nth(?integer, ?list, ?term)
Descriptionnth(N, List, Element) succeeds if the Nth argument of List is Element.
Errors
None.
Portability
GNU Prolog predicate.

8.20.13

max list/2, min list/2, sum list/2

Templates
min list(+list, ?number)
max list(+list, ?number)sum list(+list, ?number)
Description
min list(List, Min) succeeds if Min is the smallest number in List.
max list(List, Max) succeeds if Max is the largest number in List.
sum list(List, Sum) succeeds if Sum is the sum of all the elements in List.
List must be a list of arithmetic evaluable terms (section 8.6.1, page 66).
Errors140

8

PROLOG BUILT-IN PREDICATES

None.
Portability
GNU Prolog predicate.

8.20.14maplist/2-8

Templates
maplist(+callable term, +list, ..., +list)
Description
maplist(Goal, List) succeeds if Goal can succesfully be applied on all elements of List.
maplist(Goal, List1, List2) succeeds if Goal can succesfully be applied to all pairs of elements of
List1 and List2.
maplist(Goal, List1, List2, List3) succeeds if Goal can succesfully be applied to all triples of
elements of List1..List3.
maplist(Goal, List1, List2, ..., ListN ) succeeds if Goal can succesfully be applied to all N -uples(N ≤ 8) of elements of List1..ListN .
Errorsan error occurs executing a directive

see call/1 errors (section 7.2.3, page 52)

Portability
GNU Prolog predicate.

8.20.15

sort/2, msort/2, keysort/2 sort/1, msort/1, keysort/1

Templates
sort(+list, ?list)
msort(+list, ?list)
keysort(+list, ?list)
sort(+list)
msort(+list)
keysort(+list)
Descriptionsort(List1, List2) succeeds if List2 is the sorted list corresponding to List1 where duplicate elements
are merged.
msort/2 is similar to sort/2 except that duplicate elements are not merged.
keysort(List1, List2) succeeds if List2 is the sorted list of List1 according to the keys. The list
List1 consists of pairs (items of the form Key-Value). These items are sorted according to the value of8.21

Global variables

141

Key yielding the List2. Duplicate keys are not merged. This predicate is stable, i.e. if K-A occurs before
K-B in the input, then K-A will occur before K-B in the output.
sort/1, msort/1 and keysort/1 are similar to sort/2, msort/2 and keysort/2 but achieve a sort inplace destructing the original List1 (this in-place assignment is not undone at backtracking). The sorted
list occupies the same memory space as the original list (saving thus memory consumption).
The time complexity of these sorts is O(N log N ), N being the length of the list to sort.
These predicates refer to the standard ordering of terms (section 8.3.1, page 57).
ErrorsList1 is a partial list
List1 is neither a partial list nor a list
List2 is neither a partial list nor a list
for keysort/2: an element of List1 is a variablefor keysort/2: an element E of List1 is neither
a variable nor a pairfor keysort/2: an element E of List2 is neither
a variable nor a pairinstantiation error
type error(list, List1)
type error(list, List2)
instantiation error
type error(pair, E)
type error(pair, E)

Portability
sort/2 and keysort/2 are ISO predicates.
sort/1, keysort/1 and msort/1-2 are GNU Prolog predicates.

8.21

Global variables

8.21.1Introduction

GNU Prolog provides a simple and powerful way to assign and read global variables. A global variable isassociated with each atom, its initial value is the integer 0. A global variable can store 3 kinds of objects:• a copy of a term (the assignment can be made backtrackable or not).
• a link to a term (the assignment is always backtrackable).
• an array of objects (recursively).
The space necessary for copies and arrays is dynamically allocated and recovered as soon as possible. For
instance, when an atom is associated with a global variable whose current value is an array, the space forthis array is recovered (unless the assignment is to be undone when backtracking occurs).
When a link to a term is associated with a global variable, the reference to this term is stored and thus
the original term is returned when the content of the variable is read.
Global variable naming convention: a global variable is referenced by an atom.
If the variable contains an array, an index (ranging from 0) can be provided using a compound term whose
principal functor is the corresponding atom and the argument is the index. In case of a multi-dimensional
array, each index is given as the arguments of the compound term.

142

8

PROLOG BUILT-IN PREDICATES

If the variable contains a term (link or copy), it is possible to only reference a sub-term by giving its
argument number (also called argument selector). Such a sub-term is specified using a compound term
whose principal functor is -/2 and whose first argument is a global variable name and the second argument
is the argument number (from 1). This can be applied recursively to specify a sub-term of any depth. Incase of a list, a argument number I represents the Ith element of the list. In the rest of this section we
use the operator notation since - is a predefined infix operator (section 8.14.10, page 113).
In the following, GVarName represents a reference to a global variable and its syntax is as follows:
GVarName::=

Integer::=

atom
atom (Integer ,. . . ,Integer )GVarName -Integer
integer
GVarNamewhole content of a variable
element of an array
sub-term selection
immediate value
indirect value

When a GVarName is used as an index or an argument number (i.e. indirection), the value of this variablemust be an integer.
Here are some examples of the naming convention:
a
t(1)
t(k)
a-1-2

the content of variable associated with a (any kind)the 2nd element of the array associated with t
if the value associated with k is I, the Ith element of the array associated with t
if the value associated with a is f(g(a,b,c),2), the sub-term b

Here are the errors associated with global variable names and common to all predicates.
GVarName is a variable
GVarName is neither a variable nor a callable term
GVarName contains an invalid argument number(or GVarName is an array)
GVarName contains an invalid index (or GVarName
is not an array)
GVarName is used as an indirect index orargument selector and is not an integer

instantiation error
type error(callable, GVarName)
domain error(g argument selector,
GVarName)domain error(g array index, GVarName)
type error(integer, GVarName)

Arrays: the predicates g assign/2, g assignb/2 and g link/2 (section 8.21.2, page 143) can be used
to create an array. They recognize some terms as values. For instance, a compound term with principal
functor g array is used to define an array of fixed size. There are 3 forms for the term g array:• g array(Size): if Size is an integer > 0 then defines an array of Size elements which are all
initialized with the integer 0.
• g array(Size, Initial): as above but the elements are initialized with the term Initial insteadof 0. Initial can contain other array definitions allowing thus for multi-dimensional arrays.
• g array(List): as above if List is a list of length Size except that the elements of the array are
initialized according to the elements of List (which can contain other array definitions).
An array can be extended explicitly using a compound term with principal functor g array extend which
accept the same 3 forms detailed above. In that case, the existing elements of the array are not initialized.
If g array extend is used with an object which is not an array it is similar to g array.
Finally, an array can be automatically expanded when needed. The programmer does not need to
explicitly control the expansion of an automatic array. An array is expanded as soon as an index is
outside the current size of this array. Such an array is defined using a compound term with principal
functor g array auto:

8.21

Global variables

143• g array auto(Size): if Size is an integer > 0 then defines an automatic array whose initial size isSize. All elements are initialized with the integer 0. Elements created during implicit expansions
will be initialized with 0.
• g array auto(Size, Initial): as above but the elements are initialized with the term Initialinstead of 0. Initial can contain other array definitions allowing thus for multi-dimensional arrays.
Elements created during implicit expansions will be initialized with Initial.
• g array auto(List): as above if List is a list of length Size except that the elements of thearray are initialized according to the elements of List (which can contain other array definitions).
Elements created during implicit expansions will be initialized with 0.
In any case, when an array is read, a term of the form g array([Elem0,..., ElemSize-1]) is returned.
Some examples using global variables are presented later (section 8.21.7, page 146).

8.21.2

g assign/2, g assignb/2, g link/2

Templates
g assign(+callable term, ?term)g assignb(+callable term, ?term)g link(+callable term, ?term)
Description
g assign(GVarName, Value) assigns a copy of the term Value to GVarName. This assignment is notundone when backtracking occurs.
g assignb/2 is similar to g assign/2 but the assignment is undone at backtracking.
g link(GVarName, Value) makes a link between GVarName to the term Value. This allows the user togive a name to any Prolog term (in particular non-ground terms). Such an assignment is always undone
when backtracking occurs (since the term may no longer exist). If Value is an atom or an integer,g link/2 and g assignb/2 have the same behavior. Since g link/2 only handles links to existing terms
it does not require extra memory space and is not expensive in terms of execution time.
NB: argument selectors can only be used with g assign/2 (i.e. when using an argument selector inside anassignment, this one must not be backtrackable).
ErrorsSee common errors detailed in the introduction (section 8.21.1, page 141)
GVarName contains an argument selector and theassignment is backtrackable
Portability
GNU Prolog predicates.

8.21.3g read/2

Templates

domain error(g argument selector,
GVarName)

144

8

PROLOG BUILT-IN PREDICATES

g read(+callable term, ?term)
Description
g read(GVarName, Value) unifies Value with the term assigned to GVarName.
ErrorsSee common errors detailed in the introduction (section 8.21.1, page 141)
Portability
GNU Prolog predicate.

8.21.4g array size/2

Templatesg array size(+callable term, ?integer)
Description
g array size(GVarName, Value) unifies Size with the dimension (an integer > 0) of the array assigned
to GVarName. Fails if GVarName is not an array.
ErrorsSee common errors detailed in the introduction (section 8.21.1, page 141)
Size is neither a variable nor an integer

type error(integer, Size)

Portability
GNU Prolog predicate.

8.21.5g inc/3, g inc/2, g inco/2, g inc/1, g dec/3, g dec/2, g deco/2, g dec/1

Templatesg inc(+callable term, ?integer, ?integer)g inc(+callable term, ?integer)g inco(+callable term, ?integer)g inc(+callable term)g dec(+callable term, ?integer, ?integer)g dec(+callable term, ?integer)g deco(+callable term, ?integer)g dec(+callable term)
Description
g inc(GVarName, Old, New) unifies Old with the integer assigned to GVarName, increments GVarName
and then unifies New with the incremented value.

8.21

Global variables

145

g inc(GVarName, New) is equivalent to g inc(GVarName, , New).
g inco(GVarName, Old) is equivalent to g inc(GVarName, Old, ).
g inc(GVarName) is equivalent to g inc(GVarName, , ).
Predicates g dec are similar but decrement the content of GVarName instead.
ErrorsSee common errors detailed in the introduction (section 8.21.1, page 141)
Old is neither a variable nor an integer
New is neither a variable nor an integer
GVarName stores an array
GVarName stores a term T which is not an integer

type error(integer, Old)
type error(integer, New)
type error(integer, g array)
type error(integer, T)

Portability
GNU Prolog predicates.

8.21.6g set bit/2, g reset bit/2, g test set bit/2, g test reset bit/2

Templates
g set bit(+callable term, +integer)g reset bit(+callable term, +integer)g test set bit(+callable term, +integer)g test reset bit(+callable term, +integer)
Description
g set bit(GVarName, Bit) sets to 1 the bit number specified by Bit of the integer assigned to GVarName
to 1. Bit numbers range from 0 to the maximum number allowed for integers (this is architecture
dependent). If Bit is greater than this limit, the modulo with this limit is taken.
g reset bit(GVarName, Bit) is similar to g set bit/2 but sets the specified bit to 0.
g test set bit/2 succeeds if the specified bit is set to 1.
g test reset bit/2 succeeds if the specified bit is set to 0.
ErrorsSee common errors detailed in the introduction (section 8.21.1, page 141)
Bit is a variable
Bit is neither a variable nor an integer
Bit is an integer < 0
GVarName stores an array
GVarName stores a term T which is not an integer
Portability

instantiation error
type error(integer, Bit)
domain error(not less than zero, Bit)
type error(integer, g array)
type error(integer, T)

146

8

PROLOG BUILT-IN PREDICATES

GNU Prolog predicates.

8.21.7

ExamplesSimulating g inc/3: this predicate behaves like: global variable:
my_g_inc(Var, Old, New) :g_read(Var, Old),
N is Value + 1,
g_assign(Var, X),
New = N.
The query: my g inc(c, X, ) will succeed unifying X with 0, another call to my g inc(a, Y, ) willthen unify Y with 1, and so on.
Difference between g assign/2 and g assignb/2: g assign/2 does not undo its assignment whenbacktracking occurs whereas g assignb/2 undoes it.
test(Old) :g assign(x,1),(
g read(x, Old),g assign (x, 2);g read(x, Old),g assign(x, 3)).

testb(Old) :g assign(x,1),(
g read(x, Old),g assignb (x, 2);g read(x, Old),g assign(x, 3)).

The query test(Old) will succeed unifying Old with 1 and on backtracking with 2 (i.e. the assignmentof the value 2 has not been undone). The query testb(Old) will succeed unifying Old with 1 and on
backtracking with 1 (i.e. the assignment of the value 2 has been undone).
Difference between g assign/2 and g link/2: g assign/2 (and g assignb/2) creates a copy of
the term whereas g link/2 does not. g link/2 can be used to avoid passing big data structures (e.g.
dictionaries,. . . ) as arguments to predicates.
test(B) :g assign (b, f(X)),
X = 12,g read(b, B).

test(B) :g link (b, f(X)),
X = 12,g read(b, B).

The query test(B) will succeed unifying B with f( ) (g assign/2 assigns a copy of the value). The
query test(B) will succeed unifying B with f(12) (g link/2 assigns a pointer to the term).
Simple array definition: here are some queries to show how arrays can be handled:| ?- g_assign(w, g_array(3)), g_read(w, X).
X = g_array([0,0,0])| ?- g_assign(w(0), 16), g_assign(w(1), 32), g_assign(w(2), 64), g_read(w, X).
X = g_array([16,32,64])
this is equivalent to:| ?- g_assign(k, g_array([16,32,64])), g_read(k, X).

8.21

Global variables

X = g_array([16,32,64])| ?- g_assign(k, g_array(3,null)), g_read(k, X), g_array_size(k, S).
S = 3
X = g_array([null,null,null])
2-D array definition:| ?- g_assign(w, g_array(2, g_array(3))), g_read(w, X).
X = g_array([g_array([0,0,0]),g_array([0,0,0])])| ?- (;).

for(I,0,1), for(J,0,2), K is I*3+J, g_assign(w(I,J), K),
failg_read(w, X)

X = g_array([g_array([0,1,2]),g_array([3,4,5])])| ?- g_read(w(1),X).
X = g_array([3,4,5])Hybrid array:| ?- g_assign(w,g_array([1,2,g_array([a,b,c]), g_array(2,z),5])), g_read(w, X).
X = g_array([1,2,g_array([a,b,c]), g_array([z,z]),5])| ?- g_read(w(1), X), g_read(w(2,1), Y), g_read(w(3,1), Z).
X = 2
Y = b
Z = z
| ?- g_read(w(1,2),X).
uncaught exception: error(domain_error(g_array_index,w(1,2)),g_read/2)
Array extension:| ?- g_assign(a, g_array([10,20,30])), g_read(a, X).
X = g_array([10,20,30])| ?- g_assign(a, g_array_extend(5,null)), g_read(a, X).
X = g_array([10,20,30,null,null])| ?- g_assign(a, g_array([10,20,30])), g_read(a, X).
X = g_array([10,20,30])| ?- g_assign(a, g_array_extend([1,2,3,4,5,6])), g_read(a, X).
X = g_array([10,20,30,4,5,6])
Automatic array:

147

148

8

PROLOG BUILT-IN PREDICATES| ?- g_assign(t, g_array_auto(3)), g_assign(t(1), foo), g_read(t,X).
X = g_array([0,foo,0])| ?- g_assign(t(5), bar), g_read(t,X).
X = g_array([0,foo,0,0,0,bar,0,0])| ?- g_assign(t, g_array_auto(2, g_array(2))), g_assign(t(1,1), foo),g_read(t,X).
X = g_array([g_array([0,0]),g_array([0,foo])])| ?- g_assign(t(3,0), bar), g_read(t,X).
X = g_array([g_array([0,0]),g_array([0,foo]),g_array([0,0]),g_array([bar,0])])| ?- g_assign(t(3,4), bar), g_read(t,X).
uncaught exception: error(domain_error(g_array_index,t(3,4)),g_assign/2)| ?- g_assign(t, g_array_auto(2, g_array_auto(2))), g_assign(t(1,1), foo),g_read(t,X).
X = g_array([g_array([0,0]),g_array([0,foo])])| ?- g_assign(t(3,3), bar), g_read(t,X).
X = g_array([g_array([0,0]),g_array([0,foo]),g_array([0,0]),g_array([0,0,0,bar])])| ?- g_assign(t, g_array_auto(2, g_array_auto(2, null))), g_read(t(2,3), U),
g_read(t, X).
U = null
X = g_array([g_array([null,null]),g_array([null,null]),g_array([null,null,null,null]),g_array([null,null])])8.22

Prolog state

8.22.1

set prolog flag/2

Templates
set prolog flag(+flag, +term)
Description
set prolog flag(Flag, Value) sets the value of the Prolog flag Flag to Value.
Prolog flags: a Prolog flag is an atom which is associated with a value that is either implementation defined or defined by the user. Each flag has a permitted range of values; any other value is a domain error.
The following two tables present available flags, the possible values, a description and if they are ISO or
an extension. The first table presents unchangeable flags while the second one the changeable flags. For

8.22

Prolog state149

flags whose default values is machine independent, this value is underlined.
Unchangeable flags:
Flagprolog nameprolog version
prolog date
prolog copyright
dialect
versionversion databoundedmax integer
min integer

max arity
max atommax unget
home
host os
host vendor
host cpu
hostarch
address bits
unix

Valuesan atoman atoman atoman atoman atoman integera structure
true / false
an integer
an integer
toward zerodown
an integer
an integer
an integer
an atoman atoman atoman atoman atoman atoman integer
on/offcompiled at

an atomc cc

an atom

integer rounding function

c cc version datac cflags
c ldflags
argv
Changeable flags:a structure
an atoman atoma list of atoms

Description
name of the Prolog systemversion number of the Prolog systemdate of the Prolog system
copyright message of the Prolog system
fixed to gprolog
M ajor ∗ 10000 + M inor ∗ 100 + P atch
gprolog(Major,Minor,Patch,Extra)
are integers bounded ?
greatest integer
smallest integer
rnd (X) = integer part of X
rnd (X) = bXc (section 8.6.1, page 66)
maximum arity for compound terms (255)maximum number of atoms
maximum number of successive ungets
GNU Prolog home directory
Operating System identifier
Operating System vendor
processor identifier
a combination of the OS-vendor-cpu
a combination of the OS-cpu
address size of the machine (32 or 64)
is the architecture an Unix-like OS ?
compilation date using DATE and
TIME C compiler macros
C compiler used to compile GNU Prolog(gcc, cc, clang, cl,...)
c cc (Major,Minor,Patch,Extra)
CFLAGS used to compile GNU Prolog
LDFLAGS used to compile GNU Prolog
list of command-line arguments

ISO
N
N
N
N
N
N
N
Y
Y
Y
Y
Y
N
N
N
N
N
N
N
N
N
N
N
N
N
N
N
N

150

8

Flag
char conversion
singleton warning
suspicious warning

Valueson / offon / offon / off

multifile warning

on / offstrict iso
debug

on / offon / off

double quotes

back quotes

atom
chars
codes
atom no escapechars no escapecodes no escape
atom
chars
codes
atom no escapechars no escapecodes no escapeunknownerror
warningfailsyntax error

error
warningfailos errorerror
warning
fail

PROLOG BUILT-IN PREDICATES

Description
is character conversion activated ?
warn about named singleton variables ?
warn about suspicious predicate ?
warn about unsupported multifile
directive ?
strict ISO behavior ?
is the debugger activated ?
a double quoted constant is returned as:
an atoma list of charactersa list of character codes
as atom but ignore escape sequences
as chars but ignore escape sequences
as code but ignore escape sequencesa back quoted constant is returned as:
an atoma list of charactersa list of character codes
as atom but ignore escape sequences
as chars but ignore escape sequences
as code but ignore escape sequencesa predicate calls an unknown procedure:an existence error is raised
a message is displayed then fails
quietly fails
a predicate causes a syntax error:
a syntax error is raised
a message is displayed then fails
quietly fails
a predicate causes an O.S. error:a system error is raised
a message is displayed then fails
quietly fails

ISO
Y
N
N
N
N
Y

Y

N

N

Y

N

N

The strict iso flag is introduced to allow a compatibility with other Prolog systems. When turned off
the following relaxations apply:• built-in predicates are found by current predicate/1 (section 8.8.1, page 74).
• the term parser (read/1 and friends) is more indulgent, e.g. 0’’ is accepted and returns 39, theescape sequence \s (space) and \e (escape) are accepted.
• the following arithmetic rounding functions: ceiling, floor, round, truncate also accept integers(section 8.6.1, page 66).
ErrorsFlag is a variable
Value is a variable
Flag is neither a variable nor an atom
Flag is an atom but not a valid flag
Value is inappropriate for Flag
Value is appropriate for Flag but flag Flag is
not modifiableinstantiation error
instantiation error
type error(atom, Flag)
domain error(prolog flag, Flag)
domain error(flag value, Flag+Value)
permission error(modify, flag, Flag)

8.22

Prolog state

151

Portability
ISO predicate. All ISO flags are implemented.

8.22.2current prolog flag/2

Templates
current prolog flag(?flag, ?term)
Description
current prolog flag(Flag, Value) succeeds if there exists a Prolog flag that unifies with Flag andwhose value unifies with Value. This predicate is re-executable on backtracking.
ErrorsFlag is neither a variable nor an atom
Flag is an atom but not a valid flag

type error(atom, Flag)
domain error(prolog flag, Flag)

Portability
ISO predicate.

8.22.3

set bip name/2

Templates
set bip name(+atom, +arity)
Description
set bip name(Functor, Arity) initializes the context of the error (section 6.3.1, page 39) with Functor
and Arity (if Arity < 0 only Functor is significant).
ErrorsFunctor is a variable
Arity is a variable
Functor is neither a variable nor an atom
Arity is neither a variable nor an integer
Portability
GNU Prolog predicate.

8.22.4current bip name/2

Templates
current bip name(?atom, ?arity)

instantiation error
instantiation error
type error(atom, Functor)
type error(integer, Arity)

152

8

PROLOG BUILT-IN PREDICATES

Description
current bip name(Functor, Arity) succeeds if Functor and Arity correspond to the context of theerror (section 6.3.1, page 39) (if Arity < 0 only Functor is significant).
ErrorsFunctor is neither a variable nor an atom
Arity is neither a variable nor an integer

type error(atom, Functor)
type error(integer, Arity)

Portability
GNU Prolog predicate.

8.22.5

write pl state file/1, read pl state file/1

Templates
write pl state file(+source sink)read pl state file(+source sink)
Description
write pl state file(FileName) writes onto FileName all information that influences the parsing of aterm (section 8.14, page 104). This allows a sub-process written in Prolog to read this file and thenprocess any Prolog term as done by the parent process. This file can also be passed as argument of the--pl-state option when invoking gplc (section 4.4.3, page 23). More precisely the following elements
are saved:• all operator definitions (section 8.14.10, page 113).
• the character conversion table (section 8.14.12, page 116).
• the value of char conversion, double quotes, back quotes, singleton warning, suspicious warningand multifile warning Prolog flags (section 8.22.1, page 148).
read pl state file(FileName) reads (restores) from FileName all information previously saved by
write pl state file/1.
ErrorsFileName is a variable
FileName is neither a variable nor an atom
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicate.

instantiation error
type error(atom, FileName)system error(atom explaining the error )8.23

Program state

8.23

Program state

8.23.1

consult/1, ’.’/2 - program consult

153

Templates
consult(+atom or atom list)’.’(+atom, +atom list)
Description
consult(Files) compiles and loads into memory each file of the list Files. Each file is compiled forbyte-code using the GNU Prolog compiler (section 4.4, page 21) then loaded using load/1 (section 8.23.2,
page 153). It is possible to specify user as a file name to directly enter the program from the terminal.
Files can be also a single file name (i.e. an atom). Refer to the section concerning the consult of a
Prolog program for more information (section 4.2.3, page 17).
The final file name of a file is computed using the predicates prolog file name/2 (section 8.26.4,
page 159) and absolute file name/2 (section 8.26.1, page 158).
[ File | Files ], i.e. ’.’(File, Files) is equivalent to consult([ File | Files ]).
Since version 1.4.0, with the introduction of shebang support, consult/1 ignores the first line of a Prolog
source file which directly begins with #. See (section 4.2.4, page 18) for more information about shebang
support and PrologScript.
ErrorsFiles is a partial list or a list with an element E
which is a variable
Files is neither a partial list nor a list nor anatom
an element E of the Files list is neither avariable nor an atom
an element E of the Files list is an atom but nota valid pathname
an element E of the Files list is a valid
pathname but does not correspond to an existingsourcean error occurs executing a directive
Portability
GNU Prolog predicates.

8.23.2

load/1

Templatesload(+atom or atom list)
Description

instantiation error
type error(list, Files)
type error(atom, E)
domain error(os path, E)
existence error(source sink, E)
see call/1 errors (section 7.2.3, page 52)

154

8

PROLOG BUILT-IN PREDICATES

load(Files) loads into memory each file of the list Files. Each file must have been previously compiled
for byte-code using the GNU Prolog compiler (section 4.4, page 21). Files can be also a single file name(i.e. an atom).
The final file name of a file is computed using the predicates absolute file name/2 (section 8.26.1,
page 158). If no suffix is given ’.wbc’ is appended to the file name.
ErrorsFiles is a partial list or a list with an element E
which is a variable
Files is neither a partial list nor a list nor anatom
an element E of the Files list is neither avariable nor an atom
an element E of the Files list is an atom but nota valid pathname
an element E of the Files list is a valid
pathname but does not correspond to an existingsourcean error occurs executing a directive

instantiation error
type error(list, Files)
type error(atom, E)
domain error(os path, E)
existence error(source sink, E)
see call/1 errors (section 7.2.3, page 52)

Portability
GNU Prolog predicate.

8.23.3

listing/1, listing/0

Templates
listing(+predicate indicator)
listing(+atom)
listing
Description
listing(Pred) lists the clauses of the consulted predicate whose predicate indicator is Pred. Pred canalso be a single atom in which case all predicates whose name is Pred are listed (of any arity). Thispredicate uses portray clause/2 (section 8.14.8, page 112) to output the clauses.
listing lists all clauses of all consulted predicates.
ErrorsPred is a variable
Pred is neither a variable nor predicate indicatoror an atom
Portability
GNU Prolog predicate.

instantiation error
type error(predicate indicator, Pred)

8.24

System statistics

8.24

System statistics

8.24.1statistics/0, statistics/2

155

Templates
statistics
statistics(?atom, ?list)
Description
statistics displays statistics about memory usage and run times.
statistics(Key, Value) unifies Value with the current value of the statistics key Key. Value a list of
two elements. Times are in milliseconds, sizes of areas in bytes.
Keyuser timesystem time
cpu time
real time
local stackglobal stacktrail stack
cstr stackatoms

Descriptionuser CPU timesystem CPU time
total CPU time (user + system)
absolute time
local stack sizes (control, environments, choices)global stack sizes (compound terms)
trail stack sizes (variable bindings to undo)
constraint trail sizes (finite domain constraints)
atom table

Value[SinceStart, SinceLast][SinceStart, SinceLast][SinceStart, SinceLast][SinceStart, SinceLast][UsedSize, FreeSize][UsedSize, FreeSize][UsedSize, FreeSize][UsedSize, FreeSize][NumberOfAtoms, FreeNumberOfAtoms]

Note that the key runtime is recognized as user time for compatibility purpose.
ErrorsKey is neither a variable nor a valid key
Value is neither a variable nor a list of twoelements
Value is a list of two elements and an element E
is neither a variable nor an integer

domain error(statistics key, Key)domain error(statistics value, Value)
type error(integer, E)

Portability
GNU Prolog predicates.

8.24.2user time/1, system time/1, cpu time/1, real time/1

Templates
user time(?integer)system time(?integer)
cpu time(?integer)
real time(?integer)
Descriptionuser time(Time) unifies Time with the user CPU time elapsed since the start of Prolog.

156

8

PROLOG BUILT-IN PREDICATES

system time(Time) unifies Time with the system CPU time elapsed since the start of Prolog.
cpu time(Time) unifies Time with the CPU time (user + system) elapsed since the start of Prolog.
real time(Time) unifies Time with the absolute time elapsed since the start of Prolog.
ErrorsTime is neither a variable nor an integer

type error(integer, Time)

Portability
GNU Prolog predicates.

8.25

Random number generator

8.25.1

set seed/1, randomize/0

Templates
set seed(+integer)
randomizeDescription
set seed(Seed) reinitializes the random number generator seed with Seed.
randomize reinitializes the random number generator. This predicates calls set seed/1 with a random
value depending on the absolute time.
ErrorsSeed is a variable
Seed is neither a variable nor an integer
Seed is an integer < 0instantiation error
type error(integer, Seed)domain error(not less than zero, Seed)

Portability
GNU Prolog predicates.

8.25.2get seed/1

Templates
get seed(?integer)
Description
get seed(Seed) unifies Seed with the current random number generator seed.
Errors

8.25

Random number generator

Seed is neither a variable nor an integer
Seed is an integer < 0157

type error(integer, Seed)domain error(not less than zero, Seed)

Portability
GNU Prolog predicate.

8.25.3

random/1

Templates
random(-float)
Description
random(Number) unifies Number with a random floating point number such that 0.0 ≤ Number < 1.0.
ErrorsNumber is not a variable

uninstantiation error(Number)

Portability
GNU Prolog predicate.

8.25.4

random/3

Templates
random(+number, +number, -number)
Description
random(Base, Max, Number) unifies Number with a random number such that Base ≤ Number < Max.
If both Base and Max are integers Number will be an integer, otherwise Number will be a floating point
number.
ErrorsBase is a variable
Base is neither a variable nor a number
Max is a variable
Max is neither a variable nor a number
Number is not a variable
Portability
GNU Prolog predicate.

instantiation error
type error(number, Base)instantiation error
type error(number, Max)
uninstantiation error(Number)

158

8

8.26

File name processing

8.26.1absolute file name/2

PROLOG BUILT-IN PREDICATES

Templates
absolute file name(+atom, atom)
Description
absolute file name(File1, File2) succeeds if File2 is the absolute pathname associated with the relative file name File1. File1 can contain $VAR NAME sub-strings. When such a sub-string is encountered,
it is expanded with the value of the environment variable whose name is VAR NAME if exists (otherwise
no expansion is done). File1 can also begin with a sub-string ~USER NAME /, this is expanded as thehome directory of the user USER NAME . If USER NAME does not exist File1 is an invalid pathname. If no
USER NAME is given (i.e. File1 begins with ~/) the ~ character is expanded as the value of the environment variable HOME. If the HOME variable is not defined File1 is an invalid pathname. Relative references
to the current directory (/./ sub-string) and to the parent directory (/../ sub-strings) are removed andno longer appear in File2. File1 is also invalid if it contains too many /../ consecutive sub-strings(i.e. parent directory relative references). Finally if File1 is user then File2 is also unified with user
to allow this predicate to be called on Prolog file names (since user in DEC-10 input/output predicates
denotes the current input/output stream).
Under Windows the following applies:• an alternate recognized form for $VAR NAME is %VAR NAME %.
• when ~ is expanded, if the HOME variable is not defined, ~ is expanded using HOMEDIR and HOMEPATH(if HOMEPATH is not defined then File1 is an invalid pathname).
Most predicates using a file name implicitly call this predicate to obtain the desired file, e.g. open/4.
ErrorsFile1 is a variable
File1 is neither a variable nor an atom
File2 is neither a variable nor an atom
File1 is an atom but not a valid pathname

instantiation error
type error(atom, File1)
type error(atom, File2)
domain error(os path, File1)

Portability
GNU Prolog predicate.

8.26.2is absolute file name/1, is relative file name/1

Templates
is absolute file name(+atom)
is relative file name(+atom)
Description
is absolute file name(PathName) succeeds if PathName is an absolute file name.

8.26

File name processing

159

Conversely, is relative file name(PathName) succeeds if PathName is not an absolute file name.
See absolute file name/2 for information about the syntax of PathName (section 8.26.1, page 158).
The current implementation does not check the validity of PathName. If PathName starts with a / (slash)it is considered as absolute. Under Windows, PathName can also start with a \ (backslash) or a drive
specification.
ErrorsPathName is a variable
PathName is neither a variable nor an atom

instantiation error
type error(atom, PathName)

Portability
GNU Prolog predicates.

8.26.3decompose file name/4

Templates
decompose file name(+atom, ?atom, ?atom, ?atom)
Description
decompose file name(File, Directory, Prefix, Suffix) decomposes the pathname File and extracts the Directory part (characters before the last /), the Prefix part (characters after the last / andbefore the last . or until the end if there is no suffix) and the Suffix part (characters from the last . tothe end of the string).
ErrorsFile is a variable
File is neither a variable nor an atom
Directory is neither a variable nor an atom
Prefix is neither a variable nor an atom
Suffix is neither a variable nor an atom

instantiation error
type error(atom, File)type error(atom, Directory)
type error(atom, Prefix)
type error(atom, Suffix)

Portability
GNU Prolog predicate.

8.26.4

prolog file name/2

Templates
prolog file name(+atom, ?atom)
Description
prolog file name(File1, File2) unifies File2 with the Prolog file name associated with File1. Moreprecisely File2 is computed as follows:• if File1 has a suffix or if it is user then File2 is unified with File1.

160

8

PROLOG BUILT-IN PREDICATES• else if the file whose name is File1 + ’.pl’ exists then File2 is unified with this name.
• else if the file whose name is File1 + ’.pro’ exists then File2 is unified with this name.
• else if the file whose name is File1 + ’.prolog’ exists then File2 is unified with this name.
• else File2 is unified with the name File1 + ’.pl’.
This predicate uses absolute file name/2 to check the existence of a file (section 8.26.1, page 158).
ErrorsFile1 is a variable
File1 is neither a variable nor an atom
File2 is neither a variable nor an atom
File1 is an atom but not a valid pathname

instantiation error
type error(atom, File1)
type error(atom, File2)
domain error(os path, File1)

Portability
GNU Prolog predicate.

8.27

Operating system interface

8.27.1

argument counter/1

Templatesargument counter(?integer)
Description
argument counter(Counter) succeeds if Counter is the number of arguments of the command-line. Since
the first argument is always the name of the running program, Counter is always ≥ 1. See (section 4.2,
page 13) for more information about command-line arguments retrieved under the top level.
ErrorsCounter is neither a variable nor an integer

type error(integer, Counter)

Portability
GNU Prolog predicate.

8.27.2argument value/2

Templatesargument value(+integer, ?atom)
Description
argument value(N, Arg) succeeds if the Nth argument on the command-line unifies with Arg. The firstargument is always the name of the running program and its number is 0. The number of arguments on
the command-line can be obtained using argument counter/1 (section 8.27.1, page 160).

8.27

Operating system interface

161

ErrorsN is a variable
N is neither a variable nor an integer
N is an integer < 0
Arg is neither a variable nor an atom

instantiation error
type error(integer, N)
domain error(not less than zero, N)
type error(atom, Arg)

Portability
GNU Prolog predicate.

8.27.3argument list/1

Templatesargument list(?list)
Description
argument list(Args) succeeds if Args unifies with the list of atoms associated with each argument on
the command-line other than the first argument (the name of the running program).
ErrorsArgs is neither a partial list nor a list

type error(list, Args)

Portability
GNU Prolog predicate.

8.27.4

environ/2

Templates
environ(?atom, ?atom)
Description
environ(Name, Value) succeeds if Name is the name of an environment variable whose value is Value.
This predicate is re-executable on backtracking.
ErrorsName is neither a variable nor an atom
Value is neither a variable nor an atom
Portability
GNU Prolog predicate.

type error(atom, Name)
type error(atom, Value)

162

8

8.27.5PROLOG BUILT-IN PREDICATES

make directory/1, delete directory/1, change directory/1

Templates
make directory(+atom)
delete directory(+atom)change directory(+atom)
Description
make directory(PathName) creates the directory whose pathname is PathName.
delete directory(PathName) removes the directory whose pathname is PathName.
change directory(PathName) sets the current directory to the directory whose pathname is PathName.
See absolute file name/2 for information about the syntax of PathName (section 8.26.1, page 158).
ErrorsPathName is a variable
PathName is neither a variable nor an atom
PathName is an atom but not a valid pathname
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(atom, PathName)
domain error(os path, PathName)system error(atom explaining the error )Portability
GNU Prolog predicates.

8.27.6working directory/1

Templates
working directory(?atom)
Description
working directory(PathName) succeeds if PathName is the pathname of the current directory.
ErrorsPathName is neither a variable nor an atom
Portability
GNU Prolog predicate.

8.27.7

directory files/2

Templates

type error(atom, PathName)

8.27

Operating system interface

163

directory files(+atom, ?list)
Description
directory files(PathName, Files) succeeds if Files is the list of all entries (files, sub-directories,. . . )in the directory whose pathname is PathName. See absolute file name/2 for information about thesyntax of PathName (section 8.26.1, page 158).
ErrorsPathName is a variable
PathName is neither a variable nor an atom
PathName is an atom but not a valid pathname
Files is neither a partial list nor a list
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(atom, PathName)
domain error(os path, PathName)
type error(list, Files)
system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.8rename file/2

Templates
rename file(+atom, +atom)
Description
rename file(PathName1, PathName2) renames the file or directory whose pathname is PathName1 to
PathName2. See absolute file name/2 for information about the syntax of PathName1 and PathName2(section 8.26.1, page 158).
ErrorsPathName1 is a variable
PathName1 is neither a variable nor an atom
PathName1 is an atom but not a valid pathname
PathName2 is a variable
PathName2 is neither a variable nor an atom
PathName2 is an atom but not a valid pathname
an operating system error occurs and value ofthe os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicate.

8.27.9delete file/1, unlink/1

Templates

instantiation error
type error(atom, PathName1)
domain error(os path, PathName1)
instantiation error
type error(atom, PathName2)
domain error(os path, PathName2)
system error(atom explaining the error )

164

8

PROLOG BUILT-IN PREDICATES

delete file(PathName)
unlink(PathName)
Description
delete file(PathName) removes the existing file whose pathname is PathName.
unlink/1 is similar to delete file/1 except that it never causes a system error (e.g. if PathName does
not refer to an existing file).
See absolute file name/2 for information about the syntax of PathName (section 8.26.1, page 158).
ErrorsPathName is a variable
PathName is neither a variable nor an atom
PathName is an atom but not a valid pathname
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(atom, PathName)
domain error(os path, PathName)system error(atom explaining the error )Portability
GNU Prolog predicates.

8.27.10

file permission/2, file exists/1

Templates
file permission(+atom, +atom)
file permission(+atom, +atom list)
file exists(+atom)
Description
file permission(PathName, Permission) succeeds if PathName is the pathname of an existing file (ordirectory) whose permissions include Permission.
File permissions: Permission can be a single permission or a list of permissions. A permission is anatom among:• read: the file or directory can be read.
• write: the file or directory can be written.
• execute: the file can be executed.
• search: the directory can be searched.
If PathName does not exists or if its permissions do not include Permission this predicate fails.
file exists(PathName) is equivalent to file permission(PathName, []), i.e. it succeeds if PathNameis the pathname of an existing file (or directory).
See absolute file name/2 for information about the syntax of PathName (section 8.26.1, page 158).

8.27

Operating system interface

165

ErrorsPathName is a variable
PathName is neither a variable nor an atom
PathName is an atom but not a valid pathname
Permission is a partial list or a list with anelement which is a variable
Permission is neither an atom nor partial list or
a listan element E of the Permission list is neither avariable nor an atom
an element E of the Permission is an atom but
not a valid permission
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(atom, PathName)
domain error(os path, PathName)
instantiation error
type error(list, Permission)
type error(atom, E)
domain error(os file permission,
Permission)
system error(atom explaining the error )Portability
GNU Prolog predicates.

8.27.11

file property/2

Templates
file property(+atom, ?os file property)
Description
file property(PathName, Property) succeeds if PathName is the pathname of an existing file (or directory) and if Property unifies with one of the properties of the file. This predicate is re-executable on
backtracking.
File properties:• absolute file name(File): File is the absolute file name of PathName (section 8.26.1, page 158).
• real file name(File): File is the real file name of PathName (follows symbolic links).
• type(Type): Type is the type of PathName. Possible values are: regular, directory, fifo, socket,
character device, block device or unknown.
• size(Size): Size is the size (in bytes) of PathName.
• permission(Permission): Permission is a permission of PathName (section 8.27.10, page 164).
• last modification(DT): DT is the last modification date and time (section 8.27.14, page 167).
See absolute file name/2 for information about the syntax of PathName (section 8.26.1, page 158).
Errors166

8

PathName is a variable
PathName is neither a variable nor an atom
PathName is an atom but not a valid pathname
Property is neither a variable nor a file property
term
Property = absolute file name(E),real file name(E), type(E) or permission(E)and E is neither a variable nor an atom
Property = last modification(DateTime)and DateTime is neither a variable nor acompound term
Property = last modification(DateTime)and DateTime is a compound term but not a
structure dt/6
Property = size(E) or
last modification(DateTime) and DateTime isa structure dt/6 but an element E is neither avariable nor an integer
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

PROLOG BUILT-IN PREDICATES

instantiation error
type error(atom, PathName)
domain error(os path, PathName)
domain error(os file property, Property)
type error(atom, E)

type error(compound, DateTime)domain error(date time, DateTime)type error(integer, E)

system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.12

temporary name/2

Templates
temporary name(+atom, ?atom)
Description
temporary name(Template, PathName) creates a unique file name PathName whose pathname begins by
Template. Template should contain a pathname with six trailing Xs. PathName is Template with the six
Xs replaced with a letter and the process identifier. This predicate is an interface to the C Unix function
mktemp(3).
See absolute file name/2 for information about the syntax of Template (section 8.26.1, page 158).
ErrorsTemplate is a variable
Template is neither a variable nor an atom
Template is an atom but not a valid pathname
PathName is neither a variable nor an atom
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicate.

instantiation error
type error(atom, Template)domain error(os path, Template)
type error(atom, PathName)system error(atom explaining the error )8.27

Operating system interface

8.27.13167

temporary file/3

Templates
temporary file(+atom, +atom, ?atom)
Description
temporary file(Directory, Prefix, PathName) creates a unique file name PathName whose pathname
begins by Directory/Prefix. If Directory is the empty atom ’’ a standard temporary directory will
be used (e.g. /tmp). Prefix can be the empty atom ’’. This predicate is an interface to the C Unix
function tempnam(3).
See absolute file name/2 for information about the syntax of Directory (section 8.26.1, page 158).
ErrorsDirectory is a variable
Directory is neither a variable nor an atom
Directory is an atom but not a valid pathname
Prefix is a variable
Prefix is neither a variable nor an atom
PathName is neither a variable nor an atom
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(atom, Directory)
domain error(os path, Directory)
instantiation error
type error(atom, Prefix)
type error(atom, PathName)system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.14date time/1

Templates
date time(?compound)
Description
date time(DateTime) unifies DateTime with a compound term containing the current date and time.
DateTime is a structure dt(Year, Month, Day, Hour, Minute, Second). Each sub-argument of theterm dt/6 is an integer.
Errors
DateTime is neither a variable nor a compoundterm
DateTime is a compound term but not a
structure dt/6
DateTime is a structure dt/6 and an element E isneither a variable nor an integer
Portability
GNU Prolog predicate.

type error(compound, DateTime)domain error(date time, DateTime)type error(integer, E)

168

8

8.27.15

PROLOG BUILT-IN PREDICATES

host name/1

Templates
host name(?atom)
Description
host name(HostName) unifies HostName with the name of the host machine executing the current GNU
Prolog process. If the sockets are available (section 8.28.1, page 176), the name returned will be fully
qualified. In that case, host name/1 will also succeed if HostName is instantiated to the unqualified name(or an alias) of the machine.
ErrorsHostName is neither a variable nor an atom
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

type error(atom, HostName)system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.16

os version/1

Templates
os version(?atom)
Description
os version(OSVersion) unifies OSVersion with the operating system version of the machine executing
the current GNU Prolog process.
ErrorsOSVersion is neither a variable nor an atom
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicate.

8.27.17architecture/1

Templates
architecture(?atom)
Description

type error(atom, OSVersion)
system error(atom explaining the error )8.27

Operating system interface

169

architecture(Architecture) unifies Architecture with the name of the machine executing the current
GNU Prolog process.
ErrorsArchitecture is neither a variable nor an atom
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

type error(atom, Architecture)system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.18

shell/2, shell/1, shell/0

Templates
shell(+atom, ?integer)
shell(+atom)shell
Description
shell(Command, Status) invokes a new shell (named by the SHELL environment variable) passing
Command for execution and unifies Status with the result of the execution. If Command is the empty
atom ’’ a new interactive shell is executed. The control is returned to Prolog upon termination of thecalled process.
shell(Command) is equivalent to shell(Command, 0).
shell is equivalent to shell(’’, 0).
ErrorsCommand is a variable
Command is neither a variable nor an atom
Status is neither a variable nor an integer

instantiation error
type error(atom, Command)
type error(integer, Status)

Portability
GNU Prolog predicates.

8.27.19

system/2, system/1

Templates
system(+atom, ?integer)system(+atom)
Description
system(Command, Status) invokes a new default shell passing Command for execution and unifies Status

170

8

PROLOG BUILT-IN PREDICATES

with the result of the execution. The control is returned to Prolog upon termination of the shell process.
This predicate is an interface to the C Unix function system(3).
system(Command) is equivalent to system(Command, 0).
ErrorsCommand is a variable
Command is neither a variable nor an atom
Status is neither a variable nor an integer

instantiation error
type error(atom, Command)
type error(integer, Status)

Portability
GNU Prolog predicates.

8.27.20

spawn/3, spawn/2

Templates
spawn(+atom, +atom list, ?integer)
spawn(+atom, +atom list)
Description
spawn(Command, Arguments, Status) executes Command passing as arguments of the command-line eachelement of the list Arguments and unifies Status with the result of the execution. The control is returned
to Prolog upon termination of the command.
spawn(Command, Arguments) is equivalent to spawn(Command, Arguments, 0).
ErrorsCommand is a variable
Command is neither a variable nor an atom
Arguments is a partial list or a list with anelement which is a variable
Arguments is neither a partial list nor a list
an element E of the Arguments list is neither avariable nor an atom
Status is neither a variable nor an integer
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicates.

8.27.21popen/3

Templates
popen(+atom, +io mode, -stream)

instantiation error
type error(atom, Command)
instantiation error
type error(list, Arguments)
type error(atom, E)
type error(integer, Status)
system error(atom explaining the error )8.27

Operating system interface

171

Description
popen(Command, Mode, Stream) invokes a new default shell (by creating a pipe) passing Command forexecution and associates a stream either to the standard input or the standard output of the createdprocess. if Mode is read (resp. write) an input (resp. output) stream is created and Stream is unified
with the stream-term associated. Writing to the stream writes to the standard input of the command
while reading from the stream reads the command’s standard output. The stream must be closed using
close/2 (section 8.10.7, page 82). This predicate is an interface to the C Unix function popen(3).
ErrorsCommand is a variable
Command is neither a variable nor an atom
Mode is a variable
Mode is neither a variable nor an atom
Mode is an atom but neither read nor write.
Stream is not a variable
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(atom, Command)
instantiation error
type error(atom, Mode)domain error(io mode, Mode)uninstantiation error(Stream)system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.22

exec/5, exec/4

Templates
exec(+atom, -stream, -stream, -stream, -integer)exec(+atom, -stream, -stream, -stream)
Description
exec(Command, StreamIn, StreamOut, StreamErr, Pid) invokes a new default shell passing Commandfor execution and associates streams to standard streams of the created process. StreamIn is unified
with the stream-term associated with the standard input stream of Command (it is an output stream).
StreamOut is unified with the stream-term associated with the standard output stream of Command (itis an input stream). StreamErr is unified with the stream-term associated with the standard error
stream of Command (it is an input stream). Pid is unified with the process identifier of the new process.
This information is only useful if it is necessary to obtain the status of the execution using wait/2(section 8.27.25, page 173). Until a call to wait/2 is done the process remains in the system processes
table (as a zombie process if terminated). For this reason, if the status is not needed it is preferable touse exec/4.
exec/4 is similar to exec/5 but the process is removed from system processes as soon as it is terminated.
Errors172

8Command is a variable
Command is neither a variable nor an atom
StreamIn is not a variable
StreamOut is not a variable
StreamErr is not a variable
Pid is not a variable
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

PROLOG BUILT-IN PREDICATES

instantiation error
type error(atom, Command)
uninstantiation error(StreamIn)
uninstantiation error(StreamOut)
uninstantiation error(StreamErr)
uninstantiation error(Pid)system error(atom explaining the error )Portability
GNU Prolog predicates.

8.27.23

fork prolog/1

Templates
fork prolog(-integer)
Description
fork prolog(Pid) creates a child process that differs from the parent process only in its PID. In theparent process Pid is unified with the PID of the child while in the child process Pid is unified with
0. In the parent process, the status of the child process can be obtained using wait/2 (section 8.27.25,
page 173). Until a call to wait/2 is done the child process remains in the system processes table (as azombie process if terminated). This predicate is an interface to the C Unix function fork(2).
ErrorsPid is not a variable
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

uninstantiation error(Pid)system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.24

create pipe/2

Templates
create pipe(-stream, -stream)
Description
create pipe(StreamIn, StreamOut) creates a pair of streams pointing to a pipe inode. StreamIn is
unified with the stream-term associated with the input side of the pipe and StreamOut is unified with thestream-term associated with output side. This predicate is an interface to the C Unix function pipe(2).
Errors8.27

Operating system interface

StreamIn is not a variable
StreamOut is not a variable
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

173

uninstantiation error(StreamIn)
uninstantiation error(StreamOut)
system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.25

wait/2

Templates
wait(+integer, ?integer)
Description
wait(Pid, Status) waits for the child process whose identifier is Pid to terminate. Status is thenunified with the exit status. This predicate is an interface to the C Unix function waitpid(2).
ErrorsPid is a variable
Pid is neither a variable nor an integer
Status is neither a variable nor an integer
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(integer, Pid)
type error(integer, Status)
system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.26

prolog pid/1

Templates
prolog pid(?integer)
Description
prolog pid(Pid) unifies Pid with the process identifier of the current GNU Prolog process.
ErrorsPid is neither a variable nor an integer
Portability
GNU Prolog predicate.

type error(integer, Pid)

174

8

8.27.27

PROLOG BUILT-IN PREDICATES

send signal/2

Templates
send signal(+integer, +integer)
send signal(+integer, +atom)
Description
send signal(Pid, Signal) sends Signal to the process whose identifier is Pid. Signal can be specified
directly as an integer or symbolically as an atom. Allowed atoms depend on the machine (e.g. ’SIGINT’,’SIGQUIT’, ’SIGKILL’, ’SIGUSR1’, ’SIGUSR2’, ’SIGALRM’,. . . ). This predicate is an interface to the C
Unix function kill(2).
ErrorsPid is a variable
Pid is neither a variable nor an integer
Signal is a variable
Signal is neither a variable nor an integer or anatom
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(integer, Pid)
instantiation error
type error(integer, Signal)
system error(atom explaining the error )Portability
GNU Prolog predicate.

8.27.28

sleep/1

Templates
sleep(+number)
Description
sleep(Seconds) puts the GNU Prolog process to sleep for Seconds seconds. Seconds can be an integer
or a floating point number (in which case it can be < 1). This predicate is an interface to the C Unix
function usleep(3).
ErrorsSeconds is a variable
Seconds is neither a variable nor a number
Seconds is a number < 0
Portability
GNU Prolog predicate.

instantiation error
type error(number, Seconds)
domain error(not less than zero, Seconds)

8.27

Operating system interface

8.27.29175

select/5

Templates
select(+list, ?list, +list, ?list, +number)
Description
select(Reads, ReadyReads, Writes, ReadyWrites, TimeOut) waits for a number of streams (or filedescriptors) to change status. ReadyReads is unified with the list of elements listed in Reads thathave characters available for reading. Similarly ReadyWrites is unified with the list of elements ofWrites that are ok for immediate writing. The elements of Reads and Writes are either stream-terms
or aliases or integers considered as file descriptors, e.g. for sockets (section 8.28, page 176). Streams thatmust be tested with select/5 should not be buffered. This can be done at the opening using open/4(section 8.10.6, page 81) or later using set stream buffering/2 (section 8.10.27, page 93). TimeOut isan upper bound on the amount of time (in milliseconds) elapsed before select/5 returns. If TimeOut≤ 0 (no timeout) select/5 waits until something is available (either or reading or for writing) and thus
can block indefinitely. This predicate is an interface to the C Unix function select(2).
ErrorsReads (or Writes) is a partial list or a list with
an element E which is a variable
Reads is neither a partial list nor a list
Writes is neither a partial list nor a list
ReadyReads is neither a partial list nor a list
ReadyWrites is neither a partial list nor a list
an element E of the Reads (or Writes) list isneither a stream-term or alias nor an integer
an element E of the Reads (or Writes) list is nota selectable item
an element E of the Reads (or Writes) list is an
integer < 0
an element E of the Reads (or Writes) list is a
stream-tern or alias not associated with an open
streaman element E of the Reads list is associated withan output stream
an element E of the Writes list is associated withan input stream
TimeOut is a variable
TimeOut is neither a variable nor a number
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicate.

instantiation error
type error(list, Reads)
type error(list, Writes)
type error(list, ReadyReads)
type error(list, ReadyWrites)
domain error(stream or alias, E)
domain error(selectable item, E)
domain error(not less than zero, E)
existence error(stream, E)
permission error(input, stream, E)
permission error(output, stream, E)
instantiation error
type error(number, TimeOut)
system error(atom explaining the error )

176

8

8.28

Sockets input/output

8.28.1Introduction

PROLOG BUILT-IN PREDICATES

This set of predicates provides a way to manipulate sockets. The predicates are straightforward interfaces
to the corresponding BSD-type socket functions. This facility is available if the sockets part of GNU Prolog
has been installed. A reader familiar with BSD sockets will understand them immediately otherwise a
study of sockets is needed.
The domain is either the atom ’AF INET’ or ’AF UNIX’ corresponding to the same domains in BSD-type
sockets.
An address is either of the form ’AF INET’(HostName, Port) or ’AF UNIX’(SocketName). HostName is
an atom denoting a machine name, Port is a port number and SocketName is an atom denoting a socket.
By default, streams associated with sockets are block buffered. The predicate set stream buffering/2(section 8.10.27, page 93) can be used to change this mode. They are also text streams by default. Use
set stream type/2 (section 8.10.25, page 92) to change the type if binary streams are needed.

8.28.2socket/2

Templates
socket(+socket domain, -integer)
Description
socket(Domain, Socket) creates a socket whose domain is Domain (section 8.28, page 176) and unifies
Socket with the descriptor identifying the socket. This predicate is an interface to the C Unix function
socket(2).
Errors
Domain is a variable
Domain is neither a variable nor an atom
Domain is an atom but not a valid socket domain
Socket is not a variable
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicate.

8.28.3socket close/1

Templates
socket close(+integer)
Description

instantiation error
type error(atom, Domain)
domain error(socket domain, Domain)
uninstantiation error(Socket)
system error(atom explaining the error )8.28

Sockets input/output

177

socket close(Socket) closes the socket whose descriptor is Socket. This predicate should not be used
if Socket has given rise to a stream, e.g. by socket connect/4 (section 8.28.5, page 178). In that casesimply use close/2 (section 8.10.7, page 82) on the associated stream.
ErrorsSocket is a variable
Socket is neither a variable nor an integer
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(integer, Socket)
system error(atom explaining the error )Portability
GNU Prolog predicate.

8.28.4socket bind/2

Templates
socket bind(+integer, +socket address)
Description
socket bind(Socket, Address) binds the socket whose descriptor is Socket to the address specified
by Address (section 8.28, page 176). If Address if of the form ’AF INET’(HostName, Port) and if
HostName is uninstantiated then it is unified with the current machine name. If Port is uninstantiated,
it is unified to a port number picked by the operating system. This predicate is an interface to the C
Unix function bind(2).
ErrorsSocket is a variable
Socket is neither a variable nor an integer
Address is a variable
Address is neither a variable nor a valid address
Address = ’AF UNIX’(E) and E is a variable
Address = ’AF UNIX’(E) or ’AF INET’(E, )and E is neither a variable nor an atom
Address = ’AF UNIX’(E) and E is an atom but
not a valid pathname
Address = ’AF INET’( , E) and E is neither avariable nor an integer
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicate.

instantiation error
type error(integer, Socket)
instantiation error
domain error(socket address, Address)
instantiation error
type error(atom, E)
domain error(os path, E)
type error(integer, E)
system error(atom explaining the error )

178

8

8.28.5PROLOG BUILT-IN PREDICATES

socket connect/4

Templates
socket connect(+integer, +socket address, -stream, -stream)
Description
socket connect(Socket, Address, StreamIn, StreamOut) connects the socket whose descriptor is
Socket to the address specified by Address (section 8.28, page 176). StreamIn is unified with a streamterm associated with the input of the connection (it is an input stream). Reading from this stream
gets data from the socket. StreamOut is unified with a stream-term associated with the output of
the connection (it is an output stream). Writing to this stream sends data to the socket. The use of
select/5 can be useful (section 8.27.29, page 175). This predicate is an interface to the C Unix function
connect(2).
ErrorsSocket is a variable
Socket is neither a variable nor an integer
Address is a variable
Address is neither a variable nor a valid address
Address = ’AF UNIX’(E) or ’AF INET’(E, ) or
Address = ’AF INET’( , E) and E is a variable
Address = ’AF UNIX’(E) or ’AF INET’(E, )and E is neither a variable nor an atom
Address = ’AF UNIX’(E) and E is an atom but
not a valid pathname
Address = ’AF INET’( , E) and E is neither avariable nor an integer
StreamIn is not a variable
StreamOut is not a variable
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

instantiation error
type error(integer, Socket)
instantiation error
domain error(socket address, Address)
instantiation error
type error(atom, E)
domain error(os path, E)
type error(integer, E)
uninstantiation error(StreamIn)
uninstantiation error(StreamOut)
system error(atom explaining the error )Portability
GNU Prolog predicate.

8.28.6socket listen/2

Templates
socket listen(+integer, +integer)
Description
socket listen(Socket, Length) defines the socket whose descriptor is Socket to have a maximum
backlog queue of Length pending connections. This predicate is an interface to the C Unix function
listen(2).
Errors8.28

Sockets input/output

Socket is a variable
Socket is neither a variable nor an integer
Length is a variable
Length is neither a variable nor an integer
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)

179

instantiation error
type error(integer, Socket)
instantiation error
type error(integer, Length)
system error(atom explaining the error )Portability
GNU Prolog predicate.

8.28.7socket accept/4, socket accept/3

Templates
socket accept(+integer, -atom, -stream, -stream)
socket accept(+integer, -stream, -stream)
Description
socket accept(Socket, Client, StreamIn, StreamOut) extracts the first connection to the socket
whose descriptor is Socket. If the domain is ’AF INET’, Client is unified with an atom whose name is
the Internet host address in numbers-and-dots notation of the connecting machine. StreamIn is unified
with a stream-term associated with the input of the connection (it is an input stream). Reading from thisstream gets data from the socket. StreamOut is unified with a stream-term associated with the outputof the connection (it is an output stream). Writing to this stream sends data to the socket. The use of
select/5 can be useful (section 8.27.29, page 175). This predicate is an interface to the C Unix function
accept(2).
socket accept(Socket, StreamIn, StreamOut) is equivalent to socket accept(Socket, ,StreamIn, StreamOut).
ErrorsSocket is a variable
Socket is neither a variable nor an integer
Client is not a variable
StreamIn is not a variable
StreamOut is not a variable
an operating system error occurs and the valueof the os error Prolog flag is error(section 8.22.1, page 148)
Portability
GNU Prolog predicates.

8.28.8hostname address/2

Templates

instantiation error
type error(integer, Socket)
uninstantiation error(Client)
uninstantiation error(StreamIn)
uninstantiation error(StreamOut)
system error(atom explaining the error )

180

8

PROLOG BUILT-IN PREDICATES

hostname address(+atom, ?atom)
hostname address(?atom, +atom)
Description
hostname address(HostName, HostAddress) succeeds if the Internet host address in numbers-and-dots
notation of HostName is HostAddress. Hostname can be given as a fully qualified name, or an unqualified
name or an alias of the machine. The predicate will fail if the machine name or address cannot be
resolved.
ErrorsHostName and HostAddress are variables
HostName is neither a variable nor an atom
HostAddress is neither a variable nor an atom
Address is neither a variable nor a valid address

instantiation error
type error(atom, HostName)
type error(atom, HostAddress)
domain error(socket address, Address)

Portability
GNU Prolog predicate.

8.29

Linedit management

The following predicates are only available if the linedit part of GNU Prolog has been installed.

8.29.1get linedit prompt/1

Templates
get linedit prompt(?atom)
Description
get linedit prompt(Prompt) succeeds if Prompt is the current linedit prompt, e.g. the top-level
prompt is ’| ?-’. By default all other reads have an empty prompt.
Errors
Prompt is neither a variable nor an atom
Portability
GNU Prolog predicate.

8.29.2

set linedit prompt/1

Templates
set linedit prompt(+atom)
Description

type error(atom, Pred)

8.29

Linedit management181

set linedit prompt(Prompt) sets the current linedit prompt to Prompt. This prompt will be displayed
for reads from a terminal (except for top-level reads).
Errors
Prompt is a variable
Prompt is neither a variable nor an atom

instantiation error
type error(atom, Pred)

Portability
GNU Prolog predicate.

8.29.3

add linedit completion/1

Templates
add linedit completion(+atom)
Description
add linedit completion(Word) adds Word in the list of completion words maintained by linedit (section 4.2.6, page 18). Only words containing letters, digits and the underscore character are added (ifWord does not respect this restriction the predicate fails).
ErrorsWord is a variable
Word is neither a variable nor an atom

instantiation error
type error(atom, Word)

Portability
GNU Prolog predicate.

8.29.4find linedit completion/2

Templates
find linedit completion(+atom, ?atom)
Description
find linedit completion(Prefix, Word) succeeds if Word is a word beginning by Prefix and belongs
to the list of completion words maintained by linedit (section 4.2.6, page 18). This predicate is reexecutable on backtracking.
ErrorsPrefix is a variable
Prefix is neither a variable nor an atom
Word is neither a variable nor an atom
Portability
GNU Prolog predicate.

instantiation error
type error(atom, Prefix)
type error(atom, Word)

182

8

PROLOG BUILT-IN PREDICATES

183

9

Finite domain solver and built-in predicates

9.1

Introduction

The finite domain (FD) constraint solver extends Prolog with constraints over FD. This facility is available
if the FD part of GNU Prolog has been installed. The solver is an instance of the Constraint Logic
Programming scheme introduced by Jaffar and Lassez in 1987 [7]. Constraints on FD are solved using
propagation techniques, in particular arc-consistency (AC). The interested reader can refer to “Constraint
Satisfaction in Logic Programming” of P. Van Hentenryck (1989) [8]. The solver is based on the clp(FD)solver [4]. The GNU Prolog FD solver offers arithmetic constraints, boolean constraints, reified constraints
and symbolic constraints on an new kind of variables: Finite Domain variables.

9.1.1

Finite Domain variables

A new type of data is introduced: FD variables which can only take values in their domains. The
initial domain of an FD variable is 0..fd max integer where fd max integer represents the greatest
value that any FD variable can take. The predicate fd max integer/1 returns this value which may bedifferent from the max integer Prolog flag (section 8.22.1, page 148). The domain of an FD variable
X is reduced step by step by constraints in a monotonic way: when a value has been removed from thedomain of X it will never reappear in the domain of X. An FD variable is fully compatible with both
Prolog integers and Prolog variables. Namely, when an FD variable is expected by an FD constraint it ispossible to pass a Prolog integer (considered as an FD variable whose domain is a singleton) or a Prolog
variable (immediately bound to an initial range 0..fd max integer). This avoids the need for specific
type declaration. Although it is not necessary to declare the initial domain of an FD variable (since itwill be bound 0..fd max integer when appearing for the fist time in a constraint) it is advantageous todo so and thus reduce as soon as possible the size of its domain: particularly because GNU Prolog, forefficiency reasons, does not check for overflows. For instance, without any preliminary domain definitions
for X, Y and Z, the non-linear constraint X*Y#=Z will fail due to an overflow when computing the upperbound of the domain of Z: fd max integer × fd max integer. This overflow causes a negative result
for the upper bound and the constraint then fails.
There are two internal representations for an FD variable:• interval representation: only the min and the max of the variable are maintained. In thisrepresentation it is possible to store values included in 0..fd max integer.
• sparse representation: an additional bit-vector is used to store the set of possible values forthe variable (i.e. the domain). In this representation it is possible to store values included in
0..vector max. By default vector max is set to 127. This value can be redefined via an environment variable VECTORMAX or via the built-in predicate fd set vector max/1 (section 9.2.3,
page 185). The predicate fd vector max/1 returns the current value of vector max (section 9.2.1,
page 184).
The initial representation for an FD variable X is always an interval representation and is switched toa sparse representation when a “hole” appears in the domain (e.g. due to an inequality constraint).
Once a variable uses a sparse representation it will not switch back to an interval representation even if
there are no longer holes in its domain. When this switching occurs some values in the domain of X canbe lost since vector max is less than fd max integer. We say that “X is extra-constrained” since X isconstrained by the solver to the domain 0..vector max (via an imaginary constraint X #=< vector max ).
An extra cstr is associated with each FD variable to indicate that values have been lost due to the switch
to a sparse representation. This flag is updated on every operations. The domain of an extra-constrained
FD variable is output followed by the @ symbol. When a constraint fails on a extra-constrained variable

184

9

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

a message Warning: Vector too small - maybe lost solutions (FD Var:N ) is displayed (N is theaddress of the involved variable).
Example 1 (vector max = 127):
Constraint on X
X #=< 512
X #\= 10
X #=< 100

Domain of X
0..5120..9:11..127
0..9:11..100

extra cstr
off
on
off

Lost values
none
128..512
none

In this example, when the constraint X #\= 10 is posted some values are lost, the extra cstr is thenswitched on. However, posting the constraint X #=< 100 will turn off the flag (no values are lost).
Example 2:
Constraint on X
X #=< 512
X #\= 10
X #>= 256

Domain of X
0..5120..9:11..127
Warning: Vector too small...

extra cstr
off
on
on

Lost values
none
128..512
128..512

In this example, the constraint X #>= 256 fails due to the lost of 128..512 so a message is displayed
onto the terminal. The solution would consist in increasing the size of the vector either by setting theenvironment variable VECTORMAX (e.g. to 512) or using fd set vector max(512).
Finally, bit-vectors are not dynamic, i.e. all vectors have the same size (0..vector max). So the useof fd set vector max/1 is limited to the initial definition of vector sizes and must occur before any
constraint. As seen before, the solver tries to display a message when a failure occurs due to a too shortvector max. Unfortunately, in some cases it cannot detect the lost of values and no message is emitted.
So the user should always take care to this parameter to be sure that it is large to encode any vector.

9.2

FD variable parameters

9.2.1

fd max integer/1

Templates
fd max integer(?integer)
Description
fd max integer(N) succeeds if N is the current value of fd max integer (section 9.1, page 183).
ErrorsN is neither a variable nor an integer
Portability
GNU Prolog predicate.

type error(integer, N)9.3

Initial value constraints

9.2.2

185

fd vector max/1

Templates
fd vector max(?integer)
Description
fd vector max(N) succeeds if N is the current value of vector max (section 9.1, page 183).
ErrorsN is neither a variable nor an integer

type error(integer, N)

Portability
GNU Prolog predicate.

9.2.3

fd set vector max/1

Templates
fd set vector max(+integer)
Description
fd set vector max(N) initializes vector max based on the value N (section 9.1, page 183). More precisely,on 32 bit machines, vector max is set to the smallest value of (32*k)-1 which is ≥ N.
ErrorsN is a variable
N is neither a variable nor an integer
N is an integer < 0instantiation error
type error(integer, N)
domain error(not less than zero, N)

Portability
GNU Prolog predicate.

9.3

Initial value constraints

9.3.1

fd domain/3, fd domain bool/1

Templates
fd domain(+fd variable list or fd variable, +integer, +integer)
fd domain(?fd variable, +integer, +integer)
fd domain bool(+fd variable list)
fd domain bool(?fd variable)
Description

186

9

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

fd domain(Vars, Lower, Upper) constraints each element X of Vars to take a value in Lower..Upper.
This predicate is generally used to set the initial domain of variables to an interval. Vars can be also asingle FD variable (or a single Prolog variable).
fd domain bool(Vars) is equivalent to fd domain(Vars, 0, 1) and is used to declare boolean FD
variables.
ErrorsVars is not a variable but is a partial list
Vars is neither a variable nor an FD variable nor
an integer nor a list
an element E of the Vars list is neither a variable
nor an FD variable nor an integer
Lower is a variable
Lower is neither a variable nor an integer
Upper is a variable
Upper is neither a variable nor an integer

instantiation error
type error(list, Vars)
type error(fd variable, E)
instantiation error
type error(integer, Lower)
instantiation error
type error(integer, Upper)

Portability
GNU Prolog predicate.

9.3.2

fd domain/2

Templates
fd domain(+fd variable list, +integer list)
fd domain(?fd variable, +integer list)
Description
fd domain(Vars, Values) constraints each element X of the list Vars to take a value in the list Values.
This predicate is generally used to set the initial domain of variables to a set of values. The domain ofeach variable of Vars uses a sparse representation. Vars can be also a single FD variable (or a single
Prolog variable).
ErrorsVars is not a variable but is a partial list
Vars is neither a variable nor an FD variable nor
an integer nor a list
an element E of the Vars list is neither a variable
nor an FD variable nor an integer
Values is a partial list or a list with an element
E which is a variable
Values is neither a partial list nor a list
an element E of the Values list is neither avariable nor an integer
Portability
GNU Prolog predicate.

instantiation error
type error(list, Vars)
type error(fd variable, E)
instantiation error
type error(list, Values)
type error(integer, E)

9.4

Type testing

187

9.4

Type testing

9.4.1

fd var/1, non fd var/1, generic var/1, non generic var/1

Templates
fd var(?term)
non fd var(?term)

generic var(?term)
non generic var(?term)

Description
fd var(Term) succeeds if Term is currently an FD variable.
non fd var(Term) succeeds if Term is currently not an FD variable (opposite of fd var/1).
generic var(Term) succeeds if Term is either a Prolog variable or an FD variable.
non generic var(Term) succeeds if Term is neither a Prolog variable nor an FD variable (opposite ofgeneric var/1).
Errors
None.
Portability
GNU Prolog predicate.

9.5

FD variable information

These predicate allow the user to get some information about FD variables. They are not constraints,
they only return the current state of a variable.

9.5.1

fd min/2, fd max/2, fd size/2, fd dom/2

Templates
fd min(+fd variable, ?integer)
fd max(+fd variable, ?integer)
fd size(+fd variable, ?integer)
fd dom(+fd variable, ?integer list)
Description
fd min(X, N) succeeds if N is the minimal value of the current domain of X.
fd max(X, N) succeeds if N is the maximal value of the current domain of X.
fd size(X, N) succeeds if N is the number of elements of the current domain of X.
fd dom(X, Values) succeeds if Values is the list of values of the current domain of X.

188

9

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

Errors
X is a variable
X is neither an FD variable nor an integer
N is neither a variable nor an integer
an element E of the Vars list is neither a variable
nor an FD variable nor an integer
Values is neither a partial list nor a list

instantiation error
type error(fd variable, X)
type error(integer, N)
type error(fd variable, E)
type error(list, Values)

Portability
GNU Prolog predicate.

9.5.2

fd has extra cstr/1, fd has vector/1, fd use vector/1

Templates
fd has extra cstr(+fd variable)
fd has vector(+fd variable)
fd use vector(+fd variable)
Description
fd has extra cstr(X) succeeds if the extra cstr of X is currently on (section 9.1, page 183).
fd has vector(X) succeeds if the current domain of X uses a sparse representation (section 9.1, page 183).
fd use vector(X) enforces a sparse representation for the domain of X (section 9.1, page 183).
Errors
X is a variable
X is neither an FD variable nor an integer

instantiation error
type error(fd variable, X)

Portability
GNU Prolog predicates.

9.6

Arithmetic constraints

9.6.1

FD arithmetic expressions

An FD arithmetic expression is a Prolog term built from integers, variables (Prolog or FD variables), andfunctors (or operators) that represent arithmetic functions. The following table details the components
of an FD arithmetic expression:

9.6

Arithmetic constraints

FD Expression
Prolog variable
FD variable X
integer number N+ E- E
E1 + E2
E1 - E2
E1 * E2
E1 / E2
E1 ** E2
min(E1,E2)
max(E1,E2)
dist(E1,E2)
E1 // E2
E1 rem E2
quot rem(E1,E2,R)

189

Resultdomain 0..fd max integer
domain of X
domain N..N
same as E
opposite of E
sum of E1 and E2
subtraction of E2 from E1
multiplication of E1 by E2
integer division of E1 by E2 (only succeeds if the remainder is 0)
E1 raised to the power of E2 (E1 or E2 must be an integer)
minimum of E1 and E2
maximum of E1 and E2
distance, i.e. |E1 - E2|
quotient of the integer division of E1 by E2
remainder of the integer division of E1 by E2
quotient of the integer division of E1 by E2(R is the remainder of the integer division of E1 by E2)

FD expressions are not restricted to be linear. However non-linear constraints usually yield less constraint
propagation than linear constraints.
+, -, *, /, //, rem and ** are predefined infix operators. + and - are predefined prefix operators(section 8.14.10, page 113).
Errorsa sub-expression is of the form ** E and E is avariablea sub-expression E is neither a variable nor an
integer nor an FD arithmetic functor
an expression is too complex

9.6.2

instantiation error
type error(fd evaluable, E)
resource error(too big fd constraint)

Partial AC: (#=)/2 - constraint equal, (#\=)/2 - constraint not equal,(#<)/2 - constraint less than, (#=<)/2 - constraint less than or equal,(#>)/2 - constraint greater than, (#>=)/2 - constraint greater than or equalTemplates#=(?fd evaluable, ?fd evaluable)#\=(?fd evaluable, ?fd evaluable)#<(?fd evaluable, ?fd evaluable)#=<(?fd evaluable, ?fd evaluable)#>(?fd evaluable, ?fd evaluable)#>=(?fd evaluable, ?fd evaluable)
Description
FdExpr1 #= FdExpr2 constrains FdExpr1 to be equal to FdExpr2.
FdExpr1 #\= FdExpr2 constrains FdExpr1 to be different from FdExpr2.
FdExpr1 #< FdExpr2 constrains FdExpr1 to be less than FdExpr2.

190

9

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

FdExpr1 #=< FdExpr2 constrains FdExpr1 to be less than or equal to FdExpr2.
FdExpr1 #> FdExpr2 constrains FdExpr1 to be greater than FdExpr2.
FdExpr1 #>= FdExpr2 constrains FdExpr1 to be greater than or equal to FdExpr2.
FdExpr1 and FdExpr2 are arithmetic FD expressions (section 9.6.1, page 188).
#=, #\=, #<, #=<, #> and #>= are predefined infix operators (section 8.14.10, page 113).
These predicates post arithmetic constraints that are managed by the solver using a partial arc-consistency
algorithm to reduce the domain of involved variables. In this scheme only the bounds of the domain ofvariables are updated. This leads to less propagation than full arc-consistency techniques (section 9.6.3,
page 190) but is generally more efficient for arithmetic. These arithmetic constraints can be reified(section 9.7, page 191).
ErrorsRefer to the syntax of arithmetic FD expressions for possible errors (section 9.6.1, page 188).
Portability
GNU Prolog predicates.

9.6.3

Full AC: (#=#)/2 - constraint equal, (#\=#)/2 - constraint not equal,(#<#)/2 - constraint less than, (#=<#)/2 - constraint less than or equal,(#>#)/2 - constraint greater than, (#>=#)/2 - constraint greater than or equalTemplates#=#(?fd evaluable, ?fd evaluable)#\=#(?fd evaluable, ?fd evaluable)#<#(?fd evaluable, ?fd evaluable)#=<#(?fd evaluable, ?fd evaluable)#>#(?fd evaluable, ?fd evaluable)#>=#(?fd evaluable, ?fd evaluable)
Description
FdExpr1 #=# FdExpr2 constrains FdExpr1 to be equal to FdExpr2.
FdExpr1 #\=# FdExpr2 constrains FdExpr1 to be different from FdExpr2.
FdExpr1 #<# FdExpr2 constrains FdExpr1 to be less than FdExpr2.
FdExpr1 #=<# FdExpr2 constrains FdExpr1 to be less than or equal to FdExpr2.
FdExpr1 #># FdExpr2 constrains FdExpr1 to be greater than FdExpr2.
FdExpr1 #>=# FdExpr2 constrains FdExpr1 to be greater than or equal to FdExpr2.
FdExpr1 and FdExpr2 are arithmetic FD expressions (section 9.6.1, page 188).
#=#, #\=#, #<#, #=<#, #># and #>=# are predefined infix operators (section 8.14.10, page 113).

9.7

Boolean and reified constraints

191

These predicates post arithmetic constraints that are managed by the solver using a full arc-consistency
algorithm to reduce the domain of involved variables. In this scheme the full domain of variables is
updated. This leads to more propagation than partial arc-consistency techniques (section 9.6.1, page 188)
but is generally less efficient for arithmetic. These arithmetic constraints can be reified (section 9.7.1,
page 191).
ErrorsRefer to the syntax of arithmetic FD expressions for possible errors (section 9.6.1, page 188).
Portability
GNU Prolog predicates.

9.6.4

fd prime/1, fd not prime/1

Templates
fd prime(?fd variable)
fd not prime(?fd variable)
Description
fd prime(X) constraints X to be a prime number between 0..vector max. This constraint enforces asparse representation for the domain of X (section 9.1, page 183).
fd not prime(X) constraints X to be a non prime number between 0..vector max. This constraint
enforces a sparse representation for the domain of X (section 9.1, page 183).
Errors
X is neither an FD variable nor an integer

type error(fd variable, X)

Portability
GNU Prolog predicates.

9.7

Boolean and reified constraints

9.7.1

Boolean FD expressions

An boolean FD expression is a Prolog term built from integers (0 for false, 1 for true), variables (Prolog or
FD variables), partial AC arithmetic constraints (section 9.6.2, page 189), full AC arithmetic constraints(section 9.6.3, page 190) and functors (or operators) that represent boolean functions. When a subexpression of a boolean expression is an arithmetic constraint c , it is reified. Namely, as soon as thesolver detects that c is true (i.e. entailed ) the sub-expression has the value 1. Similarly when the solver
detects that c is false (i.e. disentailed ) the sub-expression evaluates as 0. While neither the entailment
nor the disentailment can be detected the sub-expression is evaluated as a domain 0..1. The following
table details the components of an FD boolean expression:

192

9

FD Expression
Prolog variable
FD variable X
0 (integer)
1 (integer)#\ E
E1 #<=> E2
E1 #\<=> E2
E1 ## E2
E1 #==> E2
E1 #\==> E2
E1 #/\ E2
E1 #\/\ E2
E1 #\/ E2
E1 #\\/ E2

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

Resultdomain 0..1
domain of X, X is constrained to be in 0..1
0 (false)
1 (true)
not E
E1 equivalent to E2
E1 not equivalent to E2 (i.e. E1 different from E2)
E1 exclusive OR E2 (i.e. E1 not equivalent to E2)
E1 implies E2
E1 does not imply E2E1 AND E2
E1 NAND E2
E1 OR E2
E1 NOR E2#<=>, #\<=>, ##, #==>, #\==>, #/\, #\/\, #\/ and #\\/ are predefined infix operators. #\ is a predefined
prefix operator (section 8.14.10, page 113).
Errorsa sub-expression E is neither a variable nor an
integer (0 or 1) nor an FD boolean functor nor
reified constraint
an expression is too complex
a sub-expression is an invalid reified constraint

9.7.2

type error(fd bool evaluable, E)
resource error(too big fd constraint)
an arithmetic constraint error (section 9.6.1,
page 188)

fd reified in/4

Templates
fd reified in(?fd variable, +integer, +integer, ?fd variable)
Description
fd reified in(X, Lower, Upper, B) captures the truth value of the constraint X ∈ [Lower..Upper] inthe boolean variable B.
Errors
X is neither a variable nor an FD variable nor an
integer
B is neither a variable nor an FD variable nor an
integer
Lower is a variable
Lower is neither a variable nor an integer
Upper is a variable
Upper is neither a variable nor an integer

type error(fd variable, X)
type error(fd variable, B)
instantiation error
type error(integer, Lower)
instantiation error
type error(integer, Upper)

9.7

Boolean and reified constraints

9.7.3

193

(#\)/1 - constraint NOT, (#<=>)/2 - constraint equivalent,(#\<=>)/2 - constraint different, (##)/2 - constraint XOR,(#==>)/2 - constraint imply, (#\==>)/2 - constraint not imply,(#/\)/2 - constraint AND, (#\/\)/2 - constraint NAND,(#\/)/2 - constraint OR, (#\\/)/2 - constraint NOR

Templates#\(?fd bool evaluable)#<=>(?fd bool evaluable, ?fd bool evaluable)#\<=>(?fd bool evaluable, ?fd bool evaluable)##(?fd bool evaluable, ?fd bool evaluable)#==>(?fd bool evaluable, ?fd bool evaluable)#\==>(?fd bool evaluable, ?fd bool evaluable)#/\(?fd bool evaluable, ?fd bool evaluable)#\/\(?fd bool evaluable, ?fd bool evaluable)#\/(?fd bool evaluable, ?fd bool evaluable)#\\/(?fd bool evaluable, ?fd bool evaluable)
Description#\ FdBoolExpr1 constraints FdBoolExpr1 to be false.
FdBoolExpr1 #<=> FdBoolExpr2 constrains FdBoolExpr1 to be equivalent to FdBoolExpr2.
FdBoolExpr1 #\<=> FdBoolExpr2 constrains FdBoolExpr1 to be equivalent to not FdBoolExpr2.
FdBoolExpr1 ## FdBoolExpr2 constrains FdBoolExpr1 XOR FdBoolExpr2 to be true
FdBoolExpr1 #==> FdBoolExpr2 constrains FdBoolExpr1 to imply FdBoolExpr2.
FdBoolExpr1 #\==> FdBoolExpr2 constrains FdBoolExpr1 to not imply FdBoolExpr2.
FdBoolExpr1 #/\ FdBoolExpr2 constrains FdBoolExpr1 AND FdBoolExpr2 to be true.
FdBoolExpr1 #\/\ FdBoolExpr2 constrains FdBoolExpr1 AND FdBoolExpr2 to be false.
FdBoolExpr1 #\/ FdBoolExpr2 constrains FdBoolExpr1 OR FdBoolExpr2 to be true.
FdBoolExpr1 #\\/ FdBoolExpr2 constrains FdBoolExpr1 OR FdBoolExpr2 to be false.
FdBoolExpr1 and FdBoolExpr2 are boolean FD expressions (section 9.7.1, page 191).
Note that #\<=> (not equivalent) and ## (exclusive or) are synonymous.
These predicates post boolean constraints that are managed by the FD solver using a partial arcconsistency algorithm to reduce the domain of involved variables. The (dis)entailment of reified constraints is detected using either the bounds (for partial AC arithmetic constraints) or the full domain(for full AC arithmetic constraints).
#<=>, #\<=>, ##, #==>, #\==>, #/\, #\/\, #\/ and #\\/ are predefined infix operators. #\ is a predefined
prefix operator (section 8.14.10, page 113).
Errors194

9

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

Refer to the syntax of boolean FD expressions for possible errors (section 9.7.1, page 191).
Portability
GNU Prolog predicates.

9.7.4

fd cardinality/2, fd cardinality/3, fd at least one/1, fd at most one/1,
fd only one/1

Templates
fd cardinality(+fd bool evaluable list, ?fd variable)
fd cardinality(+integer, ?fd variable, +integer)
fd at least one(+fd bool evaluable list)
fd at most one(+fd bool evaluable list)
fd only one(+fd bool evaluable list)
Description
fd cardinality(List, Count) unifies Count with the number of constraints that are true in List.
This is equivalent to post the constraint B1 + B2 + ...+ Bn #= Count where each variable Bi is a newvariable defined by the constraint Bi #<=> Ci where Ci is the ith constraint of List. Each Ci must be aboolean FD expression (section 9.7.1, page 191).
fd cardinality(Lower, List, Upper) is equivalent to fd cardinality(List, Count), Lower #=<Count, Count #=< Upperfd at least one(List) is equivalent to fd cardinality(List, Count), Count #>= 1.
fd at most one(List) is equivalent to fd cardinality(List, Count), Count #=< 1.
fd only one(List) is equivalent to fd cardinality(List, 1).
ErrorsList is a partial list
List is neither a partial list nor a list
Count is neither an FD variable nor an integer
Lower is a variable
Lower is neither a variable nor an integer
Upper is a variable
Upper is neither a variable nor an integer
an element E of the List list is an invalid
boolean expression
Portability
GNU Prolog predicates.

instantiation error
type error(list, List)
type error(fd variable, Count)instantiation error
type error(integer, Lower)
instantiation error
type error(integer, Upper)
an FD boolean constraint (section 9.7.1,
page 191)

9.8

Symbolic constraints

9.8

Symbolic constraints

9.8.1

fd all different/1

195

Templates
fd all different(+fd variable list)
Description
fd all different(List) constrains all variables in List to take distinct values. This is equivalent toposting an inequality constraint for each pair of variables. This constraint is triggered when a variable
becomes ground, removing its value from the domain of the other variables.
ErrorsList is a partial list
List is neither a partial list nor a list
an element E of the List list is neither a variable
nor an integer nor an FD variableinstantiation error
type error(list, List)
type error(fd variable, E)

Portability
GNU Prolog predicate.

9.8.2

fd element/3

Templates
fd element(?fd variable, +integer list, ?fd variable)
Description
fd element(I, List, X) constraints X to be equal to the Ith integer (from 1) of List.
Errors
I is neither a variable nor an FD variable nor an
integer
X is neither a variable nor an FD variable nor an
integer
List is a partial list or a list with an element E
which is a variable
List is neither a partial list nor a list
an element E of the List list is neither a variable
nor an integer
Portability
GNU Prolog predicate.

type error(fd variable, I)
type error(fd variable, X)
instantiation error
type error(list, List)
type error(integer, E)

196

9

9.8.3

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATESfd element var/3

Templates
fd element var(?fd variable, +fd variable list, ?fd variable)
Description
fd element var(I, List, X) constraints X to be equal to the Ith variable (from 1) of List. This
constraint is similar to fd element/3 (section 9.8.2, page 195) but List can also contain FD variables(rather than just integers).
Errors
I is neither a variable nor an FD variable nor an
integer
X is neither a variable nor an FD variable nor an
integer
List is a partial list
List is neither a partial list nor a list
an element E of the List list is neither a variable
nor an integer nor an FD variable

type error(fd variable, I)
type error(fd variable, X)
instantiation error
type error(list, List)
type error(fd variable, E)

Portability
GNU Prolog predicate.

9.8.4

fd atmost/3, fd atleast/3, fd exactly/3

Templates
fd atmost(+integer, +fd variable list, +integer)
fd atleast(+integer, +fd variable list, +integer)
fd exactly(+integer, +fd variable list, +integer)
Description
fd atmost(N, List, V) posts the constraint that at most N variables of List are equal to the value V.
fd atleast(N, List, V) posts the constraint that at least N variables of List are equal to the value V.
fd exactly(N, List, V) posts the constraint that at exactly N variables of List are equal to the value
V.
These constraints are special cases of fd cardinality/2 (section 9.7.4, page 194) but their implementation is more efficient.
Errors9.8

Symbolic constraints

N is a variable
N is neither a variable nor an integer
V is a variable
V is neither a variable nor an integer
List is a partial list
List is neither a partial list nor a list
an element E of the List list is neither a variable
nor an FD variable nor an integer

197

instantiation error
type error(integer, N)
instantiation error
type error(integer, V)
instantiation error
type error(list, List)
type error(fd variable, E)

Portability
GNU Prolog predicates.

9.8.5

fd relation/2, fd relationc/2

Templates
fd relation(+integer list list, ?fd variable list)
fd relationc(+integer list list, ?fd variable list)
Description
fd relation(Relation, Vars) constraints the tuple of variables Vars to be equal to one tuple of thelist Relation. A tuple is represented by a list.
Example: definition of the boolean AND relation so that X AND Y ⇔ Z:
and(X,Y,Z):fd_relation([[0,0,0],[0,1,0],[1,0,0],[1,1,1]], [X,Y,Z]).
fd relationc(Columns, Vars) is similar to fd relation/2 except that the relation is not given as thelist of tuples but as the list of the columns of the relation. A column is represented by a list.
Example:and(X,Y,Z):fd_relationc([[0,0,1,1],[0,1,0,1],[0,0,0,1]], [X,Y,Z]).
ErrorsRelation is a partial list or a list with a
sub-term E which is a variable
Relation is neither a partial list nor a list
an element E of the Relation list is neither avariable nor an integer
Vars is a partial list
Vars is neither a partial list nor a list
an element E of the Vars list is neither a variable
nor an integer nor an FD variable
Portability
GNU Prolog predicates.

instantiation error
type error(list, Relation)
type error(integer, E)
instantiation error
type error(list, Vars)
type error(fd variable, E)

198

9

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

9.9

Labeling constraints

9.9.1

fd labeling/2, fd labeling/1, fd labelingff/1

Templates
fd labeling(+fd variable list, +fd labeling option list)
fd labeling(+fd variable, +fd labeling option list)
fd labeling(+fd variable list)
fd labeling(+fd variable)
fd labelingff(+fd variable list)
fd labelingff(+fd variable)
Description
fd labeling(Vars, Options) assigns a value to each variable X of the list Vars according to the list oflabeling options given by Options. Vars can be also a single FD variable. This predicate is re-executableon backtracking.
FD labeling options: Options is a list of labeling options. If this list contains contradictory options,the rightmost option is the one which applies. Possible options are:• variable method(V): specifies the heuristics to select the variable to enumerate:– standard: no heuristics, the leftmost variable is selected.
– first fail (or ff): selects the variable with the smallest number of elements in its domain.
If several variables have the same number of elements the leftmost variable is selected.
– most constrained: like first fail but when several variables have the same number of
elements selects the variable that appears in most constraints.
– smallest: selects the variable that has the smallest value in its domain. If there is more than
one such variable selects the variable that appears in most constraints.
– largest: selects the variable that has the greatest value in its domain. If there is more than
one such variable selects the variable that appears in most constraints.
– max regret: selects the variable that has the greatest difference between the smallest value
and the next value of its domain. If there is more than one such variable selects the variable
that appears in most constraints.
– random: selects randomly a variable. Each variable is chosen only once.
The default value is standard.
• reorder(true/false): specifies if the variable heuristics should dynamically reorder the list ofvariable (true) or not (false). Dynamic reordering is generally more efficient but in some cases astatic ordering is faster. The default value is true.
• value method(V): specifies the heuristics to select the value to assign to the chosen variable:– min: enumerates the values from the smallest to the greatest (default).
– max: enumerates the values from the greatest to the smallest.
– middle: enumerates the values from the middle to the bounds.
– bounds: enumerates the values from the bounds to the middle.
– random: enumerates the values randomly. Each value is tried only once.
– bisect: recursively creates a choice between X #=< M and X #> M, where M is the midpointof the domain of the variable. Values are thus tried from the smallest to the greatest. This isalso known as domain splitting.

9.10

Optimization constraints

199

The default value is min.
• backtracks(B): unifies B with the number of backtracks during the enumeration.
fd labeling(Vars) is equivalent to fd labeling(Vars, []).
fd labelingff(Vars) is equivalent to fd labeling(Vars, [variable method(ff)]).
ErrorsVars is a partial list or a list with an element E
which is a variable
Vars is neither a partial list nor a list
an element E of the Vars list is neither a variable
nor an integer nor an FD variable
Options is a partial list or a list with an element
E which is a variable
Options is neither a partial list nor a list
an element E of the Options list is neither avariable nor a labeling option

instantiation error
type error(list, Vars)
type error(fd variable, E)
instantiation error
type error(list, Options)domain error(fd labeling option, E)

Portability
GNU Prolog predicates.

9.10

Optimization constraints

9.10.1

fd minimize/2, fd maximize/2

Templates
fd minimize(+callable term, ?fd variable)
fd maximize(+callable term, ?fd variable)
Description
fd minimize(Goal, X) repeatedly calls Goal to find a value that minimizes the variable X. Goal is a
Prolog goal that should instantiate X, a common case being the use of fd labeling/2 (section 9.9.1,
page 198). This predicate uses a branch-and-bound algorithm with restart: each time call(Goal)
succeeds the computation restarts with a new constraint X #< V where V is the value of X at the end of
the last call of Goal. When a failure occurs (either because there are no remaining choice-points for Goalor because the added constraint is inconsistent with the rest of the store) the last solution is recomputed
since it is optimal.
fd maximize(Goal, X) is similar to fd minimize/2 but X is maximized.
Errors200

9

FINITE DOMAIN SOLVER AND BUILT-IN PREDICATES

Goal is a variable
Goal is neither a variable nor a callable term
The predicate indicator Pred of Goal does notcorrespond to an existing procedure and thevalue of the unknown Prolog flag is error(section 8.22.1, page 148)
X is neither a variable nor an FD variable nor an
integer
Portability
GNU Prolog predicates.

instantiation error
type error(callable, Goal)
existence error(procedure, Pred)type error(fd variable, X)

201

10

Interfacing Prolog and C

10.1

Introduction

The foreign code interface allows the use to link Prolog and C in both directions.
A Prolog predicate can call a C function passing different kinds of arguments (input, output or input/output). The interface performs implicit Prolog ↔ C data conversions for simple types (for instancea Prolog integer is automatically converted into a C integer) and provides a set of API (Application
Programming Interface) functions to convert more complex types (lists or structures). The interface also
performs automatic error detection depending on the actual type of the passed argument. An importantfeature is the ability to write non-deterministic code in C.
It is also possible to call (or callback) a Prolog predicate from a C function and to manage Prolog nondeterminism: the C code can ask for next solutions, remove all remaining solutions or terminate and keepalternatives for the calling Prolog predicate).

10.2

Including and using gprolog.h

The C code should include gprolog.h which provides a set of C definitions (types, macros, prototypes)
associated to the API. Include this files as follows:#include <gprolog.h>
If the installation has been correctly done nothing else is needed. If the C compiler/preprocessor cannot locate gprolog.h pass the C compiler option required to specify an additional include directory(e.g.-Iinclude dir) to gplc as follows (section 4.4.3, page 23):
% gplc -C -Iinclude dir ...
The file gprolog.h declares the following C types:• PlBool as an integer and the constants PL FALSE (i.e. 0) and PL TRUE (i.e. 1).
• PlLong as an integer able to store a pointer (equivalent to intptr t). This type appeared in GNU
Prolog 1.4.0 in replacement of long to support Windows 64 bits (where the long type is only 32bits). This type is used to handle integer types.
• PlULong same as PlLong but unsigned (same as uintptr t).
• PlTerm same as intptr t. This type is used to store general Prolog terms.
New in GNU Prolog 1.3.1 and backward compatibility issues: in GNU Prolog 1.3.1 the API has
been modified to protect namespace. The name of public functions, macros, variables and types are now
prefixed with Pl , PL or pl . All these prefixes should be avoided by the foreign C-code to prevent nameclashes. To ensure a backward compatibility, the names used by the old API are available thanks to aset of #define. However, this deprecated API should not be used by recent code. It is also possible toprevent the definition of the compatibility macros using:#define __GPROLOG_FOREIGN_STRICT__#include <gprolog.h>
In addition, gprolog.h defines a set of macros:•

GNU PROLOG(as the major version).

202

10

•

INTERFACING PROLOG AND C

GPROLOG , GPROLOG MINOR and GPROLOG PATCHLEVEL . Their values are the major version,
minor version, and patch level of GNU Prolog, as integer constants. For example, GNU Prolog 1.3.2
GPROLOG to 1,
GPROLOG MINOR to 3, and
GPROLOG PATCHLEVEL to 2.
will define
If you need to write code which depends on a specific version, you must be more careful. Recall
these macros appeared in GNU Prolog 1.3.1 (undefined before), each time the minor version isincreased, the patch level is reset to zero; each time the major version is increased (which happens
rarely), the minor version and patch level are reset.

•

GPROLOG VERSION : the version as an integer defined as follows: major ∗ 10000 + minor ∗ 100 +patchlevel. For example: version 1.3.2 will result in the value 10302.

• PL PROLOG DIALECT: a C constant string (generally "gprolog"). Appeared in 1.3.2.
• PL PROLOG NAME: a C constant string (generally "GNU Prolog").
• PL PROLOG VERSION: a C constant string associated to the version (e.g. "1.4.0").
• PL PROLOG DATE: a C constant string associated with the date of this version (e.g. "Mar 29 2011".
• PL PROLOG COPYRIGHT: a C constant string associated with the copyright of this version (e.g.
"Copyright (C) 1999-2021 Daniel Diaz".
Note the above PL PROLOG ... macros are also accessible via Prolog flags thanks to the built-in predicate
current prolog flag/2 (section 8.22.2, page 151)

10.3

Calling C from Prolog

10.3.1Introduction

This interface can then be used to write both simple and complex C routines. A simple routine uses
either input or output arguments which type is simple. In that case the user does not need any knowledge
of Prolog data structures since all Prolog ↔ C data conversions are implicitly achieved. To manipulate
complex terms (lists, structures) a set of functions is provided. Finally it is also possible to write nondeterministic C code.

10.3.2

foreign/2 directive

foreign/2 directive (section 7.1.15, page 50) declares a C function interface. The general form isforeign(Template, Options) which defines an interface predicate whose prototype is Template according to the options given by Options. Template is a callable term specifying the type/mode of eachargument of the associated Prolog predicate.
Foreign options: Options is a list of foreign options. If this list contains contradictory options, therightmost option is the one which applies. Possible options are:• fct name(F): F is an atom representing the name of the C function to call. By default the name of
the C function is the same as the principal functor of Template. In any case, the atom associatedwith the name of the function must conforms to the syntax of C identifiers.
• return(boolean/none/jump): specifies the value returned by the C function:– boolean: the type of the function is PlBool (returns PL TRUE on success, PL FALSE otherwise).
– none: the type of the function is void (no returned value).
– jump: the type of the function is void(*)() (returns the address of a Prolog code to execute).

10.3

Calling C from Prolog

203

The default value is boolean.
• bip name(Name, Arity): initializes the error context with Name and Arity. If an error occurs thisinformation is used to indicate from which predicate the error occurred (section 6.3.1, page 39). It
is also possible to prevent the initialization of the error context using bip name(none). By default
Name and Arity are set to the functor and arity of Template.
• choice size(N): this option specifies that the function implements a non-deterministic code. N is
an integer specifying the size needed by the non-deterministic C function. This facility is explainedlater (section 10.3.7, page 205). By default a foreign function is deterministic.
foreign(Template) is equivalent to foreign(Template, []).
Foreign modes and types: each argument of Template specifies the foreign mode and type of thecorresponding argument. This information is used to check the type of effective arguments at run-timeand to perform Prolog ↔ C data conversions. Each argument of Template is formed with a mode symbol
followed by a type name. Possible foreign modes are:• +: input argument.
• -: output argument.
• ?: input/output argument.
Possible foreign types are:Foreign type
integerpositive
float
numberatom
boolean
char
code
byte
in charin codein bytestring
chars
codes
term

Prolog type
integerpositive integer
floating point number
numberatom
booleancharactercharacter codebyte
in-characterin-character code
in-byteatom
character list
character-code list
Prolog term

C typePlLongPlLongdoubledoublePlLongPlLongPlLongPlLongPlLongPlLongPlLongPlLongchar *
char *
char *
PlTermDescription of the C typevalue of the integer
value of the integer
value of the floating point number
value of the number
internal key of the atom
value of the boolean (0=false, 1=true)
value of (the code of) the character
value of the character-codevalue of the byte
value of the character or -1 for end-of-filevalue of the character-code or -1 for end-of-filevalue of the byte or -1 for the end-of-file
C string containing the name of the atom
C string containing the characters of the list
C string containing the characters of the list
generic Prolog term

Simple foreign type: a simple type is any foreign type listed in the above tabled except term. A simple
foreign type is an atomic term (character and character-code lists are in fact lists of constants). Eachsimple foreign type is converted to/from a C type to simplify the writing of the C function.
Complex foreign type: type foreign type term refers to any Prolog term (e.g. lists, structures. . . ).
When such an type is specified the argument is passed to the C function as a PlTerm (GNU Prolog C typeequivalent to a PlLong). Several functions are provided to manipulate PlTerm variables (section 10.4,
page 210). Since the original term is passed to the function it is possible to read its value or to unify it.
So the meaning of the mode symbol is less significant. For this reason it is possible to omit the mode
symbol. In that case term is equivalent to +term.

204

10

10.3.3

INTERFACING PROLOG AND C

The C function

The type returned by the C function depends on the value of the return foreign option (section 10.3.2,
page 202). If it is boolean then the C function is of type PlBool and shall return PL TRUE in case of
success and PL FALSE otherwise. If the return option is none the C function is of type void. Finally if
it is jump, the function shall return the address of a Prolog predicate and, at the exit of the function, thecontrol is given to that predicate.
The type of the arguments of the C function depends on the mode and type declaration specified in
Template for the corresponding argument as explained in the following sections.

10.3.4

Input arguments

An input argument is tested at run-time to check if its type conforms to the foreign type and thenit is passed to the C function. The type of the associated C argument is given by the above table(section 10.3.2, page 202). For instance, the effective argument Arg associated with +positive foreigndeclaration is submitted to the following process:• if Arg is a variable an instantiation error is raised.
• if Arg is neither a variable nor an integer a type error(integer, Arg) is raised.
• if Arg is an integer < 0 a domain error(not less than zero, Arg) is raised.
• otherwise the value of Arg is passed to the C is passed to the C function as an integer (PlLong).
When +string is specified the string passed to the function is the internal string of the corresponding
atom and should not be modified.
When +term is specified the term passed to the function is the original Prolog term. It can be read
and/or unified. It is also the case when term is specified without any mode symbol.

10.3.5

Output arguments

An output argument is tested at run-time to check if its type conforms to the foreign type and it is unified
with the value set by the C function. The type of the associated C argument is a pointer to the typegiven by the above table (section 10.3.2, page 202). For instance, the effective argument Arg associatedwith -positive foreign declaration is handled as follows:• if Arg is neither a variable nor an integer a type error(integer, Arg) is raised.
• if Arg is an integer < 0 a domain error(not less than zero, Arg) is raised.
• otherwise a pointer to an integer (PlLong *) is passed to the C function. If the function returns
PL TRUE the integer stored at this location is unified with Arg.
When -term is specified, the function must construct a term into the its corresponding argument (which
is of type PlTerm *). At the exit of the function this term will be unified with the actual predicate
argument.

10.3

Calling C from Prolog

10.3.6205

Input/output arguments

Basically an input/output argument is treated as in input argument if it is not a variable, as an output
argument otherwise. The type of the associated C argument is a pointer to a PlFIOArg (GNU Prolog Ctype) defined as follows:
typedef struct{
PlBool is_var;
PlBool unify;
union{
PlLong l;char *s;double d;}value;}PlFIOArg;
The field is var is set to PL TRUE if the argument is a variable and PL FALSE otherwise. This value canbe tested by the C function to determine which treatment to perform. The field unify controls whether
the effective argument must be unified at the exit of the C function. Initially unify is set to the samevalue as is var (i.e. a variable argument will be unified while a non-variable argument will not) but it
can be modified by the C function. The field value stores the value of the argument. It is declared as a
C union since there are several kinds of value types. The field s is used for C strings, d for C doubles
and l otherwise (int, PlLong, PlTerm). if is var is PL FALSE then value contains the input value ofthe argument with the same conventions as for input arguments (section 10.3.4, page 204). At the exitof the function, if unify is PL TRUE value must contain the value to unify with the same conventions as
for output arguments (section 10.3.5, page 204).
For instance, the effective argument Arg associated with ?positive foreign declaration is handled asfollows:• if Arg is a variable is var and unify are set to PL TRUE else to PL FALSE and its value is copied invalue.l.
• if Arg is neither a variable nor an integer a type error(integer, Arg) is raised.
• if Arg is an integer < 0 a domain error(not less than zero, Arg) is raised.
• otherwise a pointer to the PlFIOArg (PlFIOArg *) is passed to the C function. If the function
returns PL TRUE and if unify is PL TRUE the value stored in value.l is unified with Arg.

10.3.7

Writing non-deterministic C code

The interface allows the user to write non-deterministic C code. When a C function is non-deterministic,a choice-point is created for this function. When a failure occurs, if all more recent non-deterministiccode are finished, the function is re-invoked. It is then important to inform Prolog when there is no
more solution (i.e. no more choice) for a non-deterministic code. So, when no more choices remains
the function must remove the choice-point. The interface increments a counter each time the function
is re-invoked. At the first call this counter is equal to 0. This information allows the function to detect
its first call. When writing non-deterministic code, it is often useful to record data between consecutive
re-invocations of the function. The interface maintains a buffer to record such an information. The sizeof this buffer is given by choice size(N) when using foreign/2 (section 10.3.2, page 202). This size isthe number of (consecutive) PlLongs needed by the C function. Inside the function it is possible to callthe following functions/macros:

206

10

INTERFACING PROLOG AND C

int Pl_Get_Choice_Counter(void)
TYPE Pl_Get_Choice_Buffer (TYPE)
void Pl_No_More_Choice(void)The macro Pl Get Choice Counter() returns the value of the invocation counter (0 at the first call).
The macro Pl Get Choice Buffer(TYPE ) returns a pointer to the buffer (casted to TYPE ).
The function Pl No More Choice() deletes the choice point associated with the function.

10.3.8

Example: input and output arguments

All examples presented here can be found in the ExamplesC sub-directory of the distribution, in the files
examp.pl (Prolog part) and examp c.c (C part).
Let us define a predicate first occurrence(A, C, P) which unifies P with the position (from 0) of thefirst occurrence of the character C in the atom A. The predicate must fail if C does not appear in A.
In the prolog file examp.pl::- foreign(first occurrence(+string, +char, -positive)).
In the C file examp c.c:#include <string.h>#include <gprolog.h>
PlBoolfirst_occurrence(char *str, PlLong c, PlLong *pos){char *p;p = strchr(str, c);if (p == NULL)
return PL_FALSE;/* C does not appear in A *//* fail */*pos = p - str;
return PL_TRUE;/* set the output argument *//* succeed */}The compilation produces an executable called examp:% gplc examp.pl examp c.c
Examples of use:
| ?- first_occurrence(prolog, p, X).
X = 0| ?- first_occurrence(prolog, k, X).
no| ?- first_occurrence(prolog, A, X).
{exception: error(instantiation_error,first_occurrence/3)}

10.3

Calling C from Prolog

207| ?- first_occurrence(prolog, 1 ,X).
{exception: error(type_error(character,1),first_occurrence/3)}

10.3.9

Example: non-deterministic code

We here define a predicate occurrence(A, C, P) which unifies P with the position (from 0) of one
occurrence of the character C in the atom A. The predicate will fail if C does not appear in A. The predicate
is re-executable on backtracking. The information that must be recorded between two invocations of thefunction is the next starting position in A to search for C.
In the prolog file examp.pl::- foreign(occurrence(+string, +char, -positive), [choice size(1)]).
In the C file examp c.c:#include <string.h>#include <gprolog.h>
PlBooloccurrence(char *str, PlLong c, PlLong *pos){char **info_pos;char *p;info_pos = Pl_Get_Choice_Buffer(char **); /* recover the buffer */if (Pl_Get_Choice_Counter() == 0) /* first invocation ? */*info_pos = str;p = strchr(*info_pos, c);if (p == NULL){
Pl_No_More_Choice();return PL_FALSE;}*pos = p - str;
*info_pos = p + 1;
return PL_TRUE;/* c does not appear *//* remove choice-point *//* fail *//* set the output argument *//* update next starting pos *//* succeed */}The compilation produces an executable called examp:% gplc examp.pl examp c.c
Examples of use:

208

10

INTERFACING PROLOG AND C| ?- occurrence(prolog, o, X).
X = 2 ?

(here the user presses ; to compute another solution)

X = 4 ?

(here the user presses ; to compute another solution)no(no more solution)| ?- occurrence(prolog, k, X).
noIn the first example when the second (the last) occurrence is found (X=4) the choice-point remains andthe failure is detected only when another solution is requested (by pressing ;). It is possible to improve
this behavior by deleting the choice-point when there is no more occurrence. To do this it is necessary to
do one search ahead. The information stored is the position of the next occurrence. Let us define such abehavior for the predicate occurrence2/3.
In the prolog file examp.pl::- foreign(occurrence2(+string, +char, -positive), [choice size(1)]).
In the C file examp c.c:#include <string.h>#include <gprolog.h>
PlBooloccurrence2(char *str, PlLong c, PlLong *pos){char **info_pos;char *p;info_pos = Pl_Get_Choice_Buffer(char **); /* recover the buffer */if (Pl_Get_Choice_Counter() == 0) /* first invocation ? */{p = strchr(str, c);if (p == NULL)/* C does not appear at all */{Pl_No_More_Choice();/* remove choice-point */return PL_FALSE;/* fail */}*info_pos = p;}*pos = *info_pos - str;p = strchr(*info_pos + 1, c);if (p == NULL)
Pl_No_More_Choice();else*info_pos = p;
return PL_TRUE;}/* info_pos = an occurrence *//* set the output argument *//* no more occurrence *//* remove choice-point *//* else update next solution *//* succeed */10.3

Calling C from Prolog

209

Examples of use:
| ?- occurrence2(prolog, l, X).
X = 3(here the user is not prompted since there is no more alternative)| ?- occurrence2(prolog, o, X).
X = 2 ?

(here the user presses ; to compute another solution)

X = 4(here the user is not prompted since there is no more alternative)

10.3.10

Example: input/output arguments

We here define a predicate char ascii(Char, Code) which converts in both directions the character Charand its character-code Code. This predicate is then similar to char code/2 (section 8.19.4, page 130).
In the prolog file examp.pl::- foreign(char ascii(?char, ?code)).
In the C file examp c.c:#include <gprolog.h>
PlBoolchar_ascii(PlFIOArg *c, PlFIOArg *ascii){
if (!c->is_var)/* Char is not a variable */{ascii->unify = PL_TRUE;/* enforce unif. of Code */ascii->value.l = c->value.l; /* set Code */return PL_TRUE;/* succeed */}if (ascii->is_var)
Pl_Err_Instantiation();/* Code is also a variable *//* emit instantiation_error */c->value.l = ascii->value.l;
return PL_TRUE;/* set Char *//* succeed */}If Char is instantiated it is necessary to enforce the unification of Code since it could be instantiated.
Recall that by default if an input/output argument is instantiated it will not be unified at the exitof the function (section 10.3.6, page 205). If both Char and Code are variables the function raises an
instantiation error. The way to raise Prolog errors is described later (section 10.5, page 217).
The compilation produces an executable called examp:% gplc examp.pl examp c.c
Examples of use:
| ?- char_ascii(a, X).
X = 97

210

10

INTERFACING PROLOG AND C| ?- char_ascii(X, 65).
X = ’A’| ?- char_ascii(a, 12).
no| ?- char_ascii(X, X).
{exception: error(instantiation_error,char_ascii/2)}| ?- char_ascii(1, 12).
{exception: error(type_error(character,1),char_ascii/2)}

10.4

Manipulating Prolog terms

10.4.1Introduction

In the following we presents a set of functions to manipulate Prolog terms. For simple foreign terms thefunctions manipulate simple C types (section 10.3.2, page 202).
Functions managing lists handle an array of 2 elements (of type PlTerm) containing the terms corresponding to the head and the tail of the list. For the empty list NULL is passed as the array. These functions
require to flatten a list in each sub-list. To simplify the management of proper lists (i.e. lists terminatedby []) a set of functions is provided that handle the number of elements of the list (an integer) and anarray whose elements (of type PlTerm) are the elements of the list. The caller of these functions must
provide the array.
Functions managing compound terms handle a functor (the principal functor of the term), an arity N ≥0 and an array of N elements (of type PlTerm) containing the sub-terms of the compound term. Since
a list is a special case of compound term (functor = ’.’ and arity=2) it is possible to use any function
managing compound terms to deal with a list but the error detection is not the same. Indeed many
functions check if the Prolog argument is correct. The name of a read or unify function checking theProlog arguments is of the form Name Check(). For each of these functions there is a also check-freeversion called Name (). We then only present the name of checking functions.

10.4.2

Managing Prolog atoms

Each atom has a unique internal key (an integer) which corresponds to its index in the GNU Prolog atomtable. It is possible to obtain the information about an atom and to create new atoms using:char*Pl_Atom_Name(int atom)
int
Pl_Atom_Length(int atom)
PlBool Pl_Atom_Needs_Quote(int atom)
PlBool Pl_Atom_Needs_Scan(int atom)
PlBool Pl_Is_Valid_Atom(int atom)
int
Pl_Create_Atom(const char *str)
int
Pl_Create_Allocate_Atom(const char *str)
int
Pl_Find_Atom(const char *str)
int
Pl_Atom_Char(char c)

10.4

Manipulating Prolog terms

int
int
int
int

Pl_Atom_Nil
Pl_Atom_False
Pl_Atom_True
Pl_Atom_End_Of_File211(void)(void)(void)(void)

The function Pl Atom Name(atom) returns the internal string of atom (this string should not be modified).
The function Pl Atom Length(atom) returns the length (of the name) of atom.
The function Pl Atom Needs Scan(atom) indicates if the canonical form of atom needs to be quoted asdone by writeq/2 (section 8.14.6, page 108). In that case Pl Atom Needs Scan(atom) indicates if thissimply comes down to write quotes around the name of atom or if it necessary to scan each character ofthe name because there are some non-printable characters (or included quote characters). The function
Pl Is Valid Atom(atom) is true only if atom is the internal key of an existing atom.
The function Pl Create Atom(str) adds a new atom whose name is the content of str to the system
and returns its internal key. If the atom already exists its key is simply returned. The string str passed
to the function should not be modified later. The function Pl Create Allocate Atom(str) is provided
when this condition cannot be ensured. It simply makes a dynamic copy of str (using strdup(3)).
The function Pl Find Atom(str) returns the internal key of the atom whose name is str or -1 if it does
not exist.
All atoms corresponding to a single character already exist and their key can be obtained via the function
Pl Atom Char. For instance Pl Atom Char(’.’) is the atom associated with ’.’ (this atom is thefunctor of lists). The other functions return the internal key of frequently used atoms: [], false, trueand end of file.

10.4.3

Reading Prolog terms

The name of all functions presented here are of the form Pl Rd Name Check(). They all check the validityof the Prolog term to read emitting appropriate errors if necessary. Each function has a check-free version
called Pl Rd Name ().
Simple foreign types: for each simple foreign type (section 10.3.2, page 202) there is a read function(used by the interface when an input argument is provided):
PlLong Pl_Rd_Integer_Check(PlTerm term)
PlLong Pl_Rd_Positive_Check(PlTerm term)int
Pl_Rd_C_Int_Check(PlTerm term)int
Pl_Rd_C_Int_Positive_Check(PlTerm term)
double Pl_Rd_Float_Check(PlTerm term)
double Pl_Rd_Number_Check(PlTerm term)int
Pl_Rd_Atom_Check(PlTerm term)int
Pl_Rd_Boolean_Check(PlTerm term)int
Pl_Rd_Char_Check(PlTerm term)int
Pl_Rd_In_Char_Check(PlTerm term)int
Pl_Rd_Code_Check(PlTerm term)int
Pl_Rd_In_Code_Check(PlTerm term)int
Pl_Rd_Byte_Check(PlTerm term)int
Pl_Rd_In_Byte_Check(PlTerm term)char*Pl_Rd_String_Check(PlTerm term)char*Pl_Rd_Chars_Check(PlTerm term)char*Pl_Rd_Codes_Check(PlTerm term)int
Pl_Rd_Chars_Str_Check(PlTerm term, char *str)

212

10

int

Pl_Rd_Codes_Str_Check

INTERFACING PROLOG AND C(PlTerm term, char *str)

The function Pl Rd C Int Check() is similar to Pl Rd Integer Check() but returns a C int instead ofa PlLong. If the Prolog integer does not fit into a C int, a representation error is raised (this canoccur on 64-bits machine with int on 32-bits). Similarly for Pl Rd C Int Positive Check().
All functions returning a C string (char *) use a same buffer. The function Pl Rd Chars Str Check()is similar to Pl Rd Chars Check() but accepts as argument a string to store the result and returns thelength of that string (which is also the length of the Prolog list). Similarly for Pl Rd Codes Str Check().
Complex terms: the following functions return the sub-arguments (terms) of complex terms as an arrayof PlTerm except Pl Rd Proper List Check() which returns the size of the list read (and initializes thearray element). Refer to the introduction of this section for more information about the arguments ofcomplex functions (section 10.4.1, page 210).
int
Pl_Rd_Proper_List_Check(PlTerm term, PlTerm *arg)
PlTerm *Pl_Rd_List_Check(PlTerm term)
PlTerm *Pl_Rd_Compound_Check(PlTerm term, int *functor, int *arity)
PlTerm *Pl_Rd_Callable_Check(PlTerm term, int *functor, int *arity)

10.4.4

Unifying Prolog terms

The name of all functions presented here are of the form Pl Un Name Check(). They all check the validityof the Prolog term to unify emitting appropriate errors if necessary. Each function has a check-free version
called Pl Un Name ().
Simple foreign types: for each simple foreign type (section 10.3.2, page 202) there is an unify function(used by the interface when an output argument is provided):
PlBool Pl_Un_Integer_Check (PlLong n,
PlTerm term)
PlBool Pl_Un_Positive_Check(PlLong n,
PlTerm term)
PlBool Pl_Un_Float_Check(double n,
PlTerm term)
PlBool Pl_Un_Number_Check (double n,
PlTerm term)
PlBool Pl_Un_Atom_Check(int atom,
PlTerm term)
PlBool Pl_Un_Boolean_Check (int b,
PlTerm term)
PlBool Pl_Un_Char_Check(int c,PlTerm term)
PlBool Pl_Un_In_Char_Check (int c,
PlTerm term)
PlBool Pl_Un_Code_Check(int c,PlTerm term)
PlBool Pl_Un_In_Code_Check (int c,
PlTerm term)
PlBool Pl_Un_Byte_Check(int b,PlTerm term)
PlBool Pl_Un_In_Byte_Check (int b,
PlTerm term)
PlBool Pl_Un_String_Check (const char *str, PlTerm term)
PlBool Pl_Un_Chars_Check(const char *str, PlTerm term)
PlBool Pl_Un_Codes_Check(const char *str, PlTerm term)
The function Pl Un Number Check(n, term) unifies term with an integer if n is an integer, with a floating
point number otherwise. The function Pl Un String Check(str, term) creates the atom corresponding to str and then unifies term with it (same as Pl Un Atom Check(Pl Create Allocate Atom(str),term)).
The following functions perform a general unification (between 2 terms). The second one performs aoccurs-check test (while the first one does not).
PlBool Pl_Unif(PlTerm term1, PlTerm term2)
PlBool Pl_Unif_With_Occurs_Check(PlTerm term1, PlTerm term2)

10.4

Manipulating Prolog terms

213

Complex terms: the following functions accept the sub-arguments (terms) of complex terms as anarray of PlTerm. Refer to the introduction of this section for more information about the arguments ofcomplex functions (section 10.4.1, page 210).
PlBool Pl_Un_Proper_List_Check(int size, PlTerm *arg, PlTerm term)
PlBool Pl_Un_List_Check(PlTerm *arg, PlTerm term)
PlBool Pl_Un_Compound_Check(int functor, int arity, PlTerm *arg,
PlTerm term)
PlBool Pl_Un_Callable_Check(int functor, int arity, PlTerm *arg,
PlTerm term)
All these functions check the type of the term to unify and return the result of the unification. Generally
if an unification fails the C function returns PL FALSE to enforce a failure. However if there are several
arguments to unify and if an unification fails then the C function returns PL FALSE and the type of otherarguments has not been checked. Normally all error cases are tested before doing any work to be surethat the predicate fails/succeeds only if no error condition is satisfied. So a good method is to check thevalidity of all arguments to unify and later to do the unification (using check-free functions). Obviously
if there is only one to unify it is more efficient to use a unify function checking the argument. For theother cases the interface provides a set of functions to check the type of a term.
Simple foreign types: for each simple foreign type (section 10.3.2, page 202) there is check-forunification function (used by the interface when an output argument is provided):void Pl_Check_For_Un_Integer (PlTerm term)
void Pl_Check_For_Un_Positive(PlTerm term)
void Pl_Check_For_Un_Float(PlTerm term)
void Pl_Check_For_Un_Number (PlTerm term)
void Pl_Check_For_Un_Atom(PlTerm term)
void Pl_Check_For_Un_Boolean (PlTerm term)
void Pl_Check_For_Un_Char(PlTerm term)
void Pl_Check_For_Un_In_Char (PlTerm term)
void Pl_Check_For_Un_Code(PlTerm term)
void Pl_Check_For_Un_In_Code (PlTerm term)
void Pl_Check_For_Un_Byte(PlTerm term)
void Pl_Check_For_Un_In_Byte (PlTerm term)
void Pl_Check_For_Un_String (PlTerm term)
void Pl_Check_For_Un_Chars(PlTerm term)
void Pl_Check_For_Un_Codes(PlTerm term)
Complex terms: the following functions check the validity of complex terms:
void Pl_Check_For_Un_List(PlTerm term)
void Pl_Check_For_Un_Compound(PlTerm term)
void Pl_Check_For_Un_Callable(PlTerm term)
void Pl_Check_For_Un_Variable(PlTerm term)
The function Pl Check For Un List(term) checks if term can be unified with a list. This test is done
for the entire list (not only for the functor/arity of term but also recursively on the tail of the list).
The function Pl Check For Un Variable(term) ensures that term is not currently instantiated. These
functions can be defined using functions to test the type of a Prolog term (section 10.4.6, page 214) andfunctions to raise Prolog errors (section 10.5, page 217). For instance Pl Check For Un List(term) isdefined as follows:
void Pl_Check_For_Un_List(PlTerm term){if (!Pl_Builtin_List_Or_Partial_List(term))
Pl_Err_Type(type_list, term);
}

214

10

10.4.5INTERFACING PROLOG AND C

Creating Prolog terms

These functions are provided to creates Prolog terms. Each function returns a PlTerm containing thecreated term.
Simple foreign types: for each simple foreign type (section 10.3.2, page 202) there is a creation function:
PlTerm Pl_Mk_Integer (PlLong n)
PlTerm Pl_Mk_Positive(PlLong n)
PlTerm Pl_Mk_Float(double n)
PlTerm Pl_Mk_Number (double n)
PlTerm Pl_Mk_Atom(int atom)
PlTerm Pl_Mk_Boolean (int b)
PlTerm Pl_Mk_Char(int c)PlTerm Pl_Mk_In_Char (int c)
PlTerm Pl_Mk_Code(int c)PlTerm Pl_Mk_In_Code (int c)
PlTerm Pl_Mk_Byte(int b)PlTerm Pl_Mk_In_Byte (int b)
PlTerm Pl_Mk_String (const char *str)
PlTerm Pl_Mk_Chars(const char *str)
PlTerm Pl_Mk_Codes(const char *str)
The function Pl Mk Number(n, term) initializes term with an integer if n is an integer, with a floating
point number otherwise. The function Pl Mk String(str) first creates an atom corresponding to str
and then returns that Prolog atom (i.e. equivalent to Pl Mk Atom(Pl Create Allocate Atom(str))).
Complex terms: the following functions accept the sub-arguments (terms) of complex terms as anarray of PlTerm. Refer to the introduction of this section for more information about the arguments ofcomplex functions (section 10.4.1, page 210).
PlTerm Pl_Mk_Proper_List(int size, const PlTerm *arg)
PlTerm Pl_Mk_List(PlTerm *arg)
PlTerm Pl_Mk_Compound(int functor, int arity, const PlTerm *arg)
PlTerm Pl_Mk_Callable(int functor, int arity, const PlTerm *arg)

10.4.6

Testing the type of Prolog terms

The following functions test the type of a Prolog term. Each function corresponds to a type testingbuilt-in predicate (section 8.1.1, page 55).
PlBool Pl_Builtin_Var(PlTerm term)
PlBool Pl_Builtin_Non_Var(PlTerm term)
PlBool Pl_Builtin_Atom(PlTerm term)
PlBool Pl_Builtin_Integer(PlTerm term)
PlBool Pl_Builtin_Float(PlTerm term)
PlBool Pl_Builtin_Number(PlTerm term)
PlBool Pl_Builtin_Atomic(PlTerm term)
PlBool Pl_Builtin_Compound(PlTerm term)
PlBool Pl_Builtin_Callable(PlTerm term)
PlBool Pl_Builtin_List(PlTerm term)
PlBool Pl_Builtin_Partial_List(PlTerm term)
PlBool Pl_Builtin_List_Or_Partial_List(PlTerm term)
PlBool Pl_Builtin_Fd_Var(PlTerm term)

10.4

Manipulating Prolog terms

PlBool Pl_Builtin_Non_Fd_Var
PlBool Pl_Builtin_Generic_Var
PlBool Pl_Builtin_Non_Generic_Var
int
Pl_Type_Of_Term
PlLong
Pl_List_Length

215(PlTerm term)(PlTerm term)(PlTerm term)(PlTerm term)(PlTerm list)

The function Pl Type Of Term(term) returns the type of term, the following constants can be used totest this type (e.g. in a switch instruction):• PL PLV: Prolog variable.
• PL FDV: finite domain variable.
• PL INT: integer.
• PL FLT: floating point number.
• PL ATM: atom.
• PL LST: list.
• PL STC: structure
The tag PL LST means a term whose principal functor is ’.’ and whose arity is 2 (recall that the empty
list is the atom []). The tag PL STC means any other compound term.
The function Pl List Length(list) returns the number of elements of the list (0 for the empty list).
If list is not a list this function returns -1.

10.4.7Comparing Prolog terms

The following functions compares Prolog terms. Each function corresponds to a comparison built-in
predicate (section 8.3.2, page 57).
PlBool Pl_Builtin_Term_Eq (PlTerm term1, PlTerm term2)
PlBool Pl_Builtin_Term_Neq(PlTerm term1, PlTerm term2)
PlBool Pl_Builtin_Term_Lt (PlTerm term1, PlTerm term2)
PlBool Pl_Builtin_Term_Lte(PlTerm term1, PlTerm term2)
PlBool Pl_Builtin_Term_Gt (PlTerm term1, PlTerm term2)
PlBool Pl_Builtin_Term_Gte(PlTerm term1, PlTerm term2)
All these functions are based on a general comparison function returning a negative integer if term1 isless than term2, 0 if they are equal and a positive integer otherwise:
PlLong Term_Compare(PlTerm term1, PlTerm term2)
Finally, the following function gives an access to the compare/3 built-in (section 8.3.3, page 58) unifying
cmp with the atom <, = or > depending on the result of the comparison of term1 and term2.
PlBool Pl_Builtin_Compare(PlTerm cmp, PlTerm term1, PlTerm term2)

10.4.8Term processing

The following functions give access to the built-in predicates: functor/3 (section 8.4.1, page 59), arg/3(section 8.4.2, page 59) and (=..)/2 (section 8.4.3, page 60).

216

10

INTERFACING PROLOG AND C

PlBool Pl_Builtin_Functor(PlTerm term, PlTerm functor, PlTerm arity)
PlBool Pl_Builtin_Arg(PlTerm arg_no, PlTerm term, PlTerm sub_term)
PlBool Pl_Builtin_Univ(PlTerm term, PlTerm list)
The following functions make a copy of a Prolog term:
void Pl_Copy_Term(PlTerm *dst_term, const PlTerm *src_term)
void Pl_Copy_Contiguous_Term(PlTerm *dst_term, const PlTerm *src_term)
int Pl_Term_Size(PlTerm term)
The function Pl Copy Term(dst term, src term) makes a copy of the term located at src term andstores it from the address given by dst term. The result is a contiguous term. If it can be ensured that thesource term is a contiguous term (i.e. result of a previous copy) the function Pl Copy Contiguous Term()
can be used instead (it is faster). In any case, sufficient space should be available for the copy (i.e. fromdst term). The function Pl Term Size(term) returns the number of PlTerm needed by term.
The following function is an utility to display a term to the console, similarly to the built-in predicate
write/1 (section 8.14.6, page 108).
void Pl_Write(PlTerm term)This Pl Write function can be used for debugging purpose. However, it is more flexible to receive thecontent of the write/1 as a C string. This can be achieved by the following functions (using repectively
write/1, writeq/1, write canonical/1 and display/1 (section 8.14.6, page 108) to obtain a textual
representation of the term). These functions return a dynamically allocated C string (using malloc(3))
which can be freed by the user when no longer needed.
char *Pl_Write_To_String(PlTerm term)
char *Pl_Writeq_To_String(PlTerm term)
char *Pl_Write_Canonical_To_String(PlTerm term)
char *Pl_Display_To_String(PlTerm term)
Finally the following function performs the opposite converstion: given a C string it returns the associated
Prolog term. It uses read term/2 (section 8.14.1, page 104) with the option end of term(eof) (thus theC string does not need to terminate by a dot).
PlTerm Pl_Read_From_String(const char *str)

10.4.9Comparing and evaluating arithmetic expressions

The following functions compare arithmetic expressions. Each function corresponds to a comparison
built-in predicate (section 8.6.3, page 69).
PlBool Pl_Builtin_Eq (PlTerm expr1, PlTerm expr2)
PlBool Pl_Builtin_Neq(PlTerm expr1, PlTerm expr2)
PlBool Pl_Builtin_Lt (PlTerm expr1, PlTerm expr2)
PlBool Pl_Builtin_Lte(PlTerm expr1, PlTerm expr2)
PlBool Pl_Builtin_Gt (PlTerm expr1, PlTerm expr2)
PlBool Pl_Builtin_Gte(PlTerm expr1, PlTerm expr2)
The following function evaluates the expression expr and stores its result as a Prolog number (integer or
floating point number) in result:void Pl_Math_Evaluate(PlTerm expr, PlTerm *result)This function can be followed by a read function (section 10.4.3, page 211) to obtain the result.

10.5

Raising Prolog errors

10.5

217

Raising Prolog errors

The following functions allows a C function to raise a Prolog error. Refer to the section concerning Prolog
errors for more information about the effect of raising an error (section 6.3, page 39).

10.5.1

Managing the error context

When one of the following error function is invoked it refers to the implicit error context (section 6.3.1,
page 39). This context indicates the name and the arity of the concerned predicate. When using aforeign/2 declaration this context is set by default to the name and arity of the associated Prolog
predicate. This can be controlled using the bip name option (section 10.3.2, page 202). In any case, thefollowing functions can also be used to modify this context:
void Pl_Set_C_Bip_Name (const char *functor, int arity)
void Pl_Unset_C_Bip_Name(void)
The function Pl Set C Bip Name(functor, arity) initializes the context of the error with functor andarity (if arity<0 only functor is significant). The function Pl Unset C Bip Name() removes suchan initialization (the context is then reset to the last Functor/Arity set by a call to set bip name/2(section 8.22.3, page 151). This is useful when writing a C routine to define a context for errors occurringin this routine and, before exiting to restore the previous context.

10.5.2

Instantiation error

The following function raises an instantiation error (section 6.3.2, page 39):
void Pl Err Instantiation(void)10.5.3

Uninstantiation error

The following function raises an uninstantiation error (section 6.3.3, page 40):
void Pl Err Uninstantiation( PlTerm culprit)

10.5.4

Type error

The following function raises a type error (section 6.3.4, page 40):
void Pl Err Type(int atom type, PlTerm culprit)
atom type is (the internal key of) the atom associated with the expected type. For each type name T
there is a corresponding predefined atom stored in a global variable whose name is of the form pl type T .
culprit is the argument which caused the error.
Example: x is an atom while an integer was expected: Pl Err Type(pl type integer, x).

10.5.5

Domain error

The following function raises a domain error (section 6.3.5, page 40):

218

10

INTERFACING PROLOG AND C

void Pl Err Domain(int atom domain, PlTerm culprit)
atom domain is (the internal key of) the atom associated with the expected domain. For each domainname D there is a corresponding predefined atom stored in a global variable whose name is of the form
domain D . culprit is the argument which caused the error.
Example: x is < 0 but should be ≥ 0: Pl Err Domain(pl domain not less than zero, x).

10.5.6

Existence error

The following function raises an existence error (section 6.3.6, page 41):
void Pl Err Existence(int atom object, PlTerm culprit)
atom object is (the internal key of) the atom associated with the type of the object. For each object
name O there is a corresponding predefined atom stored in a global variable whose name is of the form
pl existence O . culprit is the argument which caused the error.
Example: x does not refer to an existing source: Pl Err Existence(pl existence source sink, x).

10.5.7

Permission error

The following function raises a permission error (section 6.3.7, page 41):
void Pl Err Permission(int atom operation, int atom permission, PlTerm culprit)
atom operation is (the internal key of) the atom associated with the operation which caused the error.
For each operation name O there is a corresponding predefined atom stored in a global variable whosename is of the form pl permission operation O . atom permission is (the internal key of) the atom
associated with the tried permission. For each permission name P there is a corresponding predefinedatom stored in a global variable whose name is of the form pl permission type P . culprit is theargument which caused the error.
Example: reading from an output stream x: Pl Err Permission(pl permission operation input,
pl permission type stream, x).

10.5.8

Representation error

The following function raises a representation error (section 6.3.8, page 41):
void Pl Err Representation(int atom limit)
atom limit is (the internal key of) the atom associated with the reached limit. For each limit name
L there is a corresponding predefined atom stored in a global variable whose name is of the form
pl representation L .
Example: an arity too big occurs: Pl Err Representation(pl representation max arity).

10.5.9Evaluation error

The following function raises an evaluation error (section 6.3.9, page 42):

10.5

Raising Prolog errors

219

void Pl Err Evaluation(int atom error)
atom error is (the internal key of) the atom associated with the error. For each evaluation error
name E there is a corresponding predefined atom stored in a global variable whose name is of the form
pl evaluation E .
Example: a division by zero occurs: Pl Err Evaluation(pl evaluation zero divisor).

10.5.10

Resource error

The following function raises a resource error (section 6.3.10, page 42):void Pl Err Resource(int atom resource)
atom resource is (the internal key of) the atom associated with the resource. For each resource error
name R there is a corresponding predefined atom stored in a global variable whose name is of the form
pl resource R .
Example: too many open streams: Pl Err Resource(pl resource too many open streams).

10.5.11

Syntax error

The following function raises a syntax error (section 6.3.11, page 42):void Pl Err Syntax(int atom error)
atom error is (the internal key of) the atom associated with the error. There is no predefined syntax
error atoms.
Example: a / is expected: Pl Err Syntax(Pl Create Atom("/ expected")).
The following function emits a syntax error according to the value of the syntax error Prolog flag
(section 8.22.1, page 148). This function can then return (if the value of the flag is either warning orfail). In that case the calling function should fail (e.g. returning PL FALSE). This function accepts
a file name (the empty string C "" can be passed), a line and column number and an error message
string. Using this function makes it possible to further call the built-in predicate syntax error info/4(section 8.14.4, page 107):
void Pl Emit Syntax Error(char *file name, int line, int column, char *message)
Example: a / is expected: Pl Emit Syntax Error("data", 10, 30, "/ expected").

10.5.12System error

The following function raises a system error (4.3.11, page *):void Pl Err System(int atom error)
atom error is (the internal key of) the atom associated with the error. There is no predefined systemerror atoms.
Example: an invalid pathname is given: Pl Err System(Pl Create Atom("invalid path name")).

220

10

INTERFACING PROLOG AND C

The following function emits a system error associated with an operating system error according to thevalue of the os error Prolog flag (section 8.22.1, page 148). This function can then return (if the value ofthe flag is either warning or fail). In that case the calling function should fail (e.g. returning PL FALSE).
The following function uses the value of the errno C library variable (basically it calls Pl Err Systemwith the result of strerror(errno)).
void Pl Os Error(void)
Example: if a call to the C Unix function chdir(2) returns -1 then call Os Error().

10.6

Calling Prolog from C

10.6.1Introduction

The following functions allows a C function to call a Prolog predicate:
void
int
int

Pl_Query_Begin
Pl_Query_Call
Pl_Query_Start(PlBool recoverable)(int functor, int arity, PlTerm *arg)(int functor, int arity, PlTerm *arg,
PlBool recoverable)
int
Pl_Query_Next_Solution(void)
void
Pl_Query_End(int op)
PlTerm Pl_Get_Exception(void)
void
Pl_Exec_Continuation (int functor, int arity, PlTerm *arg)
void
Pl_Throw(PlTerm ball)

The invocation of a Prolog predicate should be done as follows:• open a query using Pl Query Begin()• compute the first solution using Pl Query Call()• eventually compute next solutions using Pl Query Next Solution()• close the query using Pl Query End()The function Pl Query Begin(recoverable) is used to initialize a query. The argument recoverable
shall be set to PL TRUE if the user wants to recover, at the end of the query, the memory space consumed
by the query (in that case an additional choice-point is created). All terms created in the heap, e.g. using
Pl Mk ... family functions (section 10.4.5, page 214), after the invocation of Pl Query Begin() can berecovered when calling Pl Query End(PL TRUE) (see below).
The function Pl Query Call(functor, arity, arg) calls a predicate passing arguments. It is thenused to compute the first solution. The arguments functor, arity and arg are similar to those of thefunctions handling complex terms (section 10.4.1, page 210). This function returns:• PL FAILURE (a constant equal to PL FALSE, i.e. 0) if the query fails.
• PL SUCCESS (a constant equal to PL TRUE, i.e. 1) in case of success. In that case the argument arrayarg can be used to obtain the unification performed by the query.
• PL EXCEPTION (a constant equal to 2). In that case function Pl Get Exception() can be used toobtained the exceptional term raised by throw/1 (section 7.2.4, page 53).

10.6

Calling Prolog from C

221

The function Pl Query Start(functor, arity, arg, recoverable) is a shorthand equivalent to a callto Pl Query Begin(recoverable) followed by a call to Pl Query Call(functor, arity, arg).
The function Pl Query Next Solution() is used to compute a new solution. It must be only used if
the result of the previous solution was PL SUCCESS. This functions returns the same kind of values as
Pl Query Call() (see above).
The function Pl Query End(op) is used to finish a query. This function mainly manages the remaining
alternatives of the query. However, even if the query has no alternatives this function must be used tocorrectly finish the query. The value of op is:• PL RECOVER: to recover the memory space consumed by the query. After that the state of Prolog
stacks is exactly the same as before opening the query. To use this option the query must havebeen initialized specifying PL TRUE for recoverable (see above).
• PL CUT: to cut remaining alternatives. The effect of this option is similar to a cut after the query.
• PL KEEP FOR PROLOG: to keep the alternatives for Prolog. This is useful when the query was invoked
in a foreign C function. In that case, when the predicate corresponding to the C foreign function
is invoked a query is executed and the remaining alternatives are then available as alternatives ofthat predicate.
Note that several queries can be nested since a stack of queries is maintained. For instance, it is possible
to call a query and before terminating it to call another query. In that case the first execution of
Pl Query End() will finish the second query (i.e. the inner) and the next execution of Pl Query End()will finish the first query.
The function Pl Exec Continuation(functor, arity, arg) replaces the current calculus by the execution of the specified predicate. The arguments functor, arity and arg are similar to those of thefunctions handling complex terms (section 10.4.1, page 210).
Finally the function Pl Throw(ball) throws an exception. See the throw/1 control construct for more
information on exceptions (section 7.2.4, page 53). Note that Pl Throw(ball) is logically equivalent (butfaster) to Pl Exec Continuation(Pl Find Atom("throw"), 1, &ball) .

10.6.2

Example: my call/1 - a call/1 clone

We here define a predicate my call(Goal) which acts like call(Goal) except that we do not handle
exceptions (if an exception occurs the goal simply fails):
In the prolog file examp.pl::- foreign(my call(term)).
In the C file examp c.c:#include <string.h>#include <gprolog.h>
PlBoolmy_call(PlTerm goal){
PlTerm *arg;
int functor, arity;

222

10

INTERFACING PROLOG AND C

int result;arg = Pl_Rd_Callable_Check(goal, &functor, &arity);
Pl_Query_Begin(PL_FALSE);
result = Pl_Query_Call(functor, arity, arg);
Pl_Query_End(PL_KEEP_FOR_PROLOG);
return (result == PL_SUCCESS);}The compilation produces an executable called examp:% gplc examp.pl examp c.c
Examples of use:
| ?- my call(write(hello)).
hello| ?- my call(for(X,1,3)).
X = 1 ?

(here the user presses ; to compute another solution)

X = 2 ?

(here the user presses ; to compute another solution)

X = 3(here the user is not prompted since there is no more alternative)| ?- my call(1).
{exception: error(type error(callable,1),my call/1)}| ?- my call(call(1)).
noWhen my call(1) is called an error is raised due to the use of Pl Rd Callable Check(). However theerror raised by my call(call(1)) is ignored and PL FALSE (i.e. a failure) is returned by the foreignfunction.
To really simulate the behavior of call/1 when an exception is recovered it should be re-raised to be
captured by an earlier handler. The idea is then to execute a throw/1 as the continuation. This is what
it is done by the following code:#include <string.h>#include <gprolog.h>
PlBoolmy_call(PlTerm goal){
PlTerm *args;
int functor, arity;
int result;args = Pl_Rd_Callable_Check(goal, &functor, &arity);
Pl_Query_Begin(PL_FALSE);
result = Pl_Query_Call(functor, arity, args);
Pl_Query_End(PL_KEEP_FOR_PROLOG);
if (result == PL_EXCEPTION)
{

10.6

Calling Prolog from C

223

PlTerm except = Pl_Get_Exception();
Pl_Throw(except);// equivalent to Pl_Exec_Continuation(Find_Atom("throw"), 1, &except);}
return result;}
The following code propagates the error raised by call/1.
| ?- my call(call(1)).
{exception: error(type error(callable,1),my call/1)}
Finally note that a simpler way to define my call/1 is to use Pl Exec Continuation() as follows:#include <string.h>#include <gprolog.h>
PlBoolmy_call(PlTerm goal){
PlTerm *args;
int functor, arity;
args = Pl_Rd_Callable_Check(goal, &functor, &arity);
Pl_Exec_Continuation(functor, arity, args);
return PL_TRUE;}

10.6.3

Example: recovering the list of all operators

We here define a predicate all op(List) which unifies List with the list of all currently defined operators
as would be done by: findall(X,current op( , ,X),List).
In the prolog file examp.pl::- foreign(all op(term)).
In the C file examp c.c:#include <string.h>#include <gprolog.h>
PlBoolall_op(PlTerm list){
PlTerm op[1024];
PlTerm args[3];int n = 0;
int result;
Pl_Query_Begin(PL_TRUE);
args[0] = Pl_Mk_Variable();args[1] = Pl_Mk_Variable();args[2] = Pl_Mk_Variable();result = Pl_Query_Call(Find_Atom("current_op"), 3, args);

224

10

INTERFACING PROLOG AND C

while (result){op[n++] = Pl_Mk_Atom(Pl_Rd_Atom(args[2])); /* arg[2]: the name of the op */result = Pl_Query_Next_Solution();}
Pl_Query_End(PL_RECOVER);
return Pl_Un_Proper_List_Check(n, op, list);}
Note that we know here that there is no source for exception. In that case the result of Pl Query Calland Pl Query Next Solution can be considered as a boolean.
The compilation produces an executable called examp:% gplc examp.pl examp c.c
Example of use:
| ?- all_op(L).
L = [:-,:-,\=,=:=,#>=,#<#,@>=,-->,mod,#>=#,**,*,+,+,’,’,...]| ?- findall(X,current_op(_,_,X),L).
L = [:-,:-,\=,=:=,#>=,#<#,@>=,-->,mod,#>=#,**,*,+,+,’,’,...]

10.7

Defining a new C main() function

GNU Prolog allows the user to define his own main() function. This can be useful to perform several
tasks before starting the Prolog engine. To do this simply define a classical main(argc, argv) function.
The following functions can then be used:
int
Pl_Start_Prolog(int argc, char *argv[])
void
Pl_Stop_Prolog(void)
void
Pl_Reset_Prolog(void)PlBool Pl_Try_Execute_Top_Level(void)
The function Pl Start Prolog(argc, argv) initializes the Prolog engine (argc and argv are the commandline variables). This function collects all linked objects (issued from the compilation of Prolog files) andinitializes them. The initialization of a Prolog object file consists in adding to appropriate tables new
atoms, new predicates and executing its system directives. A system directive is generated by the Prolog
to WAM compiler to reflect a (user) directive executed at compile-time such as op/3 (section 7.1.11,
page 49). Indeed, when the compiler encounters such a directive it immediately executes it and also
generates a system directive to execute it at the start of the executable. When all system directives havebeen executed the Prolog engine executes all initialization directives defined with initialization/1(section 7.1.14, page 50). The function returns the number of user directives (i.e. initialization/1)
executed. This function must be called only once.
The function Pl Stop Prolog() stops the Prolog engine. This function must be called only once after
all Prolog treatment have been done.
The function Pl Reset Prolog() reinitializes the Prolog engine (i.e. reset all Prolog stacks).
The function Pl Try Execute Top Level() executes the top-level if linked (section 4.4.3, page 23) andreturns PL TRUE. If the top-level is not present the functions returns PL FALSE.

10.7

Defining a new C main() function

225

Here is the definition of the default GNU Prolog main() function:
static int
Main_Wrapper(int argc, char *argv[]){
int nb_user_directive;
PlBool top_level;nb_user_directive = Pl_Start_Prolog(argc, argv);
top_level = Pl_Try_Execute_Top_Level();
Pl_Stop_Prolog();if (top_level || nb_user_directive)
return 0;
fprintf(stderr,"Warning: no initial goal executed\n""use a directive :- initialization(Goal)\n""or remove the link option --no-top-level"" (or --min-bips or --min-size)\n");return 1;}
intmain(int argc, char *argv[]){
return Main_Wrapper(argc, argv);}
Note that under some circumstances it is necessary to encapsulate the code of main() inside an intermediate function called by main(). Indeed, some C compilers (e.g. gcc) treats main() particularly, producing
an incompatible code w.r.t GNU Prolog. So it is a good idea to always use a wrapper function as shown
above.

10.7.1

Example: asking for ancestors

In this example we use the following Prolog code (in a file called new main.pl):parent(bob,mary).
parent(jane, mary).
parent(mary, peter).
parent(paul, peter).
parent(peter, john).
anc(X, Y):parent(X, Y).
anc(X, Z) :parent(X, Y),
anc(Y, Z).

226

10

INTERFACING PROLOG AND C

The following file (called new main c.c) defines a main() function read the name of a person and displaying all successors of that person. This is equivalent to the Prolog query: anc(Result, Name).
static int
Main_Wrapper(int argc, char *argv[]){
int func;
PlTerm arg[10];char str[100];char *sol[100];
int i, nb_sol = 0;
PlBool res;
Pl_Start_Prolog(argc, argv);
func = Pl_Find_Atom("anc");for (;;){
printf("\nEnter a name (or ’end’ to finish): ");fflush(stdout);
scanf("%s", str);
if (strcmp(str, "end") == 0)
break;
Pl_Query_Begin(PL_TRUE);
arg[0] = Pl_Mk_Variable();arg[1] = Pl_Mk_String(str);
nb_sol = 0;
res = Pl_Query_Call(func, 2, arg);
while (res){sol[nb_sol++] = Pl_Rd_String(arg[0]);res = Pl_Query_Next_Solution();}
Pl_Query_End(PL_RECOVER);
for (i = 0; i < nb_sol; i++)printf(" solution: %s\n", sol[i]);printf("%d solution(s)\n", nb_sol);}
Pl_Stop_Prolog();
return 0;}
int
main(int argc, char *argv[]){
return Main_Wrapper(argc, argv);}
The compilation produces an executable called new main:% gplc new main.pl new main c.c10.7

Defining a new C main() function

Examples of use:
Enter a name (or ’end’ to finish): johnsolution: peter
solution: bob
solution: jane
solution: marysolution: paul
5 solution(s)Enter a name (or ’end’ to finish): marysolution: bob
solution: jane
2 solution(s)Enter a name (or ’end’ to finish): end

227

228

10

INTERFACING PROLOG AND C

REFERENCES

References[1] H. Aı̈t-Kaci. “Warren’s Abstract Machine, A Tutorial Reconstruction”.
Logic Programming Series, MIT Press, 1991.
http://web.archive.org/web/20071225092145/www.vanx.org/archive/wam/wam.html[2] W.F. Clocksin and C.S. Mellish. Programming in Prolog, Springer-Verlag, 1981.
[3] P. Codognet and D. Diaz. “wamcc: Compiling Prolog to C”.
In 12th International Conference on Logic Programming, Tokyo, Japan, MIT Press, 1995.
http://cri-dist.univ-paris1.fr/diaz/publications/WAMCC/iclp95.pdf[4] P. Codognet and D. Diaz. “Compiling Constraint in clp(FD)”.
Journal of Logic Programming, Vol. 27, No. 3, June 1996.
http://cri-dist.univ-paris1.fr/diaz/publications/CLP-FD/jlp96.pdf[5] D. Diaz and P. Codognet. “Design and Implementation of the GNU Prolog System”.
Journal of Functional and Logic Programming, Vol. 2001, No. 6, October 2001.
http://cri-dist.univ-paris1.fr/diaz/publications/GNU-PROLOG/jflp01.pdf[6] Information technology - Programming languages - Prolog - Part 1: General Core.
ISO/IEC 13211-1, 1995.
[7] J. Jaffar and J-L. Lassez. “Constraint Logic Programming”.
In Principles Of Programming Languages, Munich, Germany, January 1987.
[8] P. Van Hentenryck. “Constraint Satisfaction in Logic Programming”.
Logic Programming Series, The MIT Press, 1989.
[9] D. H. D. Warren. “An Abstract Prolog Instruction Set”.
Technical Report 309, SRI International, Oct. 1983.

229

230

REFERENCESINDEX

231

Index!/0, 51, 52’.’/2, 153(’,’)/2, 51(*->)/2, 51(-->)/2, 123(->)/2, 51(;)/2, 51(=)/2, 56(=..)/2, 60(=:=)/2, 69(==)/2, 57, 136(=<)/2, 69(=\=)/2, 69(@=<)/2, 57(@<)/2, 57(@>)/2, 57(@>=)/2, 57(#/\)/2 (FD), 193(#=)/2 (FD), 189(#==>)/2 (FD), 193(#=#)/2 (FD), 190(#=<)/2 (FD), 189(#=<#)/2 (FD), 190(##)/2 (FD), 193(#<)/2 (FD), 189(#<=>)/2 (FD), 193(#<#)/2 (FD), 190(#>)/2 (FD), 189(#>=)/2 (FD), 189(#>=#)/2 (FD), 190(#>#)/2 (FD), 190(#\)/1 (FD), 193(#\/)/2 (FD), 193(#\/\)/2 (FD), 193(#\=)/2 (FD), 189(#\==>)/2 (FD), 193(#\=#)/2 (FD), 190(#\<=>)/2 (FD), 193(#\\/)/2 (FD), 193(is)/2, 69(<)/2, 69(>)/2, 69(>=)/2, 69(\+)/1, 126(\=)/2, 57(\==)/2, 57--, 13--assembly, 23--aux-father, 29--aux-father2, 29--c-compiler, 24--cmd-line, 29--comment, 24, 24--compile-msg, 24--consult-file, 13--cstr-size, 25--decode, 29--demangling, 29--encode, 29--entry-goal, 13--fast-math, 24, 68--fd-to-c, 23--fixed-sizes, 21, 25--foreign-only, 24--global-size, 25--gui-console, 25--help, 13, 23, 29--init-goal, 13, 28--keep-void-inst, 24--linker, 25--local-size, 21, 25--mangling, 29--max-atom, 25--min-bips, 25--min-fd-bips, 25--min-pl-bips, 25--min-reg-opt, 24--min-size, 25--mini-assembly, 23--new-top-level, 25, 28--no-call-c, 24--no-debugger, 25, 25--no-del-temp, 23--no-demangling, 23--no-fd-lib, 25--no-inline, 24--no-opt-last-subterm, 24--no-redef-error, 24--no-reg-opt, 24--no-reorder, 24--no-singl-warn, 24--no-susp-warn, 24--no-top-level, 25--object, 23--output, 23--pic, 24--pl-state, 24, 152--printf, 29--query-goal, 13--relax, 29--statistics, 24--strip, 25

232--temp-dir, 23--trail-size, 25--verbose, 23--version, 13, 23, 29--wam-comment, 24--wam-for-byte-code, 23--wam-for-native, 23-A, 24-C, 24-D, 29-E, 29-F, 23-L, 25-M, 23, 29-P, 29-S, 23-W, 23-c, 23-h, 23-o, 23-s, 25-v, 23-w, 23abolish/1, 73
abort/0, 18, 34, 126
absolute file name (property), 165
absolute file name/2, 48, 81, 153, 154, 158,
159, 160, 162–167
acyclic term/1, 61
add linedit completion/1, 181
add stream alias/2, 78, 90
add stream mirror/2, 79, 91
address bits (flag), 149alias (option), 81
alias (property), 84
append (mode), 81
append/1, 121
append/3, 135
arch (flag), 149
architecture/1, 168
arg/3, 59
argument selector, 142
argument counter/1, 160
argument list/1, 14, 161
argument value/2, 14, 160
argv (flag), 149
asserta/1, 71
assertz/1, 71
at end of stream/0, 85
at end of stream/1, 85
atom/1, 55
atom chars/2, 131
atom codes/2, 131

INDEX

atom concat/3, 129
atom length/2, 129
atom property/2, 134
atomic/1, 55
back quotes (flag), 14, 104, 150, 152back quotes (token), 106
backtracks (FD option), 199
bagof/3, 77
between/3, 128
binary (option), 81, 92
bind variables/2, 64
bip name (option), 203, 217
bisect (FD option), 198
block (option), 82, 93
block device (permission), 165
bof (whence), 87
boolean (option), 202, 204
bounded (flag), 149
bounds (FD option), 198
break/0, 18, 34, 126
buffering (option), 81
buffering (property), 84
built in (property), 48, 75
built in/0 (directive), 47
built in/1 (directive), 47
built in fd (property), 48, 75
built in fd/0 (directive), 47
built in fd/1 (directive), 47
c cc (flag), 149
c cc version data (flag), 149c cflags (flag), 149
c ldflags (flag), 149
call/1, 52
call/2-11, 126
call det/2, 126
call with args/1-11, 126
callable/1, 55
catch/3, 31, 39, 53
change directory/1, 162
char code/2, 130, 209
char conversion (flag), 104, 116, 150, 152char conversion/2 (directive), 49
char conversion/2, 50, 116
character count/2, 87
character device (permission), 165
choice size (option), 203, 205
clause/2, 73
close/1, 82
close/2, 82, 171, 177close input atom stream/1, 95
close input chars stream/1, 95
close input codes stream/1, 95
close output atom stream/2, 96

INDEX

close output chars stream/2, 96
close output codes stream/2, 96
compare/3, 58
compiled at (flag), 149
completion, 19, 181
compound/1, 55
consult/1, 17, 21, 23, 153
control constructs, 51
control construct (property), 75
copy term/2, 60
cpu time/1, 155
create pipe/2, 172
current (whence), 87
current alias/2, 90
current atom/1, 134
current bip name/2, 39, 151
current char conversion/2, 116
current input/1, 79
current mirror/2, 92
current op/3, 115
current output/1, 79
current predicate/1, 72, 74
current prolog flag/2, 151
current stream/1, 83
date time/1, 167
debug (flag), 150
debug/0 (debug), 17, 18, 31
debugging/0 (debug), 31, 34
decompose file name/4, 159
Definite clause grammars, see DCG
delete/3, 136delete directory/1, 162
delete file/1, 163
demangling, 26
dialect (flag), 149
directory (permission), 165
directory files/2, 162discontiguous/1 (directive), 46
display/1, 108
display/2, 108, 119, 120
display to atom/2, 118
display to chars/2, 119
display to codes/2, 120
double quotes (flag), 104, 150, 152
dynamic (property), 75
dynamic/1 (directive), 45, 70
elif/1 (directive), 48
else/0 (directive), 48
end of stream (property), 84
end of term (option), 104
endif/0 (directive), 48
ensure linked/1 (directive), 47
ensure loaded/1 (directive), 49

233

environ/2, 161eof (whence), 87
eof action (option), 81
eof action (property), 84
eof code (option), 81, 93
error (option), 81, 93, 104
escape sequence, 14, 134, 150, 150
exclude (option), 65
exec/4, 171
exec/5, 171
execute (permission), 164
expand term/2, 124
extended (token), 106
extra-constrained, see extra cstr
extra cstr (FD), 183, 188
fail (option), 104
fail/0, 51, 127false/0, 126
fct name (option), 202
fd all different/1 (FD), 195
fd at least one/1 (FD), 194
fd at most one/1 (FD), 194
fd atleast/3 (FD), 196
fd atmost/3 (FD), 196
fd cardinality/2 (FD), 194, 196
fd cardinality/3 (FD), 194
fd dom/2 (FD), 187
fd domain/2 (FD), 186
fd domain/3 (FD), 185
fd domain bool/1 (FD), 185
fd element/3 (FD), 195
fd element var/3 (FD), 196
fd exactly/3 (FD), 196
fd has extra cstr/1 (FD), 188
fd has vector/1 (FD), 188
fd labeling/1 (FD), 198
fd labeling/2 (FD), 198, 199
fd labelingff/1 (FD), 198
fd max/2 (FD), 187
fd max integer (FD), 183, 184
fd max integer/1 (FD), 184
fd maximize/2 (FD), 199
fd min/2 (FD), 187
fd minimize/2 (FD), 199
fd not prime/1 (FD), 191
fd only one/1 (FD), 194
fd prime/1 (FD), 191
fd reified in/4 (FD), 192
fd relation/2 (FD), 197
fd relationc/2 (FD), 197
fd set vector max/1 (FD), 183, 185
fd size/2 (FD), 187
fd use vector/1 (FD), 188

234

INDEX

fd var/1 (FD), 187
fd vector max/1 (FD), 183, 185
fifo (permission), 165
file exists/1, 164
file name (property), 84
file permission/2, 164
file property/2, 165
find linedit completion/2, 181
findall/3, 76
findall/4, 76
first fail (FD option), 198flag, see Prolog flag
flatten/2, 138
float/1, 55
flush output/0, 83
flush output/1, 79, 83
for/3, 128
forall/2, 126
force (option), 83
foreign/1 (directive), 50, 202
foreign/2 (directive), 50, 202
fork prolog/1, 172
format/2, 110
format/3, 110, 119, 120
format to atom/3, 118
format to chars/3, 119
format to codes/3, 120
from (option), 64
full (debug), 32
functor/3, 59

get byte/1, 101
get byte/2, 78, 101
get char/1, 97
get char/2, 97
get code/1, 97
get code/2, 97, 98
get key/1, 98
get key/2, 98
get key no echo/1, 98
get key no echo/2, 98
get linedit prompt/1, 180
get print stream/1, 113
get seed/1, 156
gplc, 23, 26, 28, 29, 152
ground/1, 55
GUI console, 20, 25

g array (global var.), 142
g array auto (global var.), 142
g array extend (global var.), 142
g array size/2, 144
g assign/2, 143
g assignb/2, 143
g dec/1, 144
g dec/2, 144
g dec/3, 144
g deco/2, 144g inc/1, 144g inc/2, 144g inc/3, 144g inco/2, 144g link/2, 143
g read/2, 143
g reset bit/2, 145
g set bit/2, 145
g test reset bit/2, 145
g test set bit/2, 145
generic var/1 (FD), 187
get/1, 122
get0/1, 122

if/1 (directive), 48
ignore ops (option), 108
include/1 (directive), 48
infix op (property), 134
initialization/1 (directive), 26, 27, 50, 224
input (property), 84
integer/1, 55
integer rounding function (flag), 68, 149
interpreter, see top-levelis absolute file name/1, 158
is list/1, 55
is relative file name/1, 158

half (debug), 32
halt/0, 14, 18, 126
halt/1, 126
hash (property), 134
hash code, 62, 134
hexgplc, 29
home (flag), 149
host (flag), 149
host cpu (flag), 149
host name/1, 168
host os (flag), 149
host vendor (flag), 149
hostname address/2, 179

jump (option), 202, 204
keysort/1, 140
keysort/2, 140
largest (FD option), 198
last/2, 138
last modification (property), 165
last read start line column/2, 107
leash/1 (debug), 32, 33
length (property), 134

INDEX

length/2, 139line (option), 82, 93
line count/2, 88, 89
line position/2, 88
linedit, 18, 98, 180, 181
list/1, 55
list or partial list/1, 55
listing/0, 154listing/1, 34, 112, 154load/1, 17, 23, 25, 153loose (debug), 32
lower upper/2, 130
MA, 21main(), 28, 224
make directory/1, 162
maplist/2-8, 140
max (FD option), 198
max arity (flag), 149
max atom (flag), 149
max depth (option), 109
max integer (flag), 149, 183
max list/2, 139
max regret (FD option), 198
max unget (flag), 100, 103, 149
member/2, 135
memberchk/2, 135
meta predicate (property), 75
middle (FD option), 198
min (FD option), 198
min integer (flag), 149
min list/2, 139
mini-assembly, 11, 21, 29
mirror (option), 81
mirror (property), 84
mode (property), 84
monofile (property), 75
most constrained (FD option), 198
msort/1, 140
msort/2, 140
multifile (property), 75
multifile/1 (directive), 46, 47
multifile warning (flag), 150, 152
name demangling, 29
name mangling, 26, 28
name/2, 133
name query vars/2, 64
name singleton vars/1, 63, 112
namevars (option), 16, 64, 108
native code (property), 75
needs quotes (property), 134
needs scan (property), 134
new atom/1, 133
new atom/2, 133

235

next (option), 64
nl/0, 100nl/1, 100
nodebug/0 (debug), 31, 34
non fd var/1 (FD), 187
non generic var/1 (FD), 187
none (debug), 32
none (option), 81, 93, 202, 204
nonvar/1, 55
nospy/1 (debug), 32, 34
nospyall/0 (debug), 32
notrace/0 (debug), 31
nth/3, 139
number/1, 55
number atom/2, 132
number chars/2, 132
number codes/2, 132
numbervars (option), 16, 64, 108
numbervars/1, 64, 112
numbervars/3, 64
once/1, 126
op/3 (directive), 49
op/3, 49, 113
open/3, 81
open/4, 78, 81, 92, 93, 175
open input atom stream/2, 94
open input chars stream/2, 94
open input codes stream/2, 94
open output atom stream/1, 96
open output chars stream/1, 96
open output codes stream/1, 96
os error (flag), 150, 220
os version/1, 168
output (property), 84
partial list/1, 55
peek byte/1, 102
peek byte/2, 102
peek char/1, 99
peek char/2, 99
peek code/1, 99
peek code/2, 99
permission (property), 165
permutation/2, 137
phrase/2, 125
phrase/3, 125
popen/3, 78, 170
portray/1, 113
portray clause/1, 112
portray clause/2, 112, 154
portrayed (option), 109
position (property), 84
postfix op (property), 134predicate property/2, 75

236

prefix/2, 137prefix op (property), 134
print/1, 108, 111
print/2, 108, 113, 119, 120
print to atom/2, 118
print to chars/2, 119
print to codes/2, 120
priority (option), 109
private (property), 75
Prolog flag, 14, 38, 50, 68, 74, 100, 103, 104, 106,
116, 148, 151, 152, 183, 219, 220
prolog copyright (flag), 149
prolog date (flag), 149
prolog file (property), 75
prolog file name/2, 153, 159
prolog line (property), 75
prolog name (flag), 149
prolog pid/1, 173
prolog version (flag), 149
PrologScript, 18, 153
public (property), 75
public/1 (directive), 45, 71
punct (token), 106
put/1, 123
put byte/1, 103
put byte/2, 103
put char/1, 100
put char/2, 100
put code/1, 100
put code/2, 100
quoted (option), 16, 108
random (FD option), 198
random/1, 157
random/3, 157
randomize/0, 156
read (mode), 81
read (permission), 164
read/1, 104, 107
read/2, 104, 107, 117, 118
read atom/1, 105, 107
read atom/2, 105, 107, 116
read from atom/2, 117read from chars/2, 117read from codes/2, 118
read integer/1, 105, 107
read integer/2, 105, 107, 116
read number/1, 105, 107
read number/2, 105, 107, 116
read pl state file/1, 152read term/2, 104, 107
read term/3, 104, 107, 116–118
read term from atom/3, 14, 104, 117read term from chars/3, 117

INDEX

read term from codes/3, 118
read token/1, 106, 107
read token/2, 106, 107, 116–118
read token from atom/2, 117read token from chars/2, 117read token from codes/2, 118
real file name (property), 165
real time/1, 155
regular (permission), 165
remove stream mirror/2, 79, 91, 91
rename file/2, 163
reorder (FD option), 198
repeat/0, 127
reposition (option), 81
reposition (property), 84
reset (option), 81, 93
retract/1, 72
retractall/1, 72
return (option), 202, 204
reverse/2, 136
search (permission), 164
see/1, 121seeing/1, 121
seek/4, 86
seen/0, 122select/3, 136
select/5, 79, 175, 178, 179
send signal/2, 174
set bip name/2, 39, 151, 217
set input/1, 78, 80
set linedit prompt/1, 180
set output/1, 78, 80
set prolog flag/2 (directive), 50
set prolog flag/2, 50, 148
set seed/1, 156
set stream buffering/2, 79, 93, 175, 176
set stream eof action/2, 93
set stream line column/3, 89
set stream position/2, 79, 86
set stream type/2, 92, 176
setarg/3, 63
setarg/4, 63
setof/3, 77
shebang support, 18, 153shell/0, 169shell/1, 169shell/2, 169
singleton warning (flag), 150, 152
singletons (option), 64, 65, 104
size (property), 165
skip/1, 122
sleep/1, 174
smallest (FD option), 198

INDEX

socket (permission), 165
socket/2, 176
socket accept/3, 179
socket accept/4, 179
socket bind/2, 177
socket close/1, 176
socket connect/4, 78, 177, 178
socket listen/2, 178
soft-cut, 52
sort/1, 140
sort/2, 140
space args (option), 109
spawn/2, 170
spawn/3, 170
spy/1 (debug), 32, 34
spypoint condition/3 (debug), 32, 34
standard (FD option), 198
static (property), 75
statistics/0, 155statistics/2, 155
stop/0, 126
stream line column/3, 89
stream position/2, 85, 86
stream property/2, 84, 85, 86, 91, 92
strict iso (flag), 38, 74, 150
string (token), 106
sub atom/5, 129
sublist/2, 138
subsumes term/2, 61
subtract/3, 136
succ/2, 70
suffix/2, 137
sum list/2, 139
suspicious warning (flag), 150, 152
syntax error (flag), 104, 150, 219
syntax error (option), 104
syntax error info/4, 107, 219
system/1, 169
system/2, 169
system time/1, 155
tab/1, 123
tell/1, 121
telling/1, 121
temporary file/3, 167
temporary name/2, 166
term expansion/2, 124
term hash/2, 62
term hash/4, 62
term ref/2, 65
term variables/2, 61
term variables/3, 61
text (option), 81, 92
throw/1, 31, 39, 53, 220, 221

237

tight (debug), 32
told/0, 122
top-level, 13, 18, 25, 27, 126, 180, 181, 224
top level/0, 13, 126
trace/0 (debug), 17, 18, 31
true/0, 51
type (option), 81
type (property), 84, 165
unget byte/1, 102
unget byte/2, 102
unget char/1, 100unget char/2, 100unget code/1, 100unget code/2, 100
unify with occurs check/2, 56
unix (flag), 149
unknown (flag), 150
unknown (permission), 165
unlink/1, 163
user (property), 75
user, 120, 121, 153, 158, 159
user error, 78
user input, 78, 82, 120–122
user output, 78, 82, 120–122
user time/1, 155value method (FD option), 198
var (token), 106
var/1, 55
variable method (FD option), 198variable names (option), 64, 65, 104, 108
variables (option), 104
vector max (FD), 183, 185, 191
version (flag), 149version data (flag), 149
wait/2, 173
WAM, 11, 21, 22, 35
wam debug/0 (debug), 31, 35
warning (option), 104
Warren Abstract Machine, see WAM
working directory/1, 162
write (mode), 81
write (permission), 164
write/1, 108, 111
write/2, 108, 119, 120
write canonical/1, 108, 111
write canonical/2, 108, 119, 120
write canonical to atom/2, 118
write canonical to chars/2, 119
write canonical to codes/2, 120
write pl state file/1, 25, 152
write term/2, 108
write term/3, 16, 33, 108, 119, 120

238

write term to atom/3, 118
write term to chars/3, 119
write term to codes/3, 120
write to atom/2, 118
write to chars/2, 119
write to codes/2, 120
writeq/1, 108, 111
writeq/2, 108, 119, 120, 211
writeq to atom/2, 118
writeq to chars/2, 119
writeq to codes/2, 120

INDEX