sp_plpexecutor.h

Go to the documentation of this file.
00001 /** @file sp_plpexecutor.h Executor that proposes transitions to execute */
00002 
00003 /* 
00004    FAU Discrete Event Systems Library (libfaudes)
00005 
00006    The proposing executor is based on the stochastic executor, which
00007    has been developped by Christoph Doerr as part of his thesis project.
00008   
00009    Copyright (C) 2008  Thomas Moor
00010    Copyright (C) 2007  Christoph Doerr
00011    Exclusive copyright is granted to Thomas Moor
00012 
00013    todo:
00014    - compile simevent set to one vector per type to speed up iterations
00015    - fix vector pdfs  
00016    - test with elementary examples
00017    - use compiled interval time constraints
00018 
00019 */
00020 
00021 #ifndef FAUDES_SP_PLPEXECUTOR_H
00022 #define FAUDES_SP_PLPEXECUTOR_H
00023 
00024 #include "corefaudes.h"
00025 #include "tp_include.h"
00026 #include "sp_lpexecutor.h" 
00027 #include "sp_simeventset.h"
00028 #include "sp_random.h"
00029 
00030 
00031 namespace faudes {
00032   
00033 /**
00034  * Executer that proposes which transition to execute.
00035  *
00036  * \section SecSimulatorPLPEX1 Priority and Stochastic Semantics
00037  *
00038  * Whilst the LoggingExecutor (and all lower level executors) is aware of which transitions are
00039  * enabled, the ProposingExecutor actually proposes either one particular transition for execution or
00040  * a particular amount of time to let pass. The proposal refers to additional semantics
00041  * parametrised by data from SimEventAttribute. The decision procedure is organized in four stages, 
00042  * were the first stage that yields a proposal wins:
00043  * 
00044  * 1.) SimPriorityEventAttribute, positive priority
00045  * - if one or more events with positive priority are enabled, those with maximum priority
00046  *   form the candidate set
00047  * - if the candidate set is non-emty propose one event by random (uniformly distributed) to
00048  *   be executed immediately
00049  *
00050  * 2.) SimStochasticEventAttribute, stochastic timing
00051  * - if within the interval at which the set of enabled events remains constant (EnabledInterval)
00052  *   an event with stochastic timing is scheduled to occur, the earliest of such events form the candidate set.
00053  * - if the candidate set is non-emty propose one event by random (uniformly distributed) to be
00054  *   executed at the scheduled clock time.
00055  * 
00056  * 3.) passing by clock time
00057  * - if the EnabledInterval is of positive duration, let this duration pass by.
00058  * - if the EnabledInterval is of infinite duration, let all clock time pass and stop the simulation
00059  *
00060  * 4.) SimPriorityEventAttribute, negative priority
00061  * - if one or more events with negative priority are enabled, those with maximum priority
00062  *   form the candidate set
00063  * - if the candidate set is non-emty propose one event by random (uniformly distributed) to
00064  *   be executed immediately
00065  * 
00066  * Note that the above procedure will never come up with a proposal that fails to satisfy
00067  * invariant and guard conditions. In this sense, the above procedure is compliant with Alur semantics
00068  * of timed automata. 
00069  *
00070  * If the above procedure fails to indicate a transition to execute or clock time to let pass, the
00071  * system is deadlocked. If the procedure sticks with case 3) and infinite duration, it might be
00072  * either life locked (no enabled events) or just unwilling/unable to execute a negative priority event.
00073  * The latter case can be used for sensor events in a hardware-in-the-loop simulation.
00074  *
00075  *
00076  * \section SecSimulatorPLPEX2 Scheduling Stochastic Events
00077  *
00078  * The mechnism to schedule events with stochastic timing comes in three flavors.
00079  * - SimStochasticEventAttribute::Extern 
00080  * The random variable models an external stochastic process. A sample is taken
00081  * when the executor is reset to determine the first scheduled occurence. The schedule expires
00082  * when it matched the current clock time, regardless whether the event is executed or not. When the
00083  * schedule expires, a new sample is taken to determine the next scheduled occurence. 
00084  * -  SimStochasticEventAttribute::Trigger  
00085  * The random variable is used to narrow down the effective guard interval to a
00086  * point. By "effective guard interval" we refer to the interval of time in which the guard is satisfied 
00087  * w.r.t. the current timed state.
00088  * A sample is taken when the executor enters a timed state with a non-empty the effective guard 
00089  * interval. In order to guarantee that the scheduled occurence lies within the guard, the density function
00090  * is shaped accordingly. The schedule expires when either the event is actually executed or when the
00091  * effective guard interval changes due to a transition.
00092  * -  SimStochasticEventAttribute::Delay
00093  * The random variable models a delay relative to the clock time when the event is
00094  * enabled. A sample is taken when the executor is reset to determine the initial amount of delay. 
00095  * During the execution sequence the executor accumulates the durations for which the event is enabled. The event
00096  * is scheduled when the accumulated durations matches the delay. When the event is
00097  * executed the schedule expires and the random variable is sampled to re-initialised the delay.
00098  *
00099  * Note that type Extern or Delay schedules can disable the respective event in a way that
00100  * potentially leads to blocking behaviour even if the timed automata is non-blocking by Alur semantics.
00101  * This is a consequence of the fact that both types model additional phenomena that are
00102  * synchronized with the timed automata, and it is perferctly reasonable that this synchronisation
00103  * introduces blocking situations.
00104  * In contrast, events of type Trigger are not affected by the blocking issue provided that  guards lie 
00105  * within the respective invariant.  
00106  *
00107  * \section SecSimulatorPLPEX3 File IO
00108  *
00109  * For token IO, the ProposingExecutor reads and writes a section with default label 
00110  * "Executor". It contains a ParallelExecutor section to define a vector of generators,
00111  * a SimConditionSet section to define relevant conditions, and a SimEventSet section to define
00112  * the above event attributes. Example:
00113  *
00114  * \code
00115  * <Executor> 
00116  *
00117  * <Generators> 
00118  * "./some_generator.gen"
00119  * "./other_generator.gen" 
00120  * </Generators> 
00121  *
00122  * <Conditions> 
00123  *
00124  * "IdleCond"      
00125  * <EventCondition>
00126  * <StartEvents> "beta" "mue" </StartEvents>
00127  * <StopEvents>  "alpha"      </StopEvents>
00128  * </EventCondition>
00129  *
00130  * "DownCond"     
00131  * <StateCondition>
00132  * <StateSet> "down" </StateSet>           % refers to first generator
00133  * <StateSet> "down" "repair" </StateSet>  % refers to second generator
00134  * </StateCondition>
00135  *
00136  * </Conditions> 
00137  *
00138  * <SimEvents> 
00139  *
00140  * "alpha"    
00141  * <Priority> 100  </Priority>  
00142  *
00143  * "beta"   
00144  * <Stochastic> +Trigger+  +Gauss+  <Parameter> 10  5  </Parameter> </Stochastic>
00145  *
00146  * "mue"   
00147  * <Stochastic> +Delay+  +Gauss+  <Parameter> 20  5  </Parameter> </Stochastic>
00148  *
00149  * "lambda"    
00150  * <Priority> 100  </Priority>  
00151  *
00152  * </SimEvents> 
00153  *
00154  * </Executor> 
00155  * \endcode
00156  *
00157  * Technical detail: since the trace buffer only covers the dynamic state of the parallel executor,
00158  * the RevertToStep method cannot recover the stochastic event states. Including stochastic states
00159  * with the trace buffer is considered to expensive. 
00160  *
00161  * @ingroup SimulatorPlugin 
00162  */
00163 
00164 
00165 class ProposingExecutor : public LoggingExecutor {  
00166 
00167 FAUDES_TYPE_DECLARATION(ProposingExecutor, ProposingExecutor, ParallelExecutor)
00168 
00169  public:
00170     
00171   /*****************************************
00172    *****************************************
00173    *****************************************
00174    *****************************************/
00175 
00176   /** @name Constructors & Destructor */
00177   /** @{ doxygen group */
00178 
00179 
00180   /**
00181    * Creates an emtpy ProposingExecutor
00182    */
00183   ProposingExecutor();
00184 
00185 
00186   /**
00187    * Copy constrcutor
00188    */
00189   ProposingExecutor(const ProposingExecutor&);
00190 
00191 
00192 
00193   /** @} doxygen group */
00194 
00195   /*****************************************
00196    *****************************************
00197    *****************************************
00198    *****************************************/
00199 
00200   /** @name Simulation Event Attributes  */
00201   /** @{ doxygen group */
00202 
00203 
00204   /** 
00205    * Simulation event attribute lookup 
00206    *
00207    * @param index
00208    *
00209    * @return 
00210    *   reference to attribute
00211    */
00212   const SimEventAttribute& EventAttribute(Idx index) const;
00213 
00214   /**
00215    * Set simulation event attribute. Requires Reset().
00216    *
00217    * @param index
00218    *   Event index
00219    * @param rAttr
00220    *   New attribute
00221    * @exception Exception
00222    *   Index not found in EventSymbolMap (id 42)
00223    *
00224    */
00225   void EventAttribute(Idx index, const SimEventAttribute& rAttr);
00226 
00227 
00228   /**
00229    * Set all simulation event attributes. 
00230    * Any previous attributes are removed.
00231    * Any events not in rAlphabet become the default attribute attached (which is priority 0)
00232    * Requires Reset().
00233    *
00234    *  @param rAlphabet 
00235    *      EventSet with SimEventAttrute data
00236    */
00237   void Alphabet(const sEventSet& rAlphabet);
00238 
00239   /** 
00240    * Access alphabet (incl simulation event attributes) 
00241    *
00242    * @return
00243    *    Overall alphabet
00244    */
00245   const sEventSet& Alphabet(void) const { return mSimEvents; };
00246 
00247   /** @} doxygen group */
00248 
00249   /** @name Execution Proposal  */
00250   /** @{ doxygen group */
00251 
00252 
00253   /**
00254    * Execute next transition.
00255    *
00256    * Choose the transition to execute by priorities and   
00257    * stochastic properties.
00258    *
00259    *  @return 
00260    *      Executed TimedEvent
00261    */
00262   TimedEvent ExecuteNextTransition();
00263     
00264   /**
00265    * Propose next transition.
00266    * 
00267    * Propose a transition to execute by priorities and   
00268    * stochastic properties.
00269    *
00270    *  @return 
00271    *      Proposed TimedEvent
00272    */
00273   const TimedEvent& ProposeNextTransition();
00274     
00275   /**
00276    * Inspect stochastic event states (debugging)
00277    *
00278    *   return EventInfoMap string
00279    */
00280   std::string EventStatesToString(void) const;
00281 
00282 
00283   /** @} doxygen group */
00284 
00285   /*****************************************
00286    *****************************************
00287    *****************************************
00288    *****************************************/
00289 
00290   /** @name Re-implemenented from ParallelExecutor */
00291   /** @{ doxygen group */
00292 
00293   /**
00294    * Reset the ProposingExecutor.
00295    * This includes a reset of the ParallelExecutor and the simulation event states.
00296    * @param seed
00297    *     Seed for random generator, 0<>system time
00298    */
00299   virtual void Reset(long int seed=0);
00300 
00301   /**
00302    * Clear all data (generators, simulation attributes etc)
00303    */
00304   virtual void Clear(void);
00305 
00306 
00307   /**
00308    * Execute time duration.
00309    *
00310    *  @return 
00311    *     True on success
00312    */
00313   bool ExecuteTime(tpTime::Type duration);
00314     
00315   /**
00316    * Execute event.
00317    *
00318    *  @return 
00319    *     True on success
00320    */
00321   bool ExecuteEvent(Idx event);
00322     
00323 
00324   /**
00325    * Execute event by transition
00326    *
00327    *  @return 
00328    *     True on success
00329    */
00330   bool ExecuteTransition(const TimedEvent& tevent);
00331     
00332   /**
00333    * Revert executor to past step.
00334    *
00335    * This will revert only the executor dynamic state (incl clock values, current time).
00336    * The condition and event states, however, will not be reverted.
00337    *
00338    *  @return 
00339    *     True on success
00340    */
00341   bool RevertToStep(Idx step);
00342 
00343   /** @} doxygen group */
00344 
00345   /*****************************************
00346    *****************************************
00347    *****************************************
00348    *****************************************/
00349 
00350 
00351  private:
00352 
00353   /**
00354    * Simulation event attributes, incl stochastic and priority data
00355    */
00356   sEventSet mSimEvents;
00357 
00358   /** 
00359    * Valid proposal available 
00360    */
00361   bool mPValid;
00362 
00363   /** 
00364    * Available proposal 
00365    */
00366   TimedEvent mProposal; 
00367 
00368   /**
00369    * Reset stochastic state of events.
00370    */
00371   void ResetProposer(long int seed=0);
00372 
00373   /**
00374    * Evaluate random variable to schedule event.
00375    * Referring to the specified stochastic attribute, take a random sample to
00376    * schedule the next occurence of the event. The result is given as return value and is
00377    * also recorded in the simulation state of the event attribute. 
00378    *
00379    *  
00380    *  @param event
00381    *     Event to schedule, by index
00382    *  @param pattr
00383    *     Pointer to event attribute  
00384    *  @return 
00385    *     Time of next event occurrence 
00386    */
00387   tpTime::Type Schedule(Idx event, SimEventAttribute* pattr);
00388 
00389 protected:
00390 
00391   /**
00392    * Reads proposing executor from TokenReader, see also public wrappers Type::Read.
00393    *
00394    * @param rTr
00395    *   TokenReader to read from
00396    * @param rLabel
00397    *   Section to read, defaults to "LoggingExecutor"
00398    * @param pContext
00399    *   Read context to provide contextual information (ignored)
00400    *
00401    * @exception Exception
00402    *   - non-deterministic generator(s) (id 501)
00403    *   - token mismatch (id 502)
00404    *   - IO error (id 1)
00405    */
00406   virtual void DoRead(TokenReader& rTr,  const std::string& rLabel = "", const Type* pContext=0);
00407  
00408   /**
00409    * Write to TokenWriter, see also public wrappers Type::Write.
00410    *
00411    * @param rTw
00412    *   Reference to TokenWriter
00413    * @param rLabel
00414    *   Label of section to write, defaults to "LoggingExecutor"
00415    * @param pContext
00416    *   Write context to provide contextual information (ignored)
00417    *
00418    * @exception Exception 
00419    *   - IO errors (id 2)
00420    */
00421   virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
00422 
00423   /**
00424    * Assignment method
00425    *
00426    * @param rSrc
00427    *    Source to assign from
00428    */
00429   virtual void DoAssign(const ProposingExecutor& rSrc);
00430 
00431 
00432 }; // end class ProposingExecutor
00433 
00434 
00435 
00436 } // namespace faudes
00437 
00438 
00439 #endif

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen