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); }
void dom(Home home, IntVar x, const IntSet& is, BoolVar b, IntConLevel) { Limits::check(is.min(),"Int::dom"); Limits::check(is.max(),"Int::dom"); if (home.failed()) return; GECODE_ES_FAIL(Dom::ReIntSet<IntView>::post(home,x,is,b)); }
IntVar::IntVar(Space& home, const IntSet& ds) : VarImpVar<Int::IntVarImp>(new (home) Int::IntVarImp(home,ds)) { Int::Limits::check(ds.min(),"IntVar::IntVar"); Int::Limits::check(ds.max(),"IntVar::IntVar"); if (ds.size() == 0) throw Int::VariableEmptyDomain("IntVar::IntVar"); }
forceinline bool includes(const View& x, const IntSet& s) { if ((x.max() < s.min()) || (x.min() > s.max())) return false; ViewRanges<View> ix(x); IntSetRanges is(s); return Iter::Ranges::subset(ix,is); }
forceinline bool excludes(const View& x, const IntSet& s) { if ((x.max() < s.min()) || (x.min() > s.max())) return true; ViewRanges<View> ix(x); IntSetRanges is(s); return Iter::Ranges::disjoint(ix,is); }
forceinline bool undecided(const View& x, const IntSet& s) { if ((x.max() < s.min()) || (x.min() > s.max())) return false; ViewRanges<View> ix(x); IntSetRanges is(s); return Iter::Ranges::compare(ix,is) == Iter::Ranges::CS_NONE; }
void dom(Home home, IntVar x, const IntSet& is, IntConLevel) { Limits::check(is.min(),"Int::dom"); Limits::check(is.max(),"Int::dom"); if (home.failed()) return; IntView xv(x); IntSetRanges ris(is); GECODE_ME_FAIL(xv.inter_r(home,ris,false)); }
IntVarArgs::IntVarArgs(Space& home, int n, const IntSet& s) : VarArgArray<IntVar>(n) { Int::Limits::check(s.min(),"IntVarArgs::IntVarArgs"); Int::Limits::check(s.max(),"IntVarArgs::IntVarArgs"); if (s.size() == 0) throw Int::VariableEmptyDomain("IntVarArgs::IntVarArgs"); for (int i = size(); i--; ) a[i]._init(home,s); }
void CachedView<View>::initCache(Space& home, const IntSet& s) { _firstRange = NULL; for (int i=s.ranges(); i--;) { _firstRange = new (home) RangeList(s.min(i),s.max(i),_firstRange); if (i==s.ranges()-1) _lastRange = _firstRange; } _size = s.size(); }
void dom(Home home, const IntVarArgs& x, const IntSet& is, IntConLevel) { Limits::check(is.min(),"Int::dom"); Limits::check(is.max(),"Int::dom"); if (home.failed()) return; for (int i = x.size(); i--; ) { IntSetRanges ris(is); IntView xv(x[i]); GECODE_ME_FAIL(xv.inter_r(home,ris,false)); } }
SetVar::SetVar(Space& home, const IntSet& glb,int ubMin,int ubMax, unsigned int minCard, unsigned int maxCard) : VarImpVar<Set::SetVarImp>(new (home) Set::SetVarImp(home,glb,ubMin,ubMax, minCard,maxCard)) { Set::Limits::check(glb,"SetVar::SetVar"); Set::Limits::check(ubMin,"SetVar::SetVar"); Set::Limits::check(ubMax,"SetVar::SetVar"); Set::Limits::check(maxCard,"SetVar::SetVar"); if (minCard > maxCard || minCard > lubSize() || maxCard < glbSize() || glb.min() < ubMin || glb.max() > ubMax) throw Set::VariableEmptyDomain("SetVar::SetVar"); }
forceinline TakesStatus takes(const View& x, const IntSet& s) { if ((x.max() < s.min()) || (x.min() > s.max())) return TS_NO; ViewRanges<View> ix(x); IntSetRanges is(s); switch (Iter::Ranges::compare(ix,is)) { case Iter::Ranges::CS_SUBSET: return TS_YES; case Iter::Ranges::CS_DISJOINT: return TS_NO; case Iter::Ranges::CS_NONE: return TS_MAYBE; default: GECODE_NEVER; } return TS_MAYBE; }
BndSet::BndSet(Space& home, const IntSet& is) { if (is.ranges()==0) { fst(NULL); lst(NULL); _size = 0; } else { int n = is.ranges(); RangeList* r = home.alloc<RangeList>(n); fst(r); lst(r+n-1); unsigned int s = 0; for (int i = n; i--; ) { s += is.width(i); r[i].min(is.min(i)); r[i].max(is.max(i)); r[i].next(&r[i+1]); } r[n-1].next(NULL); _size = s; } assert(isConsistent()); }
forceinline RelTest holds(VX x, const IntSet& y) { if ((x.max() < y.min()) || (y.max() < x.min())) return RT_FALSE; ViewRanges<VX> rx(x); IntSetRanges ry(y); switch (Iter::Ranges::compare(rx,ry)) { case Iter::Ranges::CS_SUBSET: return RT_TRUE; case Iter::Ranges::CS_DISJOINT: return RT_FALSE; case Iter::Ranges::CS_NONE: return RT_MAYBE; default: GECODE_NEVER; } GECODE_NEVER; return RT_MAYBE; }
void dom(Home home, IntVar x, const IntSet& is, Reify r, IntConLevel) { using namespace Int; Limits::check(is.min(),"Int::dom"); Limits::check(is.max(),"Int::dom"); if (home.failed()) return; switch (r.mode()) { case RM_EQV: GECODE_ES_FAIL((Dom::ReIntSet<IntView,RM_EQV>::post(home,x,is,r.var()))); break; case RM_IMP: GECODE_ES_FAIL((Dom::ReIntSet<IntView,RM_IMP>::post(home,x,is,r.var()))); break; case RM_PMI: GECODE_ES_FAIL((Dom::ReIntSet<IntView,RM_PMI>::post(home,x,is,r.var()))); break; default: throw UnknownReifyMode("Int::dom"); } }
ExecStatus ReIntSet<View,rm>::post(Home home, View x, const IntSet& s, BoolView b) { if (s.ranges() == 0) { if (rm == RM_PMI) return ES_OK; GECODE_ME_CHECK(b.zero(home)); } else if (s.ranges() == 1) { return ReRange<View,rm>::post(home,x,s.min(),s.max(),b); } else if (b.one()) { if (rm == RM_PMI) return ES_OK; IntSetRanges i_is(s); GECODE_ME_CHECK(x.inter_r(home,i_is,false)); } else if (b.zero()) { if (rm == RM_IMP) return ES_OK; IntSetRanges i_is(s); GECODE_ME_CHECK(x.minus_r(home,i_is,false)); } else { (void) new (home) ReIntSet<View,rm>(home,x,s,b); } return ES_OK; }
void sequence(Home home, const BoolVarArgs& x, const IntSet& s, int q, int l, int u, IntConLevel) { if ((s.min() < 0) || (s.max() > 1)) throw NotZeroOne("Int::sequence"); if (x.size() == 0) throw TooFewArguments("Int::sequence"); Limits::check(q,"Int::sequence"); Limits::check(l,"Int::sequence"); Limits::check(u,"Int::sequence"); if (x.same(home)) throw ArgumentSame("Int::sequence"); if ((q < 1) || (q > x.size())) throw OutOfLimits("Int::sequence"); if (home.failed()) return; // Normalize l and u l=std::max(0,l); u=std::min(q,u); // Lower bound of values taken can never exceed upper bound if (u < l) { home.fail(); return; } // Already subsumed as any number of values taken is okay if ((0 == l) && (q == u)) return; // Check whether the set is {0,1}, then the number of values taken is q if ((s.min() == 0) && (s.max() == 1)) { if ((l > 0) || (u < q)) home.failed(); return; } assert(s.min() == s.max()); // All variables must take a value in s if (l == q) { if (s.min() == 0) { for (int i=x.size(); i--; ) { BoolView xv(x[i]); GECODE_ME_FAIL(xv.zero(home)); } } else { assert(s.min() == 1); for (int i=x.size(); i--; ) { BoolView xv(x[i]); GECODE_ME_FAIL(xv.one(home)); } } return; } // No variable can take a value in s if (0 == u) { if (s.min() == 0) { for (int i=x.size(); i--; ) { BoolView xv(x[i]); GECODE_ME_FAIL(xv.one(home)); } } else { assert(s.min() == 1); for (int i=x.size(); i--; ) { BoolView xv(x[i]); GECODE_ME_FAIL(xv.zero(home)); } } return; } ViewArray<BoolView> xv(home,x); GECODE_ES_FAIL( (Sequence::Sequence<BoolView,int>::post (home,xv,s.min(),q,l,u))); }
void sequence(Home home, const IntVarArgs& x, const IntSet &s, int q, int l, int u, IntConLevel) { Limits::check(s.min(),"Int::sequence"); Limits::check(s.max(),"Int::sequence"); if (x.size() == 0) throw TooFewArguments("Int::sequence"); Limits::check(q,"Int::sequence"); Limits::check(l,"Int::sequence"); Limits::check(u,"Int::sequence"); if (x.same(home)) throw ArgumentSame("Int::sequence"); if ((q < 1) || (q > x.size())) throw OutOfLimits("Int::sequence"); if (home.failed()) return; // Normalize l and u l=std::max(0,l); u=std::min(q,u); // Lower bound of values taken can never exceed upper bound if (u < l) { home.fail(); return; } // Already subsumed as any number of values taken is okay if ((0 == l) && (q == u)) return; // All variables must take a value in s if (l == q) { for (int i=x.size(); i--; ) { IntView xv(x[i]); IntSetRanges ris(s); GECODE_ME_FAIL(xv.inter_r(home,ris,false)); } return; } // No variable can take a value in s if (0 == u) { for (int i=x.size(); i--; ) { IntView xv(x[i]); IntSetRanges ris(s); GECODE_ME_FAIL(xv.minus_r(home,ris,false)); } return; } ViewArray<IntView> xv(home,x); if (s.size() == 1) { GECODE_ES_FAIL( (Sequence::Sequence<IntView,int>::post (home,xv,s.min(),q,l,u))); } else { GECODE_ES_FAIL( (Sequence::Sequence<IntView,IntSet>::post (home,xv,s,q,l,u))); } }