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 namespace Gecode { namespace Set { namespace Rel {
00028
00029 template <class View0, class View1>
00030 forceinline
00031 ReEq<View0,View1>::ReEq(Space* home, View0 y0, View1 y1,
00032 Gecode::Int::BoolView y2)
00033 : Propagator(home), x0(y0), x1(y1), b(y2) {
00034 b.subscribe(home,this, Gecode::Int::PC_INT_VAL);
00035 x0.subscribe(home,this, PC_SET_ANY);
00036 x1.subscribe(home,this, PC_SET_ANY);
00037 }
00038
00039 template <class View0, class View1>
00040 forceinline
00041 ReEq<View0,View1>::ReEq(Space* home, bool share, ReEq& p)
00042 : Propagator(home,share,p) {
00043 x0.update(home,share,p.x0);
00044 x1.update(home,share,p.x1);
00045 b.update(home,share,p.b);
00046 }
00047
00048 template <class View0, class View1>
00049 PropCost
00050 ReEq<View0,View1>::cost(void) const {
00051 return PC_TERNARY_LO;
00052 }
00053
00054 template <class View0, class View1>
00055 size_t
00056 ReEq<View0,View1>::dispose(Space* home) {
00057 assert(!home->failed());
00058 b.cancel(home,this, Gecode::Int::PC_INT_VAL);
00059 x0.cancel(home,this, PC_SET_ANY);
00060 x1.cancel(home,this, PC_SET_ANY);
00061 (void) Propagator::dispose(home);
00062 return sizeof(*this);
00063 }
00064
00065 template <class View0, class View1>
00066 ExecStatus
00067 ReEq<View0,View1>::post(Space* home, View0 x0, View1 x1,
00068 Gecode::Int::BoolView b) {
00069 (void) new (home) ReEq<View0,View1>(home,x0,x1,b);
00070 return ES_OK;
00071 }
00072
00073 template <class View0, class View1>
00074 Actor*
00075 ReEq<View0,View1>::copy(Space* home, bool share) {
00076 return new (home) ReEq<View0,View1>(home,share,*this);
00077 }
00078
00079 template <class View0, class View1>
00080 ExecStatus
00081 ReEq<View0,View1>::propagate(Space* home) {
00082
00083 if (b.one()) {
00084 GECODE_ES_CHECK((Eq<View0,View1>::post(home,x0,x1)));
00085 return ES_SUBSUMED;
00086 }
00087 if (b.zero()) {
00088 GECODE_ES_CHECK((Distinct<View0,View1>::post(home,x0,x1)));
00089 return ES_SUBSUMED;
00090 }
00091
00092 if (x0.assigned() && x1.assigned()) {
00093
00094 GlbRanges<View0> x0lb(x0);
00095 GlbRanges<View1> x1lb(x1);
00096 for (; x0lb() && x1lb(); ++x0lb, ++x1lb) {
00097 if (x0lb.min() != x1lb.min() ||
00098 x0lb.max() != x1lb.max()) {
00099 b.t_zero_none(home);
00100 return ES_SUBSUMED;
00101 }
00102 }
00103 if (!x0lb() && !x1lb()) {
00104 b.t_one_none(home);
00105 return ES_SUBSUMED;
00106 } else {
00107 b.t_zero_none(home);
00108 return ES_SUBSUMED;
00109 }
00110 }
00111
00112
00113 if (x0.cardMin() > x1.cardMax() ||
00114 x1.cardMin() > x0.cardMax()) {
00115 b.t_zero_none(home);
00116 return ES_SUBSUMED;
00117 }
00118
00119
00120 GlbRanges<View0> x0lb(x0);
00121 LubRanges<View1> x1ub(x1);
00122 Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View1> > diff1(x0lb, x1ub);
00123 if ( diff1() ) {
00124 b.t_zero_none(home);
00125 return ES_SUBSUMED;
00126 }
00127
00128
00129 GlbRanges<View1> x1lb(x1);
00130 LubRanges<View0> x0ub(x0);
00131 Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View0> > diff2(x1lb, x0ub);
00132 if ( diff2() ) {
00133 b.t_zero_none(home);
00134 return ES_SUBSUMED;
00135 }
00136
00137 return ES_FIX;
00138 }
00139
00140 }}}
00141
00142