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 namespace Gecode { namespace Int { namespace Bool {
00035
00036
00037
00038
00039
00040
00041 template<class BV>
00042 forceinline
00043 Lq<BV>::Lq(Home home, BV b0, BV b1)
00044 : BoolBinary<BV,BV>(home,b0,b1) {}
00045
00046 template<class BV>
00047 forceinline
00048 Lq<BV>::Lq(Space& home, Lq<BV>& p)
00049 : BoolBinary<BV,BV>(home,p) {}
00050
00051 template<class BV>
00052 Actor*
00053 Lq<BV>::copy(Space& home) {
00054 return new (home) Lq<BV>(home,*this);
00055 }
00056
00057 template<class BV>
00058 inline ExecStatus
00059 Lq<BV>::post(Home home, BV b0, BV b1) {
00060 if (b0.zero()) {
00061 return ES_OK;
00062 } else if (b0.one()) {
00063 GECODE_ME_CHECK(b1.one(home));
00064 } else if (b1.zero()) {
00065 GECODE_ME_CHECK(b0.zero(home));
00066 } else if (b1.one()) {
00067 return ES_OK;
00068 } else {
00069 (void) new (home) Lq<BV>(home,b0,b1);
00070 }
00071 return ES_OK;
00072 }
00073
00074 template<class BV>
00075 ExecStatus
00076 Lq<BV>::propagate(Space& home, const ModEventDelta&) {
00077 #define GECODE_INT_STATUS(S0,S1) \
00078 ((BV::S0<<(1*BV::BITS))|(BV::S1<<(0*BV::BITS)))
00079 switch ((x0.status()<<(1*BV::BITS)) | (x1.status()<<(0*BV::BITS))) {
00080 case GECODE_INT_STATUS(NONE,NONE):
00081 GECODE_NEVER;
00082 case GECODE_INT_STATUS(NONE,ZERO):
00083 GECODE_ME_CHECK(x0.zero_none(home)); break;
00084 case GECODE_INT_STATUS(NONE,ONE):
00085 case GECODE_INT_STATUS(ZERO,NONE):
00086 case GECODE_INT_STATUS(ZERO,ZERO):
00087 case GECODE_INT_STATUS(ZERO,ONE):
00088 break;
00089 case GECODE_INT_STATUS(ONE,NONE):
00090 GECODE_ME_CHECK(x1.one_none(home)); break;
00091 case GECODE_INT_STATUS(ONE,ZERO):
00092 return ES_FAILED;
00093 case GECODE_INT_STATUS(ONE,ONE):
00094 break;
00095 default:
00096 GECODE_NEVER;
00097 }
00098 return home.ES_SUBSUMED(*this);
00099 #undef GECODE_INT_STATUS
00100 }
00101
00102
00103
00104
00105
00106
00107
00108 template<class VX>
00109 forceinline
00110 NaryLq<VX>::NaryLq(Home home, ViewArray<VX>& x)
00111 : NaryPropagator<VX,PC_BOOL_NONE>(home,x),
00112 run(false), n_zero(0), n_one(0), c(home) {
00113 x.subscribe(home,*new (home) Advisor(home,*this,c));
00114 }
00115
00116 template<class VX>
00117 forceinline
00118 NaryLq<VX>::NaryLq(Space& home, NaryLq<VX>& p)
00119 : NaryPropagator<VX,PC_BOOL_NONE>(home,p),
00120 run(false), n_zero(0), n_one(0) {
00121 c.update(home,p.c);
00122 }
00123
00124 template<class VX>
00125 Actor*
00126 NaryLq<VX>::copy(Space& home) {
00127 return new (home) NaryLq<VX>(home,*this);
00128 }
00129
00130 template<class VX>
00131 inline ExecStatus
00132 NaryLq<VX>::post(Home home, ViewArray<VX>& x) {
00133 int i = 0;
00134 while (i < x.size())
00135 if (x[i].zero()) {
00136
00137 for (int j=0; j<i; j++)
00138 GECODE_ME_CHECK(x[j].zero_none(home));
00139 x.drop_fst(i+1); i=0;
00140 } else if (x[i].one()) {
00141
00142 for (int j=i+1; j<x.size(); j++)
00143 GECODE_ME_CHECK(x[j].one(home));
00144 x.drop_lst(i-1); break;
00145 } else {
00146 i++;
00147 }
00148
00149 if (x.size() == 2)
00150 return Lq<VX>::post(home,x[0],x[1]);
00151 if (x.size() > 2)
00152 (void) new (home) NaryLq(home,x);
00153 return ES_OK;
00154 }
00155
00156 template<class VX>
00157 PropCost
00158 NaryLq<VX>::cost(const Space&, const ModEventDelta&) const {
00159 return PropCost::binary(PropCost::LO);
00160 }
00161
00162 template<class VX>
00163 ExecStatus
00164 NaryLq<VX>::advise(Space&, Advisor&, const Delta& d) {
00165 if (VX::zero(d))
00166 n_zero++;
00167 else
00168 n_one++;
00169 return run ? ES_FIX : ES_NOFIX;
00170 }
00171
00172 template<class VX>
00173 forceinline size_t
00174 NaryLq<VX>::dispose(Space& home) {
00175 Advisors<Advisor> as(c);
00176 x.cancel(home,as.advisor());
00177 c.dispose(home);
00178 (void) NaryPropagator<VX,PC_BOOL_NONE>::dispose(home);
00179 return sizeof(*this);
00180 }
00181
00182 template<class VX>
00183 ExecStatus
00184 NaryLq<VX>::propagate(Space& home, const ModEventDelta&) {
00185 run = true;
00186 while (n_zero > 0) {
00187 int i = 0;
00188 while (x[i].none())
00189 i++;
00190 if (x[i].one())
00191 return ES_FAILED;
00192
00193 for (int j=0; j<i; j++)
00194 GECODE_ME_CHECK(x[j].zero(home));
00195 n_zero -= i + 1;
00196 assert(n_zero >= 0);
00197 x.drop_fst(i+1);
00198 }
00199
00200 while (n_one > 0) {
00201 int i = x.size() - 1;
00202 while (x[i].none())
00203 i--;
00204 assert(x[i].one());
00205
00206 for (int j=i+1; j<x.size(); j++)
00207 GECODE_ME_CHECK(x[j].one(home));
00208 n_one -= x.size() - i;
00209 assert(n_one >= 0);
00210 x.drop_lst(i-1);
00211 }
00212
00213 if (x.size() < 2)
00214 return home.ES_SUBSUMED(*this);
00215
00216 run = false;
00217 return ES_FIX;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 template<class BV>
00227 forceinline ExecStatus
00228 Le<BV>::post(Home home, BV b0, BV b1) {
00229 GECODE_ME_CHECK(b0.zero(home));
00230 GECODE_ME_CHECK(b1.one(home));
00231 return ES_OK;
00232 }
00233
00234 }}}
00235
00236
00237