Generated on Sun Feb 17 15:24:26 2019 for Gecode by doxygen 1.6.3

recorder.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2016
00008  *
00009  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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    * Functions for trace support
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    * Functions for access to slack
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    * Advisor for tracer
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    * Posting of tracer propagator
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    * Propagation for trace recorder
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     // Cancel remaining advisors
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    * Functions for trace support
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    * Trace recorder propagator
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 // STATISTICS: kernel-trace