97 string description =
"Usage: dd-generate\n\t --help |\n\t [--topo topologyFileName.topo]\n\t [--seed randomSeed]\n\t [--evtMin nbEvtMin]\n\t [--evtMax nbEvtMax]\n\t [--obsMin nbObsMin]\n\t [--obsMax nbObsMax]\n\t [--stateMin nbStateMin]\n\t [--stateMax nbStateMax]\n\t [--latex latexFileName]\n\t [--outputdir dirName]\n\t [--obsInteractionMin nbObsIntMin]\n\t [--obsInteractionMax nbObsIntMax]\n\t [--nodeBehaviour node=file.descomp ci=ej ck=el ...]]\n\t [--outputDegreeMax outDeg]\n\t [--petrinet]\n\n\n Generate a distributed discrete-event system that has the topology\n defined in the file topologyFileName.topo. The generator uses\n a random generator of number that can be initialised with the\n seed 'randomSeed'. If not provided, the seed is the starting time\n of each run of the program. As far as the behaviour of a component\n is concerned, the number of generated states is between nbStateMin\n and nbStateMax. The number of event is between nbEvtMin and nbEvtMax\n as long as it is compatible with the topology. The number of\n observable events is between nbObsMin and nbObsMax. The generated model\n consists of a set of files written in the directory 'dirName'. The\n model generator also generates a document in latex format for documentation\n purposes (if the option is set). The parameters --obsInteractionMin\n and --obsInteractionMax states the possible numbers of observable interactions.\n The --nodeBehaviour parameters states that one (and only one) of the node\n called 'node' has the predefined behaviour described in 'file.descomp'. \nConstraints like 'ci=sj' assert that the component 'node' implements the\n connection 'ci' of the topology with the iteractive event 'sj'.\n The option '--outputDegreeMax' rules the maximal number of transitions\n (i.e. events) that are the output of one state. If the --petrinet option is set, the distributed system is generated as a 1-bounded petri net. ";
156 State currentInteractingState,
157 const Event & eventCurrentNode,
158 map<Event, Topology::Connection> & mappingCurrentSideToInteraction,
159 map<Topology::Connection, Event> & mappingConnectionToInteraction,
160 const set<Event> & constrainedEvents);
194 set<Node>::const_iterator first,
195 set<Node>::const_iterator last,
196 unsigned numberOfStates,
197 unsigned outputDegreeMax,
215 unsigned obsInteractionMax,
const set<Event> & interactiveEvents,
216 const set<Event> & nonInteractiveEvents,
238 unsigned obsInteractionMax,
240 set<Event> & nonInteractiveEvents);
271 set<Node>::const_iterator first,
272 set<Node>::const_iterator last,
279 unsigned obsInteractionMin,
280 unsigned obsInteractionMax,
281 unsigned outputDegreeMax,
297 set<Node>::const_iterator first,
298 set<Node>::const_iterator last,
331 set<Node>::const_iterator first,
332 set<Node>::const_iterator last);
353 const set<Node> & nonGeneratedNeighbours,
354 pair<string, ObservableComponent *> & result);
372 set<Topology::Node> & generatedNeighbours,
373 set<Topology::Node> & nonGeneratedNeighbours,
374 list<Topology::Node> & nodesToVisit);
386 const string & dirName);
411 unsigned obsInteractionMin,
412 unsigned obsInteractionMax,
415 string dirName,
Node fixedTopoNode,
416 unsigned outputDegreeMax);
428 unsigned obsInteractionMin,
429 unsigned obsInteractionMax,
431 unsigned outputDegreeMax,
432 const string & fixedNode,
433 const string & behaviourFileName,
434 map<string, string> & assignedConnections,
437 const string & filename,
438 ofstream & latexfile);
446 unsigned obsInteractionMin,
447 unsigned obsInteractionMax,
449 unsigned outputDegreeMax,
450 const string & fixedNode,
451 const string & behaviourFileName,
452 map<string, string> & assignedConnections,
455 const string & filename);
460 const string & mapTopoFileNameDest);
463 vector<Node> & indexState);
466 unsigned numberOfTrans,
471 set<Event> & newSelection,
472 set<Event> & unusedEvents);
483 map<Event, Topology::Connection> & mappingInteractionToCurrentSide,
484 map<Event, Topology::Connection> & mappingCurrentSideToInteraction,
486 NodeMap< set<State> > & stateMapping,
487 unsigned outputDegreeMax,
495 map<Event, Topology::Connection> & mappingInteractionToCurrentSide,
498 State correspondingState,
499 NodeMap< set<State> > & stateMapping);
524 int main(
int argc,
char ** argv) {
528 cout <<
"Discrete-event system generator" << endl;
529 cout <<
"LAAS-CNRS, 2006-2017, 7 avenue du Colonel Roche, Toulouse, France" << endl;
530 cout <<
"Contact: yannick.pencole@laas.fr" << endl;
531 unsigned stateMin = 3;
532 unsigned stateMax = 10;
538 string dirName =
"model_generator_directory";
539 string latexFileName =
"generated_model_report.tex";
540 string topologyFileName =
"";
541 unsigned obsInteractionMin = 0;
542 unsigned obsInteractionMax = 3;
543 unsigned outputDegreeMax = evtMax;
544 string behaviourFileName =
"";
545 bool petrinet =
false;
546 map<string, string> assignedConnections;
547 string fixedNode =
"";
553 while (index < argc) {
555 if (getOption<Option>(argv[index],
options, currentOption)) {
556 if (
isSet[currentOption]) {
559 isSet[currentOption] =
true;
561 switch (currentOption) {
564 if ((index != 1) || (argc != 2)) {
575 getParameter<unsigned>(argc, argv, index, stateMin);
576 log<LgDebug>(
"stateMin = %1%") % stateMin;
585 getParameter<unsigned>(argc, argv, index, stateMax);
586 log<LgDebug>(
"stateMax = %1%") % stateMax;
595 getParameter<unsigned>(argc, argv, index, evtMin);
596 log<LgDebug>(
"evtMin = %1%") % evtMin;
605 getParameter<unsigned>(argc, argv, index, evtMax);
606 log<LgDebug>(
"evtMax = %1%") % evtMax;
615 getParameter<unsigned>(argc, argv, index, obsMin);
616 log<LgDebug>(
"obsMin = %1%") % obsMin;
622 getParameter<unsigned>(argc, argv, index, obsMax);
623 log<LgDebug>(
"obsMax = %1%") % obsMax;
630 getParameter<unsigned>(argc, argv, index, seed);
631 log<LgDebug>(
"seed = %1%") % seed;
637 getParameter<string>(argc, argv, index, dirName);
638 log<LgDebug>(
"dirName = %1%") % dirName;
644 getParameter<string>(argc, argv, index, latexFileName);
645 log<LgDebug>(
"latexFileName = %1%") % latexFileName;
651 getParameter<string>(argc, argv, index, topologyFileName);
652 log<LgDebug>(
"TololgyFileName = %1%") % topologyFileName;
658 getParameter<unsigned>(argc, argv, index, obsInteractionMin);
659 log<LgDebug>(
" obsInteractionMin = %1%") % obsInteractionMin;
665 getParameter<unsigned>(argc, argv, index, obsInteractionMax);
666 log<LgDebug>(
" obsInteractionMax = %1%") % obsInteractionMax;
672 set<string> parameters;
674 if (parameters.empty()) {
675 printCommandLineError(
"--nodeBehaviour expects at least one parameter. Check the command line, merci.");
677 for (set<string>::const_iterator it = parameters.begin();
678 it != parameters.end();
680 string::size_type idx = it->find(
'=');
681 if (idx == string::npos) {
682 printCommandLineError(
"Expecting --nodeBehaviour node=file.des_comp ci=sj, ck=sl..., check your command line. Merci.");
684 assignedConnections[it->substr(0, idx)] = it->substr(idx + 1);
685 log<LgDebug>(
" node behaviour = <%1%,%2%>\n")
687 % it->substr(idx + 1);
695 getParameter<unsigned>(argc, argv, index, outputDegreeMax);
696 log<LgDebug>(
" outputDegreeMax = %1%") % outputDegreeMax;
703 log<LgDebug>(
" petrinet = %1%") % petrinet;
713 string msg =
"Unrecognized option: ";
725 cout <<
"Loading the topology in file " << topologyFileName << flush;
727 topology.
import(topologyFileName);
728 }
catch (exception & e) {
729 cerr << endl <<
"The following exception has been caught:" << endl <<
">>> " << e.what() <<
"<<< " << endl;
730 cerr <<
"The generation is aborted." << endl;
733 cout <<
"Done" << endl;
736 obsInteractionMax = 0;
737 obsInteractionMin = 0;
741 printCommandLineError(
"You attempt to generate a model containing one node but you already fixed this node, so no generation is required.");
743 map<Topology::Connection, string> assignedTopoConnections;
745 set<string> topoElements;
746 set<Topology::Node> topoNodes;
747 set<Topology::Connection> topoConnections;
749 for (
const std::pair<string, string> & p : assignedConnections) {
750 if (topoElements.find(p.first) != topoElements.end()) {
751 string msg =
"The same connection/node '";
753 msg +=
"' appears more than once in the command line. Check the command line, merci.";
756 topoElements.insert(p.first);
759 while (it != topology.
nodeEnd()) {
760 if (topoElements.find(topology.
getNodeName(*it).
str()) != topoElements.end()) {
761 topoNodes.insert(*it);
766 if (topoNodes.size() == 0) {
767 string msg =
"Impossible to find in the given topology a node that corresponds to any of the following names: { ";
768 for (
const string & e : topoElements) {
775 if (topoNodes.size() > 1) {
776 string msg =
"Found more than one corresponding node in the given topology: { ";
777 for (set<Topology::Node>::const_iterator nodeIt = topoNodes.begin();
778 nodeIt != topoNodes.end();
783 msg +=
"}. Check the command line, merci.";
786 fixedTopoNode = *topoNodes.begin();
788 behaviourFileName = assignedConnections[ topology.
getNodeName(fixedTopoNode).
str()];
789 log<LgDebug>(
" found topology node = %1% assigned to model in file %2%.\n")
792 assignedConnections.erase(topology.
getNodeName(fixedTopoNode).
str());
801 if (!topoElements.empty()) {
802 string msg =
"Unrecognized connection/nodes: {";
803 for (
const string & s : topoElements) {
807 msg +=
"}. Check the command line. Merci.";
810 set<Topology::Connection> wrongConnections;
813 bool foundNode =
false;
814 while (!foundNode && (nodeIt != topology.
cliqueEnd(connection))) {
815 foundNode = (*nodeIt) == fixedTopoNode;
819 wrongConnections.insert(connection);
822 if (!wrongConnections.empty()) {
823 string msg =
"The following connections are not connected to the node '";
833 if (stateMin > stateMax) {
836 if (evtMin > evtMax) {
839 if (obsMin > obsMax) {
842 if (obsMin > evtMax) {
845 if (obsMax > evtMax) {
848 if (obsInteractionMax > obsMax) {
851 if (obsInteractionMin > obsMin) {
854 if (obsInteractionMin > obsInteractionMax) {
859 stream <<
"evtMin (" << evtMin
860 <<
") is too important as the maximal number of events that are possible is stateMax * outputDegreeMax (" 861 << stateMax * outputDegreeMax <<
").";
869 verbose<VbOutput>(
"Initialisation of the random generator with the seed %1%.\n") % seed;
874 if (
isSet[NODEBEHAVIOUR]) {
875 map<Event, Event> translation;
878 componentOfNode[fixedTopoNode]->import(behaviourFileName);
879 componentOfNode[fixedTopoNode]->setId(fixedTopoNode.id());
880 componentOfNode[fixedTopoNode]->setName(topology.
getNodeName(fixedTopoNode).
str());
882 list<Event> oldEvents;
883 oldEvents.insert(oldEvents.end(), componentOfNode[fixedTopoNode]->eventBegin(),
884 componentOfNode[fixedTopoNode]->eventEnd());
888 while (!oldEvents.empty()) {
890 oldEvents.pop_front();
891 Event newEvent = EventFactory::factory()->
getEvent(componentOfNode[fixedTopoNode]->name() +
"." + current.
nickname());
893 componentOfNode[fixedTopoNode]->replaceEvent(current, newEvent);
894 translation[newEvent] =
current;
896 newMask.
addMask(newEvent, newEvent);
898 newMask.
addMask(newEvent, newEvent);
901 componentOfNode[fixedTopoNode]->setMask(newMask);
902 }
catch (exception & e) {
903 string msg =
"des_generate caught the following exception when attempting to load the model file" 904 + behaviourFileName +
":\n" + e.what();
908 set<Event> usedEvents;
909 for (
const pair<Topology::Connection, string> & p : assignedTopoConnections) {
911 bool foundEvent =
false;
912 ObservableComponent::EventIterator eventIt = componentOfNode[fixedTopoNode]->eventBegin();
913 while ((!foundEvent) && (eventIt != componentOfNode[fixedTopoNode]->eventEnd())) {
914 foundEvent = (translation[*eventIt].label() == p.second) || (eventIt->nickname() == p.second);
920 string msg =
"The event ";
922 msg +=
" is not contained in the model ";
923 msg += behaviourFileName;
926 if (foundEvent && (usedEvents.find(*eventIt) != usedEvents.end())) {
927 string msg =
"The event ";
929 msg +=
" cannot implement two different connections.";
932 bool foundNode =
false;
934 while (!foundNode && (cliqueIt != topology.
cliqueEnd(p.first))) {
935 foundNode = fixedTopoNode == *cliqueIt;
940 string msg =
"The connection ";
942 msg +=
" does not involve the component ";
950 usedEvents.insert(*eventIt);
952 "Main: invalid event in sharedEventOfNode");
953 sharedEventOfNode[fixedTopoNode][p.first] = *eventIt;
957 unsigned numberOfPendingConnections = topology.
connectivity(fixedTopoNode) - assignedTopoConnections.size();
959 if (numberOfPendingConnections > 0) {
960 vector<Event> unusedEvents;
961 for (ObservableComponent::EventIterator eventIt = componentOfNode[fixedTopoNode]->eventBegin();
962 eventIt != componentOfNode[fixedTopoNode]->eventEnd();
964 if (usedEvents.find(*eventIt) == usedEvents.end()) {
965 unusedEvents.push_back(*eventIt);
969 set<unsigned> selectedIndexes;
970 selectNValues(0, unusedEvents.size() - 1, numberOfPendingConnections, selectedIndexes);
977 if (!sharedEventOfNode[fixedTopoNode][*connIt].isValid()) {
978 if (selectedIndexes.empty()) {
979 throw (
FunctionException(
"main",
"BUG in the selection of shared events for the fixed node."));
983 "Main: invalid event in sharedEventOfNode");
984 sharedEventOfNode[fixedTopoNode][*connIt] = unusedEvents[*selectedIndexes.begin()];
985 selectedIndexes.erase(selectedIndexes.begin());
998 string param =
"mkdir -p " + dirName;
999 system(param.c_str());
1000 string topoFileNameDest = dirName +
"/" +
"topology.topo";
1001 topology.
save(topoFileNameDest);
1007 if (!
isSet[NODEBEHAVIOUR] || (*nodeIt != fixedTopoNode)) {
1009 componentOfNode[*nodeIt]->setId(nodeIt->id());
1010 componentOfNode[*nodeIt]->setName(topology.
getNodeName(*nodeIt).
str());
1018 string rulesFileNameDest = dirName +
"/" +
"sync.rules";
1019 ofstream file(rulesFileNameDest.c_str());
1020 file <<
"components: ";
1027 if (nextNodeIt == topology.
nodeEnd()) {
1028 file <<
";" << endl;
1033 file <<
"rules:" << endl;
1039 cliqueIt != topology.
cliqueEnd(*connIt);
1041 file << sharedEventOfNode[*cliqueIt][*connIt];
1044 if (nextCliqueIt == topology.
cliqueEnd(*connIt)) {
1045 file <<
">;" << endl;
1054 verbose<VbWarning>(
"It seems that the current topology is empty. No generation then...Au revoir.\n");
1058 generateBehaviour(topology, stateMin, stateMax, evtMin, evtMax, obsMin, obsMax, obsInteractionMin, obsInteractionMax,
1059 componentOfNode, sharedEventOfNode, dirName, fixedTopoNode, outputDegreeMax);
1060 }
catch (exception & e) {
1061 stringstream stream;
1062 stream <<
"des_generate caught an exception when calling generateBehaviour():\n";
1063 stream <<
"\t here are the parameters of des_generate:" << endl;
1064 stream <<
"\t\tstateMin = " << stateMin << endl;
1065 stream <<
"\t\tstateMax = " << stateMax << endl;
1066 stream <<
"\t\tobsMin = " << obsMin << endl;
1067 stream <<
"\t\tobsMax = " << obsMax << endl;
1069 stream <<
"\t\tevtMin = " << evtMin << endl;
1070 stream <<
"\t\tevtMax = " << evtMax << endl;
1071 stream <<
"\t\tseed = " << seed << endl;
1072 stream <<
"\t\tdirName = " << dirName << endl;
1073 stream <<
"\t\tlatexFileName = " << latexFileName << endl;
1074 stream <<
"\t\ttopologyFileName = " << topologyFileName << endl;
1076 stream <<
"\t\tobsInteractionMin = " << obsInteractionMin << endl;
1077 stream <<
"\t\tobsInteractionMax = " << obsInteractionMax << endl;
1078 stream <<
"\t\toutputDegreeMax = " << outputDegreeMax << endl;
1079 stream <<
"\t\tbehaviourFileName= " << behaviourFileName << endl;
1080 stream <<
"\t\tfixedNode= " << fixedNode << endl;
1081 stream <<
"Here is the exception: " << endl;
1083 cerr << stream.str() << endl;
1084 cerr <<
"LOGS: " << endl;
1092 string latexFileNameDest = dirName +
"/" + latexFileName;
1094 evtMax, obsMin, obsMax, obsInteractionMin, obsInteractionMax, seed, outputDegreeMax, fixedNode, behaviourFileName, assignedConnections, componentOfNode, sharedEventOfNode, latexFileNameDest);
1097 string mapTopoFileNameDest = dirName +
"/" +
"topology.maptopo";
1098 exportTopologyMap(topology, sharedEventOfNode, componentOfNode, mapTopoFileNameDest);
1101 cout <<
"Not implemented yet" << endl;
1127 ofstream logfile(
"lastlog.output");
1130 verbose<VbOutput>(
"Model successfully generated...\n");
1131 return EXIT_SUCCESS;
1151 unsigned connectivityMax = 0;
1152 unsigned connectivityMin = 0;
1156 if (connectivityMin == 0) {
1167 log<LgOutput>(
"evtMax=%1% and max(connectivity)=%2%")
1168 % evtMax % connectivityMax;
1169 if (evtMax < connectivityMax) {
1170 log<LgOutput>(
"evtMax is smaller than the maximal connectivity of this topology");
1172 log<LgOutput>(
"nbObsIntMin=%1% and min(connectivity)=%2%")
1173 % nbObsIntMin % connectivityMin;
1175 if (nbObsIntMin > connectivityMin) {
1176 log<LgOutput>(
"nbObsIntMin is strictly greater than the minimal connectivity of this topology");
1178 return (evtMax >= connectivityMax) && (nbObsIntMin <= connectivityMin);
1198 if (!fixedTopoNode.valid() || (fixedTopoNode != *nodeIt)) {
1202 stringstream stream;
1204 Event evt = EventFactory::factory()->
getEvent(stream.str());
1205 stringstream nickname;
1209 "generateSharedEvents: invalid event in sharedEventOfNode");
1210 sharedEventOfNode[*nodeIt][*connIt] = evt;
1211 componentOfNode[*nodeIt]->insertEvent(evt);
1228 "generateSharedEvents: invalid event in sharedEventOfNode");
1289 unsigned obsInteractionMin,
1290 unsigned obsInteractionMax,
1295 unsigned outputDegreeMax) {
1296 list<Topology::Node> nodesToVisit;
1303 if (fixedTopoNode.
valid()) {
1305 initialNode = fixedTopoNode;
1306 visitedNodes[initialNode] = 2;
1314 set<Topology::Node> generatedNeighbours;
1315 set<Topology::Node> nonGeneratedNeighbours;
1319 generatedNeighbours,
1320 nonGeneratedNeighbours,
1329 *componentOfNode[initialNode],
1330 nonGeneratedNeighbours,
1331 projection[initialNode]);
1337 nodesToVisit.push_back(initialNode);
1338 visitedNodes[initialNode] = 1;
1342 while (!nodesToVisit.empty()) {
1343 Node node = nodesToVisit.front();
1345 nodesToVisit.pop_front();
1348 set<Topology::Node> generatedNeighbours;
1349 set<Topology::Node> nonGeneratedNeighbours;
1353 generatedNeighbours,
1354 nonGeneratedNeighbours,
1359 if (generatedNeighbours.empty() && (node != initialNode)) {
1360 throw (
FunctionException(
"generateBehaviour",
"the current node has no interaction with generated neighbours. BUG.\n"));
1367 generatedNeighbours.begin(),
1368 generatedNeighbours.end());
1370 if ((node != initialNode) && (interaction->numberOfTransitions() < generatedNeighbours.size())) {
1373 throw (
FunctionException(
"generateBehaviour",
"the interactions with generated neighbours are incorrect. BUG\n"));
1380 generatedNeighbours.begin(),
1381 generatedNeighbours.end(),
1391 componentOfNode[node]);
1396 if (!nonGeneratedNeighbours.empty()) {
1400 nonGeneratedNeighbours,
1404 visitedNodes[node] = 2;
1408 }
catch (exception & e) {
1409 if (interaction != 0) {
1416 if (projection[*nodeIt].second != 0) {
1417 delete projection[*nodeIt].second;
1443 const set<Node> & nonGeneratedNeighbours,
1444 pair<string, ObservableComponent *> & result) {
1446 stringstream streamP;
1448 for (set<Node>::const_iterator outIt = nonGeneratedNeighbours.begin();
1449 outIt != nonGeneratedNeighbours.end(); ++outIt) {
1452 streamP <<
"}(" << topology.
getNodeName(node) <<
")";
1453 result.first = streamP.
str();
1455 set<Event> projectedEvents;
1461 while (!found && (it2 != topology.
cliqueEnd(*it))) {
1462 found = (*it2 != node) && (nonGeneratedNeighbours.find(*it2) != nonGeneratedNeighbours.end());
1467 "getOutputProjection: invalid shared event found in sharedEventOfNode");
1468 projectedEvents.insert(sharedEventOfNode[node][*it]);
1472 result.second->project(&component, projectedEvents);
1473 }
catch (exception & e) {
1475 msg <<
"caught an exception." << endl;
1476 msg <<
"getOutputProjection called with the following parameters:" << endl;
1477 msg <<
"\t node= " << topology.
getNodeName(node) << endl;
1478 msg <<
"\t non generated nodes= " <<
toStream(nonGeneratedNeighbours.begin(), nonGeneratedNeighbours.end()) << endl;
1479 msg <<
"Here is the caught exception:" << endl;
1480 msg << e.what() << endl;
1483 result.second->setName(result.first);
1485 set<Event> effectiveEvents;
1486 for (ObservableComponent::TransitionIterator trIt = result.second->transitionBegin();
1487 trIt != result.second->transitionEnd(); ++trIt) {
1488 effectiveEvents.insert(result.second->getEvent(*trIt));
1521 set<Node>::const_iterator first,
1522 set<Node>::const_iterator last) {
1527 debug(verbose<VbDebug>(
"getSynchronisedInteraction on node %1%.\n") % topology.
getNodeName(node).
str());
1529 if (first == last) {
1533 vector<const ComposableModel *> composableModels;
1534 bool interactionToBeDestroyed =
false;
1536 vector<const Component *> models;
1537 for (set<Node>::const_iterator it = first; it != last; ++it) {
1538 models.push_back(projection[*it].second);
1540 if (models.size() == 1) {
1541 interaction = projection[*first].second;
1542 interactionToBeDestroyed =
false;
1549 sharedEventOfNode, projection, synchronisation);
1554 for (set<Node>::const_iterator it = first; it != last; ++it) {
1555 composableModels.push_back(
new ComposableModel(*projection[*it].second, synchronisation));
1560 interactionToBeDestroyed =
true;
1562 ComposableModel composedModel(composableModels, synchronisation,
false, interaction);
1563 for (vector<const ComposableModel *>::size_type i = 0; i < composableModels.size(); ++i) {
1564 delete composableModels[i];
1566 composableModels.clear();
1571 set<Event> projectedEvents;
1579 if (find(first, last, *it2) != last) {
1580 projectedEvents.insert(sharedEventOfNode[*it2][*it]);
1584 projectedInteraction->
project(interaction, projectedEvents);
1585 if (interactionToBeDestroyed) {
1588 interactionToBeDestroyed =
false;
1593 throw FunctionException(
"getSynchronisedInteraction",
"The returned interaction is empty, BUG. Be careful it is maybe due to a fundamental problem of the whole generation algorithm. This algorithm is based on a random generator and has not been proved to always work. Sorry for any inconvenience. Try again with another seed and good luck :-) Merci for trying\n");
1595 }
catch (exception & e) {
1596 if (projectedInteraction != 0) {
1597 delete projectedInteraction;
1599 if (interaction != 0 && interactionToBeDestroyed) {
1602 interactionToBeDestroyed =
false;
1604 for (vector<const ComposableModel *>::size_type i = 0; i < composableModels.size(); ++i) {
1605 delete composableModels[i];
1607 composableModels.clear();
1611 return projectedInteraction;
1643 set<Node>::const_iterator first,
1644 set<Node>::const_iterator last,
1651 unsigned obsInteractionMin,
1652 unsigned obsInteractionMax,
1653 unsigned outputDegreeMax,
1655 set<Event> interactiveEvents;
1656 for (ObservableComponent::EventIterator eventIt = result->
eventBegin();
1659 interactiveEvents.insert(*eventIt);
1662 set<Event> nonInteractiveEvents;
1668 nonInteractiveEvents, *result);
1672 unsigned numberOfStates = generateRandomValue(stateMin, stateMax); 1673 always_assertion(FunctionException, numberOfStates <= stateMax, "generateRandomComponent: numberOfStates > stateMax.
"); 1674 always_assertion(FunctionException, numberOfStates >= stateMin, "generateRandomComponent: numberOfStates < stateMin.
"); 1677 // let's generate the transition system of the component 1678 generateTransitionSystem(topology, node, sharedEventOfNode, interaction, first, last, numberOfStates, 1679 outputDegreeMax, *result); 1683 /************************************************************************************************/ 1697 void generateStates(ObservableComponent & result, unsigned numberOfStates, vector<Node> & indexState) { 1699 indexState.resize(numberOfStates); 1700 for (unsigned i = 0; i < numberOfStates; ++i) { 1703 indexState[i] = result.newState(s.str()); 1707 /************************************************************************************************/ 1726 void logDetailsBeforeCallingGenerateTransitionSystem(const Topology & topology, 1728 SharedEventNodeMap & sharedEventOfNode, 1729 const ObservableComponent & interaction, 1730 set<Node>::const_iterator first, 1731 set<Node>::const_iterator last, 1732 unsigned numberOfStates, 1733 unsigned outputDegreeMax, 1734 ObservableComponent & result) { 1736 verbose<VbDebug>("Generation of %1%
states.\n
") % numberOfStates; 1737 verbose<VbDebug>("Shared events involved: \n[
"); 1738 for (map<Topology::Connection, Event>::const_iterator it = sharedEventOfNode[node].begin(); 1739 it != sharedEventOfNode[node].end(); 1742 for (Topology::CliqueIterator cliqueIt = topology.cliqueBegin(it->first); 1743 cliqueIt != topology.cliqueEnd(it->first); 1745 if (*cliqueIt != node) { 1746 string nodeName = topology.getNodeName(*cliqueIt).str(); 1747 nodeNames += nodeName + " "; 1750 verbose<VbDebug>("%1% ( in connection with %2%)\n
") % it->second % nodeNames; 1753 interaction.component2dot("interaction.dot
"); 1757 /************************************************************************************************/ 1772 void initConstrainedConnectionMappings(const Topology & topology, 1774 SharedEventNodeMap & sharedEventOfNode, 1775 set<Node>::const_iterator first, 1776 set<Node>::const_iterator last, 1777 map<Event, Topology::Connection> & mappingInteractionToCurrentSide, 1778 map<Topology::Connection, Event> & mappingConnectionToInteraction, 1779 map<Event, Topology::Connection> & mappingCurrentSideToInteraction, 1780 set<Event>& constrainedEvents) { 1781 for (Topology::NodeConnectionIterator it = topology.nodeConnectionBegin(node); 1782 it != topology.nodeConnectionEnd(node); 1784 for (Topology::CliqueIterator it2 = topology.cliqueBegin(*it); 1785 it2 != topology.cliqueEnd(*it); 1787 if (find(first, last, *it2) != last) { 1788 mappingCurrentSideToInteraction[sharedEventOfNode[node][*it]] = *it; 1789 mappingInteractionToCurrentSide[sharedEventOfNode[*it2][*it]] = *it; 1790 constrainedEvents.insert(sharedEventOfNode[node][*it]); 1794 mappingConnectionToInteraction[*it] = sharedEventOfNode[*it2][*it]; 1801 /************************************************************************************************/ 1827 unsigned getNumberOfTransitions(const Selection<Event> & eventSelection, 1828 const set<Event> & constrainedEvents, 1829 const set<Event> & constrainedTriggerableEvents, 1830 unsigned numberOfAdmissibleEvents, 1831 unsigned numberOfStatesToVisit, 1832 unsigned outputDegreeMax, 1833 bool & mustUseNewEvent) { 1834 always_require(FunctionException, numberOfAdmissibleEvents > 0, "getNumberOfTransitions: there is no admissible event
"); 1835 always_require(FunctionException, outputDegreeMax > 0, "getNumberOfTransitions: outputDegreeMax is null.
"); 1836 unsigned result = 0; 1837 mustUseNewEvent = false; 1838 unsigned numberOfNonInsertedAndTriggerableEvents = 1839 count_if(eventSelection.nonSelectedBegin(), 1840 eventSelection.nonSelectedEnd(), 1841 unaryOr(isNotIn(constrainedEvents.begin(), constrainedEvents.end()), 1842 isIn(constrainedTriggerableEvents.begin(), constrainedTriggerableEvents.end()))); 1844 if (numberOfNonInsertedAndTriggerableEvents != 0) { 1845 double probablilityOfCertainlyUsingSomeNewEventInThisState = 1; 1846 if (numberOfStatesToVisit > 0) { 1847 probablilityOfCertainlyUsingSomeNewEventInThisState = 1848 min((double) 1, ((double) eventSelection.numberOfNonSelectedItems()) / ((double) numberOfStatesToVisit)); 1850 double value = generateRandomDouble(0, 1); 1851 mustUseNewEvent = value <= probablilityOfCertainlyUsingSomeNewEventInThisState; 1854 unsigned minimalNumberOfTrans = 1; 1855 unsigned maximalNumberOfTrans = min(numberOfAdmissibleEvents, outputDegreeMax); 1856 result = generateRandomValue(minimalNumberOfTrans, maximalNumberOfTrans); 1857 ensure(FunctionException, result > 0, "getNumberOfTransitions: null result.
"); 1858 ensure(FunctionException, result <= outputDegreeMax, "getNumberOfTransitions: result greater than outputDegreeMax.
"); 1859 ensure(FunctionException, result <= numberOfAdmissibleEvents, "getNumberOfTransitions: result greater than the number of admissible events
"); 1862 /************************************************************************************************/ 1880 void generateTriggerableEvents(unsigned nbTransitions, 1881 Selection<Event> & eventSelection, 1882 const vector<unsigned> & admissibleEventIndexes, 1883 unsigned numberOfNonPreviouslySelectedButAdmissibleEvents, 1884 bool mustUseNewEvent, 1885 set<Event> & selectedEvents) { 1886 always_require(FunctionException, (!mustUseNewEvent) || (numberOfNonPreviouslySelectedButAdmissibleEvents != 0), 1887 "generateTriggerableEvents: BUG the parameters mustUseNewEvent and numberOfNonPreviouslySelectedButAdmissibleEvents are incompatible.
"); 1888 always_require(FunctionException, nbTransitions > 0, "generateTriggerableEvents: BUG nbTransitions is null
"); 1889 always_require(FunctionException, eventSelection.numberOfItems() >= admissibleEventIndexes.size(), 1891 always_require(FunctionException, numberOfNonPreviouslySelectedButAdmissibleEvents <= admissibleEventIndexes.size(), 1892 "generateTriggerableEvents: BUG there are more unselected admissible events than admissible events.
"); 1893 always_require(FunctionException, numberOfNonPreviouslySelectedButAdmissibleEvents <= eventSelection.numberOfNonSelectedItems(), 1894 "generateTriggerableEvents: BUG there are more unselected admissible events than unselected events.
"); 1895 // in order to be as random as possible, first we try to get directly nbTransitions 1896 // from the admissibleEventIndexes independently from the fact a new event 1897 // must be selected or not. 1898 set<unsigned> randomResult; 1900 selectNValues(0, admissibleEventIndexes.size() - 1, nbTransitions, randomResult); 1901 } catch (exception & e) { 1902 stringstream stream; 1904 << "\n eventSelection.numberOfItems() =
" << eventSelection.numberOfItems() 1905 << "\n admissibleEventIndexes.size() =
" << admissibleEventIndexes.size() 1906 << "\n numberOfNonPreviouslySelectedButAdmissibleEvents =
" << numberOfNonPreviouslySelectedButAdmissibleEvents 1907 << "\n mustUseNewEvent =
" << mustUseNewEvent 1908 << "selectedEvents.size() =
" << selectedEvents.size() 1910 throw (FunctionException(stream.str(), e.what())); 1912 // now we check the first index, if it is greater than numberOfNonPreviouslySelectedButAdmissibleEvents 1913 // we know that the selection does not contain any new event 1914 if ((mustUseNewEvent) && (*(randomResult.begin()) >= numberOfNonPreviouslySelectedButAdmissibleEvents)) { 1915 // bad luck, let us force a bit the destiny 1916 // selection of an event never selected. 1917 unsigned selectionIndex = generateRandomValue(0, numberOfNonPreviouslySelectedButAdmissibleEvents); 1918 randomResult.erase(randomResult.begin()); 1919 randomResult.insert(selectionIndex); 1922 // now randomResult context the index of events included in eventSelection 1923 // some have never been selected, it is time to notice this fact. 1924 for (const unsigned & index : randomResult) { 1925 selectedEvents.insert(eventSelection.getItem(admissibleEventIndexes[index])); 1926 if (!eventSelection.hasBeenAlreadySelectedOnce(admissibleEventIndexes[index])) { 1927 eventSelection.select(admissibleEventIndexes[index]); 1931 always_ensure(FunctionException, selectedEvents.size() == nbTransitions, 1938 /************************************************************************************************/ 1956 void getSelectedEvents(const ObservableComponent & interaction, 1957 State currentInteractingState, 1958 map<Event, Topology::Connection> & mappingInteractionToCurrentSide, 1959 map<Event, Topology::Connection> & mappingCurrentSideToInteraction, 1960 map<Topology::Connection, Event> & mappingConnectionToInteraction, 1961 Selection<Event> & eventSelection, 1962 const set<Event> & constrainedEvents, 1963 const set<Topology::Connection> & constrainedConnections, 1964 unsigned numberOfVisitedStates, 1965 ObservableComponent & result, 1966 unsigned outputDegreeMax, 1967 set<Event> & selectedEvents) { 1968 set<Event> constrainedTriggerableEvents; 1969 for (const Event & e : constrainedEvents) { 1970 if (constrainedConnections.find(mappingCurrentSideToInteraction[e]) 1971 != constrainedConnections.end()) { 1972 // ok event e is involved with a constrainedConnection 1973 // let us see whether the associated event can be triggered by 1974 // currentInteractingState 1975 Event associatedEvent = mappingConnectionToInteraction[mappingCurrentSideToInteraction[e]]; 1976 if (interaction.outputEventTransitionBegin(currentInteractingState, 1978 != interaction.outputEventTransitionEnd(currentInteractingState, 1982 constrainedTriggerableEvents.insert(e); 1989 vector<unsigned> admissibleEventIndexes; 1990 always_require(FunctionException, result.numberOfEvents() > 0, 1993 always_require(FunctionException, eventSelection.numberOfItems() > 0, 1994 "getSelectedEvents: there is no
event of the component in the eventSelection
object.
"); 1997 always_require(FunctionException, eventSelection.numberOfItems() == result.numberOfEvents(), 1998 "getSelectedEvents: eventSelection.numberOfItems() != result.
numberOfEvents().
"); 2000 admissibleEventIndexes.reserve(result.numberOfEvents()); 2002 // an event is admissible iff it is not a constrained event or, if it is, 2003 // its corresponding event in the interaction model can be triggered 2004 // in the state currentInteractingState 2005 // In order to be more efficient when generating the selection of events, 2006 // we explore first the events that are still not in the model and then the one that 2007 // are in the model already. 2009 for (Selection<Event>::IndexIterator indexIt = eventSelection.nonSelectedIndexBegin(); 2010 indexIt != eventSelection.nonSelectedIndexEnd(); 2013 if (constrainedEvents.find(eventSelection.getItem(*indexIt)) == constrainedEvents.end()) { 2014 admissibleEventIndexes.push_back(*indexIt); 2016 if (constrainedTriggerableEvents.find(eventSelection.getItem(*indexIt)) != constrainedTriggerableEvents.end()) { 2017 admissibleEventIndexes.push_back(*indexIt); 2022 unsigned numberOfNonPreviouslySelectedButAdmissibleEvents = admissibleEventIndexes.size(); 2023 for (Selection<Event>::IndexIterator indexIt = eventSelection.selectedIndexBegin(); 2024 indexIt != eventSelection.selectedIndexEnd(); 2027 if (constrainedEvents.find(eventSelection.getItem(*indexIt)) == constrainedEvents.end()) { 2028 admissibleEventIndexes.push_back(*indexIt); 2030 if (constrainedTriggerableEvents.find(eventSelection.getItem(*indexIt)) != constrainedTriggerableEvents.end()) { 2031 admissibleEventIndexes.push_back(*indexIt); 2036 // Generation of the number of output transitions for the current state. 2037 // From a state, the behaviour is deterministic so the number of transitions 2038 // is at most the number of admissible events. Since the state of the component 2039 // is live, I also suppose that there exists at least one transition 2040 // but I also need to take care about the fact that every event is at least used 2041 // once in the model. 2043 bool mustUseNewEvent = false; 2044 unsigned nbTransitions = getNumberOfTransitions(eventSelection, 2046 constrainedTriggerableEvents, 2047 admissibleEventIndexes.size(), 2048 result.numberOfStates() - numberOfVisitedStates, 2049 outputDegreeMax, mustUseNewEvent); 2051 generateTriggerableEvents(nbTransitions, 2053 admissibleEventIndexes, 2054 numberOfNonPreviouslySelectedButAdmissibleEvents, 2059 always_ensure(FunctionException, !selectedEvents.empty(), 2060 "getSelectedEvents: the returned
set of events is empty. BUG.
"); 2064 /************************************************************************************************/ 2092 void generateTransitionSystem(const Topology & topology, 2094 SharedEventNodeMap & sharedEventOfNode, 2095 const ObservableComponent & interaction, 2096 set<Node>::const_iterator first, 2097 set<Node>::const_iterator last, 2098 unsigned numberOfStates, 2099 unsigned outputDegreeMax, 2100 ObservableComponent & result) { 2101 debug(logDetailsBeforeCallingGenerateTransitionSystem(topology, node, 2112 vector<State> indexedState; // at each index, there is a state 2113 generateStates(result, numberOfStates, indexedState); 2114 Selection<State> stateSelection(indexedState); 2116 // the component is deterministic but not minimal 2117 // I also need to take care about the fact that every event is at least used 2118 // once in the model and every transition in interaction must be triggered once. 2119 // Moreover no transition with a code shared with interaction is independent from 2122 // here are the connections that are contrained by interaction 2123 map<Event, Topology::Connection> mappingInteractionToCurrentSide; 2124 map<Topology::Connection, Event> mappingConnectionToInteraction; 2125 map<Event, Topology::Connection> mappingCurrentSideToInteraction; 2126 set<Event> constrainedEvents; 2127 initConstrainedConnectionMappings(topology, node, sharedEventOfNode, first, 2128 last, mappingInteractionToCurrentSide, 2129 mappingConnectionToInteraction, 2130 mappingCurrentSideToInteraction, 2134 // will state whether a transition of the interaction model 2135 // is taken into account into the generated model 2136 // (must be true for every transition in the end) 2137 Graph behaviour = interaction.behaviour(); 2138 EdgeMap<int> triggeredTransition(behaviour); 2140 // contains a mapping between the state of the generated model 2141 // and some corresponding states in the interaction model. 2142 // structure mainly used to complete the model in the end 2143 NodeMap< set<State> > stateMapping(result.behaviour()); 2146 // for guaranteeing that any event type will be used at least once. 2147 vector<Event> events; 2148 events.reserve(result.numberOfEvents()); 2149 copy(result.eventBegin(), result.eventEnd(), inserter(events, events.end())); 2150 Selection<Event> eventSelection(events); 2153 // common structures for visiting the state of the generated model 2154 // in parallel with the interaction model 2155 // here we suppose that the transition system has one initial state only 2156 list<State> stateToVisit; // BFS from the initial state 2157 list<State> interactingStateToVisit; // parallel exploration of the interactive model 2158 NodeMap<bool> inThePool(result.behaviour(), false); 2159 unsigned numberOfVisitedStates = 0; 2161 // let us start with the first state of indexState. It will 2162 // be the initial state of the component 2163 unsigned selectedIndex = stateSelection.newSelection(); 2164 result.setInitial(indexedState[selectedIndex]); 2165 stateToVisit.push_back(indexedState[selectedIndex]); 2166 inThePool[indexedState[selectedIndex]] = true; 2167 stateMapping[indexedState[selectedIndex]].insert(*interaction.initialStateBegin()); 2168 interactingStateToVisit.push_back(*interaction.initialStateBegin()); 2170 // if outputDegreeMax is not set, let make it maximal 2171 if (!isSet[OUTPUTDEGREEMAX]) { 2172 outputDegreeMax = result.numberOfEvents(); 2175 // if outputDegreeMax is set but greater than the number of events 2176 // set it it to this number of events 2177 if (isSet[OUTPUTDEGREEMAX] && (outputDegreeMax > result.numberOfEvents())) { 2178 outputDegreeMax = result.numberOfEvents(); 2182 // start the transition generation 2183 while (!stateToVisit.empty()) { 2184 // current state in the model under construction 2185 State currentState = stateToVisit.front(); 2186 stateToVisit.pop_front(); 2188 // current state in the interaction model 2189 State currentInteractingState = interactingStateToVisit.front(); 2190 interactingStateToVisit.pop_front(); 2192 set<Topology::Connection> constrainedConnections; 2193 for (ObservableComponent::OutputTransitionIterator it = interaction.outputTransitionBegin(currentInteractingState); 2194 it != interaction.outputTransitionEnd(currentInteractingState); 2196 constrainedConnections.insert(mappingInteractionToCurrentSide[interaction.getEvent(*it)]); 2201 set<Event> selectedEvents; 2203 getSelectedEvents(interaction, currentInteractingState, 2204 mappingInteractionToCurrentSide, 2205 mappingCurrentSideToInteraction, 2206 mappingConnectionToInteraction, 2209 constrainedConnections, 2210 numberOfVisitedStates, 2215 // before creating transitions I check whether there are still unreached states. 2216 // If there are, I select one as a target of a transition with the current 2217 // state. It is a way to be sure that every state is at least reachable from 2218 // the initial state by at least one transition since the current state is 2219 // reachable from the initial state. 2220 State unreachedState; 2221 int numberOfIterationsBefore = 0; 2222 if (!stateSelection.allSelected()) { 2223 unreachedState = indexedState[stateSelection.newSelection()]; 2224 numberOfIterationsBefore = generateRandomValue(0, selectedEvents.size() - 1); 2228 // generation of the target states and the transitions 2231 set<Event>::const_iterator eventIt = selectedEvents.begin(); 2232 for (unsigned i = 0; i < selectedEvents.size(); ++i) { 2234 if ((unreachedState.valid()) && 2235 (counter == numberOfIterationsBefore)) { 2236 // here this is the case where the transition is created 2237 // to a reach a unreached state as we selected before 2238 nextState = unreachedState; 2240 // here, this is the normal case, we choose the target state randomly 2241 // (between the reached and unreached ones) 2242 unsigned targetId = 0; 2243 targetId = generateRandomValue(0, numberOfStates - 1); 2244 // is the selected target state reached or not ? 2245 if (!stateSelection.hasBeenAlreadySelectedOnce(targetId)) { 2246 // no it was a unreached state, make it reached now 2247 stateSelection.select(targetId); 2249 nextState = indexedState[targetId]; 2252 result.newTransition(currentState, nextState, *eventIt); 2254 // it is possible that this state has been already inserted as a reached state 2255 // in a previous iteration of this loop, in this case nothing to be done 2256 if (!inThePool[nextState]) { 2257 stateToVisit.push_back(nextState); 2258 inThePool[nextState] = true; 2260 Transition correspondingInteractionTransition = 2261 getTransitionFromInteractiveCurrentState(interaction, currentInteractingState, 2263 mappingCurrentSideToInteraction, 2264 mappingConnectionToInteraction, 2266 if (correspondingInteractionTransition.valid()) { 2267 // the interaction state is changing 2268 interactingStateToVisit.push_back(correspondingInteractionTransition.target()); 2269 triggeredTransition[correspondingInteractionTransition] = 1; 2270 stateMapping[nextState].insert(correspondingInteractionTransition.target()); 2272 // the interaction state is not changing 2273 interactingStateToVisit.push_back(currentInteractingState); 2274 stateMapping[nextState].insert(currentInteractingState); 2280 ++numberOfVisitedStates; 2282 // end of the transition generation 2286 // Now we may have a problem. Some transitions from the interaction model may not be taken into account 2287 // we have to complete the generated model to make it fully consistent with the interaction model 2288 makeComponentFullyConsistent(result, node, sharedEventOfNode, interaction, mappingInteractionToCurrentSide, 2289 mappingCurrentSideToInteraction, triggeredTransition, stateMapping, outputDegreeMax, eventSelection); 2291 // And finally, in the worst case some events during the generation of the component did not occur 2292 makeComponentComplete(outputDegreeMax, eventSelection, result); 2295 /************************************************************************************************/ 2327 void makeComponentFullyConsistent(ObservableComponent & result, 2329 SharedEventNodeMap & sharedEventOfNode, 2330 const ObservableComponent & interaction, 2331 map<Event, Topology::Connection> & mappingInteractionToCurrentSide, 2332 map<Event, Topology::Connection> & mappingCurrentSideToInteraction, 2333 EdgeMap<int> & triggeredTransition, 2334 NodeMap< set<State> > & stateMapping, 2335 unsigned outputDegreeMax, 2336 Selection<Event> & eventSelection) { 2338 list<Transition> unmatchedTransitions; 2339 for (ObservableComponent::TransitionIterator it = interaction.transitionBegin(); 2340 it != interaction.transitionEnd(); 2343 if (triggeredTransition[*it] == 0) { 2344 unmatchedTransitions.push_back(*it); 2348 while (!unmatchedTransitions.empty()) { 2350 Transition currentTrans = unmatchedTransitions.front(); 2351 unmatchedTransitions.pop_front(); 2353 // looking for a source/target states: 2354 list<State> potentialSourceStates; 2355 State possibleSource; 2356 State possibleTarget; 2358 ObservableComponent::StateIterator stateIt = result.stateBegin(); 2359 while (!stop && (stateIt != result.stateEnd())) { 2360 if (stateMapping[*stateIt].find(currentTrans.source()) != stateMapping[*stateIt].end()) { 2361 potentialSourceStates.push_back(*stateIt); 2362 // looking whether there is a possible target state for this source 2363 Diades::Graph::OutEdgeIterator outTransIt = stateIt->outEdgeBegin(); 2365 while (!found && (outTransIt != stateIt->outEdgeEnd())) { 2367 found = mappingCurrentSideToInteraction[result.getEvent(*outTransIt)] == 2368 mappingInteractionToCurrentSide[interaction.getEvent(currentTrans)]; 2370 possibleTarget = outTransIt->target(); 2376 possibleSource = potentialSourceStates.back(); 2382 // we found a transition in the model that matches currentEdge 2383 triggeredTransition[currentTrans] = 1; 2384 if (stateMapping[possibleTarget].find(currentTrans.target()) == stateMapping[possibleTarget].end()) { 2385 stateMapping[possibleTarget].insert(currentTrans.target()); 2386 propagateInteractingStates(result, 2389 mappingInteractionToCurrentSide, 2390 interaction, possibleTarget, 2391 currentTrans.target(), 2395 // we haven't found a transition we need to create a new one 2396 if (potentialSourceStates.empty()) { 2397 // we cannot do anything at this stage so we must push the current transition back to the 2398 // list and wait that a source state will appear (it will!). 2399 unmatchedTransitions.push_back(currentTrans); 2401 // we are lucky, we found some sources 2402 // I just select one of them randomly and then I select a target state randomly. 2403 // Since the generation is already very randomized, I just consider a deterministic 2404 // procedure for the rest. It can be randomized. The code would be longer and a bit 2407 // but first we need to eliminate the source that already have the maximal output degree 2408 list<State> potentialSourceStatesWithCompatibleOutDeg; 2409 for (const State & s : potentialSourceStates) { 2410 if (s.outDeg() < outputDegreeMax) { 2411 potentialSourceStatesWithCompatibleOutDeg.push_back(s); 2415 unsigned counter = 0; 2416 if (potentialSourceStatesWithCompatibleOutDeg.empty()) { 2417 // we are in big trouble, unsolvable problem now I emit a warning 2418 cout << "WARNING: the outputDegreeMax option cannot be respected in the component
" << result.name() << ", the problem looks unsolvable to me. Te constraint is violated to
ensure that the model is consistent with its neighbourhood
" << endl; 2419 unsigned indexSource = generateRandomValue(0, potentialSourceStates.size() - 1); 2420 list<State>::const_iterator sourceIt = potentialSourceStates.begin(); 2421 while (counter != indexSource) { 2427 unsigned indexSource = generateRandomValue(0, potentialSourceStatesWithCompatibleOutDeg.size() - 1); 2428 list<State>::const_iterator sourceIt = potentialSourceStatesWithCompatibleOutDeg.begin(); 2429 while (counter != indexSource) { 2435 unsigned indexTarget = generateRandomValue(0, result.numberOfStates() - 1); 2437 ObservableComponent::StateIterator targetIt = result.stateBegin(); 2438 while (counter != indexTarget) { 2442 State target = *targetIt; 2443 Event eventToUse = sharedEventOfNode[node][mappingInteractionToCurrentSide[interaction.getEvent(currentTrans)]]; 2446 result.newTransition(source, target, eventToUse); 2450 while (eventToUse != eventSelection.getItem(i)) { 2452 always_assertion(FunctionException, i < eventSelection.numberOfItems(), 2453 "completeObservableCom ponent: use of an
event that is not recorded in the
event selection. BUG.
"); 2456 if (!eventSelection.hasBeenAlreadySelectedOnce(i)) { 2457 eventSelection.select(i); 2459 triggeredTransition[currentTrans] = 1; 2460 stateMapping[target].insert(currentTrans.target()); 2461 propagateInteractingStates(result, 2464 mappingInteractionToCurrentSide, 2467 currentTrans.target(), 2492 void propagateInteractingStates(ObservableComponent & result, const Node & node, 2493 SharedEventNodeMap & sharedEventOfNode, 2494 map<Event, Topology::Connection> & mappingInteractionToCurrentSide, 2495 const ObservableComponent & interaction, 2497 State correspondingState, 2498 NodeMap< set<State> > & stateMapping) { 2500 list< pair<State, State> > stack; 2501 stack.push_back(make_pair(state, correspondingState)); 2503 while (!stack.empty()) { 2505 State currentState = stack.back().first; 2506 State currentCorrespondingState = stack.back().second; 2507 Diades::Graph::OutEdgeIterator outTransIt = currentCorrespondingState.outEdgeBegin(); 2509 while ((!stop) && (outTransIt != currentCorrespondingState.outEdgeEnd())) { 2511 Event currentEvent = interaction.getEvent(*outTransIt); 2512 Event eventResultSide = sharedEventOfNode[node][mappingInteractionToCurrentSide[currentEvent]]; 2513 Diades::Graph::OutEdgeIterator outTransIt2 = currentState.outEdgeBegin(); 2516 while ((!found) && (outTransIt2 != currentState.outEdgeEnd())) { 2518 found = result.getEvent(*outTransIt2) == eventResultSide; 2520 targetState = outTransIt2->target(); 2526 if (stateMapping[targetState].find(outTransIt->target()) == stateMapping[targetState].end()) { 2527 stateMapping[targetState].insert(outTransIt->target()); 2528 stack.push_back(make_pair(targetState, outTransIt->target())); 2535 // all the successors of the (currentState,currentCorrespondingState) are correctly tagged 2544 /***********************************************************************************************/ 2562 void generateLatexFile(const Topology & topology, 2569 unsigned obsInteractionMin, 2570 unsigned obsInteractionMax, 2572 unsigned outputDegreeMax, 2573 const string & fixedNode, 2574 const string & behaviourFileName, 2575 map<string, string> & assignedConnections, 2576 const ComponentNodeMap & componentOfNode, 2577 SharedEventNodeMap & sharedEventOfNode, 2578 const string & filename) { 2580 latexfile.open(filename.c_str()); 2581 generateLatexPreamble(topology, 2589 obsInteractionMax, seed, outputDegreeMax, fixedNode, behaviourFileName, assignedConnections, 2594 generateLatexTopology(topology, sharedEventOfNode, latexfile); 2595 generateLatexComponents(topology, sharedEventOfNode, componentOfNode, latexfile); 2596 generateLatexEventIndex(topology, sharedEventOfNode, componentOfNode, latexfile); 2597 generateLatexEpilog(latexfile); 2601 /*****************************************************************************************/ 2620 void generateLatexPreamble(const Topology & topology, 2627 unsigned obsInteractionMin, 2628 unsigned obsInteractionMax, 2630 unsigned outputDegreeMax, 2631 const string & fixedNode, 2632 const string & behaviourFileName, 2633 map<string, string> & assignedConnections, 2634 const ComponentNodeMap & componentOfNode, 2635 SharedEventNodeMap & sharedEventOfNode, 2636 const string & filename, 2637 ofstream & latexfile) { 2639 latexfile << "\\documentclass[11pt]{article}
" << endl; 2640 latexfile << "\\usepackage{array}
" << endl; 2641 latexfile << "\\textwidth 17cm \\textheight 26cm \\voffset -3cm \\hoffset -1.6cm
" << endl; 2642 latexfile << "\\title{Generated discrete-
event model}
" << endl; 2645 latexfile << "\\date{
" << ctime(&rawtime) << "}
" << endl; 2646 latexfile << "\\begin{document}
" << endl; 2647 latexfile << "\\maketitle
" << endl; 2648 latexfile << "\\section{Introduction}
" << endl; 2649 latexfile << "This model has been generated with the following parameters of {\\tt des\\_generate}.
" << endl; 2650 latexfile << "\\begin{center}
" << endl; 2651 latexfile << "{\\small
" << endl; 2652 latexfile << "\\begin{tabular}{|c|c|c|}
" << endl; 2653 latexfile << "\\hline
" << endl; 2654 latexfile << "Random generator seed & {\\tt --seed} &
" << seed << " \\\\
" << endl; 2655 latexfile << "\\hline
" << endl; 2656 latexfile << "Number of components & {\\tt --topology} &
" << topology.numberOfNodes() << " \\\\
" << endl; 2657 latexfile << "\\hline
" << endl; 2658 latexfile << "Minimal number of observable per component & {\\tt --obsMin} &
" << obsMin << " \\\\
" << endl; 2659 latexfile << "\\hline
" << endl; 2660 latexfile << "Maximal number of observable events per component & {\\tt --obsMax} &
" << obsMax << " \\\\
" << endl; 2661 latexfile << "\\hline
" << endl; 2662 latexfile << "Minimal number of non-interactive events per component & {\\tt --evtMin} &
" << evtMin << " \\\\
" << endl; 2663 latexfile << "\\hline
" << endl; 2664 latexfile << "Maximal number of non-interactive events per component & {\\tt --evtMax} &
" << evtMax << " \\\\
" << endl; 2665 latexfile << "\\hline
" << endl; 2666 latexfile << "Minimal number of
states per component & {\\tt --stateMin} &
" << stateMin << " \\\\
" << endl; 2667 latexfile << "\\hline
" << endl; 2668 latexfile << "Maximal number of
states per component & {\\tt --stateMax} &
" << stateMax << " \\\\
" << endl; 2669 latexfile << "\\hline
" << endl; 2670 latexfile << "Maximal number of observable interaction per component & {\\tt --obsInteractionMax} &
" << obsInteractionMax << " \\\\
" << endl; 2671 latexfile << "\\hline
" << endl; 2672 latexfile << "Minimal number of observable interaction per component & {\\tt --obsInteractionMin} &
" << obsInteractionMin << " \\\\
" << endl; 2673 latexfile << "\\hline
" << endl; 2674 latexfile << "Maximal number of output transitions per state & {\\tt --outputDegreeMax} &
" << outputDegreeMax << " \\\\
" << endl; 2675 latexfile << "\\hline
" << endl; 2676 latexfile << "\\end{tabular}
" << endl; 2677 latexfile << "}
" << endl; 2678 latexfile << "\\end{center}
" << endl; 2680 if (!fixedNode.empty()) { 2681 latexfile << "~\\\\
"; 2682 latexfile << "The topology node {\\tt
" << fixedNode << "} has been fixed by the user and contains the behaviour described in the file: \\begin{center} \\verb|
" << behaviourFileName << "| \\end{center}\n
"; 2683 if (assignedConnections.empty()) { 2684 latexfile << "No connection of the node has been assigned by the user.
" << endl; 2686 latexfile << "Here are the connections assigned by the user:
" << endl; 2687 for (map<string, string>::const_iterator it = assignedConnections.begin(); 2688 it != assignedConnections.end(); 2690 latexfile << it->first << "$\\leftrightarrow$
" << it->second << "\\\\
"; 2698 /***********************************************************************************************/ 2707 void generateLatexTopology(const Topology & topology, SharedEventNodeMap & sharedEventOfNode, ofstream & latexfile) { 2708 latexfile << "\\section{
Topology}
" << endl; 2709 latexfile << "\\label{sec:topology}
" << endl; 2710 latexfile << "The topology of the system is composed of
"; 2711 latexfile << topology.numberOfNodes(); 2712 latexfile << " components and
" << topology.numberOfConnections(); 2713 latexfile << " connections.
" << endl; 2716 for (Topology::NodeIterator nodeIt = topology.nodeBegin(); 2717 nodeIt != topology.nodeEnd(); 2719 latexfile << "\\paragraph{Neighbourhood of component {\\tt
"; 2720 latexfile << topology.getNodeName(*nodeIt) << "}}~\\\\
" << endl; 2721 if (topology.nodeConnectionBegin(*nodeIt) != topology.nodeConnectionEnd(*nodeIt)) { 2722 latexfile << "\\begin{enumerate}
" << endl; 2723 for (Topology::NodeConnectionIterator connIt = topology.nodeConnectionBegin(*nodeIt); 2724 connIt != topology.nodeConnectionEnd(*nodeIt); 2726 for (Topology::CliqueIterator cliqueIt = topology.cliqueBegin(*connIt); 2727 cliqueIt != topology.cliqueEnd(*connIt); 2729 if (*cliqueIt != *nodeIt) { 2730 latexfile << "\\item
Component {\\tt
" << topology.getNodeName(*cliqueIt) << "} with events {\\tt
"; 2731 latexfile << sharedEventOfNode[*cliqueIt][*connIt] << "}.
" << endl; 2735 latexfile << "\\end{enumerate}
" << endl; 2740 /***********************************************************************************************/ 2750 void generateLatexComponents(const Topology & topology, SharedEventNodeMap & sharedEventOfNode, const ComponentNodeMap & componentOfNode, ofstream & latexfile) { 2751 for (Topology::NodeIterator nodeIt = topology.nodeBegin(); 2752 nodeIt != topology.nodeEnd(); 2754 latexfile << "\\newpage
" << endl; 2755 latexfile << "\\subsection{
Component {\\tt
" << topology.getNodeName(*nodeIt) << "}}
" << endl; 2756 latexfile << "\\label{comp:
" << topology.getNodeName(*nodeIt) << "}
" << endl; 2757 latexfile << "\\begin{center}
" << endl; 2758 latexfile << "{\\small
" << endl; 2759 latexfile << "\\begin{tabular}{|c|m{8cm}|}
" << endl; 2760 latexfile << "\\hline
" << endl; 2761 latexfile << "Number of
states &
" << componentOfNode[*nodeIt]->numberOfStates() << " \\\\
" << endl; 2762 latexfile << "\\hline
" << endl; 2763 latexfile << "Number of Transitions &
" << componentOfNode[*nodeIt]->numberOfTransitions() << " \\\\
" << endl; 2764 latexfile << "\\hline
" << endl; 2765 latexfile << "Interactive events & {\\tt
"; 2766 set<Event> interactives; 2767 for (map<Topology::Connection, Event>::const_iterator it = sharedEventOfNode[*nodeIt].begin(); 2768 it != sharedEventOfNode[*nodeIt].end(); 2770 latexfile << "\\verb|
" << it->second << "|
"; 2771 interactives.insert(it->second); 2773 latexfile << "} \\\\
" << endl; 2774 latexfile << "\\hline
" << endl; 2775 latexfile << "Observable events & {\\tt
"; 2776 ObservableComponent::EventIterator it = componentOfNode[*nodeIt]->observableBegin(); 2779 it != componentOfNode[*nodeIt]->observableEnd(); 2781 latexfile << "\\verb|
" << *it << "|
"; 2783 latexfile << "} \\\\
" << endl; 2784 latexfile << "\\hline
" << endl; 2785 latexfile << "Non-interactive events & {\\tt
"; 2786 for (ObservableComponent::EventIterator it = componentOfNode[*nodeIt]->eventBegin(); 2787 it != componentOfNode[*nodeIt]->eventEnd(); 2789 if (interactives.find(*it) == interactives.end()) { 2790 latexfile << "\\verb|
" << *it << "|
"; 2793 latexfile << "} \\\\
" << endl; 2794 latexfile << "\\hline
" << endl; 2795 latexfile << "\\end{tabular} }
" << endl << endl; 2796 latexfile << "\\end{center}
" << endl << endl << endl; 2797 latexfile << "\\paragraph{Initial state:} $
" << componentOfNode[*nodeIt]->getLabel(*componentOfNode[*nodeIt]->initialStateBegin()) << "$
" << endl; 2798 latexfile << "\\paragraph{
Transition system:}
" << endl; 2799 if (componentOfNode[*nodeIt]->numberOfStates() > 10) { 2800 latexfile << "Note: as the number of
states is greater than 10, only transitions involved in the first 10
states are printed.
" << endl; 2803 vector<Node> printedNodes(1); 2804 printedNodes[0] = *componentOfNode[*nodeIt]->initialStateBegin(); 2805 map<Node, int> mappingNodes; 2806 mappingNodes[*componentOfNode[*nodeIt]->initialStateBegin()] = 0; 2807 list<Node> visitingNodes; 2808 visitingNodes.push_back(*componentOfNode[*nodeIt]->initialStateBegin()); 2810 while ((!visitingNodes.empty()) && (stateNb < 10)) { 2811 Node currentState = visitingNodes.front(); 2812 visitingNodes.pop_front(); 2813 ObservableComponent::OutputTransitionIterator outTransIt = componentOfNode[*nodeIt]->outputTransitionBegin(currentState); 2814 while ((stateNb < 10) && (outTransIt != componentOfNode[*nodeIt]->outputTransitionEnd(currentState))) { 2815 if (mappingNodes.find(outTransIt->target()) == mappingNodes.end()) { 2817 printedNodes.push_back(outTransIt->target()); 2818 mappingNodes[printedNodes.back()] = printedNodes.size() - 1; 2819 visitingNodes.push_back(outTransIt->target()); 2825 latexfile << "\\begin{center}
" << endl; 2826 latexfile << "{\\small
" << endl; 2828 latexfile << "\\begin{tabular}{|c
"; 2829 for (unsigned i = 0; i < printedNodes.size(); ++i) { 2830 latexfile << "|m{1cm}
"; 2832 latexfile << "|}
" << endl; 2833 latexfile << "\\hline
" << endl; 2834 for (unsigned i = 0; i < printedNodes.size(); ++i) { 2835 latexfile << " & {\\bf $
" << componentOfNode[*nodeIt]->getLabel(printedNodes[i]) << "$}
"; 2837 latexfile << "\\\\
" << endl; 2838 latexfile << "\\hline
" << endl; 2839 for (unsigned i = 0; i < printedNodes.size(); ++i) { 2840 latexfile << "{\\bf $
" << componentOfNode[*nodeIt]->getLabel(printedNodes[i]) << "$}
"; 2841 map< State, set<string> > outEvents; 2842 for (ObservableComponent::OutputTransitionIterator outTransIt = componentOfNode[*nodeIt]->outputTransitionBegin(printedNodes[i]); 2843 outTransIt != componentOfNode[*nodeIt]->outputTransitionEnd(printedNodes[i]); 2845 if (mappingNodes.find(outTransIt->target()) != mappingNodes.end()) { 2846 outEvents[outTransIt->target()].insert(componentOfNode[*nodeIt]->getEvent(*outTransIt).nickname()); 2849 for (unsigned j = 0; j < printedNodes.size(); ++j) { 2851 for (set<string>::const_iterator stringIt = outEvents[printedNodes[j]].begin(); 2852 stringIt != outEvents[printedNodes[j]].end(); 2854 latexfile << "\\verb|
" << *stringIt << "|
"; 2857 latexfile << "\\\\
" << endl; 2858 latexfile << "\\hline
" << endl; 2862 latexfile << "\\end{tabular}
"; 2863 latexfile << "}
" << endl; 2864 latexfile << "\\end{center}
"; 2872 /***********************************************************************************************/ 2879 void generateLatexEpilog(ofstream & latexfile) { 2880 latexfile << "\\end{document}
" << endl; 2884 /***********************************************************************************************/ 2894 void exportTopologyMap(const Topology & topology, 2895 SharedEventNodeMap & sharedEventOfNode, 2896 const ComponentNodeMap & componentOfNode, 2897 const string & mapTopoFileNameDest) { 2898 TopologyMap mapping(topology); 2899 for (Topology::NodeIterator it = topology.nodeBegin(); 2900 it != topology.nodeEnd(); 2902 mapping.mapComponentToNode(*componentOfNode[*it], *it); 2904 for (Topology::ConnectionIterator it = topology.connectionBegin(); 2905 it != topology.connectionEnd(); 2907 for (Topology::CliqueIterator it2 = topology.cliqueBegin(*it); 2908 it2 != topology.cliqueEnd(*it); 2910 mapping.addConnection(*it, *it2, sharedEventOfNode[*it2][*it]); 2913 mapping.exportMap(mapTopoFileNameDest); 2917 /********************************************************************************/ 2925 void writeComponent(const ObservableComponent & component, 2926 const string & dirName) { 2927 string compFileNameDest = dirName + "/
" + component.name() + ".des_comp
"; 2928 verbose<VbOutput>("Writing the file %1%...
") % compFileNameDest; 2929 component.exportDesCompModel(compFileNameDest); 2930 verbose<VbOutput>("done.\n
"); 2931 string compFileNameDestDot = dirName + "/
" + component.name() + ".dot
"; 2932 verbose<VbOutput>("Writing the file %1%...
") % compFileNameDestDot; 2933 component.component2dot(compFileNameDestDot); 2934 verbose<VbOutput>("done.\n
"); 2937 /************************************************************************************************/ 2950 void propagateConstrainedInteractions(const Topology & topology, 2951 Topology::Node node, 2952 Diades::Graph::ConstNodeMap<int> & visitedNodes, 2953 set<Topology::Node> & generatedNeighbours, 2954 set<Topology::Node> & nonGeneratedNeighbours, 2955 list<Topology::Node> & nodesToVisit) { 2956 for (Topology::NodeConnectionIterator it = topology.nodeConnectionBegin(node); 2957 it != topology.nodeConnectionEnd(node); 2959 for (Topology::CliqueIterator cliqueIt = topology.cliqueBegin(*it); 2960 cliqueIt != topology.cliqueEnd(*it); 2962 switch (visitedNodes[*cliqueIt]) { 2963 case 0: // not visited 2965 nodesToVisit.push_back(*cliqueIt); 2966 visitedNodes[*cliqueIt] = 1; 2967 if (node != *cliqueIt) { 2968 nonGeneratedNeighbours.insert(*cliqueIt); 2974 if (node != *cliqueIt) { 2975 nonGeneratedNeighbours.insert(*cliqueIt); 2979 case 2: // saturated 2981 if (node != *cliqueIt) { 2982 generatedNeighbours.insert(*cliqueIt); 2995 /***************************************************************************************/ 2997 void printDebugStartVisit(const Topology & topology, Topology::Node node) { 2998 verbose<VbDebug>("************************************************\n
"); 2999 verbose<VbDebug>("Generation of %1% based on P_{%2%}(
") 3000 % topology.getNodeName(node).str() 3001 % topology.getNodeName(node).str(); 3004 /***************************************************************************************/ 3006 void printDebugProjectionOnGeneratedNeighbours(const set<Topology::Node> & generatedNeighbours, 3007 const Diades::Graph::NodeMap< pair<string, ObservableComponent *> > & projection) { 3008 // projection on inputs 3009 for (set<Node>::const_iterator inIt = generatedNeighbours.begin(); inIt != generatedNeighbours.end(); ++inIt) { 3010 verbose<VbDebug>("%1%
") % projection[*inIt].second->name(); 3011 set<Node>::const_iterator nextInIt = inIt; 3013 if (nextInIt != generatedNeighbours.end()) { 3014 verbose<VbDebug>(" ||
"); 3017 verbose<VbDebug>(")\n
"); 3020 /***************************************************************************************/ 3032 void initialiseSynchronisationRules(const Topology & topology, 3033 set<Node>::const_iterator first, 3034 set<Node>::const_iterator last, 3035 SharedEventNodeMap & sharedEventOfNode, 3036 const Diades::Graph::ConstNodeMap< pair<string, ObservableComponent *> > & projection, 3037 ParametrizedSynchronisation & synchronisation) { 3039 for (set<Node>::const_iterator it = first; it != last; ++it) { 3040 set<Node>::const_iterator nextIt = it; 3042 for (Topology::NodeConnectionIterator it2 = topology.nodeConnectionBegin(*it); 3043 it2 != topology.nodeConnectionEnd(*it); 3046 vector<Event> synchronisedEvents; 3047 verbose<VbDebug>("synchronised events: {
"); 3048 if (projection[*it].second->containsEvent(sharedEventOfNode[*it][*it2])) { 3049 synchronisedEvents.push_back(sharedEventOfNode[*it][*it2]); 3050 for (Topology::CliqueIterator it3 = topology.cliqueBegin(*it2); 3051 it3 != topology.cliqueEnd(*it2); 3054 if (find(nextIt, last, *it3) != last) { 3055 if (projection[*it3].second->containsEvent(sharedEventOfNode[*it3][*it2])) { 3056 verbose<VbDebug>("%1%.%2%
") % topology.getNodeName(*it3).str() % sharedEventOfNode[*it3][*it2].label(); 3057 synchronisedEvents.push_back(sharedEventOfNode[*it3][*it2]); 3061 synchronisation.synchronise(synchronisedEvents); 3063 verbose<VbDebug>("}.\n
"); 3066 synchronisation.close(); 3069 /***************************************************************************************/ 3071 void printDebugLaw(const ParametrizedSynchronisation & synchronisation) { 3073 law << synchronisation; 3074 verbose<VbDebug>("getSynchronisedInteraction: composition of the input interactions based on the following synchronisation law:\n %1%\n
") % law.str(); 3077 /***************************************************************************************/ 3091 void generateNonInteractiveEvents(const Topology & topology, 3092 Topology::Node node, 3096 unsigned obsInteractionMax, 3097 ObservableComponent & result, 3098 set<Event> & nonInteractiveEvents) { 3100 always_require(FunctionException, obsMin <= evtMax, "generateNonInteractiveEvents: obsMin > evtMax.
"); 3101 always_require(FunctionException, obsInteractionMax <= evtMax, "generateNonInteractiveEvents: obsInteractionMax <=evtMax.
"); 3102 always_require(FunctionException, result.numberOfEvents() <= evtMax, "generateNonInteractiveEvents: there is more interactive events in
this component that evtMax.
"); 3114 unsigned minimumNumberOfNonInteractiveEvents = 0; 3115 if (obsMin > obsInteractionMax) { 3116 minimumNumberOfNonInteractiveEvents = obsMin - obsInteractionMax; 3118 if (result.numberOfEvents() <= evtMin) { 3119 if ((evtMin - result.numberOfEvents()) > (minimumNumberOfNonInteractiveEvents)) { 3120 minimumNumberOfNonInteractiveEvents = (evtMin - result.numberOfEvents()); 3123 always_assertion(FunctionException, minimumNumberOfNonInteractiveEvents <= evtMax - result.numberOfEvents(), 3124 "generateNonInteractiveEvents: impossible
case, minimumNumberOfNonInteractiveEvents > evtMax-result->
numberOfEvents().BUG
"); 3126 unsigned numberOfNonInteractiveEvents = 3127 generateRandomValue(minimumNumberOfNonInteractiveEvents, evtMax - result.numberOfEvents()); 3129 unsigned numberOfEvents = 3130 result.numberOfEvents() + numberOfNonInteractiveEvents; 3132 while (result.numberOfEvents() < numberOfEvents) { 3133 stringstream stream; 3134 stream << topology.getNodeName(node) << ".e
" << eventNumber; 3135 Event evt = EventFactory::factory()->getEvent(stream.str()); 3136 stringstream nickname; 3137 nickname << "e
" << eventNumber; 3138 evt.setNickname(nickname.str()); 3139 result.insertEvent(evt); 3140 nonInteractiveEvents.insert(evt); 3143 always_ensure(FunctionException, nonInteractiveEvents.size() == numberOfNonInteractiveEvents, 3147 /***************************************************************************************/ 3160 void defineObservableMask(unsigned obsMin, unsigned obsMax, unsigned obsInteractionMin, 3161 unsigned obsInteractionMax, const set<Event> & interactiveEvents, 3162 const set<Event> & nonInteractiveEvents, 3163 ObservableComponent & result) { 3165 always_require(FunctionException, obsInteractionMin <= obsInteractionMax, 3166 "defineObservableMask: obsInteractionMin > obsInteractionMax.
"); 3167 always_require(FunctionException, interactiveEvents.size() + nonInteractiveEvents.size() == result.numberOfEvents(), 3168 "defineObservableMask: interactiveEvents.size() + nonInteractiveEvents.size() != result.
numberOfEvents().
"); 3169 always_require(FunctionException, obsInteractionMin <= interactiveEvents.size(), "defineObservableMask: obsInteractionMin > interactiveEvents.size()
"); 3170 always_require(FunctionException, obsInteractionMin <= obsMin, "defineObservableMask: obsInteractionMin > obsMin
"); 3171 always_require(FunctionException, obsInteractionMax <= obsMax, "defineObservableMask: obsInteractionMax > obsMax
"); 3177 // // Let define the observable mask 3178 // unsigned int maxOfMin = obsInteractionMin < obsMin ? obsMin : obsInteractionMin; 3179 // always_assertion(FunctionException, maxOfMin >= obsMin, "defineObservableMask: maxOfMin < obsMin.
"); 3182 // unsigned int minOfMax = (obsMax<(result.numberOfEvents()))?obsMax:result.numberOfEvents(); 3183 // always_assertion(FunctionException, minOfMax <= obsMax, "defineObservableMask: minOfMax > obsMax.
"); 3184 // always_assertion(FunctionException, maxOfMin <= minOfMax, "defineObservableMask: maxOfMin > minOfMax.
"); 3186 // unsigned int numberOfObservableEvents = generateRandomValue( maxOfMin, minOfMax ); 3189 // unsigned int interactiveMinOfMax = obsInteractionMax < numberOfObservableEvents ? obsInteractionMax : numberOfObservableEvents; 3190 // if(interactiveMinOfMax > interactiveEvents.size()) 3192 // interactiveMinOfMax = interactiveEvents.size(); 3194 // always_assertion(FunctionException,interactiveMinOfMax <= interactiveEvents.size(), 3195 // "defineObservableMask:interactiveMinOfMax > interactiveEvents.size().
"); 3197 // always_assertion(FunctionException,interactiveMinOfMax <= obsInteractionMax, 3198 // "defineObservableMask:interactiveMinOfMax > obsInteractionMax.
"); 3199 // always_assertion(FunctionException, obsInteractionMin<= interactiveMinOfMax, 3200 // "defineObservableMask:obsInteractionMin > interactiveMinOfMax.
"); 3202 // unsigned int numberOfObservableInteractions = generateRandomValue(obsInteractionMin,interactiveMinOfMax); 3203 // always_assertion(FunctionException, numberOfObservableEvents>= numberOfObservableInteractions, 3204 // "defineObservableMask:numberOfObservableEvents< numberOfObservableInteractions.
"); 3206 // unsigned int numberOfObservableNonInteractiveEvents = numberOfObservableEvents - numberOfObservableInteractions; 3210 unsigned int numberOfObservableInteractions = 0; 3211 if (obsMin - obsInteractionMin > nonInteractiveEvents.size()) { 3212 numberOfObservableInteractions = generateRandomValue(max((unsigned) obsInteractionMin, (unsigned) (obsMin - obsInteractionMin - nonInteractiveEvents.size())), min((unsigned) interactiveEvents.size(), (unsigned) obsInteractionMax)); 3214 numberOfObservableInteractions = generateRandomValue(obsInteractionMin, min((unsigned) interactiveEvents.size(), (unsigned) obsInteractionMax)); 3217 unsigned numberOfObservableNonInteractiveEvents = 0; 3218 if (obsMin > numberOfObservableInteractions) { 3219 numberOfObservableNonInteractiveEvents = generateRandomValue(obsMin - numberOfObservableInteractions, 3220 min((unsigned) obsMax - numberOfObservableInteractions, (unsigned) nonInteractiveEvents.size())); 3222 numberOfObservableNonInteractiveEvents = generateRandomValue(0, 3223 min((unsigned) obsMax - numberOfObservableInteractions, (unsigned) nonInteractiveEvents.size())); 3227 debug(log<LgDebug>("numberOfObservableEvents = %1%\n numberOfObservableInteractions = %2%\n numberOfObservableNonInteractiveEvents = %3%
") 3228 % (numberOfObservableInteractions + numberOfObservableNonInteractiveEvents) 3229 % numberOfObservableInteractions 3230 % numberOfObservableNonInteractiveEvents); 3232 always_assertion(FunctionException, numberOfObservableInteractions <= obsInteractionMax, 3234 always_assertion(FunctionException, numberOfObservableInteractions >= obsInteractionMin, 3236 always_assertion(FunctionException, numberOfObservableInteractions + numberOfObservableNonInteractiveEvents >= obsMin, 3238 always_assertion(FunctionException, numberOfObservableInteractions + numberOfObservableNonInteractiveEvents <= obsMax, 3240 always_assertion(FunctionException, numberOfObservableInteractions <= interactiveEvents.size(), 3242 always_assertion(FunctionException, numberOfObservableNonInteractiveEvents <= nonInteractiveEvents.size(), 3245 ObservableMask mask; 3246 for (ObservableComponent::EventIterator it = result.eventBegin(); 3247 it != result.eventEnd(); 3249 mask.makeUnobservable(*it); 3253 list<Event> selectedEvents; 3254 selectNRandomElements(interactiveEvents.begin(), 3255 interactiveEvents.end(), 3256 Diades::Utils::AlwaysTrue<Event>(), 3257 numberOfObservableInteractions, 3258 inserter(selectedEvents, selectedEvents.end())); 3261 // selection of non interactive observable events 3262 if (!nonInteractiveEvents.empty()) { 3264 always_assertion(FunctionException, numberOfObservableNonInteractiveEvents <= nonInteractiveEvents.size(), 3266 selectNRandomElements(nonInteractiveEvents.begin(), 3267 nonInteractiveEvents.end(), 3268 Diades::Utils::AlwaysTrue<Event>(), 3269 numberOfObservableNonInteractiveEvents, 3270 inserter(selectedEvents, selectedEvents.end())); 3273 for (const Event & e : selectedEvents) { 3274 mask.removeMask(e,mask.noEvent()); 3278 result.setMask(mask); 3279 ensure(FunctionException, selectedEvents.size() == numberOfObservableNonInteractiveEvents + numberOfObservableInteractions, 3280 "defineObservableMask: selectedEvents.size() != numberOfObservableNonInteractiveEvents + numberOfObservableInteractions.
"); 3281 ensure(FunctionException, 3282 result.mask().numberOfIdentifiableEvents() == numberOfObservableNonInteractiveEvents + numberOfObservableInteractions, 3283 Msg("defineObservableMask: result.
mask().
numberOfIdentifiableEvents() (%1%) != numberOfObservableNonInteractiveEvents (%2%) + numberOfObservableInteractions (%3%).
") 3284 % result.mask().numberOfIdentifiableEvents() % numberOfObservableNonInteractiveEvents % numberOfObservableInteractions); 3288 /***************************************************************************************/ 3302 Transition getTransitionFromInteractiveCurrentState(const ObservableComponent & interaction, 3303 State currentInteractingState, 3304 const Event & eventCurrentNode, 3305 map<Event, Topology::Connection> & mappingCurrentSideToInteraction, 3306 map<Topology::Connection, Event> & mappingConnectionToInteraction, 3307 const set<Event> & constrainedEvents) { 3308 always_require(FunctionException, currentInteractingState.valid(), "getTransitionFromInteractiveCurrentState: invalid state
"); 3310 map<Event, Topology::Connection>::const_iterator connIt = mappingCurrentSideToInteraction.find(eventCurrentNode); 3312 if ((constrainedEvents.find(eventCurrentNode) != constrainedEvents.end()) 3314 (connIt != mappingCurrentSideToInteraction.end())) { 3316 // there is a transition from currentInteractingState in interaction associated to eventFromCurrentNode 3317 ObservableComponent::OutputTransitionIterator outTransIt = interaction.outputTransitionBegin(currentInteractingState); 3320 Event eventInteractionSide = mappingConnectionToInteraction[connIt->second]; 3322 while ((!found) && (outTransIt != interaction.outputTransitionEnd(currentInteractingState))) { 3324 found = (interaction.getEvent(*outTransIt)) == eventInteractionSide; 3330 result = *outTransIt; 3337 /************************************************************************************************/ 3349 bool makeMinimalRequirement(unsigned outputDegreeMax, Selection<Event> & eventSelection, 3350 vector<State> & candidates, ObservableComponent & result) { 3351 bool solution = !candidates.empty(); 3352 Selection<Event>::IndexIterator indexIt = eventSelection.nonSelectedIndexBegin(); 3354 (indexIt != eventSelection.nonSelectedIndexEnd())) { 3355 unsigned int index = generateRandomValue(0, candidates.size() - 1); 3356 State source = candidates[index]; 3357 ObservableComponent::StateIterator targetIt = selectRandomElement(result.numberOfStates(), 3358 result.stateBegin(), 3362 result.newTransition(source, *targetIt, eventSelection.getItem(*indexIt)); 3363 if (source.outDeg() == outputDegreeMax) { 3364 candidates[index] = candidates[candidates.size() - 1]; 3365 candidates.pop_back(); 3367 solution = !candidates.empty(); 3371 bool isViolated = indexIt != eventSelection.nonSelectedIndexEnd(); 3372 while (indexIt != eventSelection.nonSelectedIndexEnd()) { 3373 // this is the case where there is no more solution, 3374 // we violate the outputDegreeMax constraint 3375 ObservableComponent::StateIterator sourceIt = selectRandomElement(result.numberOfStates(), 3376 result.stateBegin(), 3379 ObservableComponent::StateIterator targetIt = selectRandomElement(result.numberOfStates(), 3380 result.stateBegin(), 3384 result.newTransition(*sourceIt, *targetIt, eventSelection.getItem(*indexIt)); 3388 // I tried my best, I give up, I violate the outputDegreeMax condition 3392 cout << "WARNING, the outputDegreeMax parameter is violated in component
" << result.name() << endl; 3399 /************************************************************************************************/ 3409 void makeComponentComplete(unsigned outputDegreeMax, Selection<Event> & eventSelection, ObservableComponent & result) { 3410 vector<State> candidates; 3411 candidates.reserve(result.numberOfStates()); 3412 for (ObservableComponent::StateIterator stateIt = result.stateBegin(); 3413 stateIt != result.stateEnd(); 3415 if (stateIt->outDeg() < outputDegreeMax) { 3416 candidates.push_back(*stateIt); 3419 if (makeMinimalRequirement(outputDegreeMax, eventSelection, candidates, result)) { 3420 // yeah we are safe all the constraints are ok, let now be a bit more random 3421 // without constraint violation 3422 while ((!candidates.empty()) 3424 (!eventSelection.allSelected())) { 3425 // now we really select the events 3426 Event event = eventSelection.getItem(eventSelection.newSelection()); 3427 unsigned nbTransForThisEvent = generateRandomValue(1, candidates.size()); 3428 set<unsigned> sourceSelection; 3429 selectNValues(0, candidates.size() - 1, nbTransForThisEvent, sourceSelection); 3430 for (set<unsigned>::const_reverse_iterator selectionIt = sourceSelection.rbegin(); 3431 selectionIt != sourceSelection.rend(); ++selectionIt) { 3432 ObservableComponent::StateIterator targetIt = selectRandomElement(result.numberOfStates(), 3433 result.stateBegin(), 3435 // it may happen that the source state already has an output transition 3436 // with this event. In this case, I simply do not add the new one 3437 // to keep the model deterministic 3438 if (result.outputEventTransitionBegin(candidates[*selectionIt], event) 3439 == result.outputEventTransitionEnd(candidates[*selectionIt], event)) { 3440 result.newTransition(candidates[*selectionIt], *targetIt, event); 3441 if (candidates[*selectionIt].outDeg() == outputDegreeMax) { 3442 candidates[*selectionIt] = candidates[candidates.size() - 1]; 3443 candidates.pop_back(); 3452 void generateLatexEventIndex(const Topology & topology, 3453 SharedEventNodeMap & sharedEventOfNode, 3454 const ComponentNodeMap & componentOfNode, ofstream & latexfile) { 3455 latexfile << "\n \\section{
Event index}
" << endl; 3456 map<Event, pair<Node, bool> > infoEvents; 3457 map<Event, pair < Topology::Connection, pair<Node, bool> > > infoSharedEvents; 3458 for (Topology::NodeIterator nodeIt = topology.nodeBegin(); 3459 nodeIt != topology.nodeEnd(); 3461 for (map<Topology::Connection, Event>::const_iterator cit = sharedEventOfNode[*nodeIt].begin(); 3462 cit != sharedEventOfNode[*nodeIt].end(); 3464 infoSharedEvents[cit->second] = make_pair(cit->first, make_pair(*nodeIt, componentOfNode[*nodeIt]->mask().isIdentifiable(cit->second))); 3466 for (ObservableComponent::EventIterator eventIt = componentOfNode[*nodeIt]->eventBegin(); 3467 eventIt != componentOfNode[*nodeIt]->eventEnd(); 3469 if (infoSharedEvents.find(*eventIt) == infoSharedEvents.end()) { 3470 infoEvents[*eventIt] = make_pair(*nodeIt, componentOfNode[*nodeIt]->mask().isIdentifiable(*eventIt)); 3474 latexfile << "\\subsection{Non shared events}
" << endl; 3475 latexfile << "\n Here are the
set of non-shared events of the generated model associated
" << endl; 3476 latexfile << " with the component where each of them occurs. The
event may be observable or not.\\\\
" << endl; 3478 for (map < Event, pair < Node, bool> >::const_iterator it = infoEvents.begin(); 3479 it != infoEvents.end(); 3481 latexfile << "{\\tt
" << it->first.nickname() << "}:
" << "{\\tt
" << topology.getNodeName(it->second.first) << "}
"; 3482 if (it->second.second) { 3483 latexfile << ", observable
"; 3485 latexfile << "~\\\\
" << endl; 3487 latexfile << "\\subsection{Shared events}
" << endl; 3488 latexfile << "\n Here are the
set of shared events of the generated model associated
" << endl; 3489 latexfile << " with the component where each of them occurs, the connection label involved with the
event"; 3490 latexfile << " followed by the clique of components involved in the connection. The
event may be observable or not.\\\\
" << endl; 3494 for (map < Event, pair < Topology::Connection, pair < Node, bool> > >::const_iterator it = infoSharedEvents.begin(); 3495 it != infoSharedEvents.end(); 3497 latexfile << "{\\tt
" << it->first.nickname() << "}:
" << "{\\tt
" << topology.getNodeName(it->second.second.first) << "},
"; 3498 latexfile << "{\\tt
" << topology.getConnectionLabel(it->second.first) << "} $\\{$
"; 3500 for (Topology::CliqueIterator cliqueIt = topology.cliqueBegin(it->second.first); 3501 cliqueIt != topology.cliqueEnd(it->second.first); 3503 latexfile << "{\\tt
" << topology.getNodeName(*cliqueIt) << "}
"; 3505 latexfile << "$\\}$
"; 3506 if (it->second.second.second) { 3507 latexfile << ", observable
"; 3509 latexfile << "~\\\\
" << endl;
unordered_set< Node >::const_iterator NodeIterator
static Event getEvent(const Label &evtLabel)
void generateBehaviour(const Topology &topology, unsigned stateMin, unsigned stateMax, unsigned evtMin, unsigned evtMax, unsigned obsMin, unsigned obsMax, unsigned obsInteractionMin, unsigned obsInteractionMax, ComponentNodeMap &componentOfNode, SharedEventNodeMap &sharedEventOfNode, string dirName, Node fixedTopoNode, unsigned outputDegreeMax)
CliqueIterator cliqueBegin(Connection connection) const
ConnectionIterator connectionBegin() const
#define always_require(Exception, expr, message)
unsigned numberOfEvents() const
void generateLatexComponents(const Topology &topology, SharedEventNodeMap &sharedEventOfNode, const ComponentNodeMap &componentOfNode, ofstream &latexfile)
Some utilities to deal with the command line.
void generateLatexPreamble(const Topology &topology, unsigned stateMin, unsigned stateMax, unsigned evtMin, unsigned evtMax, unsigned obsMin, unsigned obsMax, unsigned obsInteractionMin, unsigned obsInteractionMax, unsigned seed, unsigned outputDegreeMax, const string &fixedNode, const string &behaviourFileName, map< string, string > &assignedConnections, const ComponentNodeMap &componentOfNode, SharedEventNodeMap &sharedEventOfNode, const string &filename, ofstream &latexfile)
vector< string > options(numberOfOptions)
Diades::Graph::Edge Transition
Diades::Graph::ConstNodeMap< Event > ConnectionMap
global variable to globally index the generated events
unsigned initialiseSeed()
int main(int argc, char **argv)
void defineObservableMask(unsigned obsMin, unsigned obsMax, unsigned obsInteractionMin, unsigned obsInteractionMax, const set< Event > &interactiveEvents, const set< Event > &nonInteractiveEvents, ObservableComponent &result)
size_t printCommandLineError(const string &msg)
void exportTopologyMap(const Topology &topology, SharedEventNodeMap &sharedEventOfNode, const ComponentNodeMap &componentOfNode, const string &mapTopoFileNameDest)
NodeIterator nodeEnd() const
Diades::Graph::Node Connection
void propagateConstrainedInteractions(const Topology &topology, Topology::Node node, Diades::Graph::ConstNodeMap< int > &visitedNodes, set< Topology::Node > &generatedNeighbours, set< Topology::Node > &nonGeneratedNeighbours, list< Topology::Node > &nodesToVisit)
void setVerboseLevel(Diades::Utils::VerboseLevel level)
void generateTransitionSystem(const Topology &topology, const Node &node, SharedEventNodeMap &sharedEventOfNode, const ObservableComponent &interaction, set< Node >::const_iterator first, set< Node >::const_iterator last, unsigned numberOfStates, unsigned outputDegreeMax, ObservableComponent &result)
void makeComponentComplete(unsigned outputDegreeMax, Selection< Event > &eventSelection, ObservableComponent &result)
const Label & nickname() const
const string & str() const
void writeComponent(const ObservableComponent &component, const string &dirName)
#define ensure(Exception, expr, message)
NodeConnectionIterator nodeConnectionEnd(Node n) const
ObservableComponent * getSynchronisedInteraction(const Topology &topology, const Node &node, SharedEventNodeMap &sharedEventOfNode, const Diades::Graph::ConstNodeMap< pair< string, ObservableComponent *> > &projection, set< Node >::const_iterator first, set< Node >::const_iterator last)
void selectNValues(unsigned int min, unsigned int max, unsigned int n, set< unsigned > &result)
void initialiseRandomGenerator()
void generateLatexFile(const Topology &topology, unsigned stateMin, unsigned stateMax, unsigned evtMin, unsigned evtMax, unsigned obsMin, unsigned obsMax, unsigned obsInteractionMin, unsigned obsInteractionMax, unsigned seed, unsigned outputDegreeMax, const string &fixedNode, const string &behaviourFileName, map< string, string > &assignedConnections, const ComponentNodeMap &componentOfNode, SharedEventNodeMap &sharedEventOfNode, const string &filename)
void generateSharedEvents(const Topology &topology, ComponentNodeMap &componentOfNode, SharedEventNodeMap &sharedEventOfNode, Topology::Node fixedTopoNode)
void printDebugLaw(const ParametrizedSynchronisation &synchronisation)
An observable Component defined as a automaton.
const Graph & graph() const
Transition getTransitionFromInteractiveCurrentState(const ObservableComponent &interaction, State currentInteractingState, const Event &eventCurrentNode, map< Event, Topology::Connection > &mappingCurrentSideToInteraction, map< Topology::Connection, Event > &mappingConnectionToInteraction, const set< Event > &constrainedEvents)
void printDebugProjectionOnGeneratedNeighbours(const set< Topology::Node > &generatedNeighbours, const Diades::Graph::NodeMap< pair< string, ObservableComponent *> > &projection)
#define always_ensure(Exception, expr, message)
unsigned numberOfTransitions() const
NodeConnectionIterator nodeConnectionBegin(Node n) const
unordered_set< Connection >::const_iterator ConnectionIterator
NodeIterator nodeBegin() const
unsigned numberOfIdentifiableEvents() const
Diades::Graph::ConstNodeMap< ObservableComponent * > ComponentNodeMap
void makeComponentFullyConsistent(ObservableComponent &result, const Node &node, SharedEventNodeMap &sharedEventOfNode, const ObservableComponent &interaction, map< Event, Topology::Connection > &mappingInteractionToCurrentSide, map< Event, Topology::Connection > &mappingCurrentSideToInteraction, EdgeMap< int > &triggeredTransition, NodeMap< set< State > > &stateMapping, unsigned outputDegreeMax, Selection< Event > &eventSelection)
#define always_assertion(Exception, expr, message)
void setInitial(State state)
Random generation utilities.
void saveAllLogs(ostream &os)
bool checkEventConsistency(const Topology &topology, unsigned evtMax, unsigned obsInteractionMin)
unsigned numberOfFileExtensions
vector< bool > isSet(numberOfOptions, false)
EventIterator eventBegin() const
void generateStates(ObservableComponent &result, unsigned numberOfStates, vector< Node > &indexState)
Diades::Utils::ToStream< InputIterator, Diades::Utils::AlwaysTrue< typename InputIterator::reference > > toStream(InputIterator first, InputIterator last)
vector< string > fileExtensions(numberOfFileExtensions)
bool isIdentifiable(const Event &e) const
const ObservableMask & mask() const
void save(const string &fileName)
const Identifier & getNodeName(Node node) const
void getSelectedEvents(const ObservableComponent &interaction, State currentInteractingState, map< Event, Topology::Connection > &mappingInteractionToCurrentSide, map< Event, Topology::Connection > &mappingCurrentSideToInteraction, map< Topology::Connection, Event > &mappingConnectionToInteraction, Selection< Event > &eventSelection, const set< Event > &constrainedEvents, const set< Topology::Connection > &constrainedConnections, unsigned numberOfVisitedStates, ObservableComponent &result, unsigned outputDegreeMax, set< Event > &selectedEvents)
void generateLatexEventIndex(const Topology &topology, SharedEventNodeMap &sharedEventOfNode, const ComponentNodeMap &componentOfNode, ofstream &latexfile)
void generateRandomComponent(const Topology &topology, const Node &node, SharedEventNodeMap &sharedEventOfNode, const ObservableComponent &interaction, set< Node >::const_iterator first, set< Node >::const_iterator last, unsigned stateMin, unsigned stateMax, unsigned obsMin, unsigned obsMax, unsigned evtMin, unsigned evtMax, unsigned obsInteractionMin, unsigned obsInteractionMax, unsigned outputDegreeMax, ObservableComponent *result)
const Identifier & getConnectionLabel(Connection connection) const
EventIterator eventEnd() const
set< Event >::const_iterator EventIterator
unsigned getNumberOfTransitions(const Selection< Event > &eventSelection, const set< Event > &constrainedEvents, const set< Event > &constrainedTriggerableEvents, unsigned numberOfAdmissibleEvents, unsigned numberOfStatesToVisit, unsigned outputDegreeMax, bool &mustUseNewEvent)
void addMask(const Event &e, const Event &obs)
void generateTriggerableEvents(unsigned numberOfUnusedEventPerState, unsigned numberOfTrans, Component::EventIterator first, Component::EventIterator last, unsigned nbEvents, set< Event > &newSelection, set< Event > &unusedEvents)
Diades::Graph::Node State
void generateLatexTopology(const Topology &topology, SharedEventNodeMap &sharedEventOfNode, ofstream &latexfile)
void setNickname(const Label &nick)
ConnectionIterator connectionEnd() const
void initialiseSynchronisationRules(const Topology &topology, set< Node >::const_iterator first, set< Node >::const_iterator last, SharedEventNodeMap &sharedEventOfNode, const Diades::Graph::ConstNodeMap< pair< string, ObservableComponent *> > &projection, ParametrizedSynchronisation &synchronisation)
void printDebugStartVisit(const Topology &topology, Topology::Node node)
Logging facilities for the Diades projects.
void import(const string &fileName)
virtual bool project(const ObservableComponent *comp, const set< Event > &projectedEvents)
void propagateInteractingStates(ObservableComponent &result, const Node &node, SharedEventNodeMap &sharedEventOfNode, map< Event, Topology::Connection > &mappingInteractionToCurrentSide, const ObservableComponent &interaction, State state, State correspondingState, NodeMap< set< State > > &stateMapping)
void getOutputProjection(const Topology &topology, const Node &node, SharedEventNodeMap &sharedEventOfNode, const ObservableComponent &component, const set< Node > &nonGeneratedNeighbours, pair< string, ObservableComponent *> &result)
void generateLatexEpilog(ofstream &latexfile)
Diades::Graph::ConstNodeMap< map< Topology::Connection, Event > > SharedEventNodeMap
void generateNonInteractiveEvents(const Topology &topology, Topology::Node node, unsigned evtMin, unsigned evtMax, unsigned obsMin, unsigned obsInteractionMax, ObservableComponent &result, set< Event > &nonInteractiveEvents)
unsigned connectivity(const Node &n) const
CliqueIterator cliqueEnd(Connection connection) const
void printUsage(const po::options_description &desc)