inline void Limits::check(const IntSet& s, const char* l) { if ((s.size() > 0) && ((s.min() < min) || (s.max() > max) || (s.min() > max) || (s.max() < min))) throw OutOfLimits(l); }
ValSelCommitBase<BoolView,int>* valselcommitbool(Space& home, int n, const IntValBranch& ivb) { switch (ivb.select()) { case IntValBranch::SEL_MIN: case IntValBranch::SEL_MED: case IntValBranch::SEL_SPLIT_MIN: case IntValBranch::SEL_RANGE_MIN: case IntValBranch::SEL_VALUES_MIN: return new (home) ValSelCommit<ValSelMin<BoolView>,ValCommitEq<BoolView> >(home,ivb); case IntValBranch::SEL_MAX: case IntValBranch::SEL_SPLIT_MAX: case IntValBranch::SEL_RANGE_MAX: case IntValBranch::SEL_VALUES_MAX: return new (home) ValSelCommit<ValSelMax<BoolView>,ValCommitEq<BoolView> >(home,ivb); case IntValBranch::SEL_RND: return new (home) ValSelCommit<ValSelRnd<BoolView>,ValCommitEq<BoolView> >(home,ivb); case IntValBranch::SEL_VAL_COMMIT: if (ivb.commit() == NULL) { return new (home) ValSelCommit<ValSelFunction<BoolView>,ValCommitEq<BoolView> >(home,ivb); } else { return new (home) ValSelCommit<ValSelFunction<BoolView>,ValCommitFunction<BoolView> >(home,ivb); } case IntValBranch::SEL_NEAR_MIN: case IntValBranch::SEL_NEAR_MAX: case IntValBranch::SEL_NEAR_INC: case IntValBranch::SEL_NEAR_DEC: { IntSharedArray v(ivb.values()); if (n != v.size()) throw ArgumentSizeMismatch("Int::branch"); for (int i=n; i--; ) if ((v[i] < 0) || (v[i] > 1)) throw OutOfLimits("Int::branch"); switch (ivb.select()) { case IntValBranch::SEL_NEAR_MIN: return new (home) ValSelCommit<ValSelNearMinMax<BoolView,true>, ValCommitEq<BoolView> >(home,ivb); case IntValBranch::SEL_NEAR_MAX: return new (home) ValSelCommit<ValSelNearMinMax<BoolView,false>, ValCommitEq<BoolView> >(home,ivb); case IntValBranch::SEL_NEAR_INC: return new (home) ValSelCommit<ValSelNearIncDec<BoolView,true>, ValCommitEq<BoolView> >(home,ivb); case IntValBranch::SEL_NEAR_DEC: return new (home) ValSelCommit<ValSelNearIncDec<BoolView,false>, ValCommitEq<BoolView> >(home,ivb); default: GECODE_NEVER; } } default: throw UnknownBranching("Int::branch"); } }
void dopost(Home home, Term* t, int n, FloatRelType frt, FloatVal c) { Limits::check(c,"Float::linear"); for (int i=n; i--; ) if (t[i].x.assigned()) { c -= t[i].a * t[i].x.val(); t[i]=t[--n]; } if ((c < Limits::min) || (c > Limits::max)) throw OutOfLimits("Float::linear"); /* * Join coefficients for aliased variables: * */ { // Group same variables TermLess tl; Support::quicksort<Term,TermLess>(t,n,tl); // Join adjacent variables int i = 0; int j = 0; while (i < n) { Limits::check(t[i].a,"Float::linear"); FloatVal a = t[i].a; FloatView x = t[i].x; while ((++i < n) && same(t[i].x,x)) { a += t[i].a; Limits::check(a,"Float::linear"); } if (a != 0.0) { t[j].a = a; t[j].x = x; j++; } } n = j; } Term *t_p, *t_n; int n_p, n_n; /* * Partition into positive/negative coefficents * */ if (n > 0) { int i = 0; int j = n-1; while (true) { while ((t[j].a < 0) && (--j >= 0)) ; while ((t[i].a > 0) && (++i < n)) ; if (j <= i) break; std::swap(t[i],t[j]); } t_p = t; n_p = i; t_n = t+n_p; n_n = n-n_p; } else { t_p = t; n_p = 0; t_n = t; n_n = 0; } /* * Make all coefficients positive * */ for (int i=n_n; i--; ) t_n[i].a = -t_n[i].a; if (frt == FRT_GQ) { frt = FRT_LQ; std::swap(n_p,n_n); std::swap(t_p,t_n); c = -c; } if (n == 0) { switch (frt) { case FRT_EQ: if (!c.in(0.0)) home.fail(); break; case FRT_LQ: if (c.max() < 0.0) home.fail(); break; default: GECODE_NEVER; } return; } /* * Test for unit coefficients only * */ bool is_unit = true; for (int i=n; i--; ) if (t[i].a != 1.0) { is_unit = false; break; } if (is_unit) { // Unit coefficients ViewArray<FloatView> x(home,n_p); for (int i = n_p; i--; ) x[i] = t_p[i].x; ViewArray<FloatView> y(home,n_n); for (int i = n_n; i--; ) y[i] = t_n[i].x; post_nary<FloatView>(home,x,y,frt,c); } else { // Arbitrary coefficients ViewArray<ScaleView> x(home,n_p); for (int i = n_p; i--; ) x[i] = ScaleView(t_p[i].a,t_p[i].x); ViewArray<ScaleView> y(home,n_n); for (int i = n_n; i--; ) y[i] = ScaleView(t_n[i].a,t_n[i].x); post_nary<ScaleView>(home,x,y,frt,c); } }
inline void Limits::check(const FloatVal& n, const char* l) { if (!valid(n)) throw OutOfLimits(l); }
inline void Limits::double_check(double n, const char* l) { if ((n < double_min) || (n > double_max)) throw OutOfLimits(l); }
inline void Limits::nonnegative(double n, const char* l) { if ((n < 0.0) || (n > max)) throw OutOfLimits(l); }
inline void Limits::positive(double n, const char* l) { if ((n <= 0.0) || (n > max)) throw OutOfLimits(l); }
inline void Limits::check(int n, const char* l) { if ((n < min) || (n > max)) throw OutOfLimits(l); }
inline void Limits::check(unsigned int n, const char* l) { if (n > card) throw OutOfLimits(l); }
inline void mul_check(long long int x, long long int y, long long int z) { if (Int::Limits::overflow_mul(x,y) || Int::Limits::overflow_mul(x*y,z)) throw OutOfLimits("Int::cumulative"); }