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