DiaDes  0.1
DIAgnosis of Discrete-Event System
ModelGenerator.cc
Go to the documentation of this file.
1 
53 #include <string.h>
54 #include <signal.h>
55 #include <sys/time.h>
56 #include <unistd.h>
57 #include <cstdlib>
58 #include <fstream>
59 #include <sstream>
60 #include <list>
61 #include <cmath>
62 #include <algorithm>
63 #include <set>
64 #include <Utils/Assertion.hh>
65 #include <Graph/Graph.hh>
66 #include <Graph/NodeMap.hh>
67 #include <Graph/EdgeMap.hh>
68 #include <AutModel/ObservableComponent.hh>
69 
70 
71 #include<h/Graph.h>
72 
73 
74 using namespace std;
75 using namespace Grph;
76 using namespace AutModel;
77 
78 
79 /* For timeouts */
80 #define MAXDELAY 600 // max delay before exiting the process in second
81 struct sigaction sa;
82 struct itimerval timer;
83 /* End for timeouts */
84 
85 
86 
87 
88 
89 
90 /***************************************************************************/
91 void generateLatexFile(int nbComp, int connectivity,
92  int nbStateMin, int nbStateMax,
93  int nbFaultMin, int nbFaultMax,
94  int nbSharedMax, int nbSharedMaxComp,
95  int nbObsMin, int nbObsMax,
96  int nbNormalMin, int nbNormalMax,
97  const Graph & topology,
98  const NodeMap<string> & compName,
99  const EdgeMap< set<long> > & sharedEvnt,
100  const vector<ObservableComponent *> & setOfComponents);
101 void generateLatexComponents(const vector<ObservableComponent *> & setOfComponents, ofstream & latexfile);
102 void generateLatexTopology(const Graph & topology, const NodeMap<string> & compName, const EdgeMap< set<long> > & sharedEvnt, ofstream & latexfile);
103 void generateLatexEpilog(ofstream & latexfile );
104 void generateLatexPreamble(const string & name,
105  int nbComp, int connectivity,
106  int nbStateMin, int nbStateMax,
107  int nbFaultMin, int nbFaultMax,
108  int nbSharedMax, int nbSharedMaxComp,
109  int nbObsMin, int nbObsMax,
110  int nbNormalMin, int nbNormalMax,ofstream & latexfile);
111 int computeTreeWidth(const Graph & topology);
112 
113 
114 /***************************************************************************/
115 
116 
117 void timer_handler(int signum)
118 {
119  cerr << "TIMEOUT reached: Generation Aborted" << endl;
120  cerr << "Delete any files that would already be generated by this process" << endl;
121  exit(1);
122 }
123 
124 /***************************************************************************/
125 
126 void setTimeOut(long delay)
127 {
128  memset(&sa,0,sizeof(sa)) ;
129  sa.sa_handler = &timer_handler;
130  sigaction(SIGALRM, &sa, NULL);
131  timer.it_value.tv_sec = delay;
132  timer.it_value.tv_usec = 0;
133  // just in case the first signal is not catched, I send another one, till there is a catch
134  timer.it_interval.tv_sec = 1;
135  timer.it_interval.tv_usec = 0;
136  setitimer(ITIMER_REAL, &timer, NULL);
137 }
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 /**************************************************************************/
148 
149 void visuDot(const Graph & topology, const NodeMap<long> & compIds,
150  const EdgeMap< set<long> > & sharedEvnt, long numberOfSharedEvents)
151 {
152 
153  ofstream file("topology.dot");
154  // writing the header
155  file << "digraph G {" << endl;
156  file << "\tratio=fill;" << endl;
157  file << "\tpage=\"8.5,11.6\";" << endl;
158  file << "\tsize=\"7.5,10.5\";" << endl;
159  file << "\tlabel = \"State Number= ";
160  file << topology.numberOfNodes() << "\\n";
161  file << "Edge Number= " << topology.numberOfEdges() << "\\n";
162  file << "Number of shared events = " << numberOfSharedEvents << "\";" << endl;
163 
164  // writing the states
165 
166  for(Grph::NodeIterator stateIt=topology.nodeBegin();
167  stateIt!=topology.nodeEnd();
168  stateIt++){
169  file << "\t" << *stateIt << "\t [label=\"" << compIds[*stateIt] << "\"];" << endl;
170 
171  }
172  // writing the transitions
173 
174  for(Grph::EdgeIterator transIt= topology.edgeBegin();
175  transIt!= topology.edgeEnd();
176  ++transIt){
177 
178  file << "\t" << transIt->source() << " -> " << transIt->target()
179  << " [label = \"";
180  for(set<long>::const_iterator longIt = sharedEvnt[*transIt].begin();
181  longIt != sharedEvnt[*transIt].end();
182  ++longIt)
183  {
184  file << *longIt << " ";
185 
186  }
187 
188  file << "\"];" << endl;
189  }
190 
191  // writing the end of file
192  file << "}" << endl;
193  file.close();
194  }
195 
196 /***************************************************************************/
197 
198 
200 {
201  cout << "Usage: ObservableComponentGenerator " << endl;
202  cout << "\t[--comp nbComp]" << endl;
203  cout << "\t[--connectivity nbConn]" << endl;
204  cout << "\t[--sharedMax nbSharedMax]" << endl;
205  cout << "\t[--sharedMaxComp nbSharedMaxComp]" << endl;
206  cout << "\t[--stateMin nbStateMin]" << endl;
207  cout << "\t[--stateMax nbStateMax ]" << endl;
208  cout << "\t[--faultMin nbFaultMin ]" << endl;
209  cout << "\t[--faultMax nbFaultMax]" << endl;
210  cout << "\t[--obsMin nbObsMin]" << endl;
211  cout << "\t[--obsMax nbObsMax]" << endl;
212  cout << "\t[--normalMin nbNormalMin]" << endl;
213  cout << "\t[--normalMax nbNormalMax]" << endl << endl;
214  cout << "Generate a model which is a cluster of 'nbComp' components (default = 3) " << endl;
215  cout << "(every component communicates with every other component either directly " << endl;
216  cout << "or indirectly). Every component contains at least nbStateMin states " << endl;
217  cout << "(default = 2), nbFaultMin fault events (default = 1), " << endl;
218  cout << "nbObsMin observable events (default = 1) and " << endl;
219  cout << "nbNormalMin normals events (default = 0). Every component contains at most " << endl;
220  cout << "nbConn direct connections (default = 3), nbStateMax states (default = 4), " << endl;
221  cout << "nbFaultMax fault events (default = 2), nbSharedMax shared events (default = 2)," << endl;
222  cout << "nbSharedMaxComp shared events between two components (default = 3), " << endl;
223  cout << "nbObsMax observable events (default = 2) and nbNormalMax normals events (default = 1)." << endl;
224  cout << "The generated components are live (every state has at least an output transition). " << endl;
225  cout << endl;
226 }
227 
228 
229 
230 /***************************************************************************/
231 
234 long generateRandomValue(long lower, long upper)
235 {
236 
237  long range = upper - lower;
238 
239  long j = lrint((double) floor(((range + 1.0)*rand())/(RAND_MAX + 1.0)));
240  //cout << "random = " << lower +j << "in [" << lower << "," << upper << "]" << endl;
241  return lower + j;
242 }
243 
244 
245 
246 /***************************************************************************/
247 
249 {
250  // Set initial seed
251  srand( (unsigned)time( NULL ) );
252 }
253 
254 
255 /***************************************************************************/
256 
257 
258 void printError(string parameter, string message)
259 {
260  cout << "Parameter error: " << parameter << endl;
261  cout << "Error: " << message << endl << endl;
262  printUsage();
263  exit(0);
264 }
265 
266 
267 
268 
269 /***************************************************************************/
270 /* Generation of a graph which will represent the topology of the system
271  * Each node will represent a component (an ID) and a transition between
272  * two nodes means that there are some communications via shared events
273  * between the two components.
274  * The topology will contain exactly 'nbComp' components and each component
275  * will have at most 'connectivity' neighbours. This connectivity also depends
276  * on the nbSharedMax value that cannot be lower than the number of input transitions
277  * + 1 for each node of the topology. All the components are connected
278  * together either directly or indirectly. There is no independent clusters in the
279  * generated topology
280  */
281 void generateTopology(unsigned nbComp, unsigned connectivity, unsigned nbSharedMax,
282  Graph & topology, NodeMap<unsigned> & compIds)
283 {
284  list<Node> unsaturatedNodes;
285  unsigned currentComp = 0;
286  Node s1 = topology.newNode();
287  unsaturatedNodes.push_back(s1);
288  compIds[s1] = currentComp;
289  ++currentComp;
290  if(nbComp > 1)
291  {
292  cout << "Creation of topology nodes:" << endl;
293  while(currentComp != nbComp)
294  {
295 
296  Node s = topology.newNode();
297  compIds[s] = currentComp;
298  ++currentComp;
299  cout << "." << flush;
301  while(s.degree() == 0)
302  {
303 
304  if(unsaturatedNodes.size() == 1)
305  {
306  // oups only one node is still not saturated, we use use it
307  // to connect with the new node
308  // Because I want to guarantee the s is not saturated in the end
309  // I will just add an output transition from s
310 
311  topology.newEdge(s,unsaturatedNodes.front());
312 
313  if(
314  (unsaturatedNodes.front().degree() == connectivity)
315  ||
316  (nbSharedMax == (unsaturatedNodes.front().inDeg()+1))
317  )
318  {
319  // here the last node in unsaturatedNodes becomes
320  // saturated because it has connectivity connections
321  // or it cannot accpet any more input connections.
322  unsaturatedNodes.pop_front();
323  }
324  }
325  else
326  {
327  list<Node>::iterator it = unsaturatedNodes.begin();
328  while((it != unsaturatedNodes.end())
329  &&
330  (s.degree() < connectivity)
331  &&
332  (nbSharedMax > (s.inDeg() +1))
333  &&
334  (unsaturatedNodes.size() > 1))
335  {
336 
337  long connected = generateRandomValue(0,2);
338 
339  if(connected != 0 && (s.degree() < connectivity)
340  && (nbSharedMax > (s.inDeg() +1))
341  )
342  {
343 
344 
345  if (connected == 1)
346  {
347  topology.newEdge(s,*it);
348 
349  }
350  else
351  {
352  topology.newEdge(*it,s);
353 
354  }
355  if((it->degree() == connectivity)
356  || (nbSharedMax == (it->inDeg() +1))
357  )
358  {
359 
360  it = unsaturatedNodes.erase(it);
361  }
362  else
363  {
364  ++it;
365  }
366  }
367  else
368  {
369  ++it;
370  }
371  }
372  }
373  }
374  if((s.degree() < connectivity)
375  &&
376  (nbSharedMax > (s.inDeg() + 1))
377  )
378  {
379  unsaturatedNodes.push_back(s);
380  }
381  }
382  }
383 }
384 
385 
386 
387 /***************************************************************************/
388 /* Generation of a graph which will represent the topology of the system
389  * Each node will represent a component (an ID) and a transition between
390  * two nodes means that there are some communications via shared events
391  * between the two components.
392  * The topology will contain exactly 'nbComp' components and each component
393  * will have at most 'connectivity' neighbours. This connectivity also depends
394  * on the nbSharedMax value that cannot be lower than the number of input transitions
395  * + 1 for each node of the topology. All the components are connected
396  * together either directly or indirectly. There is no independent clusters in the
397  * generated topology
398  */
399 void generateTopology2(unsigned nbComp, unsigned connectivity, unsigned nbSharedMax,
400  Graph & topology, NodeMap<unsigned> & compIds)
401 {
402 
403  set<Node> unsaturatedNodes;
404  unsigned currentComp = 0;
405  Node s1 = topology.newNode();
406  compIds[s1] = currentComp;
407  ++currentComp;
408  if(nbComp > 1)
409  {
410  cout << "Creation of topology nodes:" << endl;
411  while(currentComp != nbComp)
412  {
413  Node s = topology.newNode();
414  compIds[s] = currentComp;
415  ++currentComp;
416  cout << "." << flush;
417  }
418  }
419 
420 
421 
422  // now we generate the reachabilty skeleton of the topology
423  // any node is attached to the node s1, directly or indirectly
424  set<Node> saturatedNodes;
425  set<Node> reachables;
426  NodeMap<int> depth(topology);
427  reachables.insert(s1);
428  depth[s1] = 0;
429  for(Grph::NodeIterator stateIt = topology.nodeBegin();
430  stateIt != topology.nodeEnd();
431  ++stateIt)
432  {
433  if(*stateIt != s1)
434  {
435  long neighbour = generateRandomValue(1,reachables.size());
436  long index = 1;
437  set<Node>::const_iterator reachIt = reachables.begin();
438  while(index < neighbour)
439  {
440  ++reachIt;
441  ++index;
442  }
443  topology.newEdge(*reachIt,*stateIt);
444  if(reachIt->degree() == connectivity)
445  {
446  saturatedNodes.insert(*reachIt);
447  reachables.erase(reachIt);
448  }
449  if(stateIt->degree() < connectivity)
450  {
451  reachables.insert(*stateIt);
452  }
453  else
454  {
455  saturatedNodes.insert(*stateIt);
456  }
457  depth[*stateIt] = depth[*reachIt] + 1;
458  }
459  }
460 
461  //Ok now we have a network of components
462  NodeMap<unsigned> connectivityOfNodes(topology);
463 
464  // generate randomly the connectivity of any nodes
465  for(Grph::NodeIterator stateIt = topology.nodeBegin();
466  stateIt != topology.nodeEnd();
467  ++stateIt)
468  {
469  connectivityOfNodes[*stateIt] = generateRandomValue(stateIt->degree(),connectivity);
470  if(connectivityOfNodes[*stateIt] == stateIt->degree())
471  {
472  saturatedNodes.insert(*stateIt);
473  }
474  else
475  {
476  unsaturatedNodes.insert(*stateIt);
477  }
478  }
479 
480 
481  // generate randomly the connections of any nodes
482  for(Grph::NodeIterator stateIt = topology.nodeBegin();
483  stateIt != topology.nodeEnd();
484  ++stateIt)
485  {
486  if(saturatedNodes.find(*stateIt) == saturatedNodes.end())
487  {
488  unsaturatedNodes.erase(*stateIt);
489  set<Node> selectionNodes = unsaturatedNodes;
490  bool found = !selectionNodes.empty();
491  while(found && (stateIt->degree() < connectivityOfNodes[*stateIt]))
492  {
493  set<Node>::const_iterator it = selectionNodes.begin();
494  found = it != selectionNodes.end();
495  if(found)
496  {
497  long chosenIndex = generateRandomValue(1,selectionNodes.size());
498  long index = 1;
499  while(index != chosenIndex)
500  {
501  ++it;
502  ++index;
503  }
504  Node chosenNode = *it;
505  selectionNodes.erase(it);
506  if(depth[chosenNode] <= depth[*stateIt])
507  {
508  bool alreadyPresent = false;
509  Grph::OutEdgeIterator outEdgeIt = chosenNode.outEdgeBegin();
510  while((!alreadyPresent) && (outEdgeIt != chosenNode.outEdgeEnd()))
511  {
512  alreadyPresent = outEdgeIt->target() == *stateIt;
513  ++outEdgeIt;
514  }
515  if(alreadyPresent)
516  {
517  selectionNodes.erase(chosenNode);
518  }
519  else
520  {
521  topology.newEdge(chosenNode,*stateIt);
522  }
523  }
524  else
525  {
526  bool alreadyPresent = false;
527  Grph::OutEdgeIterator outEdgeIt = stateIt->outEdgeBegin();
528  while((!alreadyPresent) && (outEdgeIt != stateIt->outEdgeEnd()))
529  {
530  alreadyPresent = outEdgeIt->target() == chosenNode;
531  ++outEdgeIt;
532  }
533  if(alreadyPresent)
534  {
535  selectionNodes.erase(chosenNode);
536  }
537  else
538  {
539  topology.newEdge(*stateIt,chosenNode);
540  }
541  }
542  if(chosenNode.degree() == connectivityOfNodes[chosenNode])
543  {
544  saturatedNodes.insert(chosenNode);
545  unsaturatedNodes.erase(chosenNode);
546  selectionNodes.erase(chosenNode);
547  }
548  }
549  }
550  }
551  }
552 
553  ofstream file("topology2.dot");
554  // writing the header
555  file << "digraph G {" << endl;
556  file << "\tratio=fill;" << endl;
557  file << "\tpage=\"8.5,11.6\";" << endl;
558  file << "\tsize=\"7.5,10.5\";" << endl;
559  file << "\tlabel = \"Node Number= ";
560  file << topology.numberOfNodes() << "\\n";
561  file << "Edge Number= " << topology.numberOfEdges() << "\";" << endl;
562 
563  // writing the states
564 
565  for(Grph::NodeIterator stateIt=topology.nodeBegin();
566  stateIt!=topology.nodeEnd();
567  stateIt++){
568  file << "\t" << *stateIt << "\t [label=\"\"];" << endl;
569 
570  }
571  // writing the transitions
572 
573  for(Grph::EdgeIterator transIt= topology.edgeBegin();
574  transIt!= topology.edgeEnd();
575  ++transIt){
576 
577  file << "\t" << transIt->source() << " -> " << transIt->target() << ";" << endl;
578  }
579 
580  // writing the end of file
581  file << "}" << endl;
582  file.close();
583 
584 }
585 
586 /***************************************************************************/
587 
588 unsigned generateSharedEvents(Graph & topology,
589  EdgeMap< set<unsigned> > & sharedEvnt,
590  unsigned nbSharedMax, unsigned nbSharedMaxComp)
591 {
592  // Given the topology 'topology', this method associates a set of numbers on each
593  // edge of the topology.
594  // Each number characterises a shared event implementing the connection represented by the
595  // edge. The assignement of these numbers must be such that:
596  // 1) there are at most "nbSharedMax" different numbers linked to one node of the topology
597  // 2) there are at least one number associated to an edge and at most "nbSharedMaxComp" numbers.
598 
599 
600 
601  // BUG: NE GERE PAS LA TRANSITIVITE DES SHARED EVENTS, LA TOPOLOGIE ET LA CONNECTIVITE NE SONT
602  // DONC PAS RESPECTEES. JE CHANGE RIEN CAR FAUTE DE TEMPS ET SURTOUT C'EST UNE VIELLE VERSION
603  // QUI NECESSITE D'ETRE REINTEGREE DANS LA NOUVELLE VERSION OU LES SHARED N'EXISTENT PLUS.
604 
606  EdgeMap< set<unsigned> > nbSharedFirstTry(topology);
607  // nbSharedFirstTry[t] = {1,3,4} means that the components source and target share 3 types
608  // of events. The events emitted by the component source are indexed between 0 and nbEmitEvnt-1 (>=4)
609 
610 
611 
612  // Stage 1:
613  // for each node, we generate the number of events that the node will emit
614  // this number depends on nbSharedMax and the number of events coming
615  // from the input edge of the current node
616  // Once this number is generated, we suppose that the events are indexed from
617  // 0 to nbEmitEvnt-1 and for each output transition we generate a subset
618  // of indexes representing the shared events emitted to one neighbourhood's component.
619  // This number of events from one component to another depends on nbSharedMaxComp
620 
621  for(Grph::NodeIterator selectedNodeIt = topology.nodeBegin();
622  selectedNodeIt != topology.nodeEnd();
623  ++selectedNodeIt)
624  {
625  unsigned nbEmitEvntMax = nbSharedMax;
626  for(Grph::InEdgeIterator inEdgeIt = selectedNodeIt->inEdgeBegin();
627  inEdgeIt != selectedNodeIt->inEdgeEnd();
628  ++inEdgeIt)
629  {
630  nbEmitEvntMax = nbEmitEvntMax -
631  (nbSharedFirstTry[*inEdgeIt].empty() ? 1 : nbSharedFirstTry[*inEdgeIt].size());
632  }
633  if(nbEmitEvntMax <= 0)
634  {
635  // too many received events, we'll take care of that problem afterwards (see Stage 2)
636  nbEmitEvntMax = 1;
637  }
638 
639  // generation of the number of emitted events by the current node
640  unsigned nbEmitEvnt = generateRandomValue(1,nbEmitEvntMax);
641  unsigned nbEmitEvntPerEdgeMax = nbEmitEvnt < nbSharedMaxComp ? nbEmitEvnt : nbSharedMaxComp;
642 
643  for(Grph::OutEdgeIterator outEdgeIt = selectedNodeIt->outEdgeBegin();
644  outEdgeIt != selectedNodeIt->outEdgeEnd();
645  ++outEdgeIt)
646  {
647  // here is how it works:
648  // selectedValues contains { 1, 1 , 3} for example
649  // and instances contains { 0, 1, 2 , 3 , ...., nbEmitEvnt-1}
650  // the result is then in nbSharedFirstTry[t] = { 0, 1, 4 }
651  // because we remove the first element of instance (0) then the first element of instance (1)
652  // and finally the third one (4)
653 
654  unsigned nbEmitEvntForThisEdge = generateRandomValue(1,nbEmitEvntPerEdgeMax);
655  list<unsigned> selectedValues;
656 
657  for(unsigned index = 1; index <= nbEmitEvntForThisEdge; ++index)
658  {
659  selectedValues.push_back(generateRandomValue(1,nbEmitEvnt-index+1));
660  }
661  set<unsigned> instances;
662  for(unsigned instance = 0; instance < nbEmitEvnt; ++instance)
663  {
664  instances.insert(instance);
665  }
666  assertion(GraphInvalid, instances.size() >= selectedValues.size(),
667  "ObservableComponentGenerator: generateSharedEvent, there is a bug0 in the generation of shared events for a given edge of the topology");
668 
669  for(list<unsigned>::const_iterator selectedIt = selectedValues.begin();
670  selectedIt != selectedValues.end();
671  ++selectedIt)
672  {
673  unsigned index = 1;
674  assertion(GraphInvalid, !instances.empty(),
675  "ObservableComponentGenerator: generateSharedEvent, there is a bug1 in the generation of shared events for a given edge of the topology");
676 
677  set<unsigned>::iterator instanceIt= instances.begin();
678  while(index != *selectedIt)
679  {
680 
681  ++index;
682  ++instanceIt;
683  assertion(GraphInvalid, instanceIt != instances.end(),
684  "ObservableComponentGenerator: generateSharedEvent, there is a bug2 in the gerenration of shared events for a given edge of the topology");
685  }
686  nbSharedFirstTry[*outEdgeIt].insert(*instanceIt);
687  instances.erase(instanceIt);
688  }
689 
690  }
691 
692  }
693 
694  // Stage 2:
695  // The previous generation of shared events may not be correct since it is possible
696  // that some nodes share a number of events that is greater than nbSharedMax, we fix this
697  // problem by removing some of the shared events assigned to some transitions
698  for(Grph::NodeIterator selectedNodeIt = topology.nodeBegin();
699  selectedNodeIt != topology.nodeEnd();
700  ++selectedNodeIt)
701  {
702 
703  // Count the number of shared events for the current node
704  unsigned count = 0;
705  for(Grph::InEdgeIterator inEdgeIt = selectedNodeIt->inEdgeBegin();
706  inEdgeIt != selectedNodeIt->inEdgeEnd();
707  ++inEdgeIt)
708  {
709 
710  count = count + nbSharedFirstTry[*inEdgeIt].size();
711  }
712  set<unsigned> emittedEvents;
713  for(Grph::OutEdgeIterator outEdgeIt = selectedNodeIt->outEdgeBegin();
714  outEdgeIt != selectedNodeIt->outEdgeEnd();
715  ++outEdgeIt)
716  {
717 
718  for(set<unsigned>::const_iterator it = nbSharedFirstTry[*outEdgeIt].begin();
719  it != nbSharedFirstTry[*outEdgeIt].end();
720  ++it)
721  {
722 
723  emittedEvents.insert(*it);
724  }
725  }
726  count = count + emittedEvents.size();
727  if(count > nbSharedMax)
728  {
729  // we need to remove some of the shared events
730  // Try to remove first some of the received events
731  // The process is not random but I think it does not matter here!!
732  unsigned excess = count - nbSharedMax;
733 
734  Grph::InEdgeIterator inEdgeIt = selectedNodeIt->inEdgeBegin();
735  while((excess != 0) && (inEdgeIt != selectedNodeIt->inEdgeEnd()))
736  {
737 
738  if(nbSharedFirstTry[*inEdgeIt].size() > 1)
739  {
740  nbSharedFirstTry[*inEdgeIt].erase(nbSharedFirstTry[*inEdgeIt].begin());
741  --excess;
742  }
743  else
744  {
745  ++inEdgeIt;
746  }
747  }
748 
749 
750  // if the elimination is not sufficient, I create only one emitted event !!
751  // we could be less drastic but it is too long to code and does not worth it
752  Grph::OutEdgeIterator outEdgeIt = selectedNodeIt->outEdgeBegin();
753  while(outEdgeIt != selectedNodeIt->outEdgeEnd())
754  {
755 
756  nbSharedFirstTry[*outEdgeIt].clear();
757  nbSharedFirstTry[*outEdgeIt].insert(1);
758  ++outEdgeIt;
759  }
760  }
761  }
762 
763  //Stage 3: ready to generate the global indexes of the shared events
764  unsigned generation = 0;
765  for(Grph::NodeIterator selectedNodeIt = topology.nodeBegin();
766  selectedNodeIt != topology.nodeEnd();
767  ++selectedNodeIt)
768  {
769  unsigned nbOfEmittedEvents = 0;
770  for(Grph::OutEdgeIterator outEdgeIt = selectedNodeIt->outEdgeBegin();
771  outEdgeIt != selectedNodeIt->outEdgeEnd();
772  ++outEdgeIt)
773  {
774 
775  for(set<unsigned>::const_iterator it = nbSharedFirstTry[*outEdgeIt].begin();
776  it != nbSharedFirstTry[*outEdgeIt].end();
777  ++it)
778  {
779  sharedEvnt[*outEdgeIt].insert(generation+*it);
780  nbOfEmittedEvents = nbOfEmittedEvents > *it ? nbOfEmittedEvents : *it;
781  }
782  }
783  generation = generation + nbOfEmittedEvents + 1;
784  }
785  return generation;
786 }
787 
788 
789 /***************************************************************************/
790 
791 string appendInfo(const string & label, vector<ObservableComponent *>::size_type index)
792 {
793  string result;
794  ostringstream stream(result);
795  stream << label << index;
796  return stream.str();
797 }
798 
799 
800 /***************************************************************************/
801 /*
802  * Write the component defined the parameters in a file (lafmodel format)
803  */
804 
805 void writeComponent(const string & name,
806  const Graph & behav,
807  const EdgeMap<string> & transEvent,
808  const set<string> & faultEvents,
809  const set<string> & normalEvents,
810  const set<string> & observableEvents,
811  const set<string> & sharedEvents)
812 {
813 
814  string filename = name+".lafmodel";
815  ofstream file(filename.c_str());
816  file << name << endl;
817  file << behav.numberOfNodes() << endl;
818  for(Grph::NodeIterator it = behav.nodeBegin();
819  it != behav.nodeEnd();
820  ++it)
821  {
822 
823  file << appendInfo(name,it->id()) << " ";
824  }
825  file << endl;
826  file << faultEvents.size() << endl;
827  for(set<string>::const_iterator it = faultEvents.begin();
828  it != faultEvents.end();
829  ++it)
830  {
831 
832  file << *it << " ";
833  }
834  file << endl << normalEvents.size() << endl;
835  for(set<string>::const_iterator it = normalEvents.begin();
836  it != normalEvents.end();
837  ++it)
838  {
839 
840  file << *it << " ";
841  }
842  file << endl << sharedEvents.size() << endl;
843  for(set<string>::const_iterator it = sharedEvents.begin();
844  it != sharedEvents.end();
845  ++it)
846  {
847 
848  file << *it << " ";
849  }
850  file << endl << observableEvents.size() << endl;
851  for(set<string>::const_iterator it = observableEvents.begin();
852  it != observableEvents.end();
853  ++it)
854  {
855 
856  file << *it << " ";
857  }
858  file << endl << behav.numberOfEdges() << endl;
859  for(Grph::EdgeIterator it = behav.edgeBegin();
860  it != behav.edgeEnd();
861  ++it)
862  {
863 
864  file << appendInfo(name,it->source().id()) << " -> "
865  << appendInfo(name,it->target().id()) << " " << transEvent[*it] << endl;
866  }
867 
868  file.close();
869 }
870 
871 
872 /***************************************************************************/
873 
874 void generateStates(ObservableComponent * newObservableComponent, unsigned numberOfStates, set<Node> & unreachedStates,
875  vector<Node> & indexState)
876 {
877 
878  indexState.resize(numberOfStates);
879  for(unsigned i = 0; i < numberOfStates; ++i)
880  {
881  stringstream s;
882  s << newObservableComponent->name() << "." << i;
883  indexState[i] = newObservableComponent->newState(s.str());
884  unreachedStates.insert(indexState[i]);
885  }
886  newObservableComponent->setInitial(*unreachedStates.begin());
887 }
888 
889 /***************************************************************************/
890 // generate the set of events that will be triggered from a state of the
891 // component under construction
892 // there will numberOfUnusedEventPerNode events from unusedEvents
893 // and more generally numberOfEdge events
894 // these events are included in newSelection in the end
895 // unusedEvents is updated according to the selection
896 // this selection is compatible with the events that are under
897 // constraint due to the interaction model
898 // BUG???: shall I consider a model whose observability is live ???
899 void generateTriggerableEvents(unsigned numberOfUnusedEventPerState,
900  unsigned numberOfTrans,
901  const vector<Event> & events,
902  unsigned nbEvents,
903  const set<Event> & constrainedEvents,
904  const set<Event> & currentTriggerableConstrainedEvents,
905  set<Event> & newSelection,
906  set<Event> & unusedEvents)
907 {
908 
909  require(GraphInvalid, numberOfUnusedEventPerState <= unusedEvents.size(),
910  "generateTriggerableEvents: impossible. BUG");
911  newSelection.clear();
912  unsigned index = 1;
913 
914  while(index <= numberOfUnusedEventPerState )
915  {
916 
917  int rankOfEvent = generateRandomValue(0,unusedEvents.size()-1);
918  set<Event>::iterator it = unusedEvents.begin();
919  int counter = 0;
920  while(counter != rankOfEvent)
921  {
922 
923  ++it;
924  ++counter;
925  }
926  if(constrainedEvents.find(*it) == constrainedEvents.end())
927  {
928  newSelection.insert(*it);
929  unusedEvents.erase(it);
930  ++index;
931  }
932  else
933  {
934  if(currentTriggerableConstrainedEvents.find(*it) != currentTriggerableConstrainedEvents.end())
935  {
936  newSelection.insert(*it);
937  unusedEvents.erase(it);
938  ++index;
939  }
940  }
941  }
942  assertion(GraphInvalid, newSelection.size() <= numberOfTrans,"Bug with numberOfUnusedEventPerState");
943 
944  while( ( newSelection.size() < numberOfTrans) )
945  {
946 
947  unsigned indexOfEvent = generateRandomValue(0,nbEvents-1);
948  if(constrainedEvents.find(events[indexOfEvent]) == constrainedEvents.end())
949  {
950  set<Event>::iterator it = unusedEvents.find(events[indexOfEvent]);
951  if (it != unusedEvents.end())
952  {
953  unusedEvents.erase(it);
954  }
955  newSelection.insert(events[indexOfEvent]);
956  }
957  else
958  {
959  if(currentTriggerableConstrainedEvents.find(events[indexOfEvent])
960  != currentTriggerableConstrainedEvents.end())
961  {
962  set<Event>::iterator it = unusedEvents.find(events[indexOfEvent]);
963  if (it != unusedEvents.end())
964  {
965  unusedEvents.erase(it);
966  }
967  newSelection.insert(events[indexOfEvent]);
968  }
969  }
970 
971 
972  }
973 
974 
975  ensure(GraphInvalid,!newSelection.empty(),"generateTriggerableEvents: no possible events. Don't know whether it is a bug or the fact that there is no solution!! Try again with the same parameters");
976 }
977 
978 
979 /***************************************************************************/
980 // Here we just inserted the fact that the state 'state' has a new corresponding
981 // state 'correspondingState' in localInteraction model.
982 // This new information must be propagated to the successors of 'state'
983 void propagateInteractingStates(ObservableComponent * newObservableComponent, const ObservableComponent * localInteraction,
984  State state,
985  State correspondingState,
986  NodeMap< set<State> > & stateMapping)
987 {
988 
989  list< pair<State,State> > stack;
990  stack.push_back(make_pair(state, correspondingState));
991 
992  while(!stack.empty())
993  {
994 
995  State currentState = stack.back().first;
996  State currentCorrespondingState = stack.back().second;
997  Grph::OutEdgeIterator outTransIt = currentCorrespondingState.outEdgeBegin();
998  bool stop = false;
999  while((!stop) && (outTransIt != currentCorrespondingState.outEdgeEnd()))
1000  {
1001 
1002  Event currentEvent = localInteraction->getEvent(*outTransIt);
1003  Grph::OutEdgeIterator outTransIt2 = currentState.outEdgeBegin();
1004  bool found = false;
1005  State targetState;
1006  while((!found) && (outTransIt2 != currentState.outEdgeEnd()))
1007  {
1008 
1009  found = newObservableComponent->getEvent(*outTransIt2) == currentEvent;
1010  if(found)
1011  {
1012  targetState = outTransIt2->target();
1013  }
1014  ++outTransIt2;
1015  }
1016 
1017  if(found)
1018  {
1019  if(stateMapping[targetState].find(outTransIt->target()) == stateMapping[targetState].end())
1020  {
1021  stateMapping[targetState].insert(outTransIt->target());
1022  stack.push_back(make_pair(targetState,outTransIt->target()));
1023  stop = true;
1024  }
1025  }
1026  ++outTransIt;
1027  }
1028  if(!stop)
1029  {
1030  // all the successors of the (currentState,currentCorrespondingState) are correctly tagged
1031  stack.pop_back();
1032  }
1033  }
1034  //cout << "Stop propagating Interacting States" << endl;
1035 }
1036 
1037 
1038 /***************************************************************************/
1039 
1040 // newObservableComponent is almost generated. The problem is that some transitions
1041 // of localInteraction may not have their correpsondance in newObservableComponent yet
1042 // (triggeredEdgeition[t] = 0)
1043 // so we complete the model to have full correspindance by adding some
1044 // transitions in the newObservableComponent
1045 void completeObservableComponent(ObservableComponent * newObservableComponent,
1046  const ObservableComponent * localInteraction,
1047  EdgeMap<int> & triggeredTransition,
1048  NodeMap< set<State> > & stateMapping,
1049  set<Event> & unusedEvents)
1050 {
1051 
1052  list<Trans> unmatchedTransitions;
1053  for(ObservableComponent::TransIterator it = localInteraction->beginOfTrans();
1054  it != localInteraction->endOfTrans();
1055  ++it)
1056  {
1057 
1058  if(triggeredTransition[*it] == 0)
1059  {
1060  unmatchedTransitions.push_back(*it);
1061  }
1062  }
1063 
1064  while(!unmatchedTransitions.empty())
1065  {
1066 
1067  Trans currentTrans = unmatchedTransitions.front();
1068  unmatchedTransitions.pop_front();
1069 
1070  // looking for a source/target states:
1071  list<State> potentialSourceStates;
1072  State possibleSource;
1073  State possibleTarget;
1074  bool stop = false;
1075  ObservableComponent::StateIterator stateIt = newObservableComponent->beginOfStates();
1076  while(!stop && (stateIt != newObservableComponent->endOfStates()))
1077  {
1078  if(stateMapping[*stateIt].find(currentTrans.source()) != stateMapping[*stateIt].end())
1079  {
1080  potentialSourceStates.push_back(*stateIt);
1081  // looking whether there is a possible target state for this source
1082  Grph::OutEdgeIterator outTransIt = stateIt->outEdgeBegin();
1083  bool found = false;
1084  while(!found && (outTransIt != stateIt->outEdgeEnd()))
1085  {
1086 
1087  found = newObservableComponent->getEvent(*outTransIt) == localInteraction->getEvent(currentTrans);
1088  if(found)
1089  {
1090  possibleTarget = outTransIt->target();
1091  }
1092  ++outTransIt;
1093  }
1094  stop = found;
1095  if(stop)
1096  {
1097  possibleSource = potentialSourceStates.back();
1098  }
1099  }
1100  ++stateIt;
1101  }
1102  if(stop)
1103  {
1104  // we found a transition in the model that matches currentEdge
1105  triggeredTransition[currentTrans] = 1;
1106  if(stateMapping[possibleTarget].find(currentTrans.target()) == stateMapping[possibleTarget].end())
1107  {
1108  stateMapping[possibleTarget].insert(currentTrans.target());
1109  propagateInteractingStates(newObservableComponent,localInteraction,possibleTarget,
1110  currentTrans.target(),
1111  stateMapping);
1112  }
1113  }
1114  else
1115  {
1116  // we haven't found a transition we need to create a new one
1117  if(potentialSourceStates.empty())
1118  {
1119  // we cannot do anything at this stage so we must push the current transition back to the
1120  // list and wait that a source state will appear (it will!).
1121  unmatchedTransitions.push_back(currentTrans);
1122  }
1123  else
1124  {
1125  // we are lucky, we found some sources
1126  // I just select one of them randomly and then I select a target state randomly.
1127  // Since the generation is already very randomized, I just consider a deterministic
1128  // procedure for the rest. It can be randomized. The code would be longer and a bit
1129  // more complex.
1130  unsigned indexSource = generateRandomValue(0,potentialSourceStates.size()-1);
1131  list<State>::const_iterator sourceIt = potentialSourceStates.begin();
1132  unsigned counter = 0;
1133  while(counter != indexSource)
1134  {
1135  ++sourceIt;
1136  ++counter;
1137  }
1138  State source = *sourceIt;
1139 
1140  unsigned indexTarget = generateRandomValue(0,newObservableComponent->numberOfStates() - 1);
1141  counter = 0;
1142  ObservableComponent::StateIterator targetIt = newObservableComponent->beginOfStates();
1143  while(counter != indexTarget)
1144  {
1145  ++targetIt;
1146  ++counter;
1147  }
1148  State target = *targetIt;
1149 
1150  Trans t = newObservableComponent->newTrans(source,target, localInteraction->getEvent(currentTrans));
1151  set<Event>::iterator unusedIt = unusedEvents.find(localInteraction->getEvent(currentTrans));
1152  if(unusedIt != unusedEvents.end())
1153  {
1154  unusedEvents.erase(unusedIt);
1155  }
1156  triggeredTransition[currentTrans] = 1;
1157  stateMapping[target].insert(currentTrans.target());
1158  propagateInteractingStates(newObservableComponent,
1159  localInteraction,
1160  target,
1161  currentTrans.target(),
1162  stateMapping);
1163  }
1164  }
1165  }
1166 }
1167 
1168 
1169 /***************************************************************************/
1170 
1171 void generateTransitionSystem(ObservableComponent * newObservableComponent,
1172  const ObservableComponent * localInteraction,
1173  unsigned numberOfStates,
1174  const vector<Event> & events,
1175  unsigned nbEvents)
1176 {
1177 
1178  //localInteraction->model2dot("titi.dot");
1179  // state generation
1180  set<State> unreachedStates;
1181  vector<State> indexState;
1182  generateStates(newObservableComponent, numberOfStates, unreachedStates, indexState);
1183 
1184 
1185  // the component is deterministic but not minimal
1186  // I also need to take care about the fact that every event is at least used
1187  // once in the model and every transition in localInteraction must be triggered once.
1188  // Moreover no transition with a code shared with localInteraction is independent from
1189  // localInteraction.
1190  // Every state must be reachable from the initial state
1191 
1192 
1193  // here are the codes that are contrained by the local interaction
1194  // model (codes can be compared even if they do not bleong to the
1195  // same model (value comparison))
1196  set<Event> constrainedEvents;
1197  for(ObservableComponent::EventIterator it = localInteraction->beginOfEvents();
1198  it != localInteraction->endOfEvents();
1199  ++it)
1200  {
1201  constrainedEvents.insert(*it);
1202  }
1203 
1204 
1205  // will state whether a transition of the interaction model
1206  // is taken into account into the generated model
1207  // (must be true for every transition in the end)
1208  EdgeMap<int> triggeredTransition(localInteraction->behaviour());
1209 
1210  // contains a mapping between the state of the generated model
1211  // and some corresponding states in the intearction model.
1212  // structure mainly used to complete the model in the end
1213  NodeMap< set<State> > stateMapping(newObservableComponent->behaviour());
1214 
1215 
1216  // used to guarantee that any event type will be used at least once.
1217  set<Event> unusedEvents;
1218  for(unsigned index = 0; index < nbEvents; ++index)
1219  {
1220 
1221  unusedEvents.insert(events[index]);
1222  }
1223 
1224 
1225  // common structures for visiting the state of the generated model
1226  // in parallel with the interaction model
1227  // here we suppose that the transition system has one initial state only
1228  list<State> stateToVisit;
1229  list<State> interactingStateToVisit;
1230  stateToVisit.push_back(*newObservableComponent->beginOfInitialStates());
1231  interactingStateToVisit.push_back(*localInteraction->beginOfInitialStates());
1232  unreachedStates.erase(*newObservableComponent->beginOfInitialStates());
1233  set<State> visitingOrVisitedStates;
1234  visitingOrVisitedStates.insert(*newObservableComponent->beginOfInitialStates());
1235  stateMapping[*newObservableComponent->beginOfInitialStates()].insert(*localInteraction->beginOfInitialStates());
1236 
1237  unsigned numberOfVisitedStates=0;
1238 
1239  // start the transition generation
1240  while(!stateToVisit.empty())
1241  {
1242 
1243  // current state in the model under construction
1244  Node currentState = stateToVisit.front();
1245  stateToVisit.pop_front();
1246 
1247 
1248  // current state in the interaction model
1249  State currentInteractingState = interactingStateToVisit.front();
1250  interactingStateToVisit.pop_front();
1251  set<Event> currentTriggerableConstrainedEvents;
1252  for(ObservableComponent::OutTransIterator it = localInteraction->beginOfOutTrans(currentInteractingState);
1253  it != localInteraction->endOfOutTrans(currentInteractingState);
1254  ++it)
1255  {
1256 
1257  currentTriggerableConstrainedEvents.insert(localInteraction->getEvent(*it));
1258  }
1259 
1260 
1261  // Generation of the number of output transitions for the current state.
1262  // From a state, the behaviour is deterministic so the number of transitions
1263  // is at most the number of different events. Since the state of the component
1264  // is live, I also suppose that there exists at least one transition
1265  // but I also need to take care about the fact that every event is at least used
1266  // once in the model.
1267  unsigned numberOfTrans = 0;
1268  unsigned numberOfTriggerableEvents = nbEvents + currentTriggerableConstrainedEvents.size() - constrainedEvents.size();
1269  unsigned numberOfUnusedAndTriggerableEvents = unusedEvents.size();
1270 
1271  for(set<Event>::const_iterator it = unusedEvents.begin();
1272  it != unusedEvents.end();
1273  ++it)
1274  {
1275 
1276  if((constrainedEvents.find(*it) != constrainedEvents.end())
1277  &&
1278  (currentTriggerableConstrainedEvents.find(*it) == currentTriggerableConstrainedEvents.end()))
1279  {
1280  --numberOfUnusedAndTriggerableEvents;
1281  }
1282 
1283  }
1284 
1285 
1286  unsigned numberOfUnusedEventPerState = unusedEvents.size();
1287  if(unusedEvents.size() > 1)
1288  {
1289  numberOfUnusedEventPerState =
1290  (unsigned) (ceil((double) unusedEvents.size() / (double) (newObservableComponent->numberOfStates() - numberOfVisitedStates)));
1291  }
1292  if (numberOfUnusedEventPerState > numberOfUnusedAndTriggerableEvents)
1293  {
1294  numberOfUnusedEventPerState = numberOfUnusedAndTriggerableEvents;
1295  }
1296 
1297 
1298 
1299  unsigned minimalNumberOfTrans = 0;
1300  if(numberOfUnusedEventPerState == 0)
1301  {
1302  minimalNumberOfTrans = 1;
1303  }
1304  else
1305  {
1306  minimalNumberOfTrans = numberOfUnusedEventPerState;
1307  }
1308 
1309  // So the number of transitions for this state will be... (before completion)
1310  numberOfTrans = generateRandomValue(minimalNumberOfTrans, numberOfTriggerableEvents);
1311 
1312  // generation of the events triggerable in the current state
1313  set<Event> newSelection;
1314  //cout << "numberOfUnusedEventPerNode = " << numberOfUnusedEventPerNode << endl;
1315  //cout << "unusedEvents = " << unusedEvents.size() << endl;
1316  //cout << "number of states = " << newObservableComponent->numberOfNodes() << endl;
1317  //cout << "number of visited states = " << numberOfVisitedNodes << endl;
1318  //cout << "number of triggerable events = " << numberOfTriggerableEvents << endl;
1319  //cout << "number of constrained events = " << constrainedEvents.size() << endl;
1320 
1321  generateTriggerableEvents(numberOfUnusedEventPerState,
1322  numberOfTrans,
1323  events,
1324  nbEvents,
1325  constrainedEvents,
1326  currentTriggerableConstrainedEvents,
1327  newSelection,
1328  unusedEvents);
1329 
1330  // before creating transitions I check whether there are still unreached states.
1331  // If there are, I select one as a target of a transition with the current
1332  // state. It is a way to be sure that every state is at least reachable from
1333  // the initial state by at least one transition since the current state is
1334  // reachable from the initial state.
1335 
1336  State unreachedState;
1337  int numberOfIterationsBefore;
1338  if(!unreachedStates.empty())
1339  {
1340  unreachedState = *unreachedStates.begin();
1341  unreachedStates.erase(unreachedState);
1342  numberOfIterationsBefore = generateRandomValue(0,numberOfTrans-1);
1343  }
1344 
1345  // generation of the target states and the transitions
1346  int counter = 0;
1347  set<Event>::const_iterator eventIt = newSelection.begin();
1348  for(unsigned i = 0; i < numberOfTrans; ++i)
1349  {
1350 
1351  Trans t;
1352  if( (unreachedState.valid()) &&
1353  (counter == numberOfIterationsBefore))
1354  {
1355  // here this is the case where the transition is created
1356  // to a reach a unreached state as we selected before
1357  t = newObservableComponent->newTrans(currentState,unreachedState,*eventIt);
1358  if(visitingOrVisitedStates.find(unreachedState) == visitingOrVisitedStates.end())
1359  {
1360  // it is possible that this state has been already inserted as a reached state
1361  // in a previous iteration of this loop
1362  stateToVisit.push_back(unreachedState);
1363  visitingOrVisitedStates.insert(unreachedState);
1364 
1365 
1366  // let's update the current state in the interaction model
1367  if(currentTriggerableConstrainedEvents.find(*eventIt)
1368  != currentTriggerableConstrainedEvents.end())
1369  {
1370  // the interaction state is changing
1371  ObservableComponent::OutTransIterator outTransIt = localInteraction->beginOfOutTrans(currentInteractingState);
1372  bool found = false;
1373  while((!found) && (outTransIt != localInteraction->endOfOutTrans(currentInteractingState)))
1374  {
1375  found = (localInteraction->getEvent(*outTransIt)) == *eventIt;
1376  if(found)
1377  {
1378  interactingStateToVisit.push_back(outTransIt->target());
1379  triggeredTransition[*outTransIt] = 1;
1380  stateMapping[unreachedState].insert(outTransIt->target());
1381  }
1382  ++outTransIt;
1383  }
1384  assertion(GraphInvalid,found,"generateTransitionSystem: internal BUG1");
1385  }
1386  else
1387  {
1388  // the interaction state is not changing
1389  interactingStateToVisit.push_back(currentInteractingState);
1390  stateMapping[unreachedState].insert(currentInteractingState);
1391  }
1392  }
1393  }
1394  else
1395  {
1396  // here, this is the normal case, we choose the target state randomly
1397  // and add a new transition with the selected code
1398  // BUT BE CAREFUL HERE, NO FAULT EVENT LOOP (dixit Pauline)
1399  unsigned targetId = 0;
1400  if (newObservableComponent->isFailure(*eventIt))
1401  {
1402  targetId = generateRandomValue(0,numberOfStates-1);
1403  if(indexState[targetId] == currentState)
1404  {
1405  unsigned currentStateId = targetId;
1406  targetId = generateRandomValue(0,numberOfStates-2);
1407  if(targetId >= currentStateId)
1408  {
1409  ++targetId;
1410  }
1411  }
1412  }
1413  else
1414  {
1415  targetId = generateRandomValue(0,numberOfStates-1);
1416  }
1417  t = newObservableComponent->newTrans(currentState,indexState[targetId],*eventIt);
1418 
1419  if(visitingOrVisitedStates.find(indexState[targetId]) == visitingOrVisitedStates.end())
1420  {
1421  stateToVisit.push_back(indexState[targetId]);
1422  visitingOrVisitedStates.insert(indexState[targetId]);
1423 
1424  // let's update the current state in the interaction model
1425  if(currentTriggerableConstrainedEvents.find(*eventIt)
1426  != currentTriggerableConstrainedEvents.end())
1427  {
1428  // the interaction state is changing
1429  ObservableComponent::OutTransIterator outTransIt = localInteraction->beginOfOutTrans(currentInteractingState);
1430  bool found = false;
1431  while((!found) && (outTransIt != localInteraction->endOfOutTrans(currentInteractingState)))
1432  {
1433 
1434  found = (localInteraction->getEvent(*outTransIt))
1435  == *eventIt;
1436  if(found)
1437  {
1438  interactingStateToVisit.push_back(outTransIt->target());
1439  triggeredTransition[*outTransIt] = 1;
1440  stateMapping[indexState[targetId]].insert(outTransIt->target());
1441  }
1442  ++outTransIt;
1443  }
1444  assertion(GraphInvalid,found,"generateEdgeitionSystem: internal BUG1");
1445  }
1446  else
1447  {
1448  // the interaction state is not changing
1449  interactingStateToVisit.push_back(currentInteractingState);
1450  stateMapping[indexState[targetId]].insert(currentInteractingState);
1451  }
1452  }
1453  }
1454  ++eventIt;
1455  ++counter;
1456  }
1457  ++numberOfVisitedStates;
1458  }
1459  // end of the transition generation
1460 
1461 
1462  bool found = false;
1463  set<Event>::const_iterator it = unusedEvents.begin();
1464  while(!found && (it != unusedEvents.end()))
1465  {
1466 
1467  found = constrainedEvents.find(*it) == constrainedEvents.end();
1468  ++it;
1469  }
1470  ensure(GraphInvalid,!found,"generateTransitionSystem: some unconstrained events are not used. BUG");
1471 
1472  // Now we may have a problem. Some transitions from the interaction model may not be taken into account
1473  // we have to complete the generated model
1474  completeObservableComponent(newObservableComponent, localInteraction, triggeredTransition, stateMapping, unusedEvents);
1475 
1476  ensure(GraphInvalid,unusedEvents.empty(),"generateTransitionSystem: some events are not used. BUG");
1477  cout << "Stop generating the transition system: " << newObservableComponent->name() << endl;
1478 }
1479 
1480 
1481 
1482 
1483 
1484 
1485 /***************************************************************************/
1486 ObservableComponent * generateComponent(vector<ObservableComponent *>::size_type componentIndex,
1487  ObservableComponent * newObservableComponent,
1488  ObservableComponent * interaction,
1489  set<Event> & faultEvents,
1490  set<Event> & normalEvents,
1491  set<Event> & observableEvents,
1492  set<Event> & sharedEvents,
1493  const set<string> & labelOfSharedEvents,
1494  map<string, set< vector<ObservableComponent *>::size_type > > & unknownScope,
1495  unsigned nbStateMin,
1496  unsigned nbStateMax,
1497  unsigned nbFaultMin,
1498  unsigned nbFaultMax,
1499  unsigned nbObsMin,
1500  unsigned nbObsMax,
1501  unsigned nbNormalMin,
1502  unsigned nbNormalMax)
1503 {
1504  require(GraphInvalid, !labelOfSharedEvents.empty(), "generateComponent: this component has no interactions! BUG.");
1505  string name = appendInfo("C",componentIndex);
1506  newObservableComponent->setName(name);
1507 
1508  cout << "Start generating the component: " << newObservableComponent->name() << endl;
1509  ObservableComponent * newInteractionObservableComponent;
1510  ObservableMask mask;
1511 
1512 
1513  //vector<string> eventStrings(nbFaultMax+nbObsMax+nbNormalMax+labelOfSharedEvents.size());
1514  vector<Event> events(nbFaultMax+nbObsMax+nbNormalMax+labelOfSharedEvents.size());
1515  int indexEvents = 0;
1516 
1517  // let's generate the number of fault events and their labels
1518  long numberOfFaultEvents = generateRandomValue(nbFaultMin,nbFaultMax);
1519  //cout << "Fault events: " << endl;
1520  for(int index = 1; index <= numberOfFaultEvents; ++index)
1521  {
1522  events[indexEvents] = EventFactory::factory()->getEvent(appendInfo(name + "_F",index));
1523  newObservableComponent->insertEvent(events[indexEvents]);
1524  faultEvents.insert(events[indexEvents]);
1525  mask.makeUnobservable(events[indexEvents]);
1526  ++indexEvents;
1527  }
1528 
1529  // let's generate the number of normal events and their labels
1530  unsigned numberOfNormalEvents = generateRandomValue(nbNormalMin,nbNormalMax);
1531  //cout << "Normal events: " << endl;
1532  for(int index = 1; index <= numberOfNormalEvents; ++index)
1533  {
1534 
1535  events[indexEvents] = EventFactory::factory()->getEvent(appendInfo(name + "_N",index));
1536  newObservableComponent->insertEvent(events[indexEvents]);
1537  normalEvents.insert(events[indexEvents]);
1538  mask.makeUnobservable(events[indexEvents]);
1539  ++indexEvents;
1540  }
1541 
1542  // let's generate the number of observable events and their labels
1543  // here we consider that the events are fully identifiable
1544  unsigned numberOfObservableEvents = generateRandomValue(nbObsMin,nbObsMax);
1545  //cout << "Observable events: " << endl;
1546 
1547  for(int index = 1; index <= numberOfObservableEvents; ++index)
1548  {
1549 
1550  events[indexEvents] = EventFactory::factory()->getEvent(appendInfo(name + "_O",index));
1551  newObservableComponent->insertEvent(events[indexEvents]);
1552  observableEvents.insert(events[indexEvents]);
1553  mask.makeIdentifiable(events[indexEvents]);
1554  ++indexEvents;
1555  }
1556 
1557  // let's fill the events vector with the shared events
1558  // here we consider that the events are not observable
1560  //cout << "Shared events: " << endl;
1561  for(set<string>::const_iterator sharedEvtIt = labelOfSharedEvents.begin();
1562  sharedEvtIt != labelOfSharedEvents.end();
1563  ++sharedEvtIt)
1564  {
1565 
1566  events[indexEvents] = EventFactory::factory()->getEvent(appendInfo(name + "_" + *sharedEvtIt));
1567  newObservableComponent->insertEvent(events[indexEvents]);
1568  sharedEvents.insert(events[indexEvents]);
1569  mask.makeUnobservable(events[indexEvents]);
1570  ++indexEvents;
1571  }
1572  newObservableComponent->setMask(mask);
1573  unsigned nbEvents = indexEvents;
1574 
1575  // let's generate the number of states in this component
1576  unsigned numberOfStates = generateRandomValue(nbStateMin,nbStateMax);
1577 
1578 
1579  // let's generate the transition system of the component
1580  if(interaction->numberOfTransitions() == 0)
1581  {
1582  generateTransitionSystem(newObservableComponent,interaction, numberOfStates,events, nbEvents);
1583  // let's go project on the shared events to get the first interaction model
1584 
1585  newInteractionObservableComponent = new ObservableComponent();
1586  newInteractionObservableComponent->project(newObservableComponent,sharedEvents);
1587 
1588  //cout << "Done" << endl;
1589  }
1590  else
1591  {
1592  // project on the events that are shared with the new component to create
1593  // this projection is minimal
1594  set<Code> projectedCodes;
1595 
1596  for(CodeIterator cit = newObservableComponent->beginOfCodes();
1597  cit != newObservableComponent->endOfCodes();
1598  ++cit)
1599  {
1600 
1601  if(cit->type() == ObservableComponent::Shared)
1602  {
1603  //cout << newObservableComponent->nameOfCode(cit->id()) << endl;
1604  bool found = false;
1605  CodeIterator cit2 = interaction->beginOfCodes();
1606  while(!found && (cit2 != interaction->endOfCodes()))
1607  {
1608 
1609  found = *cit == *cit2;
1610  if(found)
1611  {
1612  projectedCodes.insert(*cit2);
1613  }
1614  ++cit2;
1615  }
1616  }
1617  }
1618 
1619 
1620 
1621 
1622  //cout << "Generating the local interaction model (input model)..." << flush;
1623  assertion(GraphInvalid,!projectedCodes.empty(),
1624  "generateComponent: There is no shared code in the new local interaction model! BUG.");
1625  ObservableComponent * localProjection = new ObservableComponent(*interaction,projectedCodes);
1626  //cout << "Done" << endl;
1627 
1628  // creation of the new component with respect to this projection
1629  generateEdgeitionSystem(newObservableComponent,localProjection, numberOfStates, eventCodes, nbEvents);
1630 
1631  // project the new component to the set of shared events that are not
1632  // involved in previous generated models
1633 
1634  set<Code> nonExclusiveSharedCodes;
1635  for(CodeIterator cit = newObservableComponent->beginOfCodes();
1636  cit != newObservableComponent->endOfCodes();
1637  ++cit)
1638  {
1639 
1640  if(cit->type() == ObservableComponent::Shared)
1641  {
1642  unknownScope[newObservableComponent->nameOfCode(cit->id())].erase(componentIndex);
1643  if(!unknownScope[newObservableComponent->nameOfCode(cit->id())].empty())
1644  {
1645  // there exist some components that share this code but are
1646  // not generated yet
1647  nonExclusiveSharedCodes.insert(*cit);
1648  }
1649  }
1650  }
1651  delete localProjection;
1652  //cout << "Generating the local interaction model (output model)..." << flush;
1653  if(!nonExclusiveSharedCodes.empty())
1654  {
1655  localProjection = new ObservableComponent(*newObservableComponent,nonExclusiveSharedCodes);
1656  }
1657  else
1658  {
1659  localProjection = 0;
1660 
1661  }
1662  //cout << "Done" << endl;
1663 
1664  // project the interaction to the same type of shared events that are in the interaction model
1665  set<Code> nonExclusiveSharedCodes2;
1666  for(CodeIterator cit = interaction->beginOfCodes();
1667  cit != interaction->endOfCodes();
1668  ++cit)
1669  {
1670 
1671  if(cit->type() == ObservableComponent::Shared)
1672  {
1673  if(!unknownScope[interaction->nameOfCode(cit->id())].empty())
1674  {
1675  nonExclusiveSharedCodes2.insert(*cit);
1676  }
1677  }
1678  }
1679  //cout << "Generating the external interaction model (output model)..." << flush;
1680 
1681  ObservableComponent * updatedInteraction = 0;
1682  if(!nonExclusiveSharedCodes2.empty())
1683  {
1684  updatedInteraction = new ObservableComponent(*interaction,nonExclusiveSharedCodes2);
1685  }
1686  //cout << "Done" << endl;
1687 
1688 
1689  //cout << "Generating the final and new interaction model (output model)..." << flush;
1690  if((localProjection == 0) && (updatedInteraction == 0))
1691  {
1692  newInteractionObservableComponent = new ObservableComponent();
1693  newInteractionObservableComponent->setName("Null_Interaction");
1694  State s = newInteractionObservableComponent->newState();
1695  newInteractionObservableComponent->setInitialState(s);
1696  newInteractionObservableComponent->setLabelOfState(s,"Null");
1697  }
1698  else
1699  {
1700  if(localProjection == 0)
1701  {
1702  newInteractionObservableComponent = updatedInteraction;
1703  }
1704  else
1705  {
1706  if(updatedInteraction == 0)
1707  {
1708  newInteractionObservableComponent = localProjection;
1709  }
1710  else
1711  {
1712  // synchronise the two new interaction models and minimize it to get the
1713  // new interaction model
1714 
1715  set<Code>::iterator cit = nonExclusiveSharedCodes.begin();
1716  while(cit != nonExclusiveSharedCodes.end())
1717  {
1718 
1719  set<Code>::iterator cit2 = nonExclusiveSharedCodes2.find(*cit);
1720  if(cit2 != nonExclusiveSharedCodes2.end())
1721  {
1722  nonExclusiveSharedCodes2.erase(cit2);
1723  nonExclusiveSharedCodes.erase(cit);
1724  }
1725  else
1726  {
1727  ++cit;
1728  }
1729  }
1730 
1731  // every previously shared code that is still in the two sets is not a shared code
1732  // for the next synchronisation
1733  // do not use set<Code> since Code is internally modified !!
1734  list<Code> normalCodes;
1735  for(set<Code>::const_iterator cit = nonExclusiveSharedCodes.begin();
1736  cit != nonExclusiveSharedCodes.end();
1737  ++cit)
1738  {
1739 
1740  normalCodes.push_back(*cit);
1741  }
1742  while(!normalCodes.empty())
1743  {
1744 
1745  localProjection->changeCodeType(normalCodes.front(), ObservableComponent::Normal);
1746  normalCodes.pop_front();
1747  }
1748 
1749  for(set<Code>::const_iterator cit = nonExclusiveSharedCodes2.begin();
1750  cit != nonExclusiveSharedCodes2.end();
1751  ++cit)
1752  {
1753 
1754  normalCodes.push_back(*cit);
1755  }
1756  while(!normalCodes.empty())
1757  {
1758 
1759  updatedInteraction->changeCodeType(normalCodes.front(), ObservableComponent::Normal);
1760  normalCodes.pop_front();
1761  }
1762 
1763  list<ObservableComponent *> models;
1764  models.push_back(localProjection);
1765  models.push_back(updatedInteraction);
1766 
1767 
1768  newInteractionObservableComponent = new ObservableComponent(models);
1769 
1770  for(CodeIterator cit = newInteractionObservableComponent->beginOfCodes();
1771  cit != newInteractionObservableComponent->endOfCodes();
1772  ++cit)
1773  {
1774 
1775  if(cit->type() == ObservableComponent::Normal)
1776  {
1777  normalCodes.push_back(*cit);
1778  }
1779  }
1780  while(!normalCodes.empty())
1781  {
1782 
1783  newInteractionObservableComponent->changeCodeType(normalCodes.front(),ObservableComponent::Shared);
1784  normalCodes.pop_front();
1785  }
1786  cout << "Done" << endl;
1787  delete localProjection;
1788  delete updatedInteraction;
1789  models.clear();
1790  }
1791  }
1792  }
1793  }
1794  cout << "Stop generating the component: " << newObservableComponent->name() << endl;
1795 
1796  // check whether there is at least a transition triggered with all the shared codes in the component
1797  set<string> labels = labelOfSharedEvents;
1798  set<string> seenLabels;
1799  Grph::EdgeIterator transIt = newObservableComponent->edgeBegin();
1800  while((transIt != newObservableComponent->edgeEnd()))
1801  {
1802 
1803  if(newObservableComponent->codeOfEdge(*transIt).type() == ObservableComponent::Shared)
1804  {
1805  string labl = newObservableComponent->nameOfCode(newObservableComponent->codeOfEdge(*transIt).id());
1806  ensure(GraphInvalid,labels.find(labl) != labels.end(),"generateComponent: there is a shared code in the generated model that is unknown");
1807  seenLabels.insert(labl);
1808  }
1809  ++transIt;
1810  }
1811  ensure(GraphInvalid,labels.size() == seenLabels.size(),
1812  "generateComponent: shared codes in the generated model are not correct");
1813  ensure(GraphInvalid,newInteractionObservableComponent->numberOfEdgeitions() > 0,
1814  "generateComponent: newInteractionObservableComponent is not correct");
1815 
1816 
1817  for(CodeIterator cit = newInteractionObservableComponent->beginOfCodes();
1818  cit != newInteractionObservableComponent->endOfCodes();
1819  ++cit)
1820  {
1821 
1822  if(cit->type() != ObservableComponent::Shared)
1823  {
1824  cerr << "Problem with the following event: " << newInteractionObservableComponent->nameOfCode(cit->id()) << endl;
1825  }
1826  ensure(GraphInvalid, cit->type() == ObservableComponent::Shared, "generateComponent: Some events of the new interaction model are not shared");
1827  }
1828  return newInteractionObservableComponent;
1829 }
1830 
1831 
1832 /***************************************************************************/
1833 void generateModel(unsigned nbComp, unsigned connectivity,
1834  unsigned nbStateMin, unsigned nbStateMax,
1835  unsigned nbFaultMin, unsigned nbFaultMax,
1836  unsigned nbSharedMax, unsigned nbSharedMaxComp,
1837  unsigned nbObsMin, unsigned nbObsMax,
1838  unsigned nbNormalMin, unsigned nbNormalMax, Graph & topology,
1839  NodeMap<string> & compName,
1840  EdgeMap< set<unsigned> > & sharedEvnt,
1841  vector<ObservableComponent *> & setOfComponents)
1842 {
1843  cout << "Generating Topology..." << flush;
1844  NodeMap<unsigned> compIds(topology);
1845  generateTopology2(nbComp,connectivity,nbSharedMax,
1846  topology,compIds);
1847  //generateTopology(nbComp,connectivity,nbSharedMax,
1848  // topology,compIds);
1849  cout << "Done" << endl;
1850 
1851 
1852  cout << "Shared event generation..." << flush;
1853  unsigned numberOfSharedEvents = generateSharedEvents(topology, sharedEvnt, nbSharedMax, nbSharedMaxComp);
1854  cout << numberOfSharedEvents << " events. Done" << endl;
1855  visuDot(topology,compIds,sharedEvnt,numberOfSharedEvents);
1856 
1857  // Let's generate the set of components'behaviour
1858  setOfComponents.resize(topology.numberOfNodes());
1859 
1860 
1861  vector< set<Event> > faultEvents(topology.numberOfNodes());
1862  vector< set<Event> > normalEvents(topology.numberOfNodes());
1863  vector< set<Event> > observableEvents(topology.numberOfNodes());
1864  vector< set<Event> > sharedEvents(topology.numberOfNodes());
1865  vector< set<string> > labelOfSharedEvents(topology.numberOfNodes());
1866  map<string, set< vector<ObservableComponent *>::size_type > > unknownScope;
1867  int index = 0;
1868 
1869  list<Node> nodesToVisit;
1870  nodesToVisit.push_back(*topology.nodeBegin());
1871  NodeMap<int> visitedNodes(topology);
1872 
1873  while( !nodesToVisit.empty() )
1874  {
1875  Node node = nodesToVisit.front();
1876  stringstream stream;
1877  stream << "C" << index;
1878  compName[node] = stream.str();
1879 
1880  nodesToVisit.pop_front();
1881  visitedNodes[node] = 1;
1882  for(Grph::OutEdgeIterator edgeIt = node.outEdgeBegin();
1883  edgeIt != node.outEdgeEnd();
1884  ++edgeIt)
1885  {
1886  if(visitedNodes[edgeIt->target()] == 0)
1887  {
1888  nodesToVisit.push_back(edgeIt->target());
1889  visitedNodes[edgeIt->target()] = 1;
1890  }
1891  for(set<unsigned>::const_iterator unsignedIt = sharedEvnt[*edgeIt].begin();
1892  unsignedIt != sharedEvnt[*edgeIt].end();
1893  ++unsignedIt)
1894  {
1895 
1896  string label = appendInfo("s",*unsignedIt);
1897  unknownScope[label].insert(index);
1898  labelOfSharedEvents[index].insert(label);
1899  }
1900  }
1901  for(Grph::InEdgeIterator edgeIt = node.inEdgeBegin();
1902  edgeIt != node.inEdgeEnd();
1903  ++edgeIt)
1904  {
1905 
1906  if(visitedNodes[edgeIt->source()] == 0)
1907  {
1908  nodesToVisit.push_back(edgeIt->source());
1909  visitedNodes[edgeIt->source()] = 1;
1910  }
1911  for(set<unsigned>::const_iterator unsignedIt = sharedEvnt[*edgeIt].begin();
1912  unsignedIt != sharedEvnt[*edgeIt].end();
1913  ++unsignedIt)
1914  {
1915 
1916  string label = appendInfo("s",*unsignedIt);
1917  unknownScope[label].insert(index);
1918  labelOfSharedEvents[index].insert(label);
1919  }
1920  }
1921  ++index;
1922 
1923  }
1924  ObservableComponent * interaction = new ObservableComponent();
1925  //cout << "Generation of the null interaction model" << endl;
1926  interaction->setName("Null_Interaction");
1927  State s = interaction->newState("Null");
1928  interaction->setInitial(s);
1929  for(vector<ObservableComponent *>::size_type index2 = 0;
1930  index2 < setOfComponents.size();
1931  ++index2)
1932  {
1933  setOfComponents[index2] = new ObservableComponent();
1934  ObservableComponent * newInteraction = generateComponent(index2,
1935  setOfComponents[index2],
1936  interaction,
1937  faultEvents[index2],
1938  normalEvents[index2],
1939  observableEvents[index2],
1940  sharedEvents[index2],
1941  labelOfSharedEvents[index2],
1942  unknownScope,
1943  nbStateMin,
1944  nbStateMax,
1945  nbFaultMin,
1946  nbFaultMax,
1947  nbObsMin,
1948  nbObsMax,
1949  nbNormalMin,
1950  nbNormalMax);
1951  delete interaction;
1952  interaction = newInteraction;
1953  }
1954  for(vector<ObservableComponent *>::size_type index2 = 0;
1955  index2 < setOfComponents.size();
1956  ++index2)
1957  {
1958  stringstream fileName;
1959  stringstream fileDotName;
1960  fileDotName << setOfComponents[index2]->name() << ".dot";
1961  fileName << setOfComponents[index2]->name() << ".lafmodel";
1962  cout << "Write file " << fileName.str() << "..." << flush;
1963  setOfComponents[index2]->export2LafObservableComponent(fileName.str().c_str());
1964  setOfComponents[index2]->model2dot(fileDotName.str());
1965  cout << "Done" << endl;
1966  }
1967 }
1968 
1969 
1970 /***************************************************************************/
1971 
1972 int main(int argc, char * argv[])
1973 {
1975  unsigned nbComp = 3;
1976  unsigned connectivity = 3;
1977  unsigned nbStateMin = 2;
1978  unsigned nbStateMax = 4;
1979  unsigned nbFaultMin = 1;
1980  unsigned nbFaultMax = 2;
1981  unsigned nbSharedMax = 6;
1982  unsigned nbSharedMaxComp = 3;
1983  unsigned nbObsMin = 1;
1984  unsigned nbObsMax = 2;
1985  unsigned nbNormalMin = 0;
1986  unsigned nbNormalMax = 1;
1987 
1988  if(argc == 2)
1989  {
1990  printUsage();
1991  }
1992  else
1993  {
1994  for(int i = 1; i < argc-1; i=i+2)
1995  {
1996 
1997  string currentParameter = argv[i];
1998  cout << currentParameter << endl;
1999  string nextParameter;
2000  if(currentParameter == "--comp")
2001  {
2002  nextParameter = argv[i+1];
2003 
2004  istringstream ist(nextParameter);
2005  bool ok = ist >> nbComp;
2006  if(!ok)
2007  {
2008  printError(currentParameter,"Wrong parameter type");
2009  }
2010  if(nbComp < 1)
2011  {
2012  printError(currentParameter,"nbComp must be greater than 1");
2013  }
2014  }
2015  if(currentParameter == "--connectivity")
2016  {
2017  nextParameter = argv[i+1];
2018 
2019  istringstream ist(nextParameter);
2020  bool ok = ist >> connectivity;
2021  if(!ok)
2022  {
2023  printError(currentParameter,"Wrong parameter type");
2024  }
2025  if(connectivity < 0)
2026  {
2027  printError(currentParameter,"connectivity must be greater than 0");
2028  }
2029  }
2030  if(currentParameter == "--stateMax")
2031  {
2032  nextParameter = argv[i+1];
2033  istringstream ist(nextParameter);
2034  bool ok = ist >> nbStateMax;
2035  if(!ok)
2036  {
2037  printError(currentParameter,"Wrong parameter type");
2038  }
2039  if(nbStateMax < 1)
2040  {
2041  printError(currentParameter,"nbStateMax must be greater than 1");
2042  }
2043  }
2044  if(currentParameter == "--faultMax")
2045  {
2046  nextParameter = argv[i+1];
2047  istringstream ist(nextParameter);
2048  bool ok = ist >> nbFaultMax;
2049  if(!ok)
2050  {
2051  printError(currentParameter,"Wrong parameter type");
2052  }
2053  if(nbFaultMax < 0)
2054  {
2055  printError(currentParameter,"nbFaultMax must be greater than 0");
2056  }
2057  }
2058  if(currentParameter == "--obsMax")
2059  {
2060  nextParameter = argv[i+1];
2061  istringstream ist(nextParameter);
2062  bool ok = ist >> nbObsMax;
2063  if(!ok)
2064  {
2065  printError(currentParameter,"Wrong parameter type");
2066  }
2067  if(nbObsMax < 0)
2068  {
2069  printError(currentParameter,"nbObsMax must be greater than 0");
2070  }
2071  }
2072  if(currentParameter == "--normalMax")
2073  {
2074  nextParameter = argv[i+1];
2075  istringstream ist(nextParameter);
2076  bool ok = ist >> nbNormalMax;
2077  if(!ok)
2078  {
2079  printError(currentParameter,"Wrong parameter type");
2080  }
2081  if(nbNormalMax < 0)
2082  {
2083  printError(currentParameter,"nbNormalMax must be greater than 0");
2084  }
2085  }
2086  if(currentParameter == "--sharedMax")
2087  {
2088  nextParameter = argv[i+1];
2089  istringstream ist(nextParameter);
2090  bool ok = ist >> nbSharedMax;
2091  if(!ok)
2092  {
2093  printError(currentParameter,"Wrong parameter type");
2094  }
2095  if(nbSharedMax < 0)
2096  {
2097  printError(currentParameter,"nbSharedMax must be greater than 0");
2098  }
2099 
2100  }
2101  if(currentParameter == "--sharedMaxComp")
2102  {
2103  nextParameter = argv[i+1];
2104  istringstream ist(nextParameter);
2105  bool ok = ist >> nbSharedMaxComp;
2106  if(!ok)
2107  {
2108  printError(currentParameter,"Wrong parameter type");
2109  }
2110  if(nbSharedMaxComp < 0)
2111  {
2112  printError(currentParameter,"nbSharedMax must be greater than 0");
2113  }
2114  }
2115  if(currentParameter == "--stateMin")
2116  {
2117  nextParameter = argv[i+1];
2118  istringstream ist(nextParameter);
2119  bool ok = ist >> nbStateMin;
2120  if(!ok)
2121  {
2122  printError(currentParameter,"Wrong parameter type");
2123  }
2124  if(nbStateMin < 1)
2125  {
2126  printError(currentParameter,"nbStateMin must be greater than 1");
2127  }
2128  }
2129  if(currentParameter == "--faultMin")
2130  {
2131  nextParameter = argv[i+1];
2132  istringstream ist(nextParameter);
2133  bool ok = ist >> nbFaultMin;
2134  if(!ok)
2135  {
2136  printError(currentParameter,"Wrong parameter type");
2137  }
2138  if(nbFaultMin < 0)
2139  {
2140  printError(currentParameter,"nbFaultMin must be greater than 0");
2141  }
2142  }
2143  if(currentParameter == "--obsMin")
2144  {
2145  nextParameter = argv[i+1];
2146  istringstream ist(nextParameter);
2147  bool ok = ist >> nbObsMin;
2148  if(!ok)
2149  {
2150  printError(currentParameter,"Wrong parameter type");
2151  }
2152  if(nbObsMin < 0)
2153  {
2154  printError(currentParameter,"nbObsMin must be greater than 0");
2155  }
2156  }
2157  if(currentParameter == "--normalMin")
2158  {
2159  nextParameter = argv[i+1];
2160  istringstream ist(nextParameter);
2161  bool ok = ist >> nbNormalMin;
2162  if(!ok)
2163  {
2164  printError(currentParameter,"Wrong parameter type");
2165  }
2166  if(nbNormalMin < 0)
2167  {
2168  printError(currentParameter,"nbNormalMin must be greater than 0");
2169  }
2170  }
2171  }
2172  // Some consistency tests
2173  if(nbStateMin > nbStateMax)
2174  {
2175  printError("nbStateMin", "nbStateMax should be at least equal to nbStateMin");
2176  }
2177  if(nbFaultMin > nbFaultMax)
2178  {
2179  printError("nbFaultMin", "nbFaultMax should be at least equal to nbFaultMin");
2180  }
2181  if(nbObsMin > nbObsMax)
2182  {
2183  printError("nbObsMin", "nbObsMax should be at least equal to nbObsMin");
2184  }
2185  if(nbNormalMin > nbNormalMax)
2186  {
2187  printError("nbNormalMin", "nbNormalMax should be at least equal to nbNormalMin");
2188  }
2189  if((nbComp > 2) && (connectivity == 1))
2190  {
2191  printError("connectivity", "Since nbComp > 2, connectivity must be >= 2");
2192  }
2193  if(nbSharedMaxComp > nbSharedMax)
2194  {
2195  printError("nbSharedMaxComp", "nbSharedMax must be greater or equal to nbSharedMaxComp");
2196  }
2197  cout << "Here are the parameters for the generation: " << endl;
2198  cout << "\tNumber of components: " << nbComp << endl;
2199  cout << "\tConnectivity: " << connectivity << endl;
2200  cout << "\tNumber of states between " << nbStateMin << " and " << nbStateMax << endl;
2201  cout << "\tNumber of fault events between " << nbFaultMin << " and " << nbFaultMax << endl;
2202  cout << "\tNumber of shared events smaller than " << nbSharedMax << endl;
2203  cout << "\tNumber of shared events between two components smaller than " << nbSharedMaxComp << endl;
2204  cout << "\tNumber of observable events between " << nbObsMin << " and " << nbObsMax << endl;
2205  cout << "\tNumber of normal events between " << nbNormalMin << " and " << nbNormalMax << endl;
2206 
2207 
2208  Graph topology;
2209  NodeMap<string> compName(topology);
2210  EdgeMap< set<unisgned> > sharedEvnt(topology,0);
2211  vector<ObservableComponent *> setOfComponents;
2212 
2213  generateModel(nbComp,connectivity,nbStateMin,nbStateMax,
2214  nbFaultMin,nbFaultMax,
2215  nbSharedMax,nbSharedMaxComp,nbObsMin,nbObsMax,
2216  nbNormalMin,nbNormalMax,topology,compName,sharedEvnt,setOfComponents);
2217  generateLatexFile(nbComp,connectivity,nbStateMin,nbStateMax,
2218  nbFaultMin,nbFaultMax,
2219  nbSharedMax,nbSharedMaxComp,nbObsMin,nbObsMax,
2220  nbNormalMin,nbNormalMax,topology,compName,sharedEvnt,setOfComponents);
2221  }
2222 };
2223 
2224 
2225 
2226 /***********************************************************************************************/
2227 
2228 
2229 void generateLatexFile(int nbComp, int connectivity,
2230  int nbStateMin, int nbStateMax,
2231  int nbFaultMin, int nbFaultMax,
2232  int nbSharedMax, int nbSharedMaxComp,
2233  int nbObsMin, int nbObsMax,
2234  int nbNormalMin, int nbNormalMax,
2235  const Graph & topology,
2236  const NodeMap<string> & compName,
2237  const EdgeMap< set<long> > & sharedEvnt,
2238  const vector<ObservableComponent *> & setOfComponents)
2239 {
2240  ofstream latexfile;
2241  stringstream stream;
2242  stream << "MOD" << (unsigned)time( NULL );
2243  string fileName = stream.str()+".tex";
2244  latexfile.open(fileName.c_str());
2245  generateLatexPreamble(stream.str(), nbComp, connectivity,
2246  nbStateMin, nbStateMax,
2247  nbFaultMin, nbFaultMax,
2248  nbSharedMax, nbSharedMaxComp,
2249  nbObsMin, nbObsMax,
2250  nbNormalMin, nbNormalMax, latexfile);
2251  generateLatexTopology(topology,compName,sharedEvnt,latexfile);
2252  generateLatexComponents(setOfComponents, latexfile);
2253  generateLatexEpilog(latexfile);
2254  latexfile.close();
2255 }
2256 
2257 /***********************************************************************************************/
2258 
2259 
2260 void generateLatexPreamble(const string & name, int nbComp, int connectivity,
2261  int nbStateMin, int nbStateMax,
2262  int nbFaultMin, int nbFaultMax,
2263  int nbSharedMax, int nbSharedMaxComp,
2264  int nbObsMin, int nbObsMax,
2265  int nbNormalMin, int nbNormalMax,
2266  ofstream & latexfile)
2267 {
2268 
2269  latexfile << "\\documentclass[11pt]{article}" << endl;
2270  latexfile << "\\usepackage{array}" << endl;
2271  latexfile << "\\textwidth 17cm \\textheight 26cm \\voffset -3cm \\hoffset -1.6cm" << endl;
2272  latexfile << "\\title{Discrete-event model: " << name << "}" << endl;
2273  time_t rawtime;
2274  time ( &rawtime );
2275  latexfile << "\\date{" << ctime( &rawtime ) << "}" << endl;
2276  latexfile << "\\begin{document}" << endl;
2277  latexfile << "\\maketitle" << endl;
2278  latexfile << "\\section{Introduction}" << endl;
2279  latexfile << "This model has been generated with the following parameters of {\\tt ObservableComponentGenerator}." << endl;
2280  latexfile << "\\begin{center}" << endl;
2281  latexfile << "{\\small" << endl;
2282  latexfile << "\\begin{tabular}{|c|c|c|} " << endl;
2283  latexfile << "\\hline" << endl;
2284  latexfile << "Number of components & {\\tt --comp} & " << nbComp << " \\\\ " << endl;
2285  latexfile << "\\hline" << endl;
2286  latexfile << "Connectivity & {\\tt --connectivity} & " << connectivity << " \\\\" << endl;
2287  latexfile << "\\hline" << endl;
2288  latexfile << "Maximal of interactive events per component & {\\tt --sharedMax} & " << nbSharedMax << " \\\\" << endl;
2289  latexfile << "\\hline" << endl;
2290  latexfile << "Maximal number of interactive events between two components & {\\tt --sharedMaxComp} & " << nbSharedMaxComp << " \\\\" << endl;
2291  latexfile << "\\hline" << endl;
2292  latexfile << "Minimal number of faults per component & {\\tt --faultMin} & " << nbFaultMin << " \\\\" << endl;
2293  latexfile << "\\hline" << endl;
2294  latexfile << "Maximal number of faults per component & {\\tt --faultMax} & " << nbFaultMax << " \\\\" << endl;
2295  latexfile << "\\hline" << endl;
2296  latexfile << "Minimal number of observable per component & {\\tt --obsMin} & " << nbObsMin << " \\\\" << endl;
2297  latexfile << "\\hline" << endl;
2298  latexfile << "Maximal number of observable events per component & {\\tt --obsMax} & " << nbObsMax << " \\\\" << endl;
2299  latexfile << "\\hline" << endl;
2300  latexfile << "Minimal number of normal events per component & {\\tt --normalMin} & " << nbNormalMin << " \\\\" << endl;
2301  latexfile << "\\hline" << endl;
2302  latexfile << "Maximal number of normal events per component & {\\tt --normalMax} & " << nbNormalMax << " \\\\" << endl;
2303  latexfile << "\\hline" << endl;
2304  latexfile << "Minimal number of states per component & {\\tt --stateMin} & " << nbStateMin << " \\\\" << endl;
2305  latexfile << "\\hline" << endl;
2306  latexfile << "Maximal number of states per component & {\\tt --stateMax} & " << nbStateMax << " \\\\" << endl;
2307  latexfile << "\\hline" << endl;
2308  latexfile << "\\end{tabular}" << endl;
2309  latexfile << "}" << endl;
2310  latexfile << "\\end{center}" << endl;
2311 };
2312 
2313 
2314 
2315 /***********************************************************************************************/
2316 
2317 
2318 void generateLatexTopology(const Graph & topology, const NodeMap<string> & compName,
2319  const EdgeMap< set<long> > & sharedEvnt, ofstream & latexfile)
2320 {
2321  latexfile << "\\section{Topology}" << endl;
2322  latexfile << "\\label{sec:topology}" << endl;
2323  latexfile << "The topology of the system is composed of ";
2324  latexfile << topology.numberOfNodes();
2325  latexfile << " components and " << topology.numberOfEdge();
2326  latexfile << " connections." << endl;
2327  latexfile << " The treewidth of this topology is " << endl;
2328  latexfile << computeTreeWidth(topology) << "." << endl;
2329 
2330 
2331  for(Grph::NodeIterator nodeIt = topology.nodeBegin();
2332  nodeIt != topology.nodeEnd();
2333  ++nodeIt)
2334  {
2335  latexfile << "\\paragraph{Neighbourhood of component {\\tt ";
2336  latexfile << compName[*nodeIt] << "}}~\\\\" << endl;
2337  latexfile << "\\begin{enumerate}" << endl;
2338  for(Grph::OutEdgeIterator outTransIt = topology.outEdgeBegin(*nodeIt);
2339  outTransIt != topology.outEdgeEnd(*nodeIt);
2340  ++outTransIt)
2341  {
2342  latexfile << "\\item Component {\\tt " << compName[outTransIt->target()] << "} with events {\\tt ";
2343  for(set<long>::const_iterator it = sharedEvnt[*outTransIt].begin();
2344  it != sharedEvnt[*outTransIt].end();
2345  ++it)
2346  {
2347  latexfile << appendInfo("s",*it);
2348  set<long>::const_iterator it2 = it;
2349  ++it2;
2350  if(it2 != sharedEvnt[*outTransIt].end())
2351  {
2352  latexfile << "}, {\\tt ";
2353  }
2354  }
2355  latexfile << "}." << endl;
2356  }
2357  for(Grph::InEdgeIterator inEdgeIt = topology.inEdgeBegin(*nodeIt);
2358  inEdgeIt != topology.inEdgeEnd(*nodeIt);
2359  ++inEdgeIt)
2360  {
2361  latexfile << "\\item Component {\\tt " << compName[inEdgeIt->source()] << "} with events {\\tt ";
2362  for(set<long>::const_iterator it = sharedEvnt[*inEdgeIt].begin();
2363  it != sharedEvnt[*inEdgeIt].end();
2364  ++it)
2365  {
2366  latexfile << appendInfo("s",*it);
2367  set<long>::const_iterator it2 = it;
2368  ++it2;
2369  if(it2 != sharedEvnt[*inEdgeIt].end())
2370  {
2371  latexfile << "}, {\\tt ";
2372  }
2373  }
2374  latexfile << "}." << endl;
2375  }
2376 
2377  latexfile << "\\end{enumerate}" << endl;
2378  }
2379 }
2380 
2381 /***********************************************************************************************/
2382 
2383 void generateLatexComponents(const vector<ObservableComponent *> & setOfComponents, ofstream & latexfile)
2384 {
2385  for(vector<ObservableComponent *>::size_type index2 = 0;
2386  index2 < setOfComponents.size();
2387  ++index2)
2388  {
2389  latexfile << "\\newpage" << endl;
2390  latexfile << "\\subsection{Component {\\tt " << setOfComponents[index2]->name() << "}}" << endl;
2391  latexfile << "\\label{comp:" << setOfComponents[index2]->name() << "}" << endl;
2392  latexfile << "\\begin{center}" << endl;
2393  latexfile << "{\\small" << endl;
2394  latexfile << "\\begin{tabular}{|c|m{8cm}|}" << endl;
2395  latexfile << "\\hline" << endl;
2396  latexfile << "Number of states & " << setOfComponents[index2]->numberOfNodes() << " \\\\" << endl;
2397  latexfile << "\\hline" << endl;
2398  latexfile << "Number of Edgeitions & " << setOfComponents[index2]->numberOfEdgeitions() << " \\\\" << endl;
2399  latexfile << "\\hline" << endl;
2400  latexfile << "Interactive events & {\\tt ";
2401  for(map<IdCode,string>::const_iterator it = setOfComponents[index2]->sharedsBegin();
2402  it != setOfComponents[index2]->sharedsEnd();
2403  ++it)
2404  {
2405  latexfile << "\\verb|" << it->second << "| ";
2406  }
2407  latexfile << "} \\\\" << endl;
2408  latexfile << "\\hline" << endl;
2409  latexfile << "Fault events & {\\tt ";
2410  for(map<IdCode,string>::const_iterator it = setOfComponents[index2]->failuresBegin();
2411  it != setOfComponents[index2]->failuresEnd();
2412  ++it)
2413  {
2414  latexfile << "\\verb|" << it->second << "| ";
2415  }
2416  latexfile << "} \\\\" << endl;
2417  latexfile << "\\hline" << endl;
2418  latexfile << "Observable events & {\\tt ";
2419  for(map<IdCode,string>::const_iterator it = setOfComponents[index2]->observablesBegin();
2420  it != setOfComponents[index2]->observablesEnd();
2421  ++it)
2422  {
2423  latexfile << "\\verb|" << it->second << "| ";
2424  }
2425  latexfile << "} \\\\" << endl;
2426  latexfile << "\\hline" << endl;
2427  latexfile << "Normal events & {\\tt ";
2428  for(map<IdCode,string>::const_iterator it = setOfComponents[index2]->normalsBegin();
2429  it != setOfComponents[index2]->normalsEnd();
2430  ++it)
2431  {
2432  latexfile << "\\verb|" << it->second << "| ";
2433  }
2434  latexfile << "} \\\\" << endl;
2435  latexfile << "\\hline" << endl;
2436  latexfile << "\\end{tabular} }" << endl << endl;
2437  latexfile << "\\end{center}" << endl << endl << endl;
2438  latexfile << "\\paragraph{Initial state:} " << setOfComponents[index2]->prettyLabelOfNode(setOfComponents[index2]->initialNode()) << endl;
2439  latexfile << "\\paragraph{Edgeition system:}" << endl;
2440  if(setOfComponents[index2]->numberOfNodes() > 10)
2441  {
2442  latexfile << "Note: as the number of states is greater than 10, only transitions involved in the first 10 states are printed." << endl;
2443  }
2444 
2445  vector<Node> printedNodes(1);
2446  printedNodes[0] = setOfComponents[index2]->initialNode();
2447  map<Node,int> mappingNodes;
2448  mappingNodes[setOfComponents[index2]->initialNode()] = 0;
2449  list<Node> visitingNodes;
2450  visitingNodes.push_back(setOfComponents[index2]->initialNode());
2451  int stateNb = 1;
2452  while((!visitingNodes.empty()) && (stateNb < 10))
2453  {
2454  Node currentState = visitingNodes.front();
2455  visitingNodes.pop_front();
2456  AObservableComponent::OutEdgeIterator outTransIt = setOfComponents[index2]->outEdgeBegin(currentState);
2457  while((stateNb < 10) && (outTransIt != setOfComponents[index2]->outEdgeEnd(currentState)))
2458  {
2459  if(mappingNodes.find(outTransIt->target()) == mappingNodes.end())
2460  {
2461  ++stateNb;
2462  printedNodes.push_back(outTransIt->target());
2463  mappingNodes[printedNodes.back()] = printedNodes.size()-1;
2464  visitingNodes.push_back(outTransIt->target());
2465  }
2466  ++outTransIt;
2467  }
2468  }
2469 
2470  latexfile << "\\begin{center}" << endl;
2471  latexfile << "{\\small" << endl;
2472 
2473  latexfile << "\\begin{tabular}{|c";
2474  for(unsigned i = 0; i< printedNodes.size(); ++i)
2475  {
2476  latexfile << "|m{1cm}";
2477  }
2478  latexfile << "|}" << endl;
2479  latexfile << "\\hline" << endl;
2480  for(unsigned i = 0; i< printedNodes.size(); ++i)
2481  {
2482  latexfile << " & {\\bf " << setOfComponents[index2]->prettyLabelOfNode(printedNodes[i]) << "}";
2483  }
2484  latexfile << "\\\\" << endl;
2485  latexfile << "\\hline" << endl;
2486  for(unsigned i = 0; i< printedNodes.size(); ++i)
2487  {
2488  latexfile << "{\\bf " << setOfComponents[index2]->prettyLabelOfNode(printedNodes[i]) << "}";
2489  map< Node,set<string> > outEvents;
2490  for(AObservableComponent::OutEdgeIterator outTransIt = setOfComponents[index2]->outEdgeBegin(printedNodes[i]);
2491  outTransIt != setOfComponents[index2]->outEdgeEnd(printedNodes[i]);
2492  ++outTransIt)
2493  {
2494  if(mappingNodes.find(outTransIt->target()) != mappingNodes.end())
2495  {
2496  outEvents[outTransIt->target()].insert( setOfComponents[index2]->nameOfCode( setOfComponents[index2]->codeOfEdge(*outTransIt).id()));
2497  }
2498  }
2499  for(unsigned j = 0; j< printedNodes.size(); ++j)
2500  {
2501  latexfile << " & ";
2502  for(set<string>::const_iterator stringIt = outEvents[printedNodes[j]].begin();
2503  stringIt != outEvents[printedNodes[j]].end();
2504  ++stringIt)
2505  {
2506  latexfile << "\\verb|" << *stringIt << "| ";
2507  }
2508  }
2509  latexfile << "\\\\" << endl;
2510  latexfile << "\\hline" << endl;
2511 
2512  }
2513 
2514  latexfile << "\\end{tabular}";
2515  latexfile << "}" << endl;
2516  latexfile << "\\end{center}";
2517  }
2518 
2519 } \
2520 
2521 
2522 /***********************************************************************************************/
2523 
2524 
2525 void generateLatexEpilog(ofstream & latexfile)
2526 {
2527  latexfile << "\\end{document}" << endl;
2528 }
2529 
2530 /***********************************************************************************************/
2531 
2533 NodeMap<BAN::Node> nodeOf;
2534 
2535 
2536 
2537 /***********************************************************************************************/
2538 
2539 int computeTreeWidth(const Graph & topology)
2540 {
2541 
2542 
2543  stringstream stream;
2544  stream << "TreeWidthBug" << (unsigned) time(0) << ".cc";
2545  string fileName = stream.str();
2546  ofstream banfile(fileName.c_str());
2547 
2548  banfile << "#include \"Node.h\"" << endl;
2549  banfile << "#include \"Graph.h\"" << endl << endl;
2550  banfile << "using namespace BAN;" << endl << endl;
2551  banfile << "int main(int argc, char** argv) {" << endl;
2552  banfile << "\t Graph g;" << endl;
2553 
2554 
2555 
2556 
2557  BAN::Graph topo;
2558  NodeMap<int> status(topology,0);
2559  nodeOf.init(topology);
2560  for(Grph::EdgeIterator it = topology.edgeBegin();
2561  it != topology.edgeEnd();
2562  ++it)
2563  {
2564  if(status[it->source()] == 0)
2565  {
2566  nodeOf[it->source()] = topo.createNode();
2567  stringstream node;
2568  node << "N" << it->source().id();
2569  banfile << "\t Node " << node.str() << " = g.createNode();" << endl;
2570  status[it->source()] = 1;
2571  }
2572  if(status[it->target()] == 0)
2573  {
2574  stringstream node;
2575  node << "N" << it->target().id();
2576  banfile << "\t Node " << node.str() << " = g.createNode();" << endl;
2577  nodeOf[it->target()] = topo.createNode();
2578  status[it->target()] = 1;
2579  }
2580  stringstream source;
2581  source << "N" << it->source().id();
2582  stringstream target;
2583  target << "N" << it->target().id();
2584 
2585  banfile << "\t g.createEdge(" << source.str() << ", " << target.str() << ");" << endl;
2586 
2587  topo.createEdge(nodeOf[it->source()],nodeOf[it->target()]);
2588  }
2589  banfile << "\t std::cout << \"TreeWidth = \" << std::flush;" << endl;
2590  banfile << "\t std::cout << g.getTreeWidth() << std::endl;" << endl;
2591  banfile << "}" << endl;
2592  banfile.close();
2593  return topo.getTreeWidth();
2594 }
2595 
2596 
2597 /***********************************************************************************************/
void writeComponent(const string &name, const Graph &behav, const EdgeMap< string > &transEvent, const set< string > &faultEvents, const set< string > &normalEvents, const set< string > &observableEvents, const set< string > &sharedEvents)
#define MAXDELAY
NodeMap< BAN::Node > nodeOf
struct sigaction sa
GraphIterator< Edge > EdgeIterator
Definition: GraphInt.hh:143
unsigned generateSharedEvents(Graph &topology, EdgeMap< set< unsigned > > &sharedEvnt, unsigned nbSharedMax, unsigned nbSharedMaxComp)
string appendInfo(const string &label, vector< ObservableComponent *>::size_type index)
void timer_handler(int signum)
STL namespace.
int computeTreeWidth(const Graph &topology)
void generateTopology(unsigned nbComp, unsigned connectivity, unsigned nbSharedMax, Graph &topology, NodeMap< unsigned > &compIds)
struct itimerval timer
#define ensure(Exception, expr, message)
Definition: Assertion.hh:98
void generateStates(ObservableComponent *newObservableComponent, unsigned numberOfStates, set< Node > &unreachedStates, vector< Node > &indexState)
void initialiseRandomGenerator()
void generateLatexEpilog(ofstream &latexfile)
void generateLatexFile(int nbComp, int connectivity, int nbStateMin, int nbStateMax, int nbFaultMin, int nbFaultMax, int nbSharedMax, int nbSharedMaxComp, int nbObsMin, int nbObsMax, int nbNormalMin, int nbNormalMax, const Graph &topology, const NodeMap< string > &compName, const EdgeMap< set< long > > &sharedEvnt, const vector< ObservableComponent *> &setOfComponents)
AutFsm::State State
Definition: Run.cc:72
DdAutFsm::EventPropertyId Event
Definition: TrimState.cc:139
GraphIterator< Node > NodeIterator
Definition: GraphInt.hh:139
void propagateInteractingStates(ObservableComponent *newObservableComponent, const ObservableComponent *localInteraction, State state, State correspondingState, NodeMap< set< State > > &stateMapping)
void generateTriggerableEvents(unsigned numberOfUnusedEventPerState, unsigned numberOfTrans, const vector< Event > &events, unsigned nbEvents, const set< Event > &constrainedEvents, const set< Event > &currentTriggerableConstrainedEvents, set< Event > &newSelection, set< Event > &unusedEvents)
void completeObservableComponent(ObservableComponent *newObservableComponent, const ObservableComponent *localInteraction, EdgeMap< int > &triggeredTransition, NodeMap< set< State > > &stateMapping, set< Event > &unusedEvents)
void visuDot(const Graph &topology, const NodeMap< long > &compIds, const EdgeMap< set< long > > &sharedEvnt, long numberOfSharedEvents)
void generateTopology2(unsigned nbComp, unsigned connectivity, unsigned nbSharedMax, Graph &topology, NodeMap< unsigned > &compIds)
#define require(Exception, expr, message)
Definition: Assertion.hh:90
long generateRandomValue(long lower, long upper)
void generateTransitionSystem(ObservableComponent *newObservableComponent, const ObservableComponent *localInteraction, unsigned numberOfStates, const vector< Event > &events, unsigned nbEvents)
void generateLatexPreamble(const string &name, int nbComp, int connectivity, int nbStateMin, int nbStateMax, int nbFaultMin, int nbFaultMax, int nbSharedMax, int nbSharedMaxComp, int nbObsMin, int nbObsMax, int nbNormalMin, int nbNormalMax, ofstream &latexfile)
int main(int argc, char *argv[])
void printUsage()
ObservableComponent * generateComponent(vector< ObservableComponent *>::size_type componentIndex, ObservableComponent *newObservableComponent, ObservableComponent *interaction, set< Event > &faultEvents, set< Event > &normalEvents, set< Event > &observableEvents, set< Event > &sharedEvents, const set< string > &labelOfSharedEvents, map< string, set< vector< ObservableComponent *>::size_type > > &unknownScope, unsigned nbStateMin, unsigned nbStateMax, unsigned nbFaultMin, unsigned nbFaultMax, unsigned nbObsMin, unsigned nbObsMax, unsigned nbNormalMin, unsigned nbNormalMax)
list< Edge >::iterator OutEdgeIterator
Definition: Edge.hh:314
void setTimeOut(long delay)
boost::adjacency_list Graph
Definition: ScaleFree.cc:9
void generateModel(unsigned nbComp, unsigned connectivity, unsigned nbStateMin, unsigned nbStateMax, unsigned nbFaultMin, unsigned nbFaultMax, unsigned nbSharedMax, unsigned nbSharedMaxComp, unsigned nbObsMin, unsigned nbObsMax, unsigned nbNormalMin, unsigned nbNormalMax, Graph &topology, NodeMap< string > &compName, EdgeMap< set< unsigned > > &sharedEvnt, vector< ObservableComponent *> &setOfComponents)
void printError(string parameter, string message)
void generateLatexTopology(const Graph &topology, const NodeMap< string > &compName, const EdgeMap< set< long > > &sharedEvnt, ofstream &latexfile)
list< Edge >::iterator InEdgeIterator
Definition: Edge.hh:313
void generateLatexComponents(const vector< ObservableComponent *> &setOfComponents, ofstream &latexfile)
BAN::Graph topo
#define assertion(Exception, expr, message)
Definition: Assertion.hh:106