Generated on Thu Mar 22 10:39:42 2012 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: 2012-02-22 06:18:28 +0100 (Wed, 22 Feb 2012) $ by $Author: tack $
00022  *     $Revision: 12538 $
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 #include <iostream>
00049 namespace Gecode {
00050 
00051   class Space;
00052 
00077   class SharedHandle {
00078   public:
00086     class Object {
00087       friend class Space;
00088       friend class SharedHandle;
00089     private:
00091       Object* next;
00093       Object* fwd;
00095       unsigned int use_cnt;
00096     public:
00098       Object(void);
00100       virtual Object* copy(void) const = 0;
00102       virtual ~Object(void);
00104       static void* operator new(size_t s);
00106       static void  operator delete(void* p);
00107     };
00108   private:
00110     Object* o;
00112     void subscribe(void);
00114     void cancel(void);
00115   public:
00117     SharedHandle(void);
00119     SharedHandle(SharedHandle::Object* so);
00121     SharedHandle(const SharedHandle& sh);
00123     SharedHandle& operator =(const SharedHandle& sh);
00125     void update(Space& home, bool share, SharedHandle& sh);
00127     ~SharedHandle(void);
00128   protected:
00130     SharedHandle::Object* object(void) const;
00132     void object(SharedHandle::Object* n);
00133   };
00134 
00143 
00144   typedef int ModEvent;
00145 
00147   const ModEvent ME_GEN_FAILED   = -1;
00149   const ModEvent ME_GEN_NONE     =  0;
00151   const ModEvent ME_GEN_ASSIGNED =  1;
00152 
00154   typedef int PropCond;
00156   const PropCond PC_GEN_NONE     = -1;
00158   const PropCond PC_GEN_ASSIGNED = 0;
00160 
00171   typedef int ModEventDelta;
00172 
00173 }
00174 
00175 #include <gecode/kernel/var-type.hpp>
00176 
00177 namespace Gecode {
00178 
00180   class NoIdxVarImpConf {
00181   public:
00183     static const int idx_c = -1;
00185     static const int idx_d = -1;
00187     static const PropCond pc_max = PC_GEN_ASSIGNED;
00189     static const int free_bits = 0;
00191     static const int med_fst = 0;
00193     static const int med_lst = 0;
00195     static const int med_mask = 0;
00197     static Gecode::ModEvent me_combine(ModEvent me1, ModEvent me2);
00199     static bool med_update(ModEventDelta& med, ModEvent me);
00200   };
00201 
00202   forceinline ModEvent
00203   NoIdxVarImpConf::me_combine(ModEvent, ModEvent) {
00204     GECODE_NEVER; return 0;
00205   }
00206   forceinline bool
00207   NoIdxVarImpConf::med_update(ModEventDelta&, ModEvent) {
00208     GECODE_NEVER; return false;
00209   }
00210 
00211 
00212   /*
00213    * These are the classes of interest
00214    *
00215    */
00216   class ActorLink;
00217   class Actor;
00218   class Propagator;
00219   class LocalObject;
00220   class Advisor;
00221   template<class A> class Council;
00222   template<class A> class Advisors;
00223   template<class VIC> class VarImp;
00224 
00225 
00226   /*
00227    * Variable implementations
00228    *
00229    */
00230 
00238   class VarImpBase {};
00239 
00246   class GECODE_VTABLE_EXPORT VarImpDisposerBase {
00247   public:
00249     GECODE_KERNEL_EXPORT virtual void dispose(Space& home, VarImpBase* x);
00251     GECODE_KERNEL_EXPORT virtual ~VarImpDisposerBase(void);
00252   };
00253 
00260   template<class VarImp>
00261   class VarImpDisposer : public VarImpDisposerBase {
00262   public:
00264     VarImpDisposer(void);
00266     virtual void dispose(Space& home, VarImpBase* x);
00267   };
00268 
00270   class Delta {
00271     template<class VIC> friend class VarImp;
00272   private:
00274     ModEvent me;
00275   };
00276 
00284   template<class VIC>
00285   class VarImp : public VarImpBase {
00286     friend class Space;
00287     friend class Propagator;
00288     template<class VarImp> friend class VarImpDisposer;
00289   private:
00290     union {
00298       ActorLink** base;
00307       VarImp<VIC>* fwd;
00308     } b;
00309 
00311     static const int idx_c = VIC::idx_c;
00313     static const int idx_d = VIC::idx_d;
00315     static const int free_bits = VIC::free_bits;
00317     unsigned int entries;
00319     unsigned int free_and_bits;
00321     static const Gecode::PropCond pc_max = VIC::pc_max;
00322 
00323     union {
00334       unsigned int idx[pc_max+1];
00336       VarImp<VIC>* next;
00337     } u;
00338 
00340     ActorLink** actor(PropCond pc);
00342     ActorLink** actorNonZero(PropCond pc);
00344     unsigned int& idx(PropCond pc);
00346     unsigned int idx(PropCond pc) const;
00347 
00354     void update(VarImp* x, ActorLink**& sub);
00361     static void update(Space& home, ActorLink**& sub);
00362 
00364     void enter(Space& home, Propagator* p, PropCond pc);
00366     void enter(Space& home, Advisor* a);
00368     void resize(Space& home);
00370     void remove(Space& home, Propagator* p, PropCond pc);
00372     void remove(Space& home, Advisor* a);
00373 
00374 
00375   protected:
00377     void cancel(Space& home);
00383     bool advise(Space& home, ModEvent me, Delta& d);
00384 #ifdef GECODE_HAS_VAR_DISPOSE
00385 
00386     static VarImp<VIC>* vars_d(Space& home);
00388     static void vars_d(Space& home, VarImp<VIC>* x);
00389 #endif
00390 
00391   public:
00393     VarImp(Space& home);
00395     VarImp(void);
00396 
00398 
00399 
00411     void subscribe(Space& home, Propagator& p, PropCond pc,
00412                    bool assigned, ModEvent me, bool schedule);
00418     void cancel(Space& home, Propagator& p, PropCond pc,
00419                 bool assigned);
00425     void subscribe(Space& home, Advisor& a, bool assigned);
00431     void cancel(Space& home, Advisor& a, bool assigned);
00432 
00439     unsigned int degree(void) const;
00446     double afc(void) const;
00448 
00450 
00451 
00452     VarImp(Space& home, bool share, VarImp& x);
00454     bool copied(void) const;
00456     VarImp* forward(void) const;
00458     VarImp* next(void) const;
00460 
00462 
00463 
00470     static void schedule(Space& home, Propagator& p, ModEvent me,
00471                          bool force = false);
00473     static ModEvent me(const ModEventDelta& med);
00475     static ModEventDelta med(ModEvent me);
00477     static ModEvent me_combine(ModEvent me1, ModEvent me2);
00479 
00481 
00482 
00483     static ModEvent modevent(const Delta& d);
00485 
00487 
00488 
00489     unsigned int bits(void) const;
00491     unsigned int& bits(void);
00493 
00494   protected:
00496     void schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me);
00497 
00498   public:
00500 
00501 
00502     static void* operator new(size_t,Space&);
00504     static void  operator delete(void*,Space&);
00506     static void  operator delete(void*);
00508   };
00509 
00518   enum ExecStatus {
00519     __ES_SUBSUMED       = -2, 
00520     ES_FAILED           = -1, 
00521     ES_NOFIX            =  0, 
00522     ES_OK               =  0, 
00523     ES_FIX              =  1, 
00524     ES_NOFIX_FORCE      =  2, 
00525     __ES_PARTIAL        =  2  
00526   };
00527 
00532   class PropCost {
00533     friend class Space;
00534   public:
00536     enum ActualCost {
00537       AC_CRAZY_LO     = 0, 
00538       AC_CRAZY_HI     = 0, 
00539       AC_CUBIC_LO     = 1, 
00540       AC_CUBIC_HI     = 1, 
00541       AC_QUADRATIC_LO = 2, 
00542       AC_QUADRATIC_HI = 2, 
00543       AC_LINEAR_HI    = 3, 
00544       AC_LINEAR_LO    = 4, 
00545       AC_TERNARY_HI   = 4, 
00546       AC_BINARY_HI    = 5, 
00547       AC_TERNARY_LO   = 5, 
00548       AC_BINARY_LO    = 6, 
00549       AC_UNARY_LO     = 6, 
00550       AC_UNARY_HI     = 6, 
00551       AC_MAX          = 6  
00552     };
00554     ActualCost ac;
00555   public:
00557     enum Mod {
00558       LO, 
00559       HI  
00560     };
00561   private:
00563     static PropCost cost(Mod m, ActualCost lo, ActualCost hi, unsigned int n);
00565     PropCost(ActualCost ac);
00566   public:
00568     static PropCost crazy(PropCost::Mod m, unsigned int n);
00570     static PropCost crazy(PropCost::Mod m, int n);
00572     static PropCost cubic(PropCost::Mod m, unsigned int n);
00574     static PropCost cubic(PropCost::Mod m, int n);
00576     static PropCost quadratic(PropCost::Mod m, unsigned int n);
00578     static PropCost quadratic(PropCost::Mod m, int n);
00580     static PropCost linear(PropCost::Mod m, unsigned int n);
00582     static PropCost linear(PropCost::Mod m, int n);
00584     static PropCost ternary(PropCost::Mod m);
00586     static PropCost binary(PropCost::Mod m);
00588     static PropCost unary(PropCost::Mod m);
00589   };
00590 
00591 
00596   enum ActorProperty {
00605     AP_DISPOSE = (1 << 0),
00611     AP_WEAKLY  = (1 << 1)
00612   };
00613 
00614 
00622   class ActorLink {
00623     friend class Actor;
00624     friend class Propagator;
00625     friend class Advisor;
00626     friend class Brancher;
00627     friend class LocalObject;
00628     friend class Space;
00629     template<class VIC> friend class VarImp;
00630   private:
00631     ActorLink* _next; ActorLink* _prev;
00632   public:
00634 
00635     ActorLink* prev(void) const; void prev(ActorLink*);
00636     ActorLink* next(void) const; void next(ActorLink*);
00637     ActorLink** next_ref(void);
00639 
00641     void init(void);
00643     void unlink(void);
00645     void head(ActorLink* al);
00647     void tail(ActorLink* al);
00649     bool empty(void) const;
00651     template<class T> static ActorLink* cast(T* a);
00653     template<class T> static const ActorLink* cast(const T* a);
00654   };
00655 
00656 
00661   class GECODE_VTABLE_EXPORT Actor : private ActorLink {
00662     friend class ActorLink;
00663     friend class Space;
00664     friend class Propagator;
00665     friend class Advisor;
00666     friend class Brancher;
00667     friend class LocalObject;
00668     template<class VIC> friend class VarImp;
00669     template<class A> friend class Council;
00670   private:
00672     static Actor* cast(ActorLink* al);
00674     static const Actor* cast(const ActorLink* al);
00675   public:
00677     virtual Actor* copy(Space& home, bool share) = 0;
00678 
00680 
00681 
00682     GECODE_KERNEL_EXPORT
00683     virtual size_t allocated(void) const;
00685     GECODE_KERNEL_EXPORT
00686     virtual size_t dispose(Space& home);
00688     static void* operator new(size_t s, Space& home);
00690     static void  operator delete(void* p, Space& home);
00691   private:
00692 #ifndef __GNUC__
00693 
00694     static void  operator delete(void* p);
00695 #endif
00696 
00697     static void* operator new(size_t s);
00699 #ifdef __GNUC__
00700   public:
00702     GECODE_KERNEL_EXPORT virtual ~Actor(void);
00704     static void  operator delete(void* p);
00705 #endif
00706   };
00707 
00708 
00709 
00713   class Home {
00714   protected:
00716     Space& s;
00718     Propagator* p;
00719   public:
00721 
00722 
00723     Home(Space& s, Propagator* p=NULL);
00725     operator Space&(void);
00727 
00728 
00729 
00730     Home operator ()(Propagator& p);
00732     Propagator* propagator(void) const;
00734 
00735 
00736 
00737     bool failed(void) const;
00739     void fail(void);
00741     void notice(Actor& a, ActorProperty p);
00743   };
00744 
00749   class GECODE_VTABLE_EXPORT Propagator : public Actor {
00750     friend class ActorLink;
00751     friend class Space;
00752     template<class VIC> friend class VarImp;
00753     friend class Advisor;
00754     template<class A> friend class Council;
00755   private:
00756     union {
00758       ModEventDelta med;
00760       size_t size;
00762       Gecode::ActorLink* advisors;
00763     } u;
00765     PropInfo& pi;
00767     static Propagator* cast(ActorLink* al);
00769     static const Propagator* cast(const ActorLink* al);
00770   protected:
00772     Propagator(Home home);
00774     Propagator(Space& home, bool share, Propagator& p);
00775 
00776   public:
00778 
00779 
00802     virtual ExecStatus propagate(Space& home, const ModEventDelta& med) = 0;
00804     virtual PropCost cost(const Space& home, const ModEventDelta& med) const = 0;
00812     ModEventDelta modeventdelta(void) const;
00848     GECODE_KERNEL_EXPORT
00849     virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00851 
00852 
00853 
00854     double afc(void) const;
00856   };
00857 
00858 
00866   template<class A>
00867   class Council {
00868     friend class Advisor;
00869     friend class Advisors<A>;
00870   private:
00872     mutable ActorLink* advisors;
00873   public:
00875     Council(void);
00877     Council(Space& home);
00879     bool empty(void) const;
00881     void update(Space& home, bool share, Council<A>& c);
00883     void dispose(Space& home);
00884   };
00885 
00886 
00891   template<class A>
00892   class Advisors {
00893   private:
00895     ActorLink* a;
00896   public:
00898     Advisors(const Council<A>& c);
00900     bool operator ()(void) const;
00902     void operator ++(void);
00904     A& advisor(void) const;
00905   };
00906 
00907 
00918   class Advisor : private ActorLink {
00919     template<class VIC> friend class VarImp;
00920     template<class A> friend class Council;
00921     template<class A> friend class Advisors;
00922   private:
00924     bool disposed(void) const;
00926     static Advisor* cast(ActorLink* al);
00928     static const Advisor* cast(const ActorLink* al);
00929   protected:
00931     Propagator& propagator(void) const;
00932   public:
00934     template<class A>
00935     Advisor(Space& home, Propagator& p, Council<A>& c);
00937     Advisor(Space& home, bool share, Advisor& a);
00938 
00940 
00941 
00942     template<class A>
00943     void dispose(Space& home, Council<A>& c);
00945     static void* operator new(size_t s, Space& home);
00947     static void  operator delete(void* p, Space& home);
00949   private:
00950 #ifndef __GNUC__
00951 
00952     static void  operator delete(void* p);
00953 #endif
00954 
00955     static void* operator new(size_t s);
00956   };
00957 
00958 
00959   class Brancher;
00969   class GECODE_VTABLE_EXPORT Choice {
00970     friend class Space;
00971   private:
00972     unsigned int _id;  
00973     unsigned int _alt; 
00974 
00976     unsigned int id(void) const;
00977   protected:
00979     Choice(const Brancher& b, const unsigned int a);
00980   public:
00982     unsigned int alternatives(void) const;
00984     GECODE_KERNEL_EXPORT virtual ~Choice(void);
00986     virtual size_t size(void) const = 0;
00988     static void* operator new(size_t);
00990     static void  operator delete(void*);
00992     GECODE_KERNEL_EXPORT virtual void archive(Archive& e) const;
00993   };
00994 
01004   class GECODE_VTABLE_EXPORT Brancher : public Actor {
01005     friend class ActorLink;
01006     friend class Space;
01007     friend class Choice;
01008   private:
01010     unsigned int _id;
01012     static Brancher* cast(ActorLink* al);
01014     static const Brancher* cast(const ActorLink* al);
01015   protected:
01017     Brancher(Home home);
01019     Brancher(Space& home, bool share, Brancher& b);
01020   public:
01022 
01023 
01031     virtual bool status(const Space& home) const = 0;
01039     virtual const Choice* choice(Space& home) = 0;
01041     virtual const Choice* choice(const Space& home, Archive& e) = 0;
01048     virtual ExecStatus commit(Space& home, const Choice& c, 
01049                               unsigned int a) = 0;
01051     unsigned int id(void) const;
01053   };
01054 
01062   class LocalObject : public Actor {
01063     friend class ActorLink;
01064     friend class Space;
01065     friend class LocalHandle;
01066   protected:
01068     LocalObject(Home home);
01070     LocalObject(Space& home, bool share, LocalObject& l);
01072     static LocalObject* cast(ActorLink* al);
01074     static const LocalObject* cast(const ActorLink* al);
01075   private:
01077     GECODE_KERNEL_EXPORT void fwdcopy(Space& home, bool share);
01078   public:
01080     LocalObject* fwd(Space& home, bool share);
01081   };
01082 
01089   class LocalHandle {
01090   private:
01092     LocalObject* o;
01093   protected:
01095     LocalHandle(void);
01097     LocalHandle(LocalObject* lo);
01099     LocalHandle(const LocalHandle& lh);
01100   public:
01102     LocalHandle& operator =(const LocalHandle& lh);
01104     void update(Space& home, bool share, LocalHandle& lh);
01106     ~LocalHandle(void);
01107   protected:
01109     LocalObject* object(void) const;
01111     void object(LocalObject* n);
01112   };
01113 
01114 
01119   enum SpaceStatus {
01120     SS_FAILED, 
01121     SS_SOLVED, 
01122     SS_BRANCH  
01123   };
01124 
01129   class StatusStatistics {
01130   public:
01132     unsigned long int propagate;
01134     bool wmp;
01136     StatusStatistics(void);
01138     void reset(void);
01140     StatusStatistics operator +(const StatusStatistics& s);
01142     StatusStatistics& operator +=(const StatusStatistics& s);
01143   };
01144 
01149   class CloneStatistics {
01150   public:
01152     CloneStatistics(void);
01154     void reset(void);
01156     CloneStatistics operator +(const CloneStatistics& s);
01158     CloneStatistics& operator +=(const CloneStatistics& s);
01159   };
01160 
01165   class CommitStatistics {
01166   public:
01168     CommitStatistics(void);
01170     void reset(void);
01172     CommitStatistics operator +(const CommitStatistics& s);
01174     CommitStatistics& operator +=(const CommitStatistics& s);
01175   };
01176 
01180   class GECODE_VTABLE_EXPORT Space {
01181     friend class Actor;
01182     friend class Propagator;
01183     friend class Brancher;
01184     friend class Advisor;
01185     template<class VIC> friend class VarImp;
01186     template<class VarImp> friend class VarImpDisposer;
01187     friend class SharedHandle;
01188     friend class LocalObject;
01189     friend class Region;
01190   private:
01192     SharedMemory* sm;
01194     MemoryManager mm;
01196     GlobalPropInfo gpi;
01198     ActorLink pl;
01200     ActorLink bl;
01206     Brancher* b_status;
01218     Brancher* b_commit;
01219     union {
01221       struct {
01234         ActorLink* active;
01236         ActorLink queue[PropCost::AC_MAX+1];
01238         unsigned int branch_id;
01240         unsigned int n_sub;
01241       } p;
01243       struct {
01245         VarImpBase* vars_u[AllVarConf::idx_c];
01247         VarImpBase* vars_noidx;
01249         SharedHandle::Object* shared;
01251         LocalObject* local;
01252       } c;
01253     } pc;
01255     void enqueue(Propagator* p);
01260 #ifdef GECODE_HAS_VAR_DISPOSE
01261 
01262     GECODE_KERNEL_EXPORT static VarImpDisposerBase* vd[AllVarConf::idx_d];
01264     VarImpBase* _vars_d[AllVarConf::idx_d];
01266     template<class VIC> VarImpBase* vars_d(void) const;
01268     template<class VIC> void vars_d(VarImpBase* x);
01269 #endif
01270 
01271     void update(ActorLink** sub);
01273 
01275     Actor** d_fst;
01277     Actor** d_cur;
01279     Actor** d_lst;
01281     GECODE_KERNEL_EXPORT void d_resize(void);
01282 
01290     unsigned int n_wmp;
01291 
01293     GECODE_KERNEL_EXPORT static StatusStatistics unused_status;
01295     GECODE_KERNEL_EXPORT static CloneStatistics unused_clone;
01297     GECODE_KERNEL_EXPORT static CommitStatistics unused_commit;
01299     GECODE_KERNEL_EXPORT static unsigned long int unused_uli;
01301     GECODE_KERNEL_EXPORT static bool unused_b;
01302 
01317     GECODE_KERNEL_EXPORT Space* _clone(bool share=true);
01318 
01351     GECODE_KERNEL_EXPORT
01352     void _commit(const Choice& c, unsigned int a);
01353 
01354   public:
01359     GECODE_KERNEL_EXPORT Space(void);
01364     GECODE_KERNEL_EXPORT virtual ~Space(void);
01375     GECODE_KERNEL_EXPORT Space(bool share, Space& s);
01382     virtual Space* copy(bool share) = 0;
01394     GECODE_KERNEL_EXPORT virtual void constrain(const Space& best);
01399     static void* operator new(size_t);
01404     static void  operator delete(void*);
01405 
01406 
01407     /*
01408      * Member functions for search engines
01409      *
01410      */
01411 
01423     GECODE_KERNEL_EXPORT
01424     SpaceStatus status(StatusStatistics& stat=unused_status);
01425 
01457     GECODE_KERNEL_EXPORT
01458     const Choice* choice(void);
01459 
01469     GECODE_KERNEL_EXPORT
01470     const Choice* choice(Archive& e) const;
01471   
01489     Space* clone(bool share=true, CloneStatistics& stat=unused_clone) const;
01490 
01525     void commit(const Choice& c, unsigned int a,
01526                 CommitStatistics& stat=unused_commit);
01527 
01535     void notice(Actor& a, ActorProperty p);
01543     void ignore(Actor& a, ActorProperty p);
01544 
01545 
01556     ExecStatus ES_SUBSUMED(Propagator& p);
01571     ExecStatus ES_SUBSUMED_DISPOSED(Propagator& p, size_t s);
01582     ExecStatus ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med);
01593     ExecStatus ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med);
01594     
01605     template<class A>
01606     ExecStatus ES_FIX_DISPOSE(Council<A>& c, A& a);
01617     template<class A>
01618     ExecStatus ES_NOFIX_DISPOSE(Council<A>& c, A& a);
01630     template<class A>
01631     ExecStatus ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a);
01632     
01640     void fail(void);
01649     bool failed(void) const;
01654     bool stable(void) const;
01661     GECODE_KERNEL_EXPORT unsigned int propagators(void) const;
01668     GECODE_KERNEL_EXPORT unsigned int branchers(void) const;
01669 
01671 
01672 
01673     Home operator ()(Propagator& p);
01675 
01687     template<class T>
01688     T* alloc(long unsigned int n);
01695     template<class T>
01696     T* alloc(long int n);
01703     template<class T>
01704     T* alloc(unsigned int n);
01711     template<class T>
01712     T* alloc(int n);
01722     template<class T>
01723     void free(T* b, long unsigned int n);
01733     template<class T>
01734     void free(T* b, long int n);
01744     template<class T>
01745     void free(T* b, unsigned int n);
01755     template<class T>
01756     void free(T* b, int n);
01768     template<class T>
01769     T* realloc(T* b, long unsigned int n, long unsigned int m);
01781     template<class T>
01782     T* realloc(T* b, long int n, long int m);
01794     template<class T>
01795     T* realloc(T* b, unsigned int n, unsigned int m);
01807     template<class T>
01808     T* realloc(T* b, int n, int m);
01816     template<class T>
01817     T** realloc(T** b, long unsigned int n, long unsigned int m);
01825     template<class T>
01826     T** realloc(T** b, long int n, long int m);
01834     template<class T>
01835     T** realloc(T** b, unsigned int n, unsigned int m);
01843     template<class T>
01844     T** realloc(T** b, int n, int m);
01846     void* ralloc(size_t s);
01848     void rfree(void* p, size_t s);
01850     void* rrealloc(void* b, size_t n, size_t m);
01852     template<size_t> void* fl_alloc(void);
01858     template<size_t> void  fl_dispose(FreeList* f, FreeList* l);
01865     size_t allocated(void) const;
01875     GECODE_KERNEL_EXPORT void flush(void);
01877 
01878 
01879 
01882     template<class T> 
01883     T& construct(void);
01889     template<class T, typename A1> 
01890     T& construct(A1 const& a1);
01896     template<class T, typename A1, typename A2> 
01897     T& construct(A1 const& a1, A2 const& a2);
01903     template<class T, typename A1, typename A2, typename A3>
01904     T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
01910     template<class T, typename A1, typename A2, typename A3, typename A4>
01911     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
01917     template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
01918     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
01920 
01926     class Propagators {
01927     private:
01929       const Space& home;
01931       const ActorLink* q;
01933       const ActorLink* c;
01935       const ActorLink* e;
01936     public:
01938       Propagators(const Space& home);
01940       bool operator ()(void) const;
01942       void operator ++(void);
01944       const Propagator& propagator(void) const;
01945     };
01946 
01952     class Branchers {
01953     private:
01955       const ActorLink* c;
01957       const ActorLink* e;
01958     public:
01960       Branchers(const Space& home);
01962       bool operator ()(void) const;
01964       void operator ++(void);
01966       const Brancher& brancher(void) const;
01967     };    
01968   };
01969 
01970 
01971 
01972 
01973   /*
01974    * Memory management
01975    *
01976    */
01977 
01978   // Heap allocated
01979   forceinline void*
01980   SharedHandle::Object::operator new(size_t s) {
01981     return heap.ralloc(s);
01982   }
01983   forceinline void
01984   SharedHandle::Object::operator delete(void* p) {
01985     heap.rfree(p);
01986   }
01987 
01988   forceinline void*
01989   Space::operator new(size_t s) {
01990     return heap.ralloc(s);
01991   }
01992   forceinline void
01993   Space::operator delete(void* p) {
01994     heap.rfree(p);
01995   }
01996 
01997   forceinline void
01998   Choice::operator delete(void* p) {
01999     heap.rfree(p);
02000   }
02001   forceinline void*
02002   Choice::operator new(size_t s) {
02003     return heap.ralloc(s);
02004   }
02005 
02006   // Space allocation: general space heaps and free lists
02007   forceinline void*
02008   Space::ralloc(size_t s) {
02009     return mm.alloc(sm,s);
02010   }
02011   forceinline void
02012   Space::rfree(void* p, size_t s) {
02013     return mm.reuse(p,s);
02014   }
02015   forceinline void*
02016   Space::rrealloc(void* _b, size_t n, size_t m) {
02017     char* b = static_cast<char*>(_b);
02018     if (n < m) {
02019       char* p = static_cast<char*>(ralloc(m));
02020       memcpy(p,b,n);
02021       rfree(b,n);
02022       return p;
02023     } else {
02024       rfree(b+m,m-n);
02025       return b;
02026     }
02027   }
02028 
02029   template<size_t s>
02030   forceinline void*
02031   Space::fl_alloc(void) {
02032     return mm.template fl_alloc<s>(sm);
02033   }
02034   template<size_t s>
02035   forceinline void
02036   Space::fl_dispose(FreeList* f, FreeList* l) {
02037     mm.template fl_dispose<s>(f,l);
02038   }
02039 
02040   forceinline size_t
02041   Space::allocated(void) const {
02042     size_t s = mm.allocated();
02043     for (Actor** a = d_fst; a < d_cur; a++)
02044       s += (*a)->allocated();
02045     return s;
02046   }
02047 
02048   /*
02049    * Typed allocation routines
02050    *
02051    */
02052   template<class T>
02053   forceinline T*
02054   Space::alloc(long unsigned int n) {
02055     T* p = static_cast<T*>(ralloc(sizeof(T)*n));
02056     for (long unsigned int i=n; i--; )
02057       (void) new (p+i) T();
02058     return p;
02059   }
02060   template<class T>
02061   forceinline T*
02062   Space::alloc(long int n) {
02063     assert(n >= 0);
02064     return alloc<T>(static_cast<long unsigned int>(n));
02065   }
02066   template<class T>
02067   forceinline T*
02068   Space::alloc(unsigned int n) {
02069     return alloc<T>(static_cast<long unsigned int>(n));
02070   }
02071   template<class T>
02072   forceinline T*
02073   Space::alloc(int n) {
02074     assert(n >= 0);
02075     return alloc<T>(static_cast<long unsigned int>(n));
02076   }
02077 
02078   template<class T>
02079   forceinline void
02080   Space::free(T* b, long unsigned int n) {
02081     for (long unsigned int i=n; i--; )
02082       b[i].~T();
02083     rfree(b,n*sizeof(T));
02084   }
02085   template<class T>
02086   forceinline void
02087   Space::free(T* b, long int n) {
02088     assert(n >= 0);
02089     free<T>(b,static_cast<long unsigned int>(n));
02090   }
02091   template<class T>
02092   forceinline void
02093   Space::free(T* b, unsigned int n) {
02094     free<T>(b,static_cast<long unsigned int>(n));
02095   }
02096   template<class T>
02097   forceinline void
02098   Space::free(T* b, int n) {
02099     assert(n >= 0);
02100     free<T>(b,static_cast<long unsigned int>(n));
02101   }
02102 
02103   template<class T>
02104   forceinline T*
02105   Space::realloc(T* b, long unsigned int n, long unsigned int m) {
02106     if (n < m) {
02107       T* p = static_cast<T*>(ralloc(sizeof(T)*m));
02108       for (long unsigned int i=n; i--; )
02109         (void) new (p+i) T(b[i]);
02110       for (long unsigned int i=n; i<m; i++)
02111         (void) new (p+i) T();
02112       free<T>(b,n);
02113       return p;
02114     } else {
02115       free<T>(b+m,m-n);
02116       return b;
02117     }
02118   }
02119   template<class T>
02120   forceinline T*
02121   Space::realloc(T* b, long int n, long int m) {
02122     assert((n >= 0) && (m >= 0));
02123     return realloc<T>(b,static_cast<long unsigned int>(n),
02124                       static_cast<long unsigned int>(m));
02125   }
02126   template<class T>
02127   forceinline T*
02128   Space::realloc(T* b, unsigned int n, unsigned int m) {
02129     return realloc<T>(b,static_cast<long unsigned int>(n),
02130                       static_cast<long unsigned int>(m));
02131   }
02132   template<class T>
02133   forceinline T*
02134   Space::realloc(T* b, int n, int m) {
02135     assert((n >= 0) && (m >= 0));
02136     return realloc<T>(b,static_cast<long unsigned int>(n),
02137                       static_cast<long unsigned int>(m));
02138   }
02139 
02140 #define GECODE_KERNEL_REALLOC(T)                                        \
02141   template<>                                                            \
02142   forceinline T*                                                        \
02143   Space::realloc<T>(T* b, long unsigned int n, long unsigned int m) {   \
02144     return static_cast<T*>(rrealloc(b,n*sizeof(T),m*sizeof(T)));        \
02145   }                                                                     \
02146   template<>                                                            \
02147   forceinline T*                                                        \
02148   Space::realloc<T>(T* b, long int n, long int m) {                     \
02149     assert((n >= 0) && (m >= 0));                                       \
02150     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02151                       static_cast<long unsigned int>(m));               \
02152   }                                                                     \
02153   template<>                                                            \
02154   forceinline T*                                                        \
02155   Space::realloc<T>(T* b, unsigned int n, unsigned int m) {             \
02156     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02157                       static_cast<long unsigned int>(m));               \
02158   }                                                                     \
02159   template<>                                                            \
02160   forceinline T*                                                        \
02161   Space::realloc<T>(T* b, int n, int m) {                               \
02162     assert((n >= 0) && (m >= 0));                                       \
02163     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02164                       static_cast<long unsigned int>(m));               \
02165   }
02166 
02167   GECODE_KERNEL_REALLOC(bool)
02168   GECODE_KERNEL_REALLOC(signed char)
02169   GECODE_KERNEL_REALLOC(unsigned char)
02170   GECODE_KERNEL_REALLOC(signed short int)
02171   GECODE_KERNEL_REALLOC(unsigned short int)
02172   GECODE_KERNEL_REALLOC(signed int)
02173   GECODE_KERNEL_REALLOC(unsigned int)
02174   GECODE_KERNEL_REALLOC(signed long int)
02175   GECODE_KERNEL_REALLOC(unsigned long int)
02176   GECODE_KERNEL_REALLOC(float)
02177   GECODE_KERNEL_REALLOC(double)
02178 
02179 #undef GECODE_KERNEL_REALLOC
02180 
02181   template<class T>
02182   forceinline T**
02183   Space::realloc(T** b, long unsigned int n, long unsigned int m) {
02184     return static_cast<T**>(rrealloc(b,n*sizeof(T),m*sizeof(T*)));
02185   }
02186   template<class T>
02187   forceinline T**
02188   Space::realloc(T** b, long int n, long int m) {
02189     assert((n >= 0) && (m >= 0));
02190     return realloc<T*>(b,static_cast<long unsigned int>(n),
02191                        static_cast<long unsigned int>(m));
02192   }
02193   template<class T>
02194   forceinline T**
02195   Space::realloc(T** b, unsigned int n, unsigned int m) {
02196     return realloc<T*>(b,static_cast<long unsigned int>(n),
02197                        static_cast<long unsigned int>(m));
02198   }
02199   template<class T>
02200   forceinline T**
02201   Space::realloc(T** b, int n, int m) {
02202     assert((n >= 0) && (m >= 0));
02203     return realloc<T*>(b,static_cast<long unsigned int>(n),
02204                        static_cast<long unsigned int>(m));
02205   }
02206 
02207 
02208 #ifdef GECODE_HAS_VAR_DISPOSE
02209   template<class VIC>
02210   forceinline VarImpBase*
02211   Space::vars_d(void) const {
02212     return _vars_d[VIC::idx_d];
02213   }
02214   template<class VIC>
02215   forceinline void
02216   Space::vars_d(VarImpBase* x) {
02217     _vars_d[VIC::idx_d] = x;
02218   }
02219 #endif
02220 
02221   // Space allocated entities: Actors, variable implementations, and advisors
02222   forceinline void
02223   Actor::operator delete(void*) {}
02224   forceinline void
02225   Actor::operator delete(void*, Space&) {}
02226   forceinline void*
02227   Actor::operator new(size_t s, Space& home) {
02228     return home.ralloc(s);
02229   }
02230 
02231   template<class VIC>
02232   forceinline void
02233   VarImp<VIC>::operator delete(void*) {}
02234   template<class VIC>
02235   forceinline void
02236   VarImp<VIC>::operator delete(void*, Space&) {}
02237   template<class VIC>
02238   forceinline void*
02239   VarImp<VIC>::operator new(size_t s, Space& home) {
02240     return home.ralloc(s);
02241   }
02242 
02243 #ifndef __GNUC__
02244   forceinline void
02245   Advisor::operator delete(void*) {}
02246 #endif
02247   forceinline void
02248   Advisor::operator delete(void*, Space&) {}
02249   forceinline void*
02250   Advisor::operator new(size_t s, Space& home) {
02251     return home.ralloc(s);
02252   }
02253 
02254   /*
02255    * Shared objects and handles
02256    *
02257    */
02258   forceinline
02259   SharedHandle::Object::Object(void)
02260     : next(NULL), fwd(NULL), use_cnt(0) {}
02261   forceinline
02262   SharedHandle::Object::~Object(void) {
02263     assert(use_cnt == 0);
02264   }
02265 
02266   forceinline SharedHandle::Object*
02267   SharedHandle::object(void) const {
02268     return o;
02269   }
02270   forceinline void
02271   SharedHandle::subscribe(void) {
02272     if (o != NULL) o->use_cnt++;
02273   }
02274   forceinline void
02275   SharedHandle::cancel(void) {
02276     if ((o != NULL) && (--o->use_cnt == 0))
02277       delete o;
02278     o=NULL;
02279   }
02280   forceinline void
02281   SharedHandle::object(SharedHandle::Object* n) {
02282     if (n != o) {
02283       cancel(); o=n; subscribe();
02284     }
02285   }
02286   forceinline
02287   SharedHandle::SharedHandle(void) : o(NULL) {}
02288   forceinline
02289   SharedHandle::SharedHandle(SharedHandle::Object* so) : o(so) {
02290     subscribe();
02291   }
02292   forceinline
02293   SharedHandle::SharedHandle(const SharedHandle& sh) : o(sh.o) {
02294     subscribe();
02295   }
02296   forceinline SharedHandle&
02297   SharedHandle::operator =(const SharedHandle& sh) {
02298     if (&sh != this) {
02299       cancel(); o=sh.o; subscribe();
02300     }
02301     return *this;
02302   }
02303   forceinline void
02304   SharedHandle::update(Space& home, bool share, SharedHandle& sh) {
02305     if (sh.o == NULL) {
02306       o=NULL; return;
02307     } else if (share) {
02308       o=sh.o;
02309     } else if (sh.o->fwd != NULL) {
02310       o=sh.o->fwd;
02311     } else {
02312       o = sh.o->copy();
02313       sh.o->fwd = o;
02314       sh.o->next = home.pc.c.shared;
02315       home.pc.c.shared = sh.o;
02316     }
02317     subscribe();
02318   }
02319   forceinline
02320   SharedHandle::~SharedHandle(void) {
02321     cancel();
02322   }
02323 
02324 
02325 
02326   /*
02327    * ActorLink
02328    *
02329    */
02330   forceinline ActorLink*
02331   ActorLink::prev(void) const {
02332     return _prev;
02333   }
02334 
02335   forceinline ActorLink*
02336   ActorLink::next(void) const {
02337     return _next;
02338   }
02339 
02340   forceinline ActorLink**
02341   ActorLink::next_ref(void) {
02342     return &_next;
02343   }
02344 
02345   forceinline void
02346   ActorLink::prev(ActorLink* al) {
02347     _prev = al;
02348   }
02349 
02350   forceinline void
02351   ActorLink::next(ActorLink* al) {
02352     _next = al;
02353   }
02354 
02355   forceinline void
02356   ActorLink::unlink(void) {
02357     ActorLink* p = _prev; ActorLink* n = _next;
02358     p->_next = n; n->_prev = p;
02359   }
02360 
02361   forceinline void
02362   ActorLink::init(void) {
02363     _next = this; _prev =this;
02364   }
02365 
02366   forceinline void
02367   ActorLink::head(ActorLink* a) {
02368     // Inserts al at head of link-chain (that is, after this)
02369     ActorLink* n = _next;
02370     this->_next = a; a->_prev = this;
02371     a->_next = n; n->_prev = a;
02372   }
02373 
02374   forceinline void
02375   ActorLink::tail(ActorLink* a) {
02376     // Inserts al at tail of link-chain (that is, before this)
02377     ActorLink* p = _prev;
02378     a->_next = this; this->_prev = a;
02379     p->_next = a; a->_prev = p;
02380   }
02381 
02382   forceinline bool
02383   ActorLink::empty(void) const {
02384     return _next == this;
02385   }
02386 
02387   template<class T>
02388   forceinline ActorLink*
02389   ActorLink::cast(T* a) {
02390     // Turning al into a reference is for gcc, assume is for MSVC
02391     GECODE_NOT_NULL(a);
02392     ActorLink& t = *a;
02393     return static_cast<ActorLink*>(&t);
02394   }
02395 
02396   template<class T>
02397   forceinline const ActorLink*
02398   ActorLink::cast(const T* a) {
02399     // Turning al into a reference is for gcc, assume is for MSVC
02400     GECODE_NOT_NULL(a);
02401     const ActorLink& t = *a;
02402     return static_cast<const ActorLink*>(&t);
02403   }
02404 
02405 
02406   /*
02407    * Actor
02408    *
02409    */
02410   forceinline Actor*
02411   Actor::cast(ActorLink* al) {
02412     // Turning al into a reference is for gcc, assume is for MSVC
02413     GECODE_NOT_NULL(al);
02414     ActorLink& t = *al;
02415     return static_cast<Actor*>(&t);
02416   }
02417 
02418   forceinline const Actor*
02419   Actor::cast(const ActorLink* al) {
02420     // Turning al into a reference is for gcc, assume is for MSVC
02421     GECODE_NOT_NULL(al);
02422     const ActorLink& t = *al;
02423     return static_cast<const Actor*>(&t);
02424   }
02425 
02426   forceinline void
02427   Space::notice(Actor& a, ActorProperty p) {
02428     if (p & AP_DISPOSE) {
02429       if (d_cur == d_lst)
02430         d_resize();
02431       *(d_cur++) = &a;
02432     }
02433     if (p & AP_WEAKLY) {
02434       if (n_wmp == 0)
02435         n_wmp = 2;
02436       else
02437         n_wmp++;
02438     }
02439   }
02440 
02441   forceinline void
02442   Home::notice(Actor& a, ActorProperty p) {
02443     s.notice(a,p);
02444   }
02445 
02446   forceinline void
02447   Space::ignore(Actor& a, ActorProperty p) {
02448     if (p & AP_DISPOSE) {
02449       // Check wether array has already been discarded as space
02450       // deletion is already in progress
02451       Actor** f = d_fst;
02452       if (f != NULL) {
02453         while (&a != *f)
02454           f++;
02455         *f = *(--d_cur);
02456       }
02457     }
02458     if (p & AP_WEAKLY) {
02459       assert(n_wmp > 1);
02460       n_wmp--;
02461     }
02462   }
02463 
02464   forceinline Space*
02465   Space::clone(bool share, CloneStatistics&) const {
02466     // Clone is only const for search engines. During cloning, several data
02467     // structures are updated (e.g. forwarding pointers), so we have to
02468     // cast away the constness.
02469     return const_cast<Space*>(this)->_clone(share);
02470   }
02471 
02472   forceinline void
02473   Space::commit(const Choice& c, unsigned int a, CommitStatistics&) {
02474     _commit(c,a);
02475   }
02476 
02477   forceinline size_t
02478   Actor::dispose(Space&) {
02479     return sizeof(*this);
02480   }
02481 
02482 
02483   /*
02484    * Home for posting actors
02485    *
02486    */
02487   forceinline
02488   Home::Home(Space& s0, Propagator* p0) : s(s0), p(p0) {}
02489   forceinline
02490   Home::operator Space&(void) { 
02491     return s; 
02492   }
02493   forceinline Home
02494   Home::operator ()(Propagator& p) {
02495     return Home(s,&p);
02496   }
02497   forceinline Home
02498   Space::operator ()(Propagator& p) {
02499     return Home(*this,&p);
02500   }
02501   forceinline Propagator*
02502   Home::propagator(void) const {
02503     return p;
02504   }
02505 
02506   /*
02507    * Propagator
02508    *
02509    */
02510   forceinline Propagator*
02511   Propagator::cast(ActorLink* al) {
02512     // Turning al into a reference is for gcc, assume is for MSVC
02513     GECODE_NOT_NULL(al);
02514     ActorLink& t = *al;
02515     return static_cast<Propagator*>(&t);
02516   }
02517 
02518   forceinline const Propagator*
02519   Propagator::cast(const ActorLink* al) {
02520     // Turning al into a reference is for gcc, assume is for MSVC
02521     GECODE_NOT_NULL(al);
02522     const ActorLink& t = *al;
02523     return static_cast<const Propagator*>(&t);
02524   }
02525 
02526   forceinline
02527   Propagator::Propagator(Home home) 
02528     : pi((home.propagator() != NULL) ?
02529          // Inherit propagator information
02530          home.propagator()->pi :
02531          // New propagator information
02532          static_cast<Space&>(home).gpi.allocate()) {
02533     u.advisors = NULL;
02534     assert((u.med == 0) && (u.size == 0));
02535     static_cast<Space&>(home).pl.head(this);
02536   }
02537 
02538   forceinline
02539   Propagator::Propagator(Space&, bool, Propagator& p) 
02540     : pi(p.pi) {
02541     u.advisors = NULL;
02542     assert((u.med == 0) && (u.size == 0));
02543     // Set forwarding pointer
02544     p.prev(this);
02545   }
02546 
02547   forceinline ModEventDelta
02548   Propagator::modeventdelta(void) const {
02549     return u.med;
02550   }
02551 
02552   forceinline double
02553   Propagator::afc(void) const {
02554     return pi.afc();
02555   }
02556 
02557   forceinline ExecStatus
02558   Space::ES_SUBSUMED_DISPOSED(Propagator& p, size_t s) {
02559     p.u.size = s;
02560     return __ES_SUBSUMED;
02561   }
02562 
02563   forceinline ExecStatus
02564   Space::ES_SUBSUMED(Propagator& p) {
02565     p.u.size = p.dispose(*this);
02566     return __ES_SUBSUMED;
02567   }
02568 
02569   forceinline ExecStatus
02570   Space::ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02571     p.u.med = med;
02572     assert(p.u.med != 0);
02573     return __ES_PARTIAL;
02574   }
02575 
02576   forceinline ExecStatus
02577   Space::ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02578     p.u.med = AllVarConf::med_combine(p.u.med,med);
02579     assert(p.u.med != 0);
02580     return __ES_PARTIAL;
02581   }
02582 
02583 
02584 
02585   /*
02586    * Brancher
02587    *
02588    */
02589   forceinline Brancher*
02590   Brancher::cast(ActorLink* al) {
02591     // Turning al into a reference is for gcc, assume is for MSVC
02592     GECODE_NOT_NULL(al);
02593     ActorLink& t = *al;
02594     return static_cast<Brancher*>(&t);
02595   }
02596 
02597   forceinline const Brancher*
02598   Brancher::cast(const ActorLink* al) {
02599     // Turning al into a reference is for gcc, assume is for MSVC
02600     GECODE_NOT_NULL(al);
02601     const ActorLink& t = *al;
02602     return static_cast<const Brancher*>(&t);
02603   }
02604 
02605   forceinline
02606   Brancher::Brancher(Home home) :
02607     _id(static_cast<Space&>(home).pc.p.branch_id++) {
02608     if (static_cast<Space&>(home).pc.p.branch_id == 0U)
02609       throw TooManyBranchers("Brancher::Brancher");
02610     // If no brancher available, make it the first one
02611     if (static_cast<Space&>(home).b_status == &static_cast<Space&>(home).bl) {
02612       static_cast<Space&>(home).b_status = this;
02613       if (static_cast<Space&>(home).b_commit == &static_cast<Space&>(home).bl)
02614         static_cast<Space&>(home).b_commit = this;
02615     }
02616     static_cast<Space&>(home).bl.tail(this);
02617   }
02618 
02619   forceinline
02620   Brancher::Brancher(Space&, bool, Brancher& b)
02621     : _id(b._id) {
02622     // Set forwarding pointer
02623     b.prev(this);
02624   }
02625 
02626   forceinline unsigned int
02627   Brancher::id(void) const {
02628     return _id;
02629   }
02630 
02631   /*
02632    * Local objects
02633    *
02634    */
02635 
02636   forceinline LocalObject*
02637   LocalObject::cast(ActorLink* al) {
02638     // Turning al into a reference is for gcc, assume is for MSVC
02639     GECODE_NOT_NULL(al);
02640     ActorLink& t = *al;
02641     return static_cast<LocalObject*>(&t);
02642   }
02643 
02644   forceinline const LocalObject*
02645   LocalObject::cast(const ActorLink* al) {
02646     // Turning al into a reference is for gcc, assume is for MSVC
02647     GECODE_NOT_NULL(al);
02648     const ActorLink& t = *al;
02649     return static_cast<const LocalObject*>(&t);
02650   }
02651 
02652   forceinline
02653   LocalObject::LocalObject(Home) {
02654     ActorLink::cast(this)->prev(NULL);
02655   }
02656 
02657   forceinline
02658   LocalObject::LocalObject(Space&,bool,LocalObject&) {
02659     ActorLink::cast(this)->prev(NULL);
02660   }
02661 
02662   forceinline LocalObject*
02663   LocalObject::fwd(Space& home, bool share) {
02664     if (prev() == NULL)
02665       fwdcopy(home,share);
02666     return LocalObject::cast(prev());
02667   }
02668 
02669   forceinline
02670   LocalHandle::LocalHandle(void) : o(NULL) {}
02671   forceinline
02672   LocalHandle::LocalHandle(LocalObject* lo) : o(lo) {}
02673   forceinline
02674   LocalHandle::LocalHandle(const LocalHandle& lh) : o(lh.o) {}
02675   forceinline LocalHandle&
02676   LocalHandle::operator =(const LocalHandle& lh) {
02677     o = lh.o;
02678     return *this;
02679   }
02680   forceinline
02681   LocalHandle::~LocalHandle(void) {}
02682   forceinline LocalObject*
02683   LocalHandle::object(void) const { return o; }
02684   forceinline void
02685   LocalHandle::object(LocalObject* n) { o = n; }
02686   forceinline void
02687   LocalHandle::update(Space& home, bool share, LocalHandle& lh) {
02688     object(lh.object()->fwd(home,share));
02689   }
02690 
02691 
02692   /*
02693    * Choices
02694    *
02695    */
02696   forceinline
02697   Choice::Choice(const Brancher& b, const unsigned int a)
02698     : _id(b.id()), _alt(a) {}
02699 
02700   forceinline unsigned int
02701   Choice::alternatives(void) const {
02702     return _alt;
02703   }
02704 
02705   forceinline unsigned int
02706   Choice::id(void) const {
02707     return _id;
02708   }
02709 
02710   forceinline
02711   Choice::~Choice(void) {}
02712 
02713 
02714 
02715   /*
02716    * Advisor
02717    *
02718    */
02719   template<class A>
02720   forceinline
02721   Advisor::Advisor(Space&, Propagator& p, Council<A>& c) {
02722     // Store propagator and forwarding in prev()
02723     ActorLink::prev(&p);
02724     // Link to next advisor in next()
02725     ActorLink::next(c.advisors); c.advisors = static_cast<A*>(this);
02726   }
02727 
02728   forceinline
02729   Advisor::Advisor(Space&, bool, Advisor&) {}
02730 
02731   forceinline bool
02732   Advisor::disposed(void) const {
02733     return prev() == NULL;
02734   }
02735 
02736   forceinline Advisor*
02737   Advisor::cast(ActorLink* al) {
02738     return static_cast<Advisor*>(al);
02739   }
02740 
02741   forceinline const Advisor*
02742   Advisor::cast(const ActorLink* al) {
02743     return static_cast<const Advisor*>(al);
02744   }
02745 
02746   forceinline Propagator&
02747   Advisor::propagator(void) const {
02748     assert(!disposed());
02749     return *Propagator::cast(ActorLink::prev());
02750   }
02751 
02752   template<class A>
02753   forceinline void
02754   Advisor::dispose(Space&,Council<A>&) {
02755     assert(!disposed());
02756     ActorLink::prev(NULL);
02757     // Shorten chains of disposed advisors by one, if possible
02758     Advisor* n = Advisor::cast(next());
02759     if ((n != NULL) && n->disposed())
02760       next(n->next());
02761   }
02762 
02763   template<class A>
02764   forceinline ExecStatus
02765   Space::ES_FIX_DISPOSE(Council<A>& c, A& a) {
02766     a.dispose(*this,c);
02767     return ES_FIX;
02768   }
02769 
02770   template<class A>
02771   forceinline ExecStatus
02772   Space::ES_NOFIX_DISPOSE(Council<A>& c, A& a) {
02773     a.dispose(*this,c);
02774     return ES_NOFIX;
02775   }
02776 
02777   template<class A>
02778   forceinline ExecStatus
02779   Space::ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a) {
02780     a.dispose(*this,c);
02781     return ES_NOFIX_FORCE;
02782   }
02783 
02784 
02785 
02786   /*
02787    * Advisor council
02788    *
02789    */
02790   template<class A>
02791   forceinline
02792   Council<A>::Council(void) {}
02793 
02794   template<class A>
02795   forceinline
02796   Council<A>::Council(Space&)
02797     : advisors(NULL) {}
02798 
02799   template<class A>
02800   forceinline bool
02801   Council<A>::empty(void) const {
02802     ActorLink* a = advisors;
02803     while ((a != NULL) && static_cast<A*>(a)->disposed())
02804       a = a->next();
02805     advisors = a;
02806     return a == NULL;
02807   }
02808 
02809   template<class A>
02810   forceinline void
02811   Council<A>::update(Space& home, bool share, Council<A>& c) {
02812     // Skip all disposed advisors
02813     {
02814       ActorLink* a = c.advisors;
02815       while ((a != NULL) && static_cast<A*>(a)->disposed())
02816         a = a->next();
02817       c.advisors = a;
02818     }
02819     // Are there any advisors to be cloned?
02820     if (c.advisors != NULL) {
02821       // The propagator in from-space
02822       Propagator* p_f = &static_cast<A*>(c.advisors)->propagator();
02823       // The propagator in to-space
02824       Propagator* p_t = Propagator::cast(p_f->prev());
02825       // Advisors in from-space
02826       ActorLink** a_f = &c.advisors;
02827       // Advisors in to-space
02828       A* a_t = NULL;
02829       while (*a_f != NULL) {
02830         if (static_cast<A*>(*a_f)->disposed()) {
02831           *a_f = (*a_f)->next();
02832         } else {
02833           // Run specific copying part
02834           A* a = new (home) A(home,share,*static_cast<A*>(*a_f));
02835           // Set propagator pointer
02836           a->prev(p_t);
02837           // Set forwarding pointer
02838           (*a_f)->prev(a);
02839           // Link
02840           a->next(a_t);
02841           a_t = a;
02842           a_f = (*a_f)->next_ref();
02843         }
02844       }
02845       advisors = a_t;
02846       // Enter advisor link for reset
02847       assert(p_f->u.advisors == NULL);
02848       p_f->u.advisors = c.advisors;
02849     } else {
02850       advisors = NULL;
02851     }
02852   }
02853 
02854   template<class A>
02855   forceinline void
02856   Council<A>::dispose(Space& home) {
02857     ActorLink* a = advisors;
02858     while (a != NULL) {
02859       if (!static_cast<A*>(a)->disposed())
02860         static_cast<A*>(a)->dispose(home,*this);
02861       a = a->next();
02862     }
02863   }
02864 
02865 
02866 
02867   /*
02868    * Advisor iterator
02869    *
02870    */
02871   template<class A>
02872   forceinline
02873   Advisors<A>::Advisors(const Council<A>& c)
02874     : a(c.advisors) {
02875     while ((a != NULL) && static_cast<A*>(a)->disposed())
02876       a = a->next();
02877   }
02878 
02879   template<class A>
02880   forceinline bool
02881   Advisors<A>::operator ()(void) const {
02882     return a != NULL;
02883   }
02884 
02885   template<class A>
02886   forceinline void
02887   Advisors<A>::operator ++(void) {
02888     do {
02889       a = a->next();
02890     } while ((a != NULL) && static_cast<A*>(a)->disposed());
02891   }
02892 
02893   template<class A>
02894   forceinline A&
02895   Advisors<A>::advisor(void) const {
02896     return *static_cast<A*>(a);
02897   }
02898 
02899 
02900 
02901   /*
02902    * Space
02903    *
02904    */
02905   forceinline void
02906   Space::enqueue(Propagator* p) {
02907     ActorLink::cast(p)->unlink();
02908     ActorLink* c = &pc.p.queue[p->cost(*this,p->u.med).ac];
02909     c->tail(ActorLink::cast(p));
02910     if (c > pc.p.active)
02911       pc.p.active = c;
02912   }
02913 
02914   forceinline void
02915   Space::fail(void) {
02916     /*
02917      * Now active points beyond the last queue. This is essential as
02918      * enqueuing a propagator in a failed space keeps the space
02919      * failed.
02920      */
02921     pc.p.active = &pc.p.queue[PropCost::AC_MAX+1]+1;
02922   }
02923   forceinline void
02924   Home::fail(void) {
02925     s.fail();
02926   }
02927 
02928   forceinline bool
02929   Space::failed(void) const {
02930     return pc.p.active > &pc.p.queue[PropCost::AC_MAX+1];
02931   }
02932   forceinline bool
02933   Home::failed(void) const {
02934     return s.failed();
02935   }
02936 
02937   forceinline bool
02938   Space::stable(void) const {
02939     return ((pc.p.active < &pc.p.queue[0]) ||
02940             (pc.p.active > &pc.p.queue[PropCost::AC_MAX+1]));
02941   }
02942 
02943 
02944 
02945   /*
02946    * Variable implementation
02947    *
02948    */
02949   template<class VIC>
02950   forceinline ActorLink**
02951   VarImp<VIC>::actor(PropCond pc) {
02952     assert((pc >= 0)  && (pc < pc_max+2));
02953     return (pc == 0) ? b.base : b.base+u.idx[pc-1];
02954   }
02955 
02956   template<class VIC>
02957   forceinline ActorLink**
02958   VarImp<VIC>::actorNonZero(PropCond pc) {
02959     assert((pc > 0)  && (pc < pc_max+2));
02960     return b.base+u.idx[pc-1];
02961   }
02962 
02963   template<class VIC>
02964   forceinline unsigned int&
02965   VarImp<VIC>::idx(PropCond pc) {
02966     assert((pc > 0)  && (pc < pc_max+2));
02967     return u.idx[pc-1];
02968   }
02969 
02970   template<class VIC>
02971   forceinline unsigned int
02972   VarImp<VIC>::idx(PropCond pc) const {
02973     assert((pc > 0)  && (pc < pc_max+2));
02974     return u.idx[pc-1];
02975   }
02976 
02977   template<class VIC>
02978   forceinline
02979   VarImp<VIC>::VarImp(Space&) {
02980     b.base = NULL; entries = 0;
02981     for (PropCond pc=1; pc<pc_max+2; pc++)
02982       idx(pc) = 0;
02983     free_and_bits = 0;
02984   }
02985 
02986   template<class VIC>
02987   forceinline
02988   VarImp<VIC>::VarImp(void) {
02989     b.base = NULL; entries = 0;
02990     for (PropCond pc=1; pc<pc_max+2; pc++)
02991       idx(pc) = 0;
02992     free_and_bits = 0;
02993   }
02994 
02995   template<class VIC>
02996   forceinline unsigned int
02997   VarImp<VIC>::degree(void) const {
02998     assert(!copied());
02999     return entries;
03000   }
03001 
03002   template<class VIC>
03003   forceinline double
03004   VarImp<VIC>::afc(void) const {
03005     if (degree() == 0)
03006       return 0.0;
03007     double d = degree();
03008     // Count the afc of each propagator
03009     {
03010       ActorLink** a = const_cast<VarImp<VIC>*>(this)->actor(0);
03011       ActorLink** e = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
03012       while (a < e) {
03013         d += Propagator::cast(*a)->afc(); a++;
03014       }
03015     }
03016     // Count the afc of each advisor's propagator
03017     {
03018       ActorLink** a = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
03019       ActorLink** e = const_cast<VarImp<VIC>*>(this)->b.base+entries;
03020       while (a < e) {
03021         d += Advisor::cast(*a)->propagator().afc(); a++;
03022       }
03023     }
03024     return d;
03025   }
03026 
03027   template<class VIC>
03028   forceinline ModEvent
03029   VarImp<VIC>::modevent(const Delta& d) {
03030     return d.me;
03031   }
03032 
03033   template<class VIC>
03034   forceinline unsigned int
03035   VarImp<VIC>::bits(void) const {
03036     return free_and_bits;
03037   }
03038 
03039   template<class VIC>
03040   forceinline unsigned int&
03041   VarImp<VIC>::bits(void) {
03042     return free_and_bits;
03043   }
03044 
03045 #ifdef GECODE_HAS_VAR_DISPOSE
03046   template<class VIC>
03047   forceinline VarImp<VIC>*
03048   VarImp<VIC>::vars_d(Space& home) {
03049     return static_cast<VarImp<VIC>*>(home.vars_d<VIC>());
03050   }
03051 
03052   template<class VIC>
03053   forceinline void
03054   VarImp<VIC>::vars_d(Space& home, VarImp<VIC>* x) {
03055     home.vars_d<VIC>(x);
03056   }
03057 #endif
03058 
03059   template<class VIC>
03060   forceinline bool
03061   VarImp<VIC>::copied(void) const {
03062     return Support::marked(b.fwd);
03063   }
03064 
03065   template<class VIC>
03066   forceinline VarImp<VIC>*
03067   VarImp<VIC>::forward(void) const {
03068     assert(copied());
03069     return static_cast<VarImp<VIC>*>(Support::unmark(b.fwd));
03070   }
03071 
03072   template<class VIC>
03073   forceinline VarImp<VIC>*
03074   VarImp<VIC>::next(void) const {
03075     assert(copied());
03076     return u.next;
03077   }
03078 
03079   template<class VIC>
03080   forceinline
03081   VarImp<VIC>::VarImp(Space& home, bool, VarImp<VIC>& x) {
03082     VarImpBase** reg;
03083     free_and_bits = x.free_and_bits & ((1 << free_bits) - 1);
03084     if (x.b.base == NULL) {
03085       // Variable implementation needs no index structure
03086       reg = &home.pc.c.vars_noidx;
03087       assert(x.degree() == 0);
03088     } else {
03089       reg = &home.pc.c.vars_u[idx_c];
03090     }
03091     // Save subscriptions in copy
03092     b.base = x.b.base;
03093     entries = x.entries;
03094     for (PropCond pc=1; pc<pc_max+2; pc++)
03095       idx(pc) = x.idx(pc);
03096 
03097     // Set forwarding pointer
03098     x.b.fwd = static_cast<VarImp<VIC>*>(Support::mark(this));
03099     // Register original
03100     x.u.next = static_cast<VarImp<VIC>*>(*reg); *reg = &x;
03101   }
03102 
03103   template<class VIC>
03104   forceinline ModEvent
03105   VarImp<VIC>::me(const ModEventDelta& med) {
03106     return static_cast<ModEvent>((med & VIC::med_mask) >> VIC::med_fst);
03107   }
03108 
03109   template<class VIC>
03110   forceinline ModEventDelta
03111   VarImp<VIC>::med(ModEvent me) {
03112     return static_cast<ModEventDelta>(me << VIC::med_fst);
03113   }
03114 
03115   template<class VIC>
03116   forceinline ModEvent
03117   VarImp<VIC>::me_combine(ModEvent me1, ModEvent me2) {
03118     return VIC::me_combine(me1,me2);
03119   }
03120 
03121   template<class VIC>
03122   forceinline void
03123   VarImp<VIC>::schedule(Space& home, Propagator& p, ModEvent me,
03124                         bool force) {
03125     if (VIC::med_update(p.u.med,me) || force)
03126       home.enqueue(&p);
03127   }
03128 
03129   template<class VIC>
03130   forceinline void
03131   VarImp<VIC>::schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me) {
03132     ActorLink** b = actor(pc1);
03133     ActorLink** p = actorNonZero(pc2+1);
03134     while (p-- > b)
03135       schedule(home,*Propagator::cast(*p),me);
03136   }
03137 
03138   template<class VIC>
03139   forceinline void
03140   VarImp<VIC>::enter(Space& home, Propagator* p, PropCond pc) {
03141     assert(pc <= pc_max);
03142     // Count one new subscription
03143     home.pc.p.n_sub += 1;
03144     if ((free_and_bits >> free_bits) == 0)
03145       resize(home);
03146     free_and_bits -= 1 << free_bits;
03147 
03148     // Enter subscription
03149     b.base[entries] = *actorNonZero(pc_max+1);
03150     entries++;
03151     for (PropCond j = pc_max; j > pc; j--) {
03152       *actorNonZero(j+1) = *actorNonZero(j);
03153       idx(j+1)++;
03154     }
03155     *actorNonZero(pc+1) = *actor(pc);
03156     idx(pc+1)++;
03157     *actor(pc) = ActorLink::cast(p);
03158 
03159 #ifdef GECODE_AUDIT
03160     ActorLink** f = actor(pc);
03161     while (f < (pc == pc_max+1 ? b.base+entries : actorNonZero(pc+1)))
03162       if (*f == p)
03163         goto found;
03164       else
03165         f++;
03166     GECODE_NEVER;
03167     found: ;
03168 #endif
03169   }
03170 
03171   template<class VIC>
03172   forceinline void
03173   VarImp<VIC>::enter(Space& home, Advisor* a) {
03174     // Count one new subscription
03175     home.pc.p.n_sub += 1;
03176     if ((free_and_bits >> free_bits) == 0)
03177       resize(home);
03178     free_and_bits -= 1 << free_bits;
03179 
03180     // Enter subscription
03181     b.base[entries++] = *actorNonZero(pc_max+1);
03182     *actorNonZero(pc_max+1) = a;
03183   }
03184 
03185   template<class VIC>
03186   void
03187   VarImp<VIC>::resize(Space& home) {
03188     if (b.base == NULL) {
03189       assert((free_and_bits >> free_bits) == 0);
03190       // Create fresh dependency array with four entries
03191       free_and_bits += 4 << free_bits;
03192       b.base = home.alloc<ActorLink*>(4);
03193       for (int i=0; i<pc_max+1; i++)
03194         u.idx[i] = 0;
03195     } else {
03196       // Resize dependency array
03197       unsigned int n = degree();
03198       // Find out whether the area is most likely in the special area
03199       // reserved for subscriptions. If yes, just resize mildly otherwise
03200       // more agressively
03201       ActorLink** s = static_cast<ActorLink**>(home.mm.subscriptions());
03202       unsigned int m =
03203         ((s <= b.base) && (b.base < s+home.pc.p.n_sub)) ?
03204         (n+4) : ((n+1)*3>>1);
03205       ActorLink** prop = home.alloc<ActorLink*>(m);
03206       free_and_bits += (m-n) << free_bits;
03207       // Copy entries
03208       Heap::copy<ActorLink*>(prop, b.base, n);
03209       home.free<ActorLink*>(b.base,n);
03210       b.base = prop;
03211     }
03212   }
03213 
03214   template<class VIC>
03215   void
03216   VarImp<VIC>::subscribe(Space& home, Propagator& p, PropCond pc,
03217                          bool assigned, ModEvent me, bool schedule) {
03218     if (assigned) {
03219       // Do not subscribe, just schedule the propagator
03220       if (schedule)
03221         VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
03222     } else {
03223       enter(home,&p,pc);
03224       // Schedule propagator
03225       if (schedule && (pc != PC_GEN_ASSIGNED))
03226         VarImp<VIC>::schedule(home,p,me);
03227     }
03228   }
03229 
03230   template<class VIC>
03231   forceinline void
03232   VarImp<VIC>::subscribe(Space& home, Advisor& a, bool assigned) {
03233     if (!assigned)
03234       enter(home,&a);
03235   }
03236 
03237   template<class VIC>
03238   forceinline void
03239   VarImp<VIC>::remove(Space& home, Propagator* p, PropCond pc) {
03240     assert(pc <= pc_max);
03241     ActorLink* a = ActorLink::cast(p);
03242     // Find actor in dependency array
03243     ActorLink** f = actor(pc);
03244 #ifdef GECODE_AUDIT
03245     while (f < actorNonZero(pc+1))
03246       if (*f == a)
03247         goto found;
03248       else
03249         f++;
03250     GECODE_NEVER;
03251   found: ;
03252 #else
03253     while (*f != a) f++;
03254 #endif
03255     // Remove actor
03256     *f = *(actorNonZero(pc+1)-1);
03257     for (PropCond j = pc+1; j< pc_max+1; j++) {
03258       *(actorNonZero(j)-1) = *(actorNonZero(j+1)-1);
03259       idx(j)--;
03260     }
03261     *(actorNonZero(pc_max+1)-1) = b.base[entries-1];
03262     idx(pc_max+1)--;
03263     entries--;
03264     free_and_bits += 1 << free_bits;
03265     home.pc.p.n_sub -= 1;
03266   }
03267 
03268   template<class VIC>
03269   forceinline void
03270   VarImp<VIC>::remove(Space& home, Advisor* a) {
03271     // Find actor in dependency array
03272     ActorLink** f = actorNonZero(pc_max+1);
03273 #ifdef GECODE_AUDIT
03274     while (f < b.base+entries)
03275       if (*f == a)
03276         goto found;
03277       else
03278         f++;
03279     GECODE_NEVER;
03280   found: ;
03281 #else
03282     while (*f != a) f++;
03283 #endif
03284     // Remove actor
03285     *f = b.base[--entries];
03286     free_and_bits += 1 << free_bits;
03287     home.pc.p.n_sub -= 1;
03288   }
03289 
03290   template<class VIC>
03291   forceinline void
03292   VarImp<VIC>::cancel(Space& home, Propagator& p, PropCond pc, bool assigned) {
03293     if (!assigned)
03294       remove(home,&p,pc);
03295   }
03296 
03297   template<class VIC>
03298   forceinline void
03299   VarImp<VIC>::cancel(Space& home, Advisor& a, bool assigned) {
03300     if (!assigned)
03301       remove(home,&a);
03302   }
03303 
03304   template<class VIC>
03305   forceinline void
03306   VarImp<VIC>::cancel(Space& home) {
03307     unsigned int n_sub = degree();
03308     home.pc.p.n_sub -= n_sub;
03309     unsigned int n = (free_and_bits >> VIC::free_bits) + n_sub;
03310     home.free<ActorLink*>(b.base,n);
03311     // Must be NULL such that cloning works
03312     b.base = NULL;
03313     // Must be 0 such that degree works
03314     entries = 0;
03315   }
03316 
03317   template<class VIC>
03318   forceinline bool
03319   VarImp<VIC>::advise(Space& home, ModEvent me, Delta& d) {
03320     /*
03321      * An advisor that is executed might remove itself due to subsumption.
03322      * As entries are removed from front to back, the advisors must
03323      * be iterated in forward direction.
03324      */
03325     ActorLink** la = actorNonZero(pc_max+1);
03326     ActorLink** le = b.base+entries;
03327     if (la == le)
03328       return true;
03329     d.me = me;
03330     // An advisor that is run, might be removed during execution.
03331     // As removal is done from the back the advisors have to be executed
03332     // in inverse order.
03333     do {
03334       Advisor* a = Advisor::cast(*la);
03335       assert(!a->disposed());
03336       Propagator& p = a->propagator();
03337       switch (p.advise(home,*a,d)) {
03338       case ES_FIX:
03339         break;
03340       case ES_FAILED:
03341         p.pi.fail(home.gpi);
03342         return false;
03343       case ES_NOFIX:
03344         schedule(home,p,me);
03345         break;
03346       case ES_NOFIX_FORCE:
03347         schedule(home,p,me,true);
03348         break;
03349       default:
03350         GECODE_NEVER;
03351       }
03352     } while (++la < le);
03353     return true;
03354   }
03355 
03356   template<class VIC>
03357   forceinline void
03358   VarImp<VIC>::update(VarImp<VIC>* x, ActorLink**& sub) {
03359     // this refers to the variable to be updated (clone)
03360     // x refers to the original
03361     // Recover from copy
03362     x->b.base = b.base;
03363     x->u.idx[0] = u.idx[0];
03364     if (pc_max > 0 && sizeof(ActorLink**) > sizeof(unsigned int))
03365       x->u.idx[1] = u.idx[1];
03366 
03367     ActorLink** f = x->b.base;
03368     unsigned int n = x->degree();
03369     ActorLink** t = sub;
03370     sub += n;
03371     b.base = t;
03372     // Set subscriptions using actor forwarding pointers
03373     while (n >= 4) {
03374       n -= 4;
03375       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03376       t[2]=f[2]->prev(); t[3]=f[3]->prev();
03377       t += 4; f += 4;
03378     }
03379     if (n >= 2) {
03380       n -= 2;
03381       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03382       t += 2; f += 2;
03383     }
03384     if (n > 0) {
03385       t[0]=f[0]->prev();
03386     }
03387   }
03388 
03389   template<class VIC>
03390   forceinline void
03391   VarImp<VIC>::update(Space& home, ActorLink**& sub) {
03392     VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home.pc.c.vars_u[idx_c]);
03393     while (x != NULL) {
03394       VarImp<VIC>* n = x->next(); x->forward()->update(x,sub); x = n;
03395     }
03396   }
03397 
03398 
03399 
03400   /*
03401    * Variable disposer
03402    *
03403    */
03404   template<class VarImp>
03405   VarImpDisposer<VarImp>::VarImpDisposer(void) {
03406 #ifdef GECODE_HAS_VAR_DISPOSE
03407     Space::vd[VarImp::idx_d] = this;
03408 #endif
03409   }
03410 
03411   template<class VarImp>
03412   void
03413   VarImpDisposer<VarImp>::dispose(Space& home, VarImpBase* _x) {
03414     VarImp* x = static_cast<VarImp*>(_x);
03415     do {
03416       x->dispose(home); x = static_cast<VarImp*>(x->next_d());
03417     } while (x != NULL);
03418   }
03419 
03420   /*
03421    * Statistics
03422    */
03423 
03424   forceinline void
03425   StatusStatistics::reset(void) {
03426     propagate = 0;
03427     wmp = false;
03428   }
03429   forceinline
03430   StatusStatistics::StatusStatistics(void) {
03431     reset();
03432   }
03433   forceinline StatusStatistics&
03434   StatusStatistics::operator +=(const StatusStatistics& s) { 
03435     propagate += s.propagate;
03436     wmp |= s.wmp;
03437     return *this;
03438   }
03439   forceinline StatusStatistics
03440   StatusStatistics::operator +(const StatusStatistics& s) {
03441     StatusStatistics t(s);
03442     return t += *this;
03443   }
03444 
03445   forceinline void
03446   CloneStatistics::reset(void) {}
03447 
03448   forceinline
03449   CloneStatistics::CloneStatistics(void) {
03450     reset();
03451   }
03452   forceinline CloneStatistics
03453   CloneStatistics::operator +(const CloneStatistics&) {
03454     CloneStatistics s;
03455     return s;
03456   }
03457   forceinline CloneStatistics&
03458   CloneStatistics::operator +=(const CloneStatistics&) { 
03459     return *this;
03460   }
03461 
03462   forceinline void
03463   CommitStatistics::reset(void) {}
03464 
03465   forceinline
03466   CommitStatistics::CommitStatistics(void) {
03467     reset();
03468   }
03469   forceinline CommitStatistics
03470   CommitStatistics::operator +(const CommitStatistics&) {
03471     CommitStatistics s;
03472     return s;
03473   }
03474   forceinline CommitStatistics&
03475   CommitStatistics::operator +=(const CommitStatistics&) { 
03476     return *this;
03477   }
03478 
03479   /*
03480    * Cost computation
03481    *
03482    */
03483 
03484   forceinline
03485   PropCost::PropCost(PropCost::ActualCost ac0) : ac(ac0) {}
03486 
03487   forceinline PropCost
03488   PropCost::cost(PropCost::Mod m,
03489                  PropCost::ActualCost lo, PropCost::ActualCost hi,
03490                  unsigned int n) {
03491     if (n < 2)
03492       return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
03493     else if (n == 2)
03494       return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
03495     else if (n == 3)
03496       return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
03497     else
03498       return (m == LO) ? lo : hi;
03499   }
03500 
03501   forceinline PropCost
03502   PropCost::crazy(PropCost::Mod m, unsigned int n) {
03503     return cost(m,AC_CRAZY_LO,AC_CRAZY_HI,n);
03504   }
03505   forceinline PropCost
03506   PropCost::crazy(PropCost::Mod m, int n) {
03507     assert(n >= 0);
03508     return crazy(m,static_cast<unsigned int>(n));
03509   }
03510   forceinline PropCost
03511   PropCost::cubic(PropCost::Mod m, unsigned int n) {
03512     return cost(m,AC_CUBIC_LO,AC_CUBIC_HI,n);
03513   }
03514   forceinline PropCost
03515   PropCost::cubic(PropCost::Mod m, int n) {
03516     assert(n >= 0);
03517     return cubic(m,static_cast<unsigned int>(n));
03518   }
03519   forceinline PropCost
03520   PropCost::quadratic(PropCost::Mod m, unsigned int n) {
03521     return cost(m,AC_QUADRATIC_LO,AC_QUADRATIC_HI,n);
03522   }
03523   forceinline PropCost
03524   PropCost::quadratic(PropCost::Mod m, int n) {
03525     assert(n >= 0);
03526     return quadratic(m,static_cast<unsigned int>(n));
03527   }
03528   forceinline PropCost
03529   PropCost::linear(PropCost::Mod m, unsigned int n) {
03530     return cost(m,AC_LINEAR_LO,AC_LINEAR_HI,n);
03531   }
03532   forceinline PropCost
03533   PropCost::linear(PropCost::Mod m, int n) {
03534     assert(n >= 0);
03535     return linear(m,static_cast<unsigned int>(n));
03536   }
03537   forceinline PropCost
03538   PropCost::ternary(PropCost::Mod m) {
03539     return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
03540   }
03541   forceinline PropCost
03542   PropCost::binary(PropCost::Mod m) {
03543     return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
03544   }
03545   forceinline PropCost
03546   PropCost::unary(PropCost::Mod m) {
03547     return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
03548   }
03549 
03550   /*
03551    * Iterators for propagators and branchers of a space
03552    *
03553    */
03554   forceinline
03555   Space::Propagators::Propagators(const Space& home0) 
03556     : home(home0), q(home.pc.p.active) {
03557     while (q >= &home.pc.p.queue[0]) {
03558       if (q->next() != q) {
03559         c = q->next(); e = q; q--;
03560         return;
03561       }
03562       q--;
03563     }
03564     q = NULL;
03565     if (!home.pl.empty()) {
03566       c = Propagator::cast(home.pl.next());
03567       e = Propagator::cast(&home.pl);
03568     } else {
03569       c = e = NULL;
03570     }
03571   }
03572   forceinline bool 
03573   Space::Propagators::operator ()(void) const {
03574     return c != NULL;
03575   }
03576   forceinline void 
03577   Space::Propagators::operator ++(void) {
03578     c = c->next();
03579     if (c == e) {
03580       if (q == NULL) {
03581         c = NULL;
03582       } else {
03583         while (q >= &home.pc.p.queue[0]) {
03584           if (q->next() != q) {
03585             c = q->next(); e = q; q--;
03586             return;
03587           }
03588           q--;
03589         }
03590         q = NULL;
03591         if (!home.pl.empty()) {
03592           c = Propagator::cast(home.pl.next());
03593           e = Propagator::cast(&home.pl);
03594         } else {
03595           c = NULL;
03596         }
03597       }
03598     }
03599   }
03600   forceinline const Propagator& 
03601   Space::Propagators::propagator(void) const {
03602     return *Propagator::cast(c);
03603   }
03604 
03605   forceinline
03606   Space::Branchers::Branchers(const Space& home) 
03607     : c(Brancher::cast(home.bl.next())), e(&home.bl) {}
03608   forceinline bool 
03609   Space::Branchers::operator ()(void) const {
03610     return c != e;
03611   }
03612   forceinline void 
03613   Space::Branchers::operator ++(void) {
03614     c = c->next();
03615   }
03616   forceinline const Brancher& 
03617   Space::Branchers::brancher(void) const {
03618     return *Brancher::cast(c);
03619   }
03620 
03621   /*
03622    * Space construction support
03623    *
03624    */
03625   template<class T> 
03626   forceinline T& 
03627   Space::construct(void) {
03628     return alloc<T>(1);
03629   }
03630   template<class T, typename A1> 
03631   forceinline T& 
03632   Space::construct(A1 const& a1) {
03633     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03634     new (&t) T(a1);
03635     return t;
03636   }
03637   template<class T, typename A1, typename A2> 
03638   forceinline T& 
03639   Space::construct(A1 const& a1, A2 const& a2) {
03640     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03641     new (&t) T(a1,a2);
03642     return t;
03643   }
03644   template<class T, typename A1, typename A2, typename A3>
03645   forceinline T& 
03646   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
03647     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03648     new (&t) T(a1,a2,a3);
03649     return t;
03650   }
03651   template<class T, typename A1, typename A2, typename A3, typename A4>
03652   forceinline T& 
03653   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
03654     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03655     new (&t) T(a1,a2,a3,a4);
03656     return t;
03657   }
03658   template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
03659   forceinline T& 
03660   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
03661     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03662     new (&t) T(a1,a2,a3,a4,a5);
03663     return t;
03664   }
03665 
03666 }
03667 
03668 // STATISTICS: kernel-core