% template for reading input, outputting input, calling solve, and outputting output
kakuro :- write('Please enter puzzle as matrix:'),
          nl,
          read(Ks),
          check(Ks,Ls),
          show(Ls),
          solve(Ls,Ms),
          show(Ms),
          !.

% TODO: Implement this predicate
solve(Ls,Ms) :- fail.

% check if alternative puzzle representation was used and convert if needed
check(Ls,Ms) :- Ls = data(_,_,_,_,_,_), !, convert(Ls,Ms).
check(Ls,Ls).

% convert alternative puzzle representation to matrix representation
convert :- read(Input), convert(Input,Zs), write(Zs), write('.'). 
convert(data(_,_,_,_,_,Ms),Zs) :- Ms =.. [[]|Rs], convertList(Rs,Zs). 
convertList([],[]).
convertList([X|Xs],[Y|Ys]) :- X =.. [[]|Y], convertList(Xs,Ys).

% pretty printer for matrix representation
show([]) :- write('EMPTY').
show([L|Ls]) :- length(L,X), show([L|Ls],X).
show([],X) :- write('+'), showDivider(X).
show([L|Ls],X) :- write('+'), showDivider(X), write('| '), showList(L,X), show(Ls,X).
showList([],Y) :- Y =:= 0 -> nl ; write('NOT RECTANGULAR'), nl.
showList([X|Xs],Y) :- atom(X), !, format('~5a | ',[' ']), Z is Y-1, showList(Xs,Z).
showList([X|Xs],Y) :- number(X), !, number_atom(X,X1), format('~5a | ',[X1]), Z is Y-1, showList(Xs,Z).
showList([x/x|Xs],Y) :- !, format('~2a/~2a | ',[x,x]), Z is Y-1, showList(Xs,Z).
showList([x/N|Xs],Y) :- !, number_atom(N,N1), format('~2a/~2a | ',[x,N1]), Z is Y-1, showList(Xs,Z).
showList([M/x|Xs],Y) :- !, number_atom(M,M1), format('~2a/~2a | ',[M1,x]), Z is Y-1, showList(Xs,Z).
showList([M/N|Xs],Y) :- number_atom(M,M1), number_atom(N,N1), format('~2a/~2a | ',[M1,N1]), Z is Y-1, showList(Xs,Z).
showDivider(0) :- !, nl.
showDivider(X) :- write('-------+'), Y is X-1, showDivider(Y).
