cfl_parallel.cpp
Go to the documentation of this file.
1 /** @file cfl_parallel.cpp parallel composition */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2006 Bernd Opitz
6  Exclusive copyright is granted to Klaus Schmidt
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
21 
22 
23 #include "cfl_parallel.h"
24 
25 /* turn on debugging for this file */
26 //#undef FD_DF
27 //#define FD_DF(a) FD_WARN(a);
28 
29 namespace faudes {
30 
31 // Parallel(rGen1, rGen2, res)
32 void Parallel(const Generator& rGen1, const Generator& rGen2, Generator& rResGen) {
33  // helpers:
34  std::map< std::pair<Idx,Idx>, Idx> cmap;
35  // prepare result
36  Generator* pResGen = &rResGen;
37  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
38  pResGen= rResGen.New();
39  }
40  // doit
41  Parallel(rGen1, rGen2, cmap, *pResGen);
42  // copy result
43  if(pResGen != &rResGen) {
44  pResGen->Move(rResGen);
45  delete pResGen;
46  }
47 }
48 
49 
50 // Parallel for Generators, transparent for event attributes.
51 void aParallel(
52  const Generator& rGen1,
53  const Generator& rGen2,
54  Generator& rResGen)
55 {
56  FD_DF("aParallel(...)");
57 
58  // inputs have to agree on attributes of shared events:
59  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
60 
61  // prepare result
62  Generator* pResGen = &rResGen;
63  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
64  pResGen= rResGen.New();
65  }
66 
67  // make product composition of inputs
68  Parallel(rGen1,rGen2,*pResGen);
69 
70  // copy all attributes of input alphabets
71  if(careattr) {
72  pResGen->EventAttributes(rGen1.Alphabet());
73  pResGen->EventAttributes(rGen2.Alphabet());
74  }
75 
76  // copy result
77  if(pResGen != &rResGen) {
78  pResGen->Move(rResGen);
79  delete pResGen;
80  }
81 
82  FD_DF("aParallel(...): done");
83 }
84 
85 
86 // Parallel for multiple Generators, transparent for event attributes.
87 void aParallel(
88  const GeneratorVector& rGenVec,
89  Generator& rResGen)
90 {
91 
92  // inputs have to agree on attributes of pairwise shared events:
93  bool careattr=true;
94  for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++)
95  for(GeneratorVector::Position j=0; j<i; j++)
96  if(!rGenVec.At(i).Alphabet().EqualAttributes(rGenVec.At(j).Alphabet()))
97  careattr=false;
98 
99  // ignore empty
100  if(rGenVec.Size()==0) {
101  return;
102  }
103 
104  // copy one
105  if(rGenVec.Size()==1) {
106  rResGen=rGenVec.At(0);
107  return;
108  }
109 
110  // run parallel
111  Parallel(rGenVec.At(0),rGenVec.At(1),rResGen);
112  for(GeneratorVector::Position i=2; i<rGenVec.Size(); i++)
113  Parallel(rGenVec.At(i),rResGen,rResGen);
114 
115  // fix alphabet
116  if(careattr) {
117  for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++)
118  rResGen.EventAttributes(rGenVec.At(i).Alphabet());
119  }
120 
121 }
122 
123 
124 // aParallel(rGen1, rGen2, rCompositionMap, res)
126  const Generator& rGen1,
127  const Generator& rGen2,
128  ProductCompositionMap& rCompositionMap,
129  Generator& rResGen)
130 {
131 
132  // inputs have to agree on attributes of shared events:
133  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
134 
135  // prepare result
136  Generator* pResGen = &rResGen;
137  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
138  pResGen= rResGen.New();
139  }
140 
141  // make product composition of inputs
142  Parallel(rGen1,rGen2,rCompositionMap.StlMap(),*pResGen);
143 
144  // copy all attributes of input alphabets
145  if(careattr) {
146  pResGen->EventAttributes(rGen1.Alphabet());
147  pResGen->EventAttributes(rGen2.Alphabet());
148  }
149 
150  // copy result
151  if(pResGen != &rResGen) {
152  pResGen->Move(rResGen);
153  delete pResGen;
154  }
155 
156 }
157 
158 // Parallel(rGen1, rGen2, rCompositionMap, res)
159 void Parallel(
160  const Generator& rGen1,
161  const Generator& rGen2,
162  ProductCompositionMap& rCompositionMap,
163  Generator& rResGen)
164 {
165  // make product composition of inputs
166  Parallel(rGen1,rGen2,rCompositionMap.StlMap(),rResGen);
167 }
168 
169 // Parallel(rGen1, rGen2, rCompositionMap, mark1, mark2, res)
170 void Parallel(
171  const Generator& rGen1, const Generator& rGen2,
172  ProductCompositionMap& rCompositionMap,
173  StateSet& rMark1,
174  StateSet& rMark2,
175  Generator& rResGen)
176 {
177 
178  // do the composition
179  Parallel(rGen1,rGen2,rCompositionMap,rResGen);
180 
181  // clear marking
182  rMark1.Clear();
183  rMark2.Clear();
184 
185  /*
186  see tmoor 20110208
187 
188  // catch special cases: a
189  if(rGen1.AlphabetSize()==0) {
190  rMark2=rGen2.MarkedStates();
191  return;
192  }
193 
194  // catch special cases: b
195  if(rGen2.AlphabetSize()==0) {
196  rMark1=rGen1.MarkedStates();
197  return;
198  }
199  */
200 
201  // retrieve marking from reverse composition map
202  StateSet::Iterator sit;
203  for(sit=rResGen.StatesBegin(); sit!=rResGen.StatesEnd(); ++sit) {
204  Idx s1=rCompositionMap.Arg1State(*sit);
205  Idx s2=rCompositionMap.Arg2State(*sit);
206  if(rGen1.ExistsMarkedState(s1)) rMark1.Insert(*sit);
207  if(rGen2.ExistsMarkedState(s2)) rMark1.Insert(*sit);
208  }
209 }
210 
211 
212 // Parallel(rGen1, rGen2, rCompositionMap, res)
213 void Parallel(
214  const Generator& rGen1, const Generator& rGen2,
215  std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
216  Generator& rResGen)
217 {
218  FD_DF("Parallel(" << &rGen1 << "," << &rGen2 << ")");
219 
220  /*
221  re-consider the special cases:
222 
223  if Sigma_1=0, we have either
224  -- L_res=L_2 (if L_1!=0)
225  -- L_res=0 (if L_1==0)
226 
227  the below special cases do not handle this correct,
228  nor do they setup the composition map; thus, we drop
229  the special cases; tmoor 20110208
230  */
231 
232  /*
233  // special case: empty alphabet
234  if(rGen1.AlphabetSize()==0) {
235  rResGen=rGen2;
236  rResGen.Name(rGen2.Name());
237  return;
238  }
239 
240  // special case: empty alphabet
241  if(rGen2.AlphabetSize()==0) {
242  rResGen=rGen1;
243  rResGen.Name(rGen1.Name());
244  return;
245  }
246  */
247 
248  // prepare result
249  Generator* pResGen = &rResGen;
250  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
251  pResGen= rResGen.New();
252  }
253  pResGen->Clear();
254  pResGen->Name(CollapsString(rGen1.Name()+"||"+rGen2.Name()));
255  rCompositionMap.clear();
256 
257  // create res alphabet
258  EventSet::Iterator eit;
259  for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
260  pResGen->InsEvent(*eit);
261  }
262  for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
263  pResGen->InsEvent(*eit);
264  }
265  FD_DF("Parallel: inserted indices in rResGen.alphabet( "
266  << pResGen->AlphabetToString() << ")");
267 
268  // shared events
269  EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
270  FD_DF("Parallel: shared events: " << sharedalphabet.ToString());
271 
272  // todo stack
273  std::stack< std::pair<Idx,Idx> > todo;
274  // current pair, new pair
275  std::pair<Idx,Idx> currentstates, newstates;
276  // state
277  Idx tmpstate;
278  StateSet::Iterator lit1,lit2;
279  TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
280  std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
281 
282  // push all combinations of initial states on todo stack
283  FD_DF("Parallel: adding all combinations of initial states to todo:");
284  for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
285  for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
286  currentstates = std::make_pair(*lit1, *lit2);
287  todo.push(currentstates);
288  tmpstate = pResGen->InsInitState();
289  rCompositionMap[currentstates] = tmpstate;
290  FD_DF("Parallel: (" << *lit1 << "|" << *lit2 << ") -> "
291  << rCompositionMap[currentstates]);
292  }
293  }
294 
295  // start algorithm
296  FD_DF("Parallel: processing reachable states:");
297  while (! todo.empty()) {
298  // allow for user interrupt
299  // LoopCallback();
300  // allow for user interrupt, incl progress report
301  FD_WPC(rCompositionMap.size(),rCompositionMap.size()+todo.size(),"Parallel(): processing");
302  // get next reachable state from todo stack
303  currentstates = todo.top();
304  todo.pop();
305  FD_DF("Parallel: processing (" << currentstates.first << "|"
306  << currentstates.second << ") -> "
307  << rCompositionMap[currentstates]);
308  // iterate over all rGen1 transitions
309  // (includes execution of shared events)
310  tit1 = rGen1.TransRelBegin(currentstates.first);
311  tit1_end = rGen1.TransRelEnd(currentstates.first);
312  for (; tit1 != tit1_end; ++tit1) {
313  // if event not shared
314  if (! sharedalphabet.Exists(tit1->Ev)) {
315  FD_DF("Parallel: exists only in rGen1");
316  newstates = std::make_pair(tit1->X2, currentstates.second);
317  // add to todo list if composition state is new
318  rcit = rCompositionMap.find(newstates);
319  if (rcit == rCompositionMap.end()) {
320  todo.push(newstates);
321  tmpstate = pResGen->InsState();
322  rCompositionMap[newstates] = tmpstate;
323  FD_DF("Parallel: todo push: (" << newstates.first << "|"
324  << newstates.second << ") -> "
325  << rCompositionMap[newstates]);
326  }
327  else {
328  tmpstate = rcit->second;
329  }
330  pResGen->SetTransition(rCompositionMap[currentstates], tit1->Ev, tmpstate);
331  FD_DF("Parallel: add transition to new generator: "
332  << rCompositionMap[currentstates] << "-" << tit1->Ev << "-"
333  << tmpstate);
334  }
335  // if shared event
336  else {
337  FD_DF("Parallel: common event");
338  // find shared transitions
339  tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
340  tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
341  for (; tit2 != tit2_end; ++tit2) {
342  newstates = std::make_pair(tit1->X2, tit2->X2);
343  // add to todo list if composition state is new
344  rcit = rCompositionMap.find(newstates);
345  if (rcit == rCompositionMap.end()) {
346  todo.push(newstates);
347  tmpstate = pResGen->InsState();
348  rCompositionMap[newstates] = tmpstate;
349  FD_DF("Parallel: todo push: (" << newstates.first << "|"
350  << newstates.second << ") -> "
351  << rCompositionMap[newstates]);
352  }
353  else {
354  tmpstate = rcit->second;
355  }
356  pResGen->SetTransition(rCompositionMap[currentstates],
357  tit1->Ev, tmpstate);
358  FD_DF("Parallel: add transition to new generator: "
359  << rCompositionMap[currentstates] << "-"
360  << tit1->Ev << "-" << tmpstate);
361  }
362  }
363  }
364  // iterate over all rGen2 transitions
365  // (without execution of shared events)
366  tit2 = rGen2.TransRelBegin(currentstates.second);
367  tit2_end = rGen2.TransRelEnd(currentstates.second);
368  for (; tit2 != tit2_end; ++tit2) {
369  if (! sharedalphabet.Exists(tit2->Ev)) {
370  FD_DF("Parallel: exists only in rGen2");
371  newstates = std::make_pair(currentstates.first, tit2->X2);
372  // add to todo list if composition state is new
373  rcit = rCompositionMap.find(newstates);
374  if (rcit == rCompositionMap.end()) {
375  todo.push(newstates);
376  tmpstate = pResGen->InsState();
377  rCompositionMap[newstates] = tmpstate;
378  FD_DF("Parallel: todo push: (" << newstates.first << "|"
379  << newstates.second << ") -> "
380  << rCompositionMap[newstates]);
381  }
382  else {
383  tmpstate = rcit->second;
384  }
385  pResGen->SetTransition(rCompositionMap[currentstates],
386  tit2->Ev, tmpstate);
387  FD_DF("Parallel: add transition to new generator: "
388  << rCompositionMap[currentstates] << "-"
389  << tit2->Ev << "-" << tmpstate);
390  }
391  }
392  }
393 
394  // set marked states
395  rcit=rCompositionMap.begin();
396  while(rcit!=rCompositionMap.end()) {
397  if(rGen1.ExistsMarkedState(rcit->first.first))
398  if(rGen2.ExistsMarkedState(rcit->first.second))
399  pResGen->SetMarkedState(rcit->second);
400  ++rcit;
401  }
402  FD_DF("Parallel: marked states: " << pResGen->MarkedStatesToString());
403 
404  // copy result
405  if(pResGen != &rResGen) {
406  rResGen = *pResGen;
407  delete pResGen;
408  }
409  // set statenames
410  if(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled())
411  SetComposedStateNames(rGen1, rGen2, rCompositionMap, rResGen);
412  else
413  rResGen.StateNamesEnabled(false);
414 }
415 
416 
417 // Product(rGen1, rGen2, res)
418 void Product(const Generator& rGen1, const Generator& rGen2, Generator& rResGen) {
419  std::map< std::pair<Idx,Idx>, Idx> cmap;
420  // doit
421  Product(rGen1, rGen2, cmap, rResGen);
422 }
423 
424 
425 // Product for Generators, transparent for event attributes.
426 void aProduct(
427  const Generator& rGen1,
428  const Generator& rGen2,
429  Generator& rResGen)
430 {
431 
432  // inputs have to agree on attributes of shared events:
433  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
434 
435  // prepare result
436  Generator* pResGen = &rResGen;
437  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
438  pResGen= rResGen.New();
439  }
440 
441  // make product composition of inputs
442  Product(rGen1,rGen2,*pResGen);
443 
444  // copy all attributes of input alphabets
445  if(careattr) {
446  pResGen->EventAttributes(rGen1.Alphabet());
447  pResGen->EventAttributes(rGen2.Alphabet());
448  }
449 
450  // copy result
451  if(pResGen != &rResGen) {
452  pResGen->Move(rResGen);
453  delete pResGen;
454  }
455 
456 }
457 
458 
459 // aProduct(rGen1, rGen2, rCompositionMap, res)
460 void aProduct(
461  const Generator& rGen1,
462  const Generator& rGen2,
463  ProductCompositionMap& rCompositionMap,
464  Generator& rResGen)
465 {
466  // inputs have to agree on attributes of shared events:
467  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
468 
469  // prepare result
470  Generator* pResGen = &rResGen;
471  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
472  pResGen= rResGen.New();
473  }
474 
475  // make product composition of inputs
476  Product(rGen1,rGen2,rCompositionMap.StlMap(),*pResGen);
477 
478  // copy all attributes of input alphabets
479  if(careattr) {
480  pResGen->EventAttributes(rGen1.Alphabet());
481  pResGen->EventAttributes(rGen2.Alphabet());
482  }
483 
484  // copy result
485  if(pResGen != &rResGen) {
486  pResGen->Move(rResGen);
487  delete pResGen;
488  }
489 
490 }
491 
492 // Product(rGen1, rGen2, rCompositionMap, mark1, mark2, res)
493 void Product(
494  const Generator& rGen1, const Generator& rGen2,
495  std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
496  StateSet& rMark1,
497  StateSet& rMark2,
498  Generator& rResGen)
499 {
500 
501  // do the composition
502  Product(rGen1,rGen2,rCompositionMap,rResGen);
503 
504  // clear marking
505  rMark1.Clear();
506  rMark2.Clear();
507 
508  // retrieve marking from reverse composition map
509  std::map< std::pair<Idx,Idx>, Idx>::iterator rit;
510  for(rit=rCompositionMap.begin(); rit!=rCompositionMap.end(); ++rit){
511  if(rGen1.ExistsMarkedState(rit->first.first)) rMark1.Insert(rit->second);
512  if(rGen2.ExistsMarkedState(rit->first.second)) rMark2.Insert(rit->second);
513  }
514 }
515 
516 
517 // Product(rGen1, rGen2, rCompositionMap, res)
518 void Product(
519  const Generator& rGen1, const Generator& rGen2,
520  std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
521  Generator& rResGen)
522 {
523  FD_DF("Product(" << rGen1.Name() << "," << rGen2.Name() << ")");
524  FD_DF("Product(): state counts " << rGen1.Size() << "/" << rGen2.Size());
525 
526  // prepare result
527  Generator* pResGen = &rResGen;
528  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
529  pResGen= rResGen.New();
530  }
531  pResGen->Clear();
532  rCompositionMap.clear();
533 
534  // shared alphabet
535  pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
536  FD_DF("Product: shared alphabet: "
537  << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
538 
539  // todo stack
540  std::stack< std::pair<Idx,Idx> > todo;
541  // current pair, new pair
542  std::pair<Idx,Idx> currentstates, newstates;
543  // state
544  Idx tmpstate;
545 
546  StateSet::Iterator lit1, lit2;
547  TransSet::Iterator tit1, tit1_end, tit2, tit2_end, tit2_begin;
548  std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
549 
550  // push all combinations of initial states on todo stack
551  FD_DF("Product: adding all combinations of initial states to todo:");
552  for (lit1 = rGen1.InitStatesBegin();
553  lit1 != rGen1.InitStatesEnd(); ++lit1) {
554  for (lit2 = rGen2.InitStatesBegin();
555  lit2 != rGen2.InitStatesEnd(); ++lit2) {
556  currentstates = std::make_pair(*lit1, *lit2);
557  todo.push(currentstates);
558  rCompositionMap[currentstates] = pResGen->InsInitState();
559  FD_DF("Product: (" << *lit1 << "|" << *lit2 << ") -> "
560  << rCompositionMap[currentstates]);
561  }
562  }
563 
564  // start algorithm
565  FD_DF("Product: processing reachable states:");
566  while (! todo.empty()) {
567  // allow for user interrupt
568  // LoopCallback();
569  // allow for user interrupt, incl progress report
570  FD_WPC(rCompositionMap.size(),rCompositionMap.size()+todo.size(),"Product(): processing");
571  // get next reachable state from todo stack
572  currentstates = todo.top();
573  todo.pop();
574  FD_DF("Product: processing (" << currentstates.first << "|"
575  << currentstates.second << ") -> " << rCompositionMap[currentstates]);
576  // iterate over all rGen1 and rGen2 transitions
577  tit1 = rGen1.TransRelBegin(currentstates.first);
578  tit1_end = rGen1.TransRelEnd(currentstates.first);
579  tit2 = rGen2.TransRelBegin(currentstates.second);
580  tit2_end = rGen2.TransRelEnd(currentstates.second);
581  while((tit1 != tit1_end) && (tit2 != tit2_end)) {
582  // sync event by tit1
583  if(tit1->Ev < tit2->Ev) {
584  ++tit1;
585  continue;
586  }
587  // sync event by tit2
588  if(tit1->Ev > tit2->Ev) {
589  ++tit2;
590  continue;
591  }
592  // shared event: iterate tit2
593  tit2_begin = tit2;
594  while(tit2 != tit2_end) {
595  // break iteration
596  if(tit1->Ev != tit2->Ev) break;
597  // successor composition state
598  newstates = std::make_pair(tit1->X2, tit2->X2);
599  // add to todo list if composition state is new
600  rcit = rCompositionMap.find(newstates);
601  if(rcit == rCompositionMap.end()) {
602  todo.push(newstates);
603  tmpstate = pResGen->InsState();
604  rCompositionMap[newstates] = tmpstate;
605  //if(tmpstate%1000==0)
606  FD_DF("Product: todo push: (" << newstates.first << "|"
607  << newstates.second << ") -> " << rCompositionMap[newstates] << " todo #" << todo.size());
608  } else {
609  tmpstate = rcit->second;
610  }
611  // set transition in result
612  pResGen->SetTransition(rCompositionMap[currentstates], tit1->Ev, tmpstate);
613  FD_DF("Product: add transition to new generator: "
614  << rCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
615  ++tit2;
616  }
617  // increment tit1
618  ++tit1;
619  // reset tit2 (needed for non-deterministic case)
620  if(tit1 != tit1_end)
621  if(tit1->Ev == tit2_begin->Ev)
622  tit2=tit2_begin;
623  }
624  } // todo
625 
626 
627  // set marked states (tmoor 2024: reorganised for performance)
628  rcit=rCompositionMap.begin();
629  while(rcit!=rCompositionMap.end()) {
630  if(rGen1.ExistsMarkedState(rcit->first.first))
631  if(rGen2.ExistsMarkedState(rcit->first.second))
632  pResGen->SetMarkedState(rcit->second);
633  ++rcit;
634  }
635  FD_DF("Parallel: marked states: " << pResGen->MarkedStatesToString());
636 
637  // copy result (TODO: use move)
638  if(pResGen != &rResGen) {
639  rResGen = *pResGen;
640  delete pResGen;
641  }
642  // set statenames
643  if(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled())
644  SetComposedStateNames(rGen1, rGen2, rCompositionMap, rResGen);
645  else
646  rResGen.ClearStateNames();
647 
648  FD_DF("Product(...): done");
649 }
650 
651 
652 
653 // SetParallelStateNames
655  const Generator& rGen1, const Generator& rGen2,
656  const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
657  Generator& rGen12)
658 {
659  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
660  for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++) {
661  Idx x1=rcit->first.first;
662  Idx x2=rcit->first.second;
663  Idx x12=rcit->second;
664  if(!rGen12.ExistsState(x12)) continue;
665  std::string name1= rGen1.StateName(x1);
666  if(name1=="") name1=ToStringInteger(x1);
667  std::string name2= rGen2.StateName(x2);
668  if(name2=="") name2=ToStringInteger(x2);
669  std::string name12= name1 + "|" + name2;
670  name12=rGen12.UniqueStateName(name12);
671  rGen12.StateName(x12,name12);
672  }
673 }
674 
675 
676 // CompositionMap1
678  const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
679  std::map<Idx,Idx>& rCompositionMap1)
680 {
681  rCompositionMap1.clear();
682  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
683  for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++)
684  rCompositionMap1.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
685 }
686 
687 
688 // CompositionMap2
690  const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
691  std::map<Idx,Idx>& rCompositionMap2)
692 {
693  rCompositionMap2.clear();
694  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
695  for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++)
696  rCompositionMap2.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
697 }
698 
699 
700 /**
701  * Rti wrapper class implementation
702  */
703 
704 // std faudes type
705 FAUDES_TYPE_IMPLEMENTATION(ProductCompositionMap,ProductCompositionMap,Type)
706 
707 // construct
709  mCompiled=true;
710 }
711 
712 // construct
714  DoAssign(rOther);
715 }
716 
717 // destruct
719 }
720 
721 // clear
723  mCompositionMap.clear();
724  mCompiled=true;
725  mArg1Map.clear();
726  mArg2Map.clear();
727 }
728 
729 // assignment
732  mCompiled=rSrc.mCompiled;
733  mArg1Map=rSrc.mArg1Map;
734  mArg2Map=rSrc.mArg2Map;
735 }
736 
737 // equality
739  return mCompositionMap==rOther.mCompositionMap;
740 }
741 
742 // C++/STL access
743 const std::map< std::pair<Idx,Idx> , Idx >& ProductCompositionMap::StlMap(void) const {
744  return mCompositionMap;
745 }
746 
747 // C++/STL access
748 std::map< std::pair<Idx,Idx> , Idx >& ProductCompositionMap::StlMap(void) {
749  mCompiled=false;
750  return mCompositionMap;
751 }
752 
753 // C++/STL access
754 void ProductCompositionMap::StlMap(const std::map< std::pair<Idx,Idx> , Idx >& rMap) {
755  mCompositionMap=rMap;
756  mCompiled=false;
757 }
758 
759 // access
761  std::pair<Idx,Idx> x12(x1,x2);
762  std::map< std::pair<Idx,Idx> , Idx >::const_iterator x12it=mCompositionMap.find(x12);
763  if(x12it==mCompositionMap.end()) return 0;
764  return x12it->second;
765 }
766 
767 // access
769  if(!mCompiled) {
770  mArg1Map.clear();
771  mArg2Map.clear();
772  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
773  for(rcit=mCompositionMap.begin(); rcit!=mCompositionMap.end(); rcit++) {
774  mArg1Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
775  mArg2Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
776  }
777  mCompiled=true;
778  }
779  std::map< Idx , Idx >::const_iterator x1it=mArg1Map.find(x1);
780  if(x1it==mArg1Map.end()) return 0;
781  return x1it->second;
782 }
783 
784 // access
786  if(!mCompiled) {
787  mArg1Map.clear();
788  mArg2Map.clear();
789  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
790  for(rcit=mCompositionMap.begin(); rcit!=mCompositionMap.end(); rcit++) {
791  mArg1Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
792  mArg2Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
793  }
794  mCompiled=true;
795  }
796  std::map< Idx , Idx >::const_iterator x2it=mArg2Map.find(x2);
797  if(x2it==mArg2Map.end()) return 0;
798  return x2it->second;
799 }
800 
801 
802 
803 } // name space
#define FD_WPC(cntnow, contdone, message)
Application callback: optional write progress report to console or application, incl count
#define FD_DF(message)
Debug: optional report on user functions.
parallel composition
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
faudes type implementation macros, overall
Definition: cfl_types.h:946
Set of indices.
Definition: cfl_indexset.h:78
Idx Insert(void)
Insert new index to set.
Set of indices with symbolic names.
Definition: cfl_nameset.h:69
bool Exists(const Idx &rIndex) const
Test existence of index.
Rti-wrapper for composition maps.
Definition: cfl_parallel.h:43
bool DoEqual(const ProductCompositionMap &rOther) const
virtual void Clear(void)
Clear configuration data.
Idx Arg1State(Idx s12) const
std::map< Idx, Idx > mArg2Map
Definition: cfl_parallel.h:68
std::map< Idx, Idx > mArg1Map
Definition: cfl_parallel.h:67
void DoAssign(const ProductCompositionMap &rSrc)
const std::map< std::pair< Idx, Idx >, Idx > & StlMap(void) const
ProductCompositionMap(void)
Rti wrapper class implementation.
Idx CompState(Idx s1, Idx s2) const
Idx Arg2State(Idx s12) const
std::map< std::pair< Idx, Idx >, Idx > mCompositionMap
Definition: cfl_parallel.h:64
std::vector< int >::size_type Position
convenience typedef for positions
virtual const T & At(const Position &pos) const
Access element.
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Iterator on transition.
Definition: cfl_transset.h:269
Base class of all libFAUDES objects that participate in the run-time interface.
Definition: cfl_types.h:239
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Write configuration data to a string.
Definition: cfl_types.cpp:169
Idx Size(void) const
Get size of vector.
Base class of all FAUDES generators.
StateSet::Iterator StatesBegin(void) const
Iterator to Begin() of state set.
StateSet::Iterator InitStatesBegin(void) const
Iterator to Begin() of mInitStates.
bool SetTransition(Idx x1, Idx ev, Idx x2)
Add a transition to generator by indices.
const EventSet & Alphabet(void) const
Return const reference to alphabet.
virtual void Move(vGenerator &rGen)
Destructive copy to other vGenerator.
std::string MarkedStatesToString(void) const
Write set of marked states to a string (no re-indexing)
TransSet::Iterator TransRelBegin(void) const
Iterator to Begin() of transition relation.
EventSet::Iterator AlphabetBegin(void) const
Iterator to Begin() of alphabet.
virtual vGenerator * New(void) const
Construct on heap.
void ClearStateNames(void)
Remove all names from generator's StateSymbolTable.
bool ExistsState(Idx index) const
Test existence of state in state set.
std::string StateName(Idx index) const
State name lookup.
void Name(const std::string &rName)
Set the generator's name.
StateSet::Iterator StatesEnd(void) const
Iterator to End() of state set.
TransSet::Iterator TransRelEnd(void) const
Iterator to End() of transition relation.
Idx InsState(void)
Add new anonymous state to generator.
void SetMarkedState(Idx index)
Set an existing state as marked state by index.
Idx InsInitState(void)
Create new anonymous state and set as initial state.
virtual void EventAttributes(const EventSet &rEventSet)
Set attributes for existing events.
bool StateNamesEnabled(void) const
Whether libFAUEDS functions are requested to generate state names.
bool InsEvent(Idx index)
Add an existing event to alphabet by index.
StateSet::Iterator InitStatesEnd(void) const
Iterator to End() of mInitStates.
EventSet::Iterator AlphabetEnd(void) const
Iterator to End() of alphabet.
Idx Size(void) const
Get generator size (number of states)
virtual void Clear(void)
Clear generator data.
bool ExistsMarkedState(Idx index) const
Test existence of state in mMarkedStates.
std::string AlphabetToString(void) const
Write generators alphabet to string.
std::string UniqueStateName(const std::string &rName) const
Create a new unique symbolic state name.
void InjectAlphabet(const EventSet &rNewalphabet)
Set mpAlphabet without consistency check.
virtual void Clear(void)
Clear all set.
Definition: cfl_baseset.h:1902
bool EqualAttributes(const TBaseSet &rOtherSet) const
Attribute access.
Definition: cfl_baseset.h:2196
void Product(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Product composition.
void aParallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Parallel composition.
void aProduct(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Product composition.
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Parallel composition.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
void SetComposedStateNames(const Generator &rGen1, const Generator &rGen2, const std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, Generator &rGen12)
Helper: uses composition map to track state names in a paralell composition.
void CompositionMap1(const std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, std::map< Idx, Idx > &rCompositionMap1)
std::string CollapsString(const std::string &rString, unsigned int len)
Limit length of string, return head and tail of string.
Definition: cfl_helper.cpp:91
std::string ToStringInteger(Int number)
integer to string
Definition: cfl_helper.cpp:43
void CompositionMap2(const std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, std::map< Idx, Idx > &rCompositionMap2)

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen