int-eq.hpp
Go to the documentation of this file.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 #include <gecode/int/rel.hh>
00039 #include <gecode/int/distinct.hh>
00040
00041 namespace Gecode { namespace Int { namespace NValues {
00042
00043 template<class VY>
00044 forceinline
00045 EqInt<VY>::EqInt(Home home, ValSet& vs, ViewArray<IntView>& x, VY y)
00046 : IntBase<VY>(home,vs,x,y) {
00047 home.notice(*this, AP_WEAKLY);
00048 }
00049
00050 template<class VY>
00051 inline ExecStatus
00052 EqInt<VY>::post(Home home, ViewArray<IntView>& x, VY y) {
00053 if (x.size() == 0) {
00054 GECODE_ME_CHECK(y.eq(home,0));
00055 return ES_OK;
00056 }
00057
00058 x.unique(home);
00059
00060 if (x.size() == 1) {
00061 GECODE_ME_CHECK(y.eq(home,1));
00062 return ES_OK;
00063 }
00064
00065 GECODE_ME_CHECK(y.gq(home,1));
00066 GECODE_ME_CHECK(y.lq(home,x.size()));
00067
00068 if (y.max() == 1) {
00069 assert(y.assigned());
00070 return Rel::NaryEqDom<IntView>::post(home,x);
00071 }
00072
00073 if (y.min() == x.size()) {
00074 assert(y.assigned());
00075 return Distinct::Dom<IntView>::post(home,x);
00076 }
00077
00078
00079 ValSet vs;
00080 int n = x.size();
00081 for (int i=n; i--; )
00082 if (x[i].assigned()) {
00083 vs.add(home, x[i].val());
00084 x[i] = x[--n];
00085 }
00086
00087 GECODE_ME_CHECK(y.gq(home,vs.size()));
00088 GECODE_ME_CHECK(y.lq(home,n + vs.size()));
00089
00090 if (n == 0) {
00091 assert(y.val() == vs.size());
00092 return ES_OK;
00093 }
00094 x.size(n);
00095 (void) new (home) EqInt<VY>(home, vs, x, y);
00096 return ES_OK;
00097 }
00098
00099 template<class VY>
00100 forceinline
00101 EqInt<VY>::EqInt(Space& home, bool share, EqInt<VY>& p)
00102 : IntBase<VY>(home, share, p) {}
00103
00104 template<class VY>
00105 Propagator*
00106 EqInt<VY>::copy(Space& home, bool share) {
00107 return new (home) EqInt<VY>(home, share, *this);
00108 }
00109
00110 template<class VY>
00111 forceinline size_t
00112 EqInt<VY>::dispose(Space& home) {
00113 home.ignore(*this, AP_WEAKLY);
00114 (void) IntBase<VY>::dispose(home);
00115 return sizeof(*this);
00116 }
00117
00118 template<class VY>
00119 ExecStatus
00120 EqInt<VY>::propagate(Space& home, const ModEventDelta& med) {
00121
00122 if (IntView::me(med) == ME_INT_VAL)
00123 add(home);
00124
00125 GECODE_ME_CHECK(y.gq(home, vs.size()));
00126 GECODE_ME_CHECK(y.lq(home, x.size() + vs.size()));
00127
00128 if (x.size() == 0)
00129 return home.ES_SUBSUMED(*this);
00130
00131
00132 if (y.max() == vs.size())
00133 return all_in_valset(home);
00134
00135
00136 Region r(home);
00137 int* dis; int n_dis;
00138 disjoint(home,r,dis,n_dis);
00139
00140
00141 GECODE_ME_CHECK(y.lq(home, x.size() + vs.size()));
00142
00143 if (x.size() == 0) {
00144 assert(y.val() == vs.size());
00145 return home.ES_SUBSUMED(*this);
00146 }
00147
00148 GECODE_ES_CHECK(prune_upper(home,g));
00149
00150
00151 if (n_dis == 0)
00152 return ES_NOFIX;
00153
00154
00155
00156 if (IntView::me(Propagator::modeventdelta()) != ME_INT_NONE)
00157 return ES_NOFIX;
00158
00159
00160 GECODE_ES_CHECK(prune_lower(home,dis,n_dis));
00161
00162 return ES_NOFIX;
00163 }
00164
00165 }}}
00166
00167