Generated on Tue Apr 18 10:21:35 2017 for Gecode by doxygen 1.6.3

ite.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, 2013
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/rel.hh>
00039 
00040 #include <algorithm>
00041 
00042 namespace Gecode { namespace Int { namespace Bool {
00043 
00044   template<class V0, class V1, class V2, PropCond pc>
00045   forceinline
00046   IteBase<V0,V1,V2,pc>::IteBase(Home home, BoolView b0, V0 y0, V1 y1, V2 y2)
00047     : Propagator(home), b(b0), x0(y0), x1(y1), x2(y2) {
00048     b.subscribe(home,*this,PC_BOOL_VAL);
00049     x0.subscribe(home,*this,pc);
00050     x1.subscribe(home,*this,pc);
00051     x2.subscribe(home,*this,pc);
00052   }
00053 
00054   template<class V0, class V1, class V2, PropCond pc>
00055   forceinline
00056   IteBase<V0,V1,V2,pc>::IteBase(Space& home, bool share,
00057                                 IteBase<V0,V1,V2,pc>& p)
00058     : Propagator(home,share,p) {
00059     b.update(home,share,p.b);
00060     x0.update(home,share,p.x0);
00061     x1.update(home,share,p.x1);
00062     x2.update(home,share,p.x2);
00063   }
00064 
00065   template<class V0, class V1, class V2, PropCond pc>
00066   PropCost
00067   IteBase<V0,V1,V2,pc>::cost(const Space&, const ModEventDelta&) const {
00068     return PropCost::ternary(PropCost::LO);
00069   }
00070 
00071   template<class V0, class V1, class V2, PropCond pc>
00072   void
00073   IteBase<V0,V1,V2,pc>::reschedule(Space& home) {
00074     b.reschedule(home,*this,PC_BOOL_VAL);
00075     x0.reschedule(home,*this,pc);
00076     x1.reschedule(home,*this,pc);
00077     x2.reschedule(home,*this,pc);
00078   }
00079 
00080   template<class V0, class V1, class V2, PropCond pc>
00081   forceinline size_t
00082   IteBase<V0,V1,V2,pc>::dispose(Space& home) {
00083     b.cancel(home,*this,PC_BOOL_VAL);
00084     x0.cancel(home,*this,pc);
00085     x1.cancel(home,*this,pc);
00086     x2.cancel(home,*this,pc);
00087     (void) Propagator::dispose(home);
00088     return sizeof(*this);
00089   }
00090 
00091 
00092 
00093   template<class V0, class V1, class V2>
00094   forceinline
00095   IteBnd<V0,V1,V2>::IteBnd(Home home, BoolView b, V0 x0, V1 x1, V2 x2)
00096     : IteBase<V0,V1,V2,PC_INT_BND>(home,b,x0,x1,x2) {}
00097 
00098   template<class V0, class V1, class V2>
00099   forceinline
00100   IteBnd<V0,V1,V2>::IteBnd(Space& home, bool share, IteBnd<V0,V1,V2>& p)
00101     : IteBase<V0,V1,V2,PC_INT_BND>(home,share,p) {}
00102 
00103   template<class V0, class V1, class V2>
00104   Actor*
00105   IteBnd<V0,V1,V2>::copy(Space& home, bool share) {
00106     return new (home) IteBnd<V0,V1,V2>(home,share,*this);
00107   }
00108 
00109   template<class V0, class V1, class V2>
00110   inline ExecStatus
00111   IteBnd<V0,V1,V2>::post(Home home, BoolView b, V0 x0, V1 x1, V2 x2) {
00112     if (b.one())
00113       return Rel::EqBnd<V2,V0>::post(home,x2,x0);
00114     if (b.zero())
00115       return Rel::EqBnd<V2,V1>::post(home,x2,x1);
00116     GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00117     GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00118     (void) new (home) IteBnd<V0,V1,V2>(home,b,x0,x1,x2);
00119     return ES_OK;
00120   }
00121 
00122   template<class V0, class V1, class V2>
00123   ExecStatus
00124   IteBnd<V0,V1,V2>::propagate(Space& home, const ModEventDelta&) {
00125     if (b.one())
00126       GECODE_REWRITE(*this,(Rel::EqBnd<V2,V0>::post(home(*this),x2,x0)));
00127     if (b.zero())
00128       GECODE_REWRITE(*this,(Rel::EqBnd<V2,V1>::post(home(*this),x2,x1)));
00129 
00130     GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00131     GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00132 
00133     RelTest eq20 = rtest_eq_bnd(x2,x0);
00134     RelTest eq21 = rtest_eq_bnd(x2,x1);
00135 
00136     if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE))
00137       return ES_FAILED;
00138 
00139     if (eq20 == RT_FALSE) {
00140       GECODE_ME_CHECK(b.zero_none(home));
00141       if (eq21 == RT_TRUE)
00142         return home.ES_SUBSUMED(*this);
00143       else
00144         GECODE_REWRITE(*this,(Rel::EqBnd<V2,V1>::post(home(*this),x2,x1)));
00145     }
00146 
00147     if (eq21 == RT_FALSE) {
00148       GECODE_ME_CHECK(b.one_none(home));
00149       if (eq20 == RT_TRUE)
00150         return home.ES_SUBSUMED(*this);
00151       else
00152         GECODE_REWRITE(*this,(Rel::EqBnd<V2,V0>::post(home(*this),x2,x0)));
00153     }
00154 
00155     if ((eq20 == RT_TRUE) && (eq21 == RT_TRUE))
00156       return home.ES_SUBSUMED(*this);
00157 
00158     return ES_FIX;
00159   }
00160 
00161 
00162 
00163   template<class V0, class V1, class V2>
00164   forceinline
00165   IteDom<V0,V1,V2>::IteDom(Home home, BoolView b, V0 x0, V1 x1, V2 x2)
00166     : IteBase<V0,V1,V2,PC_INT_DOM>(home,b,x0,x1,x2) {}
00167 
00168   template<class V0, class V1, class V2>
00169   forceinline
00170   IteDom<V0,V1,V2>::IteDom(Space& home, bool share, IteDom<V0,V1,V2>& p)
00171     : IteBase<V0,V1,V2,PC_INT_DOM>(home,share,p) {}
00172 
00173   template<class V0, class V1, class V2>
00174   Actor*
00175   IteDom<V0,V1,V2>::copy(Space& home, bool share) {
00176     return new (home) IteDom<V0,V1,V2>(home,share,*this);
00177   }
00178 
00179   template<class V0, class V1, class V2>
00180   inline ExecStatus
00181   IteDom<V0,V1,V2>::post(Home home, BoolView b, V0 x0, V1 x1, V2 x2) {
00182     if (b.one())
00183       return Rel::EqDom<V2,V0>::post(home,x2,x0);
00184     if (b.zero())
00185       return Rel::EqDom<V2,V1>::post(home,x2,x1);
00186     GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00187     GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00188     (void) new (home) IteDom<V0,V1,V2>(home,b,x0,x1,x2);
00189     return ES_OK;
00190   }
00191 
00192   template<class V0, class V1, class V2>
00193   PropCost
00194   IteDom<V0,V1,V2>::cost(const Space&, const ModEventDelta& med) const {
00195     if (V0::me(med) == ME_INT_DOM)
00196       return PropCost::ternary(PropCost::HI);
00197     else
00198       return PropCost::ternary(PropCost::LO);
00199   }
00200 
00201   template<class V0, class V1, class V2>
00202   ExecStatus
00203   IteDom<V0,V1,V2>::propagate(Space& home, const ModEventDelta& med) {
00204     if (b.one())
00205       GECODE_REWRITE(*this,(Rel::EqDom<V2,V0>::post(home(*this),x2,x0)));
00206     if (b.zero())
00207       GECODE_REWRITE(*this,(Rel::EqDom<V2,V1>::post(home(*this),x2,x1)));
00208 
00209     GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max())));
00210     GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min())));
00211 
00212     if (V0::me(med) != ME_INT_DOM) {
00213       RelTest eq20 = rtest_eq_bnd(x2,x0);
00214       RelTest eq21 = rtest_eq_bnd(x2,x1);
00215 
00216       if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE))
00217         return ES_FAILED;
00218 
00219       if (eq20 == RT_FALSE) {
00220         GECODE_ME_CHECK(b.zero_none(home));
00221         if (eq21 == RT_TRUE)
00222           return home.ES_SUBSUMED(*this);
00223         else
00224           GECODE_REWRITE(*this,
00225                          (Rel::EqDom<V2,V1>::post(home(*this),x2,x1)));
00226       }
00227 
00228       if (eq21 == RT_FALSE) {
00229         GECODE_ME_CHECK(b.one_none(home));
00230         if (eq20 == RT_TRUE)
00231           return home.ES_SUBSUMED(*this);
00232         else
00233           GECODE_REWRITE(*this,
00234                          (Rel::EqDom<V2,V0>::post(home(*this),x2,x0)));
00235       }
00236 
00237       if ((eq20 == RT_TRUE) && (eq21 == RT_TRUE))
00238         return home.ES_SUBSUMED(*this);
00239 
00240       return home.ES_FIX_PARTIAL(*this,V0::med(ME_INT_DOM));
00241     }
00242 
00243     RelTest eq20 = rtest_eq_dom(x2,x0);
00244     RelTest eq21 = rtest_eq_dom(x2,x1);
00245 
00246     if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE))
00247       return ES_FAILED;
00248 
00249     if (eq20 == RT_FALSE) {
00250       GECODE_ME_CHECK(b.zero_none(home));
00251       if (eq21 == RT_TRUE)
00252         return home.ES_SUBSUMED(*this);
00253       else
00254         GECODE_REWRITE(*this,
00255                        (Rel::EqDom<V2,V1>::post(home(*this),x2,x1)));
00256     }
00257 
00258     if (eq21 == RT_FALSE) {
00259       GECODE_ME_CHECK(b.one_none(home));
00260       if (eq20 == RT_TRUE)
00261         return home.ES_SUBSUMED(*this);
00262       else
00263         GECODE_REWRITE(*this,
00264                        (Rel::EqDom<V2,V0>::post(home(*this),x2,x0)));
00265     }
00266 
00267     assert((eq20 != RT_TRUE) || (eq21 != RT_TRUE));
00268 
00269     ViewRanges<V0> r0(x0);
00270     ViewRanges<V1> r1(x1);
00271     Iter::Ranges::Union<ViewRanges<V0>,ViewRanges<V1> > u(r0,r1);
00272 
00273     if (!shared<V0,V2>(x0,x2) && !shared<V1,V2>(x1,x2))
00274       GECODE_ME_CHECK(x2.inter_r(home,u,false));
00275     else
00276       GECODE_ME_CHECK(x2.inter_r(home,u,true));
00277 
00278     return ES_FIX;
00279   }
00280 
00281 }}}
00282 
00283 // STATISTICS: int-prop