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