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 #include <algorithm>
00041
00042 namespace Gecode { namespace Int { namespace Arithmetic {
00043
00044 template <class View, template <class View0,class View1> class Eq>
00045 ExecStatus
00046 prop_bnd(Space* home, Propagator* p, View x0, View x1) {
00047 if (x0.assigned()) {
00048 GECODE_ME_CHECK(x1.eq(home,(x0.val() < 0) ? -x0.val() : x0.val()));
00049 return ES_SUBSUMED(p,sizeof(*p));
00050 }
00051
00052 if (x1.assigned()) {
00053 if (x0.min() >= 0) {
00054 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00055 return ES_SUBSUMED(p,sizeof(*p));
00056 } else if (x0.max() <= 0) {
00057 GECODE_ME_CHECK(x0.eq(home,-x1.val()));
00058 return ES_SUBSUMED(p,sizeof(*p));
00059 } else if (x1.val() == 0) {
00060 GECODE_ME_CHECK(x0.eq(home,0));
00061 return ES_SUBSUMED(p,sizeof(*p));
00062 } else {
00063 int mp[2] = {-x1.val(),x1.val()};
00064 Iter::Values::Array i(mp,2);
00065 GECODE_ME_CHECK(x0.inter_v(home,i,false));
00066 return ES_SUBSUMED(p,home);
00067 }
00068 }
00069
00070 if (x0.min() >= 0)
00071 GECODE_REWRITE(p,(Eq<View,View>::post(home,x0,x1)));
00072
00073 if (x0.max() <= 0)
00074 GECODE_REWRITE(p,(Eq<MinusView,View>::post(home,x0,x1)));
00075
00076 GECODE_ME_CHECK(x1.lq(home,std::max(x0.max(),-x0.min())));
00077 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00078 GECODE_ME_CHECK(x0.gq(home,-x1.max()));
00079 return ES_NOFIX;
00080 }
00081
00082 template <class View>
00083 forceinline
00084 AbsBnd<View>::AbsBnd(Space* home, View x0, View x1)
00085 : BinaryPropagator<View,PC_INT_BND>(home,x0,x1) {}
00086
00087 template <class View>
00088 ExecStatus
00089 AbsBnd<View>::post(Space* home, View x0, View x1) {
00090 if (x0.min() >= 0) {
00091 return Rel::EqBnd<View,View>::post(home,x0,x1);
00092 } else if (x0.max() <= 0) {
00093 return Rel::EqBnd<MinusView,View>::post(home,x0,x1);
00094 } else {
00095 assert(!x0.assigned());
00096 GECODE_ME_CHECK(x1.gq(home,0));
00097 if (x1.assigned()) {
00098 int mp[2] = {-x1.val(),x1.val()};
00099 Iter::Values::Array i(mp,2);
00100 GECODE_ME_CHECK(x0.inter_v(home,i,false));
00101 } else if (!same(x0,x1)) {
00102 (void) new (home) AbsBnd<View>(home,x0,x1);
00103 }
00104 }
00105 return ES_OK;
00106 }
00107
00108 template <class View>
00109 forceinline void
00110 AbsBnd<View>::post(Space* home, Reflection::VarMap& vars,
00111 const Reflection::ActorSpec& spec) {
00112 spec.checkArity(2);
00113 View x0(home, vars, spec[0]);
00114 View x1(home, vars, spec[1]);
00115 (void) new (home) AbsBnd<View>(home,x0,x1);
00116 }
00117
00118 template <class View>
00119 forceinline
00120 AbsBnd<View>::AbsBnd(Space* home, bool share, AbsBnd<View>& p)
00121 : BinaryPropagator<View,PC_INT_BND>(home,share,p) {}
00122
00123 template <class View>
00124 Actor*
00125 AbsBnd<View>::copy(Space* home,bool share) {
00126 return new (home) AbsBnd<View>(home,share,*this);
00127 }
00128
00129 template <class View>
00130 PropCost
00131 AbsBnd<View>::cost(ModEventDelta med) const {
00132 if (View::me(med) == ME_INT_VAL)
00133 return PC_UNARY_LO;
00134 return PC_BINARY_LO;
00135 }
00136
00137 template <class View>
00138 ExecStatus
00139 AbsBnd<View>::propagate(Space* home, ModEventDelta) {
00140 return prop_bnd<View,Rel::EqBnd>(home, this, x0, x1);
00141 }
00142
00143 template <class View>
00144 Support::Symbol
00145 AbsBnd<View>::ati(void) {
00146 return Reflection::mangle<View>("Gecode::Int::Arithmetic::AbsBnd");
00147 }
00148
00149 template <class View>
00150 Reflection::ActorSpec
00151 AbsBnd<View>::spec(const Space* home, Reflection::VarMap& m) const {
00152 return BinaryPropagator<View,PC_INT_BND>::spec(home, m, ati());
00153 }
00154
00155 template <class View>
00156 forceinline
00157 AbsDom<View>::AbsDom(Space* home, View x0, View x1)
00158 : BinaryPropagator<View,PC_INT_DOM>(home,x0,x1) {}
00159
00160 template <class View>
00161 ExecStatus
00162 AbsDom<View>::post(Space* home, View x0, View x1) {
00163 if (x0.min() >= 0) {
00164 return Rel::EqDom<View,View>::post(home,x0,x1);
00165 } else if (x0.max() <= 0) {
00166 return Rel::EqDom<MinusView,View>::post(home,x0,x1);
00167 } else {
00168 assert(!x0.assigned());
00169 GECODE_ME_CHECK(x1.gq(home,0));
00170 if (x1.assigned()) {
00171 int mp[2] = {-x1.val(),x1.val()};
00172 Iter::Values::Array i(mp,2);
00173 GECODE_ME_CHECK(x0.inter_v(home,i,false));
00174 } else if (!same(x0,x1)) {
00175 (void) new (home) AbsDom<View>(home,x0,x1);
00176 }
00177 }
00178 return ES_OK;
00179 }
00180
00181 template <class View>
00182 forceinline void
00183 AbsDom<View>::post(Space* home, Reflection::VarMap& vars,
00184 const Reflection::ActorSpec& spec) {
00185 spec.checkArity(2);
00186 View x0(home, vars, spec[0]);
00187 View x1(home, vars, spec[1]);
00188 (void) new (home) AbsDom<View>(home,x0,x1);
00189 }
00190
00191 template <class View>
00192 forceinline
00193 AbsDom<View>::AbsDom(Space* home, bool share, AbsDom<View>& p)
00194 : BinaryPropagator<View,PC_INT_DOM>(home,share,p) {}
00195
00196 template <class View>
00197 Actor*
00198 AbsDom<View>::copy(Space* home,bool share) {
00199 return new (home) AbsDom<View>(home,share,*this);
00200 }
00201
00202 template <class View>
00203 PropCost
00204 AbsDom<View>::cost(ModEventDelta med) const {
00205 if (View::me(med) == ME_INT_VAL)
00206 return PC_UNARY_LO;
00207 if (View::me(med) == ME_INT_DOM)
00208 return PC_BINARY_HI;
00209 return PC_BINARY_LO;
00210 }
00211
00212 template <class View>
00213 ExecStatus
00214 AbsDom<View>::propagate(Space* home, ModEventDelta med) {
00215
00216 if (View::me(med) != ME_INT_DOM) {
00217 GECODE_ES_CHECK((prop_bnd<View,Rel::EqDom>(home, this, x0, x1)));
00218 return ES_NOFIX_PARTIAL(this,View::med(ME_INT_DOM));
00219 }
00220
00221 Iter::Ranges::Singleton positive(0, Limits::max);
00222 Iter::Ranges::Singleton negative(Limits::min, 0);
00223
00224 IntVarRanges xr1(x0);
00225 IntVarRanges xr2(x0);
00226
00227 Iter::Ranges::Inter<Iter::Ranges::Singleton,
00228 IntVarRanges> posInter(positive, xr1);
00229 Iter::Ranges::Inter<Iter::Ranges::Singleton,
00230 IntVarRanges> negInter(negative, xr2);
00231 Iter::Ranges::Minus<Iter::Ranges::Inter<Iter::Ranges::Singleton,
00232 IntVarRanges> > mneg(negInter);
00233 Iter::Ranges::Union<Iter::Ranges::Inter<Iter::Ranges::Singleton,
00234 IntVarRanges>,
00235 Iter::Ranges::Minus<Iter::Ranges::Inter<
00236 Iter::Ranges::Singleton,
00237 IntVarRanges> > >
00238 u(posInter, mneg);
00239
00240 GECODE_ME_CHECK(x1.inter_r(home, u));
00241
00242 IntVarRanges x1r1(x1);
00243 IntVarRanges x1r2(x1);
00244
00245 Iter::Ranges::Minus<IntVarRanges> x1m(x1r2);
00246 Iter::Ranges::Union<IntVarRanges,
00247 Iter::Ranges::Minus<IntVarRanges> > u2(x1r1,x1m);
00248 GECODE_ME_CHECK(x0.inter_r(home, u2));
00249
00250 if (x1.assigned())
00251 return ES_SUBSUMED(this,home);
00252
00253 if (x0.min() >= 0)
00254 GECODE_REWRITE(this,(Rel::EqDom<View,View>::post(home,x0,x1)));
00255
00256 if (x0.max() <= 0) {
00257 MinusView mx0(x0);
00258 GECODE_REWRITE(this,(Rel::EqDom<MinusView,View>::post(home,mx0,x1)));
00259 }
00260
00261 return ES_FIX;
00262 }
00263
00264 template <class View>
00265 Support::Symbol
00266 AbsDom<View>::ati(void) {
00267 return Reflection::mangle<View>("Gecode::Int::Arithmetic::AbsDom");
00268 }
00269
00270 template <class View>
00271 Reflection::ActorSpec
00272 AbsDom<View>::spec(const Space* home, Reflection::VarMap& m) const {
00273 return BinaryPropagator<View,PC_INT_DOM>::spec(home, m, ati());
00274 }
00275
00276 }}}
00277
00278
00279