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

ternary.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2003
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3512 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 namespace Gecode { namespace Int { namespace Linear {
00023 
00024   /*
00025    * Ternary linear propagators
00026    *
00027    */
00028   template <class Val, class A, class B, class C, PropCond pc>
00029   forceinline
00030   LinTer<Val,A,B,C,pc>::LinTer(Space* home, A y0, B y1, C y2, Val c0)
00031     : Propagator(home), x0(y0), x1(y1), x2(y2), c(c0) {
00032     x0.subscribe(home,this,pc);
00033     x1.subscribe(home,this,pc);
00034     x2.subscribe(home,this,pc);
00035   }
00036 
00037   template <class Val, class A, class B, class C, PropCond pc>
00038   forceinline
00039   LinTer<Val,A,B,C,pc>::LinTer(Space* home, bool share,
00040                                LinTer<Val,A,B,C,pc>& p)
00041     : Propagator(home,share,p), c(p.c) {
00042     x0.update(home,share,p.x0);
00043     x1.update(home,share,p.x1);
00044     x2.update(home,share,p.x2);
00045   }
00046 
00047   template <class Val, class A, class B, class C, PropCond pc>
00048   forceinline
00049   LinTer<Val,A,B,C,pc>::LinTer(Space* home, bool share, Propagator& p,
00050                                A y0, B y1, C y2, Val c0)
00051     : Propagator(home,share,p), c(c0) {
00052     x0.update(home,share,y0);
00053     x1.update(home,share,y1);
00054     x2.update(home,share,y2);
00055   }
00056 
00057   template <class Val, class A, class B, class C, PropCond pc>
00058   PropCost
00059   LinTer<Val,A,B,C,pc>::cost(void) const {
00060     return PC_TERNARY_LO;
00061   }
00062 
00063   template <class Val, class A, class B, class C, PropCond pc>
00064   size_t
00065   LinTer<Val,A,B,C,pc>::dispose(Space* home) {
00066     assert(!home->failed());
00067     x0.cancel(home,this,pc);
00068     x1.cancel(home,this,pc);
00069     x2.cancel(home,this,pc);
00070     (void) Propagator::dispose(home);
00071     return sizeof(*this);
00072   }
00073 
00074   /*
00075    * Equality propagator
00076    *
00077    */
00078 
00079   template <class Val, class A, class B, class C>
00080   forceinline
00081   EqTer<Val,A,B,C>::EqTer(Space* home, A x0, B x1, C x2, Val c)
00082     : LinTer<Val,A,B,C,PC_INT_BND>(home,x0,x1,x2,c) {}
00083 
00084   template <class Val, class A, class B, class C>
00085   ExecStatus
00086   EqTer<Val,A,B,C>::post(Space* home, A x0, B x1, C x2, Val c) {
00087     (void) new (home) EqTer<Val,A,B,C>(home,x0,x1,x2,c);
00088     return ES_OK;
00089   }
00090 
00091 
00092   template <class Val, class A, class B, class C>
00093   forceinline
00094   EqTer<Val,A,B,C>::EqTer(Space* home, bool share, EqTer<Val,A,B,C>& p)
00095     : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p) {}
00096 
00097   template <class Val, class A, class B, class C>
00098   forceinline
00099   EqTer<Val,A,B,C>::EqTer(Space* home, bool share, Propagator& p,
00100                           A x0, B x1, C x2, Val c)
00101     : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p,x0,x1,x2,c) {}
00102 
00103   template <class Val, class A, class B, class C>
00104   Actor*
00105   EqTer<Val,A,B,C>::copy(Space* home, bool share) {
00106     return new (home) EqTer<Val,A,B,C>(home,share,*this);
00107   }
00108 
00110   enum TerMod {
00111     TM_X0_MIN = 1<<0,
00112     TM_X0_MAX = 1<<1,
00113     TM_X1_MIN = 1<<2,
00114     TM_X1_MAX = 1<<3,
00115     TM_X2_MIN = 1<<4,
00116     TM_X2_MAX = 1<<5,
00117     TM_ALL    = TM_X0_MIN|TM_X0_MAX|TM_X1_MIN|TM_X1_MAX|TM_X2_MIN|TM_X2_MAX
00118   };
00119 
00120 #define GECODE_INT_PV(CASE,TELL,UPDATE)         \
00121   if (bm & (CASE)) {                            \
00122     bm -= (CASE); ModEvent me = (TELL);         \
00123     if (me_failed(me))   return ES_FAILED;      \
00124     if (me_modified(me)) bm |= (UPDATE);        \
00125   }
00126 
00127   template <class Val, class A, class B, class C>
00128   ExecStatus
00129   EqTer<Val,A,B,C>::propagate(Space* home) {
00130     int bm = TM_ALL;
00131     do {
00132       GECODE_INT_PV(TM_X0_MIN, x0.gq(home,c-x1.max()-x2.max()),
00133                     TM_X1_MAX | TM_X2_MAX);
00134       GECODE_INT_PV(TM_X1_MIN, x1.gq(home,c-x0.max()-x2.max()),
00135                     TM_X0_MAX | TM_X2_MAX);
00136       GECODE_INT_PV(TM_X2_MIN, x2.gq(home,c-x0.max()-x1.max()),
00137                     TM_X0_MAX | TM_X1_MAX);
00138       GECODE_INT_PV(TM_X0_MAX, x0.lq(home,c-x1.min()-x2.min()),
00139                     TM_X1_MIN | TM_X2_MIN);
00140       GECODE_INT_PV(TM_X1_MAX, x1.lq(home,c-x0.min()-x2.min()),
00141                     TM_X0_MIN | TM_X2_MIN);
00142       GECODE_INT_PV(TM_X2_MAX, x2.lq(home,c-x0.min()-x1.min()),
00143                     TM_X0_MIN | TM_X1_MIN);
00144     } while (bm);
00145     return (x0.assigned() && x1.assigned()) ? ES_SUBSUMED : ES_FIX;
00146   }
00147 
00148 #undef GECODE_INT_PV
00149 
00150 
00151 
00152   /*
00153    * Disequality propagator
00154    *
00155    */
00156 
00157   template <class Val, class A, class B, class C>
00158   forceinline
00159   NqTer<Val,A,B,C>::NqTer(Space* home, A x0, B x1, C x2, Val c)
00160     : LinTer<Val,A,B,C,PC_INT_VAL>(home,x0,x1,x2,c) {}
00161 
00162   template <class Val, class A, class B, class C>
00163   ExecStatus
00164   NqTer<Val,A,B,C>::post(Space* home, A x0, B x1, C x2, Val c) {
00165     (void) new (home) NqTer<Val,A,B,C>(home,x0,x1,x2,c);
00166     return ES_OK;
00167   }
00168 
00169 
00170   template <class Val, class A, class B, class C>
00171   forceinline
00172   NqTer<Val,A,B,C>::NqTer(Space* home, bool share, NqTer<Val,A,B,C>& p)
00173     : LinTer<Val,A,B,C,PC_INT_VAL>(home,share,p) {}
00174 
00175   template <class Val, class A, class B, class C>
00176   Actor*
00177   NqTer<Val,A,B,C>::copy(Space* home, bool share) {
00178     return new (home) NqTer<Val,A,B,C>(home,share,*this);
00179   }
00180 
00181   template <class Val, class A, class B, class C>
00182   forceinline
00183   NqTer<Val,A,B,C>::NqTer(Space* home, bool share, Propagator& p,
00184                           A x0, B x1, C x2, Val c)
00185     : LinTer<Val,A,B,C,PC_INT_VAL>(home,share,p,x0,x1,x2,c) {}
00186 
00187 
00188   template <class Val, class A, class B, class C>
00189   ExecStatus
00190   NqTer<Val,A,B,C>::propagate(Space* home) {
00191     if (x0.assigned() && x1.assigned()) {
00192       GECODE_ME_CHECK(x2.nq(home,c-x0.val()-x1.val()));
00193       return ES_SUBSUMED;
00194     }
00195     if (x0.assigned() && x2.assigned()) {
00196       GECODE_ME_CHECK(x1.nq(home,c-x0.val()-x2.val()));
00197       return ES_SUBSUMED;
00198     }
00199     if (x1.assigned() && x2.assigned()) {
00200       GECODE_ME_CHECK(x0.nq(home,c-x1.val()-x2.val()));
00201       return ES_SUBSUMED;
00202     }
00203     return ES_FIX;
00204   }
00205 
00206 
00207 
00208   /*
00209    * Inequality propagator
00210    *
00211    */
00212 
00213   template <class Val, class A, class B, class C>
00214   forceinline
00215   LqTer<Val,A,B,C>::LqTer(Space* home, A x0, B x1, C x2, Val c)
00216     : LinTer<Val,A,B,C,PC_INT_BND>(home,x0,x1,x2,c) {}
00217 
00218   template <class Val, class A, class B, class C>
00219   ExecStatus
00220   LqTer<Val,A,B,C>::post(Space* home, A x0, B x1, C x2, Val c) {
00221     (void) new (home) LqTer<Val,A,B,C>(home,x0,x1,x2,c);
00222     return ES_OK;
00223   }
00224 
00225 
00226   template <class Val, class A, class B, class C>
00227   forceinline
00228   LqTer<Val,A,B,C>::LqTer(Space* home, bool share, LqTer<Val,A,B,C>& p)
00229     : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p) {}
00230 
00231   template <class Val, class A, class B, class C>
00232   Actor*
00233   LqTer<Val,A,B,C>::copy(Space* home, bool share) {
00234     return new (home) LqTer<Val,A,B,C>(home,share,*this);
00235   }
00236 
00237   template <class Val, class A, class B, class C>
00238   forceinline
00239   LqTer<Val,A,B,C>::LqTer(Space* home, bool share, Propagator& p,
00240                           A x0, B x1, C x2, Val c)
00241     : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p,x0,x1,x2,c) {}
00242 
00243   template <class Val, class A, class B, class C>
00244   ExecStatus
00245   LqTer<Val,A,B,C>::propagate(Space* home) {
00246     GECODE_ME_CHECK(x0.lq(home,c-x1.min()-x2.min()));
00247     GECODE_ME_CHECK(x1.lq(home,c-x0.min()-x2.min()));
00248     GECODE_ME_CHECK(x2.lq(home,c-x0.min()-x1.min()));
00249     return (x0.max()+x1.max()+x2.max() <= c) ? ES_SUBSUMED : ES_FIX;
00250   }
00251 
00252 }}}
00253 
00254 // STATISTICS: int-prop
00255