/*
 * This file contains two predicates
 *   - read_and_just_print_codes/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 'moves' exercise of 2024.
 */

/*
 * 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_codes('grid1.txt').
 */
read_and_just_print_codes(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: the N and the grid represented as a list of
 * integer lists (the values in the rows of the grid).
 * 
 *   ?- read_and_return('grid1.txt', N, Grid).
 *   N = 5,
 *   Grid = [[15, 42, 3, 4, 7], [17, 13, 67, 4, 32], ...].
 *
 * To read the information of each of the segments, it uses the auxiliary
 * predicates read_grid/3.
 */

read_and_return(File, N, Grid) :-
    open(File, read, Stream),
    read_line(Stream, [N]),
    read_grid(Stream, N, Grid),
    close(Stream).

read_grid(Stream, N, Grid) :-
    ( N > 0 ->
	Grid = [Row|Rows],
        read_line(Stream, Row),
        N1 is N - 1,
        read_grid(Stream, N1, Rows)
    ; N =:= 0 ->
	Grid = []
    ).
 
/*
 * 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).
