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 namespace Gecode {
00028
00037
00038 typedef int ModEvent;
00039
00041 const ModEvent ME_GEN_FAILED = -1;
00043 const ModEvent ME_GEN_NONE = 0;
00045 const ModEvent ME_GEN_ASSIGNED = 1;
00047 const ModEvent ME_GEN_MAX = 15;
00048
00050 typedef int PropCond;
00052 const PropCond PC_GEN_ASSIGNED = 0;
00054 const PropCond PC_GEN_MAX = 15;
00056
00057
00070 enum VarTypeId {
00071 #include "gecode/vti.icc"
00072 VTI_LAST,
00073 VTI_NOIDX = 0
00074 };
00075
00076
00077
00078
00079
00080
00081 class Actor;
00082 class Propagator;
00083 class Space;
00084 template <VarTypeId VTI, PropCond PC, class MED> class Variable;
00085
00086
00087
00088
00089
00090
00091
00099 class VarBase {};
00100
00108 class VarTypeProcessorBase {
00109 public:
00111 virtual void process(Space* home, VarBase* x) = 0;
00118 virtual void update(VarBase* x, Propagator**& sub) = 0;
00125 virtual void dispose(Space* home, VarBase* x) = 0;
00127 GECODE_KERNEL_EXPORT virtual ~VarTypeProcessorBase(void);
00128 };
00129
00137 template <VarTypeId VTI, PropCond PC, class MED>
00138 class VarTypeProcessor : public VarTypeProcessorBase {
00139 public:
00141 VarTypeProcessor(void);
00148 virtual void update(VarBase* x, Propagator**& sub);
00155 virtual void dispose(Space* home, VarBase* x);
00156 };
00157
00168 typedef int PropModEvent;
00169
00170
00178 template <VarTypeId VTI, PropCond PC, class MED>
00179 class Variable : public VarBase {
00180 friend class Space;
00181 friend class Propagator;
00182 friend class VarTypeProcessor<VTI,PC,MED>;
00183 private:
00184 Variable* _next;
00185 union {
00193 unsigned int free_me;
00195 Variable* fwd;
00196 } u;
00197 Propagator** idx[PC+2];
00198
00200 unsigned int free(void) const;
00202 void free(unsigned int n);
00204 void free_inc(void);
00206 void free_dec(void);
00207
00214 void update(Variable* x, Propagator**& sub);
00215
00217 void resize(Space* home);
00218
00219 public:
00221 Variable(Space* home);
00222
00224
00225
00237 void subscribe(Space* home, Propagator* p, PropCond pc,
00238 bool assigned, ModEvent me, bool process);
00240 void cancel(Space* home, Propagator* p, PropCond pc);
00242 unsigned int degree(void) const;
00244 void notify(Space* home, ModEvent me);
00246 void notify(Space* home);
00248
00250
00251
00252 bool modified(void) const;
00254
00256
00257
00258 Variable(Space* home, bool share, Variable& x);
00260 bool copied(void) const;
00262 Variable* forward(void) const;
00264
00266
00267
00268 static ModEvent pme(const Propagator* p);
00270 static PropModEvent pme(ModEvent me);
00272 static ModEvent combine(ModEvent me1, ModEvent me2);
00274
00276
00277
00278 Variable* next(void);
00280 ModEvent modevent(void) const;
00282 void modevent(ModEvent me);
00284 void process(Space* home, PropCond pc1, PropCond pc2, ModEvent me);
00286 void process(Space* home);
00288
00290
00291
00292 static void* operator new(size_t,Space*);
00294 static void operator delete(void*,Space*);
00296 static void operator delete(void*);
00298 };
00299
00300
00301
00302
00307 enum ExecStatus {
00308 ES_FAILED = -1,
00309 ES_NOFIX = 0,
00310 ES_OK = 0,
00311 ES_FIX = 1,
00312 ES_SUBSUMED = 2,
00313 __ES_FIX_PARTIAL = 3,
00314 __ES_NOFIX_PARTIAL = 4
00315 };
00316
00321 enum PropCost {
00322 PC_CRAZY_LO = 0,
00323 PC_CRAZY_HI = 0,
00324 PC_CUBIC_LO = 1,
00325 PC_CUBIC_HI = 1,
00326 PC_QUADRATIC_LO = 2,
00327 PC_QUADRATIC_HI = 2,
00328 PC_LINEAR_HI = 3,
00329 PC_LINEAR_LO = 4,
00330 PC_TERNARY_HI = 5,
00331 PC_BINARY_HI = 6,
00332 PC_TERNARY_LO = 6,
00333 PC_BINARY_LO = 7,
00334 PC_UNARY_LO = 7,
00335 PC_UNARY_HI = 7,
00336 PC_MAX = 7
00337 };
00338
00346 class ActorLink {
00347 friend class Actor;
00348 friend class Space;
00349 template <VarTypeId VTI, PropCond PC, class MED> friend class Variable;
00350 private:
00351 ActorLink* _next; ActorLink* _prev;
00352 public:
00354
00355 ActorLink* prev(void) const; void prev(ActorLink*);
00356 ActorLink* next(void) const; void next(ActorLink*);
00358
00359
00361 void init(void);
00363 void unlink(void);
00365 void head(ActorLink* al);
00367 void tail(ActorLink* al);
00368 };
00369
00370
00381 class ActorDeleteLink : public ActorLink {
00382 friend class Actor;
00383 friend class Space;
00384 template <VarTypeId VTI, PropCond PC, class MED> friend class Variable;
00385 private:
00386 ActorDeleteLink* _next_d; ActorDeleteLink* _prev_d;
00387 public:
00388 ActorDeleteLink* next_delete(void) const;
00389 void next_delete(ActorDeleteLink*);
00390 ActorDeleteLink* prev_delete(void) const;
00391 void prev_delete(ActorDeleteLink*);
00392
00394 void init_delete(void);
00395 void unlink_delete(void);
00396 void insert_delete(ActorDeleteLink*,bool);
00397 };
00398
00399
00400
00405 class Actor : private ActorDeleteLink {
00406 friend class Space;
00407 template <VarTypeId VTI, PropCond PC, class MED> friend class Variable;
00408 public:
00410 virtual Actor* copy(Space*,bool) = 0;
00412 GECODE_KERNEL_EXPORT
00413 virtual size_t dispose(Space* home);
00414
00416
00417
00418 GECODE_KERNEL_EXPORT virtual void flush(void);
00420 GECODE_KERNEL_EXPORT virtual size_t cached(void) const;
00422 static void* operator new(size_t s, Space* home);
00424 static void operator delete(void* p, Space* home);
00425 private:
00426 #ifndef __GNUC__
00427
00428 static void operator delete(void* p, size_t s);
00429 #endif
00430
00431 static void* operator new(size_t s);
00433 void destruct(Space* home);
00435 #ifdef __GNUC__
00436 public:
00438 virtual ~Actor(void) {}
00440 static void operator delete(void* p, size_t s);
00441 #endif
00442 };
00443
00444
00445
00450 class Propagator : public Actor {
00451 friend class Space;
00452 template <VarTypeId VTI, PropCond PC, class MED> friend class Variable;
00453 private:
00454 PropModEvent pme;
00455 protected:
00461 Propagator(Space* home, bool fd=false);
00463 Propagator(Space* home, bool share, Propagator& p);
00464
00466
00467
00477 ExecStatus ES_FIX_PARTIAL(PropModEvent pme);
00488 ExecStatus ES_NOFIX_PARTIAL(PropModEvent pme);
00490 public:
00492
00493
00494 virtual ExecStatus propagate(Space*) = 0;
00496 virtual PropCost cost(void) const = 0;
00498 };
00499
00500
00501
00502
00503
00504
00505
00506
00507 class Branching;
00508
00518 class BranchingDesc {
00519 friend class Space;
00520 private:
00521 const unsigned int id;
00522 const unsigned int alt;
00523 protected:
00525 BranchingDesc(const Branching* b, const unsigned int a);
00526 public:
00528 GECODE_KERNEL_EXPORT virtual ~BranchingDesc(void);
00529
00531 unsigned int alternatives(void) const;
00532
00534 virtual size_t size(void) const = 0;
00536 static void* operator new(size_t);
00538 static void operator delete(void*);
00539 };
00540
00550 class Branching : public Actor {
00551 friend class Space;
00552 friend class BranchingDesc;
00553 private:
00554 unsigned int id;
00555 protected:
00557 Branching(Space* home, bool fd=false);
00559 Branching(Space* home, bool share, Branching& b);
00560
00561 public:
00563
00564
00572 virtual bool status(const Space* home) const = 0;
00582 virtual const BranchingDesc* description(const Space* home) const = 0;
00590 virtual ExecStatus commit(Space* home, const BranchingDesc* d,
00591 unsigned int a) = 0;
00593 };
00594
00595
00596
00601 enum SpaceStatus {
00602 SS_FAILED,
00603 SS_SOLVED,
00604 SS_BRANCH
00605 };
00606
00610 class Space {
00611 friend class Propagator;
00612 friend class Branching;
00613 template <VarTypeId VTI, PropCond PC, class MED> friend class Variable;
00614 template <VarTypeId VTI, PropCond PC, class MED> friend class VarTypeProcessor;
00615 private:
00616 MemoryManager mm;
00617
00622
00623 GECODE_KERNEL_EXPORT
00624 static VarTypeProcessorBase* vtp[VTI_LAST];
00626 VarBase* vars[VTI_LAST];
00628 VarBase* vars_dispose[VTI_LAST];
00630 VarBase* vars_noidx;
00632 void process(void);
00634
00639
00640 ActorLink pool[PC_MAX+1];
00642 int pool_next;
00644 void pool_put(Propagator* p);
00646 bool pool_get(Propagator*& p);
00648
00655 ActorDeleteLink a_actors;
00664 Branching* b_status;
00677 Branching* b_commit;
00679 unsigned int branch_id;
00680
00690 unsigned int n_sub;
00698 Propagator** sub;
00700 GECODE_KERNEL_EXPORT static unsigned long int unused_uli;
00701
00703 GECODE_KERNEL_EXPORT unsigned long int propagate(void);
00704
00706 void propagator(Propagator* p, bool fd);
00708 void propagator(Propagator*);
00710 void branching(Branching* b, bool fd);
00711
00716
00717 template <VarTypeId VTI, class MED>
00718 void process(Propagator* p, ModEvent me);
00720 template <VarTypeId VTI, class MED>
00721 void process(Propagator* p);
00723
00724
00725 public:
00730 GECODE_KERNEL_EXPORT Space(void);
00735 GECODE_KERNEL_EXPORT virtual ~Space(void);
00746 GECODE_KERNEL_EXPORT Space(bool share, Space& s);
00753 virtual Space* copy(bool share) = 0;
00758 static void* operator new(size_t);
00763 static void operator delete(void*);
00764
00765
00766
00767
00768
00769
00770
00771
00772
00784 SpaceStatus status(unsigned long int& pn=unused_uli);
00785
00801 const BranchingDesc* description(void) const;
00802
00819 GECODE_KERNEL_EXPORT
00820 Space* clone(bool share=true, unsigned long int& pn=unused_uli);
00821
00851 GECODE_KERNEL_EXPORT
00852 void commit(const BranchingDesc* d, unsigned int a);
00853
00864 GECODE_KERNEL_EXPORT
00865 void flush(void);
00866
00867
00868
00869
00870
00871
00872
00880 void fail(void);
00889 bool failed(void) const;
00899 GECODE_KERNEL_EXPORT
00900 unsigned int propagators(void) const;
00908 GECODE_KERNEL_EXPORT
00909 unsigned int branchings(void) const;
00910
00916
00917 void* alloc(size_t);
00919 void reuse(void*,size_t);
00921 template <size_t> void* fl_alloc(void);
00927 template <size_t> void fl_dispose(FreeList* f, FreeList* l);
00933 size_t allocated(void) const;
00935 GECODE_KERNEL_EXPORT size_t cached(void) const;
00937 template <VarTypeId VTI> VarBase* varsDisposeList(void);
00939 template <VarTypeId VTI> void varsDisposeList(VarBase* v);
00941 };
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 forceinline void*
00957 Space::operator new(size_t s) {
00958 return Memory::malloc(s);
00959 }
00960 forceinline void
00961 Space::operator delete(void* p) {
00962 Memory::free(p);
00963 }
00964
00965 forceinline void
00966 BranchingDesc::operator delete(void* p) {
00967 Memory::free(p);
00968 }
00969 forceinline void*
00970 BranchingDesc::operator new(size_t s) {
00971 return Memory::malloc(s);
00972 }
00973
00974
00975
00976
00977
00978
00979 forceinline void*
00980 Space::alloc(size_t s) {
00981 return mm.alloc(s);
00982 }
00983 forceinline void
00984 Space::reuse(void* p, size_t s) {
00985 return mm.reuse(p,s);
00986 }
00987
00988 template <size_t s>
00989 forceinline void*
00990 Space::fl_alloc(void) {
00991 return mm.template fl_alloc<s>();
00992 }
00993 template <size_t s>
00994 forceinline void
00995 Space::fl_dispose(FreeList* f, FreeList* l) {
00996 mm.template fl_dispose<s>(f,l);
00997 }
00998
00999 forceinline size_t
01000 Space::allocated(void) const {
01001 return mm.allocated()+n_sub*sizeof(Propagator**);
01002 }
01003
01004 template <VarTypeId VTI>
01005 forceinline VarBase*
01006 Space::varsDisposeList(void) {
01007 return vars_dispose[VTI];
01008 }
01009
01010 template <VarTypeId VTI>
01011 forceinline void
01012 Space::varsDisposeList(VarBase* v) {
01013 vars_dispose[VTI]=v;
01014 }
01015
01016
01017
01018
01019
01020
01021 forceinline void
01022 Actor::operator delete(void*, size_t) {}
01023 forceinline void
01024 Actor::operator delete(void*,Space*) {}
01025 forceinline void*
01026 Actor::operator new(size_t s, Space* home) {
01027 return home->alloc(s);
01028 }
01029
01030 template <VarTypeId VTI, PropCond PC, class MED>
01031 forceinline void
01032 Variable<VTI,PC,MED>::operator delete(void*) {}
01033 template <VarTypeId VTI, PropCond PC, class MED>
01034 forceinline void
01035 Variable<VTI,PC,MED>::operator delete(void*, Space*) {}
01036 template <VarTypeId VTI, PropCond PC, class MED>
01037 forceinline void*
01038 Variable<VTI,PC,MED>::operator new(size_t s, Space* home) {
01039 return home->alloc(s);
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049 forceinline ActorLink*
01050 ActorLink::prev(void) const { return _prev; }
01051 forceinline ActorLink*
01052 ActorLink::next(void) const { return _next; }
01053 forceinline void
01054 ActorLink::prev(ActorLink* al) { _prev = al; }
01055 forceinline void
01056 ActorLink::next(ActorLink* al) { _next = al; }
01057
01058 forceinline void
01059 ActorLink::unlink(void) {
01060 ActorLink* p = _prev; ActorLink* n = _next;
01061 p->_next = n; n->_prev = p;
01062 }
01063 forceinline void
01064 ActorLink::init(void) {
01065 _next = this; _prev =this;
01066 }
01067 forceinline void
01068 ActorLink::head(ActorLink* a) {
01069
01070 ActorLink* n = _next;
01071 this->_next = a; a->_prev = this;
01072 a->_next = n; n->_prev = a;
01073 }
01074 forceinline void
01075 ActorLink::tail(ActorLink* a) {
01076
01077 ActorLink* p = _prev;
01078 a->_next = this; this->_prev = a;
01079 p->_next = a; a->_prev = p;
01080 }
01081
01082
01083
01084 forceinline ActorDeleteLink*
01085 ActorDeleteLink::next_delete(void) const { return _next_d; }
01086 forceinline ActorDeleteLink*
01087 ActorDeleteLink::prev_delete(void) const { return _prev_d; }
01088 forceinline void
01089 ActorDeleteLink::next_delete(ActorDeleteLink* adl) { _next_d = adl; }
01090 forceinline void
01091 ActorDeleteLink::prev_delete(ActorDeleteLink* adl) { _prev_d = adl; }
01092
01093 forceinline void
01094 ActorDeleteLink::unlink_delete(void) {
01095 ActorDeleteLink* p = _prev_d;
01096 ActorDeleteLink* n = _next_d;
01097 p->_next_d = n; n->_prev_d = p;
01098 }
01099
01100 forceinline void
01101 ActorDeleteLink::insert_delete(ActorDeleteLink* a, bool fd) {
01102 if (fd) {
01103
01104 ActorDeleteLink* n = _next_d;
01105 this->_next_d = a; a->_prev_d = this;
01106 a->_next_d = n; n->_prev_d = a;
01107 } else {
01108
01109 a->_prev_d = a; a->_next_d = a;
01110 }
01111 }
01112
01113 forceinline void
01114 ActorDeleteLink::init_delete(void) {
01115 _next_d = this; _prev_d = this;
01116 }
01117
01118
01119
01120
01121 forceinline size_t
01122 Actor::dispose(Space*) {
01123 return sizeof(*this);
01124 }
01125
01126 forceinline void
01127 Actor::destruct(Space* home) {
01128 unlink_delete();
01129 size_t s = dispose(home);
01130 home->reuse(this,s);
01131 }
01132
01133
01134
01135
01136
01137
01138
01139 forceinline const BranchingDesc*
01140 Space::description(void) const {
01141 return b_status->description(this);
01142 }
01143
01144 forceinline bool
01145 Space::failed(void) const {
01146 return b_status == NULL;
01147 }
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 forceinline SpaceStatus
01159 Space::status(unsigned long int& pn) {
01160
01161 pn += propagate();
01162 if (failed())
01163 return SS_FAILED;
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 while (b_status != &a_actors) {
01181 if (b_status->status(this))
01182 return SS_BRANCH;
01183 b_status = static_cast<Branching*>(b_status->next());
01184 }
01185
01186 return SS_SOLVED;
01187 }
01188
01189
01190
01191
01192
01193
01194
01195 template <VarTypeId VTI, PropCond PC, class MED>
01196 forceinline
01197 Variable<VTI,PC,MED>::Variable(Space*) :
01198 _next(reinterpret_cast<Variable<VTI,PC,MED>*>(1)) {
01199 u.free_me = 0;
01200 for (int i=PC+2; i--; )
01201 idx[i] = NULL;
01202 }
01203
01204
01205 template <VarTypeId VTI, PropCond PC, class MED>
01206 forceinline unsigned int
01207 Variable<VTI,PC,MED>::degree(void) const {
01208 return static_cast<unsigned int>(idx[PC+1] - idx[0]);
01209 }
01210
01211
01212
01213 template <VarTypeId VTI, PropCond PC, class MED>
01214 forceinline ModEvent
01215 Variable<VTI,PC,MED>::modevent(void) const {
01216 return u.free_me & 15;
01217 }
01218
01219 template <VarTypeId VTI, PropCond PC, class MED>
01220 forceinline void
01221 Variable<VTI,PC,MED>::modevent(ModEvent me) {
01222 u.free_me = (u.free_me & ~15) | me;
01223 }
01224 template <VarTypeId VTI, PropCond PC, class MED>
01225 forceinline unsigned int
01226 Variable<VTI,PC,MED>::free(void) const {
01227 return u.free_me >> 4;
01228 }
01229
01230 template <VarTypeId VTI, PropCond PC, class MED>
01231 forceinline void
01232 Variable<VTI,PC,MED>::free(unsigned int n) {
01233 u.free_me = (u.free_me & 15) | (n << 4);
01234 }
01235
01236 template <VarTypeId VTI, PropCond PC, class MED>
01237 forceinline void
01238 Variable<VTI,PC,MED>::free_inc(void) {
01239 u.free_me += (1 << 4);
01240 }
01241
01242 template <VarTypeId VTI, PropCond PC, class MED>
01243 forceinline void
01244 Variable<VTI,PC,MED>::free_dec(void) {
01245 u.free_me -= (1 << 4);
01246 }
01247
01248 template <VarTypeId VTI, PropCond PC, class MED>
01249 forceinline bool
01250 Variable<VTI,PC,MED>::modified(void) const {
01251 return _next != reinterpret_cast<Variable<VTI,PC,MED>*>(1);
01252 }
01253
01254
01255
01256 template <VarTypeId VTI, PropCond PC, class MED>
01257 forceinline Variable<VTI,PC,MED>*
01258 Variable<VTI,PC,MED>::next(void) {
01259 Variable<VTI,PC,MED>* n = _next;
01260 _next = reinterpret_cast<Variable<VTI,PC,MED>*>(1);
01261 return n;
01262 }
01263
01264 template <VarTypeId VTI, PropCond PC, class MED>
01265 forceinline bool
01266 Variable<VTI,PC,MED>::copied(void) const {
01267 return _next != reinterpret_cast<Variable<VTI,PC,MED>*>(1);
01268 }
01269
01270 template <VarTypeId VTI, PropCond PC, class MED>
01271 forceinline
01272 Variable<VTI,PC,MED>::Variable(Space* home, bool, Variable<VTI,PC,MED>& x)
01273 : _next(reinterpret_cast<Variable<VTI,PC,MED>*>(1)) {
01274 VarBase** reg;
01275 if (x.idx[0] == NULL) {
01276
01277 u.free_me = 0;
01278 for (int i=PC+2; i--; )
01279 idx[i] = NULL;
01280 reg = &home->vars_noidx;
01281 } else {
01282
01283 u.free_me = x.u.free_me;
01284 reg = &home->vars[VTI];
01285 }
01286
01287 x.u.fwd = this;
01288
01289 x._next = static_cast<Variable<VTI,PC,MED>*>(*reg); *reg = &x;
01290 }
01291
01292 template <VarTypeId VTI, PropCond PC, class MED>
01293 forceinline Variable<VTI,PC,MED>*
01294 Variable<VTI,PC,MED>::forward(void) const {
01295 return u.fwd;
01296 }
01297
01298
01299
01300
01301
01302
01303 template <VarTypeId VTI, PropCond PC, class MED>
01304 forceinline ModEvent
01305 Variable<VTI,PC,MED>::pme(const Propagator* p) {
01306 return static_cast<ModEvent>((p->pme >> (VTI << 2)) & 15);
01307 }
01308
01309 template <VarTypeId VTI, PropCond PC, class MED>
01310 forceinline PropModEvent
01311 Variable<VTI,PC,MED>::pme(ModEvent me) {
01312 return static_cast<PropModEvent>(me << (VTI << 2));
01313 }
01314
01315 template <VarTypeId VTI, PropCond PC, class MED>
01316 forceinline ModEvent
01317 Variable<VTI,PC,MED>::combine(ModEvent me1, ModEvent me2) {
01318 MED med;
01319 return me2^med(me1,me2);
01320 }
01321
01322
01323
01324
01325
01326
01327 forceinline void
01328 Space::propagator(Propagator* p, bool fd) {
01329
01330 a_actors.head(p);
01331 a_actors.insert_delete(p,fd);
01332 }
01333
01334 forceinline void
01335 Space::propagator(Propagator* p) {
01336 a_actors.head(p);
01337 }
01338
01339 forceinline void
01340 Space::branching(Branching* b, bool fd) {
01341
01342 b->id = branch_id++;
01343
01344 if (b_status == &a_actors) {
01345 b_status = b;
01346 if (b_commit == &a_actors)
01347 b_commit = b;
01348 }
01349 a_actors.tail(b);
01350 a_actors.insert_delete(b,fd);
01351 }
01352
01353
01354
01355 forceinline
01356 Propagator::Propagator(Space* home, bool fd)
01357 : pme(0) {
01358 home->propagator(this,fd);
01359 }
01360
01361 forceinline
01362 Propagator::Propagator(Space*, bool, Propagator&)
01363 : pme(0) {}
01364
01365
01366
01367
01368
01369
01370
01371 forceinline
01372 Branching::Branching(Space* home, bool fd) {
01373 home->branching(this,fd);
01374 }
01375
01376 forceinline
01377 Branching::Branching(Space*, bool, Branching& b)
01378 : id(b.id) {}
01379
01380
01381
01382
01383
01384
01385
01386
01387 forceinline
01388 BranchingDesc::BranchingDesc(const Branching* b, const unsigned int a)
01389 : id(b->id), alt(a) {}
01390
01391 forceinline unsigned int
01392 BranchingDesc::alternatives(void) const {
01393 return alt;
01394 }
01395
01396 forceinline
01397 BranchingDesc::~BranchingDesc(void) {}
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408 forceinline void
01409 Space::pool_put(Propagator* p) {
01410 int c = p->cost();
01411 pool[c].tail(p);
01412 if (c > pool_next)
01413 pool_next = c;
01414 }
01415
01416 forceinline void
01417 Space::fail(void) {
01418 b_status = NULL;
01419 }
01420
01421 template <VarTypeId VTI, class MED>
01422 forceinline void
01423 Space::process(Propagator* p) {
01424
01425 PropModEvent old_pme = p->pme;
01426
01427 ModEvent old_me = old_pme & (ME_GEN_MAX << (VTI << 2));
01428
01429 if (old_me == (ME_GEN_ASSIGNED << (VTI << 2)))
01430 return;
01431
01432 p->pme ^= old_me ^ (ME_GEN_ASSIGNED << (VTI << 2));
01433
01434 p->unlink();
01435 pool_put(p);
01436 }
01437
01438 template <VarTypeId VTI, class MED>
01439 forceinline void
01440 Space::process(Propagator* p, ModEvent new_me) {
01441 MED med;
01442 PropModEvent old_pme = p->pme;
01443
01444 ModEvent old_me = ((old_pme >> (VTI << 2)) & ME_GEN_MAX);
01445
01446 ModEvent com_me = med(new_me,old_me);
01447
01448 if (com_me == 0)
01449 return;
01450
01451 p->pme ^= (com_me << (VTI << 2));
01452
01453 p->unlink();
01454 pool_put(p);
01455 }
01456
01457 forceinline ExecStatus
01458 Propagator::ES_FIX_PARTIAL(PropModEvent pme) {
01459 this->pme = pme; return __ES_FIX_PARTIAL;
01460 }
01461
01462 forceinline ExecStatus
01463 Propagator::ES_NOFIX_PARTIAL(PropModEvent pme) {
01464 this->pme = pme; return __ES_NOFIX_PARTIAL;
01465 }
01466
01467
01468
01469
01470
01471
01472
01473 template <VarTypeId VTI, PropCond PC, class MED>
01474 forceinline void
01475 Variable<VTI,PC,MED>::subscribe(Space* home, Propagator* p, PropCond pc,
01476 bool assigned, ModEvent me, bool process) {
01477 if (assigned) {
01478
01479 if (process)
01480 home->process<VTI,MED>(p);
01481 } else {
01482
01483 home->n_sub += 1;
01484 if (free() == 0)
01485 resize(home);
01486 free_dec();
01487
01488 --idx[0];
01489 for (PropCond i = 0; i < pc; i++)
01490 *(idx[i]) = *(--idx[i+1]);
01491 *idx[pc]=p;
01492
01493 if (process && (pc != PC_GEN_ASSIGNED))
01494 home->process<VTI,MED>(p,me);
01495 }
01496 }
01497
01498 template <VarTypeId VTI, PropCond PC, class MED>
01499 void
01500 Variable<VTI,PC,MED>::resize(Space* home) {
01501 assert(free() == 0);
01502 if (idx[0] == NULL) {
01503
01504 home->n_sub += 1;
01505
01506 free(4);
01507 Propagator** prop = reinterpret_cast<Propagator**>
01508 (home->alloc(4*sizeof(Propagator*))) + 4;
01509 for (PropCond i = PC+2; i--; )
01510 idx[i] = prop;
01511 } else {
01512
01513 int n = static_cast<int>(idx[PC+1] - idx[0]);
01514 Propagator** prop = reinterpret_cast<Propagator**>
01515 (home->alloc(2*n*sizeof(Propagator*))) + n;
01516 free(n);
01517
01518 memcpy(prop, idx[0], n*sizeof(Propagator*));
01519 home->reuse(idx[0], n*sizeof(Propagator*));
01520
01521 ptrdiff_t o = prop - idx[0];
01522 idx[0] = prop;
01523 for (PropCond i = PC+1; i > 0; i--)
01524 idx[i] += o;
01525 }
01526 }
01527
01528
01529
01530
01531
01532
01533
01534 template <VarTypeId VTI, PropCond PC, class MED>
01535 forceinline void
01536 Variable<VTI,PC,MED>::cancel(Space* home, Propagator* p, PropCond pc) {
01537 if (idx[0] != NULL) {
01538 Propagator** f = idx[pc];
01539 #ifdef GECODE_AUDIT
01540 while (f < idx[pc+1])
01541 if (*f == p)
01542 goto found;
01543 else
01544 f++;
01545 GECODE_NEVER;
01546 found: ;
01547 #else
01548 while (*f != p) f++;
01549 #endif
01550 *f=*idx[pc];
01551 for (PropCond i=pc; i>0; i--)
01552 *(idx[i]++)=*(idx[i-1]);
01553 idx[0]++;
01554 free_inc();
01555 home->n_sub -= 1;
01556 }
01557 }
01558
01559 template <VarTypeId VTI, PropCond PC, class MED>
01560 forceinline void
01561 Variable<VTI,PC,MED>::notify(Space* home, ModEvent new_me) {
01562 if (modified()) {
01563 MED med;
01564 u.free_me ^= med(new_me,modevent());
01565 } else {
01566 _next = static_cast<Variable<VTI,PC,MED>*>(home->vars[VTI]);
01567 home->vars[VTI] = this;
01568 modevent(new_me);
01569 }
01570 }
01571
01572 template <VarTypeId VTI, PropCond PC, class MED>
01573 forceinline void
01574 Variable<VTI,PC,MED>::notify(Space* home) {
01575 assert(!modified());
01576 _next = static_cast<Variable<VTI,PC,MED>*>(home->vars[VTI]);
01577 home->vars[VTI] = this;
01578 modevent(ME_GEN_ASSIGNED);
01579 }
01580
01581
01582
01583
01584
01585
01586
01587 template <VarTypeId VTI, PropCond PC, class MED>
01588 forceinline void
01589 Variable<VTI,PC,MED>::update(Variable<VTI,PC,MED>* x, Propagator**& sub) {
01590
01591
01592
01593 x->u.free_me = u.free_me;
01594 Propagator** f = x->idx[0];
01595 int n = static_cast<int>(x->idx[PC+1] - f);
01596 u.free_me = 1 << 4;
01597 Propagator** t = sub + 1;
01598 sub += n+1;
01599 idx[0] = t;
01600 ptrdiff_t o = t - f;
01601 for (PropCond i = PC+1; i>0; i--)
01602 idx[i] = x->idx[i]+o;
01603 while ((n-4) >= 0) {
01604 n -= 4;
01605 t[0] = static_cast<Propagator*>(f[0]->prev());;
01606 t[1] = static_cast<Propagator*>(f[1]->prev());;
01607 t[2] = static_cast<Propagator*>(f[2]->prev());;
01608 t[3] = static_cast<Propagator*>(f[3]->prev());;
01609 t += 4; f += 4;
01610 }
01611 if ((n-2) >= 0) {
01612 n -= 2;
01613 t[0] = static_cast<Propagator*>(f[0]->prev());;
01614 t[1] = static_cast<Propagator*>(f[1]->prev());;
01615 t += 2; f += 2;
01616 }
01617 if (n > 0) {
01618 t[0] = static_cast<Propagator*>(f[0]->prev());;
01619 }
01620 }
01621
01622 template <VarTypeId VTI, PropCond PC, class MED>
01623 VarTypeProcessor<VTI,PC,MED>::VarTypeProcessor(void) {
01624 Space::vtp[VTI] = this;
01625 }
01626
01627 template <VarTypeId VTI, PropCond PC, class MED>
01628 void
01629 VarTypeProcessor<VTI,PC,MED>::update(VarBase* vb, Propagator**& sub) {
01630 Variable<VTI,PC,MED>* x = static_cast<Variable<VTI,PC,MED>*>(vb);
01631 do {
01632 x->forward()->update(x,sub); x = x->next();
01633 } while (x != NULL);
01634 }
01635
01636 template <VarTypeId VTI, PropCond PC, class MED>
01637 void
01638 VarTypeProcessor<VTI,PC,MED>::dispose(Space* home, VarBase* x) {}
01639
01640
01641
01642
01643
01644 template <VarTypeId VTI, PropCond PC, class MED>
01645 forceinline void
01646 Variable<VTI,PC,MED>::process(Space* home,
01647 PropCond pc1, PropCond pc2, ModEvent me) {
01648 Propagator** b = idx[pc1];
01649 Propagator** p = idx[pc2+1];
01650 while (p-- > b)
01651 home->process<VTI,MED>(*p,me);
01652 }
01653
01654 template <VarTypeId VTI, PropCond PC, class MED>
01655 forceinline void
01656 Variable<VTI,PC,MED>::process(Space* home) {
01657
01658
01659 Propagator** b = idx[0]; idx[0] = NULL;
01660 Propagator** p = idx[PC+1]; idx[PC+1] = NULL;
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670 home->n_sub -= p-b;
01671
01672 unsigned int n = free() + (p-b);
01673 Propagator** s = p-n;
01674 while (p-- > b)
01675 home->process<VTI,MED>(*p);
01676 home->reuse(s,n*sizeof(Propagator*));
01677 }
01678
01679 }
01680
01681