A set of benchmarks to compare a new prototype MiniZinc implementation
1%------------------------------------------------------------------------------%
2
3include "count.mzn";
4
5%------------------------------------------------------------------------------%
6% Parameters
7
8int: X; % Number of cells in the x-direction
9int: Y; % NUmber of cells in the y-direction
10int: N; % Number of pairs
11
12set of int: Pairs = 1..N;
13set of int: Xs = 1..X;
14set of int: Ys = 1..Y;
15
16 % These arrays all correspond.
17 %
18array[Pairs] of Xs: end_points_start_x;
19array[Pairs] of Ys: end_points_start_y;
20array[Pairs] of Xs: end_points_end_x;
21array[Pairs] of Ys: end_points_end_y;
22
23set of int: Dom = 0..N;
24
25%------------------------------------------------------------------------------%
26% Variables
27
28array [Xs, Ys] of var Dom: board;
29array[int] of var Dom: board_check = array1d(board);
30
31%------------------------------------------------------------------------------%
32% Tests
33
34test is_end_point(int: x, int: y) =
35 exists(i in Pairs)(
36 (end_points_start_x[i] = x /\ end_points_start_y[i] = y)
37 \/ (end_points_end_x [i] = x /\ end_points_end_y [i] = y)
38 );
39
40test is_neighbour_from_xy(int: x, int: y, int: u, int: v) = (
41 u in Xs /\ v in Ys /\ x in Xs /\ y in Ys
42/\ ( (x == u /\ y in {v - 1, v + 1})
43 \/ (y == v /\ x in {u - 1, u + 1})
44 )
45);
46
47%------------------------------------------------------------------------------%
48% Constraints
49
50 % Endpoints must be match with input
51 %
52constraint
53 forall(i in Pairs)(
54 board[end_points_start_x[i], end_points_start_y[i]] = i
55 /\ board[end_points_end_x [i], end_points_end_y [i]] = i
56 );
57
58 % Every endpoint has exactly one neighbour
59 %
60constraint
61 forall(i in Pairs)(
62 let {
63 int: x1 = end_points_start_x[i],
64 int: y1 = end_points_start_y[i],
65 int: y2 = end_points_end_y [i],
66 int: x2 = end_points_end_x [i]
67 } in (
68 count([board[u, v] | u in x1-1..x1+1, v in y1-1..y1+1 where
69 is_neighbour_from_xy(x1, y1, u, v)], i, 1
70 )
71 /\ count([board[u, v] | u in x2-1..x2+1, v in y2-1..y2+1 where
72 is_neighbour_from_xy(x2, y2, u, v)], i, 1
73 )
74 )
75 );
76
77 % Interior points has exactly two neighbours
78 %
79constraint
80 forall(x in Xs, y in Ys)(
81 if is_end_point(x, y) then
82 true
83 else
84 board[x, y] != 0 ->
85 count([board[u, v] | u in x-1..x+1, v in y-1..y+1 where
86 is_neighbour_from_xy(x, y, u, v)], board[x, y], 2)
87 endif
88 );
89
90 % Some redudant constraints
91 %
92constraint redundant_constraint(
93 forall(i in Pairs)(
94 let {
95 int: x1 = min(end_points_start_x[i], end_points_end_x[i]),
96 int: y1 = min(end_points_start_y[i], end_points_end_y[i]),
97 int: x2 = max(end_points_start_x[i], end_points_end_x[i]),
98 int: y2 = max(end_points_start_y[i], end_points_end_y[i])
99 } in (
100 if x1 + 1 < x2 then
101 forall(x in x1+1..x2-1)(
102 sum(z in Ys)(bool2int(board[x, z] == i)) > 0
103 )
104 else
105 true
106 endif
107 /\ if y1 + 1 < y2 then
108 forall(y in y1+1..y2-1)(
109 sum(z in Xs)(bool2int(board[z, y] == i)) > 0
110 )
111 else
112 true
113 endif
114 )
115 )
116);
117
118%------------------------------------------------------------------------------%
119% Search
120
121solve
122 :: int_search(array1d(1..X*Y, board), input_order, indomain_split, complete)
123 satisfy;
124
125%------------------------------------------------------------------------------%
126% Output
127
128output [
129 "% "
130] ++ [
131 show_int(floor(log10(int2float(N)) + 1.0), board[x, y]) ++
132 if x = X then "\n% " else " " endif
133| y in Ys, x in Xs
134] ++ [
135 "\nboard = array2d(", show(Xs), ", ", show(Ys), ", ", show(board), ");\n"
136];
137