I have a file memo.dat
, with these terms:
memo(verdi,11).
memo(rossi,7).
memo(bianchi,9).
memo(blu,7).
memo(neri,11).
memo(carli,11).
memo(rapini,8).
I wrote a prolog program in order to obtain a set of tuples from this file:
memo_to_list(MemoList):-
open('/home/ale/Downloads/Prolog_exercises/memo.dat',read,Stream),
read_list_from_stream(Stream,MemoList),
close(Stream).
read_list_from_stream(Stream,[]):-
at_end_of_stream(Stream),!.
read_list_from_stream(Stream,[(Cognome,Ora)|RestoAppuntamenti]):-
read(Stream,memo(Cognome,Ora)),
read_list_from_stream(Stream,RestoAppuntamenti).
However, the predicate at_end_of_stream
fails to check when the stream reaches its end. What can be the problem ? (I used the ubuntu default text editor to create the file memo.dat
)
The end of the stream is only detected when you actually reach it. When you read the last fact, the end-of-file marker have yet to be read. Try instead something like:
memo_to_list(MemoList):-
open('/home/ale/Downloads/Prolog_exercises/memo.dat',read,Stream),
read(Stream,Term),
read_list_from_stream(Term,Stream,MemoList),
close(Stream).
read_list_from_stream(end_of_file,_,[]) :-
!.
read_list_from_stream(memo(Cognome,Ora),Stream,[(Cognome,Ora)|RestoAppuntamenti]):-
read(Stream,Term),
read_list_from_stream(Term,Stream,RestoAppuntamenti).
You can also avoid leaking stream handles and unclosed streams in case something is wrong with your data file by using the setup_call_cleanup/3
built-in predicate:
memo_to_list(MemoList) :-
setup_call_cleanup(
open('/Users/pmoura/Desktop/memo.dat',read,Stream),
( read(Stream,Term),
read_list_from_stream(Term,Stream,MemoList)
),
close(Stream)
).
Update
The Prolog standard requires that the .
that ends a term is followed by a layout character. Your code only works if there isn't any character (other than the end-of-file) after the last dot of the last term, which makes the Prolog text non-conforming but, depending on the Prolog system, may allow the end of stream to be detected by calling the at_end_of_stream /1
predicate after reading the last term. Note also that's common for text editors to add a new-line after the last line of text if not present on saving. That new-line is a layout character as required by the Prolog standard. Therefore, for a compliant, reliable, and portable solution, make sure there's a new line at the end of your data file and use a solution along this answer.