inline ExecStatus NaryNq<View>::post(Home home, ViewArray<View>& x) { x.unique(home); // Try to find an assigned view int n = x.size(); if (n <= 1) return ES_FAILED; for (int i=n; i--; ) if (x[i].assigned()) { std::swap(x[0],x[i]); break; } if (x[0].assigned()) { int v = x[0].val(); // Eliminate all equal views and possibly find disequal view for (int i=n-1; i>0; i--) if (!x[i].in(v)) { return ES_OK; } else if (x[i].assigned()) { assert(x[i].val() == v); x[i]=x[--n]; } x.size(n); } if (n == 1) return ES_FAILED; if (n == 2) return Nq<View>::post(home,x[0],x[1]); (void) new (home) NaryNq(home,x); return ES_OK; }
inline ExecStatus Prop<View>::post(Home home, ViewArray<View>& x, View y) { if (x.size() == 0) return ES_FAILED; x.unique(home); if (x.size() == 1) return Rel::EqDom<View,View>::post(home,x[0],y); if (x.same(home,y)) return ES_OK; // Eliminate assigned views and store them into the value set ValSet vs; add(home, vs, x); if (x.size() == 0) { ValSet::Ranges vsr(vs); GECODE_ME_CHECK(y.inter_r(home,vsr,false)); return ES_OK; } (void) new (home) Prop<View>(home, vs, x, y); return ES_OK; }
inline ExecStatus LqBool<VY>::post(Home home, ViewArray<BoolView>& x, VY y) { if (x.size() == 0) { GECODE_ME_CHECK(y.gq(home,0)); return ES_OK; } x.unique(home); GECODE_ME_CHECK(y.gq(home,1)); if (x.size() == 1) return ES_OK; if (y.max() == 1) { assert(y.assigned()); ViewArray<BoolView> xc(home,x); return Bool::NaryEq<BoolView>::post(home,xc); } if (y.min() >= 2) return ES_OK; int n = x.size(); int status = 0; for (int i=n; i--; ) if (x[i].zero()) { if (status & VS_ONE) { GECODE_ME_CHECK(y.gq(home,2)); return ES_OK; } x[i] = x[--n]; status |= VS_ZERO; } else if (x[i].one()) { if (status & VS_ZERO) { GECODE_ME_CHECK(y.gq(home,2)); return ES_OK; } x[i] = x[--n]; status |= VS_ONE; } assert(status != (VS_ZERO | VS_ONE)); if (n == 0) { assert((status != 0) && (y.min() >= 1)); return ES_OK; } x.size(n); (void) new (home) LqBool<VY>(home,status,x,y); return ES_OK; }
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; }
ExecStatus NaryEq<View>::post(Home home, ViewArray<View>& x) { x.unique(home); if (x.size() == 2) { return Eq<View,View>::post(home,x[0],x[1]); } else if (x.size() > 2) { FloatNum l = x[0].min(); FloatNum u = x[0].max(); for (int i=x.size(); i-- > 1; ) { l = std::max(l,x[i].min()); u = std::min(u,x[i].max()); } for (int i=x.size(); i--; ) { GECODE_ME_CHECK(x[i].gq(home,l)); GECODE_ME_CHECK(x[i].lq(home,u)); } (void) new (home) NaryEq<View>(home,x); } return ES_OK; }