| 101 | |
| 102 | template<class View0, class View1, class CtrlView, ReifyMode rm> |
| 103 | ExecStatus |
| 104 | ReEq<View0,View1,CtrlView,rm>::propagate(Space& home, |
| 105 | const ModEventDelta&) { |
| 106 | if (b.one()) { |
| 107 | if (rm == RM_PMI) |
| 108 | return home.ES_SUBSUMED(*this); |
| 109 | GECODE_REWRITE(*this,(Eq<View0,View1>::post(home(*this),x0,x1))); |
| 110 | } |
| 111 | if (b.zero()) { |
| 112 | if (rm == RM_IMP) |
| 113 | return home.ES_SUBSUMED(*this); |
| 114 | GECODE_REWRITE(*this,(Distinct<View0,View1>::post(home(*this),x0,x1))); |
| 115 | } |
| 116 | |
| 117 | if (x0.assigned() && x1.assigned()) { |
| 118 | // directly test x0==x1 |
| 119 | GlbRanges<View0> x0lb(x0); |
| 120 | GlbRanges<View1> x1lb(x1); |
| 121 | bool x0eqx1 = true; |
| 122 | for (; x0lb() && x1lb(); ++x0lb, ++x1lb) { |
| 123 | if (x0lb.min() != x1lb.min() || |
| 124 | x0lb.max() != x1lb.max()) { |
| 125 | x0eqx1 = false; |
| 126 | break; |
| 127 | } |
| 128 | } |
| 129 | if (x0eqx1 && !x0lb() && !x1lb()) { |
| 130 | if (rm != RM_IMP) |
| 131 | GECODE_ME_CHECK(b.one_none(home)); |
| 132 | return home.ES_SUBSUMED(*this); |
| 133 | } else { |
| 134 | if (rm != RM_PMI) |
| 135 | GECODE_ME_CHECK(b.zero_none(home)); |
| 136 | return home.ES_SUBSUMED(*this); |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | // check whether cardinalities still allow equality |
| 141 | if (x0.cardMin() > x1.cardMax() || |
| 142 | x1.cardMin() > x0.cardMax()) { |
| 143 | if (rm != RM_PMI) |
| 144 | GECODE_ME_CHECK(b.zero_none(home)); |
| 145 | return home.ES_SUBSUMED(*this); |
| 146 | } |
| 147 | |
| 148 | // check glb(x0) subset lub(x1) |
| 149 | GlbRanges<View0> x0lb(x0); |
| 150 | LubRanges<View1> x1ub(x1); |
| 151 | Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View1> > diff1(x0lb, x1ub); |
| 152 | if ( diff1() ) { |
| 153 | if (rm != RM_PMI) |
| 154 | GECODE_ME_CHECK(b.zero_none(home)); |
| 155 | return home.ES_SUBSUMED(*this); |
| 156 | } |
| 157 | |
| 158 | // check glb(x1) subset lub(x0) |
| 159 | GlbRanges<View1> x1lb(x1); |
| 160 | LubRanges<View0> x0ub(x0); |