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(Space* 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(ModEventDelta) const {
00076 return PC_TERNARY_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 template <class Val, class A, class B, class C, PropCond pc>
00091 Reflection::ActorSpec
00092 LinTer<Val,A,B,C,pc>::spec(const Space* home, Reflection::VarMap& m,
00093 const Support::Symbol& ati) const {
00094 Reflection::ActorSpec s(ati);
00095 return s << x0.spec(home, m)
00096 << x1.spec(home, m)
00097 << x2.spec(home, m)
00098 << c;
00099 }
00100
00101
00102
00103
00104
00105
00106 template <class Val, class A, class B, class C>
00107 forceinline
00108 EqTer<Val,A,B,C>::EqTer(Space* home, A x0, B x1, C x2, Val c)
00109 : LinTer<Val,A,B,C,PC_INT_BND>(home,x0,x1,x2,c) {}
00110
00111 template <class Val, class A, class B, class C>
00112 ExecStatus
00113 EqTer<Val,A,B,C>::post(Space* home, A x0, B x1, C x2, Val c) {
00114 (void) new (home) EqTer<Val,A,B,C>(home,x0,x1,x2,c);
00115 return ES_OK;
00116 }
00117
00118
00119 template <class Val, class A, class B, class C>
00120 forceinline
00121 EqTer<Val,A,B,C>::EqTer(Space* home, bool share, EqTer<Val,A,B,C>& p)
00122 : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p) {}
00123
00124 template <class Val, class A, class B, class C>
00125 forceinline
00126 EqTer<Val,A,B,C>::EqTer(Space* home, bool share, Propagator& p,
00127 A x0, B x1, C x2, Val c)
00128 : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p,x0,x1,x2,c) {}
00129
00130 template <class Val, class A, class B, class C>
00131 Actor*
00132 EqTer<Val,A,B,C>::copy(Space* home, bool share) {
00133 return new (home) EqTer<Val,A,B,C>(home,share,*this);
00134 }
00135
00136 template <class Val, class A, class B, class C>
00137 inline Support::Symbol
00138 EqTer<Val,A,B,C>::ati(void) {
00139 return Reflection::mangle<Val,A,B,C>("Gecode::Int::Linear::EqTer");
00140 }
00141
00142 template <class Val, class A, class B, class C>
00143 Reflection::ActorSpec
00144 EqTer<Val,A,B,C>::spec(const Space* home, Reflection::VarMap& m) const {
00145 return LinTer<Val,A,B,C,PC_INT_BND>::spec(home, m, ati());
00146 }
00147
00148 template <class Val, class A, class B, class C>
00149 void
00150 EqTer<Val,A,B,C>::post(Space* home, Reflection::VarMap& vars,
00151 const Reflection::ActorSpec& spec) {
00152 spec.checkArity(4);
00153 A x0(home, vars, spec[0]);
00154 B x1(home, vars, spec[1]);
00155 C x2(home, vars, spec[2]);
00156 Val c = spec[3]->toInt();
00157 (void) new (home) EqTer<Val,A,B,C>(home, x0, x1, x2, c);
00158 }
00159
00161 enum TerMod {
00162 TM_X0_MIN = 1<<0,
00163 TM_X0_MAX = 1<<1,
00164 TM_X1_MIN = 1<<2,
00165 TM_X1_MAX = 1<<3,
00166 TM_X2_MIN = 1<<4,
00167 TM_X2_MAX = 1<<5,
00168 TM_ALL = TM_X0_MIN|TM_X0_MAX|TM_X1_MIN|TM_X1_MAX|TM_X2_MIN|TM_X2_MAX
00169 };
00170
00171 #define GECODE_INT_PV(CASE,TELL,UPDATE) \
00172 if (bm & (CASE)) { \
00173 bm -= (CASE); ModEvent me = (TELL); \
00174 if (me_failed(me)) return ES_FAILED; \
00175 if (me_modified(me)) bm |= (UPDATE); \
00176 }
00177
00178 template <class Val, class A, class B, class C>
00179 ExecStatus
00180 EqTer<Val,A,B,C>::propagate(Space* home, ModEventDelta) {
00181 int bm = TM_ALL;
00182 do {
00183 GECODE_INT_PV(TM_X0_MIN, x0.gq(home,c-x1.max()-x2.max()),
00184 TM_X1_MAX | TM_X2_MAX);
00185 GECODE_INT_PV(TM_X1_MIN, x1.gq(home,c-x0.max()-x2.max()),
00186 TM_X0_MAX | TM_X2_MAX);
00187 GECODE_INT_PV(TM_X2_MIN, x2.gq(home,c-x0.max()-x1.max()),
00188 TM_X0_MAX | TM_X1_MAX);
00189 GECODE_INT_PV(TM_X0_MAX, x0.lq(home,c-x1.min()-x2.min()),
00190 TM_X1_MIN | TM_X2_MIN);
00191 GECODE_INT_PV(TM_X1_MAX, x1.lq(home,c-x0.min()-x2.min()),
00192 TM_X0_MIN | TM_X2_MIN);
00193 GECODE_INT_PV(TM_X2_MAX, x2.lq(home,c-x0.min()-x1.min()),
00194 TM_X0_MIN | TM_X1_MIN);
00195 } while (bm);
00196 return (x0.assigned() && x1.assigned()) ?
00197 ES_SUBSUMED(this,sizeof(*this)) : ES_FIX;
00198 }
00199
00200 #undef GECODE_INT_PV
00201
00202
00203
00204
00205
00206
00207
00208
00209 template <class Val, class A, class B, class C>
00210 forceinline
00211 NqTer<Val,A,B,C>::NqTer(Space* home, A x0, B x1, C x2, Val c)
00212 : LinTer<Val,A,B,C,PC_INT_VAL>(home,x0,x1,x2,c) {}
00213
00214 template <class Val, class A, class B, class C>
00215 ExecStatus
00216 NqTer<Val,A,B,C>::post(Space* home, A x0, B x1, C x2, Val c) {
00217 (void) new (home) NqTer<Val,A,B,C>(home,x0,x1,x2,c);
00218 return ES_OK;
00219 }
00220
00221
00222 template <class Val, class A, class B, class C>
00223 forceinline
00224 NqTer<Val,A,B,C>::NqTer(Space* home, bool share, NqTer<Val,A,B,C>& p)
00225 : LinTer<Val,A,B,C,PC_INT_VAL>(home,share,p) {}
00226
00227 template <class Val, class A, class B, class C>
00228 Actor*
00229 NqTer<Val,A,B,C>::copy(Space* home, bool share) {
00230 return new (home) NqTer<Val,A,B,C>(home,share,*this);
00231 }
00232
00233 template <class Val, class A, class B, class C>
00234 inline Support::Symbol
00235 NqTer<Val,A,B,C>::ati(void) {
00236 return Reflection::mangle<Val,A,B,C>("Gecode::Int::Linear::NqTer");
00237 }
00238
00239 template <class Val, class A, class B, class C>
00240 Reflection::ActorSpec
00241 NqTer<Val,A,B,C>::spec(const Space* home, Reflection::VarMap& m) const {
00242 return LinTer<Val,A,B,C,PC_INT_VAL>::spec(home, m, ati());
00243 }
00244
00245 template <class Val, class A, class B, class C>
00246 void
00247 NqTer<Val,A,B,C>::post(Space* home, Reflection::VarMap& vars,
00248 const Reflection::ActorSpec& spec) {
00249 spec.checkArity(4);
00250 A x0(home, vars, spec[0]);
00251 B x1(home, vars, spec[1]);
00252 C x2(home, vars, spec[2]);
00253 Val c = spec[3]->toInt();
00254 (void) new (home) NqTer<Val,A,B,C>(home, x0, x1, x2, c);
00255 }
00256
00257 template <class Val, class A, class B, class C>
00258 forceinline
00259 NqTer<Val,A,B,C>::NqTer(Space* home, bool share, Propagator& p,
00260 A x0, B x1, C x2, Val c)
00261 : LinTer<Val,A,B,C,PC_INT_VAL>(home,share,p,x0,x1,x2,c) {}
00262
00263
00264 template <class Val, class A, class B, class C>
00265 ExecStatus
00266 NqTer<Val,A,B,C>::propagate(Space* home, ModEventDelta) {
00267 if (x0.assigned() && x1.assigned()) {
00268 GECODE_ME_CHECK(x2.nq(home,c-x0.val()-x1.val()));
00269 return ES_SUBSUMED(this,home);
00270 }
00271 if (x0.assigned() && x2.assigned()) {
00272 GECODE_ME_CHECK(x1.nq(home,c-x0.val()-x2.val()));
00273 return ES_SUBSUMED(this,home);
00274 }
00275 if (x1.assigned() && x2.assigned()) {
00276 GECODE_ME_CHECK(x0.nq(home,c-x1.val()-x2.val()));
00277 return ES_SUBSUMED(this,home);
00278 }
00279 return ES_FIX;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289 template <class Val, class A, class B, class C>
00290 forceinline
00291 LqTer<Val,A,B,C>::LqTer(Space* home, A x0, B x1, C x2, Val c)
00292 : LinTer<Val,A,B,C,PC_INT_BND>(home,x0,x1,x2,c) {}
00293
00294 template <class Val, class A, class B, class C>
00295 ExecStatus
00296 LqTer<Val,A,B,C>::post(Space* home, A x0, B x1, C x2, Val c) {
00297 (void) new (home) LqTer<Val,A,B,C>(home,x0,x1,x2,c);
00298 return ES_OK;
00299 }
00300
00301
00302 template <class Val, class A, class B, class C>
00303 forceinline
00304 LqTer<Val,A,B,C>::LqTer(Space* home, bool share, LqTer<Val,A,B,C>& p)
00305 : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p) {}
00306
00307 template <class Val, class A, class B, class C>
00308 Actor*
00309 LqTer<Val,A,B,C>::copy(Space* home, bool share) {
00310 return new (home) LqTer<Val,A,B,C>(home,share,*this);
00311 }
00312
00313
00314 template <class Val, class A, class B, class C>
00315 inline Support::Symbol
00316 LqTer<Val,A,B,C>::ati(void) {
00317 return Reflection::mangle<Val,A,B,C>("Gecode::Int::Linear::LqTer");
00318 }
00319
00320 template <class Val, class A, class B, class C>
00321 Reflection::ActorSpec
00322 LqTer<Val,A,B,C>::spec(const Space* home, Reflection::VarMap& m) const {
00323 return LinTer<Val,A,B,C,PC_INT_BND>::spec(home, m, ati());
00324 }
00325
00326 template <class Val, class A, class B, class C>
00327 void
00328 LqTer<Val,A,B,C>::post(Space* home, Reflection::VarMap& vars,
00329 const Reflection::ActorSpec& spec) {
00330 spec.checkArity(4);
00331 A x0(home, vars, spec[0]);
00332 B x1(home, vars, spec[1]);
00333 C x2(home, vars, spec[2]);
00334 Val c = spec[3]->toInt();
00335 (void) new (home) LqTer<Val,A,B,C>(home, x0, x1, x2, c);
00336 }
00337
00338 template <class Val, class A, class B, class C>
00339 forceinline
00340 LqTer<Val,A,B,C>::LqTer(Space* home, bool share, Propagator& p,
00341 A x0, B x1, C x2, Val c)
00342 : LinTer<Val,A,B,C,PC_INT_BND>(home,share,p,x0,x1,x2,c) {}
00343
00344 template <class Val, class A, class B, class C>
00345 ExecStatus
00346 LqTer<Val,A,B,C>::propagate(Space* home, ModEventDelta) {
00347 GECODE_ME_CHECK(x0.lq(home,c-x1.min()-x2.min()));
00348 GECODE_ME_CHECK(x1.lq(home,c-x0.min()-x2.min()));
00349 GECODE_ME_CHECK(x2.lq(home,c-x0.min()-x1.min()));
00350 return (x0.max()+x1.max()+x2.max() <= c) ?
00351 ES_SUBSUMED(this,home) : ES_FIX;
00352 }
00353
00354 }}}
00355
00356
00357