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 namespace Gecode { namespace Set { namespace RelOp {
00029
00030
00031
00032
00033
00034
00035 template <class View0, class View1, class View2> ExecStatus
00036 Intersection<View0,View1,View2>::post(Space* home,
00037 View0 x0,View1 x1,View2 x2) {
00038 (void) new (home) Intersection<View0,View1,View2>(home,x0,x1,x2);
00039 return ES_OK;
00040 }
00041
00042 template <class View0, class View1, class View2>
00043 Actor*
00044 Intersection<View0,View1,View2>::copy(Space* home, bool share) {
00045 return new (home) Intersection(home,share,*this);
00046 }
00047
00048
00049 template <class View0, class View1, class View2>
00050 ExecStatus
00051 Intersection<View0,View1,View2>::propagate(Space* home) {
00052
00053 bool x0ass=x0.assigned();
00054 bool x1ass=x1.assigned();
00055 bool x2ass=x2.assigned();
00056
00057 {
00058 GlbRanges<View2> x2lb(x2);
00059 GECODE_ME_CHECK( x0.includeI(home,x2lb) );
00060 }
00061 {
00062 GlbRanges<View2> x2lb(x2);
00063 GECODE_ME_CHECK( x1.includeI(home,x2lb) );
00064 }
00065 {
00066 GlbRanges<View0> x0lb(x0);
00067 LubRanges<View2> x2ub(x2);
00068 Iter::Ranges::Diff<GlbRanges<View0>,LubRanges<View2> > m1(x0lb,x2ub);
00069 GECODE_ME_CHECK( x1.excludeI(home,m1) );
00070 }
00071 {
00072 GlbRanges<View1> x1lb(x1);
00073 LubRanges<View2> x2ub(x2);
00074
00075 Iter::Ranges::Diff<GlbRanges<View1>,LubRanges<View2> > m2(x1lb,x2ub);
00076 GECODE_ME_CHECK( x0.excludeI(home,m2) );
00077 }
00078 {
00079 GlbRanges<View0> x0lb(x0);
00080 GlbRanges<View1> x1lb(x1);
00081 Iter::Ranges::Inter<GlbRanges<View0>,GlbRanges<View1> > i1(x0lb,x1lb);
00082 GECODE_ME_CHECK( x2.includeI(home,i1) );
00083 }
00084 {
00085 LubRanges<View0> x0ub(x0);
00086 LubRanges<View1> x1ub(x1);
00087 Iter::Ranges::Inter<LubRanges<View0>,LubRanges<View1> > i2(x0ub,x1ub);
00088 GECODE_ME_CHECK( x2.intersectI(home,i2) );
00089 }
00090 unsigned int m, n;
00091 {
00092 LubRanges<View0> x0ub(x0);
00093 LubRanges<View1> x1ub(x1);
00094 Iter::Ranges::Union<LubRanges<View0>,LubRanges<View1> > u1(x0ub,x1ub);
00095 m = Iter::Ranges::size(u1);
00096 n = x0.cardMin()+x1.cardMin();
00097 if (n>m)
00098 GECODE_ME_CHECK( x2.cardMin(home,n-m) );
00099 }
00100 unsigned int s2;
00101 {
00102 LubRanges<View0> x0ub(x0);
00103 GlbRanges<View1> x1lb(x1);
00104 Iter::Ranges::Diff<GlbRanges<View1>,LubRanges<View0> > d2(x1lb,x0ub);
00105 s2 = Iter::Ranges::size(d2);
00106 assert (s2 <= x1.cardMax());
00107 GECODE_ME_CHECK( x2.cardMax(home,x1.cardMax()-s2) );
00108 }
00109 {
00110 LubRanges<View1> x1ub(x1);
00111 GlbRanges<View0> x0lb(x0);
00112 Iter::Ranges::Diff<GlbRanges<View0>,LubRanges<View1> > d1 (x0lb,x1ub);
00113 unsigned int s1 = Iter::Ranges::size(d1);
00114 assert (s1 <= x0.cardMax());
00115 GECODE_ME_CHECK( x2.cardMax(home,x0.cardMax()-s1) );
00116 if (m+x2.cardMax() > x1.cardMin())
00117 GECODE_ME_CHECK( x0.cardMax(home,m+x2.cardMax()-x1.cardMin()) );
00118
00119 if (m+x2.cardMax() > x0.cardMin())
00120 GECODE_ME_CHECK( x1.cardMax(home,m+x2.cardMax()-x0.cardMin()) );
00121
00122 GECODE_ME_CHECK( x0.cardMin(home,s1+x2.cardMin()) );
00123 GECODE_ME_CHECK( x1.cardMin(home,s2+x2.cardMin()) );
00124 }
00125 if ( x0ass + x1ass + x2ass >= 2 ) return ES_SUBSUMED;
00126
00127 return ES_NOFIX;
00128 }
00129
00130 template <class View0, class View1, class View2>
00131 forceinline
00132 Intersection<View0,View1,View2>::Intersection(Space* home,
00133 View0 y0,View1 y1,View2 y2)
00134 : InhomTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00135 View2,PC_SET_ANY>(home,y0,y1,y2) {}
00136
00137 template <class View0, class View1, class View2>
00138 forceinline
00139 Intersection<View0,View1,View2>::Intersection(Space* home, bool share,
00140 Intersection<View0,View1,View2>& p)
00141 : InhomTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00142 View2,PC_SET_ANY>(home,share,p) {}
00143
00144
00145
00146
00147
00148
00149 template <class View0, class View1>
00150 forceinline
00151 IntersectionN<View0,View1>::IntersectionN(Space* home, ViewArray<View0>& x,
00152 View1 y)
00153 : InhomNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,x,y),
00154 intOfDets(home) {
00155 shared = x.shared() || viewarrayshared(x,y);
00156 }
00157
00158 template <class View0, class View1>
00159 forceinline
00160 IntersectionN<View0,View1>::IntersectionN(Space* home, bool share,
00161 IntersectionN& p)
00162 : InhomNaryOnePropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,share,p),
00163 shared(p.shared),
00164 intOfDets() {
00165 intOfDets.update(home, p.intOfDets);
00166 }
00167
00168 template <class View0, class View1>
00169 ExecStatus
00170 IntersectionN<View0,View1>::post(Space* home,
00171 ViewArray<View0>& x, View1 y) {
00172 switch (x.size()) {
00173 case 0:
00174 GECODE_ME_CHECK(y.cardMin(home, Limits::Set::card_max));
00175 return ES_OK;
00176 case 1:
00177 return Rel::Eq<View0,View1>::post(home, x[0], y);
00178 case 2:
00179 return Intersection<View0,View0,View1>::post(home, x[0], x[1], y);
00180 default:
00181 (void) new (home) IntersectionN<View0,View1>(home,x,y);
00182 return ES_OK;
00183 }
00184 }
00185
00186 template <class View0, class View1>
00187 Actor*
00188 IntersectionN<View0,View1>::copy(Space* home, bool share) {
00189 return new (home) IntersectionN<View0,View1>(home,share,*this);
00190 }
00191
00192 template <class View0, class View1>
00193 PropCost
00194 IntersectionN<View0,View1>::cost(void) const {
00195 return PC_QUADRATIC_LO;
00196 }
00197
00198 template <class View0, class View1>
00199 ExecStatus
00200 IntersectionN<View0,View1>::propagate(Space* home) {
00201
00202 bool repeat = false;
00203 do {
00204 repeat = false;
00205 int xsize = x.size();
00206
00207 for (int i = xsize; i--; ) {
00208 GECODE_ME_CHECK( y.cardMax(home,x[i].cardMax()) );
00209 GECODE_ME_CHECK( x[i].cardMin(home,y.cardMin()) );
00210 if (x[i].cardMax()==0) {
00211 GECODE_ME_CHECK( y.exclude(home,
00212 Limits::Set::int_min,
00213 Limits::Set::int_max) );
00214 intOfDets.dispose(home);
00215 return ES_SUBSUMED;
00216 }
00217 }
00218 {
00219 GECODE_AUTOARRAY(GlbRanges<View0>,xLBs,xsize);
00220 GECODE_AUTOARRAY(LubRanges<View0>,xUBs,xsize);
00221 for (int i = xsize; i--; ) {
00222 GlbRanges<View0> lb(x[i]);
00223 LubRanges<View0> ub(x[i]);
00224 xLBs[i]=lb;
00225 xUBs[i]=ub;
00226 }
00227 Iter::Ranges::NaryInter<GlbRanges<View0> > lbi(xLBs,xsize);
00228 BndSetRanges dets1(intOfDets);
00229 Iter::Ranges::Inter< Iter::Ranges::NaryInter<GlbRanges<View0> >,
00230 BndSetRanges >
00231 lbiAll(lbi,dets1);
00232 GECODE_ME_CHECK( y.includeI(home,lbiAll) );
00233
00234 Iter::Ranges::NaryInter<LubRanges<View0> > ubi(xUBs,xsize);
00235 BndSetRanges dets2(intOfDets);
00236 Iter::Ranges::Inter< Iter::Ranges::NaryInter<LubRanges<View0> >,
00237 BndSetRanges >
00238 ubiAll(ubi,dets2);
00239 GECODE_ME_CHECK( y.intersectI(home,ubiAll) );
00240 }
00241
00242 for (int i = xsize; i--; ) {
00243 GlbRanges<View1> ylb(y);
00244 GECODE_ME_CHECK( x[i].includeI(home,ylb) );
00245 }
00246
00247
00248 {
00249 GECODE_AUTOARRAY(GLBndSet, rightSet, xsize);
00250 rightSet[xsize-1].init(home);
00251 rightSet[xsize-1].update(home,intOfDets);
00252 for (int i=xsize-1;i--;) {
00253 GlbRanges<View0> xilb(x[i+1]);
00254 BndSetRanges prev(rightSet[i+1]);
00255 Iter::Ranges::Inter<GlbRanges<View0>,
00256 BndSetRanges> inter(xilb,prev);
00257 rightSet[i].init(home);
00258 rightSet[i].includeI(home,inter);
00259 }
00260
00261 LUBndSet leftAcc(home);
00262
00263 for (int i=0;i<xsize;i++) {
00264 BndSetRanges left(leftAcc);
00265 BndSetRanges right(rightSet[i]);
00266 Iter::Ranges::Inter<BndSetRanges,
00267 BndSetRanges> inter(left, right);
00268 LubRanges<View1> yub(y);
00269 Iter::Ranges::Diff<Iter::Ranges::Inter<BndSetRanges,
00270 BndSetRanges>, LubRanges<View1> >
00271 forbidden(inter, yub);
00272 GECODE_ME_CHECK( x[i].excludeI(home,forbidden) );
00273 GlbRanges<View0> xlb(x[i]);
00274 leftAcc.intersectI(home,xlb);
00275 }
00276 for (int i=xsize; i--;)
00277 rightSet[i].dispose(home);
00278 leftAcc.dispose(home);
00279 }
00280
00281
00282 for(int i=0;i<x.size();i++){
00283
00284 while (i<x.size() && x[i].assigned()) {
00285 GlbRanges<View0> det(x[i]);
00286 if (intOfDets.intersectI(home,det)) {repeat = true;}
00287 x.move_lst(i);
00288 if (intOfDets.size()==0) {
00289 GECODE_ME_CHECK( y.exclude(home,Limits::Set::int_min,
00290 Limits::Set::int_max) );
00291 intOfDets.dispose(home);
00292 return ES_SUBSUMED;
00293 }
00294 }
00295 }
00296 if (x.size()==0) {
00297 BndSetRanges all1(intOfDets);
00298 GECODE_ME_CHECK( y.intersectI(home,all1) );
00299 BndSetRanges all2(intOfDets);
00300 GECODE_ME_CHECK( y.includeI(home,all2) );
00301 intOfDets.dispose(home);
00302 return ES_SUBSUMED;
00303 }
00304
00305 } while (repeat);
00306
00307 return shared ? ES_NOFIX : ES_FIX;
00308 }
00309
00310 }}}
00311
00312