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
00040
00041
00042 template <class V0, class V1, class Idx, class Val>
00043 forceinline void
00044 Int<V0,V1,Idx,Val>::IdxVal::mark(void) {
00045 idx = -1;
00046 }
00047 template <class V0, class V1, class Idx, class Val>
00048 forceinline bool
00049 Int<V0,V1,Idx,Val>::IdxVal::marked(void) const {
00050 return idx<0;
00051 }
00052
00053
00054 template <class V0, class V1, class Idx, class Val>
00055 forceinline
00056 Int<V0,V1,Idx,Val>::IterIdx::IterIdx(IdxVal* iv0)
00057 : iv(iv0) {
00058 Idx p=0;
00059 i = iv[p].idx_next;
00060 while ((i != 0) && iv[i].marked())
00061 i=iv[i].idx_next;
00062 iv[p].idx_next=i;
00063 }
00064 template <class V0, class V1, class Idx, class Val>
00065 forceinline bool
00066 Int<V0,V1,Idx,Val>::IterIdx::operator ()(void) const {
00067 return i != 0;
00068 }
00069 template <class V0, class V1, class Idx, class Val>
00070 forceinline void
00071 Int<V0,V1,Idx,Val>::IterIdx::operator ++(void) {
00072 int p=i;
00073 i = iv[p].idx_next;
00074 while ((i != 0) && iv[i].marked())
00075 i=iv[i].idx_next;
00076 iv[p].idx_next=i;
00077 }
00078 template <class V0, class V1, class Idx, class Val>
00079 forceinline Idx
00080 Int<V0,V1,Idx,Val>::IterIdx::val(void) const {
00081 assert(!iv[i].marked());
00082 return iv[i].idx;
00083 }
00084
00085
00086
00087 template <class V0, class V1, class Idx, class Val>
00088 forceinline
00089 Int<V0,V1,Idx,Val>::IterVal::IterVal(IdxVal* iv0)
00090 : iv(iv0), i(iv[0].val_next) {}
00091 template <class V0, class V1, class Idx, class Val>
00092 forceinline bool
00093 Int<V0,V1,Idx,Val>::IterVal::operator ()(void) const {
00094 return i != 0;
00095 }
00096 template <class V0, class V1, class Idx, class Val>
00097 forceinline void
00098 Int<V0,V1,Idx,Val>::IterVal::operator ++(void) {
00099 i=iv[i].val_next;
00100 }
00101 template <class V0, class V1, class Idx, class Val>
00102 forceinline Val
00103 Int<V0,V1,Idx,Val>::IterVal::val(void) const {
00104 assert(!iv[i].marked());
00105 return iv[i].val;
00106 }
00107
00108
00109
00110
00111 template <class V0, class V1, class Idx, class Val>
00112 forceinline
00113 Int<V0,V1,Idx,Val>::ByVal::ByVal(const IdxVal* iv0)
00114 : iv(iv0) {}
00115 template <class V0, class V1, class Idx, class Val>
00116 forceinline bool
00117 Int<V0,V1,Idx,Val>::ByVal::operator ()(Idx& i, Idx& j) {
00118 return iv[i].val < iv[j].val;
00119 }
00120
00121
00122
00123
00124
00125
00126 template <class V0, class V1, class Idx, class Val>
00127 forceinline
00128 Int<V0,V1,Idx,Val>::Int(Space& home, IntSharedArray& c0, V0 y0, V1 y1)
00129 : Propagator(home), x0(y0), x1(y1), c(c0), iv(NULL) {
00130 home.notice(*this,AP_DISPOSE);
00131 x0.subscribe(home,*this,PC_INT_DOM);
00132 x1.subscribe(home,*this,PC_INT_DOM);
00133 }
00134
00135 template <class V0, class V1, class Idx, class Val>
00136 forceinline size_t
00137 Int<V0,V1,Idx,Val>::dispose(Space& home) {
00138 home.ignore(*this,AP_DISPOSE);
00139 if (!home.failed()) {
00140 x0.cancel(home,*this,PC_INT_DOM);
00141 x1.cancel(home,*this,PC_INT_DOM);
00142 }
00143 c.~IntSharedArray();
00144 (void) Propagator::dispose(home);
00145 return sizeof(*this);
00146 }
00147
00148 template <class V0, class V1, class Idx, class Val>
00149 ExecStatus
00150 Int<V0,V1,Idx,Val>::post(Space& home, IntSharedArray& c, V0 x0, V1 x1) {
00151 GECODE_ME_CHECK(x0.gq(home,0));
00152 GECODE_ME_CHECK(x0.le(home,c.size()));
00153 if (x0.assigned()) {
00154 GECODE_ME_CHECK(x1.eq(home,c[x0.val()]));
00155 } else {
00156 (void) new (home) Int<V0,V1,Idx,Val>(home,c,x0,x1);
00157 }
00158 return ES_OK;
00159 }
00160
00161 template <class V0, class V1, class Idx, class Val>
00162 forceinline
00163 Int<V0,V1,Idx,Val>::Int(Space& home, bool share, Int& p)
00164 : Propagator(home,share,p), iv(NULL) {
00165 c.update(home,share,p.c);
00166 x0.update(home,share,p.x0);
00167 x1.update(home,share,p.x1);
00168 }
00169
00170 template <class V0, class V1, class Idx, class Val>
00171 Actor*
00172 Int<V0,V1,Idx,Val>::copy(Space& home, bool share) {
00173 return new (home) Int<V0,V1,Idx,Val>(home,share,*this);
00174 }
00175
00176 template <class V0, class V1, class Idx, class Val>
00177 PropCost
00178 Int<V0,V1,Idx,Val>::cost(const Space&, const ModEventDelta&) const {
00179 return PropCost::binary(PropCost::HI);
00180 }
00181
00182 template <class V0, class V1, class Idx, class Val>
00183 ExecStatus
00184 Int<V0,V1,Idx,Val>::propagate(Space& home, const ModEventDelta&) {
00185 bool assigned = x0.assigned() && x1.assigned();
00186 if (iv == NULL) {
00187
00188 iv = home.alloc<IdxVal>(x0.size() + 1);
00189
00190
00191
00192 IdxVal* by_idx = &iv[1];
00193 {
00194 Idx i = 0;
00195 ViewValues<V0> v(x0);
00196 while (v()) {
00197 by_idx[i].idx = static_cast<Idx>(v.val());
00198 by_idx[i].val = static_cast<Val>(c[v.val()]);
00199 ++i; ++v;
00200 }
00201 }
00202 Idx size = static_cast<Idx>(x0.size());
00203
00204 Region r(home);
00205 Idx* by_val = r.alloc<Idx>(size);
00206 for (Idx i = size; i--; )
00207 by_val[i] = i+1;
00208 ByVal less(iv);
00209 Support::quicksort<Idx>(by_val,size,less);
00210
00211 for (Idx i = size-1; i--; ) {
00212 by_idx[i].idx_next = i+2;
00213 iv[by_val[i]].val_next = by_val[i+1];
00214 }
00215 by_idx[size-1].idx_next = 0;
00216 iv[by_val[size-1]].val_next = 0;
00217
00218 iv[0].idx_next = 1;
00219 iv[0].val_next = by_val[0];
00220 } else {
00221
00222 Idx p = 0;
00223 Idx i = iv[p].idx_next;
00224 ViewRanges<V0> v(x0);
00225 while (v() && (i != 0)) {
00226 assert(!iv[i].marked());
00227 if (iv[i].idx < v.min()) {
00228 iv[i].mark(); i=iv[i].idx_next; iv[p].idx_next=i;
00229 } else if (iv[i].idx > v.max()) {
00230 ++v;
00231 } else {
00232 p=i; i=iv[i].idx_next;
00233 }
00234 }
00235 iv[p].idx_next = 0;
00236 while (i != 0) { iv[i].mark(); i=iv[i].idx_next; }
00237 }
00238
00239
00240 {
00241 Idx p = 0;
00242 Idx i = iv[p].val_next;
00243 ViewRanges<V1> v(x1);
00244 while (v() && (i != 0)) {
00245 if (iv[i].marked()) {
00246 i=iv[i].val_next; iv[p].val_next=i;
00247 } else if (iv[i].val < v.min()) {
00248 iv[i].mark(); i=iv[i].val_next; iv[p].val_next=i;
00249 } else if (iv[i].val > v.max()) {
00250 ++v;
00251 } else {
00252 p=i; i=iv[i].val_next;
00253 }
00254 }
00255 iv[p].val_next = 0;
00256 while (i != 0) { iv[i].mark(); i=iv[i].val_next; }
00257 }
00258
00259
00260 {
00261 IterIdx i(iv);
00262 GECODE_ME_CHECK(x0.narrow_v(home,i,false));
00263 IterVal v(iv);
00264 if (shared(x0,x1)) {
00265 GECODE_ME_CHECK(x1.inter_v(home,v,false));
00266 return assigned ? ES_SUBSUMED(*this,home) : ES_NOFIX;
00267 } else {
00268 GECODE_ME_CHECK(x1.narrow_v(home,v,false));
00269 return (x0.assigned() || x1.assigned()) ?
00270 ES_SUBSUMED(*this,home) : ES_FIX;
00271 }
00272 }
00273 }
00274
00275 template <class V0, class V1>
00276 forceinline ExecStatus
00277 post_int(Space& home, IntSharedArray& c, V0 x0, V1 x1) {
00278 GECODE_ME_CHECK(x0.gq(home,0));
00279 GECODE_ME_CHECK(x0.le(home,c.size()));
00280 Support::IntType idx_type = Support::s_type(c.size());
00281 int min = x1.min();
00282 int max = x1.max();
00283 for (int i=c.size(); i--; ) {
00284 min = std::min(c[i],min); max = std::max(c[i],max);
00285 }
00286 Support::IntType val_type =
00287 std::max(Support::s_type(min),Support::s_type(max));
00288 switch (idx_type) {
00289 case Support::IT_CHAR:
00290 switch (val_type) {
00291 case Support::IT_CHAR:
00292 return Int<V0,V1,signed char,signed char>::post(home,c,x0,x1);
00293 case Support::IT_SHRT:
00294 return Int<V0,V1,signed char,signed short int>::post(home,c,x0,x1);
00295 case Support::IT_INT:
00296 return Int<V0,V1,signed char,signed int>::post(home,c,x0,x1);
00297 default: GECODE_NEVER;
00298 }
00299 break;
00300 case Support::IT_SHRT:
00301 switch (val_type) {
00302 case Support::IT_CHAR:
00303 return Int<V0,V1,signed short int,signed char>::post(home,c,x0,x1);
00304 case Support::IT_SHRT:
00305 return Int<V0,V1,signed short int,signed short int>::post(home,c,x0,x1);
00306 case Support::IT_INT:
00307 return Int<V0,V1,signed short int,signed int>::post(home,c,x0,x1);
00308 default: GECODE_NEVER;
00309 }
00310 break;
00311 case Support::IT_INT:
00312 switch (val_type) {
00313 case Support::IT_CHAR:
00314 return Int<V0,V1,signed int,signed char>::post(home,c,x0,x1);
00315 case Support::IT_SHRT:
00316 return Int<V0,V1,signed int,signed short int>::post(home,c,x0,x1);
00317 case Support::IT_INT:
00318 return Int<V0,V1,signed int,signed int>::post(home,c,x0,x1);
00319 default: GECODE_NEVER;
00320 }
00321 break;
00322 default: GECODE_NEVER;
00323 }
00324 return ES_OK;
00325 }
00326
00327 }}}
00328
00329
00330