Generated on Mon Aug 25 11:35:35 2008 for Gecode by doxygen 1.5.6

base.icc

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