Generated on Wed Nov 1 15:04:31 2006 for Gecode by doxygen 1.4.5

dom.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2004
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3512 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
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    * Classes for the layered graph
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;    // One addional layer (makes layers[-1] okay)
00085     Layer         layers[2]; // Dynamically adjusted (also allow layers[...+1])
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     // e2 always points to the end of  the interval
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     // e2 always points to the end of  the interval
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    * The layered graph
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     // Allocate memory
00185     state_size = sizeof(State)*(n+1)*n_states;
00186     state_mem  = reinterpret_cast<State*>(Memory::malloc(state_size));
00187 
00188 
00189     // Initialize states (indegree and outdegree)
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     // Mark initial state as being reachable
00196     state_mem[0].i_deg = 1;
00197 
00198     // Mark final states as reachable as well
00199     for (int s = dfa.final_fst(); s < dfa.final_lst(); s++)
00200       state_mem[n*n_states + s].o_deg = 1;
00201 
00202     // First pass: add transitions
00203     for (int i = 0; i < n; i++) {
00204       Edge** p = &layers[i].edges;
00205       // Enter links leaving reachable states (indegree != 0)
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         // Compute pointers to states
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           // Add new transition as state is reachable
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       // Write endmarker for edges
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     // Second pass: prune all transitions that do not lead to final state
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           // This state is still reachable, keep edge
00244           p = &e->next;
00245         } else {
00246           // Unreachable state, prune edge
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     // Tell back variable domains
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       // Initialize size and modification data
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     // Prune edges for which no value support exists
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             // Adapt states
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             // Remove this edge
00299             *p = e->next; e = e->next;
00300           } else {
00301             // Keep edge
00302             p = &e->next; e = e->next;
00303           }
00304         }
00305         *p = NULL;
00306         // Remove all remaining edges
00307         while (e != NULL) {
00308           // Adapt states
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         // Write endmarker for edges
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             // Adapt states
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             // Remove this edge
00328             *p = e->next;
00329           } else {
00330             // Keep edge
00331             p = &e->next;
00332           }
00333           e = e->next;
00334         }
00335         // Write endmarker for edges
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             // This state is still reachable, keep edge
00346             p = &e->next;
00347           } else {
00348             // Unreachable state, prune edge
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     // Tell back variable domains
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     // n ist the number of variables
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 // STATISTICS: int-prop
00480