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