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