DiaDes  0.1
DIAgnosis of Discrete-Event System
StateMachine.hh
Go to the documentation of this file.
1 /*
2  * @file StateMachine.hh
3  * @author Yannick Pencole, ypencole@laas.fr, LAAS-CNRS, Univ. Toulouse, FRANCE
4  *
5  * Created on 20 october 2017, 13:58
6  */
7 
8 #ifndef __DIADES__AUTOMATA__STATEMACHINE_HH__
9 #define __DIADES__AUTOMATA__STATEMACHINE_HH__
10 #include <unordered_set>
11 #include <unordered_map>
12 #include <set>
13 #include <tuple>
14 #include <diades/utils/Pointer.hh>
18 #include <diades/utils/Iterator.hh>
20 #include <diades/graph/Graph.hh>
21 #include <diades/graph/NodeMap.hh>
22 #include <diades/graph/EdgeMap.hh>
25 
26 
27 namespace Diades
28 {
29  namespace Automata
30  {
31  namespace Experimental
32  {
33  using Diades::Utils::Msg;
35  using std::unordered_set;
36  using std::unordered_map;
37  using std::set;
38 
39 
43  using StatePropertyIdAsSizeT = size_t;
44 
45  template<typename StatePropertyId, typename EventPropertyId, typename NullStatePropertyId, typename NullEventPropertyId>
46  class StateMachine;
47 
50  template<typename StatePropertyId, typename EventPropertyId, typename InputIterator, typename NullStateProperty, typename NullEventProperty>
52 
53  template<typename StatePropertyId, typename EventPropertyId, typename InputIterator, typename NullStateProperty, typename NullEventProperty>
54  inline void deleteState(StateMachine<StatePropertyId, EventPropertyId, NullStateProperty, NullEventProperty> & m, InputIterator first, InputIterator last);
55 
56 
57 
58  template<typename StatePropertyId, typename EventPropertyId, typename InputIterator, typename Predicate, typename NullStatePropertyId = NullValue<StatePropertyId>, typename NullEventPropertyId>
59  inline void
60  deleteState(StateMachine<StatePropertyId, EventPropertyId, NullStatePropertyId, NullEventPropertyId> & m, InputIterator first, InputIterator last, Predicate pred);
61 
80  template<typename _StatePropertyId,
81  typename _EventPropertyId,
82  typename _NullStatePropertyId = NullValue<_StatePropertyId>,
83  typename _NullEventPropertyId = NullValue<_EventPropertyId>>
84  class StateMachine
85  {
86  public:
87  using StatePropertyId = _StatePropertyId;
88  using EventPropertyId = _EventPropertyId;
89  using NullStatePropertyId = _NullStatePropertyId;
90  using NullEventPropertyId = _NullEventPropertyId;
91  using Id = size_t;
92 
93  private:
102  using StatePropertyIdIndex = size_t;
103 
104 
105 
106 
115  using EventPropertyIdIndex = size_t;
116 
121  const size_t _nullStatePropertyIdIndex = std::numeric_limits<StatePropertyIdIndex>::max();
122 
123  public:
124 
127 
128  static string
130  {
131  return "noname";
132  }
133 
134  static string
136  {
137  return "Automata::StateMachine";
138  }
140 
141 
142  public:
147  typedef list<Transition>::const_iterator EventTransitionIterator;
148  typedef unordered_set<State>::const_iterator InitialStateIterator;
151  typedef typename vector<EventPropertyId>::const_iterator EventPropertyIdIterator;
152  typedef unordered_set<Transition>::const_iterator OutputEventTransitionIterator;
153  typedef unordered_set<Transition>::const_iterator InputEventTransitionIterator;
154  typedef unordered_set<State>::const_iterator LabelledStateIterator;
155 
156 
157 
158 
159 
160  protected:
162  unordered_set<State> _initial;
165  private:
166  string _name;
167  Id _id;
170  vector<EventPropertyId> _eventPropertyIds;
171  unordered_map<EventPropertyId, EventPropertyIdIndex> _indexOfEventPropertyId;
173 
174  vector<StatePropertyId> _statePropertyIds;
176  unordered_map<StatePropertyId, StatePropertyIdIndex> _indexOfStatePropertyIdIndex;
178  unordered_set<State> _nullStatePropertyIdStates;
182  vector< Diades::Graph::NodeMap< unordered_set<Transition> > > _transitionsWithTarget;
183  vector< Diades::Graph::NodeMap< unordered_set<Transition> > > _transitionsWithSource;
184  vector< unordered_set<State> > _sourceWithEventPropertyIdIndex;
185  vector< unordered_set<State> > _targetWithEventPropertyIdIndex;
186  vector< list<Transition> > _transitionsWithEventPropertyIdIndex;
187 
197  template<typename _Iterator>
199  {
200  public:
203  using Iterator = _Iterator;
204 
205  const Data & operator()(const MapStructure & m, Iterator it) const
206  {
207  return m.getStatePropertyId(*it);
208  }
209  };
210 
211 
212  protected:
213 
220  getEventFromIndex(size_t index) const
221  {
222  return _eventPropertyIds[index];
223  }
224 
225  public:
226 
233  template<typename StateIterator>
235 
236 
237  public:
238 
239 
240  /*********************************************************************/
241  /* GENERAL MANAGEMENT */
242  /*********************************************************************/
243 
247  StateMachine() : _behav(),
248  _initial(),
249  _isInitial(),
250  _name(defaultStateMachineName()),
251  _id(),
252  _eventPropertyIds(),
253  _indexOfEventPropertyId(),
254  _eventPropertyIdIndexOfTransition(),
255  _statePropertyIds(),
256  _stateOfStatePropertyIdIndex(),
257  _indexOfStatePropertyIdIndex(),
258  _statePropertyIdIndexOfState(),
259  _nullStatePropertyIdStates(),
260  _transitionsWithTarget(),
261  _transitionsWithSource(),
262  _sourceWithEventPropertyIdIndex(),
263  _targetWithEventPropertyIdIndex(),
264  _transitionsWithEventPropertyIdIndex()
265  {
266  _eventPropertyIdIndexOfTransition.init(_behav);
267  _statePropertyIdIndexOfState.init(_behav);
268  _isInitial.init(_behav, 0);
269  }
270 
275  StateMachine(const StateMachine & machine) :
276  _behav(machine._behav),
277  _initial(),
278  _isInitial(),
279  _name(machine.name()),
280  _id(machine.id()),
281  _eventPropertyIds(machine._eventPropertyIds),
282  _indexOfEventPropertyId(machine._indexOfEventPropertyId),
283  _eventPropertyIdIndexOfTransition(),
284  _statePropertyIds(machine._statePropertyIds),
285  _stateOfStatePropertyIdIndex(),
286  _indexOfStatePropertyIdIndex(machine._indexOfStatePropertyIdIndex),
287  _statePropertyIdIndexOfState(),
288  _nullStatePropertyIdStates(),
289  _transitionsWithTarget(),
290  _transitionsWithSource(),
291  _sourceWithEventPropertyIdIndex(),
292  _targetWithEventPropertyIdIndex(),
293  _transitionsWithEventPropertyIdIndex()
294  {
295  finaliseEventPropertyIds(machine);
296  finaliseInitialStates(machine);
297  finaliseStatePropertyIds(machine);
298  finaliseTransitions(machine);
299  }
300 
307  {
308  if(this != &machine)
309  {
310  clear();
311  _behav = machine._behav;
312  _name = machine.name();
313  _id = machine.id();
314  _eventPropertyIds = machine._eventPropertyIds;
315  _indexOfEventPropertyId = machine._indexOfEventPropertyId;
316  _statePropertyIds = machine._statePropertyIds;
317  _indexOfStatePropertyIdIndex = machine._indexOfStatePropertyIdIndex;
318  finaliseEventPropertyIds(machine);
319  finaliseInitialStates(machine);
320  finaliseStatePropertyIds(machine);
321  finaliseTransitions(machine);
322  }
323  return *this;
324  }
325 
329  virtual
331  {
332  clear();
333  }
334 
343  bool operator==(const StateMachine & machine) const
344  {
345  return this == &machine;
346  }
347 
356  bool operator!=(const StateMachine & machine) const
357  {
358  return !(*this == machine);
359  }
360 
364  virtual void
366  {
367  _behav.clear();
368  _initial.clear();
369  _isInitial.clear();
370  _name = defaultStateMachineName();
371  _id = 0;
372  _eventPropertyIds.clear();
373  _indexOfEventPropertyId.clear();
374  _eventPropertyIdIndexOfTransition.clear();
375  _statePropertyIds.clear();
376  _stateOfStatePropertyIdIndex.clear();
377  _indexOfStatePropertyIdIndex.clear();
378  _statePropertyIdIndexOfState.clear();
379  _nullStatePropertyIdStates.clear();
380  _transitionsWithTarget.clear();
381  _transitionsWithSource.clear();
382  _sourceWithEventPropertyIdIndex.clear();
383  _targetWithEventPropertyIdIndex.clear();
384  _transitionsWithEventPropertyIdIndex.clear();
385  _eventPropertyIdIndexOfTransition.init(_behav);
386  _statePropertyIdIndexOfState.init(_behav);
387  _isInitial.init(_behav, 0);
388  }
389 
397  Id
398  id() const
399  {
400  return _id;
401  }
402 
409  Id
410  setId(Id identifier)
411  {
412  return _id = identifier;
413  }
414 
418  Graph::Graph &
420  {
421  return _behav;
422  }
423 
427  const Graph::Graph &
428  behaviour() const
429  {
430  return _behav;
431  }
432 
436  bool
437  isEmpty() const
438  {
439  return(_behav.empty());
440  }
441 
448  bool
449  isValid() const
450  {
451  return !isEmpty() && name() != defaultStateMachineName();
452  }
453 
454 
455  /*********************************************************************/
456  /* NAME MANAGEMENT */
457  /*********************************************************************/
458 
463  const string &
464  setName(const string & name)
465  {
466 
467  return _name = name;
468 
469  }
470 
474  const string &
475  name() const
476  {
477 
478  return _name;
479  }
480  /********************************************************************/
481 
482 
483  /*********************************************************************/
484  /* EVENT MANAGEMENT */
485  /*********************************************************************/
486 
492  nullEvent() const
493  {
494  return nullEventPropertyId;
495  }
496 
502  bool
504  {
505  return evt == nullEventPropertyId;
506  }
507 
516  void
518  {
519  insertEventPropertyId(event);
520  }
521 
529  void
531  {
532  std::for_each(m.eventBegin(), m.eventEnd(),
533  [&](EventPropertyId event)
534  {
535  copyEventPropertyId(m, event);
536  }
537  );
538  }
539 
544  virtual
545  void
547  {
548  if(!containsEvent(event))
549  {
550  _eventPropertyIds.push_back(event);
551  //_normalEventPropertyIds.insert(event);
552  _indexOfEventPropertyId[event] = numberOfEvents() - 1;
553 
554  if(numberOfEvents() > _transitionsWithTarget.size())
555  {
556  if(_transitionsWithTarget.size() == _transitionsWithTarget.capacity())
557  {
558  require(Exception, numberOfEvents() < _transitionsWithTarget.max_size(),
559  "insertEvent: too many events, memory allocation will fail");
560  size_t capacity = _transitionsWithTarget.max_size();
561  if(_transitionsWithTarget.max_size() / 2 > numberOfEvents())
562  {
563  capacity = 2 * numberOfEvents();
564  }
565  _transitionsWithTarget.reserve(capacity);
566  _transitionsWithSource.reserve(capacity);
567  _sourceWithEventPropertyIdIndex.reserve(capacity);
568  _targetWithEventPropertyIdIndex.reserve(capacity);
569  _transitionsWithEventPropertyIdIndex.reserve(capacity);
570  }
571  _transitionsWithTarget.resize(numberOfEvents());
572  _transitionsWithSource.resize(numberOfEvents());
573  _sourceWithEventPropertyIdIndex.resize(numberOfEvents());
574  _targetWithEventPropertyIdIndex.resize(numberOfEvents());
575  _transitionsWithEventPropertyIdIndex.resize(numberOfEvents());
576  }
577 
578  _transitionsWithSource[numberOfEvents() - 1].init(_behav);
579  _transitionsWithTarget[numberOfEvents() - 1].init(_behav);
580  }
581  ensure(Exception, containsEvent(event), "insertEvent: the event is not properly recorded");
582  ensure(Exception, _sourceWithEventPropertyIdIndex.size() > numberOfEvents() - 1, "insertEvent: size problem in internal structures");
583  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _transitionsWithTarget.size(), "insertEvent: size problem in internal structures (_sourceWithEvent.size() != _transitionsWithTarget.size()");
584  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _transitionsWithSource.size(), "insertEvent: size problem in internal structures (_sourceWithEvent.size() != _transitionsWithSource.size() ");
585  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _targetWithEventPropertyIdIndex.size(), "insertEvent: size problem in internal structures (_sourceWithEvent.size() != _targetWithEvent.size()");
586  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _transitionsWithEventPropertyIdIndex.size(), "insertEvent: size problem in internal structures (_sourceWithEvent.size() != _transitionsWithEvent.size()");
587  }
588 
593  unsigned
595  {
596  return _eventPropertyIds.size();
597  }
598 
606  template<typename EventIter>
607  void
608  insertEvent(EventIter start, EventIter end)
609  {
610  EventIter it = start;
611  while(it != end)
612  {
614  ++it;
615  }
616 
617 
618 
619  }
620 
626  const EventPropertyId &
627  getEvent(Transition t) const
628  {
629  require(Exception, t.valid(), "getEvent: invalid transition");
630  require(Exception, &t.owner() == &_behav, "getEvent: the transition does not belong to this machine");
631  return _eventPropertyIds[_eventPropertyIdIndexOfTransition[t]];
632  }
633 
641  const vector<EventPropertyId> &
642  events() const
643  {
644  return _eventPropertyIds;
645  }
646 
651  EventPropertyIdIterator
652  eventBegin() const
653  {
654  return _eventPropertyIds.begin();
655  }
656 
661  EventPropertyIdIterator
662  eventEnd() const
663  {
664  return _eventPropertyIds.end();
665  }
666 
673  bool
675  {
676  return std::find(_eventPropertyIds.begin(), _eventPropertyIds.end(), e)
677  != _eventPropertyIds.end();
678  }
679 
688  void
690  {
691  if(containsEvent(e1))
692  {
693  if(e1 != e2)
694  {
695  if(!containsEvent(e2))
696  {
698  }
699  auto e1Id = _indexOfEventPropertyId.at(e1);
700  auto e2Id = _indexOfEventPropertyId.at(e2);
701 
702  for(list<Transition>::const_iterator transIt = _transitionsWithEventPropertyIdIndex[e1Id].begin();
703  transIt != _transitionsWithEventPropertyIdIndex[e1Id].end();
704  ++transIt)
705  {
706  _sourceWithEventPropertyIdIndex[e2Id].insert(transIt->source());
707  _targetWithEventPropertyIdIndex[e2Id].insert(transIt->target());
708  _transitionsWithEventPropertyIdIndex[e2Id].push_back(*transIt);
709  _eventPropertyIdIndexOfTransition[*transIt] = e2Id;
710  _transitionsWithSource[e2Id][transIt->source()].insert(*transIt);
711  _transitionsWithTarget[e2Id][transIt->target()].insert(*transIt);
712  }
714  }
715  }
716  }
717 
718 
719  /********************************************************************/
720 
726  void
728  {
730  eraseEventPropertyId(_indexOfEventPropertyId.at(e));
731  }
732 
733 
734  /*******************************************************************/
735  /* STATE MANAGEMENT */
736  /*********************************************************************/
737 
747  State
749  {
750  State result = _behav.newNode();
751  _nullStatePropertyIdStates.insert(result);
752  _statePropertyIdIndexOfState[result] = _nullStatePropertyIdIndex;
753  return result;
754  }
755 
767  std::pair<State, bool>
768  newState(const StatePropertyId & sProperty)
769  {
770  State result;
771  bool present = false;
772  if(NullStatePropertyId()(sProperty))
773  {
774  return std::make_pair(newState(), true);
775  }
776 
777 
778  auto it = _indexOfStatePropertyIdIndex.find(sProperty);
779  if(it != _indexOfStatePropertyIdIndex.end())
780  {
781  result = _stateOfStatePropertyIdIndex[it->second];
782  assertion(Exception, result.valid(), "newState: _stateOfProperty is incorrectly initialised");
783  }
784  else
785  {
786  present = true;
787  result = _behav.newNode();
788 
789 
790  _indexOfStatePropertyIdIndex[sProperty] = _statePropertyIds.size();
791  _statePropertyIdIndexOfState[result] = _statePropertyIds.size();
792  _statePropertyIds.push_back(sProperty);
793  _stateOfStatePropertyIdIndex.push_back(result);
794 
795  }
796 
797  ensure(Exception, result.valid() && (_statePropertyIdIndexOfState[result] == _indexOfStatePropertyIdIndex[sProperty]), "newState");
799  "newState: inconsistency between getStateFromIndex/getIndexOfState");
800  return std::make_pair(result, present);
801  }
802 
808  const StatePropertyId &
809  getStatePropertyId(State state) const
810  {
811  require(Exception, state.valid(), "getProperty: invalid state");
812  require(Exception, &state.owner() == &_behav, "getProperty: the state does not belong to this machine");
813  if(isNullState(state))
814  {
815  return nullStatePropertyId;
816  }
817  return _statePropertyIds[_statePropertyIdIndexOfState[state]];
818  }
819 
830  bool
831  setStatePropertyId(State state, const StatePropertyId & sProperty)
832  {
833  require(Exception, state.valid(), "setProperty: invalid state");
834  require(Exception, &state.owner() == &_behav, "setProperty: the state does not belong to this machine");
835  auto it = _indexOfStatePropertyIdIndex.find(sProperty);
836  bool isNullProperty = (sProperty == nullStatePropertyId);
837  bool success = true;
838  if(!isNullProperty)
839  {
840  success = it == _indexOfStatePropertyIdIndex.end();
841  if(!success)
842  {
843  success = _statePropertyIdIndexOfState[state] == it->second;
844  return success;
845  }
846  }
847  // state will certainly assigned to sProperty
848  if(isNullState(state) && isNullProperty)
849  {
850  return success;
851  }
852 
853  if(isNullState(state))
854  {
855  _nullStatePropertyIdStates.erase(state);
856  _indexOfStatePropertyIdIndex[sProperty] = _statePropertyIds.size();
857  _statePropertyIdIndexOfState[state] = _statePropertyIds.size();
858  _statePropertyIds.push_back(sProperty);
859  _stateOfStatePropertyIdIndex.push_back(state);
860  return success;
861  }
862 
863  eraseStatePropertyId(state);
864 
865  // and we add the new one
866  if(isNullProperty)
867  {
868  _statePropertyIdIndexOfState[state] = _nullStatePropertyIdIndex;
869  _nullStatePropertyIdStates.insert(state);
870  }
871  else
872  {
873  _indexOfStatePropertyIdIndex[sProperty] = _statePropertyIds.size();
874  _statePropertyIdIndexOfState[state] = _statePropertyIds.size();
875  _statePropertyIds.push_back(sProperty);
876  _stateOfStatePropertyIdIndex.push_back(state);
877  }
878  if(!isNullProperty)
879  {
881  "setStatePropertyId: inconsistency between getStateFromIndex/getIndexOfState");
882  }
883  return success;
884  }
885 
891  State
892  getState(const StatePropertyId & sProperty) const
893  {
894  auto it = _indexOfStatePropertyIdIndex.find(sProperty);
895  //require(Exception, it != _stateOfProperty.end(), "getState: no such a state");
896  if(it == _indexOfStatePropertyIdIndex.end())
897  {
898  return State();
899  }
900  return _stateOfStatePropertyIdIndex[it->second];
901  }
902 
908  virtual void
909  deleteState(State state)
910  {
911  require(Exception, state.valid(), "deleteState: invalid state");
912  require(Exception, &state.owner() == &_behav, "deleteState: the state does not belong to this state machine");
913 unsetInitial(state);
914 
915  if(isNullState(state))
916  {
917  _nullStatePropertyIdStates.erase(state);
918  }
919  else
920  {
921 
922  // here we need to erase the state property
923  if(_statePropertyIdIndexOfState[state] == _statePropertyIds.size() - 1)
924  {
925  //cool it is the last recorded property
926  _indexOfStatePropertyIdIndex.erase(_statePropertyIds.back());
927  _stateOfStatePropertyIdIndex.pop_back();
928  _statePropertyIds.pop_back();
929  _statePropertyIdIndexOfState[state] = _nullStatePropertyIdIndex;
930  }
931  else
932  {
933  // not cool we need to swap to have a tidy vector
934  auto stateWhosePropertyIsSwapped = _stateOfStatePropertyIdIndex[_statePropertyIds.size() - 1];
935 
936 
937 
938  auto & keptProperty = _statePropertyIds[_statePropertyIdIndexOfState[state]];
939  auto & erasedProperty = _statePropertyIds[_statePropertyIds.size() - 1];
940  std::swap(keptProperty, erasedProperty);
941  size_t keptPropertyIndex = _statePropertyIdIndexOfState[state];
942  _statePropertyIdIndexOfState[stateWhosePropertyIsSwapped] = keptPropertyIndex;
943  _stateOfStatePropertyIdIndex[keptPropertyIndex] = stateWhosePropertyIsSwapped;
944  _indexOfStatePropertyIdIndex[keptProperty] = keptPropertyIndex;
945 
946  _indexOfStatePropertyIdIndex.erase(_statePropertyIds.back());
947  _stateOfStatePropertyIdIndex.pop_back();
948  _statePropertyIds.pop_back();
949  _statePropertyIdIndexOfState[state] = _nullStatePropertyIdIndex;
950 
951  }
952  }
955  _behav.deleteNode(state);
956 
957 
958  }
959 
966  void
967  deleteState(StateIterator start, StateIterator end)
968  {
969  //list<State> tmp;
970  //tmp.insert(tmp.end(), start, end);
971  // Automata::Experimental::deleteState(*this, tmp.begin(), tmp.end());
972  Automata::Experimental::deleteState(*this, start, end);
973  }
974 
979  unsigned
981  {
982  return _behav.numberOfNodes();
983  }
984 
988  StateIterator
989  stateBegin() const
990  {
991  return _behav.nodeBegin();
992  }
993 
997  StateIterator
998  stateEnd() const
999  {
1000  return _behav.nodeEnd();
1001  }
1002 
1007  typedef typename std::vector<StatePropertyId>::const_iterator StatePropertyIdIterator;
1008 
1012  StatePropertyIdIterator
1014  {
1015  return _statePropertyIds.begin();
1016  }
1017 
1021  StatePropertyIdIterator
1023  {
1024  return _statePropertyIds.end();
1025  }
1026 
1035  template<typename StateIterator>
1037  statePropertyIdRangeIterator(StateIterator iterator) const
1038  {
1039  return StatePropertyIdRangeIterator<StateIterator>(*this, iterator);
1040  }
1041 
1047  void
1048  setInitial(State state)
1049  {
1050  if(state.valid() && (&state.owner() == &_behav))
1051  {
1052  _initial.insert(state);
1053  _isInitial[state] = 1;
1054  }
1055  }
1056 
1062  void
1063  unsetInitial(State state)
1064  {
1065  if(state.valid() && (&state.owner() == &_behav))
1066  {
1067  _initial.erase(state);
1068  _isInitial[state] = 0;
1069  }
1070  }
1071 
1076  void
1078  {
1079  _initial.insert(stateBegin(), stateEnd());
1080  _isInitial.initValue(stateBegin(), stateEnd(), 1);
1081  }
1082 
1087  void
1089  {
1090  _isInitial.initValue(stateBegin(), stateEnd(), 0);
1091  _initial.clear();
1092  }
1093 
1094 
1102  void swapInitialState(State state)
1103  {
1104  if(isInitial(state))
1105  {
1106  unsetInitial(state);
1107  }
1108  else
1109  {
1110  setInitial(state);
1111  }
1112  }
1113 
1120  InitialStateIterator
1122  {
1123  return _initial.begin();
1124  }
1125 
1132  InitialStateIterator
1134  {
1135  return _initial.end();
1136  }
1137 
1144  unsigned
1146  {
1147  return _initial.size();
1148  }
1149 
1157  bool
1158  isInitial(State state) const
1159  {
1160  return(state.valid()) && (&state.owner() == &_behav) && (_isInitial[state] == 1);
1161  }
1162 
1168  bool
1169  isNullState(State state) const
1170  {
1171  return _statePropertyIdIndexOfState[state] == _nullStatePropertyIdIndex;
1172  }
1173 
1174 
1175 
1176 
1177 
1178 
1179 
1180 
1181 
1182  /*******************************************************************/
1183  /* TRANSITION MANAGEMENT */
1184  /*********************************************************************/
1185 
1186  public:
1187 
1198  Transition
1199  newTransition(State source, State target, const EventPropertyId & event)
1200  {
1201  require(Exception, source.valid(), "newTransition: invalid source state");
1202  require(Exception, &source.owner() == &_behav, "newTransition: the source state does not belong to this component");
1203  require(Exception, target.valid(), "newTransition: invalid target state");
1204  require(Exception, &target.owner() == &_behav, "newTransition: the target state does not belong to this component");
1205 
1206  Transition result;
1207  insertEventPropertyId(event);
1208  bool found = false;
1209  OutputEventTransitionIterator it = outputEventTransitionBegin(source, event);
1210  OutputEventTransitionIterator itEnd = outputEventTransitionEnd(source, event);
1211 
1212  while(!found && (it != itEnd))
1213  {
1214  found = (target == it->target());
1215  if(!found)
1216  {
1217  ++it;
1218  }
1219  }
1220  if(found)
1221  {
1222  result = *it;
1223  }
1224  else
1225  {
1226 
1227  result = _behav.newEdge(source, target);
1228  assertion(Exception, result.valid(), "the result is not valid");
1229  assertion(Exception, &result.owner() == &_behav, "the result has not the right owner");
1230  _eventPropertyIdIndexOfTransition[result] = _indexOfEventPropertyId[event];
1231  assertion(Exception, _eventPropertyIdIndexOfTransition[result] == _indexOfEventPropertyId[event], "the event of result is not correctly set");
1232  size_t eventIndex = _indexOfEventPropertyId[event];
1233 
1234  _transitionsWithTarget[eventIndex][target].insert(result);
1235  _transitionsWithSource[eventIndex][source].insert(result);
1236  _sourceWithEventPropertyIdIndex[eventIndex].insert(source);
1237  _targetWithEventPropertyIdIndex[eventIndex].insert(target);
1238  _transitionsWithEventPropertyIdIndex[eventIndex].push_back(result);
1239  }
1240  ensure(Exception, result.valid(), "newTransition: the returned transition is invalid!");
1241  ensure(Exception, result.source() == source, "newTransition: the returned transition has an incorrect source");
1242  ensure(Exception, result.target() == target, "newTransition: the returned transition has an incorrect target");
1243  ensure(Exception, getEvent(result) == event, "newTransition: the returned transition has an incorrect event");
1244  return result;
1245  }
1246 
1256  Transition
1258  const StatePropertyId & target,
1259  const EventPropertyId & event)
1260  {
1261  return newTransition(std::get<0>(newState(source)), std::get<0>(newState(target)), event);
1262  }
1263 
1268  void
1269  deleteTransition(Transition t)
1270  {
1271  require(Exception, t.valid(), "deleteTransition: invalid transition");
1272  require(Exception, &t.owner() == &_behav, "deleteTransition: the transition does not belong to the component");
1273  const auto & e = getEvent(t);
1274  const auto & target = t.target();
1275  const auto & source = t.source();
1276  size_t eventIndex = _indexOfEventPropertyId.at(e);
1277  _transitionsWithTarget[eventIndex][target].erase(t);
1278  if(_transitionsWithTarget[eventIndex][target].empty())
1279  {
1280  _targetWithEventPropertyIdIndex[eventIndex].erase(target);
1281  }
1282 
1283  _transitionsWithSource[eventIndex][source].erase(t);
1284  if(_transitionsWithSource[eventIndex][source].empty())
1285  {
1286  _sourceWithEventPropertyIdIndex[eventIndex].erase(source);
1287  }
1288 
1289 
1290  _transitionsWithEventPropertyIdIndex[eventIndex].remove(t);
1291  _behav.deleteEdge(t);
1292 
1293 
1294  }
1295 
1301  void
1302  deleteTransition(TransitionIterator start, TransitionIterator end)
1303  {
1304  list<Transition> tmp;
1305  tmp.insert(tmp.end(), start, end);
1306  Automata::Experimental::deleteTransition(*this, tmp.begin(), tmp.end());
1307 
1308 
1309 
1310  }
1311 
1317  void
1318  deleteTransition(EventTransitionIterator start, EventTransitionIterator end)
1319  {
1320  list<Transition> tmp;
1321  tmp.insert(tmp.end(), start, end);
1322  Automata::Experimental::deleteTransition(*this, tmp.begin(), tmp.end());
1323 
1324  }
1325 
1331  LabelledStateIterator
1333  {
1335  "beginOfSourceStateOfEvent: the event does not belong to the component");
1336  return _sourceWithEventPropertyIdIndex[_indexOfEventPropertyId.at(e)].begin();
1337  }
1338 
1344  LabelledStateIterator
1346  {
1348  "endOfSourceStateOfEvent: the event does not belong to the component");
1349  return _sourceWithEventPropertyIdIndex[_indexOfEventPropertyId.at(e)].end();
1350  }
1351 
1357  LabelledStateIterator
1359  {
1361  "beginOfTargetStateOfEvent: the event does not belong to the component");
1362  return _targetWithEventPropertyIdIndex[_indexOfEventPropertyId.at(e)].begin();
1363  }
1364 
1370  LabelledStateIterator
1372  {
1374  "endOfTargetStateOfEvent: the event does not belong to the component");
1375  return _targetWithEventPropertyIdIndex[_indexOfEventPropertyId.at(e)].end();
1376  }
1377 
1383  EventTransitionIterator
1385  {
1387  "eventTransitionBegin: the event does not belong to the component");
1388  return _transitionsWithEventPropertyIdIndex[_indexOfEventPropertyId.at(e)].begin();
1389  }
1390 
1396  EventTransitionIterator
1398  {
1400  "eventTransitionEnd: the event does not belong to the component");
1401  return _transitionsWithEventPropertyIdIndex[_indexOfEventPropertyId.at(e)].end();
1402  }
1403 
1411  OutputEventTransitionIterator
1413  {
1414 
1416  Msg("outputEventTransitionBegin: the event '%1%' does not belong to the component") % e);
1417  require(Exception, s.valid(), "outputEventTransitionBegin: invalid state");
1418  require(Exception, &s.owner() == &_behav, "outputEventTransitionBegin: the state does not belong to this component");
1419  return _transitionsWithSource[_indexOfEventPropertyId.at(e)][s].begin();
1420  }
1421 
1429  OutputEventTransitionIterator
1430  outputEventTransitionEnd(State s, const EventPropertyId & e) const
1431  {
1433  Msg("outputEventTransitionEnd: the event '%1%' does not belong to the component") % e);
1434  require(Exception, s.valid(), "outputEventTransitionEnd: invalid state");
1435  require(Exception, &s.owner() == &_behav, "outputEventTransitionEnd: the state does not belong to this component");
1436  return _transitionsWithSource[_indexOfEventPropertyId.at(e)][s].end();
1437  }
1438 
1446  InputEventTransitionIterator
1447  inputEventTransitionBegin(State s, const EventPropertyId & e) const
1448  {
1450  Msg("inputEventTransitionBegin: the event '%1%' does not belong to the component") % e);
1451  require(Exception, s.valid(), "inputEventTransitionBegin: invalid state");
1452  require(Exception, &s.owner() == &_behav, "inputEventTransitionBegin: the state does not belong to this component");
1453  return _transitionsWithTarget[_indexOfEventPropertyId.at(e)][s].begin();
1454  }
1455 
1463  InputEventTransitionIterator
1464  inputEventTransitionEnd(State s, const EventPropertyId & e) const
1465  {
1467  Msg("inputEventTransitionEnd: the event '%1%' does not belong to the component") % e);
1468  require(Exception, s.valid(), "inputEventTransitionEnd: invalid state");
1469  require(Exception, &s.owner() == &_behav, "inputEventTransitionEnd: the state does not belong to this component");
1470  return _transitionsWithTarget[_indexOfEventPropertyId.at(e)][s].end();
1471  }
1472 
1476  TransitionIterator
1478  {
1479  return _behav.edgeBegin();
1480  }
1481 
1485  TransitionIterator
1487  {
1488  return _behav.edgeEnd();
1489  }
1490 
1496  OutputTransitionIterator
1497  outputTransitionBegin(State s) const
1498  {
1499  require(Exception, s.valid(), "outputTransitionBegin: the state is not valid");
1500  require(Exception, &s.owner() == &_behav, "outputTransitionBegin: the state does not belong to the component");
1501  return s.outEdgeBegin();
1502  }
1503 
1509  OutputTransitionIterator
1510  outputTransitionEnd(State s) const
1511  {
1512  require(Exception, s.valid(), "outputTransitionEnd: the state is not valid");
1513  require(Exception, &s.owner() == &_behav, "outputTransitionEnd: the state does not belong to the component");
1514  return s.outEdgeEnd();
1515  }
1516 
1522  InputTransitionIterator
1523  inputTransitionBegin(State s) const
1524  {
1525  require(Exception, s.valid(), "inputTransitionBegin: the state is not valid");
1526  require(Exception, &s.owner() == &_behav, "inputTransitionBegin: the state does not belong to the component");
1527  return s.inEdgeBegin();
1528  }
1529 
1535  InputTransitionIterator
1536  inputTransitionEnd(State s) const
1537  {
1538  require(Exception, s.valid(), "inputTransitionEnd: the state is not valid");
1539  require(Exception, &s.owner() == &_behav, "inputTransitionEnd: the state does not belong to the component");
1540  return s.inEdgeEnd();
1541  }
1542 
1547  unsigned
1549  {
1550  return _behav.numberOfEdges();
1551  }
1552 
1553 
1554  private:
1555 
1561  void
1563  {
1564 
1565  _sourceWithEventPropertyIdIndex.resize(machine._sourceWithEventPropertyIdIndex.size());
1566  _targetWithEventPropertyIdIndex.resize(machine._targetWithEventPropertyIdIndex.size());
1567  for(TransitionIterator it = machine.transitionBegin();
1568  it != machine.transitionEnd(); ++it)
1569  {
1570 
1571  _transitionsWithEventPropertyIdIndex.resize(machine._transitionsWithEventPropertyIdIndex.size());
1572  Transition transition = _behav.getEdge(it->id());
1573  auto eventId = _indexOfEventPropertyId[machine.getEvent(*it)];
1574  _eventPropertyIdIndexOfTransition[transition] = eventId;
1575  _transitionsWithTarget[eventId][transition.target()].insert(transition);
1576  _transitionsWithSource[eventId][transition.source()].insert(transition);
1577  _sourceWithEventPropertyIdIndex[eventId].insert(transition.source());
1578  _targetWithEventPropertyIdIndex[eventId].insert(transition.target());
1579  _transitionsWithEventPropertyIdIndex[eventId].push_back(transition);
1580  }
1581 
1582  }
1583 
1588  void
1590  {
1591  _isInitial.init(_behav, 0);
1592  for(InitialStateIterator it = machine.initialStateBegin();
1593  it != machine.initialStateEnd();
1594  ++it)
1595  {
1596  setInitial(_behav.getNode(it->id()));
1597  }
1598  }
1599 
1604  void
1606  {
1607  _statePropertyIdIndexOfState.init(_behav);
1608  _nullStatePropertyIdStates.clear();
1609  _stateOfStatePropertyIdIndex.resize(_statePropertyIds.size() + 1);
1610  for(StateIterator it = machine.stateBegin();
1611  it != machine.stateEnd(); ++it)
1612  {
1613  State copiedState = _behav.getNode(it->id()); // copiedState is the copy of *it
1614  if(machine.isNullState(*it))
1615  {
1616  _nullStatePropertyIdStates.insert(copiedState);
1617  _statePropertyIdIndexOfState[copiedState] = _nullStatePropertyIdIndex;
1618  }
1619  else
1620  {
1621  _statePropertyIdIndexOfState[copiedState] = machine._statePropertyIdIndexOfState[*it];
1622  _stateOfStatePropertyIdIndex[machine._statePropertyIdIndexOfState[*it]] = copiedState;
1623  ensure(Exception, getStateFromIndex(getIndexOfState(copiedState)) == copiedState,
1624  "finaliseStatePropertyIds: inconsistency between getStateFromIndex/getIndexOfState (non-null)");
1625  }
1626 
1627  }
1628  }
1629 
1634  void
1636  {
1637  _transitionsWithTarget.resize(machine._transitionsWithTarget.size());
1638  _transitionsWithSource.resize(machine._transitionsWithSource.size());
1639  _eventPropertyIdIndexOfTransition.init(_behav);
1640  for(const auto & event : _eventPropertyIds)
1641  {
1642  _transitionsWithTarget[_indexOfEventPropertyId[event]].init(_behav);
1643  _transitionsWithSource[_indexOfEventPropertyId[event]].init(_behav);
1644  }
1645  }
1646 
1652  void
1654  {
1655  eraseEventPropertyId(_indexOfEventPropertyId.at(e));
1656  }
1657 
1663  void
1665  {
1666  if(_statePropertyIdIndexOfState[state] == _statePropertyIds.size() - 1)
1667  {
1668  //cool it is the last recorded property
1669  _indexOfStatePropertyIdIndex.erase(_statePropertyIds.back());
1670  _stateOfStatePropertyIdIndex.pop_back();
1671  _statePropertyIds.pop_back();
1672  _statePropertyIdIndexOfState[state] = 0;
1673  }
1674  else
1675  {
1676  // not cool we need to swap to have a tidy vector
1677  auto stateWhosePropertyIsSwapped = _stateOfStatePropertyIdIndex[_statePropertyIds.size() - 1];
1678  auto & keptProperty = _statePropertyIds[_statePropertyIdIndexOfState[state]];
1679  auto & erasedProperty = _statePropertyIds[_statePropertyIds.size() - 1];
1680  std::swap(keptProperty, erasedProperty);
1681  size_t keptPropertyIndex = _statePropertyIdIndexOfState[state];
1682  _statePropertyIdIndexOfState[stateWhosePropertyIsSwapped] = keptPropertyIndex;
1683  _stateOfStatePropertyIdIndex[keptPropertyIndex] = stateWhosePropertyIsSwapped;
1684  _indexOfStatePropertyIdIndex[keptProperty] = keptPropertyIndex;
1685  _indexOfStatePropertyIdIndex.erase(_statePropertyIds.back());
1686  _stateOfStatePropertyIdIndex.pop_back();
1687  _statePropertyIds.pop_back();
1688  _statePropertyIdIndexOfState[state] = 0;
1689  }
1690  }
1691  protected:
1692 
1699  virtual
1700  void
1701  eraseEventPropertyId(size_t eventIndex)
1702  {
1703  // _normalEventPropertyIds.erase(_eventPropertyIds[eventIndex]);
1704  // _faultyEventPropertyIds.erase(_eventPropertyIds[eventIndex]);
1705 
1706 
1707  if(eventIndex == _eventPropertyIds.size() - 1)
1708  {
1709  //cool it is the last recorded EventProperty
1710  _indexOfEventPropertyId.erase(_eventPropertyIds.back());
1711  _eventPropertyIds.pop_back();
1712  _transitionsWithEventPropertyIdIndex.pop_back();
1713  _sourceWithEventPropertyIdIndex.pop_back();
1714  _targetWithEventPropertyIdIndex.pop_back();
1715  _transitionsWithSource.pop_back();
1716  _transitionsWithTarget.pop_back();
1717  }
1718  else
1719  {
1720  // not cool we need to swap to have a tidy vector
1721  size_t keptEventPropertyIndexBeforeSwap = _eventPropertyIds.size() - 1;
1722  _indexOfEventPropertyId.erase(_eventPropertyIds.at(eventIndex));
1723  auto keptEventPropertyIndexAfterSwap = Diades::Utils::swapRemove(_eventPropertyIds, eventIndex);
1724  _indexOfEventPropertyId[_eventPropertyIds[keptEventPropertyIndexAfterSwap]] = keptEventPropertyIndexAfterSwap;
1725  _transitionsWithEventPropertyIdIndex[keptEventPropertyIndexAfterSwap] = _transitionsWithEventPropertyIdIndex[keptEventPropertyIndexBeforeSwap];
1726  _transitionsWithEventPropertyIdIndex.pop_back();
1727  _sourceWithEventPropertyIdIndex[keptEventPropertyIndexAfterSwap] = _sourceWithEventPropertyIdIndex[keptEventPropertyIndexBeforeSwap];
1728  _sourceWithEventPropertyIdIndex.pop_back();
1729  _targetWithEventPropertyIdIndex[keptEventPropertyIndexAfterSwap] = _targetWithEventPropertyIdIndex[keptEventPropertyIndexBeforeSwap];
1730  _targetWithEventPropertyIdIndex.pop_back();
1731  _transitionsWithSource[keptEventPropertyIndexAfterSwap] = _transitionsWithSource[keptEventPropertyIndexBeforeSwap];
1732  _transitionsWithSource.pop_back();
1733  _transitionsWithTarget[keptEventPropertyIndexAfterSwap] = _transitionsWithTarget[keptEventPropertyIndexBeforeSwap];
1734  _transitionsWithTarget.pop_back();
1735 
1736 
1737  for(auto it = transitionBegin(); it != transitionEnd(); ++it)
1738  {
1739  if(_eventPropertyIdIndexOfTransition[*it] == keptEventPropertyIndexBeforeSwap)
1740  {
1741  _eventPropertyIdIndexOfTransition[*it] = keptEventPropertyIndexAfterSwap;
1742  }
1743  }
1744 
1745  }
1746 
1747 
1748  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _eventPropertyIds.size(), "eraseEventProperty: size problem in internal structures");
1749  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _transitionsWithTarget.size(), "eraseEventProperty: size problem in internal structures (_sourceWithEvent.size() != _transitionsWithTarget.size()");
1750  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _transitionsWithSource.size(), "eraseEventProperty: size problem in internal structures (_sourceWithEvent.size() != _transitionsWithSource.size() ");
1751  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _targetWithEventPropertyIdIndex.size(), "eraseEventProperty: size problem in internal structures (_sourceWithEvent.size() != _targetWithEvent.size()");
1752  ensure(Exception, _sourceWithEventPropertyIdIndex.size() == _transitionsWithEventPropertyIdIndex.size(), "eraseEventProperty: size problem in internal structures (_sourceWithEvent.size() != _transitionsWithEvent.size()");
1753 
1754 
1755  }
1756 
1764  State
1766  {
1767  if(index == _nullStatePropertyIdIndex)
1768  {
1769  return State();
1770  }
1771  return _stateOfStatePropertyIdIndex.at(index);
1772  }
1773 
1782  getIndexOfState(State s) const
1783  {
1784  if(isNullState(s))
1785  {
1787  }
1788  return _statePropertyIdIndexOfState[s];
1789  }
1790 
1791  };
1792 
1795  template<typename StatePropertyId, typename EventPropertyId, typename InputIterator, typename IsNullStatePropertyId, typename IsNullEventProperty>
1796  inline void
1798  {
1799  while(first!=last)
1800  {
1801  auto t = *first;
1802  ++first; // i do that way to avoid any issue if first is a EdgeIterator.
1803  m.deleteTransition(t);
1804  }
1805  }
1806 
1807  template<typename StatePropertyId, typename EventPropertyId, typename InputIterator, typename IsNullStateProperty, typename IsNullEventProperty>
1808  inline void
1810  {
1811  while(first!=last)
1812  {
1813  auto s = *first;
1814  ++first; // i do that way to avoid any issue if first is a NodeIterator.
1815  m.deleteState(s);
1816  }
1817  }
1818 
1819  template<typename StatePropertyId, typename EventPropertyId, typename InputIterator, typename Predicate, typename IsNullStateProperty, typename IsNullEventProperty>
1820  inline void
1822  {
1823 
1824  while(first!=last)
1825  {
1826  auto s = *first;
1827  ++first; // i do that way to avoid any issue if first is a NodeIterator.
1828  if(pred(s))
1829  {
1830  m.deleteState(s);
1831  }
1832  }
1833  }
1834  template<typename StatePropertyId, typename EventPropertyId, typename InputIterator, typename Predicate, typename IsNullStateProperty, typename IsNullEventProperty, typename StatePropertyIdInsertIterator >
1835  inline void
1836  deleteState(StateMachine<StatePropertyId, EventPropertyId, IsNullStateProperty, IsNullEventProperty> & m, InputIterator first, InputIterator last, Predicate pred, StatePropertyIdInsertIterator insertIt)
1837  {
1838 
1839  while(first!=last)
1840  {
1841  auto s = *first;
1842  ++first; // i do that way to avoid any issue if first is a NodeIterator.
1843  if(pred(s))
1844  {
1845  *insertIt++=m.getStatePropertyId(s);
1846  m.deleteState(s);
1847  }
1848  }
1849  }
1850 
1851 
1856  template<typename Type>
1858 
1859 
1864  template<typename Type>
1866 
1867 
1872  template<typename Type>
1874 
1875 
1880  template<typename Type>
1882 
1883 
1884 
1885 
1886  }
1887  }
1888 
1889 }
1890 
1891 
1892 //
1893 //
1894 //namespace std
1895 //{
1896 //
1897 // template <typename StateProperty, typename EventProperty>
1898 // struct iterator_traits<Diades::Automata::Experimental::StateMachine<StateProperty, EventProperty>>
1899 // {
1900 // using iterator_category = std::forward_iterator_tag;
1901 // using value_type = StateProperty;
1902 // };
1903 //
1904 //}
1905 //
1906 
1907 #endif /* STATEMACHINE_HH */
1908 
void copyEventPropertyId(const StateMachine &m, const EventPropertyId &event)
bool operator==(const StateMachine &machine) const
void deleteTransition(StateMachine< StatePropertyId, EventPropertyId, NullStateProperty, NullEventProperty > &m, InputIterator first, InputIterator last)
EventPropertyIdIterator eventEnd() const
NodeIterator initValue(NodeIterator begin, NodeIterator end, ConstReference value)
Definition: NodeMap.hh:354
StatePropertyIdIterator statePropertyIdBegin() const
void finaliseStatePropertyIds(const StateMachine &machine)
OutputEventTransitionIterator outputEventTransitionBegin(State s, const EventPropertyId &e) const
vector< StatePropertyId > _statePropertyIds
unordered_set< State >::const_iterator LabelledStateIterator
Diades::Graph::ConstNodeMap< Type > CstStMap
vector< Diades::Graph::NodeMap< unordered_set< Transition > > > _transitionsWithSource
void finaliseEventPropertyIdRemoval(const EventPropertyId &e)
Transition newTransition(State source, State target, const EventPropertyId &event)
void copyEventPropertyIds(const StateMachine &m)
GraphIterator< Edge > EdgeIterator
Definition: GraphInt.hh:143
unordered_set< State > _nullStatePropertyIdStates
Diades::Graph::NodeMap< StatePropertyIdIndex > _statePropertyIdIndexOfState
Edge newEdge(Node source, Node target)
vector< EventPropertyId >::const_iterator EventPropertyIdIterator
EdgeSizeType numberOfEdges() const
Definition: GraphInt.hh:323
StateMachine & operator=(const StateMachine &machine)
vector< unordered_set< State > > _sourceWithEventPropertyIdIndex
void init(Graph &g, SizeType capacity=0, ValueType dflt=ValueType())
Definition: NodeMap.hh:315
const Data & operator()(const MapStructure &m, Iterator it) const
StatePropertyIdRangeIterator< StateIterator > statePropertyIdRangeIterator(StateIterator iterator) const
Definition: Run.cc:88
EventPropertyId getEventFromIndex(size_t index) const
NodeIterator nodeEnd()
Definition: GraphInt.hh:538
virtual void eraseEventPropertyId(size_t eventIndex)
unordered_set< Transition >::const_iterator OutputEventTransitionIterator
#define ensure(Exception, expr, message)
Definition: Assertion.hh:98
bool containsEvent(const EventPropertyId &e) const
std::vector< StatePropertyId >::const_iterator StatePropertyIdIterator
void deleteState(StateMachine< StatePropertyId, EventPropertyId, NullStateProperty, NullEventProperty > &m, InputIterator first, InputIterator last)
OutputTransitionIterator outputTransitionBegin(State s) const
StatePropertyIdIndex getIndexOfState(State s) const
InitialStateIterator initialStateEnd() const
EdgeIterator edgeEnd()
Definition: GraphInt.hh:574
Diades::Graph::EdgeMap< EventPropertyIdIndex > _eventPropertyIdIndexOfTransition
InputTransitionIterator inputTransitionBegin(State s) const
Diades::Graph::OutEdgeIterator OutputTransitionIterator
std::pair< State, bool > newState(const StatePropertyId &sProperty)
EdgeIterator edgeBegin()
Definition: GraphInt.hh:565
Diades::Graph::ConstEdgeMap< Type > CstTrMap
Diades::Graph::EdgeIterator TransitionIterator
LabelledStateIterator beginOfSourceStateOfEvent(const EventPropertyId &e) const
Diades::Graph::NodeIterator StateIterator
InputEventTransitionIterator inputEventTransitionEnd(State s, const EventPropertyId &e) const
virtual void insertEventPropertyId(const EventPropertyId &event)
unordered_set< Transition >::const_iterator InputEventTransitionIterator
void removeEvent(const EventPropertyId &e)
GraphIterator< Node > NodeIterator
Definition: GraphInt.hh:139
void insertEvent(EventIter start, EventIter end)
unordered_set< State >::const_iterator InitialStateIterator
const string & setName(const string &name)
void finaliseEventPropertyIds(const StateMachine &machine)
const EventPropertyId & getEvent(Transition t) const
const vector< EventPropertyId > & events() const
LabelledStateIterator endOfSourceStateOfEvent(const EventPropertyId &e) const
void init(Graph &g, SizeType capacity=0, ValueType dflt=ValueType())
Definition: EdgeMap.hh:314
#define require(Exception, expr, message)
Definition: Assertion.hh:90
Namespace of the Diades project.
Edge getEdge(EdgeSizeType index) const
OutputTransitionIterator outputTransitionEnd(State s) const
std::vector< T >::size_type swapRemove(std::vector< T > &myVector, typename std::vector< T >::size_type index)
Definition: VectorTools.hh:35
bool setStatePropertyId(State state, const StatePropertyId &sProperty)
InputTransitionIterator inputTransitionEnd(State s) const
Transition newTransition(const StatePropertyId &source, const StatePropertyId &target, const EventPropertyId &event)
list< Edge >::iterator OutEdgeIterator
Definition: Edge.hh:314
virtual void deleteNode(Node &node)
Node getNode(NodeSizeType index) const
ConstIterator on the Net.
EventPropertyIdIterator eventBegin() const
virtual void deleteEdge(Edge &edge)
InitialStateIterator initialStateBegin() const
LabelledStateIterator endOfTargetStateOfEvent(const EventPropertyId &e) const
OutputEventTransitionIterator outputEventTransitionEnd(State s, const EventPropertyId &e) const
vector< EventPropertyId > _eventPropertyIds
void finaliseTransitions(const StateMachine &machine)
unordered_map< StatePropertyId, StatePropertyIdIndex > _indexOfStatePropertyIdIndex
Diades::Graph::EdgeMap< Type > TrMap
Diades::Graph::InEdgeIterator InputTransitionIterator
vector< list< Transition > > _transitionsWithEventPropertyIdIndex
bool empty() const
Definition: GraphInt.hh:332
void finaliseInitialStates(const StateMachine &machine)
Diades::Graph::NodeMap< Type > StMap
InputEventTransitionIterator inputEventTransitionBegin(State s, const EventPropertyId &e) const
list< Edge >::iterator InEdgeIterator
Definition: Edge.hh:313
TransitionIterator transitionBegin() const
bool operator!=(const StateMachine &machine) const
list< Transition >::const_iterator EventTransitionIterator
NodeIterator nodeBegin()
Definition: GraphInt.hh:529
boost::format Msg
Definition: Verbose.hh:42
StatePropertyIdIterator statePropertyIdEnd() const
const StatePropertyId & getStatePropertyId(State state) const
EventTransitionIterator eventTransitionEnd(const EventPropertyId &e) const
const Graph::Graph & behaviour() const
bool isNullEvent(EventPropertyId evt) const
StateMachine(const StateMachine &machine)
vector< unordered_set< State > > _targetWithEventPropertyIdIndex
LabelledStateIterator beginOfTargetStateOfEvent(const EventPropertyId &e) const
Diades::Graph::NodeMap< bool > _isInitial
vector< Diades::Graph::NodeMap< unordered_set< Transition > > > _transitionsWithTarget
NodeSizeType numberOfNodes() const
Definition: GraphInt.hh:314
void deleteTransition(TransitionIterator start, TransitionIterator end)
void deleteTransition(EventTransitionIterator start, EventTransitionIterator end)
void replaceEvent(const EventPropertyId &e1, const EventPropertyId &e2)
State getState(const StatePropertyId &sProperty) const
State getStateFromIndex(StatePropertyIdIndex index) const
#define assertion(Exception, expr, message)
Definition: Assertion.hh:106
EventTransitionIterator eventTransitionBegin(const EventPropertyId &e) const
void swapInitialState(State state)
swap the status of the state as initial/non-initial
unordered_map< EventPropertyId, EventPropertyIdIndex > _indexOfEventPropertyId
void deleteState(StateIterator start, StateIterator end)