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 CpltSet {
00039
00040 template <class View>
00041 forceinline bdd
00042 NaryCpltSetPropagator<View>::bnd_phi(int j) {
00044 if (j == -1) {
00045 return d;
00046 }
00047
00049 bdd cur = x[j].dom();
00051 bdd phires = bnd_phi(j - 1);
00053
00054
00055 if (!manager.ctrue(cur)) {
00056 bdd outvars = bdd_vars(cur);
00057 manager.existquant(cur, phires, outvars);
00058 } else {
00059 cur &= phires;
00060 }
00061 return cur;
00062 }
00063
00064
00065 template <class View>
00066 forceinline bdd
00067 NaryCpltSetPropagator<View>::phi(int i, int j) {
00068
00069 if (j == -1) {
00070 return d;
00071 }
00072
00073 if (j == i) {
00074 return phi(i, j - 1);
00075 }
00076
00077 bdd cur = bdd_true();
00078
00079 cur &= x[j].dom();
00080
00081 cur &= phi(i, j - 1);
00082
00083 int start = x[j].offset();
00084 int end = start + x[j].tableWidth() - 1;
00085 return manager.eliminate(cur, start, end);
00086 }
00087
00088 template <class View>
00089 forceinline
00090 NaryCpltSetPropagator<View>::NaryCpltSetPropagator(Space* home,
00091 ViewArray<View>& x0,
00092 bdd& d0)
00093 : Propagator(home), x(x0), d(d0) {
00094 force(home);
00095 for (int i = x.size(); i--;) {
00096 x[i].subscribe(home, this, PC_CPLTSET_DOM);
00097 }
00098 }
00099
00100 template <class View>
00101 forceinline
00102 NaryCpltSetPropagator<View>::NaryCpltSetPropagator(Space* home, bool share,
00103 NaryCpltSetPropagator& p)
00104 : Propagator(home,share,p) {
00105 d = p.d;
00106 x.update(home,share,p.x);
00107 }
00108
00109 template <class View>
00110 forceinline PropCost
00111 NaryCpltSetPropagator<View>::cost(ModEventDelta) const {
00112 return PC_CRAZY_HI;
00113 }
00114
00115 template <class View>
00116 Support::Symbol
00117 NaryCpltSetPropagator<View>::ati(void) {
00118 return Reflection::mangle<View>("Gecode::CpltSet::NaryCpltSetPropagator");
00119 }
00120
00121 template <class View>
00122 Reflection::ActorSpec
00123 NaryCpltSetPropagator<View>::spec(const Space*, Reflection::VarMap&) const {
00124 throw Reflection::ReflectionException("Not implemented");
00125 }
00126
00127 template <class View>
00128 size_t
00129 NaryCpltSetPropagator<View>::dispose(Space* home) {
00130 unforce(home);
00131 if (!home->failed()) {
00132 for (int i = x.size(); i--;) {
00133 x[i].cancel(home, this, PC_CPLTSET_DOM);
00134 }
00135 }
00136 manager.dispose(d);
00137 Propagator::dispose(home);
00138 return sizeof(*this);
00139 }
00140
00141 template <class View>
00142 forceinline ExecStatus
00143 NaryCpltSetPropagator<View>::post(Space* home, ViewArray<View>& x, bdd& d) {
00144 (void) new (home) NaryCpltSetPropagator(home,x, d);
00145 return ES_OK;
00146 }
00147
00148 template <class View>
00149 forceinline Actor*
00150 NaryCpltSetPropagator<View>::copy(Space* home, bool share) {
00151 return new (home) NaryCpltSetPropagator(home,share,*this);
00152 }
00153
00154 template <class View>
00155 ExecStatus
00156 NaryCpltSetPropagator<View>::divide_conquer(Space* home,
00157 bdd& p, int l, int r) {
00158 if (l == r) {
00159 GECODE_ME_CHECK(x[l].intersect(home, p));
00160 return ES_OK;
00161 }
00162
00163 int h = (r + l) / 2;
00164
00165
00166 bdd left = p;
00167 for (int i = r; i >= h + 1; i--) {
00168 quantify(left, x[i]);
00169 }
00170
00171 ExecStatus es = ES_OK;
00172 GECODE_ES_CHECK(es = divide_conquer(home, left, l, h));
00173
00174 bdd right = p;
00175 for (int i = h; i >= l; i-- ) {
00176 quantify(right, x[i]);
00177 }
00178
00179 GECODE_ES_CHECK(es = divide_conquer(home, right, h + 1, r));
00180 return es;
00181 }
00182
00183 template <class View>
00184 forceinline ExecStatus
00185 NaryCpltSetPropagator<View>::propagate(Space* home, ModEventDelta) {
00186 bool assigned = true;
00187 int n = x.size();
00188
00189 ExecStatus es = ES_OK;
00190 if (n == 1) {
00191 GECODE_ME_CHECK(x[0].intersect(home, d));
00192 } else {
00193 GECODE_ES_CHECK(es = divide_conquer(home, d, 0, n - 1));
00194 }
00195
00196 assigned = true;
00197 for (int i = x.size(); i--; ) {
00198 assigned &= x[i].assigned();
00199 }
00200
00201 if (assigned) {
00202 return ES_SUBSUMED(this, home);
00203 }
00204
00205 return ES_FIX;
00206 }
00207
00208 }}
00209
00210