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 namespace Gecode {
00035
00040 enum TraceEvent {
00042
00043 TE_INIT = 1 << 0,
00044 TE_PRUNE = 1 << 1,
00045 TE_FIX = 1 << 2,
00046 TE_FAIL = 1 << 3,
00047 TE_DONE = 1 << 4,
00048
00049
00050 TE_PROPAGATE = 1 << 5,
00051 TE_COMMIT = 1 << 6
00052 };
00053
00058 template<class View>
00059 class ViewTraceRecorder : public Propagator {
00060 public:
00062 typedef typename TraceTraits<View>::TraceView TraceView;
00064 typedef typename TraceTraits<View>::TraceDelta TraceDelta;
00066 typedef typename TraceTraits<View>::SlackValue SlackValue;
00068 class Slack {
00069 template<class ViewForTraceRecorder> friend class ViewTraceRecorder;
00070 protected:
00072 SlackValue i;
00074 SlackValue p;
00076 SlackValue c;
00077 public:
00079 SlackValue initial(void) const;
00081 SlackValue previous(void) const;
00083 SlackValue current(void) const;
00084 };
00085 protected:
00087 class Idx : public Advisor {
00088 protected:
00090 int _idx;
00091 public:
00093 Idx(Space& home, Propagator& p, Council<Idx>& c, int i);
00095 Idx(Space& home, Idx& a);
00097 int idx(void) const;
00098 };
00100 ViewArray<TraceView> o;
00102 ViewArray<View> n;
00104 Council<Idx> c;
00106 TraceFilter tf;
00108 int te;
00110 ViewTracer<View>& t;
00112 Slack s;
00114 ViewTraceRecorder(Space& home, ViewTraceRecorder& p);
00115 public:
00117 ViewTraceRecorder(Home home, ViewArray<View>& x,
00118 TraceFilter tf, int te, ViewTracer<View>& t);
00120 virtual Propagator* copy(Space& home);
00122 virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00124 virtual void reschedule(Space& home);
00126 virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00128 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00130 virtual size_t dispose(Space& home);
00132 static ExecStatus post(Home home, ViewArray<View>& x,
00133 TraceFilter tf, int te, ViewTracer<View>& t);
00135
00136
00137 const typename View::VarType operator [](int i) const;
00139 int size(void) const;
00141 const Slack& slack(void) const;
00143 };
00144
00153 class TraceRecorder : public Propagator {
00154 public:
00156 TraceFilter tf;
00158 int te;
00160 Tracer& t;
00162 TraceRecorder(Space& home, TraceRecorder& p);
00163 public:
00165 TraceRecorder(Home home, TraceFilter tf, int te, Tracer& t);
00167 virtual Propagator* copy(Space& home);
00169 virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00171 virtual void reschedule(Space& home);
00173 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00175 virtual size_t dispose(Space& home);
00177 static ExecStatus post(Home home, TraceFilter tf, int te, Tracer& t);
00179
00180
00181 const TraceFilter& filter(void) const;
00183 int events(void) const;
00185 Tracer& tracer(void) const;
00187 };
00188
00189
00190
00191
00192
00193
00194 template<class View>
00195 forceinline const typename View::VarType
00196 ViewTraceRecorder<View>::operator [](int i) const {
00197 const typename View::VarType x(n[i].varimp());
00198 return x;
00199 }
00200 template<class View>
00201 forceinline int
00202 ViewTraceRecorder<View>::size(void) const {
00203 return n.size();
00204 }
00205 template<class View>
00206 forceinline const typename ViewTraceRecorder<View>::Slack&
00207 ViewTraceRecorder<View>::slack(void) const {
00208 return s;
00209 }
00210
00211
00212
00213
00214
00215
00216 template<class View>
00217 forceinline typename ViewTraceRecorder<View>::SlackValue
00218 ViewTraceRecorder<View>::Slack::initial(void) const {
00219 return i;
00220 }
00221 template<class View>
00222 forceinline typename ViewTraceRecorder<View>::SlackValue
00223 ViewTraceRecorder<View>::Slack::previous(void) const {
00224 return p;
00225 }
00226 template<class View>
00227 forceinline typename ViewTraceRecorder<View>::SlackValue
00228 ViewTraceRecorder<View>::Slack::current(void) const {
00229 return c;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 template<class View>
00239 forceinline
00240 ViewTraceRecorder<View>::Idx::Idx(Space& home, Propagator& p,
00241 Council<Idx>& c, int i)
00242 : Advisor(home,p,c), _idx(i) {}
00243 template<class View>
00244 forceinline
00245 ViewTraceRecorder<View>::Idx::Idx(Space& home, Idx& a)
00246 : Advisor(home,a), _idx(a._idx) {
00247 }
00248 template<class View>
00249 forceinline int
00250 ViewTraceRecorder<View>::Idx::idx(void) const {
00251 return _idx;
00252 }
00253
00254
00255
00256
00257
00258
00259 template<class View>
00260 forceinline
00261 ViewTraceRecorder<View>::ViewTraceRecorder(Home home, ViewArray<View>& x,
00262 TraceFilter tf0, int te0,
00263 ViewTracer<View>& t0)
00264 : Propagator(home), o(home,x.size()), n(x), c(home),
00265 tf(tf0), te(te0), t(t0) {
00266 home.notice(*this, AP_VIEW_TRACE);
00267 home.notice(*this, AP_DISPOSE);
00268 for (int i=n.size(); i--; ) {
00269 o[i] = TraceView(home,n[i]);
00270 if (!n[i].assigned())
00271 n[i].subscribe(home,*new (home) Idx(home,*this,c,i));
00272 }
00273 View::schedule(home,*this,ME_GEN_ASSIGNED);
00274 s.i = TraceView::slack(n[n.size()-1]);
00275 for (int i=n.size()-1; i--; )
00276 s.i += TraceView::slack(n[i]);
00277 s.p = s.i;
00278 if ((te & TE_INIT) != 0)
00279 t._init(home,*this);
00280 }
00281
00282
00283 template<class View>
00284 forceinline ExecStatus
00285 ViewTraceRecorder<View>::post(Home home, ViewArray<View>& x,
00286 TraceFilter tf, int te, ViewTracer<View>& t) {
00287 if ((x.size() > 0) &&
00288 (te & (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE)))
00289 (void) new (home) ViewTraceRecorder(home,x,tf,te,t);
00290 return ES_OK;
00291 }
00292
00293
00294
00295
00296
00297
00298 template<class View>
00299 forceinline
00300 ViewTraceRecorder<View>::ViewTraceRecorder(Space& home, ViewTraceRecorder& p)
00301 : Propagator(home,p), tf(p.tf), te(p.te), t(p.t), s(p.s) {
00302 o.update(home, p.o);
00303 n.update(home, p.n);
00304 c.update(home, p.c);
00305 }
00306
00307 template<class View>
00308 Propagator*
00309 ViewTraceRecorder<View>::copy(Space& home) {
00310 return new (home) ViewTraceRecorder(home, *this);
00311 }
00312
00313 template<class View>
00314 inline size_t
00315 ViewTraceRecorder<View>::dispose(Space& home) {
00316 home.ignore(*this, AP_VIEW_TRACE);
00317 home.ignore(*this, AP_DISPOSE);
00318 tf.~TraceFilter();
00319
00320 for (Advisors<Idx> as(c); as(); ++as)
00321 n[as.advisor().idx()].cancel(home,as.advisor());
00322 c.dispose(home);
00323 (void) Propagator::dispose(home);
00324 return sizeof(*this);
00325 }
00326
00327 template<class View>
00328 PropCost
00329 ViewTraceRecorder<View>::cost(const Space&, const ModEventDelta&) const {
00330 return PropCost::record();
00331 }
00332
00333 template<class View>
00334 void
00335 ViewTraceRecorder<View>::reschedule(Space& home) {
00336 View::schedule(home,*this,ME_GEN_ASSIGNED);
00337 }
00338
00339 template<class View>
00340 ExecStatus
00341 ViewTraceRecorder<View>::advise(Space& home, Advisor& _a, const Delta& d) {
00342 Idx& a = static_cast<Idx&>(_a);
00343 int i = a.idx();
00344 if (((te & TE_PRUNE) != 0) && !disabled() && tf(a(home)) ) {
00345 TraceDelta td(o[i],n[i],d);
00346 t._prune(home,*this,a(home),i,td);
00347 }
00348 o[i].prune(home,n[i],d);
00349 if (n[a.idx()].assigned())
00350 a.dispose(home,c);
00351 return ES_NOFIX;
00352 }
00353
00354 template<class View>
00355 ExecStatus
00356 ViewTraceRecorder<View>::propagate(Space& home, const ModEventDelta&) {
00357 s.c = TraceView::slack(n[n.size()-1]);
00358 for (int i=n.size()-1; i--; )
00359 s.c += TraceView::slack(n[i]);
00360 if (home.failed() && ((te & TE_FAIL) != 0) && !disabled()) {
00361 t._fail(home,*this);
00362 return ES_FIX;
00363 }
00364 if ((te & TE_FIX) != 0)
00365 t._fix(home,*this);
00366 s.p = s.c;
00367 if (c.empty()) {
00368 if ((te & TE_DONE) != 0)
00369 t._done(home,*this);
00370 return home.ES_SUBSUMED(*this);
00371 }
00372 return ES_FIX;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381 forceinline const TraceFilter&
00382 TraceRecorder::filter(void) const {
00383 return tf;
00384 }
00385 forceinline int
00386 TraceRecorder::events(void) const {
00387 return te;
00388 }
00389 forceinline Tracer&
00390 TraceRecorder::tracer(void) const {
00391 return t;
00392 }
00393
00394
00395
00396
00397
00398
00399 forceinline
00400 TraceRecorder::TraceRecorder(Home home, TraceFilter tf0, int te0,
00401 Tracer& t0)
00402 : Propagator(home), tf(tf0), te(te0), t(t0) {
00403 home.notice(*this, AP_DISPOSE);
00404 home.notice(*this, AP_TRACE);
00405 }
00406
00407 forceinline ExecStatus
00408 TraceRecorder::post(Home home, TraceFilter tf, int te, Tracer& t) {
00409 if (te & (TE_PROPAGATE | TE_COMMIT))
00410 (void) new (home) TraceRecorder(home,tf,te,t);
00411 return ES_OK;
00412 }
00413
00414 forceinline
00415 TraceRecorder::TraceRecorder(Space& home, TraceRecorder& p)
00416 : Propagator(home,p), tf(p.tf), te(p.te), t(p.t) {
00417 }
00418
00419 }
00420
00421