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
00039
00040 namespace Gecode { namespace Float { namespace Rel {
00041
00042
00043
00044
00045
00046
00047 template<class View0, class View1>
00048 forceinline
00049 Eq<View0,View1>::Eq(Home home, View0 x0, View1 x1)
00050 : MixBinaryPropagator<View0,PC_FLOAT_BND,View1,PC_FLOAT_BND>(home,x0,x1) {}
00051
00052 template<class View0, class View1>
00053 ExecStatus
00054 Eq<View0,View1>::post(Home home, View0 x0, View1 x1){
00055 if (x0.assigned()) {
00056 GECODE_ME_CHECK(x1.eq(home,x0.val()));
00057 } else if (x1.assigned()) {
00058 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00059 } else if (!same(x0,x1)) {
00060 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00061 GECODE_ME_CHECK(x1.lq(home,x0.max()));
00062 GECODE_ME_CHECK(x0.gq(home,x1.min()));
00063 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00064 (void) new (home) Eq<View0,View1>(home,x0,x1);
00065 }
00066 return ES_OK;
00067 }
00068
00069 template<class View0, class View1>
00070 forceinline
00071 Eq<View0,View1>::Eq(Space& home, bool share, Eq<View0,View1>& p)
00072 : MixBinaryPropagator<View0,PC_FLOAT_BND,View1,PC_FLOAT_BND>(home,share,p) {}
00073
00074 template<class View0, class View1>
00075 forceinline
00076 Eq<View0,View1>::Eq(Space& home, bool share, Propagator& p,
00077 View0 x0, View1 x1)
00078 : MixBinaryPropagator<View0,PC_FLOAT_BND,View1,PC_FLOAT_BND>(home,share,p,
00079 x0,x1) {}
00080
00081 template<class View0, class View1>
00082 Actor*
00083 Eq<View0,View1>::copy(Space& home, bool share) {
00084 return new (home) Eq<View0,View1>(home,share,*this);
00085 }
00086
00087 template<class View0, class View1>
00088 ExecStatus
00089 Eq<View0,View1>::propagate(Space& home, const ModEventDelta&) {
00090 if (x0.assigned()) {
00091 GECODE_ME_CHECK(x1.eq(home,x0.val()));
00092 } else if (x1.assigned()) {
00093 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00094 } else {
00095 do {
00096 GECODE_ME_CHECK(x0.gq(home,x1.min()));
00097 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00098 } while (x0.min() != x1.min());
00099 do {
00100 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00101 GECODE_ME_CHECK(x1.lq(home,x0.max()));
00102 } while (x0.max() != x1.max());
00103 if (!x0.assigned())
00104 return ES_FIX;
00105 }
00106 assert(x0.assigned() && x1.assigned());
00107 return home.ES_SUBSUMED(*this);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 template<class View>
00117 forceinline
00118 NaryEq<View>::NaryEq(Home home, ViewArray<View>& x)
00119 : NaryPropagator<View,PC_FLOAT_BND>(home,x) {}
00120
00121 template<class View>
00122 ExecStatus
00123 NaryEq<View>::post(Home home, ViewArray<View>& x) {
00124 x.unique(home);
00125 if (x.size() == 2) {
00126 return Eq<View,View>::post(home,x[0],x[1]);
00127 } else if (x.size() > 2) {
00128 FloatNum l = x[0].min();
00129 FloatNum u = x[0].max();
00130 for (int i=x.size(); i-- > 1; ) {
00131 l = std::max(l,x[i].min());
00132 u = std::min(u,x[i].max());
00133 }
00134 for (int i=x.size(); i--; ) {
00135 GECODE_ME_CHECK(x[i].gq(home,l));
00136 GECODE_ME_CHECK(x[i].lq(home,u));
00137 }
00138 (void) new (home) NaryEq<View>(home,x);
00139 }
00140 return ES_OK;
00141 }
00142
00143 template<class View>
00144 forceinline
00145 NaryEq<View>::NaryEq(Space& home, bool share, NaryEq<View>& p)
00146 : NaryPropagator<View,PC_FLOAT_BND>(home,share,p) {}
00147
00148 template<class View>
00149 Actor*
00150 NaryEq<View>::copy(Space& home, bool share) {
00151 return new (home) NaryEq<View>(home,share,*this);
00152 }
00153
00154 template<class View>
00155 PropCost
00156 NaryEq<View>::cost(const Space&, const ModEventDelta& med) const {
00157 if (View::me(med) == ME_FLOAT_VAL)
00158 return PropCost::unary(PropCost::LO);
00159 else
00160 return PropCost::linear(PropCost::LO, x.size());
00161 }
00162
00163 template<class View>
00164 ExecStatus
00165 NaryEq<View>::propagate(Space& home, const ModEventDelta& med) {
00166 assert(x.size() > 2);
00167 if (View::me(med) == ME_FLOAT_VAL) {
00168
00169 for (int i = 0; ; i++)
00170 if (x[i].assigned()) {
00171 FloatVal n = x[i].val();
00172 x.move_lst(i);
00173 for (int j = x.size(); j--; )
00174 GECODE_ME_CHECK(x[j].eq(home,n));
00175 return home.ES_SUBSUMED(*this);
00176 }
00177 GECODE_NEVER;
00178 }
00179
00180 FloatNum mn = x[0].min();
00181 restart_min:
00182 for (int i = x.size(); i--; ) {
00183 GECODE_ME_CHECK(x[i].gq(home,mn));
00184 if (mn < x[i].min()) {
00185 mn = x[i].min();
00186 goto restart_min;
00187 }
00188 }
00189 FloatNum mx = x[0].max();
00190 restart_max:
00191 for (int i = x.size(); i--; ) {
00192 GECODE_ME_CHECK(x[i].lq(home,mx));
00193 if (mx > x[i].max()) {
00194 mx = x[i].max();
00195 goto restart_max;
00196 }
00197 }
00198 return x[0].assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208 template<class View, class CtrlView, ReifyMode rm>
00209 forceinline
00210 ReEq<View,CtrlView,rm>::ReEq(Home home, View x0, View x1, CtrlView b)
00211 : Int::ReBinaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,x0,x1,b) {}
00212
00213 template<class View, class CtrlView, ReifyMode rm>
00214 ExecStatus
00215 ReEq<View,CtrlView,rm>::post(Home home, View x0, View x1, CtrlView b){
00216 if (b.one()) {
00217 if (rm == RM_PMI)
00218 return ES_OK;
00219 return Eq<View,View>::post(home,x0,x1);
00220 }
00221 if (b.zero()) {
00222 if (rm == RM_IMP)
00223 return ES_OK;
00224 return Nq<View,View>::post(home,x0,x1);
00225 }
00226 if (!same(x0,x1)) {
00227 (void) new (home) ReEq(home,x0,x1,b);
00228 } else if (rm != RM_IMP) {
00229 GECODE_ME_CHECK(b.one(home));
00230 }
00231 return ES_OK;
00232 }
00233
00234
00235 template<class View, class CtrlView, ReifyMode rm>
00236 forceinline
00237 ReEq<View,CtrlView,rm>::ReEq(Space& home, bool share, ReEq& p)
00238 : Int::ReBinaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,share,p) {}
00239
00240 template<class View, class CtrlView, ReifyMode rm>
00241 Actor*
00242 ReEq<View,CtrlView,rm>::copy(Space& home, bool share) {
00243 return new (home) ReEq<View,CtrlView,rm>(home,share,*this);
00244 }
00245
00246 template<class View, class CtrlView, ReifyMode rm>
00247 ExecStatus
00248 ReEq<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00249 if (b.one()) {
00250 if (rm == RM_PMI)
00251 return home.ES_SUBSUMED(*this);
00252 GECODE_REWRITE(*this,(Eq<View,View>::post(home(*this),x0,x1)));
00253 }
00254 if (b.zero()) {
00255 if (rm == RM_IMP)
00256 return home.ES_SUBSUMED(*this);
00257 GECODE_REWRITE(*this,(Nq<View,View>::post(home(*this),x0,x1)));
00258 }
00259 switch (rtest_eq(x0,x1)) {
00260 case RT_TRUE:
00261 if (rm != RM_IMP)
00262 GECODE_ME_CHECK(b.one_none(home));
00263 break;
00264 case RT_FALSE:
00265 if (rm != RM_PMI)
00266 GECODE_ME_CHECK(b.zero_none(home));
00267 break;
00268 case RT_MAYBE:
00269 return ES_FIX;
00270 default: GECODE_NEVER;
00271 }
00272 return home.ES_SUBSUMED(*this);
00273 }
00274
00275
00276
00277
00278
00279
00280
00281 template<class View, class CtrlView, ReifyMode rm>
00282 forceinline
00283 ReEqFloat<View,CtrlView,rm>::ReEqFloat
00284 (Home home, View x, FloatVal c0, CtrlView b)
00285 : Int::ReUnaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,x,b), c(c0) {}
00286
00287 template<class View, class CtrlView, ReifyMode rm>
00288 ExecStatus
00289 ReEqFloat<View,CtrlView,rm>::post(Home home, View x, FloatVal c, CtrlView b) {
00290 if (b.one()) {
00291 if (rm != RM_PMI)
00292 GECODE_ME_CHECK(x.eq(home,c));
00293 } else if (x.assigned()) {
00294 if (overlap(x.val(),c)) {
00295 if (rm != RM_IMP)
00296 GECODE_ME_CHECK(b.one(home));
00297 } else {
00298 if (rm != RM_PMI)
00299 GECODE_ME_CHECK(b.zero(home));
00300 }
00301 } else {
00302 (void) new (home) ReEqFloat(home,x,c,b);
00303 }
00304 return ES_OK;
00305 }
00306
00307
00308 template<class View, class CtrlView, ReifyMode rm>
00309 forceinline
00310 ReEqFloat<View,CtrlView,rm>::ReEqFloat(Space& home, bool share, ReEqFloat& p)
00311 : Int::ReUnaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,share,p), c(p.c) {}
00312
00313 template<class View, class CtrlView, ReifyMode rm>
00314 Actor*
00315 ReEqFloat<View,CtrlView,rm>::copy(Space& home, bool share) {
00316 return new (home) ReEqFloat<View,CtrlView,rm>(home,share,*this);
00317 }
00318
00319 template<class View, class CtrlView, ReifyMode rm>
00320 ExecStatus
00321 ReEqFloat<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00322 if (b.one()) {
00323 if (rm != RM_PMI)
00324 GECODE_ME_CHECK(x0.eq(home,c));
00325 } else {
00326 switch (rtest_eq(x0,c)) {
00327 case RT_TRUE:
00328 if (rm != RM_IMP)
00329 GECODE_ME_CHECK(b.one(home));
00330 break;
00331 case RT_FALSE:
00332 if (rm != RM_PMI)
00333 GECODE_ME_CHECK(b.zero(home));
00334 break;
00335 case RT_MAYBE:
00336 return ES_FIX;
00337 default: GECODE_NEVER;
00338 }
00339 }
00340 return home.ES_SUBSUMED(*this);
00341 }
00342
00343
00344 }}}
00345
00346