/*
 * This file contains two predicates
 *   - read_and_just_print/1
 *   - read_and_return/3
 * that illustrate reading one line at a time from a file in SWI Prolog.
 * The file has the format of input files of the 'fair_parts' exercise.
 */

/*
 * The first predicate is not so interesting. It just shows you how you can
 * write in Prolog a predicate that contains a loop with *only* side-effects.
 * Use as:
 *
 *   ?- read_and_just_print('objects1.txt').
 */
read_and_just_print(File) :-
    open(File, read, Stream),
    repeat,
    read_line_to_codes(Stream, X),
    ( X \== end_of_file -> writeln(X), fail ; close(Stream), ! ).

/*
 * The second predicate reads the information of an input file and returns
 * it in the next two arguments: an integer represting the number of parts
 * and a list of integers (the weights of the objects), as in the example:
 * 
 *   ?- read_and_return('objects3.txt', N, Weights).
 *   N = 3,
 *   Weights = [10, 20, 30, 40, 50, 60, 70, 80, 90].
 *
 * To read each line of the file, it uses the auxiliary predicate read_line/2.
 */

read_and_return(File, N, Weights) :-
    open(File, read, Stream),
    read_line(Stream, [M, N]),
    read_line(Stream, Weights),
    length(Weights, L),
    ( L =:= M -> close(Stream)  %% just a check for for sanity
    ; format("Error: expected to read ~d weights but found ~d", [M, L]),
      close(Stream), fail
    ).

/*
 * An auxiliary predicate that reads a line and returns the list of
 * integers that the line contains.
 */
read_line(Stream, List) :-
    read_line_to_codes(Stream, Line),
    atom_codes(A, Line),
    atomic_list_concat(As, ' ', A),
    maplist(atom_number, As, List).
