I am trying to write a Shikaku solver in EclipsE Prolog. My contraints are defined as follow:
solve(Problemname):-
writeln("Start shikaku."),
problem(Problemname, Width, Height, Hints),
shikaku(Width, Height, Hints).
shikaku(Width, Height, Hints):-
length(Hints, HintCount),
array_list(HintsArray, Hints),
% Prepare the matrix and assign an ID to every Hint (from 1 to HintCount)
dim(Matrix, [Width, Height]),
Matrix[1..Width,1..Height] :: 1..HintCount,
%flatten_array(Matrix,FlattenedMatrix),
(for(ID,1,HintCount), foreach((HintX, HintY, HintNumber), Hints), param(Width, Height, Matrix, HintsArray) do
(
occurrences(ID, Matrix, HintNumber),
L :: 1..Width, R :: 1..Width,
T :: 1..Height, B :: 1..Height,
% Hint coordinates are inside the rectangle.
L #=< HintX,
R #>= HintX,
T #=< HintY,
B #>= HintY,
DeltaX #= R-L+1,
DeltaY #= B-T+1,
HintNumber #= DeltaX * DeltaY,
Matrix[L..R,T..B] :: ID..ID
%writematrix(Submatrix, DeltaX, DeltaY, HintsArray),
%flatten(Submatrix, FlatSubmatrix),
%array_list(FlatSubmatrixArray, FlatSubmatrix),
% Cell count in rectangle must equal HintNumber
%length(FlatSubmatrix, HintNumber),
% All cells in rectangle must have ID as value
%FlatSubmatrixArray[1..HintNumber] :: ID
)
),
% Start searching
labeling(Matrix),
writematrix(Matrix, Width, Height, HintsArray).
writematrix(Matrix, Width, Height, HintsArray):-
writeln("Writing as classic view:"),
(for(I, 1, Height), param(Matrix, Width, HintsArray) do
write("["),
Row is Matrix[I],
(for(J, 1, Width), param(Row, HintsArray) do
ID is Row[J],
(_,_,Val) is HintsArray[ID],
write(" "),
write(Val),
write(" ")
),
writeln("]")
).
The line in comments should check if the submatrix going from L..R - T..B only contains elements that are equal to ID. How can this be done?
Running this gives an "instantiation fault in _3264{1 .. 3} =< 3"
edit1: full code
edit2 It seems that eclipse is not able to reduce the domain of the LR/TB variables to apply an instantiation. Is this a correct assumption? If so, how would this be solvable?
I haven't run your code, but looking at the documentation of the :: operator for instantiating domains, we see that it expects a lower and upper bound of the domain range. For your example, if you just want every number in a subset of an array to be equal to let's say 4, you could simply write the following:
Matrix[A..B,C..D] :: 4..4
EDIT
The error you are receiving is not triggered by that line of code. It gives an instantiation fault while comparing a domain variable with an integer. My guess is that you accidentally wrote =< instead of #=< somewhere in code that isn't included in this question, since the domain of {1..3} is in fact =< 3 and shouldn't give any error were constraint operators correctly used.
If you can't seem to figure out which line of code is producing the error, try performing a trace - it (almost) always reveals the cause. If you are using tkeclipse, a built-in tracer tool is available.