| 55 | } |
| 56 | |
| 57 | ExecStatus |
| 58 | AtmostOne::propagate(Space& home, const ModEventDelta&) { |
| 59 | Region r; |
| 60 | LubRanges<SetView>* lubs = r.alloc<LubRanges<SetView> >(x.size()); |
| 61 | for (int i = x.size(); i--; ) { |
| 62 | lubs[i].init(x[i]); |
| 63 | } |
| 64 | Iter::Ranges::NaryUnion bigT(r, lubs, x.size()); |
| 65 | |
| 66 | Iter::Ranges::ToValues<Iter::Ranges::NaryUnion> |
| 67 | as(bigT); |
| 68 | |
| 69 | while (as()) { |
| 70 | int a = as.val(); ++as; |
| 71 | |
| 72 | // cardSa is the number of sets that contain a in the glb |
| 73 | int cardSa = 0; |
| 74 | for (int i=x.size(); i--;) |
| 75 | if (x[i].contains(a)) |
| 76 | cardSa++; |
| 77 | |
| 78 | // bigTa is the union of all lubs that contain a |
| 79 | GLBndSet bigTa(home); |
| 80 | for (int i=x.size(); i--;) { |
| 81 | if (!x[i].notContains(a)) { |
| 82 | LubRanges<SetView> xilub(x[i]); |
| 83 | bigTa.includeI(home, xilub); |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | // maxa is the maximum number of sets that can contain a |
| 88 | int maxa = static_cast<int>((bigTa.size() - 1) / (c - 1)); |
| 89 | bigTa.dispose(home); |
| 90 | |
| 91 | // Conditional Rule A: |
| 92 | // If more sets already contain a than allowed, fail. |
| 93 | if (maxa < cardSa) |
| 94 | return ES_FAILED; |
| 95 | |
| 96 | if (maxa == cardSa) { |
| 97 | // Conditional Rule B: |
| 98 | // All a used up. All other sets (those that don't have a in their |
| 99 | // glb already) cannot contain a. |
| 100 | for (int i=x.size(); i--;) { |
| 101 | if (!x[i].contains(a)) { |
| 102 | GECODE_ME_CHECK(x[i].exclude(home, a)); |
| 103 | } |
| 104 | } |
| 105 | } else { |
| 106 | LubRanges<SetView>* lubs2 = r.alloc<LubRanges<SetView> >(x.size()); |
| 107 | for (int i = x.size(); i--; ) { |
| 108 | lubs2[i].init(x[i]); |
| 109 | } |
| 110 | Iter::Ranges::NaryUnion bigT2(r, lubs2, x.size()); |
| 111 | |
| 112 | GlbRanges<SetView>* glbs = r.alloc<GlbRanges<SetView> >(cardSa); |
| 113 | int count = 0; |
| 114 | for (int i=x.size(); i--; ) { |