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