Как вы проверяете элементы подматрицы в Прологе?
Я пытаюсь написать решатель Shikaku в EclipsE Prolog. Мои ограничения определены следующим образом:
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("]")
).
Строка в комментариях должна проверять, содержит ли подматрица, идущая от L..R - T..B, только те элементы, которые равны ID. Как это может быть сделано?
Выполнение этого дает "ошибку создания экземпляра в _3264 {1.. 3} =<3"
edit1: полный код
edit2 Кажется, что eclipse не может уменьшить область переменных LR/TB, чтобы применить инстанцирование. Это правильное предположение? Если так, то как бы это было решаемо?
1 ответ
Я не запускал ваш код, но, глядя на документацию оператора:: для создания экземпляров доменов, мы видим, что он ожидает нижнюю и верхнюю границы диапазона доменов. Для вашего примера, если вы просто хотите, чтобы каждое число в подмножестве массива было равно, скажем, 4, вы можете просто написать следующее:
Matrix[A..B,C..D] :: 4..4
РЕДАКТИРОВАТЬ
Ошибка, которую вы получаете, не вызывается этой строкой кода. Это дает ошибку инстанции при сравнении переменной домена с целым числом. Я предполагаю, что вы случайно написали = <вместо # = <где-то в коде, который не включен в этот вопрос, так как домен {1..3} на самом деле = <3 и не должен давать никаких ошибок, если операторы ограничений правильно используются.
Если вы не можете понять, какая строка кода вызывает ошибку, попробуйте выполнить трассировку - она (почти) всегда выявляет причину. Если вы используете tkeclipse, доступен встроенный инструмент трассировки.