00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 namespace Gecode { namespace Int { namespace GCC {
00023 template <class View, class Card, bool isView>
00024 inline ExecStatus
00025 prop_val(Space* home, ViewArray<View>& x, ViewArray<Card>& k,
00026 bool& _cardall){
00027
00028 bool mod = false;
00029 int n = x.size();
00030 int m = k.size();
00031
00032
00033 GECODE_AUTOARRAY(int, count, m);
00034
00035 GECODE_AUTOARRAY(int, rem, m);
00036
00037 GECODE_AUTOARRAY(bool, onrem, m);
00038
00039 int rs = 0;
00040
00041
00042 int sum_min = 0;
00043 int removed = 0;
00044 for (int i = m; i--; ) {
00045
00046 removed += k[i].counter();
00047 sum_min += k[i].min();
00048
00049 count[i] = 0;
00050 onrem[i] = false;
00051 }
00052
00053 for (int i = m; i--; ) {
00054
00055
00056 if (!k[i].assigned()) {
00057 int mub = n + removed - (sum_min - k[i].min());
00058 ModEvent me = k[i].lq(home, mub);
00059 GECODE_ME_CHECK(me);
00060 mod |= (me_modified(me) && k[i].max() != mub);
00061 }
00062 }
00063
00064
00065 bool all_assigned = true;
00066
00067 int noa = 0;
00068
00069 int t_noa = 0;
00070 for (int i = n; i--; ) {
00071 bool b = x[i].assigned();
00072 all_assigned &= b;
00073 if (b) {
00074 int idx = lookupValue(k,x[i].val());
00075 if (idx == -1) {
00076 return ES_FAILED;
00077 }
00078 count[idx]++;
00079 noa++;
00080 }
00081 }
00082
00083
00084 int non = x.size() - noa;
00085
00086
00087 if (all_assigned) {
00088
00089 for (int i = m; i--; ) {
00090 int ci = count[i] + k[i].counter();
00091 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00092 return ES_FAILED;
00093 }
00094
00095 if (isView) {
00096 if (!k[i].assigned()) {
00097 ModEvent me = k[i].eq(home, ci);
00098 GECODE_ME_CHECK(me);
00099 mod |= k[i].assigned();
00100 }
00101 }
00102 }
00103 return ES_SUBSUMED;
00104 }
00105
00106
00107 int req = 0;
00108
00109
00110 int n_r = 0;
00111
00112
00113 int single = 0;
00114
00115 for (int i = m; i--; ) {
00116 int ci = count[i] + k[i].counter();
00117 t_noa += ci;
00118 if (ci == 0) {
00119 req += k[i].min();
00120 n_r++;
00121 single = i;
00122 }
00123
00124
00125
00126 if (req > non) {
00127 return ES_FAILED;
00128 }
00129 }
00130
00131
00132 if (req == non && n_r == 1) {
00133 for (int i = n; i--; ) {
00134
00135 if (!x[i].assigned()) {
00136 ModEvent me = x[i].eq(home, k[single].card());
00137 count[single]++;
00138 GECODE_ME_CHECK(me);
00139 }
00140 }
00141
00142 for (int i = m; i--; ) {
00143 int ci = count[i] + k[i].counter();
00144
00145 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00146 return ES_FAILED;
00147 }
00148
00149 if (isView) {
00150 if (!k[i].assigned()) {
00151 ModEvent me = k[i].eq(home, ci);
00152 GECODE_ME_CHECK(me);
00153 }
00154 }
00155 }
00156 return ES_SUBSUMED;
00157 }
00158
00159 for (int i = m; i--; ) {
00160 int ci = count[i] + k[i].counter();
00161 if (ci == k[i].max() && !onrem[i]) {
00162 rem[rs] = k[i].card();
00163 k[i].counter(ci);
00164 rs++;
00165 onrem[i] = true;
00166 if (isView) {
00167
00168 if (!k[i].assigned()) {
00169 ModEvent me = k[i].eq(home, ci);
00170 GECODE_ME_CHECK(me);
00171 mod |= k[i].assigned();
00172 }
00173 }
00174 } else {
00175 if (ci > k[i].max()) {
00176 return ES_FAILED;
00177 }
00178
00179
00180 if (isView) {
00181 if (!k[i].assigned()) {
00182 if (ci > k[i].min()) {
00183 ModEvent me = k[i].gq(home, ci);
00184 GECODE_ME_CHECK(me);
00185 mod |= k[i].assigned();
00186 mod |= (me_modified(me) && k[i].min() != ci);
00187 }
00188 int occupied = t_noa - ci;
00189 int mub = x.size() + removed - occupied;
00190
00191 ModEvent me = k[i].lq(home, mub);
00192 GECODE_ME_CHECK(me);
00193 mod |= k[i].assigned();
00194 mod |= (me_failed(me) && k[i].max() != mub);
00195 }
00196 }
00197 }
00198
00199 count[i] = 0;
00200 }
00201
00202
00203 for (int i = n; i--; ) {
00204 bool b = x[i].assigned();
00205 if (b) {
00206 int idx = lookupValue(k,x[i].val());
00207 if (idx == -1) {
00208 return ES_FAILED;
00209 }
00210 if (onrem[idx]) {
00211 x[i] = x[--n];
00212 x.size(n);
00213 }
00214 }
00215 }
00216
00217
00218 if (rs > 0) {
00219 IntSet remset(&rem[0], rs);
00220 IntSetRanges rr(remset);
00221 for (int i = x.size(); i--;) {
00222 if (!x[i].assigned()) {
00223 ModEvent me = x[i].minus(home, rr);
00224 if (me_failed(me)) {
00225 return ES_FAILED;
00226 }
00227 mod |= x[i].assigned();
00228 }
00229 }
00230 }
00231
00232 all_assigned = true;
00233
00234 for (int i = x.size(); i--; ) {
00235 bool b = x[i].assigned();
00236 all_assigned &= b;
00237 if (b) {
00238 int idx = lookupValue(k,x[i].val());
00239 if (idx == -1) {
00240 return ES_FAILED;
00241 }
00242 count[idx]++;
00243 }
00244 }
00245
00246 if (all_assigned) {
00247 for (int i = k.size(); i--; ) {
00248 int ci = count[i] + k[i].counter();
00249 if (!(k[i].min() <= ci && ci <= k[i].max())) {
00250 return ES_FAILED;
00251 }
00252
00253 if (isView) {
00254 if (!k[i].assigned()) {
00255 ModEvent me = k[i].eq(home, ci);
00256 GECODE_ME_CHECK(me);
00257 mod |= k[i].assigned();
00258 }
00259 }
00260 }
00261 return ES_SUBSUMED;
00262 }
00263
00264 if (isView) {
00265
00266 int reqmin = 0;
00267 int allmax = 0;
00268 m = k.size();
00269 n = x.size();
00270 for (int i = m; i--; ) {
00271 int ci = k[i].counter();
00272 if (ci > k[i].max() ) {
00273 return ES_FAILED;
00274 } else {
00275 allmax += (k[i].max() - ci);
00276 if (ci < k[i].min()) {
00277 reqmin += (k[i].min() - ci);
00278 }
00279 }
00280 if (k[i].min() > n) {
00281 return ES_FAILED;
00282 }
00283 if (!k[i].assigned()) {
00284 ModEvent me = k[i].lq(home, n);
00285 if (me_failed(me)) {
00286 return ES_FAILED;
00287 }
00288 }
00289 }
00290
00291 if (n < reqmin) {
00292 return ES_FAILED;
00293 }
00294
00295 if (_cardall && allmax < n) {
00296 return ES_FAILED;
00297 }
00298 }
00299 return mod ? ES_NOFIX : ES_FIX;
00300 }
00301
00302
00303
00304
00305
00306
00307 template <class View, class Card, bool isView>
00308 inline
00309 Val<View, Card, isView>::Val(Space* home, ViewArray<View>& x0,
00310 ViewArray<Card>& k0,
00311 bool all)
00312 :Propagator(home,true), x(x0), k(k0), card_all(all){
00313 x.subscribe(home, this, PC_INT_VAL);
00314 k.subscribe(home, this, PC_INT_VAL);
00315 }
00316
00317 template <class View, class Card, bool isView>
00318 forceinline
00319 Val<View, Card, isView>::Val(Space* home, bool share,
00320 Val<View, Card, isView>& p)
00321 : Propagator(home,share,p), card_all(p.card_all){
00322 x.update(home,share, p.x);
00323 k.update(home,share, p.k);
00324 }
00325
00326 template <class View, class Card, bool isView>
00327 size_t
00328 Val<View, Card, isView>::dispose(Space* home) {
00329 if (!home->failed()) {
00330 x.cancel(home,this, PC_INT_VAL);
00331 k.cancel(home,this, PC_INT_VAL);
00332 }
00333 (void) Propagator::dispose(home);
00334 return sizeof(*this);
00335 }
00336
00337 template <class View, class Card, bool isView>
00338 Actor*
00339 Val<View, Card, isView>::copy(Space* home, bool share) {
00340 return new (home) Val<View, Card, isView>(home,share,*this);
00341 }
00342
00343 template <class View, class Card, bool isView>
00344 ExecStatus
00345 Val<View, Card, isView>::post(Space* home,
00346 ViewArray<View>& x0,
00347 ViewArray<Card>& k0, bool all) {
00348 new (home) Val<View, Card, isView>(home, x0, k0, all);
00349 return ES_OK;
00350 }
00351
00357 template <class View, class Card, bool isView>
00358 PropCost
00359 Val<View, Card, isView>::cost (void) const {
00360 return PC_LINEAR_HI;
00361 }
00362
00363 template <class View, class Card, bool isView>
00364 ExecStatus
00365 Val<View, Card, isView>::propagate(Space* home) {
00366 assert(x.size() > 0);
00367 return prop_val<View, Card, isView>(home, x, k, card_all);
00368 }
00369
00370 }}}
00371
00372
00373