1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.

135 lines
3.5 KiB
MiniZinc

% RUNS ON mzn20_fd
% RUNS ON mzn-fzn_fd
% RUNS ON mzn20_fd_linear
% RUNS ON mzn20_mip
% Regression test for MiniZinc bug 110.
% mzn2fzn 1.1 was generating out of range array indicies in reified contexts,
% when the result of the reification should have just been "false".
% Peacable Army of queens in MiniZinc.
%
% Translation of the ESSENCE' model in the Minion Translator examples:
% http://www.cs.st-andrews.ac.uk/~andrea/examples/peacableArmyOfQueens/peaceableArmyOfQueens.eprime
% """
% Place 2 equally-sized armies of queens (white and black)
% on a chess board without attacking each other
% Maximise the size of the armies.
%
% 'occurrence' representation
% """
%
% Model created by Hakan Kjellerstrand, hakank@bonetmail.com
% See also my MiniZinc page: http://www.hakank.org/minizinc
%
% There are 18 solutions for n=5
% For n=6: 560 solutions
% board width
% given n : int(1..1000)
int: n;
% letting N be domain int(1..n)
set of int: N = 1..n;
% 0: empty field, 1:white queen, 2: black queen
array[N,N] of var 0..2: board;
var 1..(n*n) div 2: amountOfQueens;
solve :: int_search([board[i,j] | i,j in N], first_fail, indomain, complete) maximize amountOfQueens;
constraint
board[1,1] = 1 % let's place a white queen in the north-west corner
/\
% we have the same amount of white as black queens
sum(row, col in N) ( bool2int(board[row,col] = 1)) = amountOfQueens
/\
sum(row, col in N) ( bool2int(board[row,col] = 2) ) = amountOfQueens
/\
% if we have a white queen at position row and column
% there is no field on the same row/column/diagonal
% that holds a black queen
forall(row,col in N) (
(board[row, col] = 1) ->
(forall(i in N) (
((i != row) ->
(board[i,col] < 2))
/\
((i!=col) ->
(board[row,i] < 2))
/\
(((row+i <= n) /\ (col+i <= n)) ->
(board[row+i,col+i] < 2)
)
/\
(((row-i > 0) /\ (col-i > 0)) ->
(board[row-i,col-i] < 2)
)
/\
(((row+i <= n) /\ (col-i > 0)) ->
(board[row+i,col-i] < 2)
)
/\
(((row-i > 0) /\ (col+i <= n)) ->
(board[row-i,col+i] < 2)
))
)
)
/\
% if we have a black queen at position row and column
% there is no field on the same row/column/diagonal
% that holds a white queen
% original ESSENCE' comment:
% we cannot use != 1 since diseq is not reifiable
forall(row,col in N) (
(board[row, col] = 2) ->
forall(j in N) (
((j != row) ->
((board[j,col] < 1) \/ (board[j,col] > 1) ))
/\
((j!=col) ->
((board[row,j] < 1) \/ (board[row,j] > 1)))
/\
(((row+j <= n) /\ (col+j <= n)) ->
((board[row+j,col+j] < 1) \/ (board[row+j,col+j] > 1))
)
/\
(((row-j > 0) /\ (col-j > 0)) ->
((board[row-j,col-j] < 1) \/ (board[row-j,col-j] > 1))
)
/\
(((row+j <= n) /\ (col-j > 0)) ->
((board[row+j,col-j] < 1) \/ (board[row+j,col-j] > 1))
)
/\
(((row-j > 0) /\ (col+j <= n)) ->
((board[row-j,col+j] < 1) \/ (board[row-j,col+j] > 1))
)
)
)
;
%
% data
%
n = 5;
% n = 6;
output [
"board = ", show(board), ";\n",
"amountOfQueens = ", show(amountOfQueens), ";\n"
];