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