DiaDes  0.1
DIAgnosis of Discrete-Event System
abstract.cc
Go to the documentation of this file.
1 
13 #include<iostream>
14 #include<fstream>
15 #include<list>
16 #include<string>
17 #include<set>
18 
19 #include<boost/date_time/posix_time/posix_time.hpp>
20 #include<utils/Exceptions.hh>
21 #include<utils/CmdInterface.hh>
22 #include<automata/Event.hh>
24 
25 
26 using namespace std;
27 using namespace Diades::Automata;
28 using namespace Diades::Utils;
29 using namespace boost::posix_time;
30 
31 /************************************************************************************/
32 typedef enum { OUTPUT=0, VERBOSE=1, EVENTS=2, NOTEVENTS=3, HELP=4, STATEABSTRACTIONS = 5 } Option;
33 typedef enum { DESCOMP=0 } FileExtension;
34 unsigned numberOfOptions = 6;
36 
37 
39 vector<string> options(numberOfOptions);
40 vector<bool> isSet(numberOfOptions,false);
41 
42 string description="Usage: abstract --help |\n\t [file.des_comp] [ [--events | --notevents] evt1 evt2 ....] [--output result.des_comp] [--verbose trace.log] [--state-abstractions filename]\n\n\t Compute the model resulting from the abstraction of evt1, evt2 on the standard output\n\tunless the optional output file is setup.\n\tAccept model from standard input\n\tThe option --state-abstractions allows to write in a file the resulting state abstractions";
43 
45 {
46  options[OUTPUT] = "--output";
47  options[VERBOSE] = "--verbose";
48  options[EVENTS] = "--events";
49  options[NOTEVENTS] = "--notevents";
50  options[HELP] = "--help";
51  options[STATEABSTRACTIONS] = "--state-abstractions";
52  fileExtensions[DESCOMP] = "des_comp";
53 }
54 
55 
56 
57 /************************************************************************************/
58 
59 
62 
63 /************************************************************************************/
64 
65 void readParameters(int argc, char * argv[], string & modelFile, string & outputFile,
66  string & logFile, string & stateAbstractionFile,
67  unordered_set<Event> & abstractedEvents);
68 
69 /************************************************************************************/
70 
71 int main(int argc, char * argv[])
72 {
73  string modelFile;
74  string logFile;
75  string outputFile;
76  string stateAbstractionFile;
77  unordered_set<Event> abstractedEvents;
79  readParameters(argc,argv,modelFile,outputFile,
80  logFile,stateAbstractionFile,
81  abstractedEvents);
82  try
83  {
84  ptime time1(microsec_clock::universal_time());
85  if(!logFile.empty())
86  {
87  if(modelFile.empty())
88  {
89  log<LgProcess>("start importing model from the input stream at %1%")% time1;
90  }
91  else
92  {
93  log<LgProcess>("start importing model '%2%' at %1%")% time1 % modelFile;
94  }
95  }
96  ObservableComponent component;
97  if(modelFile.empty())
98  {
99  component.importDesCompModel(cin);
100  }
101  else
102  {
103  component.importDesCompModel(modelFile);
104  }
105  ptime time2(microsec_clock::universal_time());
106  if(!logFile.empty())
107  {
108  log<LgProcess>("end importing model at %1% (duration: %2%ms)")
109  % time2 % (time2-time1);
110  if(modelFile.empty())
111  {
112  log<LgProcess>("start abstracting model from the input stream on the events %1%")
113  % toStream(abstractedEvents.begin(),abstractedEvents.end());
114  }
115  else
116  {
117  log<LgProcess>("start abstracting model '%1%' on the events %2%") % modelFile % toStream(abstractedEvents.begin(),abstractedEvents.end());
118  }
119  }
120  ObservableComponent abstraction;
121  set<Event> projectedEvents;
122  if(!isSet[NOTEVENTS])
123  {
124  // complements of abtractedEvents in the component
125  for(Component::EventIterator evtIt = component.eventBegin();
126  evtIt != component.eventEnd(); ++evtIt)
127  {
128  if(abstractedEvents.find(*evtIt) == abstractedEvents.end())
129  {
130  projectedEvents.insert(*evtIt);
131  }
132  }
133  }
134  else
135  {
136  // abstraction of any event that is not in projectedEvents
137  projectedEvents.insert(abstractedEvents.begin(),abstractedEvents.end());
138  }
139  if(stateAbstractionFile.empty())
140  {
141  abstraction.project(&component,projectedEvents);
142  }
143  else
144  {
145  typedef unordered_map<Diades::Automata::State,unordered_set<Diades::Automata::State> > Dict;
146  Dict dictionary;
147  abstraction.project(&component,projectedEvents,dictionary);
148  ofstream file(stateAbstractionFile.c_str());
149  for(Dict::const_iterator it = dictionary.begin();
150  it != dictionary.end();
151  ++it)
152  {
153  file << it->first << " { ";
154  for(unordered_set<Diades::Automata::State>::const_iterator it2 = it->second.begin();
155  it2 != it->second.end();
156  ++it2)
157  {
158  file << *it2 << " ";
159  }
160  file << "}" << endl;
161  }
162  file.close();
163  }
164  abstraction.setName(component.name());
165  ptime time3(microsec_clock::universal_time());
166  if(!logFile.empty())
167  {
168  log<LgProcess>("end abstracting model at %1% (duration: %2%ms)")
169  % time3 % (time3-time2);
170 
171  if(outputFile.empty())
172  {
173  log<LgProcess>("saving model to the standard output");
174  }
175  else
176  {
177  log<LgProcess>("saving model to '%1%'") % outputFile;
178  }
179  }
180  if(!outputFile.empty())
181  {
182  ofstream file(outputFile.c_str());
183  abstraction.exportDesCompModel(file);
184  }
185  else
186  {
187  abstraction.exportDesCompModel(cout);
188  }
189  if(!logFile.empty())
190  {
191  log<LgProcess>("successful.");
192  ofstream logs(logFile.c_str());
193  saveLog(logs);
194  }
195  }
196  catch(exception & e)
197  {
198  log<LgProcess>("abstract has failed, sorry for any inconvenience: %1%")
199  % e.what();
200  saveLog(cerr);
201  }
202  return 0;
203 }
204 
205 /*************************************************************************************/
206 
207 void readParameters(int argc, char * argv[], string & modelFile, string & outputFile,
208  string & logFile, string & stateAbstractionFile, unordered_set<Event> & abstractedEvents)
209 {
210  if(argc < 1)
211  {
213  exit(1);
214  }
215 
216 
217  int index = 1;
218  while( index < argc )
219  {
220  Option currentOption;
221  if(getOption<Option>(argv[index],options,currentOption))
222  {
223  if(isSet[currentOption])
224  {
225  printError("The option '" + options[currentOption] + "' occurs at least twice.");
226  }
227  else
228  {
229  isSet[currentOption] = true;
230  }
231  switch(currentOption)
232  {
233  case STATEABSTRACTIONS:
234  {
235  ++index;
236  getParameter<string>(argc,argv,index,stateAbstractionFile);
237  if(stateAbstractionFile.empty())
238  {
239  printError("No parameter after the option " + options[currentOption]);
240  }
241  break;
242  }
243  case HELP:
244  {
246  break;
247  }
248  case OUTPUT:
249  {
250  ++index;
251  getParameter<string>(argc,argv,index,outputFile);
252  if(outputFile.empty())
253  {
254  printError("No parameter after the option " + options[currentOption]);
255  }
256  break;
257  }
258  case VERBOSE:
259  {
260  ++index;
261  getParameter<string>(argc,argv,index,logFile);
262  if(logFile.empty())
263  {
264  printError("No parameter after the option " + options[currentOption]);
265  }
266  break;
267  }
268  case EVENTS:
269  {
270  if(isSet[NOTEVENTS])
271  {
272  printError("The option '" + options[EVENTS] + "' cannot be set when the option '" + options[NOTEVENTS] + "' is set.");
273  }
274  set< string > eventLabels;
275  ++index;
276  getParameterList<string>(argc,argv,options,fileExtensions,index, eventLabels);
277  for(const string & label: eventLabels)
278  {
279  abstractedEvents.insert(EventFactory::factory()->getEvent(label));
280  }
281  break;
282  }
283  case NOTEVENTS:
284  {
285  if(isSet[EVENTS])
286  {
287  printError("The option '" + options[EVENTS] + "' cannot be set when the option '" + options[NOTEVENTS] + "' is set.");
288  }
289  set< string > eventLabels;
290  ++index;
291  getParameterList<string>(argc,argv,options,fileExtensions,index, eventLabels);
292  for(const string & label: eventLabels)
293  {
294  abstractedEvents.insert(EventFactory::factory()->getEvent(label));
295  }
296  break;
297  }
298  }
299  }
300  else
301  {
302  vector<string>::const_iterator it =
303  getFileExtension(string(argv[index]),fileExtensions.begin(),fileExtensions.end());
304  if(it == fileExtensions.end())
305  {
306  printError("Unrecognized file extension in file name: " + string(argv[index]));
307  }
308  FileExtension extension = DESCOMP;
309  switch(extension)
310  {
311  case DESCOMP:
312  {
313  modelFile = string(argv[index]);
314  break;
315  }
316  }
317  ++index;
318  }
319  }
320 }
321 
InputIterator getFileExtension(const std::basic_string< CharType, CharTraits > &fileName, InputIterator begin, InputIterator end)
Definition: StringTools.hh:57
Definition: abstract.cc:32
int main(int argc, char *argv[])
Definition: abstract.cc:71
void readParameters(int argc, char *argv[], string &modelFile, string &outputFile, string &logFile, string &stateAbstractionFile, unordered_set< Event > &abstractedEvents)
Definition: abstract.cc:207
STL namespace.
FileExtension
Definition: abstract.cc:33
unsigned numberOfFileExtensions
Definition: abstract.cc:35
vector< string > options(numberOfOptions)
An observable Component defined as a automaton.
virtual bool importDesCompModel(const string &filename)
Option
Definition: abstract.cc:32
unsigned numberOfOptions
Definition: abstract.cc:34
void saveLog(Logger logger, ostream &os)
Definition: Log.hh:163
Diades::Utils::ToStream< InputIterator, Diades::Utils::AlwaysTrue< typename InputIterator::reference > > toStream(InputIterator first, InputIterator last)
Definition: Verbose.hh:143
void initialiseOptions()
Definition: abstract.cc:44
void printError(string parameter, string message)
set< Event >::const_iterator EventIterator
Definition: Component.hh:73
Log log(Logger logger, const string &msg)
Definition: Log.hh:124
string description
Definition: abstract.cc:42
vector< string > fileExtensions(numberOfFileExtensions)
vector< bool > isSet(numberOfOptions, false)
void printUsage(const po::options_description &desc)