Hi, <div><br></div><div>Imagine I have a long enough (to fit in memory) text file with regular data, say, a lot of float numbers, divided by space.</div><div>Now I want to parse those to find the sum of all numbers. In prolog (namely, SWI) I used 'phrase_from_file' predicate which allowed to parse file by DCG in lazy manner (no need to read whole file to memory). If it's interesting I used next code:</div>
<div><br></div><div><br></div><div><div>:- set_prolog_flag(float_format,'%.15g').</div><div><br></div><div>integer(I) --></div><div> digit(D0),</div><div> digits(D),</div><div> { number_chars(I, [D0|D])</div>
<div> }.</div><div><br></div><div>digits([D|T]) --></div><div> digit(D), !,</div><div> digits(T).</div><div>digits([]) --></div><div> [].</div><div><br></div><div>digit(D) --></div><div>
[D],</div><div> { code_type(D, digit)</div><div> }.</div><div><br></div><div>float(F) --></div><div> ( "-", {Sign = -1}</div><div> ; "", {Sign = 1}</div><div> ), !,</div>
<div> integer(N),</div><div> ",",</div><div> integer(D),</div><div> {F is Sign * (N + D / 10^(ceiling(log10(D))))</div><div> }.</div><div><br></div><div>sum(S, Total) --></div><div> float(F1), !,</div>
<div> " ",</div><div> { S1 is S + F1},</div><div> sum(S1, Total).</div><div>sum(Total, Total) --></div><div> [].</div><div><br></div><div>go1 :-</div><div> phrase_from_file(sum(0, S),'numbers_large.txt', [buffer_size(16384)]),</div>
<div> writeln(S).</div></div><div><br></div><div><br></div><div>Now, for an excercise in mercury, I'm willing to write the mercury analog. If I understand correctly there is no direct analog to 'phrase_from_file' in mercury, am I right?</div>
<div><br></div><div>So, I decided to fake this by constructing some type like:</div><div><br></div><div><div>:- type parse_state ---> state(buffer_size, buffer, io.state).</div><div>:- type buffer_size == int.</div><div>
:- type buffer == list(char).</div></div><div><br></div><div>and pass this aroung those predicates like</div><div><br></div><div>:- pred some_dcg_pred(some_term::out, parse_state::in, parse_state::out) is semidet.</div><div>
<br></div><div>My thought was that I would take chars from 'buffer', and if it's empty -> read 'buffer_size' chars from io.state. </div><div><br></div><div>But! It seems that io library provides no support for buffered reading Oo. And without that, I guess, it'll be rather slow (reading 1 char at a time). Interesting, that I've looked inside the source of io module and it internally uses buffered reading, but predicates not exported to interface of those.</div>
<div><br></div><div><br></div><div>Diar sirs, what could you recommend on writing efficient (as well as elegant) analog to prolog code?</div><div><br></div><div><br></div><div>Sincerely yours,</div><div>Vladimir.</div>