DiaDes  0.1
DIAgnosis of Discrete-Event System
ActiveDiagnoser.cc
Go to the documentation of this file.
1 
14 #include <string>
15 #include <vector>
16 #include <set>
17 #include <iostream>
18 #include <fstream>
19 #include <boost/program_options/options_description.hpp>
20 #include <boost/program_options/positional_options.hpp>
21 #include <boost/program_options/variables_map.hpp>
22 #include <boost/program_options/parsers.hpp>
23 #include <utils/StringTools.hh>
24 #include <automata/Event.hh>
27 #include <sdmdl/SdmdlParser.hpp>
28 #include <sdmdl/SdmdlLexer.hpp>
29 #include <sdmdl/Unfolding.hh>
30 
31 namespace po = boost::program_options;
32 using std::string;
33 using std::vector;
34 using std::cout;
35 using std::endl;
36 using std::set;
37 using std::ifstream;
43 
44 
45 /**************************************************************************************/
46 
47 
57 {
58  switch(tag)
59  {
60  case SpecialisedActiveDiagnoser::Tag::Undiscriminable:
61  {
62  return "U";
63  }
64  case SpecialisedActiveDiagnoser::Tag::Discriminable:
65  {
66  return "D";
67  }
68  case SpecialisedActiveDiagnoser::Tag::Safe:
69  {
70  return "N";
71  }
72  case SpecialisedActiveDiagnoser::Tag::Sure:
73  {
74  return "Y";
75  }
76  }
77  return "";
78 }
79 
80 
121 int export2Hydiag(const SpecialisedActiveDiagnoser & diagnoser, const string & filename)
122 {
123  bool result = 0;
124  stringstream logStream;
125  ofstream file(filename.c_str());
126 
127 
128  if(!file)
129  {
130  result = 1;
131  logStream << "cannot open file '" << filename << "'.";
132  }
133  else
134  {
135  file << (diagnoser.numberOfStates() - 1) << endl;
136  if(!file)
137  {
138  result = 1;
139  logStream << "cannot write the number of states in file " << filename << ".";
140  }
141  else
142  {
143  file << diagnoser.events().size() << endl;
144  if(!file)
145  {
146  result = 1;
147  logStream << "cannot write the number of observable events in file " << filename << ".";
148  }
149  else
150  {
151  NodeMap<unsigned> indexOf(diagnoser.behaviour());
152  vector<State> states;
153  int index = 0;
154  indexOf[diagnoser.initialState()] = index;
155  ++index;
156 
157  // writing the states
158  stringstream streamStates;
159  streamStates << "(";
160  states.push_back(diagnoser.initialState());
161  streamStates << (indexOf[diagnoser.initialState()]+1) << "," << tag(diagnoser.tag(diagnoser.initialState())) << ")";
162  string initial = streamStates.str();
163  streamStates << endl;
164  // duplication of the initial state
165  streamStates << initial;
166 
167  for(SpecialisedActiveDiagnoser::StateIterator stateIt = diagnoser.stateBegin();
168  stateIt != diagnoser.stateEnd();
169  ++stateIt)
170  {
171  if(*stateIt != diagnoser.initialState())
172  {
173  if(!diagnoser.isHole(*stateIt))
174  {
175  states.push_back(*stateIt);
176  indexOf[*stateIt] = index;
177  ++index;
178  streamStates << " (" << (indexOf[*stateIt]+1) << "," << tag(diagnoser.tag(*stateIt)) << ")";
179  }
180  }
181  }
182  file << streamStates.str() << endl;
183  if(!file)
184  {
185  result = 1;
186  logStream << "cannot write the list of belief states in file " << filename << ".";
187  }
188  else
189  {
190  string observationLabels;
191  vector<Diades::Automata::Event> observations;
192  // writing the observations
193  for(const Diades::Automata::Event & evt : diagnoser.events())
194  {
195  observations.push_back(evt);
196  observationLabels += evt.nickname() + " ";
197  }
198  file << observationLabels << endl;
199  if(!file)
200  {
201  result = 1;
202  logStream << "cannot write the list of observations in file " << filename << ".";
203  }
204  else
205  {
206  // writing the incidence matrix
207  vector<Diades::Automata::Event>::size_type i = 0;
208  while((result==0) && (i < observations.size()))
209  {
210  stringstream matrixLine;
211  for(vector<State>::size_type j = 0; j < states.size(); ++j)
212  {
213  SpecialisedActiveDiagnoser::OutputEventTransitionIterator transIt = diagnoser.outputEventTransitionBegin(states[j],observations[i]);
214  if(transIt != diagnoser.outputEventTransitionEnd(states[j],observations[i]))
215  {
216  if(!diagnoser.isHole(transIt->target()))
217  {
218  matrixLine << indexOf[transIt->target()] << " ";
219  }
220  else
221  {
222  matrixLine << -1 << " ";
223  }
224  }
225  else
226  {
227  matrixLine << -1 << " ";
228  }
229  }
230 
231  file << matrixLine.str() << endl;
232  if(!file)
233  {
234  result = 1;
235  logStream << "cannot write the line " << i << " of the incidence matrix in file " << filename << ".";
236  }
237  else
238  {
239  ++i;
240  }
241  }
242  }
243  }
244  }
245  }
246  if(result!= 0)
247  {
248  cerr << "Export to HyDiag: " + logStream.str() << endl;
249  }
250  }
251  return result;
252 }
253 
254 
255 
256 /**************************************************************************************/
257 
258 
270 int initialiseModelFromDesComp(const string & filename,
271  ObservableComponent & globalModel,
272  const set<string> & shortNameFaults,
273  unordered_map<string,string> & dictionary,
274  set<string> & faults,
275  set<string> & nominals)
276 {
277  int result = 0;
278  try
279  {
280  string log;
281  if( ! globalModel.import(filename.c_str()))
282  {
283  cerr << "Model import: problem, see the log below: " << endl;
284  cerr << "LOG START:" << endl;
285  cerr << log << endl;
286  cerr << "LOG END" << endl;
287  result = 1;
288  }
289  else
290  {
291  for(const Diades::Automata::Event & evt : globalModel.events())
292  {
293  dictionary[evt.label()]= evt.nickname();
294  if(shortNameFaults.find(evt.nickname()) != shortNameFaults.end())
295  {
296  faults.insert(evt.label());
297  }
298  else
299  {
300  nominals.insert(evt.label());
301  }
302  }
303  }
304  }
305  catch(std::exception & e)
306  {
307  result = 1;
308  }
309 
310  return result;
311 }
312 
313 
314 
315 /**************************************************************************************/
316 
329 int initialiseModelFromSdmdl(const string & filename,
330  ObservableComponent & globalModel,
331  VariableFactory & factory,
332  const set<string> & shortNameIgnored,
333  const set<string> & shortNameFaults,
334  unordered_map<string,string> & dictionary,
335  set<string> & faults,
336  set<string> & nominals)
337 {
338  int result = 0;
339  map<string,ComponentType *> results;
340  try
341  {
342  ifstream file(filename);
343  SdmdlLexer lexer(file);
344  bool verbose = false;
345  SdmdlParser parser(lexer);
346  stringstream parsingLog;
347  parser.libraryUnit(results,factory,verbose,parsingLog);
348  file.close();
349  if(results.empty())
350  {
351  cerr << "Error: no model is loaded." << endl;
352  cerr << parsingLog.str() << endl;
353  result = 1;
354  }
355  else
356  {
357  ComponentType & component = *results.begin()->second;
358  set<string> nonNominalEvents;
359 
360 
361  for(set<string>::const_iterator it = shortNameIgnored.begin();
362  it != shortNameIgnored.end();
363  ++it)
364  {
365  if(component.containsSpontaneousEventOfLabel(*it))
366  {
367  nonNominalEvents.insert(component.spontaneousPort().label() + "." + *it);
368  }
369  else
370  {
371  nonNominalEvents.insert(*it);
372  }
373  }
374 
375  for(set<string>::const_iterator it = shortNameFaults.begin();
376  it != shortNameFaults.end();
377  ++it)
378  {
379  if(component.containsSpontaneousEventOfLabel(*it))
380  {
381  nonNominalEvents.insert(component.spontaneousPort().label() + "." + *it);
382  faults.insert(component.spontaneousPort().label() + "." + *it);
383  }
384  else
385  {
386  nonNominalEvents.insert(*it);
387  faults.insert(*it);
388  }
389  }
390 
391  for(ComponentType::EventIterator it = component.beginOfInputEvents();
392  it != component.endOfInputEvents();
393  ++it)
394  {
395  if(nonNominalEvents.find((*it)->label()) == nonNominalEvents.end())
396  {
397  nominals.insert((*it)->label());
398  }
399  }
400 
401  set<string> triggers = nominals;
402  for(set<string>::const_iterator faultIt = faults.begin();
403  faultIt != faults.end();
404  ++faultIt)
405  {
406  triggers.insert(*faultIt);
407  }
408  Unfolding unfold2(component,triggers,dictionary,"global_model");
409  string log;
410  string globalModelFileName ("global_model.des_comp");
411  if( ! globalModel.import(globalModelFileName.c_str()))
412  {
413  cerr << "Model import: problem, see the log below: " << endl;
414  cerr << "LOG START:" << endl;
415  cerr << log << endl;
416  cerr << "LOG END" << endl;
417  result = 1;
418  }
419  }
420  }
421  catch(std::exception & e)
422  {
423  result = 1;
424  }
425  for(std::pair<const string,ComponentType *> & p : results)
426  {
427  if(p.second != nullptr)
428  {
429  delete p.second;
430  p.second = nullptr;
431  }
432  }
433  results.clear();
434  return result;
435 }
436 
437 /**************************************************************************************/
438 
439 
449 int initialiseDiagnosers(const ObservableComponent & model, const set<string> & faults,
450  unordered_map<string,string> & dictionnary,
451  unordered_map<string,SpecialisedActiveDiagnoser *> & activeDiagnoser)
452 {
453  int result = 0;
454  for(set<string>::const_iterator faultIt = faults.begin();
455  faultIt != faults.end();
456  ++faultIt)
457  {
458  std::cout << "Computation of the diagnoser..." << (model.name()+ "." + dictionnary[*faultIt]) << std::endl;
459  activeDiagnoser[*faultIt] = new SpecialisedActiveDiagnoser(model,EventFactory::factory()->getEvent(model.name()+ "." + dictionnary[*faultIt]));
460  std::cout << "this is done" << std::endl;
461  string log;
462  if(!activeDiagnoser[*faultIt]->sanityCheck(log))
463  {
464  cout << "SANITY CHECK ERROR of the active diagnoser of fault " << *faultIt << ":" << endl;
465  cout << log << endl;
466  return 1;
467  }
468 
469  }
470  return result;
471 }
472 
473 /**************************************************************************************/
474 
475 
481 void printUsage(const po::options_description & desc)
482 {
483  cout << "Diades: active diagnoser" << endl;
484  cout << "LAAS, CNRS, Univ. Toulouse, FRANCE. Copyright 2006-2014" << endl;
485  cout << "Contact: ypencole@laas.fr" << endl << endl;
486 
487  cout << desc << endl;
488  cout << "Compute the active diagnoser of the file 'file.sdmdl' or the file" << endl;
489  cout << "'file.des_comp'. The events listed after '--faults' are considered" << endl;
490  cout << "as fault events. The events listed after '--ignored' are simply" << endl;
491  cout << "ignored INPUT events in the model 'file.sdmdl' (this option is" << endl;
492  cout << "simply ignored if the model is in 'des_comp' format. Any event" << endl;
493  cout << "that is in the model but not listed as a fault or as an ignored" << endl;
494  cout << "event is considered as a normal event." << endl;
495 }
496 
497 /**************************************************************************************/
498 
499 
508 int main(int ac, char ** av)
509 {
510  // Declare the supported options.
511  po::options_description desc("Allowed options");
512  desc.add_options()
513  ("help", "produce this help message")
514  ("model-file", po::value<string>(), "model file")
515  ("fault", po::value< vector<string> >(), "fault event")
516  ("ignored", po::value< vector<string> >(), "ignored input event (sdmdl model only)")
517  ("had", po::value<string>(), "Hydiag Active Diagnoser format")
518  ("dot", po::value<string>(), "dot (graphviz) format")
519  ;
520  po::positional_options_description p;
521  p.add("model-file", -1);
522  po::variables_map vm;
523  po::store(po::command_line_parser(ac, av).
524  options(desc).positional(p).run(), vm);
525  po::notify(vm);
526 
527  if (vm.count("help"))
528  {
529  printUsage(desc);
530  return 0;
531  }
532  string filename;
533  if(vm.count("model-file"))
534  {
535  filename = vm["model-file"].as<string>();
536  }
537  else
538  {
539  cout << "ERROR: expecting a model file (sdmdl or des_comp extensions)" << endl << endl;
540  printUsage(desc);
541  return 1;
542  }
543  vector<string> suffixes = { "sdmdl", "des_comp" };
544  vector<string>::const_iterator it = Diades::Utils::getFileExtension(filename,suffixes.begin(),suffixes.end());
545  if(it == suffixes.end())
546  {
547  cout << "ERROR: wrong suffix in the name of the model file. Expecting 'sdmdl' or 'des_comp' formats." << endl << endl;
548  printUsage(desc);
549  return 1;
550  }
551  bool isSdmdl = (*it == "sdmdl");
552  set<string> shortNameFaults;
553  if(vm.count("fault"))
554  {
555  const vector<string> & vtr = vm["fault"].as<vector<string>>();
556  for(size_t i = 0; i < vtr.size(); ++i)
557  {
558  shortNameFaults.insert(vtr[i]);
559  }
560  }
561  set<string> shortNameIgnored;
562  if(isSdmdl)
563  {
564  if(vm.count("ignored"))
565  {
566  const vector<string> & vtr = vm["ignored"].as<vector<string>>();
567  for(size_t i = 0; i < vtr.size(); ++i)
568  {
569  shortNameIgnored.insert(vtr[i]);
570  }
571  }
572  }
573  bool had = vm.count("had");
574  bool dot = vm.count("dot");
575  string hadfilename;
576  string dotfilename;
577  if(had)
578  {
579  hadfilename = vm["had"].as<string>();
580  }
581  if(dot)
582  {
583  dotfilename = vm["dot"].as<string>();
584  }
585 
586 
587 
588 
589  ObservableComponent globalModel;
590  unordered_map<string,string> dictionary;
591  set<string> faultEvents;
592  set<string> nominalEvents;
593  if(isSdmdl)
594  {
595  VariableFactory * factory = new VariableFactory();
596  int result = initialiseModelFromSdmdl(filename,globalModel,*factory,shortNameIgnored,shortNameFaults,dictionary,faultEvents,nominalEvents);
597  if(result!=0)
598  {
599  cout << "ERROR: the generation of the global model (automaton) from the sdmdl description has failed. Check your model." << endl;
600  delete factory;
601  return 1;
602  }
603  }
604  else
605  {
606  int result = initialiseModelFromDesComp(filename,globalModel,shortNameFaults,dictionary,faultEvents,nominalEvents);
607  if(result!=0)
608  {
609  cout << "ERROR: the import of the global model (automaton) from the des_comp file has failed. Check your model." << endl;
610  return 1;
611  }
612  }
613  unordered_map<string,SpecialisedActiveDiagnoser *> activeDiagnoser;
614  int result = initialiseDiagnosers(globalModel, faultEvents, dictionary, activeDiagnoser);
615  if(result != 0)
616  {
617  cout << "ERROR: the sanity check of the active diagnosers has failed." << endl;
618  return 1;
619  }
620  if(dot)
621  {
622  if(faultEvents.size()==1)
623  {
624  for(std::pair<const string,SpecialisedActiveDiagnoser *> & p : activeDiagnoser)
625  {
626  p.second->diagnoser2Dot(dotfilename);
627  }
628  }
629  else
630  {
631  string dotfilenameprefix;
632  unsigned found = dotfilename.find_last_of(".dot");
633  if(found!= string::npos)
634  {
635  if(found+1 == dotfilename.size())
636  {
637  dotfilenameprefix = dotfilename.substr(0,found-3);
638  }
639  else
640  {
641  dotfilenameprefix = dotfilename;
642  }
643  }
644  for(std::pair<const string,SpecialisedActiveDiagnoser *> & p : activeDiagnoser)
645  {
646  string filename = dotfilenameprefix + p.first.substr(p.first.find_first_of(".")+1,p.first.size()) + ".dot";
647  p.second->diagnoser2Dot(filename);
648  }
649  }
650  }
651  if(had)
652  {
653  if(faultEvents.size()==1)
654  {
655  for(std::pair<const string,SpecialisedActiveDiagnoser *> & p : activeDiagnoser)
656  {
657  int result = export2Hydiag(*p.second,hadfilename);
658  if(result != 0)
659  {
660  cout << "ERROR: abort." << endl;
661  }
662  }
663  }
664  else
665  {
666  string hadfilenameprefix;
667  unsigned found = hadfilename.find_last_of(".had");
668  if(found!= string::npos)
669  {
670  if(found+1 == hadfilename.size())
671  {
672  hadfilenameprefix = hadfilename.substr(0,found-3);
673  }
674  else
675  {
676  hadfilenameprefix = hadfilename;
677  }
678  }
679  for(std::pair<const string,SpecialisedActiveDiagnoser *> & p : activeDiagnoser)
680  {
681  string filename = hadfilenameprefix + p.first.substr(p.first.find_first_of(".")+1,p.first.size()) + ".had";
682  int result = export2Hydiag(*p.second,filename);
683  if(result != 0)
684  {
685  cout << "ERROR: abort." << endl;
686  }
687  }
688  }
689  }
690  return 0;
691 }
692 
693 
694 // /*
695 // * ActiveDiagnoser.cc
696 // *
697 // * Created on: 30 sept. 2008
698 // * Author: ypencole
699 // */
700 
701 
702 // #include <unordered_map>
703 // #include <iostream>
704 // #include <fstream>
705 // #include <map>
706 // #include <ctime>
707 // #include <automata/Trace.hh>
708 // #include <automata/SpecialisedActiveDiagnoser.hh>
709 // #include <utils/Substring.hh>
710 // #include <sdmdl/ComponentType.hh>
711 // #include <sdmdl/Unfolding.hh>
712 // #include <sdmdl/SdmdlLexer.hpp>
713 // #include <sdmdl/SdmdlParser.hpp>
714 // #include <active/aostar.h>
715 // #include <active/fault.h>
716 // #include <active/test.h>
717 // #include <active/obs.h>
718 
719 // using namespace Diades::Automata;
720 // using namespace Diades::Utils;
721 // using namespace Diades::Sdmdl;
722 
723 // using namespace aostar;
724 
725 // /// print out how to use the program on the standard output
726 // void printUsage();
727 
728 // /**
729 // 1) load the sdmdl file into a ComponentType object (symbolic/logic representation)
730 // 2) translate into a Model object (DES representation, see SAFEPROCESS article)
731 // and write the file "global_model.lafmodel
732 // 3) create a dictionnary (sdmdl event -> lafmodel event)
733 // **/
734 // void initialiseModels(int argc, char ** argv, VariableFactory * factory, ComponentType ** component,
735 // ObservableComponent ** model, unordered_map<string,string> & dictionnary,
736 // set<string> & faults, set<string> & nominal);
737 
738 // /**
739 // Initialise a specialised diagnoser for each fault (see SAFEPROCESS article)
740 // **/
741 // void initialiseDiagnosers(const ObservableComponent * model, const set<string> & faults,
742 // unordered_map<string,string> & dictionnary,
743 // unordered_map<string,SpecialisedActiveDiagnoser *> & activeDiagnoser);
744 
745 // /******************************************************************************************/
746 
747 // /**
748 // 1) load the cost file
749 // 2) initialize C_Obs, C_Test and C_Fault structures
750 // **/
751 // vector<C_Obs*> initObs(unordered_map<string,string> dictionnary);
752 
753 // void costFilePaser(string fileName, unordered_map<string,string> & dictionnary,
754 // vector<C_Obs*>& obs, vector<C_Test*>& test, vector<C_Fault*>& fault);
755 
756 // /**
757 // generate a scenario on globalModel
758 // **/
759 // vector<string> scenario(const ObservableComponent * model, const set<string> & faults, State& initialState);
760 // Diades::Graph::OutEdgeIterator randTrans(State currentState);
761 
762 // /**
763 // browse the scenario on the active diagnoser en return the initial state for AO*
764 // **/
765 // vector<State> activeDiagnoserBrowser(vector<string> seq, const set<string> & faults,
766 // unordered_map<string,SpecialisedActiveDiagnoser *> & activeDiagnoser);
767 
768 // /******************************************************************************************/
769 
770 // int main(int argc, char ** argv)
771 // {
772 // // Offline computation
773 // VariableFactory * factory = new VariableFactory();
774 // ObservableComponent * globalModel;
775 // ComponentType * component;
776 // unordered_map<string,SpecialisedActiveDiagnoser *> activeDiagnoser;
777 // unordered_map<string,string> dictionnary;
778 // set<string> faultEvents;
779 // set<string> nominalEvents;
780 
781 // initialiseModels(argc, argv, factory, &component, &globalModel, dictionnary, faultEvents, nominalEvents);
782 // initialiseDiagnosers(globalModel, faultEvents, dictionnary, activeDiagnoser);
783 
784 // // globalModel contains the DES model (see AModel/Model.hh)
785 // // activeDiagnoser[faultEvent] contains the specialised active diagnoser of the fault 'fault event'
786 
787 // //Online computation (NICOLAS)
788 
789 // // cost file parser
790 
791 // vector<C_Obs*> r_pObs = initObs(dictionnary);
792 // vector<C_Test*> r_pTest;
793 // vector<C_Fault*> r_pFault;
794 // string filename = argv[1];
795 // string key = "sdmdl";
796 // size_t found = filename.rfind(key);
797 // if (found!=string::npos)
798 // filename.replace (found,key.length(),"cost");
799 
800 // costFilePaser(filename, dictionnary, r_pObs, r_pTest, r_pFault);
801 
802 // // 1) générer un scénario (séquences d'événements) sur le globalModel
803 
804 // vector<State> currentState;
805 // State initialState;
806 // vector<string> sequence;
807 
808 // //do {
809 // cout << "Generation of a scenario...." << flush;
810 // sequence = scenario(globalModel, faultEvents, initialState);
811 // cout << "Done." << endl;
812 
813 // // 2) faire tourner chaque diagnostiqueur sur la séquence d'observation associée au scénario
814 
815 // currentState = activeDiagnoserBrowser(sequence, faultEvents, activeDiagnoser);
816 
817 // //}while( !(currentState[0].id()== 9) );//65 && currentState[1].id()== 26) );
818 
819 // #ifdef __DEBUG
820 // for(unsigned i = 0;i < currentState.size() ; ++i)
821 // {
822 // cout << activeDiagnoser[r_pFault[i]->Get_Name()]->eventLabel() << " " << currentState[i];
823 // switch(activeDiagnoser[r_pFault[i]->Get_Name()]->tag(currentState[i]))
824 // {
825 // case 0 : cout << "\tUndiscriminable" << endl;break;
826 // case 1 : cout << "\tDiscriminable" << endl;break;
827 // case 2 : cout << "\tSafe" << endl;break;
828 // case 3 : cout << "\tSure" << endl;break;
829 // }
830 // }
831 // #endif
832 
833 // // 3) en fonction des tags courants des diagnostiqueurs, lancé la planif diag actif
834 
835 // vector<string> seq;
836 
837 // C_Aostar l_Ao(r_pFault,r_pTest,r_pObs,sequence,activeDiagnoser);
838 
839 // if(l_Ao.Init(currentState))
840 // seq = l_Ao.Run();
841 
842 // // A FAIRE
843 
844 // // 4) appliquer le plan conditionnel sur le globalModel
845 
846 // return EXIT_SUCCESS;
847 // }
848 
849 // /******************************************************************************************/
850 
851 // void initialiseModels(int argc, char ** argv, VariableFactory * factory, ComponentType ** component,
852 // ObservableComponent ** model, unordered_map<string,string> & dictionnary,
853 // set<string> & faults, set<string> & nominal)
854 // {
855 // if(argc < 4)
856 // {
857 // printUsage();
858 // exit(1);
859 // }
860 // string currentParameter = argv[1];
861 // string goodSuffix = ".sdmdl";
862 // if (currentParameter.size() <= goodSuffix.size())
863 // {
864 // cerr << "Error: the file name " << currentParameter << " is incorrect." << endl;
865 // printUsage();
866 // exit(1);
867 // }
868 // else
869 // {
870 // string suffix = currentParameter.substr(currentParameter.size()-goodSuffix.size(),
871 // currentParameter.size()-1);
872 // if(suffix != goodSuffix)
873 // {
874 // cerr << "Error: the file name " << currentParameter << " is incorrect." << endl;
875 // exit(1);
876 // }
877 // }
878 
879 // currentParameter = argv[2];
880 // if(currentParameter != "--faults")
881 // {
882 // cerr << "Error: '--faults' is expected but it is " << currentParameter << " instead." << endl;
883 // printUsage();
884 // exit(1);
885 // }
886 
887 // // load the faulty events
888 // set<string> faultsWithShortName;
889 // int index = 3;
890 
891 // #ifdef __DEBUG
892 // cout << "Fault events: " << endl;
893 // #endif
894 
895 // while(index < argc && (currentParameter != "--ignored"))
896 // {
897 // currentParameter = argv[index];
898 // if(currentParameter != "--ignored")
899 // {
900 // faultsWithShortName.insert(currentParameter);
901 
902 // #ifdef __DEBUG
903 // cout << "\t " << currentParameter << endl;
904 // #endif
905 
906 // ++index;
907 // }
908 // }
909 
910 // set<string> ignored;
911 
912 // if(index != argc)
913 // {
914 // if(faultsWithShortName.empty())
915 // {
916 // cerr << "Error: no fault is listed so it is useless to compute an active diagnoser." << endl;
917 // printUsage();
918 // exit(1);
919 // }
920 // ++index;
921 
922 // // load the ignored events
923 // #ifdef __DEBUG
924 // cout << "Ignored events: " << endl;
925 // #endif
926 
927 // while(index < argc)
928 // {
929 // currentParameter = argv[index];
930 
931 // #ifdef __DEBUG
932 // cout << "\t " << currentParameter << endl;
933 // #endif
934 
935 // ignored.insert(currentParameter);
936 // ++index;
937 // }
938 // }
939 
940 // // Load the model
941 // #ifdef __DEBUG
942 // cout << "Model loading: " << argv[1] << endl;
943 // #endif
944 
945 // ifstream file(argv[1]);
946 // SdmdlLexer lexer(file);
947 // bool verbose = false;
948 // SdmdlParser parser(lexer);
949 // map<string,ComponentType *> results;
950 // stringstream parsingLog;
951 // parser.libraryUnit(results,*factory,verbose,parsingLog);
952 
953 // #ifdef __DEBUG
954 // cout << "Model sucessfully loaded" << endl;
955 // #endif
956 
957 // if(results.empty())
958 // {
959 // cerr << "Error: no model is loaded." << endl;
960 // cerr << parsingLog.str() << endl;
961 // exit(1);
962 // }
963 
964 // *component = results.begin()->second;
965 
966 // set<string> nonNominalEvents;
967 
968 // for(set<string>::const_iterator it = ignored.begin();
969 // it != ignored.end();
970 // ++it)
971 // {
972 // if((*component)->containsSpontaneousEventOfLabel(*it))
973 // {
974 // nonNominalEvents.insert((*component)->spontaneousPort().label() + "." + *it);
975 // }
976 // else
977 // {
978 // nonNominalEvents.insert(*it);
979 // }
980 // }
981 
982 // for(set<string>::const_iterator it = faultsWithShortName.begin();
983 // it != faultsWithShortName.end();
984 // ++it)
985 // {
986 // if((*component)->containsSpontaneousEventOfLabel(*it))
987 // {
988 // nonNominalEvents.insert((*component)->spontaneousPort().label() + "." + *it);
989 // faults.insert((*component)->spontaneousPort().label() + "." + *it);
990 // }
991 // else
992 // {
993 // nonNominalEvents.insert(*it);
994 // faults.insert(*it);
995 
996 // #ifdef __DEBUG
997 // cout << *it << " is a fault non-spontaneous event" << endl;
998 // #endif
999 
1000 // }
1001 // }
1002 
1003 // for(ComponentType::EventIterator it = (*component)->beginOfInputEvents();
1004 // it != (*component)->endOfInputEvents();
1005 // ++it)
1006 // {
1007 // if(nonNominalEvents.find((*it)->label()) == nonNominalEvents.end())
1008 // {
1009 // nominal.insert((*it)->label());
1010 // }
1011 // }
1012 
1013 // // compute the whole model of the system
1014 // #ifdef __DEBUG
1015 // cout << "Compute the global behavioural model of the system..." << endl;
1016 // #endif
1017 
1018 // set<string> triggers = nominal;
1019 // for(set<string>::const_iterator faultIt = faults.begin();
1020 // faultIt != faults.end();
1021 // ++faultIt)
1022 // {
1023 // triggers.insert(*faultIt);
1024 // }
1025 // Unfolding unfold2(**component,triggers,dictionnary,"global_model");
1026 // *model = new ObservableComponent();
1027 // string log;
1028 // string globalModelFileName ("global_model.des_comp");
1029 
1030 // // (*model)->import(globalModelFileName.c_str(),true);
1031 // if( ! (*model)->import(globalModelFileName.c_str()) )
1032 // {
1033 // cerr << "Model import: problem, see the log below: " << endl;
1034 // cerr << "LOG START:" << endl;
1035 // cerr << log << endl;
1036 // cerr << "LOG END" << endl;
1037 // }
1038 // if(! (*model)->component2dot("global_model.dot") )
1039 // {
1040 // cerr << "Model export: problem, see the log below: " << endl;
1041 // cerr << "LOG START:" << endl;
1042 // cerr << log << endl;
1043 // cerr << "LOG END" << endl;
1044 // }
1045 
1046 // #ifdef __DEBUG
1047 // cout << "Done" << endl;
1048 // #endif
1049 // }
1050 
1051 // /******************************************************************************************/
1052 
1053 // void initialiseDiagnosers(const ObservableComponent * model, const set<string> & faults,
1054 // unordered_map<string,string> & dictionnary,
1055 // unordered_map<string,SpecialisedActiveDiagnoser *> & activeDiagnoser)
1056 // {
1057 // for(set<string>::const_iterator faultIt = faults.begin();
1058 // faultIt != faults.end();
1059 // ++faultIt)
1060 // {
1061 // #ifdef __DEBUG
1062 // cout << "Compute the active diagnoser of the fault " << dictionnary[*faultIt] << " = " << *faultIt << "." << endl;
1063 // #endif
1064 
1065 
1066 // activeDiagnoser[*faultIt] = new SpecialisedActiveDiagnoser(*model,EventFactory::factory()->getEvent(model->name()+ "." + dictionnary[*faultIt]));
1067 // activeDiagnoser[*faultIt]->diagnoser2Dot(*faultIt + "_active_diagnoser.dot");
1068 
1069 // #ifdef __DEBUG
1070 // cout << "Done." << endl;
1071 // #endif
1072 // }
1073 // }
1074 
1075 // /*******************************************************************************************/
1076 
1077 // void printUsage()
1078 // {
1079 // cerr << "ActiveDiagnoser file.sdmdl --faults evt1 [evt2 ...] [--ignored evt3 [evt4 ...]]" << endl;
1080 // cerr << " Compute the active diagnoser of the file 'file.sdmdl'. " << endl;
1081 // cerr << " The events listed after '--faults' are considered as fault events in the model 'file.sdmdl'." << endl;
1082 // cerr << " The events listed after '--ignored' are simply ignored INPUT events in the model 'file.sdmdl'." << endl;
1083 // cerr << " Any event that is in the model but not listed as a fault or as an ignored event is considered as a normal event." << endl;
1084 // }
1085 
1086 // /*******************************************************************************************/
1087 // // cost file parser
1088 
1089 // vector<C_Obs*> initObs(unordered_map<string,string> dictionnary)
1090 // {
1091 // vector<C_Obs*> obs;
1092 
1093 // for(unordered_map<string,string>::const_iterator it = dictionnary.begin();it != dictionnary.end();++it)
1094 // if (it->second[0] == 'o')
1095 // obs.push_back(new C_Obs(it->second,it->first));
1096 // return obs;
1097 // }
1098 
1099 // void costFilePaser(string fileName, unordered_map<string,string> & dictionnary,
1100 // vector<C_Obs*>& obs, vector<C_Test*>& test, vector<C_Fault*>& fault)
1101 // {
1102 // string label,type,name;
1103 // set<C_Obs*> tmp;
1104 // vector<C_Obs*> obj;
1105 // vector<C_Test*> repair;
1106 // int nb,nbs;
1107 // double cost;
1108 // bool repairable;
1109 
1110 // ifstream file(fileName.c_str());
1111 
1112 // if (!file)
1113 // {
1114 // cerr << "fichier inexistant" << endl;
1115 // return;
1116 // }
1117 
1118 // while (!file.eof())
1119 // {
1120 // file >> type >> nb;
1121 // for (int i=0; i<nb; ++i)
1122 // {
1123 // if (type == "ACTION")
1124 // {
1125 // file >> label >> cost;
1126 // test.push_back(new C_Test(dictionnary[label],label,cost));
1127 // }
1128 // else if (type == "OBJECTIF")
1129 // {
1130 // file >> label >> cost;
1131 // for(unsigned j = 0;j < obs.size();++j)
1132 // if (obs[j]->Get_Name().find(label) != string::npos)
1133 // obs[j]->Add_Reward(cost);
1134 // }
1135 // else if (type == "PANNE")
1136 // {
1137 // obj.clear();
1138 // repair.clear();
1139 // file >> label >> repairable >> nbs;
1140 // if (repairable == 0)
1141 // {
1142 // for (int k = 0; k < nbs; ++k)
1143 // {
1144 // file >> name;
1145 // for(unsigned j = 0;j < obs.size();++j)
1146 // if (obs[j]->Get_Name().find(name) != string::npos)
1147 // tmp.insert(obs[j]);
1148 // }
1149 // for(set<C_Obs*>::const_iterator it = tmp.begin();it != tmp.end();++it)
1150 // obj.push_back(*it);
1151 // // cout << "obj : " << obj.size() << endl;
1152 // fault.push_back(new C_Fault(dictionnary[label],label,repairable,obj));
1153 // }
1154 // else
1155 // {
1156 // for (int k = 0; k < nbs ; ++k)
1157 // {
1158 // file >> name;
1159 // for(unsigned j = 0;j < test.size();++j)
1160 // if (test[j]->Get_Name() == name)
1161 // repair.push_back(test[j]);
1162 // }
1163 // // cout << "repair : " << repair.size() << endl;
1164 // fault.push_back(new C_Fault(dictionnary[label],label,repairable,repair));
1165 // }
1166 // }
1167 // else cerr << "mauvais fichier" << endl;
1168 // }
1169 // if (type == "PANNE") break;
1170 // }
1171 // // cout << test.size() << " " << fault.size() << " " << obs.size() << endl;
1172 // }
1173 
1174 // /*******************************************************************************************/
1175 // // 1) générer un scénario (séquences d'événements) sur le globalModel
1176 
1177 // vector<string> scenario(const ObservableComponent * model, const set<string> & faults,State& finalState)
1178 // {
1179 // vector<string> seq;
1180 // Diades::Graph::OutEdgeIterator it;
1181 // bool fin = false;
1182 
1183 // srand(time(NULL));
1184 // State currentState = *(model->initialStateBegin());
1185 
1186 // while(1)
1187 // {
1188 // it=randTrans(currentState);
1189 // currentState = it->target();
1190 // seq.push_back( model->getEvent(*it).label() );
1191 // if (model->getEvent(*it).label()[4] == 's' && model->getEvent(*it).label()[5] == 'p')
1192 // fin = true;
1193 // else if (fin == true) break;
1194 // }
1195 // finalState = currentState;
1196 // return seq;
1197 // }
1198 
1199 // Diades::Graph::OutEdgeIterator randTrans(State currentState)
1200 // {
1201 // int nb = rand() % currentState.outDeg();
1202 // Diades::Graph::OutEdgeIterator it = currentState.outEdgeBegin();
1203 // for(;nb>0;--nb)
1204 // ++it;
1205 // return it;
1206 // }
1207 
1208 // /*******************************************************************************************/
1209 // // 2) faire tourner chaque diagnostiqueur sur la séquence d'observation associée au scénario
1210 
1211 // vector<State> activeDiagnoserBrowser(vector<string> seq, const set<string> & faults,
1212 // unordered_map<string,SpecialisedActiveDiagnoser *> & activeDiagnoser)
1213 // {
1214 // unsigned int count=0;
1215 // State current;
1216 // vector<State> currentState(faults.size());
1217 
1218 // for(set<string>::const_iterator faultIt = faults.begin();faultIt != faults.end();++faultIt)
1219 // {
1220 // current = activeDiagnoser[*faultIt]->initialState();
1221 // for(unsigned i=0; i<seq.size();++i)
1222 // {
1223 // for(EdgeIterator it = activeDiagnoser[*faultIt]->transitionBegin();it != activeDiagnoser[*faultIt]->transitionEnd();++it)
1224 // if (current == it->source() && seq[i] == activeDiagnoser[*faultIt]->getEvent(*it).label())
1225 // {
1226 // current = it->target();
1227 // break;
1228 // }
1229 // }
1230 // currentState.at(count++)=current;
1231 // }
1232 // return currentState;
1233 // }
int initialiseModelFromSdmdl(const string &filename, ObservableComponent &globalModel, VariableFactory &factory, const set< string > &shortNameIgnored, const set< string > &shortNameFaults, unordered_map< string, string > &dictionary, set< string > &faults, set< string > &nominals)
Graph::Graph & behaviour()
Definition: Component.hh:215
Tag
Definition: TagStates.cc:160
OutputEventTransitionIterator outputEventTransitionBegin(State s, Event e) const
Definition: Component.hh:832
InputIterator getFileExtension(const std::basic_string< CharType, CharTraits > &fileName, InputIterator begin, InputIterator end)
Definition: StringTools.hh:57
int initialiseDiagnosers(const ObservableComponent &model, const set< string > &faults, unordered_map< string, string > &dictionnary, unordered_map< string, SpecialisedActiveDiagnoser *> &activeDiagnoser)
StateIterator stateBegin() const
Definition: Component.hh:572
int main(int ac, char **av)
vector< string > options(numberOfOptions)
StateIterator stateEnd() const
Definition: Component.hh:579
OutputEventTransitionIterator outputEventTransitionEnd(State s, Event e) const
Definition: Component.hh:850
StIndexes states
Definition: Run.cc:266
int export2Hydiag(const SpecialisedActiveDiagnoser &diagnoser, const string &filename)
Definition: Run.cc:85
An observable Component defined as a automaton.
int initialiseModelFromDesComp(const string &filename, ObservableComponent &globalModel, const set< string > &shortNameFaults, unordered_map< string, string > &dictionary, set< string > &faults, set< string > &nominals)
const string & name() const
Definition: Component.hh:256
String utilities for Diades.
unsigned numberOfStates() const
Definition: Component.hh:563
string tag(SpecialisedActiveDiagnoser::Tag tag)
Diades::Utils::Verbose verbose(const char *msg)
Definition: Verbose.hh:126
FileSuffixes suffixes({"aut","ddaut"})
Log log(Logger logger, const string &msg)
Definition: Log.hh:124
Diades::Graph::Node State
Definition: BeliefState.hh:36
virtual bool import(const string &filename)
const set< Event > & events() const
Definition: Component.hh:318
void printUsage(const po::options_description &desc)