Generated on Mon Aug 25 11:35:37 2008 for Gecode by doxygen 1.5.6

layered-graph.icc

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: 2008-02-21 07:49:55 +0100 (Thu, 21 Feb 2008) $ by $Author: schulte $
00011  *     $Revision: 6262 $
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 
00046   class State {
00047   public:
00048     unsigned int i_deg;
00049     unsigned int o_deg;
00050   };
00051 
00055   class Edge {
00056   public:
00057     State* i_state; 
00058     State* o_state; 
00059     Edge*  next;    
00060 
00061     Edge(State& i, State& o, Edge* n);
00062     static void  operator delete(void*, size_t);
00063     static void  operator delete(void*,Space*);
00064     static void* operator new(size_t, Space*);
00065   };
00066 
00067   forceinline
00068   Edge::Edge(State& i, State& o, Edge* n)
00069     : i_state(&i), o_state(&o), next(n) {
00070     i_state->o_deg++; o_state->i_deg++;
00071   }
00072   forceinline void
00073   Edge::operator delete(void*, size_t) {}
00074   forceinline void
00075   Edge::operator delete(void*,Space*) {}
00076   forceinline void*
00077   Edge::operator new(size_t s, Space* home) {
00078     return home->alloc(s);
00079   }
00080 
00081 
00083   class Support {
00084   public:
00085     int   val;   
00086     Edge* edges; 
00087   };
00088 
00090   class Layer {
00091   public:
00092     unsigned int size;     
00093     Support*     support;  
00094   };
00095 
00097   class LayerValues {
00098   private:
00099     const Support* s1; 
00100     const Support* s2; 
00101   public:
00103     LayerValues(void);
00105     LayerValues(const Layer& l);
00107     void init(const Layer& l);
00109     bool operator()(void) const;
00111     void operator++(void);
00113     int val(void) const;
00114   };
00115 
00116   forceinline
00117   LayerValues::LayerValues(void) {}
00118   forceinline
00119   LayerValues::LayerValues(const Layer& l)
00120     : s1(l.support), s2(l.support+l.size) {}
00121   forceinline void
00122   LayerValues::init(const Layer& l) {
00123     s1=l.support; s2=l.support+l.size;
00124   }
00125   forceinline bool
00126   LayerValues::operator()(void) const {
00127     return s1<s2;
00128   }
00129   forceinline void
00130   LayerValues::operator++(void) {
00131     s1++;
00132   }
00133   forceinline int
00134   LayerValues::val(void) const {
00135     return s1->val;
00136   }
00137 
00138 
00139   /*
00140    * Index advisors
00141    *
00142    */
00143   template <class View>
00144   forceinline
00145   LayeredGraph<View>::Index::Index(Space* home, Propagator* p,
00146                                    Council<Index>& c, int i0)
00147     : Advisor(home,p,c), i(i0) {}
00148 
00149   template <class View>
00150   forceinline
00151   LayeredGraph<View>::Index::Index(Space* home, bool share, Index& a)
00152     : Advisor(home,share,a), i(a.i) {}
00153 
00154   template <class View>
00155   forceinline void
00156   LayeredGraph<View>::Index::dispose(Space* home, Council<Index>& c) {
00157     Advisor::dispose(home,c);
00158   }
00159 
00160 
00161   /*
00162    * Index ranges
00163    *
00164    */
00165   template <class View>
00166   forceinline
00167   LayeredGraph<View>::IndexRange::IndexRange(void) 
00168     : _fst(INT_MAX), _lst(INT_MIN) {}
00169   template <class View>
00170   forceinline void
00171   LayeredGraph<View>::IndexRange::reset(void) {
00172     _fst=INT_MAX; _lst=INT_MIN;
00173   }
00174   template <class View>
00175   forceinline void
00176   LayeredGraph<View>::IndexRange::add(int i) {
00177     _fst=std::min(_fst,i); _lst=std::max(_lst,i);
00178   }
00179   template <class View>
00180   forceinline int
00181   LayeredGraph<View>::IndexRange::fst(void) const {
00182     return _fst;
00183   }
00184   template <class View>
00185   forceinline int
00186   LayeredGraph<View>::IndexRange::lst(void) const {
00187     return _lst;
00188   }
00189 
00190 
00191   
00192   /*
00193    * The layered graph
00194    *
00195    */
00196 
00197   template <class View>
00198   forceinline bool
00199   LayeredGraph<View>::constructed(void) const {
00200     return layers != NULL;
00201   }
00202 
00203   template <class View>
00204   forceinline void
00205   LayeredGraph<View>::eliminate(void) {
00206     if (!constructed() || (layers[0].size > 1))
00207       return;
00208     assert(layers[0].size == 1);
00209     // Skip all layers corresponding to assigned views
00210     int i = 1;
00211     while (layers[i].size == 1)
00212       i++;
00213     // There is only a single edge
00214     Edge* e = layers[i-1].support[0].edges;
00215     assert((e->next == NULL) && (e->o_state->i_deg == 1));
00216     // Map the state address to the state
00217     start = static_cast<int>(e->o_state-states) % dfa.n_states();
00218     layers += i;
00219     x.drop_fst(i);
00220     for (Advisors<Index> as(c); as(); ++as)
00221       as.advisor()->i -= i;
00222   }
00223 
00224   template <class View>
00225   forceinline ExecStatus
00226   LayeredGraph<View>::construct(Space* home) {
00227     int n = x.size();
00228     layers = static_cast<Layer*>(home->alloc(sizeof(Layer)*(n+2)))+1;
00229     
00230     unsigned int n_states = dfa.n_states();
00231 
00232     // Allocate memory
00233     states = static_cast<State*>
00234       (home->alloc(sizeof(State)*(n+1)*n_states));
00235 
00236     // Initialize states (indegree and outdegree)
00237     for (int i = (n+1)*n_states; i--; )
00238       states[i].i_deg = states[i].o_deg = 0;
00239 
00240     // Mark initial state as being reachable
00241     states[start].i_deg = 1;
00242 
00243     // Mark final states as reachable as well
00244     for (int s = dfa.final_fst(); s < dfa.final_lst(); s++)
00245       states[n*n_states + s].o_deg = 1;
00246 
00247     // Forward pass: add transitions
00248     for (int i=0; i<n; i++) {
00249       layers[i].support = 
00250         static_cast<Support*>(home->alloc(x[i].size()*sizeof(Support)));
00251       unsigned int j=0;
00252       // Enter links leaving reachable states (indegree != 0)
00253       for (ViewValues<View> nx(x[i]); nx(); ++nx) {
00254         Edge* e = NULL;
00255         for (DFA::Transitions t(dfa,nx.val()); t(); ++t)
00256           if (states[i*n_states + t.i_state()].i_deg != 0)
00257             e = new (home) Edge(states[i*n_states + t.i_state()],
00258                                 states[(i+1)*n_states +  t.o_state()],
00259                                 e);
00260         // Found support for value
00261         if (e != NULL) {
00262           layers[i].support[j].val   = nx.val();
00263           layers[i].support[j].edges = e;
00264           j++;
00265         }
00266       }
00267       if ((layers[i].size = j) == 0)
00268         return ES_FAILED;
00269     }
00270 
00271     // Backward pass: prune all transitions that do not lead to final state
00272     for (int i=n; i--; ) {
00273       unsigned int k=0;
00274       for (unsigned int j=0; j<layers[i].size; j++) {
00275         Edge** p = &layers[i].support[j].edges;
00276         Edge*  e = *p;
00277         do {
00278           if (e->o_state->o_deg != 0) {
00279             // This state is still reachable, keep edge
00280             p = &e->next;
00281           } else {
00282             // Unreachable state, prune edge
00283             e->i_state->o_deg--; e->o_state->i_deg--;
00284             *p = e->next;
00285           }
00286           e = e->next;
00287         } while (e != NULL);
00288         // Write endmarker for edges
00289         *p = NULL;
00290         // Value has support, copy the support information
00291         if (layers[i].support[j].edges != NULL)
00292           layers[i].support[k++]=layers[i].support[j];
00293       }
00294       if ((layers[i].size = k) == 0)
00295         return ES_FAILED;
00296       LayerValues lv(layers[i]);
00297       GECODE_ME_CHECK(x[i].narrow_v(home,lv,false));
00298     }
00299 
00300     if (c.empty())
00301       return ES_SUBSUMED(this,home);
00302     return ES_FIX;
00303   }
00304 
00305   template <class View>
00306   forceinline ExecStatus
00307   LayeredGraph<View>::prune(Space* home) {
00308     // Forward pass
00309     for (int i=i_ch.fst(); i<=i_ch.lst(); i++) {
00310       bool i_mod = false;
00311       bool o_mod = false;
00312       unsigned int j=0;
00313       unsigned int k=0;
00314       unsigned int s=layers[i].size;
00315       do {
00316         // Some edges might have lost support
00317         Edge** p = &layers[i].support[j].edges;
00318         Edge*  e = *p;
00319         do {
00320           if (e->i_state->i_deg == 0) {
00321             // Adapt states
00322             o_mod |= ((--e->i_state->o_deg) == 0);
00323             i_mod |= ((--e->o_state->i_deg) == 0);
00324             // Remove edge
00325             *p = e->next;
00326           } else {
00327             // Keep edge
00328             p = &e->next;
00329           }
00330           e = e->next;
00331         } while (e != NULL);
00332         // Write endmarker for edges
00333         *p=NULL;
00334         // Check whether value is still supported
00335         if (layers[i].support[j].edges == NULL) {
00336           layers[i].size--;
00337           GECODE_ME_CHECK(x[i].nq(home,layers[i].support[j++].val));
00338         } else {
00339           layers[i].support[k++]=layers[i].support[j++];
00340         }
00341       } while (j<s);
00342       assert(k > 0);
00343       // Update modification information
00344       if (o_mod) o_ch.add(i-1);
00345       if (i_mod) i_ch.add(i+1);
00346     }
00347     i_ch.reset();
00348 
00349     // Backward pass
00350     for (int i=o_ch.lst(); i>=o_ch.fst(); i--) {
00351       bool o_mod = false;
00352       unsigned int j=0;
00353       unsigned int k=0;
00354       unsigned int s=layers[i].size;
00355       do {
00356         Edge** p = &layers[i].support[j].edges;
00357         Edge*  e = *p;
00358         do {
00359           if (e->o_state->o_deg != 0) {
00360             // This state is still reachable, keep edge
00361             p = &e->next;
00362           } else {
00363             // Unreachable state, prune edge
00364             o_mod |= (--e->i_state->o_deg == 0);
00365             --e->o_state->i_deg;
00366             *p = e->next;
00367           }
00368           e = e->next;
00369         } while (e != NULL);
00370         // Write endmarker for edges
00371         *p = NULL;
00372         // Check whether value has still support
00373         if (layers[i].support[j].edges == NULL) {
00374           layers[i].size--;
00375           GECODE_ME_CHECK(x[i].nq(home,layers[i].support[j++].val));
00376         } else {
00377           layers[i].support[k++]=layers[i].support[j++];
00378         }
00379       } while (j<s);
00380       assert(k > 0);
00381       // Update modification information
00382       if (o_mod) o_ch.add(i-1);
00383     }
00384     o_ch.reset();
00385 
00386     // Check subsumption
00387     if (c.empty())
00388       return ES_SUBSUMED(this,home);
00389     return ES_FIX;
00390   }
00391 
00392   template <class View>
00393   ExecStatus
00394   LayeredGraph<View>::advise(Space* home, Advisor* _a, const Delta* d) {
00395     Index* a = static_cast<Index*>(_a);
00396     int i = a->i;
00397     bool i_mod = false;
00398     bool o_mod = false;
00399     Layer& l = layers[i];
00400     if (!constructed())
00401       goto nofix;
00402 
00403     if (l.size == x[i].size())
00404       goto fix;
00405     if (View::modevent(d) == ME_INT_VAL) {
00406       int n = x[i].val();
00407       unsigned int j=0;
00408       for (; l.support[j].val < n; j++)
00409         // Supported value not any longer in view
00410         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00411           // Adapt states
00412           o_mod |= ((--e->i_state->o_deg) == 0);
00413           i_mod |= ((--e->o_state->i_deg) == 0);
00414         }
00415       assert(l.support[j].val == n);
00416       l.support[0] = l.support[j++];
00417       unsigned int s=l.size;
00418       l.size = 1;
00419       for (; j<s; j++)
00420         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00421           // Adapt states
00422           o_mod |= ((--e->i_state->o_deg) == 0);
00423           i_mod |= ((--e->o_state->i_deg) == 0);
00424         }
00425     } else if (x[i].any(d)) {
00426       unsigned int j=0;
00427       unsigned int k=0;
00428       unsigned int s=l.size;
00429       for (ViewRanges<View> rx(x[i]); rx() && (j<s);)
00430         if (l.support[j].val < rx.min()) {
00431           // Supported value not any longer in view
00432           for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00433             // Adapt states
00434             o_mod |= ((--e->i_state->o_deg) == 0);
00435             i_mod |= ((--e->o_state->i_deg) == 0);
00436           }
00437           ++j;
00438         } else if (l.support[j].val > rx.max()) {
00439           ++rx;
00440         } else {
00441           l.support[k++]=l.support[j++];
00442         }
00443       assert(k > 0);
00444       l.size = k;
00445       // Remove remaining values
00446       for (; j<s; j++)
00447         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00448           // Adapt states
00449           o_mod |= ((--e->i_state->o_deg) == 0);
00450           i_mod |= ((--e->o_state->i_deg) == 0);
00451         }
00452     } else {
00453       int min = x[i].min(d);
00454       unsigned int j=0;
00455       // Skip values smaller than min (to keep)
00456       for (; l.support[j].val < min; j++) {}
00457       int max = x[i].max(d);
00458       unsigned int k=j;
00459       unsigned int s=l.size;
00460       // Remove pruned values
00461       for (; (j<s) && (l.support[j].val <= max); j++)
00462         for (Edge* e=l.support[j].edges; e!=NULL; e=e->next) {
00463           // Adapt states
00464           o_mod |= ((--e->i_state->o_deg) == 0);
00465           i_mod |= ((--e->o_state->i_deg) == 0);
00466         }
00467       // Keep remaining values
00468       while (j<s)
00469         l.support[k++]=l.support[j++];
00470       l.size =k;
00471       assert(k > 0);        
00472     }
00473     if (!i_mod && !o_mod)
00474       goto fix;
00475     if (o_mod) o_ch.add(i-1);
00476     if (i_mod) i_ch.add(i+1);
00477     goto nofix;
00478   nofix:
00479     return (View::modevent(d) == ME_INT_VAL) 
00480       ? ES_SUBSUMED_NOFIX(a,home,c) : ES_NOFIX;
00481   fix:
00482     if (View::modevent(d) == ME_INT_VAL) {
00483       a->dispose(home,c);
00484       return c.empty() ? ES_NOFIX : ES_FIX;
00485     }
00486     return ES_FIX;
00487   }
00488 
00489   template <class View>
00490   ExecStatus
00491   LayeredGraph<View>::propagate(Space* home, ModEventDelta) {
00492     ExecStatus es = constructed() ? prune(home) : construct(home);
00493     return es;
00494   }
00495 
00496   template <class View>
00497   forceinline
00498   LayeredGraph<View>::LayeredGraph(Space* home, ViewArray<View>& x0, DFA& d)
00499     : Propagator(home), c(home), x(x0), dfa(d), start(0), layers(NULL) {
00500     assert(x.size() > 0);
00501     ModEvent me = ME_INT_BND;
00502     for (int i=x.size(); i--; )
00503       if (x[i].assigned())
00504         me = ME_INT_VAL;
00505       else
00506         x[i].subscribe(home, new (home) Index(home,this,c,i));
00507     View::schedule(home,this,me);
00508     this->force(home);
00509   }
00510 
00511   template <>
00512   forceinline
00513   LayeredGraph<BoolView>::LayeredGraph(Space* home, ViewArray<BoolView>& x0,
00514                                        DFA& d)
00515     : Propagator(home), c(home), x(x0), dfa(d), start(0), layers(NULL) {
00516     assert(x.size() > 0);
00517     for (int i=x.size(); i--; )
00518       if (!x[i].assigned())
00519         x[i].subscribe(home, new (home) Index(home,this,c,i));
00520     BoolView::schedule(home,this,ME_BOOL_VAL);
00521     this->force(home);
00522   }
00523 
00524   template <class View>
00525   forceinline size_t
00526   LayeredGraph<View>::dispose(Space* home) {
00527     this->unforce(home);
00528     c.dispose(home);
00529     dfa.~DFA();
00530     (void) Propagator::dispose(home);
00531     return sizeof(*this);
00532   }
00533 
00534   template <class View>
00535   ExecStatus
00536   LayeredGraph<View>::post(Space* home, ViewArray<View>& x, DFA& d) {
00537     if (x.size() == 0) {
00538       // Check whether the start state 0 is also a final state
00539       if ((d.final_fst() <= 0) && (d.final_lst() >= 0))
00540         return ES_OK;
00541       return ES_FAILED;
00542     }
00543     assert(x.size() > 0);
00544     for (int i=x.size(); i--; ) {
00545       DFA::Symbols s(d);
00546       GECODE_ME_CHECK(x[i].inter_v(home,s,false));
00547     }
00548     (void) new (home) LayeredGraph<View>(home,x,d);
00549     return ES_OK;
00550   }
00551 
00552   template <class View>
00553   forceinline
00554   LayeredGraph<View>::LayeredGraph(Space* home, bool share, 
00555                                    LayeredGraph<View>& p)
00556     : Propagator(home,share,p), layers(NULL) {
00557     assert(p.x.size() > 0);
00558     p.eliminate();
00559     c.update(home,share,p.c);
00560     x.update(home,share,p.x);
00561     dfa.update(home,share,p.dfa);
00562     start = p.start;
00563   }
00564 
00565   template <class View>
00566   PropCost
00567   LayeredGraph<View>::cost(ModEventDelta) const {
00568     return cost_hi(x.size(), PC_LINEAR_HI);
00569   }
00570 
00571   template <class View>
00572   Gecode::Support::Symbol
00573   LayeredGraph<View>::ati(void) {
00574     return Reflection::mangle<View>("Gecode::Int::Extensional::LayeredGraph");
00575   }
00576 
00577   template <class View>
00578   Reflection::ActorSpec
00579   LayeredGraph<View>::spec(const Space* home, Reflection::VarMap& m) const {
00580     Reflection::ActorSpec s(ati());
00581     return s << x.spec(home, m)
00582              << dfa.spec(m);
00583   }
00584 
00585   template <class View>
00586   void
00587   LayeredGraph<View>::post(Space* home, Reflection::VarMap& vars,
00588                            const Reflection::ActorSpec& spec) {
00589     spec.checkArity(2);
00590     ViewArray<View> x(home, vars, spec[0]);
00591     DFA dfa(vars, spec[1]);
00592     (void) new (home) LayeredGraph<View>(home,x,dfa);    
00593   }
00594 
00595   template <class View>
00596   Actor*
00597   LayeredGraph<View>::copy(Space* home, bool share) {
00598     return new (home) LayeredGraph<View>(home,share,*this);
00599   }
00600 
00601 }}}
00602 
00603 // STATISTICS: int-prop
00604