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 Actor::~Actor(void) {}
00060
00061
00062
00063
00064
00065
00066 ExecStatus
00067 Propagator::advise(Space&, Advisor&, const Delta&) {
00068 GECODE_NEVER;
00069 return ES_FAILED;
00070 }
00071 void
00072 Propagator::advise(Space&, Advisor&) {
00073 GECODE_NEVER;
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
00107 StatusStatistics Space::unused_status;
00108 CloneStatistics Space::unused_clone;
00109 CommitStatistics Space::unused_commit;
00110
00111 #ifdef GECODE_HAS_VAR_DISPOSE
00112 VarImpDisposerBase* Space::vd[AllVarConf::idx_d];
00113 #endif
00114
00115 Space::Space(void) : mm(ssd.data().sm) {
00116 #ifdef GECODE_HAS_CBS
00117 var_id_counter = 0;
00118 #endif
00119 #ifdef GECODE_HAS_VAR_DISPOSE
00120 for (int i=0; i<AllVarConf::idx_d; i++)
00121 _vars_d[i] = NULL;
00122 #endif
00123
00124 pl.init();
00125 bl.init();
00126 b_status = b_commit = Brancher::cast(&bl);
00127
00128 d_fst = d_cur = d_lst = NULL;
00129
00130 pc.p.active = &pc.p.queue[0]-1;
00131
00132 for (int i=0; i<=PropCost::AC_MAX; i++)
00133 pc.p.queue[i].init();
00134 pc.p.bid_sc = (reserved_bid+1) << sc_bits;
00135 pc.p.n_sub = 0;
00136 }
00137
00138 void
00139 Space::ap_notice_dispose(Actor* a, bool duplicate) {
00140
00141 if (duplicate && (d_fst != NULL)) {
00142 for (Actor** f = d_fst; f < d_cur; f++)
00143 if (a == *f)
00144 return;
00145 }
00146 if (d_cur == d_lst) {
00147
00148 if (d_fst == NULL) {
00149
00150 d_fst = alloc<Actor*>(4);
00151 d_cur = d_fst;
00152 d_lst = d_fst+4;
00153 } else {
00154
00155 unsigned int n = static_cast<unsigned int>(d_lst - d_fst);
00156 assert(n != 0);
00157 d_fst = realloc<Actor*>(d_fst,n,2*n);
00158 d_cur = d_fst+n;
00159 d_lst = d_fst+2*n;
00160 }
00161 }
00162 *(d_cur++) = a;
00163 }
00164
00165 void
00166 Space::ap_ignore_dispose(Actor* a, bool duplicate) {
00167
00168 assert(d_fst != NULL);
00169 Actor** f = d_fst;
00170 if (duplicate) {
00171 while (f < d_cur)
00172 if (a == *f)
00173 break;
00174 else
00175 f++;
00176 if (f == d_cur)
00177 return;
00178 } else {
00179 while (a != *f)
00180 f++;
00181 }
00182 *f = *(--d_cur);
00183 }
00184
00185 Space::~Space(void) {
00186
00187 fail();
00188
00189 {
00190 Actor** a = d_fst;
00191 Actor** e = d_cur;
00192
00193 d_fst = NULL;
00194 while (a < e) {
00195
00196 if (!Support::marked(*a))
00197 (void) (*a)->dispose(*this);
00198 a++;
00199 }
00200 }
00201 #ifdef GECODE_HAS_VAR_DISPOSE
00202
00203 for (int i=AllVarConf::idx_d; i--;)
00204 if (_vars_d[i] != NULL)
00205 vd[i]->dispose(*this, _vars_d[i]);
00206 #endif
00207
00208 mm.release(ssd.data().sm);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218 TraceRecorder*
00219 Space::findtracerecorder(void) {
00220 for (Actor** a=d_fst; a<d_cur; a++) {
00221 Propagator* p = Propagator::cast(*a);
00222 if (!p->disabled())
00223 if (TraceRecorder* tr = dynamic_cast<TraceRecorder*>(p)) {
00224 std::swap(*d_fst,*a);
00225 return tr;
00226 }
00227 }
00228 return nullptr;
00229 }
00230
00231 SpaceStatus
00232 Space::status(StatusStatistics& stat) {
00233
00234 if (failed())
00235 return SS_FAILED;
00236 assert(pc.p.active <= &pc.p.queue[PropCost::AC_MAX+1]);
00237 Propagator* p;
00238
00239 if (pc.p.active >= &pc.p.queue[0]) {
00240 ModEventDelta med_o;
00241 if ((pc.p.bid_sc & ((1 << sc_bits) - 1)) == 0) {
00242
00243
00244 goto f_unstable;
00245 f_execute:
00246 stat.propagate++;
00247
00248 med_o = p->u.med;
00249
00250 p->u.med = 0;
00251 switch (p->propagate(*this,med_o)) {
00252 case ES_FAILED:
00253 goto failed;
00254 case ES_NOFIX:
00255
00256 if (p->u.med != 0) {
00257 f_unstable:
00258
00259 do {
00260 assert(pc.p.active >= &pc.p.queue[0]);
00261
00262 ActorLink* fst = pc.p.active->next();
00263 if (pc.p.active != fst) {
00264 p = Propagator::cast(fst);
00265 goto f_execute;
00266 }
00267 pc.p.active--;
00268 } while (true);
00269 GECODE_NEVER;
00270 }
00271
00272 case ES_FIX:
00273
00274 p->u.med = 0;
00275
00276 p->unlink(); pl.head(p);
00277 f_stable_or_unstable:
00278
00279 do {
00280 assert(pc.p.active >= &pc.p.queue[0]);
00281
00282 ActorLink* fst = pc.p.active->next();
00283 if (pc.p.active != fst) {
00284 p = Propagator::cast(fst);
00285 goto f_execute;
00286 }
00287 } while (--pc.p.active >= &pc.p.queue[0]);
00288 assert(pc.p.active < &pc.p.queue[0]);
00289 goto f_stable;
00290 case __ES_SUBSUMED:
00291 p->unlink(); rfree(p,p->u.size);
00292 goto f_stable_or_unstable;
00293 case __ES_PARTIAL:
00294
00295 assert(p->u.med != 0);
00296 enqueue(p);
00297 goto f_unstable;
00298 default:
00299 GECODE_NEVER;
00300 }
00301 f_stable: ;
00302 } else if ((pc.p.bid_sc & ((1 << sc_bits) - 1)) == sc_disabled) {
00303
00304 goto d_unstable;
00305 d_execute:
00306 stat.propagate++;
00307 if (p->disabled())
00308 goto d_put_into_idle;
00309
00310 med_o = p->u.med;
00311
00312 p->u.med = 0;
00313 switch (p->propagate(*this,med_o)) {
00314 case ES_FAILED:
00315 goto failed;
00316 case ES_NOFIX:
00317
00318 if (p->u.med != 0) {
00319 d_unstable:
00320
00321 do {
00322 assert(pc.p.active >= &pc.p.queue[0]);
00323
00324 ActorLink* fst = pc.p.active->next();
00325 if (pc.p.active != fst) {
00326 p = Propagator::cast(fst);
00327 goto d_execute;
00328 }
00329 pc.p.active--;
00330 } while (true);
00331 GECODE_NEVER;
00332 }
00333
00334 case ES_FIX:
00335 d_put_into_idle:
00336
00337 p->u.med = 0;
00338
00339 p->unlink(); pl.head(p);
00340 d_stable_or_unstable:
00341
00342 do {
00343 assert(pc.p.active >= &pc.p.queue[0]);
00344
00345 ActorLink* fst = pc.p.active->next();
00346 if (pc.p.active != fst) {
00347 p = Propagator::cast(fst);
00348 goto d_execute;
00349 }
00350 } while (--pc.p.active >= &pc.p.queue[0]);
00351 assert(pc.p.active < &pc.p.queue[0]);
00352 goto d_stable;
00353 case __ES_SUBSUMED:
00354 p->unlink(); rfree(p,p->u.size);
00355 goto d_stable_or_unstable;
00356 case __ES_PARTIAL:
00357
00358 assert(p->u.med != 0);
00359 enqueue(p);
00360 goto d_unstable;
00361 default:
00362 GECODE_NEVER;
00363 }
00364 d_stable: ;
00365 } else {
00366
00367
00368 TraceRecorder* tr = findtracerecorder();
00369
00370 #define GECODE_STATUS_TRACE(q,s) \
00371 if ((tr != NULL) && (tr->events() & TE_PROPAGATE) && \
00372 (tr->filter()(p->group()))) { \
00373 PropagateTraceInfo pti(p->id(),p->group(),q, \
00374 PropagateTraceInfo::s); \
00375 tr->tracer()._propagate(*this,pti); \
00376 }
00377
00378 goto t_unstable;
00379 t_execute:
00380 stat.propagate++;
00381 if (p->disabled())
00382 goto t_put_into_idle;
00383 pc.p.vti.propagator(*p);
00384
00385 med_o = p->u.med;
00386
00387 p->u.med = 0;
00388 switch (p->propagate(*this,med_o)) {
00389 case ES_FAILED:
00390 GECODE_STATUS_TRACE(p,FAILED);
00391 goto failed;
00392 case ES_NOFIX:
00393
00394 if (p->u.med != 0) {
00395 GECODE_STATUS_TRACE(p,NOFIX);
00396 t_unstable:
00397
00398 do {
00399 assert(pc.p.active >= &pc.p.queue[0]);
00400
00401 ActorLink* fst = pc.p.active->next();
00402 if (pc.p.active != fst) {
00403 p = Propagator::cast(fst);
00404 goto t_execute;
00405 }
00406 pc.p.active--;
00407 } while (true);
00408 GECODE_NEVER;
00409 }
00410
00411 case ES_FIX:
00412 GECODE_STATUS_TRACE(p,FIX);
00413 t_put_into_idle:
00414
00415 p->u.med = 0;
00416
00417 p->unlink(); pl.head(p);
00418 t_stable_or_unstable:
00419
00420 do {
00421 assert(pc.p.active >= &pc.p.queue[0]);
00422
00423 ActorLink* fst = pc.p.active->next();
00424 if (pc.p.active != fst) {
00425 p = Propagator::cast(fst);
00426 goto t_execute;
00427 }
00428 } while (--pc.p.active >= &pc.p.queue[0]);
00429 assert(pc.p.active < &pc.p.queue[0]);
00430 goto t_stable;
00431 case __ES_SUBSUMED:
00432 GECODE_STATUS_TRACE(NULL,SUBSUMED);
00433 p->unlink(); rfree(p,p->u.size);
00434 goto t_stable_or_unstable;
00435 case __ES_PARTIAL:
00436 GECODE_STATUS_TRACE(p,NOFIX);
00437
00438 assert(p->u.med != 0);
00439 enqueue(p);
00440 goto t_unstable;
00441 default:
00442 GECODE_NEVER;
00443 }
00444 t_stable:
00445 pc.p.vti.other();
00446 #undef GECODE_STATUS_TRACE
00447 }
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 while (b_status != Brancher::cast(&bl))
00474 if (b_status->status(*this)) {
00475
00476 return SS_BRANCH;
00477 } else {
00478
00479 b_status = Brancher::cast(b_status->next());
00480 }
00481
00482 return SS_SOLVED;
00483
00484
00485 failed:
00486
00487 ssd.data().gpi.fail(p->gpi());
00488
00489 fail();
00490
00491 ActorLink* e = &pc.p.queue[PropCost::AC_RECORD];
00492 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00493 Propagator* top = Propagator::cast(a);
00494
00495 ModEventDelta top_med_o = top->u.med;
00496
00497 top->u.med = 0;
00498 switch (top->propagate(*this,top_med_o)) {
00499 case ES_FIX:
00500 case __ES_SUBSUMED:
00501 break;
00502 default:
00503 GECODE_NEVER;
00504 }
00505 }
00506 return SS_FAILED;
00507 }
00508
00509
00510 const Choice*
00511 Space::choice(void) {
00512 if (!stable())
00513 throw SpaceNotStable("Space::choice");
00514 if (failed() || (b_status == Brancher::cast(&bl))) {
00515
00516
00517 Brancher* b = Brancher::cast(bl.next());
00518 while (b != Brancher::cast(&bl)) {
00519 Brancher* d = b;
00520 b = Brancher::cast(b->next());
00521 rfree(d,d->dispose(*this));
00522 }
00523 bl.init();
00524 b_status = b_commit = Brancher::cast(&bl);
00525 return NULL;
00526 }
00527
00528
00529
00530
00531 Brancher* b = Brancher::cast(bl.next());
00532 while (b != b_status) {
00533 Brancher* d = b;
00534 b = Brancher::cast(b->next());
00535 d->unlink();
00536 rfree(d,d->dispose(*this));
00537 }
00538
00539 b_commit = b_status;
00540 return b_status->choice(*this);
00541 }
00542
00543 const Choice*
00544 Space::choice(Archive& e) const {
00545 unsigned int id; e >> id;
00546 Brancher* b_cur = Brancher::cast(bl.next());
00547 while (b_cur != Brancher::cast(&bl)) {
00548 if (id == b_cur->id())
00549 return b_cur->choice(*this,e);
00550 b_cur = Brancher::cast(b_cur->next());
00551 }
00552 throw SpaceNoBrancher("Space::choice");
00553 }
00554
00555 void
00556 Space::_commit(const Choice& c, unsigned int a) {
00557 if (a >= c.alternatives())
00558 throw SpaceIllegalAlternative("Space::commit");
00559 if (failed())
00560 return;
00561 if (Brancher* b = brancher(c.bid)) {
00562
00563 if (pc.p.bid_sc & sc_trace) {
00564 TraceRecorder* tr = findtracerecorder();
00565 if ((tr != NULL) && (tr->events() & TE_COMMIT) &&
00566 tr->filter()(b->group())) {
00567 CommitTraceInfo cti(*b,c,a);
00568 tr->tracer()._commit(*this,cti);
00569 }
00570 pc.p.vti.brancher(*b);
00571 ExecStatus es = b->commit(*this,c,a);
00572 pc.p.vti.other();
00573 if (es == ES_FAILED)
00574 fail();
00575 } else {
00576 if (b->commit(*this,c,a) == ES_FAILED)
00577 fail();
00578 }
00579 } else {
00580
00581 throw SpaceNoBrancher("Space::commit");
00582 }
00583 }
00584
00585 void
00586 Space::_trycommit(const Choice& c, unsigned int a) {
00587 if (a >= c.alternatives())
00588 throw SpaceIllegalAlternative("Space::commit");
00589 if (failed())
00590 return;
00591 if (Brancher* b = brancher(c.bid)) {
00592
00593 if (pc.p.bid_sc & sc_trace) {
00594 TraceRecorder* tr = findtracerecorder();
00595 if ((tr != NULL) && (tr->events() & TE_COMMIT) &&
00596 tr->filter()(b->group())) {
00597 CommitTraceInfo cti(*b,c,a);
00598 tr->tracer()._commit(*this,cti);
00599 }
00600 pc.p.vti.brancher(*b);
00601 ExecStatus es = b->commit(*this,c,a);
00602 pc.p.vti.other();
00603 if (es == ES_FAILED)
00604 fail();
00605 } else {
00606 if (b->commit(*this,c,a) == ES_FAILED)
00607 fail();
00608 }
00609 }
00610 }
00611
00612 NGL*
00613 Space::ngl(const Choice& c, unsigned int a) {
00614 if (a >= c.alternatives())
00615 throw SpaceIllegalAlternative("Space::ngl");
00616 if (failed())
00617 return NULL;
00618 if (Brancher* b = brancher(c.bid)) {
00619
00620 return b->ngl(*this,c,a);
00621 } else {
00622 return NULL;
00623 }
00624 }
00625
00626 void
00627 Space::print(const Choice& c, unsigned int a, std::ostream& o) const {
00628 if (a >= c.alternatives())
00629 throw SpaceIllegalAlternative("Space::print");
00630 if (failed())
00631 return;
00632 if (Brancher* b = const_cast<Space&>(*this).brancher(c.bid)) {
00633
00634 b->print(*this,c,a,o);
00635 } else {
00636
00637 throw SpaceNoBrancher("Space::print");
00638 }
00639 }
00640
00641 void
00642 Space::kill_brancher(unsigned int id) {
00643 if (failed())
00644 return;
00645 for (Brancher* b = Brancher::cast(bl.next());
00646 b != Brancher::cast(&bl); b = Brancher::cast(b->next()))
00647 if (b->id() == id) {
00648 kill(*b);
00649 return;
00650 }
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 Space::Space(Space& s)
00666 : ssd(s.ssd),
00667 mm(ssd.data().sm,s.mm,s.pc.p.n_sub*sizeof(Propagator**)),
00668 #ifdef GECODE_HAS_CBS
00669 var_id_counter(s.var_id_counter),
00670 #endif
00671 d_fst(&Actor::sentinel) {
00672 #ifdef GECODE_HAS_VAR_DISPOSE
00673 for (int i=0; i<AllVarConf::idx_d; i++)
00674 _vars_d[i] = NULL;
00675 #endif
00676 for (int i=0; i<AllVarConf::idx_c; i++)
00677 pc.c.vars_u[i] = NULL;
00678 pc.c.vars_noidx = NULL;
00679 pc.c.local = NULL;
00680
00681 {
00682 ActorLink* p = &pl;
00683 ActorLink* e = &s.pl;
00684 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00685 Actor* c = Actor::cast(a)->copy(*this);
00686
00687 p->next(ActorLink::cast(c)); ActorLink::cast(c)->prev(p);
00688
00689 p = c;
00690 }
00691
00692 p->next(&pl); pl.prev(p);
00693 }
00694
00695 {
00696 ActorLink* p = &bl;
00697 ActorLink* e = &s.bl;
00698 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00699 Actor* c = Actor::cast(a)->copy(*this);
00700
00701 p->next(ActorLink::cast(c)); ActorLink::cast(c)->prev(p);
00702
00703 p = c;
00704 }
00705
00706 p->next(&bl); bl.prev(p);
00707 }
00708
00709 if (s.b_status == &s.bl) {
00710 b_status = Brancher::cast(&bl);
00711 } else {
00712 b_status = Brancher::cast(s.b_status->prev());
00713 }
00714 if (s.b_commit == &s.bl) {
00715 b_commit = Brancher::cast(&bl);
00716 } else {
00717 b_commit = Brancher::cast(s.b_commit->prev());
00718 }
00719 }
00720
00721 Space*
00722 Space::_clone(void) {
00723 if (failed())
00724 throw SpaceFailed("Space::clone");
00725 if (!stable())
00726 throw SpaceNotStable("Space::clone");
00727
00728
00729 Space* c = copy();
00730
00731 if (c->d_fst != &Actor::sentinel)
00732 throw SpaceNotCloned("Space::clone");
00733
00734
00735 {
00736 unsigned int n = static_cast<unsigned int>(d_cur - d_fst);
00737 if (n == 0) {
00738
00739 c->d_fst = c->d_cur = c->d_lst = NULL;
00740 } else {
00741
00742 c->d_fst = c->alloc<Actor*>(n+1);
00743 c->d_cur = c->d_fst;
00744 c->d_lst = c->d_fst+n+1;
00745 for (Actor** d_fst_iter = d_fst; d_fst_iter != d_cur; d_fst_iter++) {
00746 ptrdiff_t m;
00747 Actor* a = static_cast<Actor*>(Support::ptrsplit(*d_fst_iter,m));
00748 if (a->prev())
00749 *(c->d_cur++) = Actor::cast(static_cast<ActorLink*>
00750 (Support::ptrjoin(a->prev(),m)));
00751 }
00752 }
00753 }
00754
00755
00756 VarImp<NoIdxVarImpConf>* x =
00757 static_cast<VarImp<NoIdxVarImpConf>*>(c->pc.c.vars_noidx);
00758 while (x != NULL) {
00759 VarImp<NoIdxVarImpConf>* n = x->next();
00760 x->b.base = NULL; x->u.idx[0] = 0;
00761 if (sizeof(ActorLink**) > sizeof(unsigned int))
00762 *(1+&x->u.idx[0]) = 0;
00763 x = n;
00764 }
00765
00766 c->update(static_cast<ActorLink**>(c->mm.subscriptions()));
00767
00768
00769 {
00770 ActorLink* p_a = &pl;
00771 ActorLink* c_a = p_a->next();
00772
00773 while (c_a != &pl) {
00774 Propagator* p = Propagator::cast(c_a);
00775 if (p->u.advisors != NULL) {
00776 ActorLink* a = p->u.advisors;
00777 p->u.advisors = NULL;
00778 do {
00779 a->prev(p); a = a->next();
00780 } while (a != NULL);
00781 }
00782 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
00783 }
00784 }
00785 {
00786 ActorLink* p_a = &bl;
00787 ActorLink* c_a = p_a->next();
00788
00789 while (c_a != &bl) {
00790 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
00791 }
00792 }
00793
00794
00795 for (ActorLink* l = c->pc.c.local; l != NULL; l = l->next())
00796 l->prev(NULL);
00797
00798
00799 c->pc.p.active = &c->pc.p.queue[0]-1;
00800 for (int i=0; i<=PropCost::AC_MAX; i++)
00801 c->pc.p.queue[i].init();
00802
00803 c->pc.p.n_sub = pc.p.n_sub;
00804 c->pc.p.bid_sc = pc.p.bid_sc;
00805
00806
00807 c->pc.p.vti.other(); pc.p.vti.other();
00808
00809 return c;
00810 }
00811
00812 void
00813 Space::constrain(const Space&) {
00814 }
00815
00816 bool
00817 Space::master(const MetaInfo& mi) {
00818 switch (mi.type()) {
00819 case MetaInfo::RESTART:
00820 if (mi.last() != NULL)
00821 constrain(*mi.last());
00822 mi.nogoods().post(*this);
00823
00824 return true;
00825 case MetaInfo::PORTFOLIO:
00826
00827 BrancherGroup::all.kill(*this);
00828 return true;
00829 default: GECODE_NEVER;
00830 return true;
00831 }
00832 }
00833
00834 bool
00835 Space::slave(const MetaInfo&) {
00836 return true;
00837 }
00838
00839
00840 void
00841 Space::afc_unshare(void) {
00842 if (ssd.data().gpi.unshare()) {
00843 for (Propagators ps(*this); ps(); ++ps) {
00844 Propagator& p = ps.propagator();
00845 Kernel::GPI::Info* gpi
00846 = ssd.data().gpi.allocate(p.gpi().pid,p.gpi().gid);
00847 if (p.disabled())
00848 p.gpi_disabled = Support::mark(gpi);
00849 else
00850 p.gpi_disabled = gpi;
00851 }
00852 }
00853 }
00854
00855 void
00856 LocalObject::fwdcopy(Space& home) {
00857 ActorLink::cast(this)->prev(copy(home));
00858 next(home.pc.c.local);
00859 home.pc.c.local = this;
00860 }
00861
00862 void
00863 Choice::archive(Archive& e) const {
00864 e << id();
00865 }
00866
00867 bool
00868 NGL::notice(void) const {
00869 return false;
00870 }
00871
00872 NGL::~NGL(void) {
00873 }
00874
00875
00876
00877
00878
00879
00880 Group Group::all(GROUPID_ALL);
00881 Group Group::def(GROUPID_DEF);
00882
00883 PropagatorGroup PropagatorGroup::all(GROUPID_ALL);
00884 PropagatorGroup PropagatorGroup::def(GROUPID_DEF);
00885
00886 BrancherGroup BrancherGroup::all(GROUPID_ALL);
00887 BrancherGroup BrancherGroup::def(GROUPID_DEF);
00888
00889 unsigned int Group::next = GROUPID_DEF+1;
00890 Support::Mutex Group::m;
00891
00892
00893 Group::Group(void) {
00894 m.acquire();
00895 gid = next++;
00896 m.release();
00897 if (gid == GROUPID_MAX)
00898 throw TooManyGroups("Group::Group");
00899 }
00900
00901
00902 PropagatorGroup&
00903 PropagatorGroup::move(Space& home, PropagatorGroup g) {
00904 if ((id() != GROUPID_ALL) && (id() != g.id()))
00905 for (Space::Propagators ps(home); ps(); ++ps)
00906 if (g.in(ps.propagator().group()))
00907 ps.propagator().group(*this);
00908 return *this;
00909 }
00910
00911 PropagatorGroup&
00912 PropagatorGroup::move(Space& home, unsigned int pid) {
00913 if (id() == GROUPID_ALL)
00914 return *this;
00915 for (Space::Propagators ps(home); ps(); ++ps)
00916 if (ps.propagator().id() == pid) {
00917 ps.propagator().group(*this);
00918 return *this;
00919 }
00920 throw UnknownPropagator("PropagatorGroup::move");
00921 GECODE_NEVER;
00922 return *this;
00923 }
00924
00925 unsigned int
00926 PropagatorGroup::size(Space& home) const {
00927 if (home.failed())
00928 return 0;
00929 unsigned int n=0;
00930 for (Space::Propagators ps(home); ps(); ++ps)
00931 if (in(ps.propagator().group()))
00932 n++;
00933 return n;
00934 }
00935
00936 void
00937 PropagatorGroup::kill(Space& home) {
00938 if (home.failed())
00939 return;
00940 Space::Propagators ps(home);
00941 while (ps()) {
00942 Propagator& p = ps.propagator();
00943 ++ps;
00944 if (in(p.group()))
00945 home.kill(p);
00946 }
00947 }
00948
00949 void
00950 PropagatorGroup::disable(Space& home) {
00951 if (home.failed())
00952 return;
00953 for (Space::Propagators ps(home); ps(); ++ps)
00954 if (in(ps.propagator().group()))
00955 ps.propagator().disable(home);
00956 }
00957
00958 void
00959 PropagatorGroup::enable(Space& home, bool s) {
00960 if (home.failed())
00961 return;
00962 if (s) {
00963 Space::Propagators ps(home);
00964 while (ps()) {
00965 Propagator& p = ps.propagator();
00966 ++ps;
00967 if (in(p.group())) {
00968 p.enable(home);
00969 p.reschedule(home);
00970 }
00971 }
00972 } else {
00973 for (Space::Propagators ps(home); ps(); ++ps)
00974 if (in(ps.propagator().group()))
00975 ps.propagator().enable(home);
00976 }
00977 }
00978
00979
00980 BrancherGroup&
00981 BrancherGroup::move(Space& home, BrancherGroup g) {
00982 if ((id() != GROUPID_ALL) && (id() != g.id()))
00983 for (Space::Branchers bs(home); bs(); ++bs)
00984 if (g.in(bs.brancher().group()))
00985 bs.brancher().group(*this);
00986 return *this;
00987 }
00988
00989 BrancherGroup&
00990 BrancherGroup::move(Space& home, unsigned int bid) {
00991 if (id() == GROUPID_ALL)
00992 return *this;
00993 for (Space::Branchers bs(home); bs(); ++bs)
00994 if (bs.brancher().id() == bid) {
00995 bs.brancher().group(*this);
00996 return *this;
00997 }
00998 throw UnknownBrancher("BrancherGroup::move");
00999 GECODE_NEVER;
01000 return *this;
01001 }
01002
01003 unsigned int
01004 BrancherGroup::size(Space& home) const {
01005 if (home.failed())
01006 return 0;
01007 unsigned int n=0;
01008 for (Space::Branchers bs(home); bs(); ++bs)
01009 if (in(bs.brancher().group()))
01010 n++;
01011 return n;
01012 }
01013
01014 void
01015 BrancherGroup::kill(Space& home) {
01016 if (home.failed())
01017 return;
01018 Space::Branchers bs(home);
01019 while (bs()) {
01020 Brancher& b = bs.brancher();
01021 ++bs;
01022 if (in(b.group()))
01023 home.kill(b);
01024 }
01025 }
01026
01027
01028 }
01029
01030