void channel(Home home, const IntVarArgs& x, int xoff, const IntVarArgs& y, int yoff, IntConLevel icl) { using namespace Int; using namespace Channel; int n = x.size(); if (n != y.size()) throw ArgumentSizeMismatch("Int::channel"); if (x.same(home) || y.same(home)) throw ArgumentSame("Int::channel"); Limits::check(xoff,"Int::channel"); Limits::check(yoff,"Int::channel"); if ((xoff < 0) || (yoff < 0)) throw OutOfLimits("Int::channel"); if (home.failed()) return; if (n == 0) return; if ((xoff < 2) && (yoff < 2) && (xoff == yoff)) { if (icl == ICL_DOM) { DomInfo<IntView,NoOffset<IntView> >* di = static_cast<Space&>(home). alloc<DomInfo<IntView,NoOffset<IntView> > >(2*(n+xoff)); for (int i=n; i--; ) { di[xoff+i ].init(x[i],n+xoff); di[2*xoff+i+n].init(y[i],n+xoff); } if (xoff == 1) { IntVar x0(home,0,0); di[0].init(x0, n+xoff); IntVar y0(home,0,0); di[n+xoff].init(y0, n+xoff); } NoOffset<IntView> noff; if (x.same(home,y)) { GECODE_ES_FAIL((Dom<IntView,NoOffset<IntView>,true> ::post(home,n+xoff,di,noff,noff))); } else { GECODE_ES_FAIL((Dom<IntView,NoOffset<IntView>,false> ::post(home,n+xoff,di,noff,noff))); } } else { ValInfo<IntView>* vi = static_cast<Space&>(home).alloc<ValInfo<IntView> >(2*(n+xoff)); for (int i=n; i--; ) { vi[xoff+i ].init(x[i],n+xoff); vi[2*xoff+i+n].init(y[i],n+xoff); } if (xoff == 1) { IntVar x0(home,0,0); vi[0].init(x0, n+xoff); IntVar y0(home,0,0); vi[n+xoff].init(y0, n+xoff); } NoOffset<IntView> noff; if (x.same(home,y)) { GECODE_ES_FAIL((Val<IntView,NoOffset<IntView>,true> ::post(home,n+xoff,vi,noff,noff))); } else { GECODE_ES_FAIL((Val<IntView,NoOffset<IntView>,false> ::post(home,n+xoff,vi,noff,noff))); } } } else { if (icl == ICL_DOM) { DomInfo<IntView,Offset>* di = static_cast<Space&>(home).alloc<DomInfo<IntView,Offset> >(2*n); for (int i=n; i--; ) { di[i ].init(x[i],n); di[i+n].init(y[i],n); } Offset ox(-xoff); Offset oy(-yoff); if (x.same(home,y)) { GECODE_ES_FAIL((Dom<IntView,Offset,true> ::post(home,n,di,ox,oy))); } else { GECODE_ES_FAIL((Dom<IntView,Offset,false> ::post(home,n,di,ox,oy))); } } else { ValInfo<IntView>* vi = static_cast<Space&>(home).alloc<ValInfo<IntView> >(2*n); for (int i=n; i--; ) { vi[i ].init(x[i],n); vi[i+n].init(y[i],n); } Offset ox(-xoff); Offset oy(-yoff); if (x.same(home,y)) { GECODE_ES_FAIL((Val<IntView,Offset,true> ::post(home,n,vi,ox,oy))); } else { GECODE_ES_FAIL((Val<IntView,Offset,false> ::post(home,n,vi,ox,oy))); } } } }
bool Home::operator == (const Home &s) { if (iHome == s.getiHome()) return true; return false; }
void channel(Home home, BoolVar x0, IntVar x1, IntConLevel) { using namespace Int; if (home.failed()) return; GECODE_ES_FAIL(Channel::LinkSingle::post(home,x0,x1)); }
void unshare(Home home, BoolVarArgs& x, IntConLevel) { if (home.failed()) return; GECODE_ES_FAIL(Int::Unshare::unshare<BoolVar>(home,x,ICL_DEF)); }
void unshare(Home home, IntVarArgs& x, IntConLevel icl) { if (home.failed()) return; GECODE_ES_FAIL(Int::Unshare::unshare<IntVar>(home,x,icl)); }
void rel_re(Home home, View0 x, SetRelType r, View1 y, BoolVar b) { if (home.failed()) return; switch (r) { case SRT_EQ: { GECODE_ES_FAIL( (ReEq<View0,View1>::post(home, x,y,b))); } break; case SRT_NQ: { BoolVar notb(home, 0, 1); rel(home, b, IRT_NQ, notb); GECODE_ES_FAIL( (ReEq<View0,View1>::post(home,x,y,notb))); } break; case SRT_SUB: { GECODE_ES_FAIL( (ReSubset<View0,View1>::post(home, x,y,b))); } break; case SRT_SUP: { GECODE_ES_FAIL( (ReSubset<View1,View0>::post(home, y,x,b))); } break; case SRT_DISJ: { // x||y <=> b is equivalent to // ( y <= complement(x) ) <=> b ComplementView<View0> xc(x); GECODE_ES_FAIL( (ReSubset<View1,ComplementView<View0> > ::post(home, y, xc, b))); } break; case SRT_CMPL: { ComplementView<View0> xc(x); GECODE_ES_FAIL( (ReEq<ComplementView<View0>,View1> ::post(home, xc, y, b))); } break; case SRT_LQ: GECODE_ES_FAIL((ReLq<View0,View1,false>::post(home,x,y,b))); break; case SRT_LE: GECODE_ES_FAIL((ReLq<View0,View1,true>::post(home,x,y,b))); break; case SRT_GQ: GECODE_ES_FAIL((ReLq<View1,View0,false>::post(home,y,x,b))); break; case SRT_GR: GECODE_ES_FAIL((ReLq<View1,View0,true>::post(home,y,x,b))); break; default: throw UnknownRelation("Set::rel"); } }
void dom(Home home, IntVar x, int n, BoolVar b, IntConLevel) { Limits::check(n,"Int::dom"); if (home.failed()) return; GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,BoolView>::post(home,x,n,b))); }
// constant cards void count(Home home, const IntVarArgs& x, const IntSetArgs& _c, const IntArgs& _v, IntConLevel icl) { using namespace Int; IntSetArgs c(_c); IntArgs v(_v); if (v.size() != c.size()) throw ArgumentSizeMismatch("Int::count"); if (x.same(home)) throw ArgumentSame("Int::count"); for (int i=c.size(); i--; ) { Limits::check(v[i],"Int::count"); Limits::check(c[i].min(),"Int::count"); Limits::check(c[i].max(),"Int::count"); } if (home.failed()) return; removeDuplicates(home,c,v); ViewArray<IntView> xv(home, x); for (int i = v.size(); i--; ) { if (c[i].ranges() > 1) { // Found hole, so create temporary variables ViewArray<GCC::CardView> cv(home, v.size()); for (int j = v.size(); j--; ) cv[j].init(home,c[j],v[j]); 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))); } return; } } // No holes: create CardConsts ViewArray<GCC::CardConst> cv(home, c.size()); for (int i = c.size(); i--; ) cv[i].init(home,c[i].min(),c[i].max(),v[i]); switch (icl) { case ICL_BND: GECODE_ES_FAIL( (GCC::Bnd<GCC::CardConst>::post(home, xv, cv))); break; case ICL_DOM: GECODE_ES_FAIL( (GCC::Dom<GCC::CardConst>::post(home, xv, cv))); break; default: GECODE_ES_FAIL( (GCC::Val<GCC::CardConst>::post(home, xv, cv))); } }