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 home.ES_SUBSUMED(p);
00050 }
00051
00052 if (x1.assigned()) {
00053 if (x0.min() >= 0) {
00054 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00055 return home.ES_SUBSUMED(p);
00056 } else if (x0.max() <= 0) {
00057 GECODE_ME_CHECK(x0.eq(home,-x1.val()));
00058 return home.ES_SUBSUMED(p);
00059 } else if (x1.val() == 0) {
00060 GECODE_ME_CHECK(x0.eq(home,0));
00061 return home.ES_SUBSUMED(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 home.ES_SUBSUMED(p);
00067 }
00068 }
00069
00070 if (x0.min() >= 0)
00071 GECODE_REWRITE(p,(Eq<View,View>::post(home(p),x0,x1)));
00072
00073 if (x0.max() <= 0)
00074 GECODE_REWRITE(p,(Eq<MinusView,View>::post(home(p),MinusView(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(Home 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(Home 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,MinusView(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
00111 AbsBnd<View>::AbsBnd(Space& home, bool share, AbsBnd<View>& p)
00112 : BinaryPropagator<View,PC_INT_BND>(home,share,p) {}
00113
00114 template<class View>
00115 Actor*
00116 AbsBnd<View>::copy(Space& home,bool share) {
00117 return new (home) AbsBnd<View>(home,share,*this);
00118 }
00119
00120 template<class View>
00121 PropCost
00122 AbsBnd<View>::cost(const Space&, const ModEventDelta& med) const {
00123 if (View::me(med) == ME_INT_VAL)
00124 return PropCost::unary(PropCost::LO);
00125 else
00126 return PropCost::binary(PropCost::LO);
00127 }
00128
00129 template<class View>
00130 ExecStatus
00131 AbsBnd<View>::propagate(Space& home, const ModEventDelta&) {
00132 return prop_abs_bnd<View,Rel::EqBnd>(home, *this, x0, x1);
00133 }
00134
00135
00136
00137 template<class View>
00138 forceinline
00139 AbsDom<View>::AbsDom(Home home, View x0, View x1)
00140 : BinaryPropagator<View,PC_INT_DOM>(home,x0,x1) {}
00141
00142 template<class View>
00143 ExecStatus
00144 AbsDom<View>::post(Home home, View x0, View x1) {
00145 if (x0.min() >= 0) {
00146 return Rel::EqDom<View,View>::post(home,x0,x1);
00147 } else if (x0.max() <= 0) {
00148 return Rel::EqDom<MinusView,View>::post(home,MinusView(x0),x1);
00149 } else {
00150 assert(!x0.assigned());
00151 GECODE_ME_CHECK(x1.gq(home,0));
00152 if (x1.assigned()) {
00153 int mp[2] = {-x1.val(),x1.val()};
00154 Iter::Values::Array i(mp,2);
00155 GECODE_ME_CHECK(x0.inter_v(home,i,false));
00156 } else if (!same(x0,x1)) {
00157 GECODE_ME_CHECK(x1.lq(home,std::max(-x0.min(),x0.max())));
00158 (void) new (home) AbsDom<View>(home,x0,x1);
00159 }
00160 }
00161 return ES_OK;
00162 }
00163
00164 template<class View>
00165 forceinline
00166 AbsDom<View>::AbsDom(Space& home, bool share, AbsDom<View>& p)
00167 : BinaryPropagator<View,PC_INT_DOM>(home,share,p) {}
00168
00169 template<class View>
00170 Actor*
00171 AbsDom<View>::copy(Space& home,bool share) {
00172 return new (home) AbsDom<View>(home,share,*this);
00173 }
00174
00175 template<class View>
00176 PropCost
00177 AbsDom<View>::cost(const Space&, const ModEventDelta& med) const {
00178 if (View::me(med) == ME_INT_VAL)
00179 return PropCost::unary(PropCost::LO);
00180 else
00181 return PropCost::binary((View::me(med) == ME_INT_DOM) ?
00182 PropCost::HI : PropCost::LO);
00183 }
00184
00185 template<class View>
00186 ExecStatus
00187 AbsDom<View>::propagate(Space& home, const ModEventDelta& med) {
00188 if (View::me(med) != ME_INT_DOM) {
00189 GECODE_ES_CHECK((prop_abs_bnd<View,Rel::EqDom>(home, *this, x0, x1)));
00190 return home.ES_NOFIX_PARTIAL(*this,View::med(ME_INT_DOM));
00191 }
00192
00193 Region r(home);
00194
00195 {
00196 ViewRanges<View> i(x0), j(x0);
00197
00198 using namespace Iter::Ranges;
00199 Positive<ViewRanges<View> > p(i);
00200 Negative<ViewRanges<View> > n(j);
00201
00202 Minus m(r,n);
00203
00204 Union<Positive<ViewRanges<View> >,Minus> u(p,m);
00205
00206 GECODE_ME_CHECK(x1.inter_r(home,u,false));
00207
00208 }
00209
00210 {
00211 ViewRanges<View> i(x1), j(x1);
00212
00213 using namespace Iter::Ranges;
00214 Minus m(r,j);
00215
00216 Union<ViewRanges<View>,Minus> u(i,m);
00217
00218 GECODE_ME_CHECK(x0.inter_r(home,u,false));
00219 }
00220
00221 if (x1.assigned())
00222 return home.ES_SUBSUMED(*this);
00223
00224 if (x0.min() >= 0)
00225 GECODE_REWRITE(*this,(Rel::EqDom<View,View>::post(home(*this),x0,x1)));
00226
00227 if (x0.max() <= 0) {
00228 MinusView mx0(x0);
00229 GECODE_REWRITE(*this,(Rel::EqDom<MinusView,View>::post(home(*this),mx0,x1)));
00230 }
00231
00232 return ES_FIX;
00233 }
00234
00235 }}}
00236
00237
00238