/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Patrick Pekczynski * Guido Tack * * Contributing authors: * Christian Schulte * * Copyright: * Patrick Pekczynski, 2004 * Christian Schulte, 2009 * Guido Tack, 2006 * * 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 { /// Comparison operator template struct LessP { bool operator ()(const std::pair& lhs, const std::pair& rhs) { return lhs.second < rhs.second; } }; /// Make \a x and \a y equal IntVar unify(Home home, IntVar x, IntVar y) { rel(home, x, IRT_EQ, y); return x; } /// Make \a x and \a y equal IntSet unify(Home, const IntSet& x, const IntSet& y) { IntSetRanges xr(x); IntSetRanges yr(y); Iter::Ranges::Inter i(xr,yr); IntSet z(i); return z; } /// Remove dupliate entries in \a v from both \a v and \a c template void removeDuplicates(Home home, A& c, IntArgs& v) { typedef typename A::value_type S; typedef std::pair P; Region re; P* a = re.alloc

(c.size()); for (int i=0; i l; Support::quicksort(a,c.size(),l); A cc; IntArgs vv; int cur = a[0].second-1; for (int i=0; i(a,c.size()); c = cc; v = vv; } } void count(Home home, const IntVarArgs& x, const IntVarArgs& _c, const IntArgs& _v, IntPropLevel ipl) { using namespace Int; IntVarArgs c(_c); IntArgs v(_v); if (v.size() != c.size()) throw ArgumentSizeMismatch("Int::count"); if (same(x)) throw ArgumentSame("Int::count"); GECODE_POST; removeDuplicates(home,c,v); ViewArray xv(home, x); ViewArray cv(home, c.size()); // set the cardinality for (int i=0; i::post(home,xv,cv))); break; case IPL_DOM: GECODE_ES_FAIL( (GCC::Dom::post(home,xv,cv))); break; default: GECODE_ES_FAIL( (GCC::Val::post(home,xv,cv))); } } // domain is 0..|cards|- 1 void count(Home home, const IntVarArgs& x, const IntVarArgs& c, IntPropLevel ipl) { IntArgs values(c.size()); for (int i=0; i xv(home, x); for (int i=0; i 1) { // Found hole, so create temporary variables ViewArray cv(home, v.size()); for (int j=0; j::post(home, xv, cv))); break; case IPL_DOM: GECODE_ES_FAIL( (GCC::Dom::post(home, xv, cv))); break; default: GECODE_ES_FAIL( (GCC::Val::post(home, xv, cv))); } return; } } // No holes: create CardConsts ViewArray cv(home, c.size()); for (int i=0; i::post(home, xv, cv))); break; case IPL_DOM: GECODE_ES_FAIL( (GCC::Dom::post(home, xv, cv))); break; default: GECODE_ES_FAIL( (GCC::Val::post(home, xv, cv))); } } // domain is 0..|cards|- 1 void count(Home home, const IntVarArgs& x, const IntSetArgs& c, IntPropLevel ipl) { IntArgs values(c.size()); for (int i=0; i