00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 namespace Gecode { namespace Int { namespace Extensional {
00038
00039
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
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
00160