52 349 Logic Programming

Chapter 8 - Using System Procedures


§8.0 Introduction: C-Prolog §8.3.1 Character I/O
§8.1 Loading Programs §8.3.2 Term I/O
§8.2 Database Manipulation §8.3.3 I/O Problems
§8.3 File Handling §8.4 Term Handling


Previous Reading: Lists - The Basic Prolog Element

§8.0 Introduction

Throughout this chapter, we use the notation of C-Prolog (as on the SUN's)

The basics we met in the initial practicals

?- spouse(Who, paul).

?- halt.


§8.1 Inputting Programs and Data

When preparing files for use in Prolog, remember the syntactic definition of a term
- which means the last Prolog clause must be followed by at least one space or blank line.

Thereafter,

?- consult(file_name).
% Which adds all the clauses therein.

?- reconsult(file_name).
% Which replaces all the previously
% existing clauses for every added functor.

?- [file_1, file_2, ..., file_n].
% consult(file_1), consult(file_2), ..., consult(file_n).

?- [- file_1, - file_2, ..., - file_n].
reconsult(file_1), reconsult(file_2), ..., reconsult(file_n).

?- system("Unix command string").


§8.2 Database Manipulation

We can add files of rules - how about a single rule?

?- assert(
(
happy(X):-
free(X),
has_coffee(X)
)
).

asserta/1, assertz/1 are procedurally-driven variants, adding procedures respectively at the start and the end of the list of rules.


The opposite of the assert family is retract/1.


Between them, "assert" and "retract" allow the database to change as the program is run ...
... but not, of course, the associated, consulted files!

To obtain a summary of the database, use

?- listing.

but note how numbers (reflecting a memory map) replace the variable names.

clause/2 works similarly for a single procedure, by matching the head and instantiating the body.

Hint: printing to a file (see §8.3 below) the output of "listing" can be useful for future runs!


A related effect

is obtained from trace/0.


§8.3 File Handling

Prolog manipulates sequential files of text

The notion is that of streams of data

By default, the usual rules hold


Files are opened as a side effect:

for reading rule for writing
?- see(file_name). ?- tell(file_name).

and eventually closed as another side-effect:

?- seen. rule ?- told.

see/1 and tell/1 both

seen/0 and told/0 both also


Thus, assuming write/1 and nl/0 both defined below, consider the following program fragments:

tell(file_1), rule )
write('hello'), ) As on left
nl, )
told,
tell(file_2), )
write('something'), )
tell(file_1), ) As on left
write('goodbye'), )
told. )

For file_2 (which remains, potentially, open for writing) the output is

something rule something

But for file_1 (now closed) the output is

hello rule hello goodbye
goodbye


§8.3.1 Character Input & Output

Character handling is primitive - working through decimal ASCII values.


Output is straight-forward


Input is more complex

get0(X) % sets X, 0 < X < 128
get(X) % skips to X, 32 < X < 128


If we wish, we can convert between literals and ASCII using the built in

?- name(Atom, List).

(true if List is a list of the ASCII codes for the successive characters of Atom), which is useful in term manipulation.


§8.3.2 Term Input & Output

To input terms

we have read(X)


To output terms, we have write(X)


There are at least two other output elements


Let's look at a simple example, using 'read' and 'write' to improve on the crude-

square(N, N_square):-
N_square is N*N.
% 'is' instantiates N_square to N^2.

Which gives a response like:

?- square(2, X).
X = 4.
?- square (3, X).
X = 9

If we split the process into two, one to read, and one to respond:

square:-
write('Number: '),
read(N),
process(N).
process(end).
% Arbitrary atom to stop with.
process(N):-
N_square is N*N,
nl,
write('Square: '),
write(N_square),
nl,
square.

then the response is much neater than it was for the first version:

?- square.
Number: 2.
Square: 4
Number: 3.
Square: 9
Number: end.
yes


§8.3.3 Problems with Input & Output

There is a catch!

For example, read(X)

Input/Output activity is essentially deterministic


§8.4 Term Handling


Simplest equality test is X = Y


For numerical evaluation, X is Expression


Related to this is Exp_1 =:= Exp_2


When we want to test the literal equality of two terms, we use Term_1 == Term_2

Thus

?- f(a, b) == f(a, b).
yes
?- f(a, b) == f(a, X).
no
?- X = b, f(a, b) == f(a, X).
X = b


Somewhat related to this are the triple of


Moving even further towards procedural considerations, sometimes we need a guard

Prolog offers the range of guards you might expect:

integer(X).
atom(X).
atomic(X). true if X is an integer or if X is an atom
nonvar(X). true if X is atomic or if X is an instantiated variable
var(X). true if X is an uninstantiated variable

and, depending on the particular version of Prolog, may have others!


© Paul Goldfinch 1997 Next Chapter Return to 52 349 Menu