00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 namespace Gecode { namespace Int { namespace Linear {
00023
00024
00025
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
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
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
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
00255