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

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  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-02-18 01:59:54 +0100 (Mon, 18 Feb 2008) $ by $Author: schulte $
00011  *     $Revision: 6192 $
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 namespace Gecode { namespace Int {
00039 
00040   /*
00041    * Creation of new variable implementations
00042    *
00043    */
00044   forceinline
00045   BoolVarImp::BoolVarImp(int n) {
00046     assert(bits() == 0);
00047     bits() |= (n << 1) | n;
00048   }
00049   forceinline
00050   BoolVarImp::BoolVarImp(Space* home, int min, int max)
00051     : BoolVarImpBase(home) {
00052     assert(bits() == 0);
00053     bits() |= (max << 1) | min;
00054   }
00055 
00056 
00057   /*
00058    * Operations on integer variable implementations
00059    *
00060    */
00061   forceinline BoolStatus
00062   BoolVarImp::status(void) const {
00063     return bits() & 3;
00064   }
00065   forceinline int
00066   BoolVarImp::min(void) const {
00067     return bits() & 1;
00068   }
00069   forceinline int
00070   BoolVarImp::max(void) const {
00071     return (bits() & 2) >> 1;
00072   }
00073   forceinline int
00074   BoolVarImp::med(void) const {
00075     return min();
00076   }
00077 
00078   forceinline int
00079   BoolVarImp::val(void) const {
00080     assert(status() != NONE);    
00081     return min();
00082   }
00083 
00084   forceinline bool
00085   BoolVarImp::range(void) const {
00086     return true;
00087   }
00088   forceinline bool
00089   BoolVarImp::assigned(void) const {
00090     return status() != NONE;
00091   }
00092 
00093 
00094   forceinline unsigned int
00095   BoolVarImp::width(void) const {
00096     return assigned() ? 1U : 2U;
00097   }
00098 
00099   forceinline unsigned int
00100   BoolVarImp::size(void) const {
00101     return assigned() ? 1U : 2U;
00102   }
00103 
00104   forceinline unsigned int
00105   BoolVarImp::regret_min(void) const {
00106     return assigned() ? 1U : 0U;
00107   }
00108   forceinline unsigned int
00109   BoolVarImp::regret_max(void) const {
00110     return assigned() ? 1U : 0U;
00111   }
00112 
00113 
00114 
00115   /*
00116    * Tests
00117    *
00118    */
00119 
00120   forceinline bool
00121   BoolVarImp::in(int n) const {
00122     return (n >= min()) && (n <= max());
00123   }
00124   forceinline bool
00125   BoolVarImp::in(double n) const {
00126     return (n >= min()) && (n <= max());
00127   }
00128 
00129 
00130   /*
00131    * Boolean domain tests
00132    *
00133    */
00134   forceinline bool
00135   BoolVarImp::zero(void) const {
00136     return status() < NONE;
00137   }
00138   forceinline bool
00139   BoolVarImp::one(void) const {
00140     return status() > NONE;
00141   }
00142   forceinline bool
00143   BoolVarImp::none(void) const {
00144     return status() == NONE;
00145   }
00146 
00147   
00148   /*
00149    * Support for delta information
00150    *
00151    */
00152   forceinline ModEvent
00153   BoolVarImp::modevent(const Delta*) {
00154     return ME_BOOL_VAL;
00155   }
00156   forceinline int 
00157   BoolVarImp::min(const Delta*) const {
00158     return 1-val();
00159   }
00160   forceinline int 
00161   BoolVarImp::max(const Delta*) const {
00162     return 1-val();
00163   }
00164   forceinline bool 
00165   BoolVarImp::any(const Delta*) const {
00166     return false;
00167   }
00168 
00169 
00170   /*
00171    * Boolean tell operations
00172    *
00173    */
00174   forceinline ModEvent
00175   BoolVarImp::zero(Space* home) {
00176     if (one())  return ME_BOOL_FAILED;
00177     if (zero()) return ME_BOOL_NONE;
00178     return zero_none(home);
00179   }
00180   forceinline ModEvent
00181   BoolVarImp::one(Space* home) {
00182     if (one())  return ME_BOOL_NONE;
00183     if (zero()) return ME_BOOL_FAILED;
00184     return one_none(home);
00185   }
00186 
00187 
00188   /*
00189    * Tell operations
00190    *
00191    */
00192   forceinline ModEvent
00193   BoolVarImp::gq(Space* home, int n) {
00194     if (n <= 0) return ME_INT_NONE;
00195     if (n > 1)  return ME_INT_FAILED;
00196     return one(home);
00197   }
00198   forceinline ModEvent
00199   BoolVarImp::gq(Space* home, double n) {
00200     if (n <= 0) return ME_INT_NONE;
00201     if (n > 1)  return ME_INT_FAILED;
00202     return one(home);
00203   }
00204 
00205 
00206   forceinline ModEvent
00207   BoolVarImp::lq(Space* home, int n) {
00208     if (n < 0)  return ME_INT_FAILED;
00209     if (n >= 1) return ME_INT_NONE;
00210     return zero(home);
00211   }
00212   forceinline ModEvent
00213   BoolVarImp::lq(Space* home, double n) {
00214     if (n < 0)  return ME_INT_FAILED;
00215     if (n >= 1) return ME_INT_NONE;
00216     return zero(home);
00217   }
00218 
00219 
00220   forceinline ModEvent
00221   BoolVarImp::eq(Space* home, int n) {
00222     if ((n < 0) || (n > 1)) return ME_INT_FAILED;
00223     return (n == 0) ? zero(home): one(home);
00224   }
00225   forceinline ModEvent
00226   BoolVarImp::eq(Space* home, double n) {
00227     if ((n < 0) || (n > 1)) return ME_INT_FAILED;
00228     return (n == 0) ? zero(home): one(home);
00229   }
00230 
00231 
00232   forceinline ModEvent
00233   BoolVarImp::nq(Space* home, int n) {
00234     if ((n < 0) || (n > 1)) return ME_INT_NONE;
00235     return (n == 0) ? one(home): zero(home);
00236   }
00237   forceinline ModEvent
00238   BoolVarImp::nq(Space* home, double n) {
00239     if ((n < 0) || (n > 1)) return ME_INT_NONE;
00240     return (n == 0) ? one(home): zero(home);
00241   }
00242 
00243 
00244   /*
00245    * Copying a variable
00246    *
00247    */
00248 
00249   forceinline
00250   BoolVarImp::BoolVarImp(Space* home, bool share, BoolVarImp& x)
00251     : BoolVarImpBase(home,share,x) {}
00252   forceinline BoolVarImp*
00253   BoolVarImp::copy(Space* home, bool share) {
00254     if (copied())
00255       return static_cast<BoolVarImp*>(forward());
00256     else if (zero())
00257       return &s_zero;
00258     else if (one())
00259       return &s_one;
00260     else
00261       return new (home) BoolVarImp(home,share,*this);
00262   }
00263 
00264 
00265   /*
00266    * Iterator-based domain operations
00267    *
00268    */
00269   template <class I>
00270   forceinline ModEvent
00271   BoolVarImp::narrow_r(Space* home, I& i, bool) {
00272     // Is new domain empty?
00273     if (!i())
00274       return ME_INT_FAILED;
00275     assert((i.min() == 0) || (i.min() == 1)); 
00276     assert((i.max() == 0) || (i.max() == 1)); 
00277     if (i.max() == 0) {
00278       assert(!one());
00279       // Assign domain to be zero (domain cannot be one)
00280       return zero(home);
00281     }
00282     if (i.min() == 1) {
00283       // Assign domain to be one (domain cannot be zero)
00284       assert(!zero());
00285       return one(home);
00286     }
00287     assert(none());
00288     return ME_INT_NONE;
00289   }
00290   template <class I>
00291   forceinline ModEvent
00292   BoolVarImp::inter_r(Space* home, I& i, bool) {
00293     // Skip all ranges that are too small
00294     while (i() && (i.max() < 0))
00295       ++i;
00296     // Is new domain empty?
00297     if (!i() || (i.min() > 1))
00298       return ME_INT_FAILED;
00299     assert(i.min() <= 1);
00300     if (i.min() == 1)
00301       return one(home);
00302     if (i.max() == 0)
00303       return zero(home);
00304     assert((i.min() <= 0) && (i.max() >= 1));
00305     return ME_INT_NONE;
00306   }
00307   template <class I>
00308   forceinline ModEvent
00309   BoolVarImp::minus_r(Space* home, I& i, bool) {
00310     // Skip all ranges that are too small
00311     while (i() && (i.max() < 0))
00312       ++i;
00313     // Is new domain empty?
00314     if (!i() || (i.min() > 1))
00315       return ME_INT_NONE;
00316     assert(i.min() <= 1);
00317     if (i.min() == 1)
00318       return zero(home);
00319     if (i.max() == 0)
00320       return one(home);
00321     assert((i.min() <= 0) && (i.max() >= 1));
00322     return ME_INT_FAILED;
00323   }
00324 
00325   template <class I>
00326   forceinline ModEvent
00327   BoolVarImp::narrow_v(Space* home, I& i, bool) {
00328     if (!i())
00329       return ME_INT_FAILED;
00330     if (!none())
00331       return ME_INT_NONE;
00332     if (i.val() == 0) {
00333       do {
00334         ++i;
00335       } while (i() && (i.val() == 0));
00336       if (!i())
00337         return zero_none(home);
00338       return ME_INT_NONE;
00339     } else {
00340       assert(i.val() == 1);
00341       return one_none(home);
00342     }
00343   }
00344   template <class I>
00345   forceinline ModEvent
00346   BoolVarImp::inter_v(Space* home, I& i, bool) {
00347     while (i() && (i.val() < 0)) 
00348       ++i;
00349     if (!i() || (i.val() > 1))
00350       return ME_INT_FAILED;
00351     if (i.val() == 0) {
00352       do {
00353         ++i;
00354       } while (i() && (i.val() == 0));
00355       if (!i() || (i.val() > 1))
00356         return zero(home);
00357       return ME_INT_NONE;
00358     } else {
00359       assert(i.val() == 1);
00360       return one(home);
00361     }
00362   }
00363   template <class I>
00364   forceinline ModEvent
00365   BoolVarImp::minus_v(Space* home, I& i, bool) {
00366     while (i() && (i.val() < 0)) 
00367       ++i;
00368     if (!i() || (i.val() > 1))
00369       return ME_INT_NONE;
00370     if (i.val() == 0) {
00371       do {
00372         ++i;
00373       } while (i() && (i.val() == 0));
00374       if (!i() || (i.val() > 1))
00375         return one(home);
00376       return ME_INT_FAILED;
00377     } else {
00378       assert(i.val() == 1);
00379       return zero(home);
00380     }
00381   }
00382 
00383 
00384 
00385   /*
00386    * Dependencies
00387    *
00388    */
00389   forceinline void
00390   BoolVarImp::subscribe(Space* home, Propagator* p, PropCond, 
00391                         bool process) {
00392     // Subscription can be used with integer propagation conditions,
00393     // which must be remapped to the single Boolean propagation condition.
00394     BoolVarImpBase::subscribe(home,p,PC_BOOL_VAL,assigned(),process);
00395   }
00396   forceinline void
00397   BoolVarImp::cancel(Space* home, Propagator* p, PropCond) {
00398     BoolVarImpBase::cancel(home,p,PC_BOOL_VAL,assigned());
00399   }
00400 
00401   forceinline void
00402   BoolVarImp::subscribe(Space* home, Advisor* a) {
00403     BoolVarImpBase::subscribe(home,a,assigned());
00404   }
00405   forceinline void
00406   BoolVarImp::cancel(Space* home, Advisor* a) {
00407     BoolVarImpBase::cancel(home,a,assigned());
00408   }
00409 
00410   forceinline void
00411   BoolVarImp::schedule(Space* home, Propagator* p, ModEvent me) {
00412     if (me == ME_GEN_ASSIGNED)
00413       BoolVarImpBase::schedule(home,p,me);
00414   }
00415 
00416   forceinline ModEventDelta
00417   BoolVarImp::med(ModEvent me) {
00418     return BoolVarImpBase::med(me);
00419   }
00420 
00421 }}
00422 
00423 // STATISTICS: int-var