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