Generated on Tue May 22 09:40:10 2018 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   };
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    * Functions for trace support
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    * Functions for access to slack
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    * Advisor for tracer
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    * Posting of tracer propagator
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    * Propagation for trace recorder
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     // Cancel remaining advisors
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    * Functions for trace support
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    * Trace recorder propagator
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 // STATISTICS: kernel-trace