Generated on Tue Apr 18 10:22:01 2017 for Gecode by doxygen 1.6.3

bool.hpp

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: 2016-06-29 17:28:17 +0200 (Wed, 29 Jun 2016) $ by $Author: schulte $
00011  *     $Revision: 15137 $
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 Channel {
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(Home 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       if (y.assigned()) {
00105         if (y.glbSize()==static_cast<unsigned int>(y.glbMax()-y.glbMin()+1)) {
00106           new (&delta) SetDelta(y.glbMin(),y.glbMax(),1,0);
00107         } else {
00108           new (&delta) SetDelta(2,0,1,0);
00109         }
00110       }
00111       (void) new (home) IndexAdvisor(home,*this,co,-1);
00112     }
00113 
00114   template<class View>
00115   forceinline
00116   ChannelBool<View>::ChannelBool(Space& home, bool share, ChannelBool& p)
00117     : Super(home,share,p), running(false) {
00118     co.update(home, share, p.co);
00119   }
00120 
00121   template<class View>
00122   forceinline ExecStatus
00123   ChannelBool<View>::post(Home home, ViewArray<Gecode::Int::BoolView>& x,
00124                           View y) {
00125     GECODE_ME_CHECK(y.intersect(home, 0, x.size()-1));
00126     (void) new (home) ChannelBool(home,x,y);
00127     return ES_OK;
00128   }
00129 
00130   template<class View>
00131   PropCost
00132   ChannelBool<View>::cost(const Space&, const ModEventDelta&) const {
00133     return PropCost::quadratic(PropCost::LO, x.size()+1);
00134   }
00135 
00136   template<class View>
00137   void
00138   ChannelBool<View>::reschedule(Space& home) {
00139     x.reschedule(home,*this,Gecode::Int::PC_BOOL_VAL);
00140     View::schedule(home, *this, y.assigned() ? ME_SET_VAL : ME_SET_BB);
00141   }
00142 
00143   template<class View>
00144   forceinline size_t
00145   ChannelBool<View>::dispose(Space& home) {
00146     co.dispose(home);
00147     (void) Super::dispose(home);
00148     return sizeof(*this);
00149   }
00150 
00151   template<class View>
00152   Actor*
00153   ChannelBool<View>::copy(Space& home, bool share) {
00154     return new (home) ChannelBool(home,share,*this);
00155   }
00156 
00157   template<class View>
00158   ExecStatus
00159   ChannelBool<View>::propagate(Space& home, const ModEventDelta&) {
00160     running = true;
00161     if (zeros.size() > 0) {
00162       BndSetRanges zi(zeros);
00163       GECODE_ME_CHECK(y.excludeI(home, zi));
00164       zeros.init(home);
00165     }
00166     if (ones.size() > 0) {
00167       BndSetRanges oi(ones);
00168       GECODE_ME_CHECK(y.includeI(home, oi));
00169       ones.init(home);
00170     }
00171     running = false;
00172 
00173     if (delta.glbMin() != 1 || delta.glbMax() != 0) {
00174       if (!delta.glbAny()) {
00175         for (int i=delta.glbMin(); i<=delta.glbMax(); i++)
00176           GECODE_ME_CHECK(x[i].one(home));
00177       } else {
00178         GlbRanges<View> glb(y);
00179         for (Iter::Ranges::ToValues<GlbRanges<View> > gv(glb); gv(); ++gv) {
00180           GECODE_ME_CHECK(x[gv.val()].one(home));
00181         }
00182       }
00183     }
00184     if (delta.lubMin() != 1 || delta.lubMax() != 0) {
00185       if (!delta.lubAny()) {
00186         for (int i=delta.lubMin(); i<=delta.lubMax(); i++)
00187           GECODE_ME_CHECK(x[i].zero(home));
00188       } else {
00189         int cur = 0;
00190         for (LubRanges<View> lub(y); lub(); ++lub) {
00191           for (; cur < lub.min(); cur++) {
00192             GECODE_ME_CHECK(x[cur].zero(home));
00193           }
00194           cur = lub.max() + 1;
00195         }
00196         for (; cur < x.size(); cur++) {
00197           GECODE_ME_CHECK(x[cur].zero(home));
00198         }
00199       }
00200     }
00201 
00202     new (&delta) SetDelta();
00203 
00204     return y.assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
00205   }
00206 
00207   template<class View>
00208   ExecStatus
00209   ChannelBool<View>::advise(Space& home, Advisor& _a, const Delta& _d) {
00210     IndexAdvisor& a = static_cast<IndexAdvisor&>(_a);
00211     const SetDelta& d = static_cast<const SetDelta&>(_d);
00212 
00213     ModEvent me = View::modevent(d);
00214     int index = a.index();
00215     if ( (running && index == -1 && me != ME_SET_VAL)
00216          || (index == -1 && me == ME_SET_CARD) ) {
00217       return ES_OK;
00218     }
00219 
00220     if (index >= 0) {
00221       if (x[index].zero()) {
00222         SetDelta dummy;
00223         zeros.include(home, index, index, dummy);
00224       } else {
00225         assert(x[index].one());
00226         SetDelta dummy;
00227         ones.include(home, index, index, dummy);
00228       }
00229       return home.ES_NOFIX_DISPOSE( co, a);
00230     }
00231 
00232     if ((a.index() == -1) && Rel::testSetEventLB(me)) {
00233       if (d.glbAny()) {
00234         new (&delta)
00235           SetDelta(2,0, delta.lubMin(), delta.lubMax());
00236       } else {
00237         if (delta.glbMin() == 1 && delta.glbMax() == 0) {
00238           new (&delta)
00239             SetDelta(d.glbMin(), d.glbMax(),
00240                      delta.lubMin(), delta.lubMax());
00241         } else {
00242           if (delta.glbMin() != 2 || delta.glbMax() != 0) {
00243             if ((delta.glbMin() <= d.glbMin() && delta.glbMax() >= d.glbMin())
00244                 ||
00245                 (delta.glbMin() <= d.glbMax() && delta.glbMax() >= d.glbMax())
00246                ) {
00247                  new (&delta)
00248                    SetDelta(std::min(delta.glbMin(), d.glbMin()),
00249                             std::max(delta.glbMax(), d.glbMax()),
00250                             delta.lubMin(), delta.lubMax());
00251             } else {
00252               new (&delta)
00253                 SetDelta(2, 0, delta.lubMin(), delta.lubMax());
00254             }
00255           }
00256         }
00257       }
00258     }
00259     if ((a.index() == -1) && Rel::testSetEventUB(me)) {
00260       if (d.lubAny()) {
00261         new (&delta)
00262           SetDelta(delta.glbMin(), delta.glbMax(), 2,0);
00263       } else {
00264         if (delta.lubMin() == 1 && delta.lubMax() == 0) {
00265           new (&delta)
00266             SetDelta(delta.glbMin(), delta.glbMax(),
00267                      d.lubMin(), d.lubMax());
00268         } else {
00269           if (delta.lubMin() != 2 || delta.lubMax() != 0) {
00270             if ((delta.lubMin() <= d.lubMin() && delta.lubMax() >= d.lubMin())
00271                 ||
00272                 (delta.lubMin() <= d.lubMax() && delta.lubMax() >= d.lubMax())
00273                ) {
00274                  new (&delta)
00275                    SetDelta(delta.lubMin(), delta.lubMax(),
00276                             std::min(delta.lubMin(), d.lubMin()),
00277                             std::max(delta.lubMax(), d.lubMax())
00278                             );
00279             } else {
00280               new (&delta)
00281                 SetDelta(delta.glbMin(), delta.glbMax(), 2, 0);
00282             }
00283           }
00284         }
00285       }
00286     }
00287     if (y.assigned())
00288       return home.ES_NOFIX_DISPOSE( co, a);
00289     else
00290       return ES_NOFIX;
00291   }
00292 
00293 }}}
00294 
00295 // STATISTICS: set-prop