Generated on Mon Aug 25 11:35:39 2008 for Gecode by doxygen 1.5.6

core.icc

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  *  Copyright:
00009  *     Christian Schulte, 2002
00010  *     Guido Tack, 2003
00011  *     Mikael Lagerkvist, 2006
00012  *
00013  *  Bugfixes provided by:
00014  *     Alexander Samoilov <alexander_samoilov@yahoo.com>
00015  *
00016  *  Last modified:
00017  *     $Date: 2008-07-11 10:27:28 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00018  *     $Revision: 7332 $
00019  *
00020  *  This file is part of Gecode, the generic constraint
00021  *  development environment:
00022  *     http://www.gecode.org
00023  *
00024  *  Permission is hereby granted, free of charge, to any person obtaining
00025  *  a copy of this software and associated documentation files (the
00026  *  "Software"), to deal in the Software without restriction, including
00027  *  without limitation the rights to use, copy, modify, merge, publish,
00028  *  distribute, sublicense, and/or sell copies of the Software, and to
00029  *  permit persons to whom the Software is furnished to do so, subject to
00030  *  the following conditions:
00031  *
00032  *  The above copyright notice and this permission notice shall be
00033  *  included in all copies or substantial portions of the Software.
00034  *
00035  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00036  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00037  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00038  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00039  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00040  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00041  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00042  *
00043  */
00044 
00045 namespace Gecode {
00046 
00047   class Space;
00048 
00071   class SharedHandle {
00072   public:
00080     class Object {
00081       friend class Space;
00082       friend class SharedHandle;
00083     private:
00085       unsigned int use_cnt;
00087       Object* next;
00089       Object* fwd;
00090     public:
00092       Object(void);
00094       virtual Object* copy(void) const = 0;
00096       virtual ~Object(void);
00098       static void* operator new(size_t s);
00100       static void  operator delete(void* p);
00101     };
00102   private:
00104     Object* o;
00106     void subscribe(void);
00108     void cancel(void);
00109   public:
00111     SharedHandle(void);
00113     SharedHandle(Object* so);
00115     SharedHandle(const SharedHandle& sh);
00117     SharedHandle& operator=(const SharedHandle& sh);
00119     void update(Space* home, bool share, SharedHandle& sh);
00121     ~SharedHandle(void);
00122   protected:
00124     Object* object(void) const;
00126     void object(Object* n);
00127   };
00128 
00129 
00138 
00139   typedef int ModEvent;
00140 
00142   const ModEvent ME_GEN_FAILED   = -1;
00144   const ModEvent ME_GEN_NONE     =  0;
00146   const ModEvent ME_GEN_ASSIGNED =  1;
00147 
00149   typedef int PropCond;
00151   const PropCond PC_GEN_NONE     = -1;
00153   const PropCond PC_GEN_ASSIGNED = 0;
00155 
00166   typedef int ModEventDelta;
00167 
00168 }
00169 
00170 #include "gecode/kernel/var-type.icc"
00171 
00172 namespace Gecode {
00173 
00175   class NoIdxVarImpConf {
00176   public:
00178     static const int idx_c = -1;
00180     static const int idx_d = -1;
00182     static const PropCond pc_max = PC_GEN_ASSIGNED;
00184     static const int free_bits = 0;
00186     static const int med_fst = 0;
00188     static const int med_lst = 0;
00190     static const int med_mask = 0;
00192     static Gecode::ModEvent me_combine(ModEvent me1, ModEvent me2);
00194     static bool med_update(ModEventDelta& med, ModEvent me);
00196     static GECODE_KERNEL_EXPORT const Support::Symbol vti;
00197   };
00198 
00199   forceinline ModEvent
00200   NoIdxVarImpConf::me_combine(ModEvent, ModEvent) {
00201     GECODE_NEVER; return 0;
00202   }
00203   forceinline bool
00204   NoIdxVarImpConf::med_update(ModEventDelta&, ModEvent) {
00205     GECODE_NEVER; return false;
00206   }
00207 
00208 
00209   /*
00210    * These are the classes of interest
00211    *
00212    */
00213   class ActorLink;
00214   class Actor;
00215   class Propagator;
00216   class Advisor;
00217   template <class A> class Council;
00218   template <class A> class Advisors;
00219   template <class VIC> class VarImp;
00220 
00221 
00222   /*
00223    * Variable implementations
00224    *
00225    */
00226 
00234   class VarImpBase {};
00235 
00242   class GECODE_VTABLE_EXPORT VarDisposerBase {
00243   public:
00245     GECODE_KERNEL_EXPORT virtual void dispose(Space* home, VarImpBase* x);
00247     GECODE_KERNEL_EXPORT virtual ~VarDisposerBase(void);
00248   };
00249 
00256   template <class VarType>
00257   class VarDisposer : public VarDisposerBase {
00258   public:
00260     VarDisposer(void);
00262     virtual void dispose(Space* home, VarImpBase* x);
00263   };
00264 
00266   class Delta {
00267     template <class VIC> friend class VarImp;
00268   private:
00270     ModEvent me; 
00271   public:
00273     ModEvent modevent(void) const;
00274   };
00275 
00283   template <class VIC>
00284   class VarImp : public VarImpBase {
00285     friend class Space;
00286     friend class Propagator;
00287     template <class VarType> friend class VarDisposer;
00288   private:
00290     static const int idx_c = VIC::idx_c;
00292     static const int idx_d = VIC::idx_d;
00294     static const int free_bits = VIC::free_bits;
00296     unsigned int free_and_bits;
00298     static const Gecode::PropCond pc_max = VIC::pc_max;
00314     ActorLink** idx[pc_max+3];
00315 
00322     void update(VarImp* x, ActorLink**& sub);
00329     static void update(Space* home, ActorLink**& sub);
00330 
00332     void enter(Space* home, ActorLink* a, PropCond pc);
00334     void resize(Space* home);
00336     void remove(Space* home, ActorLink* a, PropCond pc);
00337 
00338   protected:
00339 #ifdef GECODE_HAS_VAR_DISPOSE
00341     static VarImp<VIC>* vars_d(Space* home);
00343     static void vars_d(Space* home, VarImp<VIC>* x);
00344 #endif
00345 
00346   public:
00348     VarImp(Space* home);
00350     VarImp(void);
00351 
00353 
00354 
00366     void subscribe(Space* home, Propagator* p, PropCond pc,
00367                    bool assigned, ModEvent me, bool schedule);
00373     void cancel(Space* home, Propagator* p, PropCond pc,
00374                 bool assigned);
00380     void subscribe(Space* home, Advisor* a, bool assigned);
00386     void cancel(Space* home, Advisor* p, bool assigned);
00388     void cancel(Space* home);
00395     unsigned int degree(void) const;
00401     bool advise(Space* home, ModEvent me, Delta* d);
00403 
00405 
00406 
00407     VarImp(Space* home, bool share, VarImp& x);
00409     bool copied(void) const;
00411     VarImp* forward(void) const;
00413     VarImp* next(void) const;
00415 
00417 
00418 
00419     static void schedule(Space* home, Propagator* p, ModEvent me);
00421     static ModEvent me(ModEventDelta med);
00423     static ModEventDelta med(ModEvent me);
00425     static ModEvent me_combine(ModEvent me1, ModEvent me2);
00427 
00429     unsigned int bits(void) const;
00431     unsigned int& bits(void);
00432 
00433   protected:
00435     void schedule(Space* home, PropCond pc1, PropCond pc2, ModEvent me);
00436 
00437   public:
00439 
00440 
00441     static void* operator new(size_t,Space*);
00443     static void  operator delete(void*,Space*);
00445     static void  operator delete(void*);
00447     
00449 
00450 
00451     static const Support::Symbol vti;
00453     
00454   };
00455 
00456   template <class VIC>
00457   const Support::Symbol
00458   VarImp<VIC>::vti = VIC::vti;
00459 
00460 
00461   namespace Reflection {
00462     class ActorSpecIter;
00463     class ActorSpec;
00464     class BranchingSpec;
00465     class VarMap;
00466   }
00467 
00476   enum ExecStatus {
00477     __ES_SUBSUMED       = -2, 
00478     ES_FAILED           = -1, 
00479     ES_NOFIX            =  0, 
00480     ES_OK               =  0, 
00481     ES_FIX              =  1, 
00482     __ES_PARTIAL        =  2  
00483   };
00484 
00489   enum PropCost {
00490     PC_CRAZY_LO     = 0, 
00491     PC_CRAZY_HI     = 0, 
00492     PC_CUBIC_LO     = 1, 
00493     PC_CUBIC_HI     = 1, 
00494     PC_QUADRATIC_LO = 2, 
00495     PC_QUADRATIC_HI = 2, 
00496     PC_LINEAR_HI    = 3, 
00497     PC_LINEAR_LO    = 4, 
00498     PC_TERNARY_HI   = 5, 
00499     PC_BINARY_HI    = 6, 
00500     PC_TERNARY_LO   = 6, 
00501     PC_BINARY_LO    = 7, 
00502     PC_UNARY_LO     = 7, 
00503     PC_UNARY_HI     = 7, 
00504     PC_MAX          = 7  
00505   };
00506 
00514   class ActorLink {
00515     friend class Actor;
00516     friend class Propagator;
00517     friend class Advisor;
00518     friend class Branching;
00519     friend class Space;
00520     template <class VIC> friend class VarImp;
00521   private:
00522     ActorLink* _next; ActorLink* _prev;
00523   public:
00525 
00526     ActorLink* prev(void) const; void prev(ActorLink*);
00527     ActorLink* next(void) const; void next(ActorLink*);
00528     ActorLink** next_ref(void);
00530 
00532     void init(void);
00534     void unlink(void);
00536     void head(ActorLink* al);
00538     void tail(ActorLink* al);
00540     template <class T> static ActorLink* cast(T* a);
00542     template <class T> static const ActorLink* cast(const T* a);
00543   };
00544 
00545 
00550   class GECODE_VTABLE_EXPORT Actor : private ActorLink {
00551     friend class ActorLink;
00552     friend class Space;
00553     friend class Propagator;
00554     friend class Advisor;
00555     friend class Branching;
00556     friend class Reflection::ActorSpecIter;
00557     template <class VIC> friend class VarImp;
00558     template <class A> friend class Council;
00559   private:
00561     static Actor* cast(ActorLink* al);
00563     static const Actor* cast(const ActorLink* al);
00564   public:
00566     virtual Actor* copy(Space*,bool) = 0;
00567 
00569 
00570 
00571     GECODE_KERNEL_EXPORT 
00572     virtual size_t allocated(void) const;
00574     GECODE_KERNEL_EXPORT
00575     virtual size_t dispose(Space* home);
00577     void force(Space* home);
00579     void unforce(Space* home);
00581     static void* operator new(size_t s, Space* home);
00583     static void  operator delete(void* p, Space* home);
00585     GECODE_KERNEL_EXPORT
00586     virtual Reflection::ActorSpec spec(const Space* home,
00587                                        Reflection::VarMap& m) const;
00588   private:
00589 #ifndef __GNUC__
00591     static void  operator delete(void* p);
00592 #endif
00594     static void* operator new(size_t s);
00595 
00596 #ifdef __GNUC__
00597   public:
00599     GECODE_KERNEL_EXPORT virtual ~Actor(void);
00601     static void  operator delete(void* p);
00602 #endif
00603   };
00604 
00605 
00625   ExecStatus ES_SUBSUMED(Propagator* p, size_t s);
00636   ExecStatus ES_SUBSUMED(Propagator* p, Space* home);
00647   ExecStatus ES_FIX_PARTIAL(Propagator* p, ModEventDelta med);
00658   ExecStatus ES_NOFIX_PARTIAL(Propagator* p, ModEventDelta med);
00659 
00664   class GECODE_VTABLE_EXPORT Propagator : public Actor {
00665     friend class ActorLink;
00666     friend class Space;
00667     template <class VIC> friend class VarImp;
00668     friend ExecStatus ES_SUBSUMED(Propagator*, size_t);
00669     friend ExecStatus ES_SUBSUMED(Propagator*, Space*);
00670     friend ExecStatus ES_FIX_PARTIAL(Propagator*, ModEventDelta);
00671     friend ExecStatus ES_NOFIX_PARTIAL(Propagator*, ModEventDelta);
00672     friend class Advisor;
00673     template <class A> friend class Council;
00674   private:
00675     union {
00677       ModEventDelta med;
00679       size_t size;
00681       Gecode::ActorLink* advisors;
00682     } u;
00684     static Propagator* cast(ActorLink* al);
00686     static const Propagator* cast(const ActorLink* al);
00687   protected:
00689     Propagator(Space* home);
00691     Propagator(Space* home, bool share, Propagator& p);
00692 
00693   public:
00695 
00696 
00719     virtual ExecStatus propagate(Space* home, ModEventDelta med) = 0;
00721     virtual PropCost cost(ModEventDelta med) const  = 0;
00751     GECODE_KERNEL_EXPORT
00752     virtual ExecStatus advise(Space* home, Advisor* a, const Delta* d);
00754   };
00755 
00756 
00764   template <class A>
00765   class Council {
00766     friend class Advisor;
00767     friend class Advisors<A>;
00768   private:
00770     mutable ActorLink* advisors;
00771   public:
00773     Council(void);
00775     Council(Space* home);
00777     bool empty(void) const;
00779     void update(Space* home, bool share, Council<A>& c);
00781     void dispose(Space* home);
00782   };
00783 
00784 
00789   template <class A>
00790   class Advisors {
00791   private:
00793     ActorLink* a;
00794   public:
00796     Advisors(const Council<A>& c);
00798     bool operator()(void) const;
00800     void operator++(void);
00802     A* advisor(void) const;
00803   };
00804 
00805 
00817   template <class A>
00818   ExecStatus ES_SUBSUMED_FIX(A* a, Space* home, Council<A>& c);
00830   template <class A>
00831   ExecStatus ES_SUBSUMED_NOFIX(A* a, Space* home, Council<A>& c);
00832 
00843   class Advisor : private ActorLink {
00844     template <class VIC> friend class VarImp;
00845     template <class A> friend class Council;
00846     template <class A> friend class Advisors;
00847   private:
00849     bool disposed(void) const;
00851     static Advisor* cast(ActorLink* al);
00853     static const Advisor* cast(const ActorLink* al);
00854   protected:
00856     Propagator* propagator(void) const; 
00857   public:
00859     template <class A>
00860     Advisor(Space* home, Propagator* p, Council<A>& c);
00862     Advisor(Space* home, bool share, Advisor& a);
00863 
00865 
00866 
00867     template <class A>
00868     void dispose(Space* home, Council<A>& c);
00870     static void* operator new(size_t s, Space* home);
00872     static void  operator delete(void* p, Space* home);
00874   private:
00875 #ifndef __GNUC__
00877     static void  operator delete(void* p);
00878 #endif
00880     static void* operator new(size_t s);
00881   };
00882 
00883 
00884   class Branching;
00885 
00895   class BranchingDesc {
00896     friend class Space;
00897     friend class Reflection::BranchingSpec;
00898   private:
00899     unsigned int _id;  
00900     unsigned int _alt; 
00901 
00903     unsigned int id(void) const;
00904   protected:
00906     BranchingDesc(const Branching* b, const unsigned int a);
00907   public:
00909     unsigned int alternatives(void) const;
00911     GECODE_KERNEL_EXPORT virtual ~BranchingDesc(void);
00913     virtual size_t size(void) const = 0;
00915     static void* operator new(size_t);
00917     static void  operator delete(void*);
00918   };
00919 
00929   class GECODE_VTABLE_EXPORT Branching : public Actor {
00930     friend class ActorLink;
00931     friend class Space;
00932     friend class BranchingDesc;
00933     friend class Reflection::ActorSpecIter;
00934   private:
00936     unsigned int id; 
00938     static Branching* cast(ActorLink* al);
00940     static const Branching* cast(const ActorLink* al);
00941   protected:
00943     Branching(Space* home);
00945     Branching(Space* home, bool share, Branching& b);
00946 
00947   public:
00949 
00950 
00958     virtual bool status(const Space* home) const = 0;
00968     virtual const BranchingDesc* description(const Space* home) const = 0;
00976     virtual ExecStatus commit(Space* home, const BranchingDesc* d,
00977                               unsigned int a) = 0;
00979     
00981 
00982 
00983     virtual GECODE_KERNEL_EXPORT Reflection::BranchingSpec
00984     branchingSpec(const Space* home,
00985                   Reflection::VarMap& m, const BranchingDesc* d) const;
00987   };
00988 
00989 
00990 
00995   enum SpaceStatus {
00996     SS_FAILED, 
00997     SS_SOLVED, 
00998     SS_BRANCH  
00999   };
01000 
01004   class GECODE_VTABLE_EXPORT Space {
01005     friend class Actor;
01006     friend class Propagator;
01007     friend class Branching;
01008     friend class Advisor;
01009     friend class Reflection::ActorSpecIter;
01010     template <class VIC> friend class VarImp;
01011     template <class VarType> friend class VarDisposer;
01012     friend class SharedHandle;
01013   private:
01015     MemoryManager mm; 
01022     ActorLink a_actors;
01028     Branching* b_status;
01040     Branching* b_commit;
01041     union {
01043       struct {
01056         ActorLink* active;
01058         ActorLink queue[PC_MAX+1];
01060         unsigned int branch_id;
01062         unsigned int n_sub;
01063       } p;
01065       struct {
01067         VarImpBase* vars_u[AllVarConf::idx_c];
01069         VarImpBase* vars_noidx;
01071         SharedHandle::Object* shared;
01072       } c;
01073     } pc;
01075     void enqueue(Propagator* p);
01080 #ifdef GECODE_HAS_VAR_DISPOSE
01082     GECODE_KERNEL_EXPORT static VarDisposerBase* vd[AllVarConf::idx_d];
01084     VarImpBase* _vars_d[AllVarConf::idx_d];
01086     template <class VIC> VarImpBase* vars_d(void) const;
01088     template <class VIC> void vars_d(VarImpBase* x);
01089 #endif
01091     void update(ActorLink** sub);
01092 
01093 
01095     Actor** d_fst;
01097     Actor** d_cur;
01099     Actor** d_lst;
01101     GECODE_KERNEL_EXPORT void d_resize(void);
01102 
01104     GECODE_KERNEL_EXPORT static unsigned long int unused_uli;
01105   public:
01110     GECODE_KERNEL_EXPORT Space(void);
01115     GECODE_KERNEL_EXPORT virtual ~Space(void);
01126     GECODE_KERNEL_EXPORT Space(bool share, Space& s);
01133     virtual Space* copy(bool share) = 0;
01138     static void* operator new(size_t);
01143     static void  operator delete(void*);
01144 
01145 
01146     /*
01147      * Member functions for search engines
01148      *
01149      */
01150 
01162     GECODE_KERNEL_EXPORT SpaceStatus status(unsigned long int& pn=unused_uli);
01163 
01179     const BranchingDesc* description(void) const;
01180 
01197     GECODE_KERNEL_EXPORT Space* clone(bool share=true);
01198 
01228     GECODE_KERNEL_EXPORT void commit(const BranchingDesc* d, unsigned int a);
01229 
01237     void fail(void);
01246     bool failed(void) const;
01251     bool stable(void) const;
01258     GECODE_KERNEL_EXPORT unsigned int propagators(void) const;
01265     GECODE_KERNEL_EXPORT unsigned int branchings(void) const;
01266 
01271 
01272     GECODE_KERNEL_EXPORT
01273     virtual void getVars(Reflection::VarMap& m, bool registerOnly);
01275     GECODE_KERNEL_EXPORT
01276     Reflection::BranchingSpec branchingSpec(Reflection::VarMap& m,
01277                                             const BranchingDesc* d) const;
01279 
01285 
01286     void* alloc(size_t);
01288     void  reuse(void*,size_t);
01290     template <size_t> void* fl_alloc(void);
01296     template <size_t> void  fl_dispose(FreeList* f, FreeList* l);
01303     GECODE_KERNEL_EXPORT 
01304     size_t allocated(void) const;
01306   };
01307 
01308 
01309 
01310 
01311   /*
01312    * Memory management
01313    *
01314    */
01315 
01316   // Heap allocated
01317   forceinline void* 
01318   SharedHandle::Object::operator new(size_t s) {
01319     return Memory::malloc(s);
01320   }
01321   forceinline void
01322   SharedHandle::Object::operator delete(void* p) {
01323     Memory::free(p);
01324   }
01325 
01326   forceinline void*
01327   Space::operator new(size_t s) {
01328     return Memory::malloc(s);
01329   }
01330   forceinline void
01331   Space::operator delete(void* p) {
01332     Memory::free(p);
01333   }
01334 
01335   forceinline void
01336   BranchingDesc::operator delete(void* p) {
01337     Memory::free(p);
01338   }
01339   forceinline void*
01340   BranchingDesc::operator new(size_t s) {
01341     return Memory::malloc(s);
01342   }
01343 
01344   // Space allocation: general space heaps and free lists
01345   forceinline void*
01346   Space::alloc(size_t s) {
01347     return mm.alloc(s);
01348   }
01349   forceinline void
01350   Space::reuse(void* p, size_t s) {
01351     return mm.reuse(p,s);
01352   }
01353   template <size_t s>
01354   forceinline void*
01355   Space::fl_alloc(void) {
01356     return mm.template fl_alloc<s>();
01357   }
01358   template <size_t s>
01359   forceinline void
01360   Space::fl_dispose(FreeList* f, FreeList* l) {
01361     mm.template fl_dispose<s>(f,l);
01362   }
01363 
01364 #ifdef GECODE_HAS_VAR_DISPOSE
01365   template <class VIC>
01366   forceinline VarImpBase*
01367   Space::vars_d(void) const {
01368     return _vars_d[VIC::idx_d];
01369   }
01370   template <class VIC>
01371   forceinline void
01372   Space::vars_d(VarImpBase* x) {
01373     _vars_d[VIC::idx_d] = x;
01374   }
01375 #endif
01376 
01377   // Space allocated entities: Actors, variable implementations, and advisors
01378   forceinline void
01379   Actor::operator delete(void*) {}
01380   forceinline void
01381   Actor::operator delete(void*, Space*) {}
01382   forceinline void*
01383   Actor::operator new(size_t s, Space* home) {
01384     return home->alloc(s);
01385   }
01386 
01387   template <class VIC>
01388   forceinline void
01389   VarImp<VIC>::operator delete(void*) {}
01390   template <class VIC>
01391   forceinline void
01392   VarImp<VIC>::operator delete(void*, Space*) {}
01393   template <class VIC>
01394   forceinline void*
01395   VarImp<VIC>::operator new(size_t s, Space* home) {
01396     return home->alloc(s);
01397   }
01398 
01399 #ifndef __GNUC__
01400   forceinline void
01401   Advisor::operator delete(void*) {}
01402 #endif
01403   forceinline void
01404   Advisor::operator delete(void*, Space*) {}
01405   forceinline void*
01406   Advisor::operator new(size_t s, Space* home) {
01407     return home->alloc(s);
01408   }
01409 
01410 
01411   /*
01412    * Shared objects and handles
01413    *
01414    */
01415   forceinline
01416   SharedHandle::Object::Object(void) 
01417     : use_cnt(0), fwd(NULL) {}
01418   forceinline
01419   SharedHandle::Object::~Object(void) {
01420     assert(use_cnt == 0);
01421   }
01422 
01423   forceinline void 
01424   SharedHandle::subscribe(void) {
01425     if (o != NULL) o->use_cnt++;
01426   }
01427   forceinline void 
01428   SharedHandle::cancel(void) {
01429     if ((o != NULL) && (--o->use_cnt == 0))
01430       delete o;
01431     o = NULL;
01432   }
01433   forceinline 
01434   SharedHandle::SharedHandle(void) : o(NULL) {}
01435   forceinline 
01436   SharedHandle::SharedHandle(SharedHandle::Object* so) : o(so) {
01437     subscribe();
01438   }
01439   forceinline 
01440   SharedHandle::SharedHandle(const SharedHandle& sh) : o(sh.o) {
01441     subscribe();
01442   }
01443   forceinline SharedHandle& 
01444   SharedHandle::operator=(const SharedHandle& sh) {
01445     if (&sh != this) {
01446       cancel(); o = sh.o; subscribe();
01447     }
01448     return *this;
01449   }
01450   forceinline void 
01451   SharedHandle::update(Space* home, bool share, SharedHandle& sh) {
01452     if (sh.o == NULL) {
01453       o = NULL;
01454     } else if (share) {
01455       o = sh.o; subscribe();
01456     } else if (sh.o->fwd != NULL) {
01457       o = sh.o->fwd; subscribe();
01458     } else {
01459       o = sh.o->copy(); 
01460       sh.o->fwd = o;
01461       sh.o->next = home->pc.c.shared; 
01462       home->pc.c.shared = sh.o;
01463       subscribe();
01464     }
01465   }
01466   forceinline 
01467   SharedHandle::~SharedHandle(void) {
01468     cancel();
01469   }
01470   forceinline SharedHandle::Object* 
01471   SharedHandle::object(void) const {
01472     return o;
01473   }
01474   forceinline void 
01475   SharedHandle::object(SharedHandle::Object* n) {
01476     if (n != o) {
01477       cancel(); o=n; subscribe();
01478     }
01479   }
01480 
01481 
01482 
01483   /*
01484    * ActorLink
01485    *
01486    */
01487   forceinline ActorLink*
01488   ActorLink::prev(void) const {
01489     return _prev; 
01490   }
01491 
01492   forceinline ActorLink*
01493   ActorLink::next(void) const { 
01494     return _next; 
01495   }
01496 
01497   forceinline ActorLink**
01498   ActorLink::next_ref(void) { 
01499     return &_next; 
01500   }
01501 
01502   forceinline void
01503   ActorLink::prev(ActorLink* al) { 
01504     _prev = al; 
01505   }
01506 
01507   forceinline void
01508   ActorLink::next(ActorLink* al) { 
01509     _next = al; 
01510   }
01511 
01512   forceinline void
01513   ActorLink::unlink(void) {
01514     ActorLink* p = _prev; ActorLink* n = _next;
01515     p->_next = n; n->_prev = p;
01516   }
01517 
01518   forceinline void
01519   ActorLink::init(void) {
01520     _next = this; _prev =this;
01521   }
01522 
01523   forceinline void
01524   ActorLink::head(ActorLink* a) {
01525     // Inserts al at head of link-chain (that is, after this)
01526     ActorLink* n = _next;
01527     this->_next = a; a->_prev = this;
01528     a->_next = n; n->_prev = a;
01529   }
01530 
01531   forceinline void
01532   ActorLink::tail(ActorLink* a) {
01533     // Inserts al at tail of link-chain (that is, before this)
01534     ActorLink* p = _prev;
01535     a->_next = this; this->_prev = a;
01536     p->_next = a; a->_prev = p;
01537   }
01538 
01539   template <class T>
01540   forceinline ActorLink* 
01541   ActorLink::cast(T* a) {
01542     // Turning al into a reference is for gcc, assume is for MSVC
01543     GECODE_NOT_NULL(a);
01544     ActorLink& t = *a;
01545     return static_cast<ActorLink*>(&t);
01546   }
01547 
01548   template <class T>
01549   forceinline const ActorLink* 
01550   ActorLink::cast(const T* a) {
01551     // Turning al into a reference is for gcc, assume is for MSVC
01552     GECODE_NOT_NULL(a);
01553     const ActorLink& t = *a;
01554     return static_cast<const ActorLink*>(&t);
01555   }
01556 
01557 
01558   /*
01559    * Actor
01560    *
01561    */
01562   forceinline Actor* 
01563   Actor::cast(ActorLink* al) {
01564     // Turning al into a reference is for gcc, assume is for MSVC
01565     GECODE_NOT_NULL(al);
01566     ActorLink& t = *al;
01567     return static_cast<Actor*>(&t);
01568   }
01569 
01570   forceinline const Actor* 
01571   Actor::cast(const ActorLink* al) {
01572     // Turning al into a reference is for gcc, assume is for MSVC
01573     GECODE_NOT_NULL(al);
01574     const ActorLink& t = *al;
01575     return static_cast<const Actor*>(&t);
01576   }
01577 
01578   forceinline void
01579   Actor::force(Space* home) {
01580     if (home->d_cur == home->d_lst)
01581       home->d_resize();
01582     *(home->d_cur++) = this;
01583   }
01584 
01585   forceinline void
01586   Actor::unforce(Space* home) {
01587     // Check wether array has already been discarded as space
01588     // deletion is already in progress
01589     Actor** f = home->d_fst;
01590     if (f != NULL) {
01591       while (this != *f)
01592         f++;
01593       *f = *(--home->d_cur);
01594     }
01595   }
01596 
01597   forceinline size_t
01598   Actor::dispose(Space*) {
01599     return sizeof(*this);
01600   }
01601 
01602 
01603   /*
01604    * Propagator
01605    *
01606    */
01607   forceinline Propagator* 
01608   Propagator::cast(ActorLink* al) {
01609     // Turning al into a reference is for gcc, assume is for MSVC
01610     GECODE_NOT_NULL(al);
01611     ActorLink& t = *al;
01612     return static_cast<Propagator*>(&t);
01613   }
01614 
01615   forceinline const Propagator* 
01616   Propagator::cast(const ActorLink* al) {
01617     // Turning al into a reference is for gcc, assume is for MSVC
01618     GECODE_NOT_NULL(al);
01619     const ActorLink& t = *al;
01620     return static_cast<const Propagator*>(&t);
01621   }
01622 
01623   forceinline
01624   Propagator::Propagator(Space* home) {
01625     u.advisors = NULL;
01626     assert(u.med == 0 && u.size == 0);
01627     home->a_actors.head(this);
01628   }
01629 
01630   forceinline
01631   Propagator::Propagator(Space*, bool, Propagator& p) {
01632     u.advisors = NULL;
01633     assert(u.med == 0 && u.size == 0);
01634     // Set forwarding pointer
01635     p.prev(this);
01636   }
01637 
01638   forceinline ExecStatus
01639   ES_SUBSUMED(Propagator* p, size_t s) {
01640     p->u.size = s; 
01641     return __ES_SUBSUMED;
01642   }
01643 
01644   forceinline ExecStatus
01645   ES_SUBSUMED(Propagator* p, Space* home) {
01646     p->u.size = p->dispose(home); 
01647     return __ES_SUBSUMED;
01648   }
01649 
01650   forceinline ExecStatus
01651   ES_FIX_PARTIAL(Propagator* p, ModEventDelta med) {
01652     p->u.med = med; 
01653     assert(p->u.med != 0);
01654     return __ES_PARTIAL;
01655   }
01656 
01657   forceinline ExecStatus
01658   ES_NOFIX_PARTIAL(Propagator* p, ModEventDelta med) {
01659     p->u.med = AllVarConf::med_combine(p->u.med,med); 
01660     assert(p->u.med != 0);
01661     return __ES_PARTIAL;
01662   }
01663 
01664 
01665 
01666   /*
01667    * Branching
01668    *
01669    */
01670   forceinline Branching* 
01671   Branching::cast(ActorLink* al) {
01672     // Turning al into a reference is for gcc, assume is for MSVC
01673     GECODE_NOT_NULL(al);
01674     ActorLink& t = *al;
01675     return static_cast<Branching*>(&t);
01676   }
01677 
01678   forceinline const Branching* 
01679   Branching::cast(const ActorLink* al) {
01680     // Turning al into a reference is for gcc, assume is for MSVC
01681     GECODE_NOT_NULL(al);
01682     const ActorLink& t = *al;
01683     return static_cast<const Branching*>(&t);
01684   }
01685 
01686   forceinline
01687   Branching::Branching(Space* home) {
01688     // Propagators are put at the tail of the link of actors
01689     id = home->pc.p.branch_id++;
01690     // If no branching available, make it the first one
01691     if (home->b_status == &(home->a_actors)) {
01692       home->b_status = this;
01693       if (home->b_commit == &(home->a_actors))
01694         home->b_commit = this;
01695     }
01696     home->a_actors.tail(this);
01697   }
01698 
01699   forceinline
01700   Branching::Branching(Space*, bool, Branching& b)
01701     : id(b.id)  {
01702     // Set forwarding pointer
01703     b.prev(this);
01704   }
01705 
01706 
01707 
01708   /*
01709    * Branching description
01710    *
01711    */
01712   forceinline
01713   BranchingDesc::BranchingDesc(const Branching* b, const unsigned int a)
01714     : _id(b->id), _alt(a) {}
01715 
01716   forceinline unsigned int
01717   BranchingDesc::alternatives(void) const {
01718     return _alt;
01719   }
01720 
01721   forceinline unsigned int
01722   BranchingDesc::id(void) const {
01723     return _id;
01724   }
01725 
01726   forceinline
01727   BranchingDesc::~BranchingDesc(void) {}
01728 
01729 
01730 
01731   /*
01732    * Delta information for advisors
01733    *
01734    */
01735   forceinline ModEvent
01736   Delta::modevent(void) const {
01737     return me;
01738   }
01739 
01740 
01741 
01742   /*
01743    * Advisor
01744    *
01745    */
01746   template <class A>
01747   forceinline 
01748   Advisor::Advisor(Space*, Propagator* p, Council<A>& c) {
01749     assert(p != NULL);
01750     // Store propagator and forwarding in prev()
01751     ActorLink::prev(p);
01752     // Link to next advisor in next()
01753     ActorLink::next(c.advisors); c.advisors = static_cast<A*>(this);
01754   }
01755 
01756   forceinline 
01757   Advisor::Advisor(Space*, bool, Advisor&) {}
01758 
01759   forceinline bool
01760   Advisor::disposed(void) const { 
01761     return prev() == NULL;
01762   }
01763 
01764   forceinline Advisor* 
01765   Advisor::cast(ActorLink* al) {
01766     return static_cast<Advisor*>(al);
01767   }
01768 
01769   forceinline const Advisor* 
01770   Advisor::cast(const ActorLink* al) {
01771     return static_cast<const Advisor*>(al);
01772   }
01773 
01774   forceinline Propagator* 
01775   Advisor::propagator(void) const { 
01776     assert(!disposed());
01777     return Propagator::cast(ActorLink::prev()); 
01778   }
01779 
01780   template <class A>
01781   forceinline void
01782   Advisor::dispose(Space*,Council<A>&) {
01783     assert(!disposed());
01784     ActorLink::prev(NULL); 
01785     // Shorten chains of disposed advisors by one, if possible
01786     Advisor* n = Advisor::cast(next());
01787     if ((n != NULL) && n->disposed())
01788       next(n->next());
01789   }
01790 
01791   template <class A>
01792   forceinline ExecStatus
01793   ES_SUBSUMED_FIX(A* a, Space* home, Council<A>& c) {
01794     a->dispose(home,c);
01795     return ES_FIX;
01796   }
01797 
01798   template <class A>
01799   forceinline ExecStatus
01800   ES_SUBSUMED_NOFIX(A* a, Space* home, Council<A>& c) {
01801     a->dispose(home,c);
01802     return ES_NOFIX;
01803   }
01804 
01805 
01806 
01807   /*
01808    * Advisor council
01809    *
01810    */
01811   template <class A>
01812   forceinline
01813   Council<A>::Council(void) {}
01814 
01815   template <class A>
01816   forceinline
01817   Council<A>::Council(Space*) 
01818     : advisors(NULL) {}
01819 
01820   template <class A>
01821   forceinline bool
01822   Council<A>::empty(void) const {
01823     ActorLink* a = advisors;
01824     while ((a != NULL) && static_cast<A*>(a)->disposed())
01825       a = a->next();
01826     advisors = a;
01827     return a == NULL;
01828   }
01829 
01830   template <class A>
01831   forceinline void
01832   Council<A>::update(Space* home, bool share, Council<A>& c) {
01833     // Skip all disposed advisors
01834     {
01835       ActorLink* a = c.advisors;
01836       while ((a != NULL) && static_cast<A*>(a)->disposed())
01837         a = a->next();
01838       c.advisors = a;
01839     }
01840     // Are there any advisors to be cloned?
01841     if (c.advisors != NULL) {
01842       // The propagator in from-space
01843       Propagator* p_f = static_cast<A*>(c.advisors)->propagator();
01844       // The propagator in to-space
01845       Propagator* p_t = Propagator::cast(p_f->prev());
01846       // Advisors in from-space
01847       ActorLink** a_f = &c.advisors;
01848       // Advisors in to-space
01849       A* a_t = NULL;
01850       while (*a_f != NULL) {
01851         if (static_cast<A*>(*a_f)->disposed()) {
01852           *a_f = (*a_f)->next();
01853         } else {
01854           // Run specific copying part
01855           A* a = new (home) A(home,share,*static_cast<A*>(*a_f));
01856           // Set propagator pointer
01857           a->prev(p_t);
01858           // Set forwarding pointer
01859           (*a_f)->prev(a);
01860           // Link
01861           a->next(a_t);
01862           a_t = a;
01863           a_f = (*a_f)->next_ref();
01864         }
01865       }
01866       advisors = a_t;
01867       // Enter advisor link for reset
01868       assert(p_f->u.advisors == NULL);
01869       p_f->u.advisors = c.advisors;
01870     }
01871   }
01872   
01873   template <class A>
01874   forceinline void
01875   Council<A>::dispose(Space* home) {
01876     ActorLink* a = advisors;
01877     while (a != NULL) {
01878       if (!static_cast<A*>(a)->disposed())
01879         static_cast<A*>(a)->dispose(home,*this); 
01880       a = a->next();
01881     }
01882   }
01883 
01884   
01885 
01886   /*
01887    * Advisor iterator
01888    *
01889    */
01890   template <class A>
01891   forceinline
01892   Advisors<A>::Advisors(const Council<A>& c)
01893     : a(c.advisors) {
01894     while ((a != NULL) && static_cast<A*>(a)->disposed())
01895       a = a->next();
01896   }
01897 
01898   template <class A>
01899   forceinline bool
01900   Advisors<A>::operator()(void) const {
01901     return a != NULL;
01902   }
01903 
01904   template <class A>
01905   forceinline void
01906   Advisors<A>::operator++(void) {
01907     do {
01908       a = a->next();
01909     } while ((a != NULL) && static_cast<A*>(a)->disposed());
01910   }
01911 
01912   template <class A>
01913   forceinline A*
01914   Advisors<A>::advisor(void) const {
01915     return static_cast<A*>(a);
01916   }
01917 
01918 
01919 
01920   /*
01921    * Space
01922    *
01923    */
01924   forceinline void
01925   Space::enqueue(Propagator* p) {
01926     ActorLink::cast(p)->unlink();
01927     ActorLink* c = &pc.p.queue[p->cost(p->u.med)];
01928     c->tail(ActorLink::cast(p));
01929     if (c > pc.p.active)
01930       pc.p.active = c;
01931   }
01932 
01933   forceinline const BranchingDesc*
01934   Space::description(void) const {
01935     return b_status->description(this);
01936   }
01937 
01938   forceinline void
01939   Space::fail(void) {
01940     pc.p.active = NULL;
01941   }
01942 
01943   forceinline bool
01944   Space::failed(void) const {
01945     return pc.p.active == NULL;
01946   }
01947 
01948   forceinline bool
01949   Space::stable(void) const {
01950     return pc.p.active < &pc.p.queue[0];
01951   }
01952 
01953 
01954 
01955   /*
01956    * Variable implementation
01957    *
01958    */
01959   template <class VIC>
01960   forceinline
01961   VarImp<VIC>::VarImp(Space*) {
01962     for (PropCond i=0; i<pc_max+3; i++)
01963       idx[i] = NULL;
01964     free_and_bits = 0;
01965   }
01966 
01967   template <class VIC>
01968   forceinline
01969   VarImp<VIC>::VarImp(void) {
01970     for (PropCond i=0; i<pc_max+3; i++)
01971       idx[i] = NULL;
01972     free_and_bits = 0;
01973   }
01974 
01975   template <class VIC>
01976   forceinline unsigned int
01977   VarImp<VIC>::degree(void) const {
01978     assert(!copied());
01979     return static_cast<unsigned int>(idx[pc_max+2] - idx[0]);
01980   }
01981 
01982   template <class VIC>
01983   forceinline unsigned int
01984   VarImp<VIC>::bits(void) const {
01985     return free_and_bits;
01986   }
01987 
01988   template <class VIC>
01989   forceinline unsigned int&
01990   VarImp<VIC>::bits(void) {
01991     return free_and_bits;
01992   }
01993 
01994 #ifdef GECODE_HAS_VAR_DISPOSE
01995   template <class VIC>
01996   forceinline VarImp<VIC>*
01997   VarImp<VIC>::vars_d(Space* home) {
01998     return static_cast<VarImp<VIC>*>(home->vars_d<VIC>());
01999   }
02000 
02001   template <class VIC>
02002   forceinline void
02003   VarImp<VIC>::vars_d(Space* home, VarImp<VIC>* x) {
02004     home->vars_d<VIC>(x);
02005   }
02006 #endif
02007 
02008   template <class VIC>
02009   forceinline bool
02010   VarImp<VIC>::copied(void) const {
02011     return Support::marked(idx[0]);
02012   }
02013 
02014   template <class VIC>
02015   forceinline VarImp<VIC>*
02016   VarImp<VIC>::forward(void) const {
02017     assert(copied());
02018     return reinterpret_cast<VarImp<VIC>*>(Support::unmark(idx[0]));
02019   }
02020 
02021   template <class VIC>
02022   forceinline VarImp<VIC>*
02023   VarImp<VIC>::next(void) const {
02024     assert(copied());
02025     return reinterpret_cast<VarImp<VIC>*>(idx[1]);
02026   }
02027 
02028   template <class VIC>
02029   forceinline
02030   VarImp<VIC>::VarImp(Space* home, bool, VarImp<VIC>& x) {
02031     VarImpBase** reg;
02032     free_and_bits = x.free_and_bits & ((1 << free_bits) - 1);
02033     if (x.idx[0] == NULL) {
02034       // Variable implementation needs no index structure
02035       for (PropCond i=0; i<pc_max+3; i++)
02036         idx[i] = NULL;
02037       reg = &home->pc.c.vars_noidx;
02038     } else {
02039       // Save original values in copy
02040       idx[0] = x.idx[0];
02041       idx[1] = x.idx[1];
02042       reg = &home->pc.c.vars_u[idx_c];
02043     }
02044     // Set forwarding pointer
02045     x.idx[0] = reinterpret_cast<ActorLink**>(Support::mark(this));
02046     // Register original
02047     x.idx[1] = reinterpret_cast<ActorLink**>(*reg); *reg = &x;
02048   }
02049 
02050   template <class VIC>
02051   forceinline ModEvent
02052   VarImp<VIC>::me(ModEventDelta med) {
02053     return static_cast<ModEvent>((med & VIC::med_mask) >> VIC::med_fst);
02054   }
02055 
02056   template <class VIC>
02057   forceinline ModEventDelta
02058   VarImp<VIC>::med(ModEvent me) {
02059     return static_cast<ModEventDelta>(me << VIC::med_fst);
02060   }
02061 
02062   template <class VIC>
02063   forceinline ModEvent
02064   VarImp<VIC>::me_combine(ModEvent me1, ModEvent me2) {
02065     return VIC::me_combine(me1,me2);
02066   }
02067 
02068   template <class VIC>
02069   forceinline void
02070   VarImp<VIC>::schedule(Space* home, Propagator* p, ModEvent me) {
02071     if (VIC::med_update(p->u.med,me))
02072       home->enqueue(p);
02073   }
02074 
02075   template <class VIC>
02076   forceinline void
02077   VarImp<VIC>::schedule(Space* home, PropCond pc1, PropCond pc2, ModEvent me) {
02078     ActorLink** b = idx[pc1];
02079     ActorLink** p = idx[pc2+1];
02080     while (p-- > b)
02081       schedule(home,Propagator::cast(*p),me);
02082   }
02083 
02084   template <class VIC>
02085   forceinline void
02086   VarImp<VIC>::enter(Space* home, ActorLink* a, PropCond pc) {
02087     // Count one new subscription
02088     home->pc.p.n_sub += 1;
02089     if ((free_and_bits >> free_bits) == 0)
02090       resize(home);
02091     free_and_bits -= 1 << free_bits;
02092     // Enter subscription
02093     --idx[0];
02094     for (PropCond i = 0; i < pc; i++)
02095       *(idx[i]) = *(--idx[i+1]);
02096     *idx[pc]=a;
02097   }
02098 
02099   template <class VIC>
02100   void
02101   VarImp<VIC>::resize(Space* home) {
02102     if (idx[0] == NULL) {
02103       assert((free_and_bits >> free_bits) == 0);
02104       // Create fresh dependency array with four entries
02105       free_and_bits += 4 << free_bits;
02106       ActorLink** prop = static_cast<ActorLink**>
02107         (home->alloc(4*sizeof(ActorLink*))) + 4;
02108       for (PropCond i=0; i<pc_max+3; i++)
02109         idx[i] = prop;
02110     } else {
02111       // Resize dependency array
02112       unsigned int n = static_cast<unsigned int>(idx[pc_max+2] - idx[0]);
02113       // Find out whether the area is most likely in the special area
02114       // reserved for subscriptions. If yes, just resize mildly otherwise
02115       // more agressively
02116       ActorLink** s = static_cast<ActorLink**>
02117         (home->mm.subscriptions());
02118       unsigned int m = 
02119         ((s <= idx[0]) && (idx[0] < s+home->pc.p.n_sub)) ?
02120         (n+4) : ((n+1)*3>>1);
02121       ActorLink** prop = static_cast<ActorLink**>
02122         (home->alloc(m*sizeof(ActorLink*))) + m-n;
02123       free_and_bits += (m-n) << free_bits;
02124       // Copy entries
02125       memcpy(prop, idx[0], n*sizeof(ActorLink*));
02126       home->reuse(idx[0], n*sizeof(ActorLink*));
02127       // Update index pointers
02128       ptrdiff_t o = prop - idx[0];
02129       idx[0] = prop;
02130       for (PropCond i = pc_max+2; i > 0; i--)
02131         idx[i] += o;
02132     }
02133   }
02134 
02135   template <class VIC>
02136   void
02137   VarImp<VIC>::subscribe(Space* home, Propagator* p, PropCond pc,
02138                          bool assigned, ModEvent me, bool schedule) {
02139     if (assigned) {
02140       // Do not subscribe, just schedule the propagator
02141       if (schedule)
02142         VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
02143     } else {
02144       enter(home,ActorLink::cast(p),pc);
02145       // Schedule propagator
02146       if (schedule && (pc != PC_GEN_ASSIGNED))
02147         VarImp<VIC>::schedule(home,p,me);
02148     }
02149   }
02150 
02151   template <class VIC>
02152   forceinline void
02153   VarImp<VIC>::subscribe(Space* home, Advisor* a, bool assigned) {
02154     if (!assigned)
02155       enter(home,a,pc_max+1);
02156   }
02157 
02158   template <class VIC>
02159   forceinline void
02160   VarImp<VIC>::remove(Space* home, ActorLink* a, PropCond pc) {
02161     /*
02162      * The entries are removed from front to back, so when iterating
02163      * over dependencies wile removing them it must be done in
02164      * forward direction.
02165      */
02166     ActorLink** f = idx[pc];
02167 #ifdef GECODE_AUDIT
02168     while (f < idx[pc+1])
02169       if (*f == a)
02170         goto found;
02171       else
02172         f++;
02173     GECODE_NEVER;
02174   found: ;
02175 #else
02176     while (*f != a) f++;
02177 #endif
02178     *f=*idx[pc];
02179     for (PropCond i=pc; i>0; i--)
02180       *(idx[i]++)=*(idx[i-1]);
02181     idx[0]++;
02182     free_and_bits += 1 << free_bits;
02183     home->pc.p.n_sub -= 1;
02184   }
02185 
02186   template <class VIC>
02187   forceinline void
02188   VarImp<VIC>::cancel(Space* home, Propagator* p, PropCond pc, bool assigned) {
02189     if (!assigned)
02190       remove(home,ActorLink::cast(p),pc);
02191   }
02192 
02193   template <class VIC>
02194   forceinline void
02195   VarImp<VIC>::cancel(Space* home, Advisor* a, bool assigned) {
02196     if (!assigned)
02197       remove(home,a,pc_max+1);
02198   }
02199 
02200   template <class VIC>
02201   forceinline void
02202   VarImp<VIC>::cancel(Space* home) {
02203     // Entries in index structure are disabled. However they
02204     // must still work for cloning (idx[0]) and degree (idx[PC+2])
02205     ActorLink** b = idx[0]; idx[0] = NULL;
02206     ActorLink** p = idx[pc_max+2]; idx[pc_max+2] = NULL;
02207     home->pc.p.n_sub -= (p-b);
02208     unsigned int n = (free_and_bits >> VIC::free_bits) + (p-b);
02209     home->reuse(p-n,n*sizeof(ActorLink*));
02210   }
02211 
02212   template <class VIC>
02213   forceinline bool
02214   VarImp<VIC>::advise(Space* home, ModEvent me, Delta* d) {
02215     /*
02216      * An advisor that is executed might remove itself due to subsumption.
02217      * As entries are removed from front to back, the advisors must
02218      * be iterated in forward direction.
02219      */
02220     ActorLink** la = idx[pc_max+1];
02221     ActorLink** le = idx[pc_max+2];
02222     if (la == le)
02223       return true;
02224     d->me = me;
02225     // An advisor that is run, might be removed during execution.
02226     // As removal is done from the back the advisors have to be executed
02227     // in inverse order.
02228     do {
02229       Advisor* a = Advisor::cast(*la);
02230       Propagator* p = a->propagator();
02231       switch (p->advise(home,a,d)) {
02232       case ES_FIX:
02233         break;
02234       case ES_FAILED:
02235         return false;
02236       case ES_NOFIX:
02237         schedule(home,p,me);
02238         break;
02239       default:
02240         GECODE_NEVER;
02241       }
02242     } while (++la < le);
02243     return true;
02244   }
02245 
02246   template <class VIC>
02247   forceinline void
02248   VarImp<VIC>::update(VarImp<VIC>* x, ActorLink**& sub) {
02249     // this refers to the variable to be updated (clone)
02250     // x refers to the original
02251     // Recover from copy
02252     x->idx[0] = idx[0];
02253     ActorLink** f = x->idx[0];
02254     x->idx[1] = idx[1];
02255     int n = static_cast<int>(x->idx[pc_max+2] - f);
02256     ActorLink** t = sub;
02257     sub += n;
02258     idx[0] = t;
02259     ptrdiff_t o = t - f;
02260     for (PropCond i = 1; i<pc_max+3; i++)
02261       idx[i] = x->idx[i]+o;
02262     while ((n-4) >= 0) {
02263       n -= 4;
02264       t[0]=f[0]->prev(); t[1]=f[1]->prev();
02265       t[2]=f[2]->prev(); t[3]=f[3]->prev();
02266       t += 4; f += 4;
02267     }
02268     if ((n-2) >= 0) {
02269       n -= 2;
02270       t[0]=f[0]->prev(); t[1]=f[1]->prev();
02271       t += 2; f += 2;
02272     }
02273     if (n > 0) {
02274       t[0]=f[0]->prev();
02275     }
02276   }
02277 
02278   template <class VIC>
02279   forceinline void
02280   VarImp<VIC>::update(Space* home, ActorLink**& sub) {
02281     VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home->pc.c.vars_u[idx_c]);
02282     while (x != NULL) {
02283       VarImp<VIC>* n = x->next(); x->forward()->update(x,sub); x = n;
02284     }
02285   }
02286 
02287 
02288 
02289   /*
02290    * Variable disposer
02291    *
02292    */
02293   template <class VarType>
02294   VarDisposer<VarType>::VarDisposer(void) {
02295 #ifdef GECODE_HAS_VAR_DISPOSE
02296     Space::vd[VarType::idx_d] = this;
02297 #endif
02298   }
02299 
02300   template <class VarType>
02301   void
02302   VarDisposer<VarType>::dispose(Space* home, VarImpBase* _x) {
02303     VarType* x = static_cast<VarType*>(_x);
02304     do {
02305       x->dispose(home); x = static_cast<VarType*>(x->next_d());
02306     } while (x != NULL);
02307   }
02308 
02309 }
02310 
02311 // STATISTICS: kernel-core