/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte * * Copyright: * Christian Schulte, 2011 * * Last modified: * $Date: 2011-08-13 22:25:20 +1000 (Sat, 13 Aug 2011) $ by $Author: schulte $ * $Revision: 12288 $ * * 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 namespace Gecode { namespace Int { namespace NValues { template forceinline GqBool::GqBool(Home home, int status, ViewArray& x, VY y) : BoolBase(home,status,x,y) {} template forceinline GqBool::GqBool(Space& home, bool share, GqBool& p) : BoolBase(home,share,p) {} template Actor* GqBool::copy(Space& home, bool share) { return new (home) GqBool(home,share,*this); } template inline ExecStatus GqBool::post(Home home, ViewArray& x, VY y) { if (x.size() == 0) { GECODE_ME_CHECK(y.lq(home,0)); return ES_OK; } x.unique(home); if (x.size() == 1) { GECODE_ME_CHECK(y.lq(home,1)); return ES_OK; } GECODE_ME_CHECK(y.lq(home,2)); if (y.max() <= 1) return ES_OK; if (y.min() == 2) { assert(y.assigned()); ViewArray xc(home,x); return Rel::NaryNq::post(home,xc); } int n = x.size(); int status = 0; for (int i=n; i--; ) if (x[i].zero()) { if (status & VS_ONE) return ES_OK; x[i] = x[--n]; status |= VS_ZERO; } else if (x[i].one()) { if (status & VS_ZERO) return ES_OK; x[i] = x[--n]; status |= VS_ONE; } assert(status != (VS_ZERO | VS_ONE)); if (n == 0) { assert(status != 0); GECODE_ME_CHECK(y.lq(home,1)); return ES_OK; } x.size(n); (void) new (home) GqBool(home,status,x,y); return ES_OK; } template ExecStatus GqBool::propagate(Space& home, const ModEventDelta&) { if (status == (VS_ZERO | VS_ONE)) return home.ES_SUBSUMED(*this); if (c.empty()) { assert(status != 0); GECODE_ME_CHECK(y.lq(home,1)); return home.ES_SUBSUMED(*this); } if (y.max() <= 1) return home.ES_SUBSUMED(*this); if (y.min() == 2) { Advisors > as(c); assert(as()); ViewAdvisor& a(as.advisor()); ++as; if (!as()) { // Only a single view is left if (status == VS_ZERO) { GECODE_ME_CHECK(a.view().one(home)); } else if (status == VS_ONE) { GECODE_ME_CHECK(a.view().zero(home)); } else { return ES_FAILED; } return home.ES_SUBSUMED(*this); } } return ES_FIX; } }}} // STATISTICS: int-prop