3

I'm running the following query in a directory having an empty file empty:

?- member(EOF_action,[error,eof_code,reset]),
   open(empty,read,S,[eof_action(EOF_action)]),
   stream_property(S,end_of_stream(EOS)),
   close(S).

Here's what I get from different Prolog systems:

Prolog system eof_action(error) eof_action(eof_code) eof_action(reset)
SICStus Prolog not not not
GNU Prolog at at not
Scryer Prolog at at at
Traella Prolog at at not
SWI-Prolog not not not

It appears that above systems behave quite differently in this particular corner case.

Does the ISO-Prolog standard specify which behaviour is right for conforming processors?

repeat
  • 18,496
  • 4
  • 54
  • 166
  • I suggest you (also) run the tests for those predicates using Logtalk's standards compliance suite. That would allow you to complete/extend that table with additional data, including for other Prolog systems. – Paulo Moura Aug 26 '22 at 12:57
  • 1
    XSB 5.0.0, SICStus Prolog 4.7.1, and LVM 4.3.0 give the same results as SWI-Prolog in your table. ECLiPSe 7.0 #57 gives `at` for all cases. – Paulo Moura Aug 26 '22 at 13:06
  • 1
    To get the complete picture, say peek_char/1 and *then* look what these values are like. – false Aug 26 '22 at 13:10
  • @false. Consider the sequence "peek_char,get_char,peek_char". With SICStus: before peek_char: "not, not,not". after peek_char: "at, at, at". after get_char: "past, past, past". after second peek_char: "(error), at, at". The beginning makes sense to me, but why go back from "past" to "at" at the end?! – repeat Aug 26 '22 at 14:39
  • @false. I think it's best to improve the focus of this question so that it's about one thing and one thing alone. Wouldn't you agree? – repeat Aug 26 '22 at 15:17

2 Answers2

3

The relation between stream position and end position:
Let S be a input stream of size n. Let p be a position in the source of the stream S.

  • The stream position is not end of stream if p < n.
  • The stream position is at end of stream if p = n.
  • The stream position is past end of stream if p > n.

On an actual implementation the stream position may be a couple (q,e) where q is the position in the source and e is in {not, at, past} such that:

  • The stream position is not end of stream if and only if q < n and e = not.
  • The stream position is at end of stream if and only if q = n and e = at.
  • The stream position is past end of stream if and only if q = n and e = past.

This is given by:

7.10.2.13
end_of_stream(E) - If the stream position is end-of-stream then E is unified with at ...

And with:

7.10.1.1
read - Input. ... input shall start at the beginning of that source.

Knowing this, the stream position is at end of stream when opening the empty file.

Either stream_property/2 has an issue or the stream is in an invalid state.

A better question could be how is a conforming system supposed to handle end of stream?

And test the empty file and non-empty file for different engines.

On the comment of the question:
There is a note on the standard that the predicate peek_char/2 leaves unaltered the stream position so query like stream_property(S, end_of_stream(Eos0)), peek_char(S, _), stream_property(S, end_of_stream(Eos)), Eos0 = Eos should succeed.

notoria
  • 2,053
  • 1
  • 4
  • 15
  • 1
    w.r.t your last remark: In SICStus, it's `Eos0 = not, Eos = at` – false Aug 28 '22 at 15:56
  • 1
    Just one remark: A stream position never is `not` or `at`. A stream position may be end-of-stream or past-end-of-stream. Only the option `end_of_stream/1` may have such values. – false Aug 28 '22 at 16:59
  • Yes, we're right at the end when opening `empty`:) But my question is not about that. It *is* about the `end_of_stream` property reported by a conforming system. I want facts. Sadly, your answer instead gives me opinion like "X has an issue" and "X should succeed". Please improve your answer. – repeat Aug 29 '22 at 12:11
  • Yes, peek_char shall not alter the stream position. But that does not necessarily mean that it may not alter the `End_of_stream` property of the stream. In fact, in SICStus Prolog it does! – repeat Aug 29 '22 at 14:02
  • In `7.10.2.13`, the property `end_of_stream` depends on stream position, if the stream position doesn't change then the property also doesn't change. – notoria Aug 29 '22 at 14:15
  • 1
    There are many questions coming from your answer. Thanks for keeping the ball rolling, though:) +1 – repeat Aug 29 '22 at 16:47
  • The issue has been conformed fo be a bug. Thanks again! – repeat Aug 30 '22 at 12:53
1

7.10.2.9 End position of a stream
When all a stream S has been input (for example by
get_byte/2 or read_term/3) S has a stream position
end-of-stream. ...

Does this include empty files, where nothing has been input, although nothing is all we have? Thinking of VSAM ... This remains pretty ambiguous no matter how we twist and turn it.

More important is what happens if we peek_char/1 or get_char/1 any further.

And even worse whether or not at_end_of_stream/0/1 and stream_property(S, end_of_stream(Eos)) are the same, at least for detecting the end the first time.

As a quick check enter

?- at_end_of_stream.

(There are two factions, two who fail and those who prompt. In the past there was much more prompting)

false
  • 10,264
  • 13
  • 101
  • 209