Generated on Tue Apr 18 10:22:06 2017 for Gecode by doxygen 1.6.3

core.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *     Guido Tack <tack@gecode.org>
00006  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00007  *
00008  *  Contributing authors:
00009  *     Filip Konvicka <filip.konvicka@logis.cz>
00010  *
00011  *  Copyright:
00012  *     Christian Schulte, 2002
00013  *     Guido Tack, 2003
00014  *     Mikael Lagerkvist, 2006
00015  *     LOGIS, s.r.o., 2009
00016  *
00017  *  Bugfixes provided by:
00018  *     Alexander Samoilov <alexander_samoilov@yahoo.com>
00019  *
00020  *  Last modified:
00021  *     $Date: 2017-03-17 23:04:57 +0100 (Fri, 17 Mar 2017) $ by $Author: schulte $
00022  *     $Revision: 15597 $
00023  *
00024  *  This file is part of Gecode, the generic constraint
00025  *  development environment:
00026  *     http://www.gecode.org
00027  *
00028  *  Permission is hereby granted, free of charge, to any person obtaining
00029  *  a copy of this software and associated documentation files (the
00030  *  "Software"), to deal in the Software without restriction, including
00031  *  without limitation the rights to use, copy, modify, merge, publish,
00032  *  distribute, sublicense, and/or sell copies of the Software, and to
00033  *  permit persons to whom the Software is furnished to do so, subject to
00034  *  the following conditions:
00035  *
00036  *  The above copyright notice and this permission notice shall be
00037  *  included in all copies or substantial portions of the Software.
00038  *
00039  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00040  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00041  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00042  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00043  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00044  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00045  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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    * These are the classes of interest
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    * Variable implementations
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      * Member functions for search engines
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    * Memory management
02825    *
02826    */
02827 
02828   // Space allocation: general space heaps and free lists
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    * Typed allocation routines
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   // Space allocated entities: Actors, variable implementations, and advisors
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    * Shared objects and handles
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    * No-goods
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    * Information from meta search engines
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    * ActorLink
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     // Inserts al at head of link-chain (that is, after this)
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     // Inserts al at tail of link-chain (that is, before this)
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     // Turning al into a reference is for gcc, assume is for MSVC
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     // Turning al into a reference is for gcc, assume is for MSVC
03294     GECODE_NOT_NULL(a);
03295     const ActorLink& t = *a;
03296     return static_cast<const ActorLink*>(&t);
03297   }
03298 
03299 
03300   /*
03301    * Actor
03302    *
03303    */
03304   forceinline Actor*
03305   Actor::cast(ActorLink* al) {
03306     // Turning al into a reference is for gcc, assume is for MSVC
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     // Turning al into a reference is for gcc, assume is for MSVC
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     // Clone is only const for search engines. During cloning, several data
03328     // structures are updated (e.g. forwarding pointers), so we have to
03329     // cast away the constness.
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    * Home for posting actors
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    * View trace information
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     // Because PROPAGATOR == 0
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    * Post information
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    * Propagate trace information
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    * Commit trace information
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    * Propagator
03516    *
03517    */
03518   forceinline Propagator*
03519   Propagator::cast(ActorLink* al) {
03520     // Turning al into a reference is for gcc, assume is for MSVC
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     // Turning al into a reference is for gcc, assume is for MSVC
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                    // Inherit propagator information
03565                    home.propagator()->gpi_disabled :
03566                    // New propagator information
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     // Set forwarding pointer
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    * Brancher
03637    *
03638    */
03639   forceinline Brancher*
03640   Brancher::cast(ActorLink* al) {
03641     // Turning al into a reference is for gcc, assume is for MSVC
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     // Turning al into a reference is for gcc, assume is for MSVC
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     // If no brancher available, make it the first one
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     // Set forwarding pointer
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     // Make sure that neither b_status nor b_commit does not point to b!
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      * Due to weakly monotonic propagators the following scenario might
03718      * occur: a brancher has been committed with all its available
03719      * choices. Then, propagation determines less information
03720      * than before and the brancher now will create new choices.
03721      * Later, during recomputation, all of these choices
03722      * can be used together, possibly interleaved with
03723      * choices for other branchers. That means all branchers
03724      * must be scanned to find the matching brancher for the choice.
03725      *
03726      * b_commit tries to optimize scanning as it is most likely that
03727      * recomputation does not generate new choices during recomputation
03728      * and hence b_commit is moved from newer to older branchers.
03729      */
03730     Brancher* b_old = b_commit;
03731     // Try whether we are lucky
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       // We did not find the brancher, start at the beginning
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    * Local objects
03752    *
03753    */
03754 
03755   forceinline LocalObject*
03756   LocalObject::cast(ActorLink* al) {
03757     // Turning al into a reference is for gcc, assume is for MSVC
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     // Turning al into a reference is for gcc, assume is for MSVC
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    * Choices
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    * No-good literal
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    * Advisor
03878    *
03879    */
03880   template<class A>
03881   forceinline
03882   Advisor::Advisor(Space&, Propagator& p, Council<A>& c) {
03883     // Store propagator and forwarding in prev()
03884     ActorLink::prev(&p);
03885     // Link to next advisor in next()
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     // Shorten chains of disposed advisors by one, if possible
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    * Advisor council
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     // Skip all disposed advisors
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     // Are there any advisors to be cloned?
03986     if (c.advisors != NULL) {
03987       // The propagator in from-space
03988       Propagator* p_f = &static_cast<A*>(c.advisors)->propagator();
03989       // The propagator in to-space
03990       Propagator* p_t = Propagator::cast(p_f->prev());
03991       // Advisors in from-space
03992       ActorLink** a_f = &c.advisors;
03993       // Advisors in to-space
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           // Run specific copying part
04000           A* a = new (home) A(home,share,*static_cast<A*>(*a_f));
04001           // Set propagator pointer
04002           a->prev(p_t);
04003           // Set forwarding pointer
04004           (*a_f)->prev(a);
04005           // Link
04006           a->next(a_t);
04007           a_t = a;
04008           a_f = (*a_f)->next_ref();
04009         }
04010       }
04011       advisors = a_t;
04012       // Enter advisor link for reset
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    * Advisor iterator
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    * Space
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      * Now active points beyond the last queue. This is essential as
04084      * enqueuing a propagator in a failed space keeps the space
04085      * failed.
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     // Currently unused
04137     if (p & AP_WEAKLY) {}
04138   }
04139 
04140   forceinline void
04141   Space::ignore(Actor& a, ActorProperty p, bool d) {
04142     // Check wether array has already been discarded as space
04143     // deletion is already in progress
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     // Currently unused
04150     if (p & AP_WEAKLY) {}
04151   }
04152 
04153 
04154 
04155   /*
04156    * Variable implementation
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     // Count the afc of each propagator
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     // Count the afc of each advisor's propagator
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       // Variable implementation needs no index structure
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     // Save subscriptions in copy
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     // Set forwarding pointer
04308     x.b.fwd = static_cast<VarImp<VIC>*>(Support::mark(this));
04309     // Register original
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       // Create fresh dependency array with four entries
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       // Resize dependency array
04360       unsigned int n = degree();
04361       // Find out whether the area is most likely in the special area
04362       // reserved for subscriptions. If yes, just resize mildly otherwise
04363       // more agressively
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       // Copy entries
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     // Count one new subscription
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     // Enter subscription
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     // Note that a might be a marked pointer
04414     // Count one new subscription
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     // Enter subscription
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       // Do not subscribe, just schedule the propagator
04431       if (schedule)
04432         VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
04433     } else {
04434       enter(home,&p,pc);
04435       // Schedule propagator
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     // Find actor in dependency array
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     // Remove actor
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     // Note that a might be a marked pointer
04502     // Find actor in dependency array
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     // Remove actor
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     // Must be NULL such that cloning works
04538     b.base = NULL;
04539     // Must be 0 such that degree works
04540     entries = 0;
04541     // Must be NULL such that afc works
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      * An advisor that is executed might remove itself due to subsumption.
04552      * As entries are removed from front to back, the advisors must
04553      * be iterated in forward direction.
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     // An advisor that is run, might be removed during execution.
04561     // As removal is done from the back the advisors have to be executed
04562     // in inverse order.
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      * An advisor that is executed might remove itself due to subsumption.
04592      * As entries are removed from front to back, the advisors must
04593      * be iterated in forward direction.
04594      */
04595     ActorLink** la = actorNonZero(pc_max+1);
04596     ActorLink** le = b.base+entries;
04597     if (la == le)
04598       return;
04599     // An advisor that is run, might be removed during execution.
04600     // As removal is done from the back the advisors have to be executed
04601     // in inverse order.
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     // this refers to the variable to be updated (clone)
04624     // x refers to the original
04625     // Recover from copy
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     // Process propagator subscriptions
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     // Process advisor subscriptions
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    * Variable disposer
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    * Statistics
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    * Cost computation
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    * Iterators for propagators and branchers of a space
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    * Groups of actors
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    * Iterators for propagators and branchers in a group
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    * Space construction support
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 // STATISTICS: kernel-core