ExecStatus Dom<View,Offset>::propagate(Space& home, const ModEventDelta& med) { if (View::me(med) == Int::ME_INT_VAL) { GECODE_ES_CHECK((Int::Distinct::prop_val<View,true>(home,y))); ExecStatus escv = connected(home); if (escv != ES_FIX) return escv; if (y.size() < 2) return home.ES_SUBSUMED(*this); return home.ES_FIX_PARTIAL(*this,View::med(Int::ME_INT_DOM)); } if (dc.available()) { GECODE_ES_CHECK(dc.sync(home)); } else { GECODE_ES_CHECK(dc.init(home,y)); } bool assigned; GECODE_ES_CHECK(dc.propagate(home,assigned)); ExecStatus esc = connected(home); if (esc != ES_FIX) return esc; // Elminiate assigned views from y, as they have been assigned // and propagated by domain consistent propagation. This is required // as we need to know how many assigned views actually exist. if (assigned) for (int i=y.size(); i--; ) if (y[i].assigned()) y.move_lst(i); return path(home); }
ExecStatus MultPlusDom<VA,VB,VC>::propagate(Space& home, const ModEventDelta& med) { if (VA::me(med) != ME_INT_DOM) { GECODE_ES_CHECK((prop_mult_plus_bnd<VA,VB,VC>(home,*this,x0,x1,x2))); return home.ES_FIX_PARTIAL(*this,VA::med(ME_INT_DOM)); } IntView y0(x0.varimp()), y1(x1.varimp()), y2(x2.varimp()); return prop_mult_dom<IntView>(home,*this,y0,y1,y2); }
ExecStatus DomEq<Val,View>::propagate(Space& home, const ModEventDelta& med) { if (View::me(med) != ME_INT_DOM) { ExecStatus es = prop_bnd<Val,View,View>(home,med,*this,x,y,c); GECODE_ES_CHECK(es); return home.ES_FIX_PARTIAL(*this,View::med(ME_INT_DOM)); } // Value of equation for partial assignment Val d = -c; int n = x.size(); int m = y.size(); Region r(home); // Create support-base iterators PosSupportIter<Val>* xp = r.alloc<PosSupportIter<Val> >(n); NegSupportIter<Val>* yp = r.alloc<NegSupportIter<Val> >(m); // Initialize views for assignments { Val l = 0; Val u = 0; for (int j=m; j--; ) { yp[j].init(r,-y[j].scale(),y[j].base(),l,u); l += y[j].max(); u += y[j].min(); } for (int i=n; i--; ) { xp[i].init(r,x[i].scale(),x[i].base(),l,u); l -= x[i].min(); u -= x[i].max(); } } // Collect support information by iterating assignments { // Force reset of all iterators in first round int i = 0; int j = 0; next_i: // Reset all iterators for positive views and update d while (i<n) { if (!xp[i].reset(d)) goto prev_i; i++; } next_j: // Reset all iterators for negative views and update d while (j<m) { if (!yp[j].reset(d)) goto prev_j; j++; } // Check whether current assignment is solution if (d == 0) { // Record support for (int is=n; is--; ) xp[is].support(); for (int js=m; js--; ) yp[js].support(); } prev_j: // Try iterating to next assignment: negative views while (j>0) { if (yp[j-1].adjust(d)) goto next_j; j--; } prev_i: // Try iterating to next assignment: positive views while (i>0) { if (xp[i-1].adjust(d)) goto next_i; i--; } } // Tell back new variable domains bool assigned = true; for (int i=n; i--; ) { GECODE_ME_CHECK(xp[i].tell(home)); if (!x[i].assigned()) assigned = false; } for (int j=m; j--; ) { GECODE_ME_CHECK(yp[j].tell(home)); if (!y[j].assigned()) assigned = false; } if (assigned) return home.ES_SUBSUMED(*this); return ES_FIX; }
ExecStatus IteDom<View>::propagate(Space& home, const ModEventDelta& med) { if (b.one()) GECODE_REWRITE(*this,(Rel::EqDom<View,View>::post(home(*this),x2,x0))); if (b.zero()) GECODE_REWRITE(*this,(Rel::EqDom<View,View>::post(home(*this),x2,x1))); GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max()))); GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min()))); if (View::me(med) != ME_INT_DOM) { RelTest eq20 = rtest_eq_bnd(x2,x0); RelTest eq21 = rtest_eq_bnd(x2,x1); if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE)) return ES_FAILED; if (eq20 == RT_FALSE) { GECODE_ME_CHECK(b.zero_none(home)); if (eq21 == RT_TRUE) return home.ES_SUBSUMED(*this); else GECODE_REWRITE(*this, (Rel::EqDom<View,View>::post(home(*this),x2,x1))); } if (eq21 == RT_FALSE) { GECODE_ME_CHECK(b.one_none(home)); if (eq20 == RT_TRUE) return home.ES_SUBSUMED(*this); else GECODE_REWRITE(*this, (Rel::EqDom<View,View>::post(home(*this),x2,x0))); } if ((eq20 == RT_TRUE) && (eq21 == RT_TRUE)) return home.ES_SUBSUMED(*this); return home.ES_FIX_PARTIAL(*this,View::med(ME_INT_DOM)); } RelTest eq20 = rtest_eq_dom(x2,x0); RelTest eq21 = rtest_eq_dom(x2,x1); if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE)) return ES_FAILED; if (eq20 == RT_FALSE) { GECODE_ME_CHECK(b.zero_none(home)); if (eq21 == RT_TRUE) return home.ES_SUBSUMED(*this); else GECODE_REWRITE(*this, (Rel::EqDom<View,View>::post(home(*this),x2,x1))); } if (eq21 == RT_FALSE) { GECODE_ME_CHECK(b.one_none(home)); if (eq20 == RT_TRUE) return home.ES_SUBSUMED(*this); else GECODE_REWRITE(*this, (Rel::EqDom<View,View>::post(home(*this),x2,x0))); } assert((eq20 != RT_TRUE) || (eq21 != RT_TRUE)); ViewRanges<View> r0(x0), r1(x1); Iter::Ranges::Union<ViewRanges<View>,ViewRanges<View> > u(r0,r1); if (!same(x0,x2) && !same(x1,x2)) GECODE_ME_CHECK(x2.inter_r(home,u,false)); else GECODE_ME_CHECK(x2.inter_r(home,u,true)); return ES_FIX; }