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 #include <gecode/int/rel.hh>
00039
00040 #include <algorithm>
00041
00042 namespace Gecode { namespace Int { namespace Bool {
00043
00044 template<class View, PropCond pc>
00045 forceinline
00046 IteBase<View,pc>::IteBase(Home home, BoolView b0, View y0, View y1, View y2)
00047 : Propagator(home), b(b0), x0(y0), x1(y1), x2(y2) {
00048 b.subscribe(home,*this,PC_BOOL_VAL);
00049 x0.subscribe(home,*this,pc);
00050 x1.subscribe(home,*this,pc);
00051 x2.subscribe(home,*this,pc);
00052 }
00053
00054 template<class View, PropCond pc>
00055 forceinline
00056 IteBase<View,pc>::IteBase(Space& home, bool share, IteBase<View,pc>& p)
00057 : Propagator(home,share,p) {
00058 b.update(home,share,p.b);
00059 x0.update(home,share,p.x0);
00060 x1.update(home,share,p.x1);
00061 x2.update(home,share,p.x2);
00062 }
00063
00064 template<class View, PropCond pc>
00065 PropCost
00066 IteBase<View,pc>::cost(const Space&, const ModEventDelta&) const {
00067 return PropCost::ternary(PropCost::LO);
00068 }
00069
00070 template<class View, PropCond pc>
00071 forceinline size_t
00072 IteBase<View,pc>::dispose(Space& home) {
00073 b.cancel(home,*this,PC_BOOL_VAL);
00074 x0.cancel(home,*this,pc);
00075 x1.cancel(home,*this,pc);
00076 x2.cancel(home,*this,pc);
00077 (void) Propagator::dispose(home);
00078 return sizeof(*this);
00079 }
00080
00081
00082
00083 template<class View>
00084 forceinline
00085 IteBnd<View>::IteBnd(Home home, BoolView b, View x0, View x1, View x2)
00086 : IteBase<View,PC_INT_BND>(home,b,x0,x1,x2) {}
00087
00088 template<class View>
00089 forceinline
00090 IteBnd<View>::IteBnd(Space& home, bool share, IteBnd<View>& p)
00091 : IteBase<View,PC_INT_BND>(home,share,p) {}
00092
00093 template<class View>
00094 Actor*
00095 IteBnd<View>::copy(Space& home, bool share) {
00096 return new (home) IteBnd<View>(home,share,*this);
00097 }
00098
00099 template<class View>
00100 inline ExecStatus
00101 IteBnd<View>::post(Home home, BoolView b, View x0, View x1, View x2) {
00102 if (same(x0,x1) || b.one())
00103 return Rel::EqBnd<View,View>::post(home,x2,x0);
00104 if (b.zero())
00105 return Rel::EqBnd<View,View>::post(home,x2,x1);
00106 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00107 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00108 (void) new (home) IteBnd<View>(home,b,x0,x1,x2);
00109 return ES_OK;
00110 }
00111
00112 template<class View>
00113 ExecStatus
00114 IteBnd<View>::propagate(Space& home, const ModEventDelta&) {
00115 if (b.one())
00116 GECODE_REWRITE(*this,(Rel::EqBnd<View,View>::post(home(*this),x2,x0)));
00117 if (b.zero())
00118 GECODE_REWRITE(*this,(Rel::EqBnd<View,View>::post(home(*this),x2,x1)));
00119
00120 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00121 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00122
00123 RelTest eq20 = rtest_eq_bnd(x2,x0);
00124 RelTest eq21 = rtest_eq_bnd(x2,x1);
00125
00126 if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE))
00127 return ES_FAILED;
00128
00129 if (eq20 == RT_FALSE) {
00130 GECODE_ME_CHECK(b.zero_none(home));
00131 if (eq21 == RT_TRUE)
00132 return home.ES_SUBSUMED(*this);
00133 else
00134 GECODE_REWRITE(*this,(Rel::EqBnd<View,View>::post(home(*this),x2,x1)));
00135 }
00136
00137 if (eq21 == RT_FALSE) {
00138 GECODE_ME_CHECK(b.one_none(home));
00139 if (eq20 == RT_TRUE)
00140 return home.ES_SUBSUMED(*this);
00141 else
00142 GECODE_REWRITE(*this,(Rel::EqBnd<View,View>::post(home(*this),x2,x0)));
00143 }
00144
00145 if ((eq20 == RT_TRUE) && (eq21 == RT_TRUE))
00146 return home.ES_SUBSUMED(*this);
00147
00148 return ES_FIX;
00149 }
00150
00151
00152
00153 template<class View>
00154 forceinline
00155 IteDom<View>::IteDom(Home home, BoolView b, View x0, View x1, View x2)
00156 : IteBase<View,PC_INT_DOM>(home,b,x0,x1,x2) {}
00157
00158 template<class View>
00159 forceinline
00160 IteDom<View>::IteDom(Space& home, bool share, IteDom<View>& p)
00161 : IteBase<View,PC_INT_DOM>(home,share,p) {}
00162
00163 template<class View>
00164 Actor*
00165 IteDom<View>::copy(Space& home, bool share) {
00166 return new (home) IteDom<View>(home,share,*this);
00167 }
00168
00169 template<class View>
00170 inline ExecStatus
00171 IteDom<View>::post(Home home, BoolView b, View x0, View x1, View x2) {
00172 if (same(x0,x1) || b.one())
00173 return Rel::EqDom<View,View>::post(home,x2,x0);
00174 if (b.zero())
00175 return Rel::EqDom<View,View>::post(home,x2,x1);
00176 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00177 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00178 (void) new (home) IteDom<View>(home,b,x0,x1,x2);
00179 return ES_OK;
00180 }
00181
00182 template<class View>
00183 PropCost
00184 IteDom<View>::cost(const Space&, const ModEventDelta& med) const {
00185 if (View::me(med) == ME_INT_DOM)
00186 return PropCost::ternary(PropCost::HI);
00187 else
00188 return PropCost::ternary(PropCost::LO);
00189 }
00190
00191 template<class View>
00192 ExecStatus
00193 IteDom<View>::propagate(Space& home, const ModEventDelta& med) {
00194 if (b.one())
00195 GECODE_REWRITE(*this,(Rel::EqDom<View,View>::post(home(*this),x2,x0)));
00196 if (b.zero())
00197 GECODE_REWRITE(*this,(Rel::EqDom<View,View>::post(home(*this),x2,x1)));
00198
00199 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00200 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00201
00202 if (View::me(med) != ME_INT_DOM) {
00203 RelTest eq20 = rtest_eq_bnd(x2,x0);
00204 RelTest eq21 = rtest_eq_bnd(x2,x1);
00205
00206 if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE))
00207 return ES_FAILED;
00208
00209 if (eq20 == RT_FALSE) {
00210 GECODE_ME_CHECK(b.zero_none(home));
00211 if (eq21 == RT_TRUE)
00212 return home.ES_SUBSUMED(*this);
00213 else
00214 GECODE_REWRITE(*this,
00215 (Rel::EqDom<View,View>::post(home(*this),x2,x1)));
00216 }
00217
00218 if (eq21 == RT_FALSE) {
00219 GECODE_ME_CHECK(b.one_none(home));
00220 if (eq20 == RT_TRUE)
00221 return home.ES_SUBSUMED(*this);
00222 else
00223 GECODE_REWRITE(*this,
00224 (Rel::EqDom<View,View>::post(home(*this),x2,x0)));
00225 }
00226
00227 if ((eq20 == RT_TRUE) && (eq21 == RT_TRUE))
00228 return home.ES_SUBSUMED(*this);
00229
00230 return home.ES_FIX_PARTIAL(*this,View::med(ME_INT_DOM));
00231 }
00232
00233 RelTest eq20 = rtest_eq_dom(x2,x0);
00234 RelTest eq21 = rtest_eq_dom(x2,x1);
00235
00236 if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE))
00237 return ES_FAILED;
00238
00239 if (eq20 == RT_FALSE) {
00240 GECODE_ME_CHECK(b.zero_none(home));
00241 if (eq21 == RT_TRUE)
00242 return home.ES_SUBSUMED(*this);
00243 else
00244 GECODE_REWRITE(*this,
00245 (Rel::EqDom<View,View>::post(home(*this),x2,x1)));
00246 }
00247
00248 if (eq21 == RT_FALSE) {
00249 GECODE_ME_CHECK(b.one_none(home));
00250 if (eq20 == RT_TRUE)
00251 return home.ES_SUBSUMED(*this);
00252 else
00253 GECODE_REWRITE(*this,
00254 (Rel::EqDom<View,View>::post(home(*this),x2,x0)));
00255 }
00256
00257 assert((eq20 != RT_TRUE) || (eq21 != RT_TRUE));
00258
00259 ViewRanges<View> r0(x0), r1(x1);
00260 Iter::Ranges::Union<ViewRanges<View>,ViewRanges<View> > u(r0,r1);
00261
00262 if (!same(x0,x2) && !same(x1,x2))
00263 GECODE_ME_CHECK(x2.inter_r(home,u,false));
00264 else
00265 GECODE_ME_CHECK(x2.inter_r(home,u,true));
00266
00267 return ES_FIX;
00268 }
00269
00270 }}}
00271
00272