DiaDes  0.1
DIAgnosis of Discrete-Event System
ComponentInfo.cc
Go to the documentation of this file.
1 
28 #include<vector>
29 #include<string>
31 
33 #include"CmdInterface.hh"
34 
35 
36 using std::string;
37 using std::vector;
38 using namespace Diades::Utils;
39 using namespace Diades::Automata;
40 using namespace Diades::CmdInterface;
41 
42 typedef enum { HELP = 0, EVENTS = 1, EVENTNB = 2,
43  STATES = 3, STATENB = 4, TRANSITIONS = 5,
47 
48 typedef enum { DESCOMP = 0 } Extension;
49 
50 unsigned numberOfOptions = 15;
52 
53 
55 vector<string> options(numberOfOptions);
56 vector<bool> isSet(numberOfOptions,false);
57 
58 string description= "Usage:\t component_info --help |\n\t\t\t file.des_comp \t (--events | --events_number\n\t\t\t\t\t | --states | --states_number\n\t\t\t\t\t | --transitions | --transitions_number\n\t\t\t\t\t | --observables | --observables_number \n\t\t\t\t\t | --unobservables | --unobservables_number\n\t\t\t\t\t | --initial_states | --initial_states_number)\n\t\t\t\t\t | --name | --statistics) \n\n\n Print on the standard output the information associated to the given option.";
59 
60 string printStatistics(const ObservableComponent & component);
61 
63 {
64  options[HELP] = "--help";
65  options[EVENTS] = "--events";
66  options[EVENTNB] = "--events_number";
67  options[STATES] = "--states";
68  options[STATENB] = "--states_number";
69  options[TRANSITIONS] = "--transitions";
70  options[TRANSITIONNB] = "--transitions_number";
71  options[OBSERVABLES] = "--observables";
72  options[OBSERVABLENB] = "--observables_number";
73  options[UNOBSERVABLES] = "--unobservables";
74  options[UNOBSERVABLENB] = "--unobservables_number";
75  options[INITIALSTATES] = "--initial_states";
76  options[INITIALSTATENB] = "--initial_states_number";
77  options[NAME] = "--name";
78  options[STATISTICS] = "--statistics";
79  fileExtensions[DESCOMP] = "des_comp";
80 }
92 int main(int argc, char ** argv)
93 {
96  bool stop = false;
97 
98  if(argc==1)
99  {
101  stop = true;
102  }
103  if(!stop)
104  {
105  Option currentOption;
106  int index = 1;
107  if(argc==2)
108  {
109  if(getOption<Option>(argv[index],options,currentOption))
110  {
111  if(currentOption != HELP)
112  {
113  printCommandLineError("Incorrect command line. Try --help.");
114  stop =true;
115  }
116  else
117  {
119  stop = true;
120  }
121  }
122  else
123  {
124  printCommandLineError("Incorrect command line. Try --help.");
125  stop = true;
126  }
127  }
128 
129  if(!stop)
130  {
131  if(argc != 3)
132  {
133  printCommandLineError("Incorrect number of paramteres in command line. Try --help.");
134  stop = true;
135  }
136 
137 
138  string modelFile;
139 
140  if(!stop)
141  {
142  if(!getOption<Option>(argv[index],options,currentOption))
143  {
144  // this should be the model file then
145  getParameter<string>(argc,argv,index,modelFile);
146  if(!fileSuffixOk(modelFile,fileExtensions[DESCOMP]))
147  {
148  printCommandLineError("The model file'" + modelFile + "' is not a diades component model file.");
149  stop = true;
150  }
151  }
152  else
153  {
154  ++index;
155  }
156  if(!stop)
157  {
158  if(!modelFile.empty())
159  {
160  // this should be an option here
161  if(!getOption<Option>(argv[index],options,currentOption))
162  {
163  printCommandLineError("Unrecognized option: " + string(argv[index]));
164  stop = true;
165  }
166  }
167  else
168  {
169  // this should be the model file then
170  getParameter<string>(argc,argv,index,modelFile);
171  if(!fileSuffixOk(modelFile,fileExtensions[DESCOMP]))
172  {
173  printCommandLineError("The model file '" + modelFile + "' is not a diades component model file.");
174  stop = true;
175  }
176  }
177  if(!stop)
178  {
179 
180  ObservableComponent component;
181  try
182  {
183  component.importDesCompModel(modelFile);
184  }
185  catch(exception & e)
186  {
187  printCommandLineError("component_info caught an exception when attempting to load the file " + modelFile + ":\n\t" + e.what());
188  stop = true;
189  }
190  if(!stop)
191  {
192 
193  switch(currentOption)
194  {
195  case HELP:
196  {
197  printCommandLineError("Incorrect use of option --help.");
198  stop = true;
199  break;
200  }
201  case EVENTS:
202  {
203  for(Component::EventIterator eventIt = component.eventBegin();
204  eventIt != component.eventEnd();
205  ++eventIt)
206  {
207  verbose<VbOutput>("%1% ") % *eventIt;
208  }
209  break;
210  }
211  case EVENTNB:
212  {
213  verbose<VbOutput>("%1% ") % component.numberOfEvents();
214  break;
215  }
216  case STATES:
217  {
218  for(Component::StateIterator stateIt = component.stateBegin();
219  stateIt != component.stateEnd();
220  ++stateIt)
221  {
222  verbose<VbOutput>("%1% ") % component.getLabel(*stateIt);
223  }
224  break;
225  }
226  case STATENB:
227  {
228  verbose<VbOutput>("%1% ") % component.numberOfStates();
229  break;
230  }
231  case TRANSITIONS:
232  {
233  for(Component::TransitionIterator transIt = component.transitionBegin();
234  transIt != component.transitionEnd();
235  ++transIt)
236  {
237  verbose<VbOutput>("%1% -> %2% %3% ")
238  % component.getLabel(transIt->source())
239  % component.getLabel(transIt->target())
240  % component.getEvent(*transIt);
241  }
242  break;
243  }
244  case TRANSITIONNB:
245  {
246  verbose<VbOutput>("%1% ") % component.numberOfTransitions();
247  break;
248  }
249  case OBSERVABLES:
250  {
251  for(Component::EventIterator eventIt = component.observableBegin();
252  eventIt != component.observableEnd();
253  ++eventIt)
254  {
255  verbose<VbOutput>("%1% ") % *eventIt;
256  }
257  break;
258  }
259  case OBSERVABLENB:
260  {
261  verbose<VbOutput>("%1% ") % component.mask().numberOfObservableEvents();
262  break;
263  }
264  case UNOBSERVABLES:
265  {
266  for(Component::EventIterator eventIt = component.eventBegin();
267  eventIt != component.eventEnd();
268  ++eventIt)
269  {
270  if(component.mask().isUnobservable(*eventIt))
271  {
272  verbose<VbOutput>("%1% ") % *eventIt;
273  }
274  }
275  break;
276  }
277  case UNOBSERVABLENB:
278  {
279  unsigned counter = 0;
280  for(Component::EventIterator eventIt = component.eventBegin();
281  eventIt != component.eventEnd();
282  ++eventIt)
283  {
284  if(component.mask().isUnobservable(*eventIt))
285  {
286  ++counter;
287  }
288  }
289  verbose<VbOutput>("%1% ") % counter;
290  break;
291  }
292  case INITIALSTATES:
293  {
294 
295  for(Component::InitialStateIterator stateIt = component.initialStateBegin();
296  stateIt != component.initialStateEnd();
297  ++stateIt)
298  {
299  verbose<VbOutput>("%1% ") % component.getLabel(*stateIt);
300  }
301  break;
302  }
303  case INITIALSTATENB:
304  {
305  verbose<VbOutput>("%1% ") % component.numberOfInitialStates();
306  break;
307  }
308  case NAME:
309  {
310  verbose<VbOutput>("%1% ") % component.name();
311  break;
312  }
313  case STATISTICS:
314  {
315  verbose<VbOutput>("%1% ") % printStatistics(component);
316  break;
317  }
318 
319  default:
320  {
321  printCommandLineError("Unrecognized option: " + string(argv[index]));
322  break;
323  }
324  }
325  }
328  }
329  }
330  }
331  }
332  }
333  return 0;
334 }
335 
336 
337 string printStatistics(const ObservableComponent & component)
338 {
339  vector<string> labels;
340  unordered_map< Event,vector<unsigned> > indegEvt;
341  unordered_map< Event,vector<unsigned> > outdegEvt;
342  vector<unsigned> outdeg(1);
343  vector<unsigned> indeg(1);
344  unsigned max = 1;
345  stringstream stream;
346  stream << "# component name: " << component.name() << endl;
347  stream << "# number of states: " << component.numberOfStates() << endl;
348  stream << "# number of transitions: " << component.numberOfTransitions() << endl;
349  stream << "# ratio transitions/states: "
350  << ((double) component.numberOfTransitions()) / ((double) component.numberOfStates()) << endl;
351  unsigned obsTransNb = 0;
352  unsigned wcOutputBacktrackNumber=0;
353  unsigned wcInputBacktrackNumber=0;
354  unordered_map<Event,unsigned> wcOutputBacktrackNumberPerObs;
355  unordered_map<Event,unsigned> wcInputBacktrackNumberPerObs;
357  obsIt != component.mask().observableEnd();
358  ++obsIt)
359  {
360  wcInputBacktrackNumberPerObs[*obsIt]=0;
361  wcOutputBacktrackNumberPerObs[*obsIt]=0;
362  }
363  for(ObservableComponent::StateIterator it = component.stateBegin();
364  it != component.stateEnd();
365  ++it)
366  {
367  unordered_map<Event,unsigned> nbOutTransWithObs;
368  unordered_map<Event,unsigned> nbInTransWithObs;
370  obsIt = component.mask().observableBegin();
371  obsIt != component.mask().observableEnd();
372  ++obsIt)
373  {
374  nbOutTransWithObs[*obsIt]=0;
375  nbInTransWithObs[*obsIt]=0;
376  }
377  unsigned unobsTransNb = 0;
378  for(ObservableComponent::OutputTransitionIterator
379  outIt = component.outputTransitionBegin(*it);
380  outIt != component.outputTransitionEnd(*it);
381  ++outIt)
382  {
383  if(component.mask().isObservable(component.getEvent(*outIt)))
384  {
385  ++obsTransNb;
386  ++nbOutTransWithObs[component.getEvent(*outIt)];
387  }
388  else
389  {
390  ++unobsTransNb;
391  }
392  }
393 
395  obsIt != component.mask().observableEnd();
396  ++obsIt)
397  {
398  if(unobsTransNb + nbOutTransWithObs[*obsIt]!=0)
399  {
400  wcOutputBacktrackNumberPerObs[*obsIt] += unobsTransNb + nbOutTransWithObs[*obsIt] -1;
401  if(outdegEvt[*obsIt].size() <= (unobsTransNb + nbOutTransWithObs[*obsIt] -1))
402  {
403  outdegEvt[*obsIt].resize(unobsTransNb + nbOutTransWithObs[*obsIt]);
404  outdegEvt[*obsIt][unobsTransNb + nbOutTransWithObs[*obsIt] -1]= 0;
405  if(max < outdegEvt[*obsIt].size())
406  {
407  max = outdegEvt[*obsIt].size();
408  }
409  }
410  ++outdegEvt[*obsIt][unobsTransNb + nbOutTransWithObs[*obsIt] -1];
411  }
412  }
413 
414 
415  unobsTransNb = 0;
416 
417  for(ObservableComponent::InputTransitionIterator
418  inIt = component.inputTransitionBegin(*it);
419  inIt != component.inputTransitionEnd(*it);
420  ++inIt)
421  {
422  if(component.mask().isObservable(component.getEvent(*inIt)))
423  {
424  ++nbInTransWithObs[component.getEvent(*inIt)];
425  }
426  else
427  {
428  ++unobsTransNb;
429  }
430  }
431 
433  obsIt = component.mask().observableBegin();
434  obsIt != component.mask().observableEnd();
435  ++obsIt)
436  {
437  if(unobsTransNb + nbInTransWithObs[*obsIt]!=0)
438  {
439  wcInputBacktrackNumberPerObs[*obsIt] += unobsTransNb + nbInTransWithObs[*obsIt] -1;
440  if(indegEvt[*obsIt].size() <= (unobsTransNb + nbInTransWithObs[*obsIt] -1))
441  {
442  indegEvt[*obsIt].resize(unobsTransNb + nbInTransWithObs[*obsIt]);
443  indegEvt[*obsIt][unobsTransNb + nbInTransWithObs[*obsIt] -1]= 0;
444  if(max < indegEvt[*obsIt].size())
445  {
446  max = indegEvt[*obsIt].size();
447  }
448  }
449  ++indegEvt[*obsIt][unobsTransNb + nbInTransWithObs[*obsIt] -1];
450  }
451  }
452 
453  if(it->outDeg() >= outdeg.size())
454  {
455  outdeg.resize(it->outDeg()+1);
456  if(max < outdeg.size())
457  {
458  max = outdeg.size();
459  }
460  }
461  outdeg[it->outDeg()]++;
462  if(it->outDeg() > 1)
463  {
464  wcOutputBacktrackNumber = wcOutputBacktrackNumber + (it->outDeg()-1);
465  }
466  if(it->inDeg() >= indeg.size())
467  {
468  indeg.resize(it->inDeg()+1);
469  if(max < indeg.size())
470  {
471  max = indeg.size();
472  }
473  }
474  indeg[it->inDeg()]++;
475  if(it->inDeg() > 1)
476  {
477  wcInputBacktrackNumber = wcInputBacktrackNumber + (it->inDeg()-1);
478  }
479  }
480 
481  stream << "# ratio obs.trans./transitions: " << ((double) obsTransNb)/((double)component.numberOfTransitions()) << endl;
482  stream << "# worst-case output backtrack number: " << wcOutputBacktrackNumber << endl;
483  stream << "# worst-case input backtrack number: " << wcInputBacktrackNumber << endl;
484 
485  stream << "# worst-case output backtrack number per observable: ";
487  obsIt = component.mask().observableBegin();
488  obsIt != component.mask().observableEnd();
489  ++obsIt)
490  {
491  stream << *obsIt << ": " << wcOutputBacktrackNumberPerObs[*obsIt] << " ";
492  }
493  stream << endl;
494  stream << "# worst-case input backtrack number per observable: ";
496  obsIt = component.mask().observableBegin();
497  obsIt != component.mask().observableEnd();
498  ++obsIt)
499  {
500  stream << *obsIt << ": " << wcInputBacktrackNumberPerObs[*obsIt] << " ";
501  }
502  stream << endl;
503 
504 
505 
506  indeg.resize(max);
507  outdeg.resize(max);
508 
509  labels.push_back("num");
510  labels.push_back("outdeg");
511  labels.push_back("indeg");
513  obsIt = component.mask().observableBegin();
514  obsIt != component.mask().observableEnd();
515  ++obsIt)
516  {
517  indegEvt[*obsIt].resize(max);
518  outdegEvt[*obsIt].resize(max);
519  stringstream stream;
520  stream << "opbp-" << *obsIt;
521  labels.push_back(stream.str());
522  stringstream stream2;
523  stream2 << "ipbp-" << *obsIt;
524  labels.push_back(stream2.str());
525  }
526 
527  for(unsigned i = 0; i < labels.size(); ++i)
528  {
529  stream << labels[i];
530  if( (i== 0) || (i-1 < labels.size()))
531  {
532  stream << '\t';
533  }
534  }
535  stream << endl;
536  for(unsigned i = 0; i < max; ++i)
537  {
538  stream << i << '\t' << outdeg[i] << '\t' << indeg[i];
540  obsIt = component.mask().observableBegin();
541  obsIt != component.mask().observableEnd();
542  ++obsIt)
543  {
544  stream << '\t' << outdegEvt[*obsIt][i] << '\t' << indegEvt[*obsIt][i];
545  }
546  stream << endl;
547  }
548  return stream.str();
549 }
550 
vector< string > fileExtensions(numberOfFileExtensions)
unsigned numberOfEvents() const
Definition: Component.hh:284
void initialiseOptions()
Some utilities to deal with the command line.
Option
Extension
size_t printCommandLineError(const string &msg)
Definition: CmdInterface.cc:98
string printStatistics(const ObservableComponent &component)
StateIterator stateBegin() const
Definition: Component.hh:572
void setVerboseLevel(Diades::Utils::VerboseLevel level)
Definition: Verbose.hh:135
const StateLabel & getLabel(State state) const
Definition: Component.hh:521
StateIterator stateEnd() const
Definition: Component.hh:579
static void destroyEvents()
InputTransitionIterator inputTransitionBegin(State s) const
Definition: Component.hh:936
TransitionIterator transitionEnd() const
Definition: Component.hh:904
unordered_set< State >::const_iterator InitialStateIterator
Definition: Component.hh:70
set< Event >::const_iterator ObservableEventIterator
InitialStateIterator initialStateEnd() const
Definition: Component.hh:648
An observable Component defined as a automaton.
Diades::Graph::NodeIterator StateIterator
Definition: Component.hh:67
unsigned numberOfInitialStates() const
Definition: Component.hh:659
virtual bool importDesCompModel(const string &filename)
const string & name() const
Definition: Component.hh:256
unsigned numberOfTransitions() const
Definition: Component.hh:958
InputTransitionIterator inputTransitionEnd(State s) const
Definition: Component.hh:948
InitialStateIterator initialStateBegin() const
Definition: Component.hh:638
unsigned numberOfStates() const
Definition: Component.hh:563
Option
Definition: abstract.cc:32
unsigned numberOfOptions
bool fileSuffixOk(const string &modelFile, const string &suffix)
ObservableEventIterator observableBegin() const
EventIterator eventBegin() const
Definition: Component.hh:328
OutputTransitionIterator outputTransitionBegin(State s) const
Definition: Component.hh:913
const ObservableMask & mask() const
ObservableEventIterator observableEnd() const
bool isObservable(const Event &e) const
vector< bool > isSet(numberOfOptions, false)
TransitionIterator transitionBegin() const
Definition: Component.hh:897
const Event & getEvent(Transition t) const
Definition: Component.hh:304
Diades::Graph::EdgeIterator TransitionIterator
Definition: Component.hh:68
string description
int main(int argc, char **argv)
EventIterator eventEnd() const
Definition: Component.hh:338
set< Event >::const_iterator EventIterator
Definition: Component.hh:73
vector< string > options(numberOfOptions)
bool isUnobservable(const Event &e) const
unsigned numberOfObservableEvents() const
unsigned numberOfFileExtensions
OutputTransitionIterator outputTransitionEnd(State s) const
Definition: Component.hh:925
void printUsage(const po::options_description &desc)