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