| 109 | |
| 110 | template<class View> |
| 111 | ExecStatus |
| 112 | ChannelSorted<View>::propagate(Space& home, const ModEventDelta&) { |
| 113 | |
| 114 | int xs_size = xs.size(); |
| 115 | |
| 116 | bool loopFlag; |
| 117 | |
| 118 | do { |
| 119 | loopFlag = false; |
| 120 | |
| 121 | // Order int vars in xs |
| 122 | GECODE_ME_CHECK(xs[0].gq(home,x0.lubMin())); |
| 123 | for (int i=xs_size-1; i--; ) { |
| 124 | GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i+1].gq(home,xs[i].min() + 1)); |
| 125 | } |
| 126 | |
| 127 | GECODE_ME_CHECK_MODIFIED(loopFlag, xs[xs_size-1].lq(home,x0.lubMax())); |
| 128 | for (int i=xs_size-2; i--; ) { |
| 129 | GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].lq(home,xs[i+1].max() - 1)); |
| 130 | } |
| 131 | |
| 132 | // if y from xs is assigned, add to glb(x0) |
| 133 | for (int i=xs_size; i--; ) { |
| 134 | if (xs[i].assigned()) { |
| 135 | GECODE_ME_CHECK_MODIFIED(loopFlag, x0.include(home,xs[i].val())); |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | // intersect every y in xs with lub(x0) |
| 140 | for (int i=xs_size; i--; ) { |
| 141 | LubRanges<View> ub(x0); |
| 142 | GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].inter_r(home,ub,false)); |
| 143 | } |
| 144 | |
| 145 | // remove gaps between vars in xs from lub(x0) |
| 146 | GECODE_ME_CHECK_MODIFIED(loopFlag, |
| 147 | x0.exclude(home,Limits::min,xs[0].min()-1)); |
| 148 | GECODE_ME_CHECK_MODIFIED(loopFlag, |
| 149 | x0.exclude(home,xs[xs_size-1].max()+1, |
| 150 | Limits::max)); |
| 151 | |
| 152 | for (int i=xs_size-1; i--; ) { |
| 153 | int start = xs[i].max() + 1; |
| 154 | int end = xs[i+1].min() - 1; |
| 155 | if (start<=end) { |
| 156 | GECODE_ME_CHECK_MODIFIED(loopFlag, x0.exclude(home,start,end)); |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | // try to assign vars in xs from glb(x0) |
| 161 | if (x0.glbSize()>0) { |
| 162 | |
| 163 | LubRanges<View> ub(x0); |
| 164 | Iter::Ranges::ToValues<LubRanges<View> > ubv(ub); |
| 165 | GlbRanges<View> lb(x0); |
| 166 | Iter::Ranges::ToValues<GlbRanges<View> > lbv(lb); |
| 167 | |
| 168 | int i=0; |