Generated on Thu Apr 11 13:59:16 2019 for Gecode by doxygen 1.6.3

wait.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  *
00006  *  Copyright:
00007  *     Christian Schulte, 2009
00008  *
00009  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00031  *
00032  */
00033 
00034 namespace Gecode {
00035 
00042   template<class View>
00043   class UnaryWait : public Propagator {
00044   protected:
00046     View x;
00048     SharedData<std::function<void(Space& home)>> c;
00050     UnaryWait(Home home, View x, std::function<void(Space& home)> c0);
00052     UnaryWait(Space& home, UnaryWait& p);
00053   public:
00055     virtual Actor* copy(Space& home);
00057     virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00059     virtual void reschedule(Space& home);
00061     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00063     static ExecStatus post(Home home, View x,
00064                            std::function<void(Space& home)> c);
00066     virtual size_t dispose(Space& home);
00067   };
00068 
00075   template<class View>
00076   class NaryWait : public Propagator {
00077   protected:
00079     ViewArray<View> x;
00081     SharedData<std::function<void(Space& home)>> c;
00083     NaryWait(Home home, ViewArray<View>& x,
00084              std::function<void(Space& home)> c0);
00086     NaryWait(Space& home, NaryWait& p);
00087   public:
00089     virtual Actor* copy(Space& home);
00091     virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00093     virtual void reschedule(Space& home);
00095     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00097     static ExecStatus post(Home home, ViewArray<View>& x,
00098                            std::function<void(Space& home)> c);
00100     virtual size_t dispose(Space& home);
00101   };
00102 
00103 
00104   /*
00105    * Wait propagator for single view
00106    *
00107    */
00108   template<class View>
00109   forceinline
00110   UnaryWait<View>::UnaryWait(Home home, View x0,
00111                              std::function<void(Space& home)> c0)
00112     : Propagator(home), x(x0), c(c0) {
00113     x.subscribe(home,*this,PC_GEN_ASSIGNED);
00114     home.notice(*this,AP_DISPOSE);
00115   }
00116   template<class View>
00117   forceinline
00118   UnaryWait<View>::UnaryWait(Space& home, UnaryWait& p)
00119     : Propagator(home,p), c(p.c) {
00120     x.update(home,p.x);
00121   }
00122   template<class View>
00123   Actor*
00124   UnaryWait<View>::copy(Space& home) {
00125     return new (home) UnaryWait<View>(home,*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   void
00134   UnaryWait<View>::reschedule(Space& home) {
00135     x.reschedule(home,*this,PC_GEN_ASSIGNED);
00136   }
00137   template<class View>
00138   ExecStatus
00139   UnaryWait<View>::propagate(Space& home, const ModEventDelta&) {
00140     assert(x.assigned());
00141     GECODE_VALID_FUNCTION(c());
00142     c()(home);
00143     return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this);
00144   }
00145   template<class View>
00146   forceinline ExecStatus
00147   UnaryWait<View>::post(Home home, View x,
00148                         std::function<void(Space& home)> c) {
00149     if (!c)
00150       throw InvalidFunction("UnaryWait::post");
00151     if (x.assigned()) {
00152       c(home);
00153       return home.failed() ? ES_FAILED : ES_OK;
00154     } else {
00155       (void) new (home) UnaryWait<View>(home,x,c);
00156       return ES_OK;
00157     }
00158   }
00159   template<class View>
00160   size_t
00161   UnaryWait<View>::dispose(Space& home) {
00162     x.cancel(home,*this,PC_GEN_ASSIGNED);
00163     home.ignore(*this,AP_DISPOSE);
00164     c.~SharedData<std::function<void(Space& home)>>();
00165     (void) Propagator::dispose(home);
00166     return sizeof(*this);
00167   }
00168 
00169 
00170   /*
00171    * Wait propagator for several views
00172    *
00173    */
00174   template<class View>
00175   forceinline
00176   NaryWait<View>::NaryWait(Home home, ViewArray<View>& x0,
00177                            std::function<void(Space& home)> c0)
00178     : Propagator(home), x(x0), c(c0) {
00179     assert(!x[0].assigned());
00180     x[0].subscribe(home,*this,PC_GEN_ASSIGNED);
00181     home.notice(*this,AP_DISPOSE);
00182   }
00183   template<class View>
00184   forceinline
00185   NaryWait<View>::NaryWait(Space& home, NaryWait& p)
00186     : Propagator(home,p), c(p.c) {
00187     x.update(home,p.x);
00188   }
00189   template<class View>
00190   Actor*
00191   NaryWait<View>::copy(Space& home) {
00192     assert(!x[0].assigned());
00193     for (int i=x.size()-1; i>0; i--)
00194       if (x[i].assigned())
00195         x.move_lst(i);
00196     assert(x.size() > 0);
00197     return new (home) NaryWait<View>(home,*this);
00198   }
00199   template<class View>
00200   PropCost
00201   NaryWait<View>::cost(const Space&, const ModEventDelta&) const {
00202     return PropCost::unary(PropCost::HI);
00203   }
00204   template<class View>
00205   void
00206   NaryWait<View>::reschedule(Space& home) {
00207     x[0].reschedule(home,*this,PC_GEN_ASSIGNED);
00208   }
00209   template<class View>
00210   ExecStatus
00211   NaryWait<View>::propagate(Space& home, const ModEventDelta& ) {
00212     assert(x[0].assigned());
00213     for (int i=x.size()-1; i>0; i--)
00214       if (x[i].assigned())
00215         x.move_lst(i);
00216     assert(x.size() > 0);
00217     if (x.size() == 1) {
00218       x.size(0);
00219       GECODE_VALID_FUNCTION(c());
00220       c()(home);
00221       return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this);
00222     } else {
00223       // Create new subscription
00224       x.move_lst(0);
00225       assert(!x[0].assigned());
00226       x[0].subscribe(home,*this,PC_GEN_ASSIGNED,false);
00227       return ES_OK;
00228     }
00229   }
00230   template<class View>
00231   forceinline ExecStatus
00232   NaryWait<View>::post(Home home, ViewArray<View>& x,
00233                        std::function<void(Space& home)> c) {
00234     if (!c)
00235       throw InvalidFunction("NaryWait::post");
00236     for (int i=x.size(); i--; )
00237       if (x[i].assigned())
00238         x.move_lst(i);
00239     if (x.size() == 0) {
00240       c(home);
00241       return home.failed() ? ES_FAILED : ES_OK;
00242     } else {
00243       x.unique();
00244       if (x.size() == 1) {
00245         return UnaryWait<View>::post(home,x[0],c);
00246       } else {
00247         (void) new (home) NaryWait<View>(home,x,c);
00248         return ES_OK;
00249       }
00250     }
00251   }
00252   template<class View>
00253   size_t
00254   NaryWait<View>::dispose(Space& home) {
00255     if (x.size() > 0)
00256       x[0].cancel(home,*this,PC_GEN_ASSIGNED);
00257     home.ignore(*this,AP_DISPOSE);
00258     c.~SharedData<std::function<void(Space& home)>>();
00259     (void) Propagator::dispose(home);
00260     return sizeof(*this);
00261   }
00262 
00263 }
00264 
00265 // STATISTICS: kernel-prop