DiaDes  0.1
DIAgnosis of Discrete-Event System
Project.cc
Go to the documentation of this file.
1 
10 #include <cstdlib>
11 #include<iostream>
12 #include<fstream>
13 #include<regex>
14 #include<boost/program_options.hpp>
15 
21 #include"../AutomataInterface.hh"
23 
24 using namespace std;
25 using namespace Diades::Automata::Experimental;
26 using namespace Diades::Utils;
27 using namespace Diades::CmdInterface;
28 
29 namespace Poptions = boost::program_options;
30 
31 
32 
37 const string program("dd-project");
38 
39 /*
40  * File suffixes
41  */
42 FileSuffixes suffixes({"aut", "ddaut"});
43 
51 void
52 initialiseOptions(int argc, char * argv[],
53  Poptions::options_description & desc,
54  Poptions::variables_map & vm)
55 {
56  desc.add_options()
57  ("help,h", "produce help message")
58  ("file,f", Poptions::value< string >(), "automaton file (.aut/.ddaut format)")
59  ("output,o", Poptions::value< string >(), "outfile name (.aut/.ddaut format)")
60  ("event,e", Poptions::value<std::vector< string > >(), "a list of events to project")
61  ("noevent,n", Poptions::value<std::vector< string > >(), "a list of events not to project")
62  ;
63  Poptions::positional_options_description p;
64  p.add("file", 1);
65  Poptions::store(Poptions::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
66  Poptions::notify(vm);
67 }
68 
69 
76 
86 template<typename FsmType,
87 typename Event>
88 bool
89 getProjectedEvents(const FsmType & fsm,
90  std::vector<Event> & events,
91  std::vector<Event> & noevents,
92  std::vector<Event> & projectedEvents)
93 {
94  if(events.empty())
95  {
96  if(noevents.empty())
97  {
98  return false;
99  }
100  else
101  {
102  std::sort(noevents.begin(), noevents.end());
103 
104  // take any event from fsm that is not in noevent
105  auto fsmEvents = fsm.events();
106  std::sort(fsmEvents.begin(), fsmEvents.end());
107  std::set_difference(fsmEvents.begin(), fsmEvents.end(), noevents.begin(), noevents.end(),
108  std::inserter(projectedEvents, projectedEvents.begin()));
109  }
110  }
111  else
112  {
113  auto fsmEvents = fsm.events();
114  std::sort(events.begin(), events.end());
115  std::sort(fsmEvents.begin(), fsmEvents.end());
116  std::set_intersection(fsmEvents.begin(), fsmEvents.end(), events.begin(), events.end(),
117  std::inserter(projectedEvents, projectedEvents.begin()));
118  // check that projectedEvents does not contain any event from noevent
119  std::vector<Event> intersection;
120  std::sort(noevents.begin(), noevents.end());
121  std::set_intersection(projectedEvents.begin(), projectedEvents.end(),
122  noevents.begin(),
123  noevents.end(),
124  std::inserter(intersection, intersection.begin()));
125  if(!intersection.empty())
126  {
127  return false;
128  }
129  }
130  return true;
131 }
132 
143 size_t
144 projectAut(const std::string & fileName, const std::string & output,
145  std::vector<std::string> & events,
146  std::vector<std::string> & noevents)
147 {
148 
149  AutFsm fsm;
150  ifstream file(fileName.c_str());
151  if(file.is_open())
152  {
153  auto loaded = fromAutFile(file, fsm);
154  file.close();
155  if(!loaded)
156  {
157  return printCommandLineError(Msg("Error when loading the automaton file %1%") % fileName);
158  }
159  }
160  else
161  {
162  return printCommandLineError(Msg("Error when opening the automaton file %1%") % fileName);
163  }
164 
165  AutFsm projection;
166  std::vector<AutEventId> projectedEvents;
167  if(getProjectedEvents(fsm, events, noevents, projectedEvents))
168  {
169  project(fsm, projection,
170  projectedEvents.begin(), projectedEvents.end());
171  }
172  else
173  {
174  return printCommandLineError(Msg("Error when analysing the events/noevents to project, they are incompatible please check them \n are they BOTH empty? \n Is an event part of both sets? \n events are %1%,\n noevents are %2%")
175  % toStream(events.begin(), events.end()) % toStream(noevents.begin(), noevents.end()));
176  }
177  return writeAut(projection, output, suffixes);
178 }
179 
192 bool
194  const std::vector<std::string> & events,
195  const std::vector<std::string> & noevents,
196  DdAutEventManager & eManager,
197  std::vector<DdAutEventId> & projectedEvents)
198 {
199  std::vector<DdAutEventId> eventIds;
200  std::vector<DdAutEventId> noeventIds;
201  std::for_each(events.begin(), events.end(),
202  [&](const std::string & event)
203  {
204  if(eManager.hasEvent(event))
205  {
206  eventIds.push_back(eManager.eventId(event));
207  }
208  });
209  std::for_each(noevents.begin(), noevents.end(),
210  [&](const std::string & event)
211  {
212  if(eManager.hasEvent(event))
213  {
214  noeventIds.push_back(eManager.eventId(event));
215  }
216  });
217  return getProjectedEvents(fsm, eventIds, noeventIds, projectedEvents);
218 }
219 
230 size_t
231 projectDdaut(const std::string & fileName, const std::string & output,
232  std::vector<std::string> & events,
233  std::vector<std::string> & noevents)
234 {
235  DdAutFileDescriptor descriptor;
236  DdAutEventManager eManager;
237  DdAutStateManager sManager;
238  DdAutStateManager sManagerProj;
239  ifstream file(fileName.c_str());
240  if(file.is_open())
241  {
242  auto loaded = descriptor.readStream(file);
243  file.close();
244  if(!loaded)
245  {
246  return printCommandLineError(Msg("Error when loading the 'ddaut' automaton file %1%") % fileName);
247  }
248  }
249  else
250  {
251  return printCommandLineError(Msg("Error when opening the 'ddaut' automaton file %1%") % fileName);
252  }
253  if(descriptor.acceptorBegin() != descriptor.acceptorEnd())
254  {
255  DdAutFA fa;
256 
257  auto loaded = faFromDescriptor(descriptor, fa, sManager, eManager);
258  if(!loaded)
259  {
260  return printCommandLineError(Msg("Error when loading the 'ddaut descriptor of the finite automaton file %1%") % fileName);
261  }
262 
263 
264  std::vector<DdAutEventId> projectedEvents;
265  DdAutFA projectedFA;
266  DdAutProjection projectionLabels;
267 
268  if(getProjectedEvents(fa, events, noevents, eManager, projectedEvents))
269  {
270  project(fa, projectedFA, sManager, sManagerProj, projectionLabels, projectedEvents.begin(), projectedEvents.end());
271  }
272  else
273  {
274  return printCommandLineError(Msg("Error when analysing the events/noevents to project, they are incompatible please check them \n are they BOTH empty? \n Is an event part of both sets? \n events are %1%,\n noevents are %2%")
275  % toStream(events.begin(), events.end()) % toStream(noevents.begin(), noevents.end()));
276  }
277  return writeFiniteAutomaton(ConstManagedDdAutFA(projectedFA, sManagerProj, eManager), output, suffixes);
278  }
279  else
280  {
281  DdAutFsm fsm;
282  auto loaded = fsmFromDescriptor(descriptor, fsm, sManager, eManager);
283  if(!loaded)
284  {
285  return printCommandLineError(Msg("Error when loading the 'ddaut descriptor of the finite state machine file %1%") % fileName);
286  }
287 
288  std::vector<DdAutEventId> projectedEvents;
289  DdAutFsm projectedFsm;
290  DdAutProjection projectionLabels;
291 
292  if(getProjectedEvents(fsm, events, noevents, eManager, projectedEvents))
293  {
294  project(fsm, projectedFsm, sManager, sManagerProj, projectionLabels, projectedEvents.begin(), projectedEvents.end());
295  }
296  else
297  {
298  return printCommandLineError(Msg("Error when analysing the events/noevents to project, they are incompatible please check them \n are they BOTH empty? \n Is an event part of both sets? \n events are %1%,\n noevents are %2%")
299  % toStream(events.begin(), events.end()) % toStream(noevents.begin(), noevents.end()));
300  }
301  return writeFiniteStateMachine(ConstManagedDdAutFsm(projectedFsm, sManagerProj, eManager), output, suffixes);
302  }
303  return false;
304 }
305 
315 size_t
316 projectFsm(const std::string & fileName, const std::string & output,
317  std::vector<std::string> & events,
318  std::vector<std::string> & noevents)
319 {
320  if(fileName.empty())
321  {
322  return printCommandLineError(Msg("Expecting a filename but I did not get anything. Use dd-project --help for documentation."));
323  }
324  if(suffixes.match(fileName, "aut"))
325  {
326  return projectAut(fileName, output, events, noevents);
327  }
328  else
329  {
330  if(suffixes.match(fileName, "ddaut"))
331  {
332  return projectDdaut(fileName, output, events, noevents);
333  }
334  else
335  {
336  return printCommandLineError(Msg("Expecting a file with a name ending with .aut, but I read %1%") % fileName);
337  }
338  }
340 }
341 
348 int
349 main(int argc, char** argv)
350 {
351  std::string fileName, output;
352  std::vector<std::string> events;
353  std::vector<std::string> noevents;
354  try
355  {
356  Poptions::options_description desc("Options");
357  Poptions::variables_map vm;
358  initialiseOptions(argc, argv, desc, vm);
359  if(vm.count("help"))
360  {
361  return printUsage(program, desc);
362  }
363  if(vm.count("file"))
364  {
365  fileName = vm["file"].as<std::string>();
366  }
367  if(vm.count("output"))
368  {
369  output = vm["output"].as<std::string>();
370  }
371  if(vm.count("event"))
372  {
373  events = vm["event"].as<std::vector < std::string >> ();
374  }
375  if(vm.count("noevent"))
376  {
377  noevents = vm["noevent"].as<std::vector < std::string >> ();
378  }
379  }
380  catch(Poptions::required_option & e)
381  {
382  return printCommandLineError(e.what());
383  }
384  catch(Poptions::error & e)
385  {
386  return printCommandLineError(e.what());
387  }
388  return projectFsm(fileName, output, events, noevents);
389 }
390 
size_t writeAut(const Diades::Automata::Experimental::AutFsm &fsm, const std::string &output, const FileSuffixes &suffixes)
StateMachine< AutStateId, AutEventId > AutFsm
Definition: AutFile.hh:45
bool hasEvent(const Event &event) const
Definition: Event.hh:128
StatePropertyManager< DdAutStateLabel, DdAutStateId > DdAutStateManager
Definition: DdAutFile.hh:63
size_t writeFiniteAutomaton(const Diades::Automata::Experimental::ConstManagedDdAutFA &mfa, const std::string &output, const FileSuffixes &suffixes)
bool fsmFromDescriptor(const DdAutFileDescriptor &descriptor, DdAutFsm &fsm, DdAutStateManager &sManager, DdAutEventManager &eManager)
const size_t ERROR_UNHANDLED_EXCEPTION
Definition: CmdInterface.hh:35
size_t printCommandLineError(const string &msg)
Definition: CmdInterface.cc:98
bool faFromDescriptor(const DdAutFileDescriptor &descriptor, DdAutFA &fa, DdAutStateManager &sManager, DdAutEventManager &eManager)
EventId eventId(const Event &event)
Definition: Event.hh:170
FileSuffixes suffixes({"aut", "ddaut"})
STL namespace.
int main(int argc, char **argv)
Definition: Project.cc:349
data structure that gathers an Fsm, a StateManager and a EventManager
Definition: DdAutFile.hh:95
void project(const Trace &source, const set< Event::Id > &projectedEvents, Trace &target)
vector< string > options(numberOfOptions)
data structure that gathers an FA, a StateManager and a EventManager
Definition: DdAutFile.hh:135
bool match(const std::string &fileName, const std::string &suffix) const
Definition: CmdInterface.cc:54
DdAutFsm::EventPropertyId Event
Definition: TrimState.cc:139
void initialiseOptions(int argc, char *argv[], Poptions::options_description &desc, Poptions::variables_map &vm)
Definition: Project.cc:52
Diades::Utils::ToStream< InputIterator, Diades::Utils::AlwaysTrue< typename InputIterator::reference > > toStream(InputIterator first, InputIterator last)
Definition: Verbose.hh:143
bool getProjectedEvents(const FsmType &fsm, std::vector< Event > &events, std::vector< Event > &noevents, std::vector< Event > &projectedEvents)
Definition: Project.cc:89
size_t writeFiniteStateMachine(const Diades::Automata::Experimental::ConstManagedDdAutFsm &mfsm, const std::string &output, const FileSuffixes &suffixes)
size_t projectDdaut(const std::string &fileName, const std::string &output, std::vector< std::string > &events, std::vector< std::string > &noevents)
Definition: Project.cc:231
EventManager< DdAutEventLabel, DdAutEventId > DdAutEventManager
Definition: DdAutFile.hh:68
bool fromAutFile(std::istream &stream, AutFsm &fsm)
StateMachine< DdAutStateId, DdAutEventId > DdAutFsm
Definition: DdAutFile.hh:42
boost::format Msg
Definition: Verbose.hh:42
const string program("dd-project")
size_t projectFsm(const std::string &fileName, const std::string &output, std::vector< std::string > &events, std::vector< std::string > &noevents)
Definition: Project.cc:316
virtual bool readStream(std::istream &stream)
size_t projectAut(const std::string &fileName, const std::string &output, std::vector< std::string > &events, std::vector< std::string > &noevents)
Definition: Project.cc:144
void printUsage(const po::options_description &desc)