Generated on Tue Apr 18 10:21:48 2017 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: 2016-06-29 17:28:17 +0200 (Wed, 29 Jun 2016) $ by $Author: schulte $
00015  *     $Revision: 15137 $
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, ts()->tuple_data);
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, p.ts()->tuple_data);
00070   }
00071 
00072   template<class View, bool subscribe>
00073   forceinline void
00074   Base<View,subscribe>::init_last(Space& home, Tuple** source, Tuple* base) {
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] = ts()->tuple_data+(source[i]-base);
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   void
00091   Base<View,subscribe>::reschedule(Space& home) {
00092     if (subscribe)
00093       x.reschedule(home, *this, PC_INT_DOM);
00094   }
00095 
00096   template<class View, bool subscribe>
00097   PropCost
00098   Base<View,subscribe>::cost(const Space&, const ModEventDelta&) const {
00099     return PropCost::quadratic(PropCost::HI,x.size());
00100   }
00101 
00102 #define GECODE_LAST_TUPLE(l) (*(l))
00103 
00104   template<class View, bool subscribe>
00105   forceinline Tuple
00106   Base<View,subscribe>::last(int i, int n) {
00107     return GECODE_LAST_TUPLE(last_data[(i*ts()->domsize) + n]);
00108   }
00109 
00110   template<class View, bool subscribe>
00111   forceinline Tuple
00112   Base<View,subscribe>::last_next(int i, int n) {
00113     assert(last(i,n) != NULL);
00114     assert(last(i,n)[i] == n+ts()->min);
00115     int pos = (i*static_cast<int>(ts()->domsize)) + n;
00116     ++(last_data[pos]);
00117     if (last(i,n)[i] != (n+ts()->min))
00118       last_data[pos] = ts()->nullpointer;
00119     return last(i,n);
00120   }
00121 
00122 
00123   template<class View, bool subscribe>
00124   forceinline void
00125   Base<View,subscribe>::init_dom(Space& home, Domain dom) {
00126     unsigned int domsize = ts()->domsize;
00127     for (int i = x.size(); i--; ) {
00128       dom[i].init(home, domsize);
00129       for (ViewValues<View> vv(x[i]); vv(); ++vv)
00130         dom[i].set(static_cast<unsigned int>(vv.val()-ts()->min));
00131     }
00132   }
00133 
00134   template<class View, bool subscribe>
00135   forceinline bool
00136   Base<View,subscribe>::valid(Tuple t, Domain dom) {
00137     for (int i = x.size(); i--; )
00138       if (!dom[i].get(static_cast<unsigned int>(t[i]-ts()->min)))
00139         return false;
00140     return true;
00141   }
00142 #undef GECODE_LAST_TUPLE
00143   template<class View, bool subscribe>
00144   forceinline Tuple
00145   Base<View,subscribe>::find_support(Domain dom, int i, int n) {
00146     Tuple l = last(i,n);
00147     while ((l != NULL) && !valid(l, dom))
00148       l = last_next(i,n);
00149     return l;
00150   }
00151 
00152 
00153   template<class View, bool subscribe>
00154   forceinline size_t
00155   Base<View,subscribe>::dispose(Space& home) {
00156     home.ignore(*this,AP_DISPOSE);
00157     (void) Propagator::dispose(home);
00158     if (subscribe)
00159       x.cancel(home,*this,PC_INT_DOM);
00160     // take care of last_data
00161     unsigned int literals = ts()->domsize*x.size();
00162     home.rfree(last_data, sizeof(Tuple*)*literals);
00163     (void) tupleSet.~TupleSet();
00164     return sizeof(*this);
00165   }
00166 
00167 }}}
00168 
00169 // STATISTICS: int-prop
00170