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

branching.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  *
00007  *  Copyright:
00008  *     Christian Schulte, 2004
00009  *     Guido Tack, 2004
00010  *
00011  *  Last modified:
00012  *     $Date: 2008-08-20 15:55:47 +0200 (Wed, 20 Aug 2008) $ by $Author: tack $
00013  *     $Revision: 7658 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 namespace Gecode {
00041 
00050 
00051   enum ViewSelStatus {
00052     VSS_NONE,   
00053     VSS_SELECT, 
00054     VSS_COMMIT  
00055   };
00056 
00083   template <class View, class Val, class ViewSel, class ValSel>
00084   class ViewValBranching : public Branching {
00085   protected:
00086     ViewArray<View> x;  
00087     mutable int start;  
00088 
00089     ViewValBranching(Space* home, bool share, ViewValBranching& b);
00090   public:
00092     ViewValBranching(Space* home, ViewArray<View>& x);
00094     virtual bool status(const Space* home) const;
00096     virtual const BranchingDesc* description(const Space* home) const;
00098     virtual ExecStatus commit(Space* home, const BranchingDesc* d,
00099                               unsigned int a);
00101     virtual Reflection::ActorSpec spec(const Space* home,
00102                                        Reflection::VarMap& m) const;
00104     virtual Reflection::BranchingSpec
00105     branchingSpec(const Space* home, 
00106                   Reflection::VarMap& m,
00107                   const BranchingDesc* d) const;
00109     static Support::Symbol ati(void);
00111     static void post(Space* home, Reflection::VarMap& m,
00112                      const Reflection::ActorSpec& spec);
00114     virtual Actor* copy(Space* home, bool share);
00115   };
00116 
00134   template <class View, class Val, class ValSel>
00135   class ViewValAssignment : public Branching {
00136   protected:
00137     ViewArray<View> x;  
00138     mutable int start;  
00139 
00140     ViewValAssignment(Space* home, bool share, ViewValAssignment& b);
00141   public:
00143     ViewValAssignment(Space* home, ViewArray<View>& x);
00145     virtual bool status(const Space* home) const;
00147     virtual const BranchingDesc* description(const Space* home) const;
00149     virtual ExecStatus commit(Space* home, const BranchingDesc* d,
00150                               unsigned int a);
00152     virtual Reflection::ActorSpec spec(const Space* home,
00153                                         Reflection::VarMap& m) const;
00155     virtual Reflection::BranchingSpec
00156     branchingSpec(const Space* home, 
00157                   Reflection::VarMap& m,
00158                   const BranchingDesc* d) const;
00160     static Support::Symbol ati(void);
00162     static void post(Space* home, Reflection::VarMap& m,
00163                      const Reflection::ActorSpec& spec);
00165     virtual Actor* copy(Space* home, bool share);
00166   };
00167 
00173   template <class Val, unsigned int alt>
00174   class PosValDesc : public BranchingDesc {
00175   protected:
00177     const int _pos;
00179     const Val _val;
00180   public:
00186     PosValDesc(const Branching* b, const int p, const Val& n);
00188     int pos(void) const;
00190     Val val(void) const;
00192     virtual size_t size(void) const;
00193   };
00194 
00196 
00197 
00198 
00199 
00200 
00201 
00202   /*
00203    * Branching descriptions with position and value
00204    *
00205    */
00206 
00207   template <class Val, unsigned int alt>
00208   forceinline
00209   PosValDesc<Val,alt>::PosValDesc(const Branching* b, const int p,
00210                                   const Val& n)
00211     : BranchingDesc(b,alt), _pos(p), _val(n) {}
00212 
00213   template <class Val, unsigned int alt>
00214   forceinline int
00215   PosValDesc<Val,alt>::pos(void) const {
00216     return _pos;
00217   }
00218 
00219   template <class Val, unsigned int alt>
00220   forceinline Val
00221   PosValDesc<Val,alt>::val(void) const {
00222     return _val;
00223   }
00224 
00225   template <class Val, unsigned int alt>
00226   size_t
00227   PosValDesc<Val,alt>::size(void) const {
00228     return sizeof(PosValDesc<Val,alt>);
00229   }
00230 
00231 
00232   /*
00233    * Generic branching based on variable/value selection
00234    *
00235    */
00236 
00237   template <class View, class Val, class ViewSel, class ValSel>
00238   forceinline
00239   ViewValBranching<View,Val,ViewSel,ValSel>
00240   ::ViewValBranching(Space* home, ViewArray<View>& x0)
00241     : Branching(home), x(x0), start(0) {}
00242 
00243 
00244   template <class View, class Val, class ViewSel, class ValSel>
00245   forceinline
00246   ViewValBranching<View,Val,ViewSel,ValSel>
00247   ::ViewValBranching(Space* home, bool share, ViewValBranching& b)
00248     : Branching(home,share,b), start(b.start) {
00249     x.update(home,share,b.x);
00250   }
00251 
00252   template <class View, class Val, class ViewSel, class ValSel>
00253   Actor*
00254   ViewValBranching<View,Val,ViewSel,ValSel>::copy(Space* home, bool share) {
00255     return new (home)
00256       ViewValBranching<View,Val,ViewSel,ValSel>(home,share,*this);
00257   }
00258 
00259   template <class View, class Val, class ViewSel, class ValSel>
00260   bool
00261   ViewValBranching<View,Val,ViewSel,ValSel>
00262   ::status(const Space*) const {
00263     for (int i=start; i < x.size(); i++)
00264       if (!x[i].assigned()) {
00265         start = i;
00266         return true;
00267       }
00268     return false;
00269   }
00270 
00271   template <class View, class Val, class ViewSel, class ValSel>
00272   const BranchingDesc*
00273   ViewValBranching<View,Val,ViewSel,ValSel>
00274   ::description(const Space* home) const {
00275     assert(!x[start].assigned());
00276     ViewSel vs; // For view selection
00277     ValSel  vl; // For value selection
00278     int i = start;
00279     int b = i++;
00280     if (vs.init(home,x[b]) != VSS_COMMIT)
00281       for (; i < x.size(); i++)
00282         if (!x[i].assigned())
00283           switch (vs.select(home,x[i])) {
00284           case VSS_SELECT: b=i; break;
00285           case VSS_COMMIT: b=i; goto create;
00286           case VSS_NONE:   break;
00287           default:         GECODE_NEVER;
00288           }
00289   create:
00290     return new PosValDesc<Val,2>(this,b,vl.val(home,x[b]));
00291   }
00292 
00293   template <class View, class Val, class ViewSel, class ValSel>
00294   ExecStatus
00295   ViewValBranching<View,Val,ViewSel,ValSel>
00296   ::commit(Space* home, const BranchingDesc* d, unsigned int a) {
00297     const PosValDesc<Val,2>* pvd = static_cast<const PosValDesc<Val,2>*>(d);
00298     ValSel vs;
00299     return me_failed(vs.tell(home,a,x[pvd->pos()],pvd->val()))
00300       ? ES_FAILED : ES_OK;
00301   }
00302 
00303   template <class View, class Val, class ViewSel, class ValSel>
00304   Support::Symbol
00305   ViewValBranching<View,Val,ViewSel,ValSel>::ati(void) {
00306     return Reflection::mangle<View,Val,ViewSel,ValSel>("Gecode::ViewValBranching");
00307   }
00308 
00309   template <class View, class Val, class ViewSel, class ValSel>
00310   void
00311   ViewValBranching<View,Val,ViewSel,ValSel>
00312     ::post(Space* home, Reflection::VarMap& vars,
00313            const Reflection::ActorSpec& spec) {
00314     spec.checkArity(1);
00315     ViewArray<View> x(home, vars, spec[0]);
00316     (void) new (home) ViewValBranching<View,Val,ViewSel,ValSel>(home, x);
00317   }
00318 
00319   template <class View, class Val, class ViewSel, class ValSel>
00320   Reflection::ActorSpec
00321   ViewValBranching<View,Val,ViewSel,ValSel>::spec(const Space* home,
00322     Reflection::VarMap& m) const {
00323     Reflection::ActorSpec s(ati());
00324     return s << x.spec(home, m);
00325   }
00326 
00327   template <class View, class Val, class ViewSel, class ValSel>
00328   Reflection::BranchingSpec
00329   ViewValBranching<View,Val,ViewSel,ValSel>::branchingSpec(const Space* home, 
00330     Reflection::VarMap& m, const BranchingDesc* d) const {
00331     Reflection::BranchingSpec bs(d);
00332     const PosValDesc<Val,2>* pvd = static_cast<const PosValDesc<Val,2>*>(d);
00333     ValSel vs;
00334     vs.branchingSpec(home, m, bs, 2, x[pvd->pos()], pvd->val());
00335     return bs;
00336   }
00337 
00338   /*
00339    * Generic assignment based on value selection
00340    *
00341    */
00342 
00343   template <class View, class Val, class ValSel>
00344   forceinline
00345   ViewValAssignment<View,Val,ValSel>
00346   ::ViewValAssignment(Space* home, ViewArray<View>& x0)
00347     : Branching(home), x(x0), start(0) {}
00348 
00349 
00350   template <class View, class Val, class ValSel>
00351   forceinline
00352   ViewValAssignment<View,Val,ValSel>
00353   ::ViewValAssignment(Space* home, bool share, ViewValAssignment& b)
00354     : Branching(home,share,b), start(b.start) {
00355     x.update(home,share,b.x);
00356   }
00357 
00358   template <class View, class Val, class ValSel>
00359   Actor*
00360   ViewValAssignment<View,Val,ValSel>::copy(Space* home, bool share) {
00361     return new (home)
00362       ViewValAssignment<View,Val,ValSel>(home,share,*this);
00363   }
00364 
00365   template <class View, class Val, class ValSel>
00366   bool
00367   ViewValAssignment<View,Val,ValSel>
00368   ::status(const Space*) const {
00369     for (int i=start; i < x.size(); i++)
00370       if (!x[i].assigned()) {
00371         start = i;
00372         return true;
00373       }
00374     return false;
00375   }
00376 
00377   template <class View, class Val, class ValSel>
00378   const BranchingDesc*
00379   ViewValAssignment<View,Val,ValSel>
00380   ::description(const Space* home) const {
00381     assert(!x[start].assigned());
00382     ValSel vl; // For value selection
00383     return new PosValDesc<Val,1>(this,start,vl.val(home,x[start]));
00384   }
00385 
00386   template <class View, class Val, class ValSel>
00387   ExecStatus
00388   ViewValAssignment<View,Val,ValSel>
00389   ::commit(Space* home, const BranchingDesc* d, unsigned int) {
00390     const PosValDesc<Val,1>* pvd = static_cast<const PosValDesc<Val,1>*>(d);
00391     ValSel vs;
00392     return me_failed(vs.tell(home,0,x[pvd->pos()],pvd->val()))
00393       ? ES_FAILED : ES_OK;
00394   }
00395 
00396   template <class View, class Val, class ValSel>
00397   Support::Symbol
00398   ViewValAssignment<View,Val,ValSel>::ati(void) {
00399     return Reflection::mangle<View,Val,ValSel>("Gecode::ViewValAssignment");
00400   }
00401 
00402   template <class View, class Val, class ValSel>
00403   void
00404   ViewValAssignment<View,Val,ValSel>
00405     ::post(Space* home, Reflection::VarMap& vars,
00406            const Reflection::ActorSpec& spec) {
00407     spec.checkArity(1);
00408     ViewArray<View> x(home, vars, spec[0]);
00409     (void) new (home) ViewValAssignment<View,Val,ValSel>(home, x);
00410   }
00411 
00412   template <class View, class Val, class ValSel>
00413   Reflection::ActorSpec
00414   ViewValAssignment<View,Val,ValSel>::spec(const Space* home,
00415     Reflection::VarMap& m) const {
00416     Reflection::ActorSpec s(ati());
00417     return s << x.spec(home, m);
00418   }
00419 
00420   template <class View, class Val, class ValSel>
00421   Reflection::BranchingSpec
00422   ViewValAssignment<View,Val,ValSel>::branchingSpec(const Space* home, 
00423     Reflection::VarMap& m, const BranchingDesc* d) const {
00424     Reflection::BranchingSpec bs(d);
00425     const PosValDesc<Val,1>* pvd = static_cast<const PosValDesc<Val,1>*>(d);
00426     ValSel vs;
00427     vs.branchingSpec(home, m, bs, 1, x[pvd->pos()], pvd->val());
00428     return bs;
00429   }
00430 
00431 }
00432 
00433 // STATISTICS: kernel-other