00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
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
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
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