I am trying to add user input to a list with add_read_list/2 until the word "end." is encountered. This is how the output is supposed to look:
add_read_list(Resultlist, [a,b]).
|: c.
|: d.
|: e.
|: f.
|: end.
Resultlist = [f,e,d,c,a,b].
This is how far I have come:
add_read_list(Resultlist,Entrylist) :-
read(end), append([], Entrylist, Resultlist).
add_read_list(Resultlist, Entrylist) :-
read(Input), append([Input], Entrylist, X),
add_read_list(Resultlist, X).
But this way every second input gets skipped:
add_read_list(Resultlist, [a,b]).
|: c.
|: d.
|: e.
|: f.
|: end.
Resultlist = [f,d,a,b].
What am I doing wrong?
drop the first clause, and use the simple 'if/then/else' construct:
add_read_list(Resultlist, Entrylist) :-
read(Input),
( Input = end
-> reverse(Resultlist, Entrylist)
; add_read_list(Resultlist, [Input|Entrylist])
).
instead of appending each item read, 'cons' it, and reverse the full list when done (well, simply unify to get the list in LIFO, as seems required. i.e. instead of reverse(Resultlist, Entrylist), Resultlist = Entrylist)
The actual error is read(end). This will only succeed, if the term read in is end. Otherwise it fails.
But I do have a lot of reservation to tell you this at all, since nobody every does this is Prolog. Here are the actual things that would need improvement.
The first, is to use end_of_file in place of end, because this is automatically generated at the end of a file, plus you can write it yourself, too.
The second is the way how to handle this. You need to read and then process the term read in:
... read(X), ( X == end_of_file -> ... ; /* whatever */ ... ), ....
However, please do reconsider your entire task. There is a single reason why this could be needed: When you are processing a Prolog file. But this you get cheaper and less error prone by saying [file].
So better design your data to fit into Prolog terms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With