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