adevs_models.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /**
  2. * Copyright (c) 2013, James Nutaro
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  18. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. *
  25. * The views and conclusions contained in the software and documentation are those
  26. * of the authors and should not be interpreted as representing official policies,
  27. * either expressed or implied, of the FreeBSD Project.
  28. *
  29. * Bugs, comments, and questions can be sent to nutaro@gmail.com
  30. */
  31. #ifndef __adevs_models_h_
  32. #define __adevs_models_h_
  33. #include "adevs_time.h"
  34. #include "adevs_bag.h"
  35. #include "adevs_set.h"
  36. #include "adevs_exception.h"
  37. #include <cstdlib>
  38. namespace adevs
  39. {
  40. /*
  41. * Declare network and atomic model so types can be used as the type of
  42. * parent in the basic Devs model and for type ID functions.
  43. */
  44. template <typename X, typename T> class Network;
  45. template <typename X, typename T> class Atomic;
  46. template <typename X, typename T> class MealyAtomic;
  47. template <typename X, typename T> class Schedule;
  48. template <typename X, typename T> class Simulator;
  49. /**
  50. * The Devs class provides basic operations for all devs models.
  51. * The model I/O type is set by the template argument X. The
  52. * type to be used for time is set with the template argument
  53. * T. The default type for time is double.
  54. */
  55. template <typename X, typename T = double> class Devs
  56. {
  57. public:
  58. /// Default constructor.
  59. Devs():
  60. parent(NULL)
  61. {
  62. }
  63. /// Destructor.
  64. virtual ~Devs()
  65. {
  66. }
  67. /**
  68. * Returns NULL if this is not a network model; returns a pointer to
  69. * itself otherwise. This method is used to avoid a relatively expensive
  70. * dynamic cast.
  71. */
  72. virtual Network<X,T>* typeIsNetwork() { return NULL; }
  73. /// Returns NULL if this is not an atomic model; returns itself otherwise.
  74. virtual Atomic<X,T>* typeIsAtomic() { return NULL; }
  75. /// Returns NULL if this is not a mealy atomic model; returns itself otherwise.
  76. virtual MealyAtomic<X,T>* typeIsMealyAtomic() { return NULL; }
  77. /**
  78. * Get the model that contains this model as a component. Returns
  79. * NULL if this model is at the top of the hierarchy.
  80. */
  81. const Network<X,T>* getParent() const { return parent; }
  82. /// Get the model that contains this model as a component.
  83. Network<X,T>* getParent() { return parent; }
  84. /**
  85. * Assign a new parent to this model. Network model's should always
  86. * call this method to make themselves the parent of their components.
  87. * If the parent is not set correctly, then the event routing algorithm
  88. * in the simulator will fail.
  89. */
  90. void setParent(Network<X,T>* parent) { this->parent = parent; }
  91. /**
  92. * This is the structure transition function, which is evaluated following
  93. * every change of the model's state. It should return true
  94. * if a structure change is to occur, and false otherwise. False is the
  95. * default return value.
  96. * This method is used by the simulator to limit the execution
  97. * of potentially expensive structure changes.
  98. * If the return value is true, then the parent's model_transition()
  99. * will also be evaluated. For network models, the model_transition() function is
  100. * preceded and anteceded by a call to getComponents(). The difference
  101. * of these two sets is used to determine if any models were added or removed
  102. * as part of the model transition.
  103. */
  104. virtual bool model_transition() { return false; }
  105. private:
  106. Network<X,T>* parent;
  107. };
  108. /**
  109. * Event objects are used for routing within a network model,
  110. * for notifying event listeners of output events, and for injecting
  111. * input into a running simulation.
  112. */
  113. template <typename X, typename T = double> class Event
  114. {
  115. public:
  116. /// Constructor. Sets the model to NULL.
  117. Event():
  118. model(NULL),
  119. value()
  120. {
  121. }
  122. /**
  123. * Constructor sets the model and value. The input into a
  124. * Simulator and in a network's routing method,
  125. * the model is the target of the input value.
  126. * In a callback to an event listener, the model is the
  127. * source of the output value.
  128. */
  129. Event(Devs<X,T>* model, const X& value):
  130. model(model),
  131. value(value)
  132. {
  133. }
  134. /// Copy constructor.
  135. Event(const Event<X,T>& src):
  136. model(src.model),
  137. value(src.value)
  138. {
  139. }
  140. /// Assignment operator.
  141. const Event<X,T>& operator=(const Event<X,T>& src)
  142. {
  143. model = src.model;
  144. value = src.value;
  145. return *this;
  146. }
  147. /// The model associated with the event.
  148. Devs<X,T>* model;
  149. /// The value associated with the event.
  150. X value;
  151. /// Destructor
  152. ~Event()
  153. {
  154. }
  155. };
  156. /**
  157. * Base type for all atomic DEVS models.
  158. */
  159. template <typename X, typename T = double> class Atomic: public Devs<X,T>
  160. {
  161. public:
  162. /// The constructor should place the model into its initial state.
  163. Atomic():
  164. Devs<X,T>(),
  165. tL(adevs_zero<T>()),
  166. q_index(0), // The Schedule requires this to be zero
  167. proc(-1),
  168. x(NULL),
  169. y(NULL)
  170. {
  171. }
  172. /// Internal transition function.
  173. virtual void delta_int() = 0;
  174. /**
  175. * External transition function.
  176. * @param e Time elapsed since the last change of state
  177. * @param xb Input for the model.
  178. */
  179. virtual void delta_ext(T e, const Bag<X>& xb) = 0;
  180. /**
  181. * Confluent transition function.
  182. * @param xb Input for the model.
  183. */
  184. virtual void delta_conf(const Bag<X>& xb) = 0;
  185. /**
  186. * Output function. Output values should be added to the bag yb.
  187. * @param yb Empty bag to be filled with the model's output
  188. */
  189. virtual void output_func(Bag<X>& yb) = 0;
  190. /**
  191. * Time advance function. adevs_inf<T>() is used for infinity.
  192. * @return The time to the next internal event
  193. */
  194. virtual T ta() = 0;
  195. /**
  196. * Garbage collection function. The objects in g are
  197. * no longer in use by the simulation engine and should be disposed of.
  198. ` * Note that the elements in g are only those objects produced as
  199. * output by this model.
  200. */
  201. virtual void gc_output(Bag<X>& g) = 0;
  202. /// Destructor.
  203. virtual ~Atomic(){}
  204. /// Returns a pointer to this model.
  205. Atomic<X,T>* typeIsAtomic() { return this; }
  206. protected:
  207. /**
  208. * Get the last event time for this model. This is
  209. * provided primarily for use with the backwards compatibility
  210. * module and should not be relied on. It is likely to be
  211. * removed in later versions of the code.
  212. */
  213. T getLastEventTime() const { return tL; }
  214. private:
  215. friend class Simulator<X,T>;
  216. friend class Schedule<X,T>;
  217. // Time of last event
  218. T tL;
  219. // Index in the priority queue
  220. unsigned int q_index;
  221. // Thread assigned to this model
  222. int proc;
  223. // Input and output event bags
  224. Bag<X> *x, *y;
  225. };
  226. /**
  227. * This is a Mealy type atomic model where its output
  228. * may depend on its input. Mealy machines cannot be
  229. * connected to other Mealy machines. An exception
  230. * will be generated by the Simulator if you attempt
  231. * to do so.
  232. */
  233. template <typename X, typename T = double> class MealyAtomic:
  234. public Atomic<X,T>
  235. {
  236. public:
  237. MealyAtomic<X,T>():Atomic<X,T>(),imm(false){}
  238. MealyAtomic<X,T>* typeIsMealyAtomic() { return this; }
  239. /**
  240. * Produce output at e < ta(q) in response to xb.
  241. * This is output preceding an external event.
  242. */
  243. virtual void output_func(T e, const Bag<X>& xb, Bag<X>& yb) = 0;
  244. /**
  245. * Produce output at e = ta(q) in response to xb.
  246. * This is output preceding a confluent event.
  247. */
  248. virtual void output_func(const Bag<X>& xb, Bag<X>& yb) = 0;
  249. virtual ~MealyAtomic(){}
  250. private:
  251. friend class Simulator<X,T>;
  252. bool imm;
  253. };
  254. /**
  255. * Base class for DEVS network models.
  256. */
  257. template <typename X, typename T = double> class Network: public Devs<X,T>
  258. {
  259. public:
  260. /// Constructor.
  261. Network():
  262. Devs<X,T>()
  263. {
  264. }
  265. /**
  266. * This method should fill the
  267. * set c with all the Network's components, excluding the
  268. * Network model itself.
  269. * @param c An empty set to the filled with the Network's components.
  270. */
  271. virtual void getComponents(Set<Devs<X,T>*>& c) = 0;
  272. /**
  273. * This method is called by the Simulator to route an output value
  274. * produced by a model. This method should fill the bag r
  275. * with Events that point to the target model and carry the value
  276. * to be delivered to the target. The target may be a component
  277. * of the Network or the Network itself, the latter causing the
  278. * Network to produce an output.
  279. * @param model The model that produced the output value
  280. * @param value The output value produced by the model
  281. * @param r A bag to be filled with (target,value) pairs
  282. */
  283. virtual void route(const X& value, Devs<X,T>* model, Bag<Event<X,T> >& r) = 0;
  284. /**
  285. * Destructor. This destructor does not delete any component models.
  286. * Any necessary cleanup should be done by the derived class.
  287. */
  288. virtual ~Network()
  289. {
  290. }
  291. /// Returns a pointer to this model.
  292. Network<X,T>* typeIsNetwork() { return this; }
  293. };
  294. } // end of namespace
  295. #endif