Generated on Tue Apr 18 10:22:07 2017 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: 2017-03-01 04:28:36 +0100 (Wed, 01 Mar 2017) $ by $Author: schulte $
00011  *     $Revision: 15541 $
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     SharedData<std::function<void(Space& home)>> c;
00059     UnaryWait(Home home, View x, std::function<void(Space& home)> c0);
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 void reschedule(Space& home);
00070     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00072     static ExecStatus post(Home home, View x,
00073                            std::function<void(Space& home)> c);
00075     virtual size_t dispose(Space& home);
00076   };
00077 
00084   template<class View>
00085   class NaryWait : public Propagator {
00086   protected:
00088     ViewArray<View> x;
00090     SharedData<std::function<void(Space& home)>> c;
00092     NaryWait(Home home, ViewArray<View>& x,
00093              std::function<void(Space& home)> c0);
00095     NaryWait(Space& home, bool shared, NaryWait& p);
00096   public:
00098     virtual Actor* copy(Space& home, bool share);
00100     virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00102     virtual void reschedule(Space& home);
00104     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00106     static ExecStatus post(Home home, ViewArray<View>& x,
00107                            std::function<void(Space& home)> c);
00109     virtual size_t dispose(Space& home);
00110   };
00111 
00112 
00113   /*
00114    * Wait propagator for single view
00115    *
00116    */
00117   template<class View>
00118   forceinline
00119   UnaryWait<View>::UnaryWait(Home home, View x0,
00120                              std::function<void(Space& home)> c0)
00121     : Propagator(home), x(x0), c(c0) {
00122     x.subscribe(home,*this,PC_GEN_ASSIGNED);
00123     home.notice(*this,AP_DISPOSE);
00124   }
00125   template<class View>
00126   forceinline
00127   UnaryWait<View>::UnaryWait(Space& home, bool shared, UnaryWait& p)
00128     : Propagator(home,shared,p) {
00129     x.update(home,shared,p.x);
00130     c.update(home,shared,p.c);
00131   }
00132   template<class View>
00133   Actor*
00134   UnaryWait<View>::copy(Space& home, bool share) {
00135     return new (home) UnaryWait<View>(home,share,*this);
00136   }
00137   template<class View>
00138   PropCost
00139   UnaryWait<View>::cost(const Space&, const ModEventDelta&) const {
00140     return PropCost::unary(PropCost::LO);
00141   }
00142   template<class View>
00143   void
00144   UnaryWait<View>::reschedule(Space& home) {
00145     x.reschedule(home,*this,PC_GEN_ASSIGNED);
00146   }
00147   template<class View>
00148   ExecStatus
00149   UnaryWait<View>::propagate(Space& home, const ModEventDelta&) {
00150     assert(x.assigned());
00151     GECODE_VALID_FUNCTION(c());
00152     c()(home);
00153     return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this);
00154   }
00155   template<class View>
00156   forceinline ExecStatus
00157   UnaryWait<View>::post(Home home, View x,
00158                         std::function<void(Space& home)> c) {
00159     if (!c)
00160       throw InvalidFunction("UnaryWait::post");
00161     if (x.assigned()) {
00162       c(home);
00163       return home.failed() ? ES_FAILED : ES_OK;
00164     } else {
00165       (void) new (home) UnaryWait<View>(home,x,c);
00166       return ES_OK;
00167     }
00168   }
00169   template<class View>
00170   size_t
00171   UnaryWait<View>::dispose(Space& home) {
00172     x.cancel(home,*this,PC_GEN_ASSIGNED);
00173     home.ignore(*this,AP_DISPOSE);
00174     c.~SharedData<std::function<void(Space& home)>>();
00175     (void) Propagator::dispose(home);
00176     return sizeof(*this);
00177   }
00178 
00179 
00180   /*
00181    * Wait propagator for several views
00182    *
00183    */
00184   template<class View>
00185   forceinline
00186   NaryWait<View>::NaryWait(Home home, ViewArray<View>& x0,
00187                            std::function<void(Space& home)> c0)
00188     : Propagator(home), x(x0), c(c0) {
00189     assert(!x[0].assigned());
00190     x[0].subscribe(home,*this,PC_GEN_ASSIGNED);
00191     home.notice(*this,AP_DISPOSE);
00192   }
00193   template<class View>
00194   forceinline
00195   NaryWait<View>::NaryWait(Space& home, bool shared, NaryWait& p)
00196     : Propagator(home,shared,p) {
00197     x.update(home,shared,p.x);
00198     c.update(home,shared,p.c);
00199   }
00200   template<class View>
00201   Actor*
00202   NaryWait<View>::copy(Space& home, bool share) {
00203     assert(!x[0].assigned());
00204     for (int i=x.size()-1; i>0; i--)
00205       if (x[i].assigned())
00206         x.move_lst(i);
00207     assert(x.size() > 0);
00208     return new (home) NaryWait<View>(home,share,*this);
00209   }
00210   template<class View>
00211   PropCost
00212   NaryWait<View>::cost(const Space&, const ModEventDelta&) const {
00213     return PropCost::unary(PropCost::HI);
00214   }
00215   template<class View>
00216   void
00217   NaryWait<View>::reschedule(Space& home) {
00218     x[0].reschedule(home,*this,PC_GEN_ASSIGNED);
00219   }
00220   template<class View>
00221   ExecStatus
00222   NaryWait<View>::propagate(Space& home, const ModEventDelta& ) {
00223     assert(x[0].assigned());
00224     for (int i=x.size()-1; i>0; i--)
00225       if (x[i].assigned())
00226         x.move_lst(i);
00227     assert(x.size() > 0);
00228     if (x.size() == 1) {
00229       x.size(0);
00230       GECODE_VALID_FUNCTION(c());
00231       c()(home);
00232       return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this);
00233     } else {
00234       // Create new subscription
00235       x.move_lst(0);
00236       assert(!x[0].assigned());
00237       x[0].subscribe(home,*this,PC_GEN_ASSIGNED,false);
00238       return ES_OK;
00239     }
00240   }
00241   template<class View>
00242   forceinline ExecStatus
00243   NaryWait<View>::post(Home home, ViewArray<View>& x,
00244                        std::function<void(Space& home)> c) {
00245     if (!c)
00246       throw InvalidFunction("NaryWait::post");
00247     for (int i=x.size(); i--; )
00248       if (x[i].assigned())
00249         x.move_lst(i);
00250     if (x.size() == 0) {
00251       c(home);
00252       return home.failed() ? ES_FAILED : ES_OK;
00253     } else {
00254       x.unique(home);
00255       if (x.size() == 1) {
00256         return UnaryWait<View>::post(home,x[0],c);
00257       } else {
00258         (void) new (home) NaryWait<View>(home,x,c);
00259         return ES_OK;
00260       }
00261     }
00262   }
00263   template<class View>
00264   size_t
00265   NaryWait<View>::dispose(Space& home) {
00266     if (x.size() > 0)
00267       x[0].cancel(home,*this,PC_GEN_ASSIGNED);
00268     home.ignore(*this,AP_DISPOSE);
00269     c.~SharedData<std::function<void(Space& home)>>();
00270     (void) Propagator::dispose(home);
00271     return sizeof(*this);
00272   }
00273 
00274 }}
00275 
00276 #endif
00277 
00278 // STATISTICS: kernel-prop