Convert Boolean FlatZinc to CNF DIMACS

大城市里の小女人 提交于 2019-12-21 04:43:15

问题


To solve a set of Boolean equations, I am experimenting with the Constraint-Programming Solver MiniZinc using the following input:

%  Solve system of Brent's equations modulo 2

%  Matrix dimensions
int: aRows = 3;
int: aCols = 3;
int: bCols = 3;
int: noOfProducts = 23;

%  Dependent parameters
int: bRows = aCols;
int: cRows = aRows;
int: cCols = bCols;
set of int: products = 1..noOfProducts;

%  Corefficients are stored in arrays
array[1..aRows, 1..aCols, products] of var bool: A;
array[1..bRows, 1..bCols, products] of var bool: B;
array[1..cRows, 1..cCols, products] of var bool: C;

constraint
    forall(rowA in 1..aRows, colA in 1..aCols) (
        forall(rowB in 1..bRows, colB in 1..bCols) (
            forall (rowC in 1..cRows, colC in 1..cCols) (
                xorall (k in products) (
                    A[rowA, colA, k] /\ B[rowB, colB, k] /\ C[rowC, colC, k]
                ) == ((rowA == rowC) /\ (colB == colC) /\ (colA == rowB))
            )
        )
    );

solve satisfy;

%  Output solution as table of variable value assignments
output 
["\nSolution for <" ++ show(aRows) ++ ", " ++ show(aCols) ++ 
                 ", " ++ show(bCols) ++ "> " ++ show(noOfProducts) ++ " products:"] ++
["\nF" ++ show(100*rowA+10*colA+k) ++ " = " ++ 
show(bool2int(A[rowA, colA, k])) |
rowA in 1..aRows, colA in 1..aCols, k in products] ++

["\nG" ++ show(100*rowB+10*colB+k) ++ " = " ++ 
show(bool2int(B[rowB, colB, k])) |
rowB in 1..bRows, colB in 1..bCols, k in products] ++

["\nD" ++ show(100*rowC+10*colC+k) ++ " = " ++ 
show(bool2int(C[rowC, colC, k])) |
rowC in 1..cRows, colC in 1..cCols, k in products];

MiniZinc does find a solution for small parameters (rows=cols=2, products=7) , but does not come to an end with the slightly increased ones. I'd like to feed the generated FlatZinc model into a SAT solver like Cryptominisat, Lingeling or Clasp. My hope is these tools might outperform the existing MiniZinc back-ends.

My Question:
Is there any tool available to convert a purely Boolean FlatZinc model into CNF (DIMACS)?
What could I do to replace the xorall() predicate as some of the MiniZinc back-ends don't seem to support it?


回答1:


I don't know of any tools that converts a FlatZinc file to and CNF (DIMACS) file. (The MiniZinc distribution has a program to convert flatzinc to XCSP format. Perhaps there's a tool for XCSP to CNF?)

However, there are some SAT based/inspired solvers that might be better, e.g. minicsp, fzn2smt. There problem is that they - as you mention - don't support the quite new xorall() function.

Also, it might be a good idea to use a labeled search, i.e. something like this (note the bool_search)

  solve :: bool_search(
       [A[i,j,k] | i in 1..aRows, j in 1..aCols, k in products],
       first_fail,
       indomain_min,
       complete)
     satisfy;

Also, I suggest you to test to convert to a 0..1 based model instead, where these solvers can be tested as well as others.

Here's my converted model where I've just changed var bool to var 0..1 and replaced the xorall() with sum() and bool2int() [I hope I converted that correct.] Update: I've changed to the version Axel suggested.

 %  Solve system of Brent's equations modulo 2

 %  Matrix dimensions
 int: aRows = 3;
 int: aCols = 3;
 int: bCols = 3;
 int: noOfProducts = 23;

 %  Dependent parameters
 int: bRows = aCols;
 int: cRows = aRows;
 int: cCols = bCols;
 set of int: products = 1..noOfProducts;

 %  Corefficients are stored in arrays
 array[1..aRows, 1..aCols, products] of var 0..1: A; % hakank: change to 0..1
 array[1..bRows, 1..bCols, products] of var 0..1: B;
 array[1..cRows, 1..cCols, products] of var 0..1: C;

constraint
     forall(rowA in 1..aRows, colA in 1..aCols) (
         forall(rowB in 1..bRows, colB in 1..bCols) (
             forall (rowC in 1..cRows, colC in 1..cCols) (
                 % hakank: changed
                 sum (k in products) (
                     bool2int(A[rowA, colA, k]=1/\ B[rowB, colB, k]=1 /\ C[rowC, colC, k]=1)
                ) == 
                     %% bool2int(rowA == rowC)+ bool2int(colB == colC) + bool2int(colA == rowB)
                     bool2int((rowA == rowC)/\(colB == colC)/\(colA == rowB))
             )
         )
     );


     solve :: int_search(
         [A[i,j,k] | i in 1..aRows, j in 1..aCols, k in products] ++ 
         [B[i,j,k] | i in 1..aRows, j in 1..aCols, k in products] ++ 
         [C[i,j,k] | i in 1..aRows, j in 1..aCols, k in products] 
         ,
         first_fail,
         indomain_min,
         complete)
     satisfy;

    %  Output solution as table of variable value assignments
    output 
    ["\nSolution for <" ++ show(aRows) ++ ", " ++ show(aCols) ++ 
             ", " ++ show(bCols) ++ "> " ++ show(noOfProducts) ++ " products:"] ++
    ["\nF" ++ show(100*rowA+10*colA+k) ++ " = " ++ 
        show(A[rowA, colA, k]) |
        rowA in 1..aRows, colA in 1..aCols, k in products] ++

    ["\nG" ++ show(100*rowB+10*colB+k) ++ " = " ++ 
       show(B[rowB, colB, k]) |
       rowB in 1..bRows, colB in 1..bCols, k in products] ++

    ["\nD" ++ show(100*rowC+10*colC+k) ++ " = " ++ 
       show(C[rowC, colC, k]) |
       rowC in 1..cRows, colC in 1..cCols, k in products];

Here's the model: http://www.hakank.org/minizinc/akemper1_2.mzn .

[Update: These times are for the earlier, wrong, model.] The problem instance in the model is solved (first solution) by minicsp in 3s (including flattening), by the Opturion CPX solver in 5s, by fzn2smt in 6s. And the model can perhaps be tweaked further with labelings etc.

Links to the solvers mentioned:

  • Opturion CPX: http://www.opturion.com/cpx.html

  • MiniCSP: http://www.inra.fr/mia/T/katsirelos/minicsp.html

  • fzn2smt: http://ima.udg.edu/Recerca/ESLIP/fzn2smt/index.html

Also see my MiniZinc page for a longer list of FlatZinc solvers: http://www.hakank.org/minizinc/ .



来源:https://stackoverflow.com/questions/22392219/convert-boolean-flatzinc-to-cnf-dimacs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!