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 #include "gecode/int.hh"
00039
00040 namespace Gecode { namespace Set { namespace Int {
00041
00042 template <class View>
00043 template <class A>
00044 forceinline
00045 ChannelBool<View>::IndexAdvisor::IndexAdvisor(Space* home,
00046 ChannelBool<View>* p,
00047 Council<A>& c, int index)
00048 : Advisor(home,p,c), idx(index) {
00049 if (idx == -1)
00050 p->y.subscribe(home,this);
00051 else {
00052 p->x[idx].subscribe(home,this);
00053 }
00054 }
00055
00056 template <class View>
00057 forceinline
00058 ChannelBool<View>::IndexAdvisor::IndexAdvisor(Space* home, bool share,
00059 IndexAdvisor& a)
00060 : Advisor(home,share,a), idx(a.idx) {}
00061
00062 template <class View>
00063 forceinline int
00064 ChannelBool<View>::IndexAdvisor::index(void) const {
00065 return idx;
00066 }
00067
00068 template <class View>
00069 template <class A>
00070 forceinline void
00071 ChannelBool<View>::IndexAdvisor::dispose(Space* home, Council<A>& c) {
00072 ChannelBool<View>* p = static_cast<ChannelBool<View>*>(propagator());
00073 if (idx == -1)
00074 p->y.cancel(home,this);
00075 else {
00076 p->x[idx].cancel(home,this);
00077 }
00078 Advisor::dispose(home,c);
00079 }
00080
00081 template <class View>
00082 forceinline
00083 ChannelBool<View>::ChannelBool(Space* home,
00084 ViewArray<Gecode::Int::BoolView>& x0,
00085 View y0)
00086 : Super(home,x0,y0), co(home), running(false) {
00087 bool assigned = false;
00088 for (int i=x.size(); i--;) {
00089 if (x[i].zero()) {
00090 assigned = true;
00091 SetDelta d;
00092 zeros.include(home, i, i, d);
00093 } else if (x[i].one()) {
00094 assigned = true;
00095 SetDelta d;
00096 ones.include(home, i, i, d);
00097 } else {
00098 (void) new (home) IndexAdvisor(home,this,co,i);
00099 }
00100 }
00101 if (assigned)
00102 Gecode::Int::BoolView::schedule(home, this, Gecode::Int::ME_BOOL_VAL);
00103 View::schedule(home, this, y.assigned() ? ME_SET_VAL : ME_SET_BB);
00104 (void) new (home) IndexAdvisor(home,this,co,-1);
00105 }
00106
00107 template <class View>
00108 forceinline
00109 ChannelBool<View>::ChannelBool(Space* home, bool share, ChannelBool& p)
00110 : Super(home,share,p), running(false) {
00111 co.update(home, share, p.co);
00112 }
00113
00114 template <class View>
00115 forceinline ExecStatus
00116 ChannelBool<View>::post(Space* home, ViewArray<Gecode::Int::BoolView>& x,
00117 View y) {
00118 GECODE_ME_CHECK(y.intersect(home, 0, x.size()-1));
00119 (void) new (home) ChannelBool(home,x,y);
00120 return ES_OK;
00121 }
00122
00123 template <class View>
00124 PropCost
00125 ChannelBool<View>::cost(ModEventDelta) const { return PC_QUADRATIC_LO; }
00126
00127 template <class View>
00128 size_t
00129 ChannelBool<View>::dispose(Space* home) {
00130 assert(!home->failed());
00131 co.dispose(home);
00132 (void) Super::dispose(home);
00133 return sizeof(*this);
00134 }
00135
00136 template <class View>
00137 Actor*
00138 ChannelBool<View>::copy(Space* home, bool share) {
00139 return new (home) ChannelBool(home,share,*this);
00140 }
00141
00142 template <class View>
00143 ExecStatus
00144 ChannelBool<View>::propagate(Space* home, ModEventDelta) {
00145 running = true;
00146 if (zeros.size() > 0) {
00147 BndSetRanges zi(zeros);
00148 GECODE_ME_CHECK(y.excludeI(home, zi));
00149 zeros.init(home);
00150 }
00151 if (ones.size() > 0) {
00152 BndSetRanges oi(ones);
00153 GECODE_ME_CHECK(y.includeI(home, oi));
00154 ones.init(home);
00155 }
00156 running = false;
00157
00158 if (delta.glbMin() != 1 || delta.glbMax() != 0) {
00159 if (!delta.glbAny()) {
00160 for (int i=delta.glbMin(); i<=delta.glbMax(); i++)
00161 GECODE_ME_CHECK(x[i].one(home));
00162 } else {
00163 GlbRanges<View> glb(y);
00164 for (Iter::Ranges::ToValues<GlbRanges<View> > gv(glb); gv(); ++gv) {
00165 GECODE_ME_CHECK(x[gv.val()].one(home));
00166 }
00167 }
00168 }
00169 if (delta.lubMin() != 1 || delta.lubMax() != 0) {
00170 if (!delta.lubAny()) {
00171 for (int i=delta.lubMin(); i<=delta.lubMax(); i++)
00172 GECODE_ME_CHECK(x[i].zero(home));
00173 } else {
00174 int cur = 0;
00175 for (LubRanges<View> lub(y); lub(); ++lub) {
00176 for (; cur < lub.min(); cur++) {
00177 GECODE_ME_CHECK(x[cur].zero(home));
00178 }
00179 cur = lub.max() + 1;
00180 }
00181 for (; cur < x.size(); cur++) {
00182 GECODE_ME_CHECK(x[cur].zero(home));
00183 }
00184 }
00185 }
00186
00187 new (&delta) SetDelta();
00188
00189 return y.assigned() ? ES_SUBSUMED(this,home) : ES_FIX;
00190 }
00191
00192 template <class View>
00193 ExecStatus
00194 ChannelBool<View>::advise(Space* home, Advisor* _a, const Delta* _d) {
00195 IndexAdvisor* a = static_cast<IndexAdvisor* >(_a);
00196 const SetDelta* d = static_cast<const SetDelta*>(_d);
00197
00198 ModEvent me = View::modevent(d);
00199 int index = a->index();
00200 if ( (running && index == -1 && me != ME_SET_VAL)
00201 || (index == -1 && me == ME_SET_CARD) ) {
00202 return ES_OK;
00203 }
00204
00205 if (index >= 0) {
00206 if (x[index].zero()) {
00207 SetDelta dummy;
00208 zeros.include(home, index, index, dummy);
00209 } else {
00210 assert(x[index].one());
00211 SetDelta dummy;
00212 ones.include(home, index, index, dummy);
00213 }
00214 return ES_SUBSUMED_NOFIX(a, home, co);
00215 }
00216
00217 if (a->index() == -1 && Rel::testSetEventLB(me)) {
00218 if (d->glbAny()) {
00219 new (&delta)
00220 SetDelta(2,0, delta.lubMin(), delta.lubMax());
00221 } else {
00222 if (delta.glbMin() == 1 && delta.glbMax() == 0) {
00223 new (&delta)
00224 SetDelta(d->glbMin(), d->glbMax(),
00225 delta.lubMin(), delta.lubMax());
00226 } else {
00227 if (delta.glbMin() != 2 || delta.glbMax() != 0) {
00228 if ((delta.glbMin() <= d->glbMin() && delta.glbMax() >= d->glbMin())
00229 ||
00230 (delta.glbMin() <= d->glbMax() && delta.glbMax() >= d->glbMax())
00231 ) {
00232 new (&delta)
00233 SetDelta(std::min(delta.glbMin(), d->glbMin()),
00234 std::max(delta.glbMax(), d->glbMax()),
00235 delta.lubMin(), delta.lubMax());
00236 } else {
00237 new (&delta)
00238 SetDelta(2, 0, delta.lubMin(), delta.lubMax());
00239 }
00240 }
00241 }
00242 }
00243 }
00244 if (a->index() == -1 && Rel::testSetEventUB(me)) {
00245 if (d->lubAny()) {
00246 new (&delta)
00247 SetDelta(delta.glbMin(), delta.glbMax(), 2,0);
00248 } else {
00249 if (delta.lubMin() == 1 && delta.lubMax() == 0) {
00250 new (&delta)
00251 SetDelta(delta.glbMin(), delta.glbMax(),
00252 d->lubMin(), d->lubMax());
00253 } else {
00254 if (delta.lubMin() != 2 || delta.lubMax() != 0) {
00255 if ((delta.lubMin() <= d->lubMin() && delta.lubMax() >= d->lubMin())
00256 ||
00257 (delta.lubMin() <= d->lubMax() && delta.lubMax() >= d->lubMax())
00258 ) {
00259 new (&delta)
00260 SetDelta(delta.lubMin(), delta.lubMax(),
00261 std::min(delta.lubMin(), d->lubMin()),
00262 std::max(delta.lubMax(), d->lubMax())
00263 );
00264 } else {
00265 new (&delta)
00266 SetDelta(delta.glbMin(), delta.glbMax(), 2, 0);
00267 }
00268 }
00269 }
00270 }
00271 }
00272
00273 if (y.assigned())
00274 return ES_SUBSUMED_NOFIX(a, home, co);
00275 else
00276 return ES_NOFIX;
00277 }
00278
00279 template <class View>
00280 Support::Symbol
00281 ChannelBool<View>::ati(void) {
00282 return Reflection::mangle<View>("Gecode::Set::Int::ChannelBool");
00283 }
00284
00285 template <class View>
00286 Reflection::ActorSpec
00287 ChannelBool<View>::spec(const Space* home, Reflection::VarMap& m) const {
00288 return Super::spec(home, m, ati());
00289 }
00290
00291 template <class View>
00292 void
00293 ChannelBool<View>::post(Space* home, Reflection::VarMap& vars,
00294 const Reflection::ActorSpec& spec) {
00295 spec.checkArity(2);
00296 ViewArray<Gecode::Int::BoolView> x0(home, vars, spec[0]);
00297 View x1(home, vars, spec[1]);
00298 (void) new (home) ChannelBool<View>(home,x0,x1);
00299 }
00300
00301 }}}
00302
00303