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
00039
00040
00041
00042
00043 namespace Gecode { namespace Set { namespace Rel {
00044
00045 template <class View0, class View1>
00046 forceinline
00047 ReEq<View0,View1>::ReEq(Space* home, View0 y0, View1 y1,
00048 Gecode::Int::BoolView y2)
00049 : Propagator(home), x0(y0), x1(y1), b(y2) {
00050 b.subscribe(home,this, Gecode::Int::PC_INT_VAL);
00051 x0.subscribe(home,this, PC_SET_ANY);
00052 x1.subscribe(home,this, PC_SET_ANY);
00053 }
00054
00055 template <class View0, class View1>
00056 forceinline
00057 ReEq<View0,View1>::ReEq(Space* home, bool share, ReEq& p)
00058 : Propagator(home,share,p) {
00059 x0.update(home,share,p.x0);
00060 x1.update(home,share,p.x1);
00061 b.update(home,share,p.b);
00062 }
00063
00064 template <class View0, class View1>
00065 PropCost
00066 ReEq<View0,View1>::cost(ModEventDelta) const {
00067 return PC_TERNARY_LO;
00068 }
00069
00070 template <class View0, class View1>
00071 Support::Symbol
00072 ReEq<View0,View1>::ati(void) {
00073 return Reflection::mangle<View0,View1>("Gecode::Set::Rel::ReEq");
00074 }
00075
00076 template <class View0, class View1>
00077 Reflection::ActorSpec
00078 ReEq<View0,View1>::spec(const Space* home, Reflection::VarMap& m) const {
00079 Reflection::ActorSpec s(ati());
00080 return s << x0.spec(home, m)
00081 << x1.spec(home, m)
00082 << b.spec(home, m);
00083 }
00084
00085 template <class View0, class View1>
00086 void
00087 ReEq<View0,View1>::post(Space* home, Reflection::VarMap& vars,
00088 const Reflection::ActorSpec& spec) {
00089 spec.checkArity(3);
00090 View0 x0(home, vars, spec[0]);
00091 View1 x1(home, vars, spec[1]);
00092 Gecode::Int::BoolView b(home, vars, spec[2]);
00093 (void) new (home) ReEq(home,x0,x1,b);
00094 }
00095
00096 template <class View0, class View1>
00097 size_t
00098 ReEq<View0,View1>::dispose(Space* home) {
00099 assert(!home->failed());
00100 b.cancel(home,this, Gecode::Int::PC_INT_VAL);
00101 x0.cancel(home,this, PC_SET_ANY);
00102 x1.cancel(home,this, PC_SET_ANY);
00103 (void) Propagator::dispose(home);
00104 return sizeof(*this);
00105 }
00106
00107 template <class View0, class View1>
00108 ExecStatus
00109 ReEq<View0,View1>::post(Space* home, View0 x0, View1 x1,
00110 Gecode::Int::BoolView b) {
00111 (void) new (home) ReEq<View0,View1>(home,x0,x1,b);
00112 return ES_OK;
00113 }
00114
00115 template <class View0, class View1>
00116 Actor*
00117 ReEq<View0,View1>::copy(Space* home, bool share) {
00118 return new (home) ReEq<View0,View1>(home,share,*this);
00119 }
00120
00121 template <class View0, class View1>
00122 ExecStatus
00123 ReEq<View0,View1>::propagate(Space* home, ModEventDelta) {
00124 if (b.one())
00125 GECODE_REWRITE(this,(Eq<View0,View1>::post(home,x0,x1)));
00126 if (b.zero())
00127 GECODE_REWRITE(this,(Distinct<View0,View1>::post(home,x0,x1)));
00128
00129 if (x0.assigned() && x1.assigned()) {
00130
00131 GlbRanges<View0> x0lb(x0);
00132 GlbRanges<View1> x1lb(x1);
00133 for (; x0lb() && x1lb(); ++x0lb, ++x1lb) {
00134 if (x0lb.min() != x1lb.min() ||
00135 x0lb.max() != x1lb.max()) {
00136 GECODE_ME_CHECK(b.zero_none(home));
00137 return ES_SUBSUMED(this,home);
00138 }
00139 }
00140 if (!x0lb() && !x1lb()) {
00141 GECODE_ME_CHECK(b.one_none(home));
00142 return ES_SUBSUMED(this,home);
00143 } else {
00144 GECODE_ME_CHECK(b.zero_none(home));
00145 return ES_SUBSUMED(this,home);
00146 }
00147 }
00148
00149
00150 if (x0.cardMin() > x1.cardMax() ||
00151 x1.cardMin() > x0.cardMax()) {
00152 GECODE_ME_CHECK(b.zero_none(home));
00153 return ES_SUBSUMED(this,home);
00154 }
00155
00156
00157 GlbRanges<View0> x0lb(x0);
00158 LubRanges<View1> x1ub(x1);
00159 Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View1> > diff1(x0lb, x1ub);
00160 if ( diff1() ) {
00161 GECODE_ME_CHECK(b.zero_none(home));
00162 return ES_SUBSUMED(this,home);
00163 }
00164
00165
00166 GlbRanges<View1> x1lb(x1);
00167 LubRanges<View0> x0ub(x0);
00168 Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View0> > diff2(x1lb, x0ub);
00169 if ( diff2() ) {
00170 GECODE_ME_CHECK(b.zero_none(home));
00171 return ES_SUBSUMED(this,home);
00172 }
00173
00174 return ES_FIX;
00175 }
00176
00177 }}}
00178
00179