Generated on Thu Mar 22 10:39:34 2012 for Gecode by doxygen 1.6.3

base.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00005  *
00006  *  Contributing authors:
00007  *     Christian Schulte <schulte@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Mikael Lagerkvist, 2007
00011  *     Christian Schulte, 2008
00012  *
00013  *  Last modified:
00014  *     $Date: 2010-07-14 17:46:18 +0200 (Wed, 14 Jul 2010) $ by $Author: schulte $
00015  *     $Revision: 11192 $
00016  *
00017  *  This file is part of Gecode, the generic constraint
00018  *  development environment:
00019  *     http://www.gecode.org
00020  *
00021  *  Permission is hereby granted, free of charge, to any person obtaining
00022  *  a copy of this software and associated documentation files (the
00023  *  "Software"), to deal in the Software without restriction, including
00024  *  without limitation the rights to use, copy, modify, merge, publish,
00025  *  distribute, sublicense, and/or sell copies of the Software, and to
00026  *  permit persons to whom the Software is furnished to do so, subject to
00027  *  the following conditions:
00028  *
00029  *  The above copyright notice and this permission notice shall be
00030  *  included in all copies or substantial portions of the Software.
00031  *
00032  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00033  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00034  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00035  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00036  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00037  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00038  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00039  *
00040  */
00041 namespace Gecode { namespace Int { namespace Extensional {
00042   /*
00043    * The propagator proper
00044    *
00045    */
00046 
00047   template<class View, bool subscribe>
00048   forceinline
00049   Base<View,subscribe>::Base(Home home, ViewArray<View>& x0,
00050                              const TupleSet& t)
00051     : Propagator(home), x(x0), tupleSet(t), last_data(NULL) {
00052     if (subscribe)
00053       x.subscribe(home, *this, PC_INT_DOM);
00054 
00055     assert(ts()->finalized());
00056 
00057     init_last(home, ts()->last);
00058 
00059     home.notice(*this,AP_DISPOSE);
00060   }
00061 
00062   template<class View, bool subscribe>
00063   forceinline
00064   Base<View,subscribe>::Base(Space& home, bool share, Base<View,subscribe>& p)
00065     : Propagator(home,share,p), last_data(NULL) {
00066     x.update(home, share, p.x);
00067     tupleSet.update(home, share, p.tupleSet);
00068 
00069     init_last(home, p.last_data);
00070   }
00071 
00072   template<class View, bool subscribe>
00073   forceinline void
00074   Base<View,subscribe>::init_last(Space& home, Tuple** source) {
00075     if (last_data == NULL) {
00076       int literals = static_cast<int>(ts()->domsize*x.size());
00077       last_data = home.alloc<Tuple*>(literals);
00078       for (int i = literals; i--; )
00079         last_data[i] = source[i];
00080     }
00081   }
00082 
00083   template<class View, bool subscribe>
00084   forceinline TupleSet::TupleSetI*
00085   Base<View,subscribe>::ts(void) {
00086     return tupleSet.implementation();
00087   }
00088 
00089   template<class View, bool subscribe>
00090   PropCost
00091   Base<View,subscribe>::cost(const Space&, const ModEventDelta&) const {
00092     return PropCost::quadratic(PropCost::HI,x.size());
00093   }
00094 
00095 #define GECODE_LAST_TUPLE(l) (*(l))
00096 
00097   template<class View, bool subscribe>
00098   forceinline Tuple
00099   Base<View,subscribe>::last(int i, int n) {
00100     return GECODE_LAST_TUPLE(last_data[(i*ts()->domsize) + n]);
00101   }
00102 
00103   template<class View, bool subscribe>
00104   forceinline Tuple
00105   Base<View,subscribe>::last_next(int i, int n) {
00106     assert(last(i,n) != NULL);
00107     assert(last(i,n)[i] == n+ts()->min);
00108     int pos = (i*static_cast<int>(ts()->domsize)) + n;
00109     ++(last_data[pos]);
00110     if (last(i,n)[i] != (n+ts()->min))
00111       last_data[pos] = ts()->nullpointer;
00112     return last(i,n);
00113   }
00114 
00115 
00116   template<class View, bool subscribe>
00117   forceinline void
00118   Base<View,subscribe>::init_dom(Space& home, Domain dom) {
00119     unsigned int domsize = ts()->domsize;
00120     for (int i = x.size(); i--; ) {
00121       dom[i].init(home, domsize);
00122       for (ViewValues<View> vv(x[i]); vv(); ++vv)
00123         dom[i].set(static_cast<unsigned int>(vv.val()-ts()->min));
00124     }
00125   }
00126 
00127   template<class View, bool subscribe>
00128   forceinline bool
00129   Base<View,subscribe>::valid(Tuple t, Domain dom) {
00130     for (int i = x.size(); i--; )
00131       if (!dom[i].get(static_cast<unsigned int>(t[i]-ts()->min)))
00132         return false;
00133     return true;
00134   }
00135 #undef GECODE_LAST_TUPLE
00136   template<class View, bool subscribe>
00137   forceinline Tuple
00138   Base<View,subscribe>::find_support(Domain dom, int i, int n) {
00139     Tuple l = last(i,n);
00140     while ((l != NULL) && !valid(l, dom))
00141       l = last_next(i,n);
00142     return l;
00143   }
00144 
00145 
00146   template<class View, bool subscribe>
00147   forceinline size_t
00148   Base<View,subscribe>::dispose(Space& home) {
00149     home.ignore(*this,AP_DISPOSE);
00150     (void) Propagator::dispose(home);
00151     if (subscribe)
00152       x.cancel(home,*this,PC_INT_DOM);
00153     // take care of last_data
00154     unsigned int literals = ts()->domsize*x.size();
00155     home.rfree(last_data, sizeof(Tuple*)*literals);
00156     (void) tupleSet.~TupleSet();
00157     return sizeof(*this);
00158   }
00159 
00160 }}}
00161 
00162 // STATISTICS: int-prop
00163