Prolog Tutorial 9: Input and Output
James Power, 1997.
More on I/O
We have already seen the predicate write(X) which will write
X onto the current output. There is a corresponding
predicate read(X) which reads the current input (up to the
next full-stop), and stores the result in X.
File I/O
Prolog calls any source or destination of data a stream.
Both the read and write predicates work with the
"current" input and output streams which, by default, are the keyboard
and the screen. To read/write to a file, it is simply necessary to
make that file the "current" stream.
The predicates to do this are as follows:
- see(F) opens the file F for reading, and makes
it the "current" stream
- seen closes the current file that you are reading from,
and resets the "current" input to be the keyboard
- tell(F) opens the file F for writing, and makes
it the "current" stream
- told closes the currently-opened file that you are writing
to, and resets the "current" stream to be the screen
The special Prolog constant end_of_file is returned when you
have read all data from a file.
Saving and Restoring a Knowledge-Base
As an example of reading from a file, here's a program which mimics
Prolog's "consult file" operation, reading the clauses from a file
into the internal database (and printing them as it does so).
consult(F) :- see(F),
repeat,
read(X),
nl, write(X),
assert(X),
X=end_of_file, %Termination condition for repeat
!, seen.
Saving a knowledge base is achieved by opening the relevant file, and
using the predicate listing which will print all the
currently-defined clauses the the current output stream.
There is a specialised version of listing which takes one argument: a
list of those predicates whose definitions we want to see. Thus, to
save the facts from the family tree example to the file
fam.pl, we might enter:
tell('fam.pl'), listing([parent/2, male/1, female/1]), told.
Other Approaches to I/O
There are a number of ways of doing I/O in Prolog; the predicates
described above comprise what's known as "Dec-10 I/O" (named after one of
the early machines on which Prolog was implemented).
You should consult the list of built-in predicates in the GNU Prolog manual for
more sophisticated version of I/O.
An Exercise
Go back to the family tree example, and enhance it using what you have
leaned about lists, changing the knowledge-base and I/O. That is,
you should change it so that:
- We no
longer have separate parent/male/female facts, but just one fact of
the form person(N,S,L), where N is the person's
name, S is either male or female, and
L is a (possibly empty) list of their children's names
- The user is presented with a menu, allowing for the following
operations:
- Add a new person (should ask if male/female); validate that they
are not already in the knowledge base
- Delete a person from the knowledge base
- Add the information that X is a child of Y
- Remove X from the list of children of Y
The add/delete operations can be implemented using assert and
retract. You might also add a "Clear all" option,
implemented using abolish.
- Finally, add options that will allow a person to save the
current family tree to a file, or read it in from an existing file.
Don't try and do all of this in one go - use some of your Software
Engineering skills to design the system first!
Written by James Power
Released under the GNU Free Documentation License
Last revised: 22 Oct 2006.