2016-03-12 11 views
5

Ich muss Sudoku-Rätsel im Format eines Vektors lösen, der 9 Vektoren (der Länge je 9) enthält. Da es sich bei Vektoren um verkettete Listen in Prolog handelt, ging ich davon aus, dass die Suche schneller vonstatten gehen würde, wenn ich die Puzzles zuerst in ein 2D-Array-Format umwandelte.Wie konvertiert man Vektoren in Arrays in ECLiPSe (CLP)? (oder Prolog)

Beispiel Puzzle:

puzzle(P) :- P = 
[[_,_,8,7,_,_,_,_,6], 
[4,_,_,_,_,9,_,_,_], 
[_,_,_,5,4,6,9,_,_], 

[_,_,_,_,_,3,_,5,_], 
[_,_,3,_,_,7,6,_,_], 
[_,_,_,_,_,_,_,8,9], 

[_,7,_,4,_,2,_,_,5], 
[8,_,_,9,_,5,_,2,3], 
[2,_,9,3,_,8,7,6,_]]. 

Ich verwende ECLIPSE CLP einen Solver zu implementieren. Das Beste, was ich mit so weit kommen habe, ist eine Domain wie folgt zu schreiben:

domain(P):- 
    dim(P,[9,9]), 
    P[1..9,1..9] :: 1..9. 

und einen Konverter für das Puzzle (Parameter P die gegebene Rätsel und Sudoku ist das neue definierten Raster mit dem 2D-Array) . Aber ich habe Probleme, die Werte von dem gegebenen Anfangsrätsel mit meinem 2D-Array zu verbinden.

convertVectorsToArray(Sudoku,P):- 
    (for(I,1,9), 
     param(Sudoku,P) 
    do 
     (for(J,1,9), 
      param(Sudoku,P,I) 
     do 
      Sudoku[I,J] is P[I,J] 
    ) 
). 

Vor diesem habe ich versucht, mit array_list (http://eclipseclp.org/doc/bips/kernel/termmanip/array_list-2.html), aber ich hielt Typ Fehler zu bekommen. Wie ich habe es vor:

convertVectorsToArray(Sudoku,P):- 
    (for(I,1,9), 
     param(Sudoku,P) 
    do 
     (for(J,1,9), 
      param(Sudoku,P,I) 
     do 
      A is Sudoku[I], 
      array_list(A,P[I]) 
    ) 
). 

Wenn mein Sudoku das Beispiel Puzzle P in folgendem Format gibt schließlich:

Sudoku = []([](_Var1, _Var2, 8, 7, ..., 6), [](4, ...), ...) 

dann werde ich glücklich sein.

Update

Ich versuchte es noch einmal mit dem array_list; Es funktioniert fast mit dem folgenden Code:

convertVectorsToArray(Sudoku,P):- 
    (for(I,1,9), 
     param(Sudoku,P) 
    do 
     X is Sudoku[I], 
     Y is P[I], 
     write(I),nl, 
     write(X),nl, 
     write(Y),nl, 
     array_list(X, Y) 
). 

Die Schreibvorgänge sind da, um zu sehen, wie die Vektoren/Arrays aussehen. Aus irgendeinem Grund stoppt es bei der zweiten Iteration (anstelle von 9 Mal) und gibt den Rest des Beispielpuzzles als Vektorenvektor aus. Nur der erste Vektor wird korrekt zugewiesen.

convertVectorsToArray(Sudoku,[],_). 
convertVectorsToArray(Sudoku,[Y|Rest],Count):- 
    X is Sudoku[Count], 
    array_list(X, Y), 
    NewCount is Count + 1, 
    convertVectorsToArray(Sudoku,Rest,NewCount). 

Dank für die zusätzliche Erklärung, warum es nicht tat:

update2

Während ich bin sicher, dass die Antwort von jschimpf richtig ist, ich meine eigene Implementierung auch heraus arbeite vorher aber!

Antwort

5

Die einfachste Lösung ist es, die Konvertierung komplett zu vermeiden, indem Sie Ihre Puzzle-Spezifikation direkt als 2-D-Array schreiben. Ein eclipse "Array" ist einfach eine Struktur mit dem Funktor '[]'/N, so können Sie schreiben:

puzzle(P) :- P = [](
    [](_,_,8,7,_,_,_,_,6), 
    [](4,_,_,_,_,9,_,_,_), 
    [](_,_,_,5,4,6,9,_,_), 

    [](_,_,_,_,_,3,_,5,_), 
    [](_,_,3,_,_,7,6,_,_), 
    [](_,_,_,_,_,_,_,8,9), 

    [](_,7,_,4,_,2,_,_,5), 
    [](8,_,_,9,_,5,_,2,3), 
    [](2,_,9,3,_,8,7,6,_)). 

Sie können dann mit diesem 2-D-Array direkt als Container für Ihre Domain Variablen:

sudoku(P) :- 
    puzzle(P), 
    P[1..9,1..9] :: 1..9, 
    ... 

Wenn Sie jedoch die Listenpuzzle-Spezifikation beibehalten und diese in ein Array-Array-Format konvertieren möchten, können Sie array_list/2 verwenden.Da aber, dass nur für 1-D-Arrays arbeitet, haben Sie die Schachtelungsebenen einzeln konvertieren:

listoflists_to_matrix(Xss, Xzz) :- 
    % list of lists to list of arrays 
    (foreach(Xs,Xss), foreach(Xz,Xzs) do 
     array_list(Xz, Xs) 
    ), 
    % list of arrays to array of arrays 
    array_list(Xzz, Xzs). 

Als Grund Ihren eigenen Code nicht funktioniert: dies auf die Index-Notation P[I] zurückzuführen ist. Diese

  • erfordert P ein Array sein
  • funktioniert nur in einem Kontext (Sie es auf Listen wurden unter Verwendung), in dem ein arithmetischer Ausdruck erwartet wird, z.B. die rechte Seite von is/2, in arithmetischen Zwangsbedingungen usw.