| 143 | } |
| 144 | template<class View0, class View1, class View2> |
| 145 | ExecStatus unionCard(Space& home, |
| 146 | bool& retmodified, View0& x0, View1& x1, View2& x2) { |
| 147 | bool modified = false; |
| 148 | do { |
| 149 | retmodified |= modified; |
| 150 | modified = false; |
| 151 | |
| 152 | { |
| 153 | LubRanges<View0> x0ub(x0); |
| 154 | LubRanges<View1> x1ub(x1); |
| 155 | Iter::Ranges::Inter<LubRanges<View0>, LubRanges<View1> > i1(x0ub,x1ub); |
| 156 | unsigned int s1 = Iter::Ranges::size(i1); |
| 157 | unsigned int res = std::max(x0.cardMin()+ |
| 158 | (x1.cardMin()<s1 ? |
| 159 | 0 : x1.cardMin()-s1), |
| 160 | std::max(x0.cardMin(), |
| 161 | x1.cardMin())); |
| 162 | GECODE_ME_CHECK_MODIFIED(modified, x2.cardMin(home,res)); |
| 163 | } |
| 164 | |
| 165 | { |
| 166 | LubRanges<View0> x0ub(x0); |
| 167 | LubRanges<View1> x1ub(x1); |
| 168 | Iter::Ranges::Union<LubRanges<View0>, LubRanges<View1> > u1(x0ub,x1ub); |
| 169 | unsigned int s1 = Iter::Ranges::size(u1); |
| 170 | GECODE_ME_CHECK_MODIFIED(modified, |
| 171 | x2.cardMax(home, |
| 172 | std::min(x0.cardMax()+x1.cardMax(),s1))); |
| 173 | } |
| 174 | |
| 175 | if (x2.cardMin() > x1.cardMax()) |
| 176 | GECODE_ME_CHECK_MODIFIED(modified, |
| 177 | x0.cardMin(home,x2.cardMin() - x1.cardMax())); |
| 178 | |
| 179 | if (x2.cardMin() > x0.cardMax()) |
| 180 | GECODE_ME_CHECK_MODIFIED(modified, |
| 181 | x1.cardMin(home,x2.cardMin() - x0.cardMax())); |
| 182 | |
| 183 | GECODE_ME_CHECK_MODIFIED(modified, |
| 184 | x0.cardMax(home,x2.cardMax())); |
| 185 | GECODE_ME_CHECK_MODIFIED(modified, |
| 186 | x1.cardMax(home,x2.cardMax())); |
| 187 | } while(modified); |
| 188 | return ES_FIX; |
| 189 | } |
| 190 | |
| 191 | template<class View0, class View1> |
| 192 | ExecStatus |