"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.