26 #include "boost/date_time/posix_time/posix_time.hpp" 29 #include<utils/CmdInterface.hh> 46 string description=
"Usage: dd-check-reachability --help | model1.des_comp [model2.des_comp ... sync.rules] [--event e1 e2 ]";
69 void clean(vector<Diades::Automata::ObservableComponent *> & components,
71 vector<Diades::Automata::ComposableModel::ConstPointer> & comps)
77 for(vector<Diades::Automata::ComposableModel::ConstPointer>::size_type i = 0; i < comps.size(); ++i)
83 for(vector<Diades::Automata::ObservableComponent *>::size_type i = 0; i < components.size();
86 if(components[i]!=
nullptr)
89 components[i]=
nullptr;
112 int main(
int argc,
char ** argv)
114 verbose<VbOutput>(
"DiaDes: check-reachability\n");
115 verbose<VbOutput>(
"LAAS-CNRS, 2006-2015, 7 avenue du Colonel Roche, Toulouse, France\n");
116 verbose<VbOutput>(
"Contact: yannick.pencole@laas.fr\n");
120 set<string> modelFile;
133 if(getOption<Option>(argv[index],
options,currentOption))
135 if(
isSet[currentOption])
137 printError(
"The option '" +
options[currentOption] +
"' occurs at least twice.");
142 isSet[currentOption] =
true;
145 switch(currentOption)
149 if((index!=1) || (argc !=2))
151 printError(
"Incorrect use of option --help.");
165 if(events.size() == 0)
167 printError(
"One or more arguments wre expected after option --event.");
175 printError(
"Unrecognized option: " +
string(argv[index]));
185 vector<string>::const_iterator it =
190 printError(
"Unrecognized file extension in file name: " +
string(argv[index]));
201 modelFile.insert(
string(argv[index]));
206 if(!ruleFile.empty())
208 printError(
"It seems that there are more than one synchronization rules file as a argument.");
211 ruleFile = string(argv[index]);
218 if(modelFile.empty())
220 printError(
"No model, so no check.");
return 1;
222 if((modelFile.size() == 1) && (!ruleFile.empty()))
224 printError(
"There is one synchronization rule file but no more than one component.");
return 1;
226 if((modelFile.size() > 1) && (ruleFile.empty()))
228 printError(
"There is no synchronization rule file but it is required as there is more than one component in the model.");
return 1;
231 vector<Diades::Automata::ObservableComponent *> components(modelFile.size(),
nullptr);
233 vector<Diades::Automata::ComposableModel::ConstPointer> comps;
239 for(
const string & name: modelFile)
242 if(!components[i]->importOldModel(name))
246 vectorComp.push_back(components[i]);
249 if(!ruleFile.empty())
251 rules.loadRules(vectorComp,ruleFile);
256 log<LgProcess>(
"The main function caught the following exception: \n\t%1%") % e.what();
258 clean(components,model,comps);
259 printError(
"Load of the files has failed. See log above.");
264 if(components.size()==1)
266 unsigned visitedTransitions = 0;
267 unsigned visitedStates = 0;
268 unsigned deadlocks = 0;
270 mask = components[0]->mask();
272 unordered_map<Diades::Automata::Event,bool> searchedEvent;
275 if(events.find(event.label()) != events.end())
277 searchedEvent.insert(make_pair(event,
false));
284 visited.
init(components[0]->behaviour(),
false);
286 components[0]->initialStateBegin();
287 it != components[0]->initialStateEnd();
290 queue.push_back(make_pair(*it, components[0]->outputTransitionBegin(*it)));
292 toDot <<
"\t " << *it <<
"\t [label=\"";
293 toDot << components[0]->getLabel(*it);
294 toDot <<
"\"];" << endl;
295 toDot <<
"\t init" << *it <<
"\t [label=\"\",color=white];" << endl;
296 toDot <<
"\t init" << *it <<
" -> " << *it <<
";" << endl;
299 if(it->outDeg() == 0)
304 while((found < searchedEvent.size()) && !(queue.empty()))
306 Diades::Automata::State currentState = queue.front().first;
307 if(queue.front().second == components[0]->outputTransitionEnd(currentState))
310 std::cout << currentState <<
": SATURATED" << std::endl;
315 ++visitedTransitions;
316 toDot <<
"\t" << currentState <<
" -> " << currentTrans.target()
317 <<
" [label=\"" << components[0]->getEvent(currentTrans).nickname();
318 toDot <<
"\"];" << endl;
319 unordered_map<Diades::Automata::Event,bool>::iterator it =
320 searchedEvent.find(components[0]->getEvent(currentTrans));
321 if(it != searchedEvent.end())
323 if(it->second ==
false)
327 std::cout <<
"FOUND" << std::endl;
330 if(!visited[currentTrans.target()])
332 queue.push_back(make_pair(currentTrans.target(), components[0]->outputTransitionBegin(currentTrans.target())));
333 toDot <<
"\t " << currentTrans.target() <<
"\t [label=\"";
334 toDot << components[0]->getLabel(currentTrans.target());
335 toDot <<
"\"];" << endl;
336 visited[currentTrans.target()]=
true;
338 if(currentTrans.target().outDeg() == 0)
343 ++queue.front().second;
346 std::cout <<
"REACHABILITY ANALYSIS" << std::endl;
347 for(unordered_map<Diades::Automata::Event,bool>::const_iterator it = searchedEvent.begin();
348 it != searchedEvent.end(); ++it)
350 std::cout << it->first <<
": ";
353 std::cout <<
"YES" << std::endl;
357 std::cout <<
"NO" << std::endl;
360 std::cout <<
"Visited States: " << ((double) visitedStates / (
double) components[0]->numberOfStates() * 100.0 ) <<
"% (" << visitedStates <<
" has been visited)" << std::endl;
361 std::cout <<
"Visited Transitions: " << ((double) visitedTransitions / (
double) components[0]->numberOfTransitions() * 100.0 ) <<
"% (" << visitedTransitions <<
" has been visited)" << std::endl;
362 std::cout <<
"Visited deadlocks: " << deadlocks << std::endl;
369 for(
unsigned i = 0 ; i < components.size(); ++i)
373 it != components[i]->mask().
eventEnd();
377 it2 != components[i]->mask().observableEnd(*it);
389 std::ofstream file(
"reachability.dot");
392 file <<
"digraph G {" << endl;
393 file <<
"\tratio=fill;" << endl;
394 file <<
"\tpage=\"8.5,11.6\";" << endl;
395 file <<
"\tsize=\"7.5,10.5\";" << endl;
396 file <<
"\tlabel=\"Component name = reachability\";" << endl;
397 file << toDot.str() << endl;
402 clean(components,model,comps);
vector< string > options(numberOfOptions)
vector< const Component * > ComponentVector
InputIterator getFileExtension(const std::basic_string< CharType, CharTraits > &fileName, InputIterator begin, InputIterator end)
Diades::Graph::Edge Transition
vector< bool > isSet(numberOfOptions, false)
void init(Graph &g, SizeType capacity=0, ValueType dflt=ValueType())
unordered_set< State >::const_iterator InitialStateIterator
set< Event >::const_iterator ObservableEventIterator
An observable Component defined as a automaton.
int main(int argc, char **argv)
ostream & toDot(ostream &os, const StateMachine &fsm, const PrintStateProperty &statePrinter, const PrintEventInfo &eventPrinter)
set< Event >::const_iterator EventIterator
Random generation utilities.
void clean(vector< Diades::Automata::ObservableComponent *> &components, Diades::Automata::ComposableModel *model, vector< Diades::Automata::ComposableModel::ConstPointer > &comps)
Diades::Graph::OutEdgeIterator OutputTransitionIterator
ObservableEventIterator observableBegin() const
void saveLog(Logger logger, ostream &os)
EventIterator eventEnd() const
void printError(string parameter, string message)
void addMask(const Event &e, const Event &obs)
Diades::Graph::Node State
unsigned numberOfFileExtensions
vector< string > fileExtensions(numberOfFileExtensions)
void printUsage(const po::options_description &desc)