/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte * * Copyright: * Christian Schulte, 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 { template inline Lex::Lex(Space* home, ViewArray >& xy, bool s) : NaryPropagator,PC_INT_BND>(home,xy), strict(s) {} template forceinline Lex::Lex(Space* home, bool share, Lex& p) : NaryPropagator,PC_INT_BND>(home,share,p), strict(p.strict) {} template Actor* Lex::copy(Space* home, bool share) { return new (home) Lex(home,share,*this); } template inline Support::Symbol Lex::ati(void) { return Reflection::mangle("Gecode::Int::Rel::Lex"); } template Reflection::ActorSpec Lex::spec(const Space* home, Reflection::VarMap& m) const { return NaryPropagator,PC_INT_BND> ::spec(home, m, ati()) << strict; } template void Lex::post(Space* home, Reflection::VarMap& vars, const Reflection::ActorSpec& spec) { spec.checkArity(2); ViewArray > x(home, vars, spec[0]); bool strict = spec[1]->toInt(); (void) new (home) Lex(home, x, strict); } template ExecStatus Lex::propagate(Space* home, ModEventDelta) { /* * State 1 * */ { int i = 0; int n = x.size(); while ((i < n) && (x[i][0].min() == x[i][1].max())) { // case: =, >= GECODE_ME_CHECK(x[i][0].lq(home,x[i][1].max())); GECODE_ME_CHECK(x[i][1].gq(home,x[i][0].min())); i++; } if (i == n) // case: $ return strict ? ES_FAILED : ES_SUBSUMED(this,sizeof(*this)); // Possible cases left: <, <=, > (yields failure), ? GECODE_ME_CHECK(x[i][0].lq(home,x[i][1].max())); GECODE_ME_CHECK(x[i][1].gq(home,x[i][0].min())); if (x[i][0].max() < x[i][1].min()) // case: < (after tell) return ES_SUBSUMED(this,home); // x[i][0] can never be equal to x[i][1] (otherwise: >=) assert(!(x[i][0].assigned() && x[i][1].assigned() && x[i][0].val() == x[i][1].val())); // Remove all elements between 0...i-1 as they are assigned and equal x.drop_fst(i); // After this, execution continues at [1] } /* * State 2 * prefix: (?|<=) * */ { int i = 1; int n = x.size(); while ((i < n) && (x[i][0].min() == x[i][1].max()) && (x[i][0].max() == x[i][1].min())) { // case: = assert(x[i][0].assigned() && x[i][1].assigned() && (x[i][0].val() == x[i][1].val())); i++; } if (i == n) { // case: $ if (strict) goto rewrite_le; else goto rewrite_lq; } if (x[i][0].max() < x[i][1].min()) // case: < goto rewrite_lq; if (x[i][0].min() > x[i][1].max()) // case: > goto rewrite_le; if (i > 1) { // Remove equal elements [1...i-1], keep element [0] x[i-1]=x[0]; x.drop_fst(i-1); } } if (x[1][0].max() <= x[1][1].min()) { // case: <= (invariant: not =, <) /* * State 3 * prefix: (?|<=),<= * */ int i = 2; int n = x.size(); while ((i < n) && (x[i][0].max() == x[i][1].min())) // case: <=, = i++; if (i == n) { // case: $ if (strict) return ES_FIX; else goto rewrite_lq; } if (x[i][0].max() < x[i][1].min()) // case: < goto rewrite_lq; if (x[i][0].min() > x[i][1].max()) { // case: > // Eliminate [i]...[n-1] for (int j=i; j= x[1][1].max()) { // case: >= (invariant: not =, >) /* * State 4 * prefix: (?|<=) >= * */ int i = 2; int n = x.size(); while ((i < n) && (x[i][0].min() == x[i][1].max())) // case: >=, = i++; if (i == n) { // case: $ if (strict) goto rewrite_le; else return ES_FIX; } if (x[i][0].min() > x[i][1].max()) // case: > goto rewrite_le; if (x[i][0].max() < x[i][1].min()) { // case: < // Eliminate [i]...[n-1] for (int j=i; j::post(home,x[0][0],x[0][1])); rewrite_lq: GECODE_REWRITE(this,Lq::post(home,x[0][0],x[0][1])); } template ExecStatus Lex::post(Space* home, ViewArray >& xy, bool strict){ if (xy.size() == 0) return strict ? ES_FAILED : ES_OK; if (xy.size() == 1) if (strict) return Le::post(home,xy[0][0],xy[0][1]); else return Lq::post(home,xy[0][0],xy[0][1]); (void) new (home) Lex(home,xy,strict); return ES_OK; } }}} // STATISTICS: int-prop