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.
\t 
for
.tsv files and , otherwise.
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).
////separator(0';) parses a semicolon separated file.
true (default false), threat double quotes as a normal 
character.
true (default false), strip leading and 
trailing blank space. RFC4180 says that blank space is part of the data.
true (default), use name/2 
on the field data. This translates the field into a number if possible.
down, downcase atomic values. If up, upcase 
them and if preserve (default), do not change the case.
row.
domain_error(row_arity(Expected), Found) 
if a row is found with different arity.
false (default true), do not reject CSV 
files where lines provide a varying number of fields (columns). This can 
be a work-around to use some incorrect CSV files.
In addition to the options of csv_read_file/3, this predicate processes the option:
end_of_file upon reaching the end of the 
input.\t 
for
.tsv files and , otherwise.
save_data(File) :-
   setup_call_cleanup(
       open(File, write, Out),
       forall(data(C1,C2,C3),
              csv_write_stream(Out, [row(C1,C2,C3)], [])),
       close(Out)),