void linear(Home home, const IntVarArgs& x, IntRelType r, IntVar y, IntConLevel icl) { if (home.failed()) return; Region re(home); Linear::Term<IntView>* t = re.alloc<Linear::Term<IntView> >(x.size()+1); for (int i = x.size(); i--; ) { t[i].a=1; t[i].x=x[i]; } int min, max; estimate(t,x.size(),0,min,max); IntView v(y); switch (r) { case IRT_EQ: GECODE_ME_FAIL(v.gq(home,min)); GECODE_ME_FAIL(v.lq(home,max)); break; case IRT_GQ: GECODE_ME_FAIL(v.lq(home,max)); break; case IRT_LQ: GECODE_ME_FAIL(v.gq(home,min)); break; default: ; } if (home.failed()) return; t[x.size()].a=-1; t[x.size()].x=y; Linear::post(home,t,x.size()+1,r,0,icl); }
void linear(Home home, const FloatValArgs& a, const FloatVarArgs& x, FloatRelType frt, FloatVar y) { using namespace Float; if (a.size() != x.size()) throw ArgumentSizeMismatch("Float::linear"); if (home.failed()) return; Region re(home); Linear::Term* t = re.alloc<Linear::Term>(x.size()+1); for (int i = x.size(); i--; ) { t[i].a=a[i]; t[i].x=x[i]; } FloatNum min, max; estimate(t,x.size(),0.0,min,max); FloatView v(y); switch (frt) { case FRT_EQ: GECODE_ME_FAIL(v.gq(home,min)); GECODE_ME_FAIL(v.lq(home,max)); break; case FRT_GQ: case FRT_GR: GECODE_ME_FAIL(v.lq(home,max)); break; case FRT_LQ: case FRT_LE: GECODE_ME_FAIL(v.gq(home,min)); break; default: ; } if (home.failed()) return; t[x.size()].a=-1.0; t[x.size()].x=y; Linear::post(home,t,x.size()+1,frt,0.0); }
void rel(Home home, IntVar x0, IntRelType irt, IntVar x1, IntConLevel icl) { if (home.failed()) return; switch (irt) { case IRT_EQ: if ((icl == ICL_DOM) || (icl == ICL_DEF)) { GECODE_ES_FAIL((Rel::EqDom<IntView,IntView>::post(home,x0,x1))); } else { GECODE_ES_FAIL((Rel::EqBnd<IntView,IntView>::post(home,x0,x1))); } break; case IRT_NQ: GECODE_ES_FAIL(Rel::Nq<IntView>::post(home,x0,x1)); break; case IRT_GQ: std::swap(x0,x1); // Fall through case IRT_LQ: GECODE_ES_FAIL(Rel::Lq<IntView>::post(home,x0,x1)); break; case IRT_GR: std::swap(x0,x1); // Fall through case IRT_LE: GECODE_ES_FAIL(Rel::Le<IntView>::post(home,x0,x1)); break; default: throw UnknownRelation("Int::rel"); } }
void unary(Home home, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, const BoolVarArgs& m, IntConLevel icl) { using namespace Gecode::Int; using namespace Gecode::Int::Unary; if ((s.size() != p.size()) || (s.size() != m.size()) || (s.size() != e.size())) throw Int::ArgumentSizeMismatch("Int::unary"); if (home.failed()) return; for (int i=p.size(); i--; ) { rel(home, p[i], IRT_GQ, 0); } bool allMandatory = true; for (int i=m.size(); i--;) { if (!m[i].one()) { allMandatory = false; break; } } if (allMandatory) { unary(home,s,p,e,icl); } else { TaskArray<OptFlexTask> t(home,s.size()); for (int i=s.size(); i--; ) t[i].init(s[i],p[i],e[i],m[i]); GECODE_ES_FAIL(OptProp<OptFlexTask>::post(home,t)); } }
void unary(Home home, const IntVarArgs& s, const IntArgs& p, const BoolVarArgs& m, IntConLevel icl) { using namespace Gecode::Int; using namespace Gecode::Int::Unary; if (s.same(home)) throw Int::ArgumentSame("Int::unary"); if ((s.size() != p.size()) || (s.size() != m.size())) throw Int::ArgumentSizeMismatch("Int::unary"); for (int i=p.size(); i--; ) { Int::Limits::nonnegative(p[i],"Int::unary"); Int::Limits::check(static_cast<double>(s[i].max()) + p[i], "Int::unary"); } bool allMandatory = true; for (int i=m.size(); i--;) { if (!m[i].one()) { allMandatory = false; break; } } if (allMandatory) { unary(home,s,p,icl); } else { if (home.failed()) return; TaskArray<OptFixPTask> t(home,s.size()); for (int i=s.size(); i--; ) t[i].init(s[i],p[i],m[i]); GECODE_ES_FAIL(OptProp<OptFixPTask>::post(home,t)); } }
void pow(Home home, FloatNum base, FloatVar x0, FloatVar x1) { using namespace Float; if (home.failed()) return; GECODE_ES_FAIL((Transcendental::Pow<FloatView,FloatView> ::post(home,base,x0,x1))); }
void wait(Home home, const BoolVarArgs& x, void (*c)(Space& home), IntConLevel) { if (home.failed()) return; ViewArray<Int::BoolView> xv(home,x); GECODE_ES_FAIL(Kernel::NaryWait<Int::BoolView>::post(home,xv,c)); }
void binpacking(Home home, const IntVarArgs& l, const IntVarArgs& b, const IntArgs& s, IntConLevel) { using namespace Int; if (l.same(home,b)) throw ArgumentSame("Int::binpacking"); if (b.size() != s.size()) throw ArgumentSizeMismatch("Int::binpacking"); for (int i=s.size(); i--; ) Limits::nonnegative(s[i],"Int::binpacking"); if (home.failed()) return; ViewArray<OffsetView> lv(home,l.size()); for (int i=l.size(); i--; ) lv[i] = OffsetView(l[i],0); if (b.size() == 0) { for (int i=l.size(); i--; ) GECODE_ME_FAIL(lv[i].eq(home,0)); return; } ViewArray<BinPacking::Item> bs(home,b.size()); for (int i=bs.size(); i--; ) bs[i] = BinPacking::Item(b[i],s[i]); Support::quicksort(&bs[0], bs.size()); GECODE_ES_FAIL(Int::BinPacking::Pack::post(home,lv,bs)); }
void channel(Home home, const BoolVarArgs& x, SetVar y) { if (home.failed()) return; ViewArray<Int::BoolView> xv(home,x); GECODE_ES_FAIL((Set::Int::ChannelBool<Set::SetView> ::post(home,xv,y))); }
void mod(Home home, IntVar x0, IntVar x1, IntVar x2, IntConLevel icl) { if (home.failed()) return; IntVar _div(home, Int::Limits::min, Int::Limits::max); divmod(home, x0, x1, _div, x2, icl); }
void qrel(Home home, QBoolVar qx0, BoolOpType o, QBoolVar qx1, BoolVar x2) { using namespace Int; if (home.failed()) return; switch (o) { case BOT_AND: { NegBoolView n0(qx0.x); NegBoolView n1(qx1.x); NegBoolView n2(x2); GECODE_ES_FAIL((Bool::QOr<NegBoolView,NegBoolView,NegBoolView> ::post(home,n0,qx0.q,qx0.r,n1,qx1.q,qx1.r,n2))); } break; case BOT_OR: GECODE_ES_FAIL((Bool::QOr<BoolView,BoolView,BoolView> ::post(home,qx0.x,qx0.q,qx0.r,qx1.x,qx1.q,qx1.r,x2))); break; case BOT_IMP: { NegBoolView n0(qx0.x); GECODE_ES_FAIL((Bool::QOr<NegBoolView,BoolView,BoolView> ::post(home,n0,qx0.q,qx0.r,qx1.x,qx1.q,qx1.r,x2))); } break; case BOT_EQV: GECODE_ES_FAIL((Bool::QEqv<BoolView,BoolView,BoolView> ::post(home,qx0,qx1,x2))); break; case BOT_XOR: GECODE_ES_FAIL((Bool::QXorv<BoolView,BoolView,BoolView> ::post(home,qx0,qx1,x2))); break; default: throw UnknownOperation("Int::rel"); } }
void div(Home home, IntVar x0, IntVar x1, IntVar x2, IntConLevel) { if (home.failed()) return; GECODE_ES_FAIL( (Arithmetic::DivBnd<IntView>::post(home,x0,x1,x2))); }
void distinct(Home home, const IntArgs& c, const IntVarArgs& x, IntConLevel icl) { if (x.same(home)) throw ArgumentSame("Int::distinct"); if (c.size() != x.size()) throw ArgumentSizeMismatch("Int::distinct"); if (home.failed()) return; ViewArray<OffsetView> cx(home,x.size()); for (int i = c.size(); i--; ) { long long int cx_min = (static_cast<long long int>(c[i]) + static_cast<long long int>(x[i].min())); long long int cx_max = (static_cast<long long int>(c[i]) + static_cast<long long int>(x[i].max())); Limits::check(c[i],"Int::distinct"); Limits::check(cx_min,"Int::distinct"); Limits::check(cx_max,"Int::distinct"); cx[i] = OffsetView(x[i],c[i]); } switch (icl) { case ICL_BND: GECODE_ES_FAIL(Distinct::Bnd<OffsetView>::post(home,cx)); break; case ICL_DOM: GECODE_ES_FAIL(Distinct::Dom<OffsetView>::post(home,cx)); break; default: GECODE_ES_FAIL(Distinct::Val<OffsetView>::post(home,cx)); } }
void extensional(Home home, const BoolVarArgs& x, const TupleSet& t, ExtensionalPropKind epk, IntConLevel) { using namespace Int; if (!t.finalized()) throw NotYetFinalized("Int::extensional"); if (t.arity() != x.size()) throw ArgumentSizeMismatch("Int::extensional"); if (home.failed()) return; // Construct view array ViewArray<BoolView> xv(home,x); switch (epk) { case EPK_SPEED: GECODE_ES_FAIL((Extensional::Incremental<BoolView> ::post(home,xv,t))); break; default: if (x.same(home)) { GECODE_ES_FAIL((Extensional::Basic<BoolView,true> ::post(home,xv,t))); } else { GECODE_ES_FAIL((Extensional::Basic<BoolView,false> ::post(home,xv,t))); } break; } }
void div(Home home, FloatVar x0, FloatVar x1, FloatVar x2) { using namespace Float; if (home.failed()) return; GECODE_ES_FAIL( (Arithmetic::Div<FloatView,FloatView,FloatView>::post(home,x0,x1,x2))); }
void member(Home home, const BoolVarArgs& x, BoolVar y, Reify r, IntConLevel) { using namespace Int; if (home.failed()) return; ViewArray<BoolView> xv(home,x); switch (r.mode()) { case RM_EQV: GECODE_ES_FAIL((Member::ReProp<BoolView,RM_EQV> ::post(home,xv,y,r.var()))); break; case RM_IMP: GECODE_ES_FAIL((Member::ReProp<BoolView,RM_IMP> ::post(home,xv,y,r.var()))); break; case RM_PMI: GECODE_ES_FAIL((Member::ReProp<BoolView,RM_PMI> ::post(home,xv,y,r.var()))); break; default: throw UnknownReifyMode("Int::member"); } }
void log(Home home, FloatVar x0, FloatVar x1) { using namespace Float; if (home.failed()) return; GECODE_ES_FAIL((Transcendental::Exp<FloatView,FloatView> ::post(home,x1,x0))); }
void nooverlap(Home home, const IntVarArgs& x, const IntArgs& w, const IntVarArgs& y, const IntArgs& h, IntConLevel) { using namespace Int; using namespace NoOverlap; if (x.same(home) || y.same(home)) throw ArgumentSame("Int::nooverlap"); if ((x.size() != w.size()) || (x.size() != y.size()) || (x.size() != h.size())) throw ArgumentSizeMismatch("Int::nooverlap"); for (int i=x.size(); i--; ) { Limits::nonnegative(w[i],"Int::nooverlap"); Limits::nonnegative(h[i],"Int::nooverlap"); Limits::check(static_cast<double>(x[i].max()) + w[i], "Int::nooverlap"); Limits::check(static_cast<double>(y[i].max()) + h[i], "Int::nooverlap"); } if (home.failed()) return; ManBox<FixDim,2>* b = static_cast<Space&>(home).alloc<ManBox<FixDim,2> >(x.size()); for (int i=x.size(); i--; ) { b[i][0] = FixDim(x[i],w[i]); b[i][1] = FixDim(y[i],h[i]); } GECODE_ES_FAIL((NoOverlap::ManProp<FixDim,2>::post(home,b,x.size()))); }
void channel(Home home, FloatVar x0, IntVar x1) { using namespace Float; using namespace Int; if (home.failed()) return; GECODE_ES_FAIL((Arithmetic::Channel<FloatView,IntView>::post(home,x0,x1))); }
void count(Home home, const IntVarArgs& x, const IntVarArgs& _c, const IntArgs& _v, IntConLevel icl) { using namespace Int; IntVarArgs c(_c); IntArgs v(_v); if (v.size() != c.size()) throw ArgumentSizeMismatch("Int::count"); if (x.same(home)) throw ArgumentSame("Int::count"); if (home.failed()) return; removeDuplicates(home,c,v); ViewArray<IntView> xv(home, x); ViewArray<GCC::CardView> cv(home, c.size()); // set the cardinality for (int i = v.size(); i--; ) cv[i].init(c[i],v[i]); switch (icl) { case ICL_BND: GECODE_ES_FAIL( (GCC::Bnd<GCC::CardView>::post(home,xv,cv))); break; case ICL_DOM: GECODE_ES_FAIL( (GCC::Dom<GCC::CardView>::post(home,xv,cv))); break; default: GECODE_ES_FAIL( (GCC::Val<GCC::CardView>::post(home,xv,cv))); } }
void when(Home home, BoolVar x, void (*t)(Space& home), void (*e)(Space& home), IntConLevel) { if (home.failed()) return; GECODE_ES_FAIL(Int::Exec::When::post(home,x,t,e)); }
BrancherHandle branch(Home home, const SetVarArgs& x, SetVarBranch vars, SetValBranch vals, const Symmetries& syms, SetBranchFilter bf, SetVarValPrint vvp) { using namespace Set; if (home.failed()) return BrancherHandle(); vars.expand(home,x); ViewArray<SetView> xv(home,x); ViewSel<SetView>* vs[1] = { Branch::viewsel(home,vars) }; // Construct mapping from each variable in the array to its index // in the array. VariableMap variableMap; for (int i = 0 ; i < x.size() ; i++) variableMap[x[i].varimp()] = i; // Convert the modelling-level Symmetries object into an array of // SymmetryImp objects. int n = syms.size(); SymmetryImp<SetView>** array = static_cast<Space&>(home).alloc<SymmetryImp<SetView>* >(n); for (int i = 0 ; i < n ; i++) { array[i] = createSetSym(home, syms[i], variableMap); } return LDSBSetBrancher<SetView,1,int,2>::post (home,xv,vs,Branch::valselcommit(home,vals),array,n,bf,vvp); }
void argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak, IntConLevel) { using namespace Int; if (x.size() == 0) throw TooFewArguments("Int::argmin"); if (x.same(home,y)) throw ArgumentSame("Int::argmin"); if (home.failed()) return; // Constrain y properly IntView yv(y); GECODE_ME_FAIL(yv.gq(home,0)); GECODE_ME_FAIL(yv.le(home,x.size())); // Construct index view array IdxViewArray<MinusView> ix(home,x.size()); for (int i=x.size(); i--; ) { ix[i].idx=i; ix[i].view=MinusView(x[i]); } if (tiebreak) GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,true> ::post(home,ix,yv))); else GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,false> ::post(home,ix,yv))); }
void dom(Home home, IntVar x, int min, int max, BoolVar b, IntConLevel) { Limits::check(min,"Int::dom"); Limits::check(max,"Int::dom"); if (home.failed()) return; GECODE_ES_FAIL(Dom::ReRange<IntView>::post(home,x,min,max,b)); }
void unary(Home home, const IntVarArgs& s, const IntVarArgs& p, const IntVarArgs& e, IntConLevel icl) { using namespace Gecode::Int; using namespace Gecode::Int::Unary; if ((s.size() != p.size()) || (s.size() != e.size())) throw Int::ArgumentSizeMismatch("Int::unary"); if (home.failed()) return; for (int i=p.size(); i--; ) { rel(home, p[i], IRT_GQ, 0); } bool fixP = true; for (int i=p.size(); i--;) { if (!p[i].assigned()) { fixP = false; break; } } if (fixP) { IntArgs pp(p.size()); for (int i=p.size(); i--;) pp[i] = p[i].val(); unary(home,s,pp,icl); } else { TaskArray<ManFlexTask> t(home,s.size()); for (int i=s.size(); i--; ) t[i].init(s[i],p[i],e[i]); GECODE_ES_FAIL(ManProp<ManFlexTask>::post(home,t)); } }
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)); }
void unary(Home home, const TaskTypeArgs& t, const IntVarArgs& flex, const IntArgs& fix, IntConLevel icl) { using namespace Gecode::Int; using namespace Gecode::Int::Unary; if ((flex.size() != fix.size()) || (flex.size() != t.size())) throw Int::ArgumentSizeMismatch("Int::unary"); for (int i=fix.size(); i--; ) { if (t[i] == TT_FIXP) Int::Limits::nonnegative(fix[i],"Int::unary"); else Int::Limits::check(fix[i],"Int::unary"); Int::Limits::check(static_cast<double>(flex[i].max()) + fix[i], "Int::unary"); } if (home.failed()) return; bool fixp = true; for (int i=t.size(); i--;) if (t[i] != TT_FIXP) { fixp = false; break; } if (fixp) { unary(home, flex, fix, icl); } else { TaskArray<ManFixPSETask> tasks(home,flex.size()); for (int i=flex.size(); i--;) tasks[i].init(t[i],flex[i],fix[i]); GECODE_ES_FAIL(ManProp<ManFixPSETask>::post(home,tasks)); } }
void dom(Home home, IntVar x, int n, IntConLevel) { Limits::check(n,"Int::dom"); if (home.failed()) return; IntView xv(x); GECODE_ME_FAIL(xv.eq(home,n)); }
void assign(Home home, const BoolVarArgs& x, IntAssign vals, const ValBranchOptions& o_vals) { using namespace Int; if (home.failed()) return; ViewArray<BoolView> xv(home,x); ViewSelNone<BoolView> v(home,VarBranchOptions::def); switch (vals) { case INT_ASSIGN_MIN: case INT_ASSIGN_MED: { Branch::AssignValZero<BoolView> a(home,o_vals); ViewValBrancher <ViewSelNone<BoolView>,Branch::AssignValZero<BoolView> > ::post(home,xv,v,a); } break; case INT_ASSIGN_MAX: { Branch::AssignValZero<NegBoolView> a(home,o_vals); ViewValBrancher <ViewSelNone<BoolView>,Branch::AssignValZero<NegBoolView> > ::post(home,xv,v,a); } break; case INT_ASSIGN_RND: { Branch::AssignValRnd<BoolView> a(home,o_vals); ViewValBrancher <ViewSelNone<BoolView>,Branch::AssignValRnd<BoolView> > ::post(home,xv,v,a); } break; default: throw UnknownBranching("Int::assign"); } }
void rel(Home home, SetOpType op, const SetVarArgs& x, const IntSet& z, SetVar y) { if (home.failed()) return; Set::Limits::check(z, "Set::rel"); ViewArray<SetView> xa(home,x); switch (op) { case SOT_UNION: GECODE_ES_FAIL((RelOp::UnionN<SetView,SetView>::post(home, xa, z, y))); break; case SOT_DUNION: GECODE_ES_FAIL( (RelOp::PartitionN<SetView,SetView>::post(home, xa, z, y))); break; case SOT_INTER: { GECODE_ES_FAIL( (RelOp::IntersectionN<SetView,SetView> ::post(home, xa, z, y))); } break; case SOT_MINUS: throw IllegalOperation("Set::rel"); break; default: throw UnknownOperation("Set::rel"); } }