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

libFAUDES 2.34d --- 2026.03.11 --- c++ api documentaion by doxygen