Generated on Thu Mar 22 10:39:43 2012 for Gecode by doxygen 1.6.3

wait.hh

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  *
00006  *  Copyright:
00007  *     Christian Schulte, 2009
00008  *
00009  *  Last modified:
00010  *     $Date: 2010-03-03 17:32:21 +0100 (Wed, 03 Mar 2010) $ by $Author: schulte $
00011  *     $Revision: 10364 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #ifndef __GECODE_KERNEL_WAIT_HH__
00039 #define __GECODE_KERNEL_WAIT_HH__
00040 
00041 #include <gecode/kernel.hh>
00042 
00043 namespace Gecode { namespace Kernel {
00044 
00051   template<class View>
00052   class UnaryWait : public Propagator {
00053   protected:
00055     View x;
00057     void (*c)(Space&);
00059     UnaryWait(Space& home, View x, void (*c0)(Space&));
00061     UnaryWait(Space& home, bool shared, UnaryWait& p);
00062   public:
00064     virtual Actor* copy(Space& home, bool share);
00066     virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00068     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00070     static ExecStatus post(Space& home, View x, void (*c)(Space&));
00072     virtual size_t dispose(Space& home);
00073   };
00074 
00081   template<class View>
00082   class NaryWait : public Propagator {
00083   protected:
00085     ViewArray<View> x;
00087     void (*c)(Space&);
00089     NaryWait(Space& home, ViewArray<View>& x, void (*c0)(Space&));
00091     NaryWait(Space& home, bool shared, NaryWait& p);
00092   public:
00094     virtual Actor* copy(Space& home, bool share);
00096     virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00098     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00100     static ExecStatus post(Space& home, ViewArray<View>& x, void (*c)(Space&));
00102     virtual size_t dispose(Space& home);
00103   };
00104 
00105 
00106   /*
00107    * Wait propagator for single view
00108    *
00109    */
00110   template<class View>
00111   forceinline
00112   UnaryWait<View>::UnaryWait(Space& home, View x0, void (*c0)(Space&))
00113     : Propagator(home), x(x0), c(c0) {
00114     x.subscribe(home,*this,PC_GEN_ASSIGNED);
00115   }
00116   template<class View>
00117   forceinline
00118   UnaryWait<View>::UnaryWait(Space& home, bool shared, UnaryWait& p) 
00119     : Propagator(home,shared,p), c(p.c) {
00120     x.update(home,shared,p.x);
00121   }
00122   template<class View>
00123   Actor* 
00124   UnaryWait<View>::copy(Space& home, bool share) {
00125     return new (home) UnaryWait<View>(home,share,*this);
00126   }
00127   template<class View>
00128   PropCost 
00129   UnaryWait<View>::cost(const Space&, const ModEventDelta&) const {
00130     return PropCost::unary(PropCost::LO);
00131   }
00132   template<class View>
00133   ExecStatus 
00134   UnaryWait<View>::propagate(Space& home, const ModEventDelta&) {
00135     assert(x.assigned());
00136     c(home);
00137     return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this);
00138   }
00139   template<class View>
00140   ExecStatus 
00141   UnaryWait<View>::post(Space& home, View x, void (*c)(Space&)) {
00142     if (x.assigned()) {
00143       c(home);
00144       return home.failed() ? ES_FAILED : ES_OK;
00145     } else {
00146       (void) new (home) UnaryWait<View>(home,x,c);
00147       return ES_OK;
00148     }
00149   }
00150   template<class View>
00151   size_t 
00152   UnaryWait<View>::dispose(Space& home) {
00153     x.cancel(home,*this,PC_GEN_ASSIGNED);
00154     (void) Propagator::dispose(home);
00155     return sizeof(*this);
00156   }
00157 
00158 
00159   /*
00160    * Wait propagator for several views
00161    *
00162    */
00163   template<class View>
00164   forceinline
00165   NaryWait<View>::NaryWait(Space& home, ViewArray<View>& x0, 
00166                            void (*c0)(Space&))
00167     : Propagator(home), x(x0), c(c0) {
00168     assert(!x[0].assigned());
00169     x[0].subscribe(home,*this,PC_GEN_ASSIGNED);
00170   }
00171   template<class View>
00172   forceinline
00173   NaryWait<View>::NaryWait(Space& home, bool shared, NaryWait& p) 
00174     : Propagator(home,shared,p), c(p.c) {
00175     x.update(home,shared,p.x);
00176   }
00177   template<class View>
00178   Actor* 
00179   NaryWait<View>::copy(Space& home, bool share) {
00180     assert(!x[0].assigned());
00181     for (int i=x.size()-1; i>0; i--)
00182       if (x[i].assigned())
00183         x.move_lst(i);
00184     assert(x.size() > 0);
00185     return new (home) NaryWait<View>(home,share,*this);
00186   }
00187   template<class View>
00188   PropCost 
00189   NaryWait<View>::cost(const Space&, const ModEventDelta&) const {
00190     return PropCost::unary(PropCost::HI);
00191   }
00192   template<class View>
00193   ExecStatus 
00194   NaryWait<View>::propagate(Space& home, const ModEventDelta& ) {
00195     assert(x[0].assigned());
00196     for (int i=x.size()-1; i>0; i--)
00197       if (x[i].assigned())
00198         x.move_lst(i);
00199     assert(x.size() > 0);
00200     if (x.size() == 1) {
00201       x.size(0);
00202       c(home);
00203       return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this);
00204     } else {
00205       // Create new subscription
00206       x.move_lst(0);
00207       assert(!x[0].assigned());
00208       x[0].subscribe(home,*this,PC_GEN_ASSIGNED,false);
00209       return ES_OK;
00210     }
00211   }
00212   template<class View>
00213   ExecStatus 
00214   NaryWait<View>::post(Space& home, ViewArray<View>& x, void (*c)(Space&)) {
00215     for (int i=x.size(); i--; )
00216       if (x[i].assigned())
00217         x.move_lst(i);
00218     if (x.size() == 0) {
00219       c(home);
00220       return home.failed() ? ES_FAILED : ES_OK;
00221     } else {
00222       x.unique(home);
00223       if (x.size() == 1) {
00224         return UnaryWait<View>::post(home,x[0],c);
00225       } else {
00226         (void) new (home) NaryWait<View>(home,x,c);
00227         return ES_OK;
00228       }
00229     }
00230   }
00231   template<class View>
00232   size_t 
00233   NaryWait<View>::dispose(Space& home) {
00234     if (x.size() > 0) 
00235       x[0].cancel(home,*this,PC_GEN_ASSIGNED);
00236     (void) Propagator::dispose(home);
00237     return sizeof(*this);
00238   }
00239 
00240 }}
00241 
00242 #endif
00243 
00244 // STATISTICS: kernel-prop