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 /*
24 Notes:
25 
26 This file is a copy edited version of the "syn_supnbcon.h",
27 "syn_supnbcon.cpp", "libzhou.h" and "libzhou.cpp", originally
28 written by Hao Zhou in course of his Master Thesis. The merge is
29 meant to minimise the public interface and to decouple side
30 effects of further development of libFAUDES.
31 
32 Relevant literature:
33 
34 "On Compostional Approaches for Discrete Event Systems Verification and Synthesis"
35 Sahar Mohajerani, PhD, Sweden, 2015
36 
37 
38 */
39 
40 #include "syn_compsyn.h"
41 #include "syn_synthequiv.h"
42 #include "corefaudes.h"
43 
44 namespace faudes {
45 
46 /*
47 ****************************************************************
48 PART A: Class "ComSyn"
49 
50 This class provides a buffer for input and output data to
51 iteratively apply indivual algorithms for compositional synthesis
52 
53 ****************************************************************
54 */
55 
56 class 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,
153  GeneratorVector::Position WithoutMe,
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 ****************************************************************
168 PART 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  */
184 void 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  */
202 void 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  */
214 void 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  */
225 void 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  */
241 void 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  */
263 void 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  */
284 void SelectSubsystem_V1(GeneratorVector& rGenVec,
285  Generator& rResGen);
286 
287 void SelectSubsystem_V2(GeneratorVector& rGenVec,
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  */
302 void ComputeHSupConNB(const Generator& rOrigGen,
303  const EventSet& rConAlph,
304  const EventSet& rLocAlph,
305  Generator& rHSupGen);
306 
307 
308 
309 /*
310 ****************************************************************
311 PART C: implementation of all of the above
312 
313 ****************************************************************
314 */
315 
316 
317 // Constructor
318 ComSyn::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
370  GConAlph.Insert(w);
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  ComputeHSupConNB(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 {
568  pEvSymTab->ClrEntry(w);
569 }
570 
571 
572 // SetPartUnion
574  GeneratorVector::Position WithoutMe,
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
604 void 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)
649 void 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 
725 void 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();
767  TransSet::Iterator tit2;
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  */
856 void SplittGen(Generator& rGen,
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);
898 void 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
977 class SmallSize {
978 
979 private:
981 
982 public:
984  rGenVec(rGenVec) {}
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)
1013 bool 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
1132  GeneratorVector::Position j = 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 "ComputeHSupConNB()"
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 HSupConNB()
1184 void 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;
1202  TransSetX2EvX1::Iterator tit_end;
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 // ComputeHSupConNB(OrigGen, ConAlph, LocAlph, rHSupGen)
1225 void ComputeHSupConNB(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 ****************************************************************
1295 PART 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 
1379 void 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
Elementary type.
GeneratorVector * pDisGenVec
keep reference to distinguisher-generator
ComSyn(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec, std::map< Idx, Idx > &rMapEventsToPlant, GeneratorVector &rDisGenVec, GeneratorVector &rSupGenVec)
Constructer: construct the synthesis-buffer for running compositional synthesis algorithmus and initi...
GeneratorVector GenVec
synthesis-buffer
Idx w
the termination-event
GeneratorVector * pSupGenVec
keep reference to supervisor-generator
SymbolTable * pEvSymTab
keep reference to EventSymbolTable
EventSet GConAlph
global controllable events
void SetPartUnion(const GeneratorVector &rGenVec, GeneratorVector::Position WithoutMe, EventSet &rRestAlph)
the union of eventset from generators but without a speicified generator
void Synthesis(void)
Compositional Synthesis Algorithmus after Preprocess.
~ComSyn(void)
Destructer.
std::map< Idx, Idx > * pMapEventsToPlant
keep reference to event-map
void comsyn_ComputeBisimulation(Generator &rGen)
adjust bisimulation relation to compositional synthesis
void Preprocess(void)
Preprocess: firstly abstract every generator in synthesis-buffer before running synthesis-algorithmus...
Faudes exception class.
Set of indices.
Definition: cfl_indexset.h:78
Idx Insert(void)
Insert new index to set.
Set of indices with symbolic names.
Definition: cfl_nameset.h:69
bool Exists(const Idx &rIndex) const
Test existence of index.
void SymbolicName(Idx index, const std::string &rName)
Set new name for existing index.
virtual void InsertSet(const NameSet &rOtherSet)
Inserts all elements of rOtherSet.
bool Insert(const Idx &rIndex)
Add an element by index.
virtual bool Erase(const Idx &rIndex)
Delete element by index.
const GeneratorVector & rGenVec
SmallSize(const GeneratorVector &rGenVec)
bool operator()(const std::vector< GeneratorVector::Position > rPosVec1, const std::vector< GeneratorVector::Position > rPosVec2)
A SymbolTable associates sybolic names with indices.
void ClrEntry(Idx index)
Delete entry by index.
std::string UniqueSymbol(const std::string &rName) const
Create unique symbolic name by adding an underscore and extra digits.
Idx InsEntry(Idx index, const std::string &rName)
Add new entry (aka symbolic name and index) to symboltable,.
Iterator class for high-level api to TBaseSet.
Definition: cfl_baseset.h:387
std::vector< int >::size_type Position
convenience typedef for positions
virtual const T & At(const Position &pos) const
Access element.
Iterator Begin(void) const
Iterator to begin of set.
Iterator End(void) const
Iterator to end of set.
Iterator EndByEv(Idx ev) const
Iterator to first Transition after specified by event.
Iterator BeginByX2(Idx x2) const
Iterator to first Transition specified by successor state x2.
Iterator BeginByEv(Idx ev) const
Iterator to first Transition specified by event.
bool Insert(const Transition &rTransition)
Add a Transition.
Iterator EndByX2(Idx x2) const
Iterator to first Transition after specified successor state x2.
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Iterator on transition.
Definition: cfl_transset.h:269
virtual Type & Assign(const Type &rSrc)
Assign configuration data from other object.
Definition: cfl_types.cpp:77
size_t Position
convenience typedef for positions (must be unsigned)
virtual void Erase(const Position &pos)
Erase entry by position.
virtual void Append(const Type &rElem)
Append specified entry.
virtual void PushBack(const Type &rElem)
Append specified entry.
virtual void Replace(const Position &pos, const Type &rElem)
Replace specified entry.
Idx Size(void) const
Get size of vector.
virtual void Clear(void)
Clear all vector.
Base class of all FAUDES generators.
StateSet::Iterator StatesBegin(void) const
Iterator to Begin() of state set.
const TransSet & TransRel(void) const
Return reference to transition relation.
bool SetTransition(Idx x1, Idx ev, Idx x2)
Add a transition to generator by indices.
const StateSet & MarkedStates(void) const
Return const ref of marked states.
const EventSet & Alphabet(void) const
Return const reference to alphabet.
virtual vGenerator & Assign(const Type &rSrc)
Copy from other faudes type.
EventSet ActiveEventSet(Idx x1) const
Return active event set at state x1.
TransSet::Iterator TransRelBegin(void) const
Iterator to Begin() of transition relation.
void ClrTransition(Idx x1, Idx ev, Idx x2)
Remove a transition by indices.
SymbolTable * EventSymbolTablep(void) const
Get Pointer to EventSymbolTable currently used by this vGenerator.
bool DelEvent(Idx index)
Delete event from generator by index.
void ClrTransitions(Idx x1, Idx ev)
Remove a transitions by state and event.
StateSet BlockingStates(void) const
Compute set of blocking states.
bool ExistsState(Idx index) const
Test existence of state in state set.
StateSet::Iterator MarkedStatesBegin(void) const
Iterator to Begin() of mMarkedStates.
bool DelEventFromAlphabet(Idx index)
Delete event from alphabet without consistency check.
void Name(const std::string &rName)
Set the generator's name.
StateSet::Iterator StatesEnd(void) const
Iterator to End() of state set.
void DelStates(const StateSet &rDelStates)
Delete a set of states Cleans mpStates, mInitStates, mMarkedStates, mpTransrel, and mpStateSymboltabl...
TransSet::Iterator TransRelEnd(void) const
Iterator to End() of transition relation.
bool IsDeterministic(void) const
Check if generator is deterministic.
bool ExistsEvent(Idx index) const
Test existence of event in alphabet.
Idx InsState(void)
Add new anonymous state to generator.
bool InsEvent(Idx index)
Add an existing event to alphabet by index.
void SetDefaultStateNames(void)
Assign each state a default name based on its index.
Idx TransRelSize(void) const
Get number of transitions.
std::string EventName(Idx index) const
Event name lookup.
void MinimizeAlphabet(void)
Set the alphabet to used events.
Idx Size(void) const
Get generator size (number of states)
virtual void Clear(void)
Clear generator data.
Includes all libFAUDES headers, no plugins.
bool Empty(void) const
Test whether if the TBaseSet is Empty.
Definition: cfl_baseset.h:1824
void SetDifference(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1078
bool Exists(const T &rElem) const
Test existence of element.
Definition: cfl_baseset.h:2115
virtual void Clear(void)
Clear all set.
Definition: cfl_baseset.h:1902
Iterator End(void) const
Iterator to the end of set.
Definition: cfl_baseset.h:1896
Iterator Begin(void) const
Iterator to the begin of set.
Definition: cfl_baseset.h:1891
void SetUnion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1019
void SetIntersection(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1049
Idx Size(void) const
Get Size of TBaseSet.
Definition: cfl_baseset.h:1819
void ComputeBisimulation(const Generator &rGenOrig, map< Idx, Idx > &rMapStateToPartition)
Computation of the coarsest bisimulation relation for a specified generator.
void aParallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Parallel composition.
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Parallel composition.
bool IsDeterministic(const vGenerator &rGen)
RTI wrapper function.
void CompositionalSynthesis(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec, std::map< Idx, Idx > &rMapEventsToPlant, GeneratorVector &rDisGenVec, GeneratorVector &rSupGenVec)
Compositional synthesis.
void ComputeSynthObsEquiv(const Generator &rGenOrig, const EventSet &rConAlph, const EventSet &rLocAlph, std::map< Idx, Idx > &rMapStateToPartition, Generator &rResGen)
Synthesis-observation equivalence.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
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)
Compositional synthesis.
void TransSpec(const GeneratorVector &rSpecGenVec, const EventSet &rGUncAlph, GeneratorVector &rResGenVec)
translate specification into plant
void SelectSubsystem_V2(GeneratorVector &rGenVec, Generator &rResGen)
void SplittGen(Generator &rGen, Idx parent, const std::vector< Idx > &kids)
subfunction for Splitter: splitt the events in a generator
void SelectSubsystem_V1(GeneratorVector &rGenVec, Generator &rResGen)
heuristic: vorious approaches to select subsystem from synthesis-buffer then compose them and remove ...
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)
make a distinguisher and a map for solving nondeterminism and rewrite abstracted automaton
void H_tocollect(StateSet &rBlockingstates, const TransSetX2EvX1 &rRtrel, const EventSet &rLouc, const EventSet &rShuc, TransSetX2EvX1 &rToredirect)
void LocalSelfloop(Generator &rGen, EventSet &rLocAlph)
remove the events from a generator which have only selfloop transitions
void ControlProblemConsistencyCheck(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec)
Compositional synthesis.
void GlobalSelfloop(GeneratorVector &rGenVec)
remove the events from the entire buffer which have only selfloop transitions
void ComputeWSOE(const Generator &rGenOrig, const EventSet &rConAlph, const EventSet &rLocAlph, std::map< Idx, Idx > &rMapStateToPartition, Generator &rResGen)
weak synthesis obeservation equivalence [not implemented]
void Splitter(const std::map< Idx, std::vector< Idx > > &rMapOldToNew, EventSet &rConAlph, GeneratorVector &rGenVec, std::map< Idx, Idx > &rMapEventsToPlant, GeneratorVector &rDisGenVec, GeneratorVector &rSupGenVec)
update the generators in synthesis-buffer and in supervisor with new events
void ComputeHSupConNB(const Generator &rOrigGen, const EventSet &rConAlph, const EventSet &rLocAlph, Generator &rHSupGen)
halbway-synthesis
Compositional synthesis.
Synthesis-observation equivalence.

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