val.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 namespace Gecode { namespace Int { namespace Distinct {
00039
00040
00041
00042
00043
00044 template<class View, bool complete>
00045 ExecStatus
00046 prop_val(Space& home, ViewArray<View>& x) {
00047 assert(x.size() > 1);
00048 int n = x.size();
00049
00050 Region r(home);
00051 int* stack = r.alloc<int>(n);
00052 int* c_v = &stack[0];
00053
00054 int c_n = 0;
00055
00056
00057 for (int i = n; i--; )
00058 if (x[i].assigned()) {
00059 c_v[c_n++]=x[i].val(); x[i]=x[--n];
00060 }
00061
00062
00063 int t = 0;
00064 do {
00065 t++;
00066 if (!complete && (t > 16)) {
00067
00068
00069
00070 ExecStatus es = ES_FIX;
00071 while (c_n > 0) {
00072 int v = c_v[--c_n];
00073
00074 for (int i = c_n; i--; )
00075 if (c_v[i] == v)
00076 goto failed;
00077
00078 for (int i = n; i--; ) {
00079 ModEvent me = x[i].nq(home,v);
00080 if (me_failed(me))
00081 goto failed;
00082 if (me == ME_INT_VAL)
00083 es = ES_NOFIX;
00084 }
00085 }
00086 x.size(n);
00087 return es;
00088 }
00089 if (c_n > 31) {
00090
00091 IntSet d(&c_v[0],c_n);
00092
00093
00094 if (d.size() != static_cast<unsigned int>(c_n))
00095 goto failed;
00096
00097 c_n = 0;
00098
00099 for (int i = n; i--; )
00100 if ((d.min() <= x[i].max()) && (d.max() >= x[i].min())) {
00101 IntSetRanges dr(d);
00102 ModEvent me = x[i].minus_r(home,dr,false);
00103 if (me_failed(me))
00104 goto failed;
00105 if (me == ME_INT_VAL) {
00106 c_v[c_n++]=x[i].val(); x[i]=x[--n];
00107 }
00108 }
00109 } else {
00110
00111 int* n_v = &c_v[c_n];
00112
00113 int n_n = 0;
00114 while (c_n > 0) {
00115 int v = c_v[--c_n];
00116
00117 for (int i = c_n; i--; )
00118 if (c_v[i] == v)
00119 goto failed;
00120
00121 for (int i = n_n; i--; )
00122 if (n_v[i] == v)
00123 goto failed;
00124
00125 for (int i = n; i--; ) {
00126 ModEvent me = x[i].nq(home,v);
00127 if (me_failed(me))
00128 goto failed;
00129 if (me == ME_INT_VAL) {
00130 n_v[n_n++]=x[i].val(); x[i]=x[--n];
00131 }
00132 }
00133 }
00134 c_v = n_v; c_n = n_n;
00135 }
00136 } while (c_n > 0);
00137 x.size(n);
00138 return ES_FIX;
00139 failed:
00140 x.size(0);
00141 return ES_FAILED;
00142 }
00143
00144
00145
00146
00147
00148
00149 template<class View>
00150 forceinline
00151 Val<View>::Val(Home home, ViewArray<View>& x)
00152 : NaryPropagator<View,PC_INT_VAL>(home,x) {}
00153
00154 template<class View>
00155 forceinline
00156 Val<View>::Val(Space& home, bool share, Val<View>& p)
00157 : NaryPropagator<View,PC_INT_VAL>(home,share,p) {}
00158
00159 template<class View>
00160 Actor*
00161 Val<View>::copy(Space& home, bool share) {
00162 return new (home) Val<View>(home,share,*this);
00163 }
00164
00165 template<class View>
00166 ExecStatus
00167 Val<View>::propagate(Space& home, const ModEventDelta&) {
00168 GECODE_ES_CHECK((prop_val<View,true>(home,x)));
00169 return (x.size() < 2) ? home.ES_SUBSUMED(*this) : ES_FIX;
00170 }
00171
00172 template<class View>
00173 ExecStatus
00174 Val<View>::post(Home home, ViewArray<View>& x) {
00175 if (x.size() == 2)
00176 return Rel::Nq<View>::post(home,x[0],x[1]);
00177 if (x.size() > 2)
00178 (void) new (home) Val<View>(home,x);
00179 return ES_OK;
00180 }
00181
00182 }}}
00183
00184
00185