## A.18 library(pio): Pure I/O

This library provides pure list-based I/O processing for Prolog, where the communication to the actual I/O device is performed transparently through coroutining. This module itself is just an interface to the actual implementation modules.

### A.18.1 library(pure_input): Pure Input from files

author
  - Ulrich Neumerkel
  - Jan Wielemaker
To be done
  - Provide support for alternative input readers, e.g. reading terms, tokens, etc.
  - Support non-repositioning streams, such as sockets and pipes.

This module is part of `pio.pl`, dealing with pure input: processing input streams from the outside world using pure predicates, notably grammar rules (DCG). Using pure predicates makes non-deterministic processing of input much simpler.

Pure input uses coroutining (freeze/2) to read input from the external source into a list on demand. The overhead of lazy reading is more than compensated for by using block reads based on read_pending_input/3.

[nondet]phrase_from_file(:Grammar, +File)
  Process the content of File using the DCG rule Grammar. The space usage of this mechanism depends on the length of the not committed part of Grammar. Committed parts of the temporary list are reclaimed by the garbage collector, while the list is extended on demand. Here is a very simple definition for searching a string in a file:

      ... --> []|[_],... .

      file_contains(File, Pattern) :-
              phrase_from_file((..., Pattern, ...), File).

      match_count(File, Pattern, Count) :-
              findall(x, file_contains(File, Pattern), Xs),
              length(Xs, Count).

  This can be called as (note that the pattern must be a string (code list)):

      ?- match_count('pure_input.pl', "file", Count).

[nondet]phrase_from_file(:Grammar, +File, +Options)
  As phrase_from_file/2, providing additional Options. Options are passed to open/4, except for `buffer_size`, which is passed to set_stream/2. If not specified, the default buffer size is 512 bytes. Of particular importance are the open/4 options `type` and `encoding`.
[det]stream_to_lazy_list(+Stream, -List)
  Create a lazy list representing the character codes in Stream. It must be possible to reposition Stream. List is a list that ends in a delayed goal. List can be unified completely transparent to a (partial) list and processed transparently using DCGs, but please be aware that a lazy list is not the same as a materialized list in all respects.

  Typically, this predicate is used as a building block for more high level safe predicates such as phrase_from_file/2.

  To be done
    Enhance of lazy list throughout the system.