DiaDes  0.1
DIAgnosis of Discrete-Event System
run.cc
Go to the documentation of this file.
1 #include<fstream>
2 #include<string>
3 #include<vector>
4 #include<list>
5 #include<map>
6 #include<boost/date_time/posix_time/posix_time.hpp>
7 #include<boost/archive/text_oarchive.hpp>
8 #include<utils/Random.hh>
9 #include<utils/CmdInterface.hh>
13 #include<automata/FBFS.hh>
14 #include<automata/FDFS.hh>
15 #include<automata/FGFS.hh>
16 #include<io/xml/automata/Simulation.hh>
17 #include<automata/Diagnose.hh>
19 
20 
33 typedef enum { FAULTS = 0, ALGORITHMS = 1 } Option;
34 typedef enum { DESCOMP=0, RULES=1, XML=2} FileExtension;
35 unsigned numberOfOptions = 2;
37 
39 vector<string> options(numberOfOptions);
40 vector<bool> isSet(numberOfOptions,false);
41 
42 string description="Usage:\t dd-run --algorithms ALG1 [ALG2...] --faults evt1 [evt2 ...] file1.des_comp [file2.des_comp file3.des_comp... sync.rules] scenario.xml\n\t Diagnose the sequence of observations given in the scenarios with the set of available algorithms. Write the diagnostic history in\n\t a file 'histALG.archv' for each algorithm ALG and the perfect diagnosis in 'perfect_history.archv'.\n\t The implemented algorithms are: FBFS, FDFS, FGFS, AFBFS.";
43 
45 {
46  options[FAULTS] = "--faults";
47  options[ALGORITHMS] = "--algorithms";
48  fileExtensions[DESCOMP] = "des_comp";
49  fileExtensions[RULES] = "rules";
50  fileExtensions[XML] = "xml";
51 }
52 
53 void readScenario(const string & filename,
54  vector< EventOccurrence > & simulation,
55  vector< EventOccurrence > & observations);
56 
57 void readParameters(int argc, char * argv[],
58  list<string> & modelFiles,
59  set<string> & algos,
60  unordered_set<Event> & faults,
61  string & ruleFiles,
62  string & scenarioFile);
63 
64 
65 /***************************************************************************************/
66 
67 int main(int argc, char ** argv)
68 {
70  list<string> modelFiles;
71  set<string> algos;
72  unordered_set<Event> faults;
73  string ruleFile;
74  string scenarioFile;
76  readParameters(argc,argv,modelFiles,algos,faults,ruleFile,scenarioFile);
77 
78  // model loading
79  vector<ObservableComponent *> components;
80  vector<ObservableComponent::CRef> comps;
81  ParametrizedSynchronisation::ComponentVector vectorComp;
82  for(const string & filename : modelFiles)
83  {
84  components.push_back(new ObservableComponent());
85  components.back()->importDesCompModel(filename);
86  vectorComp.push_back(components.back());
87  comps.push_back(cref(*components.back()));
88  }
89 
90  // synchronisation rules loading
92  if(!ruleFile.empty())
93  {
94  loadSynchronisationRules(vectorComp,ruleFile,rules);
95  }
96  set<Event> synchronisedEvents;
97  for(SynchronisationRules::SynchronisationIterator sit = rules.beginOfSynchronisedEvents();
98  sit != rules.endOfSynchronisedEvents();
99  ++sit)
100  {
101  for(Diades::Automata::SynchronisationEvent::ComponentIterator cit = sit->beginOfSupport();
102  cit != sit->endOfSupport();
103  ++cit)
104  {
105  synchronisedEvents.insert(sit->getAssociatedEvent(cit));
106  }
107  }
108 
109  // scenario loading
110  vector< EventOccurrence > observations;
111  vector< EventOccurrence > simulation;
112  readScenario(scenarioFile,simulation,observations);
113 
114  std::cout << "Scenario:" << std::endl;
115  for(const EventOccurrence & evo: observations)
116  {
117  std::cout << "(" << evo.first << "," << evo.second << ") ";
118  }
119  std::cout << std::endl;
120 
121 
122 
123 
124  list<Diagnosis> results;
125  string histFile = "hist.archv";
126  for(const string & algo: algos)
127  {
128  if(algo == "FBFS")
129  {
130  FaultDiagProblem problem(comps, faults, rules, observations);
131  cout << "FBFS starting.." << endl;
132  Diagnose<FBFS> d1(problem);
133  std::ofstream ofs1( "FBFS" + histFile);
134  boost::archive::text_oarchive oa1(ofs1);
135  oa1 << d1.history();
136  results.push_back(d1.history().getDiagnosis(d1.history().lastTimePoint()));
137  }
138  if(algo == "FDFS")
139  {
140  FaultDiagProblem problem(comps, faults, rules, observations);
141  cout << "FDFS starting.." << endl;
142  Diagnose<FDFS> d2(problem);
143  std::ofstream ofs2( "FDFS" + histFile);
144  boost::archive::text_oarchive oa2(ofs2);
145  oa2 << d2.history();
146  results.push_back(d2.history().getDiagnosis(d2.history().lastTimePoint()));
147  }
148  if(algo == "FGFS")
149  {
150  FaultDiagProblem problem(comps, faults, rules, observations);
151  cout << "FGFS starting.." << endl;
152  Diagnose<FGFS> d3(problem);
153  std::ofstream ofs3( "FGFS" + histFile);
154  boost::archive::text_oarchive oa3(ofs3);
155  oa3 << d3.history();
156  results.push_back(d3.history().getDiagnosis(d3.history().lastTimePoint()));
157  }
158  if(algo == "AFBFS")
159  {
160  cout << "pre-ABFS starting" << endl;
161  // model abstracting
162  typedef unordered_map<Diades::Automata::State,unordered_set<Diades::Automata::State> > Dict;
163  vector<Dict> dictionary;
164  vector<ObservableComponent *> absComponents;
165  vector<ObservableComponent::CRef> abscomps;
166  ParametrizedSynchronisation::ComponentVector vectorAbsComp;
167  for(const ObservableComponent & comp : comps)
168  {
169  absComponents.push_back(new ObservableComponent());
170  set<Event> projectedEvents;
171  for(ObservableComponent::EventIterator evtIt = comp.eventBegin();
172  evtIt != comp.eventEnd();
173  ++evtIt)
174  {
175  if(synchronisedEvents.find(*evtIt) != synchronisedEvents.end())
176  {
177  projectedEvents.insert(*evtIt);
178  }
179  if(comp.mask().isObservable(*evtIt))
180  {
181  projectedEvents.insert(*evtIt);
182  }
183  if(faults.find(*evtIt) != faults.end())
184  {
185  projectedEvents.insert(*evtIt);
186  }
187  }
188  dictionary.push_back(Dict());
189  absComponents.back()->project(&comp,projectedEvents,dictionary.back());
190  absComponents.back()->setName(comp.name());
191  abscomps.push_back(cref(*absComponents.back()));
192  vectorAbsComp.push_back(absComponents.back());
193  }
194  // synchronisation rules loading
196  if(!ruleFile.empty())
197  {
198  loadSynchronisationRules(vectorAbsComp,ruleFile,absrules);
199  }
200  FaultDiagProblem problem( abscomps, faults, absrules, observations);
201  cout << "AFBFS starting.." << endl;
202  Diagnose<FBFS> d4(problem);
203  cout << "Done" << endl;
204  std::ofstream ofs4( "AFBFS" + histFile);
205  boost::archive::text_oarchive oa4(ofs4);
206  typedef unordered_map<Diades::Automata::Candidate::StateId,unordered_set<Diades::Automata::Candidate::StateId> > DictId;
207  vector<DictId> dictionaryId(dictionary.size());
208  for(unsigned i = 0; i < dictionary.size(); ++i)
209  {
210  for(Dict::const_iterator it1 = dictionary[i].begin();
211  it1 != dictionary[i].end();
212  ++it1)
213  {
214  for(unordered_set<Diades::Automata::State>::const_iterator it2 = it1->second.begin();
215  it2 != it1->second.end();
216  ++it2)
217  {
218  dictionaryId[i][it1->first.id()].insert(it2->id());
219  }
220  }
221  }
222  Diades::Automata::History nonAbsHist(d4.history(),dictionaryId);cout << "here8" << endl;
223  oa4 << nonAbsHist;
224  results.push_back(nonAbsHist.getDiagnosis(d4.history().lastTimePoint()));
225  }
226  }
227  cout << "Result: ";
228  list<Diagnosis>::const_iterator rit = results.begin();
229  for(set<string>::const_iterator it = algos.begin();
230  it != algos.end();
231  ++it)
232  {
233  set<string>::const_iterator it2 = it;
234  list<Diagnosis>::const_iterator rit2 = rit;
235  ++it2;
236  ++rit2;
237  for(; it2 != algos.end(); ++it2)
238  {
239  cout << *it << "/" << *it2 << " ? " << (*rit == *rit2 ) << endl;
240  ++rit2;
241  }
242  }
243 }
244 
245 
246 
247 
248 /***************************************************************************************/
249 
250 void readParameters(int argc, char * argv[],
251  list<string> & modelFiles,
252  set<string> & algos,
253  unordered_set<Event> & faults,
254  string & ruleFile, string & scenarioFile)
255 {
256  list<string>::size_type nbModel = 0;
257  if(argc < 3)
258  {
260  }
261  int index = 1;
262  while( index < argc )
263  {
264  Option currentOption;
265  if(getOption<Option>(argv[index],options,currentOption))
266  {
267  if(isSet[currentOption])
268  {
269  printError("The option '" + options[currentOption] + "' occurs at least twice.");
270  }
271  else
272  {
273  isSet[currentOption] = true;
274  }
275  switch(currentOption)
276  {
277  case FAULTS:
278  {
279  ++index;
280  set<string> faultstring;
281  getParameterList<string>(argc,argv,options,fileExtensions,
282  index,faultstring);
283  if(faultstring.empty())
284  {
285  printError("No parameter after the option " + options[currentOption]);
286  }
287  else
288  {
289  for(const string & s : faultstring)
290  {
291  faults.insert(EventFactory::factory()->getEvent(s));
292  }
293  }
294  break;
295  }
296  case ALGORITHMS:
297  {
298  ++index;
299 
300  getParameterList<string>(argc,argv,options,fileExtensions,
301  index,algos);
302  if(algos.empty())
303  {
304  printError("No parameter after the option " + options[currentOption]);
305  }
306  break;
307  }
308  }
309  }
310  else
311  {
312  vector<string>::const_iterator it =
313  getFileExtension(string(argv[index]),fileExtensions.begin(),fileExtensions.end());
314  if(it == fileExtensions.end())
315  {
316  printError("Unrecognized file extension in file name: " + string(argv[index]));
317  }
318  FileExtension extension = DESCOMP;
319  if(*it==fileExtensions[RULES]) { extension = RULES; }
320  if(*it==fileExtensions[XML]) { extension = XML; }
321  switch(extension)
322  {
323  case DESCOMP:
324  {
325  if(find(modelFiles.begin(),modelFiles.end(),string(argv[index])) == modelFiles.end())
326  {
327  ++nbModel;
328  modelFiles.push_back(string(argv[index]));
329  }
330  break;
331  }
332  case RULES:
333  {
334  if(!ruleFile.empty())
335  {
336  printError("The dreamap command does not accept two synchronisation files at the same time.");
337  }
338  ruleFile = string(argv[index]);
339  break;
340  }
341  case XML:
342  {
343  if(!scenarioFile.empty())
344  {
345  printError("The dreamap command does not accept two scenarios at the same time.");
346  }
347  scenarioFile = string(argv[index]);
348  break;
349  }
350  }
351  ++index;
352  }
353  }
354  if(faults.empty())
355  {
356  printError("No fault found.");
357  }
358  if(scenarioFile.empty())
359  {
360  printError("No scenario file found.");
361  }
362  if((nbModel > 1) && (ruleFile.empty()))
363  {
364  printError("No rule file found.");
365  }
366  if((nbModel == 1) && (!ruleFile.empty()))
367  {
368  printError("Only one component found so no rule file is needed.");
369  }
370  if(modelFiles.empty())
371  {
372  printError("No model found");
373  }
374 }
375 
376 /***********************************************************************************/
377 
378 
379 void readScenario(const string & filename,
380  vector< EventOccurrence > & simulation,
381  vector< EventOccurrence > & observations)
382 {
383  list<EventOccurrence> tmp1;
384  list<EventOccurrence> tmp2;
385 
386  back_insert_iterator< list< EventOccurrence > > simIt(tmp1);
387  back_insert_iterator< list< EventOccurrence > > obsIt(tmp2);
388  try
389  {
390  Diades::Io::Xml::loadXmlSimulation(filename, simIt,obsIt);
391  }
392  catch(exception & e)
393  {
394  printError("The function readScenario has caught an exception when loading the file " + filename + ": \n" + e.what());
395  }
396 
397  for(const EventOccurrence & evo : tmp1)
398  {
399  simulation.push_back(evo);
400  }
401 
402  for(const EventOccurrence & evo : tmp2)
403  {
404  observations.push_back(evo);
405  }
406 
407 
408 }
409 
410 /***********************************************************************************/
vector< string > fileExtensions(numberOfFileExtensions)
InputIterator getFileExtension(const std::basic_string< CharType, CharTraits > &fileName, InputIterator begin, InputIterator end)
Definition: StringTools.hh:57
pair< time_duration, Event > EventOccurrence
Definition: Diagnose.hh:13
unsigned initialiseSeed()
FileExtension
Definition: run.cc:34
ComposableModelSearch< Diades::Utils::GFS< NextTransitions, TargetDiagState, list< DiagState >, list< DiagState >, VisitedDiagState, IsCandidate, IncorrectPath > > FGFS
Definition: FGFS.hh:322
const History & history() const
Definition: Diagnose.hh:35
FileExtension
Definition: abstract.cc:33
bool loadSynchronisationRules(const ParametrizedSynchronisation::ComponentVector &models, const string &filename, ParametrizedSynchronisation &sync)
pair< time_duration, Event > EventOccurrence
Definition: Diagnose.cc:82
void initialiseOptions()
Definition: run.cc:44
SynchronisationIterator beginOfSynchronisedEvents() const
Definition of a fault diagnosis problem in a discrete-event system.
Definition: run.cc:34
unsigned numberOfOptions
Definition: run.cc:35
An observable Component defined as a automaton.
Definition: run.cc:33
Option
Definition: run.cc:33
DdAutFsm::EventPropertyId Event
Definition: TrimState.cc:139
unsigned numberOfFileExtensions
Definition: run.cc:36
Random generation utilities.
Definition of a fault diagnosis problem in a discrete-event system.
Option
Definition: abstract.cc:32
SynchronisationIterator endOfSynchronisedEvents() const
void readScenario(const string &filename, vector< EventOccurrence > &simulation, vector< EventOccurrence > &observations)
Definition: run.cc:379
int main(int argc, char **argv)
Definition: run.cc:67
ComposableModelSearch< Diades::Utils::DFS< NextTransitions, TargetDiagState, list< DiagState >, list< DiagState >, VisitedDiagState, IsCandidate, IncorrectPath > > FDFS
Definition: FDFS.hh:15
void initialiseRandomGenerator(unsigned int seed)
void printError(string parameter, string message)
vector< string > options(numberOfOptions)
Definition: run.cc:34
ComposableModelSearch< Diades::Utils::BFS< NextTransitions, TargetDiagState, list< DiagState >, list< DiagState >, VisitedDiagState, IsCandidate, IncorrectPath > > FBFS
Definition: FBFS.hh:16
void readParameters(int argc, char *argv[], list< string > &modelFiles, set< string > &algos, unordered_set< Event > &faults, string &ruleFiles, string &scenarioFile)
Definition: run.cc:250
string description
Definition: run.cc:42
Definition: run.cc:34
vector< bool > isSet(numberOfOptions, false)
void printUsage(const po::options_description &desc)