dom.icc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gecode/iter.hh"
00023
00024 #include "gecode/support/static-stack.hh"
00025 #include "gecode/support/block-allocator.hh"
00026
00027 namespace Gecode { namespace Int { namespace Regular {
00028
00029
00030
00031
00032
00033
00034
00038 class State {
00039 public:
00040 unsigned int i_deg;
00041 unsigned int o_deg;
00042 };
00043
00044 class Edge;
00045 typedef Support::BlockAllocator<Edge> EdgeAllocator;
00046
00050 class Edge : public Support::BlockClient<Edge> {
00051 public:
00052 int val;
00053 State* i_state;
00054 State* o_state;
00055 Edge* next;
00056 };
00057
00062 const int MOD_NONE = 0;
00063 const int MOD_IDEG = 1;
00064 const int MOD_ODEG = 2;
00065
00066
00070 class Layer {
00071 public:
00072 Edge* edges;
00073 unsigned int size;
00074 int modified;
00075 };
00076
00078 template <class View>
00079 class Dom<View>::LayeredGraph {
00080 private:
00081 EdgeAllocator ea;
00082 size_t state_size;
00083 State* state_mem;
00084 Layer _layer;
00085 Layer layers[2];
00086 public:
00088 LayeredGraph(ViewArray<View> x, const DFA& d);
00090 ~LayeredGraph(void);
00091
00093 ExecStatus prune_initial(Space* home, ViewArray<View> x);
00095 ExecStatus prune(Space* home, ViewArray<View> x);
00096
00098 size_t size(void) const;
00099 static void* operator new(size_t,int);
00100 static void operator delete(void*);
00101 static void operator delete(void*,int);
00102 };
00103
00104
00105
00110 class EdgeRanges {
00111 private:
00112 const Edge* e1; const Edge* e2;
00113 public:
00114 EdgeRanges(void);
00115 EdgeRanges(const Edge*);
00116 void init(const Edge*);
00117 bool operator()(void) const;
00118 void operator++(void);
00119 int min(void) const;
00120 int max(void) const;
00121 unsigned int width(void) const;
00122 };
00123
00124 forceinline
00125 EdgeRanges::EdgeRanges(void) {}
00126 forceinline
00127 EdgeRanges::EdgeRanges(const Edge* e)
00128 : e1(e), e2(e) {
00129 assert(e1);
00130
00131 while ((e2->next != NULL) && (e2->next->val <= e2->val+1))
00132 e2 = e2->next;
00133 }
00134 forceinline void
00135 EdgeRanges::init(const Edge* e) {
00136 e1=e; e2=e;
00137 assert(e1);
00138
00139 while ((e2->next != NULL) && (e2->next->val <= e2->val+1))
00140 e2 = e2->next;
00141 }
00142
00143 forceinline bool
00144 EdgeRanges::operator()(void) const {
00145 return e1 != NULL;
00146 }
00147
00148 forceinline void
00149 EdgeRanges::operator++(void) {
00150 e1 = e2->next;
00151 if (e1 != NULL) {
00152 e2 = e1;
00153 while ((e2->next != NULL) && (e2->next->val <= e2->val+1))
00154 e2 = e2->next;
00155 }
00156 }
00157
00158 forceinline int
00159 EdgeRanges::min(void) const {
00160 return e1->val;
00161 }
00162 forceinline int
00163 EdgeRanges::max(void) const {
00164 return e2->val;
00165 }
00166 forceinline unsigned int
00167 EdgeRanges::width(void) const {
00168 return max()-min()+1;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 template <class View>
00179 forceinline
00180 Dom<View>::LayeredGraph::LayeredGraph(ViewArray<View> x, const DFA& dfa) {
00181 int n = x.size();
00182 unsigned int n_states = dfa.n_states();
00183
00184
00185 state_size = sizeof(State)*(n+1)*n_states;
00186 state_mem = reinterpret_cast<State*>(Memory::malloc(state_size));
00187
00188
00189
00190 for (int i = (n+1)*n_states; i--; ) {
00191 state_mem[i].i_deg = 0;
00192 state_mem[i].o_deg = 0;
00193 }
00194
00195
00196 state_mem[0].i_deg = 1;
00197
00198
00199 for (int s = dfa.final_fst(); s < dfa.final_lst(); s++)
00200 state_mem[n*n_states + s].o_deg = 1;
00201
00202
00203 for (int i = 0; i < n; i++) {
00204 Edge** p = &layers[i].edges;
00205
00206 DFA::Transitions t_a(dfa);
00207 ViewRanges<View> rx(x[i]);
00208 while (rx() && t_a()) {
00209 const DFA::Transition* t = t_a.transition();
00210
00211 State* i_state = state_mem + (i )*n_states + t->i_state;
00212 State* o_state = state_mem + (i+1)*n_states + t->o_state;
00213 if (t->symbol > rx.max()) {
00214 ++rx;
00215 } else if ((t->symbol >= rx.min()) && (i_state->i_deg > 0)) {
00216
00217 i_state->o_deg++; o_state->i_deg++;
00218 Edge* e = new (ea) Edge;
00219 e->i_state = i_state;
00220 e->val = t->symbol;
00221 e->o_state = o_state;
00222 *p = e;
00223 p = &e->next;
00224 ++t_a;
00225 } else {
00226 ++t_a;
00227 }
00228 }
00229
00230 *p = NULL;
00231 }
00232 }
00233
00234 template <class View>
00235 forceinline ExecStatus
00236 Dom<View>::LayeredGraph::prune_initial(Space* home, ViewArray<View> x) {
00237
00238 for (int i = x.size(); i--; ) {
00239 Edge** p = &layers[i].edges;
00240 Edge* e = *p;
00241 while (e != NULL) {
00242 if (e->o_state->o_deg != 0) {
00243
00244 p = &e->next;
00245 } else {
00246
00247 *p = e->next;
00248 e->i_state->o_deg--; e->o_state->i_deg--;
00249 }
00250 e = e->next;
00251 }
00252 *p = NULL;
00253 }
00254
00255
00256 ExecStatus es = ES_FIX;
00257 for (int i=x.size(); i--; ) {
00258 if (layers[i].edges == NULL)
00259 return ES_FAILED;
00260 if (x[i].modified())
00261 es = ES_NOFIX;
00262 EdgeRanges er(layers[i].edges);
00263 if (x[i].modified()) {
00264 GECODE_ME_CHECK(x[i].inter(home,er));
00265 } else {
00266 x[i].narrow(home,er);
00267 }
00268
00269 layers[i].modified = MOD_NONE;
00270 layers[i].size = x[i].size();
00271 }
00272 for (int i=x.size(); i--; )
00273 if (!x[i].assigned())
00274 return es;
00275 return ES_SUBSUMED;
00276 }
00277
00278 template <class View>
00279 forceinline ExecStatus
00280 Dom<View>::LayeredGraph::prune(Space* home, ViewArray<View> x) {
00281 int n = x.size();
00282
00283 for (int i = 0; i < n; i++)
00284 if (layers[i].size != x[i].size()) {
00285 layers[i].size = x[i].size();
00286 Edge** p = &layers[i].edges;
00287 Edge* e = *p;
00288 ViewRanges<View> rx(x[i]);
00289 while (rx() && (e != NULL)) {
00290 if (e->val > rx.max()) {
00291 ++rx;
00292 } else if ((e->val < rx.min()) || (e->i_state->i_deg == 0)) {
00293
00294 if ((--e->i_state->o_deg) == 0)
00295 layers[i-1].modified |= MOD_ODEG;
00296 if ((--e->o_state->i_deg) == 0)
00297 layers[i+1].modified |= MOD_IDEG;
00298
00299 *p = e->next; e = e->next;
00300 } else {
00301
00302 p = &e->next; e = e->next;
00303 }
00304 }
00305 *p = NULL;
00306
00307 while (e != NULL) {
00308
00309 if (--e->i_state->o_deg == 0)
00310 layers[i-1].modified |= MOD_ODEG;
00311 if (--e->o_state->i_deg == 0)
00312 layers[i+1].modified |= MOD_IDEG;
00313 e = e->next;
00314 }
00315
00316 } else if (layers[i].modified & MOD_IDEG) {
00317 assert(layers[i].size == x[i].size());
00318 Edge** p = &layers[i].edges;
00319 Edge* e = *p;
00320 while (e != NULL) {
00321 if (e->i_state->i_deg == 0) {
00322
00323 if (--e->i_state->o_deg == 0)
00324 layers[i-1].modified |= MOD_ODEG;
00325 if (--e->o_state->i_deg == 0)
00326 layers[i+1].modified |= MOD_IDEG;
00327
00328 *p = e->next;
00329 } else {
00330
00331 p = &e->next;
00332 }
00333 e = e->next;
00334 }
00335
00336 *p = NULL;
00337 }
00338
00339 for (int i=n; i--; )
00340 if (layers[i].modified & MOD_ODEG) {
00341 Edge** p = &layers[i].edges;
00342 Edge* e = *p;
00343 while (e != NULL) {
00344 if (e->o_state->o_deg != 0) {
00345
00346 p = &e->next;
00347 } else {
00348
00349 if (--e->i_state->o_deg == 0)
00350 layers[i-1].modified |= MOD_ODEG;
00351 --e->o_state->i_deg;
00352 *p = e->next;
00353 }
00354 e = e->next;
00355 }
00356 *p = NULL;
00357 }
00358
00359 ExecStatus es = ES_FIX;
00360 for (int i=n; i--; )
00361 if (layers[i].modified) {
00362 layers[i].modified = MOD_NONE;
00363 if (layers[i].edges == NULL)
00364 return ES_FAILED;
00365 if (x[i].modified())
00366 es = ES_NOFIX;
00367 EdgeRanges er(layers[i].edges);
00368 if (x[i].modified()) {
00369 GECODE_ME_CHECK(x[i].inter(home,er));
00370 } else {
00371 x[i].narrow(home,er);
00372 }
00373 layers[i].size = x[i].size();
00374 }
00375 for (int i=x.size(); i--; )
00376 if (!x[i].assigned())
00377 return es;
00378 return ES_SUBSUMED;
00379 }
00380
00381 template <class View>
00382 forceinline
00383 Dom<View>::LayeredGraph::~LayeredGraph(void) {
00384 Memory::free(state_mem);
00385 }
00386
00387 template <class View>
00388 forceinline size_t
00389 Dom<View>::LayeredGraph::size(void) const {
00390 return state_size + ea.size();
00391 }
00392
00393 template <class View>
00394 forceinline void
00395 Dom<View>::LayeredGraph::operator delete(void* p) {
00396 Memory::free(p);
00397 }
00398
00399 template <class View>
00400 forceinline void
00401 Dom<View>::LayeredGraph::operator delete(void* p, int) {
00402 Memory::free(p);
00403 }
00404
00405 template <class View>
00406 forceinline void*
00407 Dom<View>::LayeredGraph::operator new(size_t s, int n) {
00408
00409 return Memory::malloc(sizeof(LayeredGraph) + n*sizeof(Layer));
00410 }
00411
00412 template <class View>
00413 ExecStatus
00414 Dom<View>::propagate(Space* home) {
00415 if (lg == NULL) {
00416 lg = new (this->x.size()) LayeredGraph(this->x,dfa);
00417 return lg->prune_initial(home,this->x);
00418 } else {
00419 return lg->prune(home,this->x);
00420 }
00421 }
00422
00423 template <class View>
00424 forceinline
00425 Dom<View>::Dom(Space* home, ViewArray<View>& x, DFA& d)
00426 : NaryPropagator<View,PC_INT_DOM>(home,x,true),
00427 dfa(d), lg(NULL) {
00428 }
00429
00430 template <class View>
00431 ExecStatus
00432 Dom<View>::post(Space* home, ViewArray<View>& x, DFA& d) {
00433 (void) new (home) Dom<View>(home,x,d);
00434 return ES_OK;
00435 }
00436
00437 template <class View>
00438 forceinline
00439 Dom<View>::Dom(Space* home, bool share, Dom<View>& p)
00440 : NaryPropagator<View,PC_INT_DOM>(home,share,p), lg(NULL) {
00441 dfa.update(share,p.dfa);
00442 }
00443
00444 template <class View>
00445 size_t
00446 Dom<View>::dispose(Space* home) {
00447 dfa.~DFA();
00448 delete lg;
00449 (void) NaryPropagator<View,PC_INT_DOM>::dispose(home);
00450 return sizeof(*this);
00451 }
00452
00453 template <class View>
00454 void
00455 Dom<View>::flush(void) {
00456 delete lg; lg = NULL;
00457 }
00458
00459 template <class View>
00460 size_t
00461 Dom<View>::size(void) const {
00462 return (lg != NULL) ? lg->size() : 0;
00463 }
00464
00465 template <class View>
00466 PropCost
00467 Dom<View>::cost(void) const {
00468 return cost_hi(this->x.size(), PC_LINEAR_HI);
00469 }
00470
00471 template <class View>
00472 Actor*
00473 Dom<View>::copy(Space* home, bool share) {
00474 return new (home) Dom<View>(home,share,*this);
00475 }
00476
00477 }}}
00478
00479
00480