Listing an asserted fact with a stream argument

It seems that the listing format output changed from 7.x to 8.x :

In 7.2.3:

1 ?- open('log.txt',write,S),assertz(p(S)).
S = <stream>(00000000071F4030).

2 ?- listing(p/1).
:- dynamic p/1.

p(<stream>(00000000071F4030)).

true.

However, in 8.5.0:

?- open('log.txt',write,S),assertz(p(S)).
S = <stream>(00000000076B77A0).

?- listing(p/1).
:- dynamic p/1.

p('$BLOB'("<stream>(00000000076B77A0)")).

true.

Now, the stream is enclosed in $BLOB/1. Incidentally, this new format is not applied to print/1. Is there a way to reproduce the old behaviour of listing?

1 Like

At the moment not. What is the reason you don’t like that? As blobs are not readable you could not read back the output of listing. The idea of this change is to get something that is at least valid syntax. That allows (for example) to compare to listings in Prolog. You cannot reproduce the blobs, but that is on purpose (so we can safely discard them without the risk of someone (re)creating a blob that points into unknown memory).

I used listing/1 to dump into a file the “state” of the system, which is defined by some dynamic predicates. Next, consulting this file restored that state, including facts with streams. So, if p(<stream>(Number)) is in the file, after consulting it, one can do p(Stream), close(Stream), for example.

I guess that a workaround is changing how stream arguments are read because p(Stream), close(Stream) would not work for the new format. Something like p(BLOB), blob_to_stream(BLOB,Stream), close(Stream) would fit, but I am unaware of such a conversion predicate.

!? reading p(<stream>(Number)) simply results in a syntax error unless you define < as a prefix op with priority more than the priority of >. Even if the syntax would be valid, the pointer that is there is very unlikely to be valid in the new process. Even if you reload in the same process, blobs cannot be read and surely cannot refer to the same memory address. The only thing you can do is use current_blob/2 to enumerate the existing blobs and than, if you find a blob that has the same address you could assume that to be the blob you are looking for. Note that there is no guarantee: the system may have garbage collected the old blob and recreated one at the same address. The whole idea behind blobs was to make handles to foreign data safe.

1 Like

That’s true, I rechecked this and version 7.2.3 rejects such a stream representation. Sorry for the inconveniences and many thanks.