inline ExecStatus EqInt<VY>::post(Home home, ViewArray<IntView>& x, VY y) { if (x.size() == 0) { GECODE_ME_CHECK(y.eq(home,0)); return ES_OK; } x.unique(home); if (x.size() == 1) { GECODE_ME_CHECK(y.eq(home,1)); return ES_OK; } GECODE_ME_CHECK(y.gq(home,1)); GECODE_ME_CHECK(y.lq(home,x.size())); if (y.max() == 1) { assert(y.assigned()); return Rel::NaryEqDom<IntView>::post(home,x); } if (y.min() == x.size()) { assert(y.assigned()); return Distinct::Dom<IntView>::post(home,x); } // Eliminate assigned views and store them into the value set ValSet vs; int n = x.size(); for (int i=n; i--; ) if (x[i].assigned()) { vs.add(home, x[i].val()); x[i] = x[--n]; } GECODE_ME_CHECK(y.gq(home,vs.size())); GECODE_ME_CHECK(y.lq(home,n + vs.size())); if (n == 0) { assert(y.val() == vs.size()); return ES_OK; } x.size(n); (void) new (home) EqInt<VY>(home, vs, x, y); return ES_OK; }
inline ExecStatus ReProp<View,rm>::post(Home home, ViewArray<View>& x, View y, BoolView b) { if (x.size() == 0) { if (rm != RM_PMI) GECODE_ME_CHECK(b.zero(home)); return ES_OK; } x.unique(home); if (x.size() == 1) return Rel::ReEqDom<View,BoolView,rm>::post(home,x[0],y,b); if (x.same(home,y)) { if (rm != RM_IMP) GECODE_ME_CHECK(b.one(home)); return ES_OK; } // Eliminate assigned views and store them into the value set ValSet vs; add(home, vs, x); switch (vs.compare(y)) { case Iter::Ranges::CS_SUBSET: if (rm != RM_IMP) GECODE_ME_CHECK(b.one(home)); return ES_OK; case Iter::Ranges::CS_DISJOINT: if (x.size() == 0) { if (rm != RM_PMI) GECODE_ME_CHECK(b.zero(home)); return ES_OK; } break; case Iter::Ranges::CS_NONE: break; default: GECODE_NEVER; } (void) new (home) ReProp<View,rm>(home, vs, x, y, b); return ES_OK; }
forceinline void Prop<View>::add(Space& home, ValSet& vs, ViewArray<View>& x) { int n=x.size(); for (int i=n; i--; ) if (x[i].assigned()) { vs.add(home, x[i].val()); x[i] = x[--n]; } x.size(n); }