Generated on Mon Jul 6 18:09:15 2009 for Gecode by doxygen 1.5.9

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: 2009-05-05 18:30:06 +0200 (Tue, 05 May 2009) $ by $Author: schulte $
00022  *     $Revision: 8992 $
00023  *
00024  *  This file is part of Gecode, the generic constraint
00025  *  development environment:
00026  *     http://www.gecode.org
00027  *
00028  *  Permission is hereby granted, free of charge, to any person obtaining
00029  *  a copy of this software and associated documentation files (the
00030  *  "Software"), to deal in the Software without restriction, including
00031  *  without limitation the rights to use, copy, modify, merge, publish,
00032  *  distribute, sublicense, and/or sell copies of the Software, and to
00033  *  permit persons to whom the Software is furnished to do so, subject to
00034  *  the following conditions:
00035  *
00036  *  The above copyright notice and this permission notice shall be
00037  *  included in all copies or substantial portions of the Software.
00038  *
00039  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00040  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00041  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00042  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00043  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00044  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00045  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00046  *
00047  */
00048 
00049 namespace Gecode {
00050 
00051   class Space;
00052 
00080   class CopiedHandle {
00081   public:
00089     class Object {
00090       friend class Space;
00091       friend class CopiedHandle;
00092     private:
00094       Object* next;
00096       Object* fwd;
00097     public:
00099       Object(void);
00101       virtual Object* copy(void) const = 0;
00103       virtual ~Object(void);
00105       static void* operator new(size_t, Space&);
00107       static void operator delete(void*, size_t);
00109       static void operator delete(void*, Space&);
00110     private:
00111       static void* operator new(size_t);
00112     };
00113   private:
00115     Object* o;
00116   public:
00118     CopiedHandle(void);
00120     CopiedHandle(Object* so);
00122     CopiedHandle(const CopiedHandle& sh);
00124     CopiedHandle& operator =(const CopiedHandle& sh);
00126     void update(Space& home, bool share, CopiedHandle& sh);
00128     void dispose(Space& home);
00129   protected:
00131     Object* object(void) const;
00133     void object(Object* n);
00134   };
00135 
00149   class SharedHandle : public CopiedHandle {
00150   public:
00158     class Object : public CopiedHandle::Object {
00159       friend class Space;
00160       friend class SharedHandle;
00161     private:
00163       unsigned int use_cnt;
00164     public:
00166       Object(void);
00168       virtual ~Object(void);
00170       static void* operator new(size_t s);
00172       static void  operator delete(void* p);
00173     };
00174   private:
00176     void subscribe(void);
00178     void cancel(void);
00179   public:
00181     SharedHandle(void);
00183     SharedHandle(Object* so);
00185     SharedHandle(const SharedHandle& sh);
00187     SharedHandle& operator =(const SharedHandle& sh);
00189     void update(Space& home, bool share, SharedHandle& sh);
00191     ~SharedHandle(void);
00192   protected:
00194     Object* object(void) const;
00196     void object(Object* n);
00197   };
00198 
00199 
00208 
00209   typedef int ModEvent;
00210 
00212   const ModEvent ME_GEN_FAILED   = -1;
00214   const ModEvent ME_GEN_NONE     =  0;
00216   const ModEvent ME_GEN_ASSIGNED =  1;
00217 
00219   typedef int PropCond;
00221   const PropCond PC_GEN_NONE     = -1;
00223   const PropCond PC_GEN_ASSIGNED = 0;
00225 
00236   typedef int ModEventDelta;
00237 
00238 }
00239 
00240 #include <gecode/kernel/var-type.hpp>
00241 
00242 namespace Gecode {
00243 
00245   class NoIdxVarImpConf {
00246   public:
00248     static const int idx_c = -1;
00250     static const int idx_d = -1;
00252     static const PropCond pc_max = PC_GEN_ASSIGNED;
00254     static const int free_bits = 0;
00256     static const int med_fst = 0;
00258     static const int med_lst = 0;
00260     static const int med_mask = 0;
00262     static Gecode::ModEvent me_combine(ModEvent me1, ModEvent me2);
00264     static bool med_update(ModEventDelta& med, ModEvent me);
00265   };
00266 
00267   forceinline ModEvent
00268   NoIdxVarImpConf::me_combine(ModEvent, ModEvent) {
00269     GECODE_NEVER; return 0;
00270   }
00271   forceinline bool
00272   NoIdxVarImpConf::med_update(ModEventDelta&, ModEvent) {
00273     GECODE_NEVER; return false;
00274   }
00275 
00276 
00277   /*
00278    * These are the classes of interest
00279    *
00280    */
00281   class ActorLink;
00282   class Actor;
00283   class Propagator;
00284   class Advisor;
00285   template<class A> class Council;
00286   template<class A> class Advisors;
00287   template<class VIC> class VarImp;
00288 
00289 
00290   /*
00291    * Variable implementations
00292    *
00293    */
00294 
00302   class VarImpBase {};
00303 
00310   class GECODE_VTABLE_EXPORT VarDisposerBase {
00311   public:
00313     GECODE_KERNEL_EXPORT virtual void dispose(Space& home, VarImpBase* x);
00315     GECODE_KERNEL_EXPORT virtual ~VarDisposerBase(void);
00316   };
00317 
00324   template<class VarType>
00325   class VarDisposer : public VarDisposerBase {
00326   public:
00328     VarDisposer(void);
00330     virtual void dispose(Space& home, VarImpBase* x);
00331   };
00332 
00334   class Delta {
00335     template<class VIC> friend class VarImp;
00336   private:
00338     ModEvent me;
00339   public:
00341     ModEvent modevent(void) const;
00342   };
00343 
00351   template<class VIC>
00352   class VarImp : public VarImpBase {
00353     friend class Space;
00354     friend class Propagator;
00355     template<class VarType> friend class VarDisposer;
00356   private:
00368     ActorLink** base;
00369 
00371     static const int idx_c = VIC::idx_c;
00373     static const int idx_d = VIC::idx_d;
00375     static const int free_bits = VIC::free_bits;
00377     unsigned int entries;
00379     unsigned int free_and_bits;
00381     static const Gecode::PropCond pc_max = VIC::pc_max;
00382 
00383     union {
00394       unsigned int idx[pc_max+1];
00396       VarImp<VIC>* next;
00397     } u;
00398 
00400     ActorLink** actor(PropCond pc);
00402     ActorLink** actorNonZero(PropCond pc);
00404     unsigned int& idx(PropCond pc);
00406     unsigned int idx(PropCond pc) const;
00407 
00414     void update(VarImp* x, ActorLink**& sub);
00421     static void update(Space& home, ActorLink**& sub);
00422 
00424     void enter(Space& home, Propagator* p, PropCond pc);
00426     void enter(Space& home, Advisor* a);
00428     void resize(Space& home);
00430     void remove(Space& home, Propagator* p, PropCond pc);
00432     void remove(Space& home, Advisor* a);
00433 
00434   protected:
00435 #ifdef GECODE_HAS_VAR_DISPOSE
00437     static VarImp<VIC>* vars_d(Space& home);
00439     static void vars_d(Space& home, VarImp<VIC>* x);
00440 #endif
00441 
00442   public:
00444     VarImp(Space& home);
00446     VarImp(void);
00447 
00449 
00450 
00462     void subscribe(Space& home, Propagator& p, PropCond pc,
00463                    bool assigned, ModEvent me, bool schedule);
00469     void cancel(Space& home, Propagator& p, PropCond pc,
00470                 bool assigned);
00476     void subscribe(Space& home, Advisor& a, bool assigned);
00482     void cancel(Space& home, Advisor& a, bool assigned);
00484     void cancel(Space& home);
00491     unsigned int degree(void) const;
00497     bool advise(Space& home, ModEvent me, Delta& d);
00499 
00501 
00502 
00503     VarImp(Space& home, bool share, VarImp& x);
00505     bool copied(void) const;
00507     VarImp* forward(void) const;
00509     VarImp* next(void) const;
00511 
00513 
00514 
00515     static void schedule(Space& home, Propagator& p, ModEvent me);
00517     static ModEvent me(const ModEventDelta& med);
00519     static ModEventDelta med(ModEvent me);
00521     static ModEvent me_combine(ModEvent me1, ModEvent me2);
00523 
00525     unsigned int bits(void) const;
00527     unsigned int& bits(void);
00528 
00529   protected:
00531     void schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me);
00532 
00533   public:
00535 
00536 
00537     static void* operator new(size_t,Space&);
00539     static void  operator delete(void*,Space&);
00541     static void  operator delete(void*);
00543   };
00544 
00553   enum ExecStatus {
00554     __ES_SUBSUMED       = -2, 
00555     ES_FAILED           = -1, 
00556     ES_NOFIX            =  0, 
00557     ES_OK               =  0, 
00558     ES_FIX              =  1, 
00559     __ES_PARTIAL        =  2  
00560   };
00561 
00566   class PropCost {
00567     friend class Space;
00568   public:
00570     enum ActualCost {
00571       AC_CRAZY_LO     = 0, 
00572       AC_CRAZY_HI     = 0, 
00573       AC_CUBIC_LO     = 1, 
00574       AC_CUBIC_HI     = 1, 
00575       AC_QUADRATIC_LO = 2, 
00576       AC_QUADRATIC_HI = 2, 
00577       AC_LINEAR_HI    = 3, 
00578       AC_LINEAR_LO    = 4, 
00579       AC_TERNARY_HI   = 4, 
00580       AC_BINARY_HI    = 5, 
00581       AC_TERNARY_LO   = 5, 
00582       AC_BINARY_LO    = 6, 
00583       AC_UNARY_LO     = 6, 
00584       AC_UNARY_HI     = 6, 
00585       AC_MAX          = 6  
00586     };
00588     ActualCost ac;
00589   public:
00591     enum Mod {
00592       LO, 
00593       HI  
00594     };
00595   private:
00597     static PropCost cost(Mod m, ActualCost lo, ActualCost hi, unsigned int n);
00599     PropCost(ActualCost ac);
00600   public:
00602     static PropCost crazy(PropCost::Mod m, unsigned int n);
00604     static PropCost crazy(PropCost::Mod m, int n);
00606     static PropCost cubic(PropCost::Mod m, unsigned int n);
00608     static PropCost cubic(PropCost::Mod m, int n);
00610     static PropCost quadratic(PropCost::Mod m, unsigned int n);
00612     static PropCost quadratic(PropCost::Mod m, int n);
00614     static PropCost linear(PropCost::Mod m, unsigned int n);
00616     static PropCost linear(PropCost::Mod m, int n);
00618     static PropCost ternary(PropCost::Mod m);
00620     static PropCost binary(PropCost::Mod m);
00622     static PropCost unary(PropCost::Mod m);
00623   };
00624 
00625 
00630   enum ActorProperty {
00639     AP_DISPOSE = (1 << 0),
00645     AP_WEAKLY  = (1 << 1)
00646   };
00647 
00648 
00656   class ActorLink {
00657     friend class Actor;
00658     friend class Propagator;
00659     friend class Advisor;
00660     friend class Branching;
00661     friend class Space;
00662     template<class VIC> friend class VarImp;
00663   private:
00664     ActorLink* _next; ActorLink* _prev;
00665   public:
00667 
00668     ActorLink* prev(void) const; void prev(ActorLink*);
00669     ActorLink* next(void) const; void next(ActorLink*);
00670     ActorLink** next_ref(void);
00672 
00674     void init(void);
00676     void unlink(void);
00678     void head(ActorLink* al);
00680     void tail(ActorLink* al);
00682     bool empty(void) const;
00684     template<class T> static ActorLink* cast(T* a);
00686     template<class T> static const ActorLink* cast(const T* a);
00687   };
00688 
00689 
00694   class GECODE_VTABLE_EXPORT Actor : private ActorLink {
00695     friend class ActorLink;
00696     friend class Space;
00697     friend class Propagator;
00698     friend class Advisor;
00699     friend class Branching;
00700     template<class VIC> friend class VarImp;
00701     template<class A> friend class Council;
00702   private:
00704     static Actor* cast(ActorLink* al);
00706     static const Actor* cast(const ActorLink* al);
00707   public:
00709     virtual Actor* copy(Space& home, bool share) = 0;
00710 
00712 
00713 
00714     GECODE_KERNEL_EXPORT
00715     virtual size_t allocated(void) const;
00717     GECODE_KERNEL_EXPORT
00718     virtual size_t dispose(Space& home);
00720     static void* operator new(size_t s, Space& home);
00722     static void  operator delete(void* p, Space& home);
00723   private:
00724 #ifndef __GNUC__
00726     static void  operator delete(void* p);
00727 #endif
00729     static void* operator new(size_t s);
00730 
00731 #ifdef __GNUC__
00732   public:
00734     GECODE_KERNEL_EXPORT virtual ~Actor(void);
00736     static void  operator delete(void* p);
00737 #endif
00738   };
00739 
00740 
00760   ExecStatus ES_SUBSUMED(Propagator& p, size_t s);
00771   ExecStatus ES_SUBSUMED(Propagator& p, Space& home);
00782   ExecStatus ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med);
00793   ExecStatus ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med);
00794 
00799   class GECODE_VTABLE_EXPORT Propagator : public Actor {
00800     friend class ActorLink;
00801     friend class Space;
00802     template<class VIC> friend class VarImp;
00803     friend ExecStatus ES_SUBSUMED(Propagator&, size_t);
00804     friend ExecStatus ES_SUBSUMED(Propagator&, Space&);
00805     friend ExecStatus ES_FIX_PARTIAL(Propagator&, const ModEventDelta&);
00806     friend ExecStatus ES_NOFIX_PARTIAL(Propagator&, const ModEventDelta&);
00807     friend class Advisor;
00808     template<class A> friend class Council;
00809   private:
00810     union {
00812       ModEventDelta med;
00814       size_t size;
00816       Gecode::ActorLink* advisors;
00817     } u;
00819     static Propagator* cast(ActorLink* al);
00821     static const Propagator* cast(const ActorLink* al);
00822   protected:
00824     Propagator(Space& home);
00826     Propagator(Space& home, bool share, Propagator& p);
00827 
00828   public:
00830 
00831 
00854     virtual ExecStatus propagate(Space& home, const ModEventDelta& med) = 0;
00856     virtual PropCost cost(const Space& home, const ModEventDelta& med) const = 0;
00886     GECODE_KERNEL_EXPORT
00887     virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00889   };
00890 
00891 
00899   template<class A>
00900   class Council {
00901     friend class Advisor;
00902     friend class Advisors<A>;
00903   private:
00905     mutable ActorLink* advisors;
00906   public:
00908     Council(void);
00910     Council(Space& home);
00912     bool empty(void) const;
00914     void update(Space& home, bool share, Council<A>& c);
00916     void dispose(Space& home);
00917   };
00918 
00919 
00924   template<class A>
00925   class Advisors {
00926   private:
00928     ActorLink* a;
00929   public:
00931     Advisors(const Council<A>& c);
00933     bool operator ()(void) const;
00935     void operator ++(void);
00937     A& advisor(void) const;
00938   };
00939 
00940 
00952   template<class A>
00953   ExecStatus ES_SUBSUMED_FIX(A& a, Space& home, Council<A>& c);
00965   template<class A>
00966   ExecStatus ES_SUBSUMED_NOFIX(A& a, Space& home, Council<A>& c);
00967 
00978   class Advisor : private ActorLink {
00979     template<class VIC> friend class VarImp;
00980     template<class A> friend class Council;
00981     template<class A> friend class Advisors;
00982   private:
00984     bool disposed(void) const;
00986     static Advisor* cast(ActorLink* al);
00988     static const Advisor* cast(const ActorLink* al);
00989   protected:
00991     Propagator& propagator(void) const;
00992   public:
00994     template<class A>
00995     Advisor(Space& home, Propagator& p, Council<A>& c);
00997     Advisor(Space& home, bool share, Advisor& a);
00998 
01000 
01001 
01002     template<class A>
01003     void dispose(Space& home, Council<A>& c);
01005     static void* operator new(size_t s, Space& home);
01007     static void  operator delete(void* p, Space& home);
01009   private:
01010 #ifndef __GNUC__
01012     static void  operator delete(void* p);
01013 #endif
01015     static void* operator new(size_t s);
01016   };
01017 
01018 
01019   class Branching;
01020 
01030   class BranchingDesc {
01031     friend class Space;
01032   private:
01033     unsigned int _id;  
01034     unsigned int _alt; 
01035 
01037     unsigned int id(void) const;
01038   protected:
01040     BranchingDesc(const Branching& b, const unsigned int a);
01041   public:
01043     unsigned int alternatives(void) const;
01045     GECODE_KERNEL_EXPORT virtual ~BranchingDesc(void);
01047     virtual size_t size(void) const = 0;
01049     static void* operator new(size_t);
01051     static void  operator delete(void*);
01052   };
01053 
01063   class GECODE_VTABLE_EXPORT Branching : public Actor {
01064     friend class ActorLink;
01065     friend class Space;
01066     friend class BranchingDesc;
01067   private:
01069     unsigned int _id;
01071     static Branching* cast(ActorLink* al);
01073     static const Branching* cast(const ActorLink* al);
01074   protected:
01076     Branching(Space& home);
01078     Branching(Space& home, bool share, Branching& b);
01079   public:
01081 
01082 
01090     virtual bool status(const Space& home) const = 0;
01098     virtual const BranchingDesc* description(Space& home) = 0;
01106     virtual ExecStatus commit(Space& home, const BranchingDesc& d,
01107                               unsigned int a) = 0;
01109     unsigned int id(void) const;
01111   };
01112 
01113 
01114 
01119   enum SpaceStatus {
01120     SS_FAILED, 
01121     SS_SOLVED, 
01122     SS_BRANCH  
01123   };
01124 
01129   class StatusStatistics {
01130   public:
01132     unsigned long int propagate;
01134     bool wmp;
01136     StatusStatistics(void);
01138     void reset(void);
01140     StatusStatistics operator +(const StatusStatistics& s);
01142     StatusStatistics& operator +=(const StatusStatistics& s);
01143   };
01144 
01149   class CloneStatistics {
01150   public:
01152     CloneStatistics(void);
01154     void reset(void);
01156     CloneStatistics operator +(const CloneStatistics& s);
01158     CloneStatistics& operator +=(const CloneStatistics& s);
01159   };
01160 
01165   class CommitStatistics {
01166   public:
01168     CommitStatistics(void);
01170     void reset(void);
01172     CommitStatistics operator +(const CommitStatistics& s);
01174     CommitStatistics& operator +=(const CommitStatistics& s);
01175   };
01176 
01180   class GECODE_VTABLE_EXPORT Space {
01181     friend class Actor;
01182     friend class Propagator;
01183     friend class Branching;
01184     friend class Advisor;
01185     template<class VIC> friend class VarImp;
01186     template<class VarType> friend class VarDisposer;
01187     friend class CopiedHandle;
01188     friend class Region;
01189   private:
01191     SharedMemory* sm;
01193     MemoryManager mm;
01195     ActorLink pl;
01197     ActorLink bl;
01203     Branching* b_status;
01215     Branching* b_commit;
01216     union {
01218       struct {
01231         ActorLink* active;
01233         ActorLink queue[PropCost::AC_MAX+1];
01235         unsigned int branch_id;
01237         unsigned int n_sub;
01238       } p;
01240       struct {
01242         VarImpBase* vars_u[AllVarConf::idx_c];
01244         VarImpBase* vars_noidx;
01246         CopiedHandle::Object* copied;
01247       } c;
01248     } pc;
01250     void enqueue(Propagator* p);
01255 #ifdef GECODE_HAS_VAR_DISPOSE
01257     GECODE_KERNEL_EXPORT static VarDisposerBase* vd[AllVarConf::idx_d];
01259     VarImpBase* _vars_d[AllVarConf::idx_d];
01261     template<class VIC> VarImpBase* vars_d(void) const;
01263     template<class VIC> void vars_d(VarImpBase* x);
01264 #endif
01266     void update(ActorLink** sub);
01267 
01268 
01270     Actor** d_fst;
01272     Actor** d_cur;
01274     Actor** d_lst;
01276     GECODE_KERNEL_EXPORT void d_resize(void);
01277 
01285     unsigned int n_wmp;
01286 
01288     GECODE_KERNEL_EXPORT static StatusStatistics unused_status;
01290     GECODE_KERNEL_EXPORT static CloneStatistics unused_clone;
01292     GECODE_KERNEL_EXPORT static CommitStatistics unused_commit;
01294     GECODE_KERNEL_EXPORT static unsigned long int unused_uli;
01296     GECODE_KERNEL_EXPORT static bool unused_b;
01297 
01312     GECODE_KERNEL_EXPORT Space* _clone(bool share=true);
01313 
01346     GECODE_KERNEL_EXPORT
01347     void _commit(const BranchingDesc& d, unsigned int a);
01348 
01349   public:
01354     GECODE_KERNEL_EXPORT Space(void);
01359     GECODE_KERNEL_EXPORT virtual ~Space(void);
01370     GECODE_KERNEL_EXPORT Space(bool share, Space& s);
01377     virtual Space* copy(bool share) = 0;
01389     GECODE_KERNEL_EXPORT virtual void constrain(const Space& best);
01394     static void* operator new(size_t);
01399     static void  operator delete(void*);
01400 
01401 
01402     /*
01403      * Member functions for search engines
01404      *
01405      */
01406 
01418     GECODE_KERNEL_EXPORT
01419     SpaceStatus status(StatusStatistics& stat=unused_status);
01420 
01452     GECODE_KERNEL_EXPORT
01453     const BranchingDesc* description(void);
01454 
01472     Space* clone(bool share=true, CloneStatistics& stat=unused_clone) const;
01473 
01508     void commit(const BranchingDesc& d, unsigned int a,
01509                 CommitStatistics& stat=unused_commit);
01510 
01518     void notice(Actor& a, ActorProperty p);
01526     void ignore(Actor& a, ActorProperty p);
01527 
01535     void fail(void);
01544     bool failed(void) const;
01549     bool stable(void) const;
01556     GECODE_KERNEL_EXPORT unsigned int propagators(void) const;
01563     GECODE_KERNEL_EXPORT unsigned int branchings(void) const;
01564 
01576     template<class T>
01577     T* alloc(long unsigned int n);
01584     template<class T>
01585     T* alloc(long int n);
01592     template<class T>
01593     T* alloc(unsigned int n);
01600     template<class T>
01601     T* alloc(int n);
01611     template<class T>
01612     void free(T* b, long unsigned int n);
01622     template<class T>
01623     void free(T* b, long int n);
01633     template<class T>
01634     void free(T* b, unsigned int n);
01644     template<class T>
01645     void free(T* b, int n);
01657     template<class T>
01658     T* realloc(T* b, long unsigned int n, long unsigned int m);
01670     template<class T>
01671     T* realloc(T* b, long int n, long int m);
01683     template<class T>
01684     T* realloc(T* b, unsigned int n, unsigned int m);
01696     template<class T>
01697     T* realloc(T* b, int n, int m);
01705     template<class T>
01706     T** realloc(T** b, long unsigned int n, long unsigned int m);
01714     template<class T>
01715     T** realloc(T** b, long int n, long int m);
01723     template<class T>
01724     T** realloc(T** b, unsigned int n, unsigned int m);
01732     template<class T>
01733     T** realloc(T** b, int n, int m);
01735     void* ralloc(size_t s);
01737     void rfree(void* p, size_t s);
01739     void* rrealloc(void* b, size_t n, size_t m);
01741     template<size_t> void* fl_alloc(void);
01747     template<size_t> void  fl_dispose(FreeList* f, FreeList* l);
01754     size_t allocated(void) const;
01762     GECODE_KERNEL_EXPORT void flush(void);
01764 
01765 
01766 
01769     template<class T> 
01770     T& construct(void);
01776     template<class T, typename A1> 
01777     T& construct(A1 const& a1);
01783     template<class T, typename A1, typename A2> 
01784     T& construct(A1 const& a1, A2 const& a2);
01790     template<class T, typename A1, typename A2, typename A3>
01791     T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
01797     template<class T, typename A1, typename A2, typename A3, typename A4>
01798     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
01804     template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
01805     T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
01807 
01813     class Propagators {
01814     private:
01816       const Space& home;
01818       const ActorLink* q;
01820       const ActorLink* c;
01822       const ActorLink* e;
01823     public:
01825       Propagators(const Space& home);
01827       bool operator ()(void) const;
01829       void operator ++(void);
01831       const Propagator& propagator(void) const;
01832     };
01833 
01839     class Branchings {
01840     private:
01842       const ActorLink* c;
01844       const ActorLink* e;
01845     public:
01847       Branchings(const Space& home);
01849       bool operator ()(void) const;
01851       void operator ++(void);
01853       const Branching& branching(void) const;
01854     };    
01855   };
01856 
01857 
01858 
01859 
01860   /*
01861    * Memory management
01862    *
01863    */
01864 
01865   // Heap allocated
01866   forceinline void*
01867   SharedHandle::Object::operator new(size_t s) {
01868     return heap.ralloc(s);
01869   }
01870   forceinline void
01871   SharedHandle::Object::operator delete(void* p) {
01872     heap.rfree(p);
01873   }
01874 
01875   forceinline void*
01876   Space::operator new(size_t s) {
01877     return heap.ralloc(s);
01878   }
01879   forceinline void
01880   Space::operator delete(void* p) {
01881     heap.rfree(p);
01882   }
01883 
01884   forceinline void
01885   BranchingDesc::operator delete(void* p) {
01886     heap.rfree(p);
01887   }
01888   forceinline void*
01889   BranchingDesc::operator new(size_t s) {
01890     return heap.ralloc(s);
01891   }
01892 
01893   // Space allocation: general space heaps and free lists
01894   forceinline void*
01895   Space::ralloc(size_t s) {
01896     return mm.alloc(sm,s);
01897   }
01898   forceinline void
01899   Space::rfree(void* p, size_t s) {
01900     return mm.reuse(p,s);
01901   }
01902   forceinline void*
01903   Space::rrealloc(void* _b, size_t n, size_t m) {
01904     char* b = static_cast<char*>(_b);
01905     if (n < m) {
01906       char* p = static_cast<char*>(ralloc(m));
01907       memcpy(p,b,n);
01908       rfree(b,n);
01909       return p;
01910     } else {
01911       rfree(b+m,m-n);
01912       return b;
01913     }
01914   }
01915 
01916   template<size_t s>
01917   forceinline void*
01918   Space::fl_alloc(void) {
01919     return mm.template fl_alloc<s>(sm);
01920   }
01921   template<size_t s>
01922   forceinline void
01923   Space::fl_dispose(FreeList* f, FreeList* l) {
01924     mm.template fl_dispose<s>(f,l);
01925   }
01926 
01927   forceinline size_t
01928   Space::allocated(void) const {
01929     size_t s = mm.allocated();
01930     for (Actor** a = d_fst; a < d_cur; a++)
01931       s += (*a)->allocated();
01932     return s;
01933   }
01934 
01935   /*
01936    * Typed allocation routines
01937    *
01938    */
01939   template<class T>
01940   forceinline T*
01941   Space::alloc(long unsigned int n) {
01942     T* p = static_cast<T*>(ralloc(sizeof(T)*n));
01943     for (long unsigned int i=n; i--; )
01944       (void) new (p+i) T();
01945     return p;
01946   }
01947   template<class T>
01948   forceinline T*
01949   Space::alloc(long int n) {
01950     assert(n >= 0);
01951     return alloc<T>(static_cast<long unsigned int>(n));
01952   }
01953   template<class T>
01954   forceinline T*
01955   Space::alloc(unsigned int n) {
01956     return alloc<T>(static_cast<long unsigned int>(n));
01957   }
01958   template<class T>
01959   forceinline T*
01960   Space::alloc(int n) {
01961     assert(n >= 0);
01962     return alloc<T>(static_cast<long unsigned int>(n));
01963   }
01964 
01965   template<class T>
01966   forceinline void
01967   Space::free(T* b, long unsigned int n) {
01968     for (long unsigned int i=n; i--; )
01969       b[i].~T();
01970     rfree(b,n*sizeof(T));
01971   }
01972   template<class T>
01973   forceinline void
01974   Space::free(T* b, long int n) {
01975     assert(n >= 0);
01976     free<T>(b,static_cast<long unsigned int>(n));
01977   }
01978   template<class T>
01979   forceinline void
01980   Space::free(T* b, unsigned int n) {
01981     free<T>(b,static_cast<long unsigned int>(n));
01982   }
01983   template<class T>
01984   forceinline void
01985   Space::free(T* b, int n) {
01986     assert(n >= 0);
01987     free<T>(b,static_cast<long unsigned int>(n));
01988   }
01989 
01990   template<class T>
01991   forceinline T*
01992   Space::realloc(T* b, long unsigned int n, long unsigned int m) {
01993     if (n < m) {
01994       T* p = static_cast<T*>(ralloc(sizeof(T)*m));
01995       for (long unsigned int i=n; i--; )
01996         (void) new (p+i) T(b[i]);
01997       for (long unsigned int i=n; i<m; i++)
01998         (void) new (p+i) T();
01999       free<T>(b,n);
02000       return p;
02001     } else {
02002       free<T>(b+m,m-n);
02003       return b;
02004     }
02005   }
02006   template<class T>
02007   forceinline T*
02008   Space::realloc(T* b, long int n, long int m) {
02009     assert((n >= 0) && (m >= 0));
02010     return realloc<T>(b,static_cast<long unsigned int>(n),
02011                       static_cast<long unsigned int>(m));
02012   }
02013   template<class T>
02014   forceinline T*
02015   Space::realloc(T* b, unsigned int n, unsigned int m) {
02016     return realloc<T>(b,static_cast<long unsigned int>(n),
02017                       static_cast<long unsigned int>(m));
02018   }
02019   template<class T>
02020   forceinline T*
02021   Space::realloc(T* b, int n, int m) {
02022     assert((n >= 0) && (m >= 0));
02023     return realloc<T>(b,static_cast<long unsigned int>(n),
02024                       static_cast<long unsigned int>(m));
02025   }
02026 
02027 #define GECODE_KERNEL_REALLOC(T)                                        \
02028   template<>                                                            \
02029   forceinline T*                                                        \
02030   Space::realloc<T>(T* b, long unsigned int n, long unsigned int m) {   \
02031     return static_cast<T*>(rrealloc(b,n*sizeof(T),m*sizeof(T)));        \
02032   }                                                                     \
02033   template<>                                                            \
02034   forceinline T*                                                        \
02035   Space::realloc<T>(T* b, long int n, long int m) {                     \
02036     assert((n >= 0) && (m >= 0));                                       \
02037     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02038                       static_cast<long unsigned int>(m));               \
02039   }                                                                     \
02040   template<>                                                            \
02041   forceinline T*                                                        \
02042   Space::realloc<T>(T* b, unsigned int n, unsigned int m) {             \
02043     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02044                       static_cast<long unsigned int>(m));               \
02045   }                                                                     \
02046   template<>                                                            \
02047   forceinline T*                                                        \
02048   Space::realloc<T>(T* b, int n, int m) {                               \
02049     assert((n >= 0) && (m >= 0));                                       \
02050     return realloc<T>(b,static_cast<long unsigned int>(n),              \
02051                       static_cast<long unsigned int>(m));               \
02052   }
02053 
02054   GECODE_KERNEL_REALLOC(bool)
02055   GECODE_KERNEL_REALLOC(signed char)
02056   GECODE_KERNEL_REALLOC(unsigned char)
02057   GECODE_KERNEL_REALLOC(signed short int)
02058   GECODE_KERNEL_REALLOC(unsigned short int)
02059   GECODE_KERNEL_REALLOC(signed int)
02060   GECODE_KERNEL_REALLOC(unsigned int)
02061   GECODE_KERNEL_REALLOC(signed long int)
02062   GECODE_KERNEL_REALLOC(unsigned long int)
02063   GECODE_KERNEL_REALLOC(float)
02064   GECODE_KERNEL_REALLOC(double)
02065 
02066 #undef GECODE_KERNEL_REALLOC
02067 
02068   template<class T>
02069   forceinline T**
02070   Space::realloc(T** b, long unsigned int n, long unsigned int m) {
02071     return static_cast<T**>(rrealloc(b,n*sizeof(T),m*sizeof(T*)));
02072   }
02073   template<class T>
02074   forceinline T**
02075   Space::realloc(T** b, long int n, long int m) {
02076     assert((n >= 0) && (m >= 0));
02077     return realloc<T*>(b,static_cast<long unsigned int>(n),
02078                        static_cast<long unsigned int>(m));
02079   }
02080   template<class T>
02081   forceinline T**
02082   Space::realloc(T** b, unsigned int n, unsigned int m) {
02083     return realloc<T*>(b,static_cast<long unsigned int>(n),
02084                        static_cast<long unsigned int>(m));
02085   }
02086   template<class T>
02087   forceinline T**
02088   Space::realloc(T** b, int n, int m) {
02089     assert((n >= 0) && (m >= 0));
02090     return realloc<T*>(b,static_cast<long unsigned int>(n),
02091                        static_cast<long unsigned int>(m));
02092   }
02093 
02094 
02095 #ifdef GECODE_HAS_VAR_DISPOSE
02096   template<class VIC>
02097   forceinline VarImpBase*
02098   Space::vars_d(void) const {
02099     return _vars_d[VIC::idx_d];
02100   }
02101   template<class VIC>
02102   forceinline void
02103   Space::vars_d(VarImpBase* x) {
02104     _vars_d[VIC::idx_d] = x;
02105   }
02106 #endif
02107 
02108   // Space allocated entities: Actors, variable implementations, and advisors
02109   forceinline void
02110   Actor::operator delete(void*) {}
02111   forceinline void
02112   Actor::operator delete(void*, Space&) {}
02113   forceinline void*
02114   Actor::operator new(size_t s, Space& home) {
02115     return home.ralloc(s);
02116   }
02117 
02118   template<class VIC>
02119   forceinline void
02120   VarImp<VIC>::operator delete(void*) {}
02121   template<class VIC>
02122   forceinline void
02123   VarImp<VIC>::operator delete(void*, Space&) {}
02124   template<class VIC>
02125   forceinline void*
02126   VarImp<VIC>::operator new(size_t s, Space& home) {
02127     return home.ralloc(s);
02128   }
02129 
02130 #ifndef __GNUC__
02131   forceinline void
02132   Advisor::operator delete(void*) {}
02133 #endif
02134   forceinline void
02135   Advisor::operator delete(void*, Space&) {}
02136   forceinline void*
02137   Advisor::operator new(size_t s, Space& home) {
02138     return home.ralloc(s);
02139   }
02140 
02141   forceinline void
02142   CopiedHandle::Object::operator delete(void*, size_t) {}
02143   forceinline void
02144   CopiedHandle::Object::operator delete(void*, Space&) {}
02145   forceinline void*
02146   CopiedHandle::Object::operator new(size_t s, Space& home) {
02147     return home.ralloc(s);
02148   }
02149 
02150   /*
02151    * Copied objects and handles
02152    *
02153    */
02154   forceinline
02155   CopiedHandle::Object::Object(void)
02156     : fwd(NULL) {}
02157   forceinline
02158   CopiedHandle::Object::~Object(void) {}
02159 
02160   forceinline
02161   CopiedHandle::CopiedHandle(void) : o(NULL) {}
02162   forceinline
02163   CopiedHandle::CopiedHandle(CopiedHandle::Object* so) : o(so) {}
02164   forceinline
02165   CopiedHandle::CopiedHandle(const CopiedHandle& sh) : o(sh.o) {}
02166   forceinline CopiedHandle&
02167   CopiedHandle::operator =(const CopiedHandle& sh) {
02168     o = sh.o;
02169     return *this;
02170   }
02171   forceinline void
02172   CopiedHandle::update(Space& home, bool, CopiedHandle& sh) {
02173     if (sh.o == NULL) {
02174       o = NULL;
02175     } else if (sh.o->fwd != NULL) {
02176       o = sh.o->fwd;
02177     } else {
02178       o = sh.o->copy();
02179       sh.o->fwd = o;
02180       sh.o->next = home.pc.c.copied;
02181       home.pc.c.copied = sh.o;
02182     }
02183   }
02184   forceinline void
02185   CopiedHandle::dispose(Space&) {
02186     (*o).~Object();
02187   }
02188   forceinline CopiedHandle::Object*
02189   CopiedHandle::object(void) const {
02190     return o;
02191   }
02192   forceinline void
02193   CopiedHandle::object(CopiedHandle::Object* n) {
02194     o=n;
02195   }
02196 
02197   /*
02198    * Shared objects and handles
02199    *
02200    */
02201   forceinline
02202   SharedHandle::Object::Object(void)
02203     : use_cnt(0) {}
02204   forceinline
02205   SharedHandle::Object::~Object(void) {
02206     assert(use_cnt == 0);
02207   }
02208 
02209   forceinline SharedHandle::Object*
02210   SharedHandle::object(void) const {
02211     return static_cast<SharedHandle::Object*>(CopiedHandle::object());
02212   }
02213   forceinline void
02214   SharedHandle::subscribe(void) {
02215     if (object() != NULL) object()->use_cnt++;
02216   }
02217   forceinline void
02218   SharedHandle::cancel(void) {
02219     if ((object() != NULL) && (--object()->use_cnt == 0))
02220       delete object();
02221     CopiedHandle::object(NULL);
02222   }
02223   forceinline void
02224   SharedHandle::object(SharedHandle::Object* n) {
02225     if (n != object()) {
02226       cancel(); CopiedHandle::object(n); subscribe();
02227     }
02228   }
02229   forceinline
02230   SharedHandle::SharedHandle(void) {}
02231   forceinline
02232   SharedHandle::SharedHandle(SharedHandle::Object* so) : CopiedHandle(so) {
02233     subscribe();
02234   }
02235   forceinline
02236   SharedHandle::SharedHandle(const SharedHandle& sh) : CopiedHandle(sh) {
02237     subscribe();
02238   }
02239   forceinline SharedHandle&
02240   SharedHandle::operator =(const SharedHandle& sh) {
02241     if (&sh != this) {
02242       cancel(); CopiedHandle::object(sh.object()); subscribe();
02243     }
02244     return *this;
02245   }
02246   forceinline void
02247   SharedHandle::update(Space& home, bool share, SharedHandle& sh) {
02248     if (sh.object() == NULL) {
02249       CopiedHandle::object(NULL);
02250     } else if (share) {
02251       CopiedHandle::object(sh.object()); subscribe();
02252     } else {
02253       CopiedHandle::update(home, share, sh);
02254       subscribe();
02255     }
02256   }
02257   forceinline
02258   SharedHandle::~SharedHandle(void) {
02259     cancel();
02260   }
02261 
02262 
02263 
02264   /*
02265    * ActorLink
02266    *
02267    */
02268   forceinline ActorLink*
02269   ActorLink::prev(void) const {
02270     return _prev;
02271   }
02272 
02273   forceinline ActorLink*
02274   ActorLink::next(void) const {
02275     return _next;
02276   }
02277 
02278   forceinline ActorLink**
02279   ActorLink::next_ref(void) {
02280     return &_next;
02281   }
02282 
02283   forceinline void
02284   ActorLink::prev(ActorLink* al) {
02285     _prev = al;
02286   }
02287 
02288   forceinline void
02289   ActorLink::next(ActorLink* al) {
02290     _next = al;
02291   }
02292 
02293   forceinline void
02294   ActorLink::unlink(void) {
02295     ActorLink* p = _prev; ActorLink* n = _next;
02296     p->_next = n; n->_prev = p;
02297   }
02298 
02299   forceinline void
02300   ActorLink::init(void) {
02301     _next = this; _prev =this;
02302   }
02303 
02304   forceinline void
02305   ActorLink::head(ActorLink* a) {
02306     // Inserts al at head of link-chain (that is, after this)
02307     ActorLink* n = _next;
02308     this->_next = a; a->_prev = this;
02309     a->_next = n; n->_prev = a;
02310   }
02311 
02312   forceinline void
02313   ActorLink::tail(ActorLink* a) {
02314     // Inserts al at tail of link-chain (that is, before this)
02315     ActorLink* p = _prev;
02316     a->_next = this; this->_prev = a;
02317     p->_next = a; a->_prev = p;
02318   }
02319 
02320   forceinline bool
02321   ActorLink::empty(void) const {
02322     return _next == this;
02323   }
02324 
02325   template<class T>
02326   forceinline ActorLink*
02327   ActorLink::cast(T* a) {
02328     // Turning al into a reference is for gcc, assume is for MSVC
02329     GECODE_NOT_NULL(a);
02330     ActorLink& t = *a;
02331     return static_cast<ActorLink*>(&t);
02332   }
02333 
02334   template<class T>
02335   forceinline const ActorLink*
02336   ActorLink::cast(const T* a) {
02337     // Turning al into a reference is for gcc, assume is for MSVC
02338     GECODE_NOT_NULL(a);
02339     const ActorLink& t = *a;
02340     return static_cast<const ActorLink*>(&t);
02341   }
02342 
02343 
02344   /*
02345    * Actor
02346    *
02347    */
02348   forceinline Actor*
02349   Actor::cast(ActorLink* al) {
02350     // Turning al into a reference is for gcc, assume is for MSVC
02351     GECODE_NOT_NULL(al);
02352     ActorLink& t = *al;
02353     return static_cast<Actor*>(&t);
02354   }
02355 
02356   forceinline const Actor*
02357   Actor::cast(const ActorLink* al) {
02358     // Turning al into a reference is for gcc, assume is for MSVC
02359     GECODE_NOT_NULL(al);
02360     const ActorLink& t = *al;
02361     return static_cast<const Actor*>(&t);
02362   }
02363 
02364   forceinline void
02365   Space::notice(Actor& a, ActorProperty p) {
02366     if (p & AP_DISPOSE) {
02367       if (d_cur == d_lst)
02368         d_resize();
02369       *(d_cur++) = &a;
02370     }
02371     if (p & AP_WEAKLY) {
02372       if (n_wmp == 0)
02373         n_wmp = 2;
02374       else
02375         n_wmp++;
02376     }
02377   }
02378 
02379   forceinline void
02380   Space::ignore(Actor& a, ActorProperty p) {
02381     if (p & AP_DISPOSE) {
02382       // Check wether array has already been discarded as space
02383       // deletion is already in progress
02384       Actor** f = d_fst;
02385       if (f != NULL) {
02386         while (&a != *f)
02387           f++;
02388         *f = *(--d_cur);
02389       }
02390     }
02391     if (p & AP_WEAKLY) {
02392       assert(n_wmp > 1);
02393       n_wmp--;
02394     }
02395   }
02396 
02397   forceinline Space*
02398   Space::clone(bool share, CloneStatistics&) const {
02399     // Clone is only const for search engines. During cloning, several data
02400     // structures are updated (e.g. forwarding pointers), so we have to
02401     // cast away the constness.
02402     return const_cast<Space*>(this)->_clone(share);
02403   }
02404 
02405   forceinline void
02406   Space::commit(const BranchingDesc& d, unsigned int a,
02407                 CommitStatistics&) {
02408     _commit(d,a);
02409   }
02410 
02411   forceinline size_t
02412   Actor::dispose(Space&) {
02413     return sizeof(*this);
02414   }
02415 
02416 
02417   /*
02418    * Propagator
02419    *
02420    */
02421   forceinline Propagator*
02422   Propagator::cast(ActorLink* al) {
02423     // Turning al into a reference is for gcc, assume is for MSVC
02424     GECODE_NOT_NULL(al);
02425     ActorLink& t = *al;
02426     return static_cast<Propagator*>(&t);
02427   }
02428 
02429   forceinline const Propagator*
02430   Propagator::cast(const ActorLink* al) {
02431     // Turning al into a reference is for gcc, assume is for MSVC
02432     GECODE_NOT_NULL(al);
02433     const ActorLink& t = *al;
02434     return static_cast<const Propagator*>(&t);
02435   }
02436 
02437   forceinline
02438   Propagator::Propagator(Space& home) {
02439     u.advisors = NULL;
02440     assert(u.med == 0 && u.size == 0);
02441     home.pl.head(this);
02442   }
02443 
02444   forceinline
02445   Propagator::Propagator(Space&, bool, Propagator& p) {
02446     u.advisors = NULL;
02447     assert(u.med == 0 && u.size == 0);
02448     // Set forwarding pointer
02449     p.prev(this);
02450   }
02451 
02452   forceinline ExecStatus
02453   ES_SUBSUMED(Propagator& p, size_t s) {
02454     p.u.size = s;
02455     return __ES_SUBSUMED;
02456   }
02457 
02458   forceinline ExecStatus
02459   ES_SUBSUMED(Propagator& p, Space& home) {
02460     p.u.size = p.dispose(home);
02461     return __ES_SUBSUMED;
02462   }
02463 
02464   forceinline ExecStatus
02465   ES_FIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02466     p.u.med = med;
02467     assert(p.u.med != 0);
02468     return __ES_PARTIAL;
02469   }
02470 
02471   forceinline ExecStatus
02472   ES_NOFIX_PARTIAL(Propagator& p, const ModEventDelta& med) {
02473     p.u.med = AllVarConf::med_combine(p.u.med,med);
02474     assert(p.u.med != 0);
02475     return __ES_PARTIAL;
02476   }
02477 
02478 
02479 
02480   /*
02481    * Branching
02482    *
02483    */
02484   forceinline Branching*
02485   Branching::cast(ActorLink* al) {
02486     // Turning al into a reference is for gcc, assume is for MSVC
02487     GECODE_NOT_NULL(al);
02488     ActorLink& t = *al;
02489     return static_cast<Branching*>(&t);
02490   }
02491 
02492   forceinline const Branching*
02493   Branching::cast(const ActorLink* al) {
02494     // Turning al into a reference is for gcc, assume is for MSVC
02495     GECODE_NOT_NULL(al);
02496     const ActorLink& t = *al;
02497     return static_cast<const Branching*>(&t);
02498   }
02499 
02500   forceinline
02501   Branching::Branching(Space& home) :
02502     _id(home.pc.p.branch_id++) {
02503     if (home.pc.p.branch_id == 0U)
02504       throw TooManyBranchings("Branching::Branching");
02505     // If no branching available, make it the first one
02506     if (home.b_status == &home.bl) {
02507       home.b_status = this;
02508       if (home.b_commit == &home.bl)
02509         home.b_commit = this;
02510     }
02511     home.bl.tail(this);
02512   }
02513 
02514   forceinline
02515   Branching::Branching(Space&, bool, Branching& b)
02516     : _id(b._id) {
02517     // Set forwarding pointer
02518     b.prev(this);
02519   }
02520 
02521   forceinline unsigned int
02522   Branching::id(void) const {
02523     return _id;
02524   }
02525 
02526 
02527 
02528   /*
02529    * Branching description
02530    *
02531    */
02532   forceinline
02533   BranchingDesc::BranchingDesc(const Branching& b, const unsigned int a)
02534     : _id(b.id()), _alt(a) {}
02535 
02536   forceinline unsigned int
02537   BranchingDesc::alternatives(void) const {
02538     return _alt;
02539   }
02540 
02541   forceinline unsigned int
02542   BranchingDesc::id(void) const {
02543     return _id;
02544   }
02545 
02546   forceinline
02547   BranchingDesc::~BranchingDesc(void) {}
02548 
02549 
02550 
02551   /*
02552    * Delta information for advisors
02553    *
02554    */
02555   forceinline ModEvent
02556   Delta::modevent(void) const {
02557     return me;
02558   }
02559 
02560 
02561 
02562   /*
02563    * Advisor
02564    *
02565    */
02566   template<class A>
02567   forceinline
02568   Advisor::Advisor(Space&, Propagator& p, Council<A>& c) {
02569     // Store propagator and forwarding in prev()
02570     ActorLink::prev(&p);
02571     // Link to next advisor in next()
02572     ActorLink::next(c.advisors); c.advisors = static_cast<A*>(this);
02573   }
02574 
02575   forceinline
02576   Advisor::Advisor(Space&, bool, Advisor&) {}
02577 
02578   forceinline bool
02579   Advisor::disposed(void) const {
02580     return prev() == NULL;
02581   }
02582 
02583   forceinline Advisor*
02584   Advisor::cast(ActorLink* al) {
02585     return static_cast<Advisor*>(al);
02586   }
02587 
02588   forceinline const Advisor*
02589   Advisor::cast(const ActorLink* al) {
02590     return static_cast<const Advisor*>(al);
02591   }
02592 
02593   forceinline Propagator&
02594   Advisor::propagator(void) const {
02595     assert(!disposed());
02596     return *Propagator::cast(ActorLink::prev());
02597   }
02598 
02599   template<class A>
02600   forceinline void
02601   Advisor::dispose(Space&,Council<A>&) {
02602     assert(!disposed());
02603     ActorLink::prev(NULL);
02604     // Shorten chains of disposed advisors by one, if possible
02605     Advisor* n = Advisor::cast(next());
02606     if ((n != NULL) && n->disposed())
02607       next(n->next());
02608   }
02609 
02610   template<class A>
02611   forceinline ExecStatus
02612   ES_SUBSUMED_FIX(A& a, Space& home, Council<A>& c) {
02613     a.dispose(home,c);
02614     return ES_FIX;
02615   }
02616 
02617   template<class A>
02618   forceinline ExecStatus
02619   ES_SUBSUMED_NOFIX(A& a, Space& home, Council<A>& c) {
02620     a.dispose(home,c);
02621     return ES_NOFIX;
02622   }
02623 
02624 
02625 
02626   /*
02627    * Advisor council
02628    *
02629    */
02630   template<class A>
02631   forceinline
02632   Council<A>::Council(void) {}
02633 
02634   template<class A>
02635   forceinline
02636   Council<A>::Council(Space&)
02637     : advisors(NULL) {}
02638 
02639   template<class A>
02640   forceinline bool
02641   Council<A>::empty(void) const {
02642     ActorLink* a = advisors;
02643     while ((a != NULL) && static_cast<A*>(a)->disposed())
02644       a = a->next();
02645     advisors = a;
02646     return a == NULL;
02647   }
02648 
02649   template<class A>
02650   forceinline void
02651   Council<A>::update(Space& home, bool share, Council<A>& c) {
02652     // Skip all disposed advisors
02653     {
02654       ActorLink* a = c.advisors;
02655       while ((a != NULL) && static_cast<A*>(a)->disposed())
02656         a = a->next();
02657       c.advisors = a;
02658     }
02659     // Are there any advisors to be cloned?
02660     if (c.advisors != NULL) {
02661       // The propagator in from-space
02662       Propagator* p_f = &static_cast<A*>(c.advisors)->propagator();
02663       // The propagator in to-space
02664       Propagator* p_t = Propagator::cast(p_f->prev());
02665       // Advisors in from-space
02666       ActorLink** a_f = &c.advisors;
02667       // Advisors in to-space
02668       A* a_t = NULL;
02669       while (*a_f != NULL) {
02670         if (static_cast<A*>(*a_f)->disposed()) {
02671           *a_f = (*a_f)->next();
02672         } else {
02673           // Run specific copying part
02674           A* a = new (home) A(home,share,*static_cast<A*>(*a_f));
02675           // Set propagator pointer
02676           a->prev(p_t);
02677           // Set forwarding pointer
02678           (*a_f)->prev(a);
02679           // Link
02680           a->next(a_t);
02681           a_t = a;
02682           a_f = (*a_f)->next_ref();
02683         }
02684       }
02685       advisors = a_t;
02686       // Enter advisor link for reset
02687       assert(p_f->u.advisors == NULL);
02688       p_f->u.advisors = c.advisors;
02689     } else {
02690       advisors = NULL;
02691     }
02692   }
02693 
02694   template<class A>
02695   forceinline void
02696   Council<A>::dispose(Space& home) {
02697     ActorLink* a = advisors;
02698     while (a != NULL) {
02699       if (!static_cast<A*>(a)->disposed())
02700         static_cast<A*>(a)->dispose(home,*this);
02701       a = a->next();
02702     }
02703   }
02704 
02705 
02706 
02707   /*
02708    * Advisor iterator
02709    *
02710    */
02711   template<class A>
02712   forceinline
02713   Advisors<A>::Advisors(const Council<A>& c)
02714     : a(c.advisors) {
02715     while ((a != NULL) && static_cast<A*>(a)->disposed())
02716       a = a->next();
02717   }
02718 
02719   template<class A>
02720   forceinline bool
02721   Advisors<A>::operator ()(void) const {
02722     return a != NULL;
02723   }
02724 
02725   template<class A>
02726   forceinline void
02727   Advisors<A>::operator ++(void) {
02728     do {
02729       a = a->next();
02730     } while ((a != NULL) && static_cast<A*>(a)->disposed());
02731   }
02732 
02733   template<class A>
02734   forceinline A&
02735   Advisors<A>::advisor(void) const {
02736     return *static_cast<A*>(a);
02737   }
02738 
02739 
02740 
02741   /*
02742    * Space
02743    *
02744    */
02745   forceinline void
02746   Space::enqueue(Propagator* p) {
02747     ActorLink::cast(p)->unlink();
02748     ActorLink* c = &pc.p.queue[p->cost(*this,p->u.med).ac];
02749     c->tail(ActorLink::cast(p));
02750     if (c > pc.p.active)
02751       pc.p.active = c;
02752   }
02753 
02754   forceinline void
02755   Space::fail(void) {
02756     pc.p.active = NULL;
02757   }
02758 
02759   forceinline bool
02760   Space::failed(void) const {
02761     return pc.p.active == NULL;
02762   }
02763 
02764   forceinline bool
02765   Space::stable(void) const {
02766     return pc.p.active < &pc.p.queue[0];
02767   }
02768 
02769 
02770 
02771   /*
02772    * Variable implementation
02773    *
02774    */
02775   template<class VIC>
02776   forceinline ActorLink**
02777   VarImp<VIC>::actor(PropCond pc) {
02778     assert((pc >= 0)  && (pc < pc_max+2));
02779     return (pc == 0) ? base : base+u.idx[pc-1];
02780   }
02781 
02782   template<class VIC>
02783   forceinline ActorLink**
02784   VarImp<VIC>::actorNonZero(PropCond pc) {
02785     assert((pc > 0)  && (pc < pc_max+2));
02786     return base+u.idx[pc-1];
02787   }
02788 
02789   template<class VIC>
02790   forceinline unsigned int&
02791   VarImp<VIC>::idx(PropCond pc) {
02792     assert((pc > 0)  && (pc < pc_max+2));
02793     return u.idx[pc-1];
02794   }
02795 
02796   template<class VIC>
02797   forceinline unsigned int
02798   VarImp<VIC>::idx(PropCond pc) const {
02799     assert((pc > 0)  && (pc < pc_max+2));
02800     return u.idx[pc-1];
02801   }
02802 
02803   template<class VIC>
02804   forceinline
02805   VarImp<VIC>::VarImp(Space&) {
02806     base = NULL; entries = 0;
02807     for (PropCond pc=1; pc<pc_max+2; pc++)
02808       idx(pc) = 0;
02809     free_and_bits = 0;
02810   }
02811 
02812   template<class VIC>
02813   forceinline
02814   VarImp<VIC>::VarImp(void) {
02815     base = NULL; entries = 0;
02816     for (PropCond pc=1; pc<pc_max+2; pc++)
02817       idx(pc) = 0;
02818     free_and_bits = 0;
02819   }
02820 
02821   template<class VIC>
02822   forceinline unsigned int
02823   VarImp<VIC>::degree(void) const {
02824     assert(!copied());
02825     return entries;
02826   }
02827 
02828   template<class VIC>
02829   forceinline unsigned int
02830   VarImp<VIC>::bits(void) const {
02831     return free_and_bits;
02832   }
02833 
02834   template<class VIC>
02835   forceinline unsigned int&
02836   VarImp<VIC>::bits(void) {
02837     return free_and_bits;
02838   }
02839 
02840 #ifdef GECODE_HAS_VAR_DISPOSE
02841   template<class VIC>
02842   forceinline VarImp<VIC>*
02843   VarImp<VIC>::vars_d(Space& home) {
02844     return static_cast<VarImp<VIC>*>(home.vars_d<VIC>());
02845   }
02846 
02847   template<class VIC>
02848   forceinline void
02849   VarImp<VIC>::vars_d(Space& home, VarImp<VIC>* x) {
02850     home.vars_d<VIC>(x);
02851   }
02852 #endif
02853 
02854   template<class VIC>
02855   forceinline bool
02856   VarImp<VIC>::copied(void) const {
02857     return Support::marked(base);
02858   }
02859 
02860   template<class VIC>
02861   forceinline VarImp<VIC>*
02862   VarImp<VIC>::forward(void) const {
02863     assert(copied());
02864     return reinterpret_cast<VarImp<VIC>*>(Support::unmark(base));
02865   }
02866 
02867   template<class VIC>
02868   forceinline VarImp<VIC>*
02869   VarImp<VIC>::next(void) const {
02870     assert(copied());
02871     return u.next;
02872   }
02873 
02874   template<class VIC>
02875   forceinline
02876   VarImp<VIC>::VarImp(Space& home, bool, VarImp<VIC>& x) {
02877     VarImpBase** reg;
02878     free_and_bits = x.free_and_bits & ((1 << free_bits) - 1);
02879     if (x.base == NULL) {
02880       // Variable implementation needs no index structure
02881       reg = &home.pc.c.vars_noidx;
02882       assert(x.degree() == 0);
02883     } else {
02884       reg = &home.pc.c.vars_u[idx_c];
02885     }
02886     // Save subscriptions in copy
02887     base = x.base;
02888     entries = x.entries;
02889     for (PropCond pc=1; pc<pc_max+2; pc++)
02890       idx(pc) = x.idx(pc);
02891 
02892     // Set forwarding pointer
02893     x.base = reinterpret_cast<ActorLink**>(Support::mark(this));
02894     // Register original
02895     x.u.next = static_cast<VarImp<VIC>*>(*reg); *reg = &x;
02896   }
02897 
02898   template<class VIC>
02899   forceinline ModEvent
02900   VarImp<VIC>::me(const ModEventDelta& med) {
02901     return static_cast<ModEvent>((med & VIC::med_mask) >> VIC::med_fst);
02902   }
02903 
02904   template<class VIC>
02905   forceinline ModEventDelta
02906   VarImp<VIC>::med(ModEvent me) {
02907     return static_cast<ModEventDelta>(me << VIC::med_fst);
02908   }
02909 
02910   template<class VIC>
02911   forceinline ModEvent
02912   VarImp<VIC>::me_combine(ModEvent me1, ModEvent me2) {
02913     return VIC::me_combine(me1,me2);
02914   }
02915 
02916   template<class VIC>
02917   forceinline void
02918   VarImp<VIC>::schedule(Space& home, Propagator& p, ModEvent me) {
02919     if (VIC::med_update(p.u.med,me))
02920       home.enqueue(&p);
02921   }
02922 
02923   template<class VIC>
02924   forceinline void
02925   VarImp<VIC>::schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me) {
02926     ActorLink** b = actor(pc1);
02927     ActorLink** p = actorNonZero(pc2+1);
02928     while (p-- > b)
02929       schedule(home,*Propagator::cast(*p),me);
02930   }
02931 
02932   template<class VIC>
02933   forceinline void
02934   VarImp<VIC>::enter(Space& home, Propagator* p, PropCond pc) {
02935     assert(pc <= pc_max);
02936     // Count one new subscription
02937     home.pc.p.n_sub += 1;
02938     if ((free_and_bits >> free_bits) == 0)
02939       resize(home);
02940     free_and_bits -= 1 << free_bits;
02941 
02942     // Enter subscription
02943     base[entries] = *actorNonZero(pc_max+1);
02944     entries++;
02945     for (PropCond j = pc_max; j > pc; j--) {
02946       *actorNonZero(j+1) = *actorNonZero(j);
02947       idx(j+1)++;
02948     }
02949     *actorNonZero(pc+1) = *actor(pc);
02950     idx(pc+1)++;
02951     *actor(pc) = ActorLink::cast(p);
02952 
02953 #ifdef GECODE_AUDIT
02954     ActorLink** f = actor(pc);
02955     while (f < (pc == pc_max+1 ? base+entries : actorNonZero(pc+1)))
02956       if (*f == p)
02957         goto found;
02958       else
02959         f++;
02960     GECODE_NEVER;
02961     found: ;
02962 #endif
02963   }
02964 
02965   template<class VIC>
02966   forceinline void
02967   VarImp<VIC>::enter(Space& home, Advisor* a) {
02968     // Count one new subscription
02969     home.pc.p.n_sub += 1;
02970     if ((free_and_bits >> free_bits) == 0)
02971       resize(home);
02972     free_and_bits -= 1 << free_bits;
02973 
02974     // Enter subscription
02975     base[entries++] = *actorNonZero(pc_max+1);
02976     *actorNonZero(pc_max+1) = a;
02977   }
02978 
02979   template<class VIC>
02980   void
02981   VarImp<VIC>::resize(Space& home) {
02982     if (base == NULL) {
02983       assert((free_and_bits >> free_bits) == 0);
02984       // Create fresh dependency array with four entries
02985       free_and_bits += 4 << free_bits;
02986       base = home.alloc<ActorLink*>(4);
02987       for (int i=0; i<pc_max+1; i++)
02988         u.idx[i] = 0;
02989     } else {
02990       // Resize dependency array
02991       unsigned int n = degree();
02992       // Find out whether the area is most likely in the special area
02993       // reserved for subscriptions. If yes, just resize mildly otherwise
02994       // more agressively
02995       ActorLink** s = static_cast<ActorLink**>(home.mm.subscriptions());
02996       unsigned int m =
02997         ((s <= base) && (base < s+home.pc.p.n_sub)) ?
02998         (n+4) : ((n+1)*3>>1);
02999       ActorLink** prop = home.alloc<ActorLink*>(m);
03000       free_and_bits += (m-n) << free_bits;
03001       // Copy entries
03002       Heap::copy<ActorLink*>(prop, base, n);
03003       home.free<ActorLink*>(base,n);
03004       base = prop;
03005     }
03006   }
03007 
03008   template<class VIC>
03009   void
03010   VarImp<VIC>::subscribe(Space& home, Propagator& p, PropCond pc,
03011                          bool assigned, ModEvent me, bool schedule) {
03012     if (assigned) {
03013       // Do not subscribe, just schedule the propagator
03014       if (schedule)
03015         VarImp<VIC>::schedule(home,p,ME_GEN_ASSIGNED);
03016     } else {
03017       enter(home,&p,pc);
03018       // Schedule propagator
03019       if (schedule && (pc != PC_GEN_ASSIGNED))
03020         VarImp<VIC>::schedule(home,p,me);
03021     }
03022   }
03023 
03024   template<class VIC>
03025   forceinline void
03026   VarImp<VIC>::subscribe(Space& home, Advisor& a, bool assigned) {
03027     if (!assigned)
03028       enter(home,&a);
03029   }
03030 
03031   template<class VIC>
03032   forceinline void
03033   VarImp<VIC>::remove(Space& home, Propagator* p, PropCond pc) {
03034     assert(pc <= pc_max);
03035     ActorLink* a = ActorLink::cast(p);
03036     // Find actor in dependency array
03037     ActorLink** f = actor(pc);
03038 #ifdef GECODE_AUDIT
03039     while (f < actorNonZero(pc+1))
03040       if (*f == a)
03041         goto found;
03042       else
03043         f++;
03044     GECODE_NEVER;
03045   found: ;
03046 #else
03047     while (*f != a) f++;
03048 #endif
03049     // Remove actor
03050     *f = *(actorNonZero(pc+1)-1);
03051     for (PropCond j = pc+1; j< pc_max+1; j++) {
03052       *(actorNonZero(j)-1) = *(actorNonZero(j+1)-1);
03053       idx(j)--;
03054     }
03055     *(actorNonZero(pc_max+1)-1) = base[entries-1];
03056     idx(pc_max+1)--;
03057     entries--;
03058     free_and_bits += 1 << free_bits;
03059     home.pc.p.n_sub -= 1;
03060   }
03061 
03062   template<class VIC>
03063   forceinline void
03064   VarImp<VIC>::remove(Space& home, Advisor* a) {
03065     // Find actor in dependency array
03066     ActorLink** f = actorNonZero(pc_max+1);
03067 #ifdef GECODE_AUDIT
03068     while (f < base+entries)
03069       if (*f == a)
03070         goto found;
03071       else
03072         f++;
03073     GECODE_NEVER;
03074   found: ;
03075 #else
03076     while (*f != a) f++;
03077 #endif
03078     // Remove actor
03079     *f = base[--entries];
03080     free_and_bits += 1 << free_bits;
03081     home.pc.p.n_sub -= 1;
03082   }
03083 
03084   template<class VIC>
03085   forceinline void
03086   VarImp<VIC>::cancel(Space& home, Propagator& p, PropCond pc, bool assigned) {
03087     if (!assigned)
03088       remove(home,&p,pc);
03089   }
03090 
03091   template<class VIC>
03092   forceinline void
03093   VarImp<VIC>::cancel(Space& home, Advisor& a, bool assigned) {
03094     if (!assigned)
03095       remove(home,&a);
03096   }
03097 
03098   template<class VIC>
03099   forceinline void
03100   VarImp<VIC>::cancel(Space& home) {
03101     // Entries in index structure are disabled. However they
03102     // must still work for cloning (base) and degree (idx(pc_max+2))
03103     unsigned int n_sub = degree();
03104     home.pc.p.n_sub -= n_sub;
03105     unsigned int n = (free_and_bits >> VIC::free_bits) + n_sub;
03106     home.free<ActorLink*>(base,n);
03107     base = NULL;
03108     entries = 0;
03109   }
03110 
03111   template<class VIC>
03112   forceinline bool
03113   VarImp<VIC>::advise(Space& home, ModEvent me, Delta& d) {
03114     /*
03115      * An advisor that is executed might remove itself due to subsumption.
03116      * As entries are removed from front to back, the advisors must
03117      * be iterated in forward direction.
03118      */
03119     ActorLink** la = actorNonZero(pc_max+1);
03120     ActorLink** le = base+entries;
03121     if (la == le)
03122       return true;
03123     d.me = me;
03124     // An advisor that is run, might be removed during execution.
03125     // As removal is done from the back the advisors have to be executed
03126     // in inverse order.
03127     do {
03128       Advisor* a = Advisor::cast(*la);
03129       assert(!a->disposed());
03130       Propagator& p = a->propagator();
03131       switch (p.advise(home,*a,d)) {
03132       case ES_FIX:
03133         break;
03134       case ES_FAILED:
03135         return false;
03136       case ES_NOFIX:
03137         schedule(home,p,me);
03138         break;
03139       default:
03140         GECODE_NEVER;
03141       }
03142     } while (++la < le);
03143     return true;
03144   }
03145 
03146   template<class VIC>
03147   forceinline void
03148   VarImp<VIC>::update(VarImp<VIC>* x, ActorLink**& sub) {
03149     // this refers to the variable to be updated (clone)
03150     // x refers to the original
03151     // Recover from copy
03152     x->base = base;
03153     x->u.idx[0] = u.idx[0];
03154     if (pc_max > 0 && sizeof(ActorLink**) > sizeof(unsigned int))
03155       x->u.idx[1] = u.idx[1];
03156 
03157     ActorLink** f = x->base;
03158     unsigned int n = x->degree();
03159     ActorLink** t = sub;
03160     sub += n;
03161     base = t;
03162     // Set subscriptions using actor forwarding pointers
03163     while (n >= 4) {
03164       n -= 4;
03165       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03166       t[2]=f[2]->prev(); t[3]=f[3]->prev();
03167       t += 4; f += 4;
03168     }
03169     if (n >= 2) {
03170       n -= 2;
03171       t[0]=f[0]->prev(); t[1]=f[1]->prev();
03172       t += 2; f += 2;
03173     }
03174     if (n > 0) {
03175       t[0]=f[0]->prev();
03176     }
03177   }
03178 
03179   template<class VIC>
03180   forceinline void
03181   VarImp<VIC>::update(Space& home, ActorLink**& sub) {
03182     VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home.pc.c.vars_u[idx_c]);
03183     while (x != NULL) {
03184       VarImp<VIC>* n = x->next(); x->forward()->update(x,sub); x = n;
03185     }
03186   }
03187 
03188 
03189 
03190   /*
03191    * Variable disposer
03192    *
03193    */
03194   template<class VarType>
03195   VarDisposer<VarType>::VarDisposer(void) {
03196 #ifdef GECODE_HAS_VAR_DISPOSE
03197     Space::vd[VarType::idx_d] = this;
03198 #endif
03199   }
03200 
03201   template<class VarType>
03202   void
03203   VarDisposer<VarType>::dispose(Space& home, VarImpBase* _x) {
03204     VarType* x = static_cast<VarType*>(_x);
03205     do {
03206       x->dispose(home); x = static_cast<VarType*>(x->next_d());
03207     } while (x != NULL);
03208   }
03209 
03210   /*
03211    * Statistics
03212    */
03213 
03214   forceinline void
03215   StatusStatistics::reset(void) {
03216     propagate = 0;
03217     wmp = false;
03218   }
03219   forceinline
03220   StatusStatistics::StatusStatistics(void) {
03221     reset();
03222   }
03223   forceinline StatusStatistics&
03224   StatusStatistics::operator +=(const StatusStatistics& s) { 
03225     propagate += s.propagate;
03226     wmp |= s.wmp;
03227     return *this;
03228   }
03229   forceinline StatusStatistics
03230   StatusStatistics::operator +(const StatusStatistics& s) {
03231     StatusStatistics t(s);
03232     return t += *this;
03233   }
03234 
03235   forceinline void
03236   CloneStatistics::reset(void) {}
03237 
03238   forceinline
03239   CloneStatistics::CloneStatistics(void) {
03240     reset();
03241   }
03242   forceinline CloneStatistics
03243   CloneStatistics::operator +(const CloneStatistics&) {
03244     CloneStatistics s;
03245     return s;
03246   }
03247   forceinline CloneStatistics&
03248   CloneStatistics::operator +=(const CloneStatistics&) { 
03249     return *this;
03250   }
03251 
03252   forceinline void
03253   CommitStatistics::reset(void) {}
03254 
03255   forceinline
03256   CommitStatistics::CommitStatistics(void) {
03257     reset();
03258   }
03259   forceinline CommitStatistics
03260   CommitStatistics::operator +(const CommitStatistics&) {
03261     CommitStatistics s;
03262     return s;
03263   }
03264   forceinline CommitStatistics&
03265   CommitStatistics::operator +=(const CommitStatistics&) { 
03266     return *this;
03267   }
03268 
03269   /*
03270    * Cost computation
03271    *
03272    */
03273 
03274   forceinline
03275   PropCost::PropCost(PropCost::ActualCost ac0) : ac(ac0) {}
03276 
03277   forceinline PropCost
03278   PropCost::cost(PropCost::Mod m,
03279                  PropCost::ActualCost lo, PropCost::ActualCost hi,
03280                  unsigned int n) {
03281     if (n < 2)
03282       return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
03283     else if (n == 2)
03284       return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
03285     else if (n == 3)
03286       return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
03287     else
03288       return (m == LO) ? lo : hi;
03289   }
03290 
03291   forceinline PropCost
03292   PropCost::crazy(PropCost::Mod m, unsigned int n) {
03293     return cost(m,AC_CRAZY_LO,AC_CRAZY_HI,n);
03294   }
03295   forceinline PropCost
03296   PropCost::crazy(PropCost::Mod m, int n) {
03297     assert(n >= 0);
03298     return crazy(m,static_cast<unsigned int>(n));
03299   }
03300   forceinline PropCost
03301   PropCost::cubic(PropCost::Mod m, unsigned int n) {
03302     return cost(m,AC_CUBIC_LO,AC_CUBIC_HI,n);
03303   }
03304   forceinline PropCost
03305   PropCost::cubic(PropCost::Mod m, int n) {
03306     assert(n >= 0);
03307     return cubic(m,static_cast<unsigned int>(n));
03308   }
03309   forceinline PropCost
03310   PropCost::quadratic(PropCost::Mod m, unsigned int n) {
03311     return cost(m,AC_QUADRATIC_LO,AC_QUADRATIC_HI,n);
03312   }
03313   forceinline PropCost
03314   PropCost::quadratic(PropCost::Mod m, int n) {
03315     assert(n >= 0);
03316     return quadratic(m,static_cast<unsigned int>(n));
03317   }
03318   forceinline PropCost
03319   PropCost::linear(PropCost::Mod m, unsigned int n) {
03320     return cost(m,AC_LINEAR_LO,AC_LINEAR_HI,n);
03321   }
03322   forceinline PropCost
03323   PropCost::linear(PropCost::Mod m, int n) {
03324     assert(n >= 0);
03325     return linear(m,static_cast<unsigned int>(n));
03326   }
03327   forceinline PropCost
03328   PropCost::ternary(PropCost::Mod m) {
03329     return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
03330   }
03331   forceinline PropCost
03332   PropCost::binary(PropCost::Mod m) {
03333     return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
03334   }
03335   forceinline PropCost
03336   PropCost::unary(PropCost::Mod m) {
03337     return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
03338   }
03339 
03340   /*
03341    * Iterators for propagators and branchings of a space
03342    *
03343    */
03344   forceinline
03345   Space::Propagators::Propagators(const Space& home0) 
03346     : home(home0), q(home.pc.p.active) {
03347     while (q >= &home.pc.p.queue[0]) {
03348       if (q->next() != q) {
03349         c = q->next(); e = q; q--;
03350         return;
03351       }
03352       q--;
03353     }
03354     q = NULL;
03355     if (!home.pl.empty()) {
03356       c = Propagator::cast(home.pl.next());
03357       e = Propagator::cast(&home.pl);
03358     } else {
03359       c = e = NULL;
03360     }
03361   }
03362   forceinline bool 
03363   Space::Propagators::operator ()(void) const {
03364     return c != NULL;
03365   }
03366   forceinline void 
03367   Space::Propagators::operator ++(void) {
03368     c = c->next();
03369     if (c == e) {
03370       if (q == NULL) {
03371         c = NULL;
03372       } else {
03373         while (q >= &home.pc.p.queue[0]) {
03374           if (q->next() != q) {
03375             c = q->next(); e = q; q--;
03376             return;
03377           }
03378           q--;
03379         }
03380         q = NULL;
03381         if (!home.pl.empty()) {
03382           c = Propagator::cast(home.pl.next());
03383           e = Propagator::cast(&home.pl);
03384         } else {
03385           c = NULL;
03386         }
03387       }
03388     }
03389   }
03390   forceinline const Propagator& 
03391   Space::Propagators::propagator(void) const {
03392     return *Propagator::cast(c);
03393   }
03394 
03395   forceinline
03396   Space::Branchings::Branchings(const Space& home) 
03397     : c(Branching::cast(home.bl.next())), e(&home.bl) {}
03398   forceinline bool 
03399   Space::Branchings::operator ()(void) const {
03400     return c != e;
03401   }
03402   forceinline void 
03403   Space::Branchings::operator ++(void) {
03404     c = c->next();
03405   }
03406   forceinline const Branching& 
03407   Space::Branchings::branching(void) const {
03408     return *Branching::cast(c);
03409   }
03410 
03411   /*
03412    * Space construction support
03413    *
03414    */
03415   template<class T> 
03416   forceinline T& 
03417   Space::construct(void) {
03418     return alloc<T>(1);
03419   }
03420   template<class T, typename A1> 
03421   forceinline T& 
03422   Space::construct(A1 const& a1) {
03423     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03424     new (&t) T(a1);
03425     return t;
03426   }
03427   template<class T, typename A1, typename A2> 
03428   forceinline T& 
03429   Space::construct(A1 const& a1, A2 const& a2) {
03430     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03431     new (&t) T(a1,a2);
03432     return t;
03433   }
03434   template<class T, typename A1, typename A2, typename A3>
03435   forceinline T& 
03436   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
03437     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03438     new (&t) T(a1,a2,a3);
03439     return t;
03440   }
03441   template<class T, typename A1, typename A2, typename A3, typename A4>
03442   forceinline T& 
03443   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
03444     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03445     new (&t) T(a1,a2,a3,a4);
03446     return t;
03447   }
03448   template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
03449   forceinline T& 
03450   Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
03451     T& t = *static_cast<T*>(ralloc(sizeof(T)));
03452     new (&t) T(a1,a2,a3,a4,a5);
03453     return t;
03454   }
03455 
03456 }
03457 
03458 // STATISTICS: kernel-core