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