Generated on Mon Jul 6 18:09:09 2009 for Gecode by doxygen 1.5.9

layered-graph.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2009-03-25 17:34:58 +0100 (Wed, 25 Mar 2009) $ by $Author: schulte $
00011  *     $Revision: 8564 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include <climits>
00039 #include <algorithm>
00040 
00041 namespace Gecode { namespace Int { namespace Extensional {
00042 
00043   template <class View, class Degree, class StateIdx>
00044   forceinline
00045   LayeredGraph<View,Degree,StateIdx>::Edge::Edge(StateIdx i, StateIdx o, Edge* n)
00046     : i_state(i), o_state(o), next(n) {}
00047   template <class View, class Degree, class StateIdx>
00048   forceinline void
00049   LayeredGraph<View,Degree,StateIdx>::Edge::operator delete(void* p, size_t s) {
00050     (void) p; (void) s;
00051   }
00052   template <class View, class Degree, class StateIdx>
00053   forceinline void
00054   LayeredGraph<View,Degree,StateIdx>::Edge::operator delete(void* p, Space& home) {
00055     (void) p; (void) home;
00056   }
00057   template <class View, class Degree, class StateIdx>
00058   forceinline void*
00059   LayeredGraph<View,Degree,StateIdx>::Edge::operator new(size_t s, Space& home) {
00060     return home.ralloc(s);
00061   }
00062 
00063 
00064 
00065   template <class View, class Degree, class StateIdx>
00066   forceinline
00067   LayeredGraph<View,Degree,StateIdx>::LayerValues::LayerValues(void) {}
00068   template <class View, class Degree, class StateIdx>
00069   forceinline
00070   LayeredGraph<View,Degree,StateIdx>::LayerValues::LayerValues(const Layer& l)
00071     : s1(l.support), s2(l.support+l.size) {}
00072   template <class View, class Degree, class StateIdx>
00073   forceinline void
00074   LayeredGraph<View,Degree,StateIdx>::LayerValues::init(const Layer& l) {
00075     s1=l.support; s2=l.support+l.size;
00076   }
00077   template <class View, class Degree, class StateIdx>
00078   forceinline bool
00079   LayeredGraph<View,Degree,StateIdx>::LayerValues::operator ()(void) const {
00080     return s1<s2;
00081   }
00082   template <class View, class Degree, class StateIdx>
00083   forceinline void
00084   LayeredGraph<View,Degree,StateIdx>::LayerValues::operator ++(void) {
00085     s1++;
00086   }
00087   template <class View, class Degree, class StateIdx>
00088   forceinline int
00089   LayeredGraph<View,Degree,StateIdx>::LayerValues::val(void) const {
00090     return s1->val;
00091   }
00092 
00093 
00094   /*
00095    * Index advisors
00096    *
00097    */
00098   template <class View, class Degree, class StateIdx>
00099   forceinline
00100   LayeredGraph<View,Degree,StateIdx>::Index::Index(Space& home, Propagator& p,
00101                                                    Council<Index>& c,
00102                                                    StateIdx i0)
00103     : Advisor(home,p,c), i(i0) {}
00104 
00105   template <class View, class Degree, class StateIdx>
00106   forceinline
00107   LayeredGraph<View,Degree,StateIdx>::Index::Index(Space& home, bool share,
00108                                                    Index& a)
00109     : Advisor(home,share,a), i(a.i) {}
00110 
00111 
00112   /*
00113    * Index ranges
00114    *
00115    */
00116   template <class View, class Degree, class StateIdx>
00117   forceinline
00118   LayeredGraph<View,Degree,StateIdx>::IndexRange::IndexRange(void)
00119     : _fst(INT_MAX), _lst(INT_MIN) {}
00120   template <class View, class Degree, class StateIdx>
00121   forceinline void
00122   LayeredGraph<View,Degree,StateIdx>::IndexRange::reset(void) {
00123     _fst=INT_MAX; _lst=INT_MIN;
00124   }
00125   template <class View, class Degree, class StateIdx>
00126   forceinline void
00127   LayeredGraph<View,Degree,StateIdx>::IndexRange::add(int i) {
00128     _fst=std::min(_fst,i); _lst=std::max(_lst,i);
00129   }
00130   template <class View, class Degree, class StateIdx>
00131   forceinline int
00132   LayeredGraph<View,Degree,StateIdx>::IndexRange::fst(void) const {
00133     return _fst;
00134   }
00135   template <class View, class Degree, class StateIdx>
00136   forceinline int
00137   LayeredGraph<View,Degree,StateIdx>::IndexRange::lst(void) const {
00138     return _lst;
00139   }
00140 
00141 
00142 
00143   /*
00144    * The layered graph
00145    *
00146    */
00147 
00148   template <class View, class Degree, class StateIdx>
00149   forceinline bool
00150   LayeredGraph<View,Degree,StateIdx>::constructed(void) const {
00151     return layers != NULL;
00152   }
00153 
00154   template <class View, class Degree, class StateIdx>
00155   forceinline void
00156   LayeredGraph<View,Degree,StateIdx>::eliminate(void) {
00157     if (!constructed() || (layers[0].size > 1))
00158       return;
00159     assert(layers[0].size == 1);
00160     // Skip all layers corresponding to assigned views
00161     StateIdx i = 1;
00162     while (layers[i].size == 1)
00163       i++;
00164     // There is only a single edge
00165     Edge* e = layers[i-1].support[0].edges;
00166     assert((e->next == NULL) && (states[e->o_state].i_deg == 1));
00167     // New start state
00168     start = e->o_state % dfa.n_states();
00169     layers += i;
00170     x.drop_fst(i);
00171     for (Advisors<Index> as(c); as(); ++as)
00172       as.advisor().i -= i;
00173   }
00174 
00175   template <class View, class Degree, class StateIdx>
00176   forceinline ExecStatus
00177   LayeredGraph<View,Degree,StateIdx>::construct(Space& home) {
00178     int n = x.size();
00179     layers = home.alloc<Layer>(n+2)+1;
00180 
00181     int n_states = dfa.n_states();
00182 
00183     // Allocate memory
00184     states = home.alloc<State>((n+1)*n_states);
00185 
00186     // Initialize states (indegree and outdegree)
00187     for (int i = (n+1)*n_states; i--; )
00188       states[i].i_deg = states[i].o_deg = 0;
00189 
00190     // Mark initial state as being reachable
00191     states[start].i_deg = 1;
00192 
00193     // Mark final states as reachable as well
00194     for (int s = dfa.final_fst(); s < dfa.final_lst(); s++)
00195       states[n*n_states + s].o_deg = 1;
00196 
00197     // Forward pass: add transitions
00198     for (int i=0; i<n; i++) {
00199       layers[i].support = home.alloc<Support >(x[i].size());
00200       unsigned int j=0;
00201       // Enter links leaving reachable states (indegree != 0)
00202       for (ViewValues<View> nx(x[i]); nx(); ++nx) {
00203         Edge* e = NULL;
00204         for (DFA::Transitions t(dfa,nx.val()); t(); ++t)
00205           if (states[i*n_states + t.i_state()].i_deg != 0) {
00206             StateIdx i_s = static_cast<StateIdx>(i*n_states + t.i_state());
00207             states[i_s].o_deg++;
00208             StateIdx o_s = static_cast<StateIdx>((i+1)*n_states +  t.o_state());
00209             states[o_s].i_deg++;
00210             e = new (home) Edge(i_s, o_s, e);
00211           }
00212         // Found support for value
00213         if (e != NULL) {
00214           layers[i].support[j].val   = nx.val();
00215           layers[i].support[j].edges = e;
00216           j++;
00217         }
00218       }
00219       if ((layers[i].size = j) == 0)
00220         return ES_FAILED;
00221     }
00222 
00223     // Backward pass: prune all transitions that do not lead to final state
00224     for (int i=n; i--; ) {
00225       unsigned int k=0;
00226       for (unsigned int j=0; j<layers[i].size; j++) {
00227         Edge** p = &layers[i].support[j].edges;
00228         Edge*  e = *p;
00229         do {
00230           if (states[e->o_state].o_deg != 0) {
00231             // This state is still reachable, keep edge
00232             p = &e->next;
00233           } else {
00234             // Unreachable state, prune edge
00235             states[e->i_state].o_deg--; states[e->o_state].i_deg--;
00236             *p = e->next;
00237           }
00238           e = e->next;
00239         } while (e != NULL);
00240         // Write endmarker for edges
00241         *p = NULL;
00242         // Value has support, copy the support information
00243         if (layers[i].support[j].edges != NULL)
00244           layers[i].support[k++]=layers[i].support[j];
00245       }
00246       if ((layers[i].size = k) == 0)
00247         return ES_FAILED;
00248       LayerValues lv(layers[i]);
00249       GECODE_ME_CHECK(x[i].narrow_v(home,lv,false));
00250     }
00251 
00252     if (c.empty())
00253       return ES_SUBSUMED(*this,home);
00254     return ES_FIX;
00255   }
00256 
00257   template <class View, class Degree, class StateIdx>
00258   forceinline ExecStatus
00259   LayeredGraph<View,Degree,StateIdx>::prune(Space& home) {
00260     // Forward pass
00261     for (int i=i_ch.fst(); i<=i_ch.lst(); i++) {
00262       bool i_mod = false;
00263       bool o_mod = false;
00264       unsigned int j=0;
00265       unsigned int k=0;
00266       unsigned int s=layers[i].size;
00267       do {
00268         // Some edges might have lost support
00269         Edge** p = &layers[i].support[j].edges;
00270         Edge*  e = *p;
00271         do {
00272           if (states[e->i_state].i_deg == 0) {
00273             // Adapt states
00274             o_mod |= ((--states[e->i_state].o_deg) == 0);
00275             i_mod |= ((--states[e->o_state].i_deg) == 0);
00276             // Remove edge
00277             *p = e->next;
00278           } else {
00279             // Keep edge
00280             p = &e->next;
00281           }
00282           e = e->next;
00283         } while (e != NULL);
00284         // Write endmarker for edges
00285         *p=NULL;
00286         // Check whether value is still supported
00287         if (layers[i].support[j].edges == NULL) {
00288           layers[i].size--;
00289           GECODE_ME_CHECK(x[i].nq(home,layers[i].support[j++].val));
00290         } else {
00291           layers[i].support[k++]=layers[i].support[j++];
00292         }
00293       } while (j<s);
00294       assert(k > 0);
00295       // Update modification information
00296       if (o_mod && (i > 0))
00297         o_ch.add(i-1);
00298       if (i_mod && (i+1 < x.size()))
00299         i_ch.add(i+1);
00300     }
00301     i_ch.reset();
00302 
00303     // Backward pass
00304     for (int i=o_ch.lst(); i>=o_ch.fst(); i--) {
00305       bool o_mod = false;
00306       unsigned int j=0;
00307       unsigned int k=0;
00308       unsigned int s=layers[i].size;
00309       do {
00310         Edge** p = &layers[i].support[j].edges;
00311         Edge*  e = *p;
00312         do {
00313           if (states[e->o_state].o_deg != 0) {
00314             // This state is still reachable, keep edge
00315             p = &e->next;
00316           } else {
00317             // Unreachable state, prune edge
00318             o_mod |= (--states[e->i_state].o_deg == 0);
00319             --states[e->o_state].i_deg;
00320             *p = e->next;
00321           }
00322           e = e->next;
00323         } while (e != NULL);
00324         // Write endmarker for edges
00325         *p = NULL;
00326         // Check whether value has still support
00327         if (layers[i].support[j].edges == NULL) {
00328           layers[i].size--;
00329           GECODE_ME_CHECK(x[i].nq(home,layers[i].support[j++].val));
00330         } else {
00331           layers[i].support[k++]=layers[i].support[j++];
00332         }
00333       } while (j<s);
00334       assert(k > 0);
00335       // Update modification information
00336       if (o_mod && (i > 0))
00337         o_ch.add(i-1);
00338     }
00339     o_ch.reset();
00340 
00341     // Check subsumption
00342     if (c.empty())
00343       return ES_SUBSUMED(*this,home);
00344     return ES_FIX;
00345   }
00346 
00347   template <class View, class Degree, class StateIdx>
00348   ExecStatus
00349   LayeredGraph<View,Degree,StateIdx>::advise(Space& home,
00350                                              Advisor& _a, const Delta& d) {
00351     Index& a = static_cast<Index&>(_a);
00352     int i = a.i;
00353     bool i_mod = false;
00354     bool o_mod = false;
00355     bool is_fix = true;
00356     Layer& l = layers[i];
00357 
00358     if (!constructed())
00359       goto nofix;
00360 
00361     if (l.size == x[i].size())
00362       goto fix;
00363 
00364     if (View::modevent(d) == ME_INT_VAL) {
00365       int n = x[i].val();
00366       unsigned int j=0;
00367       for (; l.support[j].val < n; j++)
00368         // Supported value not any longer in view
00369         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00370           // Adapt states
00371           o_mod |= ((--states[e->i_state].o_deg) == 0);
00372           i_mod |= ((--states[e->o_state].i_deg) == 0);
00373         }
00374       assert(l.support[j].val == n);
00375       l.support[0] = l.support[j++];
00376       unsigned int s=l.size;
00377       l.size = 1;
00378       for (; j<s; j++)
00379         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00380           // Adapt states
00381           o_mod |= ((--states[e->i_state].o_deg) == 0);
00382           i_mod |= ((--states[e->o_state].i_deg) == 0);
00383         }
00384     } else if (x[i].any(d)) {
00385       unsigned int j=0;
00386       unsigned int k=0;
00387       unsigned int s=l.size;
00388       for (ViewRanges<View> rx(x[i]); rx() && (j<s);)
00389         if (l.support[j].val < rx.min()) {
00390           // Supported value not any longer in view
00391           for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00392             // Adapt states
00393             o_mod |= ((--states[e->i_state].o_deg) == 0);
00394             i_mod |= ((--states[e->o_state].i_deg) == 0);
00395           }
00396           ++j;
00397         } else if (l.support[j].val > rx.max()) {
00398           ++rx;
00399         } else {
00400           l.support[k++]=l.support[j++];
00401         }
00402       assert(k > 0);
00403       l.size = k;
00404       // Remove remaining values
00405       for (; j<s; j++)
00406         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00407           // Adapt states
00408           o_mod |= ((--states[e->i_state].o_deg) == 0);
00409           i_mod |= ((--states[e->o_state].i_deg) == 0);
00410         }
00411     } else {
00412       int min = x[i].min(d);
00413       unsigned int j=0;
00414       // Skip values smaller than min (to keep)
00415       for (; l.support[j].val < min; j++) {}
00416       int max = x[i].max(d);
00417       unsigned int k=j;
00418       unsigned int s=l.size;
00419       // Remove pruned values
00420       for (; (j<s) && (l.support[j].val <= max); j++)
00421         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00422           // Adapt states
00423           o_mod |= ((--states[e->i_state].o_deg) == 0);
00424           i_mod |= ((--states[e->o_state].i_deg) == 0);
00425         }
00426       // Keep remaining values
00427       while (j<s)
00428         l.support[k++]=l.support[j++];
00429       l.size =k;
00430       assert(k > 0);
00431     }
00432     if (o_mod && (i > 0)) {
00433       o_ch.add(i-1); is_fix = false;
00434      }
00435     if (i_mod && (i+1 < x.size())) {
00436       i_ch.add(i+1); is_fix = false;
00437     }
00438     if (is_fix) {
00439     fix:
00440       if (View::modevent(d) == ME_INT_VAL) {
00441         a.dispose(home,c);
00442         return c.empty() ? ES_NOFIX : ES_FIX;
00443       }
00444       return ES_FIX;
00445     } else {
00446     nofix:
00447       return (View::modevent(d) == ME_INT_VAL)
00448         ? ES_SUBSUMED_NOFIX(a,home,c) : ES_NOFIX;
00449     }
00450   }
00451 
00452   template <class View, class Degree, class StateIdx>
00453   ExecStatus
00454   LayeredGraph<View,Degree,StateIdx>::propagate(Space& home,
00455                                                 const ModEventDelta&) {
00456     ExecStatus es = constructed() ? prune(home) : construct(home);
00457     return es;
00458   }
00459 
00460   template <class View, class Degree, class StateIdx>
00461   forceinline
00462   LayeredGraph<View,Degree,StateIdx>::LayeredGraph(Space& home,
00463                                                    ViewArray<View>& x0, DFA& d)
00464     : Propagator(home), c(home), x(x0), dfa(d), start(0), layers(NULL) {
00465     assert(x.size() > 0);
00466     ModEvent me = ME_INT_BND;
00467     for (StateIdx i=static_cast<StateIdx>(x.size()); i--; )
00468       if (x[i].assigned())
00469         me = ME_INT_VAL;
00470       else
00471         x[i].subscribe(home, *new (home) Index(home,*this,c,i));
00472     View::schedule(home,*this,me);
00473     home.notice(*this,AP_DISPOSE);
00474   }
00475 
00476   template <class View, class Degree, class StateIdx>
00477   forceinline size_t
00478   LayeredGraph<View,Degree,StateIdx>::dispose(Space& home) {
00479     home.ignore(*this,AP_DISPOSE);
00480     c.dispose(home);
00481     dfa.~DFA();
00482     (void) Propagator::dispose(home);
00483     return sizeof(*this);
00484   }
00485 
00486   template <class View, class Degree, class StateIdx>
00487   forceinline ExecStatus
00488   LayeredGraph<View,Degree,StateIdx>::post(Space& home, ViewArray<View>& x,
00489                                            DFA& d) {
00490     if (x.size() == 0) {
00491       // Check whether the start state 0 is also a final state
00492       if ((d.final_fst() <= 0) && (d.final_lst() >= 0))
00493         return ES_OK;
00494       return ES_FAILED;
00495     }
00496     assert(x.size() > 0);
00497     for (int i=x.size(); i--; ) {
00498       DFA::Symbols s(d);
00499       GECODE_ME_CHECK(x[i].inter_v(home,s,false));
00500     }
00501     (void) new (home) LayeredGraph<View,Degree,StateIdx>(home,x,d);
00502     return ES_OK;
00503   }
00504 
00505   template <class View, class Degree, class StateIdx>
00506   forceinline
00507   LayeredGraph<View,Degree,StateIdx>
00508   ::LayeredGraph(Space& home, bool share,
00509                  LayeredGraph<View,Degree,StateIdx>& p)
00510     : Propagator(home,share,p), layers(NULL) {
00511     assert(p.x.size() > 0);
00512     p.eliminate();
00513     c.update(home,share,p.c);
00514     x.update(home,share,p.x);
00515     dfa.update(home,share,p.dfa);
00516     start = p.start;
00517   }
00518 
00519   template <class View, class Degree, class StateIdx>
00520   PropCost
00521   LayeredGraph<View,Degree,StateIdx>::cost(const Space&,
00522                                            const ModEventDelta&) const {
00523     return PropCost::linear(PropCost::HI,x.size());
00524   }
00525 
00526   template <class View, class Degree, class StateIdx>
00527   Actor*
00528   LayeredGraph<View,Degree,StateIdx>::copy(Space& home, bool share) {
00529     return new (home) LayeredGraph<View,Degree,StateIdx>(home,share,*this);
00530   }
00531 
00533   template <class View>
00534   forceinline ExecStatus
00535   post_lgp(Space& home, ViewArray<View>& x, DFA dfa) {
00536     Gecode::Support::IntType t_state_idx =
00537       Gecode::Support::s_type((x.size()+2)*dfa.n_states());
00538     Gecode::Support::IntType t_degree =
00539       Gecode::Support::u_type(dfa.max_degree());
00540     switch (t_state_idx) {
00541     case Gecode::Support::IT_CHAR:
00542     case Gecode::Support::IT_SHRT:
00543       switch (t_degree) {
00544       case Gecode::Support::IT_CHAR:
00545         return Extensional::LayeredGraph<View,unsigned char,short int>
00546           ::post(home,x,dfa);
00547       case Gecode::Support::IT_SHRT:
00548         return Extensional::LayeredGraph<View,unsigned short int,short int>
00549           ::post(home,x,dfa);
00550       case Gecode::Support::IT_INT:
00551         return Extensional::LayeredGraph<View,unsigned int,short int>
00552           ::post(home,x,dfa);
00553       default: GECODE_NEVER;
00554       }
00555       break;
00556     case Gecode::Support::IT_INT:
00557       switch (t_degree) {
00558       case Gecode::Support::IT_CHAR:
00559         return Extensional::LayeredGraph<View,unsigned char,int>
00560           ::post(home,x,dfa);
00561       case Gecode::Support::IT_SHRT:
00562         return Extensional::LayeredGraph<View,unsigned short int,int>
00563           ::post(home,x,dfa);
00564       case Gecode::Support::IT_INT:
00565         return Extensional::LayeredGraph<View,unsigned int,int>
00566           ::post(home,x,dfa);
00567       default: GECODE_NEVER;
00568       }
00569       break;
00570     default: GECODE_NEVER;
00571     }
00572     return ES_OK;
00573   }
00574 
00575 }}}
00576 
00577 // STATISTICS: int-prop
00578