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 namespace Gecode { namespace Int { namespace Channel {
00043
00048 template <class View>
00049 class DomInfo {
00050 public:
00051 View view;
00052 unsigned int card;
00053 int min;
00054 int max;
00056 static DomInfo<View>* allocate(Space* home, int n);
00058 void init(View x, int n);
00060 void update(Space* home, bool share, DomInfo<View>& vcb);
00062 bool doval(void) const;
00064 bool dodom(void) const;
00066 void assigned(void);
00068 void removed(int i);
00070 void done(void);
00071 };
00072
00073 template <class View>
00074 forceinline DomInfo<View>*
00075 DomInfo<View>::allocate(Space* home, int n) {
00076 return static_cast<DomInfo<View>*>
00077 (home->alloc(n*sizeof(DomInfo<View>)));
00078 }
00079
00080 template <class View>
00081 forceinline void
00082 DomInfo<View>::init(View x, int n) {
00083 view = x;
00084 card = static_cast<unsigned int>(n);
00085 min = 0;
00086 max = n-1;
00087 }
00088
00089 template <class View>
00090 forceinline void
00091 DomInfo<View>::update(Space* home, bool share, DomInfo<View>& di) {
00092 view.update(home,share,di.view);
00093 card = di.card;
00094 min = di.min;
00095 max = di.max;
00096 }
00097
00098 template <class View>
00099 forceinline bool
00100 DomInfo<View>::doval(void) const {
00101 return (card != 1) && view.assigned();
00102 }
00103
00104 template <class View>
00105 forceinline bool
00106 DomInfo<View>::dodom(void) const {
00107 return card != view.size();
00108 }
00109
00110 template <class View>
00111 forceinline void
00112 DomInfo<View>::assigned(void) {
00113 card = 1;
00114 }
00115
00116 template <class View>
00117 forceinline void
00118 DomInfo<View>::removed(int i) {
00119 card--;
00120 if (i == min)
00121 min++;
00122 else if (i == max)
00123 max--;
00124 }
00125
00126 template <class View>
00127 forceinline void
00128 DomInfo<View>::done(void) {
00129 card = view.size();
00130 min = view.min();
00131 max = view.max();
00132 }
00133
00134
00135 template <class View>
00136 ExecStatus
00137 prop_dom(Space* home, int n, DomInfo<View>* x, DomInfo<View>* y,
00138 ProcessStack& ya) {
00139 for (int i = n; i--; )
00140
00141 if (x[i].dodom()) {
00142
00143 ViewRanges<View>
00144 xir(x[i].view);
00145 Iter::Ranges::ComplVal<ViewRanges<View> >
00146 xirc(x[i].min,x[i].max,xir);
00147 Iter::Ranges::ToValues<Iter::Ranges::ComplVal<ViewRanges<View> > >
00148 jv(xirc);
00149 while (jv()) {
00150
00151 int j = jv.val();
00152 ModEvent me = y[j].view.nq(home,i);
00153 if (me_failed(me))
00154 return ES_FAILED;
00155 if (me_modified(me)) {
00156 if (me == ME_INT_VAL) {
00157
00158 ya.push(j);
00159 } else {
00160
00161 y[j].removed(i);
00162 }
00163 }
00164 ++jv;
00165 }
00166
00167 x[i].done();
00168 }
00169 return ES_OK;
00170 }
00171
00172
00173
00174
00175
00176 template <class View, bool shared>
00177 forceinline
00178 Dom<View,shared>::Dom(Space* home, int n, DomInfo<View>* xy)
00179 : Base<DomInfo<View>,PC_INT_DOM>(home,n,xy) {}
00180
00181 template <class View, bool shared>
00182 forceinline
00183 Dom<View,shared>::Dom(Space* home, bool share, Dom<View,shared>& p)
00184 : Base<DomInfo<View>,PC_INT_DOM>(home,share,p) {}
00185
00186 template <class View, bool shared>
00187 Actor*
00188 Dom<View,shared>::copy(Space* home, bool share) {
00189 return new (home) Dom<View,shared>(home,share,*this);
00190 }
00191
00192 template <class View, bool shared>
00193 PropCost
00194 Dom<View,shared>::cost(ModEventDelta med) const {
00195 return (View::me(med) == ME_INT_VAL) ? PC_QUADRATIC_LO : PC_CUBIC_HI;
00196 }
00197
00198 template <class View, bool shared>
00199 Support::Symbol
00200 Dom<View,shared>::ati(void) {
00201 return Reflection::mangle<View>("Gecode::Int::Channel::Dom",shared);
00202 }
00203
00204 template <class View, bool shared>
00205 Reflection::ActorSpec
00206 Dom<View,shared>::spec(const Space* home, Reflection::VarMap& m) const {
00207 return Base<DomInfo<View>,PC_INT_DOM>::spec(home, m, ati());
00208 }
00209
00210 template <class View, bool shared>
00211 void
00212 Dom<View,shared>::post(Space* home, Reflection::VarMap& vars,
00213 const Reflection::ActorSpec& spec) {
00214 const int n = spec.noOfArgs();
00215 DomInfo<View>* vi
00216 = DomInfo<View>::allocate(home,n);
00217 for (int i=0; i<n; i++) {
00218 vi[i].init(View(home, vars, spec[i]),n/2);
00219 }
00220 (void) new (home) Dom<View,shared>(home,n/2,vi);
00221 }
00222
00223 template <class View, bool shared>
00224 ExecStatus
00225 Dom<View,shared>::propagate(Space* home, ModEventDelta med) {
00226 GECODE_AUTOSTACK(int,-1, xa, n);
00227 GECODE_AUTOSTACK(int,-1, ya, n);
00228
00229 DomInfo<View>* x = xy;
00230 DomInfo<View>* y = xy+n;
00231
00232 if (View::me(med) == ME_INT_VAL) {
00233
00234 for (int i = n; i--; ) {
00235 if (x[i].doval()) xa.push(i);
00236 if (y[i].doval()) ya.push(i);
00237 }
00238
00239 if (shared) {
00240 do {
00241
00242 GECODE_ES_CHECK((prop_val<View,DomInfo<View> >
00243 (home,n,x,y,n_na,xa,ya)));
00244
00245 GECODE_ES_CHECK((prop_val<View,DomInfo<View> >
00246 (home,n,y,x,n_na,ya,xa)));
00247 assert(ya.empty());
00248 } while (!xa.empty() || !ya.empty());
00249 return ES_NOFIX_PARTIAL(this,View::med(ME_INT_DOM));
00250 } else {
00251 do {
00252
00253 GECODE_ES_CHECK((prop_val<View,DomInfo<View> >
00254 (home,n,x,y,n_na,xa,ya)));
00255
00256 GECODE_ES_CHECK((prop_val<View,DomInfo<View> >
00257 (home,n,y,x,n_na,ya,xa)));
00258 assert(ya.empty());
00259 } while (!xa.empty());
00260 return ES_FIX_PARTIAL(this,View::med(ME_INT_DOM));
00261 }
00262 }
00263
00264
00265
00266
00267 GECODE_ES_CHECK(prop_dom(home,n,y,x,xa));
00268
00269
00270 GECODE_ES_CHECK((prop_val<View,DomInfo<View> >(home,n,x,y,n_na,xa,ya)));
00271
00272
00273 if (dc.available()) {
00274 GECODE_ES_CHECK(dc.sync());
00275 } else {
00276 GECODE_AUTOARRAY(View,xv,n);
00277 for (int i=n; i--; )
00278 xv[i] = x[i].view;
00279 GECODE_ES_CHECK(dc.init(home,n,&xv[0]));
00280 }
00281 bool assigned;
00282 GECODE_ES_CHECK(dc.propagate(home,assigned));
00283 if (assigned) {
00284
00285
00286
00287
00288 for (int i=n; i--; )
00289 if (x[i].doval()) {
00290 int j = x[i].view.val();
00291
00292 ModEvent me = y[j].view.eq(home,i);
00293 if (me_failed(me))
00294 return ES_FAILED;
00295 if (me_modified(me)) {
00296
00297 assert(me == ME_INT_VAL);
00298
00299 ya.push(j);
00300 }
00301 x[i].assigned(); n_na--;
00302 }
00303 }
00304
00305
00306
00307
00308 GECODE_ES_CHECK(prop_dom(home,n,x,y,ya));
00309
00310
00311 while (!xa.empty() || !ya.empty()) {
00312
00313 GECODE_ES_CHECK((prop_val<View,DomInfo<View> >(home,n,x,y,n_na,xa,ya)));
00314
00315 GECODE_ES_CHECK((prop_val<View,DomInfo<View> >(home,n,y,x,n_na,ya,xa)));
00316 };
00317
00318 if (shared) {
00319 for (int i=2*n; i--; )
00320 if (!xy[i].view.assigned())
00321 return ES_NOFIX;
00322 return ES_SUBSUMED(this,home);
00323 } else {
00324 return (n_na == 0) ? ES_SUBSUMED(this,home) : ES_FIX;
00325 }
00326 }
00327
00328 template <class View, bool shared>
00329 ExecStatus
00330 Dom<View,shared>::post(Space* home, int n, DomInfo<View>* xy) {
00331 assert(n > 0);
00332 if (n == 1) {
00333 GECODE_ME_CHECK(xy[0].view.eq(home,0));
00334 GECODE_ME_CHECK(xy[1].view.eq(home,0));
00335 return ES_OK;
00336 }
00337 for (int i=2*n; i--; ) {
00338 GECODE_ME_CHECK(xy[i].view.gq(home,0));
00339 GECODE_ME_CHECK(xy[i].view.le(home,n));
00340 }
00341 (void) new (home) Dom<View,shared>(home,n,xy);
00342 return ES_OK;
00343 }
00344
00345 }}}
00346
00347
00348