00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "gecode/cpltset/propagators.hh"
00039
00040 using namespace Gecode::CpltSet;
00041
00042 namespace Gecode {
00043
00044 namespace CpltSet { namespace AtMost {
00045
00052 template <class View>
00053 void
00054 atmostOne_post(Space* home, ViewArray<View>& x, int c) {
00055 if (home->failed()) return;
00056 int n = x.size();
00057
00058 int minx = x[0].initialLubMin();
00059 int maxx = x[0].initialLubMax();
00060 unsigned int xtab = x[0].tableWidth();
00061 for (int i = n; i--;) {
00062 if (x[i].initialLubMin() < minx) {
00063 minx = x[i].initialLubMin();
00064 }
00065 if (x[i].initialLubMax() > maxx) {
00066 maxx = x[i].initialLubMax();
00067 }
00068 if (x[i].tableWidth() > xtab) {
00069 xtab = x[i].tableWidth();
00070 }
00071 }
00072
00073 bdd d0 = bdd_true();
00074 for (int i = 0; i < n; i++) {
00075 unsigned int xoff = x[i].offset();
00076 unsigned int xtab = x[i].tableWidth();
00077 d0 &= cardcheck(xtab, xoff, c, c);
00078 }
00079
00080 for (int i = 0; i < n - 1; i++) {
00081 for (int j = i + 1; j < n; j++) {
00082 d0 &= extcardcheck(x[i], x[j], 0, 1);
00083 }
00084 }
00085 GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00086 }
00087
00088 template <class View>
00089 void
00090 atmost_post(Space* home, ViewArray<View>& x, int c,
00091 SetRelType, int) {
00092 if (home->failed()) return;
00093
00094 unsigned int x1_tab = x[1].tableWidth();
00095
00096
00097 bdd d0 = bdd_true();
00098
00099
00100 for (unsigned int i = x1_tab; i--;) {
00101 d0 &= ((x[0].element(i) & x[1].element(i)) % (x[2].element(i)));
00102 }
00103
00104
00105 bdd c0 = bdd_true();
00106 unsigned int off = x[2].offset();
00107 unsigned int tab = x[2].tableWidth();
00108
00109 c0 = cardcheck(tab, off, 0, c);
00110
00111
00112 d0 &= c0;
00113
00114 GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00115
00116 }
00117
00118 template <class View>
00119 void
00120 atmost_post(Space* home, ViewArray<View>& x, int c,
00121 CpltSetRelType lex, int card) {
00122 if (home->failed()) return;
00123
00124 unsigned int x1_tab = x[1].tableWidth();
00125
00126
00127 bdd d0 = bdd_true();
00128
00129
00130 for (unsigned int i = x1_tab; i--;) {
00131 d0 &= ((x[0].element(i) & x[1].element(i)) % (x[2].element(i)));
00132 }
00133
00134
00135 bdd c0 = bdd_true();
00136 unsigned int off = x[2].offset();
00137 unsigned int tab = x[2].tableWidth();
00138
00139 c0 = cardcheck(tab, off, 0, c);
00140
00141
00142 d0 &= c0;
00143
00144
00145
00146 unsigned int xoff = x[0].offset();
00147 unsigned int yoff = x[1].offset();
00148 unsigned int xtab = x[0].tableWidth();
00149 unsigned int ytab = x[1].tableWidth();
00150 switch (lex) {
00151 case SRT_LE:
00152 {
00153 d0 &= lexlt(xoff, yoff, xtab, xtab - 1);
00154 break;
00155 }
00156 case SRT_GR:
00157 {
00158 d0 &= lexlt(yoff, xoff, xtab, xtab - 1);
00159 break;
00160 }
00161 case SRT_LQ:
00162 {
00163 d0 &= lexlq(xoff, yoff, xtab, xtab - 1);
00164 break;
00165 }
00166 case SRT_GQ:
00167 {
00168 d0 &= lexlq(yoff, xoff, xtab, xtab - 1);
00169 break;
00170 }
00171 case SRT_LE_REV:
00172 {
00173 d0 &= lexltrev(xoff, yoff, xtab, 0);
00174 break;
00175 }
00176 case SRT_GR_REV:
00177 {
00178 d0 &= lexltrev(yoff, xoff, xtab, 0);
00179 break;
00180 }
00181 case SRT_LQ_REV:
00182 {
00183 d0 &= lexlqrev(xoff, yoff, xtab, 0);
00184 break;
00185 }
00186 case SRT_GQ_REV:
00187 {
00188 d0 &= lexlqrev(yoff, xoff, xtab, 0);
00189 break;
00190 }
00191 default:
00192 {
00193
00194 break;
00195 }
00196 }
00197
00198
00199 GECODE_ES_FAIL(home, NaryCpltSetPropagator<View>::post(home, x, d0));
00200
00201 }
00202
00203 template <class View>
00204 void
00205 atmost_post(Space* home, View& x, View& y, int c, CpltSetRelType lex,
00206 int card) {
00207 if (home->failed()) return;
00208
00209 unsigned int xoff = x.offset();
00210 unsigned int yoff = y.offset();
00211 unsigned int xtab = x.tableWidth();
00212 unsigned int ytab = y.tableWidth();
00213
00214
00215 bdd d0 = bdd_true();
00216 d0 = extcardcheck(x, y, 0, c);
00217
00218
00219 switch (lex) {
00220 case SRT_LE:
00221 {
00222 d0 &= lexlt(xoff, yoff, xtab, xtab - 1);
00223 break;
00224 }
00225 case SRT_GR:
00226 {
00227 d0 &= lexlt(yoff, xoff, xtab, xtab - 1);
00228 break;
00229 }
00230 case SRT_LQ:
00231 {
00232 d0 &= lexlq(xoff, yoff, xtab, xtab - 1);
00233 break;
00234 }
00235 case SRT_GQ:
00236 {
00237 d0 &= lexlq(yoff, xoff, xtab, xtab - 1);
00238 break;
00239 }
00240 case SRT_LE_REV:
00241 {
00242 d0 &= lexltrev(xoff, yoff, xtab, 0);
00243 break;
00244 }
00245 case SRT_GR_REV:
00246 {
00247 d0 &= lexltrev(yoff, xoff, xtab, 0);
00248 break;
00249 }
00250 case SRT_LQ_REV:
00251 {
00252 d0 &= lexlqrev(xoff, yoff, xtab, 0);
00253 break;
00254 }
00255 case SRT_GQ_REV:
00256 {
00257 d0 &= lexlqrev(yoff, xoff, xtab, 0);
00258 break;
00259 }
00260 default:
00261 {
00262
00263 break;
00264 }
00265 }
00266
00267
00268 if (card > -1) {
00269 d0 &= cardcheck(xtab, xoff, card, card);
00270 d0 &= cardcheck(ytab, yoff, card, card);
00271 }
00272
00273 if (x.assigned()) {
00274 d0 &= x.dom();
00275 }
00276
00277 if (y.assigned()) {
00278 d0 &= y.dom();
00279 }
00280 GECODE_ES_FAIL(home,
00281 (BinaryCpltSetPropagator<View,View>::post(home, x, y, d0)));
00282 }
00283
00284 template <class View>
00285 void
00286 atmost_post(Space* home, View& x, View& y, int c, SetRelType,
00287 int card) {
00288 if (home->failed()) return;
00289
00290 unsigned int xoff = x.offset();
00291 unsigned int yoff = y.offset();
00292 unsigned int xtab = x.tableWidth();
00293 unsigned int ytab = y.tableWidth();
00294
00295
00296 bdd d0 = bdd_true();
00297 d0 = extcardcheck(x, y, 0, c);
00298
00299
00300
00301
00302 if (card > -1) {
00303 d0 &= cardcheck(xtab, xoff, card, card);
00304 d0 &= cardcheck(ytab, yoff, card, card);
00305 }
00306
00307 if (x.assigned()) {
00308 d0 &= x.dom();
00309 }
00310
00311 if (y.assigned()) {
00312 d0 &= y.dom();
00313 }
00314 GECODE_ES_FAIL(home,
00315 (BinaryCpltSetPropagator<View,View>::post(home, x, y, d0)));
00316 }
00317
00318 template <class Rel>
00319 forceinline void
00320 atmost_con(Space* home, const CpltSetVar& x, const CpltSetVar& y, int c,
00321 Rel lex, int card) {
00322 CpltSetView xv(x);
00323 CpltSetView yv(y);
00324 atmost_post(home, xv, yv, c, lex, card);
00325 }
00326
00327 template <class Rel>
00328 forceinline void
00329 atmost_con(Space* home, const CpltSetVar& x, const CpltSetVar& y,
00330 const CpltSetVar& z, int c, Rel lex, int card) {
00331 ViewArray<CpltSetView> bv(home, 3);
00332 bv[0] = x;
00333 bv[1] = y;
00334 bv[2] = z;
00335 atmost_post(home, bv, c, lex, card);
00336 }
00337
00338
00339 forceinline void
00340 atmostOne_con(Space* home, const CpltSetVarArgs& x, int c) {
00341 int n = x.size();
00342 ViewArray<CpltSetView> bv(home, n);
00343 for (int i = 0; i < n; i++) {
00344 bv[i] = x[i];
00345 }
00346 atmostOne_post(home, bv, c);
00347 }
00348
00349
00350 }}
00351
00352 using namespace CpltSet::AtMost;
00353
00354 void
00355 exactly(Space* home, CpltSetVar x, IntSet& is, unsigned int c) {
00356 if (home->failed()) return;
00357 Set::Limits::check(c, "CpltSet::exactly");
00358
00359 ViewArray<CpltSetView> bv(home, 1);
00360 bv[0] = x;
00361
00362 CpltSetVarGlbRanges glb(x);
00363 if (glb()) {
00364 IntSetRanges ir(is);
00365 Gecode::Iter::Ranges::Inter<CpltSetVarGlbRanges, IntSetRanges>
00366 inter(glb, ir);
00367 if (inter()) {
00368 int s = inter.width();
00369 ++inter;
00370 if (!inter() && s == 1) {
00371 return;
00372 } else {
00373 home->fail();
00374 return;
00375 }
00376 }
00377 }
00378
00379 CpltSetVarUnknownRanges delta(x);
00380 IntSetRanges irange(is);
00381 Gecode::Iter::Ranges::Inter<CpltSetVarUnknownRanges, IntSetRanges>
00382 interdel(delta, irange);
00383 if (!interdel()) {
00384 home->fail();
00385 return;
00386 }
00387
00388 int mi = interdel.min();
00389 int ma = interdel.max();
00390 int s = interdel.width();
00391 ++interdel;
00392 if (!interdel() && s == 1) {
00393 GECODE_ME_FAIL(home, bv[0].include(home, mi));
00394 return;
00395 }
00396
00397 Iter::Ranges::SingletonAppend<
00398 Gecode::Iter::Ranges::Inter<CpltSetVarUnknownRanges, IntSetRanges>
00399 > si(mi,ma,interdel);
00400
00401 unsigned int xtab = bv[0].tableWidth();
00402 unsigned int xoff = bv[0].offset();
00403 int xmin = bv[0].initialLubMin();
00404
00405 bdd d = cardConst(xtab, xoff, xmin, c, c, si);
00406 GECODE_ES_FAIL(home,
00407 UnaryCpltSetPropagator<CpltSetView>::post(home, bv[0], d));
00408 }
00409
00410 void
00411 atmost(Space* home, CpltSetVar x, IntSet& is, unsigned int c) {
00412 Set::Limits::check(c, "CpltSet::atmost");
00413 if (home->failed()) return;
00414 ViewArray<CpltSetView> bv(home, 1);
00415 bv[0] = x;
00416
00417 unsigned int xtab = bv[0].tableWidth();
00418 unsigned int xoff = bv[0].offset();
00419 int xmin = bv[0].initialLubMin();
00420 IntSetRanges ir(is);
00421 bdd d = cardConst(xtab, xoff, xmin, 0, c, ir);
00422
00423 GECODE_ES_FAIL(home,
00424 UnaryCpltSetPropagator<CpltSetView>::post(home, bv[0], d));
00425 }
00426
00427 void
00428 atmost(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c) {
00429 Set::Limits::check(c, "CpltSet::atmost");
00430 atmost_con(home, x, y, c, SRT_EQ, -1);
00431 }
00432
00433 void
00434 atmostLex(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c,
00435 CpltSetRelType lex) {
00436 Set::Limits::check(c, "CpltSet::atmostLex");
00437 atmost_con(home, x, y, c, lex, -1);
00438 }
00439
00440 void
00441 atmostLexCard(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c,
00442 CpltSetRelType lex, unsigned int d) {
00443 Set::Limits::check(c, "CpltSet::atmostLexCard");
00444 Set::Limits::check(d, "CpltSet::atmostLexCard");
00445 atmost_con(home, x, y, c, lex, d);
00446 }
00447
00448 void
00449 atmostCard(Space* home, CpltSetVar x, CpltSetVar y, unsigned int c,
00450 unsigned int d) {
00451 Set::Limits::check(c, "CpltSet::atmostCard");
00452 Set::Limits::check(d, "CpltSet::atmostCard");
00453 atmost_con(home, x, y, c, SRT_EQ, d);
00454 }
00455
00456 void
00457 atmost(Space* home, CpltSetVar x, CpltSetVar y, CpltSetVar z,
00458 unsigned int c) {
00459 Set::Limits::check(c, "CpltSet::atmost");
00460 atmost_con(home, x, y, z, c, SRT_EQ, -1);
00461 }
00462
00463 void
00464 atmostOne(Space* home, const CpltSetVarArgs& x, unsigned int c) {
00465 Set::Limits::check(c, "CpltSet::atmostOne");
00466 atmostOne_con(home, x, c);
00467 }
00468
00469
00470 }
00471
00472