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_abs_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 GECODE_ME_CHECK(x1.lq(home,std::max(-x0.min(),x0.max())));
00103 (void) new (home) AbsBnd<View>(home,x0,x1);
00104 }
00105 }
00106 return ES_OK;
00107 }
00108
00109 template <class View>
00110 forceinline void
00111 AbsBnd<View>::post(Space* home, Reflection::VarMap& vars,
00112 const Reflection::ActorSpec& spec) {
00113 spec.checkArity(2);
00114 View x0(home, vars, spec[0]);
00115 View x1(home, vars, spec[1]);
00116 (void) new (home) AbsBnd<View>(home,x0,x1);
00117 }
00118
00119 template <class View>
00120 forceinline
00121 AbsBnd<View>::AbsBnd(Space* home, bool share, AbsBnd<View>& p)
00122 : BinaryPropagator<View,PC_INT_BND>(home,share,p) {}
00123
00124 template <class View>
00125 Actor*
00126 AbsBnd<View>::copy(Space* home,bool share) {
00127 return new (home) AbsBnd<View>(home,share,*this);
00128 }
00129
00130 template <class View>
00131 PropCost
00132 AbsBnd<View>::cost(ModEventDelta med) const {
00133 if (View::me(med) == ME_INT_VAL)
00134 return PC_UNARY_LO;
00135 return PC_BINARY_LO;
00136 }
00137
00138 template <class View>
00139 ExecStatus
00140 AbsBnd<View>::propagate(Space* home, ModEventDelta) {
00141 return prop_abs_bnd<View,Rel::EqBnd>(home, this, x0, x1);
00142 }
00143
00144 template <class View>
00145 Support::Symbol
00146 AbsBnd<View>::ati(void) {
00147 return Reflection::mangle<View>("Gecode::Int::Arithmetic::AbsBnd");
00148 }
00149
00150 template <class View>
00151 Reflection::ActorSpec
00152 AbsBnd<View>::spec(const Space* home, Reflection::VarMap& m) const {
00153 return BinaryPropagator<View,PC_INT_BND>::spec(home, m, ati());
00154 }
00155
00156 template <class View>
00157 forceinline
00158 AbsDom<View>::AbsDom(Space* home, View x0, View x1)
00159 : BinaryPropagator<View,PC_INT_DOM>(home,x0,x1) {}
00160
00161 template <class View>
00162 ExecStatus
00163 AbsDom<View>::post(Space* home, View x0, View x1) {
00164 if (x0.min() >= 0) {
00165 return Rel::EqDom<View,View>::post(home,x0,x1);
00166 } else if (x0.max() <= 0) {
00167 return Rel::EqDom<MinusView,View>::post(home,x0,x1);
00168 } else {
00169 assert(!x0.assigned());
00170 GECODE_ME_CHECK(x1.gq(home,0));
00171 if (x1.assigned()) {
00172 int mp[2] = {-x1.val(),x1.val()};
00173 Iter::Values::Array i(mp,2);
00174 GECODE_ME_CHECK(x0.inter_v(home,i,false));
00175 } else if (!same(x0,x1)) {
00176 GECODE_ME_CHECK(x1.lq(home,std::max(-x0.min(),x0.max())));
00177 (void) new (home) AbsDom<View>(home,x0,x1);
00178 }
00179 }
00180 return ES_OK;
00181 }
00182
00183 template <class View>
00184 forceinline void
00185 AbsDom<View>::post(Space* home, Reflection::VarMap& vars,
00186 const Reflection::ActorSpec& spec) {
00187 spec.checkArity(2);
00188 View x0(home, vars, spec[0]);
00189 View x1(home, vars, spec[1]);
00190 (void) new (home) AbsDom<View>(home,x0,x1);
00191 }
00192
00193 template <class View>
00194 forceinline
00195 AbsDom<View>::AbsDom(Space* home, bool share, AbsDom<View>& p)
00196 : BinaryPropagator<View,PC_INT_DOM>(home,share,p) {}
00197
00198 template <class View>
00199 Actor*
00200 AbsDom<View>::copy(Space* home,bool share) {
00201 return new (home) AbsDom<View>(home,share,*this);
00202 }
00203
00204 template <class View>
00205 PropCost
00206 AbsDom<View>::cost(ModEventDelta med) const {
00207 if (View::me(med) == ME_INT_VAL)
00208 return PC_UNARY_LO;
00209 if (View::me(med) == ME_INT_DOM)
00210 return PC_BINARY_HI;
00211 return PC_BINARY_LO;
00212 }
00213
00214 template <class View>
00215 ExecStatus
00216 AbsDom<View>::propagate(Space* home, ModEventDelta med) {
00217 if (View::me(med) != ME_INT_DOM) {
00218 GECODE_ES_CHECK((prop_abs_bnd<View,Rel::EqDom>(home, this, x0, x1)));
00219 return ES_NOFIX_PARTIAL(this,View::med(ME_INT_DOM));
00220 }
00221
00222 {
00223 ViewRanges<View> i(x0), j(x0);
00224
00225 using namespace Iter::Ranges;
00226 Positive<ViewRanges<View> > p(i);
00227 Negative<ViewRanges<View> > n(j);
00228
00229 Minus<Negative<ViewRanges<View> > > m(n);
00230
00231 Union<Positive<ViewRanges<View> >,
00232 Minus<Negative<ViewRanges<View> > > > u(p,m);
00233
00234 GECODE_ME_CHECK(x1.inter_r(home,u,false));
00235
00236 }
00237
00238 {
00239 ViewRanges<View> i(x1), j(x1);
00240
00241 using namespace Iter::Ranges;
00242 Minus<ViewRanges<View> > m(j);
00243
00244 Union<ViewRanges<View>,Minus<ViewRanges<View> > > u(i,m);
00245
00246 GECODE_ME_CHECK(x0.inter_r(home,u,false));
00247 }
00248
00249 if (x1.assigned())
00250 return ES_SUBSUMED(this,home);
00251
00252 if (x0.min() >= 0)
00253 GECODE_REWRITE(this,(Rel::EqDom<View,View>::post(home,x0,x1)));
00254
00255 if (x0.max() <= 0) {
00256 MinusView mx0(x0);
00257 GECODE_REWRITE(this,(Rel::EqDom<MinusView,View>::post(home,mx0,x1)));
00258 }
00259
00260 return ES_FIX;
00261 }
00262
00263 template <class View>
00264 Support::Symbol
00265 AbsDom<View>::ati(void) {
00266 return Reflection::mangle<View>("Gecode::Int::Arithmetic::AbsDom");
00267 }
00268
00269 template <class View>
00270 Reflection::ActorSpec
00271 AbsDom<View>::spec(const Space* home, Reflection::VarMap& m) const {
00272 return BinaryPropagator<View,PC_INT_DOM>::spec(home, m, ati());
00273 }
00274
00275 }}}
00276
00277
00278