9. PROLOG I/O

advertisement
9. PROLOG I/O
• I/O and the relational model.
• PROLOG I/O operators.
– Not really predicates.
• I/O with characters.
• I/O with terms.
• I/O with lists.
• I/O with files.
• Turning lists of characters into atoms.
9.1
I//O And The Relational Model
• I/O does not fit into the relational model of
computation.
– I/O cannot be backtracked.
– Theoretically could backtrack over input.
 Very inefficient though.
– Cannot backtrack output.
 What’s said is said.
• PROLOG provides I/O operators as an “add on”.
• PROLOG I/O operators are not really predicates.
9.2
PROLOG I/O Operators
• PROLOG handles I/O via constructs which are
essentially C++/Java style statements :
• get0(Ch)
– Next input character = Ch.
• get(Ch)
– Next valid input character = Ch.
– A valid input character is any printable character
except spaces, tabs and end of line characters.
• put(Ch)
– Next output character = Ch.
• PROLOG treats characters as ordinal numbers (i.e. as
ASCII/Unicode numbers).
– The arguments of get0, get and put must be
numbers, not characters.
9.3
PROLOG I/O Operators II
• nl
– Next output character = end of line.
• read(X)
– Next input term = X.
• write(X)
– Next output term = X.
• Note that = means match.
• get0, get, put, nl, read and write cannot be
backtracked in the usual way.
– GNU PROLOG will backtrack over them but it
cannot undo the I/O.
– Some PROLOGs will not backtrack over them at all.
9.4
I/O With Characters
• Reading a single character :
| ?- get0(Ch).
a
Ch = 97
yes
| ?-
• Matching a single character :
| ?- get0(97).
a
yes
| ?-
• A common mistake (‘9’ has ASCII code 57) :
| ?- get0(97).
97
no
| ?-
9.5
I/O With Characters II
• Using ; (logical or) :
| ?| ?yes
| ?| ?yes
| ?-
get0(Ch) ; true.
q
get0(97) ; get0(97).
qa
• First query works because of the true.
Second query works because the second
input character is ‘a’.
• get is identical to get0 except that it ignores
all non-printable characters, spaces, tabs and
end of line characters.
9.6
I/O With Characters III
• put takes a numeric argument and prints
the corresponding character.
| ?- put(97).
a
yes
| ?- put(X).
uncaught exception ...
| ?- X is 90 + 10, put(X).
d
| ?- put(97), nl, put(100).
a
d
yes
| ?-
• put requires its argument to be instantiated.
– Same as the other arithmetic operators.
9.7
I/O With Terms
• PROLOG will input and output whole terms :
| ?- read(X), read(Y).
| ?- p(1,2). q(jim,joe).
X = p(1,2)
Y = q(jim,joe)
yes
| ?- write(q(a,b,c)), write(p(1,2,3)).
q(a,b,c)p(1,2,3)
yes
| ?- X = 1, Y = 2, write(p(X,Y)).
p(1,2)
X = 1
Y = 2
yes
| ?9.8
I/O With Lists
• Read characters up to a ‘.’ and compute a
checksum :
checkSum(Chs, N) :get0(Ch),
(Ch = 46,
% . character
Chs = [],
N = 0
;
checkSum(NewChs, NewN),
Chs = [Ch | NewChs],
N is Ch + NewN
).
| ?- checkSum(L, R).
hello world.
L = [104, ... 100]
R = 1116
| ?-
9.9
I/O With Lists II
• Using get :
checkSum2(Chs, N) :get(Ch),
(Ch = 46,
% . character
Chs = [],
N = 0
;
checkSum2(NewChs, NewN),
Chs = [Ch | NewChs],
N is Ch + NewN
).
| ?- checkSum2(L, R).
hello world.
L = [104, ... 100]
R = 1084
| ?9.10
I/O With Lists III
• Printing a list of terms :
printList([]).
printList([T | Ts]) :write(T),
nl,
printList(Ts).
| ?- printList([hello, world]).
hello
world
yes
| ?-
9.11
I/O With Files
• PROLOG reads input from the standard input stream.
– Normally connected to the keyboard.
• PROLOG writes output to the standard output stream.
– Normally connected to the screen.
• The standard I/O streams can be redirected to files.
• see(fileName) : Connect input stream to file fileName.
• seen : Disconnect the input stream.
• tell(fileName) : Connect the output stream to file fileName.
• told : Disconnect the output stream.
• Similar mechanism to open and close in C++.
– Voodoo in Java.
9.12
I/O With Files II
• see, seen, tell and told cannot be (properly)
backtracked over.
– GNU PROLOG backtracks over them but does
not undo their effect on the file system.
– Some PROLOGs will refuse to backtrack over
them at all.
• Logical variables can be used as arguments to see
and tell.
– Arguments must be valid terms.
• The filename user means the keyboard or screen.
– see(user) : connect the input stream to the
keyboard.
– tell(user) : connect the output stream to the
screen.
9.13
Copying A File
copyFile :read(InFileName),
read(OutFileName),
see(InFileName),
tell(OutFileName),
echo,
seen,
told,
see(user),
tell(user).
echo :get0(Ch),
(Ch = -1,
;
put(Ch),
echo
).
9.14
Copying A File II
• Most PROLOGs connect back to the standard
streams after seen and told but it is safest not to
rely on it.
• Not all PROLOGs return ASCII -1 when reading
from an empty file.
| ?- copyFile.
temp.
temp1.
true ?
(10 ms) yes
| ?-
• The query succeeds and as a side effect copies
the contents of the file temp to the file temp1.
9.15
Echoing The Keyboard To The Screen
• Could use echo on the standard I/O streams :
| ?- echo.
sljdkljhsdfljhsdf
sljdkljhsdfljhsdf
30457305703785rwpwirnpfwpfhpwf
30457305703785rwpwirnpfwpfhpwf
<CTRL-D>
true ? ;
uncaught exception ...
| ?-
• Must use <CTRL-D> to send the end of file character.
• If we force a backtrack GNU PROLOG gives an error
message.
– Don’t try to backtrack I/O operations.
9.16
Turning Lists Of Characters Into Atoms
• name(A,
Str)
– Succeeds if the atom A matches with the
contents of the string Str.
• To PROLOG a string is a list of ASCII numbers.
– Goal succeeds if Str is the list of ASCII
numbers of the characters which make up A.
| ?- name(fred, Str).
Str = [102,114,101,100]
| ?- name(X,[102,114,101,100])
X = fred.
| ?-
• name is most useful for converting text read
from input into atoms.
– Particularly useful with assert.
9.17
Turning Lists Of Characters Into Atoms II
• readAtom reads a string of characters
from input and converts it into an atom.
– The string is terminated by the ‘.’
character (ASCII 46).
readAtom(A) :readStr(Str),
name(A,Str).
readStr(Str) :get0(Ch),
(Ch = 46,
Str = []
;
readStr(NewStr),
Str = [Ch | NewStr]
).
9.18
Turning Lists Of Characters Into Atoms III
| ?- readAtom(A).
fred.
A = fred ?
yes
| ?- readAtom(A), assertz(word(A)).
fred.
A = fred ?
yes
| ?- word(X).
X = fred
yes
| ?- readAtom(A).
a123->>>--<<<<102949 aqa.
A = ‘a123->>>--<<<<102949 aqa’
yes
| ?- read(A).
a123->>>--<<<<102949 aqa.
uncaught exception ....
| ?-
• readAtom is more powerful than PROLOG’s read.
9.19
Summary
• I/O is an “add on” to PROLOG.
– Not relational.
– PROLOG cannot undo I/O operations on
backtracking.
• get0(Ch) : Next input character = Ch.
• get(Ch) : Next valid input character = Ch.
• put(Ch) : Next output character = Ch.
• PROLOG treats characters as ASCII/Unicode
numbers.
• nl : Next output character = end of line.
• read(X) : Next input term = X.
• write(X) : Next output term = X.
9.20
Summary II
• PROLOG reads input from the standard input stream.
• PROLOG writes output to the standard output stream.
• see(fileName) : Connect input stream to file filename.
• seen : Disconnect input stream from file filename.
• tell(fileName) : Connect output stream to file filename.
• told : Disconnect output stream from file filename.
• Filename user means keyboard / screen.
• name(A, Str) : Succeeds if A matches with the string Str.
– Can use name to convert strings into atoms.
– Particularly useful with asserta and assertz.
9.21
Download