core.cc
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 #include "gecode/kernel.hh"
00023
00024 namespace Gecode {
00025
00026 unsigned long int Space::unused_uli;
00027
00028
00029
00030
00031
00032
00033 VarTypeProcessorBase* Space::vtp[VTI_LAST];
00034
00035 VarTypeProcessorBase::~VarTypeProcessorBase(void) {}
00036
00037 Space::Space(void) {
00038
00039 for (int i=0; i<VTI_LAST; i++) {
00040 vars[i]=NULL;
00041 vars_dispose[i]=NULL;
00042 }
00043 vars_noidx = NULL;
00044
00045 pool_next = 0;
00046 for (int i=0; i<=PC_MAX; i++)
00047 pool[i].init();
00048
00049 a_actors.init();
00050 a_actors.init_delete();
00051 b_status = static_cast<Branching*>(&a_actors);
00052 b_commit = static_cast<Branching*>(&a_actors);
00053 n_sub = 0;
00054 sub = NULL;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064 void
00065 Actor::flush(void) {}
00066
00067 size_t
00068 Actor::cached(void) const {
00069 return 0;
00070 }
00071
00072 void
00073 Space::flush(void) {
00074
00075 ActorDeleteLink* e = &a_actors;
00076 ActorDeleteLink* a = e->next_delete();
00077 while (a != e) {
00078 static_cast<Actor*>(a)->flush(); a = a->next_delete();
00079 }
00080 }
00081
00082 size_t
00083 Space::cached(void) const {
00084 size_t s = 0;
00085 const ActorDeleteLink* e = &a_actors;
00086 const ActorDeleteLink* a = e->next_delete();
00087 while (a != e) {
00088 s += static_cast<const Actor*>(a)->cached();
00089 a = a->next_delete();
00090 }
00091 return s;
00092 }
00093
00094 Space::~Space(void) {
00095
00096 fail();
00097
00098 ActorDeleteLink* e = &a_actors;
00099 ActorDeleteLink* a = e->next_delete();
00100 while (a != e) {
00101 Actor* d = static_cast<Actor*>(a);
00102 a = a->next_delete();
00103 d->dispose(this);
00104 }
00105
00106 for (int vti=VTI_LAST; vti--;)
00107 if (vars_dispose[vti] != NULL)
00108 vtp[vti]->dispose(this, vars_dispose[vti]);
00109 if (sub != NULL)
00110 Memory::free(sub);
00111 }
00112
00113
00114
00115
00116
00117
00118
00119 forceinline void
00120 Space::process(void) {
00121 for (int vti=VTI_LAST; vti--; ) {
00122 VarBase* vs = vars[vti];
00123 if (vs != NULL) {
00124 vars[vti] = NULL; vtp[vti]->process(this,vs);
00125 }
00126 }
00127 }
00128
00129 forceinline bool
00130 Space::pool_get(Propagator*& p) {
00131 for (int c = pool_next+1; c--; ) {
00132
00133 ActorLink* lnk = &pool[c];
00134
00135 ActorLink* fst = lnk->next();
00136 if (lnk != fst) {
00137 pool_next = c;
00138
00139 ActorLink* snd = fst->next();
00140 lnk->next(snd); snd->prev(lnk);
00141 p = static_cast<Propagator*>(fst);
00142 return true;
00143 }
00144 }
00145 pool_next = 0;
00146 return false;
00147 }
00148
00149 unsigned long int
00150 Space::propagate(void) {
00151 if (failed())
00152 return 0;
00153 const PropModEvent PME_NONE = 0;
00154 const PropModEvent PME_ASSIGNED =
00155 ((ME_GEN_ASSIGNED << 0) | (ME_GEN_ASSIGNED << 4) |
00156 (ME_GEN_ASSIGNED << 8) | (ME_GEN_ASSIGNED << 12) |
00157 (ME_GEN_ASSIGNED << 16) | (ME_GEN_ASSIGNED << 20) |
00158 (ME_GEN_ASSIGNED << 24) | (ME_GEN_ASSIGNED << 28));
00159
00160
00161
00162
00163 unsigned long int pn = 0;
00164
00165
00166
00167
00168
00169 process();
00170 Propagator* p;
00171 while (pool_get(p)) {
00172 pn++;
00173 switch (p->propagate(this)) {
00174 case ES_FAILED:
00175 fail();
00176 return pn;
00177 case ES_FIX:
00178 {
00179
00180 propagator(p);
00181
00182 p->pme = PME_ASSIGNED;
00183 process();
00184 p->pme = PME_NONE;
00185 }
00186 break;
00187 case ES_NOFIX:
00188 {
00189
00190 propagator(p);
00191 p->pme = PME_NONE;
00192 process();
00193 }
00194 break;
00195 case ES_SUBSUMED:
00196 {
00197
00198 p->pme = PME_ASSIGNED;
00199 process();
00200 p->destruct(this);
00201 }
00202 break;
00203 case __ES_FIX_PARTIAL:
00204 {
00205
00206 PropModEvent keep = p->pme;
00207
00208 p->pme = PME_ASSIGNED;
00209 process();
00210 p->pme = keep;
00211 assert(p->pme);
00212 pool_put(p);
00213 }
00214 break;
00215 case __ES_NOFIX_PARTIAL:
00216 {
00217
00218 pool_put(p);
00219 process();
00220 }
00221 break;
00222 default:
00223 GECODE_NEVER;
00224 }
00225 }
00226 return pn;
00227 }
00228
00229 void
00230 Space::commit(const BranchingDesc* d, unsigned int a) {
00231 if (failed())
00232 return;
00233
00234
00235
00236
00237
00238
00239
00240
00241 while ((b_commit != &a_actors) && (d->id != b_commit->id)) {
00242 Branching* b = b_commit;
00243 b_commit = static_cast<Branching*>(b_commit->next());
00244 if (b == b_status)
00245 b_status = b_commit;
00246 b->unlink(); b->destruct(this);
00247 }
00248 if (b_commit == &a_actors)
00249 throw SpaceNoBranching();
00250 if (a >= d->alternatives())
00251 throw SpaceIllegalAlternative();
00252 if (b_commit->commit(this,d,a) == ES_FAILED)
00253 fail();
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 Space::Space(bool share, Space& s) : mm(s.mm) {
00269
00270 for (int i=0; i<VTI_LAST; i++) {
00271 vars[i]=NULL;
00272 vars_dispose[i]=NULL;
00273 }
00274 vars_noidx = NULL;
00275
00276 pool_next = 0;
00277 for (int i=0; i<=PC_MAX; i++)
00278 pool[i].init();
00279
00280 {
00281 ActorLink* p = &a_actors;
00282 ActorLink* e = &s.a_actors;
00283 for (ActorLink* a = e->next(); a != e; a = a->next()) {
00284 ActorLink* c = static_cast<Actor*>(a)->copy(this,share);
00285
00286 p->next(c); c->prev(p);
00287
00288 a->prev(c);
00289
00290 static_cast<ActorDeleteLink*>(c)->init_delete();
00291 p = c;
00292 }
00293
00294 p->next(&a_actors); a_actors.prev(p);
00295 }
00296
00297 {
00298 ActorDeleteLink* p = &a_actors;
00299 ActorDeleteLink* e = &s.a_actors;
00300 for (ActorDeleteLink* a = e->next_delete(); a != e;
00301 a = a->next_delete()) {
00302 ActorDeleteLink* c = static_cast<ActorDeleteLink*>(a->prev());
00303
00304 p->next_delete(c); c->prev_delete(p);
00305
00306 p = c;
00307 }
00308
00309 p->next_delete(&a_actors); a_actors.prev_delete(p);
00310 }
00311
00312 if (s.b_status == &s.a_actors) {
00313 b_status = static_cast<Branching*>(&a_actors);
00314 } else {
00315 b_status = static_cast<Branching*>(s.b_status->prev());
00316 }
00317 if (s.b_commit == &s.a_actors) {
00318 b_commit = static_cast<Branching*>(&a_actors);
00319 } else {
00320 b_commit = static_cast<Branching*>(s.b_commit->prev());
00321 }
00322 }
00323
00324
00325
00326
00327
00328
00329
00331 class __Combine {
00332 public:
00333 ModEvent operator()(ModEvent,ModEvent) {
00334 GECODE_NEVER;
00335 return ME_GEN_ASSIGNED;
00336 }
00337 };
00338
00339 Space*
00340 Space::clone(bool share, unsigned long int& pn) {
00341 pn += propagate();
00342 if (failed())
00343 throw SpaceFailed("Space::clone");
00344
00345
00346
00347
00348
00349
00350
00351 Space* c = copy(share);
00352
00353
00354
00355
00356
00357
00358
00359
00360 for (Variable<VTI_NOIDX,0,__Combine>* x
00361 = static_cast<Variable<VTI_NOIDX,0,__Combine>*>(c->vars_noidx);
00362 x != NULL; x = x->next())
00363 x->u.free_me = 0;
00364 c->vars_noidx = NULL;
00365
00366 Propagator** s;
00367 if (n_sub > 0)
00368 s = reinterpret_cast<Propagator**>
00369 (Memory::malloc(n_sub*sizeof(Propagator*)));
00370 else
00371 s = NULL;
00372 c->sub = s;
00373 for (int vti=VTI_LAST; vti--; ) {
00374 VarBase* vs = c->vars[vti];
00375 if (vs != NULL) {
00376 c->vars[vti] = NULL; vtp[vti]->update(vs,s);
00377 }
00378 }
00379
00380
00381 unsigned int n = s - c->sub;
00382 assert(n <= n_sub);
00383 c->n_sub = n; n_sub = n;
00384
00385 ActorLink* p = &a_actors;
00386 ActorLink* a = p->next();
00387 while (a != &a_actors) {
00388 a->prev(p); p = a; a = a->next();
00389 }
00390 assert(a->prev() == p);
00391 return c;
00392 }
00393
00394 unsigned int
00395 Space::propagators(void) const {
00396 if (failed())
00397 throw SpaceFailed("Space::propagators");
00398 unsigned int n = 0;
00399 for (const ActorLink* a = a_actors.next(); a != b_commit; a = a->next())
00400 n++;
00401 return n;
00402 }
00403
00404 unsigned int
00405 Space::branchings(void) const {
00406 if (failed())
00407 throw SpaceFailed("Space::branchings");
00408 unsigned int n = 0;
00409 for (const ActorLink* a = b_status; a != &a_actors; a = a->next())
00410 n++;
00411 return n;
00412 }
00413
00414 }
00415
00416
00417