Generated on Mon Jul 6 18:09:04 2009 for Gecode by doxygen 1.5.9

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: 2009-02-03 11:13:22 +0100 (Tue, 03 Feb 2009) $ by $Author: schulte $
00015  *     $Revision: 8129 $
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(Space& 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     if (!ts()->finalized()) ts()->finalize();
00056     init_last(home, ts()->last);
00057 
00058     home.notice(*this,AP_DISPOSE);
00059   }
00060 
00061   template <class View, bool subscribe>
00062   forceinline
00063   Base<View,subscribe>::Base(Space& home, bool share, Base<View,subscribe>& p)
00064     : Propagator(home,share,p), last_data(NULL) {
00065     x.update(home, share, p.x);
00066     tupleSet.update(home, share, p.tupleSet);
00067 
00068     init_last(home, p.last_data);
00069   }
00070 
00071   template <class View, bool subscribe>
00072   forceinline void
00073   Base<View,subscribe>::init_last(Space& home, Tuple** source) {
00074     if (last_data == NULL) {
00075       int literals = ts()->domsize*x.size();
00076       last_data = home.alloc<Tuple*>(literals);
00077       for (int i = literals; i--; )
00078         last_data[i] = source[i];
00079     }
00080   }
00081 
00082   template <class View, bool subscribe>
00083   forceinline TupleSet::TupleSetI*
00084   Base<View,subscribe>::ts(void) {
00085     return tupleSet.implementation();
00086   }
00087 
00088   template <class View, bool subscribe>
00089   PropCost
00090   Base<View,subscribe>::cost(const Space&, const ModEventDelta&) const {
00091     return PropCost::quadratic(PropCost::HI,x.size());
00092   }
00093 
00094 #define GECODE_LAST_TUPLE(l) (*(l))
00095 
00096   template <class View, bool subscribe>
00097   forceinline Tuple
00098   Base<View,subscribe>::last(int i, int n) {
00099     return GECODE_LAST_TUPLE(last_data[(i*ts()->domsize) + n]);
00100   }
00101 
00102   template <class View, bool subscribe>
00103   forceinline Tuple
00104   Base<View,subscribe>::last_next(int i, int n) {
00105     assert(last(i,n) != NULL);
00106     assert(last(i,n)[i] == n+ts()->min);
00107     int pos = (i*ts()->domsize) + n;
00108     ++(last_data[pos]);
00109     if (last(i,n)[i] != (n+ts()->min))
00110       last_data[pos] = ts()->nullptr;
00111     return last(i,n);
00112   }
00113 
00114 
00115   template <class View, bool subscribe>
00116   forceinline void
00117   Base<View,subscribe>::init_dom(Space& home, Domain dom) {
00118     int domsize = ts()->domsize;
00119     for (int i = x.size(); i--; ) {
00120       dom[i].init(home, domsize);
00121       for (ViewValues<View> vv(x[i]); vv(); ++vv)
00122         dom[i].set(vv.val()-ts()->min);
00123     }
00124   }
00125 
00126   template <class View, bool subscribe>
00127   forceinline bool
00128   Base<View,subscribe>::valid(Tuple t, Domain dom) {
00129     for (int i = x.size(); i--; )
00130       if (!dom[i].get(t[i]-ts()->min))
00131         return false;
00132     return true;
00133   }
00134 #undef GECODE_LAST_TUPLE
00135   template <class View, bool subscribe>
00136   forceinline Tuple
00137   Base<View,subscribe>::find_support(Domain dom, int i, int n) {
00138     Tuple l = last(i,n);
00139     while ((l != NULL) && !valid(l, dom))
00140       l = last_next(i,n);
00141     return l;
00142   }
00143 
00144 
00145   template <class View, bool subscribe>
00146   size_t
00147   Base<View,subscribe>::dispose(Space& home) {
00148     home.ignore(*this,AP_DISPOSE);
00149     (void) Propagator::dispose(home);
00150     if (!home.failed()) {
00151       if (subscribe)
00152         x.cancel(home,*this,PC_INT_DOM);
00153       // take care of last_data
00154       int literals = ts()->domsize*x.size();
00155       home.rfree(last_data, sizeof(Tuple*)*literals);
00156     }
00157     (void) tupleSet.~TupleSet();
00158     return sizeof(*this);
00159   }
00160 }}}
00161 
00162 // STATISTICS: int-prop
00163