tag - Wie konvertiert man Vektoren zu Arrays in ECLiPSe(CLP)?(oder Prolog)



was ist ein meta title (1)

Ich muss Sudoku-Puzzles 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.

Beispielpuzzle:

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, um einen Solver zu implementieren. Das Beste, was ich bisher herausgefunden habe, ist eine Domain wie folgt zu schreiben:

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

und ein Konverter für das Puzzle (Parameter P ist das gegebene Puzzle und Sudoku ist das neue definierte Gitter 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]
      )
  ).

Davor habe ich versucht array_list ( http://eclipseclp.org/doc/bips/kernel/termanip/array_list-2.html ) zu benutzen, aber ich bekam immer wieder Typfehler. Wie ich es vorher gemacht habe:

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 schließlich das Beispielrätsel P in folgendem Format ausgibt:

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

dann werde ich glücklich sein.

aktualisieren

Ich habe es erneut mit der array_list versucht; 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.

update2

Obwohl ich sicher bin, dass die Antwort von jschimpf richtig ist, habe ich auch meine eigene Implementierung herausgefunden:

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

Danke für die zusätzliche Erklärung, warum es vorher nicht funktioniert hat!

https://src-bin.com


Answer #1

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

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 dieses 2-D-Array dann direkt als Container für Ihre Domänenvariablen verwenden:

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

Wenn Sie jedoch die array_list/2 und diese in ein Array-Array-Format konvertieren array_list/2 , können Sie array_list/2 . Da dies jedoch nur für 1-D-Arrays funktioniert, müssen Sie die Verschachtelungsebenen 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).

Da der eigene Code nicht funktionierte, liegt das an der tiefgestellten Notation P[I] . Dies

  • erfordert, dass P ein Array ist (Sie haben es in Listen verwendet)
  • funktioniert nur in Kontexten, in denen ein arithmetischer Ausdruck erwartet wird, z. B. die rechte Seite von is/2 , in arithmetischen Zwangsbedingungen usw.




eclipse-clp