syn_compsyn.cpp
Go to the documentation of this file.
1/** @file syn_compsyn.cpp Compositional synthesis */
2
3/* FAU Discrete Event Systems Library (libfaudes)
4
5 Copyright (C) 2015 Hao Zhou
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/*
24Notes:
25
26This file is a copy edited version of the "syn_supnbcon.h",
27"syn_supnbcon.cpp", "libzhou.h" and "libzhou.cpp", originally
28written by Hao Zhou in course of his Master Thesis. The merge is
29meant to minimise the public interface and to decouple side
30effects of further development of libFAUDES.
31
32Relevant literature:
33
34"On Compostional Approaches for Discrete Event Systems Verification and Synthesis"
35Sahar Mohajerani, PhD, Sweden, 2015
36
37
38*/
39
40#include "syn_compsyn.h"
41#include "syn_synthequiv.h"
42#include "corefaudes.h"
43
44namespace faudes {
45
46/*
47****************************************************************
48PART A: Class "ComSyn"
49
50This class provides a buffer for input and output data to
51iteratively apply indivual algorithms for compositional synthesis
52
53****************************************************************
54*/
55
56class ComSyn {
57
58 public:
59
60 /**
61 * Constructer:
62 * construct the synthesis-buffer for running compositional synthesis algorithmus
63 * and initialize the map and supervisors.
64 *
65 * Input:
66 * @param rPlantGenVec
67 * plant generator-vector
68 * @param rConAlph
69 * controllable events
70 * @param rSpecGenVec
71 * specification generator-vector
72 *
73 * Output:
74 * @param rMapEventsToPlant
75 * map the events in supervisor to plant
76 * @param rDisGenVec
77 * distinguisher generator-vector
78 * @param rSupGenVec
79 * supervisor generator-vector
80 */
81 ComSyn(const GeneratorVector& rPlantGenVec,
82 const EventSet& rConAlph,
83 const GeneratorVector& rSpecGenVec,
84 std::map<Idx,Idx>& rMapEventsToPlant,
85 GeneratorVector& rDisGenVec,
86 GeneratorVector& rSupGenVec);
87
88 /**
89 * Destructer
90 */
91 ~ComSyn(void);
92
93 /**
94 * Preprocess:
95 * firstly abstract every generator in synthesis-buffer before running synthesis-algorithmus
96 */
97 void Preprocess(void);
98
99 /**
100 * Compositional Synthesis Algorithmus after Preprocess
101 */
102 void Synthesis(void);
103
104
105 private:
106
107 /**
108 * global controllable events
109 */
111
112 /**
113 * synthesis-buffer
114 */
116
117 /**
118 * keep reference to event-map
119 */
120 std::map<Idx,Idx>* pMapEventsToPlant;
121
122 /**
123 * keep reference to distinguisher-generator
124 */
126
127 /**
128 * keep reference to supervisor-generator
129 */
131
132 /**
133 * keep reference to EventSymbolTable
134 */
136
137 /**
138 * the termination-event
139 */
141
142 /**
143 * the union of eventset from generators but without a speicified generator
144 *
145 * @param rGenVec
146 * the generators which to be extracted
147 * @param WithoutMe
148 * the specified generator
149 * @param rRestAlph
150 * result
151 */
152 void SetPartUnion(const GeneratorVector& rGenVec,
154 EventSet& rRestAlph);
155 /**
156 * adjust bisimulation relation to compositional synthesis
157 *
158 * @param rGen
159 * the adjusted generator
160 */
162
163};
164
165
166/*
167****************************************************************
168PART B: Subroutines for compositional synthesis algorithm
169
170****************************************************************
171*/
172
173
174/**
175 * translate specification into plant
176 *
177 * @param rSpecGenVec
178 * specification generator-vector
179 * @param rGUncAlph
180 * global uncontrollable events
181 * @param rResGenVec
182 * synthesis-buffer
183 */
184void TransSpec(const GeneratorVector& rSpecGenVec,
185 const EventSet& rGUncAlph,
186 GeneratorVector& rResGenVec);
187
188/**
189 * weak synthesis obeservation equivalence [not implemented]
190 *
191 * @param rGenOrig
192 * original generator
193 * @param rConAlph
194 * controllable events
195 * @param rLocAlph
196 * local events
197 * @param rMapStateToPartition
198 * map state to equivalent class
199 * @param rResGen
200 * the quotient automaton
201 */
202void ComputeWSOE(const Generator& rGenOrig,
203 const EventSet& rConAlph,
204 const EventSet& rLocAlph,
205 std::map<Idx,Idx>& rMapStateToPartition,
206 Generator& rResGen);
207
208/**
209 * remove the events from the entire buffer which have only selfloop transitions
210 *
211 * @param rGenVec
212 * synthesis-buffer
213 */
214void GlobalSelfloop(GeneratorVector& rGenVec);
215
216
217/**
218 * remove the events from a generator which have only selfloop transitions
219 *
220 * @param rGen
221 * generator which is to be abstracted
222 * @param rLocAlph
223 * local events
224 */
225void LocalSelfloop(Generator& rGen, EventSet& rLocAlph);
226
227
228/**
229 * make a distinguisher and a map for solving nondeterminism
230 * and rewrite abstracted automaton
231 *
232 * @param AbstGen
233 * the abstracted generator
234 * @param rMapStateToPartition
235 * map state to equivalent class
236 * @param OrigGen
237 * the non-abstracted generator (after halbway-synthesis bevor abstraction)
238 * @param rMapOldToNew
239 * map the replaced events to new events
240 */
241void MakeDistinguisher(Generator& AbstGen,
242 std::map<Idx,Idx>& rMapStateToPartition,
243 Generator& OrigGen,
244 std::map<Idx,std::vector<Idx> >& rMapOldToNew);
245
246
247/**
248 * update the generators in synthesis-buffer and in supervisor with new events
249 *
250 * @param rMapOldToNew
251 * map the replaced events to new events
252 * @param rConAlph
253 * controllable events
254 * @param rGenVec
255 * synthesis-buffer
256 * @param rMapEventsToPlant
257 * map the events in supervisor to plant
258 * @param rDisGenVec
259 * distinguisher generator-vector
260 * @param rSupGenVec
261 * supervisor generator-vector
262 */
263void Splitter(const std::map<Idx, std::vector<Idx> >& rMapOldToNew,
264 EventSet& rConAlph,
265 GeneratorVector& rGenVec,
266 std::map<Idx,Idx>& rMapEventsToPlant,
267 GeneratorVector& rDisGenVec,
268 GeneratorVector& rSupGenVec);
269
270
271/**
272 * heuristic:
273 * vorious approaches to select subsystem from synthesis-buffer then compose them
274 * and remove them from buffer.
275 * 1. determine subsystem
276 * 2. parallel composition for subsystem
277 * 3. delete subsystem from "GenVec"
278 *
279 * @param rGenVec
280 * synthesis-buffer
281 * @param rResGen
282 * the composed new generator
283 */
285 Generator& rResGen);
286
288 Generator& rResGen);
289
290/**
291 * halbway-synthesis
292 *
293 * @param rOrigGen
294 * the resulting composed new generator from synthesis-buffer
295 * @param rConAlph
296 * controllable events
297 * @param rLocAlph
298 * local events
299 * @param rHSupGen
300 * the resulting generator after halbway-synthesis
301 */
302void ComputeHSupCon(const Generator& rOrigGen,
303 const EventSet& rConAlph,
304 const EventSet& rLocAlph,
305 Generator& rHSupGen);
306
307
308
309/*
310****************************************************************
311PART C: implementation of all of the above
312
313****************************************************************
314*/
315
316
317// Constructor
318ComSyn::ComSyn(const GeneratorVector& rPlantGenVec,
319 const EventSet& rConAlph,
320 const GeneratorVector& rSpecGenVec,
321 std::map<Idx,Idx>& rMapEventsToPlant,
322 GeneratorVector& rDisGenVec,
323 GeneratorVector& rSupGenVec)
324{
325 // write reference to output
326 pMapEventsToPlant = &rMapEventsToPlant;
327 pDisGenVec = &rDisGenVec;
328 pSupGenVec = &rSupGenVec;
329
330 // construct global controllable events
331 GConAlph.Assign(rConAlph);
332
333 // construct global events
334 EventSet GAlph;
335 SetUnion(rPlantGenVec, GAlph);
336 EventSet GSpecAlph;
337 SetUnion(rSpecGenVec, GSpecAlph);
338 SetUnion(GAlph, GSpecAlph, GAlph);
339
340 // initialize map
341 EventSet::Iterator eit=GAlph.Begin();
342 for(; eit!=GAlph.End(); ++eit) rMapEventsToPlant[*eit]=*eit;
343
344 // construct global uncontrollable events
345 EventSet GUncAlph;
346 SetDifference(GAlph, GConAlph, GUncAlph);
347
348 // take a copy of plant-generators for synthese-buffer and supervisors
350 for(; pos < rPlantGenVec.Size(); ++pos) {
351 GenVec.PushBack(rPlantGenVec.At(pos));
352 pSupGenVec->PushBack(rPlantGenVec.At(pos));
353 }
354
355 // take a copy of specification-generators for supervisors
356 pos=0;
357 for(; pos < rSpecGenVec.Size(); ++pos)
358 pSupGenVec->PushBack(rSpecGenVec.At(pos));
359
360 // translation of specifications into plants
361
362 TransSpec(rSpecGenVec, GUncAlph, GenVec);
363
364 // add a new event for termination in event-symboltable
366 std::string wname = pEvSymTab->UniqueSymbol("WEvent");
367 w = pEvSymTab->InsEntry(wname);
368
369 // add w to controllable events
371
372 // add w and w-selfloop to every automat in GenVec
373 pos=0;
374 for(; pos < GenVec.Size(); ++pos) {
375 GenVec.At(pos).InsEvent(w);
376 StateSet::Iterator sit = GenVec.At(pos).MarkedStatesBegin();
377 for(; sit != GenVec.At(pos).MarkedStatesEnd(); ++sit)
378 GenVec.At(pos).SetTransition(*sit, w, *sit);
379 }
380
381}
382
383
384// void ComSyn::Preprocess(void);
386{
387 // helpers
388 EventSet RestAlph; // global alphabet without the specified generator
389 EventSet LocAlph; // local alphabet of the specified generator
390 EventSet ConAlph; // local controllable events in the specified generator
391
392 Generator AbstGen; // generator after abstraction
393
394 // a state map from "HSupGen" to "AbstGen"
395 std::map<Idx,Idx> MapStateToPartition;
396
397 // a map in which a event[original] (the first idx) -
398 // is replaced by two events[alias] (the second idx)
399 std::map<Idx,std::vector<Idx> > MapOldToNew;
400
401 // loop for GenVec
403 for(; i < GenVec.Size(); ++i) {
404
405 // build related eventset
406 // ****from class private ****
407 SetPartUnion(GenVec, i, RestAlph);
408 // construct local alphabet of OrigGen
409 SetDifference(GenVec.At(i).Alphabet(), RestAlph, LocAlph);
410 // construct controllable alphabet of OrigGen
411 SetIntersection(GenVec.At(i).Alphabet(), GConAlph, ConAlph);
412
413 //GenVec.At(i).Write();
414 // abstraction rule -> SOE
415
416 ComputeSynthObsEquiv(GenVec.At(i), ConAlph, LocAlph, MapStateToPartition, AbstGen);
417 //AbstGen.Write();
418
419 // abstraction rule -> remove local events if it hat only selfloop-transitions
420 LocalSelfloop(AbstGen, LocAlph);
421
422 // abstraction rule -> give up the AbstGen if it hat only one state
423 if(AbstGen.Size() == 1) {
424 GenVec.Erase(i--);
425 continue;
426 }
427
428 // replace the OrigGen by AbstGen if AbstGen is deterministic
429 if(IsDeterministic(AbstGen))
430 GenVec.Replace(i, AbstGen);
431
432 else {
433
434 // rewrite OrigGen, AbstGen and construct the related MapOldToNewMap
435 MakeDistinguisher(AbstGen, MapStateToPartition, GenVec.At(i), MapOldToNew);
436
437 // remove w
438 GenVec.At(i).DelEvent(w);
439 // set a new name for distinguisher
440 std::stringstream str_dis;
441 str_dis<<" Distinguisher from "<<GenVec.At(i).Name();
442 GenVec.At(i).Name(str_dis.str());
443 // save distinguisher
445
446 // replace the OrigGen by AbstGen in GenVec
447 GenVec.Replace(i, AbstGen);
448
449
450 Splitter(MapOldToNew, GConAlph, GenVec,
452 }
453 }
454
455 // abstraction rule -> GlobalSelfloop
456
458}
459
460
461// void ComSyn::Synthesis(void);
463{
464 // helpers
465 EventSet RestAlph; // global alphabet without the current generator
466 EventSet LocAlph; // local alphabet of the specified generator
467 EventSet ConAlph; // controllable events in the specified generator
468
469 Generator OrigGen; // generator after synchronisation
470 Generator HSupGen; // generator after halbway-synthsis
471 Generator AbstGen; // generator after abstraction
472
473 // a state map from "HSupGen" to "AbstGen"
474 std::map<Idx,Idx> MapStateToPartition;
475
476 // a map in which a event[original] (the first idx) -
477 // is replaced by two events[alias] (the second idx)
478 std::map<Idx,std::vector<Idx> > MapOldToNew;
479
480 // loop for GenVec
481 while(GenVec.Size() > 1) {
482
483 // Step 1: Select subsystem and compose them, then remove subsystem from buffer
484
485 SelectSubsystem_V1(GenVec, OrigGen);
486 // set default state name of OrigGen
487 OrigGen.SetDefaultStateNames();
488 // test
489 ////////////////////////////////////////////////////////////////
490
491 // Step 2: construct related events
492 SetUnion(GenVec, RestAlph);
493 SetDifference(OrigGen.Alphabet(), RestAlph, LocAlph);
494 SetIntersection(OrigGen.Alphabet(), GConAlph, ConAlph);
495 // test
496 ////////////////////////////////////////////////////////////////
497
498 // Step 3: abstraction rule -> halbway synthesis
499
500 ComputeHSupCon(OrigGen, ConAlph, LocAlph, HSupGen);
501 // test
502 //HSupGen.Write();
503 ////////////////////////////////////////////////////////////////
504
505 // Step 4: compare HSupGen with OrigGen
506 if(HSupGen.TransRelSize() < OrigGen.TransRelSize()) {
507 // add to supervisors
508 pSupGenVec->PushBack(HSupGen);
509 // remove w
511 }
512 // test
513 ////////////////////////////////////////////////////////////////
514
515 // Step 5: abstraction rule -> bisimulation
516 // an additional interface for function ComputeBisimulation
517
519 // test
520 ////////////////////////////////////////////////////////////////
521
522 // Step 6: abstraction rule -> bisimulation
523
524 ComputeSynthObsEquiv(HSupGen, ConAlph, LocAlph, MapStateToPartition, AbstGen);
525 // test
526 ////////////////////////////////////////////////////////////////
527
528 // Step 7: abstraction rule -> LocalSelfloop
529 // remove local events if it hat only selfloop-transitions
530
531 LocalSelfloop(AbstGen, LocAlph);
532 // test
533 ////////////////////////////////////////////////////////////////
534
535 // Step 8 : test determinism
536 // take a copy of AbstGen to buffer if AbstGen is deterministic
537 if(IsDeterministic(AbstGen))
538 GenVec.PushBack(AbstGen);
539 else {
540 // rewrite HSupGen, AbstGen and construct the related MapOldToNewMap
541
542 MakeDistinguisher(AbstGen, MapStateToPartition, HSupGen, MapOldToNew);
543
544 // remove w
545 HSupGen.DelEvent(w);
546 // set a new name for distinguisher
547 std::stringstream str_dis;
548 str_dis<<" Distinguisher from "<<HSupGen.Name();
549 HSupGen.Name(str_dis.str());
550 // rSupGenVec take a copy of HSupGen (HSupGen is now a distinguisher)
551 pDisGenVec->PushBack(HSupGen);
552
553 // let GenVec take a copy of AbstGen
554 GenVec.PushBack(AbstGen);
555
556 // update the event everywhere
557
558 Splitter(MapOldToNew, GConAlph, GenVec,
560 }
561 }
562}
563
564
565// Destructer
567{
569}
570
571
572// SetPartUnion
575 EventSet& rRestAlph) {
576 // clear date
577 rRestAlph.Clear();
578
579 // loop
581 for(; i < rGenVec.Size(); ++i)
582 if(i != WithoutMe) rRestAlph.InsertSet(rGenVec.At(i).Alphabet());
583}
584
585
586// comsyn_ComputeBisimulation
588{
589 // prepare data for interface ComputeBisimulation of libfaudes
590 faudes::Generator OrigGen;
591 OrigGen.Assign(rGen);
592 std::map<faudes::Idx,faudes::Idx> MapStateToPartition;
593
594 // run interface
595 ComputeBisimulation(OrigGen, MapStateToPartition, rGen);
596}
597
598
599////////////////////////////////////////////////////////////////
600// TransSpec
601////////////////////////////////////////////////////////////////
602
603// subfunction for TransSpec
604void SingleTransSpec(const Generator& rSpecGen,
605 const EventSet& rUncAlph,
606 Generator& rResGen) {
607
608 // copy the particular specification generator to rResGen
609 rResGen.Assign(rSpecGen);
610
611 // construct local uncontrollable alphabet
612 EventSet UncAlph;
613 SetIntersection(rUncAlph, rResGen.Alphabet(), UncAlph);
614
615 // test the need
616 if(UncAlph.Empty()) return;
617
618 // helpers
619 TransSet toadd;
620 EventSet todo;
621 Generator gen;
622 Idx temp = 1; // not used, only take place
623
624 // loop for every state in the rResGen
625 StateSet::Iterator sit = rResGen.StatesBegin();
626 for(; sit != rResGen.StatesEnd(); ++sit){
627 // build todo that will to be used for setting new Transitions
628 todo.Clear();
629 SetDifference(UncAlph, rResGen.ActiveEventSet(*sit), todo);
630 // loop for setting transitions if todo is not empty
631 EventSet::Iterator eit=todo.Begin();
632 for(; eit != todo.End(); ++eit) toadd.Insert(*sit, *eit, temp);
633 }
634
635 // no need to insert new state if toadd is empty
636 if(toadd.Empty()) return;
637 // add a new blocking state to rResGen
638 Idx bstate = rResGen.InsState();
639
640 // rewrite rResGen by inserting new transitions
641 TransSet::Iterator tit = toadd.Begin();
642 for(; tit != toadd.End(); ++tit)
643 rResGen.SetTransition(tit->X1, tit->Ev, bstate);
644}
645
646
647
648// TransSpec(rSpecGenVec, GUncAlph, GenVec)
649void TransSpec(const GeneratorVector& rSpecGenVec,
650 const EventSet& rGUncAlph,
651 GeneratorVector& rResGenVec) {
652
653 // helpers
654 Generator NewGen;
655
656 // loop
658 for(; i < rSpecGenVec.Size(); ++i) {
659
660 // translate a generator into plant
661 SingleTransSpec(rSpecGenVec.At(i), rGUncAlph, NewGen);
662 rResGenVec.Append(NewGen);
663 }
664
665}
666
667
668
669////////////////////////////////////////////////////////////////
670// GlobalSelfloop
671////////////////////////////////////////////////////////////////
672
674
675 EventSet toinspect;
676 SetUnion(rGenVec, toinspect);
677
678 // a loop for every event in "toinspect" to check
679 for(EventSet::Iterator eit = toinspect.Begin(); eit != toinspect.End(); ++eit){
680
681 // collect Positions of generator in rGenVec that have the current event *eit
682 std::vector<GeneratorVector::Position> PsubGens;
683 for(GeneratorVector::Position i=0; i<rGenVec.Size(); ++i){
684 if(rGenVec.At(i).ExistsEvent(*eit))
685 PsubGens.push_back(i);
686 }
687
688
689 // <<gibt's ein solche MemberFunction von generator class, zwar lässt sich TransSet::Iterator nur durch ev auslesen??>>
690 // test whether all the transtions with the current event *eit that are in collected generators is only selfloop.
691 // when yes, "remove" remains true; when no, set "remove" false and break the loop
692 bool remove = true;
693 for(std::vector<GeneratorVector::Position>::iterator vit = PsubGens.begin(); vit != PsubGens.end(); ++vit){
694 for(TransSet::Iterator tit = rGenVec.At(*vit).TransRelBegin(); tit != rGenVec.At(*vit).TransRelEnd(); ++tit){
695 if((*eit == tit->Ev) && (tit->X1 != tit->X2)){
696 remove = false;
697 break;
698 }// end if
699 }// end inner forn
700 if(remove == false)
701 break;
702 }// end outer for
703
704
705 //when "remove" is true, remove all the transitions with current event that are only selfloop and minimize the Alphabet through remove the unused events
706 if(remove){
707 for(std::vector<GeneratorVector::Position>::iterator vit = PsubGens.begin(); vit != PsubGens.end(); ++vit){
708 for(TransSet::Iterator tit = rGenVec.At(*vit).TransRelBegin(); tit != rGenVec.At(*vit).TransRelEnd(); ){
709 if((*eit == tit->Ev) && (tit->X1 == tit->X2))
710 rGenVec.At(*vit).ClrTransition(tit++); // tmoor 201602
711 else
712 ++tit;
713 }//end inner for
714 rGenVec.At(*vit).MinimizeAlphabet();
715 }//end outer for
716 }//end if
717 }//end first for
718
719}
720
721////////////////////////////////////////////////////////////////
722// LocalSelfloop
723////////////////////////////////////////////////////////////////
724
725void LocalSelfloop(Generator& rGen, EventSet& rLocAlph) {
726
727 // construct inverse transition set
728 TransSetEvX1X2 InvTransSet;
729 rGen.TransRel(InvTransSet);
730
731 // loop for every local event
732 EventSet::Iterator eit = rLocAlph.Begin();
733 for(; eit != rLocAlph.End(); ++eit) {
734 bool IsSelfloop = true;
735 // find related transitions in the inverse transition set
736 TransSetEvX1X2::Iterator tit = InvTransSet.BeginByEv(*eit);
737 for(; tit != InvTransSet.EndByEv(*eit); ++tit)
738 // test whether it is selfloop
739 if(tit->X1 != tit->X2) {IsSelfloop = false; break;}
740
741 // remove transitions and event from alphabet if selfloop
742 if(IsSelfloop) rGen.DelEvent(*eit);
743 }
744}
745
746
747////////////////////////////////////////////////////////////////
748// MakeDistinguisher
749////////////////////////////////////////////////////////////////
750
751
752//MakeDistinguisher(AbstGen, MapStateToPartition, OrigGen, MapOldToNew);
754 std::map<Idx,Idx>& rMapStateToPartition,
755 Generator& OrigGen,
756 std::map<Idx,std::vector<Idx> >& rMapOldToNew) {
757
758 // clear rMapOldToNew
759 rMapOldToNew.clear();
760
761 // helpers
762 std::vector<std::vector<TransSet::Iterator> > NonDet;
763 std::vector<Idx> OrigStates;
764
765 // find the transitions in AbstGen that are nondeterministic
766 TransSet::Iterator tit1 = AbstGen.TransRelBegin();
768 for(tit2 = tit1++; tit1 != AbstGen.TransRelEnd(); tit2 = tit1++) {
769 if((tit2->X1 == tit1->X1) && (tit2->Ev == tit1->Ev)) {
770 std::vector<TransSet::Iterator> nondet;
771 nondet.push_back(tit2);
772 nondet.push_back(tit1);
773 NonDet.push_back(nondet);
774 }
775 }
776
777 std::string oldev;
778 std::string new_1_name;
779 std::string new_2_name;
780
781 // loop for all nondet:
782 std::vector<std::vector<TransSet::Iterator> >::iterator vvit=NonDet.begin();
783 for(; vvit != NonDet.end(); ++vvit) {
784 // 1. set new events
785 oldev = AbstGen.EventName((*vvit)[0]->Ev);
786 //new_1_name = AbstGen.EventSymbolTablep->UniqueSymbol(oldev);
787 //new_2_name = AbstGen.EventSymbolTablep->UniqueSymbol(oldev);
788 new_1_name = oldev + "_1_";
789 new_2_name = oldev + "_2_";
790 Idx new1 = AbstGen.InsEvent(new_1_name);
791 Idx new2 = AbstGen.InsEvent(new_2_name);
792 OrigGen.InsEvent(new1);
793 OrigGen.InsEvent(new2);
794
795 // 2. record in map
796 if(rMapOldToNew.find((*vvit)[0]->Ev) == rMapOldToNew.end()) {
797 rMapOldToNew[(*vvit)[0]->Ev].push_back(new1);
798 rMapOldToNew[(*vvit)[0]->Ev].push_back(new2);
799 }
800
801 // 3. replace old by two new in AbstGen
802 AbstGen.SetTransition((*vvit)[0]->X1, new1, (*vvit)[0]->X2);
803 AbstGen.SetTransition((*vvit)[1]->X1, new2, (*vvit)[1]->X2);
804
805 // 4. find the related transitions in OrigGen
806 OrigStates.clear();
807 std::map<Idx,Idx>::iterator mitSt = rMapStateToPartition.begin();
808 for(; mitSt != rMapStateToPartition.end(); ++mitSt)
809 if(mitSt->second == (*vvit)[0]->X1) OrigStates.push_back(mitSt->first);
810
811 // 5. set new and remove old transitions in OrigGen
812 std::vector<Idx>::iterator vit = OrigStates.begin();
813 for(; vit != OrigStates.end(); ++vit) {
814 // find related transitions
815 TransSet::Iterator tit = OrigGen.TransRelBegin(*vit, (*vvit)[0]->Ev);
816 TransSet::Iterator tit_end = OrigGen.TransRelEnd(*vit, (*vvit)[0]->Ev);
817 if(tit!=tit_end) { // this means at least transition does exist
818
819 if(rMapStateToPartition[tit->X2] == (*vvit)[0]->X2) {
820 OrigGen.SetTransition(tit->X1, new1, tit->X2);
821 OrigGen.ClrTransition(tit);
822 }
823 if(rMapStateToPartition[tit->X2] == (*vvit)[1]->X2) {
824 OrigGen.SetTransition(tit->X1, new2, tit->X2);
825 OrigGen.ClrTransition(tit);
826 }
827 }
828
829 }
830 // 6. clr old transitions in AbstGen
831 AbstGen.ClrTransitions((*vvit)[0]->X1, (*vvit)[0]->Ev);
832 // delete the related events
833 // AbstGen.DelEventFromAlphabet(titDet->Ev);
834 // OrigGen.DelEventFromAlphabet(titDet->Ev);
835 // ...not right now,
836 // later in function Splitter which test where exist yet old event
837 }
838
839}
840
841////////////////////////////////////////////////////////////////
842// Splitter
843////////////////////////////////////////////////////////////////
844
845/**
846 * subfunction for Splitter:
847 * splitt the events in a generator
848 *
849 * @param rGen
850 * a generator
851 * @param parent
852 * primal event
853 * @param kids
854 * new events
855 */
857 Idx parent,
858 const std::vector<Idx>& kids) {
859
860
861 // insert kids and debug
862 std::vector<Idx>::const_iterator vit = kids.begin();
863 for(; vit != kids.end(); ++vit)
864 rGen.InsEvent(*vit);
865
866 // find the transitions which via parent
867 TransSetEvX1X2 InvRel;
868 rGen.TransRel(InvRel);
869 TransSetEvX1X2::Iterator tit = InvRel.BeginByEv(parent);
870 TransSetEvX1X2::Iterator tit_end = InvRel.EndByEv(parent);
871 // int ts=0;
872 for(; tit != tit_end; ++tit) {
873 // record
874 //++ts;
875
876 // clr the transitions with the parent
877 rGen.ClrTransition(tit->X1, tit->Ev, tit->X2);
878
879 // set new transitions
880 std::vector<Idx>::const_iterator vit = kids.begin();
881 for(; vit != kids.end(); ++vit) {
882 Boolean isset = false;
883 isset = rGen.SetTransition(tit->X1, *vit, tit->X2);
884 if(!isset) {
885 std::cout << "in Function Splitter(): ";
886 std::cout << "the SetTransition in rGenVec is failed\n";
887 }
888 }
889 }
890
891 // delete the no longer used parent from alphabet
892 rGen.DelEventFromAlphabet(parent);
893
894}
895
896// Splitter(MapOldToNew, GConAlph, GenVec,
897// rMapEventsToPlant, rDisGenVec, rSupGenVec);
898void Splitter(const std::map<Idx, std::vector<Idx> >& rMapOldToNew,
899 EventSet& rConAlph,
900 GeneratorVector& rGenVec,
901 std::map<Idx,Idx>& rMapEventsToPlant,
902 GeneratorVector& rDisGenVec,
903 GeneratorVector& rSupGenVec) {
904
905
906 // loop for every element in rMapOldToNew
907 std::map<Idx, std::vector<Idx> >::const_iterator nemit = rMapOldToNew.begin();
908 for(; nemit != rMapOldToNew.end(); ++nemit) {
909
910 // helper
911 Idx parent = nemit->first;
912 const std::vector<Idx>& kids = nemit->second;
913
914 ////////////////////////////////
915 // splitt event in rConAlph
916 ////////////////////////////////
917
918 if(rConAlph.Exists(parent)) {
919 // erase parent
920 rConAlph.Erase(parent);
921 // insert kids
922 std::vector<Idx>::const_iterator vit = kids.begin();
923 for(; vit != kids.end(); ++vit) rConAlph.Insert(*vit);
924 }
925
926 ////////////////////////////////
927 // splitt event in rMapEventsToPartition
928 ////////////////////////////////
929
930 // erase parent
931 rMapEventsToPlant.erase(rMapEventsToPlant.find(parent));
932 // insert kids
933 std::vector<Idx>::const_iterator vit = kids.begin();
934 for(; vit != kids.end(); ++vit)
935 rMapEventsToPlant.insert(std::make_pair(*vit, parent));
936
937 ////////////////////////////////
938 // splitt event in rGenVec
939 ////////////////////////////////
940
942 for(; i < rGenVec.Size(); ++i)
943 if(rGenVec.At(i).ExistsEvent(parent)) SplittGen(rGenVec.At(i), parent, kids);
944
945 ////////////////////////////////
946 // split event in rSupGenVec
947 ////////////////////////////////
948
949 i=0;
950 for(; i < rSupGenVec.Size(); ++i)
951 if(rSupGenVec.At(i).ExistsEvent(parent)) SplittGen(rSupGenVec.At(i), parent, kids);
952
953 ////////////////////////////////
954 // split event in rDisGenVec
955 ////////////////////////////////
956
957 i=0;
958 for(; i < rDisGenVec.Size(); ++i)
959 if(rDisGenVec.At(i).ExistsEvent(parent)) SplittGen(rDisGenVec.At(i), parent, kids);
960
961
962 ////////////////////////////////
963 // The End
964 ////////////////////////////////
965
966 } // end the loop for rMapOldToNew
967}
968
969
970
971////////////////////////////////////////////////////////////////
972// SelectSubsystem_V1
973////////////////////////////////////////////////////////////////
974
975
976// make class as predicate for passing more parameters in STL algorithm
978
979private:
981
982public:
985
986 bool operator()(const std::vector<GeneratorVector::Position> rPosVec1,
987 const std::vector<GeneratorVector::Position> rPosVec2) {
988
989 Generator Gen1;
990 GeneratorVector GenVec1;
991 std::vector<GeneratorVector::Position>::const_iterator vit1;
992 vit1 = rPosVec1.begin();
993 for(; vit1 != rPosVec1.end(); ++vit1) GenVec1.PushBack(rGenVec.At(*vit1));
994 aParallel(GenVec1, Gen1);
995
996 Generator Gen2;
997 GeneratorVector GenVec2;
998 std::vector<GeneratorVector::Position>::const_iterator vit2;
999 vit2 = rPosVec2.begin();
1000 for(; vit2 != rPosVec2.end(); ++vit2) GenVec2.PushBack(rGenVec.At(*vit2));
1001 aParallel(GenVec2, Gen2);
1002
1003 return Gen1.Size() < Gen2.Size();
1004 }
1005};
1006
1007////////////////
1008// select_V1
1009// MustL + MinS
1010////////////////
1011
1012// BiggerMax(Candidate, rGenVec)
1013bool BiggerMax(std::vector<GeneratorVector::Position>& rCandidate,
1014 GeneratorVector& rGenVec) {
1015
1016 //the size of rCandidate is always >= 2
1017
1018 // set Max
1019 Idx Max=5000;
1020
1021 Generator gen;
1022 gen=rGenVec.At(rCandidate[0]);
1023 std::vector<GeneratorVector::Position>::iterator vit=rCandidate.begin();
1024 for(std::advance(vit,1);vit!=rCandidate.end();++vit) {
1025 Parallel(rGenVec.At(*vit),gen,gen);
1026 if(gen.Size()>Max) return true;
1027 }
1028 return false;
1029
1030}
1031
1033 Generator& rResGen) {
1034
1035 // if only two generators in the vector
1036 if(rGenVec.Size() == 2) {
1037 Parallel(rGenVec.At(0), rGenVec.At(1), rResGen);
1038 rGenVec.Clear();
1039 return;
1040 }
1041
1042 // construct a global alphabet from "rGenVec"
1043 EventSet GAlph;
1044 SetUnion(rGenVec, GAlph);
1045
1046 // prepare data
1047 std::vector<GeneratorVector::Position> Candidate;
1048 std::vector<std::vector<GeneratorVector::Position> > Candidates;
1049 Candidates.reserve(GAlph.Size());
1050
1051 // Step 1: construct candidate and candidates
1052 EventSet::Iterator eit = GAlph.Begin();
1053 for(; eit != GAlph.End(); ++eit) {
1054 Candidate.clear();
1056 for(; i < rGenVec.Size(); ++i)
1057 if(rGenVec.At(i).ExistsEvent(*eit)) Candidate.push_back(i);
1058 if(Candidate.size() == 1) continue;
1059 // give up the candidate which is bigger than MAX
1060 if(BiggerMax(Candidate, rGenVec)) continue;
1061 Candidates.push_back(Candidate);
1062 }
1063
1064 // step 2 is expensive, because of composing for large automaton
1065 // before the step2 firstly test the size of every candidate !!
1066 // give up which is bigger than a given size
1067 //
1068
1069 // Step 2: find the target
1070 std::vector<std::vector<GeneratorVector::Position> >::iterator PosTarget;
1071 PosTarget = std::min_element(Candidates.begin(), Candidates.end(),
1072 SmallSize(rGenVec));
1073
1074 // *parallel composition
1075
1076 rResGen.Assign(rGenVec.At(PosTarget->at(0)));
1077 std::vector<GeneratorVector::Position>::iterator vit=PosTarget->begin();
1078 for(std::advance(vit,1); vit!=PosTarget->end();++vit)
1079 Parallel(rResGen, rGenVec.At(*vit), rResGen);
1080
1081 // *delete subsystem from "GenVec"
1083 vit = PosTarget->begin();
1084 for(; vit != PosTarget->end(); ++vit) {
1085 rGenVec.Erase(*vit-x);
1086 ++x;
1087 }
1088}
1089
1090
1091////////////////////////////////////////////////////////////////
1092// SelectSubsystem_V2
1093////////////////////////////////////////////////////////////////
1094
1095////////////////
1096// Select_V2
1097// MaxC + MinS
1098////////////////
1099
1101 Generator& rResGen) {
1102
1103 // clear output
1104 rResGen.Clear();
1105
1106 // if only two generators in the vector
1107 if(rGenVec.Size() == 2) {
1108 Parallel(rGenVec.At(0), rGenVec.At(1), rResGen);
1109 rGenVec.Clear();
1110 return;
1111 }
1112 // *select subsystem
1113 // helpers
1114 std::vector<GeneratorVector::Position> candidate;
1115 std::vector<std::vector<GeneratorVector::Position> > candidates;
1116
1117 Idx maxsize;
1119 EventSet alph;
1120
1121 // step 1: loop for constructing candidates
1123 for(; i < rGenVec.Size()-1; ++i) {
1124 // component 1
1125 const EventSet& alph1 = rGenVec.At(i).Alphabet();
1126
1127 // determine component 2
1128 SetIntersection(alph1, rGenVec.At(i+1).Alphabet(), alph);
1129 pos = i+1;
1130 maxsize = alph.Size();
1131 // loop from i+2
1133 for(; j < rGenVec.Size(); ++j) {
1134 // setintersection
1135 SetIntersection(alph1, rGenVec.At(j).Alphabet(), alph);
1136 // "MaxC": maximal common event
1137 if(alph.Size() > maxsize) {pos = j; maxsize = alph.Size();}
1138 else if(alph.Size() == maxsize) {
1139 Generator g_pos;
1140 Generator g_j;
1141 Parallel(rGenVec.At(i), rGenVec.At(pos), g_pos);
1142 Parallel(rGenVec.At(i), rGenVec.At(j), g_j);
1143 // choose "MinS" if the number of common events is same
1144 // or choose others: "MaxL"
1145 if(g_j.Size() < g_pos.Size()) {pos = j; maxsize = alph.Size();}
1146 }
1147 }
1148
1149 // save as a candidate in candidates
1150 candidate.clear();
1151 candidate.push_back(i);
1152 candidate.push_back(pos);
1153 candidates.push_back(candidate);
1154 }
1155
1156 // step 2: pick out the best candidate
1157 std::vector<std::vector<GeneratorVector::Position> >::iterator PosTarget;
1158 PosTarget = std::min_element(candidates.begin(), candidates.end(),
1159 SmallSize(rGenVec));
1160
1161 // *parallel composition
1162 Parallel(rGenVec.At(PosTarget->at(0)), rGenVec.At(PosTarget->at(1)), rResGen);
1163
1164 // *delete subsystem from "GenVec"
1165 rGenVec.Erase(PosTarget->at(0));
1166 rGenVec.Erase(PosTarget->at(1)-1);
1167}
1168
1169
1170
1171
1172////////////////////////////////////////////////////////////////
1173// Halbway-Synthesis
1174////////////////////////////////////////////////////////////////
1175
1176
1177// for function "ComputeHSupCon()"
1178
1179//this is a internal function that aiding to collecting states
1180//which lead to blockingstates via local uncontrollable events
1181//and collecting transition relation which is further to redirecting
1182
1183// internal function for HSupCon()
1184void H_tocollect(StateSet& rBlockingstates,
1185 const TransSetX2EvX1& rRtrel,
1186 const EventSet& rLouc,
1187 const EventSet& rShuc,
1188 TransSetX2EvX1& rToredirect) {
1189
1190 //initialize todo stack
1191 std::stack<Idx> todo;
1192 StateSet::Iterator sit;
1193 for(sit = rBlockingstates.Begin(); sit != rBlockingstates.End(); ++sit){
1194 todo.push(*sit);
1195 }
1196
1197 rBlockingstates.Clear();
1198
1199 //loop variables
1200 Idx x2;
1203 //loop
1204 while(!todo.empty()){
1205 //pop
1206 x2 = todo.top();
1207 todo.pop();
1208 //save result
1209 if(rBlockingstates.Exists(x2)) continue;
1210 rBlockingstates.Insert(x2);
1211 //iterate/push
1212 tit = rRtrel.BeginByX2(x2);
1213 tit_end = rRtrel.EndByX2(x2);
1214 for(; tit_end != tit; ++tit){
1215 if(rLouc.Exists(tit->Ev))
1216 todo.push(tit->X1);
1217 else if(rShuc.Exists(tit->Ev))
1218 rToredirect.Insert(*tit);
1219 }
1220 }
1221
1222}
1223
1224// ComputeHSupCon(OrigGen, ConAlph, LocAlph, rHSupGen)
1225void ComputeHSupCon(const Generator& rOrigGen,
1226 const EventSet& rConAlph,
1227 const EventSet& rLocAlph,
1228 Generator& rHSupGen) {
1229
1230 // initialize rHSupGen
1231 rHSupGen.Assign(rOrigGen);
1232
1233 // initialize blockingstates
1234 StateSet blockingstates;
1235 blockingstates = rHSupGen.BlockingStates();
1236
1237 // verify the need to perform
1238 Boolean isneed;
1239 isneed = !blockingstates.Empty();
1240
1241 // construct uncontrollable alphabet
1242 EventSet rUCAlph;
1243 SetDifference(rHSupGen.Alphabet(), rConAlph, rUCAlph);
1244
1245 // loop variables
1246 EventSet shalph;
1247 EventSet louc;
1248 EventSet shuc;
1249 TransSetX2EvX1 toredirect;
1250 TransSetX2EvX1 itrel;
1251
1252 //initialize loop variables if need
1253 if(isneed){
1254 //set inverse transition relation from generator
1255 rHSupGen.TransRel(itrel);
1256 //set shared alphabet
1257 SetDifference(rHSupGen.Alphabet(), rLocAlph, shalph);
1258 //verify local uncontrollable events
1259 SetIntersection(rUCAlph, rLocAlph, louc);
1260 //verify shared uncontrollable events
1261 SetIntersection(rUCAlph, shalph, shuc);
1262 }
1263
1264 //loop until no more blockingstates
1265 while(!blockingstates.Empty()){
1266 //collect more blockingstates and transition relation which need to be redirected
1267 H_tocollect(blockingstates, itrel, louc, shuc, toredirect); //to implement
1268 //delete blockingstates
1269 rHSupGen.DelStates(blockingstates);
1270 //update blockingstates
1271 blockingstates = rHSupGen.BlockingStates();
1272 //update itrel
1273 rHSupGen.TransRel(itrel);
1274 }
1275
1276 if(!toredirect.Empty()) {
1277 //insert a blockingstate into gererator to redirect
1278 Idx bstate = rHSupGen.InsState();
1279 // set the transitions which is via shared uncontrollable events
1280 TransSetX2EvX1::Iterator tit = toredirect.Begin();
1281 TransSetX2EvX1::Iterator tit_end = toredirect.End();
1282 for(; tit != tit_end; ++tit) {
1283 if(!rHSupGen.ExistsState(tit->X1)) continue;
1284 rHSupGen.SetTransition(tit->X1, tit->Ev, bstate);
1285 }
1286 }
1287
1288}
1289
1290
1291
1292/*
1293****************************************************************
1294****************************************************************
1295PART C: Minimal API
1296
1297****************************************************************
1298****************************************************************
1299*/
1300
1302 const EventSet& rConAlph,
1303 const GeneratorVector& rSpecGenVec)
1304{
1305 // Check 1: all generators in "rPlantGenVec" and "rSpecGenVec" must be deterministic
1307 for(; i < rPlantGenVec.Size(); ++i)
1308 if(!rPlantGenVec.At(i).IsDeterministic()) {
1309 std::stringstream errstr;
1310 errstr<<"Plant:"<<rPlantGenVec.At(i).Name()<<" is nondeterministic\n";
1311 throw Exception("Zhou::ParameterCheck", errstr.str(), 900);
1312 }
1313
1314 i=0;
1315 for(; i < rSpecGenVec.Size(); ++i)
1316 if(!rSpecGenVec.At(i).IsDeterministic()) {
1317 std::stringstream errstr;
1318 errstr<<"Spec:"<<rSpecGenVec.At(i).Name()<<" is nondeterministic\n";
1319 throw Exception("Zhou::ParameterCheck", errstr.str(), 901);
1320 }
1321
1322 // Check 2: all generators must have marked states
1323 i=0;
1324 for(; i < rPlantGenVec.Size(); ++i) {
1325 const StateSet& stateset = rPlantGenVec.At(i).MarkedStates();
1326 if(stateset.Empty()) {
1327 std::stringstream errstr;
1328 errstr<<"Plant:"<<rPlantGenVec.At(i).Name()<<" hat no marked states\n";
1329 throw Exception("Zhou::ParameterCheck", errstr.str(), 910);
1330 }
1331 }
1332
1333 i=0;
1334 for(; i < rSpecGenVec.Size(); ++i) {
1335 const StateSet& stateset = rSpecGenVec.At(i).MarkedStates();
1336 if(stateset.Empty()) {
1337 std::stringstream errstr;
1338 errstr<<"Spec:"<<rSpecGenVec.At(i).Name()<<" hat no marked states\n";
1339 throw Exception("Zhou::ParameterCheck", errstr.str(), 911);
1340 }
1341 }
1342
1343 // Check 3: the correctness of controllable events
1344 // i.e. all controllable events muss be included in global alphabet
1345 EventSet GAlph;
1346 SetUnion(rPlantGenVec, GAlph);
1347 EventSet GSpecAlph;
1348 SetUnion(rSpecGenVec, GSpecAlph);
1349 SetUnion(GAlph, GSpecAlph, GAlph);
1350
1351 EventSet::Iterator eit = rConAlph.Begin();
1352 for(; eit != rConAlph.End(); ++eit)
1353 if(!GAlph.Exists(*eit)) {
1354 std::stringstream errstr;
1355 errstr<<"event:"<<rConAlph.SymbolicName(*eit)<<" is not included in generator\n";
1356 throw Exception("Zhou::ParameterCheck", errstr.str(), 920);
1357 }
1358}
1359
1360
1362 const EventSet& rConAlph,
1363 const GeneratorVector& rSpecGenVec,
1364 std::map<Idx,Idx>& rMapEventsToPlant,
1365 GeneratorVector& rDisGenVec,
1366 GeneratorVector& rSupGenVec)
1367{
1368 // Construct an instance of Class "ComSyn"
1369 ComSyn comsyn = ComSyn(rPlantGenVec, rConAlph, rSpecGenVec,
1370 rMapEventsToPlant, rDisGenVec, rSupGenVec);
1371 // run Preprocess
1372 comsyn.Preprocess();
1373 // run Synthesis
1374 comsyn.Synthesis();
1375}
1376
1377
1378
1379void CompositionalSynthesis(const GeneratorVector& rPlantGenVec,
1380 const EventSet& rConAlph,
1381 const GeneratorVector& rSpecGenVec,
1382 std::map<Idx,Idx>& rMapEventsToPlant,
1383 GeneratorVector& rDisGenVec,
1384 GeneratorVector& rSupGenVec)
1385{
1386 // PARAMETER CHECK
1387 ControlProblemConsistencyCheck(rPlantGenVec, rConAlph, rSpecGenVec);
1388
1389 // ALGORITHM
1390 CompositionalSynthesisUnchecked(rPlantGenVec, rConAlph, rSpecGenVec, rMapEventsToPlant, rDisGenVec, rSupGenVec);
1391}
1392
1393
1394} // namespace
GeneratorVector * pDisGenVec
ComSyn(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec, std::map< Idx, Idx > &rMapEventsToPlant, GeneratorVector &rDisGenVec, GeneratorVector &rSupGenVec)
GeneratorVector GenVec
GeneratorVector * pSupGenVec
SymbolTable * pEvSymTab
void SetPartUnion(const GeneratorVector &rGenVec, GeneratorVector::Position WithoutMe, EventSet &rRestAlph)
void Synthesis(void)
std::map< Idx, Idx > * pMapEventsToPlant
void comsyn_ComputeBisimulation(Generator &rGen)
void Preprocess(void)
const std::string & Name(void) const
bool Exists(const Idx &rIndex) const
void SymbolicName(Idx index, const std::string &rName)
virtual void InsertSet(const NameSet &rOtherSet)
bool Insert(const Idx &rIndex)
virtual bool Erase(const Idx &rIndex)
const GeneratorVector & rGenVec
SmallSize(const GeneratorVector &rGenVec)
bool operator()(const std::vector< GeneratorVector::Position > rPosVec1, const std::vector< GeneratorVector::Position > rPosVec2)
void ClrEntry(Idx index)
std::string UniqueSymbol(const std::string &rName) const
Idx InsEntry(Idx index, const std::string &rName)
std::vector< int >::size_type Position
virtual Iterator Erase(const Iterator &vit)
virtual const T & At(const Position &pos) const
Iterator Begin(void) const
Iterator End(void) const
Iterator EndByEv(Idx ev) const
Iterator BeginByX2(Idx x2) const
Iterator BeginByEv(Idx ev) const
bool Insert(const Transition &rTransition)
Iterator EndByX2(Idx x2) const
virtual Type & Assign(const Type &rSrc)
Definition cfl_types.cpp:82
virtual void Append(const Type &rElem)
virtual void PushBack(const Type &rElem)
virtual void Replace(const Position &pos, const Type &rElem)
virtual void Clear(void)
StateSet::Iterator StatesBegin(void) const
const TransSet & TransRel(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
const StateSet & MarkedStates(void) const
const EventSet & Alphabet(void) const
virtual vGenerator & Assign(const Type &rSrc)
EventSet ActiveEventSet(Idx x1) const
TransSet::Iterator TransRelBegin(void) const
void ClrTransition(Idx x1, Idx ev, Idx x2)
SymbolTable * EventSymbolTablep(void) const
bool DelEvent(Idx index)
void ClrTransitions(Idx x1, Idx ev)
StateSet BlockingStates(void) const
bool ExistsState(Idx index) const
StateSet::Iterator MarkedStatesBegin(void) const
bool DelEventFromAlphabet(Idx index)
StateSet::Iterator StatesEnd(void) const
void DelStates(const StateSet &rDelStates)
TransSet::Iterator TransRelEnd(void) const
bool IsDeterministic(void) const
bool ExistsEvent(Idx index) const
bool InsEvent(Idx index)
void SetDefaultStateNames(void)
Idx TransRelSize(void) const
std::string EventName(Idx index) const
Idx Size(void) const
virtual void Clear(void)
bool Empty(void) const
void SetDifference(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
bool Exists(const T &rElem) const
virtual void Clear(void)
Iterator End(void) const
Iterator Begin(void) const
void SetUnion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
void SetIntersection(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Idx Size(void) const
void ComputeBisimulation(const Generator &rGenOrig, map< Idx, Idx > &rMapStateToPartition)
void aParallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
bool IsDeterministic(const vGenerator &rGen)
void CompositionalSynthesis(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec, std::map< Idx, Idx > &rMapEventsToPlant, GeneratorVector &rDisGenVec, GeneratorVector &rSupGenVec)
void ComputeSynthObsEquiv(const Generator &rGenOrig, const EventSet &rConAlph, const EventSet &rLocAlph, std::map< Idx, Idx > &rMapStateToPartition, Generator &rResGen)
uint32_t Idx
void SingleTransSpec(const Generator &rSpecGen, const EventSet &rUncAlph, Generator &rResGen)
void CompositionalSynthesisUnchecked(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec, std::map< Idx, Idx > &rMapEventsToPlant, GeneratorVector &rDisGenVec, GeneratorVector &rSupGenVec)
void TransSpec(const GeneratorVector &rSpecGenVec, const EventSet &rGUncAlph, GeneratorVector &rResGenVec)
void SelectSubsystem_V2(GeneratorVector &rGenVec, Generator &rResGen)
void SplittGen(Generator &rGen, Idx parent, const std::vector< Idx > &kids)
void SelectSubsystem_V1(GeneratorVector &rGenVec, Generator &rResGen)
bool BiggerMax(std::vector< GeneratorVector::Position > &rCandidate, GeneratorVector &rGenVec)
void MakeDistinguisher(Generator &AbstGen, std::map< Idx, Idx > &rMapStateToPartition, Generator &OrigGen, std::map< Idx, std::vector< Idx > > &rMapOldToNew)
void H_tocollect(StateSet &rBlockingstates, const TransSetX2EvX1 &rRtrel, const EventSet &rLouc, const EventSet &rShuc, TransSetX2EvX1 &rToredirect)
void LocalSelfloop(Generator &rGen, EventSet &rLocAlph)
void ControlProblemConsistencyCheck(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec)
void ComputeHSupCon(const Generator &rOrigGen, const EventSet &rConAlph, const EventSet &rLocAlph, Generator &rHSupGen)
void GlobalSelfloop(GeneratorVector &rGenVec)
void ComputeWSOE(const Generator &rGenOrig, const EventSet &rConAlph, const EventSet &rLocAlph, std::map< Idx, Idx > &rMapStateToPartition, Generator &rResGen)
void Splitter(const std::map< Idx, std::vector< Idx > > &rMapOldToNew, EventSet &rConAlph, GeneratorVector &rGenVec, std::map< Idx, Idx > &rMapEventsToPlant, GeneratorVector &rDisGenVec, GeneratorVector &rSupGenVec)

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen