base.icc
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 Circuit {
00039
00040 template <class View>
00041 forceinline
00042 Base<View>::Base(Space* home, ViewArray<View>& x)
00043 : NaryPropagator<View,PC_INT_DOM>(home,x), y(home,x) {}
00044
00045 template <class View>
00046 forceinline
00047 Base<View>::Base(Space* home, bool share, Base<View>& p)
00048 : NaryPropagator<View,PC_INT_DOM>(home,share,p) {
00049 y.update(home,share,p.y);
00050 }
00051
00053 template <class View>
00054 class SsccInfo {
00055 public:
00056 int min, low, pre;
00057 ViewValues<View> v;
00058 };
00059
00061 template<class View>
00062 class TellInfo {
00063 public:
00064 View x; int n;
00065 };
00066
00067 template <class View>
00068 ExecStatus
00069 Base<View>::connected(Space* home) {
00070 int n = x.size();
00071
00073 int start = 0;
00074 while (x[start].assigned()) {
00075 start = x[start].val();
00076 if (start == 0) break;
00077 }
00078
00080 GECODE_AUTOARRAY(SsccInfo<View>,si,n);
00081 unsigned int n_edges = 0;
00082 for (int i=n; i--; ) {
00083 n_edges += x[i].size();
00084 si[i].pre=-1;
00085 }
00086
00087
00088 GECODE_AUTOSTACK(int,-1,next,n);
00089
00090
00091 GECODE_AUTOARRAY(TellInfo<View>,eq,n);
00092 int n_eq = 0;
00093
00094
00095 GECODE_AUTOARRAY(TellInfo<View>,nq,n_edges);
00096 int n_nq = 0;
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int i = start;
00123
00124 int cnt = 0;
00125
00126 int subtree_min = 0;
00127
00128 int subtree_max = 0;
00129
00130 int back = 0;
00131 start:
00132 si[i].min = si[i].pre = si[i].low = cnt++;
00133 si[i].v.init(x[i]);
00134 do {
00135 if (si[si[i].v.val()].pre < 0) {
00136 next.push(i);
00137 i=si[i].v.val();
00138 goto start;
00139 } else if ((subtree_min <= si[si[i].v.val()].pre) &&
00140 (si[si[i].v.val()].pre <= subtree_max)) {
00141 back++;
00142 eq[n_eq].x = x[i];
00143 eq[n_eq].n = si[i].v.val();
00144 } else if (si[si[i].v.val()].pre < subtree_min) {
00145 nq[n_nq].x = x[i];
00146 nq[n_nq].n = si[i].v.val();
00147 n_nq++;
00148 }
00149 cont:
00150 if (si[si[i].v.val()].low < si[i].min)
00151 si[i].min = si[si[i].v.val()].low;
00152 ++si[i].v;
00153 } while (si[i].v());
00154 if (si[i].min < si[i].low) {
00155 si[i].low = si[i].min;
00156 } else if (i != start) {
00157
00158 return ES_FAILED;
00159 }
00160 if (!next.empty()) {
00161 i=next.pop();
00162 if (i == start) {
00163
00164 if (back == 0)
00165 return ES_FAILED;
00166
00167 if (back == 1)
00168 n_eq++;
00169 back = 0;
00170 subtree_min = subtree_max+1;
00171 subtree_max = cnt-1;
00172 }
00173 goto cont;
00174 }
00175
00176 if (cnt != n)
00177 return ES_FAILED;
00178 ExecStatus es = ES_FIX;
00179
00180 while (n_eq-- > 0) {
00181 ModEvent me = eq[n_eq].x.eq(home,eq[n_eq].n);
00182 if (me_failed(me))
00183 return ES_FAILED;
00184 if (me_modified(me))
00185 es = ES_NOFIX;
00186 }
00187
00188 while (n_nq-- > 0) {
00189 ModEvent me = nq[n_nq].x.nq(home,nq[n_nq].n);
00190 if (me_failed(me))
00191 return ES_FAILED;
00192 if (me_modified(me))
00193 es = ES_NOFIX;
00194 }
00195 return es;
00196 }
00197
00198 template <class View>
00199 ExecStatus
00200 Base<View>::path(Space* home) {
00201
00202
00203 int n=x.size();
00204
00205
00206
00207 GECODE_AUTOARRAY(int,end,n);
00208 for (int i=n; i--; )
00209 end[i]=-1;
00210
00211
00212 GECODE_AUTOSTACK(int,-1,tell,n);
00213
00214 for (int i=y.size(); i--; ) {
00215 assert(!y[i].assigned());
00216
00217 ViewValues<View> v(y[i]);
00218
00219 do {
00220 int j0=v.val();
00221
00222 if (x[j0].assigned() && (end[j0] < 0)) {
00223
00224
00225
00226
00227 int j = j0;
00228 do {
00229 j=x[j].val();
00230 } while (x[j].assigned());
00231
00232
00233
00234 end[j0]=j; tell.push(j0);
00235 }
00236 ++v;
00237 } while (v());
00238 }
00239
00240
00241 while (!tell.empty()) {
00242 int i = tell.pop();
00243 assert(end[i] >= 0);
00244 GECODE_ME_CHECK(x[end[i]].nq(home,i));
00245 }
00246 return ES_NOFIX;
00247 }
00248
00249 template <class View>
00250 forceinline size_t
00251 Base<View>::dispose(Space* home) {
00252 (void) NaryPropagator<View,PC_INT_DOM>::dispose(home);
00253 return sizeof(*this);
00254 }
00255
00256 template <class View>
00257 Reflection::ActorSpec
00258 Base<View>::spec(const Space* home, Reflection::VarMap& m,
00259 const Support::Symbol& name) const {
00260 return NaryPropagator<View,PC_INT_DOM>::spec(home, m, name);
00261 }
00262
00263 }}}
00264
00265
00266