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