Как вы проверяете элементы подматрицы в Прологе?

Я пытаюсь написать решатель 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, доступен встроенный инструмент трассировки.

Другие вопросы по тегам