Generated on Fri Mar 20 15:56:17 2015 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: 2015-03-20 15:37:34 +0100 (Fri, 20 Mar 2015) $ by $Author: schulte $
00022  *     $Revision: 14471 $
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 {
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);
00106       static void* operator new(size_t s);
00108       static void  operator delete(void* p);
00109     };
00110   private:
00112     Object* o;
00114     void subscribe(void);
00116     void cancel(void);
00117   public:
00119     SharedHandle(void);
00121     SharedHandle(SharedHandle::Object* so);
00123     SharedHandle(const SharedHandle& sh);
00125     SharedHandle& operator =(const SharedHandle& sh);
00127     void update(Space& home, bool share, SharedHandle& sh);
00129     ~SharedHandle(void);
00130   protected:
00132     SharedHandle::Object* object(void) const;
00134     void object(SharedHandle::Object* n);
00135   };
00136 
00145 
00146   typedef int ModEvent;
00147 
00149   const ModEvent ME_GEN_FAILED   = -1;
00151   const ModEvent ME_GEN_NONE     =  0;
00153   const ModEvent ME_GEN_ASSIGNED =  1;
00154 
00156   typedef int PropCond;
00158   const PropCond PC_GEN_NONE     = -1;
00160   const PropCond PC_GEN_ASSIGNED = 0;
00162 
00173   typedef int ModEventDelta;
00174 
00175 }
00176 
00177 #include <gecode/kernel/var-type.hpp>
00178 
00179 namespace Gecode {
00180 
00182   class NoIdxVarImpConf {
00183   public:
00185     static const int idx_c = -1;
00187     static const int idx_d = -1;
00189     static const PropCond pc_max = PC_GEN_ASSIGNED;
00191     static const int free_bits = 0;
00193     static const int med_fst = 0;
00195     static const int med_lst = 0;
00197     static const int med_mask = 0;
00199     static Gecode::ModEvent me_combine(ModEvent me1, ModEvent me2);
00201     static bool med_update(ModEventDelta& med, ModEvent me);
00202   };
00203 
00204   forceinline ModEvent
00205   NoIdxVarImpConf::me_combine(ModEvent, ModEvent) {
00206     GECODE_NEVER; return 0;
00207   }
00208   forceinline bool
00209   NoIdxVarImpConf::med_update(ModEventDelta&, ModEvent) {
00210     GECODE_NEVER; return false;
00211   }
00212 
00213 
00214   /*
00215    * These are the classes of interest
00216    *
00217    */
00218   class ActorLink;
00219   class Actor;
00220   class Propagator;
00221   class LocalObject;
00222   class Advisor;
00223   class AFC;
00224   class Brancher;
00225   class BrancherHandle;
00226   template<class A> class Council;
00227   template<class A> class Advisors;
00228   template<class VIC> class VarImp;
00229 
00230 
00231   /*
00232    * Variable implementations
00233    *
00234    */
00235 
00243   class VarImpBase {};
00244 
00251   class GECODE_VTABLE_EXPORT VarImpDisposerBase {
00252   public:
00254     GECODE_KERNEL_EXPORT virtual void dispose(Space& home, VarImpBase* x);
00256     GECODE_KERNEL_EXPORT virtual ~VarImpDisposerBase(void);
00257   };
00258 
00265   template<class VarImp>
00266   class VarImpDisposer : public VarImpDisposerBase {
00267   public:
00269     VarImpDisposer(void);
00271     virtual void dispose(Space& home, VarImpBase* x);
00272   };
00273 
00275   class Delta {
00276     template<class VIC> friend class VarImp;
00277   private:
00279     ModEvent me;
00280   };
00281 
00289   template<class VIC>
00290   class VarImp : public VarImpBase {
00291     friend class Space;
00292     friend class Propagator;
00293     template<class VarImp> friend class VarImpDisposer;
00294   private:
00295     union {
00303       ActorLink** base;
00312       VarImp<VIC>* fwd;
00313     } b;
00314 
00316     static const int idx_c = VIC::idx_c;
00318     static const int idx_d = VIC::idx_d;
00320     static const int free_bits = VIC::free_bits;
00322     unsigned int entries;
00324     unsigned int free_and_bits;
00326     static const Gecode::PropCond pc_max = VIC::pc_max;
00327 
00328     union {
00339       unsigned int idx[pc_max+1];
00341       VarImp<VIC>* next;
00342     } u;
00343 
00345     ActorLink** actor(PropCond pc);
00347     ActorLink** actorNonZero(PropCond pc);
00349     unsigned int& idx(PropCond pc);
00351     unsigned int idx(PropCond pc) const;
00352 
00359     void update(VarImp* x, ActorLink**& sub);
00366     static void update(Space& home, ActorLink**& sub);
00367 
00369     void enter(Space& home, Propagator* p, PropCond pc);
00371     void enter(Space& home, Advisor* a);
00373     void resize(Space& home);
00375     void remove(Space& home, Propagator* p, PropCond pc);
00377     void remove(Space& home, Advisor* a);
00378 
00379 
00380   protected:
00382     void cancel(Space& home);
00388     bool advise(Space& home, ModEvent me, Delta& d);
00389 #ifdef GECODE_HAS_VAR_DISPOSE
00390 
00391     static VarImp<VIC>* vars_d(Space& home);
00393     static void vars_d(Space& home, VarImp<VIC>* x);
00394 #endif
00395 
00396   public:
00398     VarImp(Space& home);
00400     VarImp(void);
00401 
00403 
00404 
00416     void subscribe(Space& home, Propagator& p, PropCond pc,
00417                    bool assigned, ModEvent me, bool schedule);
00423     void cancel(Space& home, Propagator& p, PropCond pc,
00424                 bool assigned);
00430     void subscribe(Space& home, Advisor& a, bool assigned);
00436     void cancel(Space& home, Advisor& a, bool assigned);
00437 
00444     unsigned int degree(void) const;
00451     double afc(const Space& home) const;
00453 
00455 
00456 
00457     VarImp(Space& home, bool share, VarImp& x);
00459     bool copied(void) const;
00461     VarImp* forward(void) const;
00463     VarImp* next(void) const;
00465 
00467 
00468 
00475     static void schedule(Space& home, Propagator& p, ModEvent me,
00476                          bool force = false);
00478     static ModEvent me(const ModEventDelta& med);
00480     static ModEventDelta med(ModEvent me);
00482     static ModEvent me_combine(ModEvent me1, ModEvent me2);
00484 
00486 
00487 
00488     static ModEvent modevent(const Delta& d);
00490 
00492 
00493 
00494     unsigned int bits(void) const;
00496     unsigned int& bits(void);
00498 
00499   protected:
00501     void schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me);
00502 
00503   public:
00505 
00506 
00507     static void* operator new(size_t,Space&);
00509     static void  operator delete(void*,Space&);
00511     static void  operator delete(void*);
00513   };
00514 
00523   enum ExecStatus {
00524     __ES_SUBSUMED       = -2, 
00525     ES_FAILED           = -1, 
00526     ES_NOFIX            =  0, 
00527     ES_OK               =  0, 
00528     ES_FIX              =  1, 
00529     ES_NOFIX_FORCE      =  2, 
00530     __ES_PARTIAL        =  2  
00531   };
00532 
00537   class PropCost {
00538     friend class Space;
00539   public:
00541     enum ActualCost {
00542       AC_CRAZY_LO     = 0, 
00543       AC_CRAZY_HI     = 0, 
00544       AC_CUBIC_LO     = 1, 
00545       AC_CUBIC_HI     = 1, 
00546       AC_QUADRATIC_LO = 2, 
00547       AC_QUADRATIC_HI = 2, 
00548       AC_LINEAR_HI    = 3, 
00549       AC_LINEAR_LO    = 4, 
00550       AC_TERNARY_HI   = 4, 
00551       AC_BINARY_HI    = 5, 
00552       AC_TERNARY_LO   = 5, 
00553       AC_BINARY_LO    = 6, 
00554       AC_UNARY_LO     = 6, 
00555       AC_UNARY_HI     = 6, 
00556       AC_MAX          = 6  
00557     };
00559     ActualCost ac;
00560   public:
00562     enum Mod {
00563       LO, 
00564       HI  
00565     };
00566   private:
00568     static PropCost cost(Mod m, ActualCost lo, ActualCost hi, unsigned int n);
00570     PropCost(ActualCost ac);
00571   public:
00573     static PropCost crazy(PropCost::Mod m, unsigned int n);
00575     static PropCost crazy(PropCost::Mod m, int n);
00577     static PropCost cubic(PropCost::Mod m, unsigned int n);
00579     static PropCost cubic(PropCost::Mod m, int n);
00581     static PropCost quadratic(PropCost::Mod m, unsigned int n);
00583     static PropCost quadratic(PropCost::Mod m, int n);
00585     static PropCost linear(PropCost::Mod m, unsigned int n);
00587     static PropCost linear(PropCost::Mod m, int n);
00589     static PropCost ternary(PropCost::Mod m);
00591     static PropCost binary(PropCost::Mod m);
00593     static PropCost unary(PropCost::Mod m);
00594   };
00595 
00596 
00601   enum ActorProperty {
00610     AP_DISPOSE = (1 << 0),
00616     AP_WEAKLY  = (1 << 1)
00617   };
00618 
00619 
00627   class ActorLink {
00628     friend class Actor;
00629     friend class Propagator;
00630     friend class Advisor;
00631     friend class Brancher;
00632     friend class LocalObject;
00633     friend class Space;
00634     template<class VIC> friend class VarImp;
00635   private:
00636     ActorLink* _next; ActorLink* _prev;
00637   public:
00639 
00640     ActorLink* prev(void) const; void prev(ActorLink*);
00641     ActorLink* next(void) const; void next(ActorLink*);
00642     ActorLink** next_ref(void);
00644 
00646     void init(void);
00648     void unlink(void);
00650     void head(ActorLink* al);
00652     void tail(ActorLink* al);
00654     bool empty(void) const;
00656     template<class T> static ActorLink* cast(T* a);
00658     template<class T> static const ActorLink* cast(const T* a);
00659   };
00660 
00661 
00666   class GECODE_VTABLE_EXPORT Actor : private ActorLink {
00667     friend class ActorLink;
00668     friend class Space;
00669     friend class Propagator;
00670     friend class Advisor;
00671     friend class Brancher;
00672     friend class LocalObject;
00673     template<class VIC> friend class VarImp;
00674     template<class A> friend class Council;
00675   private:
00677     static Actor* cast(ActorLink* al);
00679     static const Actor* cast(const ActorLink* al);
00681     GECODE_KERNEL_EXPORT static Actor* sentinel;
00682   public:
00684     virtual Actor* copy(Space& home, bool share) = 0;
00685 
00687 
00688 
00689     GECODE_KERNEL_EXPORT
00690     virtual size_t dispose(Space& home);
00692     static void* operator new(size_t s, Space& home);
00694     static void  operator delete(void* p, Space& home);
00695   private:
00696 #ifndef __GNUC__
00697 
00698     static void  operator delete(void* p);
00699 #endif
00700 
00701     static void* operator new(size_t s);
00703 #ifdef __GNUC__
00704   public:
00706     GECODE_KERNEL_EXPORT virtual ~Actor(void);
00708     static void  operator delete(void* p);
00709 #endif
00710   };
00711 
00712 
00713 
00717   class Home {
00718   protected:
00720     Space& s;
00722     Propagator* p;
00723   public:
00725 
00726 
00727     Home(Space& s, Propagator* p=NULL);
00729     Home& operator =(const Home& h);
00731     operator Space&(void);
00733 
00734 
00735 
00736     Home operator ()(Propagator& p);
00738     Propagator* propagator(void) const;
00740 
00741 
00742 
00743     bool failed(void) const;
00745     void fail(void);
00747     void notice(Actor& a, ActorProperty p, bool duplicate=false);
00749   };
00750 
00755   class GECODE_VTABLE_EXPORT Propagator : public Actor {
00756     friend class ActorLink;
00757     friend class Space;
00758     template<class VIC> friend class VarImp;
00759     friend class Advisor;
00760     template<class A> friend class Council;
00761   private:
00762     union {
00764       ModEventDelta med;
00766       size_t size;
00768       Gecode::ActorLink* advisors;
00769     } u;
00771     GlobalAFC::Counter& gafc;
00773     static Propagator* cast(ActorLink* al);
00775     static const Propagator* cast(const ActorLink* al);
00776   protected:
00778     Propagator(Home home);
00780     Propagator(Space& home, bool share, Propagator& p);
00782     Propagator* fwd(void) const;
00783 
00784   public:
00786 
00787 
00810     virtual ExecStatus propagate(Space& home, const ModEventDelta& med) = 0;
00812     virtual PropCost cost(const Space& home, const ModEventDelta& med) const = 0;
00820     ModEventDelta modeventdelta(void) const;
00856     GECODE_KERNEL_EXPORT
00857     virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00859 
00860 
00861 
00862     double afc(const Space& home) const;
00864   };
00865 
00866 
00874   template<class A>
00875   class Council {
00876     friend class Advisor;
00877     friend class Advisors<A>;
00878   private:
00880     mutable ActorLink* advisors;
00881   public:
00883     Council(void);
00885     Council(Space& home);
00887     bool empty(void) const;
00889     void update(Space& home, bool share, Council<A>& c);
00891     void dispose(Space& home);
00892   };
00893 
00894 
00899   template<class A>
00900   class Advisors {
00901   private:
00903     ActorLink* a;
00904   public:
00906     Advisors(const Council<A>& c);
00908     bool operator ()(void) const;
00910     void operator ++(void);
00912     A& advisor(void) const;
00913   };
00914 
00915 
00926   class Advisor : private ActorLink {
00927     template<class VIC> friend class VarImp;
00928     template<class A> friend class Council;
00929     template<class A> friend class Advisors;
00930   private:
00932     bool disposed(void) const;
00934     static Advisor* cast(ActorLink* al);
00936     static const Advisor* cast(const ActorLink* al);
00937   protected:
00939     Propagator& propagator(void) const;
00940   public:
00942     template<class A>
00943     Advisor(Space& home, Propagator& p, Council<A>& c);
00945     Advisor(Space& home, bool share, Advisor& a);
00946 
00948 
00949 
00950     template<class A>
00951     void dispose(Space& home, Council<A>& c);
00953     static void* operator new(size_t s, Space& home);
00955     static void  operator delete(void* p, Space& home);
00957   private:
00958 #ifndef __GNUC__
00959 
00960     static void  operator delete(void* p);
00961 #endif
00962 
00963     static void* operator new(size_t s);
00964   };
00965 
00966 
00971   class GECODE_VTABLE_EXPORT NGL {
00972   private:
00974     void* nl;
00975   public:
00977     enum Status {
00978       FAILED,   
00979       SUBSUMED, 
00980       NONE      
00981     };
00983     NGL(void);
00985     NGL(Space& home);
00987     NGL(Space& home, bool share, NGL& ngl);
00989     virtual void subscribe(Space& home, Propagator& p) = 0;
00991     virtual void cancel(Space& home, Propagator& p) = 0;
00993     virtual NGL::Status status(const Space& home) const = 0;
00995     virtual ExecStatus prune(Space& home) = 0;
00997     virtual NGL* copy(Space& home, bool share) = 0;
00999     GECODE_KERNEL_EXPORT
01000     virtual bool notice(void) const;
01002     virtual size_t dispose(Space& home);
01004 
01005 
01006     bool leaf(void) const;
01008     NGL* next(void) const;
01010     void leaf(bool l);
01012     void next(NGL* n);
01014     NGL* add(NGL* n, bool l);
01016 
01017 
01018 
01019     static void* operator new(size_t s, Space& home);
01021     static void  operator delete(void* s, Space& home);
01023     static void  operator delete(void* p);
01025   };
01026 
01036   class GECODE_VTABLE_EXPORT Choice {
01037     friend class Space;
01038   private:
01039     unsigned int _id;  
01040     unsigned int _alt; 
01041 
01043     unsigned int id(void) const;
01044   protected:
01046     Choice(const Brancher& b, const unsigned int a);
01047   public:
01049     unsigned int alternatives(void) const;
01051     GECODE_KERNEL_EXPORT virtual ~Choice(void);
01053     virtual size_t size(void) const = 0;
01055     static void* operator new(size_t);
01057     static void  operator delete(void*);
01059     GECODE_KERNEL_EXPORT virtual void archive(Archive& e) const;
01060   };
01061 
01071   class GECODE_VTABLE_EXPORT Brancher : public Actor {
01072     friend class ActorLink;
01073     friend class Space;
01074     friend class Choice;
01075   private:
01077     unsigned int _id;
01079     static Brancher* cast(ActorLink* al);
01081     static const Brancher* cast(const ActorLink* al);
01082   protected:
01084     Brancher(Home home);
01086     Brancher(Space& home, bool share, Brancher& b);
01087   public:
01089 
01090 
01091     unsigned int id(void) const;
01100     virtual bool status(const Space& home) const = 0;
01108     virtual const Choice* choice(Space& home) = 0;
01110     virtual const Choice* choice(const Space& home, Archive& e) = 0;
01117     virtual ExecStatus commit(Space& home, const Choice& c, 
01118                               unsigned int a) = 0;
01132     GECODE_KERNEL_EXPORT 
01133     virtual NGL* ngl(Space& home, const Choice& c, unsigned int a) const;
01143     GECODE_KERNEL_EXPORT 
01144     virtual void print(const Space& home, const Choice& c, unsigned int a,
01145                        std::ostream& o) const;
01147   };
01148 
01157   class BrancherHandle {
01158   private:
01160     unsigned int _id;
01161   public:
01163     BrancherHandle(void);
01165     BrancherHandle(const Brancher& b);
01167     void update(Space& home, bool share, BrancherHandle& bh);
01169     unsigned int id(void) const;
01171     bool operator ()(const Space& home) const;
01173     void kill(Space& home);
01174   };
01175 
01183   class LocalObject : public Actor {
01184     friend class ActorLink;
01185     friend class Space;
01186     friend class LocalHandle;
01187   protected:
01189     LocalObject(Home home);
01191     LocalObject(Space& home, bool share, LocalObject& l);
01193     static LocalObject* cast(ActorLink* al);
01195     static const LocalObject* cast(const ActorLink* al);
01196   private:
01198     GECODE_KERNEL_EXPORT void fwdcopy(Space& home, bool share);
01199   public:
01201     LocalObject* fwd(Space& home, bool share);
01202   };
01203 
01210   class LocalHandle {
01211   private:
01213     LocalObject* o;
01214   protected:
01216     LocalHandle(void);
01218     LocalHandle(LocalObject* lo);
01220     LocalHandle(const LocalHandle& lh);
01221   public:
01223     LocalHandle& operator =(const LocalHandle& lh);
01225     void update(Space& home, bool share, LocalHandle& lh);
01227     ~LocalHandle(void);
01228   protected:
01230     LocalObject* object(void) const;
01232     void object(LocalObject* n);
01233   };
01234 
01235 
01240   class GECODE_VTABLE_EXPORT NoGoods {
01241   protected:
01243     unsigned long int n;
01244   public:
01246     NoGoods(void);
01248     GECODE_KERNEL_EXPORT 
01249     virtual void post(Space& home) const;
01251     unsigned long int ng(void) const;
01253     void ng(unsigned long int n);
01255     virtual ~NoGoods(void);
01257     GECODE_KERNEL_EXPORT
01258     static NoGoods eng;
01259   };
01260 
01265   class GECODE_VTABLE_EXPORT CRI {
01266   protected:
01268     const unsigned long int r;
01270     const unsigned long int s;
01272     const unsigned long int f;
01274     const Space* l;
01276     const NoGoods& ng;
01277   public:
01279     CRI(unsigned long int r,
01280         unsigned long int s,
01281         unsigned long int f,
01282         const Space* l,
01283         NoGoods& ng);
01285     unsigned long int restart(void) const;
01287     unsigned long int solution(void) const;
01289     unsigned long int fail(void) const;
01291     const Space* last(void) const;
01293     const NoGoods& nogoods(void) const;
01294   };
01295 
01300   enum SpaceStatus {
01301     SS_FAILED, 
01302     SS_SOLVED, 
01303     SS_BRANCH  
01304   };
01305 
01310   class StatusStatistics {
01311   public:
01313     unsigned long int propagate;
01315     bool wmp;
01317     StatusStatistics(void);
01319     void reset(void);
01321     StatusStatistics operator +(const StatusStatistics& s);
01323     StatusStatistics& operator +=(const StatusStatistics& s);
01324   };
01325 
01330   class CloneStatistics {
01331   public:
01333     CloneStatistics(void);
01335     void reset(void);
01337     CloneStatistics operator +(const CloneStatistics& s);
01339     CloneStatistics& operator +=(const CloneStatistics& s);
01340   };
01341 
01346   class CommitStatistics {
01347   public:
01349     CommitStatistics(void);
01351     void reset(void);
01353     CommitStatistics operator +(const CommitStatistics& s);
01355     CommitStatistics& operator +=(const CommitStatistics& s);
01356   };
01357 
01358 
01362   class GECODE_VTABLE_EXPORT Space {
01363     friend class Actor;
01364     friend class Propagator;
01365     friend class Brancher;
01366     friend class Advisor;
01367     template<class VIC> friend class VarImp;
01368     template<class VarImp> friend class VarImpDisposer;
01369     friend class SharedHandle;
01370     friend class LocalObject;
01371     friend class Region;
01372     friend class AFC;
01373     friend class BrancherHandle;
01374   private:
01376     SharedMemory* sm;
01378     MemoryManager mm;
01380     GlobalAFC gafc;
01382     ActorLink pl;
01384     ActorLink bl;
01390     Brancher* b_status;
01402     Brancher* b_commit;
01404     Brancher* brancher(unsigned int id);
01406     GECODE_KERNEL_EXPORT
01407     void kill_brancher(unsigned int id);
01409     static const unsigned reserved_branch_id = 0U;
01410     union {
01412       struct {
01425         ActorLink* active;
01427         ActorLink queue[PropCost::AC_MAX+1];
01429         unsigned int branch_id;
01431         unsigned int n_sub;
01432       } p;
01434       struct {
01436         VarImpBase* vars_u[AllVarConf::idx_c];
01438         VarImpBase* vars_noidx;
01440         SharedHandle::Object* shared;
01442         LocalObject* local;
01443       } c;
01444     } pc;
01446     void enqueue(Propagator* p);
01451 #ifdef GECODE_HAS_VAR_DISPOSE
01452 
01453     GECODE_KERNEL_EXPORT static VarImpDisposerBase* vd[AllVarConf::idx_d];
01455     VarImpBase* _vars_d[AllVarConf::idx_d];
01457     template<class VIC> VarImpBase* vars_d(void) const;
01459     template<class VIC> void vars_d(VarImpBase* x);
01460 #endif
01461 
01462     void update(ActorLink** sub);
01464 
01466     Actor** d_fst;
01468     Actor** d_cur;
01470     Actor** d_lst;
01471 
01483     unsigned int _wmp_afc;
01485     void afc_enable(void);
01487     bool afc_enabled(void) const;
01489     void wmp(unsigned int n);
01491     unsigned int wmp(void) const;
01492 
01494     GECODE_KERNEL_EXPORT static StatusStatistics unused_status;
01496     GECODE_KERNEL_EXPORT static CloneStatistics unused_clone;
01498     GECODE_KERNEL_EXPORT static CommitStatistics unused_commit;
01499 
01518     GECODE_KERNEL_EXPORT Space* _clone(bool share=true);
01519 
01552     GECODE_KERNEL_EXPORT
01553     void _commit(const Choice& c, unsigned int a);
01554 
01585     GECODE_KERNEL_EXPORT
01586     void _trycommit(const Choice& c, unsigned int a);
01587 
01588   public:
01593     GECODE_KERNEL_EXPORT Space(void);
01598     GECODE_KERNEL_EXPORT virtual ~Space(void);
01609     GECODE_KERNEL_EXPORT Space(bool share, Space& s);
01616     virtual Space* copy(bool share) = 0;
01627     GECODE_KERNEL_EXPORT virtual void constrain(const Space& best);
01642     GECODE_KERNEL_EXPORT 
01643     virtual bool master(const CRI& cri);
01662     GECODE_KERNEL_EXPORT 
01663     virtual bool slave(const CRI& cri);
01668     static void* operator new(size_t);
01673     static void  operator delete(void*);
01674 
01675 
01676     /*
01677      * Member functions for search engines
01678      *
01679      */
01680 
01692     GECODE_KERNEL_EXPORT
01693     SpaceStatus status(StatusStatistics& stat=unused_status);
01694 
01726     GECODE_KERNEL_EXPORT
01727     const Choice* choice(void);
01728 
01738     GECODE_KERNEL_EXPORT
01739     const Choice* choice(Archive& e) const;
01740   
01761     Space* clone(bool share=true, CloneStatistics& stat=unused_clone) const;
01762 
01797     void commit(const Choice& c, unsigned int a,
01798                 CommitStatistics& stat=unused_commit);
01831     void trycommit(const Choice& c, unsigned int a,
01832                    CommitStatistics& stat=unused_commit);
01851     GECODE_KERNEL_EXPORT
01852     NGL* ngl(const Choice& c, unsigned int a);
01853 
01868     GECODE_KERNEL_EXPORT
01869     void print(const Choice& c, unsigned int a, std::ostream& o) const;
01870 
01879     GECODE_KERNEL_EXPORT
01880     void notice(Actor& a, ActorProperty p, bool duplicate=false);
01888     GECODE_KERNEL_EXPORT
01889     void ignore(Actor& a, ActorProperty p, bool duplicate=false);
01890 
01891 
01902     ExecStatus ES_SUBSUMED(Propagator& p);
01917     ExecStatus ES_SUBSUMED_DISPOSED(Propagator& p, size_t s);
01928     ExecStatus ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med);
01939     ExecStatus ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med);
01940     
01951     template<class A>
01952     ExecStatus ES_FIX_DISPOSE(Council<A>& c, A& a);
01963     template<class A>
01964     ExecStatus ES_NOFIX_DISPOSE(Council<A>& c, A& a);
01976     template<class A>
01977     ExecStatus ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a);
01978     
01986     void fail(void);
01995     bool failed(void) const;
02000     bool stable(void) const;
02007     GECODE_KERNEL_EXPORT unsigned int propagators(void) const;
02014     GECODE_KERNEL_EXPORT unsigned int branchers(void) const;
02015 
02017 
02018 
02019     Home operator ()(Propagator& p);
02021 
02033     template<class T>
02034     T* alloc(long unsigned int n);
02041     template<class T>
02042     T* alloc(long int n);
02049     template<class T>
02050     T* alloc(unsigned int n);
02057     template<class T>
02058     T* alloc(int n);
02068     template<class T>
02069     void free(T* b, long unsigned int n);
02079     template<class T>
02080     void free(T* b, long int n);
02090     template<class T>
02091     void free(T* b, unsigned int n);
02101     template<class T>
02102     void free(T* b, int n);
02114     template<class T>
02115     T* realloc(T* b, long unsigned int n, long unsigned int m);
02127     template<class T>
02128     T* realloc(T* b, long int n, long int m);
02140     template<class T>
02141     T* realloc(T* b, unsigned int n, unsigned int m);
02153     template<class T>
02154     T* realloc(T* b, int n, int m);
02162     template<class T>
02163     T** realloc(T** b, long unsigned int n, long unsigned int m);
02171     template<class T>
02172     T** realloc(T** b, long int n, long int m);
02180     template<class T>
02181     T** realloc(T** b, unsigned int n, unsigned int m);
02189     template<class T>
02190     T** realloc(T** b, int n, int m);
02192     void* ralloc(size_t s);
02194     void rfree(void* p, size_t s);
02196     void* rrealloc(void* b, size_t n, size_t m);
02198     template<size_t> void* fl_alloc(void);
02204     template<size_t> void  fl_dispose(FreeList* f, FreeList* l);
02213     GECODE_KERNEL_EXPORT void flush(void);
02215 
02216 
02217 
02220     template<class T> 
02221     T& construct(void);
02227     template<class T, typename A1> 
02228     T& construct(A1 const& a1);
02234     template<class T, typename A1, typename A2> 
02235     T& construct(A1 const& a1, A2 const& a2);
02241     template<class T, typename A1, typename A2, typename A3>
02242     T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
02248     template<class T, typename A1, typename A2, typename A3, typename A4>
02249     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
02255     template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
02256     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
02258 
02264     class Propagators {
02265     private:
02267       const Space& home;
02269       const ActorLink* q;
02271       const ActorLink* c;
02273       const ActorLink* e;
02274     public:
02276       Propagators(const Space& home);
02278       bool operator ()(void) const;
02280       void operator ++(void);
02282       const Propagator& propagator(void) const;
02283     };
02284 
02290     class Branchers {
02291     private:
02293       const ActorLink* c;
02295       const ActorLink* e;
02296     public:
02298       Branchers(const Space& home);
02300       bool operator ()(void) const;
02302       void operator ++(void);
02304       const Brancher& brancher(void) const;
02305     };    
02306 
02308 
02309 
02310     GECODE_KERNEL_EXPORT
02311     void afc_decay(double d);
02313     double afc_decay(void) const;
02315     GECODE_KERNEL_EXPORT
02316     void afc_set(double a);
02318   };
02319 
02320 
02321 
02322 
02323   /*
02324    * Memory management
02325    *
02326    */
02327 
02328   // Heap allocated
02329   forceinline void*
02330   SharedHandle::Object::operator new(size_t s) {
02331     return heap.ralloc(s);
02332   }
02333   forceinline void
02334   SharedHandle::Object::operator delete(void* p) {
02335     heap.rfree(p);
02336   }
02337 
02338   forceinline void*
02339   Space::operator new(size_t s) {
02340     return heap.ralloc(s);
02341   }
02342   forceinline void
02343   Space::operator delete(void* p) {
02344     heap.rfree(p);
02345   }
02346 
02347   forceinline void
02348   Choice::operator delete(void* p) {
02349     heap.rfree(p);
02350   }
02351   forceinline void*
02352   Choice::operator new(size_t s) {
02353     return heap.ralloc(s);
02354   }
02355 
02356 
02357   // Space allocation: general space heaps and free lists
02358   forceinline void*
02359   Space::ralloc(size_t s) {
02360     return mm.alloc(sm,s);
02361   }
02362   forceinline void
02363   Space::rfree(void* p, size_t s) {
02364     return mm.reuse(p,s);
02365   }
02366   forceinline void*
02367   Space::rrealloc(void* _b, size_t n, size_t m) {
02368     char* b = static_cast<char*>(_b);
02369     if (n < m) {
02370       char* p = static_cast<char*>(ralloc(m));
02371       memcpy(p,b,n);
02372       rfree(b,n);
02373       return p;
02374     } else {
02375       rfree(b+m,m-n);
02376       return b;
02377     }
02378   }
02379 
02380   template<size_t s>
02381   forceinline void*
02382   Space::fl_alloc(void) {
02383     return mm.template fl_alloc<s>(sm);
02384   }
02385   template<size_t s>
02386   forceinline void
02387   Space::fl_dispose(FreeList* f, FreeList* l) {
02388     mm.template fl_dispose<s>(f,l);
02389   }
02390 
02391   /*
02392    * Typed allocation routines
02393    *
02394    */
02395   template<class T>
02396   forceinline T*
02397   Space::alloc(long unsigned int n) {
02398     T* p = static_cast<T*>(ralloc(sizeof(T)*n));
02399     for (long unsigned int i=n; i--; )
02400       (void) new (p+i) T();
02401     return p;
02402   }
02403   template<class T>
02404   forceinline T*
02405   Space::alloc(long int n) {
02406     assert(n >= 0);
02407     return alloc<T>(static_cast<long unsigned int>(n));
02408   }
02409   template<class T>
02410   forceinline T*
02411   Space::alloc(unsigned int n) {
02412     return alloc<T>(static_cast<long unsigned int>(n));
02413   }
02414   template<class T>
02415   forceinline T*
02416   Space::alloc(int n) {
02417     assert(n >= 0);
02418     return alloc<T>(static_cast<long unsigned int>(n));
02419   }
02420 
02421   template<class T>
02422   forceinline void
02423   Space::free(T* b, long unsigned int n) {
02424     for (long unsigned int i=n; i--; )
02425       b[i].~T();
02426     rfree(b,n*sizeof(T));
02427   }
02428   template<class T>
02429   forceinline void
02430   Space::free(T* b, long int n) {
02431     assert(n >= 0);
02432     free<T>(b,static_cast<long unsigned int>(n));
02433   }
02434   template<class T>
02435   forceinline void
02436   Space::free(T* b, unsigned int n) {
02437     free<T>(b,static_cast<long unsigned int>(n));
02438   }
02439   template<class T>
02440   forceinline void
02441   Space::free(T* b, int n) {
02442     assert(n >= 0);
02443     free<T>(b,static_cast<long unsigned int>(n));
02444   }
02445 
02446   template<class T>
02447   forceinline T*
02448   Space::realloc(T* b, long unsigned int n, long unsigned int m) {
02449     if (n < m) {
02450       T* p = static_cast<T*>(ralloc(sizeof(T)*m));
02451       for (long unsigned int i=n; i--; )
02452         (void) new (p+i) T(b[i]);
02453       for (long unsigned int i=n; i<m; i++)
02454         (void) new (p+i) T();
02455       free<T>(b,n);
02456       return p;
02457     } else {
02458       free<T>(b+m,m-n);
02459       return b;
02460     }
02461   }
02462   template<class T>
02463   forceinline T*
02464   Space::realloc(T* b, long int n, long int m) {
02465     assert((n >= 0) && (m >= 0));
02466     return realloc<T>(b,static_cast<long unsigned int>(n),
02467                       static_cast<long unsigned int>(m));
02468   }
02469   template<class T>
02470   forceinline T*
02471   Space::realloc(T* b, unsigned int n, unsigned int m) {
02472     return realloc<T>(b,static_cast<long unsigned int>(n),
02473                       static_cast<long unsigned int>(m));
02474   }
02475   template<class T>
02476   forceinline T*
02477   Space::realloc(T* b, int n, int m) {
02478     assert((n >= 0) && (m >= 0));
02479     return realloc<T>(b,static_cast<long unsigned int>(n),
02480                       static_cast<long unsigned int>(m));
02481   }
02482 
02483 #define GECODE_KERNEL_REALLOC(T)                                        \
02484   template<>                                                            \
02485   forceinline T*                                                        \
02486   Space::realloc<T>(T* b, long unsigned int n, long unsigned int m) {   \
02487     return static_cast<T*>(rrealloc(b,n*sizeof(T),m*sizeof(T)));        \
02488   }                                                                     \
02489   template<>                                                            \
02490   forceinline T*                                                        \
02491   Space::realloc<T>(T* b, long int n, long int m) {                     \
02492     assert((n >= 0) && (m >= 0));                                       \
02493     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02494                       static_cast<long unsigned int>(m));               \
02495   }                                                                     \
02496   template<>                                                            \
02497   forceinline T*                                                        \
02498   Space::realloc<T>(T* b, unsigned int n, unsigned int m) {             \
02499     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02500                       static_cast<long unsigned int>(m));               \
02501   }                                                                     \
02502   template<>                                                            \
02503   forceinline T*                                                        \
02504   Space::realloc<T>(T* b, int n, int m) {                               \
02505     assert((n >= 0) && (m >= 0));                                       \
02506     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02507                       static_cast<long unsigned int>(m));               \
02508   }
02509 
02510   GECODE_KERNEL_REALLOC(bool)
02511   GECODE_KERNEL_REALLOC(signed char)
02512   GECODE_KERNEL_REALLOC(unsigned char)
02513   GECODE_KERNEL_REALLOC(signed short int)
02514   GECODE_KERNEL_REALLOC(unsigned short int)
02515   GECODE_KERNEL_REALLOC(signed int)
02516   GECODE_KERNEL_REALLOC(unsigned int)
02517   GECODE_KERNEL_REALLOC(signed long int)
02518   GECODE_KERNEL_REALLOC(unsigned long int)
02519   GECODE_KERNEL_REALLOC(float)
02520   GECODE_KERNEL_REALLOC(double)
02521 
02522 #undef GECODE_KERNEL_REALLOC
02523 
02524   template<class T>
02525   forceinline T**
02526   Space::realloc(T** b, long unsigned int n, long unsigned int m) {
02527     return static_cast<T**>(rrealloc(b,n*sizeof(T),m*sizeof(T*)));
02528   }
02529   template<class T>
02530   forceinline T**
02531   Space::realloc(T** b, long int n, long int m) {
02532     assert((n >= 0) && (m >= 0));
02533     return realloc<T*>(b,static_cast<long unsigned int>(n),
02534                        static_cast<long unsigned int>(m));
02535   }
02536   template<class T>
02537   forceinline T**
02538   Space::realloc(T** b, unsigned int n, unsigned int m) {
02539     return realloc<T*>(b,static_cast<long unsigned int>(n),
02540                        static_cast<long unsigned int>(m));
02541   }
02542   template<class T>
02543   forceinline T**
02544   Space::realloc(T** b, int n, int m) {
02545     assert((n >= 0) && (m >= 0));
02546     return realloc<T*>(b,static_cast<long unsigned int>(n),
02547                        static_cast<long unsigned int>(m));
02548   }
02549 
02550 
02551 #ifdef GECODE_HAS_VAR_DISPOSE
02552   template<class VIC>
02553   forceinline VarImpBase*
02554   Space::vars_d(void) const {
02555     return _vars_d[VIC::idx_d];
02556   }
02557   template<class VIC>
02558   forceinline void
02559   Space::vars_d(VarImpBase* x) {
02560     _vars_d[VIC::idx_d] = x;
02561   }
02562 #endif
02563 
02564   // Space allocated entities: Actors, variable implementations, and advisors
02565   forceinline void
02566   Actor::operator delete(void*) {}
02567   forceinline void
02568   Actor::operator delete(void*, Space&) {}
02569   forceinline void*
02570   Actor::operator new(size_t s, Space& home) {
02571     return home.ralloc(s);
02572   }
02573 
02574   template<class VIC>
02575   forceinline void
02576   VarImp<VIC>::operator delete(void*) {}
02577   template<class VIC>
02578   forceinline void
02579   VarImp<VIC>::operator delete(void*, Space&) {}
02580   template<class VIC>
02581   forceinline void*
02582   VarImp<VIC>::operator new(size_t s, Space& home) {
02583     return home.ralloc(s);
02584   }
02585 
02586 #ifndef __GNUC__
02587   forceinline void
02588   Advisor::operator delete(void*) {}
02589 #endif
02590   forceinline void
02591   Advisor::operator delete(void*, Space&) {}
02592   forceinline void*
02593   Advisor::operator new(size_t s, Space& home) {
02594     return home.ralloc(s);
02595   }
02596 
02597   forceinline void
02598   NGL::operator delete(void*) {}
02599   forceinline void
02600   NGL::operator delete(void*, Space&) {}
02601   forceinline void*
02602   NGL::operator new(size_t s, Space& home) {
02603     return home.ralloc(s);
02604   }
02605 
02606   /*
02607    * Shared objects and handles
02608    *
02609    */
02610   forceinline
02611   SharedHandle::Object::Object(void)
02612     : next(NULL), fwd(NULL), use_cnt(0) {}
02613   forceinline
02614   SharedHandle::Object::~Object(void) {
02615     assert(use_cnt == 0);
02616   }
02617 
02618   forceinline SharedHandle::Object*
02619   SharedHandle::object(void) const {
02620     return o;
02621   }
02622   forceinline void
02623   SharedHandle::subscribe(void) {
02624     if (o != NULL) o->use_cnt++;
02625   }
02626   forceinline void
02627   SharedHandle::cancel(void) {
02628     if ((o != NULL) && (--o->use_cnt == 0))
02629       delete o;
02630     o=NULL;
02631   }
02632   forceinline void
02633   SharedHandle::object(SharedHandle::Object* n) {
02634     if (n != o) {
02635       cancel(); o=n; subscribe();
02636     }
02637   }
02638   forceinline
02639   SharedHandle::SharedHandle(void) : o(NULL) {}
02640   forceinline
02641   SharedHandle::SharedHandle(SharedHandle::Object* so) : o(so) {
02642     subscribe();
02643   }
02644   forceinline
02645   SharedHandle::SharedHandle(const SharedHandle& sh) : o(sh.o) {
02646     subscribe();
02647   }
02648   forceinline SharedHandle&
02649   SharedHandle::operator =(const SharedHandle& sh) {
02650     if (&sh != this) {
02651       cancel(); o=sh.o; subscribe();
02652     }
02653     return *this;
02654   }
02655   forceinline void
02656   SharedHandle::update(Space& home, bool share, SharedHandle& sh) {
02657     if (sh.o == NULL) {
02658       o=NULL; return;
02659     } else if (share) {
02660       o=sh.o;
02661     } else if (sh.o->fwd != NULL) {
02662       o=sh.o->fwd;
02663     } else {
02664       o = sh.o->copy();
02665       sh.o->fwd = o;
02666       sh.o->next = home.pc.c.shared;
02667       home.pc.c.shared = sh.o;
02668     }
02669     subscribe();
02670   }
02671   forceinline
02672   SharedHandle::~SharedHandle(void) {
02673     cancel();
02674   }
02675 
02676 
02677 
02678   /*
02679    * No-goods
02680    *
02681    */
02682   forceinline
02683   NoGoods::NoGoods(void) 
02684     : n(0) {}
02685   forceinline unsigned long int
02686   NoGoods::ng(void) const {
02687     return n;
02688   }
02689   forceinline void
02690   NoGoods::ng(unsigned long int n0) {
02691     n=n0;
02692   }
02693   forceinline
02694   NoGoods::~NoGoods(void) {}
02695 
02696 
02697   /*
02698    * Current restart information
02699    */
02700   forceinline
02701   CRI::CRI(unsigned long int r0,
02702            unsigned long int s0,
02703            unsigned long int f0,
02704            const Space* l0,
02705            NoGoods& ng0)
02706     : r(r0), s(s0), f(f0), l(l0), ng(ng0) {}
02707 
02708   forceinline unsigned long int
02709   CRI::restart(void) const {
02710     return r;
02711   }
02712   forceinline unsigned long int
02713   CRI::solution(void) const {
02714     return s;
02715   }
02716   forceinline unsigned long int
02717   CRI::fail(void) const {
02718     return f;
02719   }
02720   forceinline const Space*
02721   CRI::last(void) const {
02722     return l;
02723   }
02724   forceinline const NoGoods&
02725   CRI::nogoods(void) const {
02726     return ng;
02727   }
02728 
02729 
02730 
02731   /*
02732    * ActorLink
02733    *
02734    */
02735   forceinline ActorLink*
02736   ActorLink::prev(void) const {
02737     return _prev;
02738   }
02739 
02740   forceinline ActorLink*
02741   ActorLink::next(void) const {
02742     return _next;
02743   }
02744 
02745   forceinline ActorLink**
02746   ActorLink::next_ref(void) {
02747     return &_next;
02748   }
02749 
02750   forceinline void
02751   ActorLink::prev(ActorLink* al) {
02752     _prev = al;
02753   }
02754 
02755   forceinline void
02756   ActorLink::next(ActorLink* al) {
02757     _next = al;
02758   }
02759 
02760   forceinline void
02761   ActorLink::unlink(void) {
02762     ActorLink* p = _prev; ActorLink* n = _next;
02763     p->_next = n; n->_prev = p;
02764   }
02765 
02766   forceinline void
02767   ActorLink::init(void) {
02768     _next = this; _prev =this;
02769   }
02770 
02771   forceinline void
02772   ActorLink::head(ActorLink* a) {
02773     // Inserts al at head of link-chain (that is, after this)
02774     ActorLink* n = _next;
02775     this->_next = a; a->_prev = this;
02776     a->_next = n; n->_prev = a;
02777   }
02778 
02779   forceinline void
02780   ActorLink::tail(ActorLink* a) {
02781     // Inserts al at tail of link-chain (that is, before this)
02782     ActorLink* p = _prev;
02783     a->_next = this; this->_prev = a;
02784     p->_next = a; a->_prev = p;
02785   }
02786 
02787   forceinline bool
02788   ActorLink::empty(void) const {
02789     return _next == this;
02790   }
02791 
02792   template<class T>
02793   forceinline ActorLink*
02794   ActorLink::cast(T* a) {
02795     // Turning al into a reference is for gcc, assume is for MSVC
02796     GECODE_NOT_NULL(a);
02797     ActorLink& t = *a;
02798     return static_cast<ActorLink*>(&t);
02799   }
02800 
02801   template<class T>
02802   forceinline const ActorLink*
02803   ActorLink::cast(const T* a) {
02804     // Turning al into a reference is for gcc, assume is for MSVC
02805     GECODE_NOT_NULL(a);
02806     const ActorLink& t = *a;
02807     return static_cast<const ActorLink*>(&t);
02808   }
02809 
02810 
02811   /*
02812    * Actor
02813    *
02814    */
02815   forceinline Actor*
02816   Actor::cast(ActorLink* al) {
02817     // Turning al into a reference is for gcc, assume is for MSVC
02818     GECODE_NOT_NULL(al);
02819     ActorLink& t = *al;
02820     return static_cast<Actor*>(&t);
02821   }
02822 
02823   forceinline const Actor*
02824   Actor::cast(const ActorLink* al) {
02825     // Turning al into a reference is for gcc, assume is for MSVC
02826     GECODE_NOT_NULL(al);
02827     const ActorLink& t = *al;
02828     return static_cast<const Actor*>(&t);
02829   }
02830 
02831   forceinline void
02832   Space::afc_enable(void) {
02833     _wmp_afc |= 1U;
02834   }
02835   forceinline bool
02836   Space::afc_enabled(void) const {
02837     return (_wmp_afc & 1U) != 0U;
02838   }
02839   forceinline void
02840   Space::wmp(unsigned int n) {
02841     _wmp_afc = (_wmp_afc & 1U) | (n << 1);
02842   }
02843   forceinline unsigned int
02844   Space::wmp(void) const {
02845     return _wmp_afc >> 1U;
02846   }
02847 
02848   forceinline void
02849   Home::notice(Actor& a, ActorProperty p, bool duplicate) {
02850     s.notice(a,p,duplicate);
02851   }
02852 
02853   forceinline Space*
02854   Space::clone(bool share, CloneStatistics&) const {
02855     // Clone is only const for search engines. During cloning, several data
02856     // structures are updated (e.g. forwarding pointers), so we have to
02857     // cast away the constness.
02858     return const_cast<Space*>(this)->_clone(share);
02859   }
02860 
02861   forceinline void
02862   Space::commit(const Choice& c, unsigned int a, CommitStatistics&) {
02863     _commit(c,a);
02864   }
02865 
02866   forceinline void
02867   Space::trycommit(const Choice& c, unsigned int a, CommitStatistics&) {
02868     _trycommit(c,a);
02869   }
02870 
02871   forceinline double
02872   Space::afc_decay(void) const {
02873     return gafc.decay();
02874   }
02875 
02876   forceinline size_t
02877   Actor::dispose(Space&) {
02878     return sizeof(*this);
02879   }
02880 
02881 
02882   /*
02883    * Home for posting actors
02884    *
02885    */
02886   forceinline
02887   Home::Home(Space& s0, Propagator* p0) : s(s0), p(p0) {}
02888   forceinline Home&
02889   Home::operator =(const Home& h) {
02890     s=h.s; p=h.p;
02891     return *this;
02892   }
02893   forceinline
02894   Home::operator Space&(void) { 
02895     return s; 
02896   }
02897   forceinline Home
02898   Home::operator ()(Propagator& p) {
02899     return Home(s,&p);
02900   }
02901   forceinline Home
02902   Space::operator ()(Propagator& p) {
02903     return Home(*this,&p);
02904   }
02905   forceinline Propagator*
02906   Home::propagator(void) const {
02907     return p;
02908   }
02909 
02910   /*
02911    * Propagator
02912    *
02913    */
02914   forceinline Propagator*
02915   Propagator::cast(ActorLink* al) {
02916     // Turning al into a reference is for gcc, assume is for MSVC
02917     GECODE_NOT_NULL(al);
02918     ActorLink& t = *al;
02919     return static_cast<Propagator*>(&t);
02920   }
02921 
02922   forceinline const Propagator*
02923   Propagator::cast(const ActorLink* al) {
02924     // Turning al into a reference is for gcc, assume is for MSVC
02925     GECODE_NOT_NULL(al);
02926     const ActorLink& t = *al;
02927     return static_cast<const Propagator*>(&t);
02928   }
02929 
02930   forceinline Propagator*
02931   Propagator::fwd(void) const {
02932     return static_cast<Propagator*>(prev());
02933   }
02934 
02935   forceinline
02936   Propagator::Propagator(Home home) 
02937     : gafc((home.propagator() != NULL) ?
02938            // Inherit time counter information
02939            home.propagator()->gafc :
02940            // New propagator information
02941            static_cast<Space&>(home).gafc.allocate()) {
02942     u.advisors = NULL;
02943     assert((u.med == 0) && (u.size == 0));
02944     static_cast<Space&>(home).pl.head(this);
02945   }
02946 
02947   forceinline
02948   Propagator::Propagator(Space&, bool, Propagator& p) 
02949     : gafc(p.gafc) {
02950     u.advisors = NULL;
02951     assert((u.med == 0) && (u.size == 0));
02952     // Set forwarding pointer
02953     p.prev(this);
02954   }
02955 
02956   forceinline ModEventDelta
02957   Propagator::modeventdelta(void) const {
02958     return u.med;
02959   }
02960 
02961   forceinline double
02962   Propagator::afc(const Space& home) const {
02963     return const_cast<Space&>(home).gafc.afc(gafc);
02964   }
02965 
02966   forceinline ExecStatus
02967   Space::ES_SUBSUMED_DISPOSED(Propagator& p, size_t s) {
02968     p.u.size = s;
02969     return __ES_SUBSUMED;
02970   }
02971 
02972   forceinline ExecStatus
02973   Space::ES_SUBSUMED(Propagator& p) {
02974     p.u.size = p.dispose(*this);
02975     return __ES_SUBSUMED;
02976   }
02977 
02978   forceinline ExecStatus
02979   Space::ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02980     p.u.med = med;
02981     assert(p.u.med != 0);
02982     return __ES_PARTIAL;
02983   }
02984 
02985   forceinline ExecStatus
02986   Space::ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02987     p.u.med = AllVarConf::med_combine(p.u.med,med);
02988     assert(p.u.med != 0);
02989     return __ES_PARTIAL;
02990   }
02991 
02992 
02993 
02994   /*
02995    * Brancher
02996    *
02997    */
02998   forceinline Brancher*
02999   Brancher::cast(ActorLink* al) {
03000     // Turning al into a reference is for gcc, assume is for MSVC
03001     GECODE_NOT_NULL(al);
03002     ActorLink& t = *al;
03003     return static_cast<Brancher*>(&t);
03004   }
03005 
03006   forceinline const Brancher*
03007   Brancher::cast(const ActorLink* al) {
03008     // Turning al into a reference is for gcc, assume is for MSVC
03009     GECODE_NOT_NULL(al);
03010     const ActorLink& t = *al;
03011     return static_cast<const Brancher*>(&t);
03012   }
03013 
03014   forceinline
03015   Brancher::Brancher(Home home) :
03016     _id(static_cast<Space&>(home).pc.p.branch_id++) {
03017     if (static_cast<Space&>(home).pc.p.branch_id == 0U)
03018       throw TooManyBranchers("Brancher::Brancher");
03019     // If no brancher available, make it the first one
03020     if (static_cast<Space&>(home).b_status == &static_cast<Space&>(home).bl) {
03021       static_cast<Space&>(home).b_status = this;
03022       if (static_cast<Space&>(home).b_commit == &static_cast<Space&>(home).bl)
03023         static_cast<Space&>(home).b_commit = this;
03024     }
03025     static_cast<Space&>(home).bl.tail(this);
03026   }
03027 
03028   forceinline
03029   Brancher::Brancher(Space&, bool, Brancher& b)
03030     : _id(b._id) {
03031     // Set forwarding pointer
03032     b.prev(this);
03033   }
03034 
03035   forceinline unsigned int
03036   Brancher::id(void) const {
03037     return _id;
03038   }
03039 
03040   forceinline Brancher*
03041   Space::brancher(unsigned int id) {
03042     /*
03043      * Due to weakly monotonic propagators the following scenario might
03044      * occur: a brancher has been committed with all its available
03045      * choices. Then, propagation determines less information
03046      * than before and the brancher now will create new choices.
03047      * Later, during recomputation, all of these choices
03048      * can be used together, possibly interleaved with 
03049      * choices for other branchers. That means all branchers
03050      * must be scanned to find the matching brancher for the choice.
03051      *
03052      * b_commit tries to optimize scanning as it is most likely that
03053      * recomputation does not generate new choices during recomputation
03054      * and hence b_commit is moved from newer to older branchers.
03055      */
03056     Brancher* b_old = b_commit;
03057     // Try whether we are lucky
03058     while (b_commit != Brancher::cast(&bl))
03059       if (id != b_commit->id())
03060         b_commit = Brancher::cast(b_commit->next());
03061       else
03062         return b_commit;
03063     if (b_commit == Brancher::cast(&bl)) {
03064       // We did not find the brancher, start at the beginning
03065       b_commit = Brancher::cast(bl.next());
03066       while (b_commit != b_old)
03067         if (id != b_commit->id())
03068           b_commit = Brancher::cast(b_commit->next());
03069         else
03070           return b_commit;
03071     }
03072     return NULL;
03073   }
03074   
03075   /*
03076    * Brancher handle
03077    *
03078    */
03079   forceinline
03080   BrancherHandle::BrancherHandle(void)
03081     : _id(Space::reserved_branch_id) {}
03082   forceinline
03083   BrancherHandle::BrancherHandle(const Brancher& b)
03084     : _id(b.id()) {}
03085   forceinline void
03086   BrancherHandle::update(Space&, bool, BrancherHandle& bh) {
03087     _id = bh._id;
03088   }
03089   forceinline unsigned int
03090   BrancherHandle::id(void) const {
03091     return _id;
03092   }
03093   forceinline bool
03094   BrancherHandle::operator ()(const Space& home) const {
03095     return const_cast<Space&>(home).brancher(_id) != NULL;
03096   }
03097   forceinline void
03098   BrancherHandle::kill(Space& home) {
03099     home.kill_brancher(_id);
03100   }
03101 
03102   
03103   /*
03104    * Local objects
03105    *
03106    */
03107 
03108   forceinline LocalObject*
03109   LocalObject::cast(ActorLink* al) {
03110     // Turning al into a reference is for gcc, assume is for MSVC
03111     GECODE_NOT_NULL(al);
03112     ActorLink& t = *al;
03113     return static_cast<LocalObject*>(&t);
03114   }
03115 
03116   forceinline const LocalObject*
03117   LocalObject::cast(const ActorLink* al) {
03118     // Turning al into a reference is for gcc, assume is for MSVC
03119     GECODE_NOT_NULL(al);
03120     const ActorLink& t = *al;
03121     return static_cast<const LocalObject*>(&t);
03122   }
03123 
03124   forceinline
03125   LocalObject::LocalObject(Home) {
03126     ActorLink::cast(this)->prev(NULL);
03127   }
03128 
03129   forceinline
03130   LocalObject::LocalObject(Space&,bool,LocalObject&) {
03131     ActorLink::cast(this)->prev(NULL);
03132   }
03133 
03134   forceinline LocalObject*
03135   LocalObject::fwd(Space& home, bool share) {
03136     if (prev() == NULL)
03137       fwdcopy(home,share);
03138     return LocalObject::cast(prev());
03139   }
03140 
03141   forceinline
03142   LocalHandle::LocalHandle(void) : o(NULL) {}
03143   forceinline
03144   LocalHandle::LocalHandle(LocalObject* lo) : o(lo) {}
03145   forceinline
03146   LocalHandle::LocalHandle(const LocalHandle& lh) : o(lh.o) {}
03147   forceinline LocalHandle&
03148   LocalHandle::operator =(const LocalHandle& lh) {
03149     o = lh.o;
03150     return *this;
03151   }
03152   forceinline
03153   LocalHandle::~LocalHandle(void) {}
03154   forceinline LocalObject*
03155   LocalHandle::object(void) const { return o; }
03156   forceinline void
03157   LocalHandle::object(LocalObject* n) { o = n; }
03158   forceinline void
03159   LocalHandle::update(Space& home, bool share, LocalHandle& lh) {
03160     object(lh.object()->fwd(home,share));
03161   }
03162 
03163 
03164   /*
03165    * Choices
03166    *
03167    */
03168   forceinline
03169   Choice::Choice(const Brancher& b, const unsigned int a)
03170     : _id(b.id()), _alt(a) {}
03171 
03172   forceinline unsigned int
03173   Choice::alternatives(void) const {
03174     return _alt;
03175   }
03176 
03177   forceinline unsigned int
03178   Choice::id(void) const {
03179     return _id;
03180   }
03181 
03182   forceinline
03183   Choice::~Choice(void) {}
03184 
03185 
03186 
03187   /*
03188    * No-good literal
03189    *
03190    */
03191   forceinline bool
03192   NGL::leaf(void) const {
03193     return Support::marked(nl);
03194   }
03195   forceinline NGL*
03196   NGL::next(void) const {
03197     return static_cast<NGL*>(Support::funmark(nl));
03198   }
03199   forceinline void
03200   NGL::leaf(bool l) {
03201     nl = l ? Support::fmark(nl) : Support::funmark(nl);
03202   }
03203   forceinline void
03204   NGL::next(NGL* n) {
03205     nl = Support::marked(nl) ? Support::mark(n) : n;
03206   }
03207   forceinline NGL*
03208   NGL::add(NGL* n, bool l) {
03209     nl = Support::marked(nl) ? Support::mark(n) : n;
03210     n->leaf(l);
03211     return n;
03212   }
03213 
03214   forceinline
03215   NGL::NGL(void) 
03216     : nl(NULL) {}
03217   forceinline
03218   NGL::NGL(Space&) 
03219     : nl(NULL) {}
03220   forceinline
03221   NGL::NGL(Space&, bool, NGL&) 
03222     : nl(NULL) {}
03223   forceinline size_t
03224   NGL::dispose(Space&) {
03225     return sizeof(*this);
03226   }
03227 
03228   /*
03229    * Advisor
03230    *
03231    */
03232   template<class A>
03233   forceinline
03234   Advisor::Advisor(Space&, Propagator& p, Council<A>& c) {
03235     // Store propagator and forwarding in prev()
03236     ActorLink::prev(&p);
03237     // Link to next advisor in next()
03238     ActorLink::next(c.advisors); c.advisors = static_cast<A*>(this);
03239   }
03240 
03241   forceinline
03242   Advisor::Advisor(Space&, bool, Advisor&) {}
03243 
03244   forceinline bool
03245   Advisor::disposed(void) const {
03246     return prev() == NULL;
03247   }
03248 
03249   forceinline Advisor*
03250   Advisor::cast(ActorLink* al) {
03251     return static_cast<Advisor*>(al);
03252   }
03253 
03254   forceinline const Advisor*
03255   Advisor::cast(const ActorLink* al) {
03256     return static_cast<const Advisor*>(al);
03257   }
03258 
03259   forceinline Propagator&
03260   Advisor::propagator(void) const {
03261     assert(!disposed());
03262     return *Propagator::cast(ActorLink::prev());
03263   }
03264 
03265   template<class A>
03266   forceinline void
03267   Advisor::dispose(Space&,Council<A>&) {
03268     assert(!disposed());
03269     ActorLink::prev(NULL);
03270     // Shorten chains of disposed advisors by one, if possible
03271     Advisor* n = Advisor::cast(next());
03272     if ((n != NULL) && n->disposed())
03273       next(n->next());
03274   }
03275 
03276   template<class A>
03277   forceinline ExecStatus
03278   Space::ES_FIX_DISPOSE(Council<A>& c, A& a) {
03279     a.dispose(*this,c);
03280     return ES_FIX;
03281   }
03282 
03283   template<class A>
03284   forceinline ExecStatus
03285   Space::ES_NOFIX_DISPOSE(Council<A>& c, A& a) {
03286     a.dispose(*this,c);
03287     return ES_NOFIX;
03288   }
03289 
03290   template<class A>
03291   forceinline ExecStatus
03292   Space::ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a) {
03293     a.dispose(*this,c);
03294     return ES_NOFIX_FORCE;
03295   }
03296 
03297 
03298 
03299   /*
03300    * Advisor council
03301    *
03302    */
03303   template<class A>
03304   forceinline
03305   Council<A>::Council(void) {}
03306 
03307   template<class A>
03308   forceinline
03309   Council<A>::Council(Space&)
03310     : advisors(NULL) {}
03311 
03312   template<class A>
03313   forceinline bool
03314   Council<A>::empty(void) const {
03315     ActorLink* a = advisors;
03316     while ((a != NULL) && static_cast<A*>(a)->disposed())
03317       a = a->next();
03318     advisors = a;
03319     return a == NULL;
03320   }
03321 
03322   template<class A>
03323   forceinline void
03324   Council<A>::update(Space& home, bool share, Council<A>& c) {
03325     // Skip all disposed advisors
03326     {
03327       ActorLink* a = c.advisors;
03328       while ((a != NULL) && static_cast<A*>(a)->disposed())
03329         a = a->next();
03330       c.advisors = a;
03331     }
03332     // Are there any advisors to be cloned?
03333     if (c.advisors != NULL) {
03334       // The propagator in from-space
03335       Propagator* p_f = &static_cast<A*>(c.advisors)->propagator();
03336       // The propagator in to-space
03337       Propagator* p_t = Propagator::cast(p_f->prev());
03338       // Advisors in from-space
03339       ActorLink** a_f = &c.advisors;
03340       // Advisors in to-space
03341       A* a_t = NULL;
03342       while (*a_f != NULL) {
03343         if (static_cast<A*>(*a_f)->disposed()) {
03344           *a_f = (*a_f)->next();
03345         } else {
03346           // Run specific copying part
03347           A* a = new (home) A(home,share,*static_cast<A*>(*a_f));
03348           // Set propagator pointer
03349           a->prev(p_t);
03350           // Set forwarding pointer
03351           (*a_f)->prev(a);
03352           // Link
03353           a->next(a_t);
03354           a_t = a;
03355           a_f = (*a_f)->next_ref();
03356         }
03357       }
03358       advisors = a_t;
03359       // Enter advisor link for reset
03360       assert(p_f->u.advisors == NULL);
03361       p_f->u.advisors = c.advisors;
03362     } else {
03363       advisors = NULL;
03364     }
03365   }
03366 
03367   template<class A>
03368   forceinline void
03369   Council<A>::dispose(Space& home) {
03370     ActorLink* a = advisors;
03371     while (a != NULL) {
03372       if (!static_cast<A*>(a)->disposed())
03373         static_cast<A*>(a)->dispose(home,*this);
03374       a = a->next();
03375     }
03376   }
03377 
03378 
03379 
03380   /*
03381    * Advisor iterator
03382    *
03383    */
03384   template<class A>
03385   forceinline
03386   Advisors<A>::Advisors(const Council<A>& c)
03387     : a(c.advisors) {
03388     while ((a != NULL) && static_cast<A*>(a)->disposed())
03389       a = a->next();
03390   }
03391 
03392   template<class A>
03393   forceinline bool
03394   Advisors<A>::operator ()(void) const {
03395     return a != NULL;
03396   }
03397 
03398   template<class A>
03399   forceinline void
03400   Advisors<A>::operator ++(void) {
03401     do {
03402       a = a->next();
03403     } while ((a != NULL) && static_cast<A*>(a)->disposed());
03404   }
03405 
03406   template<class A>
03407   forceinline A&
03408   Advisors<A>::advisor(void) const {
03409     return *static_cast<A*>(a);
03410   }
03411 
03412 
03413 
03414   /*
03415    * Space
03416    *
03417    */
03418   forceinline void
03419   Space::enqueue(Propagator* p) {
03420     ActorLink::cast(p)->unlink();
03421     ActorLink* c = &pc.p.queue[p->cost(*this,p->u.med).ac];
03422     c->tail(ActorLink::cast(p));
03423     if (c > pc.p.active)
03424       pc.p.active = c;
03425   }
03426 
03427   forceinline void
03428   Space::fail(void) {
03429     /*
03430      * Now active points beyond the last queue. This is essential as
03431      * enqueuing a propagator in a failed space keeps the space
03432      * failed.
03433      */
03434     pc.p.active = &pc.p.queue[PropCost::AC_MAX+1]+1;
03435   }
03436   forceinline void
03437   Home::fail(void) {
03438     s.fail();
03439   }
03440 
03441   forceinline bool
03442   Space::failed(void) const {
03443     return pc.p.active > &pc.p.queue[PropCost::AC_MAX+1];
03444   }
03445   forceinline bool
03446   Home::failed(void) const {
03447     return s.failed();
03448   }
03449 
03450   forceinline bool
03451   Space::stable(void) const {
03452     return ((pc.p.active < &pc.p.queue[0]) ||
03453             (pc.p.active > &pc.p.queue[PropCost::AC_MAX+1]));
03454   }
03455 
03456 
03457 
03458   /*
03459    * Variable implementation
03460    *
03461    */
03462   template<class VIC>
03463   forceinline ActorLink**
03464   VarImp<VIC>::actor(PropCond pc) {
03465     assert((pc >= 0)  && (pc < pc_max+2));
03466     return (pc == 0) ? b.base : b.base+u.idx[pc-1];
03467   }
03468 
03469   template<class VIC>
03470   forceinline ActorLink**
03471   VarImp<VIC>::actorNonZero(PropCond pc) {
03472     assert((pc > 0)  && (pc < pc_max+2));
03473     return b.base+u.idx[pc-1];
03474   }
03475 
03476   template<class VIC>
03477   forceinline unsigned int&
03478   VarImp<VIC>::idx(PropCond pc) {
03479     assert((pc > 0)  && (pc < pc_max+2));
03480     return u.idx[pc-1];
03481   }
03482 
03483   template<class VIC>
03484   forceinline unsigned int
03485   VarImp<VIC>::idx(PropCond pc) const {
03486     assert((pc > 0)  && (pc < pc_max+2));
03487     return u.idx[pc-1];
03488   }
03489 
03490   template<class VIC>
03491   forceinline
03492   VarImp<VIC>::VarImp(Space&) {
03493     b.base = NULL; entries = 0;
03494     for (PropCond pc=1; pc<pc_max+2; pc++)
03495       idx(pc) = 0;
03496     free_and_bits = 0;
03497   }
03498 
03499   template<class VIC>
03500   forceinline
03501   VarImp<VIC>::VarImp(void) {
03502     b.base = NULL; entries = 0;
03503     for (PropCond pc=1; pc<pc_max+2; pc++)
03504       idx(pc) = 0;
03505     free_and_bits = 0;
03506   }
03507 
03508   template<class VIC>
03509   forceinline unsigned int
03510   VarImp<VIC>::degree(void) const {
03511     assert(!copied());
03512     return entries;
03513   }
03514 
03515   template<class VIC>
03516   forceinline double
03517   VarImp<VIC>::afc(const Space& home) const {
03518     double d = 0.0;
03519     // Count the afc of each propagator
03520     {
03521       ActorLink** a = const_cast<VarImp<VIC>*>(this)->actor(0);
03522       ActorLink** e = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
03523       while (a < e) {
03524         d += Propagator::cast(*a)->afc(home); a++;
03525       }
03526     }
03527     // Count the afc of each advisor's propagator
03528     {
03529       ActorLink** a = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
03530       ActorLink** e = const_cast<VarImp<VIC>*>(this)->b.base+entries;
03531       while (a < e) {
03532         d += Advisor::cast(*a)->propagator().afc(home); a++;
03533       }
03534     }
03535     return d;
03536   }
03537 
03538   template<class VIC>
03539   forceinline ModEvent
03540   VarImp<VIC>::modevent(const Delta& d) {
03541     return d.me;
03542   }
03543 
03544   template<class VIC>
03545   forceinline unsigned int
03546   VarImp<VIC>::bits(void) const {
03547     return free_and_bits;
03548   }
03549 
03550   template<class VIC>
03551   forceinline unsigned int&
03552   VarImp<VIC>::bits(void) {
03553     return free_and_bits;
03554   }
03555 
03556 #ifdef GECODE_HAS_VAR_DISPOSE
03557   template<class VIC>
03558   forceinline VarImp<VIC>*
03559   VarImp<VIC>::vars_d(Space& home) {
03560     return static_cast<VarImp<VIC>*>(home.vars_d<VIC>());
03561   }
03562 
03563   template<class VIC>
03564   forceinline void
03565   VarImp<VIC>::vars_d(Space& home, VarImp<VIC>* x) {
03566     home.vars_d<VIC>(x);
03567   }
03568 #endif
03569 
03570   template<class VIC>
03571   forceinline bool
03572   VarImp<VIC>::copied(void) const {
03573     return Support::marked(b.fwd);
03574   }
03575 
03576   template<class VIC>
03577   forceinline VarImp<VIC>*
03578   VarImp<VIC>::forward(void) const {
03579     assert(copied());
03580     return static_cast<VarImp<VIC>*>(Support::unmark(b.fwd));
03581   }
03582 
03583   template<class VIC>
03584   forceinline VarImp<VIC>*
03585   VarImp<VIC>::next(void) const {
03586     assert(copied());
03587     return u.next;
03588   }
03589 
03590   template<class VIC>
03591   forceinline
03592   VarImp<VIC>::VarImp(Space& home, bool, VarImp<VIC>& x) {
03593     VarImpBase** reg;
03594     free_and_bits = x.free_and_bits & ((1 << free_bits) - 1);
03595     if (x.b.base == NULL) {
03596       // Variable implementation needs no index structure
03597       reg = &home.pc.c.vars_noidx;
03598       assert(x.degree() == 0);
03599     } else {
03600       reg = &home.pc.c.vars_u[idx_c];
03601     }
03602     // Save subscriptions in copy
03603     b.base = x.b.base;
03604     entries = x.entries;
03605     for (PropCond pc=1; pc<pc_max+2; pc++)
03606       idx(pc) = x.idx(pc);
03607 
03608     // Set forwarding pointer
03609     x.b.fwd = static_cast<VarImp<VIC>*>(Support::mark(this));
03610     // Register original
03611     x.u.next = static_cast<VarImp<VIC>*>(*reg); *reg = &x;
03612   }
03613 
03614   template<class VIC>
03615   forceinline ModEvent
03616   VarImp<VIC>::me(const ModEventDelta& med) {
03617     return static_cast<ModEvent>((med & VIC::med_mask) >> VIC::med_fst);
03618   }
03619 
03620   template<class VIC>
03621   forceinline ModEventDelta
03622   VarImp<VIC>::med(ModEvent me) {
03623     return static_cast<ModEventDelta>(me << VIC::med_fst);
03624   }
03625 
03626   template<class VIC>
03627   forceinline ModEvent
03628   VarImp<VIC>::me_combine(ModEvent me1, ModEvent me2) {
03629     return VIC::me_combine(me1,me2);
03630   }
03631 
03632   template<class VIC>
03633   forceinline void
03634   VarImp<VIC>::schedule(Space& home, Propagator& p, ModEvent me,
03635                         bool force) {
03636     if (VIC::med_update(p.u.med,me) || force)
03637       home.enqueue(&p);
03638   }
03639 
03640   template<class VIC>
03641   forceinline void
03642   VarImp<VIC>::schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me) {
03643     ActorLink** b = actor(pc1);
03644     ActorLink** p = actorNonZero(pc2+1);
03645     while (p-- > b)
03646       schedule(home,*Propagator::cast(*p),me);
03647   }
03648 
03649   template<class VIC>
03650   forceinline void
03651   VarImp<VIC>::enter(Space& home, Propagator* p, PropCond pc) {
03652     assert(pc <= pc_max);
03653     // Count one new subscription
03654     home.pc.p.n_sub += 1;
03655     if ((free_and_bits >> free_bits) == 0)
03656       resize(home);
03657     free_and_bits -= 1 << free_bits;
03658 
03659     // Enter subscription
03660     b.base[entries] = *actorNonZero(pc_max+1);
03661     entries++;
03662     for (PropCond j = pc_max; j > pc; j--) {
03663       *actorNonZero(j+1) = *actorNonZero(j);
03664       idx(j+1)++;
03665     }
03666     *actorNonZero(pc+1) = *actor(pc);
03667     idx(pc+1)++;
03668     *actor(pc) = ActorLink::cast(p);
03669 
03670 #ifdef GECODE_AUDIT
03671     ActorLink** f = actor(pc);
03672     while (f < (pc == pc_max+1 ? b.base+entries : actorNonZero(pc+1)))
03673       if (*f == p)
03674         goto found;
03675       else
03676         f++;
03677     GECODE_NEVER;
03678     found: ;
03679 #endif
03680   }
03681 
03682   template<class VIC>
03683   forceinline void
03684   VarImp<VIC>::enter(Space& home, Advisor* a) {
03685     // Count one new subscription
03686     home.pc.p.n_sub += 1;
03687     if ((free_and_bits >> free_bits) == 0)
03688       resize(home);
03689     free_and_bits -= 1 << free_bits;
03690 
03691     // Enter subscription
03692     b.base[entries++] = *actorNonZero(pc_max+1);
03693     *actorNonZero(pc_max+1) = a;
03694   }
03695 
03696   template<class VIC>
03697   void
03698   VarImp<VIC>::resize(Space& home) {
03699     if (b.base == NULL) {
03700       assert((free_and_bits >> free_bits) == 0);
03701       // Create fresh dependency array with four entries
03702       free_and_bits += 4 << free_bits;
03703       b.base = home.alloc<ActorLink*>(4);
03704       for (int i=0; i<pc_max+1; i++)
03705         u.idx[i] = 0;
03706     } else {
03707       // Resize dependency array
03708       unsigned int n = degree();
03709       // Find out whether the area is most likely in the special area
03710       // reserved for subscriptions. If yes, just resize mildly otherwise
03711       // more agressively
03712       ActorLink** s = static_cast<ActorLink**>(home.mm.subscriptions());
03713       unsigned int m =
03714         ((s <= b.base) && (b.base < s+home.pc.p.n_sub)) ?
03715         (n+4) : ((n+1)*3>>1);
03716       ActorLink** prop = home.alloc<ActorLink*>(m);
03717       free_and_bits += (m-n) << free_bits;
03718       // Copy entries
03719       Heap::copy<ActorLink*>(prop, b.base, n);
03720       home.free<ActorLink*>(b.base,n);
03721       b.base = prop;
03722     }
03723   }
03724 
03725   template<class VIC>
03726   void
03727   VarImp<VIC>::subscribe(Space& home, Propagator& p, PropCond pc,
03728                          bool assigned, ModEvent me, bool schedule) {
03729     if (assigned) {
03730       // Do not subscribe, just schedule the propagator
03731       if (schedule)
03732         VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
03733     } else {
03734       enter(home,&p,pc);
03735       // Schedule propagator
03736       if (schedule && (pc != PC_GEN_ASSIGNED))
03737         VarImp<VIC>::schedule(home,p,me);
03738     }
03739   }
03740 
03741   template<class VIC>
03742   forceinline void
03743   VarImp<VIC>::subscribe(Space& home, Advisor& a, bool assigned) {
03744     if (!assigned)
03745       enter(home,&a);
03746   }
03747 
03748   template<class VIC>
03749   forceinline void
03750   VarImp<VIC>::remove(Space& home, Propagator* p, PropCond pc) {
03751     assert(pc <= pc_max);
03752     ActorLink* a = ActorLink::cast(p);
03753     // Find actor in dependency array
03754     ActorLink** f = actor(pc);
03755 #ifdef GECODE_AUDIT
03756     while (f < actorNonZero(pc+1))
03757       if (*f == a)
03758         goto found;
03759       else
03760         f++;
03761     GECODE_NEVER;
03762   found: ;
03763 #else
03764     while (*f != a) f++;
03765 #endif
03766     // Remove actor
03767     *f = *(actorNonZero(pc+1)-1);
03768     for (PropCond j = pc+1; j< pc_max+1; j++) {
03769       *(actorNonZero(j)-1) = *(actorNonZero(j+1)-1);
03770       idx(j)--;
03771     }
03772     *(actorNonZero(pc_max+1)-1) = b.base[entries-1];
03773     idx(pc_max+1)--;
03774     entries--;
03775     free_and_bits += 1 << free_bits;
03776     home.pc.p.n_sub -= 1;
03777   }
03778 
03779   template<class VIC>
03780   forceinline void
03781   VarImp<VIC>::remove(Space& home, Advisor* a) {
03782     // Find actor in dependency array
03783     ActorLink** f = actorNonZero(pc_max+1);
03784 #ifdef GECODE_AUDIT
03785     while (f < b.base+entries)
03786       if (*f == a)
03787         goto found;
03788       else
03789         f++;
03790     GECODE_NEVER;
03791   found: ;
03792 #else
03793     while (*f != a) f++;
03794 #endif
03795     // Remove actor
03796     *f = b.base[--entries];
03797     free_and_bits += 1 << free_bits;
03798     home.pc.p.n_sub -= 1;
03799   }
03800 
03801   template<class VIC>
03802   forceinline void
03803   VarImp<VIC>::cancel(Space& home, Propagator& p, PropCond pc, bool assigned) {
03804     if (!assigned)
03805       remove(home,&p,pc);
03806   }
03807 
03808   template<class VIC>
03809   forceinline void
03810   VarImp<VIC>::cancel(Space& home, Advisor& a, bool assigned) {
03811     if (!assigned)
03812       remove(home,&a);
03813   }
03814 
03815   template<class VIC>
03816   forceinline void
03817   VarImp<VIC>::cancel(Space& home) {
03818     unsigned int n_sub = degree();
03819     home.pc.p.n_sub -= n_sub;
03820     unsigned int n = (free_and_bits >> VIC::free_bits) + n_sub;
03821     home.free<ActorLink*>(b.base,n);
03822     // Must be NULL such that cloning works
03823     b.base = NULL;
03824     // Must be 0 such that degree works
03825     entries = 0;
03826   }
03827 
03828   template<class VIC>
03829   forceinline bool
03830   VarImp<VIC>::advise(Space& home, ModEvent me, Delta& d) {
03831     /*
03832      * An advisor that is executed might remove itself due to subsumption.
03833      * As entries are removed from front to back, the advisors must
03834      * be iterated in forward direction.
03835      */
03836     ActorLink** la = actorNonZero(pc_max+1);
03837     ActorLink** le = b.base+entries;
03838     if (la == le)
03839       return true;
03840     d.me = me;
03841     // An advisor that is run, might be removed during execution.
03842     // As removal is done from the back the advisors have to be executed
03843     // in inverse order.
03844     do {
03845       Advisor* a = Advisor::cast(*la);
03846       assert(!a->disposed());
03847       Propagator& p = a->propagator();
03848       switch (p.advise(home,*a,d)) {
03849       case ES_FIX:
03850         break;
03851       case ES_FAILED:
03852         if (home.afc_enabled())
03853           home.gafc.fail(p.gafc);
03854         return false;
03855       case ES_NOFIX:
03856         schedule(home,p,me);
03857         break;
03858       case ES_NOFIX_FORCE:
03859         schedule(home,p,me,true);
03860         break;
03861       case __ES_SUBSUMED:
03862       default:
03863         GECODE_NEVER;
03864       }
03865     } while (++la < le);
03866     return true;
03867   }
03868 
03869   template<class VIC>
03870   forceinline void
03871   VarImp<VIC>::update(VarImp<VIC>* x, ActorLink**& sub) {
03872     // this refers to the variable to be updated (clone)
03873     // x refers to the original
03874     // Recover from copy
03875     x->b.base = b.base;
03876     x->u.idx[0] = u.idx[0];
03877     if (pc_max > 0 && sizeof(ActorLink**) > sizeof(unsigned int))
03878       x->u.idx[1] = u.idx[1];
03879 
03880     ActorLink** f = x->b.base;
03881     unsigned int n = x->degree();
03882     ActorLink** t = sub;
03883     sub += n;
03884     b.base = t;
03885     // Set subscriptions using actor forwarding pointers
03886     while (n >= 4) {
03887       n -= 4;
03888       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03889       t[2]=f[2]->prev(); t[3]=f[3]->prev();
03890       t += 4; f += 4;
03891     }
03892     if (n >= 2) {
03893       n -= 2;
03894       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03895       t += 2; f += 2;
03896     }
03897     if (n > 0) {
03898       t[0]=f[0]->prev();
03899     }
03900   }
03901 
03902   template<class VIC>
03903   forceinline void
03904   VarImp<VIC>::update(Space& home, ActorLink**& sub) {
03905     VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home.pc.c.vars_u[idx_c]);
03906     while (x != NULL) {
03907       VarImp<VIC>* n = x->next(); x->forward()->update(x,sub); x = n;
03908     }
03909   }
03910 
03911 
03912 
03913   /*
03914    * Variable disposer
03915    *
03916    */
03917   template<class VarImp>
03918   VarImpDisposer<VarImp>::VarImpDisposer(void) {
03919 #ifdef GECODE_HAS_VAR_DISPOSE
03920     Space::vd[VarImp::idx_d] = this;
03921 #endif
03922   }
03923 
03924   template<class VarImp>
03925   void
03926   VarImpDisposer<VarImp>::dispose(Space& home, VarImpBase* _x) {
03927     VarImp* x = static_cast<VarImp*>(_x);
03928     do {
03929       x->dispose(home); x = static_cast<VarImp*>(x->next_d());
03930     } while (x != NULL);
03931   }
03932 
03933   /*
03934    * Statistics
03935    */
03936 
03937   forceinline void
03938   StatusStatistics::reset(void) {
03939     propagate = 0;
03940     wmp = false;
03941   }
03942   forceinline
03943   StatusStatistics::StatusStatistics(void) {
03944     reset();
03945   }
03946   forceinline StatusStatistics&
03947   StatusStatistics::operator +=(const StatusStatistics& s) { 
03948     propagate += s.propagate;
03949     wmp |= s.wmp;
03950     return *this;
03951   }
03952   forceinline StatusStatistics
03953   StatusStatistics::operator +(const StatusStatistics& s) {
03954     StatusStatistics t(s);
03955     return t += *this;
03956   }
03957 
03958   forceinline void
03959   CloneStatistics::reset(void) {}
03960 
03961   forceinline
03962   CloneStatistics::CloneStatistics(void) {
03963     reset();
03964   }
03965   forceinline CloneStatistics
03966   CloneStatistics::operator +(const CloneStatistics&) {
03967     CloneStatistics s;
03968     return s;
03969   }
03970   forceinline CloneStatistics&
03971   CloneStatistics::operator +=(const CloneStatistics&) { 
03972     return *this;
03973   }
03974 
03975   forceinline void
03976   CommitStatistics::reset(void) {}
03977 
03978   forceinline
03979   CommitStatistics::CommitStatistics(void) {
03980     reset();
03981   }
03982   forceinline CommitStatistics
03983   CommitStatistics::operator +(const CommitStatistics&) {
03984     CommitStatistics s;
03985     return s;
03986   }
03987   forceinline CommitStatistics&
03988   CommitStatistics::operator +=(const CommitStatistics&) { 
03989     return *this;
03990   }
03991 
03992   /*
03993    * Cost computation
03994    *
03995    */
03996 
03997   forceinline
03998   PropCost::PropCost(PropCost::ActualCost ac0) : ac(ac0) {}
03999 
04000   forceinline PropCost
04001   PropCost::cost(PropCost::Mod m,
04002                  PropCost::ActualCost lo, PropCost::ActualCost hi,
04003                  unsigned int n) {
04004     if (n < 2)
04005       return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
04006     else if (n == 2)
04007       return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
04008     else if (n == 3)
04009       return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
04010     else
04011       return (m == LO) ? lo : hi;
04012   }
04013 
04014   forceinline PropCost
04015   PropCost::crazy(PropCost::Mod m, unsigned int n) {
04016     return cost(m,AC_CRAZY_LO,AC_CRAZY_HI,n);
04017   }
04018   forceinline PropCost
04019   PropCost::crazy(PropCost::Mod m, int n) {
04020     assert(n >= 0);
04021     return crazy(m,static_cast<unsigned int>(n));
04022   }
04023   forceinline PropCost
04024   PropCost::cubic(PropCost::Mod m, unsigned int n) {
04025     return cost(m,AC_CUBIC_LO,AC_CUBIC_HI,n);
04026   }
04027   forceinline PropCost
04028   PropCost::cubic(PropCost::Mod m, int n) {
04029     assert(n >= 0);
04030     return cubic(m,static_cast<unsigned int>(n));
04031   }
04032   forceinline PropCost
04033   PropCost::quadratic(PropCost::Mod m, unsigned int n) {
04034     return cost(m,AC_QUADRATIC_LO,AC_QUADRATIC_HI,n);
04035   }
04036   forceinline PropCost
04037   PropCost::quadratic(PropCost::Mod m, int n) {
04038     assert(n >= 0);
04039     return quadratic(m,static_cast<unsigned int>(n));
04040   }
04041   forceinline PropCost
04042   PropCost::linear(PropCost::Mod m, unsigned int n) {
04043     return cost(m,AC_LINEAR_LO,AC_LINEAR_HI,n);
04044   }
04045   forceinline PropCost
04046   PropCost::linear(PropCost::Mod m, int n) {
04047     assert(n >= 0);
04048     return linear(m,static_cast<unsigned int>(n));
04049   }
04050   forceinline PropCost
04051   PropCost::ternary(PropCost::Mod m) {
04052     return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
04053   }
04054   forceinline PropCost
04055   PropCost::binary(PropCost::Mod m) {
04056     return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
04057   }
04058   forceinline PropCost
04059   PropCost::unary(PropCost::Mod m) {
04060     return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
04061   }
04062 
04063   /*
04064    * Iterators for propagators and branchers of a space
04065    *
04066    */
04067   forceinline
04068   Space::Propagators::Propagators(const Space& home0) 
04069     : home(home0), q(home.pc.p.active) {
04070     while (q >= &home.pc.p.queue[0]) {
04071       if (q->next() != q) {
04072         c = q->next(); e = q; q--;
04073         return;
04074       }
04075       q--;
04076     }
04077     q = NULL;
04078     if (!home.pl.empty()) {
04079       c = Propagator::cast(home.pl.next());
04080       e = Propagator::cast(&home.pl);
04081     } else {
04082       c = e = NULL;
04083     }
04084   }
04085   forceinline bool 
04086   Space::Propagators::operator ()(void) const {
04087     return c != NULL;
04088   }
04089   forceinline void 
04090   Space::Propagators::operator ++(void) {
04091     c = c->next();
04092     if (c == e) {
04093       if (q == NULL) {
04094         c = NULL;
04095       } else {
04096         while (q >= &home.pc.p.queue[0]) {
04097           if (q->next() != q) {
04098             c = q->next(); e = q; q--;
04099             return;
04100           }
04101           q--;
04102         }
04103         q = NULL;
04104         if (!home.pl.empty()) {
04105           c = Propagator::cast(home.pl.next());
04106           e = Propagator::cast(&home.pl);
04107         } else {
04108           c = NULL;
04109         }
04110       }
04111     }
04112   }
04113   forceinline const Propagator& 
04114   Space::Propagators::propagator(void) const {
04115     return *Propagator::cast(c);
04116   }
04117 
04118   forceinline
04119   Space::Branchers::Branchers(const Space& home) 
04120     : c(Brancher::cast(home.bl.next())), e(&home.bl) {}
04121   forceinline bool 
04122   Space::Branchers::operator ()(void) const {
04123     return c != e;
04124   }
04125   forceinline void 
04126   Space::Branchers::operator ++(void) {
04127     c = c->next();
04128   }
04129   forceinline const Brancher& 
04130   Space::Branchers::brancher(void) const {
04131     return *Brancher::cast(c);
04132   }
04133 
04134   /*
04135    * Space construction support
04136    *
04137    */
04138   template<class T> 
04139   forceinline T& 
04140   Space::construct(void) {
04141     return alloc<T>(1);
04142   }
04143   template<class T, typename A1> 
04144   forceinline T& 
04145   Space::construct(A1 const& a1) {
04146     T& t = *static_cast<T*>(ralloc(sizeof(T)));
04147     new (&t) T(a1);
04148     return t;
04149   }
04150   template<class T, typename A1, typename A2> 
04151   forceinline T& 
04152   Space::construct(A1 const& a1, A2 const& a2) {
04153     T& t = *static_cast<T*>(ralloc(sizeof(T)));
04154     new (&t) T(a1,a2);
04155     return t;
04156   }
04157   template<class T, typename A1, typename A2, typename A3>
04158   forceinline T& 
04159   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
04160     T& t = *static_cast<T*>(ralloc(sizeof(T)));
04161     new (&t) T(a1,a2,a3);
04162     return t;
04163   }
04164   template<class T, typename A1, typename A2, typename A3, typename A4>
04165   forceinline T& 
04166   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
04167     T& t = *static_cast<T*>(ralloc(sizeof(T)));
04168     new (&t) T(a1,a2,a3,a4);
04169     return t;
04170   }
04171   template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
04172   forceinline T& 
04173   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
04174     T& t = *static_cast<T*>(ralloc(sizeof(T)));
04175     new (&t) T(a1,a2,a3,a4,a5);
04176     return t;
04177   }
04178 
04179 }
04180 
04181 // STATISTICS: kernel-core