Generated on Wed Mar 13 11:48:31 2013 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: 2013-03-05 15:37:20 +0100 (Tue, 05 Mar 2013) $ by $Author: schulte $
00022  *     $Revision: 13437 $
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   class AFC;
00222   class Brancher;
00223   class BrancherHandle;
00224   template<class A> class Council;
00225   template<class A> class Advisors;
00226   template<class VIC> class VarImp;
00227 
00228 
00229   /*
00230    * Variable implementations
00231    *
00232    */
00233 
00241   class VarImpBase {};
00242 
00249   class GECODE_VTABLE_EXPORT VarImpDisposerBase {
00250   public:
00252     GECODE_KERNEL_EXPORT virtual void dispose(Space& home, VarImpBase* x);
00254     GECODE_KERNEL_EXPORT virtual ~VarImpDisposerBase(void);
00255   };
00256 
00263   template<class VarImp>
00264   class VarImpDisposer : public VarImpDisposerBase {
00265   public:
00267     VarImpDisposer(void);
00269     virtual void dispose(Space& home, VarImpBase* x);
00270   };
00271 
00273   class Delta {
00274     template<class VIC> friend class VarImp;
00275   private:
00277     ModEvent me;
00278   };
00279 
00287   template<class VIC>
00288   class VarImp : public VarImpBase {
00289     friend class Space;
00290     friend class Propagator;
00291     template<class VarImp> friend class VarImpDisposer;
00292   private:
00293     union {
00301       ActorLink** base;
00310       VarImp<VIC>* fwd;
00311     } b;
00312 
00314     static const int idx_c = VIC::idx_c;
00316     static const int idx_d = VIC::idx_d;
00318     static const int free_bits = VIC::free_bits;
00320     unsigned int entries;
00322     unsigned int free_and_bits;
00324     static const Gecode::PropCond pc_max = VIC::pc_max;
00325 
00326     union {
00337       unsigned int idx[pc_max+1];
00339       VarImp<VIC>* next;
00340     } u;
00341 
00343     ActorLink** actor(PropCond pc);
00345     ActorLink** actorNonZero(PropCond pc);
00347     unsigned int& idx(PropCond pc);
00349     unsigned int idx(PropCond pc) const;
00350 
00357     void update(VarImp* x, ActorLink**& sub);
00364     static void update(Space& home, ActorLink**& sub);
00365 
00367     void enter(Space& home, Propagator* p, PropCond pc);
00369     void enter(Space& home, Advisor* a);
00371     void resize(Space& home);
00373     void remove(Space& home, Propagator* p, PropCond pc);
00375     void remove(Space& home, Advisor* a);
00376 
00377 
00378   protected:
00380     void cancel(Space& home);
00386     bool advise(Space& home, ModEvent me, Delta& d);
00387 #ifdef GECODE_HAS_VAR_DISPOSE
00388 
00389     static VarImp<VIC>* vars_d(Space& home);
00391     static void vars_d(Space& home, VarImp<VIC>* x);
00392 #endif
00393 
00394   public:
00396     VarImp(Space& home);
00398     VarImp(void);
00399 
00401 
00402 
00414     void subscribe(Space& home, Propagator& p, PropCond pc,
00415                    bool assigned, ModEvent me, bool schedule);
00421     void cancel(Space& home, Propagator& p, PropCond pc,
00422                 bool assigned);
00428     void subscribe(Space& home, Advisor& a, bool assigned);
00434     void cancel(Space& home, Advisor& a, bool assigned);
00435 
00442     unsigned int degree(void) const;
00449     double afc(const Space& home) const;
00451 
00453 
00454 
00455     VarImp(Space& home, bool share, VarImp& x);
00457     bool copied(void) const;
00459     VarImp* forward(void) const;
00461     VarImp* next(void) const;
00463 
00465 
00466 
00473     static void schedule(Space& home, Propagator& p, ModEvent me,
00474                          bool force = false);
00476     static ModEvent me(const ModEventDelta& med);
00478     static ModEventDelta med(ModEvent me);
00480     static ModEvent me_combine(ModEvent me1, ModEvent me2);
00482 
00484 
00485 
00486     static ModEvent modevent(const Delta& d);
00488 
00490 
00491 
00492     unsigned int bits(void) const;
00494     unsigned int& bits(void);
00496 
00497   protected:
00499     void schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me);
00500 
00501   public:
00503 
00504 
00505     static void* operator new(size_t,Space&);
00507     static void  operator delete(void*,Space&);
00509     static void  operator delete(void*);
00511   };
00512 
00521   enum ExecStatus {
00522     __ES_SUBSUMED       = -2, 
00523     ES_FAILED           = -1, 
00524     ES_NOFIX            =  0, 
00525     ES_OK               =  0, 
00526     ES_FIX              =  1, 
00527     ES_NOFIX_FORCE      =  2, 
00528     __ES_PARTIAL        =  2  
00529   };
00530 
00535   class PropCost {
00536     friend class Space;
00537   public:
00539     enum ActualCost {
00540       AC_CRAZY_LO     = 0, 
00541       AC_CRAZY_HI     = 0, 
00542       AC_CUBIC_LO     = 1, 
00543       AC_CUBIC_HI     = 1, 
00544       AC_QUADRATIC_LO = 2, 
00545       AC_QUADRATIC_HI = 2, 
00546       AC_LINEAR_HI    = 3, 
00547       AC_LINEAR_LO    = 4, 
00548       AC_TERNARY_HI   = 4, 
00549       AC_BINARY_HI    = 5, 
00550       AC_TERNARY_LO   = 5, 
00551       AC_BINARY_LO    = 6, 
00552       AC_UNARY_LO     = 6, 
00553       AC_UNARY_HI     = 6, 
00554       AC_MAX          = 6  
00555     };
00557     ActualCost ac;
00558   public:
00560     enum Mod {
00561       LO, 
00562       HI  
00563     };
00564   private:
00566     static PropCost cost(Mod m, ActualCost lo, ActualCost hi, unsigned int n);
00568     PropCost(ActualCost ac);
00569   public:
00571     static PropCost crazy(PropCost::Mod m, unsigned int n);
00573     static PropCost crazy(PropCost::Mod m, int n);
00575     static PropCost cubic(PropCost::Mod m, unsigned int n);
00577     static PropCost cubic(PropCost::Mod m, int n);
00579     static PropCost quadratic(PropCost::Mod m, unsigned int n);
00581     static PropCost quadratic(PropCost::Mod m, int n);
00583     static PropCost linear(PropCost::Mod m, unsigned int n);
00585     static PropCost linear(PropCost::Mod m, int n);
00587     static PropCost ternary(PropCost::Mod m);
00589     static PropCost binary(PropCost::Mod m);
00591     static PropCost unary(PropCost::Mod m);
00592   };
00593 
00594 
00599   enum ActorProperty {
00608     AP_DISPOSE = (1 << 0),
00614     AP_WEAKLY  = (1 << 1)
00615   };
00616 
00617 
00625   class ActorLink {
00626     friend class Actor;
00627     friend class Propagator;
00628     friend class Advisor;
00629     friend class Brancher;
00630     friend class LocalObject;
00631     friend class Space;
00632     template<class VIC> friend class VarImp;
00633   private:
00634     ActorLink* _next; ActorLink* _prev;
00635   public:
00637 
00638     ActorLink* prev(void) const; void prev(ActorLink*);
00639     ActorLink* next(void) const; void next(ActorLink*);
00640     ActorLink** next_ref(void);
00642 
00644     void init(void);
00646     void unlink(void);
00648     void head(ActorLink* al);
00650     void tail(ActorLink* al);
00652     bool empty(void) const;
00654     template<class T> static ActorLink* cast(T* a);
00656     template<class T> static const ActorLink* cast(const T* a);
00657   };
00658 
00659 
00664   class GECODE_VTABLE_EXPORT Actor : private ActorLink {
00665     friend class ActorLink;
00666     friend class Space;
00667     friend class Propagator;
00668     friend class Advisor;
00669     friend class Brancher;
00670     friend class LocalObject;
00671     template<class VIC> friend class VarImp;
00672     template<class A> friend class Council;
00673   private:
00675     static Actor* cast(ActorLink* al);
00677     static const Actor* cast(const ActorLink* al);
00679     GECODE_KERNEL_EXPORT static Actor* sentinel;
00680   public:
00682     virtual Actor* copy(Space& home, bool share) = 0;
00683 
00685 
00686 
00687     GECODE_KERNEL_EXPORT
00688     virtual size_t allocated(void) const;
00690     GECODE_KERNEL_EXPORT
00691     virtual size_t dispose(Space& home);
00693     static void* operator new(size_t s, Space& home);
00695     static void  operator delete(void* p, Space& home);
00696   private:
00697 #ifndef __GNUC__
00698 
00699     static void  operator delete(void* p);
00700 #endif
00701 
00702     static void* operator new(size_t s);
00704 #ifdef __GNUC__
00705   public:
00707     GECODE_KERNEL_EXPORT virtual ~Actor(void);
00709     static void  operator delete(void* p);
00710 #endif
00711   };
00712 
00713 
00714 
00718   class Home {
00719   protected:
00721     Space& s;
00723     Propagator* p;
00724   public:
00726 
00727 
00728     Home(Space& s, Propagator* p=NULL);
00730     Home& operator =(const Home& h);
00732     operator Space&(void);
00734 
00735 
00736 
00737     Home operator ()(Propagator& p);
00739     Propagator* propagator(void) const;
00741 
00742 
00743 
00744     bool failed(void) const;
00746     void fail(void);
00748     void notice(Actor& a, ActorProperty p);
00750   };
00751 
00756   class GECODE_VTABLE_EXPORT Propagator : public Actor {
00757     friend class ActorLink;
00758     friend class Space;
00759     template<class VIC> friend class VarImp;
00760     friend class Advisor;
00761     template<class A> friend class Council;
00762   private:
00763     union {
00765       ModEventDelta med;
00767       size_t size;
00769       Gecode::ActorLink* advisors;
00770     } u;
00772     GlobalAFC::Counter& gafc;
00774     static Propagator* cast(ActorLink* al);
00776     static const Propagator* cast(const ActorLink* al);
00777   protected:
00779     Propagator(Home home);
00781     Propagator(Space& home, bool share, Propagator& p);
00782 
00783   public:
00785 
00786 
00809     virtual ExecStatus propagate(Space& home, const ModEventDelta& med) = 0;
00811     virtual PropCost cost(const Space& home, const ModEventDelta& med) const = 0;
00819     ModEventDelta modeventdelta(void) const;
00855     GECODE_KERNEL_EXPORT
00856     virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00858 
00859 
00860 
00861     double afc(const Space& home) const;
00863   };
00864 
00865 
00873   template<class A>
00874   class Council {
00875     friend class Advisor;
00876     friend class Advisors<A>;
00877   private:
00879     mutable ActorLink* advisors;
00880   public:
00882     Council(void);
00884     Council(Space& home);
00886     bool empty(void) const;
00888     void update(Space& home, bool share, Council<A>& c);
00890     void dispose(Space& home);
00891   };
00892 
00893 
00898   template<class A>
00899   class Advisors {
00900   private:
00902     ActorLink* a;
00903   public:
00905     Advisors(const Council<A>& c);
00907     bool operator ()(void) const;
00909     void operator ++(void);
00911     A& advisor(void) const;
00912   };
00913 
00914 
00925   class Advisor : private ActorLink {
00926     template<class VIC> friend class VarImp;
00927     template<class A> friend class Council;
00928     template<class A> friend class Advisors;
00929   private:
00931     bool disposed(void) const;
00933     static Advisor* cast(ActorLink* al);
00935     static const Advisor* cast(const ActorLink* al);
00936   protected:
00938     Propagator& propagator(void) const;
00939   public:
00941     template<class A>
00942     Advisor(Space& home, Propagator& p, Council<A>& c);
00944     Advisor(Space& home, bool share, Advisor& a);
00945 
00947 
00948 
00949     template<class A>
00950     void dispose(Space& home, Council<A>& c);
00952     static void* operator new(size_t s, Space& home);
00954     static void  operator delete(void* p, Space& home);
00956   private:
00957 #ifndef __GNUC__
00958 
00959     static void  operator delete(void* p);
00960 #endif
00961 
00962     static void* operator new(size_t s);
00963   };
00964 
00965 
00975   class GECODE_VTABLE_EXPORT Choice {
00976     friend class Space;
00977   private:
00978     unsigned int _id;  
00979     unsigned int _alt; 
00980 
00982     unsigned int id(void) const;
00983   protected:
00985     Choice(const Brancher& b, const unsigned int a);
00986   public:
00988     unsigned int alternatives(void) const;
00990     GECODE_KERNEL_EXPORT virtual ~Choice(void);
00992     virtual size_t size(void) const = 0;
00994     static void* operator new(size_t);
00996     static void  operator delete(void*);
00998     GECODE_KERNEL_EXPORT virtual void archive(Archive& e) const;
00999   };
01000 
01010   class GECODE_VTABLE_EXPORT Brancher : public Actor {
01011     friend class ActorLink;
01012     friend class Space;
01013     friend class Choice;
01014   private:
01016     unsigned int _id;
01018     static Brancher* cast(ActorLink* al);
01020     static const Brancher* cast(const ActorLink* al);
01021   protected:
01023     Brancher(Home home);
01025     Brancher(Space& home, bool share, Brancher& b);
01026   public:
01028 
01029 
01037     virtual bool status(const Space& home) const = 0;
01045     virtual const Choice* choice(Space& home) = 0;
01047     virtual const Choice* choice(const Space& home, Archive& e) = 0;
01054     virtual ExecStatus commit(Space& home, const Choice& c, 
01055                               unsigned int a) = 0;
01057     unsigned int id(void) const;
01059   };
01060 
01069   class BrancherHandle {
01070   private:
01072     unsigned int _id;
01073   public:
01075     BrancherHandle(void);
01077     BrancherHandle(const Brancher& b);
01079     void update(Space& home, bool share, BrancherHandle& bh);
01081     unsigned int id(void) const;
01083     bool operator ()(const Space& home) const;
01085     void kill(Space& home);
01086   };
01087 
01095   class LocalObject : public Actor {
01096     friend class ActorLink;
01097     friend class Space;
01098     friend class LocalHandle;
01099   protected:
01101     LocalObject(Home home);
01103     LocalObject(Space& home, bool share, LocalObject& l);
01105     static LocalObject* cast(ActorLink* al);
01107     static const LocalObject* cast(const ActorLink* al);
01108   private:
01110     GECODE_KERNEL_EXPORT void fwdcopy(Space& home, bool share);
01111   public:
01113     LocalObject* fwd(Space& home, bool share);
01114   };
01115 
01122   class LocalHandle {
01123   private:
01125     LocalObject* o;
01126   protected:
01128     LocalHandle(void);
01130     LocalHandle(LocalObject* lo);
01132     LocalHandle(const LocalHandle& lh);
01133   public:
01135     LocalHandle& operator =(const LocalHandle& lh);
01137     void update(Space& home, bool share, LocalHandle& lh);
01139     ~LocalHandle(void);
01140   protected:
01142     LocalObject* object(void) const;
01144     void object(LocalObject* n);
01145   };
01146 
01147 
01152   enum SpaceStatus {
01153     SS_FAILED, 
01154     SS_SOLVED, 
01155     SS_BRANCH  
01156   };
01157 
01162   class StatusStatistics {
01163   public:
01165     unsigned long int propagate;
01167     bool wmp;
01169     StatusStatistics(void);
01171     void reset(void);
01173     StatusStatistics operator +(const StatusStatistics& s);
01175     StatusStatistics& operator +=(const StatusStatistics& s);
01176   };
01177 
01182   class CloneStatistics {
01183   public:
01185     CloneStatistics(void);
01187     void reset(void);
01189     CloneStatistics operator +(const CloneStatistics& s);
01191     CloneStatistics& operator +=(const CloneStatistics& s);
01192   };
01193 
01198   class CommitStatistics {
01199   public:
01201     CommitStatistics(void);
01203     void reset(void);
01205     CommitStatistics operator +(const CommitStatistics& s);
01207     CommitStatistics& operator +=(const CommitStatistics& s);
01208   };
01209 
01210 
01214   class GECODE_VTABLE_EXPORT Space {
01215     friend class Actor;
01216     friend class Propagator;
01217     friend class Brancher;
01218     friend class Advisor;
01219     template<class VIC> friend class VarImp;
01220     template<class VarImp> friend class VarImpDisposer;
01221     friend class SharedHandle;
01222     friend class LocalObject;
01223     friend class Region;
01224     friend class AFC;
01225     friend class BrancherHandle;
01226   private:
01228     SharedMemory* sm;
01230     MemoryManager mm;
01232     GlobalAFC gafc;
01234     ActorLink pl;
01236     ActorLink bl;
01242     Brancher* b_status;
01254     Brancher* b_commit;
01256     Brancher* brancher(unsigned int id);
01258     GECODE_KERNEL_EXPORT
01259     void kill_brancher(unsigned int id);
01261     static const unsigned reserved_branch_id = 0U;
01262     union {
01264       struct {
01277         ActorLink* active;
01279         ActorLink queue[PropCost::AC_MAX+1];
01281         unsigned int branch_id;
01283         unsigned int n_sub;
01284       } p;
01286       struct {
01288         VarImpBase* vars_u[AllVarConf::idx_c];
01290         VarImpBase* vars_noidx;
01292         SharedHandle::Object* shared;
01294         LocalObject* local;
01295       } c;
01296     } pc;
01298     void enqueue(Propagator* p);
01303 #ifdef GECODE_HAS_VAR_DISPOSE
01304 
01305     GECODE_KERNEL_EXPORT static VarImpDisposerBase* vd[AllVarConf::idx_d];
01307     VarImpBase* _vars_d[AllVarConf::idx_d];
01309     template<class VIC> VarImpBase* vars_d(void) const;
01311     template<class VIC> void vars_d(VarImpBase* x);
01312 #endif
01313 
01314     void update(ActorLink** sub);
01316 
01318     Actor** d_fst;
01320     Actor** d_cur;
01322     Actor** d_lst;
01324     GECODE_KERNEL_EXPORT void d_resize(void);
01325 
01337     unsigned int _wmp_afc;
01339     void afc_enable(void);
01341     bool afc_enabled(void) const;
01343     void wmp(unsigned int n);
01345     unsigned int wmp(void) const;
01346 
01348     GECODE_KERNEL_EXPORT static StatusStatistics unused_status;
01350     GECODE_KERNEL_EXPORT static CloneStatistics unused_clone;
01352     GECODE_KERNEL_EXPORT static CommitStatistics unused_commit;
01353 
01372     GECODE_KERNEL_EXPORT Space* _clone(bool share=true);
01373 
01406     GECODE_KERNEL_EXPORT
01407     void _commit(const Choice& c, unsigned int a);
01408 
01410     GECODE_KERNEL_EXPORT
01411     void afc_decay(double d);
01413     double afc_decay(void) const;
01414   public:
01419     GECODE_KERNEL_EXPORT Space(void);
01424     GECODE_KERNEL_EXPORT virtual ~Space(void);
01435     GECODE_KERNEL_EXPORT Space(bool share, Space& s);
01442     virtual Space* copy(bool share) = 0;
01453     GECODE_KERNEL_EXPORT virtual void constrain(const Space& best);
01466     GECODE_KERNEL_EXPORT 
01467     virtual void master(unsigned long int i, const Space* s);
01480     GECODE_KERNEL_EXPORT 
01481     virtual void slave(unsigned long int i, const Space* s);
01486     static void* operator new(size_t);
01491     static void  operator delete(void*);
01492 
01493 
01494     /*
01495      * Member functions for search engines
01496      *
01497      */
01498 
01510     GECODE_KERNEL_EXPORT
01511     SpaceStatus status(StatusStatistics& stat=unused_status);
01512 
01544     GECODE_KERNEL_EXPORT
01545     const Choice* choice(void);
01546 
01556     GECODE_KERNEL_EXPORT
01557     const Choice* choice(Archive& e) const;
01558   
01579     Space* clone(bool share=true, CloneStatistics& stat=unused_clone) const;
01580 
01615     void commit(const Choice& c, unsigned int a,
01616                 CommitStatistics& stat=unused_commit);
01617 
01625     void notice(Actor& a, ActorProperty p);
01633     void ignore(Actor& a, ActorProperty p);
01634 
01635 
01646     ExecStatus ES_SUBSUMED(Propagator& p);
01661     ExecStatus ES_SUBSUMED_DISPOSED(Propagator& p, size_t s);
01672     ExecStatus ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med);
01683     ExecStatus ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med);
01684     
01695     template<class A>
01696     ExecStatus ES_FIX_DISPOSE(Council<A>& c, A& a);
01707     template<class A>
01708     ExecStatus ES_NOFIX_DISPOSE(Council<A>& c, A& a);
01720     template<class A>
01721     ExecStatus ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a);
01722     
01730     void fail(void);
01739     bool failed(void) const;
01744     bool stable(void) const;
01751     GECODE_KERNEL_EXPORT unsigned int propagators(void) const;
01758     GECODE_KERNEL_EXPORT unsigned int branchers(void) const;
01759 
01761 
01762 
01763     Home operator ()(Propagator& p);
01765 
01777     template<class T>
01778     T* alloc(long unsigned int n);
01785     template<class T>
01786     T* alloc(long int n);
01793     template<class T>
01794     T* alloc(unsigned int n);
01801     template<class T>
01802     T* alloc(int n);
01812     template<class T>
01813     void free(T* b, long unsigned int n);
01823     template<class T>
01824     void free(T* b, long int n);
01834     template<class T>
01835     void free(T* b, unsigned int n);
01845     template<class T>
01846     void free(T* b, int n);
01858     template<class T>
01859     T* realloc(T* b, long unsigned int n, long unsigned int m);
01871     template<class T>
01872     T* realloc(T* b, long int n, long int m);
01884     template<class T>
01885     T* realloc(T* b, unsigned int n, unsigned int m);
01897     template<class T>
01898     T* realloc(T* b, int n, int m);
01906     template<class T>
01907     T** realloc(T** b, long unsigned int n, long unsigned int m);
01915     template<class T>
01916     T** realloc(T** b, long int n, long int m);
01924     template<class T>
01925     T** realloc(T** b, unsigned int n, unsigned int m);
01933     template<class T>
01934     T** realloc(T** b, int n, int m);
01936     void* ralloc(size_t s);
01938     void rfree(void* p, size_t s);
01940     void* rrealloc(void* b, size_t n, size_t m);
01942     template<size_t> void* fl_alloc(void);
01948     template<size_t> void  fl_dispose(FreeList* f, FreeList* l);
01955     size_t allocated(void) const;
01964     GECODE_KERNEL_EXPORT void flush(void);
01966 
01967 
01968 
01971     template<class T> 
01972     T& construct(void);
01978     template<class T, typename A1> 
01979     T& construct(A1 const& a1);
01985     template<class T, typename A1, typename A2> 
01986     T& construct(A1 const& a1, A2 const& a2);
01992     template<class T, typename A1, typename A2, typename A3>
01993     T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
01999     template<class T, typename A1, typename A2, typename A3, typename A4>
02000     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
02006     template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
02007     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
02009 
02015     class Propagators {
02016     private:
02018       const Space& home;
02020       const ActorLink* q;
02022       const ActorLink* c;
02024       const ActorLink* e;
02025     public:
02027       Propagators(const Space& home);
02029       bool operator ()(void) const;
02031       void operator ++(void);
02033       const Propagator& propagator(void) const;
02034     };
02035 
02041     class Branchers {
02042     private:
02044       const ActorLink* c;
02046       const ActorLink* e;
02047     public:
02049       Branchers(const Space& home);
02051       bool operator ()(void) const;
02053       void operator ++(void);
02055       const Brancher& brancher(void) const;
02056     };    
02057   };
02058 
02059 
02060 
02061 
02062   /*
02063    * Memory management
02064    *
02065    */
02066 
02067   // Heap allocated
02068   forceinline void*
02069   SharedHandle::Object::operator new(size_t s) {
02070     return heap.ralloc(s);
02071   }
02072   forceinline void
02073   SharedHandle::Object::operator delete(void* p) {
02074     heap.rfree(p);
02075   }
02076 
02077   forceinline void*
02078   Space::operator new(size_t s) {
02079     return heap.ralloc(s);
02080   }
02081   forceinline void
02082   Space::operator delete(void* p) {
02083     heap.rfree(p);
02084   }
02085 
02086   forceinline void
02087   Choice::operator delete(void* p) {
02088     heap.rfree(p);
02089   }
02090   forceinline void*
02091   Choice::operator new(size_t s) {
02092     return heap.ralloc(s);
02093   }
02094 
02095   // Space allocation: general space heaps and free lists
02096   forceinline void*
02097   Space::ralloc(size_t s) {
02098     return mm.alloc(sm,s);
02099   }
02100   forceinline void
02101   Space::rfree(void* p, size_t s) {
02102     return mm.reuse(p,s);
02103   }
02104   forceinline void*
02105   Space::rrealloc(void* _b, size_t n, size_t m) {
02106     char* b = static_cast<char*>(_b);
02107     if (n < m) {
02108       char* p = static_cast<char*>(ralloc(m));
02109       memcpy(p,b,n);
02110       rfree(b,n);
02111       return p;
02112     } else {
02113       rfree(b+m,m-n);
02114       return b;
02115     }
02116   }
02117 
02118   template<size_t s>
02119   forceinline void*
02120   Space::fl_alloc(void) {
02121     return mm.template fl_alloc<s>(sm);
02122   }
02123   template<size_t s>
02124   forceinline void
02125   Space::fl_dispose(FreeList* f, FreeList* l) {
02126     mm.template fl_dispose<s>(f,l);
02127   }
02128 
02129   forceinline size_t
02130   Space::allocated(void) const {
02131     size_t s = mm.allocated();
02132     for (Actor** a = d_fst; a < d_cur; a++)
02133       s += (*a)->allocated();
02134     return s;
02135   }
02136 
02137   /*
02138    * Typed allocation routines
02139    *
02140    */
02141   template<class T>
02142   forceinline T*
02143   Space::alloc(long unsigned int n) {
02144     T* p = static_cast<T*>(ralloc(sizeof(T)*n));
02145     for (long unsigned int i=n; i--; )
02146       (void) new (p+i) T();
02147     return p;
02148   }
02149   template<class T>
02150   forceinline T*
02151   Space::alloc(long int n) {
02152     assert(n >= 0);
02153     return alloc<T>(static_cast<long unsigned int>(n));
02154   }
02155   template<class T>
02156   forceinline T*
02157   Space::alloc(unsigned int n) {
02158     return alloc<T>(static_cast<long unsigned int>(n));
02159   }
02160   template<class T>
02161   forceinline T*
02162   Space::alloc(int n) {
02163     assert(n >= 0);
02164     return alloc<T>(static_cast<long unsigned int>(n));
02165   }
02166 
02167   template<class T>
02168   forceinline void
02169   Space::free(T* b, long unsigned int n) {
02170     for (long unsigned int i=n; i--; )
02171       b[i].~T();
02172     rfree(b,n*sizeof(T));
02173   }
02174   template<class T>
02175   forceinline void
02176   Space::free(T* b, long int n) {
02177     assert(n >= 0);
02178     free<T>(b,static_cast<long unsigned int>(n));
02179   }
02180   template<class T>
02181   forceinline void
02182   Space::free(T* b, unsigned int n) {
02183     free<T>(b,static_cast<long unsigned int>(n));
02184   }
02185   template<class T>
02186   forceinline void
02187   Space::free(T* b, int n) {
02188     assert(n >= 0);
02189     free<T>(b,static_cast<long unsigned int>(n));
02190   }
02191 
02192   template<class T>
02193   forceinline T*
02194   Space::realloc(T* b, long unsigned int n, long unsigned int m) {
02195     if (n < m) {
02196       T* p = static_cast<T*>(ralloc(sizeof(T)*m));
02197       for (long unsigned int i=n; i--; )
02198         (void) new (p+i) T(b[i]);
02199       for (long unsigned int i=n; i<m; i++)
02200         (void) new (p+i) T();
02201       free<T>(b,n);
02202       return p;
02203     } else {
02204       free<T>(b+m,m-n);
02205       return b;
02206     }
02207   }
02208   template<class T>
02209   forceinline T*
02210   Space::realloc(T* b, long int n, long int m) {
02211     assert((n >= 0) && (m >= 0));
02212     return realloc<T>(b,static_cast<long unsigned int>(n),
02213                       static_cast<long unsigned int>(m));
02214   }
02215   template<class T>
02216   forceinline T*
02217   Space::realloc(T* b, unsigned int n, unsigned int m) {
02218     return realloc<T>(b,static_cast<long unsigned int>(n),
02219                       static_cast<long unsigned int>(m));
02220   }
02221   template<class T>
02222   forceinline T*
02223   Space::realloc(T* b, int n, int m) {
02224     assert((n >= 0) && (m >= 0));
02225     return realloc<T>(b,static_cast<long unsigned int>(n),
02226                       static_cast<long unsigned int>(m));
02227   }
02228 
02229 #define GECODE_KERNEL_REALLOC(T)                                        \
02230   template<>                                                            \
02231   forceinline T*                                                        \
02232   Space::realloc<T>(T* b, long unsigned int n, long unsigned int m) {   \
02233     return static_cast<T*>(rrealloc(b,n*sizeof(T),m*sizeof(T)));        \
02234   }                                                                     \
02235   template<>                                                            \
02236   forceinline T*                                                        \
02237   Space::realloc<T>(T* b, long int n, long int m) {                     \
02238     assert((n >= 0) && (m >= 0));                                       \
02239     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02240                       static_cast<long unsigned int>(m));               \
02241   }                                                                     \
02242   template<>                                                            \
02243   forceinline T*                                                        \
02244   Space::realloc<T>(T* b, unsigned int n, unsigned int m) {             \
02245     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02246                       static_cast<long unsigned int>(m));               \
02247   }                                                                     \
02248   template<>                                                            \
02249   forceinline T*                                                        \
02250   Space::realloc<T>(T* b, int n, int m) {                               \
02251     assert((n >= 0) && (m >= 0));                                       \
02252     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02253                       static_cast<long unsigned int>(m));               \
02254   }
02255 
02256   GECODE_KERNEL_REALLOC(bool)
02257   GECODE_KERNEL_REALLOC(signed char)
02258   GECODE_KERNEL_REALLOC(unsigned char)
02259   GECODE_KERNEL_REALLOC(signed short int)
02260   GECODE_KERNEL_REALLOC(unsigned short int)
02261   GECODE_KERNEL_REALLOC(signed int)
02262   GECODE_KERNEL_REALLOC(unsigned int)
02263   GECODE_KERNEL_REALLOC(signed long int)
02264   GECODE_KERNEL_REALLOC(unsigned long int)
02265   GECODE_KERNEL_REALLOC(float)
02266   GECODE_KERNEL_REALLOC(double)
02267 
02268 #undef GECODE_KERNEL_REALLOC
02269 
02270   template<class T>
02271   forceinline T**
02272   Space::realloc(T** b, long unsigned int n, long unsigned int m) {
02273     return static_cast<T**>(rrealloc(b,n*sizeof(T),m*sizeof(T*)));
02274   }
02275   template<class T>
02276   forceinline T**
02277   Space::realloc(T** b, long int n, long int m) {
02278     assert((n >= 0) && (m >= 0));
02279     return realloc<T*>(b,static_cast<long unsigned int>(n),
02280                        static_cast<long unsigned int>(m));
02281   }
02282   template<class T>
02283   forceinline T**
02284   Space::realloc(T** b, unsigned int n, unsigned int m) {
02285     return realloc<T*>(b,static_cast<long unsigned int>(n),
02286                        static_cast<long unsigned int>(m));
02287   }
02288   template<class T>
02289   forceinline T**
02290   Space::realloc(T** b, int n, int m) {
02291     assert((n >= 0) && (m >= 0));
02292     return realloc<T*>(b,static_cast<long unsigned int>(n),
02293                        static_cast<long unsigned int>(m));
02294   }
02295 
02296 
02297 #ifdef GECODE_HAS_VAR_DISPOSE
02298   template<class VIC>
02299   forceinline VarImpBase*
02300   Space::vars_d(void) const {
02301     return _vars_d[VIC::idx_d];
02302   }
02303   template<class VIC>
02304   forceinline void
02305   Space::vars_d(VarImpBase* x) {
02306     _vars_d[VIC::idx_d] = x;
02307   }
02308 #endif
02309 
02310   // Space allocated entities: Actors, variable implementations, and advisors
02311   forceinline void
02312   Actor::operator delete(void*) {}
02313   forceinline void
02314   Actor::operator delete(void*, Space&) {}
02315   forceinline void*
02316   Actor::operator new(size_t s, Space& home) {
02317     return home.ralloc(s);
02318   }
02319 
02320   template<class VIC>
02321   forceinline void
02322   VarImp<VIC>::operator delete(void*) {}
02323   template<class VIC>
02324   forceinline void
02325   VarImp<VIC>::operator delete(void*, Space&) {}
02326   template<class VIC>
02327   forceinline void*
02328   VarImp<VIC>::operator new(size_t s, Space& home) {
02329     return home.ralloc(s);
02330   }
02331 
02332 #ifndef __GNUC__
02333   forceinline void
02334   Advisor::operator delete(void*) {}
02335 #endif
02336   forceinline void
02337   Advisor::operator delete(void*, Space&) {}
02338   forceinline void*
02339   Advisor::operator new(size_t s, Space& home) {
02340     return home.ralloc(s);
02341   }
02342 
02343   /*
02344    * Shared objects and handles
02345    *
02346    */
02347   forceinline
02348   SharedHandle::Object::Object(void)
02349     : next(NULL), fwd(NULL), use_cnt(0) {}
02350   forceinline
02351   SharedHandle::Object::~Object(void) {
02352     assert(use_cnt == 0);
02353   }
02354 
02355   forceinline SharedHandle::Object*
02356   SharedHandle::object(void) const {
02357     return o;
02358   }
02359   forceinline void
02360   SharedHandle::subscribe(void) {
02361     if (o != NULL) o->use_cnt++;
02362   }
02363   forceinline void
02364   SharedHandle::cancel(void) {
02365     if ((o != NULL) && (--o->use_cnt == 0))
02366       delete o;
02367     o=NULL;
02368   }
02369   forceinline void
02370   SharedHandle::object(SharedHandle::Object* n) {
02371     if (n != o) {
02372       cancel(); o=n; subscribe();
02373     }
02374   }
02375   forceinline
02376   SharedHandle::SharedHandle(void) : o(NULL) {}
02377   forceinline
02378   SharedHandle::SharedHandle(SharedHandle::Object* so) : o(so) {
02379     subscribe();
02380   }
02381   forceinline
02382   SharedHandle::SharedHandle(const SharedHandle& sh) : o(sh.o) {
02383     subscribe();
02384   }
02385   forceinline SharedHandle&
02386   SharedHandle::operator =(const SharedHandle& sh) {
02387     if (&sh != this) {
02388       cancel(); o=sh.o; subscribe();
02389     }
02390     return *this;
02391   }
02392   forceinline void
02393   SharedHandle::update(Space& home, bool share, SharedHandle& sh) {
02394     if (sh.o == NULL) {
02395       o=NULL; return;
02396     } else if (share) {
02397       o=sh.o;
02398     } else if (sh.o->fwd != NULL) {
02399       o=sh.o->fwd;
02400     } else {
02401       o = sh.o->copy();
02402       sh.o->fwd = o;
02403       sh.o->next = home.pc.c.shared;
02404       home.pc.c.shared = sh.o;
02405     }
02406     subscribe();
02407   }
02408   forceinline
02409   SharedHandle::~SharedHandle(void) {
02410     cancel();
02411   }
02412 
02413 
02414 
02415   /*
02416    * ActorLink
02417    *
02418    */
02419   forceinline ActorLink*
02420   ActorLink::prev(void) const {
02421     return _prev;
02422   }
02423 
02424   forceinline ActorLink*
02425   ActorLink::next(void) const {
02426     return _next;
02427   }
02428 
02429   forceinline ActorLink**
02430   ActorLink::next_ref(void) {
02431     return &_next;
02432   }
02433 
02434   forceinline void
02435   ActorLink::prev(ActorLink* al) {
02436     _prev = al;
02437   }
02438 
02439   forceinline void
02440   ActorLink::next(ActorLink* al) {
02441     _next = al;
02442   }
02443 
02444   forceinline void
02445   ActorLink::unlink(void) {
02446     ActorLink* p = _prev; ActorLink* n = _next;
02447     p->_next = n; n->_prev = p;
02448   }
02449 
02450   forceinline void
02451   ActorLink::init(void) {
02452     _next = this; _prev =this;
02453   }
02454 
02455   forceinline void
02456   ActorLink::head(ActorLink* a) {
02457     // Inserts al at head of link-chain (that is, after this)
02458     ActorLink* n = _next;
02459     this->_next = a; a->_prev = this;
02460     a->_next = n; n->_prev = a;
02461   }
02462 
02463   forceinline void
02464   ActorLink::tail(ActorLink* a) {
02465     // Inserts al at tail of link-chain (that is, before this)
02466     ActorLink* p = _prev;
02467     a->_next = this; this->_prev = a;
02468     p->_next = a; a->_prev = p;
02469   }
02470 
02471   forceinline bool
02472   ActorLink::empty(void) const {
02473     return _next == this;
02474   }
02475 
02476   template<class T>
02477   forceinline ActorLink*
02478   ActorLink::cast(T* a) {
02479     // Turning al into a reference is for gcc, assume is for MSVC
02480     GECODE_NOT_NULL(a);
02481     ActorLink& t = *a;
02482     return static_cast<ActorLink*>(&t);
02483   }
02484 
02485   template<class T>
02486   forceinline const ActorLink*
02487   ActorLink::cast(const T* a) {
02488     // Turning al into a reference is for gcc, assume is for MSVC
02489     GECODE_NOT_NULL(a);
02490     const ActorLink& t = *a;
02491     return static_cast<const ActorLink*>(&t);
02492   }
02493 
02494 
02495   /*
02496    * Actor
02497    *
02498    */
02499   forceinline Actor*
02500   Actor::cast(ActorLink* al) {
02501     // Turning al into a reference is for gcc, assume is for MSVC
02502     GECODE_NOT_NULL(al);
02503     ActorLink& t = *al;
02504     return static_cast<Actor*>(&t);
02505   }
02506 
02507   forceinline const Actor*
02508   Actor::cast(const ActorLink* al) {
02509     // Turning al into a reference is for gcc, assume is for MSVC
02510     GECODE_NOT_NULL(al);
02511     const ActorLink& t = *al;
02512     return static_cast<const Actor*>(&t);
02513   }
02514 
02515   forceinline void
02516   Space::afc_enable(void) {
02517     _wmp_afc |= 1U;
02518   }
02519   forceinline bool
02520   Space::afc_enabled(void) const {
02521     return (_wmp_afc & 1U) != 0U;
02522   }
02523   forceinline void
02524   Space::wmp(unsigned int n) {
02525     _wmp_afc = (_wmp_afc & 1U) | (n << 1);
02526   }
02527   forceinline unsigned int
02528   Space::wmp(void) const {
02529     return _wmp_afc >> 1U;
02530   }
02531 
02532   forceinline void
02533   Space::notice(Actor& a, ActorProperty p) {
02534     if (p & AP_DISPOSE) {
02535       if (d_cur == d_lst)
02536         d_resize();
02537       *(d_cur++) = &a;
02538     }
02539     if (p & AP_WEAKLY) {
02540       if (wmp() == 0)
02541         wmp(2);
02542       else
02543         wmp(wmp()+1);
02544     }
02545   }
02546 
02547   forceinline void
02548   Home::notice(Actor& a, ActorProperty p) {
02549     s.notice(a,p);
02550   }
02551 
02552   forceinline void
02553   Space::ignore(Actor& a, ActorProperty p) {
02554     if (p & AP_DISPOSE) {
02555       // Check wether array has already been discarded as space
02556       // deletion is already in progress
02557       Actor** f = d_fst;
02558       if (f != NULL) {
02559         while (&a != *f)
02560           f++;
02561         *f = *(--d_cur);
02562       }
02563     }
02564     if (p & AP_WEAKLY) {
02565       assert(wmp() > 1U);
02566       wmp(wmp()-1);
02567     }
02568   }
02569 
02570   forceinline Space*
02571   Space::clone(bool share, CloneStatistics&) const {
02572     // Clone is only const for search engines. During cloning, several data
02573     // structures are updated (e.g. forwarding pointers), so we have to
02574     // cast away the constness.
02575     return const_cast<Space*>(this)->_clone(share);
02576   }
02577 
02578   forceinline void
02579   Space::commit(const Choice& c, unsigned int a, CommitStatistics&) {
02580     _commit(c,a);
02581   }
02582 
02583   forceinline double
02584   Space::afc_decay(void) const {
02585     return gafc.decay();
02586   }
02587 
02588   forceinline size_t
02589   Actor::dispose(Space&) {
02590     return sizeof(*this);
02591   }
02592 
02593 
02594   /*
02595    * Home for posting actors
02596    *
02597    */
02598   forceinline
02599   Home::Home(Space& s0, Propagator* p0) : s(s0), p(p0) {}
02600   forceinline Home&
02601   Home::operator =(const Home& h) {
02602     s=h.s; p=h.p;
02603     return *this;
02604   }
02605   forceinline
02606   Home::operator Space&(void) { 
02607     return s; 
02608   }
02609   forceinline Home
02610   Home::operator ()(Propagator& p) {
02611     return Home(s,&p);
02612   }
02613   forceinline Home
02614   Space::operator ()(Propagator& p) {
02615     return Home(*this,&p);
02616   }
02617   forceinline Propagator*
02618   Home::propagator(void) const {
02619     return p;
02620   }
02621 
02622   /*
02623    * Propagator
02624    *
02625    */
02626   forceinline Propagator*
02627   Propagator::cast(ActorLink* al) {
02628     // Turning al into a reference is for gcc, assume is for MSVC
02629     GECODE_NOT_NULL(al);
02630     ActorLink& t = *al;
02631     return static_cast<Propagator*>(&t);
02632   }
02633 
02634   forceinline const Propagator*
02635   Propagator::cast(const ActorLink* al) {
02636     // Turning al into a reference is for gcc, assume is for MSVC
02637     GECODE_NOT_NULL(al);
02638     const ActorLink& t = *al;
02639     return static_cast<const Propagator*>(&t);
02640   }
02641 
02642   forceinline
02643   Propagator::Propagator(Home home) 
02644     : gafc((home.propagator() != NULL) ?
02645            // Inherit time counter information
02646            home.propagator()->gafc :
02647            // New propagator information
02648            static_cast<Space&>(home).gafc.allocate()) {
02649     u.advisors = NULL;
02650     assert((u.med == 0) && (u.size == 0));
02651     static_cast<Space&>(home).pl.head(this);
02652   }
02653 
02654   forceinline
02655   Propagator::Propagator(Space&, bool, Propagator& p) 
02656     : gafc(p.gafc) {
02657     u.advisors = NULL;
02658     assert((u.med == 0) && (u.size == 0));
02659     // Set forwarding pointer
02660     p.prev(this);
02661   }
02662 
02663   forceinline ModEventDelta
02664   Propagator::modeventdelta(void) const {
02665     return u.med;
02666   }
02667 
02668   forceinline double
02669   Propagator::afc(const Space& home) const {
02670     return const_cast<Space&>(home).gafc.afc(gafc);
02671   }
02672 
02673   forceinline ExecStatus
02674   Space::ES_SUBSUMED_DISPOSED(Propagator& p, size_t s) {
02675     p.u.size = s;
02676     return __ES_SUBSUMED;
02677   }
02678 
02679   forceinline ExecStatus
02680   Space::ES_SUBSUMED(Propagator& p) {
02681     p.u.size = p.dispose(*this);
02682     return __ES_SUBSUMED;
02683   }
02684 
02685   forceinline ExecStatus
02686   Space::ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02687     p.u.med = med;
02688     assert(p.u.med != 0);
02689     return __ES_PARTIAL;
02690   }
02691 
02692   forceinline ExecStatus
02693   Space::ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02694     p.u.med = AllVarConf::med_combine(p.u.med,med);
02695     assert(p.u.med != 0);
02696     return __ES_PARTIAL;
02697   }
02698 
02699 
02700 
02701   /*
02702    * Brancher
02703    *
02704    */
02705   forceinline Brancher*
02706   Brancher::cast(ActorLink* al) {
02707     // Turning al into a reference is for gcc, assume is for MSVC
02708     GECODE_NOT_NULL(al);
02709     ActorLink& t = *al;
02710     return static_cast<Brancher*>(&t);
02711   }
02712 
02713   forceinline const Brancher*
02714   Brancher::cast(const ActorLink* al) {
02715     // Turning al into a reference is for gcc, assume is for MSVC
02716     GECODE_NOT_NULL(al);
02717     const ActorLink& t = *al;
02718     return static_cast<const Brancher*>(&t);
02719   }
02720 
02721   forceinline
02722   Brancher::Brancher(Home home) :
02723     _id(static_cast<Space&>(home).pc.p.branch_id++) {
02724     if (static_cast<Space&>(home).pc.p.branch_id == 0U)
02725       throw TooManyBranchers("Brancher::Brancher");
02726     // If no brancher available, make it the first one
02727     if (static_cast<Space&>(home).b_status == &static_cast<Space&>(home).bl) {
02728       static_cast<Space&>(home).b_status = this;
02729       if (static_cast<Space&>(home).b_commit == &static_cast<Space&>(home).bl)
02730         static_cast<Space&>(home).b_commit = this;
02731     }
02732     static_cast<Space&>(home).bl.tail(this);
02733   }
02734 
02735   forceinline
02736   Brancher::Brancher(Space&, bool, Brancher& b)
02737     : _id(b._id) {
02738     // Set forwarding pointer
02739     b.prev(this);
02740   }
02741 
02742   forceinline unsigned int
02743   Brancher::id(void) const {
02744     return _id;
02745   }
02746 
02747   forceinline Brancher*
02748   Space::brancher(unsigned int id) {
02749     /*
02750      * Due to weakly monotonic propagators the following scenario might
02751      * occur: a brancher has been committed with all its available
02752      * choices. Then, propagation determines less information
02753      * than before and the brancher now will create new choices.
02754      * Later, during recomputation, all of these choices
02755      * can be used together, possibly interleaved with 
02756      * choices for other branchers. That means all branchers
02757      * must be scanned to find the matching brancher for the choice.
02758      *
02759      * b_commit tries to optimize scanning as it is most likely that
02760      * recomputation does not generate new choices during recomputation
02761      * and hence b_commit is moved from newer to older branchers.
02762      */
02763     Brancher* b_old = b_commit;
02764     // Try whether we are lucky
02765     while (b_commit != Brancher::cast(&bl))
02766       if (id != b_commit->id())
02767         b_commit = Brancher::cast(b_commit->next());
02768       else
02769         return b_commit;
02770     if (b_commit == Brancher::cast(&bl)) {
02771       // We did not find the brancher, start at the beginning
02772       b_commit = Brancher::cast(bl.next());
02773       while (b_commit != b_old)
02774         if (id != b_commit->id())
02775           b_commit = Brancher::cast(b_commit->next());
02776         else
02777           return b_commit;
02778     }
02779     return NULL;
02780   }
02781   
02782   /*
02783    * Brancher handle
02784    *
02785    */
02786   forceinline
02787   BrancherHandle::BrancherHandle(void)
02788     : _id(Space::reserved_branch_id) {}
02789   forceinline
02790   BrancherHandle::BrancherHandle(const Brancher& b)
02791     : _id(b.id()) {}
02792   forceinline void
02793   BrancherHandle::update(Space&, bool, BrancherHandle& bh) {
02794     _id = bh._id;
02795   }
02796   forceinline unsigned int
02797   BrancherHandle::id(void) const {
02798     return _id;
02799   }
02800   forceinline bool
02801   BrancherHandle::operator ()(const Space& home) const {
02802     return const_cast<Space&>(home).brancher(_id) != NULL;
02803   }
02804   forceinline void
02805   BrancherHandle::kill(Space& home) {
02806     home.kill_brancher(_id);
02807   }
02808 
02809   
02810   /*
02811    * Local objects
02812    *
02813    */
02814 
02815   forceinline LocalObject*
02816   LocalObject::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<LocalObject*>(&t);
02821   }
02822 
02823   forceinline const LocalObject*
02824   LocalObject::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 LocalObject*>(&t);
02829   }
02830 
02831   forceinline
02832   LocalObject::LocalObject(Home) {
02833     ActorLink::cast(this)->prev(NULL);
02834   }
02835 
02836   forceinline
02837   LocalObject::LocalObject(Space&,bool,LocalObject&) {
02838     ActorLink::cast(this)->prev(NULL);
02839   }
02840 
02841   forceinline LocalObject*
02842   LocalObject::fwd(Space& home, bool share) {
02843     if (prev() == NULL)
02844       fwdcopy(home,share);
02845     return LocalObject::cast(prev());
02846   }
02847 
02848   forceinline
02849   LocalHandle::LocalHandle(void) : o(NULL) {}
02850   forceinline
02851   LocalHandle::LocalHandle(LocalObject* lo) : o(lo) {}
02852   forceinline
02853   LocalHandle::LocalHandle(const LocalHandle& lh) : o(lh.o) {}
02854   forceinline LocalHandle&
02855   LocalHandle::operator =(const LocalHandle& lh) {
02856     o = lh.o;
02857     return *this;
02858   }
02859   forceinline
02860   LocalHandle::~LocalHandle(void) {}
02861   forceinline LocalObject*
02862   LocalHandle::object(void) const { return o; }
02863   forceinline void
02864   LocalHandle::object(LocalObject* n) { o = n; }
02865   forceinline void
02866   LocalHandle::update(Space& home, bool share, LocalHandle& lh) {
02867     object(lh.object()->fwd(home,share));
02868   }
02869 
02870 
02871   /*
02872    * Choices
02873    *
02874    */
02875   forceinline
02876   Choice::Choice(const Brancher& b, const unsigned int a)
02877     : _id(b.id()), _alt(a) {}
02878 
02879   forceinline unsigned int
02880   Choice::alternatives(void) const {
02881     return _alt;
02882   }
02883 
02884   forceinline unsigned int
02885   Choice::id(void) const {
02886     return _id;
02887   }
02888 
02889   forceinline
02890   Choice::~Choice(void) {}
02891 
02892 
02893 
02894   /*
02895    * Advisor
02896    *
02897    */
02898   template<class A>
02899   forceinline
02900   Advisor::Advisor(Space&, Propagator& p, Council<A>& c) {
02901     // Store propagator and forwarding in prev()
02902     ActorLink::prev(&p);
02903     // Link to next advisor in next()
02904     ActorLink::next(c.advisors); c.advisors = static_cast<A*>(this);
02905   }
02906 
02907   forceinline
02908   Advisor::Advisor(Space&, bool, Advisor&) {}
02909 
02910   forceinline bool
02911   Advisor::disposed(void) const {
02912     return prev() == NULL;
02913   }
02914 
02915   forceinline Advisor*
02916   Advisor::cast(ActorLink* al) {
02917     return static_cast<Advisor*>(al);
02918   }
02919 
02920   forceinline const Advisor*
02921   Advisor::cast(const ActorLink* al) {
02922     return static_cast<const Advisor*>(al);
02923   }
02924 
02925   forceinline Propagator&
02926   Advisor::propagator(void) const {
02927     assert(!disposed());
02928     return *Propagator::cast(ActorLink::prev());
02929   }
02930 
02931   template<class A>
02932   forceinline void
02933   Advisor::dispose(Space&,Council<A>&) {
02934     assert(!disposed());
02935     ActorLink::prev(NULL);
02936     // Shorten chains of disposed advisors by one, if possible
02937     Advisor* n = Advisor::cast(next());
02938     if ((n != NULL) && n->disposed())
02939       next(n->next());
02940   }
02941 
02942   template<class A>
02943   forceinline ExecStatus
02944   Space::ES_FIX_DISPOSE(Council<A>& c, A& a) {
02945     a.dispose(*this,c);
02946     return ES_FIX;
02947   }
02948 
02949   template<class A>
02950   forceinline ExecStatus
02951   Space::ES_NOFIX_DISPOSE(Council<A>& c, A& a) {
02952     a.dispose(*this,c);
02953     return ES_NOFIX;
02954   }
02955 
02956   template<class A>
02957   forceinline ExecStatus
02958   Space::ES_NOFIX_DISPOSE_FORCE(Council<A>& c, A& a) {
02959     a.dispose(*this,c);
02960     return ES_NOFIX_FORCE;
02961   }
02962 
02963 
02964 
02965   /*
02966    * Advisor council
02967    *
02968    */
02969   template<class A>
02970   forceinline
02971   Council<A>::Council(void) {}
02972 
02973   template<class A>
02974   forceinline
02975   Council<A>::Council(Space&)
02976     : advisors(NULL) {}
02977 
02978   template<class A>
02979   forceinline bool
02980   Council<A>::empty(void) const {
02981     ActorLink* a = advisors;
02982     while ((a != NULL) && static_cast<A*>(a)->disposed())
02983       a = a->next();
02984     advisors = a;
02985     return a == NULL;
02986   }
02987 
02988   template<class A>
02989   forceinline void
02990   Council<A>::update(Space& home, bool share, Council<A>& c) {
02991     // Skip all disposed advisors
02992     {
02993       ActorLink* a = c.advisors;
02994       while ((a != NULL) && static_cast<A*>(a)->disposed())
02995         a = a->next();
02996       c.advisors = a;
02997     }
02998     // Are there any advisors to be cloned?
02999     if (c.advisors != NULL) {
03000       // The propagator in from-space
03001       Propagator* p_f = &static_cast<A*>(c.advisors)->propagator();
03002       // The propagator in to-space
03003       Propagator* p_t = Propagator::cast(p_f->prev());
03004       // Advisors in from-space
03005       ActorLink** a_f = &c.advisors;
03006       // Advisors in to-space
03007       A* a_t = NULL;
03008       while (*a_f != NULL) {
03009         if (static_cast<A*>(*a_f)->disposed()) {
03010           *a_f = (*a_f)->next();
03011         } else {
03012           // Run specific copying part
03013           A* a = new (home) A(home,share,*static_cast<A*>(*a_f));
03014           // Set propagator pointer
03015           a->prev(p_t);
03016           // Set forwarding pointer
03017           (*a_f)->prev(a);
03018           // Link
03019           a->next(a_t);
03020           a_t = a;
03021           a_f = (*a_f)->next_ref();
03022         }
03023       }
03024       advisors = a_t;
03025       // Enter advisor link for reset
03026       assert(p_f->u.advisors == NULL);
03027       p_f->u.advisors = c.advisors;
03028     } else {
03029       advisors = NULL;
03030     }
03031   }
03032 
03033   template<class A>
03034   forceinline void
03035   Council<A>::dispose(Space& home) {
03036     ActorLink* a = advisors;
03037     while (a != NULL) {
03038       if (!static_cast<A*>(a)->disposed())
03039         static_cast<A*>(a)->dispose(home,*this);
03040       a = a->next();
03041     }
03042   }
03043 
03044 
03045 
03046   /*
03047    * Advisor iterator
03048    *
03049    */
03050   template<class A>
03051   forceinline
03052   Advisors<A>::Advisors(const Council<A>& c)
03053     : a(c.advisors) {
03054     while ((a != NULL) && static_cast<A*>(a)->disposed())
03055       a = a->next();
03056   }
03057 
03058   template<class A>
03059   forceinline bool
03060   Advisors<A>::operator ()(void) const {
03061     return a != NULL;
03062   }
03063 
03064   template<class A>
03065   forceinline void
03066   Advisors<A>::operator ++(void) {
03067     do {
03068       a = a->next();
03069     } while ((a != NULL) && static_cast<A*>(a)->disposed());
03070   }
03071 
03072   template<class A>
03073   forceinline A&
03074   Advisors<A>::advisor(void) const {
03075     return *static_cast<A*>(a);
03076   }
03077 
03078 
03079 
03080   /*
03081    * Space
03082    *
03083    */
03084   forceinline void
03085   Space::enqueue(Propagator* p) {
03086     ActorLink::cast(p)->unlink();
03087     ActorLink* c = &pc.p.queue[p->cost(*this,p->u.med).ac];
03088     c->tail(ActorLink::cast(p));
03089     if (c > pc.p.active)
03090       pc.p.active = c;
03091   }
03092 
03093   forceinline void
03094   Space::fail(void) {
03095     /*
03096      * Now active points beyond the last queue. This is essential as
03097      * enqueuing a propagator in a failed space keeps the space
03098      * failed.
03099      */
03100     pc.p.active = &pc.p.queue[PropCost::AC_MAX+1]+1;
03101   }
03102   forceinline void
03103   Home::fail(void) {
03104     s.fail();
03105   }
03106 
03107   forceinline bool
03108   Space::failed(void) const {
03109     return pc.p.active > &pc.p.queue[PropCost::AC_MAX+1];
03110   }
03111   forceinline bool
03112   Home::failed(void) const {
03113     return s.failed();
03114   }
03115 
03116   forceinline bool
03117   Space::stable(void) const {
03118     return ((pc.p.active < &pc.p.queue[0]) ||
03119             (pc.p.active > &pc.p.queue[PropCost::AC_MAX+1]));
03120   }
03121 
03122 
03123 
03124   /*
03125    * Variable implementation
03126    *
03127    */
03128   template<class VIC>
03129   forceinline ActorLink**
03130   VarImp<VIC>::actor(PropCond pc) {
03131     assert((pc >= 0)  && (pc < pc_max+2));
03132     return (pc == 0) ? b.base : b.base+u.idx[pc-1];
03133   }
03134 
03135   template<class VIC>
03136   forceinline ActorLink**
03137   VarImp<VIC>::actorNonZero(PropCond pc) {
03138     assert((pc > 0)  && (pc < pc_max+2));
03139     return b.base+u.idx[pc-1];
03140   }
03141 
03142   template<class VIC>
03143   forceinline unsigned int&
03144   VarImp<VIC>::idx(PropCond pc) {
03145     assert((pc > 0)  && (pc < pc_max+2));
03146     return u.idx[pc-1];
03147   }
03148 
03149   template<class VIC>
03150   forceinline unsigned int
03151   VarImp<VIC>::idx(PropCond pc) const {
03152     assert((pc > 0)  && (pc < pc_max+2));
03153     return u.idx[pc-1];
03154   }
03155 
03156   template<class VIC>
03157   forceinline
03158   VarImp<VIC>::VarImp(Space&) {
03159     b.base = NULL; entries = 0;
03160     for (PropCond pc=1; pc<pc_max+2; pc++)
03161       idx(pc) = 0;
03162     free_and_bits = 0;
03163   }
03164 
03165   template<class VIC>
03166   forceinline
03167   VarImp<VIC>::VarImp(void) {
03168     b.base = NULL; entries = 0;
03169     for (PropCond pc=1; pc<pc_max+2; pc++)
03170       idx(pc) = 0;
03171     free_and_bits = 0;
03172   }
03173 
03174   template<class VIC>
03175   forceinline unsigned int
03176   VarImp<VIC>::degree(void) const {
03177     assert(!copied());
03178     return entries;
03179   }
03180 
03181   template<class VIC>
03182   forceinline double
03183   VarImp<VIC>::afc(const Space& home) const {
03184     double d = 0.0;
03185     // Count the afc of each propagator
03186     {
03187       ActorLink** a = const_cast<VarImp<VIC>*>(this)->actor(0);
03188       ActorLink** e = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
03189       while (a < e) {
03190         d += Propagator::cast(*a)->afc(home); a++;
03191       }
03192     }
03193     // Count the afc of each advisor's propagator
03194     {
03195       ActorLink** a = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
03196       ActorLink** e = const_cast<VarImp<VIC>*>(this)->b.base+entries;
03197       while (a < e) {
03198         d += Advisor::cast(*a)->propagator().afc(home); a++;
03199       }
03200     }
03201     return d;
03202   }
03203 
03204   template<class VIC>
03205   forceinline ModEvent
03206   VarImp<VIC>::modevent(const Delta& d) {
03207     return d.me;
03208   }
03209 
03210   template<class VIC>
03211   forceinline unsigned int
03212   VarImp<VIC>::bits(void) const {
03213     return free_and_bits;
03214   }
03215 
03216   template<class VIC>
03217   forceinline unsigned int&
03218   VarImp<VIC>::bits(void) {
03219     return free_and_bits;
03220   }
03221 
03222 #ifdef GECODE_HAS_VAR_DISPOSE
03223   template<class VIC>
03224   forceinline VarImp<VIC>*
03225   VarImp<VIC>::vars_d(Space& home) {
03226     return static_cast<VarImp<VIC>*>(home.vars_d<VIC>());
03227   }
03228 
03229   template<class VIC>
03230   forceinline void
03231   VarImp<VIC>::vars_d(Space& home, VarImp<VIC>* x) {
03232     home.vars_d<VIC>(x);
03233   }
03234 #endif
03235 
03236   template<class VIC>
03237   forceinline bool
03238   VarImp<VIC>::copied(void) const {
03239     return Support::marked(b.fwd);
03240   }
03241 
03242   template<class VIC>
03243   forceinline VarImp<VIC>*
03244   VarImp<VIC>::forward(void) const {
03245     assert(copied());
03246     return static_cast<VarImp<VIC>*>(Support::unmark(b.fwd));
03247   }
03248 
03249   template<class VIC>
03250   forceinline VarImp<VIC>*
03251   VarImp<VIC>::next(void) const {
03252     assert(copied());
03253     return u.next;
03254   }
03255 
03256   template<class VIC>
03257   forceinline
03258   VarImp<VIC>::VarImp(Space& home, bool, VarImp<VIC>& x) {
03259     VarImpBase** reg;
03260     free_and_bits = x.free_and_bits & ((1 << free_bits) - 1);
03261     if (x.b.base == NULL) {
03262       // Variable implementation needs no index structure
03263       reg = &home.pc.c.vars_noidx;
03264       assert(x.degree() == 0);
03265     } else {
03266       reg = &home.pc.c.vars_u[idx_c];
03267     }
03268     // Save subscriptions in copy
03269     b.base = x.b.base;
03270     entries = x.entries;
03271     for (PropCond pc=1; pc<pc_max+2; pc++)
03272       idx(pc) = x.idx(pc);
03273 
03274     // Set forwarding pointer
03275     x.b.fwd = static_cast<VarImp<VIC>*>(Support::mark(this));
03276     // Register original
03277     x.u.next = static_cast<VarImp<VIC>*>(*reg); *reg = &x;
03278   }
03279 
03280   template<class VIC>
03281   forceinline ModEvent
03282   VarImp<VIC>::me(const ModEventDelta& med) {
03283     return static_cast<ModEvent>((med & VIC::med_mask) >> VIC::med_fst);
03284   }
03285 
03286   template<class VIC>
03287   forceinline ModEventDelta
03288   VarImp<VIC>::med(ModEvent me) {
03289     return static_cast<ModEventDelta>(me << VIC::med_fst);
03290   }
03291 
03292   template<class VIC>
03293   forceinline ModEvent
03294   VarImp<VIC>::me_combine(ModEvent me1, ModEvent me2) {
03295     return VIC::me_combine(me1,me2);
03296   }
03297 
03298   template<class VIC>
03299   forceinline void
03300   VarImp<VIC>::schedule(Space& home, Propagator& p, ModEvent me,
03301                         bool force) {
03302     if (VIC::med_update(p.u.med,me) || force)
03303       home.enqueue(&p);
03304   }
03305 
03306   template<class VIC>
03307   forceinline void
03308   VarImp<VIC>::schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me) {
03309     ActorLink** b = actor(pc1);
03310     ActorLink** p = actorNonZero(pc2+1);
03311     while (p-- > b)
03312       schedule(home,*Propagator::cast(*p),me);
03313   }
03314 
03315   template<class VIC>
03316   forceinline void
03317   VarImp<VIC>::enter(Space& home, Propagator* p, PropCond pc) {
03318     assert(pc <= pc_max);
03319     // Count one new subscription
03320     home.pc.p.n_sub += 1;
03321     if ((free_and_bits >> free_bits) == 0)
03322       resize(home);
03323     free_and_bits -= 1 << free_bits;
03324 
03325     // Enter subscription
03326     b.base[entries] = *actorNonZero(pc_max+1);
03327     entries++;
03328     for (PropCond j = pc_max; j > pc; j--) {
03329       *actorNonZero(j+1) = *actorNonZero(j);
03330       idx(j+1)++;
03331     }
03332     *actorNonZero(pc+1) = *actor(pc);
03333     idx(pc+1)++;
03334     *actor(pc) = ActorLink::cast(p);
03335 
03336 #ifdef GECODE_AUDIT
03337     ActorLink** f = actor(pc);
03338     while (f < (pc == pc_max+1 ? b.base+entries : actorNonZero(pc+1)))
03339       if (*f == p)
03340         goto found;
03341       else
03342         f++;
03343     GECODE_NEVER;
03344     found: ;
03345 #endif
03346   }
03347 
03348   template<class VIC>
03349   forceinline void
03350   VarImp<VIC>::enter(Space& home, Advisor* a) {
03351     // Count one new subscription
03352     home.pc.p.n_sub += 1;
03353     if ((free_and_bits >> free_bits) == 0)
03354       resize(home);
03355     free_and_bits -= 1 << free_bits;
03356 
03357     // Enter subscription
03358     b.base[entries++] = *actorNonZero(pc_max+1);
03359     *actorNonZero(pc_max+1) = a;
03360   }
03361 
03362   template<class VIC>
03363   void
03364   VarImp<VIC>::resize(Space& home) {
03365     if (b.base == NULL) {
03366       assert((free_and_bits >> free_bits) == 0);
03367       // Create fresh dependency array with four entries
03368       free_and_bits += 4 << free_bits;
03369       b.base = home.alloc<ActorLink*>(4);
03370       for (int i=0; i<pc_max+1; i++)
03371         u.idx[i] = 0;
03372     } else {
03373       // Resize dependency array
03374       unsigned int n = degree();
03375       // Find out whether the area is most likely in the special area
03376       // reserved for subscriptions. If yes, just resize mildly otherwise
03377       // more agressively
03378       ActorLink** s = static_cast<ActorLink**>(home.mm.subscriptions());
03379       unsigned int m =
03380         ((s <= b.base) && (b.base < s+home.pc.p.n_sub)) ?
03381         (n+4) : ((n+1)*3>>1);
03382       ActorLink** prop = home.alloc<ActorLink*>(m);
03383       free_and_bits += (m-n) << free_bits;
03384       // Copy entries
03385       Heap::copy<ActorLink*>(prop, b.base, n);
03386       home.free<ActorLink*>(b.base,n);
03387       b.base = prop;
03388     }
03389   }
03390 
03391   template<class VIC>
03392   void
03393   VarImp<VIC>::subscribe(Space& home, Propagator& p, PropCond pc,
03394                          bool assigned, ModEvent me, bool schedule) {
03395     if (assigned) {
03396       // Do not subscribe, just schedule the propagator
03397       if (schedule)
03398         VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
03399     } else {
03400       enter(home,&p,pc);
03401       // Schedule propagator
03402       if (schedule && (pc != PC_GEN_ASSIGNED))
03403         VarImp<VIC>::schedule(home,p,me);
03404     }
03405   }
03406 
03407   template<class VIC>
03408   forceinline void
03409   VarImp<VIC>::subscribe(Space& home, Advisor& a, bool assigned) {
03410     if (!assigned)
03411       enter(home,&a);
03412   }
03413 
03414   template<class VIC>
03415   forceinline void
03416   VarImp<VIC>::remove(Space& home, Propagator* p, PropCond pc) {
03417     assert(pc <= pc_max);
03418     ActorLink* a = ActorLink::cast(p);
03419     // Find actor in dependency array
03420     ActorLink** f = actor(pc);
03421 #ifdef GECODE_AUDIT
03422     while (f < actorNonZero(pc+1))
03423       if (*f == a)
03424         goto found;
03425       else
03426         f++;
03427     GECODE_NEVER;
03428   found: ;
03429 #else
03430     while (*f != a) f++;
03431 #endif
03432     // Remove actor
03433     *f = *(actorNonZero(pc+1)-1);
03434     for (PropCond j = pc+1; j< pc_max+1; j++) {
03435       *(actorNonZero(j)-1) = *(actorNonZero(j+1)-1);
03436       idx(j)--;
03437     }
03438     *(actorNonZero(pc_max+1)-1) = b.base[entries-1];
03439     idx(pc_max+1)--;
03440     entries--;
03441     free_and_bits += 1 << free_bits;
03442     home.pc.p.n_sub -= 1;
03443   }
03444 
03445   template<class VIC>
03446   forceinline void
03447   VarImp<VIC>::remove(Space& home, Advisor* a) {
03448     // Find actor in dependency array
03449     ActorLink** f = actorNonZero(pc_max+1);
03450 #ifdef GECODE_AUDIT
03451     while (f < b.base+entries)
03452       if (*f == a)
03453         goto found;
03454       else
03455         f++;
03456     GECODE_NEVER;
03457   found: ;
03458 #else
03459     while (*f != a) f++;
03460 #endif
03461     // Remove actor
03462     *f = b.base[--entries];
03463     free_and_bits += 1 << free_bits;
03464     home.pc.p.n_sub -= 1;
03465   }
03466 
03467   template<class VIC>
03468   forceinline void
03469   VarImp<VIC>::cancel(Space& home, Propagator& p, PropCond pc, bool assigned) {
03470     if (!assigned)
03471       remove(home,&p,pc);
03472   }
03473 
03474   template<class VIC>
03475   forceinline void
03476   VarImp<VIC>::cancel(Space& home, Advisor& a, bool assigned) {
03477     if (!assigned)
03478       remove(home,&a);
03479   }
03480 
03481   template<class VIC>
03482   forceinline void
03483   VarImp<VIC>::cancel(Space& home) {
03484     unsigned int n_sub = degree();
03485     home.pc.p.n_sub -= n_sub;
03486     unsigned int n = (free_and_bits >> VIC::free_bits) + n_sub;
03487     home.free<ActorLink*>(b.base,n);
03488     // Must be NULL such that cloning works
03489     b.base = NULL;
03490     // Must be 0 such that degree works
03491     entries = 0;
03492   }
03493 
03494   template<class VIC>
03495   forceinline bool
03496   VarImp<VIC>::advise(Space& home, ModEvent me, Delta& d) {
03497     /*
03498      * An advisor that is executed might remove itself due to subsumption.
03499      * As entries are removed from front to back, the advisors must
03500      * be iterated in forward direction.
03501      */
03502     ActorLink** la = actorNonZero(pc_max+1);
03503     ActorLink** le = b.base+entries;
03504     if (la == le)
03505       return true;
03506     d.me = me;
03507     // An advisor that is run, might be removed during execution.
03508     // As removal is done from the back the advisors have to be executed
03509     // in inverse order.
03510     do {
03511       Advisor* a = Advisor::cast(*la);
03512       assert(!a->disposed());
03513       Propagator& p = a->propagator();
03514       switch (p.advise(home,*a,d)) {
03515       case ES_FIX:
03516         break;
03517       case ES_FAILED:
03518         if (home.afc_enabled())
03519           home.gafc.fail(p.gafc);
03520         return false;
03521       case ES_NOFIX:
03522         schedule(home,p,me);
03523         break;
03524       case ES_NOFIX_FORCE:
03525         schedule(home,p,me,true);
03526         break;
03527       default:
03528         GECODE_NEVER;
03529       }
03530     } while (++la < le);
03531     return true;
03532   }
03533 
03534   template<class VIC>
03535   forceinline void
03536   VarImp<VIC>::update(VarImp<VIC>* x, ActorLink**& sub) {
03537     // this refers to the variable to be updated (clone)
03538     // x refers to the original
03539     // Recover from copy
03540     x->b.base = b.base;
03541     x->u.idx[0] = u.idx[0];
03542     if (pc_max > 0 && sizeof(ActorLink**) > sizeof(unsigned int))
03543       x->u.idx[1] = u.idx[1];
03544 
03545     ActorLink** f = x->b.base;
03546     unsigned int n = x->degree();
03547     ActorLink** t = sub;
03548     sub += n;
03549     b.base = t;
03550     // Set subscriptions using actor forwarding pointers
03551     while (n >= 4) {
03552       n -= 4;
03553       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03554       t[2]=f[2]->prev(); t[3]=f[3]->prev();
03555       t += 4; f += 4;
03556     }
03557     if (n >= 2) {
03558       n -= 2;
03559       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03560       t += 2; f += 2;
03561     }
03562     if (n > 0) {
03563       t[0]=f[0]->prev();
03564     }
03565   }
03566 
03567   template<class VIC>
03568   forceinline void
03569   VarImp<VIC>::update(Space& home, ActorLink**& sub) {
03570     VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home.pc.c.vars_u[idx_c]);
03571     while (x != NULL) {
03572       VarImp<VIC>* n = x->next(); x->forward()->update(x,sub); x = n;
03573     }
03574   }
03575 
03576 
03577 
03578   /*
03579    * Variable disposer
03580    *
03581    */
03582   template<class VarImp>
03583   VarImpDisposer<VarImp>::VarImpDisposer(void) {
03584 #ifdef GECODE_HAS_VAR_DISPOSE
03585     Space::vd[VarImp::idx_d] = this;
03586 #endif
03587   }
03588 
03589   template<class VarImp>
03590   void
03591   VarImpDisposer<VarImp>::dispose(Space& home, VarImpBase* _x) {
03592     VarImp* x = static_cast<VarImp*>(_x);
03593     do {
03594       x->dispose(home); x = static_cast<VarImp*>(x->next_d());
03595     } while (x != NULL);
03596   }
03597 
03598   /*
03599    * Statistics
03600    */
03601 
03602   forceinline void
03603   StatusStatistics::reset(void) {
03604     propagate = 0;
03605     wmp = false;
03606   }
03607   forceinline
03608   StatusStatistics::StatusStatistics(void) {
03609     reset();
03610   }
03611   forceinline StatusStatistics&
03612   StatusStatistics::operator +=(const StatusStatistics& s) { 
03613     propagate += s.propagate;
03614     wmp |= s.wmp;
03615     return *this;
03616   }
03617   forceinline StatusStatistics
03618   StatusStatistics::operator +(const StatusStatistics& s) {
03619     StatusStatistics t(s);
03620     return t += *this;
03621   }
03622 
03623   forceinline void
03624   CloneStatistics::reset(void) {}
03625 
03626   forceinline
03627   CloneStatistics::CloneStatistics(void) {
03628     reset();
03629   }
03630   forceinline CloneStatistics
03631   CloneStatistics::operator +(const CloneStatistics&) {
03632     CloneStatistics s;
03633     return s;
03634   }
03635   forceinline CloneStatistics&
03636   CloneStatistics::operator +=(const CloneStatistics&) { 
03637     return *this;
03638   }
03639 
03640   forceinline void
03641   CommitStatistics::reset(void) {}
03642 
03643   forceinline
03644   CommitStatistics::CommitStatistics(void) {
03645     reset();
03646   }
03647   forceinline CommitStatistics
03648   CommitStatistics::operator +(const CommitStatistics&) {
03649     CommitStatistics s;
03650     return s;
03651   }
03652   forceinline CommitStatistics&
03653   CommitStatistics::operator +=(const CommitStatistics&) { 
03654     return *this;
03655   }
03656 
03657   /*
03658    * Cost computation
03659    *
03660    */
03661 
03662   forceinline
03663   PropCost::PropCost(PropCost::ActualCost ac0) : ac(ac0) {}
03664 
03665   forceinline PropCost
03666   PropCost::cost(PropCost::Mod m,
03667                  PropCost::ActualCost lo, PropCost::ActualCost hi,
03668                  unsigned int n) {
03669     if (n < 2)
03670       return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
03671     else if (n == 2)
03672       return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
03673     else if (n == 3)
03674       return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
03675     else
03676       return (m == LO) ? lo : hi;
03677   }
03678 
03679   forceinline PropCost
03680   PropCost::crazy(PropCost::Mod m, unsigned int n) {
03681     return cost(m,AC_CRAZY_LO,AC_CRAZY_HI,n);
03682   }
03683   forceinline PropCost
03684   PropCost::crazy(PropCost::Mod m, int n) {
03685     assert(n >= 0);
03686     return crazy(m,static_cast<unsigned int>(n));
03687   }
03688   forceinline PropCost
03689   PropCost::cubic(PropCost::Mod m, unsigned int n) {
03690     return cost(m,AC_CUBIC_LO,AC_CUBIC_HI,n);
03691   }
03692   forceinline PropCost
03693   PropCost::cubic(PropCost::Mod m, int n) {
03694     assert(n >= 0);
03695     return cubic(m,static_cast<unsigned int>(n));
03696   }
03697   forceinline PropCost
03698   PropCost::quadratic(PropCost::Mod m, unsigned int n) {
03699     return cost(m,AC_QUADRATIC_LO,AC_QUADRATIC_HI,n);
03700   }
03701   forceinline PropCost
03702   PropCost::quadratic(PropCost::Mod m, int n) {
03703     assert(n >= 0);
03704     return quadratic(m,static_cast<unsigned int>(n));
03705   }
03706   forceinline PropCost
03707   PropCost::linear(PropCost::Mod m, unsigned int n) {
03708     return cost(m,AC_LINEAR_LO,AC_LINEAR_HI,n);
03709   }
03710   forceinline PropCost
03711   PropCost::linear(PropCost::Mod m, int n) {
03712     assert(n >= 0);
03713     return linear(m,static_cast<unsigned int>(n));
03714   }
03715   forceinline PropCost
03716   PropCost::ternary(PropCost::Mod m) {
03717     return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
03718   }
03719   forceinline PropCost
03720   PropCost::binary(PropCost::Mod m) {
03721     return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
03722   }
03723   forceinline PropCost
03724   PropCost::unary(PropCost::Mod m) {
03725     return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
03726   }
03727 
03728   /*
03729    * Iterators for propagators and branchers of a space
03730    *
03731    */
03732   forceinline
03733   Space::Propagators::Propagators(const Space& home0) 
03734     : home(home0), q(home.pc.p.active) {
03735     while (q >= &home.pc.p.queue[0]) {
03736       if (q->next() != q) {
03737         c = q->next(); e = q; q--;
03738         return;
03739       }
03740       q--;
03741     }
03742     q = NULL;
03743     if (!home.pl.empty()) {
03744       c = Propagator::cast(home.pl.next());
03745       e = Propagator::cast(&home.pl);
03746     } else {
03747       c = e = NULL;
03748     }
03749   }
03750   forceinline bool 
03751   Space::Propagators::operator ()(void) const {
03752     return c != NULL;
03753   }
03754   forceinline void 
03755   Space::Propagators::operator ++(void) {
03756     c = c->next();
03757     if (c == e) {
03758       if (q == NULL) {
03759         c = NULL;
03760       } else {
03761         while (q >= &home.pc.p.queue[0]) {
03762           if (q->next() != q) {
03763             c = q->next(); e = q; q--;
03764             return;
03765           }
03766           q--;
03767         }
03768         q = NULL;
03769         if (!home.pl.empty()) {
03770           c = Propagator::cast(home.pl.next());
03771           e = Propagator::cast(&home.pl);
03772         } else {
03773           c = NULL;
03774         }
03775       }
03776     }
03777   }
03778   forceinline const Propagator& 
03779   Space::Propagators::propagator(void) const {
03780     return *Propagator::cast(c);
03781   }
03782 
03783   forceinline
03784   Space::Branchers::Branchers(const Space& home) 
03785     : c(Brancher::cast(home.bl.next())), e(&home.bl) {}
03786   forceinline bool 
03787   Space::Branchers::operator ()(void) const {
03788     return c != e;
03789   }
03790   forceinline void 
03791   Space::Branchers::operator ++(void) {
03792     c = c->next();
03793   }
03794   forceinline const Brancher& 
03795   Space::Branchers::brancher(void) const {
03796     return *Brancher::cast(c);
03797   }
03798 
03799   /*
03800    * Space construction support
03801    *
03802    */
03803   template<class T> 
03804   forceinline T& 
03805   Space::construct(void) {
03806     return alloc<T>(1);
03807   }
03808   template<class T, typename A1> 
03809   forceinline T& 
03810   Space::construct(A1 const& a1) {
03811     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03812     new (&t) T(a1);
03813     return t;
03814   }
03815   template<class T, typename A1, typename A2> 
03816   forceinline T& 
03817   Space::construct(A1 const& a1, A2 const& a2) {
03818     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03819     new (&t) T(a1,a2);
03820     return t;
03821   }
03822   template<class T, typename A1, typename A2, typename A3>
03823   forceinline T& 
03824   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
03825     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03826     new (&t) T(a1,a2,a3);
03827     return t;
03828   }
03829   template<class T, typename A1, typename A2, typename A3, typename A4>
03830   forceinline T& 
03831   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
03832     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03833     new (&t) T(a1,a2,a3,a4);
03834     return t;
03835   }
03836   template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
03837   forceinline T& 
03838   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
03839     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03840     new (&t) T(a1,a2,a3,a4,a5);
03841     return t;
03842   }
03843 
03844 }
03845 
03846 // STATISTICS: kernel-core