adevs
adevs_pdevs.h
1 #ifndef _adevs_hier_h_
2 #define _adevs_hier_h_
3 #include "adevs_base.h"
4 #include <set>
5 #include <map>
6 
7 namespace adevs
8 {
9 
10 template <typename DataType, typename TimeType> class Network;
11 
21 template <typename DataType,typename TimeType=Time>
22 class Devs:
23  public Model<DataType,TimeType>
24 {
25  public:
26  Devs():Model<DataType,TimeType>(),m_parent(NULL){}
34  Network<DataType,TimeType>* parent() const { return m_parent; }
36  virtual void add(SimEnv<DataType,TimeType>* env) = 0;
37  virtual ~Devs(){}
38  private:
40  friend class Network<DataType,TimeType>;
41 };
42 
52 template <typename DataType, typename TimeType=Time>
53 class Atomic:
54  public Devs<DataType,TimeType>
55 {
56  public:
59  virtual void delta_int() = 0;
61  virtual void delta_ext(TimeType e, std::vector<DataType>& x) = 0;
63  virtual void delta_conf(std::vector<DataType>& x) = 0;
65  virtual TimeType ta() = 0;
73  virtual void output_func(std::vector<DataType>& y) = 0;
75  TimeType init(SimEnv<DataType,TimeType>* env);
78  TimeType update(SimEnv<DataType,TimeType>* env);
80  TimeType update(
81  SimEnv<DataType,TimeType>* env, std::vector<DataType>& x);
83  void fini(TimeType){}
85  void add(SimEnv<DataType,TimeType>* env) { env->add(this); }
86  private:
87  TimeType schedule_internal_events(SimEnv<DataType,TimeType>* env);
88  void transmit_output(SimEnv<DataType,TimeType>* env);
89  std::vector<DataType> y;
90  enum Mode { STATE_CHANGE, OUTPUT, PASSIVE };
91  Mode mode;
92  TimeType tL, tN;
93 };
94 
95 template <typename DataType, typename TimeType>
98 {
99  tL = env->now();
100  return (tN = schedule_internal_events(env));
101 }
102 
103 template <typename DataType, typename TimeType>
106 {
107  assert(mode != PASSIVE);
108  // Assign the state caused by the interal event
109  if (mode == STATE_CHANGE)
110  {
111  delta_int();
112  tL = env->now();
113  tN = schedule_internal_events(env);
114  }
115  // Otherwise generate output for this event and
116  // then schedule the change of state
117  else // (mode == OUTPUT)
118  {
119  transmit_output(env);
120  mode = STATE_CHANGE;
121  tN = env->now() + adevs_epsilon<TimeType>();
122  }
123  return tN;
124 }
125 
126 template <typename DataType, typename TimeType>
128  SimEnv<DataType,TimeType>* env, std::vector<DataType>& x)
129 {
130  // External event
131  if (env->now() < tN || (env->now() == tN && mode != STATE_CHANGE))
132  {
133  delta_ext(env->now()-tL,x);
134  tL = env->now();
135  tN = schedule_internal_events(env);
136  }
137  // Confluent event
138  else
139  {
140  delta_conf(x);
141  tL = env->now();
142  tN = schedule_internal_events(env);
143  }
144  return tN;
145 }
146 
147 template <typename DataType, typename TimeType>
150 {
151  // Get the time of the next event
152  TimeType h = ta();
153  // If this is for the next instant then send
154  // output generated by the initial state and
155  // the next state will be assigned at that
156  // time
157  if (h == adevs_zero<TimeType>())
158  {
159  transmit_output(env);
160  mode = STATE_CHANGE;
161  return env->now() + adevs_epsilon<TimeType>();
162  }
163  // Otherwise if h < inf() schedule an event
164  // immediately prior to the new state to
165  // generate that output
166  if (h < adevs_inf<TimeType>())
167  {
168  mode = OUTPUT;
169  return env->now()+h;
170  }
171  // Otherwise we are passive
172  mode = PASSIVE;
173  return h;
174 }
175 
176 template <typename DataType, typename TimeType>
178 {
179  output_func(y);
180  for (unsigned i = 0; i < y.size() && this->parent() != NULL; i++)
181  env->send(this,this->parent(),y[i]);
182  y.clear();
183 }
184 
192 template <typename DataType, typename TimeType=Time>
193 class Network:
194  public Devs<DataType,TimeType>
195 {
196  public:
197  Network():Devs<DataType,TimeType>(),routing(false){}
203  model->m_parent = this;
204  }
217  virtual void route(
218  Model<DataType,TimeType>* src, DataType data,
219  std::vector<std::pair<Model<DataType,TimeType>*,DataType> >& msgs) = 0;
221  virtual ~Network(){}
223  TimeType update(SimEnv<DataType,TimeType>*) { return adevs_inf<TimeType>(); }
225  TimeType update(SimEnv<DataType,TimeType>*, std::vector<DataType>&) {
226  return adevs_inf<TimeType>();
227  }
229  TimeType init(SimEnv<DataType,TimeType>*) { return adevs_inf<TimeType>(); }
231  void fini(TimeType){}
233  std::pair<Model<DataType,TimeType>*,DataType> relay(
234  Model<DataType,TimeType>* src, DataType x);
235  private:
236  std::vector<std::pair<Model<DataType,TimeType>*,DataType> > msgs;
237  unsigned pos;
238  bool routing;
239 };
240 
241 template <typename DataType, typename TimeType>
242 std::pair<Model<DataType,TimeType>*,DataType>
244 {
245  if (!routing)
246  {
247  // If the source is our parent, route it to our children
248  if (src == this->parent() || src == NULL)
249  route(this,x,msgs);
250  // The source is us or a child of the network
251  else
252  route(src,x,msgs);
253  routing = true;
254  pos = 0;
255  }
256  while (pos < msgs.size())
257  {
258  // This is a message to child of the network
259  if (msgs[pos].first != this)
260  {
261  return msgs[pos++];
262  }
263  // Output from the network goes to its parent to be routed
264  if (this->parent() != NULL)
265  {
266  msgs[pos].first = this->parent();
267  return msgs[pos++];
268  }
269  pos++;
270  }
271  msgs.clear();
272  routing = false;
273  return std::pair<Model<DataType,TimeType>*,DataType>(NULL,x);
274 }
275 
277 template <typename DataType>
279 {
281  int port;
283  DataType value;
284  port_value(){}
286  port_value(int port, DataType value):
287  port(port),value(value){}
288 };
289 
291 template <typename DataType, typename TimeType=Time>
292 class Digraph:
293  public Network<port_value<DataType>,TimeType>
294 {
295  public:
296  Digraph():Network<port_value<DataType>,TimeType>(){}
297  ~Digraph();
303  void add(SimEnv<port_value<DataType>,TimeType>* env);
311  void couple(Devs<port_value<DataType>,TimeType>* src, int src_port,
312  Devs<port_value<DataType>,TimeType>* dst, int dst_port);
314  void route(
315  Model<port_value<DataType>,TimeType>* src, port_value<DataType> data,
316  std::vector<std::pair<Model<port_value<DataType>,TimeType>*,
317  port_value<DataType> > >& msgs);
318  private:
319  std::set<Devs<port_value<DataType>,TimeType>* > models;
320  std::map<std::pair<Model<port_value<DataType>,TimeType>*,int>,
321  std::vector<std::pair<Model<port_value<DataType>,TimeType>*,int> > > graph;
322 };
323 
324 template <typename DataType, typename TimeType>
326 {
327  typename std::set<Devs<port_value<DataType>,TimeType>* >::iterator iter =
328  models.begin();
329  for (; iter != models.end(); iter++)
330  if (*iter != this)
331  delete *iter;
332 }
333 
334 template <typename DataType, typename TimeType>
336  SimEnv<port_value<DataType>,TimeType>* env)
337 {
338  typename std::set<Devs<port_value<DataType>,TimeType>* >::iterator iter =
339  models.begin();
340  for (; iter != models.end(); iter++)
341  {
342  if (*iter != this)
343  {
344  this->assign_parent(*iter);
345  (*iter)->add(env);
346  }
347  }
348 }
349 
350 template <typename DataType, typename TimeType>
352  Devs<port_value<DataType>,TimeType>* src, int src_port,
353  Devs<port_value<DataType>,TimeType>* dst, int dst_port)
354 {
355  models.insert(src);
356  models.insert(dst);
357  std::pair<Model<port_value<DataType>,TimeType>*,int> a(src,src_port);
358  std::pair<Model<port_value<DataType>,TimeType>*,int> b(dst,dst_port);
359  graph[a].push_back(b);
360 }
361 
362 template <typename DataType, typename TimeType>
364  Model<port_value<DataType>,TimeType>* src, port_value<DataType> data,
365  std::vector<std::pair<Model<port_value<DataType>,TimeType>*,
366  port_value<DataType> > >& msgs)
367 {
368  std::pair<Model<port_value<DataType>,TimeType>*,int> a(src,data.port);
369  typename std::map<std::pair<Model<port_value<DataType>,TimeType>*,int>,
370  std::vector<std::pair<Model<port_value<DataType>,TimeType>*,int> > >::const_iterator
371  iter = graph.find(a);
372  if (iter != graph.end())
373  {
374  const std::vector<std::pair<Model<port_value<DataType>,TimeType>*,int> >&
375  link = (*iter).second;
376  for (unsigned i = 0; i < link.size(); i++)
377  {
378  data.port = link[i].second;
379  msgs.push_back(
380  std::pair<Model<port_value<DataType>,TimeType>*,port_value<DataType> >(
381  link[i].first,data));
382  }
383  }
384 }
385 
391 template <typename DataType, typename TimeType=Time>
393  public Network<DataType,TimeType>
394 {
395  public:
397  ~SimpleDigraph();
403  void add(SimEnv<DataType,TimeType>* env);
409  void couple(Devs<DataType,TimeType>* src, Devs<DataType,TimeType>* dst);
411  void route(
412  Model<DataType,TimeType>* src, DataType data,
413  std::vector<std::pair<Model<DataType,TimeType>*,DataType> >& msgs);
414  private:
415  std::set<Devs<DataType,TimeType>* > models;
416  std::map<Model<DataType,TimeType>*,
417  std::vector<Model<DataType,TimeType>* > > graph;
418 };
419 
420 template <typename DataType, typename TimeType>
422 {
423  typename std::set<Devs<DataType,TimeType>* >::iterator iter =
424  models.begin();
425  for (; iter != models.end(); iter++)
426  if (*iter != this)
427  delete *iter;
428 }
429 
430 template <typename DataType, typename TimeType>
432 {
433  typename std::set<Devs<DataType,TimeType>* >::iterator iter =
434  models.begin();
435  for (; iter != models.end(); iter++)
436  {
437  if (*iter != this)
438  {
439  this->assign_parent(*iter);
440  (*iter)->add(env);
441  }
442  }
443 }
444 
445 template <typename DataType, typename TimeType>
448 {
449  models.insert(src);
450  models.insert(dst);
451  graph[src].push_back(dst);
452 }
453 
454 template <typename DataType, typename TimeType>
456  Model<DataType,TimeType>* src, DataType data,
457  std::vector<std::pair<Model<DataType,TimeType>*,
458  DataType> >& msgs)
459 {
460  typename std::map<Model<DataType,TimeType>*,
461  std::vector<Model<DataType,TimeType>* > >::const_iterator
462  iter = graph.find(src);
463  if (iter != graph.end())
464  {
465  const std::vector<Model<DataType,TimeType>*>& link =
466  (*iter).second;
467  for (unsigned i = 0; i < link.size(); i++)
468  {
469  msgs.push_back(
470  std::pair<Model<DataType,TimeType>*,DataType >(
471  link[i],data));
472  }
473  }
474 }
475 
476 }; // end of namespace
477 
478 #endif
DataType value
The message data.
Definition: adevs_pdevs.h:283
virtual void add(Model< DataType, TimeType > *model)=0
Add a model to the simulator.
void couple(Devs< port_value< DataType >, TimeType > *src, int src_port, Devs< port_value< DataType >, TimeType > *dst, int dst_port)
Create a link in the network.
Definition: adevs_pdevs.h:351
std::pair< Model< DataType, TimeType > *, DataType > relay(Model< DataType, TimeType > *src, DataType x)
Relay uses the route method to redirect messages. Do not override.
Definition: adevs_pdevs.h:243
void route(Model< port_value< DataType >, TimeType > *src, port_value< DataType > data, std::vector< std::pair< Model< port_value< DataType >, TimeType > *, port_value< DataType > > > &msgs)
The network&#39;s route method. Do not override.
Definition: adevs_pdevs.h:363
port_value(int port, DataType value)
Assigns initial values to port and value.
Definition: adevs_pdevs.h:286
void assign_parent(Devs< DataType, TimeType > *model)
Set the parent of a model to be this Network.
Definition: adevs_pdevs.h:202
virtual std::pair< Model< DataType, TimeType > *, DataType > relay(Model< DataType, TimeType > *src, DataType x)
Relay a message to another model.
Definition: adevs_base.h:141
int port
Port on which the data is sent or arriving.
Definition: adevs_pdevs.h:281
void add(SimEnv< DataType, TimeType > *env)
Adds this model to the simulation context.
Definition: adevs_pdevs.h:85
A simple graph model.
Definition: adevs_pdevs.h:392
virtual void add(SimEnv< DataType, TimeType > *env)=0
Add this model and any submodels to the simulation.
Data type for a Digraph model.
Definition: adevs_pdevs.h:278
This is a Parallel DEVS network model.
Definition: adevs_pdevs.h:10
void fini(TimeType)
No op fini.
Definition: adevs_pdevs.h:83
virtual ~Network()
Destructor.
Definition: adevs_pdevs.h:221
virtual TimeType init(SimEnv< DataType, TimeType > *env)=0
Called when the model is added to the simulation.
void fini(TimeType)
No op fini.
Definition: adevs_pdevs.h:231
Definition: adevs_base.h:21
TimeType init(SimEnv< DataType, TimeType > *)
No op init.
Definition: adevs_pdevs.h:229
virtual TimeType update(SimEnv< DataType, TimeType > *env, std::vector< DataType > &x)=0
Called to assign a new state to the model at now() when input is present.
virtual void send(Model< DataType, TimeType > *src, Model< DataType, TimeType > *dst, DataType data)=0
Send a message to a model.
TimeType update(SimEnv< DataType, TimeType > *, std::vector< DataType > &)
No op update.
Definition: adevs_pdevs.h:225
This is the base class for all components in a Parallel DEVS model.
Definition: adevs_pdevs.h:22
void couple(Devs< DataType, TimeType > *src, Devs< DataType, TimeType > *dst)
Create a link in the network.
Definition: adevs_pdevs.h:446
TimeType init(SimEnv< DataType, TimeType > *env)
Schedules the first output event. Do not override this method.
Definition: adevs_pdevs.h:96
void add(SimEnv< port_value< DataType >, TimeType > *env)
Add this model and its submodels to the simulation context. You must couple your models first...
Definition: adevs_pdevs.h:335
Interface to a simulation context for sending messages, getting the time, and adding or removing mode...
Definition: adevs_base.h:38
TimeType update(SimEnv< DataType, TimeType > *env)
Definition: adevs_pdevs.h:104
A typical digraph network model with port value pairs for input and output.
Definition: adevs_pdevs.h:292
This class offers the standard PDEVS interface for an atomic model.
Definition: adevs_pdevs.h:53
TimeType update(SimEnv< DataType, TimeType > *)
No op update.
Definition: adevs_pdevs.h:223
A model in the simulation.
Definition: adevs_base.h:24
void route(Model< DataType, TimeType > *src, DataType data, std::vector< std::pair< Model< DataType, TimeType > *, DataType > > &msgs)
The network&#39;s route method. Do not override.
Definition: adevs_pdevs.h:455
Network< DataType, TimeType > * parent() const
Get the parent of this model.
Definition: adevs_pdevs.h:34
void add(SimEnv< DataType, TimeType > *env)
Add this model and its submodels to the simulation context. You must couple your models first...
Definition: adevs_pdevs.h:431
virtual TimeType now()=0
Get the current time.