DiaDes  0.1
DIAgnosis of Discrete-Event System
CheckAccuracy.cc
Go to the documentation of this file.
1 #include<set>
2 #include<sstream>
3 #include<utils/Log.hh>
4 #include<utils/Verbose.hh>
5 #include<utils/StringTools.hh>
6 #include<utils/Exceptions.hh>
7 #include<automata/Topology.hh>
11 #include<automata/Accuracy.hh>
12 
13 using namespace std;
14 using namespace Diades::Utils;
15 
16 enum Parameter {
20 };
21 
22 
23 void generateLatexPreamble( ofstream & latexfile)
24 {
25  latexfile << "\\documentclass[11pt]{article}" << endl;
26  latexfile << "\\usepackage{array}" << endl;
27  latexfile << "\\textwidth 17cm \\textheight 26cm \\voffset -3cm \\hoffset -1.6cm" << endl;
28  latexfile << "\\title{Report on the accuracy analysis}" << endl;
29  time_t rawtime;
30  time ( &rawtime );
31  latexfile << "\\date{" << ctime( &rawtime ) << "}" << endl;
32  latexfile << "\\author{Diades::check\\_accuracy tool, CNRS-LAAS, 2006-2011}" << endl;
33  latexfile << "\\begin{document}" << endl;
34  latexfile << "\\maketitle" << endl;
35 }
36 
37 /*************************************************************************************/
38 
39 void generateLatexEpilog(ofstream & latexfile)
40 {
41  latexfile << "\\end{document}" << endl;
42 }
43 /*************************************************************************************/
44 
45 
46 void printUsage()
47 {
48  verbose<VbOutput>("Usage: check_accuracy Component.Fault topology.topo topologymap.maptopo subconfiguration.subconf [--depth number | --verbose verbose_mode --no_observable_interactions]\n");
49  verbose<VbOutput>(" - Component.Fault: label of an event. 'Component' corresponds to the name of a component and\n");
50  verbose<VbOutput>(" and Fault corresponds to the label of the event as written in the corresponding des_comp file\n");
51  verbose<VbOutput>(" - verbose_mode is ether 'on' (simple output) or 'debug' (more details)\n");
52  verbose<VbOutput>(" - the depth number is to limit the search for recommendations to a given depth.\n");
53  verbose<VbOutput>(" Without this option, there is no limit, with depth= 0 there is no limit. BE CAREFUL,\n");
54  verbose<VbOutput>(" THE RECOMMENDATION ALGORITHM IS EXPONENTIAL TO DEPTH. It may happen that for a given\n");
55  verbose<VbOutput>(" depth, the algorithm does not find a solution, in this case it will return the whole set\n");
56  verbose<VbOutput>(" of events that are relaxed and present in the traces generating an accuracy problem.\n\n");
57  exit(0);
58 }
59 
60 /*************************************************************************************/
61 
62 
63 void getInterface(int argc, char ** argv, Diades::Utils::Identifier & component, Diades::Utils::Identifier & event,
64  string & topologyFile, string & topologyMapFile, string & subconfigurationFile,
65  int & depth, VerboseLevel & level)
66 {
67  if((argc < 5) || (argc > 9))
68  {
69 
70  printUsage();
71  }
72  else
73  {
74  topologyFile.clear();
75  topologyMapFile.clear();
76  subconfigurationFile.clear();
77 
78  stringstream stream;
79  stream << argv[1];
80  char point;
81  stream >> component >> point >> event;
82  if(point != '.')
83  {
84  cerr << "The interpretation of the fault event has failed, please check the format COMP.EVENT" << endl;
85  throw Diades::Utils::Failure("main");
86  }
87  list<string> extensions;
88  extensions.push_back("topo");
89  extensions.push_back("subconf");
90  extensions.push_back("maptopo");
91  list<string>::const_iterator it = Diades::Utils::getFileExtension(string(argv[2]),extensions.begin(),extensions.end());
92  string ext1 = *it;
93  if(ext1=="topo")
94  {
95  topologyFile = argv[2];
96  }
97  else
98  {
99  if(ext1=="subconf")
100  {
101  subconfigurationFile = argv[2];
102  }
103  else
104  {
105  if(ext1=="maptopo")
106  {
107  topologyMapFile = argv[2];
108  }
109  else
110  {
111 
112  printUsage();
113  }
114  }
115  }
116  it= Diades::Utils::getFileExtension(string(argv[3]),extensions.begin(),extensions.end());
117  string ext2(*it);
118  if((ext2 == "topo") && (topologyFile.empty()))
119  {
120  topologyFile = argv[3];
121  }
122  else
123  {
124  if((ext2 == "subconf") && (subconfigurationFile.empty()))
125  {
126  subconfigurationFile = argv[3];
127  }
128  else
129  {
130  if((ext2 == "maptopo") && (topologyMapFile.empty()))
131  {
132  topologyMapFile = argv[3];
133  }
134  else
135  {
136  printUsage();
137  }
138  }
139  }
140 
141  it = Diades::Utils::getFileExtension(string(argv[4]),extensions.begin(),extensions.end());
142  string ext3(*it);
143  if((ext3 == "topo") && (topologyFile.empty()))
144  {
145  topologyFile = argv[4];
146  }
147  else
148  {
149  if((ext3 == "subconf") && (subconfigurationFile.empty()))
150  {
151  subconfigurationFile = argv[4];
152  }
153  else
154  {
155  if((ext3 == "maptopo") && (topologyMapFile.empty()))
156  {
157  topologyMapFile = argv[4];
158  }
159  else
160  {
161  printUsage();
162  }
163  }
164  }
165 
166 
167  int index = 5;
168  while(argc > index)
169  {
170  string currentParameter = argv[index];
171  Parameter param = NOPARAMETER;
172  if((param == NOPARAMETER) && (currentParameter == "--verbose")) { param = VERBOSE; }
173  if((param == NOPARAMETER) && (currentParameter == "--depth")) { param = DEPTH; }
174  switch(param)
175  {
176  case VERBOSE:
177  {
178  ++index;
179  if(argc == index)
180  {
181  printUsage();
182  }
183  currentParameter = argv[index];
184  if(currentParameter=="debug")
185  {
186  level = VbDebug;
187  }
188  else
189  {
190  if(currentParameter=="on")
191  {
192  level = VbInfo;
193  }
194  else
195  {
196  printUsage();
197  }
198  }
199  break;
200  }
201  case DEPTH:
202  {
203  ++index;
204  if(argc == index)
205  {
206  printUsage();
207  }
208  currentParameter = argv[index];
209  cout << "string = " << currentParameter << endl;
210  stringstream stream;
211  stream << currentParameter << endl;
212  stream >> depth;
213  cout << depth << endl;
214  break;
215  }
216  default:
217  {
218  printUsage();
219  }
220  break;
221  }
222  ++index;
223  }
224  }
225 }
226 
227 /*************************************************************************************/
228 
229 int main(int argc, char ** argv)
230 {
231  ofstream latexFile("check_accuracy_report.tex");
232  generateLatexPreamble(latexFile);
233  latexFile << "\\section{General information about the analysed model}" << endl;
234  latexFile << "\\begin{itemize}" << endl;
235  VerboseLevel level = VbOutput;
236  setVerboseLevel(level);
237  verbose<VbOutput>("Accuracy checker\n");
238  verbose<VbOutput>("LAAS-CNRS, 2006-2011, 7 avenue du Colonel Roche, Toulouse, France\n");
239  verbose<VbOutput>("Contact: yannick.pencole@laas.fr\n");
240  vector<Diades::Automata::ObservableComponent *> components;
241  try
242  {
243 
244  int depth = 0;
245  string topologyFile;
246  string subconfigurationFile;
247  string topologyMapFile;
248  Diades::Utils::Identifier component,event;
249  getInterface(argc,argv,component,event,topologyFile,topologyMapFile,subconfigurationFile,depth,level);
250  latexFile << "\\item Fault event to be analysed: {\\tt " << event << "} from the component {\\tt " << component << "}." << endl;
251  setVerboseLevel(level);
253  Diades::Automata::TopologyMap topoMap(topology);
254  topology.import(topologyFile);
255  latexFile << "\\end{itemize}" << endl;
256  latexFile << "\\subsection{Topology}" << endl;
257  latexFile << "\\begin{itemize}" << endl;
258  latexFile << "\\item Topology to analyse: " << topology.numberOfNodes() << " nodes, " << topology.numberOfConnections() << " connections." << endl;
259  double numberFreeProductStates = 1.0;
260  string information;
262  Diades::Automata::Event studiedEvent = Diades::Automata::EventFactory::factory()->getEvent(component.str() + "." + event.str());
264  it != topology.nodeEnd();
265  ++it)
266  {
267  components.push_back(new Diades::Automata::ObservableComponent());
268  if(components.back()->importDesCompModel(topology.getNodeName(*it).str() + ".des_comp"))
269  {
270  topoMap.mapComponentToNode(*components.back(),*it);
271  latexFile << "\\item Node {\\tt " << topology.getNodeName(*it).str() << "}: " << components.back()->numberOfStates() << " states, " << components.back()->numberOfTransitions() << " transitions." << endl;
272  numberFreeProductStates = numberFreeProductStates * components.back()->numberOfStates();
273  latexFile << "\\item Events of Node {\\tt " << topology.getNodeName(*it).str() << "}: ";
274  for(Diades::Automata::ObservableComponent::EventIterator eventIt= components.back()->eventBegin();
275  eventIt != components.back()->eventEnd();
276  ++eventIt)
277  {
278  latexFile << "{\\tt " << eventIt->nickname() << "} ";
279  }
280  latexFile << endl;
281 
282  if(component.str() == topology.getNodeName(*it).str())
283  {
284  if(!components.back()->containsEvent(studiedEvent))
285  {
286  log<LgProcess>("The event %1% does not belong to the component %2%")
287  % studiedEvent.label()
288  % topology.getNodeName(*it).str();
289  log<LgProcess>("Here are the events contained in this component: %1%")
290  % toStream(components.back()->eventBegin(), components.back()->eventEnd());
291  throw Diades::Utils::Failure("main");
292  }
293  root = *it;
294  }
295  }
296  else
297  {
298  throw Diades::Utils::Failure("main");
299  }
300  }
301  latexFile << "\\item Number of free product states: \\verb|" << numberFreeProductStates << "|" << endl;
302 
303  topoMap.importMap(topologyMapFile);
304 
306  connIt != topology.connectionEnd();++connIt)
307  {
308  latexFile << "\\item Connection {\\tt " << topology.getConnectionLabel(*connIt) << "} involves the events: " << endl;
309  const Diades::Automata::ConnectionMap & connMap = topoMap.getConnectionMap(*connIt);
311  eventIt != connMap.eventEnd();
312  ++eventIt)
313  {
314  latexFile << "{\\tt " << *eventIt << "} ";
315  }
316  latexFile << endl;
317  }
318 
319 
320  Diades::Automata::SubConfiguration subconf(topology);
321  ifstream file(subconfigurationFile.c_str());
322  subconf.importSubConf(file);
323  file.close();
324 
325  latexFile << "\\end{itemize}" << endl;
326  latexFile << "\\subsection{Subconfiguration}" << endl;
327  latexFile << "\\begin{itemize}" << endl;
328  latexFile << "\\item Contains " << subconf.numberOfComponents() << " components: ";
330  compIt != subconf.componentEnd();
331  ++compIt)
332  {
333  latexFile << "{\\tt " << topology.getNodeName(*compIt).str() << "} ";
334 
335  }
336  latexFile << endl;
337 
338  if(subconf.isMaximal())
339  {
340  latexFile << "\\item This subconfiguration is maximal, that there is no relaxed connections involving two components of the subconfiguration" << endl;
341  }
342  else
343  {
344  latexFile << "\\item This subconfiguration is not maximal, that there are some relaxed connections involving two components of the subconfiguration." << endl;
345  }
346  latexFile << "\\item Contains " << subconf.numberOfEffectiveConnections() << " effective connections: ";
348  connIt != subconf.effectiveConnectionEnd();
349  ++connIt)
350  {
351  latexFile << "{\\tt " << topology.getConnectionLabel(*connIt).str() << "} ";
352 
353  }
354 
355  latexFile << "\\item Contains " << subconf.numberOfRelaxedConnections() << " relaxed connections: ";
357  connIt != subconf.relaxedConnectionEnd();
358  ++connIt)
359  {
360  latexFile << "{\\tt " << topology.getConnectionLabel(*connIt).str() << "} ";
361 
362  }
363 
364 
365  latexFile << "\\item Contains " << subconf.numberOfExternalConnections() << " external connections: ";
367  connIt != subconf.externalConnectionEnd();
368  ++connIt)
369  {
370  latexFile << "{\\tt " << topology.getConnectionLabel(*connIt).str() << "} ";
371 
372  }
373 
374  // finally let check that the root node is the correct one
375  if(subconf.root() != root)
376  {
377  latexFile<< "\\item The root node of the subconfiguration is not the component where the fault takes place." << endl;
378  throw Diades::Utils::Failure("main: the root node in the subconfiguration is not the correct one.");
379  }
380  latexFile<< "\\item The root node of the subconfiguration is {\\tt " << topology.getNodeName(subconf.root()).str()
381  << "} that is the component where the fault to analyse occurs." << endl;
382 
383  latexFile << "\\item If there is an accuracy problem with this subconfiguration, it is due to the following shared events: " << endl;
384  latexFile << "\\begin{description}" << endl;
386  connIt != subconf.externalConnectionEnd();
387  ++connIt)
388  { latexFile << "\\item[External event] ";
389  const Diades::Automata::ConnectionMap & connMap = topoMap.getConnectionMap(*connIt);
391  eventIt != connMap.eventEnd();
392  ++eventIt)
393  {
394  latexFile << "{\\tt " << *eventIt << "} ";
395  }
396  latexFile << " from connection {\\tt " << topology.getConnectionLabel(*connIt).str() << "} ";
397  }
399  connIt != subconf.relaxedConnectionEnd();
400  ++connIt)
401  { latexFile << "\\item[Relaxed event] ";
402  const Diades::Automata::ConnectionMap & connMap = topoMap.getConnectionMap(*connIt);
404  eventIt != connMap.eventEnd();
405  ++eventIt)
406  {
407  latexFile << "{\\tt " << *eventIt << "} ";
408  }
409  latexFile << " from connection {\\tt " << topology.getConnectionLabel(*connIt).str() << "} ";
410  }
411  latexFile << "\\end{description}" << endl;
412  set<Diades::Automata::Event> events;
413  events.insert(studiedEvent);
414  bool result;
415  set< set<Diades::Automata::Event> > minimalCombinations;
416  latexFile << "\\end{itemize}" << endl;
417  latexFile << "\\section{Accuracy analysis}" << endl;
418  latexFile << "\\begin{itemize}" << endl;
419  checkSubconfigurationAccuracy(topoMap,subconf,events, information, result, minimalCombinations,depth,latexFile);
420  if(result)
421  {
422  verbose<VbOutput>("ACCURATE\n");
423  verbose<VbProcess>("Here are some details:\n %1% \n") % information;
424  }
425  else
426  {
427  verbose<VbOutput>("MAY BE NOT ACCURATE\n");
428  verbose<VbInfo>("Here are some details:\n %1% \n") % information;
429  for(set< set<Diades::Automata::Event> >::const_iterator it = minimalCombinations.begin();
430  it != minimalCombinations.end(); ++it)
431  {
432  verbose<VbOutput>("%1%\n") % toStream( it->begin(), it->end());
433  }
434  }
435  }
436  catch(exception & e)
437  {
438  latexFile << "\\end{itemize}" << endl;
439  latexFile << "\\newpage \\huge{ALERT: failure}\\\\" << endl;
440  latexFile << "Here are the logs recorded during the analysis." << endl;
441  latexFile << "\\begin{verbatim}" << endl;
442  log<LgProcess>("check_accuracy has failed, sorry for any inconvience: %1%")
443  % e.what();
444  saveLog(cerr);
445  saveLog(latexFile);
446  latexFile << "\\end{verbatim}" << endl;
447  generateLatexEpilog(latexFile);
448  latexFile.close();
449  for(vector<Diades::Automata::ObservableComponent *>::size_type i = 0; i < components.size();
450  ++i)
451  {
452  if(components[i]!=0)
453  {
454  delete components[i];
455  }
456  }
457  }
458  latexFile << "\\end{itemize}" << endl;
459  latexFile << "End of the accuracy analysis." << endl;
460  generateLatexEpilog(latexFile);
461  latexFile.close();
462  return 0;
463 }
const Label & label() const
unordered_set< Node >::const_iterator NodeIterator
Definition: Topology.hh:41
Event getEvent(Event::Id id)
void generateLatexPreamble(ofstream &latexfile)
An Identifier is a reference to a string (IdentifierData) that only contains alpha-numeric characters...
Definition: Identifier.hh:133
ConnectionIterator connectionBegin() const
Definition: Topology.hh:304
ComponentIterator componentBegin() const
InputIterator getFileExtension(const std::basic_string< CharType, CharTraits > &fileName, InputIterator begin, InputIterator end)
Definition: StringTools.hh:57
ConnectionIterator relaxedConnectionEnd() const
Parameter
NodeIterator nodeEnd() const
Definition: Topology.hh:457
void setVerboseLevel(Diades::Utils::VerboseLevel level)
Definition: Verbose.hh:135
ConnectionIterator externalConnectionBegin() const
STL namespace.
const string & str() const
Definition: Identifier.hh:421
void importMap(const string &fileName)
vector< Event >::const_iterator EventIterator
An observable Component defined as a automaton.
ConnectionSet::const_iterator ConnectionIterator
void printUsage()
void generateLatexEpilog(ofstream &latexfile)
unordered_set< Connection >::const_iterator ConnectionIterator
Definition: Topology.hh:40
EventIterator eventBegin() const
NodeIterator nodeBegin() const
Definition: Topology.hh:447
ConnectionIterator effectiveConnectionEnd() const
String utilities for Diades.
void getInterface(int argc, char **argv, Diades::Utils::Identifier &component, Diades::Utils::Identifier &event, string &topologyFile, string &topologyMapFile, string &subconfigurationFile, int &depth, VerboseLevel &level)
Diades::Graph::Node Node
Definition: Topology.hh:39
void saveLog(Logger logger, ostream &os)
Definition: Log.hh:163
const ConnectionMap & getConnectionMap(Topology::Connection connection) const
Definition: TopologyMap.hh:90
Diades::Utils::ToStream< InputIterator, Diades::Utils::AlwaysTrue< typename InputIterator::reference > > toStream(InputIterator first, InputIterator last)
Definition: Verbose.hh:143
const Identifier & getNodeName(Node node) const
Definition: Topology.hh:98
ComponentIterator componentEnd() const
void mapComponentToNode(const ObservableComponent &component, Topology::Node itsNode)
const Identifier & getConnectionLabel(Connection connection) const
Definition: Topology.hh:114
unsigned numberOfConnections() const
Definition: Topology.hh:188
unsigned numberOfNodes() const
Definition: Topology.hh:177
ConnectionIterator effectiveConnectionBegin() const
static EventFactory * factory()
set< Event >::const_iterator EventIterator
Definition: Component.hh:73
ConnectionIterator relaxedConnectionBegin() const
ConnectionIterator connectionEnd() const
Definition: Topology.hh:314
Logging facilities for the Diades projects.
ComponentSet::const_iterator ComponentIterator
EventIterator eventEnd() const
ConnectionIterator externalConnectionEnd() const
void import(const string &fileName)
int main(int argc, char **argv)
void checkSubconfigurationAccuracy(const TopologyMap &topology, const SubConfiguration &subConfiguration, const set< Event > &events, string &information, bool &result, set< set< Event > > &minimalCombinations, int depth, ofstream &toLatex)