"If Stream is not open, an existence error is raised."
So closing a stream is not idempotent as you get an exception on the second call:
?-
open('/etc/motd','read',Stream),close(Stream),close(Stream).
ERROR: stream `<stream>(0x19fb860)' does not exist (already closed)
This is often not what one wants. A stream may be closed from several places in the call stack after operations are done.
The solution is of course:
idempotent_close(Stream) :- is_stream(Stream) -> close(Stream) ; true.
Then:
?-
open('/etc/motd','read',Stream),idempotent_close(Stream), idempotent_close(Stream).
Stream = <stream>(0x19fbc30).
Note that the stream "blob" retains the quality of identifying a stream after the stream has been closed:
?- open("/etc/motd",read,Stream),
is_stream(Stream),
atomic(Stream),
blob(Stream,T),
close(Stream),
blob(Stream,TT).
Stream = <stream>(0x29db6b0),
T = TT, TT = stream.