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 View0, class View1>
00041 forceinline
00042 BinaryCpltSetPropagator<View0,View1>
00043 ::BinaryCpltSetPropagator(Space* home, View0& x0, View1& y0, bdd& d0)
00044 : Propagator(home), x(x0), y(y0), d(d0) {
00045 force(home);
00046 x.subscribe(home, this, PC_CPLTSET_DOM);
00047 y.subscribe(home, this, PC_CPLTSET_DOM);
00048 }
00049
00050 template <class View0, class View1>
00051 forceinline
00052 BinaryCpltSetPropagator<View0,View1>
00053 ::BinaryCpltSetPropagator(Space* home, bool share,
00054 BinaryCpltSetPropagator& p)
00055 : Propagator(home,share,p) {
00056 d = p.d;
00057 x.update(home, share, p.x);
00058 y.update(home, share, p.y);
00059 }
00060
00061 template <class View0, class View1>
00062 forceinline PropCost
00063 BinaryCpltSetPropagator<View0,View1>::cost(ModEventDelta) const {
00064 if (manager.ctrue(x.dom()) || manager.ctrue(d)) {
00065 return PC_LINEAR_LO;
00066 } else {
00067 return PC_QUADRATIC_HI;
00068 }
00069 }
00070
00071 template <class View0, class View1>
00072 Support::Symbol
00073 BinaryCpltSetPropagator<View0,View1>::ati(void) {
00074 return
00075 Reflection::mangle<View0,View1>("Gecode::CpltSet::BinaryCpltSetPropagator");
00076 }
00077
00078 template <class View0, class View1>
00079 Reflection::ActorSpec
00080 BinaryCpltSetPropagator<View0,View1>::spec(const Space*,
00081 Reflection::VarMap&) const {
00082 throw Reflection::ReflectionException("Not implemented");
00083 }
00084
00085 template <class View0, class View1>
00086 size_t
00087 BinaryCpltSetPropagator<View0,View1>::dispose(Space* home) {
00088 unforce(home);
00089 if (!home->failed()) {
00090 x.cancel(home, this, PC_CPLTSET_DOM);
00091 y.cancel(home, this, PC_CPLTSET_DOM);
00092 }
00093 manager.dispose(d);
00094 Propagator::dispose(home);
00095 return sizeof(*this);
00096 }
00097
00098 template <class View0, class View1>
00099 forceinline ExecStatus
00100 BinaryCpltSetPropagator<View0,View1>::post(Space* home,
00101 View0& x0, View1& y0, bdd& d0) {
00102 (void) new (home) BinaryCpltSetPropagator(home, x0, y0, d0);
00103 return ES_OK;
00104 }
00105
00106 template <class View0, class View1>
00107 forceinline Actor*
00108 BinaryCpltSetPropagator<View0,View1>::copy(Space* home, bool share) {
00109 return new (home) BinaryCpltSetPropagator(home, share, *this);
00110 }
00111
00112 template <class View0, class View1>
00113 forceinline ExecStatus
00114 BinaryCpltSetPropagator<View0,View1>::propagate(Space* home, ModEventDelta) {
00115 bool assigned = true;
00116 {
00117 bdd dom = y.dom();
00118 int s = y.offset();
00119 int w = s + y.tableWidth() - 1;
00120 manager.existquant(dom, d, s, w);
00121 ModEvent me = x.intersect(home, dom);
00122 GECODE_ME_CHECK(me);
00123 }
00124 {
00125 bdd dom = x.dom();
00126 int s = x.offset();
00127 int w = s + x.tableWidth() - 1;
00128 manager.existquant(dom, d, s, w);
00129 ModEvent me = y.intersect(home, dom);
00130 GECODE_ME_CHECK(me);
00131 }
00132
00133 assigned = true;
00134 assigned &= (x.assigned() && y.assigned());
00135
00136 if (assigned) {
00137 return ES_SUBSUMED(this, home);
00138 }
00139 return ES_FIX;
00140 }
00141
00142
00143
00144 template <class View0, class View1>
00145 forceinline
00146 BinRelDisj<View0,View1>::BinRelDisj(Space* home, View0& x0, View1& y0,
00147 bdd& d0)
00148 : BinaryCpltSetPropagator<View0,View1>(home, x0, y0, d0) { }
00149
00150 template <class View0, class View1>
00151 forceinline
00152 BinRelDisj<View0,View1>::BinRelDisj(Space* home, bool share, BinRelDisj& p)
00153 : BinaryCpltSetPropagator<View0,View1>(home,share,p) { }
00154
00155
00156 template <class View0, class View1>
00157 size_t
00158 BinRelDisj<View0,View1>::dispose(Space* home) {
00159 BinaryCpltSetPropagator<View0,View1>::dispose(home);
00160 return sizeof(*this);
00161 }
00162
00163 template <class View0, class View1>
00164 forceinline ExecStatus
00165 BinRelDisj<View0,View1>::post(Space* home, View0& x0, View1& y0,
00166 bdd& d0) {
00167 (void) new (home) BinRelDisj(home, x0, y0, d0);
00168 return ES_OK;
00169 }
00170
00171 template <class View0, class View1>
00172 forceinline Actor*
00173 BinRelDisj<View0,View1>::copy(Space* home, bool share) {
00174 return new (home) BinRelDisj(home, share, *this);
00175 }
00176
00177 template <class View0, class View1>
00178 forceinline ExecStatus
00179 BinRelDisj<View0,View1>::propagate(Space* home, ModEventDelta) {
00180 bool assigned = true;
00181
00182 if (x.assigned()) {
00183 Set::GlbRanges<View0> glbx(x);
00184 if (y.assigned()) {
00185 Set::GlbRanges<View1> glby(y);
00186 Iter::Ranges::Inter<Set::GlbRanges<View0>, Set::GlbRanges<View1> >
00187 inter(glbx, glby);
00188 if (inter())
00189 return ES_FAILED;
00190 return ES_SUBSUMED(this, home);
00191 }
00192 ModEvent me = y.excludeI(home, glbx);
00193 GECODE_ME_CHECK(me);
00194 return ES_SUBSUMED(this, home);
00195 }
00196
00197 if (y.assigned()) {
00198 Set::GlbRanges<View1> glby(y);
00199 ModEvent me = x.excludeI(home, glby);
00200 GECODE_ME_CHECK(me);
00201 }
00202
00203 Set::LubRanges<View0> lubx(x);
00204 Set::LubRanges<View1> luby(y);
00205 Iter::Ranges::Inter<Set::LubRanges<View0>, Set::LubRanges<View1> >
00206 inter(lubx, luby);
00207 Iter::Ranges::ToValues<
00208 Iter::Ranges::Inter<Set::LubRanges<View0>, Set::LubRanges<View1> >
00209 > ival(inter);
00210
00211 Iter::Ranges::ValCache<
00212 Iter::Ranges::ToValues<
00213 Iter::Ranges::Inter<Set::LubRanges<View0>, Set::LubRanges<View1> >
00214 >
00215 > cache(ival);
00216
00217 if (!cache()) {
00218 return ES_SUBSUMED(this, home);
00219 } else {
00220 d = bdd_true();
00221 cache.last();
00222 for (; cache(); --cache) {
00223 int v = cache.min();
00224 int xmin = x.initialLubMin();
00225 int ymin = y.initialLubMin();
00226 d &= (!(x.element(v - xmin) & y.element(v - ymin)));
00227 }
00228 }
00229
00230 {
00231 bdd dom = y.dom();
00232 int s = y.offset();
00233 int w = s + y.tableWidth() - 1;
00234 manager.existquant(dom, d, s, w);
00235 ModEvent me = x.intersect(home, dom);
00236 GECODE_ME_CHECK(me);
00237 }
00238 {
00239 bdd dom = x.dom();
00240 int s = x.offset();
00241 int w = s + x.tableWidth() - 1;
00242 manager.existquant(dom, d, s, w);
00243 ModEvent me = y.intersect(home, dom);
00244 GECODE_ME_CHECK(me);
00245 }
00246
00247 assigned = true;
00248 assigned &= (x.assigned() && y.assigned());
00249
00250 if (assigned) {
00251 return ES_SUBSUMED(this, home);
00252 }
00253
00254 return ES_FIX;
00255 }
00256
00257
00258 }}
00259
00260