diff --git a/examples/flatzinc/bobs_sale.fzn b/examples/flatzinc/bobs_sale.fzn index 5e956020d1..8e62c04b8f 100644 --- a/examples/flatzinc/bobs_sale.fzn +++ b/examples/flatzinc/bobs_sale.fzn @@ -1,445 +1,26 @@ predicate all_different_int(array [int] of var int: x); -predicate count(array [int] of var int: x, var int: y, var int: c); +predicate count_eq(array [int] of var int: x, var int: y, var int: c); +predicate count_reif(array [int] of var int: x, var int: y, var int: c, var bool: b); +predicate fixed_cumulative(array [int] of var int: s, array [int] of int: d, array [int] of int: r, int: b); predicate global_cardinality(array [int] of var int: x, array [int] of int: cover, array [int] of var int: counts); +predicate global_cardinality_closed(array [int] of var int: x, array [int] of int: cover, array [int] of var int: counts); +predicate global_cardinality_low_up(array [int] of var int: x, array [int] of int: cover, array [int] of int: lbound, array [int] of int: ubound); +predicate global_cardinality_low_up_closed(array [int] of var int: x, array [int] of int: cover, array [int] of int: lbound, array [int] of int: ubound); +predicate maximum_int(var int: m, array [int] of var int: x); +predicate minimum_int(var int: m, array [int] of var int: x); +predicate sliding_sum(int: low, int: up, int: seq, array [int] of var int: vs); +predicate sort(array [int] of var int: x, array [int] of var int: y); predicate table_bool(array [int] of var bool: x, array [int, int] of bool: t); predicate table_int(array [int] of var int: x, array [int, int] of int: t); +predicate var_cumulative(array [int] of var int: s, array [int] of int: d, array [int] of int: r, var int: b); array [1..10] of int: labels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; array [1..10] of int: num_labels = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; array [1..2] of int: precedences = [1, 10]; array [1..10] of int: stock = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; -var bool: BOOL____00001 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00003 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00005 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00007 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00009 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00011 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00013 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00015 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00017 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00019 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00022 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00024 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00026 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00028 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00030 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00032 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00034 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00036 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00038 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00040 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00043 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00045 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00047 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00049 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00051 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00053 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00055 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00057 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00059 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00061 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00064 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00066 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00068 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00070 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00072 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00074 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00076 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00078 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00080 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00082 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00085 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00087 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00089 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00091 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00093 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00095 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00097 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00099 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00101 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00103 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00106 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00108 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00110 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00112 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00114 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00116 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00118 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00120 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00122 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00124 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00127 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00129 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00131 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00133 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00135 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00137 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00139 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00141 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00143 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00145 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00148 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00150 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00152 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00154 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00156 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00158 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00160 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00162 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00164 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00166 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00169 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00171 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00173 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00175 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00177 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00179 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00181 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00183 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00185 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00187 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00190 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00192 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00194 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00196 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00198 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00200 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00202 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00204 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00206 :: is_defined_var :: var_is_introduced; -var bool: BOOL____00208 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00002 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00004 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00006 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00008 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00010 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00012 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00014 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00016 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00018 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00020 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00021 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00023 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00025 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00027 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00029 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00031 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00033 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00035 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00037 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00039 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00041 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00042 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00044 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00046 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00048 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00050 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00052 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00054 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00056 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00058 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00060 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00062 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00063 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00065 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00067 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00069 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00071 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00073 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00075 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00077 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00079 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00081 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00083 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00084 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00086 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00088 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00090 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00092 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00094 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00096 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00098 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00100 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00102 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00104 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00105 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00107 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00109 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00111 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00113 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00115 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00117 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00119 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00121 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00123 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00125 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00126 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00128 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00130 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00132 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00134 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00136 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00138 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00140 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00142 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00144 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00146 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00147 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00149 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00151 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00153 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00155 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00157 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00159 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00161 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00163 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00165 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00167 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00168 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00170 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00172 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00174 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00176 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00178 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00180 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00182 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00184 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00186 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00188 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00189 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00191 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00193 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00195 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00197 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00199 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00201 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00203 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00205 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00207 :: is_defined_var :: var_is_introduced; -var 0..1: INT____00209 :: is_defined_var :: var_is_introduced; -var 0..10: INT____00210 :: is_defined_var :: var_is_introduced; -var 55..550: INT____00211 :: is_defined_var :: var_is_introduced; -var 55..550: objective :: output_var = INT____00211; +var 55..550: INT____00001 :: is_defined_var :: var_is_introduced; +var 55..550: objective :: output_var = INT____00001; array [1..10] of var 1..10: prices :: output_array([1..10]); -constraint bool2int(BOOL____00001, INT____00002) :: defines_var(INT____00002); -constraint bool2int(BOOL____00003, INT____00004) :: defines_var(INT____00004); -constraint bool2int(BOOL____00005, INT____00006) :: defines_var(INT____00006); -constraint bool2int(BOOL____00007, INT____00008) :: defines_var(INT____00008); -constraint bool2int(BOOL____00009, INT____00010) :: defines_var(INT____00010); -constraint bool2int(BOOL____00011, INT____00012) :: defines_var(INT____00012); -constraint bool2int(BOOL____00013, INT____00014) :: defines_var(INT____00014); -constraint bool2int(BOOL____00015, INT____00016) :: defines_var(INT____00016); -constraint bool2int(BOOL____00017, INT____00018) :: defines_var(INT____00018); -constraint bool2int(BOOL____00019, INT____00020) :: defines_var(INT____00020); -constraint bool2int(BOOL____00022, INT____00023) :: defines_var(INT____00023); -constraint bool2int(BOOL____00024, INT____00025) :: defines_var(INT____00025); -constraint bool2int(BOOL____00026, INT____00027) :: defines_var(INT____00027); -constraint bool2int(BOOL____00028, INT____00029) :: defines_var(INT____00029); -constraint bool2int(BOOL____00030, INT____00031) :: defines_var(INT____00031); -constraint bool2int(BOOL____00032, INT____00033) :: defines_var(INT____00033); -constraint bool2int(BOOL____00034, INT____00035) :: defines_var(INT____00035); -constraint bool2int(BOOL____00036, INT____00037) :: defines_var(INT____00037); -constraint bool2int(BOOL____00038, INT____00039) :: defines_var(INT____00039); -constraint bool2int(BOOL____00040, INT____00041) :: defines_var(INT____00041); -constraint bool2int(BOOL____00043, INT____00044) :: defines_var(INT____00044); -constraint bool2int(BOOL____00045, INT____00046) :: defines_var(INT____00046); -constraint bool2int(BOOL____00047, INT____00048) :: defines_var(INT____00048); -constraint bool2int(BOOL____00049, INT____00050) :: defines_var(INT____00050); -constraint bool2int(BOOL____00051, INT____00052) :: defines_var(INT____00052); -constraint bool2int(BOOL____00053, INT____00054) :: defines_var(INT____00054); -constraint bool2int(BOOL____00055, INT____00056) :: defines_var(INT____00056); -constraint bool2int(BOOL____00057, INT____00058) :: defines_var(INT____00058); -constraint bool2int(BOOL____00059, INT____00060) :: defines_var(INT____00060); -constraint bool2int(BOOL____00061, INT____00062) :: defines_var(INT____00062); -constraint bool2int(BOOL____00064, INT____00065) :: defines_var(INT____00065); -constraint bool2int(BOOL____00066, INT____00067) :: defines_var(INT____00067); -constraint bool2int(BOOL____00068, INT____00069) :: defines_var(INT____00069); -constraint bool2int(BOOL____00070, INT____00071) :: defines_var(INT____00071); -constraint bool2int(BOOL____00072, INT____00073) :: defines_var(INT____00073); -constraint bool2int(BOOL____00074, INT____00075) :: defines_var(INT____00075); -constraint bool2int(BOOL____00076, INT____00077) :: defines_var(INT____00077); -constraint bool2int(BOOL____00078, INT____00079) :: defines_var(INT____00079); -constraint bool2int(BOOL____00080, INT____00081) :: defines_var(INT____00081); -constraint bool2int(BOOL____00082, INT____00083) :: defines_var(INT____00083); -constraint bool2int(BOOL____00085, INT____00086) :: defines_var(INT____00086); -constraint bool2int(BOOL____00087, INT____00088) :: defines_var(INT____00088); -constraint bool2int(BOOL____00089, INT____00090) :: defines_var(INT____00090); -constraint bool2int(BOOL____00091, INT____00092) :: defines_var(INT____00092); -constraint bool2int(BOOL____00093, INT____00094) :: defines_var(INT____00094); -constraint bool2int(BOOL____00095, INT____00096) :: defines_var(INT____00096); -constraint bool2int(BOOL____00097, INT____00098) :: defines_var(INT____00098); -constraint bool2int(BOOL____00099, INT____00100) :: defines_var(INT____00100); -constraint bool2int(BOOL____00101, INT____00102) :: defines_var(INT____00102); -constraint bool2int(BOOL____00103, INT____00104) :: defines_var(INT____00104); -constraint bool2int(BOOL____00106, INT____00107) :: defines_var(INT____00107); -constraint bool2int(BOOL____00108, INT____00109) :: defines_var(INT____00109); -constraint bool2int(BOOL____00110, INT____00111) :: defines_var(INT____00111); -constraint bool2int(BOOL____00112, INT____00113) :: defines_var(INT____00113); -constraint bool2int(BOOL____00114, INT____00115) :: defines_var(INT____00115); -constraint bool2int(BOOL____00116, INT____00117) :: defines_var(INT____00117); -constraint bool2int(BOOL____00118, INT____00119) :: defines_var(INT____00119); -constraint bool2int(BOOL____00120, INT____00121) :: defines_var(INT____00121); -constraint bool2int(BOOL____00122, INT____00123) :: defines_var(INT____00123); -constraint bool2int(BOOL____00124, INT____00125) :: defines_var(INT____00125); -constraint bool2int(BOOL____00127, INT____00128) :: defines_var(INT____00128); -constraint bool2int(BOOL____00129, INT____00130) :: defines_var(INT____00130); -constraint bool2int(BOOL____00131, INT____00132) :: defines_var(INT____00132); -constraint bool2int(BOOL____00133, INT____00134) :: defines_var(INT____00134); -constraint bool2int(BOOL____00135, INT____00136) :: defines_var(INT____00136); -constraint bool2int(BOOL____00137, INT____00138) :: defines_var(INT____00138); -constraint bool2int(BOOL____00139, INT____00140) :: defines_var(INT____00140); -constraint bool2int(BOOL____00141, INT____00142) :: defines_var(INT____00142); -constraint bool2int(BOOL____00143, INT____00144) :: defines_var(INT____00144); -constraint bool2int(BOOL____00145, INT____00146) :: defines_var(INT____00146); -constraint bool2int(BOOL____00148, INT____00149) :: defines_var(INT____00149); -constraint bool2int(BOOL____00150, INT____00151) :: defines_var(INT____00151); -constraint bool2int(BOOL____00152, INT____00153) :: defines_var(INT____00153); -constraint bool2int(BOOL____00154, INT____00155) :: defines_var(INT____00155); -constraint bool2int(BOOL____00156, INT____00157) :: defines_var(INT____00157); -constraint bool2int(BOOL____00158, INT____00159) :: defines_var(INT____00159); -constraint bool2int(BOOL____00160, INT____00161) :: defines_var(INT____00161); -constraint bool2int(BOOL____00162, INT____00163) :: defines_var(INT____00163); -constraint bool2int(BOOL____00164, INT____00165) :: defines_var(INT____00165); -constraint bool2int(BOOL____00166, INT____00167) :: defines_var(INT____00167); -constraint bool2int(BOOL____00169, INT____00170) :: defines_var(INT____00170); -constraint bool2int(BOOL____00171, INT____00172) :: defines_var(INT____00172); -constraint bool2int(BOOL____00173, INT____00174) :: defines_var(INT____00174); -constraint bool2int(BOOL____00175, INT____00176) :: defines_var(INT____00176); -constraint bool2int(BOOL____00177, INT____00178) :: defines_var(INT____00178); -constraint bool2int(BOOL____00179, INT____00180) :: defines_var(INT____00180); -constraint bool2int(BOOL____00181, INT____00182) :: defines_var(INT____00182); -constraint bool2int(BOOL____00183, INT____00184) :: defines_var(INT____00184); -constraint bool2int(BOOL____00185, INT____00186) :: defines_var(INT____00186); -constraint bool2int(BOOL____00187, INT____00188) :: defines_var(INT____00188); -constraint bool2int(BOOL____00190, INT____00191) :: defines_var(INT____00191); -constraint bool2int(BOOL____00192, INT____00193) :: defines_var(INT____00193); -constraint bool2int(BOOL____00194, INT____00195) :: defines_var(INT____00195); -constraint bool2int(BOOL____00196, INT____00197) :: defines_var(INT____00197); -constraint bool2int(BOOL____00198, INT____00199) :: defines_var(INT____00199); -constraint bool2int(BOOL____00200, INT____00201) :: defines_var(INT____00201); -constraint bool2int(BOOL____00202, INT____00203) :: defines_var(INT____00203); -constraint bool2int(BOOL____00204, INT____00205) :: defines_var(INT____00205); -constraint bool2int(BOOL____00206, INT____00207) :: defines_var(INT____00207); -constraint bool2int(BOOL____00208, INT____00209) :: defines_var(INT____00209); -constraint int_eq_reif(prices[1], 1, BOOL____00001) :: defines_var(BOOL____00001); -constraint int_eq_reif(prices[1], 2, BOOL____00022) :: defines_var(BOOL____00022); -constraint int_eq_reif(prices[1], 3, BOOL____00043) :: defines_var(BOOL____00043); -constraint int_eq_reif(prices[1], 4, BOOL____00064) :: defines_var(BOOL____00064); -constraint int_eq_reif(prices[1], 5, BOOL____00085) :: defines_var(BOOL____00085); -constraint int_eq_reif(prices[1], 6, BOOL____00106) :: defines_var(BOOL____00106); -constraint int_eq_reif(prices[1], 7, BOOL____00127) :: defines_var(BOOL____00127); -constraint int_eq_reif(prices[1], 8, BOOL____00148) :: defines_var(BOOL____00148); -constraint int_eq_reif(prices[1], 9, BOOL____00169) :: defines_var(BOOL____00169); -constraint int_eq_reif(prices[1], 10, BOOL____00190) :: defines_var(BOOL____00190); -constraint int_eq_reif(prices[2], 1, BOOL____00003) :: defines_var(BOOL____00003); -constraint int_eq_reif(prices[2], 2, BOOL____00024) :: defines_var(BOOL____00024); -constraint int_eq_reif(prices[2], 3, BOOL____00045) :: defines_var(BOOL____00045); -constraint int_eq_reif(prices[2], 4, BOOL____00066) :: defines_var(BOOL____00066); -constraint int_eq_reif(prices[2], 5, BOOL____00087) :: defines_var(BOOL____00087); -constraint int_eq_reif(prices[2], 6, BOOL____00108) :: defines_var(BOOL____00108); -constraint int_eq_reif(prices[2], 7, BOOL____00129) :: defines_var(BOOL____00129); -constraint int_eq_reif(prices[2], 8, BOOL____00150) :: defines_var(BOOL____00150); -constraint int_eq_reif(prices[2], 9, BOOL____00171) :: defines_var(BOOL____00171); -constraint int_eq_reif(prices[2], 10, BOOL____00192) :: defines_var(BOOL____00192); -constraint int_eq_reif(prices[3], 1, BOOL____00005) :: defines_var(BOOL____00005); -constraint int_eq_reif(prices[3], 2, BOOL____00026) :: defines_var(BOOL____00026); -constraint int_eq_reif(prices[3], 3, BOOL____00047) :: defines_var(BOOL____00047); -constraint int_eq_reif(prices[3], 4, BOOL____00068) :: defines_var(BOOL____00068); -constraint int_eq_reif(prices[3], 5, BOOL____00089) :: defines_var(BOOL____00089); -constraint int_eq_reif(prices[3], 6, BOOL____00110) :: defines_var(BOOL____00110); -constraint int_eq_reif(prices[3], 7, BOOL____00131) :: defines_var(BOOL____00131); -constraint int_eq_reif(prices[3], 8, BOOL____00152) :: defines_var(BOOL____00152); -constraint int_eq_reif(prices[3], 9, BOOL____00173) :: defines_var(BOOL____00173); -constraint int_eq_reif(prices[3], 10, BOOL____00194) :: defines_var(BOOL____00194); -constraint int_eq_reif(prices[4], 1, BOOL____00007) :: defines_var(BOOL____00007); -constraint int_eq_reif(prices[4], 2, BOOL____00028) :: defines_var(BOOL____00028); -constraint int_eq_reif(prices[4], 3, BOOL____00049) :: defines_var(BOOL____00049); -constraint int_eq_reif(prices[4], 4, BOOL____00070) :: defines_var(BOOL____00070); -constraint int_eq_reif(prices[4], 5, BOOL____00091) :: defines_var(BOOL____00091); -constraint int_eq_reif(prices[4], 6, BOOL____00112) :: defines_var(BOOL____00112); -constraint int_eq_reif(prices[4], 7, BOOL____00133) :: defines_var(BOOL____00133); -constraint int_eq_reif(prices[4], 8, BOOL____00154) :: defines_var(BOOL____00154); -constraint int_eq_reif(prices[4], 9, BOOL____00175) :: defines_var(BOOL____00175); -constraint int_eq_reif(prices[4], 10, BOOL____00196) :: defines_var(BOOL____00196); -constraint int_eq_reif(prices[5], 1, BOOL____00009) :: defines_var(BOOL____00009); -constraint int_eq_reif(prices[5], 2, BOOL____00030) :: defines_var(BOOL____00030); -constraint int_eq_reif(prices[5], 3, BOOL____00051) :: defines_var(BOOL____00051); -constraint int_eq_reif(prices[5], 4, BOOL____00072) :: defines_var(BOOL____00072); -constraint int_eq_reif(prices[5], 5, BOOL____00093) :: defines_var(BOOL____00093); -constraint int_eq_reif(prices[5], 6, BOOL____00114) :: defines_var(BOOL____00114); -constraint int_eq_reif(prices[5], 7, BOOL____00135) :: defines_var(BOOL____00135); -constraint int_eq_reif(prices[5], 8, BOOL____00156) :: defines_var(BOOL____00156); -constraint int_eq_reif(prices[5], 9, BOOL____00177) :: defines_var(BOOL____00177); -constraint int_eq_reif(prices[5], 10, BOOL____00198) :: defines_var(BOOL____00198); -constraint int_eq_reif(prices[6], 1, BOOL____00011) :: defines_var(BOOL____00011); -constraint int_eq_reif(prices[6], 2, BOOL____00032) :: defines_var(BOOL____00032); -constraint int_eq_reif(prices[6], 3, BOOL____00053) :: defines_var(BOOL____00053); -constraint int_eq_reif(prices[6], 4, BOOL____00074) :: defines_var(BOOL____00074); -constraint int_eq_reif(prices[6], 5, BOOL____00095) :: defines_var(BOOL____00095); -constraint int_eq_reif(prices[6], 6, BOOL____00116) :: defines_var(BOOL____00116); -constraint int_eq_reif(prices[6], 7, BOOL____00137) :: defines_var(BOOL____00137); -constraint int_eq_reif(prices[6], 8, BOOL____00158) :: defines_var(BOOL____00158); -constraint int_eq_reif(prices[6], 9, BOOL____00179) :: defines_var(BOOL____00179); -constraint int_eq_reif(prices[6], 10, BOOL____00200) :: defines_var(BOOL____00200); -constraint int_eq_reif(prices[7], 1, BOOL____00013) :: defines_var(BOOL____00013); -constraint int_eq_reif(prices[7], 2, BOOL____00034) :: defines_var(BOOL____00034); -constraint int_eq_reif(prices[7], 3, BOOL____00055) :: defines_var(BOOL____00055); -constraint int_eq_reif(prices[7], 4, BOOL____00076) :: defines_var(BOOL____00076); -constraint int_eq_reif(prices[7], 5, BOOL____00097) :: defines_var(BOOL____00097); -constraint int_eq_reif(prices[7], 6, BOOL____00118) :: defines_var(BOOL____00118); -constraint int_eq_reif(prices[7], 7, BOOL____00139) :: defines_var(BOOL____00139); -constraint int_eq_reif(prices[7], 8, BOOL____00160) :: defines_var(BOOL____00160); -constraint int_eq_reif(prices[7], 9, BOOL____00181) :: defines_var(BOOL____00181); -constraint int_eq_reif(prices[7], 10, BOOL____00202) :: defines_var(BOOL____00202); -constraint int_eq_reif(prices[8], 1, BOOL____00015) :: defines_var(BOOL____00015); -constraint int_eq_reif(prices[8], 2, BOOL____00036) :: defines_var(BOOL____00036); -constraint int_eq_reif(prices[8], 3, BOOL____00057) :: defines_var(BOOL____00057); -constraint int_eq_reif(prices[8], 4, BOOL____00078) :: defines_var(BOOL____00078); -constraint int_eq_reif(prices[8], 5, BOOL____00099) :: defines_var(BOOL____00099); -constraint int_eq_reif(prices[8], 6, BOOL____00120) :: defines_var(BOOL____00120); -constraint int_eq_reif(prices[8], 7, BOOL____00141) :: defines_var(BOOL____00141); -constraint int_eq_reif(prices[8], 8, BOOL____00162) :: defines_var(BOOL____00162); -constraint int_eq_reif(prices[8], 9, BOOL____00183) :: defines_var(BOOL____00183); -constraint int_eq_reif(prices[8], 10, BOOL____00204) :: defines_var(BOOL____00204); -constraint int_eq_reif(prices[9], 1, BOOL____00017) :: defines_var(BOOL____00017); -constraint int_eq_reif(prices[9], 2, BOOL____00038) :: defines_var(BOOL____00038); -constraint int_eq_reif(prices[9], 3, BOOL____00059) :: defines_var(BOOL____00059); -constraint int_eq_reif(prices[9], 4, BOOL____00080) :: defines_var(BOOL____00080); -constraint int_eq_reif(prices[9], 5, BOOL____00101) :: defines_var(BOOL____00101); -constraint int_eq_reif(prices[9], 6, BOOL____00122) :: defines_var(BOOL____00122); -constraint int_eq_reif(prices[9], 7, BOOL____00143) :: defines_var(BOOL____00143); -constraint int_eq_reif(prices[9], 8, BOOL____00164) :: defines_var(BOOL____00164); -constraint int_eq_reif(prices[9], 9, BOOL____00185) :: defines_var(BOOL____00185); -constraint int_eq_reif(prices[9], 10, BOOL____00206) :: defines_var(BOOL____00206); -constraint int_eq_reif(prices[10], 1, BOOL____00019) :: defines_var(BOOL____00019); -constraint int_eq_reif(prices[10], 2, BOOL____00040) :: defines_var(BOOL____00040); -constraint int_eq_reif(prices[10], 3, BOOL____00061) :: defines_var(BOOL____00061); -constraint int_eq_reif(prices[10], 4, BOOL____00082) :: defines_var(BOOL____00082); -constraint int_eq_reif(prices[10], 5, BOOL____00103) :: defines_var(BOOL____00103); -constraint int_eq_reif(prices[10], 6, BOOL____00124) :: defines_var(BOOL____00124); -constraint int_eq_reif(prices[10], 7, BOOL____00145) :: defines_var(BOOL____00145); -constraint int_eq_reif(prices[10], 8, BOOL____00166) :: defines_var(BOOL____00166); -constraint int_eq_reif(prices[10], 9, BOOL____00187) :: defines_var(BOOL____00187); -constraint int_eq_reif(prices[10], 10, BOOL____00208) :: defines_var(BOOL____00208); +constraint global_cardinality_low_up_closed(prices, labels, num_labels, num_labels); constraint int_le(prices[1], prices[10]); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00002, INT____00004, INT____00006, INT____00008, INT____00010, INT____00012, INT____00014, INT____00016, INT____00018, INT____00020], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00023, INT____00025, INT____00027, INT____00029, INT____00031, INT____00033, INT____00035, INT____00037, INT____00039, INT____00041], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00044, INT____00046, INT____00048, INT____00050, INT____00052, INT____00054, INT____00056, INT____00058, INT____00060, INT____00062], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00065, INT____00067, INT____00069, INT____00071, INT____00073, INT____00075, INT____00077, INT____00079, INT____00081, INT____00083], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00086, INT____00088, INT____00090, INT____00092, INT____00094, INT____00096, INT____00098, INT____00100, INT____00102, INT____00104], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00107, INT____00109, INT____00111, INT____00113, INT____00115, INT____00117, INT____00119, INT____00121, INT____00123, INT____00125], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00128, INT____00130, INT____00132, INT____00134, INT____00136, INT____00138, INT____00140, INT____00142, INT____00144, INT____00146], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00149, INT____00151, INT____00153, INT____00155, INT____00157, INT____00159, INT____00161, INT____00163, INT____00165, INT____00167], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00170, INT____00172, INT____00174, INT____00176, INT____00178, INT____00180, INT____00182, INT____00184, INT____00186, INT____00188], 1); -constraint int_lin_eq([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00191, INT____00193, INT____00195, INT____00197, INT____00199, INT____00201, INT____00203, INT____00205, INT____00207, INT____00209], 1); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00021, INT____00002, INT____00004, INT____00006, INT____00008, INT____00010, INT____00012, INT____00014, INT____00016, INT____00018, INT____00020], 0) :: defines_var(INT____00021); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00042, INT____00023, INT____00025, INT____00027, INT____00029, INT____00031, INT____00033, INT____00035, INT____00037, INT____00039, INT____00041], 0) :: defines_var(INT____00042); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00063, INT____00044, INT____00046, INT____00048, INT____00050, INT____00052, INT____00054, INT____00056, INT____00058, INT____00060, INT____00062], 0) :: defines_var(INT____00063); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00084, INT____00065, INT____00067, INT____00069, INT____00071, INT____00073, INT____00075, INT____00077, INT____00079, INT____00081, INT____00083], 0) :: defines_var(INT____00084); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00105, INT____00086, INT____00088, INT____00090, INT____00092, INT____00094, INT____00096, INT____00098, INT____00100, INT____00102, INT____00104], 0) :: defines_var(INT____00105); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00126, INT____00107, INT____00109, INT____00111, INT____00113, INT____00115, INT____00117, INT____00119, INT____00121, INT____00123, INT____00125], 0) :: defines_var(INT____00126); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00147, INT____00128, INT____00130, INT____00132, INT____00134, INT____00136, INT____00138, INT____00140, INT____00142, INT____00144, INT____00146], 0) :: defines_var(INT____00147); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00168, INT____00149, INT____00151, INT____00153, INT____00155, INT____00157, INT____00159, INT____00161, INT____00163, INT____00165, INT____00167], 0) :: defines_var(INT____00168); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00189, INT____00170, INT____00172, INT____00174, INT____00176, INT____00178, INT____00180, INT____00182, INT____00184, INT____00186, INT____00188], 0) :: defines_var(INT____00189); -constraint int_lin_eq([-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [INT____00210, INT____00191, INT____00193, INT____00195, INT____00197, INT____00199, INT____00201, INT____00203, INT____00205, INT____00207, INT____00209], 0) :: defines_var(INT____00210); -constraint int_lin_eq([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [INT____00211, prices[1], prices[2], prices[3], prices[4], prices[5], prices[6], prices[7], prices[8], prices[9], prices[10]], 0) :: defines_var(INT____00211); -solve minimize INT____00211; +constraint int_lin_eq([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [INT____00001, prices[1], prices[2], prices[3], prices[4], prices[5], prices[6], prices[7], prices[8], prices[9], prices[10]], 0) :: defines_var(INT____00001); +solve minimize INT____00001; diff --git a/src/constraint_solver/constraint_solver.h b/src/constraint_solver/constraint_solver.h index 98829b15e2..942e166fae 100644 --- a/src/constraint_solver/constraint_solver.h +++ b/src/constraint_solver/constraint_solver.h @@ -1572,6 +1572,20 @@ class Solver { Constraint* MakeDistribute(const std::vector& vars, const std::vector& card_min, const std::vector& card_max); + // Aggregated version of count with bounded cardinalities: + // forall j in 0 .. card_size - 1: + // card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max); + // Aggregated version of count with bounded cardinalities: + // forall j in 0 .. card_size - 1: + // card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max); // Deviation constraint: // sum_i |n * vars[i] - total_sum| <= deviation_var and diff --git a/src/constraint_solver/count_cst.cc b/src/constraint_solver/count_cst.cc index 6b9b161911..55bf5953a3 100644 --- a/src/constraint_solver/count_cst.cc +++ b/src/constraint_solver/count_cst.cc @@ -891,11 +891,13 @@ class BoundedDistribute : public Constraint { BoundedDistribute(Solver* const s, const IntVar* const * vars, int vsize, + const std::vector& values, const std::vector& card_min, const std::vector& card_max); BoundedDistribute(Solver* const s, const IntVar* const * vars, int vsize, + const std::vector& values, const std::vector& card_min, const std::vector& card_max); virtual ~BoundedDistribute() {} @@ -941,6 +943,249 @@ class BoundedDistribute : public Constraint { visitor->EndVisitConstraint(ModelVisitor::kDistribute, this); } + private: + const scoped_array vars_; + const int var_size_; + ConstIntArray values_; + ConstIntArray card_min_; + ConstIntArray card_max_; + const int64 card_size_; + RevBitMatrix undecided_; + NumericalRevArray min_; + NumericalRevArray max_; + scoped_array holes_; +}; + +BoundedDistribute::BoundedDistribute(Solver* const s, + const IntVar* const * vars, + int vsize, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max) + : Constraint(s), + vars_(new IntVar*[vsize]), + var_size_(vsize), + values_(values), + card_min_(card_min), + card_max_(card_max), + card_size_(card_min.size()), + undecided_(var_size_, card_size_), + min_(card_size_, 0), + max_(card_size_, 0), + holes_(new IntVarIterator*[var_size_]) { + memcpy(vars_.get(), vars, var_size_ * sizeof(*vars)); + for (int var_index = 0; var_index < var_size_; ++var_index) { + holes_[var_index] = vars_[var_index]->MakeHoleIterator(true); + } +} + +BoundedDistribute::BoundedDistribute(Solver* const s, + const IntVar* const * vars, + int vsize, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max) + : Constraint(s), + vars_(new IntVar*[vsize]), + var_size_(vsize), + values_(values), + card_min_(card_min), + card_max_(card_max), + card_size_(card_min.size()), + undecided_(var_size_, card_size_), + min_(card_size_, 0), + max_(card_size_, 0), + holes_(new IntVarIterator*[var_size_]) { + memcpy(vars_.get(), vars, var_size_ * sizeof(*vars)); + for (int var_index = 0; var_index < var_size_; ++var_index) { + holes_[var_index] = vars_[var_index]->MakeHoleIterator(true); + } +} + +string BoundedDistribute::DebugString() const { + return StringPrintf( + "BoundedDistribute([%s], values = [%s], card_min = [%s], card_max = [%s]", + DebugStringArray(vars_.get(), var_size_, ", ").c_str(), + values_.DebugString().c_str(), + card_min_.DebugString().c_str(), + card_max_.DebugString().c_str()); +} + +void BoundedDistribute::Post() { + for (int var_index = 0; var_index < var_size_; ++var_index) { + IntVar* const var = vars_[var_index]; + if (!var->Bound()) { + Demon* d = MakeConstraintDemon1(solver(), + this, + &BoundedDistribute::OneBound, + "OneBound", + var_index); + var->WhenBound(d); + d = MakeConstraintDemon1(solver(), + this, + &BoundedDistribute::OneDomain, + "OneDomain", + var_index); + var->WhenDomain(d); + } + } +} + +void BoundedDistribute::InitialPropagate() { + Solver* const s = solver(); + + int64 sum_card_min = 0; + for (int i = 0; i < card_size_; ++i) { + if (card_max_[i] < card_min_[i]) { + solver()->Fail(); + } + sum_card_min += card_min_[i]; + } + if (sum_card_min > var_size_) { + s->Fail(); + } + if (sum_card_min == var_size_) { + for (int i = 0; i < var_size_; ++i) { + vars_[i]->SetValues(values_.RawVector()); + } + } + + for (int card_index = 0; card_index < card_size_; ++card_index) { + const int64 value = values_[card_index]; + int min = 0; + int max = 0; + for (int i = 0; i < var_size_; ++i) { + IntVar* const var = vars_[i]; + if (var->Bound()) { + if (var->Min() == value) { + min++; + max++; + } + } else if (var->Contains(value)) { + max++; + undecided_.SetToOne(s, i, card_index); + } + } + min_.SetValue(s, card_index, min); + max_.SetValue(s, card_index, max); + CountVar(card_index); + } +} + +void BoundedDistribute::OneBound(int index) { + IntVar* const var = vars_[index]; + const int64 var_min = var->Min(); + for (int card_index = 0; card_index < card_size_; ++card_index) { + if (undecided_.IsSet(index, card_index)) { + if (var_min == values_[card_index]) { + SetRevDoContribute(index, card_index); + } else { + SetRevCannotContribute(index, card_index); + } + } + } +} + +void BoundedDistribute::OneDomain(int index) { + IntVar* const var = vars_[index]; + Solver* const s = solver(); + for (int card_index = 0; card_index < card_size_; ++card_index) { + if (undecided_.IsSet(index, card_index)) { + if (!var->Contains(values_[card_index])) { + SetRevCannotContribute(index, card_index); + } + } + } +} + +void BoundedDistribute::CountVar(int card_index) { + const int64 stored_min = min_[card_index]; + const int64 stored_max = max_[card_index]; + if (card_min_[card_index] > stored_max || + card_max_[card_index] < stored_min) { + solver()->Fail(); + } + if (card_min_[card_index] == stored_max) { + CardMax(card_index); + } + if (card_max_[card_index] == stored_min) { + CardMin(card_index); + } +} + +void BoundedDistribute::CardMin(int card_index) { + for (int var_index = 0; var_index < var_size_; ++var_index) { + if (undecided_.IsSet(var_index, card_index)) { + vars_[var_index]->RemoveValue(values_[card_index]); + } + } +} + +void BoundedDistribute::CardMax(int card_index) { + for (int var_index = 0; var_index < var_size_; ++var_index) { + if (undecided_.IsSet(var_index, card_index)) { + vars_[var_index]->SetValue(values_[card_index]); + } + } +} + +// ----- BoundedFastDistribute ----- + +class BoundedFastDistribute : public Constraint { + public: + BoundedFastDistribute(Solver* const s, + const IntVar* const * vars, + int vsize, + const std::vector& card_min, + const std::vector& card_max); + BoundedFastDistribute(Solver* const s, + const IntVar* const * vars, + int vsize, + const std::vector& card_min, + const std::vector& card_max); + virtual ~BoundedFastDistribute() {} + + virtual void Post(); + virtual void InitialPropagate(); + void OneBound(int vindex); + void OneDomain(int vindex); + void CountVar(int card_index); + void CardMin(int card_index); + void CardMax(int card_index); + virtual string DebugString() const; + void SetRevCannotContribute(int64 var_index, int64 card_index) { + Solver* const s = solver(); + undecided_.SetToZero(s, var_index, card_index); + max_.Decr(s, card_index); + if (max_[card_index] < card_min_[card_index]) { + solver()->Fail(); + } + if (max_[card_index] == card_min_[card_index]) { + CardMax(card_index); + } + } + void SetRevDoContribute(int64 var_index, int64 card_index) { + Solver* const s = solver(); + undecided_.SetToZero(s, var_index, card_index); + min_.Incr(s, card_index); + if (min_[card_index] > card_max_[card_index]) { + solver()->Fail(); + } + if (min_[card_index] == card_max_[card_index]) { + CardMin(card_index); + } + } + + virtual void Accept(ModelVisitor* const visitor) const { + visitor->BeginVisitConstraint(ModelVisitor::kDistribute, this); + visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument, + vars_.get(), + var_size_); + visitor->VisitConstIntArrayArgument(ModelVisitor::kMinArgument, card_min_); + visitor->VisitConstIntArrayArgument(ModelVisitor::kMaxArgument, card_max_); + visitor->EndVisitConstraint(ModelVisitor::kDistribute, this); + } + private: const scoped_array vars_; const int var_size_; @@ -953,7 +1198,7 @@ class BoundedDistribute : public Constraint { scoped_array holes_; }; -BoundedDistribute::BoundedDistribute(Solver* const s, +BoundedFastDistribute::BoundedFastDistribute(Solver* const s, const IntVar* const * vars, int vsize, const std::vector& card_min, @@ -974,7 +1219,7 @@ BoundedDistribute::BoundedDistribute(Solver* const s, } } -BoundedDistribute::BoundedDistribute(Solver* const s, +BoundedFastDistribute::BoundedFastDistribute(Solver* const s, const IntVar* const * vars, int vsize, const std::vector& card_min, @@ -995,27 +1240,27 @@ BoundedDistribute::BoundedDistribute(Solver* const s, } } -string BoundedDistribute::DebugString() const { +string BoundedFastDistribute::DebugString() const { return StringPrintf( - "BoundedDistribute([%s], card_min = [%s], card_max = [%s]", + "BoundedFastDistribute([%s], card_min = [%s], card_max = [%s]", DebugStringArray(vars_.get(), var_size_, ", ").c_str(), card_min_.DebugString().c_str(), card_max_.DebugString().c_str()); } -void BoundedDistribute::Post() { +void BoundedFastDistribute::Post() { for (int var_index = 0; var_index < var_size_; ++var_index) { IntVar* const var = vars_[var_index]; if (!var->Bound()) { Demon* d = MakeConstraintDemon1(solver(), this, - &BoundedDistribute::OneBound, + &BoundedFastDistribute::OneBound, "OneBound", var_index); var->WhenBound(d); d = MakeConstraintDemon1(solver(), this, - &BoundedDistribute::OneDomain, + &BoundedFastDistribute::OneDomain, "OneDomain", var_index); var->WhenDomain(d); @@ -1023,7 +1268,7 @@ void BoundedDistribute::Post() { } } -void BoundedDistribute::InitialPropagate() { +void BoundedFastDistribute::InitialPropagate() { Solver* const s = solver(); int64 sum_card_min = 0; @@ -1063,7 +1308,7 @@ void BoundedDistribute::InitialPropagate() { } } -void BoundedDistribute::OneBound(int index) { +void BoundedFastDistribute::OneBound(int index) { IntVar* const var = vars_[index]; const int64 var_min = var->Min(); for (int card_index = 0; card_index < card_size_; ++card_index) { @@ -1077,7 +1322,7 @@ void BoundedDistribute::OneBound(int index) { } } -void BoundedDistribute::OneDomain(int index) { +void BoundedFastDistribute::OneDomain(int index) { IntVar* const var = vars_[index]; const int64 oldmin = var->OldMin(); const int64 oldmax = var->OldMax(); @@ -1108,7 +1353,7 @@ void BoundedDistribute::OneDomain(int index) { } } -void BoundedDistribute::CountVar(int card_index) { +void BoundedFastDistribute::CountVar(int card_index) { const int64 stored_min = min_[card_index]; const int64 stored_max = max_[card_index]; if (card_min_[card_index] > stored_max || @@ -1123,7 +1368,7 @@ void BoundedDistribute::CountVar(int card_index) { } } -void BoundedDistribute::CardMin(int card_index) { +void BoundedFastDistribute::CardMin(int card_index) { for (int var_index = 0; var_index < var_size_; ++var_index) { if (undecided_.IsSet(var_index, card_index)) { vars_[var_index]->RemoveValue(card_index); @@ -1131,7 +1376,7 @@ void BoundedDistribute::CardMin(int card_index) { } } -void BoundedDistribute::CardMax(int card_index) { +void BoundedFastDistribute::CardMax(int card_index) { for (int var_index = 0; var_index < var_size_; ++var_index) { if (undecided_.IsSet(var_index, card_index)) { vars_[var_index]->SetValue(card_index); @@ -1267,27 +1512,53 @@ Constraint* Solver::MakeDistribute(const std::vector& vars, CHECK_EQ(this, (*it)->solver()); } return RevAlloc( - new BoundedDistribute(this, vars.data(), vars.size(), mins, maxes)); + new BoundedFastDistribute(this, vars.data(), vars.size(), mins, maxes)); } Constraint* Solver::MakeDistribute(const std::vector& vars, const std::vector& card_min, const std::vector& card_max) { CHECK_NE(vars.size(), 0); - return RevAlloc(new BoundedDistribute(this, - vars.data(), - vars.size(), - card_min, - card_max)); + return RevAlloc(new BoundedFastDistribute(this, + vars.data(), + vars.size(), + card_min, + card_max)); } Constraint* Solver::MakeDistribute(const std::vector& vars, const std::vector& card_min, const std::vector& card_max) { CHECK_NE(vars.size(), 0); + return RevAlloc(new BoundedFastDistribute(this, + vars.data(), + vars.size(), + card_min, + card_max)); +} + +Constraint* Solver::MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max) { + CHECK_NE(vars.size(), 0); return RevAlloc(new BoundedDistribute(this, vars.data(), vars.size(), + values, + card_min, + card_max)); +} + +Constraint* Solver::MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max) { + CHECK_NE(vars.size(), 0); + return RevAlloc(new BoundedDistribute(this, + vars.data(), + vars.size(), + values, card_min, card_max)); } diff --git a/src/flatzinc/mznlib/global_cardinality_closed.mzn b/src/flatzinc/mznlib/global_cardinality_closed.mzn new file mode 100644 index 0000000000..9ddc26ef2e --- /dev/null +++ b/src/flatzinc/mznlib/global_cardinality_closed.mzn @@ -0,0 +1,3 @@ +predicate global_cardinality_closed(array[int] of var int: x, + array[int] of int: cover, + array[int] of var int: counts); diff --git a/src/flatzinc/mznlib/global_cardinality_low_up.mzn b/src/flatzinc/mznlib/global_cardinality_low_up.mzn new file mode 100644 index 0000000000..b8e428975e --- /dev/null +++ b/src/flatzinc/mznlib/global_cardinality_low_up.mzn @@ -0,0 +1,4 @@ +predicate global_cardinality_low_up(array[int] of var int: x, + array[int] of int: cover, + array[int] of int: lbound, + array[int] of int: ubound); diff --git a/src/flatzinc/mznlib/global_cardinality_low_up_closed.mzn b/src/flatzinc/mznlib/global_cardinality_low_up_closed.mzn new file mode 100644 index 0000000000..c8d61910e1 --- /dev/null +++ b/src/flatzinc/mznlib/global_cardinality_low_up_closed.mzn @@ -0,0 +1,4 @@ +predicate global_cardinality_low_up_closed(array[int] of var int: x, + array[int] of int: cover, + array[int] of int: lbound, + array[int] of int: ubound); diff --git a/src/flatzinc/registry.cc b/src/flatzinc/registry.cc index 8bdba5a095..cdb8015a51 100644 --- a/src/flatzinc/registry.cc +++ b/src/flatzinc/registry.cc @@ -2498,6 +2498,104 @@ void p_global_cardinality(FlatZincModel* const model, CtSpec* const spec) { solver->AddConstraint(ct); } +void p_global_cardinality_closed(FlatZincModel* const model, + CtSpec* const spec) { + Solver* const solver = model->solver(); + AstArray* const array_variables = spec->Arg(0)->getArray(); + const int size = array_variables->a.size(); + std::vector variables(size); + for (int i = 0; i < size; ++i) { + variables[i] = model->GetIntExpr(array_variables->a[i])->Var(); + } + AstArray* const array_coefficients = spec->Arg(1)->getArray(); + const int vsize = array_coefficients->a.size(); + std::vector values(vsize); + for (int i = 0; i < vsize; ++i) { + values[i] = array_coefficients->a[i]->getInt(); + } + AstArray* const array_cards = spec->Arg(2)->getArray(); + const int csize = array_cards->a.size(); + std::vector cards(csize); + for (int i = 0; i < csize; ++i) { + cards[i] = model->GetIntExpr(array_cards->a[i])->Var(); + } + Constraint* const ct = solver->MakeDistribute(variables, values, cards); + VLOG(1) << " - posted " << ct->DebugString(); + solver->AddConstraint(ct); + for (int i = 0; i < size; ++i) { + Constraint* const ct2 = solver->MakeMemberCt(variables[i], values); + VLOG(1) << " + " << ct2->DebugString(); + } +} + +void p_global_cardinality_low_up(FlatZincModel* const model, + CtSpec* const spec) { + Solver* const solver = model->solver(); + AstArray* const array_variables = spec->Arg(0)->getArray(); + const int size = array_variables->a.size(); + std::vector variables(size); + for (int i = 0; i < size; ++i) { + variables[i] = model->GetIntExpr(array_variables->a[i])->Var(); + } + AstArray* const array_coefficients = spec->Arg(1)->getArray(); + const int vsize = array_coefficients->a.size(); + std::vector values(vsize); + for (int i = 0; i < vsize; ++i) { + values[i] = array_coefficients->a[i]->getInt(); + } + AstArray* const array_low = spec->Arg(2)->getArray(); + const int lsize = array_low->a.size(); + std::vector low(lsize); + for (int i = 0; i < lsize; ++i) { + low[i] = array_low->a[i]->getInt(); + } + AstArray* const array_up = spec->Arg(2)->getArray(); + const int usize = array_up->a.size(); + std::vector up(usize); + for (int i = 0; i < usize; ++i) { + up[i] = array_up->a[i]->getInt(); + } + Constraint* const ct = solver->MakeDistribute(variables, values, low, up); + VLOG(1) << " - posted " << ct->DebugString(); + solver->AddConstraint(ct); +} + +void p_global_cardinality_low_up_closed(FlatZincModel* const model, + CtSpec* const spec) { + Solver* const solver = model->solver(); + AstArray* const array_variables = spec->Arg(0)->getArray(); + const int size = array_variables->a.size(); + std::vector variables(size); + for (int i = 0; i < size; ++i) { + variables[i] = model->GetIntExpr(array_variables->a[i])->Var(); + } + AstArray* const array_coefficients = spec->Arg(1)->getArray(); + const int vsize = array_coefficients->a.size(); + std::vector values(vsize); + for (int i = 0; i < vsize; ++i) { + values[i] = array_coefficients->a[i]->getInt(); + } + AstArray* const array_low = spec->Arg(2)->getArray(); + const int lsize = array_low->a.size(); + std::vector low(lsize); + for (int i = 0; i < lsize; ++i) { + low[i] = array_low->a[i]->getInt(); + } + AstArray* const array_up = spec->Arg(2)->getArray(); + const int usize = array_up->a.size(); + std::vector up(usize); + for (int i = 0; i < usize; ++i) { + up[i] = array_up->a[i]->getInt(); + } + Constraint* const ct = solver->MakeDistribute(variables, values, low, up); + VLOG(1) << " - posted " << ct->DebugString(); + solver->AddConstraint(ct); + for (int i = 0; i < size; ++i) { + Constraint* const ct2 = solver->MakeMemberCt(variables[i], values); + VLOG(1) << " + " << ct2->DebugString(); + } +} + void p_global_cardinality_old(FlatZincModel* const model, CtSpec* const spec) { Solver* const solver = model->solver(); AstArray* const array_variables = spec->Arg(0)->getArray(); @@ -2782,6 +2880,12 @@ class IntBuilder { global_model_builder.Register("count_eq", &p_count); global_model_builder.Register("count_reif", &p_count_reif); global_model_builder.Register("global_cardinality", &p_global_cardinality); + global_model_builder.Register("global_cardinality_closed", + &p_global_cardinality_closed); + global_model_builder.Register("global_cardinality_low_up", + &p_global_cardinality_low_up); + global_model_builder.Register("global_cardinality_low_up_closed", + &p_global_cardinality_low_up_closed); global_model_builder.Register("global_cardinality_old", &p_global_cardinality_old); global_model_builder.Register("table_int", &p_table_int); diff --git a/src/util/const_int_array.h b/src/util/const_int_array.h index bac4b96ff7..35a3816cf3 100644 --- a/src/util/const_int_array.h +++ b/src/util/const_int_array.h @@ -133,6 +133,10 @@ class ConstIntArray { return data_->data(); } + const std::vector& RawVector() const { + return *data_.get(); + } + // Check the status of a given info bit. It will scan the array on demand. // This is not valid after Release() has been called. bool HasProperty(Property info);