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 #include "gecode/iter.hh"
00027
00028 namespace Gecode { namespace Int { namespace Channel {
00029
00034 template <class View>
00035 class ValInfo {
00036 public:
00038 View view;
00040 bool a;
00042 static ValInfo<View>* allocate(Space* home, int n);
00044 void init(View x, int n);
00046 void update(Space* home, bool share, ValInfo<View>& vi);
00048 bool doval(void) const;
00050 bool dodom(void) const;
00052 void assigned(void);
00054 void removed(int i);
00056 void done(void);
00057 };
00058
00059 template <class View>
00060 forceinline ValInfo<View>*
00061 ValInfo<View>::allocate(Space* home, int n) {
00062 return reinterpret_cast<ValInfo<View>*>
00063 (home->alloc(n*sizeof(ValInfo<View>)));
00064 }
00065
00066 template <class View>
00067 forceinline void
00068 ValInfo<View>::init(View x, int) {
00069 view = x; a = false;
00070 }
00071
00072 template <class View>
00073 forceinline void
00074 ValInfo<View>::update(Space* home, bool share, ValInfo<View>& vi) {
00075 view.update(home,share,vi.view); a = vi.a;
00076 }
00077
00078 template <class View>
00079 forceinline bool
00080 ValInfo<View>::doval(void) const {
00081 return !a && view.assigned();
00082 }
00083
00084 template <class View>
00085 forceinline bool
00086 ValInfo<View>::dodom(void) const {
00087 return false;
00088 }
00089
00090 template <class View>
00091 forceinline void
00092 ValInfo<View>::assigned(void) {
00093 a = true;
00094 }
00095
00096 template <class View>
00097 forceinline void
00098 ValInfo<View>::removed(int) {}
00099
00100 template <class View>
00101 forceinline void
00102 ValInfo<View>::done(void) {}
00103
00104
00105
00106 template <class View, class Info>
00107 ExecStatus
00108 doprop_val(Space* home, int n, Info* x, Info* y,
00109 int& n_na, ProcessStack& xa, ProcessStack& ya) {
00110 do {
00111 int i = xa.pop();
00112 int j = x[i].view.val();
00113
00114 {
00115 ModEvent me = y[j].view.eq(home,i);
00116 if (me_failed(me))
00117 return ES_FAILED;
00118
00119 if (me_modified(me))
00120 ya.push(j);
00121 }
00122
00123 for (int k=i; k--; ) {
00124 ModEvent me = x[k].view.nq(home,j);
00125 if (me_failed(me))
00126 return ES_FAILED;
00127 if (me_modified(me))
00128 if (me == ME_INT_VAL) {
00129
00130 xa.push(k);
00131 } else {
00132
00133
00134
00135 x[k].removed(j);
00136 }
00137 }
00138
00139 for (int k=i+1; k<n; k++) {
00140 ModEvent me = x[k].view.nq(home,j);
00141 if (me_failed(me))
00142 return ES_FAILED;
00143 if (me_modified(me))
00144 if (me == ME_INT_VAL) {
00145
00146 xa.push(k);
00147 } else {
00148
00149
00150
00151 x[k].removed(j);
00152 }
00153 }
00154 x[i].assigned(); n_na--;
00155 } while (!xa.empty());
00156 return ES_OK;
00157 }
00158
00159
00160 template <class View, class Info>
00161 forceinline ExecStatus
00162 prop_val(Space* home, int n, Info* x, Info* y,
00163 int& n_na, ProcessStack& xa, ProcessStack& ya) {
00164 if (xa.empty())
00165 return ES_OK;
00166 return doprop_val<View,Info>(home,n,x,y,n_na,xa,ya);
00167 }
00168
00169
00170
00171
00172
00173 template <class View>
00174 forceinline
00175 Val<View>::Val(Space* home, int n, ValInfo<View>* xy)
00176 : Base<ValInfo<View>,PC_INT_VAL>(home,n,xy) {}
00177
00178 template <class View>
00179 forceinline
00180 Val<View>::Val(Space* home, bool share, Val<View>& p)
00181 : Base<ValInfo<View>,PC_INT_VAL>(home,share,p) {}
00182
00183 template <class View>
00184 Actor*
00185 Val<View>::copy(Space* home, bool share) {
00186 return new (home) Val<View>(home,share,*this);
00187 }
00188
00189 template <class View>
00190 ExecStatus
00191 Val<View>::propagate(Space* home) {
00192 GECODE_AUTOARRAY(int, __xa, n+1);
00193 GECODE_AUTOARRAY(int, __ya, n+1);
00194 ProcessStack xa(__xa);
00195 ProcessStack ya(__ya);
00196
00197 ValInfo<View>* x = xy;
00198 ValInfo<View>* y = xy+n;
00199
00200
00201 for (int i = n; i--; ) {
00202 if (x[i].doval()) xa.push(i);
00203 if (y[i].doval()) ya.push(i);
00204 }
00205
00206 do {
00207
00208 if (prop_val<View,ValInfo<View> >(home,n,x,y,n_na,xa,ya) == ES_FAILED)
00209 return ES_FAILED;
00210
00211 if (prop_val<View,ValInfo<View> >(home,n,y,x,n_na,ya,xa) == ES_FAILED)
00212 return ES_FAILED;
00213 assert(ya.empty());
00214 } while (!xa.empty());
00215
00216 return (n_na == 0) ? ES_SUBSUMED : ES_FIX;
00217 }
00218
00219 template <class View>
00220 ExecStatus
00221 Val<View>::post(Space* home, int n, ValInfo<View>* xy) {
00222 assert(n > 0);
00223 if (n == 1) {
00224 GECODE_ME_CHECK(xy[0].view.eq(home,0));
00225 GECODE_ME_CHECK(xy[1].view.eq(home,0));
00226 return ES_OK;
00227 }
00228 for (int i=2*n; i--; ) {
00229 GECODE_ME_CHECK(xy[i].view.gq(home,0));
00230 GECODE_ME_CHECK(xy[i].view.le(home,n));
00231 }
00232 (void) new (home) Val<View>(home,n,xy);
00233 return ES_OK;
00234 }
00235
00236 }}}
00237
00238
00239