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