00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 namespace Gecode { namespace Int { namespace Bool {
00023
00024
00025
00026
00027
00028
00029 template <class BVA, class BVB>
00030 forceinline
00031 OrTrue<BVA,BVB>::OrTrue(Space* home, BVA b0, BVB b1)
00032 : BoolBinary<BVA,BVB>(home,b0,b1) {}
00033
00034 template <class BVA, class BVB>
00035 forceinline
00036 OrTrue<BVA,BVB>::OrTrue(Space* home, bool share, OrTrue<BVA,BVB>& p)
00037 : BoolBinary<BVA,BVB>(home,share,p) {}
00038
00039 template <class BVA, class BVB>
00040 forceinline
00041 OrTrue<BVA,BVB>::OrTrue(Space* home, bool share, Propagator& p,
00042 BVA b0, BVB b1)
00043 : BoolBinary<BVA,BVB>(home,share,p,b0,b1) {}
00044
00045 template <class BVA, class BVB>
00046 inline ExecStatus
00047 OrTrue<BVA,BVB>::post(Space* home, BVA b0, BVB b1) {
00048 switch (bool_test(b0,b1)) {
00049 case BT_SAME:
00050 GECODE_ME_CHECK(b0.t_one(home));
00051 break;
00052 case BT_COMP:
00053 break;
00054 case BT_NONE:
00055 if (b0.zero()) {
00056 GECODE_ES_CHECK(b1.t_one(home));
00057 } else if (b1.zero()) {
00058 GECODE_ES_CHECK(b0.t_one(home));
00059 } else if (!b0.one() && !b1.one()) {
00060 (void) new (home) OrTrue<BVA,BVB>(home,b0,b1);
00061 }
00062 break;
00063 default: GECODE_NEVER;
00064 }
00065 return ES_OK;
00066 }
00067
00068 template <class BVA, class BVB>
00069 Actor*
00070 OrTrue<BVA,BVB>::copy(Space* home, bool share) {
00071 return new (home) OrTrue<BVA,BVB>(home,share,*this);
00072 }
00073
00074 template <class BVA, class BVB>
00075 ExecStatus
00076 OrTrue<BVA,BVB>::propagate(Space* home) {
00077 if (x0.zero()) {
00078 GECODE_ME_CHECK(x1.t_one(home));
00079 } else if (x1.zero()) {
00080 GECODE_ME_CHECK(x0.t_one(home));
00081 } else {
00082 assert(x0.one() || x1.one());
00083 }
00084 return ES_SUBSUMED;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093 template <class BVA, class BVB, class BVC>
00094 forceinline
00095 Or<BVA,BVB,BVC>::Or(Space* home, BVA b0, BVB b1, BVC b2)
00096 : BoolTernary<BVA,BVB,BVC>(home,b0,b1,b2) {}
00097
00098 template <class BVA, class BVB, class BVC>
00099 forceinline
00100 Or<BVA,BVB,BVC>::Or(Space* home, bool share, Or<BVA,BVB,BVC>& p)
00101 : BoolTernary<BVA,BVB,BVC>(home,share,p) {}
00102
00103 template <class BVA, class BVB, class BVC>
00104 forceinline
00105 Or<BVA,BVB,BVC>::Or(Space* home, bool share, Propagator& p,
00106 BVA b0, BVB b1, BVC b2)
00107 : BoolTernary<BVA,BVB,BVC>(home,share,p,b0,b1,b2) {}
00108
00109 template <class BVA, class BVB, class BVC>
00110 inline ExecStatus
00111 Or<BVA,BVB,BVC>::post(Space* home, BVA b0, BVB b1, BVC b2) {
00112 if (b2.zero()) {
00113 GECODE_ME_CHECK(b0.t_zero(home));
00114 GECODE_ME_CHECK(b1.t_zero(home));
00115 } else if (b2.one()) {
00116 return OrTrue<BVA,BVB>::post(home,b0,b1);
00117 } else {
00118 switch (bool_test(b0,b1)) {
00119 case BT_SAME:
00120 return Eq<BVA,BVC>::post(home,b0,b2);
00121 case BT_COMP:
00122 GECODE_ME_CHECK(b2.t_one(home));
00123 break;
00124 case BT_NONE:
00125 if (b0.one() || b1.one()) {
00126 GECODE_ME_CHECK(b2.t_one(home));
00127 } else if (b0.zero()) {
00128 return Eq<BVB,BVC>::post(home,b1,b2);
00129 } else if (b1.zero()) {
00130 return Eq<BVA,BVC>::post(home,b0,b2);
00131 } else {
00132 (void) new (home) Or<BVA,BVB,BVC>(home,b0,b1,b2);
00133 }
00134 break;
00135 default: GECODE_NEVER;
00136 }
00137 }
00138 return ES_OK;
00139 }
00140
00141 template <class BVA, class BVB, class BVC>
00142 Actor*
00143 Or<BVA,BVB,BVC>::copy(Space* home, bool share) {
00144 return new (home) Or<BVA,BVB,BVC>(home,share,*this);
00145 }
00146
00147 template <class BVA, class BVB, class BVC>
00148 ExecStatus
00149 Or<BVA,BVB,BVC>::propagate(Space* home) {
00150 if (x0.one() || x1.one()) {
00151 GECODE_ES_CHECK(x2.t_one(home));
00152 } else if (x2.zero()) {
00153 GECODE_ES_CHECK(x0.t_zero(home));
00154 GECODE_ES_CHECK(x1.t_zero(home));
00155 } else if (x2.one()) {
00156 if (x0.zero()) {
00157 GECODE_ES_CHECK(x1.t_one(home));
00158 } else if (x1.zero()) {
00159 GECODE_ES_CHECK(x0.t_one(home));
00160 } else {
00161 return ES_FIX;
00162 }
00163 } else if (x0.zero() && x1.zero()) {
00164 GECODE_ES_CHECK(x2.t_zero(home));
00165 } else {
00166 return ES_FIX;
00167 }
00168 return ES_SUBSUMED;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 template<class View>
00179 forceinline
00180 NaryOrTrue<View>::NaryOrTrue(Space* home, ViewArray<View>& b)
00181 : BinaryPropagator<View,PC_INT_VAL>(home,
00182 b[b.size()-2],
00183 b[b.size()-1]), x(b) {
00184 assert(x.size() > 2);
00185 x.size(x.size()-2);
00186 }
00187
00188 template<class View>
00189 PropCost
00190 NaryOrTrue<View>::cost(void) const {
00191 return cost_lo(x.size(),PC_LINEAR_LO);
00192 }
00193
00194 template<class View>
00195 forceinline
00196 NaryOrTrue<View>::NaryOrTrue(Space* home, bool share, NaryOrTrue<View>& p)
00197 : BinaryPropagator<View,PC_INT_VAL>(home,share,p), x(home,p.x.size()) {
00198
00199 int n = p.x.size();
00200 for (int i=n; i--; )
00201 if (p.x[i].zero()) {
00202 n--; p.x[i]=p.x[n]; x[i]=x[n];
00203 } else if (p.x[i].one()) {
00204 x[i].update(home,share,p.x[i]);
00205
00206 while (i--)
00207 if (p.x[i].zero() || p.x[i].one()) {
00208 n--; p.x[i]=p.x[n]; x[i]=x[n];
00209 } else {
00210 x[i].update(home,share,p.x[i]);
00211 }
00212 goto done;
00213 } else {
00214 x[i].update(home,share,p.x[i]);
00215 }
00216 done:
00217 x.size(n); p.x.size(n);
00218 }
00219
00220 template<class View>
00221 inline ExecStatus
00222 NaryOrTrue<View>::post(Space* home, ViewArray<View>& b) {
00223 for (int i=b.size(); i--; )
00224 if (b[i].one())
00225 return ES_OK;
00226 else if (b[i].zero())
00227 b.move_lst(i);
00228 if (b.size() == 0)
00229 return ES_FAILED;
00230 b.unique();
00231 if (b.size() == 1) {
00232 GECODE_ME_CHECK(b[0].t_one(home));
00233 } else if (b.size() == 2) {
00234 return OrTrue<View,View>::post(home,b[0],b[1]);
00235 } else {
00236 (void) new (home) NaryOrTrue(home,b);
00237 }
00238 return ES_OK;
00239 }
00240
00241 template<class View>
00242 Actor*
00243 NaryOrTrue<View>::copy(Space* home, bool share) {
00244 return new (home) NaryOrTrue<View>(home,share,*this);
00245 }
00246
00247 template<class View>
00248 forceinline ExecStatus
00249 NaryOrTrue<View>::resubscribe(Space* home, View& x0, View x1) {
00250 if (x0.zero()) {
00251 int n = x.size();
00252 for (int i=n; i--; )
00253 if (x[i].one()) {
00254 x.size(n);
00255 return ES_SUBSUMED;
00256 } else if (x[i].zero()) {
00257 x[i] = x[--n];
00258 } else {
00259
00260 assert(!x[i].zero() && !x[i].one());
00261
00262 if (i == 0) {
00263 View y = x[0];
00264 x.size(0);
00265 GECODE_ES_CHECK((OrTrue<View,View>::post(home,x1,y)));
00266 return ES_SUBSUMED;
00267 }
00268
00269 x0=x[i]; x[i]=x[--n];
00270 x.size(n);
00271 x0.subscribe(home,this,PC_INT_VAL,false);
00272 return ES_FIX;
00273 }
00274
00275 x.size(0);
00276 GECODE_ME_CHECK(x1.t_one(home));
00277 return ES_SUBSUMED;
00278 }
00279 return ES_FIX;
00280 }
00281
00282 template<class View>
00283 ExecStatus
00284 NaryOrTrue<View>::propagate(Space* home) {
00285 if (x0.one() || x1.one())
00286 return ES_SUBSUMED;
00287 ExecStatus e = resubscribe(home,x0,x1);
00288 if (e != ES_FIX)
00289 return e;
00290 return resubscribe(home,x1,x0);
00291 }
00292
00293
00294
00295
00296
00297
00298
00299 template<class View>
00300 forceinline
00301 NaryOr<View>::NaryOr(Space* home, ViewArray<View>& b, View c)
00302 : NaryOnePropagator<View,PC_INT_VAL>(home,b,c) {}
00303
00304 template<class View>
00305 forceinline
00306 NaryOr<View>::NaryOr(Space* home, bool share, NaryOr<View>& p)
00307 : NaryOnePropagator<View,PC_INT_VAL>(home,share,p) {}
00308
00309 template<class View>
00310 inline ExecStatus
00311 NaryOr<View>::post(Space* home, ViewArray<View>& b, View c) {
00312 if (c.one())
00313 return NaryOrTrue<View>::post(home,b);
00314 if (c.zero()) {
00315 for (int i=b.size(); i--; )
00316 GECODE_ME_CHECK(b[i].t_zero(home));
00317 return ES_OK;
00318 }
00319 for (int i=b.size(); i--; )
00320 if (b[i].one()) {
00321 GECODE_ME_CHECK(c.t_one(home));
00322 return ES_OK;
00323 } else if (b[i].zero()) {
00324 b.move_lst(i);
00325 }
00326 if (b.size() == 0)
00327 return ES_FAILED;
00328 b.unique();
00329 if (b.size() == 1)
00330 return Eq<View,View>::post(home,b[0],c);
00331 if (b.size() == 2)
00332 return Or<View,View,View>::post(home,b[0],b[1],c);
00333 (void) new (home) NaryOr(home,b,c);
00334 return ES_OK;
00335 }
00336
00337 template<class View>
00338 Actor*
00339 NaryOr<View>::copy(Space* home, bool share) {
00340 if (x.size() == 1)
00341 return new (home) Eq<View,View>(home,share,*this,
00342 x[0],y);
00343 if (x.size() == 2)
00344 return new (home) Or<View,View,View>(home,share,*this,
00345 x[0],x[1],y);
00346 return new (home) NaryOr<View>(home,share,*this);
00347 }
00348
00349 template<class View>
00350 ExecStatus
00351 NaryOr<View>::propagate(Space* home) {
00352 if (y.zero()) {
00353 for (int i = x.size(); i--; )
00354 GECODE_ME_CHECK(x[i].t_zero(home));
00355 return ES_SUBSUMED;
00356 }
00357 if (y.one()) {
00358 GECODE_ES_CHECK(NaryOrTrue<View>::post(home,x));
00359 return ES_SUBSUMED;
00360 }
00361 for (int i = x.size(); i--; ) {
00362 if (x[i].one()) {
00363 y.t_one_none(home);
00364 return ES_SUBSUMED;
00365 }
00366 if (x[i].zero())
00367 x.move_lst(i);
00368 }
00369 if (x.size() == 0) {
00370 y.t_zero_none(home);
00371 return ES_SUBSUMED;
00372 }
00373 return ES_FIX;
00374 }
00375
00376
00377 }}}
00378
00379
00380