bimandre@kulcs.uucp (Andre Marien) (03/22/88)
article <783@cresswell.quintus.UUCP> Richard A. O'Keefe > It is interesting that Marien and Demoen fell into exactly this trap. Sorry for being inaccurate: we should have taken the trouble of explaining what BIMprolog's predicate eof/0 does and it is different from what Richard's at_eof/0 does: eof/0 succeeds only after a read/1 or get0/1 has failed because end of file was encountered so, let me change buggy_read into: non_buggy_read(Term) :- bim_read(Term), ! . non_buggy_read(end_of_file) :- eof . actually, eof/0 is written using a predicate in_status/1 which unifies its argument with an integer indicating the 'status' of the input stream > end-failure approach, despite having asked Bart Demoen at the Prolog > Benchmarking Workshop for enlightenment on this point. Again, this Perhaps you asked Andre' Marien, but not Bart Demoen: he was not at the Prolog Benchmarking Workshop Now about the transformation of s1: a -> s2. s1: b -> s1. s1: $ -> accept. to a prolog procedure; 1. the textbook uses an explicit end of file marker, so it is clear that the behavior of Cprolog's get0/1 suites better in this transformation; still, I would rather represent a state by a predicate with arity 0 and let it get its character itself: s1 :- get0(X) , (X = a , s2 ; X = b , s1 ; X = -1 , true ) . this of course with get0/1 behaving like in Cprolog 2. Now, do it with BIMprolog's get0/1, I will call it BIMget0 so that you will always know which behavior to expect s1 :- BIMget0(X) , (X = a , s2 ; X = b , s1 ) . s1 :- eof . this doesn't look very nice, but a. I would expect that in a parser, in most states eof indicates an error, so that error recovery must be done, which is very easy (in prolog) by backtracking to the appropriate level (state) in the parser; so in most states, there would be no clause like s1 :- eof. then, on eof, s1 fails as it does on input characters different from a or b see Pascal : an endpoint is the endmarker, and occurrence of eof during tokenizing means an error see Prolog : every clause must have an endpoint; eof could only occur after a clause b. prolog (at least BIMprolog) is used for other things than writing tokenizers - actually, tokenizers should not be written at all: they should be generated - and in an administrative application written in prolog, using BIMread or BIMget, the programmer can feel at ease: after a successful BIMread or BIMget, he has got data; it is in a way impossible for him to forget testing for eof, because otherwise the execution of the program would never have gone so far 3. A more general approach can be used, using a state transition table. The previous program can be derived from this by partial evaluation. In the triangle puzzle problem discussion, R.O'K argued that this approach is more general. step_state(accept) :- ! . step_state(From) :- BIMget0(X), !, From : X => New, step_state(New) . step_state(From) :- BIMeof, From : '$' => New, step_state(New) . s1: a => s2. s1: b => s1. s1: '$' => accept. If eof is to be treated as an error, remove the last clause of step_state/1. Eof is handled in one place, in Cprolog one should add : transit(si,-1,error) . for all states, or write : state(From) :- get0(X), noteof(X), !, transit(From,X,New), state(New) . noteof(-1) :- !, fail . noteof(_) . To sum up: there is an appropriate level of testing for eof: BIMread and BIMget (and BSIread and BSIget for that matter, to answer one of Richard's questions and worries) allow you to do this testing of eof at these levels only, while read and get0 of Cprolog force you to test it after every input operation Andre' Marien B.I.M. bimandre@kulcs Bart Demoen K.U.Leuven bimbart@kulcs