210 likes | 485 Views
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. I//O And The Relational Model. I/O does not fit into the relational model of computation.
E N D
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.
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.
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.
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.
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 | ?-
I/O With Characters II • Using ; (logical or) : | ?- get0(Ch) ; true. | ?- q yes | ?- get0(97) ; get0(97). | ?- qa yes | ?- • 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.
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.
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 | ?-
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 | ?-
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 | ?-
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 | ?-
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.
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.
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 ).
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.
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.
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.
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] ).
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.
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.
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.