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
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
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
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
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