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 Set { namespace Rel {
00039
00040 template<class View0, class View1, ReifyMode rm, bool strict>
00041 forceinline
00042 ReLq<View0,View1,rm,strict>::ReLq(Home home, View0 y0, View1 y1,
00043 Gecode::Int::BoolView y2)
00044 : Propagator(home), x0(y0), x1(y1), b(y2) {
00045 b.subscribe(home,*this, Gecode::Int::PC_INT_VAL);
00046 x0.subscribe(home,*this, PC_SET_ANY);
00047 x1.subscribe(home,*this, PC_SET_ANY);
00048 }
00049
00050 template<class View0, class View1, ReifyMode rm, bool strict>
00051 forceinline
00052 ReLq<View0,View1,rm,strict>::ReLq(Space& home, bool share, ReLq& p)
00053 : Propagator(home,share,p) {
00054 x0.update(home,share,p.x0);
00055 x1.update(home,share,p.x1);
00056 b.update(home,share,p.b);
00057 }
00058
00059 template<class View0, class View1, ReifyMode rm, bool strict>
00060 PropCost
00061 ReLq<View0,View1,rm,strict>::cost(const Space&, const ModEventDelta&) const
00062 {
00063 return PropCost::ternary(PropCost::LO);
00064 }
00065
00066 template<class View0, class View1, ReifyMode rm, bool strict>
00067 void
00068 ReLq<View0,View1,rm,strict>::reschedule(Space& home) {
00069 b.reschedule(home,*this, Gecode::Int::PC_INT_VAL);
00070 x0.reschedule(home,*this, PC_SET_ANY);
00071 x1.reschedule(home,*this, PC_SET_ANY);
00072 }
00073
00074 template<class View0, class View1, ReifyMode rm, bool strict>
00075 forceinline size_t
00076 ReLq<View0,View1,rm,strict>::dispose(Space& home) {
00077 b.cancel(home,*this, Gecode::Int::PC_INT_VAL);
00078 x0.cancel(home,*this, PC_SET_ANY);
00079 x1.cancel(home,*this, PC_SET_ANY);
00080 (void) Propagator::dispose(home);
00081 return sizeof(*this);
00082 }
00083
00084 template<class View0, class View1, ReifyMode rm, bool strict>
00085 ExecStatus
00086 ReLq<View0,View1,rm,strict>::post(Home home, View0 x0, View1 x1,
00087 Gecode::Int::BoolView b) {
00088 (void) new (home) ReLq<View0,View1,rm,strict>(home,x0,x1,b);
00089 return ES_OK;
00090 }
00091
00092 template<class View0, class View1, ReifyMode rm, bool strict>
00093 Actor*
00094 ReLq<View0,View1,rm,strict>::copy(Space& home, bool share) {
00095 return new (home) ReLq<View0,View1,rm,strict>(home,share,*this);
00096 }
00097
00098 template<class View0, class View1, ReifyMode rm, bool strict>
00099 ExecStatus
00100 ReLq<View0,View1,rm,strict>::propagate(Space& home, const ModEventDelta&) {
00101 if (b.one()) {
00102 if (rm == RM_PMI)
00103 return home.ES_SUBSUMED(*this);
00104 GECODE_REWRITE(*this,(Lq<View0,View1,strict>::post(home(*this),x0,x1)));
00105 }
00106 if (b.zero()) {
00107 if (rm == RM_IMP)
00108 return home.ES_SUBSUMED(*this);
00109 GECODE_REWRITE(*this,
00110 (Lq<View1,View0,!strict>::post(home(*this),x1,x0)));
00111 }
00112 if (x0.cardMax() == 0) {
00113 if ( (!strict) || x1.cardMin() > 0) {
00114 if (rm != RM_IMP)
00115 GECODE_ME_CHECK(b.one_none(home));
00116 return home.ES_SUBSUMED(*this);
00117 }
00118 if (strict && x1.cardMax() == 0) {
00119 if (rm != RM_PMI)
00120 GECODE_ME_CHECK(b.zero_none(home));
00121 return home.ES_SUBSUMED(*this);
00122 }
00123 }
00124
00125 if (x0.assigned() && x1.assigned()) {
00126
00127 int min01;
00128 {
00129 GlbRanges<View0> x0l(x0);
00130 GlbRanges<View1> x1l(x1);
00131 Iter::Ranges::Diff<GlbRanges<View1>,GlbRanges<View0> > d(x1l,x0l);
00132 if (!d()) {
00133 if ((!strict) && x0.cardMax() == x1.cardMax()) {
00134
00135 if (rm != RM_IMP)
00136 GECODE_ME_CHECK(b.one_none(home));
00137 } else {
00138
00139 if (rm != RM_PMI)
00140 GECODE_ME_CHECK(b.zero_none(home));
00141 }
00142 return home.ES_SUBSUMED(*this);
00143 }
00144 min01 = d.min();
00145 }
00146 int min10;
00147 {
00148 GlbRanges<View0> x0l(x0);
00149 GlbRanges<View1> x1l(x1);
00150 Iter::Ranges::Diff<GlbRanges<View0>,GlbRanges<View1> > d(x0l,x1l);
00151 if (!d()) {
00152 if (strict && x0.cardMax() == x1.cardMax()) {
00153
00154 if (rm != RM_PMI)
00155 GECODE_ME_CHECK(b.zero_none(home));
00156 } else {
00157
00158 if (rm != RM_IMP)
00159 GECODE_ME_CHECK(b.one_none(home));
00160 }
00161 return home.ES_SUBSUMED(*this);
00162 }
00163 min10 = d.min();
00164 }
00165
00166 assert(min01 != min10);
00167 if (min01<min10) {
00168 if (rm != RM_IMP)
00169 GECODE_ME_CHECK(b.one_none(home));
00170 } else {
00171 if (rm != RM_PMI)
00172 GECODE_ME_CHECK(b.zero_none(home));
00173 }
00174 return home.ES_SUBSUMED(*this);
00175 }
00176
00177
00178 if (x1.cardMax() > 0) {
00179 GlbRanges<View0> x0l(x0);
00180 LubRanges<View1> x1u(x1);
00181 int x1umin=x1u.min();
00182 Iter::Ranges::Diff<GlbRanges<View0>,LubRanges<View1> > d(x0l,x1u);
00183 if (d() && d.min() < x1umin) {
00184 if (rm != RM_PMI)
00185 GECODE_ME_CHECK(b.zero_none(home));
00186 return home.ES_SUBSUMED(*this);
00187 }
00188 }
00189
00190 if (x0.cardMax() > 0) {
00191 LubRanges<View0> x0u(x0);
00192 GlbRanges<View1> x1l(x1);
00193 int x0umin=x0u.min();
00194 Iter::Ranges::Diff<GlbRanges<View1>,LubRanges<View0> > d(x1l,x0u);
00195 if (d() && d.min() < x0umin) {
00196 if (rm != RM_IMP)
00197 GECODE_ME_CHECK(b.one_none(home));
00198 return home.ES_SUBSUMED(*this);
00199 }
00200 }
00201
00202 return ES_FIX;
00203 }
00204
00205 }}}
00206
00207