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 namespace Gecode { namespace Int { namespace Element {
00039
00049 class IdxValLink {
00050 public:
00051 IdxValLink* idx_next;
00052 IdxValLink* val_next;
00053 int idx, val;
00054
00055 void mark(void);
00056 bool marked(void) const;
00057 };
00058
00059 forceinline void
00060 IdxValLink::mark(void) {
00061 idx = -1;
00062 }
00063 forceinline bool
00064 IdxValLink::marked(void) const {
00065 return idx<0;
00066 }
00067
00068
00069
00076 class IterIdx {
00077 private:
00078 IdxValLink* l;
00079 public:
00080 IterIdx(void);
00081 IterIdx(IdxValLink&);
00082 void init(IdxValLink&);
00083 bool operator()(void) const;
00084 void operator++(void);
00085 int val(void) const;
00086 };
00087
00088 forceinline
00089 IterIdx::IterIdx(void) {}
00090 forceinline
00091 IterIdx::IterIdx(IdxValLink& ivl) {
00092 IdxValLink* p=&ivl;
00093 l = p->idx_next;
00094 while ((l != NULL) && l->marked())
00095 l=l->idx_next;
00096 p->idx_next=l;
00097 }
00098 forceinline void
00099 IterIdx::init(IdxValLink& ivl) {
00100 IdxValLink* p=&ivl;
00101 l = p->idx_next;
00102 while ((l != NULL) && l->marked())
00103 l=l->idx_next;
00104 p->idx_next=l;
00105 }
00106 forceinline bool
00107 IterIdx::operator()(void) const {
00108 return l != NULL;
00109 }
00110 forceinline void
00111 IterIdx::operator++(void) {
00112 IdxValLink* p=l;
00113 l = p->idx_next;
00114 while ((l != NULL) && l->marked())
00115 l=l->idx_next;
00116 p->idx_next=l;
00117 }
00118 forceinline int
00119 IterIdx::val(void) const {
00120 assert(!l->marked());
00121 return l->idx;
00122 }
00123
00124
00125
00132 class IterVal {
00133 private:
00134 const IdxValLink* l;
00135 public:
00136 IterVal(void);
00137 IterVal(const IdxValLink&);
00138 void init(const IdxValLink&);
00139 bool operator()(void) const;
00140 void operator++(void);
00141 int val(void) const;
00142 };
00143
00144 forceinline
00145 IterVal::IterVal(void) {}
00146 forceinline
00147 IterVal::IterVal(const IdxValLink& ivl)
00148 : l(ivl.val_next) {}
00149 forceinline void
00150 IterVal::init(const IdxValLink& ivl) {
00151 l = ivl.val_next;
00152 }
00153 forceinline bool
00154 IterVal::operator()(void) const {
00155 return l != NULL;
00156 }
00157 forceinline void
00158 IterVal::operator++(void) {
00159 l=l->val_next;
00160 }
00161 forceinline int
00162 IterVal::val(void) const {
00163 assert(!l->marked());
00164 return l->val;
00165 }
00166
00167
00168
00169
00174 class IdxValMap {
00175 private:
00177 class ByVal {
00178 public:
00179 bool operator()(IdxValLink*&, IdxValLink*&);
00180 };
00181 size_t _size;
00182 IdxValLink iv[1];
00183 public:
00185 static IdxValMap* allocate(int);
00186 template <class ViewA> void init(int*,ViewA);
00187
00189 template <class ViewA> void prune_idx(ViewA);
00190 template <class ViewB> void prune_val(ViewB);
00191
00193 template <class ViewA, class ViewB>
00194 ExecStatus tell(Space*,ViewA,ViewB);
00195
00196 size_t size(void) const;
00197 static void operator delete(void* p,size_t);
00198 private:
00199 static void* operator new(size_t);
00200 };
00201
00202 forceinline bool
00203 IdxValMap::ByVal::operator()(IdxValLink*& x, IdxValLink*& y) {
00204 return x->val < y->val;
00205 }
00206
00207 forceinline IdxValMap*
00208 IdxValMap::allocate(int n) {
00209 size_t s = sizeof(IdxValMap)+n*sizeof(IdxValLink);
00210 IdxValMap* ivm = static_cast<IdxValMap*>(Memory::malloc(s));
00211 ivm->_size = s;
00212 return ivm;
00213 }
00214
00215 forceinline size_t
00216 IdxValMap::size(void) const {
00217 return _size;
00218 }
00219
00220 template <class ViewA>
00221 inline void
00222 IdxValMap::init(int* a, ViewA ix) {
00223
00224
00225 IdxValLink* by_idx = &iv[1];
00226 {
00227 int i = 0;
00228 ViewValues<ViewA> v(ix);
00229 while (v()) {
00230 by_idx[i].idx = v.val();
00231 by_idx[i].val = a[v.val()];
00232 ++i; ++v;
00233 }
00234 }
00235 int size = ix.size();
00236
00237 GECODE_AUTOARRAY(IdxValLink*,by_val,size);
00238 for (int i = size; i--; )
00239 by_val[i] = &iv[i+1];
00240 ByVal lt;
00241 Support::quicksort<IdxValLink*>(by_val,size,lt);
00242
00243 for (int i = size-1; i--; ) {
00244 by_idx[i].idx_next = by_idx+i+1;
00245 by_val[i]->val_next = by_val[i+1];
00246 }
00247 by_idx[size-1].idx_next = NULL;
00248 by_val[size-1]->val_next = NULL;
00249
00250 iv[0].idx_next = &by_idx[0];
00251 iv[0].val_next = by_val[0];
00252 }
00253
00254 template <class ViewA>
00255 forceinline void
00256 IdxValMap::prune_idx(ViewA x0) {
00257 IdxValLink* p = &iv[0];
00258 IdxValLink* l = p->idx_next;
00259 ViewRanges<ViewA> i(x0);
00260 while (i() && (l != NULL)) {
00261 assert(!l->marked());
00262 if (l->idx < i.min()) {
00263 l->mark(); l=l->idx_next; p->idx_next=l;
00264 } else if (l->idx > i.max()) {
00265 ++i;
00266 } else {
00267 p=l; l=l->idx_next;
00268 }
00269 }
00270 p->idx_next = NULL;
00271 while (l != NULL) { l->mark(); l=l->idx_next; }
00272 }
00273
00274 template <class ViewB>
00275 forceinline void
00276 IdxValMap::prune_val(ViewB x1) {
00277 IdxValLink* p = &iv[0];
00278 IdxValLink* l = p->val_next;
00279 ViewRanges<ViewB> v(x1);
00280 while (v() && (l != NULL)) {
00281 if (l->marked()) {
00282 l=l->val_next; p->val_next=l;
00283 } else if (l->val < v.min()) {
00284 l->mark(); l=l->val_next; p->val_next=l;
00285 } else if (l->val > v.max()) {
00286 ++v;
00287 } else {
00288 p=l; l=l->val_next;
00289 }
00290 }
00291 p->val_next = NULL;
00292 while (l != NULL) { l->mark(); l=l->val_next; }
00293 }
00294
00295 template <class ViewA, class ViewB>
00296 forceinline ExecStatus
00297 IdxValMap::tell(Space* home, ViewA x0, ViewB x1) {
00298 IterIdx i(iv[0]);
00299 GECODE_ME_CHECK(x0.narrow_v(home,i,false));
00300 IterVal v(iv[0]);
00301 if (shared(x0,x1)) {
00302 GECODE_ME_CHECK(x1.inter_v(home,v,false));
00303 return ES_NOFIX;
00304 } else {
00305 GECODE_ME_CHECK(x1.narrow_v(home,v,false));
00306 return ES_FIX;
00307 }
00308 }
00309
00310 forceinline void
00311 IdxValMap::operator delete(void* p,size_t) {
00312 Memory::free(p);
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 template <class ViewA, class ViewB>
00325 forceinline
00326 Int<ViewA,ViewB>::Int(Space* home, IntSharedArray& c0, ViewA y0, ViewB y1)
00327 : Propagator(home), x0(y0), x1(y1), c(c0), ivm(NULL) {
00328 force(home);
00329 x0.subscribe(home,this,PC_INT_DOM);
00330 x1.subscribe(home,this,PC_INT_DOM);
00331 }
00332
00333 template <class ViewA, class ViewB>
00334 forceinline size_t
00335 Int<ViewA,ViewB>::dispose(Space* home) {
00336 unforce(home);
00337 if (!home->failed()) {
00338 x0.cancel(home,this,PC_INT_DOM);
00339 x1.cancel(home,this,PC_INT_DOM);
00340 }
00341 c.~IntSharedArray();
00342 delete ivm;
00343 (void) Propagator::dispose(home);
00344 return sizeof(*this);
00345 }
00346
00347 template <class ViewA, class ViewB>
00348 ExecStatus
00349 Int<ViewA,ViewB>::post(Space* home, IntSharedArray& c, ViewA x0, ViewB x1) {
00350 GECODE_ME_CHECK(x0.gq(home,0));
00351 GECODE_ME_CHECK(x0.le(home,c.size()));
00352 if (x0.assigned()) {
00353 GECODE_ME_CHECK(x1.eq(home,c[x0.val()]));
00354 } else {
00355 (void) new (home) Int<ViewA,ViewB>(home,c,x0,x1);
00356 }
00357 return ES_OK;
00358 }
00359
00360
00361 template <class ViewA, class ViewB>
00362 size_t
00363 Int<ViewA,ViewB>::allocated(void) const {
00364 return (ivm != NULL) ? ivm->size() : 0;
00365 }
00366
00367 template <class ViewA, class ViewB>
00368 forceinline
00369 Int<ViewA,ViewB>::Int(Space* home, bool share, Int& p)
00370 : Propagator(home,share,p), ivm(NULL) {
00371 c.update(home,share,p.c);
00372 x0.update(home,share,p.x0);
00373 x1.update(home,share,p.x1);
00374 }
00375
00376 template <class ViewA, class ViewB>
00377 Actor*
00378 Int<ViewA,ViewB>::copy(Space* home, bool share) {
00379 return new (home) Int<ViewA,ViewB>(home,share,*this);
00380 }
00381
00382 template <class ViewA, class ViewB>
00383 PropCost
00384 Int<ViewA,ViewB>::cost(ModEventDelta) const {
00385 return PC_BINARY_HI;
00386 }
00387
00388 template <class ViewA, class ViewB>
00389 inline Support::Symbol
00390 Int<ViewA,ViewB>::ati(void) {
00391 return Reflection::mangle<ViewA,ViewB>("Gecode::Int::Element::Int");
00392 }
00393
00394 template <class ViewA, class ViewB>
00395 Reflection::ActorSpec
00396 Int<ViewA,ViewB>::spec(const Space* home, Reflection::VarMap& m) const {
00397 Reflection::ActorSpec s(ati());
00398 return s << x0.spec(home, m)
00399 << x1.spec(home, m)
00400 << Reflection::Arg::newIntArray(c);
00401 }
00402
00403 template <class ViewA, class ViewB>
00404 void
00405 Int<ViewA,ViewB>::post(Space* home, Reflection::VarMap& vars,
00406 const Reflection::ActorSpec& spec) {
00407 spec.checkArity(3);
00408 ViewA x0(home, vars, spec[0]);
00409 ViewB x1(home, vars, spec[1]);
00410 Reflection::IntArrayArg* a = spec[2]->toIntArray();
00411 IntSharedArray is(a->size());
00412 for (int i=a->size(); i--; ) {
00413 is[i] = (*a)[i];
00414 }
00415 (void) new (home) Int<ViewA,ViewB>(home, is, x0, x1);
00416 }
00417
00418 template <class ViewA, class ViewB>
00419 ExecStatus
00420 Int<ViewA,ViewB>::propagate(Space* home, ModEventDelta) {
00421 bool assigned = x0.assigned() && x1.assigned();
00422 if (ivm == NULL) {
00423 ivm = IdxValMap::allocate(x0.size());
00424 ivm->init(&c[0],x0);
00425 } else {
00426 ivm->prune_idx(x0);
00427 }
00428 ivm->prune_val(x1);
00429
00430 ExecStatus es = ivm->tell(home,x0,x1);
00431 if (es == ES_FAILED)
00432 return es;
00433 if (es == ES_NOFIX)
00434 return assigned ? ES_SUBSUMED(this,home) : ES_NOFIX;
00435
00436 return (x0.assigned() || x1.assigned()) ?
00437 ES_SUBSUMED(this,home) : es;
00438 }
00439
00440 }}}
00441
00442
00443
00444