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>
00039 forceinline
00040 Prop<View>::Prop(Home home, ValSet& vs0, ViewArray<View>& x, View y)
00041 : NaryOnePropagator<View,PC_INT_DOM>(home,x,y),
00042 vs(vs0) {}
00043
00044 template<class View>
00045 forceinline void
00046 Prop<View>::add(Space& home, ValSet& vs, ViewArray<View>& x) {
00047 int n=x.size();
00048 for (int i=n; i--; )
00049 if (x[i].assigned()) {
00050 vs.add(home, x[i].val());
00051 x[i] = x[--n];
00052 }
00053 x.size(n);
00054 }
00055
00056 template<class View>
00057 forceinline void
00058 Prop<View>::eliminate(Space& home) {
00059 int n=x.size();
00060 for (int i=n; i--; )
00061 if ((rtest_eq_dom(x[i],y) == RT_FALSE) || vs.subset(x[i])) {
00062
00063 x[i].cancel(home, *this, PC_INT_DOM);
00064 x[i] = x[--n];
00065 }
00066 x.size(n);
00067 }
00068
00069 template<class View>
00070 inline ExecStatus
00071 Prop<View>::post(Home home, ViewArray<View>& x, View y) {
00072 if (x.size() == 0)
00073 return ES_FAILED;
00074
00075 x.unique();
00076
00077 if (x.size() == 1)
00078 return Rel::EqDom<View,View>::post(home,x[0],y);
00079
00080 if (x.same(y))
00081 return ES_OK;
00082
00083
00084 ValSet vs;
00085 add(home, vs, x);
00086
00087 if (x.size() == 0) {
00088 ValSet::Ranges vsr(vs);
00089 GECODE_ME_CHECK(y.inter_r(home,vsr,false));
00090 return ES_OK;
00091 }
00092
00093 (void) new (home) Prop<View>(home, vs, x, y);
00094 return ES_OK;
00095 }
00096
00097 template<class View>
00098 forceinline ExecStatus
00099 Prop<View>::post(Home home, ValSet& vs, ViewArray<View>& x, View y) {
00100 (void) new (home) Prop<View>(home, vs, x, y);
00101 return ES_OK;
00102 }
00103
00104 template<class View>
00105 forceinline
00106 Prop<View>::Prop(Space& home, Prop<View>& p)
00107 : NaryOnePropagator<View,PC_INT_DOM>(home, p) {
00108 vs.update(home, p.vs);
00109 }
00110
00111 template<class View>
00112 Propagator*
00113 Prop<View>::copy(Space& home) {
00114 return new (home) Prop<View>(home, *this);
00115 }
00116
00117 template<class View>
00118 forceinline size_t
00119 Prop<View>::dispose(Space& home) {
00120 vs.dispose(home);
00121 (void) NaryOnePropagator<View,PC_INT_DOM>::dispose(home);
00122 return sizeof(*this);
00123 }
00124
00125 template<class View>
00126 PropCost
00127 Prop<View>::cost(const Space&, const ModEventDelta&) const {
00128 return PropCost::linear(PropCost::HI, x.size()+1);
00129 }
00130
00131 template<class View>
00132 ExecStatus
00133 Prop<View>::propagate(Space& home, const ModEventDelta& med) {
00134
00135 if (View::me(med) == ME_INT_VAL)
00136 add(home,vs,x);
00137
00138
00139 eliminate(home);
00140
00141 if (x.size() == 0) {
00142
00143 ValSet::Ranges vsr(vs);
00144 GECODE_ME_CHECK(y.inter_r(home,vsr,false));
00145 return home.ES_SUBSUMED(*this);
00146 }
00147
00148
00149 Region r;
00150
00151 assert(x.size() > 0);
00152 ValSet::Ranges vsr(vs);
00153 ViewRanges<View> xsr(x[x.size()-1]);
00154 Iter::Ranges::NaryUnion u(r,vsr,xsr);
00155 for (int i=x.size()-1; i--; ) {
00156 ViewRanges<View> xir(x[i]);
00157 u |= xir;
00158 }
00159
00160 GECODE_ME_CHECK(y.inter_r(home,u,false));
00161
00162
00163 if (vs.subset(y))
00164 return home.ES_SUBSUMED(*this);
00165
00166 return ES_FIX;
00167 }
00168
00169 }}}
00170
00171