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