/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte * Gabor Szokoli * * Copyright: * Christian Schulte, 2003 * Gabor Szokoli, 2003 * * Last modified: * $Date: 2008-01-31 18:29:16 +0100 (Thu, 31 Jan 2008) $ by $Author: tack $ * $Revision: 6017 $ * * 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. * */ namespace Gecode { namespace Int { namespace Rel { /* * Less or equal propagator * */ template forceinline Lq::Lq(Space* home, View x0, View x1) : BinaryPropagator(home,x0,x1) {} template ExecStatus Lq::post(Space* home, View x0, View x1) { GECODE_ME_CHECK(x0.lq(home,x1.max())); GECODE_ME_CHECK(x1.gq(home,x0.min())); if (!same(x0,x1) && (x0.max() > x1.min())) (void) new (home) Lq(home,x0,x1); return ES_OK; } template forceinline Lq::Lq(Space* home, bool share, Lq& p) : BinaryPropagator(home,share,p) {} template Actor* Lq::copy(Space* home, bool share) { return new (home) Lq(home,share,*this); } template inline Support::Symbol Lq::ati(void) { return Reflection::mangle("Gecode::Int::Rel::Lq"); } template Reflection::ActorSpec Lq::spec(const Space* home, Reflection::VarMap& m) const { return BinaryPropagator::spec(home, m, ati()); } template void Lq::post(Space* home, Reflection::VarMap& vars, const Reflection::ActorSpec& spec) { spec.checkArity(2); View x0(home, vars, spec[0]); View x1(home, vars, spec[1]); (void) new (home) Lq(home, x0, x1); } template ExecStatus Lq::propagate(Space* home, ModEventDelta) { GECODE_ME_CHECK(x0.lq(home,x1.max())); GECODE_ME_CHECK(x1.gq(home,x0.min())); return (x0.max() <= x1.min()) ? ES_SUBSUMED(this,home) : ES_FIX; } /* * Less propagator * */ template forceinline Le::Le(Space* home, View x0, View x1) : BinaryPropagator(home,x0,x1) {} template ExecStatus Le::post(Space* home, View x0, View x1) { if (same(x0,x1)) return ES_FAILED; GECODE_ME_CHECK(x0.le(home,x1.max())); GECODE_ME_CHECK(x1.gr(home,x0.min())); if (x0.max() >= x1.min()) (void) new (home) Le(home,x0,x1); return ES_OK; } template forceinline Le::Le(Space* home, bool share, Le& p) : BinaryPropagator(home,share,p) {} template Actor* Le::copy(Space* home, bool share) { return new (home) Le(home,share,*this); } template inline Support::Symbol Le::ati(void) { return Reflection::mangle("Gecode::Int::Rel::Le"); } template Reflection::ActorSpec Le::spec(const Space* home, Reflection::VarMap& m) const { return BinaryPropagator ::spec(home, m, ati()); } template void Le::post(Space* home, Reflection::VarMap& vars, const Reflection::ActorSpec& spec) { spec.checkArity(2); View x0(home, vars, spec[0]); View x1(home, vars, spec[1]); (void) new (home) Le(home, x0, x1); } template ExecStatus Le::propagate(Space* home, ModEventDelta) { GECODE_ME_CHECK(x0.le(home,x1.max())); GECODE_ME_CHECK(x1.gr(home,x0.min())); return (x0.max() < x1.min()) ? ES_SUBSUMED(this,home) : ES_FIX; } /* * Reified less or equal propagator * */ template forceinline ReLq::ReLq(Space* home, View x0, View x1, CtrlView b) : ReBinaryPropagator(home,x0,x1,b) {} template ExecStatus ReLq::post(Space* home, View x0, View x1, CtrlView b) { if (b.one()) return Lq::post(home,x0,x1); if (b.zero()) return Le::post(home,x1,x0); if (!same(x0,x1)) { switch (rtest_lq(x0,x1)) { case RT_TRUE: GECODE_ME_CHECK(b.one_none(home)); break; case RT_FALSE: GECODE_ME_CHECK(b.zero_none(home)); break; case RT_MAYBE: (void) new (home) ReLq(home,x0,x1,b); break; default: GECODE_NEVER; } } else { GECODE_ME_CHECK(b.one_none(home)); } return ES_OK; } template forceinline ReLq::ReLq(Space* home, bool share, ReLq& p) : ReBinaryPropagator(home,share,p) {} template Actor* ReLq::copy(Space* home, bool share) { return new (home) ReLq(home,share,*this); } template inline Support::Symbol ReLq::ati(void) { return Reflection::mangle("Gecode::Int::Rel::ReLq"); } template Reflection::ActorSpec ReLq::spec(const Space* home, Reflection::VarMap& m) const { return ReBinaryPropagator::spec(home, m, ati()); } template void ReLq::post(Space* home, Reflection::VarMap& vars, const Reflection::ActorSpec& spec) { spec.checkArity(3); View x0(home, vars, spec[0]); View x1(home, vars, spec[1]); CtrlView b(home, vars, spec[2]); (void) new (home) ReLq(home, x0, x1, b); } template ExecStatus ReLq::propagate(Space* home, ModEventDelta) { if (b.one()) GECODE_REWRITE(this,Lq::post(home,x0,x1)); if (b.zero()) GECODE_REWRITE(this,Le::post(home,x1,x0)); switch (rtest_lq(x0,x1)) { case RT_TRUE: GECODE_ME_CHECK(b.one_none(home)); return ES_SUBSUMED(this,home); case RT_FALSE: GECODE_ME_CHECK(b.zero_none(home)); return ES_SUBSUMED(this,home); case RT_MAYBE: break; default: GECODE_NEVER; } return ES_FIX; } /* * Reified less or equal propagator involving one variable * */ template forceinline ReLqInt::ReLqInt(Space* home, View x, int c0, CtrlView b) : ReUnaryPropagator(home,x,b), c(c0) {} template ExecStatus ReLqInt::post(Space* home, View x, int c, CtrlView b) { if (b.one()) { GECODE_ME_CHECK(x.lq(home,c)); } else if (b.zero()) { GECODE_ME_CHECK(x.gr(home,c)); } else { switch (rtest_lq(x,c)) { case RT_TRUE: GECODE_ME_CHECK(b.one_none(home)); break; case RT_FALSE: GECODE_ME_CHECK(b.zero_none(home)); break; case RT_MAYBE: (void) new (home) ReLqInt(home,x,c,b); break; default: GECODE_NEVER; } } return ES_OK; } template forceinline ReLqInt::ReLqInt(Space* home, bool share, ReLqInt& p) : ReUnaryPropagator(home,share,p), c(p.c) {} template Actor* ReLqInt::copy(Space* home, bool share) { return new (home) ReLqInt(home,share,*this); } template inline Support::Symbol ReLqInt::ati(void) { return Reflection::mangle("Gecode::Int::Rel::ReLqInt"); } template Reflection::ActorSpec ReLqInt::spec(const Space* home, Reflection::VarMap& m) const { return ReUnaryPropagator ::spec(home, m, ati()) << c; } template void ReLqInt::post(Space* home, Reflection::VarMap& vars, const Reflection::ActorSpec& spec) { spec.checkArity(3); View x0(home, vars, spec[0]); CtrlView b(home, vars, spec[1]); int c = spec[2]->toInt(); (void) new (home) ReLqInt(home, x0, c, b); } template ExecStatus ReLqInt::propagate(Space* home, ModEventDelta) { if (b.one()) { GECODE_ME_CHECK(x0.lq(home,c)); goto subsumed; } if (b.zero()) { GECODE_ME_CHECK(x0.gr(home,c)); goto subsumed; } switch (rtest_lq(x0,c)) { case RT_TRUE: GECODE_ME_CHECK(b.one_none(home)); goto subsumed; case RT_FALSE: GECODE_ME_CHECK(b.zero_none(home)); goto subsumed; case RT_MAYBE: break; default: GECODE_NEVER; } return ES_FIX; subsumed: return ES_SUBSUMED(this,home); } }}} // STATISTICS: int-prop