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