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/kernel.hh>
00039
00040 namespace Gecode {
00041
00042
00043
00044
00045
00046 void
00047 VarImpDisposerBase::dispose(Space&,VarImpBase*) {}
00048
00049 VarImpDisposerBase::~VarImpDisposerBase(void) {}
00050
00051
00052
00053
00054
00055
00056
00057 Actor* Actor::sentinel;
00058
00059 #ifdef __GNUC__
00060
00061 Actor::~Actor(void) {}
00062 #endif
00063
00064
00065
00066
00067
00068
00069
00070 ExecStatus
00071 Propagator::advise(Space&, Advisor&, const Delta&) {
00072 assert(false);
00073 return ES_FAILED;
00074 }
00075
00076
00077
00078
00079
00080
00081 void
00082 NoGoods::post(Space&) const {
00083 }
00084
00085 NoGoods NoGoods::eng;
00086
00087
00088
00089
00090
00091 NGL*
00092 Brancher::ngl(Space&, const Choice&, unsigned int) const {
00093 return NULL;
00094 }
00095
00096 void
00097 Brancher::print(const Space&, const Choice&, unsigned int,
00098 std::ostream&) const {
00099 }
00100
00101
00102
00103
00104
00105
00106 StatusStatistics Space::unused_status;
00107 CloneStatistics Space::unused_clone;
00108 CommitStatistics Space::unused_commit;
00109
00110 #ifdef GECODE_HAS_VAR_DISPOSE
00111 VarImpDisposerBase* Space::vd[AllVarConf::idx_d];
00112 #endif
00113
00114 Space::Space(void)
00115 : sm(new SharedMemory), mm(sm), _wmp_afc(0U) {
00116 #ifdef GECODE_HAS_VAR_DISPOSE
00117 for (int i=0; i<AllVarConf::idx_d; i++)
00118 _vars_d[i] = NULL;
00119 #endif
00120
00121 pl.init();
00122 bl.init();
00123 b_status = b_commit = Brancher::cast(&bl);
00124
00125 d_fst = d_cur = d_lst = NULL;
00126
00127 pc.p.active = &pc.p.queue[0]-1;
00128
00129 for (int i=0; i<=PropCost::AC_MAX; i++)
00130 pc.p.queue[i].init();
00131 pc.p.branch_id = reserved_branch_id+1;
00132 pc.p.n_sub = 0;
00133 }
00134
00135 void
00136 Space::notice(Actor& a, ActorProperty p, bool duplicate) {
00137 if (p & AP_DISPOSE) {
00138 if (duplicate && (d_fst != NULL)) {
00139 for (Actor** f = d_fst; f < d_cur; f++)
00140 if (&a == *f)
00141 return;
00142 }
00143 if (d_cur == d_lst) {
00144
00145 if (d_fst == NULL) {
00146
00147 d_fst = alloc<Actor*>(4);
00148 d_cur = d_fst;
00149 d_lst = d_fst+4;
00150 } else {
00151
00152 unsigned int n = static_cast<unsigned int>(d_lst - d_fst);
00153 assert(n != 0);
00154 d_fst = realloc<Actor*>(d_fst,n,2*n);
00155 d_cur = d_fst+n;
00156 d_lst = d_fst+2*n;
00157 }
00158 }
00159 *(d_cur++) = &a;
00160 } else if (p & AP_WEAKLY) {
00161 if (wmp() == 0)
00162 wmp(2);
00163 else
00164 wmp(wmp()+1);
00165 }
00166 }
00167
00168 void
00169 Space::ignore(Actor& a, ActorProperty p, bool duplicate) {
00170 if (p & AP_DISPOSE) {
00171
00172
00173 if (d_fst == NULL)
00174 return;
00175 Actor** f = d_fst;
00176 if (duplicate) {
00177 while (f < d_cur)
00178 if (&a == *f)
00179 break;
00180 else
00181 f++;
00182 if (f == d_cur)
00183 return;
00184 } else {
00185 while (&a != *f)
00186 f++;
00187 }
00188 *f = *(--d_cur);
00189 } else if (p & AP_WEAKLY) {
00190 assert(wmp() > 1U);
00191 wmp(wmp()-1);
00192 }
00193 }
00194
00195 unsigned int
00196 Space::propagators(void) const {
00197 unsigned int n = 0;
00198 for (Propagators p(*this); p(); ++p)
00199 n++;
00200 return n;
00201 }
00202
00203 unsigned int
00204 Space::branchers(void) const {
00205 unsigned int n = 0;
00206 for (Branchers b(*this); b(); ++b)
00207 n++;
00208 return n;
00209 }
00210
00211 void
00212 Space::flush(void) {
00213
00214 sm->flush();
00215 }
00216
00217 Space::~Space(void) {
00218
00219 fail();
00220
00221 {
00222 Actor** a = d_fst;
00223 Actor** e = d_cur;
00224
00225 d_fst = NULL;
00226 while (a < e) {
00227 (void) (*a)->dispose(*this);
00228 a++;
00229 }
00230 }
00231 #ifdef GECODE_HAS_VAR_DISPOSE
00232
00233 for (int i=AllVarConf::idx_d; i--;)
00234 if (_vars_d[i] != NULL)
00235 vd[i]->dispose(*this, _vars_d[i]);
00236 #endif
00237
00238 mm.release(sm);
00239
00240 if (sm->release())
00241 delete sm;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251 SpaceStatus
00252 Space::status(StatusStatistics& stat) {
00253 SpaceStatus s = SS_FAILED;
00254
00255 if (failed()) {
00256 s = SS_FAILED; goto exit;
00257 }
00258 assert(pc.p.active <= &pc.p.queue[PropCost::AC_MAX+1]);
00259
00260 if (pc.p.active >= &pc.p.queue[0]) {
00261 Propagator* p;
00262 ModEventDelta med_o;
00263 goto unstable;
00264 execute:
00265 stat.propagate++;
00266
00267 med_o = p->u.med;
00268
00269 p->u.med = 0;
00270 switch (p->propagate(*this,med_o)) {
00271 case ES_FAILED:
00272
00273 if (afc_enabled())
00274 gafc.fail(p->gafc);
00275
00276 fail(); s = SS_FAILED; goto exit;
00277 case ES_NOFIX:
00278
00279 if (p->u.med != 0) {
00280 unstable:
00281
00282 do {
00283 assert(pc.p.active >= &pc.p.queue[0]);
00284
00285 ActorLink* fst = pc.p.active->next();
00286 if (pc.p.active != fst) {
00287 p = Propagator::cast(fst);
00288 goto execute;
00289 }
00290 pc.p.active--;
00291 } while (true);
00292 GECODE_NEVER;
00293 }
00294
00295 case ES_FIX:
00296
00297 p->u.med = 0; p->unlink(); pl.head(p);
00298 stable_or_unstable:
00299
00300 do {
00301 assert(pc.p.active >= &pc.p.queue[0]);
00302
00303 ActorLink* fst = pc.p.active->next();
00304 if (pc.p.active != fst) {
00305 p = Propagator::cast(fst);
00306 goto execute;
00307 }
00308 } while (--pc.p.active >= &pc.p.queue[0]);
00309 assert(pc.p.active < &pc.p.queue[0]);
00310 goto stable;
00311 case __ES_SUBSUMED:
00312 p->unlink(); rfree(p,p->u.size);
00313 goto stable_or_unstable;
00314 case __ES_PARTIAL:
00315
00316 assert(p->u.med != 0);
00317 enqueue(p);
00318 goto unstable;
00319 default:
00320 GECODE_NEVER;
00321 }
00322 }
00323 stable:
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 while (b_status != Brancher::cast(&bl))
00348 if (b_status->status(*this)) {
00349
00350 s = SS_BRANCH; goto exit;
00351 } else {
00352
00353 b_status = Brancher::cast(b_status->next());
00354 }
00355
00356 s = SS_SOLVED;
00357 exit:
00358 stat.wmp = (wmp() > 0U);
00359 if (wmp() == 1U)
00360 wmp(0U);
00361 return s;
00362 }
00363
00364
00365 const Choice*
00366 Space::choice(void) {
00367 if (!stable())
00368 throw SpaceNotStable("Space::choice");
00369 if (failed() || (b_status == Brancher::cast(&bl))) {
00370
00371
00372 Brancher* b = Brancher::cast(bl.next());
00373 while (b != Brancher::cast(&bl)) {
00374 Brancher* d = b;
00375 b = Brancher::cast(b->next());
00376 rfree(d,d->dispose(*this));
00377 }
00378 bl.init();
00379 b_status = b_commit = Brancher::cast(&bl);
00380 return NULL;
00381 }
00382
00383
00384
00385
00386 Brancher* b = Brancher::cast(bl.next());
00387 while (b != b_status) {
00388 Brancher* d = b;
00389 b = Brancher::cast(b->next());
00390 d->unlink();
00391 rfree(d,d->dispose(*this));
00392 }
00393
00394 b_commit = b_status;
00395 return b_status->choice(*this);
00396 }
00397
00398 const Choice*
00399 Space::choice(Archive& e) const {
00400 unsigned int id; e >> id;
00401 Brancher* b_cur = Brancher::cast(bl.next());
00402 while (b_cur != Brancher::cast(&bl)) {
00403 if (id == b_cur->id())
00404 return b_cur->choice(*this,e);
00405 b_cur = Brancher::cast(b_cur->next());
00406 }
00407 throw SpaceNoBrancher("Space::choice");
00408 }
00409
00410 void
00411 Space::_commit(const Choice& c, unsigned int a) {
00412 if (a >= c.alternatives())
00413 throw SpaceIllegalAlternative("Space::commit");
00414 if (failed())
00415 return;
00416 if (Brancher* b = brancher(c._id)) {
00417
00418 if (b->commit(*this,c,a) == ES_FAILED)
00419 fail();
00420 } else {
00421
00422 throw SpaceNoBrancher("Space::commit");
00423 }
00424 }
00425
00426 void
00427 Space::_trycommit(const Choice& c, unsigned int a) {
00428 if (a >= c.alternatives())
00429 throw SpaceIllegalAlternative("Space::commit");
00430 if (failed())
00431 return;
00432 if (Brancher* b = brancher(c._id)) {
00433
00434 if (b->commit(*this,c,a) == ES_FAILED)
00435 fail();
00436 }
00437 }
00438
00439 NGL*
00440 Space::ngl(const Choice& c, unsigned int a) {
00441 if (a >= c.alternatives())
00442 throw SpaceIllegalAlternative("Space::ngl");
00443 if (failed())
00444 return NULL;
00445 if (Brancher* b = brancher(c._id)) {
00446
00447 return b->ngl(*this,c,a);
00448 } else {
00449 return NULL;
00450 }
00451 }
00452
00453 void
00454 Space::print(const Choice& c, unsigned int a, std::ostream& o) const {
00455 if (a >= c.alternatives())
00456 throw SpaceIllegalAlternative("Space::print");
00457 if (failed())
00458 return;
00459 if (Brancher* b = const_cast<Space&>(*this).brancher(c._id)) {
00460
00461 b->print(*this,c,a,o);
00462 } else {
00463
00464 throw SpaceNoBrancher("Space::print");
00465 }
00466 }
00467
00468 void
00469 Space::kill_brancher(unsigned int id) {
00470 if (failed())
00471 return;
00472 for (Brancher* b = Brancher::cast(bl.next());
00473 b != Brancher::cast(&bl); b = Brancher::cast(b->next()))
00474 if (b->id() == id) {
00475
00476 if (b_commit == b)
00477 b_commit = Brancher::cast(b->next());
00478 if (b_status == b)
00479 b_status = Brancher::cast(b->next());
00480 b->unlink();
00481 rfree(b,b->dispose(*this));
00482 return;
00483 }
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 Space::Space(bool share, Space& s)
00501 : sm(s.sm->copy(share)),
00502 mm(sm,s.mm,s.pc.p.n_sub*sizeof(Propagator**)),
00503 gafc(s.gafc),
00504 d_fst(&Actor::sentinel),
00505 _wmp_afc(s._wmp_afc) {
00506 #ifdef GECODE_HAS_VAR_DISPOSE
00507 for (int i=0; i<AllVarConf::idx_d; i++)
00508 _vars_d[i] = NULL;
00509 #endif
00510 for (int i=0; i<AllVarConf::idx_c; i++)
00511 pc.c.vars_u[i] = NULL;
00512 pc.c.vars_noidx = NULL;
00513 pc.c.shared = NULL;
00514 pc.c.local = NULL;
00515
00516 {
00517 ActorLink* p = &pl;
00518 ActorLink* e = &s.pl;
00519 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00520 Actor* c = Actor::cast(a)->copy(*this,share);
00521
00522 p->next(ActorLink::cast(c)); ActorLink::cast(c)->prev(p);
00523
00524 p = c;
00525 }
00526
00527 p->next(&pl); pl.prev(p);
00528 }
00529
00530 {
00531 ActorLink* p = &bl;
00532 ActorLink* e = &s.bl;
00533 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00534 Actor* c = Actor::cast(a)->copy(*this,share);
00535
00536 p->next(ActorLink::cast(c)); ActorLink::cast(c)->prev(p);
00537
00538 p = c;
00539 }
00540
00541 p->next(&bl); bl.prev(p);
00542 }
00543
00544 if (s.b_status == &s.bl) {
00545 b_status = Brancher::cast(&bl);
00546 } else {
00547 b_status = Brancher::cast(s.b_status->prev());
00548 }
00549 if (s.b_commit == &s.bl) {
00550 b_commit = Brancher::cast(&bl);
00551 } else {
00552 b_commit = Brancher::cast(s.b_commit->prev());
00553 }
00554 }
00555
00556 Space*
00557 Space::_clone(bool share) {
00558 if (failed())
00559 throw SpaceFailed("Space::clone");
00560 if (!stable())
00561 throw SpaceNotStable("Space::clone");
00562
00563
00564 Space* c = copy(share);
00565
00566 if (c->d_fst != &Actor::sentinel)
00567 throw SpaceNotCloned("Space::clone");
00568
00569
00570 {
00571 unsigned int n = static_cast<unsigned int>(d_cur - d_fst);
00572 if (n == 0) {
00573
00574 c->d_fst = c->d_cur = c->d_lst = NULL;
00575 } else {
00576
00577 c->d_fst = c->alloc<Actor*>(n+1);
00578 c->d_cur = c->d_fst;
00579 c->d_lst = c->d_fst+n+1;
00580 for (Actor** d_fst_iter = d_fst; d_fst_iter != d_cur; d_fst_iter++) {
00581 if ((*d_fst_iter)->prev())
00582 *(c->d_cur++) = Actor::cast((*d_fst_iter)->prev());
00583 }
00584 }
00585 }
00586
00587
00588 VarImp<NoIdxVarImpConf>* x =
00589 static_cast<VarImp<NoIdxVarImpConf>*>(c->pc.c.vars_noidx);
00590 while (x != NULL) {
00591 VarImp<NoIdxVarImpConf>* n = x->next();
00592 x->b.base = NULL; x->u.idx[0] = 0;
00593 if (sizeof(ActorLink**) > sizeof(unsigned int))
00594 *(1+&x->u.idx[0]) = 0;
00595 x = n;
00596 }
00597
00598 c->update(static_cast<ActorLink**>(c->mm.subscriptions()));
00599
00600
00601 {
00602 ActorLink* p_a = &pl;
00603 ActorLink* c_a = p_a->next();
00604
00605 while (c_a != &pl) {
00606 Propagator* p = Propagator::cast(c_a);
00607 if (p->u.advisors != NULL) {
00608 ActorLink* a = p->u.advisors;
00609 p->u.advisors = NULL;
00610 do {
00611 a->prev(p); a = a->next();
00612 } while (a != NULL);
00613 }
00614 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
00615 }
00616 }
00617 {
00618 ActorLink* p_a = &bl;
00619 ActorLink* c_a = p_a->next();
00620
00621 while (c_a != &bl) {
00622 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
00623 }
00624 }
00625
00626
00627 for (SharedHandle::Object* s = c->pc.c.shared; s != NULL; s = s->next)
00628 s->fwd = NULL;
00629
00630
00631 for (ActorLink* l = c->pc.c.local; l != NULL; l = l->next())
00632 l->prev(NULL);
00633
00634
00635 c->pc.p.active = &c->pc.p.queue[0]-1;
00636 for (int i=0; i<=PropCost::AC_MAX; i++)
00637 c->pc.p.queue[i].init();
00638
00639 c->pc.p.n_sub = pc.p.n_sub;
00640 c->pc.p.branch_id = pc.p.branch_id;
00641 return c;
00642 }
00643
00644 void
00645 Space::constrain(const Space&) {
00646 }
00647
00648 bool
00649 Space::master(const CRI& cri) {
00650 if (cri.last() != NULL)
00651 constrain(*cri.last());
00652 cri.nogoods().post(*this);
00653
00654 return true;
00655 }
00656
00657 bool
00658 Space::slave(const CRI&) {
00659 return true;
00660 }
00661
00662 void
00663 LocalObject::fwdcopy(Space& home, bool share) {
00664 ActorLink::cast(this)->prev(copy(home,share));
00665 next(home.pc.c.local);
00666 home.pc.c.local = this;
00667 }
00668
00669 void
00670 Choice::archive(Archive& e) const {
00671 e << id();
00672 }
00673
00674 void
00675 Space::afc_decay(double d) {
00676 afc_enable();
00677
00678 if (gafc.decay() != 1.0)
00679 for (Propagators p(*this); p(); ++p)
00680 (void) gafc.afc(p.propagator().gafc);
00681 gafc.decay(d);
00682 }
00683
00684 void
00685 Space::afc_set(double a) {
00686 afc_enable();
00687 for (Propagators p(*this); p(); ++p)
00688 gafc.set(p.propagator().gafc,a);
00689 }
00690
00691
00692 bool
00693 NGL::notice(void) const {
00694 return false;
00695 }
00696
00697 }
00698
00699