## A.9 library(csv): Process CSV (Comma-Separated Values) data

See also
  RFC 4180
To be done
  - Implement immediate assert of the data to avoid possible stack overflows.
  - Writing creates an intermediate code-list, possibly overflowing resources. This waits for pure output!

This library parses and generates CSV data. CSV data is represented in Prolog as a list of rows. Each row is a compound term, where all rows have the same name and arity.

[det]csv_read_file(+File, -Rows)
[det]csv_read_file(+File, -Rows, +Options)
  Read a CSV file into a list of rows. Each row is a Prolog term with the same arity. Options is handed to csv/4. Remaining options are processed by phrase_from_file/3.

  Suppose we want to create a predicate table/6 from a CSV file that we know contains 6 fields per record. This can be done using the code below. Without the option arity(6), this would generate a predicate table/N, where N is the number of fields per record in the data.

      ?- csv_read_file(File, Rows, [functor(table), arity(6)]),
         maplist(assert, Rows).

[det]csv(?Rows)`//`
[det]csv(?Rows, +Options)`//`
  Prolog DCG to `read/write' CSV data. Options:
  separator(+Code)
    The comma-separator. Must be a character code. Default is (of course) the comma. Character codes can be specified using the 0' notion. E.g., `separator(0';)`.
  strip(+Boolean)
    If `true` (default `false`), strip leading and trailing blank-space. RFC4180 says that blank space is part of the data.
  convert(+Boolean)
    if `true` (Default), use name/2 on the field-data. This translates the field into a number if possible.
  functor(+Atom)
    Functor to use for creating row-terms. Default is `row`.
  arity(?Arity)
    Number of fields in each row. This predicate raises a domain_error(row_arity(Expected), Found) if a row is found with different arity.
[det]csv_write_file(+File, +Data)
[det]csv_write_file(+File, +Data, +Options)
  Write a list of Prolog terms to a CSV file. Options are given to csv/4. Remaining options are given to open/4.