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(Home 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(Home 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(const Space&, const ModEventDelta&) const {
00126 return PropCost::quadratic(PropCost::LO, x.size()+1);
00127 }
00128
00129 template<class View>
00130 size_t
00131 ChannelBool<View>::dispose(Space& home) {
00132 assert(!home.failed());
00133 co.dispose(home);
00134 (void) Super::dispose(home);
00135 return sizeof(*this);
00136 }
00137
00138 template<class View>
00139 Actor*
00140 ChannelBool<View>::copy(Space& home, bool share) {
00141 return new (home) ChannelBool(home,share,*this);
00142 }
00143
00144 template<class View>
00145 ExecStatus
00146 ChannelBool<View>::propagate(Space& home, const ModEventDelta&) {
00147 running = true;
00148 if (zeros.size() > 0) {
00149 BndSetRanges zi(zeros);
00150 GECODE_ME_CHECK(y.excludeI(home, zi));
00151 zeros.init(home);
00152 }
00153 if (ones.size() > 0) {
00154 BndSetRanges oi(ones);
00155 GECODE_ME_CHECK(y.includeI(home, oi));
00156 ones.init(home);
00157 }
00158 running = false;
00159
00160 if (delta.glbMin() != 1 || delta.glbMax() != 0) {
00161 if (!delta.glbAny()) {
00162 for (int i=delta.glbMin(); i<=delta.glbMax(); i++)
00163 GECODE_ME_CHECK(x[i].one(home));
00164 } else {
00165 GlbRanges<View> glb(y);
00166 for (Iter::Ranges::ToValues<GlbRanges<View> > gv(glb); gv(); ++gv) {
00167 GECODE_ME_CHECK(x[gv.val()].one(home));
00168 }
00169 }
00170 }
00171 if (delta.lubMin() != 1 || delta.lubMax() != 0) {
00172 if (!delta.lubAny()) {
00173 for (int i=delta.lubMin(); i<=delta.lubMax(); i++)
00174 GECODE_ME_CHECK(x[i].zero(home));
00175 } else {
00176 int cur = 0;
00177 for (LubRanges<View> lub(y); lub(); ++lub) {
00178 for (; cur < lub.min(); cur++) {
00179 GECODE_ME_CHECK(x[cur].zero(home));
00180 }
00181 cur = lub.max() + 1;
00182 }
00183 for (; cur < x.size(); cur++) {
00184 GECODE_ME_CHECK(x[cur].zero(home));
00185 }
00186 }
00187 }
00188
00189 new (&delta) SetDelta();
00190
00191 return y.assigned() ? ES_SUBSUMED(*this,home) : ES_FIX;
00192 }
00193
00194 template<class View>
00195 ExecStatus
00196 ChannelBool<View>::advise(Space& home, Advisor& _a, const Delta& _d) {
00197 IndexAdvisor& a = static_cast<IndexAdvisor&>(_a);
00198 const SetDelta& d = static_cast<const SetDelta&>(_d);
00199
00200 ModEvent me = View::modevent(d);
00201 int index = a.index();
00202 if ( (running && index == -1 && me != ME_SET_VAL)
00203 || (index == -1 && me == ME_SET_CARD) ) {
00204 return ES_OK;
00205 }
00206
00207 if (index >= 0) {
00208 if (x[index].zero()) {
00209 SetDelta dummy;
00210 zeros.include(home, index, index, dummy);
00211 } else {
00212 assert(x[index].one());
00213 SetDelta dummy;
00214 ones.include(home, index, index, dummy);
00215 }
00216 return ES_SUBSUMED_NOFIX(a, home, co);
00217 }
00218
00219 if ((a.index() == -1) && Rel::testSetEventLB(me)) {
00220 if (d.glbAny()) {
00221 new (&delta)
00222 SetDelta(2,0, delta.lubMin(), delta.lubMax());
00223 } else {
00224 if (delta.glbMin() == 1 && delta.glbMax() == 0) {
00225 new (&delta)
00226 SetDelta(d.glbMin(), d.glbMax(),
00227 delta.lubMin(), delta.lubMax());
00228 } else {
00229 if (delta.glbMin() != 2 || delta.glbMax() != 0) {
00230 if ((delta.glbMin() <= d.glbMin() && delta.glbMax() >= d.glbMin())
00231 ||
00232 (delta.glbMin() <= d.glbMax() && delta.glbMax() >= d.glbMax())
00233 ) {
00234 new (&delta)
00235 SetDelta(std::min(delta.glbMin(), d.glbMin()),
00236 std::max(delta.glbMax(), d.glbMax()),
00237 delta.lubMin(), delta.lubMax());
00238 } else {
00239 new (&delta)
00240 SetDelta(2, 0, delta.lubMin(), delta.lubMax());
00241 }
00242 }
00243 }
00244 }
00245 }
00246 if ((a.index() == -1) && Rel::testSetEventUB(me)) {
00247 if (d.lubAny()) {
00248 new (&delta)
00249 SetDelta(delta.glbMin(), delta.glbMax(), 2,0);
00250 } else {
00251 if (delta.lubMin() == 1 && delta.lubMax() == 0) {
00252 new (&delta)
00253 SetDelta(delta.glbMin(), delta.glbMax(),
00254 d.lubMin(), d.lubMax());
00255 } else {
00256 if (delta.lubMin() != 2 || delta.lubMax() != 0) {
00257 if ((delta.lubMin() <= d.lubMin() && delta.lubMax() >= d.lubMin())
00258 ||
00259 (delta.lubMin() <= d.lubMax() && delta.lubMax() >= d.lubMax())
00260 ) {
00261 new (&delta)
00262 SetDelta(delta.lubMin(), delta.lubMax(),
00263 std::min(delta.lubMin(), d.lubMin()),
00264 std::max(delta.lubMax(), d.lubMax())
00265 );
00266 } else {
00267 new (&delta)
00268 SetDelta(delta.glbMin(), delta.glbMax(), 2, 0);
00269 }
00270 }
00271 }
00272 }
00273 }
00274
00275 if (y.assigned())
00276 return ES_SUBSUMED_NOFIX(a, home, co);
00277 else
00278 return ES_NOFIX;
00279 }
00280
00281 }}}
00282
00283