DiaDes  0.1
DIAgnosis of Discrete-Event System
FaultDiagnosis.cc
Go to the documentation of this file.
1 #include <map>
2 
3 
4 #include <unordered_map>
5 #include <unordered_set>
6 #include <utils/MyTime.hh>
7 #include <FaultDiagnosis.hh>
8 
9 
10 namespace Diades
11 {
12  namespace Automata
13  {
14 
15  /*****************************************************************************************************/
16 
23  FaultDiagnosis::FaultDiagnosis(const vector<const ObservableComponent *> models,
24  const SynchronisationRules & rules,
25  const set<Event> & faults):
26  _type(Comp),_faultEvents(faults),
27  _globalModel(0),_diagnoser(0),_globalComposableModel(0),
28  _currentState(0),
29  _currentFaults(0),_currentGlobalStates()
30  {
31  // initialisation of the diagnosis. The belief state is the product of the initial states
32  // of the components. BE CAREFUL, THE ALGORITHM IS ENUMERATIVE SO IT WONT WORK FOR VERY
33  // BIG SETS. @todo BE SYMBOLIC !!!
34  _currentState = new list< vector<State> >;
35  _currentFaults = new list< set<Event> >;
36  vector<ObservableComponent::InitialStateIterator> its(_models.size());
37  bool finished = false;
38 
39  for(unsigned i = 0; i < models.size(); ++i)
40  {
41  its[i] = models[i]->initialStateBegin();
42  finished = finished
43  ||
44  ( models[i]->initialStateBegin() == models[i]->initialStateEnd());
45  }
46 
47  while(!finished)
48  {
49  _currentState->push_back(vector<State>(_models.size()));
50  _currentFaults->push_back(set<Event>());
51  for(unsigned i = 0; i < _models.size(); ++i)
52  {
53  _currentState->back().operator[](i) = *its[i];
54  }
55  ++its[0];
56  unsigned j = 0;
57  while((j < (_models.size() - 1))
58  &&
59  (its[j] == _models[j]->endOfInitialStates()))
60  {
61  its[j] = _models[j]->beginOfInitialStates();
62  ++j;
63  ++its[j];
64  }
65  finished =
66  (its[_models.size() - 1] == _models[_models.size() - 1]->endOfInitialStates());
67  }
68  // Now let initialize the ComposableModel from which we will retrieve the global model
69  // transitions on the fly.
70  for(unsigned i = 0; i < models.size(); ++i)
71  {
72  _models.push_back(new ComposableModel(*models[i],rules));
73  }
74 
75  // Now the implicit global model
77 
78 
79  }
80 
81 
82  /*****************************************************************************************************/
83 
84 
93  _currentState(0),
95  {
96  require(Exception,diagnoser.valid(),"FaultDiagnosis::constructor: invalid diagnoser");
97  _faultEvents.insert(diagnoser.beginOfDiagnosedEvents(),
98  diagnoser.endOfDiagnosedEvents());
99  // initialisation of the diagnosis. The belief state is the set of initial states
100  // contained in the diagnoser. The data structure _currentState and _currentFaults
101  // are not used in this algorithm as it would be totally redundant with the diagnoser
103  }
104 
105 
106  /*****************************************************************************************************/
107 
113  FaultDiagnosis::FaultDiagnosis(const ObservableComponent & globalModel, const set<Event> & faults):
114  _type(Global),_faultEvents(faults),
115  _globalModel(&globalModel),_diagnoser(0),_models(0), _globalComposableModel(0),_rules(0),
116  _currentState(0),
118  {
119  require(Exception,globalModel.valid(),"FaultDiagnosis::constructor: invalid global model");
120  require(Exception,!faults.empty(),"FaultDiagnosis::constructor: no fault");
121 
122  _currentState = new list< vector<State> >;
123  _currentFaults = new list< set<Event> >;
124  // initialisation of the diagnosis. The belief state is the set of initial states
125  // of the global model
126  // note that for genericity reasons a state is declared as a vector of State (for component-based
127  // algorithms). Here a state is in a vector of size 1.
129  it != globalModel.initialStateEnd();
130  ++it)
131  {
132  vector<State> globalState(1);
133  globalState[0] = *it;
134  _currentState->push_back(globalState);
135  _currentFaults->push_back(set<Event>());
136 
137  }
138  // ok so here _currentState contains the initial belief state according to the model 'globalModel'
139  // and for each state we say that no fault has occurred (in _currentFaults).
140  // for efficieny purpose, _currentGlobalStates will also contain the belief state
141  _currentGlobalStates.insert(globalModel.initialStateBegin(), globalModel.initialStateEnd());
142 
143  }
144 
145 
146  /*****************************************************************************************************/
147 
153  {
154 
155 
156  switch(_type)
157  {
158  case Global:
159  {
160  require(Exception,!_currentState->empty(), "FaultDiagnosis::printDiagnosis The diagnosis is empty");
161  require(Exception,_currentFaults->size() == _currentState->size(), "FaultDiagnosis::printDiagnosis The diagnosis is not correctly set");
162  list< vector<State> >::const_iterator currentStateIt = _currentState->begin();
163  list< set<Event> >::const_iterator currentFaultsIt = _currentFaults->begin();
164  while((currentStateIt != _currentState->end())
165  &&
166  (currentFaultsIt != _currentFaults->end()))
167  {
168  vector<Diades::Graph::NodeId> state;
169  state.push_back(currentStateIt->front().id());
170  vector< set<Event> > faults;
171  faults.push_back(*currentFaultsIt);
172  diagnosis.addCandidate(Candidate(state,faults));
173  ++currentFaultsIt;
174  ++currentStateIt;
175  }
176  }
177  break;
178  case Diagnoser:
179  {
180  _diagnoser->getDiagnosis(diagnosis);
181  }
182  break;
183  default:
184  {
185  cout << "UNKNOWN ALGORITHM" << endl;
186  }
187  }
188  }
189 
190 
191  /*****************************************************************************************************/
192 
198  void FaultDiagnosis::diagnose(const Event & obs)
199  {
200  // so, this method is in charge of diagnosing independently
201  // of the underlying algorithm.
202  switch(_type)
203  {
204  case Global:
205  {
206  globalModelDiagnose(obs);
207  break;
208  }
209  case Diagnoser:
210  {
211  diagnoserDiagnose(obs);
212  break;
213  }
214  case Comp:
215  {
216  componentDiagnose(obs);
217  break;
218  }
219  default:
220  {
221  cout << "HEY MAN, I ALREADY TOLD YOU IT WAS NOT IMPLEMENTED" << endl;
222  }
223  }
224  }
225  /********************************************************************************************/
226 
232  {
233  // this method is in charge of diagnosing 'label'
234  // with a naive search (BFS) on the global model
235 
236 
237  // this structure is in charge of saving the results
238  // By observing 'label' from one initial state one may reach
239  // a set of states. And to reach them, it may be possible
240  // that fault events occur
241  unordered_map< State, list< pair<State,set<Event> > > > solutions;
242 
243 
244  // the state space is (model state x faults)
245  // during the search we need to know the state of the model AND
246  // the set of faults that can occur before reaching this state.
247  list< pair<State,set<Event> > > visitingStates;
248 
249  // here, i will store model states which I found out that no future
250  // trajectory can emit the observation 'label'
251  // a state in "noSolutions" means that the previous diagnosis is refined
252  // any candidate in noSolutions is incompatible with the new observation.
253  set<State> noSolutions;
254  bool thereIsSolution = false;
255 
256  // loop on the current belief state
257  for(set<State>::const_iterator stateIt = _currentGlobalStates.begin();
258  stateIt != _currentGlobalStates.end();
259  ++stateIt)
260  {
261  // just to avoid visiting states an infinite number of time, one is enough
262  unordered_multimap< State , set<Event> > visitedOrVisitingStates;
263 
264  // feel lucky, otherwise i put the current state in the queue and tag it
265  // as visitedOrVisiting to avoid to put it again in the queue afterwards.
266  if(noSolutions.find(*stateIt) == noSolutions.end())
267  {
268  visitingStates.push_back( make_pair(*stateIt, set<Event>()) );
269  visitedOrVisitingStates.insert(visitingStates.back());
270  }
271 
272  // as long as the queue is not empty, there are states to visit
273  while(!visitingStates.empty())
274  {
275  // current model state
276  State & currentState = visitingStates.front().first;
277  // current set of fault that has occured before 'currentState'
278  set<Event> & currentFaults = visitingStates.front().second;
279 
280 
281 
282  bool noSolutionForThisState = true;
283  // let's have a look at the successors of the currentState
285  outTransIt != _globalModel->outputTransitionEnd(currentState); ++outTransIt)
286  {
287  if(_globalModel->getEvent(*outTransIt) == obs)
288  {
289  // good, a transition is labeled with 'obs' so the target is a solution
290  thereIsSolution = true;
291  noSolutionForThisState = false;
292  // so, from *stateIt, by observing 'obs', we can reach 'outTransIt->target()' and
293  // 'currentFaults' has occurred during the trip
294  solutions[*stateIt].push_back(make_pair(outTransIt->target(), currentFaults) );
295  }
296  else
297  {
298  // no luck, it is not obs :-(
299 
300 
301  if(!_globalModel->mask().isObservable(_globalModel->getEvent(*outTransIt)))
302  {
303  // seems this transition is not observable
304  // so we need to explore its successors...
305 
306  if(noSolutions.find(outTransIt->target()) == noSolutions.end())
307  {
308  // the target of the transition is not registered as a "no solution state"
309  // so we need to explore its successors...
310  noSolutionForThisState = false;
311  set<Event> newCurrentFaults = currentFaults;
312 
313  if(_faultEvents.find(_globalModel->getEvent(*outTransIt)) != _faultEvents.end())
314  {
315  // the visited transitions trigger a fault, we need to keep trace of it!
316 
317  newCurrentFaults.insert(_globalModel->getEvent(*outTransIt));
318  }
319 
320  //ok now we need to explore the state (outTransIt->target(), newCurrentFaults)
321  // but it may already be in the queue, let's have a look....
322  typedef unordered_multimap <State, set<Event> >::const_iterator MapIterator;
323  pair< MapIterator, MapIterator > range = visitedOrVisitingStates.equal_range(outTransIt->target());
324 
325  bool found = false;
326  MapIterator visitedIt = range.first;
327  while( (!found) && (visitedIt != range.second) )
328  {
329  found = visitedIt->second == newCurrentFaults;
330  ++visitedIt;
331  }
332 
333  if(!found)
334  {
335  // the state (outTransIt->target(), newCurrentFaults) is not in the queue,
336  // need to add it in the end (that is a BFS)
337  visitingStates.push_back(make_pair(outTransIt->target(),newCurrentFaults));
338  visitedOrVisitingStates.insert(visitingStates.back());
339  }
340  }
341  }
342  }
343  }
344  if(noSolutionForThisState)
345  {
346  // from current state, we have not found any trajectory that
347  // emit the observation 'obs'. Let us save this information somewhere
348  // as it may help for further search...
349  noSolutions.insert(currentState);
350  }
351  // finally current_state has been visited, let us handle the next state in the queue....
352  visitingStates.pop_front();
353  }
354  }
355 
356  if(!thereIsSolution)
357  {
358  // this is the worst case ever, it should never happen with the hypotheses we took for pj work.
359  // anyway, code is never perfect, just for debugging...
360  cout << "No solution found for the following problem" << endl;
361  cout << "Observation = " << obs.label() << endl;
362  cout << "Previous Diagnosis = " << endl;
363  Diagnosis diagnosis;
364  getDiagnosis(diagnosis);
365  cout << diagnosis << endl;
366  }
367 
368  // let us update the diagnosis now!
369  // don't forget that the table solutions contains the result of the search
370  // between the initial beliefstate and the new belief state with
371  // a record of the fault event that has occurred during this search
372  // now we need to 'append' this table with the previous diagnosis
373  // by updating the past set of faults with the new ones....
374 
375 
376 
377  // will put the new belief state here
378  _currentGlobalStates.clear();
379 
380  // let save the previous belief state temporally
381  list< vector<State> > * previousCurrentState = _currentState;
382  list< set<Event> > * previousCurrentFaults = _currentFaults;
383 
384  // and create new structures for the new one
385  _currentState = new list< vector<State> >;
386  _currentFaults = new list< set<Event> >;
387 
388  // for each previous candidate (previousCurrentState,previousCurrentFaults), do....
389  list< vector<State> >::const_iterator previousCurrentStateIt = previousCurrentState->begin();
390  list< set<Event> >::const_iterator previousCurrentFaultsIt = previousCurrentFaults->begin();
391  while((previousCurrentStateIt != previousCurrentState->end())
392  &&
393  (previousCurrentFaultsIt != previousCurrentFaults->end()))
394  {
395  State previousState = previousCurrentStateIt->front(); // only one state in the list here
396 
397  // futureStates are the possible futurs of previousState
398  list< pair< State,set<Event> > > & futureStates = solutions[previousState];
399  for(list< pair<State,set<Event> > >::const_iterator futureStateIt = futureStates.begin();
400  futureStateIt != futureStates.end(); ++futureStateIt)
401  {
402  // futureState is a possible futur of previousState
403  State futureState = futureStateIt->first;
404  // futureFaults is set to be the faults that occurred BEFORE previousState and is appended
405  // to the faults that occurred between previousState and futureState
406  set<Event> futureFaults = *previousCurrentFaultsIt;
407  for(set<Event>::const_iterator codeIt = futureStateIt->second.begin();
408  codeIt != futureStateIt->second.end();
409  ++codeIt)
410  {
411  futureFaults.insert(*codeIt);
412  }
413  // check whether the couple (futureState, futureFaults) is already in the new diagnosis
414  bool found = false;
415  list< vector<State> >::const_iterator currentStateIt = _currentState->begin();
416  list< set<Event> >::const_iterator currentFaultsIt = _currentFaults->begin();
417  while((currentStateIt != _currentState->end())
418  &&
419  (currentFaultsIt != _currentFaults->end())
420  &&
421  (!found))
422  {
423  found = (currentStateIt->front() == futureState)
424  && (*currentFaultsIt == futureFaults);
425  ++currentFaultsIt;
426  ++currentStateIt;
427  }
428  if(!found)
429  {
430  // (futureState, futureFaults) is a new diagnosis candidate, we save it.
431  _currentState->push_back(vector<State>());
432  _currentGlobalStates.insert(futureState);
433  _currentState->back().push_back(futureState);
434  _currentFaults->push_back(futureFaults);
435  }
436  }
437  ++previousCurrentFaultsIt;
438  ++previousCurrentStateIt;
439  }
440 
441  // let us do some cleaning, c++ is not java, it does not do the job for us....
442  for(list< vector<State> >::iterator it = previousCurrentState->begin();
443  it != previousCurrentState->end();
444  ++it)
445  {
446  it->clear();
447  }
448 
449  delete previousCurrentFaults;
450  delete previousCurrentState;
451 
452  ensure(Exception,!_currentGlobalStates.empty(),"_globalModelDiagnose: _currentGlobalStates is empty");
453  ensure(Exception,thereIsSolution,"_globalModelDiagnose: cannot determine a solution (bug or check scenario)");
454 
455  }
456 
457 
458  /********************************************************************************************/
459 
460 
466  {
467  _diagnoser->diagnose(obs);
468  }
469 
470 
471  /********************************************************************************************/
472 
474  {
475  // this method is in charge of diagnosing 'label'
476  // with a naive search (BFS) on the global model
477 
478 
479 
480  // this structure is in charge of saving the results
481  // By observing 'label' from one initial state one may reach
482  // a set of states. And to reach them, it may be possible
483  // that fault events occur
484  unordered_map< State, list< pair<State,set<Event> > > > solutions;
485 
486 
487  // the state space is (model state x faults)
488  // during the search we need to know the state of the model AND
489  // the set of faults that can occur before reaching this state.
490  list< pair<State,set<Event> > > visitingStates;
491 
492  // here, i will store model states which I found out that no future
493  // trajectory can emit the observation 'label'
494  // a state in "noSolutions" means that the previous diagnosis is refined
495  // any candidate in noSolutions is incompatible with the new observation.
496  set<State> noSolutions;
497  bool thereIsSolution = false;
498 
499  // loop on the current belief state
500  for(set<State>::const_iterator stateIt = _currentGlobalStates.begin();
501  stateIt != _currentGlobalStates.end();
502  ++stateIt)
503  {
504  // just to avoid visiting states an infinite number of time, one is enough
505  unordered_multimap< State , set<Event> > visitedOrVisitingStates;
506 
507  // feel lucky, otherwise i put the current state in the queue and tag it
508  // as visitedOrVisiting to avoid to put it again in the queue afterwards.
509  if(noSolutions.find(*stateIt) == noSolutions.end())
510  {
511  visitingStates.push_back( make_pair(*stateIt, set<Event>()) );
512  visitedOrVisitingStates.insert(visitingStates.back());
513  }
514 
515  // as long as the queue is not empty, there are states to visit
516  while(!visitingStates.empty())
517  {
518  // current model state
519  State & currentState = visitingStates.front().first;
520  // current set of fault that has occured before 'currentState'
521  set<Event> & currentFaults = visitingStates.front().second;
522 
523 
524 
525  bool noSolutionForThisState = true;
526  // let's have a look at the successors of the currentState
528  outTransIt != _globalModel->outputTransitionEnd(currentState); ++outTransIt)
529  {
530  if(_globalModel->getEvent(*outTransIt) == obs)
531  {
532  // good, a transition is labeled with 'obs' so the target is a solution
533  thereIsSolution = true;
534  noSolutionForThisState = false;
535  // so, from *stateIt, by observing 'obs', we can reach 'outTransIt->target()' and
536  // 'currentFaults' has occurred during the trip
537  solutions[*stateIt].push_back(make_pair(outTransIt->target(), currentFaults) );
538  }
539  else
540  {
541  // no luck, it is not obs :-(
542 
543 
544  if(!_globalModel->mask().isObservable(_globalModel->getEvent(*outTransIt)))
545  {
546  // seems this transition is not observable
547  // so we need to explore its successors...
548 
549  if(noSolutions.find(outTransIt->target()) == noSolutions.end())
550  {
551  // the target of the transition is not registered as a "no solution state"
552  // so we need to explore its successors...
553  noSolutionForThisState = false;
554  set<Event> newCurrentFaults = currentFaults;
555 
556  if(_faultEvents.find(_globalModel->getEvent(*outTransIt)) != _faultEvents.end())
557  {
558  // the visited transitions trigger a fault, we need to keep trace of it!
559 
560  newCurrentFaults.insert(_globalModel->getEvent(*outTransIt));
561  }
562 
563  //ok now we need to explore the state (outTransIt->target(), newCurrentFaults)
564  // but it may already be in the queue, let's have a look....
565  typedef unordered_multimap <State, set<Event> >::const_iterator MapIterator;
566  pair< MapIterator, MapIterator > range = visitedOrVisitingStates.equal_range(outTransIt->target());
567 
568  bool found = false;
569  MapIterator visitedIt = range.first;
570  while( (!found) && (visitedIt != range.second) )
571  {
572  found = visitedIt->second == newCurrentFaults;
573  ++visitedIt;
574  }
575 
576  if(!found)
577  {
578  // the state (outTransIt->target(), newCurrentFaults) is not in the queue,
579  // need to add it in the end (that is a BFS)
580  visitingStates.push_back(make_pair(outTransIt->target(),newCurrentFaults));
581  visitedOrVisitingStates.insert(visitingStates.back());
582  }
583  }
584  }
585  }
586  }
587  if(noSolutionForThisState)
588  {
589  // from current state, we have not found any trajectory that
590  // emit the observation 'obs'. Let us save this information somewhere
591  // as it may help for further search...
592  noSolutions.insert(currentState);
593  }
594  // finally current_state has been visited, let us handle the next state in the queue....
595  visitingStates.pop_front();
596  }
597  }
598 
599  if(!thereIsSolution)
600  {
601  // this is the worst case ever, it should never happen with the hypotheses we took for pj work.
602  // anyway, code is never perfect, just for debugging...
603  cout << "No solution found for the following problem" << endl;
604  cout << "Observation = " << obs.label() << endl;
605  cout << "Previous Diagnosis = " << endl;
606  Diagnosis diagnosis;
607  getDiagnosis(diagnosis);
608  cout << diagnosis << endl;
609  }
610 
611  // let us update the diagnosis now!
612  // don't forget that the table solutions contains the result of the search
613  // between the initial beliefstate and the new belief state with
614  // a record of the fault event that has occurred during this search
615  // now we need to 'append' this table with the previous diagnosis
616  // by updating the past set of faults with the new ones....
617 
618 
619 
620  // will put the new belief state here
621  _currentGlobalStates.clear();
622 
623  // let save the previous belief state temporally
624  list< vector<State> > * previousCurrentState = _currentState;
625  list< set<Event> > * previousCurrentFaults = _currentFaults;
626 
627  // and create new structures for the new one
628  _currentState = new list< vector<State> >;
629  _currentFaults = new list< set<Event> >;
630 
631  // for each previous candidate (previousCurrentState,previousCurrentFaults), do....
632  list< vector<State> >::const_iterator previousCurrentStateIt = previousCurrentState->begin();
633  list< set<Event> >::const_iterator previousCurrentFaultsIt = previousCurrentFaults->begin();
634  while((previousCurrentStateIt != previousCurrentState->end())
635  &&
636  (previousCurrentFaultsIt != previousCurrentFaults->end()))
637  {
638  State previousState = previousCurrentStateIt->front(); // only one state in the list here
639 
640  // futureStates are the possible futurs of previousState
641  list< pair< State,set<Event> > > & futureStates = solutions[previousState];
642  for(list< pair<State,set<Event> > >::const_iterator futureStateIt = futureStates.begin();
643  futureStateIt != futureStates.end(); ++futureStateIt)
644  {
645  // futureState is a possible futur of previousState
646  State futureState = futureStateIt->first;
647  // futureFaults is set to be the faults that occurred BEFORE previousState and is appended
648  // to the faults that occurred between previousState and futureState
649  set<Event> futureFaults = *previousCurrentFaultsIt;
650  for(set<Event>::const_iterator codeIt = futureStateIt->second.begin();
651  codeIt != futureStateIt->second.end();
652  ++codeIt)
653  {
654  futureFaults.insert(*codeIt);
655  }
656  // check whether the couple (futureState, futureFaults) is already in the new diagnosis
657  bool found = false;
658  list< vector<State> >::const_iterator currentStateIt = _currentState->begin();
659  list< set<Event> >::const_iterator currentFaultsIt = _currentFaults->begin();
660  while((currentStateIt != _currentState->end())
661  &&
662  (currentFaultsIt != _currentFaults->end())
663  &&
664  (!found))
665  {
666  found = (currentStateIt->front() == futureState)
667  && (*currentFaultsIt == futureFaults);
668  ++currentFaultsIt;
669  ++currentStateIt;
670  }
671  if(!found)
672  {
673  // (futureState, futureFaults) is a new diagnosis candidate, we save it.
674  _currentState->push_back(vector<State>());
675  _currentGlobalStates.insert(futureState);
676  _currentState->back().push_back(futureState);
677  _currentFaults->push_back(futureFaults);
678  }
679  }
680  ++previousCurrentFaultsIt;
681  ++previousCurrentStateIt;
682  }
683 
684  // let us do some cleaning, c++ is not java, it does not do the job for us....
685  for(list< vector<State> >::iterator it = previousCurrentState->begin();
686  it != previousCurrentState->end();
687  ++it)
688  {
689  it->clear();
690  }
691 
692  delete previousCurrentFaults;
693  delete previousCurrentState;
694 
695  ensure(Exception,!_currentGlobalStates.empty(),"_globalModelDiagnose: _currentGlobalStates is empty");
696  ensure(Exception,thereIsSolution,"_globalModelDiagnose: cannot determine a solution (bug or check scenario)");
697 
698  }
699 
700  };
701 };
702 
703 
const Label & label() const
void getDiagnosis(Diagnosis &diagnosis) const
list< vector< State > > * _currentState
const ObservableComponent * _globalModel
unordered_set< Event >::const_iterator beginOfDiagnosedEvents() const
void diagnoserDiagnose(const Event &obs)
FaultDiagnosis(const vector< const ObservableComponent *> models, const SynchronisationRules &rules, const set< Event > &faults)
#define ensure(Exception, expr, message)
Definition: Assertion.hh:98
list< set< Event > > * _currentFaults
void diagnose(const Event &obs)
void addCandidate(const Candidate &candidate)
unordered_set< State >::const_iterator InitialStateIterator
Definition: Component.hh:70
InitialStateIterator initialStateEnd() const
Definition: Component.hh:648
An observable Component defined as a automaton.
void getDiagnosis(Diagnosis &diagnosis)
ComposableModel * _globalComposableModel
InitialStateIterator initialStateBegin() const
Definition: Component.hh:638
const SynchronisationRules * _rules
Definition: Diagnose.cc:84
#define require(Exception, expr, message)
Definition: Assertion.hh:90
Diades::Graph::OutEdgeIterator OutputTransitionIterator
Definition: Component.hh:72
Namespace of the Diades project.
ClassicalDiagnoser * _diagnoser
OutputTransitionIterator outputTransitionBegin(State s) const
Definition: Component.hh:913
const ObservableMask & mask() const
unordered_set< Event >::const_iterator endOfDiagnosedEvents() const
void componentDiagnose(const Event &obs)
bool isObservable(const Event &e) const
const Event & getEvent(Transition t) const
Definition: Component.hh:304
Diades::Graph::Node State
Definition: BeliefState.hh:36
vector< const ComposableModel * > _models
typename Map< Key, Value >::iterator MapIterator
Definition: MapIterators.hh:32
void globalModelDiagnose(const Event &obs)
OutputTransitionIterator outputTransitionEnd(State s) const
Definition: Component.hh:925
void diagnose(const Event &obs)