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 #include <gecode/int/rel.hh>
00035
00036 namespace Gecode { namespace Int { namespace Member {
00037
00038 template<class View, ReifyMode rm>
00039 forceinline
00040 ReProp<View,rm>::ReProp(Home home, ValSet& vs, ViewArray<View>& x, View y,
00041 BoolView b0)
00042 : Prop<View>(home,vs,x,y), b(b0) {
00043 b.subscribe(home,*this,PC_BOOL_VAL);
00044 }
00045
00046 template<class View, ReifyMode rm>
00047 inline ExecStatus
00048 ReProp<View,rm>::post(Home home, ViewArray<View>& x, View y, BoolView b) {
00049 if (x.size() == 0) {
00050 if (rm != RM_PMI)
00051 GECODE_ME_CHECK(b.zero(home));
00052 return ES_OK;
00053 }
00054
00055 x.unique();
00056
00057 if (x.size() == 1)
00058 return Rel::ReEqDom<View,BoolView,rm>::post(home,x[0],y,b);
00059
00060 if (x.same(y)) {
00061 if (rm != RM_IMP)
00062 GECODE_ME_CHECK(b.one(home));
00063 return ES_OK;
00064 }
00065
00066
00067 ValSet vs;
00068 add(home, vs, x);
00069
00070 switch (vs.compare(y)) {
00071 case Iter::Ranges::CS_SUBSET:
00072 if (rm != RM_IMP)
00073 GECODE_ME_CHECK(b.one(home));
00074 return ES_OK;
00075 case Iter::Ranges::CS_DISJOINT:
00076 if (x.size() == 0) {
00077 if (rm != RM_PMI)
00078 GECODE_ME_CHECK(b.zero(home));
00079 return ES_OK;
00080 }
00081 break;
00082 case Iter::Ranges::CS_NONE:
00083 break;
00084 default:
00085 GECODE_NEVER;
00086 }
00087
00088 (void) new (home) ReProp<View,rm>(home, vs, x, y, b);
00089 return ES_OK;
00090 }
00091
00092 template<class View, ReifyMode rm>
00093 forceinline
00094 ReProp<View,rm>::ReProp(Space& home, ReProp<View,rm>& p)
00095 : Prop<View>(home, p) {
00096 b.update(home, p.b);
00097 }
00098
00099 template<class View, ReifyMode rm>
00100 Propagator*
00101 ReProp<View,rm>::copy(Space& home) {
00102 return new (home) ReProp<View,rm>(home, *this);
00103 }
00104
00105 template<class View, ReifyMode rm>
00106 forceinline size_t
00107 ReProp<View,rm>::dispose(Space& home) {
00108 b.cancel(home, *this, PC_BOOL_VAL);
00109 (void) Prop<View>::dispose(home);
00110 return sizeof(*this);
00111 }
00112
00113 template<class View, ReifyMode rm>
00114 ExecStatus
00115 ReProp<View,rm>::propagate(Space& home, const ModEventDelta& med) {
00116
00117 if (View::me(med) == ME_INT_VAL)
00118 add(home,vs,x);
00119
00120 if (b.one()) {
00121 if (rm == RM_PMI)
00122 return home.ES_SUBSUMED(*this);
00123 ValSet vsc(vs);
00124 vs.flush();
00125 GECODE_REWRITE(*this,Prop<View>::post(home(*this),vsc,x,y));
00126 }
00127
00128 if (b.zero()) {
00129 if (rm != RM_IMP) {
00130 ValSet::Ranges vsr(vs);
00131 GECODE_ME_CHECK(y.minus_r(home,vsr,false));
00132 for (int i=x.size(); i--; )
00133 GECODE_ES_CHECK((Rel::Nq<View,View>::post(Home(home),x[i],y)));
00134 }
00135 return home.ES_SUBSUMED(*this);
00136 }
00137
00138
00139 eliminate(home);
00140
00141 switch (vs.compare(y)) {
00142 case Iter::Ranges::CS_SUBSET:
00143 if (rm != RM_IMP)
00144 GECODE_ME_CHECK(b.one(home));
00145 return home.ES_SUBSUMED(*this);
00146 case Iter::Ranges::CS_DISJOINT:
00147 if (x.size() == 0) {
00148 if (rm != RM_PMI)
00149 GECODE_ME_CHECK(b.zero(home));
00150 return home.ES_SUBSUMED(*this);
00151 }
00152 break;
00153 case Iter::Ranges::CS_NONE:
00154 break;
00155 default:
00156 GECODE_NEVER;
00157 }
00158
00159
00160 if (x.size() > 0) {
00161 Region r;
00162
00163 ValSet::Ranges vsr(vs);
00164 ViewRanges<View> xsr(x[x.size()-1]);
00165 Iter::Ranges::NaryUnion u(r,vsr,xsr);
00166 for (int i=x.size()-1; i--; ) {
00167 ViewRanges<View> xir(x[i]);
00168 u |= xir;
00169 }
00170
00171 ViewRanges<View> yr(y);
00172
00173 if (Iter::Ranges::disjoint(u,yr)) {
00174 if (rm != RM_PMI)
00175 GECODE_ME_CHECK(b.zero(home));
00176 return home.ES_SUBSUMED(*this);
00177 }
00178 }
00179
00180 return ES_FIX;
00181 }
00182
00183 }}}
00184
00185