%Prints a list of list to the console
prettyprint([]).
prettyprint([H|L]) :- printhelp(H), prettyprint(L).
printhelp([]) :- nl.

printhelp([H|T]) :-
	write(H),write(' '),
	printhelp(T).


%Edge-correcting version of grabA/grabB from 
grabA(Res,_,0,_) :- Res = 7.
grabA(Res,0,_,_) :- Res = 7.
grabA(Res,_,_,[]) :- Res = 7.
grabA(Res,Xpos,1,[H|_]) :- !,grabB(Res,Xpos,H).
grabA(Res, Xpos,Ypos,[_|T]) :- Yposnew is Ypos - 1, grabA(Res, Xpos, Yposnew, T) .


grabB(Res,0,_) :- Res = 7.
grabB(Res,_,[]) :- Res = 7.
grabB(Res, 1 ,[H|_]) :- !,Res = H.
grabB(Res, Xpos ,[_|T]) :- Xposnew is Xpos - 1, grabB(Res, Xposnew, T).

% List Flattener
flatten([],[]).
flatten(Out,[H|T]) :- is_list(H), flatten(H2, H), flatten(T2, T), append(H2,T2,Out).
flatten(Out,[H|T]) :- flatten(T2, T), Out = [H|T2].
flatten(A,A).

% Counts instances of a variable from a list.
% First version is optimistic, second is pessimistic.
countHigh(Res,_,[]) :- Res = 0.
countHigh(Res,V,[H|T]) :- (var(H);H = V), !, countHigh(Res2,V,T), Res is Res2 + 1.
countHigh(Res,V,[_|T]) :- countHigh(Res,V,T).

countLow(Res,_,[]) :- Res =0.
countLow(Res,V,[H|T]) :- (var(H);H \= V),  !, countLow(Res,V,T).
countLow(Res,V,[_|T]) :- countLow(Res2,V,T), Res is Res2 + 1.

%Adjacency function.
adjacent(Res,L,X,Y) :- 
Xp is X + 1, Xm is X - 1,
Yp is Y + 1, Ym is Y - 1,
M is mod(Y,2),
grabA(V1,Xm,Y,L),
grabA(V2,Xp,Y,L),
grabA(V3,X,Ym,L),
grabA(V4,X,Yp,L),
(
 (
  M = 0,
  grabA(V5,Xp,Ym,L),
  grabA(V6,Xp,Yp,L)
 );
 (
  M = 1,
  grabA(V5,Xm,Ym,L),
  grabA(V6,Xm,Yp,L)
 )
),
Res = [V1,V2,V3,V4,V5,V6].


%      0,1,2,3,4,5,6,
solver(A,B,C,D,E,F,G,Xsize,Ysize,Puzzle) :-
 % 1.  Check Contraints
 % 2.  Assign value to wildcard
 % 3.  Check Solution.
 % 4.  Repeat.
 fail.