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

channel-bool.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Guido Tack, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-01-31 18:29:16 +0100 (Thu, 31 Jan 2008) $ by $Author: tack $
00011  *     $Revision: 6017 $
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 "gecode/int.hh"
00039 
00040 namespace Gecode { namespace Set { namespace Int {
00041       
00042   template <class View>
00043   template <class A>
00044   forceinline
00045   ChannelBool<View>::IndexAdvisor::IndexAdvisor(Space* home, 
00046                                                 ChannelBool<View>* p, 
00047                                                 Council<A>& c, int index)
00048     : Advisor(home,p,c), idx(index) {
00049     if (idx == -1)
00050       p->y.subscribe(home,this);
00051     else {
00052       p->x[idx].subscribe(home,this);
00053     }
00054   }
00055 
00056   template <class View>
00057   forceinline
00058   ChannelBool<View>::IndexAdvisor::IndexAdvisor(Space* home, bool share, 
00059                                                 IndexAdvisor& a) 
00060     : Advisor(home,share,a), idx(a.idx) {}
00061 
00062   template <class View>
00063   forceinline int
00064   ChannelBool<View>::IndexAdvisor::index(void) const {
00065     return idx;
00066   }
00067 
00068   template <class View>
00069   template <class A>
00070   forceinline void
00071   ChannelBool<View>::IndexAdvisor::dispose(Space* home, Council<A>& c) {
00072     ChannelBool<View>* p = static_cast<ChannelBool<View>*>(propagator());
00073     if (idx == -1)
00074       p->y.cancel(home,this);
00075     else {
00076       p->x[idx].cancel(home,this);
00077     }
00078     Advisor::dispose(home,c);
00079   }
00080 
00081   template <class View>
00082   forceinline
00083   ChannelBool<View>::ChannelBool(Space* home, 
00084                                  ViewArray<Gecode::Int::BoolView>& x0,
00085                                  View y0)
00086     : Super(home,x0,y0), co(home), running(false) {
00087       bool assigned = false;
00088       for (int i=x.size(); i--;) {
00089         if (x[i].zero()) {
00090           assigned = true;
00091           SetDelta d;
00092           zeros.include(home, i, i, d);
00093         } else if (x[i].one()) {
00094           assigned = true;
00095           SetDelta d;
00096           ones.include(home, i, i, d);          
00097         } else {
00098           (void) new (home) IndexAdvisor(home,this,co,i);
00099         }
00100       }
00101       if (assigned)
00102         Gecode::Int::BoolView::schedule(home, this, Gecode::Int::ME_BOOL_VAL);
00103       View::schedule(home, this, y.assigned() ? ME_SET_VAL : ME_SET_BB);
00104       (void) new (home) IndexAdvisor(home,this,co,-1);
00105     }
00106       
00107   template <class View>
00108   forceinline
00109   ChannelBool<View>::ChannelBool(Space* home, bool share, ChannelBool& p)
00110     : Super(home,share,p), running(false) {
00111     co.update(home, share, p.co);  
00112   }
00113 
00114   template <class View>
00115   forceinline ExecStatus
00116   ChannelBool<View>::post(Space* home, ViewArray<Gecode::Int::BoolView>& x,
00117                           View y) {
00118     GECODE_ME_CHECK(y.intersect(home, 0, x.size()-1));
00119     (void) new (home) ChannelBool(home,x,y);
00120     return ES_OK;
00121   }
00122 
00123   template <class View>
00124   PropCost
00125   ChannelBool<View>::cost(ModEventDelta) const { return PC_QUADRATIC_LO; }
00126 
00127   template <class View>
00128   size_t
00129   ChannelBool<View>::dispose(Space* home) {
00130     assert(!home->failed());
00131     co.dispose(home);
00132     (void) Super::dispose(home);
00133     return sizeof(*this);
00134   }
00135 
00136   template <class View>
00137   Actor*
00138   ChannelBool<View>::copy(Space* home, bool share) {
00139     return new (home) ChannelBool(home,share,*this);
00140   }
00141 
00142   template <class View>
00143   ExecStatus
00144   ChannelBool<View>::propagate(Space* home, ModEventDelta) {
00145     running = true;
00146     if (zeros.size() > 0) {
00147       BndSetRanges zi(zeros);
00148       GECODE_ME_CHECK(y.excludeI(home, zi));
00149       zeros.init(home);
00150     }
00151     if (ones.size() > 0) {
00152       BndSetRanges oi(ones);
00153       GECODE_ME_CHECK(y.includeI(home, oi));
00154       ones.init(home);
00155     }
00156     running = false;
00157     
00158     if (delta.glbMin() != 1 || delta.glbMax() != 0) {    
00159       if (!delta.glbAny()) {
00160         for (int i=delta.glbMin(); i<=delta.glbMax(); i++)
00161           GECODE_ME_CHECK(x[i].one(home));
00162       } else {
00163         GlbRanges<View> glb(y);
00164         for (Iter::Ranges::ToValues<GlbRanges<View> > gv(glb); gv(); ++gv) {
00165           GECODE_ME_CHECK(x[gv.val()].one(home));
00166         }      
00167       }
00168     }
00169     if (delta.lubMin() != 1 || delta.lubMax() != 0) {
00170       if (!delta.lubAny()) {
00171         for (int i=delta.lubMin(); i<=delta.lubMax(); i++)
00172           GECODE_ME_CHECK(x[i].zero(home));      
00173       } else {
00174         int cur = 0;
00175         for (LubRanges<View> lub(y); lub(); ++lub) {
00176           for (; cur < lub.min(); cur++) {
00177             GECODE_ME_CHECK(x[cur].zero(home));
00178           }
00179           cur = lub.max() + 1;
00180         }
00181         for (; cur < x.size(); cur++) {
00182           GECODE_ME_CHECK(x[cur].zero(home));
00183         }      
00184       }
00185     }
00186     
00187     new (&delta) SetDelta();
00188 
00189     return y.assigned() ? ES_SUBSUMED(this,home) : ES_FIX;
00190   }
00191 
00192   template <class View>
00193   ExecStatus
00194   ChannelBool<View>::advise(Space* home, Advisor* _a, const Delta* _d) {
00195     IndexAdvisor* a = static_cast<IndexAdvisor* >(_a);
00196     const SetDelta* d = static_cast<const SetDelta*>(_d);
00197 
00198     ModEvent me = View::modevent(d);
00199     int index = a->index();
00200     if ( (running && index == -1 && me != ME_SET_VAL)
00201          || (index == -1 && me == ME_SET_CARD) ) {
00202       return ES_OK;
00203     }
00204 
00205     if (index >= 0) {
00206       if (x[index].zero()) {
00207         SetDelta dummy;
00208         zeros.include(home, index, index, dummy);
00209       } else {
00210         assert(x[index].one());
00211         SetDelta dummy;
00212         ones.include(home, index, index, dummy);
00213       }
00214       return ES_SUBSUMED_NOFIX(a, home, co);
00215     }
00216 
00217     if (a->index() == -1 && Rel::testSetEventLB(me)) {
00218       if (d->glbAny()) {
00219         new (&delta)
00220           SetDelta(2,0, delta.lubMin(), delta.lubMax());
00221       } else {
00222         if (delta.glbMin() == 1 && delta.glbMax() == 0) {
00223           new (&delta)
00224             SetDelta(d->glbMin(), d->glbMax(),
00225                      delta.lubMin(), delta.lubMax());
00226         } else {
00227           if (delta.glbMin() != 2 || delta.glbMax() != 0) {
00228             if ((delta.glbMin() <= d->glbMin() && delta.glbMax() >= d->glbMin())
00229                 ||
00230                 (delta.glbMin() <= d->glbMax() && delta.glbMax() >= d->glbMax())    
00231                ) {
00232                  new (&delta)
00233                    SetDelta(std::min(delta.glbMin(), d->glbMin()),
00234                             std::max(delta.glbMax(), d->glbMax()),
00235                             delta.lubMin(), delta.lubMax());
00236             } else {
00237               new (&delta)
00238                 SetDelta(2, 0, delta.lubMin(), delta.lubMax());            
00239             }
00240           }
00241         }
00242       }
00243     }
00244     if (a->index() == -1 && Rel::testSetEventUB(me)) {
00245       if (d->lubAny()) {
00246         new (&delta)
00247           SetDelta(delta.glbMin(), delta.glbMax(), 2,0);
00248       } else {
00249         if (delta.lubMin() == 1 && delta.lubMax() == 0) {
00250           new (&delta)
00251             SetDelta(delta.glbMin(), delta.glbMax(),
00252                      d->lubMin(), d->lubMax());
00253         } else {
00254           if (delta.lubMin() != 2 || delta.lubMax() != 0) {
00255             if ((delta.lubMin() <= d->lubMin() && delta.lubMax() >= d->lubMin())
00256                 ||
00257                 (delta.lubMin() <= d->lubMax() && delta.lubMax() >= d->lubMax())    
00258                ) {
00259                  new (&delta)
00260                    SetDelta(delta.lubMin(), delta.lubMax(),
00261                             std::min(delta.lubMin(), d->lubMin()),
00262                             std::max(delta.lubMax(), d->lubMax())
00263                             );
00264             } else {
00265               new (&delta)
00266                 SetDelta(delta.glbMin(), delta.glbMax(), 2, 0);          
00267             }
00268           }
00269         }
00270       }
00271     }
00272     
00273     if (y.assigned())
00274       return ES_SUBSUMED_NOFIX(a, home, co);
00275     else
00276       return ES_NOFIX;
00277   }
00278 
00279   template <class View>
00280   Support::Symbol
00281   ChannelBool<View>::ati(void) {
00282     return Reflection::mangle<View>("Gecode::Set::Int::ChannelBool");
00283   }
00284 
00285   template <class View>
00286   Reflection::ActorSpec
00287   ChannelBool<View>::spec(const Space* home, Reflection::VarMap& m) const {
00288     return Super::spec(home, m, ati());
00289   }
00290   
00291   template <class View>
00292   void
00293   ChannelBool<View>::post(Space* home, Reflection::VarMap& vars,
00294                           const Reflection::ActorSpec& spec) {
00295     spec.checkArity(2);
00296     ViewArray<Gecode::Int::BoolView> x0(home, vars, spec[0]);
00297     View x1(home, vars, spec[1]);
00298     (void) new (home) ChannelBool<View>(home,x0,x1);
00299   }
00300 
00301 }}}
00302 
00303 // STATISTICS: set-prop