Generated on Wed Nov 1 15:04:28 2006 for Gecode by doxygen 1.4.5

abs.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2004
00008  *     Guido Tack, 2006
00009  *
00010  *  Last modified:
00011  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00012  *     $Revision: 3512 $
00013  *
00014  *  This file is part of Gecode, the generic constraint
00015  *  development environment:
00016  *     http://www.gecode.org
00017  *
00018  *  See the file "LICENSE" for information on usage and
00019  *  redistribution of this file, and for a
00020  *     DISCLAIMER OF ALL WARRANTIES.
00021  *
00022  */
00023 
00024 #include "gecode/iter.hh"
00025 #include <algorithm>
00026 
00027 namespace Gecode { namespace Int { namespace Arithmetic {
00028 
00029   template <class View, template <class View0,class View1> class Eq>
00030   ExecStatus
00031   prop_bnd(Space* home, View x0, View x1) {
00032     if (x0.assigned()) {
00033       GECODE_ME_CHECK(x1.eq(home,(x0.val() < 0) ? -x0.val() : x0.val()));
00034       return ES_SUBSUMED;
00035     }
00036 
00037     if (x1.assigned()) {
00038       if (x0.min() >= 0) {
00039         GECODE_ME_CHECK(x0.eq(home,x1.val()));
00040       } else if (x0.max() <= 0) {
00041         GECODE_ME_CHECK(x0.eq(home,-x1.val()));
00042       } else if (x1.val() == 0) {
00043         GECODE_ME_CHECK(x0.eq(home,0));
00044       } else {
00045         Iter::Ranges::Array::Range r[2]
00046           = { {-x1.val(),-x1.val()}, {x1.val(),x1.val()} };
00047         Iter::Ranges::Array i(r,2);
00048         GECODE_ME_CHECK(x0.inter(home,i));
00049       }
00050       return ES_SUBSUMED;
00051     }
00052 
00053     if (x0.min() >= 0) {
00054       return (Eq<View,View>::post(home,x0,x1) == ES_FAILED)
00055         ? ES_FAILED : ES_SUBSUMED;
00056     }
00057 
00058     if (x0.max() <= 0) {
00059       MinusView mx0(x0);
00060       return (Eq<MinusView,View>::post(home,mx0,x1) == ES_FAILED)
00061         ? ES_FAILED : ES_SUBSUMED;
00062     }
00063 
00064     GECODE_ME_CHECK(x1.lq(home,std::max(x0.max(),-x0.min())));
00065     GECODE_ME_CHECK(x0.lq(home,x1.max()));
00066     GECODE_ME_CHECK(x0.gq(home,-x1.max()));
00067     return ES_NOFIX;
00068   }
00069 
00070   template <class View>
00071   forceinline
00072   AbsBnd<View>::AbsBnd(Space* home, View x0, View x1)
00073     : BinaryPropagator<View,PC_INT_BND>(home,x0,x1) {}
00074 
00075   template <class View>
00076   ExecStatus
00077   AbsBnd<View>::post(Space* home, View x0, View x1) {
00078     GECODE_ME_CHECK(x1.gq(home,0));
00079     if (!same(x0,x1)) {
00080       (void) new (home) AbsBnd<View>(home,x0,x1);
00081     }
00082     return ES_OK;
00083   }
00084 
00085 
00086   template <class View>
00087   forceinline
00088   AbsBnd<View>::AbsBnd(Space* home, bool share, AbsBnd<View>& p)
00089     : BinaryPropagator<View,PC_INT_BND>(home,share,p) {}
00090 
00091   template <class View>
00092   Actor*
00093   AbsBnd<View>::copy(Space* home,bool share) {
00094     return new (home) AbsBnd<View>(home,share,*this);
00095   }
00096 
00097   template <class View>
00098   PropCost
00099   AbsBnd<View>::cost(void) const {
00100     if (View::pme(this) == ME_INT_VAL)
00101       return PC_UNARY_LO;
00102     return PC_BINARY_LO;
00103   }
00104 
00105   template <class View>
00106   ExecStatus
00107   AbsBnd<View>::propagate(Space* home) {
00108     return prop_bnd<View,Rel::EqBnd>(home, x0, x1);
00109   }
00110 
00111   template <class View>
00112   forceinline
00113   AbsDom<View>::AbsDom(Space* home, View x0, View x1)
00114     : BinaryPropagator<View,PC_INT_DOM>(home,x0,x1) {}
00115 
00116   template <class View>
00117   ExecStatus
00118   AbsDom<View>::post(Space* home, View x0, View x1) {
00119     if (x0.min() >= 0) {
00120       return Rel::EqDom<View,View>::post(home,x0,x1);
00121     } else if (x0.max() <= 0) {
00122       MinusView mx0(x0);
00123       return Rel::EqDom<MinusView,View>::post(home,mx0,x1);
00124     }
00125     GECODE_ME_CHECK(x1.gq(home,0));
00126     if (!same(x0,x1)) {
00127       (void) new (home) AbsDom<View>(home,x0,x1);
00128     }
00129     return ES_OK;
00130   }
00131 
00132   template <class View>
00133   forceinline
00134   AbsDom<View>::AbsDom(Space* home, bool share, AbsDom<View>& p)
00135     : BinaryPropagator<View,PC_INT_DOM>(home,share,p) {}
00136 
00137   template <class View>
00138   Actor*
00139   AbsDom<View>::copy(Space* home,bool share) {
00140     return new (home) AbsDom<View>(home,share,*this);
00141   }
00142 
00143   template <class View>
00144   PropCost
00145   AbsDom<View>::cost(void) const {
00146     if (View::pme(this) == ME_INT_VAL)
00147       return PC_UNARY_LO;
00148     if (View::pme(this) == ME_INT_DOM)
00149       return PC_BINARY_HI;
00150     return PC_BINARY_LO;
00151   }
00152 
00153   template <class View>
00154   ExecStatus
00155   AbsDom<View>::propagate(Space* home) {
00156 
00157     if (View::pme(this) != ME_INT_DOM) {
00158       ExecStatus es = prop_bnd<View,Rel::EqDom>(home, x0, x1);
00159       if (es != ES_NOFIX)
00160         return es;
00161       return this->ES_NOFIX_PARTIAL(View::pme(ME_INT_DOM));
00162     }
00163 
00164     Iter::Ranges::Singleton positive(0, Limits::Int::int_max);
00165     Iter::Ranges::Singleton negative(Limits::Int::int_min, 0);
00166 
00167     IntVarRanges xr1(x0);
00168     IntVarRanges xr2(x0);
00169 
00170     Iter::Ranges::Inter<Iter::Ranges::Singleton,
00171       IntVarRanges> posInter(positive, xr1);
00172     Iter::Ranges::Inter<Iter::Ranges::Singleton,
00173       IntVarRanges> negInter(negative, xr2);
00174     Iter::Ranges::Minus<Iter::Ranges::Inter<Iter::Ranges::Singleton,
00175       IntVarRanges> > mneg(negInter);
00176     Iter::Ranges::Union<Iter::Ranges::Inter<Iter::Ranges::Singleton,
00177       IntVarRanges>,
00178       Iter::Ranges::Minus<Iter::Ranges::Inter<
00179       Iter::Ranges::Singleton,
00180       IntVarRanges> > >
00181       u(posInter, mneg);
00182 
00183     GECODE_ME_CHECK(x1.inter(home, u));
00184 
00185     IntVarRanges x1r1(x1);
00186     IntVarRanges x1r2(x1);
00187 
00188     Iter::Ranges::Minus<IntVarRanges> x1m(x1r2);
00189     Iter::Ranges::Union<IntVarRanges,
00190       Iter::Ranges::Minus<IntVarRanges> > u2(x1r1,x1m);
00191     GECODE_ME_CHECK(x0.inter(home, u2));
00192 
00193     if (x1.assigned())
00194       return ES_SUBSUMED;
00195 
00196     if (x0.min() >= 0) {
00197       return (Rel::EqDom<View,View>::post(home,x0,x1) == ES_FAILED)
00198         ? ES_FAILED : ES_SUBSUMED;
00199     }
00200 
00201     if (x0.max() <= 0) {
00202       MinusView mx0(x0);
00203       return (Rel::EqDom<MinusView,View>::post(home,mx0,x1) == ES_FAILED)
00204         ? ES_FAILED : ES_SUBSUMED;
00205     }
00206 
00207     return ES_FIX;
00208   }
00209 
00210 }}}
00211 
00212 // STATISTICS: int-prop
00213