I'm trying to solve a Light-Up puzzle and I'm having troubles nailing down the constraints.
My main predicate is:
akari(Rows, Size) :-
length(Rows, Size), maplist(length_list(Size), Rows),
append(Rows, Board),
domain(Board, 0, 2),
processRows(Rows, Rows, 0-0, Size),
% transpose(Rows, Columns),
% processRows(Columns, Columns, 0-0, Size),
labeling([], Board),
write(Board), nl,
printBoard(Board, Size).
The Rows
are in a form of a matrix, for example, a case with every free square:
start :-
akari([[_,_,_],
[_,_,_],
[_,_,_]], 3).
To process every row I use:
processRows([], _Board, _Row-_Col, _Size).
processRows([H|T], Board, Row-Col, Size) :-
processRow(H, Board, Row-Col, Size, []),
NewRow is Row + 1,
processRows(T, Board, NewRow-0, Size).
processRow([], _Board, _Row-_Col, _Size, _VarList).
processRow([H|T], _Board, _Row-Col, _Size, _VarList) :-
H == 2,
NewCol is Col + 1,
processRow(T, Board, Row-NewCol, Size, []).
processRow([H|T], Board, Row-Col, Size, VarList) :-
gatherLeft(Board, Row-Col, Row-Col, Size, VarList).
NewCol is Col + 1,
processRow(T, Board, Row-NewCol, Size, []).
So I go through each element of the matrix, and I gather, starting with gatherLeft
- which summons the other cardinal gathers, Right, Up and Down - the row and column of the square I'm processing.
The idea is that each intersection of row and column - a cross, if you will - can one have at most one lightbulb.
But if I do something like this:
count2([],0).
count2([H|T], Count) :-
H #= 1 #<=> C,
count2(T, C2),
Count #= C + C2.
Or this sum(VarList, #=<, 1)
My intent is "Each cross can have at most one lightbulb", but I end up selecting every space and I end up saying "The whole board can have at most one light". And I end up with an empty board.
Edit
For posterity, the solution I came up with was is:
Every square can have at most one light, so sum([H], #=<, 1)
.
Taking a square, it's column and row can have at most one light, so sum(Row, #=<, 1)
.
The neighborhood of a square must have at least one light, so sum(VarList, #>=, 1)
.
It now appears to be working.