2016-05-22 23 views
2

Ich versuche, einen Shikaku Solver in EclipsE Prolog zu schreiben. Meine contraints sind wie folgt definiert:Wie überprüfen Sie die Elemente einer Submatrix in 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("]") 
). 

Die Linie in den Kommentaren sollte prüfen, ob die Submatrix von L..R gehen - T..B nur enthält Elemente, die ID gleich sind. Wie kann das gemacht werden?

Laufen dies gibt einen "Instanziierung Fehler in _3264 {1 .. 3} = < 3"

edit1: vollständiger Code

edit2 Es scheint, dass Eclipse nicht in der Lage ist, zu reduzieren, die Domäne der LR/TB-Variablen, um eine Instanziierung anzuwenden. Ist das eine korrekte Annahme? Wenn ja, wie wäre das lösbar?

+0

Aha, vielleicht liegt das Problem in der Tatsache, dass Sie auf Matrix für eine Teilmenge von L..R, T..B zugreifen, aber diese Variablen werden beim Eingeben der Codezeile nicht immer geerdet. Sie können keine Bereiche für Array-Subsets angeben, die eine Domäne haben. Eine Möglichkeit könnte darin bestehen, die Suche nach dem Einstellen der Domäne der LRTB-Variablen durchzuführen, jedoch bevor die ID..ID-Domäne auf die Matrix-Untergruppe gesetzt wird. – SND

+0

Wie würde man das genau machen? :) – JorenV

+0

Verwenden der ECLiPSe-integrierten Suche/6, wie Sie während des Aufrufs von labeling/1 vorgehen. Nur, anstatt es nach der Schleife aufzurufen, rufen Sie es innerhalb der Schleife zwischen den Domäneninstanzen von L..R und T..B auf, aber vor der Zeile mit Matrix [L..R, T..B] :: ID ..ICH WÜRDE. – SND

Antwort

1

Ich habe Ihren Code nicht ausgeführt, aber beim Betrachten der documentation des Operators :: :: zum Instanziieren von Domänen sehen wir, dass er eine untere und obere Grenze des Domänenbereichs erwartet. Für Ihr Beispiel, wenn Sie nur jede Zahl in einer Teilmenge eines Arrays wollen die 4 gleich sagen lassen, könnte man einfach schreiben folgenden:

Matrix[A..B,C..D] :: 4..4 

EDIT

Der Fehler, den Sie erhalten wird von dieser Codezeile nicht ausgelöst. Es gibt einen Instanziierungsfehler beim Vergleichen einer Domänenvariablen mit einer Ganzzahl. Meine Vermutung ist, dass Sie versehentlich = < anstelle von # = < irgendwo in Code, der nicht in dieser Frage enthalten ist, da die Domäne von {1..3} in der Tat = < 3 ist und keinen Fehler geben sollte Beschränkungsoperatoren korrekt verwendet.

Wenn Sie nicht herausfinden können, welche Codezeile den Fehler verursacht, versuchen Sie, eine Ablaufverfolgung durchzuführen - sie zeigt (fast) immer die Ursache an. Wenn Sie tkeclipse verwenden, ist ein integriertes Tracer-Werkzeug verfügbar.

+0

ändern :: ID zu :: ID..ID gibt mit dem gleichen Fehler – JorenV

+0

Ich habe die Antwort geändert. – SND

+0

siehe aktualisierten Code. Das Tracen schlägt fehl, wenn die Matrix :: ID..ID-Zeile das zweite Mal erreicht wird.Es scheint, dass Eclipse nicht in der Lage ist, die Domäne der LR/TB-Variablen zu reduzieren, um eine Instanziierung anzuwenden – JorenV