| 233 | |
| 234 | template<class View, class Offset> |
| 235 | ExecStatus |
| 236 | Base<View,Offset>::path(Space& home) { |
| 237 | // Prunes that partial assigned paths are not completed to cycles |
| 238 | |
| 239 | int n=x.size(); |
| 240 | |
| 241 | Region r; |
| 242 | |
| 243 | // The path starting at assigned x[i] ends at x[end[j]] which is |
| 244 | // not assigned. |
| 245 | int* end = r.alloc<int>(n); |
| 246 | for (int i=0; i<n; i++) |
| 247 | end[i]=-1; |
| 248 | |
| 249 | // A stack that records all indices i such that end[i] != -1 |
| 250 | Support::StaticStack<int,Region> tell(r,n); |
| 251 | |
| 252 | typedef typename Offset::ViewType OView; |
| 253 | for (int i=0; i<y.size(); i++) { |
| 254 | assert(!y[i].assigned()); |
| 255 | // Non-assigned views serve as starting points for assigned paths |
| 256 | Int::ViewValues<OView> v(o(y[i])); |
| 257 | // Try all connected values |
| 258 | do { |
| 259 | int j0=v.val(); |
| 260 | // Starting point for not yet followed assigned path found |
| 261 | if (x[j0].assigned() && (end[j0] < 0)) { |
| 262 | // Follow assigned path until non-assigned view: |
| 263 | // all assigned view on the paths can be skipped, as |
| 264 | // if x[i] is assigned to j, then x[j] will only have |
| 265 | // x[i] as predecessor due to propagating distinct. |
| 266 | int j = j0; |
| 267 | do { |
| 268 | j=o(x[j]).val(); |
| 269 | } while (x[j].assigned()); |
| 270 | // Now there cannot be a cycle from x[j] to x[v.val()]! |
| 271 | // However, the tell cannot be done here as j might be |
| 272 | // equal to i and might hence kill the iterator v! |
| 273 | end[j0]=j; tell.push(j0); |
| 274 | } |
| 275 | ++v; |
| 276 | } while (v()); |
| 277 | } |
| 278 | |
| 279 | // Now do the tells based on the end information |
| 280 | while (!tell.empty()) { |
| 281 | int i = tell.pop(); |
| 282 | assert(end[i] >= 0); |
| 283 | GECODE_ME_CHECK(o(x[end[i]]).nq(home,i)); |
| 284 | } |
| 285 | return ES_NOFIX; |
| 286 | } |
| 287 | |
| 288 | template<class View, class Offset> |
| 289 | forceinline size_t |