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
00041
00042
00043
00044 namespace Gecode { namespace Set { namespace RelOp {
00045
00046
00047
00048
00049
00050
00051 template <class View0, class View1, class View2> ExecStatus
00052 Intersection<View0,View1,View2>::post(Space* home,
00053 View0 x0,View1 x1,View2 x2) {
00054 (void) new (home) Intersection<View0,View1,View2>(home,x0,x1,x2);
00055 return ES_OK;
00056 }
00057
00058 template <class View0, class View1, class View2>
00059 Actor*
00060 Intersection<View0,View1,View2>::copy(Space* home, bool share) {
00061 return new (home) Intersection(home,share,*this);
00062 }
00063
00064 template <class View0, class View1, class View2>
00065 Support::Symbol
00066 Intersection<View0,View1,View2>::ati(void) {
00067 return Reflection::mangle<View0,View1,View2>("Gecode::Set::RelOp::Intersection");
00068 }
00069
00070 template <class View0, class View1, class View2>
00071 Reflection::ActorSpec
00072 Intersection<View0,View1,View2>::spec(const Space* home,
00073 Reflection::VarMap& m) const {
00074 return MixTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00075 View2,PC_SET_ANY>::spec(home, m, ati());
00076 }
00077
00078 template <class View0, class View1, class View2>
00079 void
00080 Intersection<View0,View1,View2>::post(Space* home,
00081 Reflection::VarMap& vars,
00082 const Reflection::ActorSpec& spec) {
00083 spec.checkArity(3);
00084 View0 x0(home, vars, spec[0]);
00085 View1 x1(home, vars, spec[1]);
00086 View2 x2(home, vars, spec[2]);
00087 (void) new (home) Intersection(home,x0,x1,x2);
00088 }
00089
00090 template <class View0, class View1, class View2>
00091 ExecStatus
00092 Intersection<View0,View1,View2>::propagate(Space* home, ModEventDelta med) {
00093
00094
00095
00096 bool x0ass = x0.assigned();
00097 bool x1ass = x1.assigned();
00098 bool x2ass = x2.assigned();
00099
00100 ModEvent me0 = View0::me(med);
00101 ModEvent me1 = View1::me(med);
00102 ModEvent me2 = View2::me(med);
00103
00104 bool x0lbmod = false;
00105 bool x1lbmod = false;
00106 bool modified = false;
00107
00108 do {
00109
00110 modified = false;
00111 do {
00112
00113 {
00114 GlbRanges<View0> x0lb(x0);
00115 GlbRanges<View1> x1lb(x1);
00116 Iter::Ranges::Inter<GlbRanges<View0>, GlbRanges<View1> >
00117 i2(x0lb,x1lb);
00118 GECODE_ME_CHECK_MODIFIED(modified, x2.includeI(home,i2) );
00119 }
00120
00121 if (modified || Rel::testSetEventLB(me2) )
00122 {
00123 modified = false;
00124
00125 GlbRanges<View2> x2lb1(x2);
00126 GECODE_ME_CHECK_MODIFIED(modified, x0.includeI(home,x2lb1) );
00127 x0lbmod |= modified;
00128
00129
00130 bool modified2=false;
00131 GlbRanges<View2> x2lb2(x2);
00132 GECODE_ME_CHECK_MODIFIED(modified2, x1.includeI(home,x2lb2) );
00133 x1lbmod |= modified2;
00134 modified |= modified2;
00135 }
00136
00137 } while (modified);
00138
00139 modified = false;
00140 do {
00141 bool modifiedOld = modified;
00142 modified = false;
00143
00144 if (Rel::testSetEventUB(me2) || Rel::testSetEventLB(me0)
00145 || x0lbmod || modifiedOld)
00146 {
00147
00148 GlbRanges<View0> x0lb(x0);
00149 LubRanges<View2> x2ub(x2);
00150 Iter::Ranges::Diff<GlbRanges<View0>,LubRanges<View2> >
00151 diff(x0lb, x2ub);
00152 GECODE_ME_CHECK_MODIFIED(modified, x1.excludeI(home,diff) );
00153 }
00154
00155 if (Rel::testSetEventUB(me2) || Rel::testSetEventLB(me1)
00156 || x1lbmod || modifiedOld)
00157 {
00158
00159 GlbRanges<View1> x1lb(x1);
00160 LubRanges<View2> x2ub(x2);
00161 Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View2> >
00162 diff(x1lb, x2ub);
00163 GECODE_ME_CHECK_MODIFIED(modified, x0.excludeI(home,diff) );
00164 }
00165
00166 if (Rel::testSetEventUB(me0,me1) || modified)
00167 {
00168
00169
00170 LubRanges<View0> x0ub(x0);
00171 LubRanges<View1> x1ub(x1);
00172 Iter::Ranges::Inter<LubRanges<View0>, LubRanges<View1> >
00173 i1(x0ub,x1ub);
00174 GECODE_ME_CHECK_MODIFIED(modified, x2.intersectI(home,i1) );
00175 }
00176
00177 } while(modified);
00178
00179 modified = false;
00180 {
00181
00182 ExecStatus ret = interCard(home,modified, x0, x1, x2);
00183 GECODE_ES_CHECK(ret);
00184 }
00185
00186 if (x2.cardMin() == Set::Limits::card) {
00187 GECODE_ME_CHECK( x0.cardMin(home, Set::Limits::card) );
00188 GECODE_ME_CHECK( x1.cardMin(home, Set::Limits::card) );
00189 return ES_SUBSUMED(this,home);
00190 }
00191
00192 if (x0.cardMin() == Set::Limits::card)
00193 GECODE_REWRITE(this,(Rel::Eq<View1,View2>::post(home,x1,x2)));
00194 if (x1.cardMin() == Set::Limits::card)
00195 GECODE_REWRITE(this,(Rel::Eq<View0,View2>::post(home,x0,x2)));
00196
00197 } while(modified);
00198
00199 if (shared(x0,x1,x2)) {
00200 return (x0ass && x1ass && x2ass) ? ES_SUBSUMED(this,home) : ES_NOFIX;
00201 } else {
00202 if (x0ass && x1ass && x2ass)
00203 return ES_SUBSUMED(this,home);
00204 if (x0ass != x0.assigned() ||
00205 x1ass != x1.assigned() ||
00206 x2ass != x2.assigned()) {
00207 return ES_NOFIX;
00208 } else {
00209 return ES_FIX;
00210 }
00211 }
00212 }
00213
00214 template <class View0, class View1, class View2>
00215 forceinline
00216 Intersection<View0,View1,View2>::Intersection(Space* home,
00217 View0 y0,View1 y1,View2 y2)
00218 : MixTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00219 View2,PC_SET_ANY>(home,y0,y1,y2) {}
00220
00221 template <class View0, class View1, class View2>
00222 forceinline
00223 Intersection<View0,View1,View2>::Intersection(Space* home, bool share,
00224 Intersection<View0,View1,View2>& p)
00225 : MixTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00226 View2,PC_SET_ANY>(home,share,p) {}
00227
00228
00229
00230
00231
00232
00233 template <class View0, class View1>
00234 forceinline
00235 IntersectionN<View0,View1>::IntersectionN(Space* home, ViewArray<View0>& x,
00236 View1 y)
00237 : MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,x,y),
00238 intOfDets(home) {
00239 shared = x.shared() || viewarrayshared(x,y);
00240 }
00241
00242 template <class View0, class View1>
00243 forceinline
00244 IntersectionN<View0,View1>::IntersectionN(Space* home, ViewArray<View0>& x,
00245 const IntSet& z, View1 y)
00246 : MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,x,y),
00247 intOfDets(home) {
00248 shared = x.shared() || viewarrayshared(x,y);
00249 IntSetRanges rz(z);
00250 intOfDets.intersectI(home, rz);
00251 }
00252
00253 template <class View0, class View1>
00254 forceinline
00255 IntersectionN<View0,View1>::IntersectionN(Space* home, bool share,
00256 IntersectionN& p)
00257 : MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,share,p),
00258 shared(p.shared),
00259 intOfDets() {
00260 intOfDets.update(home, p.intOfDets);
00261 }
00262
00263 template <class View0, class View1>
00264 ExecStatus
00265 IntersectionN<View0,View1>::post(Space* home,
00266 ViewArray<View0>& x, View1 y) {
00267 switch (x.size()) {
00268 case 0:
00269 GECODE_ME_CHECK(y.cardMin(home, Limits::card));
00270 return ES_OK;
00271 case 1:
00272 return Rel::Eq<View0,View1>::post(home, x[0], y);
00273 case 2:
00274 return Intersection<View0,View0,View1>::post(home, x[0], x[1], y);
00275 default:
00276 (void) new (home) IntersectionN<View0,View1>(home,x,y);
00277 return ES_OK;
00278 }
00279 }
00280
00281 template <class View0, class View1>
00282 ExecStatus
00283 IntersectionN<View0,View1>::post(Space* home, ViewArray<View0>& x,
00284 const IntSet& z, View1 y) {
00285 (void) new (home) IntersectionN<View0,View1>(home,x,z,y);
00286 return ES_OK;
00287 }
00288
00289 template <class View0, class View1>
00290 Actor*
00291 IntersectionN<View0,View1>::copy(Space* home, bool share) {
00292 return new (home) IntersectionN<View0,View1>(home,share,*this);
00293 }
00294
00295 template <class View0, class View1>
00296 PropCost
00297 IntersectionN<View0,View1>::cost(ModEventDelta) const {
00298 return PC_QUADRATIC_LO;
00299 }
00300
00301 template <class View0, class View1>
00302 Support::Symbol
00303 IntersectionN<View0,View1>::ati(void) {
00304 return Reflection::mangle<View0,View1>("Gecode::Set::RelOp::IntersectionN");
00305 }
00306
00307 template <class View0, class View1>
00308 Reflection::ActorSpec
00309 IntersectionN<View0,View1>::spec(const Space* home,
00310 Reflection::VarMap& m) const {
00311 Reflection::ActorSpec s =
00312 MixNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>
00313 ::spec(home, m, ati());
00314 int count = 0;
00315 for (BndSetRanges iod(intOfDets); iod(); ++iod)
00316 count++;
00317 Reflection::IntArrayArg* a = Reflection::Arg::newIntArray(count*2);
00318 count = 0;
00319 for (BndSetRanges iod(intOfDets); iod(); ++iod) {
00320 (*a)[count++] = iod.min();
00321 (*a)[count++] = iod.max();
00322 }
00323 return s << a;
00324 }
00325
00326 template <class View0, class View1>
00327 void
00328 IntersectionN<View0,View1>::post(Space* home,
00329 Reflection::VarMap& vars,
00330 const Reflection::ActorSpec& spec) {
00331 spec.checkArity(3);
00332 ViewArray<View0> x0(home, vars, spec[0]);
00333 View1 x1(home, vars, spec[1]);
00334 Reflection::IntArrayArgRanges zr(spec[2]->toIntArray());
00335 IntSet z(zr);
00336 (void) new (home) IntersectionN(home,x0,z,x1);
00337 }
00338
00339 template <class View0, class View1>
00340 ExecStatus
00341 IntersectionN<View0,View1>::propagate(Space* home, ModEventDelta) {
00342
00343 bool repeat = false;
00344 do {
00345 repeat = false;
00346 int xsize = x.size();
00347 if (xsize == 0)
00348 goto size0;
00349 for (int i = xsize; i--; ) {
00350 GECODE_ME_CHECK( y.cardMax(home,x[i].cardMax()) );
00351 GECODE_ME_CHECK( x[i].cardMin(home,y.cardMin()) );
00352 if (x[i].cardMax()==0) {
00353 GECODE_ME_CHECK( y.cardMax(home, 0));
00354 intOfDets.dispose(home);
00355 return ES_SUBSUMED(this,home);
00356 }
00357 }
00358 {
00359 GECODE_AUTOARRAY(GlbRanges<View0>,xLBs,xsize);
00360 GECODE_AUTOARRAY(LubRanges<View0>,xUBs,xsize);
00361 for (int i = xsize; i--; ) {
00362 GlbRanges<View0> lb(x[i]);
00363 LubRanges<View0> ub(x[i]);
00364 xLBs[i]=lb;
00365 xUBs[i]=ub;
00366 }
00367 Iter::Ranges::NaryInter<GlbRanges<View0> > lbi(xLBs,xsize);
00368 BndSetRanges dets1(intOfDets);
00369 Iter::Ranges::Inter< Iter::Ranges::NaryInter<GlbRanges<View0> >,
00370 BndSetRanges >
00371 lbiAll(lbi,dets1);
00372 GECODE_ME_CHECK( y.includeI(home,lbiAll) );
00373
00374 Iter::Ranges::NaryInter<LubRanges<View0> > ubi(xUBs,xsize);
00375 BndSetRanges dets2(intOfDets);
00376 Iter::Ranges::Inter< Iter::Ranges::NaryInter<LubRanges<View0> >,
00377 BndSetRanges >
00378 ubiAll(ubi,dets2);
00379 GECODE_ME_CHECK( y.intersectI(home,ubiAll) );
00380 }
00381
00382 for (int i = xsize; i--; ) {
00383 GlbRanges<View1> ylb(y);
00384 GECODE_ME_CHECK( x[i].includeI(home,ylb) );
00385 }
00386
00387
00388 {
00389 GECODE_AUTOARRAY(GLBndSet, rightSet, xsize);
00390 new (&rightSet[xsize-1]) GLBndSet(home);
00391 rightSet[xsize-1].update(home,intOfDets);
00392 for (int i=xsize-1;i--;) {
00393 GlbRanges<View0> xilb(x[i+1]);
00394 BndSetRanges prev(rightSet[i+1]);
00395 Iter::Ranges::Inter<GlbRanges<View0>,
00396 BndSetRanges> inter(xilb,prev);
00397 new (&rightSet[i]) GLBndSet(home);
00398 rightSet[i].includeI(home,inter);
00399 }
00400
00401 LUBndSet leftAcc(home);
00402
00403 for (int i=0;i<xsize;i++) {
00404 BndSetRanges left(leftAcc);
00405 BndSetRanges right(rightSet[i]);
00406 Iter::Ranges::Inter<BndSetRanges,
00407 BndSetRanges> inter(left, right);
00408 LubRanges<View1> yub(y);
00409 Iter::Ranges::Diff<Iter::Ranges::Inter<BndSetRanges,
00410 BndSetRanges>, LubRanges<View1> >
00411 forbidden(inter, yub);
00412 GECODE_ME_CHECK( x[i].excludeI(home,forbidden) );
00413 GlbRanges<View0> xlb(x[i]);
00414 leftAcc.intersectI(home,xlb);
00415 }
00416 for (int i=xsize; i--;)
00417 rightSet[i].dispose(home);
00418 leftAcc.dispose(home);
00419 }
00420
00421
00422 for(int i=0;i<x.size();i++){
00423
00424 while (i<x.size() && x[i].assigned()) {
00425 GlbRanges<View0> det(x[i]);
00426 if (intOfDets.intersectI(home,det)) {repeat = true;}
00427 x.move_lst(i);
00428 if (intOfDets.size()==0) {
00429 GECODE_ME_CHECK( y.cardMax(home,0) );
00430 intOfDets.dispose(home);
00431 return ES_SUBSUMED(this,home);
00432 }
00433 }
00434 }
00435 size0:
00436 if (x.size()==0) {
00437 BndSetRanges all1(intOfDets);
00438 GECODE_ME_CHECK( y.intersectI(home,all1) );
00439 BndSetRanges all2(intOfDets);
00440 GECODE_ME_CHECK( y.includeI(home,all2) );
00441 intOfDets.dispose(home);
00442 return ES_SUBSUMED(this,home);
00443 }
00444
00445 } while (repeat);
00446
00447 return shared ? ES_NOFIX : ES_FIX;
00448 }
00449
00450 }}}
00451
00452