core.cpp
Go to the documentation of this file.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 size_t
00058 Actor::allocated(void) const {
00059 return 0;
00060 }
00061
00062 Actor* Actor::sentinel;
00063
00064 #ifdef __GNUC__
00065
00066 Actor::~Actor(void) {}
00067 #endif
00068
00069
00070
00071
00072
00073
00074
00075 ExecStatus
00076 Propagator::advise(Space&, Advisor&, const Delta&) {
00077 assert(false);
00078 return ES_FAILED;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 StatusStatistics Space::unused_status;
00088 CloneStatistics Space::unused_clone;
00089 CommitStatistics Space::unused_commit;
00090
00091 #ifdef GECODE_HAS_VAR_DISPOSE
00092 VarImpDisposerBase* Space::vd[AllVarConf::idx_d];
00093 #endif
00094
00095 Space::Space(void)
00096 : sm(new SharedMemory), mm(sm), _wmp_afc(0U) {
00097 #ifdef GECODE_HAS_VAR_DISPOSE
00098 for (int i=0; i<AllVarConf::idx_d; i++)
00099 _vars_d[i] = NULL;
00100 #endif
00101
00102 pl.init();
00103 bl.init();
00104 b_status = b_commit = Brancher::cast(&bl);
00105
00106 d_fst = d_cur = d_lst = NULL;
00107
00108 pc.p.active = &pc.p.queue[0]-1;
00109
00110 for (int i=0; i<=PropCost::AC_MAX; i++)
00111 pc.p.queue[i].init();
00112 pc.p.branch_id = reserved_branch_id+1;
00113 pc.p.n_sub = 0;
00114 }
00115
00116 void
00117 Space::d_resize(void) {
00118 if (d_fst == NULL) {
00119
00120 d_fst = alloc<Actor*>(4);
00121 d_cur = d_fst;
00122 d_lst = d_fst+4;
00123 } else {
00124
00125 unsigned int n = static_cast<unsigned int>(d_lst - d_fst);
00126 assert(n != 0);
00127 d_fst = realloc<Actor*>(d_fst,n,2*n);
00128 d_cur = d_fst+n;
00129 d_lst = d_fst+2*n;
00130 }
00131 }
00132
00133 unsigned int
00134 Space::propagators(void) const {
00135 unsigned int n = 0;
00136 for (Propagators p(*this); p(); ++p)
00137 n++;
00138 return n;
00139 }
00140
00141 unsigned int
00142 Space::branchers(void) const {
00143 unsigned int n = 0;
00144 for (Branchers b(*this); b(); ++b)
00145 n++;
00146 return n;
00147 }
00148
00149 void
00150 Space::flush(void) {
00151
00152 sm->flush();
00153 }
00154
00155 Space::~Space(void) {
00156
00157 fail();
00158
00159 {
00160 Actor** a = d_fst;
00161 Actor** e = d_cur;
00162
00163 d_fst = NULL;
00164 while (a < e) {
00165 (void) (*a)->dispose(*this);
00166 a++;
00167 }
00168 }
00169 #ifdef GECODE_HAS_VAR_DISPOSE
00170
00171 for (int i=AllVarConf::idx_d; i--;)
00172 if (_vars_d[i] != NULL)
00173 vd[i]->dispose(*this, _vars_d[i]);
00174 #endif
00175
00176 mm.release(sm);
00177
00178 if (sm->release())
00179 delete sm;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189 SpaceStatus
00190 Space::status(StatusStatistics& stat) {
00191 SpaceStatus s = SS_FAILED;
00192
00193 if (failed()) {
00194 s = SS_FAILED; goto exit;
00195 }
00196 assert(pc.p.active <= &pc.p.queue[PropCost::AC_MAX+1]);
00197
00198 if (pc.p.active >= &pc.p.queue[0]) {
00199 Propagator* p;
00200 ModEventDelta med_o;
00201 goto unstable;
00202 execute:
00203 stat.propagate++;
00204
00205 med_o = p->u.med;
00206
00207 p->u.med = 0;
00208 switch (p->propagate(*this,med_o)) {
00209 case ES_FAILED:
00210
00211 if (afc_enabled())
00212 gafc.fail(p->gafc);
00213
00214 fail(); s = SS_FAILED; goto exit;
00215 case ES_NOFIX:
00216
00217 if (p->u.med != 0) {
00218 unstable:
00219
00220 do {
00221 assert(pc.p.active >= &pc.p.queue[0]);
00222
00223 ActorLink* fst = pc.p.active->next();
00224 if (pc.p.active != fst) {
00225 p = Propagator::cast(fst);
00226 goto execute;
00227 }
00228 pc.p.active--;
00229 } while (true);
00230 GECODE_NEVER;
00231 }
00232
00233 case ES_FIX:
00234
00235 p->u.med = 0; p->unlink(); pl.head(p);
00236 stable_or_unstable:
00237
00238 do {
00239 assert(pc.p.active >= &pc.p.queue[0]);
00240
00241 ActorLink* fst = pc.p.active->next();
00242 if (pc.p.active != fst) {
00243 p = Propagator::cast(fst);
00244 goto execute;
00245 }
00246 } while (--pc.p.active >= &pc.p.queue[0]);
00247 assert(pc.p.active < &pc.p.queue[0]);
00248 goto stable;
00249 case __ES_SUBSUMED:
00250 p->unlink(); rfree(p,p->u.size);
00251 goto stable_or_unstable;
00252 case __ES_PARTIAL:
00253
00254 assert(p->u.med != 0);
00255 enqueue(p);
00256 goto unstable;
00257 default:
00258 GECODE_NEVER;
00259 }
00260 }
00261 stable:
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 while (b_status != Brancher::cast(&bl))
00286 if (b_status->status(*this)) {
00287
00288 s = SS_BRANCH; goto exit;
00289 } else {
00290
00291 b_status = Brancher::cast(b_status->next());
00292 }
00293
00294 s = SS_SOLVED;
00295 exit:
00296 stat.wmp = (wmp() > 0U);
00297 if (wmp() == 1U)
00298 wmp(0U);
00299 return s;
00300 }
00301
00302
00303 const Choice*
00304 Space::choice(void) {
00305 if (!stable())
00306 throw SpaceNotStable("Space::choice");
00307 if (failed() || (b_status == Brancher::cast(&bl))) {
00308
00309
00310 Brancher* b = Brancher::cast(bl.next());
00311 while (b != Brancher::cast(&bl)) {
00312 Brancher* d = b;
00313 b = Brancher::cast(b->next());
00314 rfree(d,d->dispose(*this));
00315 }
00316 bl.init();
00317 b_status = b_commit = Brancher::cast(&bl);
00318 return NULL;
00319 }
00320
00321
00322
00323
00324 Brancher* b = Brancher::cast(bl.next());
00325 while (b != b_status) {
00326 Brancher* d = b;
00327 b = Brancher::cast(b->next());
00328 d->unlink();
00329 rfree(d,d->dispose(*this));
00330 }
00331
00332 b_commit = b_status;
00333 return b_status->choice(*this);
00334 }
00335
00336 const Choice*
00337 Space::choice(Archive& e) const {
00338 unsigned int id; e >> id;
00339 Brancher* b_cur = Brancher::cast(bl.next());
00340 while (b_cur != Brancher::cast(&bl)) {
00341 if (id == b_cur->id())
00342 return b_cur->choice(*this,e);
00343 b_cur = Brancher::cast(b_cur->next());
00344 }
00345 throw SpaceNoBrancher("Space::choice");
00346 }
00347
00348 void
00349 Space::_commit(const Choice& c, unsigned int a) {
00350 if (a >= c.alternatives())
00351 throw SpaceIllegalAlternative();
00352 if (failed())
00353 return;
00354 if (Brancher* b = brancher(c._id)) {
00355
00356 if (b->commit(*this,c,a) == ES_FAILED)
00357 fail();
00358 } else {
00359
00360 throw SpaceNoBrancher("Space::commit");
00361 }
00362 }
00363
00364 void
00365 Space::kill_brancher(unsigned int id) {
00366 if (failed())
00367 return;
00368 for (Brancher* b = Brancher::cast(bl.next());
00369 b != Brancher::cast(&bl); b = Brancher::cast(b->next()))
00370 if (b->id() == id) {
00371
00372 if (b_commit == b)
00373 b_commit = Brancher::cast(b->next());
00374 if (b_status == b)
00375 b_status = Brancher::cast(b->next());
00376 b->unlink();
00377 rfree(b,b->dispose(*this));
00378 return;
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 Space::Space(bool share, Space& s)
00397 : sm(s.sm->copy(share)),
00398 mm(sm,s.mm,s.pc.p.n_sub*sizeof(Propagator**)),
00399 gafc(s.gafc),
00400 d_fst(&Actor::sentinel),
00401 _wmp_afc(s._wmp_afc) {
00402 #ifdef GECODE_HAS_VAR_DISPOSE
00403 for (int i=0; i<AllVarConf::idx_d; i++)
00404 _vars_d[i] = NULL;
00405 #endif
00406 for (int i=0; i<AllVarConf::idx_c; i++)
00407 pc.c.vars_u[i] = NULL;
00408 pc.c.vars_noidx = NULL;
00409 pc.c.shared = NULL;
00410 pc.c.local = NULL;
00411
00412 {
00413 ActorLink* p = &pl;
00414 ActorLink* e = &s.pl;
00415 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00416 Actor* c = Actor::cast(a)->copy(*this,share);
00417
00418 p->next(ActorLink::cast(c)); ActorLink::cast(c)->prev(p);
00419
00420 p = c;
00421 }
00422
00423 p->next(&pl); pl.prev(p);
00424 }
00425
00426 {
00427 ActorLink* p = &bl;
00428 ActorLink* e = &s.bl;
00429 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00430 Actor* c = Actor::cast(a)->copy(*this,share);
00431
00432 p->next(ActorLink::cast(c)); ActorLink::cast(c)->prev(p);
00433
00434 p = c;
00435 }
00436
00437 p->next(&bl); bl.prev(p);
00438 }
00439
00440 if (s.b_status == &s.bl) {
00441 b_status = Brancher::cast(&bl);
00442 } else {
00443 b_status = Brancher::cast(s.b_status->prev());
00444 }
00445 if (s.b_commit == &s.bl) {
00446 b_commit = Brancher::cast(&bl);
00447 } else {
00448 b_commit = Brancher::cast(s.b_commit->prev());
00449 }
00450 }
00451
00452 Space*
00453 Space::_clone(bool share) {
00454 if (failed())
00455 throw SpaceFailed("Space::clone");
00456 if (!stable())
00457 throw SpaceNotStable("Space::clone");
00458
00459
00460 Space* c = copy(share);
00461
00462 if (c->d_fst != &Actor::sentinel)
00463 throw SpaceNotCloned("Space::clone");
00464
00465
00466 {
00467 unsigned int n = static_cast<unsigned int>(d_cur - d_fst);
00468 if (n == 0) {
00469
00470 c->d_fst = c->d_cur = c->d_lst = NULL;
00471 } else {
00472
00473 c->d_fst = c->alloc<Actor*>(n+1);
00474 c->d_cur = c->d_fst;
00475 c->d_lst = c->d_fst+n+1;
00476 for (Actor** d_fst_iter = d_fst; d_fst_iter != d_cur; d_fst_iter++) {
00477 if ((*d_fst_iter)->prev())
00478 *(c->d_cur++) = Actor::cast((*d_fst_iter)->prev());
00479 }
00480 }
00481 }
00482
00483
00484 VarImp<NoIdxVarImpConf>* x =
00485 static_cast<VarImp<NoIdxVarImpConf>*>(c->pc.c.vars_noidx);
00486 while (x != NULL) {
00487 VarImp<NoIdxVarImpConf>* n = x->next();
00488 x->b.base = NULL; x->u.idx[0] = 0;
00489 if (sizeof(ActorLink**) > sizeof(unsigned int))
00490 *(1+&x->u.idx[0]) = 0;
00491 x = n;
00492 }
00493
00494 c->update(static_cast<ActorLink**>(c->mm.subscriptions()));
00495
00496
00497 {
00498 ActorLink* p_a = &pl;
00499 ActorLink* c_a = p_a->next();
00500
00501 while (c_a != &pl) {
00502 Propagator* p = Propagator::cast(c_a);
00503 if (p->u.advisors != NULL) {
00504 ActorLink* a = p->u.advisors;
00505 p->u.advisors = NULL;
00506 do {
00507 a->prev(p); a = a->next();
00508 } while (a != NULL);
00509 }
00510 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
00511 }
00512 }
00513 {
00514 ActorLink* p_a = &bl;
00515 ActorLink* c_a = p_a->next();
00516
00517 while (c_a != &bl) {
00518 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
00519 }
00520 }
00521
00522
00523 for (SharedHandle::Object* s = c->pc.c.shared; s != NULL; s = s->next)
00524 s->fwd = NULL;
00525
00526
00527 for (ActorLink* l = c->pc.c.local; l != NULL; l = l->next())
00528 l->prev(NULL);
00529
00530
00531 c->pc.p.active = &c->pc.p.queue[0]-1;
00532 for (int i=0; i<=PropCost::AC_MAX; i++)
00533 c->pc.p.queue[i].init();
00534
00535 c->pc.p.n_sub = pc.p.n_sub;
00536 c->pc.p.branch_id = pc.p.branch_id;
00537 return c;
00538 }
00539
00540 void
00541 Space::constrain(const Space&) {
00542 }
00543
00544 void
00545 Space::master(unsigned long int, const Space*) {
00546 }
00547
00548 void
00549 Space::slave(unsigned long int, const Space*) {
00550 }
00551
00552 void
00553 LocalObject::fwdcopy(Space& home, bool share) {
00554 ActorLink::cast(this)->prev(copy(home,share));
00555 next(home.pc.c.local);
00556 home.pc.c.local = this;
00557 }
00558
00559 void
00560 Choice::archive(Archive& e) const {
00561 e << id();
00562 }
00563
00564 void
00565 Space::afc_decay(double d) {
00566 afc_enable();
00567
00568 if (gafc.decay() != 1.0)
00569 for (Propagators p(*this); p(); ++p)
00570 (void) gafc.afc(p.propagator().gafc);
00571 gafc.decay(d);
00572 }
00573
00574
00575 }
00576
00577