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 #include "cfl_conflequiv.h"
25 
26 /* turn on debugging for this file */
27 //#undef FD_DF
28 //#define FD_DF(a) FD_WARN(a);
29 
30 namespace faudes {
31 
32 // Parallel(rGen1, rGen2, res)
33 void Parallel(const Generator& rGen1, const Generator& rGen2, Generator& rResGen) {
34  // helpers:
35  std::map< std::pair<Idx,Idx>, Idx> cmap;
36  // prepare result
37  Generator* pResGen = &rResGen;
38  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
39  pResGen= rResGen.New();
40  }
41  // doit
42  Parallel(rGen1, rGen2, cmap, *pResGen);
43  // copy result
44  if(pResGen != &rResGen) {
45  pResGen->Move(rResGen);
46  delete pResGen;
47  }
48 }
49 
50 
51 // Parallel for multiple Generators
52 void Parallel(
53  const GeneratorVector& rGenVec,
54  Generator& rResGen)
55 {
56  // helpers:
57  std::map< std::pair<Idx,Idx>, Idx> cmap;
58  // prepare result
59  rResGen.Clear();
60  bool rnames=rResGen.StateNamesEnabled();
61  // ignore empty
62  if(rGenVec.Size()==0) {
63  return;
64  }
65  // copy one
66  rResGen=rGenVec.At(0);
67  rResGen.StateNamesEnabled(rnames);
68  // run parallel
69  for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++) {
70  Parallel(rResGen,rGenVec.At(i),cmap,rResGen);
71  FD_DF("Parallel() cnt " << i << " states " << rResGen.Size());
72  FD_DF("Parallel() cnt " << i << " coreach " << rResGen.CoaccessibleSet().Size());
73  }
74 }
75 
76 // Parallel for multiple Generators, nonblocking part only
78  const GeneratorVector& rGenVec,
79  Generator& rResGen)
80 {
81  // helpers:
82  std::map< std::pair<Idx,Idx>, Idx> cmap;
83  // prepare result
84  rResGen.Clear();
85  bool rnames=rResGen.StateNamesEnabled();
86  // ignore empty
87  if(rGenVec.Size()==0) {
88  return;
89  }
90  // copy one
91  rResGen=rGenVec.At(0);
92  rResGen.StateNamesEnabled(rnames);
93  // run parallel
94  for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++) {
95  RemoveNonCoaccessibleOut(rResGen);
96  FD_DF("ParallelNB() cnt " << i << " certconf trans #" << rResGen.TransRel().Size());
97  Parallel(rResGen,rGenVec.At(i),cmap,rResGen);
98  FD_DF("ParallelNB() cnt " << i << " parallel trans #" << rResGen.TransRel().Size());
99  }
100 }
101 
102 // Parallel for Generators, transparent for event attributes.
104  const Generator& rGen1,
105  const Generator& rGen2,
106  Generator& rResGen)
107 {
108  FD_DF("aParallel(...)");
109 
110  // inputs have to agree on attributes of shared events:
111  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
112 
113  // prepare result
114  Generator* pResGen = &rResGen;
115  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
116  pResGen= rResGen.New();
117  }
118 
119  // make product composition of inputs
120  Parallel(rGen1,rGen2,*pResGen);
121 
122  // copy all attributes of input alphabets
123  if(careattr) {
124  pResGen->EventAttributes(rGen1.Alphabet());
125  pResGen->EventAttributes(rGen2.Alphabet());
126  }
127 
128  // copy result
129  if(pResGen != &rResGen) {
130  pResGen->Move(rResGen);
131  delete pResGen;
132  }
133 
134  FD_DF("aParallel(...): done");
135 }
136 
137 
138 // Parallel for multiple Generators, transparent for event attributes.
140  const GeneratorVector& rGenVec,
141  Generator& rResGen)
142 {
143 
144  // inputs have to agree on attributes of pairwise shared events:
145  bool careattr=true;
146  for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++)
147  for(GeneratorVector::Position j=0; j<i; j++)
148  if(!rGenVec.At(i).Alphabet().EqualAttributes(rGenVec.At(j).Alphabet()))
149  careattr=false;
150 
151  // ignore empty
152  if(rGenVec.Size()==0) {
153  return;
154  }
155 
156  // copy one
157  if(rGenVec.Size()==1) {
158  rResGen=rGenVec.At(0);
159  return;
160  }
161 
162  // run parallel
163  Parallel(rGenVec.At(0),rGenVec.At(1),rResGen);
164  for(GeneratorVector::Position i=2; i<rGenVec.Size(); i++)
165  Parallel(rGenVec.At(i),rResGen,rResGen);
166 
167  // fix alphabet
168  if(careattr) {
169  for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++)
170  rResGen.EventAttributes(rGenVec.At(i).Alphabet());
171  }
172 
173 }
174 
175 
176 // aParallel(rGen1, rGen2, rCompositionMap, res)
178  const Generator& rGen1,
179  const Generator& rGen2,
180  ProductCompositionMap& rCompositionMap,
181  Generator& rResGen)
182 {
183 
184  // inputs have to agree on attributes of shared events:
185  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
186 
187  // prepare result
188  Generator* pResGen = &rResGen;
189  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
190  pResGen= rResGen.New();
191  }
192 
193  // make product composition of inputs
194  Parallel(rGen1,rGen2,rCompositionMap.StlMap(),*pResGen);
195 
196  // copy all attributes of input alphabets
197  if(careattr) {
198  pResGen->EventAttributes(rGen1.Alphabet());
199  pResGen->EventAttributes(rGen2.Alphabet());
200  }
201 
202  // copy result
203  if(pResGen != &rResGen) {
204  pResGen->Move(rResGen);
205  delete pResGen;
206  }
207 
208 }
209 
210 // Parallel(rGen1, rGen2, rCompositionMap, res)
211 void Parallel(
212  const Generator& rGen1,
213  const Generator& rGen2,
214  ProductCompositionMap& rCompositionMap,
215  Generator& rResGen)
216 {
217  // make product composition of inputs
218  Parallel(rGen1,rGen2,rCompositionMap.StlMap(),rResGen);
219 }
220 
221 // Parallel(rGen1, rGen2, rCompositionMap, mark1, mark2, res)
222 void Parallel(
223  const Generator& rGen1, const Generator& rGen2,
224  ProductCompositionMap& rCompositionMap,
225  StateSet& rMark1,
226  StateSet& rMark2,
227  Generator& rResGen)
228 {
229 
230  // do the composition
231  Parallel(rGen1,rGen2,rCompositionMap,rResGen);
232 
233  // clear marking
234  rMark1.Clear();
235  rMark2.Clear();
236 
237  /*
238  see tmoor 20110208
239 
240  // catch special cases: a
241  if(rGen1.AlphabetSize()==0) {
242  rMark2=rGen2.MarkedStates();
243  return;
244  }
245 
246  // catch special cases: b
247  if(rGen2.AlphabetSize()==0) {
248  rMark1=rGen1.MarkedStates();
249  return;
250  }
251  */
252 
253  // retrieve marking from reverse composition map
254  StateSet::Iterator sit;
255  for(sit=rResGen.StatesBegin(); sit!=rResGen.StatesEnd(); ++sit) {
256  Idx s1=rCompositionMap.Arg1State(*sit);
257  Idx s2=rCompositionMap.Arg2State(*sit);
258  if(rGen1.ExistsMarkedState(s1)) rMark1.Insert(*sit);
259  if(rGen2.ExistsMarkedState(s2)) rMark1.Insert(*sit);
260  }
261 }
262 
263 
264 // Parallel(rGen1, rGen2, rCompositionMap, res)
265 void Parallel(
266  const Generator& rGen1, const Generator& rGen2,
267  std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
268  Generator& rResGen)
269 {
270  FD_DF("Parallel(" << &rGen1 << "," << &rGen2 << ")");
271 
272  /*
273  re-consider the special cases:
274 
275  if Sigma_1=0, we have either
276  -- L_res=L_2 (if L_1!=0)
277  -- L_res=0 (if L_1==0)
278 
279  the below special cases do not handle this correct,
280  nor do they setup the composition map; thus, we drop
281  the special cases; tmoor 20110208
282  */
283 
284  /*
285  // special case: empty alphabet
286  if(rGen1.AlphabetSize()==0) {
287  rResGen=rGen2;
288  rResGen.Name(rGen2.Name());
289  return;
290  }
291 
292  // special case: empty alphabet
293  if(rGen2.AlphabetSize()==0) {
294  rResGen=rGen1;
295  rResGen.Name(rGen1.Name());
296  return;
297  }
298  */
299 
300  // prepare result
301  Generator* pResGen = &rResGen;
302  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
303  pResGen= rResGen.New();
304  }
305  pResGen->Clear();
306  pResGen->Name(CollapsString(rGen1.Name()+"||"+rGen2.Name()));
307  rCompositionMap.clear();
308 
309  // create res alphabet
310  EventSet::Iterator eit;
311  for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
312  pResGen->InsEvent(*eit);
313  }
314  for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
315  pResGen->InsEvent(*eit);
316  }
317  FD_DF("Parallel: inserted indices in rResGen.alphabet( "
318  << pResGen->AlphabetToString() << ")");
319 
320  // shared events
321  EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
322  FD_DF("Parallel: shared events: " << sharedalphabet.ToString());
323 
324  // todo stack
325  std::stack< std::pair<Idx,Idx> > todo;
326  // current pair, new pair
327  std::pair<Idx,Idx> currentstates, newstates;
328  // state
329  Idx tmpstate;
330  StateSet::Iterator lit1,lit2;
331  TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
332  std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
333 
334  // push all combinations of initial states on todo stack
335  FD_DF("Parallel: adding all combinations of initial states to todo:");
336  for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
337  for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
338  currentstates = std::make_pair(*lit1, *lit2);
339  todo.push(currentstates);
340  tmpstate = pResGen->InsInitState();
341  rCompositionMap[currentstates] = tmpstate;
342  FD_DF("Parallel: (" << *lit1 << "|" << *lit2 << ") -> "
343  << rCompositionMap[currentstates]);
344  }
345  }
346 
347  // start algorithm
348  FD_DF("Parallel: processing reachable states:");
349  while (! todo.empty()) {
350  // allow for user interrupt
351  // LoopCallback();
352  // allow for user interrupt, incl progress report
353  FD_WPC(rCompositionMap.size(),rCompositionMap.size()+todo.size(),"Parallel(): processing");
354  // get next reachable state from todo stack
355  currentstates = todo.top();
356  todo.pop();
357  FD_DF("Parallel: processing (" << currentstates.first << "|"
358  << currentstates.second << ") -> "
359  << rCompositionMap[currentstates]);
360  // iterate over all rGen1 transitions
361  // (includes execution of shared events)
362  tit1 = rGen1.TransRelBegin(currentstates.first);
363  tit1_end = rGen1.TransRelEnd(currentstates.first);
364  for (; tit1 != tit1_end; ++tit1) {
365  // if event not shared
366  if (! sharedalphabet.Exists(tit1->Ev)) {
367  FD_DF("Parallel: exists only in rGen1");
368  newstates = std::make_pair(tit1->X2, currentstates.second);
369  // add to todo list if composition state is new
370  rcit = rCompositionMap.find(newstates);
371  if (rcit == rCompositionMap.end()) {
372  todo.push(newstates);
373  tmpstate = pResGen->InsState();
374  rCompositionMap[newstates] = tmpstate;
375  FD_DF("Parallel: todo push: (" << newstates.first << "|"
376  << newstates.second << ") -> "
377  << rCompositionMap[newstates]);
378  }
379  else {
380  tmpstate = rcit->second;
381  }
382  pResGen->SetTransition(rCompositionMap[currentstates], tit1->Ev, tmpstate);
383  FD_DF("Parallel: add transition to new generator: "
384  << rCompositionMap[currentstates] << "-" << tit1->Ev << "-"
385  << tmpstate);
386  }
387  // if shared event
388  else {
389  FD_DF("Parallel: common event");
390  // find shared transitions
391  tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
392  tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
393  for (; tit2 != tit2_end; ++tit2) {
394  newstates = std::make_pair(tit1->X2, tit2->X2);
395  // add to todo list if composition state is new
396  rcit = rCompositionMap.find(newstates);
397  if (rcit == rCompositionMap.end()) {
398  todo.push(newstates);
399  tmpstate = pResGen->InsState();
400  rCompositionMap[newstates] = tmpstate;
401  FD_DF("Parallel: todo push: (" << newstates.first << "|"
402  << newstates.second << ") -> "
403  << rCompositionMap[newstates]);
404  }
405  else {
406  tmpstate = rcit->second;
407  }
408  pResGen->SetTransition(rCompositionMap[currentstates],
409  tit1->Ev, tmpstate);
410  FD_DF("Parallel: add transition to new generator: "
411  << rCompositionMap[currentstates] << "-"
412  << tit1->Ev << "-" << tmpstate);
413  }
414  }
415  }
416  // iterate over all rGen2 transitions
417  // (without execution of shared events)
418  tit2 = rGen2.TransRelBegin(currentstates.second);
419  tit2_end = rGen2.TransRelEnd(currentstates.second);
420  for (; tit2 != tit2_end; ++tit2) {
421  if (! sharedalphabet.Exists(tit2->Ev)) {
422  FD_DF("Parallel: exists only in rGen2");
423  newstates = std::make_pair(currentstates.first, tit2->X2);
424  // add to todo list if composition state is new
425  rcit = rCompositionMap.find(newstates);
426  if (rcit == rCompositionMap.end()) {
427  todo.push(newstates);
428  tmpstate = pResGen->InsState();
429  rCompositionMap[newstates] = tmpstate;
430  FD_DF("Parallel: todo push: (" << newstates.first << "|"
431  << newstates.second << ") -> "
432  << rCompositionMap[newstates]);
433  }
434  else {
435  tmpstate = rcit->second;
436  }
437  pResGen->SetTransition(rCompositionMap[currentstates],
438  tit2->Ev, tmpstate);
439  FD_DF("Parallel: add transition to new generator: "
440  << rCompositionMap[currentstates] << "-"
441  << tit2->Ev << "-" << tmpstate);
442  }
443  }
444  }
445 
446  // set marked states
447  rcit=rCompositionMap.begin();
448  while(rcit!=rCompositionMap.end()) {
449  if(rGen1.ExistsMarkedState(rcit->first.first))
450  if(rGen2.ExistsMarkedState(rcit->first.second))
451  pResGen->SetMarkedState(rcit->second);
452  ++rcit;
453  }
454  FD_DF("Parallel: marked states: " << pResGen->MarkedStatesToString());
455 
456  // copy result
457  if(pResGen != &rResGen) {
458  rResGen = *pResGen;
459  delete pResGen;
460  }
461  // set statenames
462  if(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled())
463  SetComposedStateNames(rGen1, rGen2, rCompositionMap, rResGen);
464  else
465  rResGen.StateNamesEnabled(false);
466 }
467 
468 
469 // Product(rGen1, rGen2, res)
470 void Product(const Generator& rGen1, const Generator& rGen2, Generator& rResGen) {
471  std::map< std::pair<Idx,Idx>, Idx> cmap;
472  // doit
473  Product(rGen1, rGen2, cmap, rResGen);
474 }
475 
476 
477 // Product for Generators, transparent for event attributes.
478 void aProduct(
479  const Generator& rGen1,
480  const Generator& rGen2,
481  Generator& rResGen)
482 {
483 
484  // inputs have to agree on attributes of shared events:
485  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
486 
487  // prepare result
488  Generator* pResGen = &rResGen;
489  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
490  pResGen= rResGen.New();
491  }
492 
493  // make product composition of inputs
494  Product(rGen1,rGen2,*pResGen);
495 
496  // copy all attributes of input alphabets
497  if(careattr) {
498  pResGen->EventAttributes(rGen1.Alphabet());
499  pResGen->EventAttributes(rGen2.Alphabet());
500  }
501 
502  // copy result
503  if(pResGen != &rResGen) {
504  pResGen->Move(rResGen);
505  delete pResGen;
506  }
507 
508 }
509 
510 
511 // aProduct(rGen1, rGen2, rCompositionMap, res)
512 void aProduct(
513  const Generator& rGen1,
514  const Generator& rGen2,
515  ProductCompositionMap& rCompositionMap,
516  Generator& rResGen)
517 {
518  // inputs have to agree on attributes of shared events:
519  bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
520 
521  // prepare result
522  Generator* pResGen = &rResGen;
523  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
524  pResGen= rResGen.New();
525  }
526 
527  // make product composition of inputs
528  Product(rGen1,rGen2,rCompositionMap.StlMap(),*pResGen);
529 
530  // copy all attributes of input alphabets
531  if(careattr) {
532  pResGen->EventAttributes(rGen1.Alphabet());
533  pResGen->EventAttributes(rGen2.Alphabet());
534  }
535 
536  // copy result
537  if(pResGen != &rResGen) {
538  pResGen->Move(rResGen);
539  delete pResGen;
540  }
541 
542 }
543 
544 // Product(rGen1, rGen2, rCompositionMap, mark1, mark2, res)
545 void Product(
546  const Generator& rGen1, const Generator& rGen2,
547  std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
548  StateSet& rMark1,
549  StateSet& rMark2,
550  Generator& rResGen)
551 {
552 
553  // do the composition
554  Product(rGen1,rGen2,rCompositionMap,rResGen);
555 
556  // clear marking
557  rMark1.Clear();
558  rMark2.Clear();
559 
560  // retrieve marking from reverse composition map
561  std::map< std::pair<Idx,Idx>, Idx>::iterator rit;
562  for(rit=rCompositionMap.begin(); rit!=rCompositionMap.end(); ++rit){
563  if(rGen1.ExistsMarkedState(rit->first.first)) rMark1.Insert(rit->second);
564  if(rGen2.ExistsMarkedState(rit->first.second)) rMark2.Insert(rit->second);
565  }
566 }
567 
568 
569 // Product(rGen1, rGen2, rCompositionMap, res)
570 void Product(
571  const Generator& rGen1, const Generator& rGen2,
572  std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
573  Generator& rResGen)
574 {
575  FD_DF("Product(" << rGen1.Name() << "," << rGen2.Name() << ")");
576  FD_DF("Product(): state counts " << rGen1.Size() << "/" << rGen2.Size());
577 
578  // prepare result
579  Generator* pResGen = &rResGen;
580  if(&rResGen== &rGen1 || &rResGen== &rGen2) {
581  pResGen= rResGen.New();
582  }
583  pResGen->Clear();
584  rCompositionMap.clear();
585 
586  // shared alphabet
587  pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
588  FD_DF("Product: shared alphabet: "
589  << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
590 
591  // todo stack
592  std::stack< std::pair<Idx,Idx> > todo;
593  // current pair, new pair
594  std::pair<Idx,Idx> currentstates, newstates;
595  // state
596  Idx tmpstate;
597 
598  StateSet::Iterator lit1, lit2;
599  TransSet::Iterator tit1, tit1_end, tit2, tit2_end, tit2_begin;
600  std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
601 
602  // push all combinations of initial states on todo stack
603  FD_DF("Product: adding all combinations of initial states to todo:");
604  for (lit1 = rGen1.InitStatesBegin();
605  lit1 != rGen1.InitStatesEnd(); ++lit1) {
606  for (lit2 = rGen2.InitStatesBegin();
607  lit2 != rGen2.InitStatesEnd(); ++lit2) {
608  currentstates = std::make_pair(*lit1, *lit2);
609  todo.push(currentstates);
610  rCompositionMap[currentstates] = pResGen->InsInitState();
611  FD_DF("Product: (" << *lit1 << "|" << *lit2 << ") -> "
612  << rCompositionMap[currentstates]);
613  }
614  }
615 
616  // start algorithm
617  FD_DF("Product: processing reachable states:");
618  while (! todo.empty()) {
619  // allow for user interrupt
620  // LoopCallback();
621  // allow for user interrupt, incl progress report
622  FD_WPC(rCompositionMap.size(),rCompositionMap.size()+todo.size(),"Product(): processing");
623  // get next reachable state from todo stack
624  currentstates = todo.top();
625  todo.pop();
626  FD_DF("Product: processing (" << currentstates.first << "|"
627  << currentstates.second << ") -> " << rCompositionMap[currentstates]);
628  // iterate over all rGen1 and rGen2 transitions
629  tit1 = rGen1.TransRelBegin(currentstates.first);
630  tit1_end = rGen1.TransRelEnd(currentstates.first);
631  tit2 = rGen2.TransRelBegin(currentstates.second);
632  tit2_end = rGen2.TransRelEnd(currentstates.second);
633  while((tit1 != tit1_end) && (tit2 != tit2_end)) {
634  // sync event by tit1
635  if(tit1->Ev < tit2->Ev) {
636  ++tit1;
637  continue;
638  }
639  // sync event by tit2
640  if(tit1->Ev > tit2->Ev) {
641  ++tit2;
642  continue;
643  }
644  // shared event: iterate tit2
645  tit2_begin = tit2;
646  while(tit2 != tit2_end) {
647  // break iteration
648  if(tit1->Ev != tit2->Ev) break;
649  // successor composition state
650  newstates = std::make_pair(tit1->X2, tit2->X2);
651  // add to todo list if composition state is new
652  rcit = rCompositionMap.find(newstates);
653  if(rcit == rCompositionMap.end()) {
654  todo.push(newstates);
655  tmpstate = pResGen->InsState();
656  rCompositionMap[newstates] = tmpstate;
657  //if(tmpstate%1000==0)
658  FD_DF("Product: todo push: (" << newstates.first << "|"
659  << newstates.second << ") -> " << rCompositionMap[newstates] << " todo #" << todo.size());
660  } else {
661  tmpstate = rcit->second;
662  }
663  // set transition in result
664  pResGen->SetTransition(rCompositionMap[currentstates], tit1->Ev, tmpstate);
665  FD_DF("Product: add transition to new generator: "
666  << rCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
667  ++tit2;
668  }
669  // increment tit1
670  ++tit1;
671  // reset tit2 (needed for non-deterministic case)
672  if(tit1 != tit1_end)
673  if(tit1->Ev == tit2_begin->Ev)
674  tit2=tit2_begin;
675  }
676  } // todo
677 
678 
679  // set marked states (tmoor 2024: reorganised for performance)
680  rcit=rCompositionMap.begin();
681  while(rcit!=rCompositionMap.end()) {
682  if(rGen1.ExistsMarkedState(rcit->first.first))
683  if(rGen2.ExistsMarkedState(rcit->first.second))
684  pResGen->SetMarkedState(rcit->second);
685  ++rcit;
686  }
687  FD_DF("Parallel: marked states: " << pResGen->MarkedStatesToString());
688 
689  // copy result (TODO: use move)
690  if(pResGen != &rResGen) {
691  rResGen = *pResGen;
692  delete pResGen;
693  }
694  // set statenames
695  if(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled())
696  SetComposedStateNames(rGen1, rGen2, rCompositionMap, rResGen);
697  else
698  rResGen.ClearStateNames();
699 
700  FD_DF("Product(...): done");
701 }
702 
703 
704 
705 // SetParallelStateNames
707  const Generator& rGen1, const Generator& rGen2,
708  const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
709  Generator& rGen12)
710 {
711  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
712  for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++) {
713  Idx x1=rcit->first.first;
714  Idx x2=rcit->first.second;
715  Idx x12=rcit->second;
716  if(!rGen12.ExistsState(x12)) continue;
717  std::string name1= rGen1.StateName(x1);
718  if(name1=="") name1=ToStringInteger(x1);
719  std::string name2= rGen2.StateName(x2);
720  if(name2=="") name2=ToStringInteger(x2);
721  std::string name12= name1 + "|" + name2;
722  name12=rGen12.UniqueStateName(name12);
723  rGen12.StateName(x12,name12);
724  }
725 }
726 
727 
728 // CompositionMap1
730  const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
731  std::map<Idx,Idx>& rCompositionMap1)
732 {
733  rCompositionMap1.clear();
734  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
735  for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++)
736  rCompositionMap1.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
737 }
738 
739 
740 // CompositionMap2
742  const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
743  std::map<Idx,Idx>& rCompositionMap2)
744 {
745  rCompositionMap2.clear();
746  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
747  for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++)
748  rCompositionMap2.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
749 }
750 
751 
752 /**
753  * Rti wrapper class implementation
754  */
755 
756 // std faudes type
757 FAUDES_TYPE_IMPLEMENTATION(ProductCompositionMap,ProductCompositionMap,Type)
758 
759 // construct
761  mCompiled=true;
762 }
763 
764 // construct
766  DoAssign(rOther);
767 }
768 
769 // destruct
771 }
772 
773 // clear
775  mCompositionMap.clear();
776  mCompiled=true;
777  mArg1Map.clear();
778  mArg2Map.clear();
779 }
780 
781 // assignment
784  mCompiled=rSrc.mCompiled;
785  mArg1Map=rSrc.mArg1Map;
786  mArg2Map=rSrc.mArg2Map;
787 }
788 
789 // equality
791  return mCompositionMap==rOther.mCompositionMap;
792 }
793 
794 // C++/STL access
795 const std::map< std::pair<Idx,Idx> , Idx >& ProductCompositionMap::StlMap(void) const {
796  return mCompositionMap;
797 }
798 
799 // C++/STL access
800 std::map< std::pair<Idx,Idx> , Idx >& ProductCompositionMap::StlMap(void) {
801  mCompiled=false;
802  return mCompositionMap;
803 }
804 
805 // C++/STL access
806 void ProductCompositionMap::StlMap(const std::map< std::pair<Idx,Idx> , Idx >& rMap) {
807  mCompositionMap=rMap;
808  mCompiled=false;
809 }
810 
811 // access
813  std::pair<Idx,Idx> x12(x1,x2);
814  std::map< std::pair<Idx,Idx> , Idx >::const_iterator x12it=mCompositionMap.find(x12);
815  if(x12it==mCompositionMap.end()) return 0;
816  return x12it->second;
817 }
818 
819 // access
821  if(!mCompiled) {
822  mArg1Map.clear();
823  mArg2Map.clear();
824  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
825  for(rcit=mCompositionMap.begin(); rcit!=mCompositionMap.end(); rcit++) {
826  mArg1Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
827  mArg2Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
828  }
829  mCompiled=true;
830  }
831  std::map< Idx , Idx >::const_iterator x1it=mArg1Map.find(x1);
832  if(x1it==mArg1Map.end()) return 0;
833  return x1it->second;
834 }
835 
836 // access
838  if(!mCompiled) {
839  mArg1Map.clear();
840  mArg2Map.clear();
841  std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
842  for(rcit=mCompositionMap.begin(); rcit!=mCompositionMap.end(); rcit++) {
843  mArg1Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
844  mArg2Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
845  }
846  mCompiled=true;
847  }
848  std::map< Idx , Idx >::const_iterator x2it=mArg2Map.find(x2);
849  if(x2it==mArg2Map.end()) return 0;
850  return x2it->second;
851 }
852 
853 
854 
855 } // name space
#define FD_WPC(cntnow, contdone, message)
#define FD_DF(message)
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition: cfl_types.h:951
bool Exists(const Idx &rIndex) const
bool DoEqual(const ProductCompositionMap &rOther) const
Idx Arg1State(Idx s12) const
std::map< Idx, Idx > mArg2Map
Definition: cfl_parallel.h:73
std::map< Idx, Idx > mArg1Map
Definition: cfl_parallel.h:72
void DoAssign(const ProductCompositionMap &rSrc)
const std::map< std::pair< Idx, Idx >, Idx > & StlMap(void) const
Idx CompState(Idx s1, Idx s2) const
Idx Arg2State(Idx s12) const
std::map< std::pair< Idx, Idx >, Idx > mCompositionMap
Definition: cfl_parallel.h:69
std::vector< int >::size_type Position
virtual const T & At(const Position &pos) const
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Definition: cfl_transset.h:273
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_types.cpp:170
Idx Size(void) const
StateSet::Iterator StatesBegin(void) const
StateSet::Iterator InitStatesBegin(void) const
const TransSet & TransRel(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
const EventSet & Alphabet(void) const
virtual void Move(vGenerator &rGen)
std::string MarkedStatesToString(void) const
TransSet::Iterator TransRelBegin(void) const
EventSet::Iterator AlphabetBegin(void) const
virtual vGenerator * New(void) const
void ClearStateNames(void)
bool ExistsState(Idx index) const
std::string StateName(Idx index) const
void Name(const std::string &rName)
StateSet::Iterator StatesEnd(void) const
TransSet::Iterator TransRelEnd(void) const
void SetMarkedState(Idx index)
virtual void EventAttributes(const EventSet &rEventSet)
bool StateNamesEnabled(void) const
bool InsEvent(Idx index)
StateSet::Iterator InitStatesEnd(void) const
EventSet::Iterator AlphabetEnd(void) const
StateSet CoaccessibleSet(void) const
Idx Size(void) const
virtual void Clear(void)
bool ExistsMarkedState(Idx index) const
std::string AlphabetToString(void) const
std::string UniqueStateName(const std::string &rName) const
void InjectAlphabet(const EventSet &rNewalphabet)
virtual void Clear(void)
Definition: cfl_baseset.h:1919
bool EqualAttributes(const TBaseSet &rOtherSet) const
Definition: cfl_baseset.h:2213
Idx Size(void) const
Definition: cfl_baseset.h:1836
void Product(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void aParallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void aProduct(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
uint32_t Idx
void SetComposedStateNames(const Generator &rGen1, const Generator &rGen2, const std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, Generator &rGen12)
void RemoveNonCoaccessibleOut(Generator &g)
void ParallelNB(const GeneratorVector &rGenVec, Generator &rResGen)
void CompositionMap1(const std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, std::map< Idx, Idx > &rCompositionMap1)
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43
void CompositionMap2(const std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, std::map< Idx, Idx > &rCompositionMap2)
std::string CollapsString(const std::string &rString, unsigned int len)
Definition: cfl_utils.cpp:91

libFAUDES 2.33c --- 2025.05.15 --- c++ api documentaion by doxygen