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