IntElemBounds(IntView<U> _y, IntView<V> _x, vec<IntView<W> >& _a) : y(_y), x(_x), a(_a), min_support(-1), max_support(-1), fixed_index(-1), no_min_support(false), no_max_support(false) { for (int i = 0; i < a.size(); i++) a[i].attach(this, i, EVENT_LU); y.attach(this, a.size(), EVENT_LU); x.attach(this, a.size()+1, EVENT_C); }
Min2(IntView<U> _x, IntView<U> _y, IntView<U> _z) : x(_x), y(_y), z(_z) { priority = 1; x.attach(this, 0, EVENT_LU); y.attach(this, 1, EVENT_LU); z.attach(this, 2, EVENT_L); }
int checkSatisfied() { if (satisfied) return 1; if (x.isFixed() && y.isFixed() && a[static_cast<int>(x.getVal())].isFixed()) { satisfied = true; } return 3; }
ExecStatus TellCache::tell(Space& home, IntView x) { if (_eq == -2) { return ES_FAILED; } else if (_eq >= 0) { GECODE_ME_CHECK(x.eq(home,_eq)); } Iter::Values::Array nqi(_nq, _n_nq); GECODE_ME_CHECK(x.minus_v(home, nqi)); _n_nq=0; _eq=-1; return ES_OK; }
bool propagate() { if (y.getMax() < k) { int64_t m = y.getMax()-1; setDom(x, setMax, m, y.getMaxLit()); } int64_t m = x.getMin()+1; if (m > k) m = k; setDom(y, setMin, m, x.getMinLit()); return true; }
Minimum(vec<IntView<U> > _x, IntView<U> _y) : sz(_x.size()), x(_x.release()), y(_y), min_max_var(-1), min_max(INT_MAX), min_fixed(INT_MAX), lower_change(false) { priority = 1; for (int i = 0; i < sz; i++) x[i].attach(this, i, EVENT_LU); y.attach(this, sz, EVENT_L); }
forceinline ExecStatus LinkMulti::post(Home home, ViewArray<BoolView>& x, IntView y, int o) { int n=x.size(); GECODE_ME_CHECK(y.gq(home,o)); GECODE_ME_CHECK(y.lq(home,o+n-1)); assert(n > 0); if (n == 1) { GECODE_ME_CHECK(x[0].one(home)); assert(y.val() == o); } else if (y.assigned()) { int j=y.val()-o; GECODE_ME_CHECK(x[j].one(home)); for (int i=0; i<j; i++) GECODE_ME_CHECK(x[i].zero(home)); for (int i=j+1; i<n; i++) GECODE_ME_CHECK(x[i].zero(home)); } else { for (int i=n; i--; ) if (x[i].one()) { for (int j=0; j<i; j++) GECODE_ME_CHECK(x[j].zero(home)); for (int j=i+1; j<n; j++) GECODE_ME_CHECK(x[j].zero(home)); GECODE_ME_CHECK(y.eq(home,o+i)); return ES_OK; } else if (x[i].zero()) { GECODE_ME_CHECK(y.nq(home,o+i)); } (void) new (home) LinkMulti(home,x,y,o); } return ES_OK; }
void wakeup(int i, int c) { if (i == a.size()+1 && (c & EVENT_F)) { fixed_index = x.getVal(); no_min_support = no_max_support = false; pushInQueue(); } if (fixed_index >= 0) { if (i == a.size() || i == fixed_index) pushInQueue(); } else { if (i < a.size()) { if (i == min_support && a[i].getMin() > y.getMin()) no_min_support = true; if (i == max_support && a[i].getMax() < y.getMax()) no_max_support = true; pushInQueue(); } else if (i == a.size()+1) { if (!x.indomain(min_support)) { no_min_support = true; pushInQueue(); } if (!x.indomain(max_support)) { no_max_support = true; pushInQueue(); } } else pushInQueue(); } }
bool propagate() { // make a less than or equal to min(max(x_i)) setDom(y, setMax, min_max, x[min_max_var].getMaxLit()); if (lower_change) { // make a greater than or equal to min(min(b_i)) int64_t m = INT64_MAX; for (int i = 0; i < sz; i++) { int64_t t = x[i].getMin(); if (t < m) m = t; } if (y.setMinNotR(m)) { Clause *r = NULL; if (so.lazy) { r = Reason_new(sz+1); // Finesse lower bounds // Add reason ![y <= m-1] \/ [x_1 <= m-1] \/ ... \/ [x_n <= m-1] for (int i = 0; i < sz; i++) (*r)[i+1] = x[i].getFMinLit(m); // for (int i = 0; i < sz; i++) (*r)[i+1] = x[i].getLit(m-1, 3); } if (!y.setMin(m, r)) return false; } // make b_i greater than or equal to min(a) m = y.getMin(); Clause *r = NULL; if (so.lazy) { r = Reason_new(2); (*r)[1] = y.getMinLit(); } for (int i = 0; i < sz; i++) { if (x[i].setMinNotR(m)) if (!x[i].setMin(m, r)) return false; } } // Necessary and sufficient conditions for redundancy if (y.getMin() == min_max) satisfied = true; return true; }
Times(IntView<U> _x, IntView<V> _y, IntView<W> _z) : x(_x), y(_y), z(_z) { priority = 1; assert(x.getMin() >= 0 && y.getMin() >= 0 && z.getMin() >= 0); x.attach(this, 0, EVENT_LU); y.attach(this, 1, EVENT_LU); z.attach(this, 2, EVENT_LU); }
forceinline int ValSelRangeMin::val(const Space&, IntView x, int) { if (x.range()) { return (x.width() == 2) ? x.min() : (x.min() + (x.max()-x.min())/2); } else { ViewRanges<View> r(x); return r.max(); } }
forceinline ModEvent SupportSet::tell(Space& home, IntView& x) const { switch (bs.status()) { case Support::BSS_NONE: return ME_INT_FAILED; case Support::BSS_ALL: return ME_INT_NONE; case Support::BSS_SOME: { ResultIter i(*this,x); return x.minus_v(home,i); } default: GECODE_NEVER; } return ME_INT_NONE; }
forceinline int ValSelRangeMax::val(const Space&, IntView x, int) { if (x.range()) { return (x.width() == 2) ? x.max() : (x.max() - (x.max()-x.min())/2); } else { int min; ViewRanges<IntView> r(x); do { min = r.min(); ++r; } while (r()); return min; } }
void wakeup(int i, int c) { if (i < sz) { if (c & EVENT_F) { int64_t m = x[i].getVal(); if (m < min_fixed) min_fixed = m; } int64_t m = x[i].getMax(); if (m < min_max) { min_max_var = i; min_max = m; pushInQueue(); } } if (c & y.getEvent(EVENT_L)) { lower_change = true; pushInQueue(); } }
bool propagate() { // make a less than or equal to min(max(b_i)) setDom(z, setMax, x.getMax(), x.getMaxLit()); setDom(z, setMax, y.getMax(), y.getMaxLit()); int64_t m = (x.getMin() < y.getMin() ? x.getMin() : y.getMin()); setDom(z, setMin, m, x.getFMinLit(m), y.getFMinLit(m)); setDom(x, setMin, z.getMin(), z.getMinLit()); setDom(y, setMin, z.getMin(), z.getMinLit()); if (z.getMin() == x.getMax() || z.getMin() == y.getMax()) satisfied = true; return true; }
int checkSatisfied() { if (satisfied) return 1; if (y.getMin() == min_max) satisfied = true; return 2; }
forceinline unsigned long long int IntTraceView::slack(IntView x) { return x.width()-1; }
Abs(IntView<U> _x, IntView<V> _y) : x(_x), y(_y) { priority = 1; x.attach(this, 0, EVENT_LU); y.attach(this, 1, EVENT_U); }
forceinline void IntTraceView::prune(Space& home, IntView y, const Delta& d) { if (y.range() && (dom->next() == NULL)) { dom->min(y.min()); dom->max(y.max()); } else if (!y.any(d) && (y.max(d)+1 == y.min())) { // The lower bound has been adjusted if (y.min() > dom->max()) { RangeList* p = dom; RangeList* l = p->next(); while ((l != NULL) && (l->max() < y.min())) { p=l; l=l->next(); } dom->dispose(home,p); dom = l; } dom->min(y.min()); } else if (!y.any(d) && (y.max()+1 == y.min(d))) { // upper bound has been adjusted if ((y.max() <= dom->max()) && (dom->next() == NULL)) { dom->max(y.max()); } else { RangeList* p = dom; RangeList* l = p->next(); while ((l != NULL) && (l->min() <= y.max())) { p=l; l=l->next(); } p->max(y.max()); if (p->next() != NULL) p->next()->dispose(home); p->next(NULL); } } else { // Just copy the domain ViewRanges<IntView> yr(y); RangeList::overwrite(home,dom,yr); } }
bool propagate() { int64_t l = x.getMin(); int64_t u = x.getMax(); if (l >= 0) { setDom(y, setMin, l, x.getMinLit()); setDom(y, setMax, u, x.getMinLit(), x.getMaxLit()); } else if (u <= 0) { setDom(y, setMin, -u, x.getMaxLit()); setDom(y, setMax, -l, x.getMaxLit(), x.getMinLit()); } else { // Finesse stronger bound int64_t t = (-l > u ? -l : u); setDom(y, setMax, t, x.getMaxLit(), x.getMinLit()); // setDom(y, setMax, t, x.getFMaxLit(t), x.getFMinLit(-t)); // setDom(y, setMax, t, x.getLit(t+1, 2), x.getLit(-t-1, 3)); } setDom(x, setMax, y.getMax(), y.getMaxLit()); setDom(x, setMin, -y.getMax(), y.getMaxLit()); /* if (x.isFixed()) { if (x.getVal() < 0) { setDom(y, setMin, -x.getVal(), x.getMaxLit()); setDom(y, setMax, -x.getVal(), x.getMinLit()); } else if (x.getVal() > 0) { setDom(y, setMin, x.getVal(), x.getMinLit()); setDom(y, setMax, x.getVal(), x.getMaxLit()); } else { setDom(y, setVal, 0, x.getMinLit(), x.getMaxLit()); } } */ return true; }
bool check() { return (x.getShadowVal() * y.getShadowVal() == z.getShadowVal()); }
bool propagate() { int64_t x_min = x.getMin(), x_max = x.getMax(); int64_t y_min = y.getMin(), y_max = y.getMax(); int64_t z_min = z.getMin(), z_max = z.getMax(); // z >= x.min * y.min setDom(z, setMin, x_min*y_min, x.getMinLit(), y.getMinLit()); // z <= x.max * y.max if (x_max * y_max < IntVar::max_limit) setDom(z, setMax, x_max*y_max, x.getMaxLit(), y.getMaxLit()); // x >= ceil(z.min / y.max) if (y_max >= 1) { setDom(x, setMin, (z_min+y_max-1)/y_max, y.getMaxLit(), z.getMinLit()); } // x <= floor(z.max / y.min) if (y_min >= 1) { setDom(x, setMax, z_max/y_min, y.getMinLit(), z.getMaxLit()); } // y >= ceil(z.min / x.max) if (x_max >= 1) { setDom(y, setMin, (z_min+x_max-1)/x_max, x.getMaxLit(), z.getMinLit()); } // y <= floor(z.max / x.min) if (x_min >= 1) { setDom(y, setMax, z_max/x_min, x.getMinLit(), z.getMaxLit()); } return true; }
bool propagate() { int64_t x_min = x.getMin(), x_max = x.getMax(); int64_t y_min = y.getMin(), y_max = y.getMax(); int64_t z_min = z.getMin(), z_max = z.getMax(); // z >= ceil(x.min / y.max) setDom(z, setMin, (x_min+y_max-1)/y_max, x.getMinLit(), y.getMaxLit()); // z <= ceil(x.max / y.min) setDom(z, setMax, (x_max+y_min-1)/y_min, x.getMaxLit(), y.getMinLit()); // x >= y.min * (z.min - 1) + 1 setDom(x, setMin, y_min*(z_min-1)+1, y.getMinLit(), z.getMinLit()); // x <= y.max * z.max setDom(x, setMax, y_max*z_max, y.getMaxLit(), z.getMaxLit()); // y >= ceil(x.min / z.max) if (z_max >= 1) { setDom(y, setMin, (x_min+z_max-1)/z_max, x.getMinLit(), z.getMaxLit()); } // y <= ceil(x.max / z.min-1) - 1 if (z_min >= 2) { setDom(y, setMax, (x_max+z_min-2)/(z_min-1)-1, x.getMaxLit(), z.getMinLit()); } return true; }
bool check() { return ((x.getShadowVal() == y.getShadowVal()) || (x.getShadowVal() == -y.getShadowVal())); }
bool check() { return ((int) ceil(x.getShadowVal() / y.getShadowVal()) == z.getShadowVal()); }
forceinline ViewRanges<IntView>::ViewRanges(const IntView& x) : IntVarImpFwd(x.varimp()) {}
bool check() { int min = INT_MAX; for (int i = 0; i < sz; i++) if (x[i].getShadowVal() < min) min = x[i].getShadowVal(); return (y.getShadowVal() == min); }
bool check() { return ((int) std::min(x.getShadowVal(), y.getShadowVal()) == z.getShadowVal()); }
forceinline void ViewRanges<IntView>::init(const IntView& x) { IntVarImpFwd::init(x.varimp()); }
int checkSatisfied() { if (satisfied) return 1; if (z.getMin() == x.getMax() || z.getMin() == y.getMax()) satisfied = true; return 3; }