/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte * * Copyright: * Christian Schulte, 2002 * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include #include namespace Gecode { void rel(Home home, BoolVar x0, IntRelType irt, BoolVar x1, IntPropLevel) { using namespace Int; GECODE_POST; switch (irt) { case IRT_EQ: GECODE_ES_FAIL((Bool::Eq ::post(home,x0,x1))); break; case IRT_NQ: { NegBoolView n1(x1); GECODE_ES_FAIL((Bool::Eq ::post(home,x0,n1))); } break; case IRT_GQ: GECODE_ES_FAIL(Bool::Lq::post(home,x1,x0)); break; case IRT_LQ: GECODE_ES_FAIL(Bool::Lq::post(home,x0,x1)); break; case IRT_GR: GECODE_ES_FAIL(Bool::Le::post(home,x1,x0)); break; case IRT_LE: GECODE_ES_FAIL(Bool::Le::post(home,x0,x1)); break; default: throw UnknownRelation("Int::rel"); } } void rel(Home home, BoolVar x0, IntRelType irt, int n, IntPropLevel) { using namespace Int; GECODE_POST; BoolView x(x0); if (n == 0) { switch (irt) { case IRT_LQ: case IRT_EQ: GECODE_ME_FAIL(x.zero(home)); break; case IRT_NQ: case IRT_GR: GECODE_ME_FAIL(x.one(home)); break; case IRT_LE: home.fail(); break; case IRT_GQ: break; default: throw UnknownRelation("Int::rel"); } } else if (n == 1) { switch (irt) { case IRT_GQ: case IRT_EQ: GECODE_ME_FAIL(x.one(home)); break; case IRT_NQ: case IRT_LE: GECODE_ME_FAIL(x.zero(home)); break; case IRT_GR: home.fail(); break; case IRT_LQ: break; default: throw UnknownRelation("Int::rel"); } } else { throw NotZeroOne("Int::rel"); } } void rel(Home home, BoolVar x0, IntRelType irt, BoolVar x1, Reify r, IntPropLevel) { using namespace Int; GECODE_POST; switch (irt) { case IRT_EQ: switch (r.mode()) { case RM_EQV: GECODE_ES_FAIL((Bool::Eqv ::post(home,x0,x1,r.var()))); break; case RM_IMP: GECODE_ES_FAIL((Rel::ReEqBnd ::post(home,x0,x1,r.var()))); break; case RM_PMI: GECODE_ES_FAIL((Rel::ReEqBnd ::post(home,x0,x1,r.var()))); break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_NQ: { NegBoolView nr(r.var()); switch (r.mode()) { case RM_EQV: GECODE_ES_FAIL((Bool::Eqv ::post(home,x0,x1,nr))); break; case RM_IMP: GECODE_ES_FAIL((Rel::ReEqBnd ::post(home,x0,x1,nr))); break; case RM_PMI: GECODE_ES_FAIL((Rel::ReEqBnd ::post(home,x0,x1,nr))); break; default: throw UnknownReifyMode("Int::rel"); } } break; case IRT_GQ: std::swap(x0,x1); // Fall through case IRT_LQ: switch (r.mode()) { case RM_EQV: { NegBoolView n0(x0); GECODE_ES_FAIL((Bool::Or ::post(home,n0,x1,r.var()))); } break; case RM_IMP: GECODE_ES_FAIL((Rel::ReLq ::post(home,x0,x1,r.var()))); break; case RM_PMI: GECODE_ES_FAIL((Rel::ReLq ::post(home,x0,x1,r.var()))); break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_LE: std::swap(x0,x1); // Fall through case IRT_GR: { NegBoolView nr(r.var()); switch (r.mode()) { case RM_EQV: { NegBoolView n0(x0); GECODE_ES_FAIL((Bool::Or ::post(home,n0,x1,nr))); } break; case RM_IMP: GECODE_ES_FAIL((Rel::ReLq ::post(home,x0,x1,nr))); break; case RM_PMI: GECODE_ES_FAIL((Rel::ReLq ::post(home,x0,x1,nr))); break; default: throw UnknownReifyMode("Int::rel"); } } break; default: throw UnknownRelation("Int::rel"); } } void rel(Home home, BoolVar x0, IntRelType irt, int n, Reify r, IntPropLevel) { using namespace Int; GECODE_POST; BoolView x(x0); BoolView y(r.var()); if (n == 0) { switch (irt) { case IRT_LQ: case IRT_EQ: switch (r.mode()) { case RM_EQV: { NegBoolView ny(y); GECODE_ES_FAIL((Bool::Eq ::post(home,x,ny))); } break; case RM_IMP: { NegBoolView nx(x); NegBoolView ny(y); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,nx,ny))); } break; case RM_PMI: GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,x,y))); break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_NQ: case IRT_GR: switch (r.mode()) { case RM_EQV: GECODE_ES_FAIL((Bool::Eq ::post(home,x,y))); break; case RM_IMP: { NegBoolView ny(y); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,x,ny))); } break; case RM_PMI: { NegBoolView nx(x); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,nx,y))); } break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_LE: switch (r.mode()) { case RM_EQV: case RM_IMP: GECODE_ME_FAIL(y.zero(home)); break; case RM_PMI: break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_GQ: switch (r.mode()) { case RM_EQV: case RM_PMI: GECODE_ME_FAIL(y.one(home)); break; case RM_IMP: break; default: throw UnknownReifyMode("Int::rel"); } break; default: throw UnknownRelation("Int::rel"); } } else if (n == 1) { switch (irt) { case IRT_NQ: case IRT_LE: switch (r.mode()) { case RM_EQV: { NegBoolView ny(y); GECODE_ES_FAIL((Bool::Eq ::post(home,x,ny))); } break; case RM_IMP: { NegBoolView nx(x); NegBoolView ny(y); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,nx,ny))); } break; case RM_PMI: GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,x,y))); break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_EQ: case IRT_GQ: switch (r.mode()) { case RM_EQV: GECODE_ES_FAIL((Bool::Eq ::post(home,x,y))); break; case RM_IMP: { NegBoolView ny(y); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,x,ny))); } break; case RM_PMI: { NegBoolView nx(x); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,nx,y))); } break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_GR: switch (r.mode()) { case RM_EQV: case RM_IMP: GECODE_ME_FAIL(y.zero(home)); break; case RM_PMI: break; default: throw UnknownReifyMode("Int::rel"); } break; case IRT_LQ: switch (r.mode()) { case RM_EQV: case RM_PMI: GECODE_ME_FAIL(y.one(home)); break; case RM_IMP: break; default: throw UnknownReifyMode("Int::rel"); } break; default: throw UnknownRelation("Int::rel"); } } else { throw NotZeroOne("Int::rel"); } } void rel(Home home, const BoolVarArgs& x, IntRelType irt, BoolVar y, IntPropLevel) { using namespace Int; GECODE_POST; switch (irt) { case IRT_EQ: for (int i=0; i ::post(home,x[i],y))); } break; case IRT_NQ: { NegBoolView n(y); for (int i=0; i ::post(home,x[i],n))); } } break; case IRT_GQ: for (int i=0; i::post(home,y,x[i])); } break; case IRT_LQ: for (int i=0; i::post(home,x[i],y)); } break; case IRT_GR: for (int i=0; i::post(home,y,x[i])); } break; case IRT_LE: for (int i=0; i::post(home,x[i],y)); } break; default: throw UnknownRelation("Int::rel"); } } void rel(Home home, const BoolVarArgs& x, IntRelType irt, int n, IntPropLevel) { using namespace Int; GECODE_POST; if (n == 0) { switch (irt) { case IRT_LQ: case IRT_EQ: for (int i=0; i y(home,x); GECODE_ES_FAIL(Bool::NaryEq::post(home,y)); } break; case IRT_NQ: { ViewArray y(home,x); GECODE_ES_FAIL((Rel::NaryNq::post(home,y))); } break; case IRT_LE: if (x.size() == 2) { GECODE_ES_FAIL(Bool::Le::post(home,x[0],x[1])); } else { home.fail(); } break; case IRT_LQ: { ViewArray y(home,x); GECODE_ES_FAIL(Bool::NaryLq::post(home,y)); } break; case IRT_GR: if (x.size() == 2) { GECODE_ES_FAIL(Bool::Le::post(home,x[1],x[0])); } else { home.fail(); } break; case IRT_GQ: { ViewArray y(home,x.size()); for (int i=0; i::post(home,y)); } break; default: throw UnknownRelation("Int::rel"); } } void rel(Home home, const BoolVarArgs& x, IntRelType irt, const BoolVarArgs& y, IntPropLevel) { using namespace Int; GECODE_POST; switch (irt) { case IRT_GR: { ViewArray xv(home,x), yv(home,y); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,yv,xv,true))); } break; case IRT_LE: { ViewArray xv(home,x), yv(home,y); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,xv,yv,true))); } break; case IRT_GQ: { ViewArray xv(home,x), yv(home,y); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,yv,xv,false))); } break; case IRT_LQ: { ViewArray xv(home,x), yv(home,y); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,xv,yv,false))); } break; case IRT_EQ: for (int i=0; i ::post(home,x[i],y[i]))); } break; case IRT_NQ: { ViewArray xv(home,x), yv(home,y); GECODE_ES_FAIL((Rel::LexNq ::post(home,xv,yv))); } break; default: throw UnknownRelation("Int::rel"); } } namespace { /// Return view array ViewArray viewarray(Space& home, const IntArgs& x) { ViewArray xv(home, x.size()); for (int i=0; i xv(home,x); ViewArray yv(viewarray(home,y)); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,yv,xv,true))); } break; case IRT_LE: { ViewArray xv(home,x); ViewArray yv(viewarray(home,y)); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,xv,yv,true))); } break; case IRT_GQ: { ViewArray xv(home,x); ViewArray yv(viewarray(home,y)); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,yv,xv,false))); } break; case IRT_LQ: { ViewArray xv(home,x); ViewArray yv(viewarray(home,y)); GECODE_ES_FAIL((Rel::LexLqLe ::post(home,xv,yv,false))); } break; case IRT_EQ: if (x.size() != y.size()) { home.fail(); } else { for (int i=0; i xv(home,x); ViewArray yv(viewarray(home,y)); GECODE_ES_FAIL((Rel::LexNq ::post(home,xv,yv))); } break; default: throw UnknownRelation("Int::rel"); } } void rel(Home home, const IntArgs& x, IntRelType irt, const BoolVarArgs& y, IntPropLevel ipl) { rel(home,y,irt,x,ipl); } void rel(Home home, BoolVar x0, BoolOpType o, BoolVar x1, BoolVar x2, IntPropLevel) { using namespace Int; GECODE_POST; switch (o) { case BOT_AND: { NegBoolView n0(x0); NegBoolView n1(x1); NegBoolView n2(x2); GECODE_ES_FAIL((Bool::Or ::post(home,n0,n1,n2))); } break; case BOT_OR: GECODE_ES_FAIL((Bool::Or ::post(home,x0,x1,x2))); break; case BOT_IMP: { NegBoolView n0(x0); GECODE_ES_FAIL((Bool::Or ::post(home,n0,x1,x2))); } break; case BOT_EQV: GECODE_ES_FAIL((Bool::Eqv ::post(home,x0,x1,x2))); break; case BOT_XOR: { NegBoolView n2(x2); GECODE_ES_FAIL((Bool::Eqv ::post(home,x0,x1,n2))); } break; default: throw UnknownOperation("Int::rel"); } } void rel(Home home, BoolVar x0, BoolOpType o, BoolVar x1, int n, IntPropLevel) { using namespace Int; GECODE_POST; if (n == 0) { switch (o) { case BOT_AND: { NegBoolView n0(x0); NegBoolView n1(x1); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,n0,n1))); } break; case BOT_OR: { BoolView b0(x0); BoolView b1(x1); GECODE_ME_FAIL(b0.zero(home)); GECODE_ME_FAIL(b1.zero(home)); } break; case BOT_IMP: { BoolView b0(x0); BoolView b1(x1); GECODE_ME_FAIL(b0.one(home)); GECODE_ME_FAIL(b1.zero(home)); } break; case BOT_EQV: { NegBoolView n0(x0); GECODE_ES_FAIL((Bool::Eq::post(home,n0,x1))); } break; case BOT_XOR: GECODE_ES_FAIL((Bool::Eq::post(home,x0,x1))); break; default: throw UnknownOperation("Int::rel"); } } else if (n == 1) { switch (o) { case BOT_AND: { BoolView b0(x0); BoolView b1(x1); GECODE_ME_FAIL(b0.one(home)); GECODE_ME_FAIL(b1.one(home)); } break; case BOT_OR: GECODE_ES_FAIL((Bool::BinOrTrue::post(home,x0,x1))); break; case BOT_IMP: { NegBoolView n0(x0); GECODE_ES_FAIL((Bool::BinOrTrue ::post(home,n0,x1))); } break; case BOT_EQV: GECODE_ES_FAIL((Bool::Eq::post(home,x0,x1))); break; case BOT_XOR: { NegBoolView n0(x0); GECODE_ES_FAIL((Bool::Eq::post(home,n0,x1))); } break; default: throw UnknownOperation("Int::rel"); } } else { throw NotZeroOne("Int::rel"); } } void rel(Home home, BoolOpType o, const BoolVarArgs& x, BoolVar y, IntPropLevel) { using namespace Int; GECODE_POST; int m = x.size(); Region r; switch (o) { case BOT_AND: { ViewArray b(home,m); for (int i=0; i ::post(home,b,ny))); } break; case BOT_OR: { ViewArray b(home,x); b.unique(); GECODE_ES_FAIL((Bool::NaryOr::post(home,b,y))); } break; case BOT_IMP: if (m < 2) { throw TooFewArguments("Int::rel"); } else { ViewArray a(home,x.size()-1); for (int i=x.size()-1; i--; ) a[i]=NegBoolView(x[i]); ViewArray b(home,1); b[0]=x[x.size()-1]; GECODE_ES_FAIL((Bool::Clause ::post(home,b,a,y))); } break; case BOT_EQV: { ViewArray xy(home, x.size() + 1); for (int i=0; i xy(home, x.size() + 1); for (int i=0; i 1)) throw NotZeroOne("Int::rel"); GECODE_POST; int m = x.size(); Region r; switch (o) { case BOT_AND: if (n == 0) { ViewArray b(home,m); for (int i=0; i::post(home,b)); } else { for (int i=0; i b(home,x); b.unique(); GECODE_ES_FAIL(Bool::NaryOrTrue::post(home,b)); } break; case BOT_IMP: if (m < 2) { throw TooFewArguments("Int::rel"); } else if (n == 0) { for (int i=m-1; i--; ) GECODE_ME_FAIL(BoolView(x[i]).one(home)); GECODE_ME_FAIL(BoolView(x[m-1]).zero(home)); } else { ViewArray a(home,x.size()-1); for (int i=x.size()-1; i--; ) a[i]=NegBoolView(x[i]); ViewArray b(home,1); b[0]=x[x.size()-1]; GECODE_ES_FAIL((Bool::ClauseTrue ::post(home,b,a))); } break; case BOT_EQV: { ViewArray b(home,x); GECODE_ES_FAIL(Bool::NaryEqv::post(home,b,n)); } break; case BOT_XOR: { ViewArray b(home,x); GECODE_ES_FAIL(Bool::NaryEqv::post(home,b,1^n)); } break; default: throw UnknownOperation("Int::rel"); } } void clause(Home home, BoolOpType o, const BoolVarArgs& x, const BoolVarArgs& y, int n, IntPropLevel) { using namespace Int; if ((n < 0) || (n > 1)) throw NotZeroOne("Int::rel"); GECODE_POST; switch (o) { case BOT_AND: if (n == 0) { ViewArray xv(home,x.size()); for (int i=0; i yv(home,y); xv.unique(); yv.unique(); GECODE_ES_FAIL((Bool::ClauseTrue ::post(home,xv,yv))); } else { for (int i=0; i xv(home,x); ViewArray yv(home,y.size()); for (int i=0; i ::post(home,xv,yv))); } break; default: throw IllegalOperation("Int::clause"); } } void clause(Home home, BoolOpType o, const BoolVarArgs& x, const BoolVarArgs& y, BoolVar z, IntPropLevel) { using namespace Int; GECODE_POST; switch (o) { case BOT_AND: { ViewArray xv(home,x.size()); for (int i=0; i yv(home,y); xv.unique(); yv.unique(); NegBoolView nz(z); GECODE_ES_FAIL((Bool::Clause ::post(home,xv,yv,nz))); } break; case BOT_OR: { ViewArray xv(home,x); ViewArray yv(home,y.size()); for (int i=0; i ::post(home,xv,yv,z))); } break; default: throw IllegalOperation("Int::clause"); } } void ite(Home home, BoolVar b, IntVar x, IntVar y, IntVar z, IntPropLevel ipl) { using namespace Int; GECODE_POST; if (vbd(ipl) == IPL_BND) { GECODE_ES_FAIL((Bool::IteBnd ::post(home,b,x,y,z))); } else { GECODE_ES_FAIL((Bool::IteDom ::post(home,b,x,y,z))); } } void ite(Home home, BoolVar b, BoolVar x, BoolVar y, BoolVar z, IntPropLevel) { using namespace Int; GECODE_POST; GECODE_ES_FAIL((Bool::IteBnd ::post(home,b,x,y,z))); } } // STATISTICS: int-post