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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <iostream>
00050
00051 namespace Gecode {
00052
00053 class Space;
00054
00079 class SharedHandle {
00080 public:
00088 class Object : public HeapAllocated {
00089 friend class Space;
00090 friend class SharedHandle;
00091 private:
00093 Object* next;
00095 Object* fwd;
00097 unsigned int use_cnt;
00098 public:
00100 Object(void);
00102 virtual Object* copy(void) const = 0;
00104 virtual ~Object(void);
00105 };
00106 private:
00108 Object* o;
00110 void subscribe(void);
00112 void cancel(void);
00113 public:
00115 SharedHandle(void);
00117 SharedHandle(SharedHandle::Object* so);
00119 SharedHandle(const SharedHandle& sh);
00121 SharedHandle& operator =(const SharedHandle& sh);
00123 void update(Space& home, bool share, SharedHandle& sh);
00125 ~SharedHandle(void);
00126 protected:
00128 SharedHandle::Object* object(void) const;
00130 void object(SharedHandle::Object* n);
00131 };
00132
00141
00142 typedef int ModEvent;
00143
00145 const ModEvent ME_GEN_FAILED = -1;
00147 const ModEvent ME_GEN_NONE = 0;
00149 const ModEvent ME_GEN_ASSIGNED = 1;
00150
00152 typedef int PropCond;
00154 const PropCond PC_GEN_NONE = -1;
00156 const PropCond PC_GEN_ASSIGNED = 0;
00158
00169 typedef int ModEventDelta;
00170
00171 }
00172
00173 #include <gecode/kernel/var-type.hpp>
00174
00175 namespace Gecode {
00176
00178 class NoIdxVarImpConf {
00179 public:
00181 static const int idx_c = -1;
00183 static const int idx_d = -1;
00185 static const PropCond pc_max = PC_GEN_ASSIGNED;
00187 static const int free_bits = 0;
00189 static const int med_fst = 0;
00191 static const int med_lst = 0;
00193 static const int med_mask = 0;
00195 static Gecode::ModEvent me_combine(ModEvent me1, ModEvent me2);
00197 static bool med_update(ModEventDelta& med, ModEvent me);
00198 };
00199
00200 forceinline ModEvent
00201 NoIdxVarImpConf::me_combine(ModEvent, ModEvent) {
00202 GECODE_NEVER; return 0;
00203 }
00204 forceinline bool
00205 NoIdxVarImpConf::med_update(ModEventDelta&, ModEvent) {
00206 GECODE_NEVER; return false;
00207 }
00208
00209
00210
00211
00212
00213
00214 class ActorLink;
00215 class Actor;
00216 class Propagator;
00217 class SubscribedPropagators;
00218 class LocalObject;
00219 class Advisor;
00220 class AFC;
00221 class Choice;
00222 class Brancher;
00223 class Group;
00224 class PropagatorGroup;
00225 class BrancherGroup;
00226 class PostInfo;
00227 class ViewTraceInfo;
00228 class PropagateTraceInfo;
00229 class CommitTraceInfo;
00230 class TraceRecorder;
00231
00232 template<class A> class Council;
00233 template<class A> class Advisors;
00234 template<class VIC> class VarImp;
00235
00236
00237
00238
00239
00240
00241
00249 class VarImpBase {};
00250
00257 class GECODE_VTABLE_EXPORT VarImpDisposerBase {
00258 public:
00260 GECODE_KERNEL_EXPORT virtual void dispose(Space& home, VarImpBase* x);
00262 GECODE_KERNEL_EXPORT virtual ~VarImpDisposerBase(void);
00263 };
00264
00271 template<class VarImp>
00272 class VarImpDisposer : public VarImpDisposerBase {
00273 public:
00275 VarImpDisposer(void);
00277 virtual void dispose(Space& home, VarImpBase* x);
00278 };
00279
00281 class Delta {
00282 template<class VIC> friend class VarImp;
00283 private:
00285 ModEvent me;
00286 };
00287
00295 template<class VIC>
00296 class VarImp : public VarImpBase {
00297 friend class Space;
00298 friend class Propagator;
00299 template<class VarImp> friend class VarImpDisposer;
00300 friend class SubscribedPropagators;
00301 private:
00302 union {
00310 ActorLink** base;
00319 VarImp<VIC>* fwd;
00320 } b;
00321
00323 static const int idx_c = VIC::idx_c;
00325 static const int idx_d = VIC::idx_d;
00327 static const int free_bits = VIC::free_bits;
00329 unsigned int entries;
00331 unsigned int free_and_bits;
00333 static const Gecode::PropCond pc_max = VIC::pc_max;
00334
00335 union {
00346 unsigned int idx[pc_max+1];
00348 VarImp<VIC>* next;
00349 } u;
00350
00352 ActorLink** actor(PropCond pc);
00354 ActorLink** actorNonZero(PropCond pc);
00356 unsigned int& idx(PropCond pc);
00358 unsigned int idx(PropCond pc) const;
00359
00366 void update(VarImp* x, ActorLink**& sub);
00373 static void update(Space& home, ActorLink**& sub);
00374
00376 void enter(Space& home, Propagator* p, PropCond pc);
00378 void enter(Space& home, Advisor* a);
00380 void resize(Space& home);
00382 void remove(Space& home, Propagator* p, PropCond pc);
00384 void remove(Space& home, Advisor* a);
00385
00386
00387 protected:
00389 void cancel(Space& home);
00395 bool advise(Space& home, ModEvent me, Delta& d);
00396 private:
00398 void _fail(Space& home);
00399 protected:
00401 ModEvent fail(Space& home);
00402 #ifdef GECODE_HAS_VAR_DISPOSE
00403
00404 static VarImp<VIC>* vars_d(Space& home);
00406 static void vars_d(Space& home, VarImp<VIC>* x);
00407 #endif
00408
00409 public:
00411 VarImp(Space& home);
00413 VarImp(void);
00414
00416
00417
00429 void subscribe(Space& home, Propagator& p, PropCond pc,
00430 bool assigned, ModEvent me, bool schedule);
00432 void cancel(Space& home, Propagator& p, PropCond pc);
00441 void subscribe(Space& home, Advisor& a, bool assigned, bool fail);
00443 void cancel(Space& home, Advisor& a, bool fail);
00444
00451 unsigned int degree(void) const;
00458 double afc(void) const;
00460
00462
00463
00464 VarImp(Space& home, bool share, VarImp& x);
00466 bool copied(void) const;
00468 VarImp* forward(void) const;
00470 VarImp* next(void) const;
00472
00474
00475
00482 static void schedule(Space& home, Propagator& p, ModEvent me,
00483 bool force = false);
00491 static void reschedule(Space& home, Propagator& p, PropCond pc,
00492 bool assigned, ModEvent me);
00494 static ModEvent me(const ModEventDelta& med);
00496 static ModEventDelta med(ModEvent me);
00498 static ModEvent me_combine(ModEvent me1, ModEvent me2);
00500
00502
00503
00504 static ModEvent modevent(const Delta& d);
00506
00508
00509
00510 unsigned int bits(void) const;
00512 unsigned int& bits(void);
00514
00515 protected:
00517 void schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me);
00518
00519 public:
00521
00522
00523 static void* operator new(size_t,Space&);
00525 static void operator delete(void*,Space&);
00527 static void operator delete(void*);
00529 };
00530
00531
00540 enum ExecStatus {
00541 __ES_SUBSUMED = -2,
00542 ES_FAILED = -1,
00543 ES_NOFIX = 0,
00544 ES_OK = 0,
00545 ES_FIX = 1,
00546 ES_NOFIX_FORCE = 2,
00547 __ES_PARTIAL = 2
00548 };
00549
00554 class PropCost {
00555 friend class Space;
00556 public:
00558 enum ActualCost {
00559 AC_RECORD = 0,
00560 AC_CRAZY_LO = 1,
00561 AC_CRAZY_HI = 1,
00562 AC_CUBIC_LO = 1,
00563 AC_CUBIC_HI = 1,
00564 AC_QUADRATIC_LO = 2,
00565 AC_QUADRATIC_HI = 2,
00566 AC_LINEAR_HI = 3,
00567 AC_LINEAR_LO = 4,
00568 AC_TERNARY_HI = 4,
00569 AC_BINARY_HI = 5,
00570 AC_TERNARY_LO = 5,
00571 AC_BINARY_LO = 6,
00572 AC_UNARY_LO = 6,
00573 AC_UNARY_HI = 6,
00574 AC_MAX = 6
00575 };
00577 ActualCost ac;
00578 public:
00580 enum Mod {
00581 LO,
00582 HI
00583 };
00584 private:
00586 static PropCost cost(Mod m, ActualCost lo, ActualCost hi, unsigned int n);
00588 PropCost(ActualCost ac);
00589 public:
00591 static PropCost record(void);
00593 static PropCost crazy(PropCost::Mod m, unsigned int n);
00595 static PropCost crazy(PropCost::Mod m, int n);
00597 static PropCost cubic(PropCost::Mod m, unsigned int n);
00599 static PropCost cubic(PropCost::Mod m, int n);
00601 static PropCost quadratic(PropCost::Mod m, unsigned int n);
00603 static PropCost quadratic(PropCost::Mod m, int n);
00605 static PropCost linear(PropCost::Mod m, unsigned int n);
00607 static PropCost linear(PropCost::Mod m, int n);
00609 static PropCost ternary(PropCost::Mod m);
00611 static PropCost binary(PropCost::Mod m);
00613 static PropCost unary(PropCost::Mod m);
00614 };
00615
00616
00621 enum ActorProperty {
00630 AP_DISPOSE = (1 << 0),
00636 AP_WEAKLY = (1 << 1),
00641 AP_VIEW_TRACE = (1 << 2),
00646 AP_TRACE = (1 << 3)
00647 };
00648
00649
00657 class ActorLink {
00658 friend class Actor;
00659 friend class Propagator;
00660 friend class Advisor;
00661 friend class Brancher;
00662 friend class LocalObject;
00663 friend class Space;
00664 template<class VIC> friend class VarImp;
00665 private:
00666 ActorLink* _next; ActorLink* _prev;
00667 public:
00669
00670 ActorLink* prev(void) const; void prev(ActorLink*);
00671 ActorLink* next(void) const; void next(ActorLink*);
00672 ActorLink** next_ref(void);
00674
00676 void init(void);
00678 void unlink(void);
00680 void head(ActorLink* al);
00682 void tail(ActorLink* al);
00684 bool empty(void) const;
00686 template<class T> static ActorLink* cast(T* a);
00688 template<class T> static const ActorLink* cast(const T* a);
00689 };
00690
00691
00696 class GECODE_VTABLE_EXPORT Actor : private ActorLink {
00697 friend class ActorLink;
00698 friend class Space;
00699 friend class Propagator;
00700 friend class Advisor;
00701 friend class Brancher;
00702 friend class LocalObject;
00703 template<class VIC> friend class VarImp;
00704 template<class A> friend class Council;
00705 private:
00707 static Actor* cast(ActorLink* al);
00709 static const Actor* cast(const ActorLink* al);
00711 GECODE_KERNEL_EXPORT static Actor* sentinel;
00712 public:
00714 virtual Actor* copy(Space& home, bool share) = 0;
00715
00717
00718
00719 GECODE_KERNEL_EXPORT
00720 virtual size_t dispose(Space& home);
00722 static void* operator new(size_t s, Space& home);
00724 static void operator delete(void* p, Space& home);
00726 public:
00728 GECODE_KERNEL_EXPORT virtual ~Actor(void);
00730 static void* operator new(size_t s);
00732 static void operator delete(void* p);
00733 };
00734
00735 class Home;
00736
00741 class Group {
00742 friend class Home;
00743 friend class Propagator;
00744 friend class Brancher;
00745 friend class ViewTraceInfo;
00746 friend class PropagateTraceInfo;
00747 friend class CommitTraceInfo;
00748 protected:
00750 static const unsigned int GROUPID_ALL = 0U;
00752 static const unsigned int GROUPID_DEF = 1U;
00754 static const unsigned int GROUPID_MAX = UINT_MAX >> 2;
00756 unsigned int gid;
00758 GECODE_KERNEL_EXPORT
00759 static unsigned int next;
00761 GECODE_KERNEL_EXPORT
00762 static Support::Mutex m;
00764 Group(unsigned int gid0);
00765 public:
00767
00768
00769 GECODE_KERNEL_EXPORT
00770 Group(void);
00772 Group(const Group& g);
00774 Group& operator =(const Group& g);
00776 unsigned int id(void) const;
00778 bool in(Group a) const;
00780 bool in(void) const;
00782
00783 GECODE_KERNEL_EXPORT
00784 static Group all;
00786 GECODE_KERNEL_EXPORT
00787 static Group def;
00788 };
00789
00794 class PropagatorGroup : public Group {
00795 friend class Propagator;
00796 friend class ViewTraceInfo;
00797 friend class PropagateTraceInfo;
00798 protected:
00800 PropagatorGroup(unsigned int gid);
00801 public:
00803
00804
00805 PropagatorGroup(void);
00807 PropagatorGroup(const PropagatorGroup& g);
00809 PropagatorGroup& operator =(const PropagatorGroup& g);
00811 Home operator ()(Space& home);
00813
00814
00815
00816 GECODE_KERNEL_EXPORT
00817 PropagatorGroup& move(Space& home, PropagatorGroup g);
00819 PropagatorGroup& move(Space& home, Propagator& p);
00826 GECODE_KERNEL_EXPORT
00827 PropagatorGroup& move(Space& home, unsigned int id);
00829
00830
00831
00832 bool operator ==(PropagatorGroup g) const;
00834 bool operator !=(PropagatorGroup g) const;
00836 GECODE_KERNEL_EXPORT
00837 unsigned int size(Space& home) const;
00839 GECODE_KERNEL_EXPORT
00840 void kill(Space& home);
00842 GECODE_KERNEL_EXPORT
00843 void disable(Space& home);
00850 GECODE_KERNEL_EXPORT
00851 void enable(Space& home, bool s=true);
00853
00854 GECODE_KERNEL_EXPORT
00855 static PropagatorGroup all;
00857 GECODE_KERNEL_EXPORT
00858 static PropagatorGroup def;
00859 };
00860
00865 class BrancherGroup : public Group {
00866 friend class Brancher;
00867 protected:
00869 BrancherGroup(unsigned int gid);
00870 public:
00872
00873
00874 BrancherGroup(void);
00876 BrancherGroup(const BrancherGroup& g);
00878 BrancherGroup& operator =(const BrancherGroup& g);
00880 Home operator ()(Space& home);
00882
00883
00884
00885 GECODE_KERNEL_EXPORT
00886 BrancherGroup& move(Space& home, BrancherGroup g);
00888 BrancherGroup& move(Space& home, Brancher& b);
00895 GECODE_KERNEL_EXPORT
00896 BrancherGroup& move(Space& home, unsigned int id);
00898
00899
00900
00901 bool operator ==(BrancherGroup g) const;
00903 bool operator !=(BrancherGroup g) const;
00905 GECODE_KERNEL_EXPORT
00906 unsigned int size(Space& home) const;
00908 GECODE_KERNEL_EXPORT
00909 void kill(Space& home);
00911
00912 GECODE_KERNEL_EXPORT
00913 static BrancherGroup all;
00915 GECODE_KERNEL_EXPORT
00916 static BrancherGroup def;
00917 };
00918
00922 class Home {
00923 friend class PostInfo;
00924 protected:
00926 Space& s;
00928 Propagator* p;
00930 PropagatorGroup pg;
00932 BrancherGroup bg;
00933 public:
00935
00936
00937 Home(Space& s, Propagator* p=NULL,
00938 PropagatorGroup pg=PropagatorGroup::def,
00939 BrancherGroup bg=BrancherGroup::def);
00941 Home& operator =(const Home& h);
00943 operator Space&(void);
00945
00946
00947
00948 Home operator ()(Propagator& p);
00950 Home operator ()(PropagatorGroup pg);
00952 Home operator ()(BrancherGroup bg);
00954 Propagator* propagator(void) const;
00956 PropagatorGroup propagatorgroup(void) const;
00958 BrancherGroup branchergroup(void) const;
00960
00961
00962
00963 bool failed(void) const;
00965 void fail(void);
00967 void notice(Actor& a, ActorProperty p, bool duplicate=false);
00969 };
00970
00974 class ViewTraceInfo {
00975 friend class Space;
00976 friend class PostInfo;
00977 public:
00979 enum What {
00981 PROPAGATOR = 0,
00983 BRANCHER = 1,
00985 POST = 2,
00987 OTHER = 3
00988 };
00989 protected:
00991 ptrdiff_t who;
00993 void propagator(Propagator& p);
00995 void brancher(Brancher& b);
00997 void post(PropagatorGroup g);
00999 void other(void);
01000 public:
01002 What what(void) const;
01004 const Propagator& propagator(void) const;
01006 const Brancher& brancher(void) const;
01008 PropagatorGroup post(void) const;
01009 };
01010
01014 class PostInfo {
01015 protected:
01017 Space& h;
01018 public:
01020 PostInfo(Home home);
01022 ~PostInfo(void);
01023 };
01024
01028 class PropagateTraceInfo {
01029 friend class Space;
01030 public:
01032 enum Status {
01033 FIX,
01034 NOFIX,
01035 FAILED,
01036 SUBSUMED
01037 };
01038 protected:
01040 unsigned int i;
01042 PropagatorGroup g;
01044 const Propagator* p;
01046 Status s;
01048 PropagateTraceInfo(unsigned int i, PropagatorGroup g,
01049 const Propagator* p, Status s);
01050 public:
01052 unsigned int id(void) const;
01054 PropagatorGroup group(void) const;
01056 const Propagator* propagator(void) const;
01058 Status status(void) const;
01059 };
01060
01064 class CommitTraceInfo {
01065 friend class Space;
01066 protected:
01068 const Brancher& b;
01070 const Choice& c;
01072 unsigned int a;
01074 CommitTraceInfo(const Brancher& b, const Choice& c, unsigned int a);
01075 public:
01077 unsigned int id(void) const;
01079 BrancherGroup group(void) const;
01081 const Brancher& brancher(void) const;
01083 const Choice& choice(void) const;
01085 unsigned int alternative(void) const;
01086 };
01087
01092 class GECODE_VTABLE_EXPORT Propagator : public Actor {
01093 friend class ActorLink;
01094 friend class Space;
01095 template<class VIC> friend class VarImp;
01096 friend class Advisor;
01097 template<class A> friend class Council;
01098 friend class SubscribedPropagators;
01099 friend class PropagatorGroup;
01100 private:
01101 union {
01103 ModEventDelta med;
01105 size_t size;
01107 Gecode::ActorLink* advisors;
01108 } u;
01110 void* gpi_disabled;
01112 static Propagator* cast(ActorLink* al);
01114 static const Propagator* cast(const ActorLink* al);
01116 void disable(Space& home);
01118 void enable(Space& home);
01119 protected:
01121 Propagator(Home home);
01123 Propagator(Space& home, bool share, Propagator& p);
01125 Propagator* fwd(void) const;
01127 GPI::Info& gpi(void);
01128
01129 public:
01131
01132
01140 virtual void reschedule(Space& home) = 0;
01164 virtual ExecStatus propagate(Space& home, const ModEventDelta& med) = 0;
01166 virtual PropCost cost(const Space& home, const ModEventDelta& med) const = 0;
01174 ModEventDelta modeventdelta(void) const;
01210 GECODE_KERNEL_EXPORT
01211 virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
01213 GECODE_KERNEL_EXPORT
01214 virtual void advise(Space& home, Advisor& a);
01216
01217
01218
01219 double afc(void) const;
01221
01222
01223
01224 unsigned int id(void) const;
01226 PropagatorGroup group(void) const;
01228 void group(PropagatorGroup g);
01230 bool disabled(void) const;
01232 };
01233
01234
01242 template<class A>
01243 class Council {
01244 friend class Advisor;
01245 friend class Advisors<A>;
01246 private:
01248 mutable ActorLink* advisors;
01249 public:
01251 Council(void);
01253 Council(Space& home);
01255 bool empty(void) const;
01257 void update(Space& home, bool share, Council<A>& c);
01259 void dispose(Space& home);
01260 };
01261
01262
01267 template<class A>
01268 class Advisors {
01269 private:
01271 ActorLink* a;
01272 public:
01274 Advisors(const Council<A>& c);
01276 bool operator ()(void) const;
01278 void operator ++(void);
01280 A& advisor(void) const;
01281 };
01282
01283
01294 class Advisor : private ActorLink {
01295 template<class VIC> friend class VarImp;
01296 template<class A> friend class Council;
01297 template<class A> friend class Advisors;
01298 friend class SubscribedPropagators;
01299 private:
01301 bool disposed(void) const;
01303 static Advisor* cast(ActorLink* al);
01305 static const Advisor* cast(const ActorLink* al);
01306 protected:
01308 Propagator& propagator(void) const;
01309 public:
01311 template<class A>
01312 Advisor(Space& home, Propagator& p, Council<A>& c);
01314 Advisor(Space& home, bool share, Advisor& a);
01316 const ViewTraceInfo& operator ()(const Space& home) const;
01317
01319
01320
01321 template<class A>
01322 void dispose(Space& home, Council<A>& c);
01324 static void* operator new(size_t s, Space& home);
01326 static void operator delete(void* p, Space& home);
01328 private:
01329 #ifndef __GNUC__
01330
01331 static void operator delete(void* p);
01332 #endif
01333
01334 static void* operator new(size_t s);
01335 };
01336
01337
01342 class GECODE_VTABLE_EXPORT NGL {
01343 private:
01345 void* nl;
01346 public:
01348 enum Status {
01349 FAILED,
01350 SUBSUMED,
01351 NONE
01352 };
01354 NGL(void);
01356 NGL(Space& home);
01358 NGL(Space& home, bool share, NGL& ngl);
01360 virtual void subscribe(Space& home, Propagator& p) = 0;
01362 virtual void cancel(Space& home, Propagator& p) = 0;
01364 virtual void reschedule(Space& home, Propagator& p) = 0;
01366 virtual NGL::Status status(const Space& home) const = 0;
01368 virtual ExecStatus prune(Space& home) = 0;
01370 virtual NGL* copy(Space& home, bool share) = 0;
01372 GECODE_KERNEL_EXPORT
01373 virtual bool notice(void) const;
01375 virtual size_t dispose(Space& home);
01377
01378
01379 bool leaf(void) const;
01381 NGL* next(void) const;
01383 void leaf(bool l);
01385 void next(NGL* n);
01387 NGL* add(NGL* n, bool l);
01389
01390
01391
01392 static void* operator new(size_t s, Space& home);
01394 static void operator delete(void* s, Space& home);
01396 static void operator delete(void* p);
01398 public:
01400 GECODE_KERNEL_EXPORT virtual ~NGL(void);
01402 static void* operator new(size_t s);
01403 };
01404
01414 class GECODE_VTABLE_EXPORT Choice : public HeapAllocated {
01415 friend class Space;
01416 private:
01417 unsigned int bid;
01418 unsigned int alt;
01419
01421 unsigned int id(void) const;
01422 protected:
01424 Choice(const Brancher& b, const unsigned int a);
01425 public:
01427 unsigned int alternatives(void) const;
01429 GECODE_KERNEL_EXPORT virtual ~Choice(void);
01431 virtual size_t size(void) const = 0;
01433 GECODE_KERNEL_EXPORT
01434 virtual void archive(Archive& e) const;
01435 };
01436
01446 class GECODE_VTABLE_EXPORT Brancher : public Actor {
01447 friend class ActorLink;
01448 friend class Space;
01449 friend class Choice;
01450 private:
01452 unsigned int bid;
01454 unsigned int gid;
01456 static Brancher* cast(ActorLink* al);
01458 static const Brancher* cast(const ActorLink* al);
01459 protected:
01461 Brancher(Home home);
01463 Brancher(Space& home, bool share, Brancher& b);
01464 public:
01466
01467
01475 virtual bool status(const Space& home) const = 0;
01483 virtual const Choice* choice(Space& home) = 0;
01485 virtual const Choice* choice(const Space& home, Archive& e) = 0;
01492 virtual ExecStatus commit(Space& home, const Choice& c,
01493 unsigned int a) = 0;
01507 GECODE_KERNEL_EXPORT
01508 virtual NGL* ngl(Space& home, const Choice& c, unsigned int a) const;
01516 GECODE_KERNEL_EXPORT
01517 virtual void print(const Space& home, const Choice& c, unsigned int a,
01518 std::ostream& o) const;
01520
01521
01522
01523 unsigned int id(void) const;
01525 BrancherGroup group(void) const;
01527 void group(BrancherGroup g);
01529 };
01530
01538 class LocalObject : public Actor {
01539 friend class ActorLink;
01540 friend class Space;
01541 friend class LocalHandle;
01542 protected:
01544 LocalObject(Home home);
01546 LocalObject(Space& home, bool share, LocalObject& l);
01548 static LocalObject* cast(ActorLink* al);
01550 static const LocalObject* cast(const ActorLink* al);
01551 private:
01553 GECODE_KERNEL_EXPORT void fwdcopy(Space& home, bool share);
01554 public:
01556 LocalObject* fwd(Space& home, bool share);
01557 };
01558
01565 class LocalHandle {
01566 private:
01568 LocalObject* o;
01569 protected:
01571 LocalHandle(void);
01573 LocalHandle(LocalObject* lo);
01575 LocalHandle(const LocalHandle& lh);
01576 public:
01578 LocalHandle& operator =(const LocalHandle& lh);
01580 void update(Space& home, bool share, LocalHandle& lh);
01582 ~LocalHandle(void);
01583 protected:
01585 LocalObject* object(void) const;
01587 void object(LocalObject* n);
01588 };
01589
01590
01595 class GECODE_VTABLE_EXPORT NoGoods {
01596 protected:
01598 unsigned long int n;
01599 public:
01601 NoGoods(void);
01603 GECODE_KERNEL_EXPORT
01604 virtual void post(Space& home) const;
01606 unsigned long int ng(void) const;
01608 void ng(unsigned long int n);
01610 virtual ~NoGoods(void);
01612 GECODE_KERNEL_EXPORT
01613 static NoGoods eng;
01614 };
01615
01620 class GECODE_VTABLE_EXPORT MetaInfo {
01621 public:
01623 enum Type {
01625 RESTART,
01627 PORTFOLIO
01628 };
01629 protected:
01631 const Type t;
01633
01634
01635 const unsigned long int r;
01637 const unsigned long int s;
01639 const unsigned long int f;
01641 const Space* l;
01643 const NoGoods& ng;
01645
01646
01647
01648 const unsigned int a;
01650 public:
01652
01653
01654 MetaInfo(unsigned long int r,
01655 unsigned long int s,
01656 unsigned long int f,
01657 const Space* l,
01658 NoGoods& ng);
01660 MetaInfo(unsigned int a);
01662
01663 Type type(void) const;
01665
01666
01667 unsigned long int restart(void) const;
01669 unsigned long int solution(void) const;
01671 unsigned long int fail(void) const;
01673 const Space* last(void) const;
01675 const NoGoods& nogoods(void) const;
01677
01678
01679
01680 unsigned int asset(void) const;
01682 };
01683
01688 enum SpaceStatus {
01689 SS_FAILED,
01690 SS_SOLVED,
01691 SS_BRANCH
01692 };
01693
01698 class StatusStatistics {
01699 public:
01701 unsigned long int propagate;
01703 StatusStatistics(void);
01705 void reset(void);
01707 StatusStatistics operator +(const StatusStatistics& s);
01709 StatusStatistics& operator +=(const StatusStatistics& s);
01710 };
01711
01716 class CloneStatistics {
01717 public:
01719 CloneStatistics(void);
01721 void reset(void);
01723 CloneStatistics operator +(const CloneStatistics& s);
01725 CloneStatistics& operator +=(const CloneStatistics& s);
01726 };
01727
01732 class CommitStatistics {
01733 public:
01735 CommitStatistics(void);
01737 void reset(void);
01739 CommitStatistics operator +(const CommitStatistics& s);
01741 CommitStatistics& operator +=(const CommitStatistics& s);
01742 };
01743
01744
01748 class GECODE_VTABLE_EXPORT Space : public HeapAllocated {
01749 friend class Actor;
01750 friend class Propagator;
01751 friend class PropagatorGroup;
01752 friend class Propagators;
01753 friend class Brancher;
01754 friend class BrancherGroup;
01755 friend class Branchers;
01756 friend class Advisor;
01757 template <class A> friend class Council;
01758 template<class VIC> friend class VarImp;
01759 template<class VarImp> friend class VarImpDisposer;
01760 friend class SharedHandle;
01761 friend class LocalObject;
01762 friend class Region;
01763 friend class AFC;
01764 friend class PostInfo;
01765 private:
01767 SharedMemory* sm;
01769 MemoryManager mm;
01771 GPI gpi;
01773 ActorLink pl;
01775 ActorLink bl;
01781 Brancher* b_status;
01793 Brancher* b_commit;
01795 Brancher* brancher(unsigned int id);
01796
01798 void kill(Brancher& b);
01800 void kill(Propagator& p);
01801
01803 GECODE_KERNEL_EXPORT
01804 void kill_brancher(unsigned int id);
01805
01807 static const unsigned reserved_bid = 0U;
01808
01810 static const unsigned int sc_bits = 2;
01812 static const unsigned int sc_fast = 0;
01814 static const unsigned int sc_disabled = 1;
01816 static const unsigned int sc_trace = 2;
01817
01818 union {
01820 struct {
01833 ActorLink* active;
01835 ActorLink queue[PropCost::AC_MAX+1];
01842 unsigned int bid_sc;
01844 unsigned int n_sub;
01846 ViewTraceInfo vti;
01847 } p;
01849 struct {
01851 VarImpBase* vars_u[AllVarConf::idx_c];
01853 VarImpBase* vars_noidx;
01855 SharedHandle::Object* shared;
01857 LocalObject* local;
01858 } c;
01859 } pc;
01861 void enqueue(Propagator* p);
01866 #ifdef GECODE_HAS_VAR_DISPOSE
01867
01868 GECODE_KERNEL_EXPORT static VarImpDisposerBase* vd[AllVarConf::idx_d];
01870 VarImpBase* _vars_d[AllVarConf::idx_d];
01872 template<class VIC> VarImpBase* vars_d(void) const;
01874 template<class VIC> void vars_d(VarImpBase* x);
01875 #endif
01876
01877 void update(ActorLink** sub);
01879
01881 TraceRecorder* findtr(void);
01882
01884 Actor** d_fst;
01886 Actor** d_cur;
01888 Actor** d_lst;
01889
01891 GECODE_KERNEL_EXPORT static StatusStatistics unused_status;
01893 GECODE_KERNEL_EXPORT static CloneStatistics unused_clone;
01895 GECODE_KERNEL_EXPORT static CommitStatistics unused_commit;
01896
01918 GECODE_KERNEL_EXPORT Space* _clone(bool share_data=true,
01919 bool share_info=true);
01920
01953 GECODE_KERNEL_EXPORT
01954 void _commit(const Choice& c, unsigned int a);
01955
01986 GECODE_KERNEL_EXPORT
01987 void _trycommit(const Choice& c, unsigned int a);
01988
01995 GECODE_KERNEL_EXPORT
01996 void ap_notice_dispose(Actor* a, bool d);
02003 GECODE_KERNEL_EXPORT
02004 void ap_ignore_dispose(Actor* a, bool d);
02005
02006 public:
02011 GECODE_KERNEL_EXPORT
02012 Space(void);
02024 GECODE_KERNEL_EXPORT
02025 Space(bool share, Space& s);
02030 GECODE_KERNEL_EXPORT
02031 virtual ~Space(void);
02038 virtual Space* copy(bool share) = 0;
02049 GECODE_KERNEL_EXPORT virtual void constrain(const Space& best);
02073 GECODE_KERNEL_EXPORT
02074 virtual bool master(const MetaInfo& mi);
02100 GECODE_KERNEL_EXPORT
02101 virtual bool slave(const MetaInfo& mi);
02102
02103
02104
02105
02106
02107
02119 GECODE_KERNEL_EXPORT
02120 SpaceStatus status(StatusStatistics& stat=unused_status);
02121
02153 GECODE_KERNEL_EXPORT
02154 const Choice* choice(void);
02155
02165 GECODE_KERNEL_EXPORT
02166 const Choice* choice(Archive& e) const;
02167
02191 Space* clone(bool share_data=true,
02192 bool share_info=true,
02193 CloneStatistics& stat=unused_clone) const;
02194
02229 void commit(const Choice& c, unsigned int a,
02230 CommitStatistics& stat=unused_commit);
02263 void trycommit(const Choice& c, unsigned int a,
02264 CommitStatistics& stat=unused_commit);
02283 GECODE_KERNEL_EXPORT
02284 NGL* ngl(const Choice& c, unsigned int a);
02285
02300 GECODE_KERNEL_EXPORT
02301 void print(const Choice& c, unsigned int a, std::ostream& o) const;
02302
02311 GECODE_KERNEL_EXPORT
02312 void notice(Actor& a, ActorProperty p, bool duplicate=false);
02320 GECODE_KERNEL_EXPORT
02321 void ignore(Actor& a, ActorProperty p, bool duplicate=false);
02322
02323
02334 ExecStatus ES_SUBSUMED(Propagator& p);
02349 ExecStatus ES_SUBSUMED_DISPOSED(Propagator& p, size_t s);
02360 ExecStatus ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med);
02371 ExecStatus ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med);
02372
02383 template<class A>
02384 ExecStatus ES_FIX_DISPOSE(Council<A>& c, A& a);
02395 template<class A>
02396 ExecStatus ES_NOFIX_DISPOSE(Council<A>& c, A& a);
02408 template<class A>
02409 ExecStatus ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a);
02410
02418 void fail(void);
02427 bool failed(void) const;
02432 bool stable(void) const;
02433
02435
02436
02437 Home operator ()(Propagator& p);
02439 Home operator ()(PropagatorGroup pg);
02441 Home operator ()(BrancherGroup bg);
02443
02455 template<class T>
02456 T* alloc(long unsigned int n);
02463 template<class T>
02464 T* alloc(long int n);
02471 template<class T>
02472 T* alloc(unsigned int n);
02479 template<class T>
02480 T* alloc(int n);
02490 template<class T>
02491 void free(T* b, long unsigned int n);
02501 template<class T>
02502 void free(T* b, long int n);
02512 template<class T>
02513 void free(T* b, unsigned int n);
02523 template<class T>
02524 void free(T* b, int n);
02536 template<class T>
02537 T* realloc(T* b, long unsigned int n, long unsigned int m);
02549 template<class T>
02550 T* realloc(T* b, long int n, long int m);
02562 template<class T>
02563 T* realloc(T* b, unsigned int n, unsigned int m);
02575 template<class T>
02576 T* realloc(T* b, int n, int m);
02584 template<class T>
02585 T** realloc(T** b, long unsigned int n, long unsigned int m);
02593 template<class T>
02594 T** realloc(T** b, long int n, long int m);
02602 template<class T>
02603 T** realloc(T** b, unsigned int n, unsigned int m);
02611 template<class T>
02612 T** realloc(T** b, int n, int m);
02614 void* ralloc(size_t s);
02616 void rfree(void* p, size_t s);
02618 void* rrealloc(void* b, size_t n, size_t m);
02620 template<size_t> void* fl_alloc(void);
02626 template<size_t> void fl_dispose(FreeList* f, FreeList* l);
02635 GECODE_KERNEL_EXPORT void flush(void);
02637
02638
02639
02642 template<class T>
02643 T& construct(void);
02649 template<class T, typename A1>
02650 T& construct(A1 const& a1);
02656 template<class T, typename A1, typename A2>
02657 T& construct(A1 const& a1, A2 const& a2);
02663 template<class T, typename A1, typename A2, typename A3>
02664 T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
02670 template<class T, typename A1, typename A2, typename A3, typename A4>
02671 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
02677 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
02678 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
02680
02682
02683
02684 void afc_decay(double d);
02686 double afc_decay(void) const;
02688
02689 private:
02695 class Propagators {
02696 private:
02698 Space& home;
02700 ActorLink* q;
02702 ActorLink* c;
02704 ActorLink* e;
02705 public:
02707 Propagators(Space& home);
02709 bool operator ()(void) const;
02711 void operator ++(void);
02713 Propagator& propagator(void) const;
02714 };
02720 class ScheduledPropagators {
02721 private:
02723 Space& home;
02725 ActorLink* q;
02727 ActorLink* c;
02729 ActorLink* e;
02730 public:
02732 ScheduledPropagators(Space& home);
02734 bool operator ()(void) const;
02736 void operator ++(void);
02738 Propagator& propagator(void) const;
02739 };
02745 class IdlePropagators {
02746 private:
02748 ActorLink* c;
02750 ActorLink* e;
02751 public:
02753 IdlePropagators(Space& home);
02755 bool operator ()(void) const;
02757 void operator ++(void);
02759 Propagator& propagator(void) const;
02760 };
02766 class Branchers {
02767 private:
02769 ActorLink* c;
02771 ActorLink* e;
02772 public:
02774 Branchers(Space& home);
02776 bool operator ()(void) const;
02778 void operator ++(void);
02780 Brancher& brancher(void) const;
02781 };
02782 };
02783
02785 class Propagators {
02786 private:
02788 Space::Propagators ps;
02790 PropagatorGroup g;
02791 public:
02793 Propagators(Space& home, PropagatorGroup g);
02795 bool operator ()(void) const;
02797 void operator ++(void);
02799 const Propagator& propagator(void) const;
02800 };
02801
02803 class Branchers {
02804 private:
02806 Space::Branchers bs;
02808 BrancherGroup g;
02809 public:
02811 Branchers(Space& home, BrancherGroup g);
02813 bool operator ()(void) const;
02815 void operator ++(void);
02817 const Brancher& brancher(void) const;
02818 };
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829 forceinline void*
02830 Space::ralloc(size_t s) {
02831 return mm.alloc(sm,s);
02832 }
02833 forceinline void
02834 Space::rfree(void* p, size_t s) {
02835 return mm.reuse(p,s);
02836 }
02837 forceinline void*
02838 Space::rrealloc(void* _b, size_t n, size_t m) {
02839 char* b = static_cast<char*>(_b);
02840 if (n < m) {
02841 char* p = static_cast<char*>(ralloc(m));
02842 memcpy(p,b,n);
02843 rfree(b,n);
02844 return p;
02845 } else {
02846 rfree(b+m,m-n);
02847 return b;
02848 }
02849 }
02850
02851 template<size_t s>
02852 forceinline void*
02853 Space::fl_alloc(void) {
02854 return mm.template fl_alloc<s>(sm);
02855 }
02856 template<size_t s>
02857 forceinline void
02858 Space::fl_dispose(FreeList* f, FreeList* l) {
02859 mm.template fl_dispose<s>(f,l);
02860 }
02861
02862
02863
02864
02865
02866 template<class T>
02867 forceinline T*
02868 Space::alloc(long unsigned int n) {
02869 T* p = static_cast<T*>(ralloc(sizeof(T)*n));
02870 for (long unsigned int i=n; i--; )
02871 (void) new (p+i) T();
02872 return p;
02873 }
02874 template<class T>
02875 forceinline T*
02876 Space::alloc(long int n) {
02877 assert(n >= 0);
02878 return alloc<T>(static_cast<long unsigned int>(n));
02879 }
02880 template<class T>
02881 forceinline T*
02882 Space::alloc(unsigned int n) {
02883 return alloc<T>(static_cast<long unsigned int>(n));
02884 }
02885 template<class T>
02886 forceinline T*
02887 Space::alloc(int n) {
02888 assert(n >= 0);
02889 return alloc<T>(static_cast<long unsigned int>(n));
02890 }
02891
02892 template<class T>
02893 forceinline void
02894 Space::free(T* b, long unsigned int n) {
02895 for (long unsigned int i=n; i--; )
02896 b[i].~T();
02897 rfree(b,n*sizeof(T));
02898 }
02899 template<class T>
02900 forceinline void
02901 Space::free(T* b, long int n) {
02902 assert(n >= 0);
02903 free<T>(b,static_cast<long unsigned int>(n));
02904 }
02905 template<class T>
02906 forceinline void
02907 Space::free(T* b, unsigned int n) {
02908 free<T>(b,static_cast<long unsigned int>(n));
02909 }
02910 template<class T>
02911 forceinline void
02912 Space::free(T* b, int n) {
02913 assert(n >= 0);
02914 free<T>(b,static_cast<long unsigned int>(n));
02915 }
02916
02917 template<class T>
02918 forceinline T*
02919 Space::realloc(T* b, long unsigned int n, long unsigned int m) {
02920 if (n < m) {
02921 T* p = static_cast<T*>(ralloc(sizeof(T)*m));
02922 for (long unsigned int i=n; i--; )
02923 (void) new (p+i) T(b[i]);
02924 for (long unsigned int i=n; i<m; i++)
02925 (void) new (p+i) T();
02926 free<T>(b,n);
02927 return p;
02928 } else {
02929 free<T>(b+m,m-n);
02930 return b;
02931 }
02932 }
02933 template<class T>
02934 forceinline T*
02935 Space::realloc(T* b, long int n, long int m) {
02936 assert((n >= 0) && (m >= 0));
02937 return realloc<T>(b,static_cast<long unsigned int>(n),
02938 static_cast<long unsigned int>(m));
02939 }
02940 template<class T>
02941 forceinline T*
02942 Space::realloc(T* b, unsigned int n, unsigned int m) {
02943 return realloc<T>(b,static_cast<long unsigned int>(n),
02944 static_cast<long unsigned int>(m));
02945 }
02946 template<class T>
02947 forceinline T*
02948 Space::realloc(T* b, int n, int m) {
02949 assert((n >= 0) && (m >= 0));
02950 return realloc<T>(b,static_cast<long unsigned int>(n),
02951 static_cast<long unsigned int>(m));
02952 }
02953
02954 #define GECODE_KERNEL_REALLOC(T) \
02955 template<> \
02956 forceinline T* \
02957 Space::realloc<T>(T* b, long unsigned int n, long unsigned int m) { \
02958 return static_cast<T*>(rrealloc(b,n*sizeof(T),m*sizeof(T))); \
02959 } \
02960 template<> \
02961 forceinline T* \
02962 Space::realloc<T>(T* b, long int n, long int m) { \
02963 assert((n >= 0) && (m >= 0)); \
02964 return realloc<T>(b,static_cast<long unsigned int>(n), \
02965 static_cast<long unsigned int>(m)); \
02966 } \
02967 template<> \
02968 forceinline T* \
02969 Space::realloc<T>(T* b, unsigned int n, unsigned int m) { \
02970 return realloc<T>(b,static_cast<long unsigned int>(n), \
02971 static_cast<long unsigned int>(m)); \
02972 } \
02973 template<> \
02974 forceinline T* \
02975 Space::realloc<T>(T* b, int n, int m) { \
02976 assert((n >= 0) && (m >= 0)); \
02977 return realloc<T>(b,static_cast<long unsigned int>(n), \
02978 static_cast<long unsigned int>(m)); \
02979 }
02980
02981 GECODE_KERNEL_REALLOC(bool)
02982 GECODE_KERNEL_REALLOC(signed char)
02983 GECODE_KERNEL_REALLOC(unsigned char)
02984 GECODE_KERNEL_REALLOC(signed short int)
02985 GECODE_KERNEL_REALLOC(unsigned short int)
02986 GECODE_KERNEL_REALLOC(signed int)
02987 GECODE_KERNEL_REALLOC(unsigned int)
02988 GECODE_KERNEL_REALLOC(signed long int)
02989 GECODE_KERNEL_REALLOC(unsigned long int)
02990 GECODE_KERNEL_REALLOC(float)
02991 GECODE_KERNEL_REALLOC(double)
02992
02993 #undef GECODE_KERNEL_REALLOC
02994
02995 template<class T>
02996 forceinline T**
02997 Space::realloc(T** b, long unsigned int n, long unsigned int m) {
02998 return static_cast<T**>(rrealloc(b,n*sizeof(T),m*sizeof(T*)));
02999 }
03000 template<class T>
03001 forceinline T**
03002 Space::realloc(T** b, long int n, long int m) {
03003 assert((n >= 0) && (m >= 0));
03004 return realloc<T*>(b,static_cast<long unsigned int>(n),
03005 static_cast<long unsigned int>(m));
03006 }
03007 template<class T>
03008 forceinline T**
03009 Space::realloc(T** b, unsigned int n, unsigned int m) {
03010 return realloc<T*>(b,static_cast<long unsigned int>(n),
03011 static_cast<long unsigned int>(m));
03012 }
03013 template<class T>
03014 forceinline T**
03015 Space::realloc(T** b, int n, int m) {
03016 assert((n >= 0) && (m >= 0));
03017 return realloc<T*>(b,static_cast<long unsigned int>(n),
03018 static_cast<long unsigned int>(m));
03019 }
03020
03021
03022 #ifdef GECODE_HAS_VAR_DISPOSE
03023 template<class VIC>
03024 forceinline VarImpBase*
03025 Space::vars_d(void) const {
03026 return _vars_d[VIC::idx_d];
03027 }
03028 template<class VIC>
03029 forceinline void
03030 Space::vars_d(VarImpBase* x) {
03031 _vars_d[VIC::idx_d] = x;
03032 }
03033 #endif
03034
03035
03036 forceinline void
03037 Actor::operator delete(void*) {}
03038 forceinline void
03039 Actor::operator delete(void*, Space&) {}
03040 forceinline void*
03041 Actor::operator new(size_t s, Space& home) {
03042 return home.ralloc(s);
03043 }
03044
03045 template<class VIC>
03046 forceinline void
03047 VarImp<VIC>::operator delete(void*) {}
03048 template<class VIC>
03049 forceinline void
03050 VarImp<VIC>::operator delete(void*, Space&) {}
03051 template<class VIC>
03052 forceinline void*
03053 VarImp<VIC>::operator new(size_t s, Space& home) {
03054 return home.ralloc(s);
03055 }
03056
03057 #ifndef __GNUC__
03058 forceinline void
03059 Advisor::operator delete(void*) {}
03060 #endif
03061 forceinline void
03062 Advisor::operator delete(void*, Space&) {}
03063 forceinline void*
03064 Advisor::operator new(size_t s, Space& home) {
03065 return home.ralloc(s);
03066 }
03067
03068 forceinline void
03069 NGL::operator delete(void*) {}
03070 forceinline void
03071 NGL::operator delete(void*, Space&) {}
03072 forceinline void*
03073 NGL::operator new(size_t s, Space& home) {
03074 return home.ralloc(s);
03075 }
03076
03077
03078
03079
03080
03081 forceinline
03082 SharedHandle::Object::Object(void)
03083 : next(NULL), fwd(NULL), use_cnt(0) {}
03084 forceinline
03085 SharedHandle::Object::~Object(void) {
03086 assert(use_cnt == 0);
03087 }
03088
03089 forceinline SharedHandle::Object*
03090 SharedHandle::object(void) const {
03091 return o;
03092 }
03093 forceinline void
03094 SharedHandle::subscribe(void) {
03095 if (o != NULL) o->use_cnt++;
03096 }
03097 forceinline void
03098 SharedHandle::cancel(void) {
03099 if ((o != NULL) && (--o->use_cnt == 0))
03100 delete o;
03101 o=NULL;
03102 }
03103 forceinline void
03104 SharedHandle::object(SharedHandle::Object* n) {
03105 if (n != o) {
03106 cancel(); o=n; subscribe();
03107 }
03108 }
03109 forceinline
03110 SharedHandle::SharedHandle(void) : o(NULL) {}
03111 forceinline
03112 SharedHandle::SharedHandle(SharedHandle::Object* so) : o(so) {
03113 subscribe();
03114 }
03115 forceinline
03116 SharedHandle::SharedHandle(const SharedHandle& sh) : o(sh.o) {
03117 subscribe();
03118 }
03119 forceinline SharedHandle&
03120 SharedHandle::operator =(const SharedHandle& sh) {
03121 if (&sh != this) {
03122 cancel(); o=sh.o; subscribe();
03123 }
03124 return *this;
03125 }
03126 forceinline void
03127 SharedHandle::update(Space& home, bool share, SharedHandle& sh) {
03128 if (sh.o == NULL) {
03129 o=NULL; return;
03130 } else if (share) {
03131 o=sh.o;
03132 } else if (sh.o->fwd != NULL) {
03133 o=sh.o->fwd;
03134 } else {
03135 o = sh.o->copy();
03136 sh.o->fwd = o;
03137 sh.o->next = home.pc.c.shared;
03138 home.pc.c.shared = sh.o;
03139 }
03140 subscribe();
03141 }
03142 forceinline
03143 SharedHandle::~SharedHandle(void) {
03144 cancel();
03145 }
03146
03147
03148
03149
03150
03151
03152
03153 forceinline
03154 NoGoods::NoGoods(void)
03155 : n(0) {}
03156 forceinline unsigned long int
03157 NoGoods::ng(void) const {
03158 return n;
03159 }
03160 forceinline void
03161 NoGoods::ng(unsigned long int n0) {
03162 n=n0;
03163 }
03164 forceinline
03165 NoGoods::~NoGoods(void) {}
03166
03167
03168
03169
03170
03171 forceinline
03172 MetaInfo::MetaInfo(unsigned long int r0,
03173 unsigned long int s0,
03174 unsigned long int f0,
03175 const Space* l0,
03176 NoGoods& ng0)
03177 : t(RESTART), r(r0), s(s0), f(f0), l(l0), ng(ng0), a(0) {}
03178
03179 forceinline
03180 MetaInfo::MetaInfo(unsigned int a0)
03181 : t(PORTFOLIO), r(0), s(0), f(0), l(NULL), ng(NoGoods::eng), a(a0) {}
03182
03183 forceinline MetaInfo::Type
03184 MetaInfo::type(void) const {
03185 return t;
03186 }
03187 forceinline unsigned long int
03188 MetaInfo::restart(void) const {
03189 assert(type() == RESTART);
03190 return r;
03191 }
03192 forceinline unsigned long int
03193 MetaInfo::solution(void) const {
03194 assert(type() == RESTART);
03195 return s;
03196 }
03197 forceinline unsigned long int
03198 MetaInfo::fail(void) const {
03199 assert(type() == RESTART);
03200 return f;
03201 }
03202 forceinline const Space*
03203 MetaInfo::last(void) const {
03204 assert(type() == RESTART);
03205 return l;
03206 }
03207 forceinline const NoGoods&
03208 MetaInfo::nogoods(void) const {
03209 assert(type() == RESTART);
03210 return ng;
03211 }
03212 forceinline unsigned int
03213 MetaInfo::asset(void) const {
03214 assert(type() == PORTFOLIO);
03215 return a;
03216 }
03217
03218
03219
03220
03221
03222
03223
03224 forceinline ActorLink*
03225 ActorLink::prev(void) const {
03226 return _prev;
03227 }
03228
03229 forceinline ActorLink*
03230 ActorLink::next(void) const {
03231 return _next;
03232 }
03233
03234 forceinline ActorLink**
03235 ActorLink::next_ref(void) {
03236 return &_next;
03237 }
03238
03239 forceinline void
03240 ActorLink::prev(ActorLink* al) {
03241 _prev = al;
03242 }
03243
03244 forceinline void
03245 ActorLink::next(ActorLink* al) {
03246 _next = al;
03247 }
03248
03249 forceinline void
03250 ActorLink::unlink(void) {
03251 ActorLink* p = _prev; ActorLink* n = _next;
03252 p->_next = n; n->_prev = p;
03253 }
03254
03255 forceinline void
03256 ActorLink::init(void) {
03257 _next = this; _prev =this;
03258 }
03259
03260 forceinline void
03261 ActorLink::head(ActorLink* a) {
03262
03263 ActorLink* n = _next;
03264 this->_next = a; a->_prev = this;
03265 a->_next = n; n->_prev = a;
03266 }
03267
03268 forceinline void
03269 ActorLink::tail(ActorLink* a) {
03270
03271 ActorLink* p = _prev;
03272 a->_next = this; this->_prev = a;
03273 p->_next = a; a->_prev = p;
03274 }
03275
03276 forceinline bool
03277 ActorLink::empty(void) const {
03278 return _next == this;
03279 }
03280
03281 template<class T>
03282 forceinline ActorLink*
03283 ActorLink::cast(T* a) {
03284
03285 GECODE_NOT_NULL(a);
03286 ActorLink& t = *a;
03287 return static_cast<ActorLink*>(&t);
03288 }
03289
03290 template<class T>
03291 forceinline const ActorLink*
03292 ActorLink::cast(const T* a) {
03293
03294 GECODE_NOT_NULL(a);
03295 const ActorLink& t = *a;
03296 return static_cast<const ActorLink*>(&t);
03297 }
03298
03299
03300
03301
03302
03303
03304 forceinline Actor*
03305 Actor::cast(ActorLink* al) {
03306
03307 GECODE_NOT_NULL(al);
03308 ActorLink& t = *al;
03309 return static_cast<Actor*>(&t);
03310 }
03311
03312 forceinline const Actor*
03313 Actor::cast(const ActorLink* al) {
03314
03315 GECODE_NOT_NULL(al);
03316 const ActorLink& t = *al;
03317 return static_cast<const Actor*>(&t);
03318 }
03319
03320 forceinline void
03321 Home::notice(Actor& a, ActorProperty p, bool duplicate) {
03322 s.notice(a,p,duplicate);
03323 }
03324
03325 forceinline Space*
03326 Space::clone(bool share_data, bool share_info, CloneStatistics&) const {
03327
03328
03329
03330 return const_cast<Space*>(this)->_clone(share_data,share_info);
03331 }
03332
03333 forceinline void
03334 Space::commit(const Choice& c, unsigned int a, CommitStatistics&) {
03335 _commit(c,a);
03336 }
03337
03338 forceinline void
03339 Space::trycommit(const Choice& c, unsigned int a, CommitStatistics&) {
03340 _trycommit(c,a);
03341 }
03342
03343 forceinline double
03344 Space::afc_decay(void) const {
03345 return gpi.decay();
03346 }
03347
03348 forceinline void
03349 Space::afc_decay(double d) {
03350 gpi.decay(d);
03351 }
03352
03353 forceinline size_t
03354 Actor::dispose(Space&) {
03355 return sizeof(*this);
03356 }
03357
03358
03359
03360
03361
03362
03363 forceinline
03364 Home::Home(Space& s0, Propagator* p0,
03365 PropagatorGroup pg0, BrancherGroup bg0)
03366 : s(s0), p(p0), pg(pg0), bg(bg0) {}
03367 forceinline Home&
03368 Home::operator =(const Home& h) {
03369 s=h.s; p=h.p; pg=h.pg; bg=h.bg;
03370 return *this;
03371 }
03372 forceinline
03373 Home::operator Space&(void) {
03374 return s;
03375 }
03376 forceinline Home
03377 Home::operator ()(Propagator& p) {
03378 return Home(s,&p);
03379 }
03380 forceinline Home
03381 Home::operator ()(PropagatorGroup pg) {
03382 return Home(s,NULL,pg,BrancherGroup::def);
03383 }
03384 forceinline Home
03385 Home::operator ()(BrancherGroup bg) {
03386 return Home(s,NULL,PropagatorGroup::def,bg);
03387 }
03388 forceinline Home
03389 Space::operator ()(Propagator& p) {
03390 return Home(*this,&p);
03391 }
03392 forceinline Propagator*
03393 Home::propagator(void) const {
03394 return p;
03395 }
03396 forceinline PropagatorGroup
03397 Home::propagatorgroup(void) const {
03398 return pg;
03399 }
03400 forceinline BrancherGroup
03401 Home::branchergroup(void) const {
03402 return bg;
03403 }
03404
03405
03406
03407
03408
03409 forceinline void
03410 ViewTraceInfo::propagator(Propagator& p) {
03411 who = reinterpret_cast<ptrdiff_t>(&p) | PROPAGATOR;
03412 }
03413 forceinline void
03414 ViewTraceInfo::brancher(Brancher& b) {
03415 who = reinterpret_cast<ptrdiff_t>(&b) | BRANCHER;
03416 }
03417 forceinline void
03418 ViewTraceInfo::post(PropagatorGroup g) {
03419 who = (g.id() << 2) | POST;
03420 }
03421 forceinline void
03422 ViewTraceInfo::other(void) {
03423 who = OTHER;
03424 }
03425 forceinline ViewTraceInfo::What
03426 ViewTraceInfo::what(void) const {
03427 return static_cast<What>(who & 3);
03428 }
03429 forceinline const Propagator&
03430 ViewTraceInfo::propagator(void) const {
03431 assert(what() == PROPAGATOR);
03432
03433 return *reinterpret_cast<Propagator*>(who);
03434 }
03435 forceinline const Brancher&
03436 ViewTraceInfo::brancher(void) const {
03437 assert(what() == BRANCHER);
03438 return *reinterpret_cast<Brancher*>(who & ~3);
03439 }
03440 forceinline PropagatorGroup
03441 ViewTraceInfo::post(void) const {
03442 assert(what() == POST);
03443 return PropagatorGroup(static_cast<unsigned int>(who >> 2));
03444 }
03445
03446
03447
03448
03449 forceinline
03450 PostInfo::PostInfo(Home home) : h(home) {
03451 h.pc.p.vti.post(home.propagatorgroup());
03452 }
03453 forceinline
03454 PostInfo::~PostInfo(void) {
03455 h.pc.p.vti.other();
03456 }
03457
03458
03459
03460
03461
03462 forceinline
03463 PropagateTraceInfo::PropagateTraceInfo(unsigned int i0, PropagatorGroup g0,
03464 const Propagator* p0, Status s0)
03465 : i(i0), g(g0), p(p0), s(s0) {}
03466 forceinline unsigned int
03467 PropagateTraceInfo::id(void) const {
03468 return i;
03469 }
03470 forceinline PropagatorGroup
03471 PropagateTraceInfo::group(void) const {
03472 return g;
03473 }
03474 forceinline const Propagator*
03475 PropagateTraceInfo::propagator(void) const {
03476 return p;
03477 }
03478 forceinline PropagateTraceInfo::Status
03479 PropagateTraceInfo::status(void) const {
03480 return s;
03481 }
03482
03483
03484
03485
03486
03487
03488 forceinline
03489 CommitTraceInfo::CommitTraceInfo(const Brancher& b0, const Choice& c0,
03490 unsigned int a0)
03491 : b(b0), c(c0), a(a0) {}
03492 forceinline unsigned int
03493 CommitTraceInfo::id(void) const {
03494 return b.id();
03495 }
03496 forceinline BrancherGroup
03497 CommitTraceInfo::group(void) const {
03498 return b.group();
03499 }
03500 forceinline const Brancher&
03501 CommitTraceInfo::brancher(void) const {
03502 return b;
03503 }
03504 forceinline const Choice&
03505 CommitTraceInfo::choice(void) const {
03506 return c;
03507 }
03508 forceinline unsigned int
03509 CommitTraceInfo::alternative(void) const {
03510 return a;
03511 }
03512
03513
03514
03515
03516
03517
03518 forceinline Propagator*
03519 Propagator::cast(ActorLink* al) {
03520
03521 GECODE_NOT_NULL(al);
03522 ActorLink& t = *al;
03523 return static_cast<Propagator*>(&t);
03524 }
03525
03526 forceinline const Propagator*
03527 Propagator::cast(const ActorLink* al) {
03528
03529 GECODE_NOT_NULL(al);
03530 const ActorLink& t = *al;
03531 return static_cast<const Propagator*>(&t);
03532 }
03533
03534 forceinline Propagator*
03535 Propagator::fwd(void) const {
03536 return static_cast<Propagator*>(prev());
03537 }
03538
03539 forceinline bool
03540 Propagator::disabled(void) const {
03541 return Support::marked(gpi_disabled);
03542 }
03543
03544 forceinline void
03545 Propagator::disable(Space& home) {
03546 home.pc.p.bid_sc |= Space::sc_disabled;
03547 gpi_disabled = Support::fmark(gpi_disabled);
03548 }
03549
03550 forceinline void
03551 Propagator::enable(Space& home) {
03552 (void) home;
03553 gpi_disabled = Support::funmark(gpi_disabled);
03554 }
03555
03556 forceinline GPI::Info&
03557 Propagator::gpi(void) {
03558 return *static_cast<GPI::Info*>(Support::funmark(gpi_disabled));
03559 }
03560
03561 forceinline
03562 Propagator::Propagator(Home home)
03563 : gpi_disabled((home.propagator() != NULL) ?
03564
03565 home.propagator()->gpi_disabled :
03566
03567 static_cast<Space&>(home).gpi.allocate(home.propagatorgroup().gid)) {
03568 u.advisors = NULL;
03569 assert((u.med == 0) && (u.size == 0));
03570 static_cast<Space&>(home).pl.head(this);
03571 }
03572
03573 forceinline
03574 Propagator::Propagator(Space&, bool, Propagator& p)
03575 : gpi_disabled(p.gpi_disabled) {
03576 u.advisors = NULL;
03577 assert((u.med == 0) && (u.size == 0));
03578
03579 p.prev(this);
03580 }
03581
03582 forceinline ModEventDelta
03583 Propagator::modeventdelta(void) const {
03584 return u.med;
03585 }
03586
03587 forceinline double
03588 Propagator::afc(void) const {
03589 return const_cast<Propagator&>(*this).gpi().afc;
03590 }
03591
03592 forceinline unsigned int
03593 Propagator::id(void) const {
03594 return const_cast<Propagator&>(*this).gpi().pid;
03595 }
03596
03597 forceinline PropagatorGroup
03598 Propagator::group(void) const {
03599 return PropagatorGroup(const_cast<Propagator&>(*this).gpi().gid);
03600 }
03601
03602 forceinline void
03603 Propagator::group(PropagatorGroup g) {
03604 gpi().gid = g.id();
03605 }
03606
03607 forceinline ExecStatus
03608 Space::ES_SUBSUMED_DISPOSED(Propagator& p, size_t s) {
03609 p.u.size = s;
03610 return __ES_SUBSUMED;
03611 }
03612
03613 forceinline ExecStatus
03614 Space::ES_SUBSUMED(Propagator& p) {
03615 p.u.size = p.dispose(*this);
03616 return __ES_SUBSUMED;
03617 }
03618
03619 forceinline ExecStatus
03620 Space::ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
03621 p.u.med = med;
03622 assert(p.u.med != 0);
03623 return __ES_PARTIAL;
03624 }
03625
03626 forceinline ExecStatus
03627 Space::ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
03628 p.u.med = AllVarConf::med_combine(p.u.med,med);
03629 assert(p.u.med != 0);
03630 return __ES_PARTIAL;
03631 }
03632
03633
03634
03635
03636
03637
03638
03639 forceinline Brancher*
03640 Brancher::cast(ActorLink* al) {
03641
03642 GECODE_NOT_NULL(al);
03643 ActorLink& t = *al;
03644 return static_cast<Brancher*>(&t);
03645 }
03646
03647 forceinline const Brancher*
03648 Brancher::cast(const ActorLink* al) {
03649
03650 GECODE_NOT_NULL(al);
03651 const ActorLink& t = *al;
03652 return static_cast<const Brancher*>(&t);
03653 }
03654
03655 forceinline
03656 Brancher::Brancher(Home _home) :
03657 gid(_home.branchergroup().gid) {
03658 Space& home = static_cast<Space&>(_home);
03659 bid = home.pc.p.bid_sc >> Space::sc_bits;
03660 home.pc.p.bid_sc += (1 << Space::sc_bits);
03661 if ((home.pc.p.bid_sc >> Space::sc_bits) == 0U)
03662 throw TooManyBranchers("Brancher::Brancher");
03663
03664 if (home.b_status == &static_cast<Space&>(home).bl) {
03665 home.b_status = this;
03666 if (home.b_commit == &static_cast<Space&>(home).bl)
03667 home.b_commit = this;
03668 }
03669 home.bl.tail(this);
03670 }
03671
03672 forceinline
03673 Brancher::Brancher(Space&, bool, Brancher& b)
03674 : bid(b.bid), gid(b.gid) {
03675
03676 b.prev(this);
03677 }
03678
03679 forceinline unsigned int
03680 Brancher::id(void) const {
03681 return bid;
03682 }
03683
03684 forceinline BrancherGroup
03685 Brancher::group(void) const {
03686 return BrancherGroup(gid);
03687 }
03688
03689 forceinline void
03690 Brancher::group(BrancherGroup g) {
03691 gid = g.id();
03692 }
03693
03694
03695 forceinline void
03696 Space::kill(Brancher& b) {
03697 assert(!failed());
03698
03699 if (b_commit == &b)
03700 b_commit = Brancher::cast(b.next());
03701 if (b_status == &b)
03702 b_status = Brancher::cast(b.next());
03703 b.unlink();
03704 rfree(&b,b.dispose(*this));
03705 }
03706
03707 forceinline void
03708 Space::kill(Propagator& p) {
03709 assert(!failed());
03710 p.unlink();
03711 rfree(&p,p.dispose(*this));
03712 }
03713
03714 forceinline Brancher*
03715 Space::brancher(unsigned int id) {
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730 Brancher* b_old = b_commit;
03731
03732 while (b_commit != Brancher::cast(&bl))
03733 if (id != b_commit->id())
03734 b_commit = Brancher::cast(b_commit->next());
03735 else
03736 return b_commit;
03737 if (b_commit == Brancher::cast(&bl)) {
03738
03739 b_commit = Brancher::cast(bl.next());
03740 while (b_commit != b_old)
03741 if (id != b_commit->id())
03742 b_commit = Brancher::cast(b_commit->next());
03743 else
03744 return b_commit;
03745 }
03746 return NULL;
03747 }
03748
03749
03750
03751
03752
03753
03754
03755 forceinline LocalObject*
03756 LocalObject::cast(ActorLink* al) {
03757
03758 GECODE_NOT_NULL(al);
03759 ActorLink& t = *al;
03760 return static_cast<LocalObject*>(&t);
03761 }
03762
03763 forceinline const LocalObject*
03764 LocalObject::cast(const ActorLink* al) {
03765
03766 GECODE_NOT_NULL(al);
03767 const ActorLink& t = *al;
03768 return static_cast<const LocalObject*>(&t);
03769 }
03770
03771 forceinline
03772 LocalObject::LocalObject(Home home) {
03773 (void) home;
03774 ActorLink::cast(this)->prev(NULL);
03775 }
03776
03777 forceinline
03778 LocalObject::LocalObject(Space&,bool,LocalObject&) {
03779 ActorLink::cast(this)->prev(NULL);
03780 }
03781
03782 forceinline LocalObject*
03783 LocalObject::fwd(Space& home, bool share) {
03784 if (prev() == NULL)
03785 fwdcopy(home,share);
03786 return LocalObject::cast(prev());
03787 }
03788
03789 forceinline
03790 LocalHandle::LocalHandle(void) : o(NULL) {}
03791 forceinline
03792 LocalHandle::LocalHandle(LocalObject* lo) : o(lo) {}
03793 forceinline
03794 LocalHandle::LocalHandle(const LocalHandle& lh) : o(lh.o) {}
03795 forceinline LocalHandle&
03796 LocalHandle::operator =(const LocalHandle& lh) {
03797 o = lh.o;
03798 return *this;
03799 }
03800 forceinline
03801 LocalHandle::~LocalHandle(void) {}
03802 forceinline LocalObject*
03803 LocalHandle::object(void) const { return o; }
03804 forceinline void
03805 LocalHandle::object(LocalObject* n) { o = n; }
03806 forceinline void
03807 LocalHandle::update(Space& home, bool share, LocalHandle& lh) {
03808 object(lh.object()->fwd(home,share));
03809 }
03810
03811
03812
03813
03814
03815
03816 forceinline
03817 Choice::Choice(const Brancher& b, const unsigned int a)
03818 : bid(b.id()), alt(a) {}
03819
03820 forceinline unsigned int
03821 Choice::alternatives(void) const {
03822 return alt;
03823 }
03824
03825 forceinline unsigned int
03826 Choice::id(void) const {
03827 return bid;
03828 }
03829
03830 forceinline
03831 Choice::~Choice(void) {}
03832
03833
03834
03835
03836
03837
03838
03839 forceinline bool
03840 NGL::leaf(void) const {
03841 return Support::marked(nl);
03842 }
03843 forceinline NGL*
03844 NGL::next(void) const {
03845 return static_cast<NGL*>(Support::funmark(nl));
03846 }
03847 forceinline void
03848 NGL::leaf(bool l) {
03849 nl = l ? Support::fmark(nl) : Support::funmark(nl);
03850 }
03851 forceinline void
03852 NGL::next(NGL* n) {
03853 nl = Support::marked(nl) ? Support::mark(n) : n;
03854 }
03855 forceinline NGL*
03856 NGL::add(NGL* n, bool l) {
03857 nl = Support::marked(nl) ? Support::mark(n) : n;
03858 n->leaf(l);
03859 return n;
03860 }
03861
03862 forceinline
03863 NGL::NGL(void)
03864 : nl(NULL) {}
03865 forceinline
03866 NGL::NGL(Space&)
03867 : nl(NULL) {}
03868 forceinline
03869 NGL::NGL(Space&, bool, NGL&)
03870 : nl(NULL) {}
03871 forceinline size_t
03872 NGL::dispose(Space&) {
03873 return sizeof(*this);
03874 }
03875
03876
03877
03878
03879
03880 template<class A>
03881 forceinline
03882 Advisor::Advisor(Space&, Propagator& p, Council<A>& c) {
03883
03884 ActorLink::prev(&p);
03885
03886 ActorLink::next(c.advisors); c.advisors = static_cast<A*>(this);
03887 }
03888
03889 forceinline
03890 Advisor::Advisor(Space&, bool, Advisor&) {}
03891
03892 forceinline bool
03893 Advisor::disposed(void) const {
03894 return prev() == NULL;
03895 }
03896
03897 forceinline Advisor*
03898 Advisor::cast(ActorLink* al) {
03899 return static_cast<Advisor*>(al);
03900 }
03901
03902 forceinline const Advisor*
03903 Advisor::cast(const ActorLink* al) {
03904 return static_cast<const Advisor*>(al);
03905 }
03906
03907 forceinline Propagator&
03908 Advisor::propagator(void) const {
03909 assert(!disposed());
03910 return *Propagator::cast(ActorLink::prev());
03911 }
03912
03913 template<class A>
03914 forceinline void
03915 Advisor::dispose(Space&,Council<A>&) {
03916 assert(!disposed());
03917 ActorLink::prev(NULL);
03918
03919 Advisor* n = Advisor::cast(next());
03920 if ((n != NULL) && n->disposed())
03921 next(n->next());
03922 }
03923
03924 forceinline const ViewTraceInfo&
03925 Advisor::operator ()(const Space& home) const {
03926 return home.pc.p.vti;
03927 }
03928
03929 template<class A>
03930 forceinline ExecStatus
03931 Space::ES_FIX_DISPOSE(Council<A>& c, A& a) {
03932 a.dispose(*this,c);
03933 return ES_FIX;
03934 }
03935
03936 template<class A>
03937 forceinline ExecStatus
03938 Space::ES_NOFIX_DISPOSE(Council<A>& c, A& a) {
03939 a.dispose(*this,c);
03940 return ES_NOFIX;
03941 }
03942
03943 template<class A>
03944 forceinline ExecStatus
03945 Space::ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a) {
03946 a.dispose(*this,c);
03947 return ES_NOFIX_FORCE;
03948 }
03949
03950
03951
03952
03953
03954
03955
03956 template<class A>
03957 forceinline
03958 Council<A>::Council(void) {}
03959
03960 template<class A>
03961 forceinline
03962 Council<A>::Council(Space&)
03963 : advisors(NULL) {}
03964
03965 template<class A>
03966 forceinline bool
03967 Council<A>::empty(void) const {
03968 ActorLink* a = advisors;
03969 while ((a != NULL) && static_cast<A*>(a)->disposed())
03970 a = a->next();
03971 advisors = a;
03972 return a == NULL;
03973 }
03974
03975 template<class A>
03976 forceinline void
03977 Council<A>::update(Space& home, bool share, Council<A>& c) {
03978
03979 {
03980 ActorLink* a = c.advisors;
03981 while ((a != NULL) && static_cast<A*>(a)->disposed())
03982 a = a->next();
03983 c.advisors = a;
03984 }
03985
03986 if (c.advisors != NULL) {
03987
03988 Propagator* p_f = &static_cast<A*>(c.advisors)->propagator();
03989
03990 Propagator* p_t = Propagator::cast(p_f->prev());
03991
03992 ActorLink** a_f = &c.advisors;
03993
03994 A* a_t = NULL;
03995 while (*a_f != NULL) {
03996 if (static_cast<A*>(*a_f)->disposed()) {
03997 *a_f = (*a_f)->next();
03998 } else {
03999
04000 A* a = new (home) A(home,share,*static_cast<A*>(*a_f));
04001
04002 a->prev(p_t);
04003
04004 (*a_f)->prev(a);
04005
04006 a->next(a_t);
04007 a_t = a;
04008 a_f = (*a_f)->next_ref();
04009 }
04010 }
04011 advisors = a_t;
04012
04013 assert(p_f->u.advisors == NULL);
04014 p_f->u.advisors = c.advisors;
04015 } else {
04016 advisors = NULL;
04017 }
04018 }
04019
04020 template<class A>
04021 forceinline void
04022 Council<A>::dispose(Space& home) {
04023 ActorLink* a = advisors;
04024 while (a != NULL) {
04025 if (!static_cast<A*>(a)->disposed())
04026 static_cast<A*>(a)->dispose(home,*this);
04027 a = a->next();
04028 }
04029 }
04030
04031
04032
04033
04034
04035
04036
04037 template<class A>
04038 forceinline
04039 Advisors<A>::Advisors(const Council<A>& c)
04040 : a(c.advisors) {
04041 while ((a != NULL) && static_cast<A*>(a)->disposed())
04042 a = a->next();
04043 }
04044
04045 template<class A>
04046 forceinline bool
04047 Advisors<A>::operator ()(void) const {
04048 return a != NULL;
04049 }
04050
04051 template<class A>
04052 forceinline void
04053 Advisors<A>::operator ++(void) {
04054 do {
04055 a = a->next();
04056 } while ((a != NULL) && static_cast<A*>(a)->disposed());
04057 }
04058
04059 template<class A>
04060 forceinline A&
04061 Advisors<A>::advisor(void) const {
04062 return *static_cast<A*>(a);
04063 }
04064
04065
04066
04067
04068
04069
04070
04071 forceinline void
04072 Space::enqueue(Propagator* p) {
04073 ActorLink::cast(p)->unlink();
04074 ActorLink* c = &pc.p.queue[p->cost(*this,p->u.med).ac];
04075 c->tail(ActorLink::cast(p));
04076 if (c > pc.p.active)
04077 pc.p.active = c;
04078 }
04079
04080 forceinline void
04081 Space::fail(void) {
04082
04083
04084
04085
04086
04087 pc.p.active = &pc.p.queue[PropCost::AC_MAX+1]+1;
04088 }
04089 forceinline void
04090 Home::fail(void) {
04091 s.fail();
04092 }
04093
04094 forceinline bool
04095 Space::failed(void) const {
04096 return pc.p.active > &pc.p.queue[PropCost::AC_MAX+1];
04097 }
04098 forceinline bool
04099 Home::failed(void) const {
04100 return s.failed();
04101 }
04102
04103 forceinline bool
04104 Space::stable(void) const {
04105 return ((pc.p.active < &pc.p.queue[0]) ||
04106 (pc.p.active > &pc.p.queue[PropCost::AC_MAX+1]));
04107 }
04108
04109 forceinline TraceRecorder*
04110 Space::findtr(void) {
04111 TraceRecorder* tr = NULL;
04112 for (Actor** a=d_fst; a<d_cur; a++)
04113 if (Support::marked(*a) &&
04114 !static_cast<Propagator*>(Support::unmark(*a))->disabled()) {
04115 tr = static_cast<TraceRecorder*>(Support::unmark(*a));
04116 std::swap(*d_fst,*a);
04117 break;
04118 }
04119 return tr;
04120 }
04121
04122 forceinline void
04123 Space::notice(Actor& a, ActorProperty p, bool d) {
04124 if (p & AP_DISPOSE) {
04125 ap_notice_dispose(&a,d);
04126 }
04127 if (p & AP_VIEW_TRACE) {
04128 pc.p.bid_sc |= sc_trace;
04129 }
04130 if (p & AP_TRACE) {
04131 pc.p.bid_sc |= sc_trace;
04132 if (findtr())
04133 throw MoreThanOneTracer("Space::notice");
04134 ap_notice_dispose(static_cast<Actor*>(Support::fmark(&a)),d);
04135 }
04136
04137 if (p & AP_WEAKLY) {}
04138 }
04139
04140 forceinline void
04141 Space::ignore(Actor& a, ActorProperty p, bool d) {
04142
04143
04144 if ((p & AP_DISPOSE) && (d_fst != NULL))
04145 ap_ignore_dispose(&a,d);
04146 if (p & AP_VIEW_TRACE) {}
04147 if ((p & AP_TRACE) && (d_fst != NULL))
04148 ap_ignore_dispose(static_cast<Actor*>(Support::fmark(&a)),d);
04149
04150 if (p & AP_WEAKLY) {}
04151 }
04152
04153
04154
04155
04156
04157
04158
04159 template<class VIC>
04160 forceinline ActorLink**
04161 VarImp<VIC>::actor(PropCond pc) {
04162 assert((pc >= 0) && (pc < pc_max+2));
04163 return (pc == 0) ? b.base : b.base+u.idx[pc-1];
04164 }
04165
04166 template<class VIC>
04167 forceinline ActorLink**
04168 VarImp<VIC>::actorNonZero(PropCond pc) {
04169 assert((pc > 0) && (pc < pc_max+2));
04170 return b.base+u.idx[pc-1];
04171 }
04172
04173 template<class VIC>
04174 forceinline unsigned int&
04175 VarImp<VIC>::idx(PropCond pc) {
04176 assert((pc > 0) && (pc < pc_max+2));
04177 return u.idx[pc-1];
04178 }
04179
04180 template<class VIC>
04181 forceinline unsigned int
04182 VarImp<VIC>::idx(PropCond pc) const {
04183 assert((pc > 0) && (pc < pc_max+2));
04184 return u.idx[pc-1];
04185 }
04186
04187 template<class VIC>
04188 forceinline
04189 VarImp<VIC>::VarImp(Space&) {
04190 b.base = NULL; entries = 0;
04191 for (PropCond pc=1; pc<pc_max+2; pc++)
04192 idx(pc) = 0;
04193 free_and_bits = 0;
04194 }
04195
04196 template<class VIC>
04197 forceinline
04198 VarImp<VIC>::VarImp(void) {
04199 b.base = NULL; entries = 0;
04200 for (PropCond pc=1; pc<pc_max+2; pc++)
04201 idx(pc) = 0;
04202 free_and_bits = 0;
04203 }
04204
04205 template<class VIC>
04206 forceinline unsigned int
04207 VarImp<VIC>::degree(void) const {
04208 assert(!copied());
04209 return entries;
04210 }
04211
04212 template<class VIC>
04213 forceinline double
04214 VarImp<VIC>::afc(void) const {
04215 double d = 0.0;
04216
04217 {
04218 ActorLink** a = const_cast<VarImp<VIC>*>(this)->actor(0);
04219 ActorLink** e = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
04220 while (a < e) {
04221 d += Propagator::cast(*a)->afc(); a++;
04222 }
04223 }
04224
04225 {
04226 ActorLink** a = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
04227 ActorLink** e = const_cast<VarImp<VIC>*>(this)->b.base+entries;
04228 while (a < e) {
04229 d += Advisor::cast(static_cast<ActorLink*>(Support::funmark(*a)))
04230 ->propagator().afc();
04231 a++;
04232 }
04233 }
04234 return d;
04235 }
04236
04237 template<class VIC>
04238 forceinline ModEvent
04239 VarImp<VIC>::modevent(const Delta& d) {
04240 return d.me;
04241 }
04242
04243 template<class VIC>
04244 forceinline unsigned int
04245 VarImp<VIC>::bits(void) const {
04246 return free_and_bits;
04247 }
04248
04249 template<class VIC>
04250 forceinline unsigned int&
04251 VarImp<VIC>::bits(void) {
04252 return free_and_bits;
04253 }
04254
04255 #ifdef GECODE_HAS_VAR_DISPOSE
04256 template<class VIC>
04257 forceinline VarImp<VIC>*
04258 VarImp<VIC>::vars_d(Space& home) {
04259 return static_cast<VarImp<VIC>*>(home.vars_d<VIC>());
04260 }
04261
04262 template<class VIC>
04263 forceinline void
04264 VarImp<VIC>::vars_d(Space& home, VarImp<VIC>* x) {
04265 home.vars_d<VIC>(x);
04266 }
04267 #endif
04268
04269 template<class VIC>
04270 forceinline bool
04271 VarImp<VIC>::copied(void) const {
04272 return Support::marked(b.fwd);
04273 }
04274
04275 template<class VIC>
04276 forceinline VarImp<VIC>*
04277 VarImp<VIC>::forward(void) const {
04278 assert(copied());
04279 return static_cast<VarImp<VIC>*>(Support::unmark(b.fwd));
04280 }
04281
04282 template<class VIC>
04283 forceinline VarImp<VIC>*
04284 VarImp<VIC>::next(void) const {
04285 assert(copied());
04286 return u.next;
04287 }
04288
04289 template<class VIC>
04290 forceinline
04291 VarImp<VIC>::VarImp(Space& home, bool, VarImp<VIC>& x) {
04292 VarImpBase** reg;
04293 free_and_bits = x.free_and_bits & ((1 << free_bits) - 1);
04294 if (x.b.base == NULL) {
04295
04296 reg = &home.pc.c.vars_noidx;
04297 assert(x.degree() == 0);
04298 } else {
04299 reg = &home.pc.c.vars_u[idx_c];
04300 }
04301
04302 b.base = x.b.base;
04303 entries = x.entries;
04304 for (PropCond pc=1; pc<pc_max+2; pc++)
04305 idx(pc) = x.idx(pc);
04306
04307
04308 x.b.fwd = static_cast<VarImp<VIC>*>(Support::mark(this));
04309
04310 x.u.next = static_cast<VarImp<VIC>*>(*reg); *reg = &x;
04311 }
04312
04313 template<class VIC>
04314 forceinline ModEvent
04315 VarImp<VIC>::me(const ModEventDelta& med) {
04316 return static_cast<ModEvent>((med & VIC::med_mask) >> VIC::med_fst);
04317 }
04318
04319 template<class VIC>
04320 forceinline ModEventDelta
04321 VarImp<VIC>::med(ModEvent me) {
04322 return static_cast<ModEventDelta>(me << VIC::med_fst);
04323 }
04324
04325 template<class VIC>
04326 forceinline ModEvent
04327 VarImp<VIC>::me_combine(ModEvent me1, ModEvent me2) {
04328 return VIC::me_combine(me1,me2);
04329 }
04330
04331 template<class VIC>
04332 forceinline void
04333 VarImp<VIC>::schedule(Space& home, Propagator& p, ModEvent me,
04334 bool force) {
04335 if (VIC::med_update(p.u.med,me) || force)
04336 home.enqueue(&p);
04337 }
04338
04339 template<class VIC>
04340 forceinline void
04341 VarImp<VIC>::schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me) {
04342 ActorLink** b = actor(pc1);
04343 ActorLink** p = actorNonZero(pc2+1);
04344 while (p-- > b)
04345 schedule(home,*Propagator::cast(*p),me);
04346 }
04347
04348 template<class VIC>
04349 forceinline void
04350 VarImp<VIC>::resize(Space& home) {
04351 if (b.base == NULL) {
04352 assert((free_and_bits >> free_bits) == 0);
04353
04354 free_and_bits += 4 << free_bits;
04355 b.base = home.alloc<ActorLink*>(4);
04356 for (int i=0; i<pc_max+1; i++)
04357 u.idx[i] = 0;
04358 } else {
04359
04360 unsigned int n = degree();
04361
04362
04363
04364 ActorLink** s = static_cast<ActorLink**>(home.mm.subscriptions());
04365 unsigned int m =
04366 ((s <= b.base) && (b.base < s+home.pc.p.n_sub)) ?
04367 (n+4) : ((n+1)*3>>1);
04368 ActorLink** prop = home.alloc<ActorLink*>(m);
04369 free_and_bits += (m-n) << free_bits;
04370
04371 Heap::copy<ActorLink*>(prop, b.base, n);
04372 home.free<ActorLink*>(b.base,n);
04373 b.base = prop;
04374 }
04375 }
04376
04377 template<class VIC>
04378 forceinline void
04379 VarImp<VIC>::enter(Space& home, Propagator* p, PropCond pc) {
04380 assert(pc <= pc_max);
04381
04382 home.pc.p.n_sub += 1;
04383 if ((free_and_bits >> free_bits) == 0)
04384 resize(home);
04385 free_and_bits -= 1 << free_bits;
04386
04387
04388 b.base[entries] = *actorNonZero(pc_max+1);
04389 entries++;
04390 for (PropCond j = pc_max; j > pc; j--) {
04391 *actorNonZero(j+1) = *actorNonZero(j);
04392 idx(j+1)++;
04393 }
04394 *actorNonZero(pc+1) = *actor(pc);
04395 idx(pc+1)++;
04396 *actor(pc) = ActorLink::cast(p);
04397
04398 #ifdef GECODE_AUDIT
04399 ActorLink** f = actor(pc);
04400 while (f < (pc == pc_max+1 ? b.base+entries : actorNonZero(pc+1)))
04401 if (*f == p)
04402 goto found;
04403 else
04404 f++;
04405 GECODE_NEVER;
04406 found: ;
04407 #endif
04408 }
04409
04410 template<class VIC>
04411 forceinline void
04412 VarImp<VIC>::enter(Space& home, Advisor* a) {
04413
04414
04415 home.pc.p.n_sub += 1;
04416 if ((free_and_bits >> free_bits) == 0)
04417 resize(home);
04418 free_and_bits -= 1 << free_bits;
04419
04420
04421 b.base[entries++] = *actorNonZero(pc_max+1);
04422 *actorNonZero(pc_max+1) = a;
04423 }
04424
04425 template<class VIC>
04426 forceinline void
04427 VarImp<VIC>::subscribe(Space& home, Propagator& p, PropCond pc,
04428 bool assigned, ModEvent me, bool schedule) {
04429 if (assigned) {
04430
04431 if (schedule)
04432 VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
04433 } else {
04434 enter(home,&p,pc);
04435
04436 if (schedule && (pc != PC_GEN_ASSIGNED))
04437 VarImp<VIC>::schedule(home,p,me);
04438 }
04439 }
04440
04441 template<class VIC>
04442 forceinline void
04443 VarImp<VIC>::subscribe(Space& home, Advisor& a, bool assigned, bool fail) {
04444 if (!assigned) {
04445 Advisor* ma = static_cast<Advisor*>(Support::ptrjoin(&a,fail ? 1 : 0));
04446 enter(home,ma);
04447 }
04448 }
04449
04450 template<class VIC>
04451 forceinline void
04452 VarImp<VIC>::reschedule(Space& home, Propagator& p, PropCond pc,
04453 bool assigned, ModEvent me) {
04454 if (assigned)
04455 VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
04456 else if (pc != PC_GEN_ASSIGNED)
04457 VarImp<VIC>::schedule(home,p,me);
04458 }
04459
04460 template<class VIC>
04461 void
04462 VarImp<VIC>::remove(Space& home, Propagator* p, PropCond pc) {
04463 assert(pc <= pc_max);
04464 ActorLink* a = ActorLink::cast(p);
04465
04466 ActorLink** f = actor(pc);
04467 #ifdef GECODE_AUDIT
04468 while (f < actorNonZero(pc+1))
04469 if (*f == a)
04470 goto found;
04471 else
04472 f++;
04473 GECODE_NEVER;
04474 found: ;
04475 #else
04476 while (*f != a) f++;
04477 #endif
04478
04479 *f = *(actorNonZero(pc+1)-1);
04480 for (PropCond j = pc+1; j< pc_max+1; j++) {
04481 *(actorNonZero(j)-1) = *(actorNonZero(j+1)-1);
04482 idx(j)--;
04483 }
04484 *(actorNonZero(pc_max+1)-1) = b.base[entries-1];
04485 idx(pc_max+1)--;
04486 entries--;
04487 free_and_bits += 1 << free_bits;
04488 home.pc.p.n_sub -= 1;
04489 }
04490
04491 template<class VIC>
04492 forceinline void
04493 VarImp<VIC>::cancel(Space& home, Propagator& p, PropCond pc) {
04494 if (b.base != NULL)
04495 remove(home,&p,pc);
04496 }
04497
04498 template<class VIC>
04499 void
04500 VarImp<VIC>::remove(Space& home, Advisor* a) {
04501
04502
04503 ActorLink** f = actorNonZero(pc_max+1);
04504 #ifdef GECODE_AUDIT
04505 while (f < b.base+entries)
04506 if (*f == a)
04507 goto found;
04508 else
04509 f++;
04510 GECODE_NEVER;
04511 found: ;
04512 #else
04513 while (*f != a) f++;
04514 #endif
04515
04516 *f = b.base[--entries];
04517 free_and_bits += 1 << free_bits;
04518 home.pc.p.n_sub -= 1;
04519 }
04520
04521 template<class VIC>
04522 forceinline void
04523 VarImp<VIC>::cancel(Space& home, Advisor& a, bool fail) {
04524 if (b.base != NULL) {
04525 Advisor* ma = static_cast<Advisor*>(Support::ptrjoin(&a,fail ? 1 : 0));
04526 remove(home,ma);
04527 }
04528 }
04529
04530 template<class VIC>
04531 forceinline void
04532 VarImp<VIC>::cancel(Space& home) {
04533 unsigned int n_sub = degree();
04534 home.pc.p.n_sub -= n_sub;
04535 unsigned int n = (free_and_bits >> free_bits) + n_sub;
04536 home.free<ActorLink*>(b.base,n);
04537
04538 b.base = NULL;
04539
04540 entries = 0;
04541
04542 for (PropCond pc=1; pc<pc_max+2; pc++)
04543 idx(pc) = 0;
04544 free_and_bits &= (1 << free_bits) - 1;
04545 }
04546
04547 template<class VIC>
04548 forceinline bool
04549 VarImp<VIC>::advise(Space& home, ModEvent me, Delta& d) {
04550
04551
04552
04553
04554
04555 ActorLink** la = actorNonZero(pc_max+1);
04556 ActorLink** le = b.base+entries;
04557 if (la == le)
04558 return true;
04559 d.me = me;
04560
04561
04562
04563 do {
04564 Advisor* a = Advisor::cast
04565 (static_cast<ActorLink*>(Support::funmark(*la)));
04566 assert(!a->disposed());
04567 Propagator& p = a->propagator();
04568 switch (p.advise(home,*a,d)) {
04569 case ES_FIX:
04570 break;
04571 case ES_FAILED:
04572 return false;
04573 case ES_NOFIX:
04574 schedule(home,p,me);
04575 break;
04576 case ES_NOFIX_FORCE:
04577 schedule(home,p,me,true);
04578 break;
04579 case __ES_SUBSUMED:
04580 default:
04581 GECODE_NEVER;
04582 }
04583 } while (++la < le);
04584 return true;
04585 }
04586
04587 template<class VIC>
04588 void
04589 VarImp<VIC>::_fail(Space& home) {
04590
04591
04592
04593
04594
04595 ActorLink** la = actorNonZero(pc_max+1);
04596 ActorLink** le = b.base+entries;
04597 if (la == le)
04598 return;
04599
04600
04601
04602 do {
04603 if (Support::marked(*la)) {
04604 Advisor* a = Advisor::cast(static_cast<ActorLink*>
04605 (Support::unmark(*la)));
04606 assert(!a->disposed());
04607 Propagator& p = a->propagator();
04608 p.advise(home,*a);
04609 }
04610 } while (++la < le);
04611 }
04612
04613 template<class VIC>
04614 ModEvent
04615 VarImp<VIC>::fail(Space& home) {
04616 _fail(home);
04617 return ME_GEN_FAILED;
04618 }
04619
04620 template<class VIC>
04621 forceinline void
04622 VarImp<VIC>::update(VarImp<VIC>* x, ActorLink**& sub) {
04623
04624
04625
04626 x->b.base = b.base;
04627 x->u.idx[0] = u.idx[0];
04628 if (pc_max > 0 && sizeof(ActorLink**) > sizeof(unsigned int))
04629 x->u.idx[1] = u.idx[1];
04630
04631 unsigned int np =
04632 static_cast<unsigned int>(x->actorNonZero(pc_max+1) - x->actor(0));
04633 unsigned int na =
04634 static_cast<unsigned int >(x->b.base + x->entries -
04635 x->actorNonZero(pc_max+1));
04636 unsigned int n = na + np;
04637 assert(n == x->degree());
04638
04639 ActorLink** f = x->b.base;
04640 ActorLink** t = sub;
04641
04642 sub += n;
04643 b.base = t;
04644
04645 while (np >= 4) {
04646 ActorLink* p3 = f[3]->prev();
04647 ActorLink* p0 = f[0]->prev();
04648 ActorLink* p1 = f[1]->prev();
04649 ActorLink* p2 = f[2]->prev();
04650 t[0] = p0; t[1] = p1; t[2] = p2; t[3] = p3;
04651 np -= 4; t += 4; f += 4;
04652 }
04653 if (np >= 2) {
04654 ActorLink* p0 = f[0]->prev();
04655 ActorLink* p1 = f[1]->prev();
04656 t[0] = p0; t[1] = p1;
04657 np -= 2; t += 2; f += 2;
04658 }
04659 if (np > 0) {
04660 ActorLink* p0 = f[0]->prev();
04661 t[0] = p0;
04662 t += 1; f += 1;
04663 }
04664
04665 while (na >= 4) {
04666 ptrdiff_t m0, m1, m2, m3;
04667 ActorLink* p3 =
04668 static_cast<ActorLink*>(Support::ptrsplit(f[3],m3))->prev();
04669 ActorLink* p0 =
04670 static_cast<ActorLink*>(Support::ptrsplit(f[0],m0))->prev();
04671 ActorLink* p1 =
04672 static_cast<ActorLink*>(Support::ptrsplit(f[1],m1))->prev();
04673 ActorLink* p2 =
04674 static_cast<ActorLink*>(Support::ptrsplit(f[2],m2))->prev();
04675 t[0] = static_cast<ActorLink*>(Support::ptrjoin(p0,m0));
04676 t[1] = static_cast<ActorLink*>(Support::ptrjoin(p1,m1));
04677 t[2] = static_cast<ActorLink*>(Support::ptrjoin(p2,m2));
04678 t[3] = static_cast<ActorLink*>(Support::ptrjoin(p3,m3));
04679 na -= 4; t += 4; f += 4;
04680 }
04681 if (na >= 2) {
04682 ptrdiff_t m0, m1;
04683 ActorLink* p0 =
04684 static_cast<ActorLink*>(Support::ptrsplit(f[0],m0))->prev();
04685 ActorLink* p1 =
04686 static_cast<ActorLink*>(Support::ptrsplit(f[1],m1))->prev();
04687 t[0] = static_cast<ActorLink*>(Support::ptrjoin(p0,m0));
04688 t[1] = static_cast<ActorLink*>(Support::ptrjoin(p1,m1));
04689 na -= 2; t += 2; f += 2;
04690 }
04691 if (na > 0) {
04692 ptrdiff_t m0;
04693 ActorLink* p0 =
04694 static_cast<ActorLink*>(Support::ptrsplit(f[0],m0))->prev();
04695 t[0] = static_cast<ActorLink*>(Support::ptrjoin(p0,m0));
04696 }
04697 }
04698
04699 template<class VIC>
04700 forceinline void
04701 VarImp<VIC>::update(Space& home, ActorLink**& sub) {
04702 VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home.pc.c.vars_u[idx_c]);
04703 while (x != NULL) {
04704 VarImp<VIC>* n = x->next(); x->forward()->update(x,sub); x = n;
04705 }
04706 }
04707
04708
04709
04710
04711
04712
04713
04714 template<class VarImp>
04715 VarImpDisposer<VarImp>::VarImpDisposer(void) {
04716 #ifdef GECODE_HAS_VAR_DISPOSE
04717 Space::vd[VarImp::idx_d] = this;
04718 #endif
04719 }
04720
04721 template<class VarImp>
04722 void
04723 VarImpDisposer<VarImp>::dispose(Space& home, VarImpBase* _x) {
04724 VarImp* x = static_cast<VarImp*>(_x);
04725 do {
04726 x->dispose(home); x = static_cast<VarImp*>(x->next_d());
04727 } while (x != NULL);
04728 }
04729
04730
04731
04732
04733
04734 forceinline void
04735 StatusStatistics::reset(void) {
04736 propagate = 0;
04737 }
04738 forceinline
04739 StatusStatistics::StatusStatistics(void) {
04740 reset();
04741 }
04742 forceinline StatusStatistics&
04743 StatusStatistics::operator +=(const StatusStatistics& s) {
04744 propagate += s.propagate;
04745 return *this;
04746 }
04747 forceinline StatusStatistics
04748 StatusStatistics::operator +(const StatusStatistics& s) {
04749 StatusStatistics t(s);
04750 return t += *this;
04751 }
04752
04753 forceinline void
04754 CloneStatistics::reset(void) {}
04755
04756 forceinline
04757 CloneStatistics::CloneStatistics(void) {
04758 reset();
04759 }
04760 forceinline CloneStatistics
04761 CloneStatistics::operator +(const CloneStatistics&) {
04762 CloneStatistics s;
04763 return s;
04764 }
04765 forceinline CloneStatistics&
04766 CloneStatistics::operator +=(const CloneStatistics&) {
04767 return *this;
04768 }
04769
04770 forceinline void
04771 CommitStatistics::reset(void) {}
04772
04773 forceinline
04774 CommitStatistics::CommitStatistics(void) {
04775 reset();
04776 }
04777 forceinline CommitStatistics
04778 CommitStatistics::operator +(const CommitStatistics&) {
04779 CommitStatistics s;
04780 return s;
04781 }
04782 forceinline CommitStatistics&
04783 CommitStatistics::operator +=(const CommitStatistics&) {
04784 return *this;
04785 }
04786
04787
04788
04789
04790
04791
04792 forceinline
04793 PropCost::PropCost(PropCost::ActualCost ac0) : ac(ac0) {}
04794
04795 forceinline PropCost
04796 PropCost::cost(PropCost::Mod m,
04797 PropCost::ActualCost lo, PropCost::ActualCost hi,
04798 unsigned int n) {
04799 if (n < 2)
04800 return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
04801 else if (n == 2)
04802 return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
04803 else if (n == 3)
04804 return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
04805 else
04806 return (m == LO) ? lo : hi;
04807 }
04808
04809 forceinline PropCost
04810 PropCost::record(void) {
04811 return AC_RECORD;
04812 }
04813 forceinline PropCost
04814 PropCost::crazy(PropCost::Mod m, unsigned int n) {
04815 return cost(m,AC_CRAZY_LO,AC_CRAZY_HI,n);
04816 }
04817 forceinline PropCost
04818 PropCost::crazy(PropCost::Mod m, int n) {
04819 assert(n >= 0);
04820 return crazy(m,static_cast<unsigned int>(n));
04821 }
04822 forceinline PropCost
04823 PropCost::cubic(PropCost::Mod m, unsigned int n) {
04824 return cost(m,AC_CUBIC_LO,AC_CUBIC_HI,n);
04825 }
04826 forceinline PropCost
04827 PropCost::cubic(PropCost::Mod m, int n) {
04828 assert(n >= 0);
04829 return cubic(m,static_cast<unsigned int>(n));
04830 }
04831 forceinline PropCost
04832 PropCost::quadratic(PropCost::Mod m, unsigned int n) {
04833 return cost(m,AC_QUADRATIC_LO,AC_QUADRATIC_HI,n);
04834 }
04835 forceinline PropCost
04836 PropCost::quadratic(PropCost::Mod m, int n) {
04837 assert(n >= 0);
04838 return quadratic(m,static_cast<unsigned int>(n));
04839 }
04840 forceinline PropCost
04841 PropCost::linear(PropCost::Mod m, unsigned int n) {
04842 return cost(m,AC_LINEAR_LO,AC_LINEAR_HI,n);
04843 }
04844 forceinline PropCost
04845 PropCost::linear(PropCost::Mod m, int n) {
04846 assert(n >= 0);
04847 return linear(m,static_cast<unsigned int>(n));
04848 }
04849 forceinline PropCost
04850 PropCost::ternary(PropCost::Mod m) {
04851 return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
04852 }
04853 forceinline PropCost
04854 PropCost::binary(PropCost::Mod m) {
04855 return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
04856 }
04857 forceinline PropCost
04858 PropCost::unary(PropCost::Mod m) {
04859 return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
04860 }
04861
04862
04863
04864
04865
04866 forceinline
04867 Space::Propagators::Propagators(Space& home0)
04868 : home(home0), q(home.pc.p.active) {
04869 while (q >= &home.pc.p.queue[0]) {
04870 if (q->next() != q) {
04871 c = q->next(); e = q; q--;
04872 return;
04873 }
04874 q--;
04875 }
04876 q = NULL;
04877 if (!home.pl.empty()) {
04878 c = Propagator::cast(home.pl.next());
04879 e = Propagator::cast(&home.pl);
04880 } else {
04881 c = e = NULL;
04882 }
04883 }
04884 forceinline bool
04885 Space::Propagators::operator ()(void) const {
04886 return c != NULL;
04887 }
04888 forceinline void
04889 Space::Propagators::operator ++(void) {
04890 c = c->next();
04891 if (c == e) {
04892 if (q == NULL) {
04893 c = NULL;
04894 } else {
04895 while (q >= &home.pc.p.queue[0]) {
04896 if (q->next() != q) {
04897 c = q->next(); e = q; q--;
04898 return;
04899 }
04900 q--;
04901 }
04902 q = NULL;
04903 if (!home.pl.empty()) {
04904 c = Propagator::cast(home.pl.next());
04905 e = Propagator::cast(&home.pl);
04906 } else {
04907 c = NULL;
04908 }
04909 }
04910 }
04911 }
04912 forceinline Propagator&
04913 Space::Propagators::propagator(void) const {
04914 return *Propagator::cast(c);
04915 }
04916
04917
04918 forceinline
04919 Space::ScheduledPropagators::ScheduledPropagators(Space& home0)
04920 : home(home0), q(home.pc.p.active) {
04921 while (q >= &home.pc.p.queue[0]) {
04922 if (q->next() != q) {
04923 c = q->next(); e = q; q--;
04924 return;
04925 }
04926 q--;
04927 }
04928 q = c = e = NULL;
04929 }
04930 forceinline bool
04931 Space::ScheduledPropagators::operator ()(void) const {
04932 return c != NULL;
04933 }
04934 forceinline void
04935 Space::ScheduledPropagators::operator ++(void) {
04936 c = c->next();
04937 if (c == e) {
04938 if (q == NULL) {
04939 c = NULL;
04940 } else {
04941 while (q >= &home.pc.p.queue[0]) {
04942 if (q->next() != q) {
04943 c = q->next(); e = q; q--;
04944 return;
04945 }
04946 q--;
04947 }
04948 q = c = e = NULL;
04949 }
04950 }
04951 }
04952 forceinline Propagator&
04953 Space::ScheduledPropagators::propagator(void) const {
04954 return *Propagator::cast(c);
04955 }
04956
04957
04958 forceinline
04959 Space::IdlePropagators::IdlePropagators(Space& home) {
04960 c = Propagator::cast(home.pl.next());
04961 e = Propagator::cast(&home.pl);
04962 }
04963 forceinline bool
04964 Space::IdlePropagators::operator ()(void) const {
04965 return c != e;
04966 }
04967 forceinline void
04968 Space::IdlePropagators::operator ++(void) {
04969 c = c->next();
04970 }
04971 forceinline Propagator&
04972 Space::IdlePropagators::propagator(void) const {
04973 return *Propagator::cast(c);
04974 }
04975
04976
04977 forceinline
04978 Space::Branchers::Branchers(Space& home)
04979 : c(Brancher::cast(home.bl.next())), e(&home.bl) {}
04980 forceinline bool
04981 Space::Branchers::operator ()(void) const {
04982 return c != e;
04983 }
04984 forceinline void
04985 Space::Branchers::operator ++(void) {
04986 c = c->next();
04987 }
04988 forceinline Brancher&
04989 Space::Branchers::brancher(void) const {
04990 return *Brancher::cast(c);
04991 }
04992
04993
04994
04995
04996
04997 forceinline
04998 Group::Group(unsigned int gid0) : gid(gid0) {}
04999
05000 forceinline bool
05001 Group::in(Group actor) const {
05002 return (gid == GROUPID_ALL) || (gid == actor.gid);
05003 }
05004
05005 forceinline bool
05006 Group::in(void) const {
05007 return (gid != GROUPID_ALL) && (gid != GROUPID_DEF);
05008 }
05009
05010 forceinline
05011 Group::Group(const Group& g) : gid(g.gid) {}
05012
05013 forceinline Group&
05014 Group::operator =(const Group& g) {
05015 gid=g.gid; return *this;
05016 }
05017
05018 forceinline unsigned int
05019 Group::id(void) const {
05020 return gid;
05021 }
05022
05023
05024 forceinline
05025 PropagatorGroup::PropagatorGroup(void) {}
05026
05027 forceinline
05028 PropagatorGroup::PropagatorGroup(unsigned int gid)
05029 : Group(gid) {}
05030
05031 forceinline
05032 PropagatorGroup::PropagatorGroup(const PropagatorGroup& g)
05033 : Group(g) {}
05034
05035 forceinline PropagatorGroup&
05036 PropagatorGroup::operator =(const PropagatorGroup& g) {
05037 return static_cast<PropagatorGroup&>(Group::operator =(g));
05038 }
05039
05040 forceinline Home
05041 PropagatorGroup::operator ()(Space& home) {
05042 return Home(home,NULL,*this,BrancherGroup::def);
05043 }
05044
05045 forceinline bool
05046 PropagatorGroup::operator ==(PropagatorGroup g) const {
05047 return id() == g.id();
05048 }
05049 forceinline bool
05050 PropagatorGroup::operator !=(PropagatorGroup g) const {
05051 return id() != g.id();
05052 }
05053
05054 forceinline PropagatorGroup&
05055 PropagatorGroup::move(Space& , Propagator& p) {
05056 if (id() != GROUPID_ALL)
05057 p.group(*this);
05058 return *this;
05059 }
05060
05061
05062 forceinline
05063 BrancherGroup::BrancherGroup(void) {}
05064
05065 forceinline
05066 BrancherGroup::BrancherGroup(unsigned int gid)
05067 : Group(gid) {}
05068
05069 forceinline
05070 BrancherGroup::BrancherGroup(const BrancherGroup& g)
05071 : Group(g) {}
05072
05073 forceinline BrancherGroup&
05074 BrancherGroup::operator =(const BrancherGroup& g) {
05075 return static_cast<BrancherGroup&>(Group::operator =(g));
05076 }
05077
05078 forceinline Home
05079 BrancherGroup::operator ()(Space& home) {
05080 return Home(home,NULL,PropagatorGroup::def,*this);
05081 }
05082
05083 forceinline bool
05084 BrancherGroup::operator ==(BrancherGroup g) const {
05085 return id() == g.id();
05086 }
05087 forceinline bool
05088 BrancherGroup::operator !=(BrancherGroup g) const {
05089 return id() != g.id();
05090 }
05091
05092 forceinline BrancherGroup&
05093 BrancherGroup::move(Space& , Brancher& p) {
05094 if (id() != GROUPID_ALL)
05095 p.group(*this);
05096 return *this;
05097 }
05098
05099
05100
05101
05102
05103
05104 forceinline
05105 Propagators::Propagators(Space& home, PropagatorGroup g0)
05106 : ps(home), g(g0) {
05107 while (ps() && !g.in(ps.propagator().group()))
05108 ++ps;
05109 }
05110 forceinline bool
05111 Propagators::operator ()(void) const {
05112 return ps();
05113 }
05114 forceinline void
05115 Propagators::operator ++(void) {
05116 do
05117 ++ps;
05118 while (ps() && !g.in(ps.propagator().group()));
05119 }
05120 forceinline const Propagator&
05121 Propagators::propagator(void) const {
05122 return ps.propagator();
05123 }
05124
05125 forceinline
05126 Branchers::Branchers(Space& home, BrancherGroup g0)
05127 : bs(home), g(g0) {
05128 while (bs() && !g.in(bs.brancher().group()))
05129 ++bs;
05130 }
05131 forceinline bool
05132 Branchers::operator ()(void) const {
05133 return bs();
05134 }
05135 forceinline void
05136 Branchers::operator ++(void) {
05137 do
05138 ++bs;
05139 while (bs() && !g.in(bs.brancher().group()));
05140 }
05141 forceinline const Brancher&
05142 Branchers::brancher(void) const {
05143 return bs.brancher();
05144 }
05145
05146
05147
05148
05149
05150
05151 template<class T>
05152 forceinline T&
05153 Space::construct(void) {
05154 return alloc<T>(1);
05155 }
05156 template<class T, typename A1>
05157 forceinline T&
05158 Space::construct(A1 const& a1) {
05159 T& t = *static_cast<T*>(ralloc(sizeof(T)));
05160 new (&t) T(a1);
05161 return t;
05162 }
05163 template<class T, typename A1, typename A2>
05164 forceinline T&
05165 Space::construct(A1 const& a1, A2 const& a2) {
05166 T& t = *static_cast<T*>(ralloc(sizeof(T)));
05167 new (&t) T(a1,a2);
05168 return t;
05169 }
05170 template<class T, typename A1, typename A2, typename A3>
05171 forceinline T&
05172 Space::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
05173 T& t = *static_cast<T*>(ralloc(sizeof(T)));
05174 new (&t) T(a1,a2,a3);
05175 return t;
05176 }
05177 template<class T, typename A1, typename A2, typename A3, typename A4>
05178 forceinline T&
05179 Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
05180 T& t = *static_cast<T*>(ralloc(sizeof(T)));
05181 new (&t) T(a1,a2,a3,a4);
05182 return t;
05183 }
05184 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
05185 forceinline T&
05186 Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
05187 T& t = *static_cast<T*>(ralloc(sizeof(T)));
05188 new (&t) T(a1,a2,a3,a4,a5);
05189 return t;
05190 }
05191
05192 }
05193
05194