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.
Jip J. Dekker fad1b07018 Squashed 'software/minizinc/' content from commit 4f10c8205
git-subtree-dir: software/minizinc
git-subtree-split: 4f10c82056ffcb1041d7ffef29d77a7eef92cf76
2021-06-16 14:06:46 +10:00

83 lines
2.3 KiB
MiniZinc

/***
!Test
expected:
- !Result
solution: !Solution
sokPosns: [14, 13, 8, 7, 8, 9, 4, 5, 10, 1, 1, 1]
stime: 9
***/
% Regression test for bug #335.
% Previous versions of CPX found this model to be unsatisfiable.
% A slightly later version found a solution but it was not optimal
% (stime = 11, rather than the optimal stime = 9.)
int: w; % width of board
int: n; % board positions 1, ..., w, w+1, ...., 2w, ...,
constraint assert(n mod w == 0, "board must be rectangular");
set of int: POS = 1..n;
int: stps; % max steps in solution
set of int: STEPS = 1..stps;
int: nw; % number of walls
set of int: WALLS = 1..nw;
array[WALLS] of POS: walls; % wall positions
int: nc; % number of crates + goals
set of int: CRATES = 1..nc;
set of POS: goals; % goal positions;
array[CRATES] of POS: crates; % initial crate positions
POS: pInit; % initial sokoban position
set of int: MOVES = {-w,-1,1,w}; % possible moves
include "alldifferent.mzn";
array[STEPS] of var POS: sokPosn; % sokoban position
array[STEPS] of var MOVES: move; % sokoban position
array[STEPS,CRATES] of var POS: cratePosns;
var STEPS: stime :: add_to_output; % time of solution
%% initial positions
constraint sokPosn[1] = pInit;
constraint forall(c in CRATES)(cratePosns[1,c] = crates[c]);
%% no overlap of crates, walls and sokoban
constraint forall(s in STEPS)(
alldifferent(walls ++ [sokPosn[s]] ++ [cratePosns[s,c] | c in CRATES])
);
%% at the end all crates are in a position
constraint forall(c in CRATES)(
cratePosns[stime,c] in goals
);
% legal move at each step
constraint forall(s in 1..stps-1)(
sokPosn[s+1] - sokPosn[s] = move[s]
);
% crate pushing
constraint forall(s in 1..stps-1, c in CRATES)(
cratePosns[s+1,c] = cratePosns[s,c] + bool2int(sokPosn[s+1] == cratePosns[s,c]) * move[s]
);
solve minimize stime;
% output for test case comparison
array[STEPS] of var POS: sokPosns :: add_to_output;
constraint forall (s in 1..stime) (sokPosns[s] = sokPosn[s]);
constraint forall (s in (stime+1)..stps) (sokPosns[s] = 1); % Just fill the rest with 1 for consistency
w = 5;
n = 15;
stps = 12;
nw = 0;
walls = [];
nc = 2;
crates = [7,9];
goals = {6,15};
pInit = 14;