ExecStatus LqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) { // Eliminate decided views int n_x = x.size(); for (int i=n_x; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i] = x[--n_x]; break; case RT_TRUE: x[i] = x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); if (c < 0) return ES_FAILED; if (c >= n_x) return ES_OK; // All views must be different if (c == 0) return post_false(home,x,y); (void) new (home) LqInt<VX,VY>(home,x,n_x-c+1,y,c); return ES_OK; }
ExecStatus EqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) { // Eliminate decided views int n_x = x.size(); for (int i=n_x; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i] = x[--n_x]; break; case RT_TRUE: x[i] = x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); // RHS too small or too large if ((c < 0) || (c > n_x)) return ES_FAILED; // All views must be different if (c == 0) return post_false(home,x,y); // All views must be equal if (c == n_x) return post_true(home,x,y); // Compute how many subscriptions must be created int n_s = std::max(c,n_x-c)+1; assert(n_s <= n_x); (void) new (home) EqInt<VX,VY>(home,x,n_s,y,c); return ES_OK; }
ExecStatus EqInt<VX,VY>::propagate(Space& home, const ModEventDelta&) { // Eliminate decided views from subscribed views int n_x = x.size(); for (int i=n_s; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i].cancel(home,*this,PC_INT_DOM); x[i]=x[--n_s]; x[n_s]=x[--n_x]; break; case RT_TRUE: x[i].cancel(home,*this,PC_INT_DOM); x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); if ((c < 0) || (c > n_x)) return ES_FAILED; // Eliminate decided views from unsubscribed views for (int i=n_x; i-- > n_s; ) switch (holds(x[i],y)) { case RT_FALSE: x[i]=x[--n_x]; break; case RT_TRUE: x[i]=x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); if ((c < 0) || (c > n_x)) return ES_FAILED; if (c == 0) { // All views must be different GECODE_ES_CHECK(post_false(home,x,y)); return home.ES_SUBSUMED(*this); } if (c == n_x) { // All views must be equal GECODE_ES_CHECK(post_true(home,x,y)); return home.ES_SUBSUMED(*this); } int m = std::max(c,n_x-c)+1; assert(m <= n_x); // Now, there must be new subscriptions from x[n_s] up to x[m-1] while (n_s < m) x[n_s++].subscribe(home,*this,PC_INT_DOM,false); return ES_FIX; }
ExecStatus LqView<VX,VY,VZ,shr>::propagate(Space& home, const ModEventDelta&) { count(home); GECODE_ME_CHECK(z.gq(home,atleast())); if (z.max() == atleast()) { GECODE_ES_CHECK(post_false(home,x,y)); return home.ES_SUBSUMED(*this); } if (x.size() == 0) return home.ES_SUBSUMED(*this); if (z.assigned()) { VY yc(y); GECODE_REWRITE(*this,(LqInt<VX,VY>::post(home(*this),x,yc,z.val()+c))); } return shr ? ES_NOFIX : ES_FIX; }
ExecStatus EqView<VX,VY,VZ,shr,dom>::propagate(Space& home, const ModEventDelta&) { count(home); GECODE_ME_CHECK(z.gq(home,atleast())); GECODE_ME_CHECK(z.lq(home,atmost())); if (z.assigned()) { if (z.val() == atleast()) { GECODE_ES_CHECK(post_false(home,x,y)); return home.ES_SUBSUMED(*this); } if (z.val() == atmost()) { GECODE_ES_CHECK(post_true(home,x,y)); return home.ES_SUBSUMED(*this); } if (!dom || (vtd(y) != VTD_VARVIEW)) { VY yc(y); GECODE_REWRITE(*this,(EqInt<VX,VY> ::post(home(*this),x,yc,z.val()+c))); } } if (dom && (vtd(y) == VTD_VARVIEW) && (z.min() > 0)) { /* * Only if the propagator is at fixpoint here, continue * when things are shared: the reason is that prune * requires that the views in x overlap with y! */ if (shr && (VX::me(Propagator::modeventdelta()) != ME_INT_NONE)) return ES_NOFIX; GECODE_ES_CHECK(prune(home,x,y)); return ES_NOFIX; } return shr ? ES_NOFIX : ES_FIX; }