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 TE_POST = 1 << 7
00053 };
00054
00059 template<class View>
00060 class ViewTraceRecorder : public Propagator {
00061 public:
00063 typedef typename TraceTraits<View>::TraceView TraceView;
00065 typedef typename TraceTraits<View>::TraceDelta TraceDelta;
00067 typedef typename TraceTraits<View>::SlackValue SlackValue;
00069 class Slack {
00070 template<class ViewForTraceRecorder> friend class ViewTraceRecorder;
00071 protected:
00073 SlackValue i;
00075 SlackValue p;
00077 SlackValue c;
00078 public:
00080 SlackValue initial(void) const;
00082 SlackValue previous(void) const;
00084 SlackValue current(void) const;
00085 };
00086 protected:
00088 class Idx : public Advisor {
00089 protected:
00091 int _idx;
00092 public:
00094 Idx(Space& home, Propagator& p, Council<Idx>& c, int i);
00096 Idx(Space& home, Idx& a);
00098 int idx(void) const;
00099 };
00101 ViewArray<TraceView> o;
00103 ViewArray<View> n;
00105 Council<Idx> c;
00107 TraceFilter tf;
00109 int te;
00111 ViewTracer<View>& t;
00113 Slack s;
00115 ViewTraceRecorder(Space& home, ViewTraceRecorder& p);
00116 public:
00118 ViewTraceRecorder(Home home, ViewArray<View>& x,
00119 TraceFilter tf, int te, ViewTracer<View>& t);
00121 virtual Propagator* copy(Space& home);
00123 virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00125 virtual void reschedule(Space& home);
00127 virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00129 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00131 virtual size_t dispose(Space& home);
00133 static ExecStatus post(Home home, ViewArray<View>& x,
00134 TraceFilter tf, int te, ViewTracer<View>& t);
00136
00137
00138 const typename View::VarType operator [](int i) const;
00140 int size(void) const;
00142 const Slack& slack(void) const;
00144 };
00145
00154 class TraceRecorder : public Propagator {
00155 public:
00157 TraceFilter tf;
00159 int te;
00161 Tracer& t;
00163 TraceRecorder(Space& home, TraceRecorder& p);
00164 public:
00166 TraceRecorder(Home home, TraceFilter tf, int te, Tracer& t);
00168 virtual Propagator* copy(Space& home);
00170 virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00172 virtual void reschedule(Space& home);
00174 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00176 virtual size_t dispose(Space& home);
00178 static ExecStatus post(Home home, TraceFilter tf, int te, Tracer& t);
00180
00181
00182 const TraceFilter& filter(void) const;
00184 int events(void) const;
00186 Tracer& tracer(void) const;
00188 };
00189
00190
00191
00192
00193
00194
00195 template<class View>
00196 forceinline const typename View::VarType
00197 ViewTraceRecorder<View>::operator [](int i) const {
00198 const typename View::VarType x(n[i].varimp());
00199 return x;
00200 }
00201 template<class View>
00202 forceinline int
00203 ViewTraceRecorder<View>::size(void) const {
00204 return n.size();
00205 }
00206 template<class View>
00207 forceinline const typename ViewTraceRecorder<View>::Slack&
00208 ViewTraceRecorder<View>::slack(void) const {
00209 return s;
00210 }
00211
00212
00213
00214
00215
00216
00217 template<class View>
00218 forceinline typename ViewTraceRecorder<View>::SlackValue
00219 ViewTraceRecorder<View>::Slack::initial(void) const {
00220 return i;
00221 }
00222 template<class View>
00223 forceinline typename ViewTraceRecorder<View>::SlackValue
00224 ViewTraceRecorder<View>::Slack::previous(void) const {
00225 return p;
00226 }
00227 template<class View>
00228 forceinline typename ViewTraceRecorder<View>::SlackValue
00229 ViewTraceRecorder<View>::Slack::current(void) const {
00230 return c;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 template<class View>
00240 forceinline
00241 ViewTraceRecorder<View>::Idx::Idx(Space& home, Propagator& p,
00242 Council<Idx>& c, int i)
00243 : Advisor(home,p,c), _idx(i) {}
00244 template<class View>
00245 forceinline
00246 ViewTraceRecorder<View>::Idx::Idx(Space& home, Idx& a)
00247 : Advisor(home,a), _idx(a._idx) {
00248 }
00249 template<class View>
00250 forceinline int
00251 ViewTraceRecorder<View>::Idx::idx(void) const {
00252 return _idx;
00253 }
00254
00255
00256
00257
00258
00259
00260 template<class View>
00261 forceinline
00262 ViewTraceRecorder<View>::ViewTraceRecorder(Home home, ViewArray<View>& x,
00263 TraceFilter tf0, int te0,
00264 ViewTracer<View>& t0)
00265 : Propagator(home), o(home,x.size()), n(x), c(home),
00266 tf(tf0), te(te0), t(t0) {
00267 home.notice(*this, AP_VIEW_TRACE);
00268 home.notice(*this, AP_DISPOSE);
00269 for (int i=0; i<n.size(); i++) {
00270 o[i] = TraceView(home,n[i]);
00271 if (!n[i].assigned())
00272 n[i].subscribe(home,*new (home) Idx(home,*this,c,i));
00273 }
00274 View::schedule(home,*this,ME_GEN_ASSIGNED);
00275 s.i = TraceView::slack(n[0]);
00276 for (int i=1; i<n.size(); i++)
00277 s.i += TraceView::slack(n[i]);
00278 s.p = s.i;
00279 if ((te & TE_INIT) != 0)
00280 t._init(home,*this);
00281 }
00282
00283
00284 template<class View>
00285 forceinline ExecStatus
00286 ViewTraceRecorder<View>::post(Home home, ViewArray<View>& x,
00287 TraceFilter tf, int te, ViewTracer<View>& t) {
00288 if ((x.size() > 0) &&
00289 (te & (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE)))
00290 (void) new (home) ViewTraceRecorder(home,x,tf,te,t);
00291 return ES_OK;
00292 }
00293
00294
00295
00296
00297
00298
00299 template<class View>
00300 forceinline
00301 ViewTraceRecorder<View>::ViewTraceRecorder(Space& home, ViewTraceRecorder& p)
00302 : Propagator(home,p), tf(p.tf), te(p.te), t(p.t), s(p.s) {
00303 o.update(home, p.o);
00304 n.update(home, p.n);
00305 c.update(home, p.c);
00306 }
00307
00308 template<class View>
00309 Propagator*
00310 ViewTraceRecorder<View>::copy(Space& home) {
00311 return new (home) ViewTraceRecorder(home, *this);
00312 }
00313
00314 template<class View>
00315 inline size_t
00316 ViewTraceRecorder<View>::dispose(Space& home) {
00317 home.ignore(*this, AP_VIEW_TRACE);
00318 home.ignore(*this, AP_DISPOSE);
00319 tf.~TraceFilter();
00320
00321 for (Advisors<Idx> as(c); as(); ++as)
00322 n[as.advisor().idx()].cancel(home,as.advisor());
00323 c.dispose(home);
00324 (void) Propagator::dispose(home);
00325 return sizeof(*this);
00326 }
00327
00328 template<class View>
00329 PropCost
00330 ViewTraceRecorder<View>::cost(const Space&, const ModEventDelta&) const {
00331 return PropCost::record();
00332 }
00333
00334 template<class View>
00335 void
00336 ViewTraceRecorder<View>::reschedule(Space& home) {
00337 View::schedule(home,*this,ME_GEN_ASSIGNED);
00338 }
00339
00340 template<class View>
00341 ExecStatus
00342 ViewTraceRecorder<View>::advise(Space& home, Advisor& _a, const Delta& d) {
00343 Idx& a = static_cast<Idx&>(_a);
00344 int i = a.idx();
00345 if (((te & TE_PRUNE) != 0) && !disabled() && tf(a(home)) ) {
00346 TraceDelta td(o[i],n[i],d);
00347 t._prune(home,*this,a(home),i,td);
00348 }
00349 o[i].prune(home,n[i],d);
00350 if (n[a.idx()].assigned())
00351 a.dispose(home,c);
00352 return ES_NOFIX;
00353 }
00354
00355 template<class View>
00356 ExecStatus
00357 ViewTraceRecorder<View>::propagate(Space& home, const ModEventDelta&) {
00358 s.c = TraceView::slack(n[0]);
00359 for (int i=1; i<n.size(); i++)
00360 s.c += TraceView::slack(n[i]);
00361 if (home.failed() && ((te & TE_FAIL) != 0) && !disabled()) {
00362 t._fail(home,*this);
00363 return ES_FIX;
00364 }
00365 if ((te & TE_FIX) != 0)
00366 t._fix(home,*this);
00367 s.p = s.c;
00368 if (c.empty()) {
00369 if ((te & TE_DONE) != 0)
00370 t._done(home,*this);
00371 return home.ES_SUBSUMED(*this);
00372 }
00373 return ES_FIX;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 forceinline const TraceFilter&
00383 TraceRecorder::filter(void) const {
00384 return tf;
00385 }
00386 forceinline int
00387 TraceRecorder::events(void) const {
00388 return te;
00389 }
00390 forceinline Tracer&
00391 TraceRecorder::tracer(void) const {
00392 return t;
00393 }
00394
00395
00396
00397
00398
00399
00400 forceinline
00401 TraceRecorder::TraceRecorder(Home home, TraceFilter tf0, int te0,
00402 Tracer& t0)
00403 : Propagator(home), tf(tf0), te(te0), t(t0) {
00404 home.notice(*this, AP_DISPOSE);
00405 home.notice(*this, AP_TRACE);
00406 }
00407
00408 forceinline ExecStatus
00409 TraceRecorder::post(Home home, TraceFilter tf, int te, Tracer& t) {
00410 if (te & (TE_PROPAGATE | TE_COMMIT | TE_POST))
00411 (void) new (home) TraceRecorder(home,tf,te,t);
00412 return ES_OK;
00413 }
00414
00415 forceinline
00416 TraceRecorder::TraceRecorder(Space& home, TraceRecorder& p)
00417 : Propagator(home,p), tf(p.tf), te(p.te), t(p.t) {
00418 }
00419
00420 }
00421
00422