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