/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Mikael Lagerkvist * * Contributing authors: * Christian Schulte * * Copyright: * Mikael Lagerkvist, 2007 * Christian Schulte, 2008 * * Last modified: * $Date: 2010-07-15 01:46:18 +1000 (Thu, 15 Jul 2010) $ by $Author: schulte $ * $Revision: 11192 $ * * 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 Extensional { /* * The propagator proper * */ template forceinline Base::Base(Home home, ViewArray& x0, const TupleSet& t) : Propagator(home), x(x0), tupleSet(t), last_data(NULL) { if (subscribe) x.subscribe(home, *this, PC_INT_DOM); assert(ts()->finalized()); init_last(home, ts()->last); home.notice(*this,AP_DISPOSE); } template forceinline Base::Base(Space& home, bool share, Base& p) : Propagator(home,share,p), last_data(NULL) { x.update(home, share, p.x); tupleSet.update(home, share, p.tupleSet); init_last(home, p.last_data); } template forceinline void Base::init_last(Space& home, Tuple** source) { if (last_data == NULL) { int literals = static_cast(ts()->domsize*x.size()); last_data = home.alloc(literals); for (int i = literals; i--; ) last_data[i] = source[i]; } } template forceinline TupleSet::TupleSetI* Base::ts(void) { return tupleSet.implementation(); } template PropCost Base::cost(const Space&, const ModEventDelta&) const { return PropCost::quadratic(PropCost::HI,x.size()); } #define GECODE_LAST_TUPLE(l) (*(l)) template forceinline Tuple Base::last(int i, int n) { return GECODE_LAST_TUPLE(last_data[(i*ts()->domsize) + n]); } template forceinline Tuple Base::last_next(int i, int n) { assert(last(i,n) != NULL); assert(last(i,n)[i] == n+ts()->min); int pos = (i*static_cast(ts()->domsize)) + n; ++(last_data[pos]); if (last(i,n)[i] != (n+ts()->min)) last_data[pos] = ts()->nullpointer; return last(i,n); } template forceinline void Base::init_dom(Space& home, Domain dom) { unsigned int domsize = ts()->domsize; for (int i = x.size(); i--; ) { dom[i].init(home, domsize); for (ViewValues vv(x[i]); vv(); ++vv) dom[i].set(static_cast(vv.val()-ts()->min)); } } template forceinline bool Base::valid(Tuple t, Domain dom) { for (int i = x.size(); i--; ) if (!dom[i].get(static_cast(t[i]-ts()->min))) return false; return true; } #undef GECODE_LAST_TUPLE template forceinline Tuple Base::find_support(Domain dom, int i, int n) { Tuple l = last(i,n); while ((l != NULL) && !valid(l, dom)) l = last_next(i,n); return l; } template forceinline size_t Base::dispose(Space& home) { home.ignore(*this,AP_DISPOSE); (void) Propagator::dispose(home); if (subscribe) x.cancel(home,*this,PC_INT_DOM); // take care of last_data unsigned int literals = ts()->domsize*x.size(); home.rfree(last_data, sizeof(Tuple*)*literals); (void) tupleSet.~TupleSet(); return sizeof(*this); } }}} // STATISTICS: int-prop