DiaDes  0.1
DIAgnosis of Discrete-Event System
ComposableModel.hh
Go to the documentation of this file.
1 
9 #ifndef __DIADES__AUTOMATA__EXPERIMENTAL__COMPOSABLEMODEL__HH__
10 #define __DIADES__AUTOMATA__EXPERIMENTAL__COMPOSABLEMODEL__HH__
11 
12 #include<unordered_set>
18 
19 namespace Diades
20 {
21  namespace Automata
22  {
23  namespace Experimental
24  {
25 
26 
27 
28 
42  template<typename Fsm, typename StateCreator>
44  {
45  public:
46 
47  static string
49  {
50  return "Diades::Automata::Experimental::ComposableModel";
51  }
53  using Component = Fsm;
54  using Event = typename Component::EventPropertyId;
62  using State = typename Component::State;
64  using StateVector = std::vector<State>;
66  using VectorOfState = std::unordered_map<State, StateVector>;
69  using SyncEvent = typename SyncRules::SyncEvent;
70  private:
71  vector<typename Ptr<ComposableModel>::ConstP> _models;
72  std::unordered_map<typename Ptr<Component>::ConstP, size_t> _compIds;
79  std::unordered_map<typename Ptr<SyncEvent>::ConstP, std::unordered_set<size_t> > _synchronisationEventsInUse;
80  std::unordered_map<Event, typename Ptr<SyncEvent>::ConstP > _synchronisationEventsOfSynchronisedEvent;
81  mutable std::unordered_map<State, std::unordered_set < Event>> _pendingOutputs;
82  mutable std::unordered_map<State, std::unordered_set < Event>> _pendingInputs;
83  bool _valid;
84  mutable bool _notStarted;
85  mutable typename Ptr<StateCreator>::P _creator;
86 
87  private:
88 
92  void
94  {
95  StateVector initialStates;
96  State initialState;
97  while(newInitialState(initialStates, initialState))
98  {
99  }
100  }
101 
102  public:
103 
110  {
111  if(_comp == nullptr)
112  {
114  return _synchronisedFsm->initialStateBegin();
115  }
116  return _comp->initialStateBegin();
117  }
118 
125  {
126  if(_comp == nullptr)
127  {
128 
129  StateVector initialStates;
130  initialStates.reserve(_models.size());
131  State initialState;
132  while(newInitialState(initialStates, initialState))
133  {
134  }
135  return _synchronisedFsm->initialStateEnd();
136  }
137  return _comp->initialStateEnd();
138  }
139 
144  bool
145  isValid() const
146  {
147  return _valid;
148  }
149 
150 
151 
155  ComposableModel() = default;
156 
157 
162  ComposableModel(ComposableModel const& other) = default;
168  ComposableModel& operator=(ComposableModel const& other) = default;
173  ComposableModel(ComposableModel && other) = default;
179  ComposableModel& operator=(ComposableModel && other) = default;
183  virtual ~ComposableModel() = default;
184 
199  const SynchronisationRules<Fsm> & synchronisation) :
200  _models(),
201  _compIds(),
202  _comp(Ptr<Component>::get(component)),
203  _synchronisedFsm(nullptr),
204  _sync(Ptr<SynchronisationRules<Fsm>>::get(synchronisation)),
205  _stateOfVector(),
206  _vectorOfState(),
207  _initialStateEnumerator(),
208  _synchronisationEventsInUse(),
209  _synchronisationEventsOfSynchronisedEvent(),
210  _pendingOutputs(),
211  _pendingInputs(),
212  _valid(true),
213  _notStarted(true),
214  _creator(nullptr)
215  {
216  }
217 
226  ComposableModel(const vector<typename Ptr<ComposableModel>::ConstP> & models, const SynchronisationRules<Fsm> & synchronisation, StateCreator & creator) :
227  _models(models),
228  _compIds(),
229  _comp(nullptr),
230  _synchronisedFsm(nullptr),
231  _sync(Ptr<SynchronisationRules<Fsm>>::get(synchronisation)),
232  _stateOfVector(),
233  _vectorOfState(),
234  _initialStateEnumerator(),
235  _synchronisationEventsInUse(),
236  _synchronisationEventsOfSynchronisedEvent(),
237  _pendingOutputs(),
238  _pendingInputs(),
239  _valid(true),
240  _notStarted(true),
241  _creator(Ptr<StateCreator>::get(creator))
242  {
243  for(size_t i = 0; i < models.size(); ++i)
244  {
245  _compIds[Ptr<Component>::get(models[i]->component())] = i;
246  }
248  }
249 
259  ComposableModel(const vector<typename Ptr<ComposableModel>::ConstP> & models, const SynchronisationRules<Fsm> & synchronisation,
260  StateCreator & creator,
261  Fsm & result) :
262  _models(models),
263  _compIds(),
264  _comp(nullptr),
265  _synchronisedFsm(Ptr<Fsm>::get(result)),
266  _sync(Ptr<SynchronisationRules<Fsm>>::get(synchronisation)),
267  _stateOfVector(),
268  _vectorOfState(),
269  _initialStateEnumerator(),
270  _synchronisationEventsInUse(),
271  _synchronisationEventsOfSynchronisedEvent(),
272  _pendingOutputs(),
273  _pendingInputs(),
274  _valid(true),
275  _notStarted(true),
276  _creator(Ptr<StateCreator>::get(creator))
277  {
278  for(size_t i = 0; i < models.size(); ++i)
279  {
280  _compIds[Ptr<Fsm>::get(models[i]->component())] = i;
281  }
283  _creator->setStateMachine(result);
285  }
286 
293  bool
294  completeSynchronisation(Fsm & synchronisedFsm)
295  {
296  if(isValid())
297  {
298  bool result = true;
299  init(synchronisedFsm);
301  return result;
302  }
303  return false;
304  }
305 
306  private:
307 
312  void
314  {
315  if(_comp == nullptr && _synchronisedFsm != nullptr)
316  {
318  while(!_pendingOutputs.empty())
319  {
320  State pendingState = _pendingOutputs.begin()->first;
321  Event pendingEvent = *(_pendingOutputs.begin()->second.begin());
322  synchroniseOutputs(pendingState, pendingEvent);
323  }
324  }
325  }
326 
327  public:
328 
336  stateBegin() const
337  {
338  if(_comp == nullptr)
339  {
340  if(_notStarted || (!_pendingOutputs.empty()))
341  {
343  }
344  return _synchronisedFsm->stateBegin();
345  }
346  return _comp->stateBegin();
347  }
348 
356  stateEnd() const
357  {
358  if(_comp == nullptr)
359  {
360  if(_notStarted || (!_pendingOutputs.empty()))
361  {
363  }
364  return _synchronisedFsm->stateEnd();
365  }
366  return _comp->stateEnd();
367  }
368 
377  {
378  if(_comp == nullptr)
379  {
380  if(_notStarted || (!_pendingOutputs.empty()))
381  {
383  }
384  return _synchronisedFsm->transitionBegin();
385  }
386  return _comp->transitionBegin();
387  }
388 
397  {
398  if(_comp == nullptr)
399  {
400  if(_notStarted || (!_pendingOutputs.empty()))
401  {
403  }
404  return _synchronisedFsm->transitionEnd();
405  }
406  return _comp->transitionEnd();
407  }
408 
414  {
415  return *_sync;
416  }
417 
427  void
428  init(Fsm & synchronisedFsm)
429  {
430  if(_comp == nullptr)
431  {
432  _synchronisedFsm = Ptr<Fsm>::get(synchronisedFsm);
433  _synchronisedFsm->clear();
434  _stateOfVector.clear();
435  _vectorOfState.clear();
436  _pendingOutputs.clear();
437  _pendingInputs.clear();
438  _notStarted = true;
439  if(_creator != nullptr)
440  {
441  _creator->setStateMachine(synchronisedFsm);
442  }
444  }
445  }
446  private:
447 
451  void
453  {
454  std::vector<InitialStateIterator> start;
455  start.reserve(models().size());
456  std::vector<InitialStateIterator> end;
457  end.reserve(models().size());
458  std::for_each(_models.begin(), _models.end(),
459  [&](typename Ptr<ComposableModel>::ConstP composableModel)
460  {
461  start.push_back(composableModel->component().initialStateBegin());
462  end.push_back(composableModel->component().initialStateEnd());
463  });
464  _initialStateEnumerator.setup(std::move(start), std::move(end));
465  }
466  public:
467 
473  const Component &
474  component() const
475  {
476  if(_synchronisedFsm != nullptr)
477  {
478  return *_synchronisedFsm;
479  }
480  return *_comp;
481  }
482 
489  const vector<typename Ptr<ComposableModel>::ConstP> &
490  models() const
491  {
492  return _models;
493  }
494 
501  vector<typename Ptr<ComposableModel>::ConstP> &
503  {
504  return _models;
505  }
506 
511  const std::string &
512  name() const
513  {
514  return component().name();
515  }
516 
524  bool
525  newState(const StateVector & states, State & result) const
526  {
528  if(_stateOfVector.getLeaf(states.begin(), states.end(), result))
529  {
530  return false;
531  }
532  bool created;
533  std::tie(result,created) = _creator->newState(states);
534  _stateOfVector.insertSuccessiveBranches(states.begin(), states.end(), result);
535  _vectorOfState[result] = states;
536  _notStarted = false;
537  _pendingOutputs[result].insert(
538  KeyIterator(_synchronisationEventsOfSynchronisedEvent.begin()),
539  KeyIterator(_synchronisationEventsOfSynchronisedEvent.end()));
540  _pendingInputs[result].insert(
541  KeyIterator(_synchronisationEventsOfSynchronisedEvent.begin()),
542  KeyIterator(_synchronisationEventsOfSynchronisedEvent.end()));
543  return created;
544  }
545 
553  bool
554  newInitialState(StateVector & initialStates, State & initialState) const
555  {
556  if(_initialStateEnumerator.completed())
557  {
558  return false;
559  }
560  bool isCreated = false;
561  initialStates.clear();
562  initialStates.reserve(_models.size());
563  while(!isCreated && !_initialStateEnumerator.completed())
564  {
565  std::for_each(_initialStateEnumerator.current().begin(),
566  _initialStateEnumerator.current().end(),
567  [&](typename InitialStateEnumerator::Value it)
568  {
569  initialStates.push_back(*it);
570  }
571  );
572  isCreated = newState(initialStates, initialState);
573  if(!isCreated)
574  {
575  _initialStateEnumerator.hasNext();
576  initialStates.clear();
577  }
578  else
579  {
580  _synchronisedFsm->setInitial(initialState);
581  }
582  }
583  return isCreated;
584  }
585 
594  void
595  synchroniseOutputs(State state, Event event) const
596  {
597  auto evtIt = _synchronisationEventsOfSynchronisedEvent.find(event);
598  if(evtIt != _synchronisationEventsOfSynchronisedEvent.end())
599  {
600  const auto & synchronisationEvent = *(evtIt->second);
601  auto stateIt = _vectorOfState.find(state);
602  if(stateIt != _vectorOfState.end())
603  {
604  const auto & stateVector = stateIt->second;
605  StateVector targetVector = stateVector;
606  auto supportIt = _synchronisationEventsInUse.find(Ptr<SyncEvent>::get(synchronisationEvent));
607  if(supportIt != _synchronisationEventsInUse.end())
608  {
609  const auto & support = supportIt->second;
610  std::vector<OutputEventTransitionIterator> start, end;
611  start.reserve(support.size());
612  end.reserve(support.size());
613  std::for_each(support.begin(), support.end(),
614  [&](size_t modelIndex)
615  {
616  auto & model = _models[modelIndex];
617  auto & compState = stateVector[modelIndex];
618  auto event = synchronisationEvent.getAssociatedEvent(model->component());
619  start.push_back(model->outputEventTransitionBegin(compState, event));
620  end.push_back(model->outputEventTransitionEnd(compState, event));
621  });
622 
624  if(!enumerator.empty())
625  {
626  enumerator.start();
627  do
628  {
629  size_t index = 0;
630  for(auto it = support.begin(); it != support.end(); ++it)
631  {
632  targetVector[*it] = (enumerator.current().at(index))->target();
633  ++index;
634  }
635  State target;
636  newState(targetVector, target);
637  _synchronisedFsm->newTransition(state, target, event);
638  }
639  while(enumerator.hasNext());
640  }
641 
642  }
643  }
644  _pendingOutputs[state].erase(event);
645  if(_pendingOutputs[state].empty())
646  {
647  _pendingOutputs.erase(state);
648  }
649  }
650  }
651 
660  void
661  synchroniseInputs(State state, Event event) const
662  {
663  auto evtIt = _synchronisationEventsOfSynchronisedEvent.find(event);
664  if(evtIt != _synchronisationEventsOfSynchronisedEvent.end())
665  {
666  const auto & synchronisationEvent = *(evtIt->second);
667  auto stateIt = _vectorOfState.find(state);
668  if(stateIt != _vectorOfState.end())
669  {
670  const auto & stateVector = stateIt->second;
671  StateVector sourceVector = stateVector;
672  auto supportIt = _synchronisationEventsInUse.find(Ptr<SyncEvent>::get(synchronisationEvent));
673  if(supportIt != _synchronisationEventsInUse.end())
674  {
675  const auto & support = supportIt->second;
676  std::vector<InputEventTransitionIterator> start, end;
677  start.reserve(support.size());
678  end.reserve(support.size());
679  std::for_each(support.begin(), support.end(),
680  [&](size_t modelIndex)
681  {
682  auto & model = _models[modelIndex];
683  auto & compState = stateVector[modelIndex];
684  auto event = synchronisationEvent.getAssociatedEvent(model->component());
685  start.push_back(model->inputEventTransitionBegin(compState, event));
686  end.push_back(model->inputEventTransitionEnd(compState, event));
687  });
688 
690  if(!enumerator.empty())
691  {
692  enumerator.start();
693 
694  do
695  {
696  size_t index = 0;
697  for(auto it = support.begin(); it != support.end(); ++it)
698  {
699  sourceVector[*it] = (enumerator.current().at(index))->target();
700  ++index;
701  }
702  State source;
703  newState(sourceVector, source);
704  _synchronisedFsm->newTransition(source, state, event);
705  }
706  while(enumerator.hasNext());
707  }
708 
709  }
710  }
711  _pendingInputs[state].erase(event);
712  if(_pendingInputs[state].empty())
713  {
714  _pendingInputs.erase(state);
715  }
716  }
717  }
718 
729  {
730  if(_comp == nullptr)
731  {
732  auto it = _pendingOutputs.find(s);
733 
734  if((it != _pendingOutputs.end())
735  &&
736  (it->second.find(e) != it->second.end()))
737  {
738  synchroniseOutputs(s, e);
739  }
740  return _synchronisedFsm->outputEventTransitionBegin(s, e);
741  }
742  return _comp->outputEventTransitionBegin(s, e);
743  }
744 
755  {
756  if(_comp == nullptr)
757  {
758  auto it = _pendingOutputs.find(s);
759 
760  if((it != _pendingOutputs.end())
761  &&
762  (it->second.find(e) != it->second.end()))
763  {
764  synchroniseOutputs(s, e);
765  }
766  return _synchronisedFsm->outputEventTransitionEnd(s, e);
767  }
768  return _comp->outputEventTransitionEnd(s, e);
769  }
770 
782  {
783  if(_comp == nullptr)
784  {
785 
786  auto it = _pendingInputs.find(s);
787 
788  if((it != _pendingInputs.end())
789  &&
790  (it->second.find(e) != it->second.end()))
791  {
792  synchroniseInputs(s, e);
793  }
794  return _synchronisedFsm->inputEventTransitionBegin(s, e);
795  }
796  return _comp->inputEventTransitionBegin(s, e);
797  }
798 
809  {
810  if(_comp == nullptr)
811  {
812  auto it = _pendingInputs.find(s);
813 
814  if((it != _pendingInputs.end())
815  &&
816  (it->second.find(e) != it->second.end()))
817  {
818  synchroniseInputs(s, e);
819  }
820  return _synchronisedFsm->inputEventTransitionEnd(s, e);
821  }
822  return _comp->inputEventTransitionEnd(s, e);
823  }
824 
834  {
835  if(_comp == nullptr)
836  {
837  auto it = _pendingOutputs.find(s);
838  if(it != _pendingOutputs.end())
839  {
840  auto currentSize = _pendingOutputs.size();
841  while(_pendingOutputs.size() == currentSize)
842  {
843 
844  Event pendingEvent = *(it->second.begin());
845  synchroniseOutputs(s, pendingEvent);
846  }
847  }
848  return _synchronisedFsm->outputTransitionBegin(s);
849  }
850  return _comp->outputTransitionBegin(s);
851  }
852 
862  {
863  if(_comp == nullptr)
864  {
865  auto it = _pendingOutputs.find(s);
866  if(it != _pendingOutputs.end())
867  {
868  auto currentSize = _pendingOutputs.size();
869  while(_pendingOutputs.size() == currentSize)
870  {
871 
872  Event pendingEvent = *(it->second.begin());
873  synchroniseOutputs(s, pendingEvent);
874  }
875  }
876 
877  return _synchronisedFsm->outputTransitionEnd(s);
878  }
879  return _comp->outputTransitionEnd(s);
880  }
881 
889  {
890  if(_comp == nullptr)
891  {
892  auto it = _pendingInputs.find(s);
893  if(it != _pendingInputs.end())
894  {
895  auto currentSize = _pendingInputs.size();
896  while(_pendingInputs.size() == currentSize)
897  {
898 
899  Event pendingEvent = *(it->second.begin());
900  synchroniseInputs(s, pendingEvent);
901  }
902  }
903  return _synchronisedFsm->inputTransitionBegin(s);
904  }
905  return _comp->inputTransitionBegin(s);
906  }
907 
918  {
919  if(_comp == nullptr)
920  {
921  auto it = _pendingInputs.find(s);
922  if(it != _pendingInputs.end())
923  {
924  auto currentSize = _pendingInputs.size();
925  while(_pendingInputs.size() == currentSize)
926  {
927 
928  Event pendingEvent = *(it->second.begin());
929  synchroniseInputs(s, pendingEvent);
930  }
931  }
932  return _synchronisedFsm->inputTransitionEnd(s);
933  }
934  return _comp->inputTransitionEnd(s);
935  }
936 
937 
938 
939 
940 
941 
942  private:
943 
953  bool
955  {
956  auto it = _sync->beginOfSynchronisedEvents();
957  while(it != _sync->endOfSynchronisedEvents())
958  {
959  if(!checkSynchronisationEvent(*it))
960  {
961  _synchronisationEventsInUse.clear();
962  return false;
963  }
964  ++it;
965  }
966  return true;
967  }
968 
978  bool
980  {
981  bool isIn = false;
982  bool isOut = false;
983  auto it = syncEvent.beginOfSupport();
984  while(!(isIn && isOut) && it != syncEvent.endOfSupport())
985  {
986  auto compIdIt = _compIds.find(Ptr<Component>::get(*it));
987  bool found = (compIdIt != _compIds.end());
988  isIn = isIn || found;
989  isOut = isOut || (!found);
990  if(found)
991  {
992  _synchronisationEventsOfSynchronisedEvent[syncEvent.synchronisedEvent()] = Ptr<SyncEvent>::get(syncEvent);
993  _synchronisationEventsInUse[Ptr<SyncEvent>::get(syncEvent)].insert(compIdIt->second);
994  }
995  ++it;
996  }
997  return !(isIn && isOut);
998  }
999 
1000 
1001 
1002  };
1003  }
1004  }
1005 }
1006 
1007 
1008 #endif /* __DIADES__AUTOMATA__EXPERIMENTAL__COMPOSABLEMODEL__HH__ */
1009 
void synchroniseOutputs(State state, Event event) const
static ConstP get(const T &obj)
Definition: Pointer.hh:37
typename Component::InitialStateIterator InitialStateIterator
const SynchronisationRules< Fsm > & synchronisationLaw() const
ComposableModel(const vector< typename Ptr< ComposableModel >::ConstP > &models, const SynchronisationRules< Fsm > &synchronisation, StateCreator &creator)
Leaf & insertSuccessiveBranches(NodeIterator begin, NodeIterator end, const Leaf &info)
Definition: NAryTree.hh:304
OutputTransitionIterator outputTransitionBegin(State s) const
OutputEventTransitionIterator outputEventTransitionBegin(State s, Event e) const
const T * ConstP
Definition: Pointer.hh:31
vector< typename Ptr< ComposableModel >::ConstP > _models
FaultyEventStateMachine< CandidateId, EventInfoId > Fsm
Definition: Run.cc:88
InputTransitionIterator inputTransitionBegin(State s) const
typename Component::OutputTransitionIterator OutputTransitionIterator
InputEventTransitionIterator inputEventTransitionEnd(State s, Event e) const
std::unordered_map< State, StateVector > VectorOfState
ComposableModel & operator=(ComposableModel const &other)=default
typename Component::TransitionIterator TransitionIterator
std::unordered_map< Event, typename Ptr< SyncEvent >::ConstP > _synchronisationEventsOfSynchronisedEvent
StIndexes states
Definition: Run.cc:266
std::unordered_map< State, std::unordered_set< Event > > _pendingInputs
std::unordered_map< State, std::unordered_set< Event > > _pendingOutputs
InputTransitionIterator inputTransitionEnd(State s) const
typename Component::OutputEventTransitionIterator OutputEventTransitionIterator
unordered_set< State >::const_iterator InitialStateIterator
Definition: Component.hh:70
bool newInitialState(StateVector &initialStates, State &initialState) const
std::unordered_map< typename Ptr< SyncEvent >::ConstP, std::unordered_set< size_t > > _synchronisationEventsInUse
Diades::Graph::NodeIterator StateIterator
Definition: Component.hh:67
ComposableModel(const Component &component, const SynchronisationRules< Fsm > &synchronisation)
ComposableModel(const vector< typename Ptr< ComposableModel >::ConstP > &models, const SynchronisationRules< Fsm > &synchronisation, StateCreator &creator, Fsm &result)
AutFsm::State State
Definition: Run.cc:72
AutFsm::Transition Transition
Definition: Run.cc:73
InputEventTransitionIterator inputEventTransitionBegin(State s, Event e) const
typename Component::InputTransitionIterator InputTransitionIterator
OutputTransitionIterator outputTransitionEnd(State s) const
bool getLeaf(NodeIterator begin, NodeIterator end, Leaf &result)
Definition: NAryTree.hh:324
IsIn< InputIterator > isIn(InputIterator first, InputIterator last)
Definition: Functors.hh:141
bool newState(const StateVector &states, State &result) const
Diades::Graph::OutEdgeIterator OutputTransitionIterator
Definition: Component.hh:72
Namespace of the Diades project.
typename Component::StateIterator StateIterator
void setup(std::vector< T > &&start, const std::vector< T > &&end)
Definition: Enumerators.hh:81
typename Component::EventPropertyId Event
bool checkSynchronisationEvent(const SyncEvent &syncEvent)
Diades::Graph::InEdgeIterator InputTransitionIterator
Definition: Component.hh:71
const vector< typename Ptr< ComposableModel >::ConstP > & models() const
unordered_set< Transition >::const_iterator OutputEventTransitionIterator
Definition: Component.hh:74
Diades::Graph::EdgeIterator TransitionIterator
Definition: Component.hh:68
const std::vector< T > & current() const
Definition: Enumerators.hh:107
vector< typename Ptr< ComposableModel >::ConstP > & models()
typename Component::InputEventTransitionIterator InputEventTransitionIterator
unordered_set< Transition >::const_iterator InputEventTransitionIterator
Definition: Component.hh:75
void synchroniseInputs(State state, Event event) const
OutputEventTransitionIterator outputEventTransitionEnd(State s, Event e) const
std::unordered_map< typename Ptr< Component >::ConstP, size_t > _compIds