hio_functions.cpp
Go to the documentation of this file.
1 /** @file hio_functions.cpp Algorithms for hierarchical discrete event systems with inputs and outputs */
2 
3 /* Hierarchical IO Systems Plug-In for FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2006 Sebastian Perk
6  Copyright (C) 2006 Thomas Moor
7  Copyright (C) 2006 Klaus Schmidt
8 
9 */
10 
11 // note: deterministic generators only
12 
13 // todo: exceptions on invalid input data if FAUDES_CHECKED
14 // todo: files eg: normal. cycles. hiotest. hiosynth.
15 // todo: implement routines that check hio properties
16 // todo: only use statenames if statenamesenabled (eg HioFreeInput)
17 
18 // todo: other todos below
19 
20 #include "hio_functions.h"
21 #include "syn_include.h"
22 
23 
24 namespace faudes {
25 
26 
27 // This is Sebastian'y version of SupNorm with a special
28 // marking of the result. It also uses a different order
29 // of arguments
30 
31 // SupNormSP(rL,rOAlph,rK,rResult)
32 bool SupNormSP(
33  Generator& rL,
34  const EventSet& rOAlph,
35  const Generator& rK,
36  Generator& rResult)
37 {
38  FD_DF("SupNorm(" << rK.Name() << "," << rL.Name() << "," << rOAlph.Name() << ")");
39 
40  NormalityConsistencyCheck(rL,rOAlph,rK);
41 
42  // prepare result
43  rResult.Clear();
44 
45  //extract overall alphabet:
46  EventSet allevents;
47  allevents=rL.Alphabet();
48 
49  //extract alphabet of rK:
50  EventSet Kevents=rK.Alphabet();
51 
52  // record name and marked states of rL
53  std::string rLname=rL.Name();
54  StateSet rLmarked=rL.MarkedStates();
55 
56  // involved operations from cfl_regular.h operate on the marked
57  // languages -> turn generated languages into marked langs
58  rL.InjectMarkedStates(rL.States());
59  Generator prK=rK;
60  prK.InjectMarkedStates(prK.States());
61  rResult = prK;
62 
63  // calculate "L-K" (ToDo: use LanguageDifference):
64  LanguageComplement(rResult);
65  FD_DF("SupNorm: size of complement(K): "<<rResult.Size()<<",marked: "<<rResult.MarkedStatesSize());
66  Generator tempgen;
67  LanguageIntersection(rL, rResult, tempgen);
68  rResult.Clear();
69  FD_DF("SupNorm: sizeof L U complement(K)=L-K: "<<tempgen.Size());
70 
71  // calculate Pinv(P(L-K)):
72  Project(tempgen,rOAlph,rResult);
73  tempgen.Clear();
74  FD_DF("SupNorm: sizeof p(L-K): "<< rResult.Size());
75  InvProject(rResult,allevents);
76  FD_DF("SupNorm: sizeof pinv(p(L-K)): "<<rResult.Size());
77 
78  // FD_DF("SupNorm: sizeof pinv(p(L-K)): "<<rResult.Size());
79 
80  //calculate remaining set difference -> supnorm(K)
81  LanguageComplement(rResult);
82  LanguageIntersection(prK, rResult, tempgen);
83  rResult=tempgen;
84  tempgen.Clear();
85  FD_DF("SupNorm: sizeof K - pinv(p(L-K)) (result): "<<rResult.Size());
86 
87  // language MARKED by rResult is the result -> remove blocking states, mark all remaining states.
88  rResult.Trim();
89  rResult.InjectMarkedStates(rResult.States());
90 
91  // restore original rL
92  rL.Name(rLname);
93  rL.InjectMarkedStates(rLmarked);
94 
95  return !( rResult.InitStatesEmpty() );
96 }
97 
98 
99 
100 
101 
102 
103 // CompleteSynth(rPlant,rCAlph,rSpec,rClosedLoop)
105  const Generator& rPlant,
106  const EventSet rCAlph,
107  const Generator& rSpec,
108  Generator& rClosedLoop) {
109  FD_DF("CompleteSynth(" << rPlant.Name() << "," << rSpec.Name()<< ")");
110 
111  // prepare result
112  rClosedLoop.Clear();
113 
114  //check for trivial result
115  if(rSpec.InitStatesEmpty()){
116  FD_DF("CompleteSynth::empty language specification: empty closed loop.");
117  rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
118  return false;
119  }
120 
121  // spec as candidate for closed loop
122  Generator ClosedLoopCand=rSpec;
123 
124  // iterate supcon and dead end elimination
125  while(true) {
126  // try std synthesis
127  FD_DF("CompleteSynth:: spec size " << ClosedLoopCand.Size());
128 
129  // try SupCon
130  SupConClosed(rPlant, rCAlph, ClosedLoopCand, rClosedLoop);
131  //std::cout<<std::endl<<"CompleteSynth:: current result after SupCon: tmp_ContLoop.gen";
132  FD_DF("CompleteSynth: size of current result after SupCon: "<<rClosedLoop.Size());
133  //std::cout<<" (Size: "<<rClosedLoop.Size()<<").";
134 
135  //check for empty result
136  if(rClosedLoop.InitStatesEmpty()) {
137  FD_DF("CompleteSynth:: failed: empty language result.");
138  rClosedLoop.StateNamesEnabled(false);
139  rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
140  return false;
141  }
142 
143  FD_DF("CompleteSynth:: candidate size " << rClosedLoop.Size());
144 
145  // find dead ends and return success if no dead end found
146  StateSet dead_ends=rClosedLoop.TerminalStates(rClosedLoop.AccessibleSet());
147  if(dead_ends.Empty()) {
148  rClosedLoop.StateNamesEnabled(false);
149  FD_DF("CompleteSynth:: done");
150  rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
151  return true;
152  }
153 
154  // report to console
155  FD_DF("CompleteSynth:: eliminating following " << dead_ends.Size() << " dead ends");
156  FD_DF(rClosedLoop.StateSetToString(dead_ends));
157 
158  // eliminate dead ends.
159  rClosedLoop.DelStates(dead_ends);
160  // becomes new candidate for SupCon
161  ClosedLoopCand=rClosedLoop;
162 
163  //std::cout<<std::endl<<"CompleteSynth:: current result after Complete: tmp_CompleteLoop.gen";
164  FD_DF("CompleteSynth:: size of result after removing dead ends: "<<rClosedLoop.Size());
165  //std::cout<<" (Size: "<<rClosedLoop.Size()<<").";
166 
167  //check for empty result
168  if(rClosedLoop.InitStatesEmpty()) {
169  FD_DF("CompleteSynth:: failed: empty language result.");
170  rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
171  return false;
172  }
173  rClosedLoop.Clear();
174  }
175 }
176 
177 // NormalCompleteSynth(rPlant,rCAlph,rOAlph,rSpec,rClosedLoop)
179  Generator& rPlant,
180  const EventSet& rCAlph,
181  const EventSet& rOAlph,
182  const Generator& rSpec,
183  Generator& rClosedLoop)
184 {
185  FD_DF("NormalCompleteSynth(" << rPlant.Name() << "," << rSpec.Name()<< ")");
186 
187  // prepare result
188  rClosedLoop.Clear();
189 
190  // spec as candidate for closed loop
191  Generator Spec=rSpec;
192 
193  while(true) {
194 
195  // try CompleteSynth and check for empty result:
196  if(!CompleteSynth(rPlant,rCAlph,Spec,rClosedLoop)) {
197  FD_DF("NormalCompleteSynth:: failed: empty result after CompleteSynth().");
198  std::cout<<std::endl<<"NormalCompleteSynth:: failed: empty result after CompleteSynth().";
199  rClosedLoop.Name("NormalCompleteSynth(" + rPlant.Name() + "," + rSpec.Name()+ ")");
200  return false;
201  }
202 
203  // check for normality and return on success
204  if(IsNormal(rPlant,rOAlph,rClosedLoop)) {
205  FD_DF("NormalCompleteSynth:: candidate supervisor is normal. success.");
206  rClosedLoop.Name("NormalCompleteSynth(" + rPlant.Name() + "," + rSpec.Name()+ ")");
207  return true;
208  }
209 
210  // supremal normal sublanguage of rClosedLoop as new spec
211  // return false on empty result
212  FD_DF("NormalCompleteSynth:: candidate supervisor not normal. running SupNorm");
213  if(!SupNormSP(rPlant, rOAlph, rClosedLoop, Spec)) {
214  FD_DF("NormalCompleteSynth:: failed: empty result after SupNorm().");
215  std::cout<<std::endl<<"NormalCompleteSynth:: failed: empty result after SupNorm().";
216  rClosedLoop.Clear();
217  rClosedLoop.Name("NormalCompleteSynth(" + rPlant.Name() + "," + rSpec.Name()+ ")");
218  return false;
219  }
220 
221  Spec.StateNamesEnabled(false);
222  //std::cout<<std::endl<<"NormalCompleteSynth:: current result after SupNorm():";
223  //std::cout<<" Size: "<<Spec.Size()<<".";
224  FD_DF("NormalCompleteSynth:: size of result after SupNorm(): "<<Spec.Size());
225  }
226 }
227 
228 
229 // NormalCompleteSynthNB(rPlant,rCAlph,rOAlph,rSpec,rClosedLoop)
231  Generator& rPlant,
232  const EventSet& rCAlph,
233  const EventSet& rOAlph,
234  const Generator& rSpec,
235  Generator& rClosedLoop)
236 {
237  FD_DF("NormalCompleteSynth(" << rPlant.Name() << "," << rSpec.Name()<< ")");
238 
239  // prepare result
240  rClosedLoop.Clear();
241 
242  // spec as candidate for closed loop
243  Generator Spec=rSpec;
244  while(true) {
245 
246  // try NormalCompleteSynth and check for empty result:
247  if(!NormalCompleteSynth(rPlant,rCAlph,rOAlph,Spec,rClosedLoop)) {
248  FD_DF("NormalCompleteSynthNB:: failed: empty result after NormalCompleteSynth().");
249  std::cout<<std::endl<<"NormalCompleteSynthNB:: failed: empty result after NormalCompleteSynth().";
250  rClosedLoop.Name("NormalCompleteSynthNB(" + rPlant.Name() + "," + rSpec.Name()+ ")");
251  return false;
252  }
253 
254  // check for coaccessibility and return on success
255  if(rClosedLoop.IsTrim()) {
256  FD_DF("NormalCompleteSynthNB:: candidate supervisor is trim. success.");
257  rClosedLoop.Name("NormalCompleteSynthNB(" + rPlant.Name() + "," + rSpec.Name()+ ")");
258  return true;
259  }
260 
261  // supremal nonblocking sublanguage of rClosedLoop as new Spec
262  // return false on empty result
263  FD_DF("NormalCompleteSynthNB:: candidate supervisor not Trim. running Trim()");
264  Spec=rClosedLoop;
265  if(!Spec.Trim()) {
266  FD_DF("NormalCompleteSynthNB:: failed: empty result after Trim().");
267  std::cout<<std::endl<<"NormalCompleteSynthNB:: failed: empty result after Trim().";
268  rClosedLoop.Clear();
269  rClosedLoop.Name("NormalCompleteSynthNB(" + rPlant.Name() + "," + rSpec.Name()+ ")");
270  return false;
271  }
272  //std::cout<<std::endl<<"NormalCompleteSynthNB:: current result after Trim():";
273  //std::cout<<" Size: "<<Spec.Size()<<".";
274  FD_DF("NormalCompleteSynthNB:: size of result after Trim():"<<Spec.Size());
275  }
276 }
277 
278 
279 // HioSortCL(const EventSet& rYc,rUc,rYp,rUP,rYe,rUe)
281  const EventSet& rYc,
282  const EventSet& rUc,
283  const EventSet& rYp,
284  const EventSet& rUp,
285  const EventSet& rYe,
286  const EventSet& rUe)
287 {
288  FD_DF("HioSortCL(...)");
289 
290  #ifdef FAUDES_CHECKED
291  // check for nonempty sets
292  if (rYc.Empty()||rUc.Empty()||rYp.Empty()||rUp.Empty()||rYe.Empty()||rUe.Empty()){
293  std::stringstream errstr;
294  errstr << "At least one empty parameter.";
295  throw Exception("HioSortCL", errstr.str(), 0);
296  }
297  #endif
298 
299  // create resulting alphabet while checking for disjoint sets
300  EventSet alphabet,errevents;
301  // initialize with rYc
302  alphabet.InsertSet(rYc);
303  // insert remaining events one by one and check if new
304  EventSet::Iterator evit;
305  // rUc
306  for (evit = rUc.Begin(); evit != rUc.End(); ++evit) {
307  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
308  }
309  // rYp
310  for (evit = rYp.Begin(); evit != rYp.End(); ++evit) {
311  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
312  }
313  // rUp
314  for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
315  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
316  }
317  // rYe
318  for (evit = rYe.Begin(); evit != rYe.End(); ++evit) {
319  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
320  }
321  // rUe
322  for (evit = rUe.Begin(); evit != rUe.End(); ++evit) {
323  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
324  }
325 
326  #ifdef FAUDES_CHECKED
327  // throw exception on non disjoint alphabets
328  if (!errevents.Empty()){
329  std::stringstream errstr;
330  errstr << "Non-disjoint parameters; ambiguous events:\n" <<errevents.ToString();
331  throw Exception("HioSortCL", errstr.str(), 0);
332  }
333  #endif
334 
335  // create result
336  Generator ResGen;
337 
338  ResGen.Name("HioSortCL("+rYc.Name()+","+rUc.Name()+","+rYp.Name()+","+rUp.Name()+","+rYe.Name()+","+rUe.Name()+")");
339 
340  ResGen.InjectAlphabet(alphabet);
341  alphabet.Clear();
342 
343  // 5 marked states with initial state 1:
344  ResGen.InsInitState("Yp_or_Ye");
345  ResGen.SetMarkedState("Yp_or_Ye");
346  ResGen.InsMarkedState("Yc_or_Up");
347  ResGen.InsMarkedState("Uc");
348  ResGen.InsMarkedState("Up");
349  ResGen.InsMarkedState("Ue");
350 
351  // set transitions according to desired ioSorting structure:
352  // all Yp-events lead from state 1 to state 2:
353  for (evit = rYp.Begin(); evit != rYp.End(); ++evit) {
354  ResGen.SetTransition("Yp_or_Ye",rYp.SymbolicName(*evit),"Yc_or_Up");
355  }
356  // all Yc-events lead from state 2 to state 3:
357  for (evit = rYc.Begin(); evit != rYc.End(); ++evit) {
358  ResGen.SetTransition("Yc_or_Up",rYc.SymbolicName(*evit),"Uc");
359  }
360  // all Uc-events lead from state 3 to state 4:
361  for (evit = rUc.Begin(); evit != rUc.End(); ++evit) {
362  ResGen.SetTransition("Uc",rUc.SymbolicName(*evit),"Up");
363  }
364  // all Up-events lead from state 2 and 4 to state 1:
365  for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
366  ResGen.SetTransition("Yc_or_Up",rUp.SymbolicName(*evit),"Yp_or_Ye");
367  ResGen.SetTransition("Up",rUp.SymbolicName(*evit),"Yp_or_Ye");
368  }
369  // all Ye-events lead from state 1 to state 5:
370  for (evit = rYe.Begin(); evit != rYe.End(); ++evit) {
371  ResGen.SetTransition("Yp_or_Ye",rYe.SymbolicName(*evit),"Ue");
372  }
373  // all Ue-events lead from state 5 to state 1:
374  for (evit = rUe.Begin(); evit != rUe.End(); ++evit) {
375  ResGen.SetTransition("Ue",rUe.SymbolicName(*evit),"Yp_or_Ye");
376  }
377  return ResGen;
378 }
379 
380 // HioFreeInput(rGen,rInput,rOutput,rResGen,rErrState1,rErrState2,rErrState1Idx,rErrState2Idx)
382  const Generator& rGen,
383  const EventSet& rInput,
384  const EventSet& rOutput,
385  Generator& rResGen,
386  const std::string& rErrState1,
387  const std::string& rErrState2,
388  Idx& rErrState1Idx,
389  Idx& rErrState2Idx) {
390  FD_DF("HioFreeInput( [generator] " << rGen.Name() << ")");
391 
392  Generator* pResGen = &rResGen;
393  if(&rResGen== &rGen) {
394  pResGen= rResGen.New();
395  }
396 
397  #ifdef FAUDES_CHECKED
398  // exception on empty Input-alphabet or non-disjoint Input and Output
399  if(rInput.Empty() || !((rInput*rOutput).Empty())) {
400  std::stringstream errstr;
401  errstr << "Empty Input-alphabet or non-disjoint Input and Output.\n";
402  errstr << "Input: "<< rInput.ToString()<<"\n";
403  errstr << "Output: "<< rOutput.ToString()<<"\n";
404  errstr << "Input*Output: "<< (rInput*rOutput).ToString()<<"\n";
405  throw Exception("HioFreeInput", errstr.str(), 0);
406  }
407  #endif
408 
409  // check for enabled state names:
410  bool StateNamesEnabled = pResGen->StateNamesEnabled();
411  // Warning on inconsistency with error-state names
412  if(!StateNamesEnabled && (!rErrState1.empty()||!rErrState2.empty())) {
413  FD_WARN("HioFreeInput: state names disabled in rResGen: error state names ignored.");
414  }
415 
416  // prepare result, preserve StateNamesEnabled of rGen
417  *pResGen=rGen;
418  pResGen->StateNamesEnabled(StateNamesEnabled);
419  pResGen->Name("HioFreeInput("+rGen.Name()+")");
420 
421  //create first error state, where inserted Input-events shall lead to:
422  std::string errstate1;
423  if(StateNamesEnabled) {
424  errstate1=pResGen->UniqueStateName(rErrState1);
425  rErrState1Idx=pResGen->InsMarkedState(errstate1);
426  }
427  else {
428  rErrState1Idx=pResGen->InsMarkedState();
429  }
430 
431  //find Input-states
432  StateSet::Iterator sit=pResGen->StatesBegin();
433  EventSet::Iterator evit;
434  bool InputInserted = false;
435  for(;sit!=pResGen->StatesEnd();sit++){
436  EventSet disabledInput;
437  disabledInput = rInput - pResGen->ActiveEventSet(*sit);
438  //if at least one Input-event is enabled AND at least one Input-event is disabled:
439  //insert missing Input-transitions to error state
440  if( (disabledInput!=rInput) && !disabledInput.Empty()) {
441  FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
442  InputInserted = true;
443  for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
444  pResGen->SetTransition(*sit,*evit,rErrState1Idx);
445  }
446  }
447  }//for-loop through states
448 
449  //insert err_Input-state and connect both err-states with Input-Output-loop in case missing Input-events were inserted:
450  if(InputInserted) {
451  if(StateNamesEnabled) {
452  FD_DF("HioFreeInput(...): inserted error state 1: " << errstate1 << " with Idx: " << rErrState1Idx);
453  }
454  else {
455  FD_DF("HioFreeInput(...): inserted error state 1 with Idx: " << rErrState1Idx);
456  }
457  if(!rOutput.Empty()) { // this 'if' and the 'if' before are seperated because of the 'else' below !
458  //create second error state
459  std::string errstate2;
460  if(StateNamesEnabled) {
461  errstate2=pResGen->UniqueStateName(rErrState2);
462  rErrState2Idx=pResGen->InsMarkedState(errstate2);
463  FD_DF("HioFreeInput(...): inserted error state 2: " << errstate2);
464  }
465  else {
466  rErrState2Idx=pResGen->InsMarkedState();
467  FD_DF("HioFreeInput(...): inserted error state 2 with Idx: " << rErrState2Idx);
468  }
469 
470  //insert Input-events:
471  for (evit = rInput.Begin(); evit != rInput.End(); ++evit) {
472  pResGen->SetTransition(rErrState2Idx,*evit,rErrState1Idx);
473  }
474  //insert output-events:
475  for (evit = rOutput.Begin(); evit != rOutput.End(); ++evit) {
476  pResGen->SetTransition(rErrState1Idx,*evit,rErrState2Idx);
477  }
478  }
479  }
480  //else delete err_Output-state
481  else {
482  pResGen->DelState(rErrState1Idx);
483  }
484  // if necessary, move pResGen to rResGen
485  if(pResGen != &rResGen) {
486  pResGen->Move(rResGen);
487  delete pResGen;
488  }
489 }
490 
491 // HioFreeInput(rGen,rInput,rOutput,rResGen,rErrState1,rErrState2)
493  const Generator& rGen,
494  const EventSet& rInput,
495  const EventSet& rOutput,
496  Generator& rResGen,
497  const std::string& rErrState1,
498  const std::string& rErrState2) {
499  Idx errstate1,errstate2;
500  HioFreeInput(rGen,rInput,rOutput,rResGen,rErrState1,rErrState2,errstate1,errstate2);
501 }
502 
503 // HioFreeInput(rGen,rInput,rOutput,rResGen)
505  const Generator& rGen,
506  const EventSet& rInput,
507  const EventSet& rOutput,
508  Generator& rResGen)
509 {
510  //Call HioFreeInput with empty names for error states
511  std::string ErrState1,ErrState2;
512  HioFreeInput(rGen,rInput,rOutput,rResGen,ErrState1,ErrState2);
513 }
514 
515 // HioFreeInput(HioPlant,HioPlant)
517  const HioPlant& rPlant,
518  HioPlant& rResPlant)
519 {
520 
521  FD_DF("HioFreeInput( [plant] " << rPlant.Name() << ")");
522 
523  // Call HioFreeInput with certain names for error state,
524  // set Err-flag
525  Idx errstateUp,errstateUe,errstate2;
526  std::string ErrState1,ErrState2;
527 
528  EventSet NoOutput,uP,uE,yP,yE;
529  uP=rPlant.UpEvents();
530  uE=rPlant.UeEvents();
531  yP=rPlant.YpEvents();
532  yE=rPlant.YeEvents();
533 
534  ErrState1="UpError";
535  HioFreeInput(rPlant,uP,NoOutput,rResPlant,ErrState1,ErrState2,errstateUp,errstate2);
536 
537  ErrState1="UeError";
538  HioFreeInput(rResPlant,uE,NoOutput,rResPlant,ErrState1,ErrState2,errstateUe,errstate2);
539 
540  // set HioStateFlag Err
541  if(rResPlant.ExistsState(errstateUp)) rResPlant.SetErr(errstateUp);
542  if(rResPlant.ExistsState(errstateUe)) rResPlant.SetErr(errstateUe);
543 
544  // restore event attributes
545  rResPlant.SetYp(yP);
546  rResPlant.SetUp(uP);
547  rResPlant.SetYe(yE);
548  rResPlant.SetUe(uE);
549 
550 }
551 
552 // HioFreeInput(HioController,HioController)
554  const HioController& rController,
555  HioController& rResController)
556 {
557  FD_DF("HioFreeInput( [controller] " << rController.Name() << ")");
558 
559  HioController* pResController = &rResController;
560  if(&rResController== &rController) {
561  pResController=rResController.New();
562  }
563 
564  // check for enabled state names:
565  bool StateNamesEnabled = pResController->StateNamesEnabled();
566 
567  // prepare error state names
568  std::string errStr1, errStr2;
569 
570  // prepare error state indeces
571  Idx errIdx1, errIdx2;
572 
573  // prepare result, preserve StateNamesEnabled of rGen
574  pResController->Assign(rController);
575  //*pResController=rController; // didn't work (should work ... check!!)
576  //pResController=&rController; // didn't work (cannot work anyway)
577  pResController->StateNamesEnabled(StateNamesEnabled);
578  pResController->Name("HioFreeInput("+rController.Name()+")");
579 
580  // figure input alphabets
581  EventSet UcEvents = rController.UcEvents();
582  EventSet YpEvents = rController.YpEvents();
583  EventSet YcEvents = rController.YcEvents();
584  EventSet UpEvents = rController.UpEvents();
585 
586  //create first error state, where inserted Uc- or Yp-events shall lead to:
587  if(StateNamesEnabled) {
588  errStr1=pResController->UniqueStateName("UcYpError");
589  errIdx1=pResController->InsMarkedState(errStr1);
590  }
591  else {
592  errIdx1=pResController->InsMarkedState();
593  }
594  // set HioStateFlag Err
595  pResController->SetErr(errIdx1);
596 
597  // set state attribute QUp
598  pResController->SetQUp(errIdx1);
599 
600  //find Input-states
601  StateSet::Iterator sit=pResController->StatesBegin();
602  EventSet::Iterator evit;
603  bool InputInserted = false;
604  for(;sit!=pResController->StatesEnd();sit++){
605  EventSet disabledInput, active;
606  active = pResController->ActiveEventSet(*sit);
607  // first treat Uc-events
608  disabledInput = UcEvents - active;
609  //if at least one Input-event is enabled AND at least one Input-event is disabled:
610  //insert missing Input-transitions to error state
611  if( (disabledInput!=UcEvents) && !disabledInput.Empty()) {
612  // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
613  InputInserted = true;
614  for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
615  pResController->SetTransition(*sit,*evit,errIdx1);
616  }
617  }
618  // then treat Yp-events
619  disabledInput = YpEvents - active;
620  //if at least one Input-event is enabled AND at least one Input-event is disabled:
621  //insert missing Input-transitions to error state
622  if( (disabledInput!=YpEvents) && !disabledInput.Empty()) {
623  // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
624  InputInserted = true;
625  for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
626  pResController->SetTransition(*sit,*evit,errIdx1);
627  }
628  }
629  }//for-loop through states
630 
631  //insert err_Input-state and connect both err-states with Input-Output-loop in case missing Input-events were inserted:
632  if(InputInserted) {
633  //create second error state
634  std::string errstate2;
635  if(StateNamesEnabled) {
636  FD_DF("HioFreeInput(...): inserted error state 1: " << errStr1);
637  errStr2=pResController->UniqueStateName("ErrorQYp");
638  errIdx2=pResController->InsMarkedState(errStr2);
639  FD_DF("HioFreeInput(...): inserted error state 2: " << errStr2);
640  }
641  else {
642  FD_DF("HioFreeInput(...): inserted error state 1 with Idx: " << errIdx1);
643  errIdx2=pResController->InsMarkedState();
644  FD_DF("HioFreeInput(...): inserted error state 2 with Idx: " << errIdx2);
645  }
646 
647  // set HioStateFlag Err
648  pResController->SetErr(errIdx2);
649  // set HioStateFlag QYp
650  pResController->SetQYp(errIdx2);
651 
652  //insert Up-events:
653  for (evit = UpEvents.Begin(); evit != UpEvents.End(); ++evit) {
654  pResController->SetTransition(errIdx1,*evit,errIdx2);
655  }
656  //insert Yp-events:
657  for (evit = YpEvents.Begin(); evit != YpEvents.End(); ++evit) {
658  pResController->SetTransition(errIdx2,*evit,errIdx1);
659  }
660  }
661 
662  //else delete error-state 1
663  else {
664  pResController->DelState(errIdx1);
665  }
666 
667  // if necessary, move pResGen to rResGen
668  if(pResController != &rResController) {
669  pResController->Move(rResController);
670  delete pResController;
671  }
672  // restore event attributes
673  rResController.SetYc(YcEvents);
674  rResController.SetUc(UcEvents);
675  rResController.SetYp(YpEvents);
676  rResController.SetUp(UpEvents);
677 }
678 
679 // HioFreeInput(HioEnvironment,HioEnvironment)
681  const HioEnvironment& rEnvironment,
682  HioEnvironment& rResEnvironment)
683 {
684  FD_DF("HioFreeInput( [environment] " << rEnvironment.Name() << ")");
685 
686  HioEnvironment* pResEnvironment = &rResEnvironment;
687  if(&rResEnvironment== &rEnvironment) {
688  pResEnvironment=rResEnvironment.New();
689  }
690 
691  // check for enabled state names:
692  bool StateNamesEnabled = pResEnvironment->StateNamesEnabled();
693 
694  // prepare error state names
695  std::string errStr1, errStr2;
696 
697  // prepare error state indeces
698  Idx errIdx1, errIdx2;
699 
700  // prepare result, preserve StateNamesEnabled of rGen
701  pResEnvironment->Assign(rEnvironment);
702  //*pResEnvironment=rEnvironment; // didn't work
703  //pResEnvironment=&rEnvironment; // didn't work
704  pResEnvironment->StateNamesEnabled(StateNamesEnabled);
705  pResEnvironment->Name("HioFreeInput("+rEnvironment.Name()+")");
706 
707  // figure alphabets
708  EventSet UlEvents = rEnvironment.UlEvents();
709  EventSet YeEvents = rEnvironment.YeEvents();
710  EventSet YlEvents = rEnvironment.YlEvents();
711  EventSet UeEvents = rEnvironment.UeEvents();
712 
713  //create first error state, where inserted Uc- or Yp-events shall lead to:
714  if(StateNamesEnabled) {
715  errStr1=pResEnvironment->UniqueStateName("UlYeError");
716  errIdx1=pResEnvironment->InsMarkedState(errStr1);
717  }
718  else {
719  errIdx1=pResEnvironment->InsMarkedState();
720  }
721 
722  // set HioStateFlag Err
723  pResEnvironment->SetErr(errIdx1);
724  // set HioStateFlag QUe
725  pResEnvironment->SetQUe(errIdx1);
726 
727  //find Input-states
728  StateSet::Iterator sit=pResEnvironment->StatesBegin();
729  EventSet::Iterator evit;
730  bool InputInserted = false;
731  for(;sit!=pResEnvironment->StatesEnd();sit++){
732  EventSet disabledInput, active;
733  active = pResEnvironment->ActiveEventSet(*sit);
734  // first treat Uc-events
735  disabledInput = UlEvents - active;
736  //if at least one Input-event is enabled AND at least one Input-event is disabled:
737  //insert missing Input-transitions to error state
738  if( (disabledInput!=UlEvents) && !disabledInput.Empty()) {
739  // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
740  InputInserted = true;
741  for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
742  pResEnvironment->SetTransition(*sit,*evit,errIdx1);
743  }
744  }
745  // then treat Yp-events
746  disabledInput = YeEvents - active;
747  //if at least one Input-event is enabled AND at least one Input-event is disabled:
748  //insert missing Input-transitions to error state
749  if( (disabledInput!=YeEvents) && !disabledInput.Empty()) {
750  // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
751  InputInserted = true;
752  for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
753  pResEnvironment->SetTransition(*sit,*evit,errIdx1);
754  }
755  }
756  }//for-loop through states
757 
758  //insert err_Input-state and connect both err-states with Input-Output-loop in case missing Input-events were inserted:
759  if(InputInserted) {
760  //create second error state
761  std::string errstate2;
762  if(StateNamesEnabled) {
763  FD_DF("HioFreeInput(...): inserted error state 1: " << errStr1);
764  errStr2=pResEnvironment->UniqueStateName("ErrorQYe");
765  errIdx2=pResEnvironment->InsMarkedState(errStr2);
766  FD_DF("HioFreeInput(...): inserted error state 2: " << errStr2);
767  }
768  else {
769  FD_DF("HioFreeInput(...): inserted error state 1 with Idx: " << errIdx1);
770  errIdx2=pResEnvironment->InsMarkedState();
771  FD_DF("HioFreeInput(...): inserted error state 2 with Idx: " << errIdx2);
772  }
773 
774  // set HioStateFlag Err
775  pResEnvironment->SetErr(errIdx2);
776  // set state attribute QYe
777  pResEnvironment->SetQYe(errIdx2);
778 
779  //insert Ue-events:
780  for (evit = UeEvents.Begin(); evit != UeEvents.End(); ++evit) {
781  pResEnvironment->SetTransition(errIdx1,*evit,errIdx2);
782  }
783  //insert Ye-events:
784  for (evit = YeEvents.Begin(); evit != YeEvents.End(); ++evit) {
785  pResEnvironment->SetTransition(errIdx2,*evit,errIdx1);
786  }
787  }
788 
789  //else delete error-state 1
790  else {
791  pResEnvironment->DelState(errIdx1);
792  }
793  // if necessary, move pResGen to rResGen
794  if(pResEnvironment != &rResEnvironment) {
795  pResEnvironment->Move(rResEnvironment);
796  delete pResEnvironment;
797  }
798  // restore event attributes
799  rResEnvironment.SetYl(YlEvents);
800  rResEnvironment.SetUl(UlEvents);
801  rResEnvironment.SetYe(YeEvents);
802  rResEnvironment.SetUe(UeEvents);
803 }
804 
805 // HioFreeInput(HioConstraint,HioConstraint)
807  const HioConstraint& rConstraint,
808  HioConstraint& rResConstraint)
809 {
810  // Call HioFreeInput with certain names for error states,
811  // set Err-flags
812  Idx errstate1,errstate2;
813  std::string ErrState1="Y-Error";
814  std::string ErrState2="ErrorQY";
815  EventSet y,u;
816  y=rConstraint.YEvents();
817  u=rConstraint.UEvents();
818  HioFreeInput(rConstraint,y,u,rResConstraint,ErrState1,ErrState2,errstate1,errstate2);
819  // set HioStateFlag Err
820  rResConstraint.SetErr(errstate1);
821  rResConstraint.SetErr(errstate2);
822  // restore event attributes
823  rResConstraint.SetY(y);
824  rResConstraint.SetU(u);
825 }
826 
827 // HioFreeInput(HioPlant)
828 void HioFreeInput(HioPlant& rPlant) {
829  FD_DF("HioFreeInput( [single arg plant] " << rPlant.Name() << ")");
830  HioFreeInput(rPlant,rPlant);
831 }
832 
833 // HioFreeInput(HioController)
834 void HioFreeInput(HioController& rController) {
835  HioFreeInput(rController,rController);
836 }
837 
838 // HioFreeInput(HioEnvironment)
839 void HioFreeInput(HioEnvironment& rEnvironment) {
840  HioFreeInput(rEnvironment,rEnvironment);
841 }
842 
843 // HioFreeInput(HioConstraint)
844 void HioFreeInput(HioConstraint& rConstraint) {
845  HioFreeInput(rConstraint,rConstraint);
846 }
847 
848 
849 
850 //**********************************************************
851 //******************** Completeness ************************
852 //**********************************************************
853 
854 
855 
856 //**********************************************************
857 //******************** I/O-shuffle ************************
858 //**********************************************************
859 
860 //******************** current version: marked parameters + marking of alternation ************************
861 
862 // MarkHioShuffle(rGen1,rGen2,rMapOrigToResult,rShuffle)
863 void MarkHioShuffle(const Generator& rGen1,const Generator& rGen2,
864  const std::map< std::pair<Idx,Idx>, Idx >& rMapOrigToResult,
865  Generator& rShuffle) {
866 
867  // invert mapOrigToResult (possible, as map is expected to be from parallel composition and thus must be bijective)
868  std::map< Idx, std::pair<Idx,Idx> > mapResultToOrig;
869  std::map< std::pair<Idx,Idx>, Idx >::const_iterator iter;
870  for( iter = rMapOrigToResult.begin(); iter != rMapOrigToResult.end(); ++iter ) {
871  mapResultToOrig.insert(std::make_pair( iter->second, iter->first ));
872  }
873 
874  // (I) duplicate all non-marked states, whose corresponding state in rGen1 or rGen2 is marked.
875  StateSet nonmarked=rShuffle.States()-rShuffle.MarkedStates();
876  StateSet::Iterator sit;
877  std::map< Idx, Idx > rGen1Clones,rGen2Clones;
878  for(sit = nonmarked.Begin(); sit != nonmarked.End(); sit ++) {
879  // marked in rGen1?
880  if(rGen1.ExistsMarkedState(mapResultToOrig[*sit].first)) {
881  rGen1Clones[*sit]=rShuffle.InsMarkedState();
882  }
883  // marked in rGen2?
884  if(rGen2.ExistsMarkedState(mapResultToOrig[*sit].first)) {
885  rGen2Clones[*sit]=rShuffle.InsMarkedState();
886  }
887  }
888 
889  // (II) MOVE HEAD OF rGen1-transitions whose X2 has a rGen1-clone, and head of rGen2-transitions whose
890  // X2 has a rGen2-clone
891  TransSet TransToClear, TransToSet;
892  TransSet::Iterator tit=rShuffle.TransRelBegin();
893  TransSet::Iterator tit_end=rShuffle.TransRelEnd();
894  std::map<Idx,Idx>::iterator cloneit;
895  bool x1hasGen1Clone,x1hasGen2Clone, x2hasClone;
896  for(;tit!=tit_end;tit++) {
897 
898  x1hasGen1Clone=false;
899  x1hasGen2Clone=false;
900  x2hasClone=false;
901 
902  //##################################################
903  // CASE (I) - X2 has clone: move head of transition, also duplicate transition if X1 has clone
904  //##################################################
905 
906  // preliminarily check if X1 has clone
907  cloneit=rGen1Clones.find(tit->X1);
908  if(cloneit!=rGen1Clones.end()) x1hasGen1Clone=true;
909  cloneit=rGen2Clones.find(tit->X1);
910  if(cloneit!=rGen2Clones.end()) x1hasGen2Clone=true;
911 
912 
913  // distinguish rGen1-events and rGen2-events
914  if(rGen1.Alphabet().Exists(tit->Ev)) {
915  // exists rGen1-clone?
916  cloneit=rGen1Clones.find(tit->X2);
917  if(cloneit!=rGen1Clones.end()) {
918  x2hasClone=true;
919  // move head to clone: delete original trans, insert moved trans
920  TransToClear.Insert(*tit);
921  TransToSet.Insert(tit->X1,tit->Ev,rGen1Clones[tit->X2]);
922  // if X1 has a clone make copy starting from clone of X1
923  if(x1hasGen1Clone) {
924  TransToSet.Insert(rGen1Clones[tit->X1],tit->Ev,rGen1Clones[tit->X2]);
925  }
926  if(x1hasGen2Clone) {
927  TransToSet.Insert(rGen2Clones[tit->X1],tit->Ev,rGen1Clones[tit->X2]);
928  }
929  }
930  }
931 
932  // else, tit is rGen2-transition
933  else {
934  // exists rGen2-clone?
935  cloneit=rGen2Clones.find(tit->X2);
936  if(cloneit!=rGen2Clones.end()) {
937  x2hasClone=true;
938  // move head to clone: delete original trans, insert moved trans
939  TransToClear.Insert(*tit);
940  TransToSet.Insert(tit->X1,tit->Ev,cloneit->second);
941  // if X1 has a clone make copy starting from clone of X1
942  if(x1hasGen1Clone) {
943  TransToSet.Insert(rGen1Clones[tit->X1],tit->Ev,rGen2Clones[tit->X2]);
944  }
945  if(x1hasGen2Clone) {
946  TransToSet.Insert(rGen2Clones[tit->X1],tit->Ev,rGen2Clones[tit->X2]);
947  }
948  }
949  }
950 
951  //###################################################
952  // CASE (II) - (only) X1 has clone: duplicate transition (see Case I for case also X2 has clone)
953  //###################################################
954 
955  if( (x1hasGen1Clone||x1hasGen2Clone) && !x2hasClone ) {
956  if(x1hasGen1Clone) TransToSet.Insert(rGen1Clones[tit->X1],tit->Ev,tit->X2);
957  if(x1hasGen2Clone) TransToSet.Insert(rGen2Clones[tit->X1],tit->Ev,tit->X2);
958  }
959  }
960 
961  // clear invalid transitions
962  tit=TransToClear.Begin();
963  tit_end=TransToClear.End();
964  for(;tit!=tit_end;tit++) rShuffle.ClrTransition(*tit);
965 
966  // set updated transitions
967  tit=TransToSet.Begin();
968  tit_end=TransToSet.End();
969  for(;tit!=tit_end;tit++) rShuffle.SetTransition(*tit);
970 
971  // cosmetics
972  rShuffle.Accessible();
973  return;
974 }
975 
976 // MarkAlternationAB(Aset,Bset,AltAB)
978  const EventSet rAset,
979  const EventSet rBset,
980  Generator& rAltAB)
981 {
982  FD_DF("MarkAlternationAB()");
983 
984  #ifdef FAUDES_CHECKED
985  // validate parameters
986  if (rAset.Empty()){
987  std::stringstream errstr;
988  errstr << "Empty parameter rAset.";
989  throw Exception("CheapAltAnB", errstr.str(), 0);
990  }
991  if (rBset.Empty()){
992  std::stringstream errstr;
993  errstr << "Empty parameter rBset.";
994  throw Exception("CheapAltAnB", errstr.str(), 0);
995  }
996  #endif
997 
998  rAltAB.Clear();
999  rAltAB.InjectAlphabet(rAset+rBset);
1000 
1001  Idx s1,s2,s3,s4,s5;
1002 
1003  s1=rAltAB.InsInitState();
1004  rAltAB.SetMarkedState(s1);
1005  s2=rAltAB.InsMarkedState();
1006  s3=rAltAB.InsMarkedState();
1007  s4=rAltAB.InsState();
1008  s5=rAltAB.InsState();
1009  EventSet::Iterator evit=rAset.Begin();
1010  EventSet::Iterator evit_end=rAset.End();
1011  for(;evit!=evit_end;++evit) {
1012  rAltAB.SetTransition(s1,*evit,s2);
1013  rAltAB.SetTransition(s2,*evit,s4);
1014  rAltAB.SetTransition(s3,*evit,s2);
1015  rAltAB.SetTransition(s4,*evit,s4);
1016  rAltAB.SetTransition(s5,*evit,s2);
1017  }
1018  evit=rBset.Begin();
1019  evit_end=rBset.End();
1020  for(;evit!=evit_end;++evit) {
1021  rAltAB.SetTransition(s1,*evit,s3);
1022  rAltAB.SetTransition(s2,*evit,s3);
1023  rAltAB.SetTransition(s3,*evit,s5);
1024  rAltAB.SetTransition(s4,*evit,s3);
1025  rAltAB.SetTransition(s5,*evit,s5);
1026  }
1027 }
1028 
1029 // HioShuffleUnchecked(rPlantA,rPlantB,rYp,rUp,rYe,rUe,rIOShuffAB)
1031  const Generator& rPlantA,
1032  const Generator& rPlantB,
1033  const EventSet& rYp,
1034  const EventSet& rUp,
1035  const EventSet& rYe,
1036  const EventSet& rUe,
1037  Generator& rIOShuffAB)
1038 {
1039  FD_DF("HioShuffle()");
1040 
1041  //Extract alphabets:
1042  EventSet A,B,SigmaP;
1043  A = rPlantA.Alphabet();
1044  B = rPlantB.Alphabet();
1045 
1046  // parallel composition of plantA and plantB (i.e. shuffle as there are no shared events)
1047  Generator parallel1, parallel2;
1048  std::map< std::pair<Idx,Idx>, Idx > MapOrigToResult;
1049  Parallel(rPlantA,rPlantB,MapOrigToResult,parallel1);
1050  MarkHioShuffle(rPlantA,rPlantB,MapOrigToResult,parallel1);
1051 
1052  // restrict to event pairs [(SigA SigA)*+(SigB SigB)*]*, which results
1053  // in correct I/O sorting L_IO.
1054  Generator EventPairs; // generator of above sorting language
1055  EventPairs.InjectAlphabet(A + B);
1056  Idx state1,state2,state3;
1057  state1=EventPairs.InsInitState("1");
1058  EventPairs.SetMarkedState(state1);
1059  state2=EventPairs.InsMarkedState("2");
1060  state3=EventPairs.InsMarkedState("3");
1061  EventSet::Iterator evit;
1062  for (evit = A.Begin(); evit != A.End(); ++evit) {
1063  EventPairs.SetTransition(state1,*evit,state2);
1064  EventPairs.SetTransition(state2,*evit,state1);
1065  }
1066  for (evit = B.Begin(); evit != B.End(); ++evit) {
1067  EventPairs.SetTransition(state1,*evit,state3);
1068  EventPairs.SetTransition(state3,*evit,state1);
1069  }
1070  Parallel(parallel1,EventPairs,parallel2);
1071  parallel1 = parallel2;
1072 
1073 // //#####################################################################################
1074 // //#####################################################################################
1075 // //#####################################################################################
1076 // //restrict to IO-sorting structure with forced alternation:
1077 //
1078 // // Old Vers before Dez 4 2006: Alternation of whole alphabets
1079 // A = rPlantA.Alphabet();
1080 // B = rPlantB.Alphabet();
1081 //
1082 //
1083 //// // New Vers: Alternation of YP Events only
1084 //// // -> currently leads to normality problems during superposed controller synthesis
1085 //// SigmaP.InsertSet(rYp);
1086 //// SigmaP.InsertSet(rUp);
1087 //// A.RestrictSet(SigmaP);
1088 //// B.RestrictSet(SigmaP);
1089 //
1090 //
1091 //
1092 // Generator AltAB;
1093 // A.Name("A");
1094 // B.Name("B");
1095 // CheapAltAB(A,B,Depth,AltAB);
1096 // // Alt_AB.Write("tmp_Alternation_AB.gen");
1097 // Parallel(parallel2, AltAB, parallel1);
1098 // //parallel2.Write("tmp_IOS3.gen");
1099 //
1100 //
1101 //
1102 
1103 
1104  // bugfix to resolve normality problem: whenever plant A
1105  // can send a yp-event and at the same time plant B can
1106  // send a ye-event, then let the ye-event be sent first:
1107  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1108  //*** Environment-first policy: If, in some state both, Yp- and Ye events are
1109  //*** active, then cancel all Yp-transitions in this state, as environment has
1110  //*** to be updated first.
1111 
1112  FD_DF("------ HioShuffle with Environment-First-Policy! -----");
1113 
1114  // loop all states
1115  StateSet::Iterator sit = parallel1.StatesBegin();
1116  StateSet::Iterator sit_end = parallel1.StatesEnd();
1117 
1118  for(; sit != sit_end; sit++)
1119  {
1120  // figure active Yp-events and active Ye-events
1121  //std::cout << "End: " << *sit_end <<"...done: " << *sit << std::endl;
1122  EventSet ActiveYe;
1123  EventSet ActiveYp = parallel1.TransRel().ActiveEvents(*sit);
1124  ActiveYe=ActiveYp;
1125  ActiveYe.RestrictSet(rYe);
1126  ActiveYp.RestrictSet(rYp);
1127  if (!(ActiveYe.Empty())&& !(ActiveYp.Empty()))
1128  {
1129  TransSet TransToClear;
1130  TransSet::Iterator tit=parallel1.TransRelBegin(*sit);
1131  TransSet::Iterator tit_end=parallel1.TransRelEnd(*sit);
1132  for(;tit!=tit_end;tit++)
1133  {
1134  //std::cout << "finding Yp-events to delete... ";
1135  if(ActiveYp.Exists(tit->Ev))
1136  {
1137  TransToClear.Insert(*tit);
1138  }
1139  }
1140  tit=TransToClear.Begin();
1141  tit_end=TransToClear.End();
1142  for(;tit!=tit_end;tit++)
1143  {
1144  //std::cout<<" ...deleting" <<std::endl;
1145  parallel1.ClrTransition(*tit);
1146  }
1147  }
1148  }
1149 
1150  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1151 
1152 
1153 
1154 //~ ////
1155 //~ // //#####################################################################################
1156 //~ // //#####################################################################################
1157 //~ // //#####################################################################################
1158 
1159 
1160  // Insert Error Behaviour, i.e. make UP and UE free in (YP,UP)-port of result:
1161  // free UP:
1162  HioFreeInput(parallel1, rUp, rYp, parallel2, "errYp_Ye", "errUp");
1163  //parallel1.Write("tmp_IOS4.gen");
1164  // free UE:
1165  HioFreeInput(parallel2, rUe, rYe, parallel1, "errYp_Ye", "errUe");
1166  //parallel2.Write("tmp_IOS5.gen");
1167 
1168  // Mark Alternation of YP-events
1169  A.RestrictSet(rYp);
1170  B.RestrictSet(rYp);
1171  MarkAlternationAB(A,B,parallel2);
1172  Parallel(parallel2,parallel1,parallel1);
1173 
1174  rIOShuffAB = parallel1;
1175  rIOShuffAB.Name("HioShuffle("+rPlantA.Name()+rPlantB.Name()+")");
1176  return;
1177 }
1178 
1179 
1180 // HioShuffle(rPlantA,rPlantB,rYp,rUp,rYe,rUe,rIOShuffAB)
1182  const Generator& rPlantA,
1183  const Generator& rPlantB,
1184  const EventSet& rYp,
1185  const EventSet& rUp,
1186  const EventSet& rYe,
1187  const EventSet& rUe,
1188  Generator& rIOShuffAB)
1189 {
1190  rIOShuffAB.Clear();
1191  #ifdef FAUDES_CHECKED
1192  // exception on empty alphabets
1193  if (rYp.Empty()){
1194  std::stringstream errstr;
1195  errstr << "Empty Yp alphabet\n";
1196  throw Exception("HioShuffle", errstr.str(), 0);
1197  }
1198  if (rUp.Empty()){
1199  std::stringstream errstr;
1200  errstr << "Empty Up alphabet\n";
1201  throw Exception("HioShuffle", errstr.str(), 0);
1202  }
1203  if (rYe.Empty()){
1204  std::stringstream errstr;
1205  errstr << "Empty Ye alphabet\n";
1206  throw Exception("HioShuffle", errstr.str(), 0);
1207  }
1208  if (rUe.Empty()){
1209  std::stringstream errstr;
1210  errstr << "Empty Ue alphabet\n";
1211  throw Exception("HioShuffle", errstr.str(), 0);
1212  }
1213 
1214  // create resulting alphabet while checking for disjoint sets
1215  EventSet alphabet,alphabetA,alphabetB,errevents;
1216  alphabetA=rPlantA.Alphabet();
1217  alphabetB=rPlantB.Alphabet();
1218  // initialize with rYp
1219  alphabet.InsertSet(rYp);
1220  // insert remaining events one by one and check if new
1221  EventSet::Iterator evit;
1222  // rUp
1223  for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
1224  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
1225  }
1226  // rYe
1227  for (evit = rYe.Begin(); evit != rYe.End(); ++evit) {
1228  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
1229  }
1230  // rUe
1231  for (evit = rUe.Begin(); evit != rUe.End(); ++evit) {
1232  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
1233  }
1234  // throw exception on non disjoint alphabets
1235  if (!errevents.Empty()){
1236  std::stringstream errstr;
1237  errstr << "Non-disjoint parameters; ambiguous events:\n" <<errevents.ToString();
1238  throw Exception("HioShuffle", errstr.str(), 0);
1239  }
1240 
1241  // check alphabet match with plant A and B-alphabets:
1242  // The union of plant A and B alphabets need not equal but must be included in the union of EventSet parameters.
1243 
1244  errevents=alphabetA+alphabetB-alphabet;
1245  if (!errevents.Empty()){
1246  std::stringstream errstr;
1247  errstr << "Plant A- or plant B-events missing in Yp,Up,Ye or Ue:\n" <<errevents.ToString();
1248  throw Exception("HioShuffle", errstr.str(), 0);
1249  }
1250 
1251  // plant A and plant B must be in HioPlantForm
1252  HioPlant hioPlantA=HioPlant(rPlantA,rYp*alphabetA,rUp*alphabetA,rYe*alphabetA,rUe*alphabetA);
1253  std::string report;
1254  if(!IsHioPlantForm(hioPlantA,report)){
1255  std::stringstream errstr;
1256  errstr << "plant A not in HioPlantForm:\n" << report;
1257  throw Exception("HioShuffle", errstr.str(), 0);
1258  }
1259 
1260  HioPlant hioPlantB=HioPlant(rPlantB,rYp*alphabetB,rUp*alphabetB,rYe*alphabetB,rUe*alphabetB);
1261  report.clear();
1262  if(!IsHioPlantForm(hioPlantB,report)){
1263  std::stringstream errstr;
1264  errstr << "plant B not in HioPlantForm:\n" << report;
1265  throw Exception("HioShuffle", errstr.str(), 0);
1266  }
1267  #endif
1268 
1269  // compute I/O-shuffle
1270  HioShuffleUnchecked(rPlantA, rPlantB, rYp, rUp, rYe, rUe, rIOShuffAB);
1271 
1272 }
1273 
1275  const HioPlant& rPlantA,
1276  const HioPlant& rPlantB,
1277  HioPlant& rIOShuffAB) {
1278 
1279  //prepare result
1280  rIOShuffAB.Clear();
1281 
1282  EventSet yp = rPlantA.YpEvents()+rPlantB.YpEvents();
1283  EventSet up = rPlantA.UpEvents()+rPlantB.UpEvents();
1284  EventSet ye = rPlantA.YeEvents()+rPlantB.YeEvents();
1285  EventSet ue = rPlantA.UeEvents()+rPlantB.UeEvents();
1286 
1287  // compute I/O-shuffle
1288  HioShuffle(rPlantA, rPlantB, yp, up, ye, ue, rIOShuffAB);
1289 
1290  // set event and state attributes
1291  rIOShuffAB.SetYp(yp);
1292  rIOShuffAB.SetUp(up);
1293  rIOShuffAB.SetYe(ye);
1294  rIOShuffAB.SetUe(ue);
1295 
1296  IsHioPlantForm(rIOShuffAB);
1297 }
1298 //******************** old version: no marking, forced alternation ************************
1299 
1300 // CheapAltAnB(rAset,rBset,Depth,rAltAnB)
1302  const EventSet rAset,
1303  const EventSet rBset,
1304  const int Depth,
1305  Generator& rAltAnB)
1306 {
1307  FD_DF("CheapAltAnB()");
1308 
1309  // validate parameters
1310  if (Depth<1){
1311  std::stringstream errstr;
1312  errstr << "Parameter Depth must be 1 or greater.";
1313  throw Exception("CheapAltAnB", errstr.str(), 0);
1314  }
1315  #ifdef FAUDES_CHECKED
1316  if (rAset.Empty()){
1317  std::stringstream errstr;
1318  errstr << "Empty parameter rAset.";
1319  throw Exception("CheapAltAnB", errstr.str(), 0);
1320  }
1321  if (rBset.Empty()){
1322  std::stringstream errstr;
1323  errstr << "Empty parameter rBset.";
1324  throw Exception("CheapAltAnB", errstr.str(), 0);
1325  }
1326  #endif
1327 
1328  // prepare result
1329  rAltAnB.Clear();
1330  rAltAnB.Name("CheapAltAnB(" + rAset.Name() + "," + rBset.Name() + "," + ToStringInteger(Depth) + ")");
1331 
1332  // create initial state
1333  Idx init = rAltAnB.InsInitState("alt_"+rAset.Name()+"_init");
1334  rAltAnB.SetMarkedState(init);
1335 
1336  Idx last = init;
1337  rAltAnB.InjectAlphabet(rAset + rBset);
1338 
1339  // selfloop initial state with Bset:
1340  EventSet::Iterator evit;
1341  for (evit = rBset.Begin(); evit != rBset.End(); ++evit) {
1342  rAltAnB.SetTransition(last,*evit,last);
1343  }
1344 
1345  //create n concatenated pathes A->|a|A->|b| and transitions B from |b| to initial state.
1346  for (int i=0; i!=Depth; ++i) {
1347  Idx a = rAltAnB.InsMarkedState("alt_"+rAset.Name()+"_U"+ToStringInteger(i+1));
1348  Idx b = rAltAnB.InsMarkedState("alt_"+rAset.Name()+"_Y"+ToStringInteger(i+2));
1349  //connect last,a and b with A-transitions.
1350  for (evit = rAset.Begin(); evit != rAset.End(); ++evit) {
1351  rAltAnB.SetTransition(last,*evit,a);
1352  rAltAnB.SetTransition(a,*evit,b);
1353  }
1354  //insert B-transitions from b to init
1355  for (evit = rBset.Begin(); evit != rBset.End(); ++evit) {
1356  rAltAnB.SetTransition(b,*evit,init);
1357  }
1358  last = b;
1359  }
1360 }
1361 
1362 // CheapAltAB(rAset,rBset,Depth,rAltAnB)
1364  const EventSet rAset,
1365  const EventSet rBset,
1366  const int Depth,
1367  Generator& rAltAB)
1368 {
1369  FD_DF("CheapAltAB()");
1370  // prepare result
1371  rAltAB.Clear();
1372 
1373  Generator AnB, BnA;
1374  CheapAltAnB(rAset,rBset,Depth,AnB);
1375  CheapAltAnB(rBset,rAset,Depth,BnA);
1376  Parallel(AnB,BnA,rAltAB);
1377  rAltAB.Name("CheapAltAB("+rAset.Name()+","+rBset.Name()+","+ToStringInteger(Depth)+")");
1378 }
1379 
1380 // HioShuffleTU(rPlantA,rPlantB,rYp,rUp,rYe,rUe,Depth,rIOShuffAB)
1382  const Generator& rPlantA,
1383  const Generator& rPlantB,
1384  const EventSet& rUp,
1385  const EventSet& rYp,
1386  const EventSet& rYe,
1387  const EventSet& rUe,
1388  const int Depth,
1389  Generator& rIOShuffAB)
1390 {
1391  FD_DF("HioShuffle()");
1392 
1393  //Extract alphabets:
1394  EventSet A,B,SigmaP;
1395  A = rPlantA.Alphabet();
1396  B = rPlantB.Alphabet();
1397 
1398  // parallel composition of plantA and plantB (i.e. shuffle as there are no shared events)
1399  Generator parallel1, parallel2;
1400  Parallel(rPlantA,rPlantB,parallel1);
1401 
1402  // restrict to event pairs [(SigA SigA)*+(SigB SigB)*]*, which results
1403  // in correct I/O sorting L_IO.
1404  Generator EventPairs; // generator of above sorting language
1405  EventPairs.InjectAlphabet(A + B);
1406  Idx state1,state2,state3;
1407  state1=EventPairs.InsInitState("1");
1408  EventPairs.SetMarkedState(state1);
1409  state2=EventPairs.InsMarkedState("2");
1410  state3=EventPairs.InsMarkedState("3");
1411  EventSet::Iterator evit;
1412  for (evit = A.Begin(); evit != A.End(); ++evit) {
1413  EventPairs.SetTransition(state1,*evit,state2);
1414  EventPairs.SetTransition(state2,*evit,state1);
1415  }
1416  for (evit = B.Begin(); evit != B.End(); ++evit) {
1417  EventPairs.SetTransition(state1,*evit,state3);
1418  EventPairs.SetTransition(state3,*evit,state1);
1419  }
1420  Parallel(parallel1,EventPairs,parallel2);
1421 
1422  //restrict to IO-sorting structure with forced alternation:
1423 
1424 //////// // Old Vers before Dez 4 2006: Alternation of whole alphabets
1425 //////// A = rPlantA.Alphabet();
1426 //////// B = rPlantB.Alphabet();
1427 //////
1428 ////// // New Vers: Alternation of YP Events only
1429 ////// // -> currently leads to normality problems during superposed controller synthesis
1430 ////// SigmaP.InsertSet(rYp);
1431 ////// SigmaP.InsertSet(rUp);
1432 ////// A.RestrictSet(SigmaP);
1433 ////// B.RestrictSet(SigmaP);
1434 //////
1435 //////
1436 ////// Generator AltAB;
1437 ////// A.Name("A");
1438 ////// B.Name("B");
1439 ////// CheapAltAB(A,B,Depth,AltAB);
1440 ////// // Alt_AB.Write("tmp_Alternation_AB.gen");
1441 ////// Parallel(parallel2, AltAB, parallel1);
1442 ////// //parallel2.Write("tmp_IOS3.gen");
1443 
1444  // Old Vers before Dez 4 2006: Alternation of whole alphabets
1445  EventSet Ap, Bp, Ae, Be, SigmaE;
1446 
1447  Ap = rPlantA.Alphabet();
1448  Bp = rPlantB.Alphabet();
1449 
1450  Ae = rPlantA.Alphabet();
1451  Be = rPlantB.Alphabet();
1452 
1453 
1454 
1455  //*************************************************************************
1456  //// New Vers: Alternation of YP Events only
1457  //// -> currently leads to normality problems during superposed controller synthesis
1458  SigmaP.InsertSet(rYp);
1459  SigmaP.InsertSet(rUp);
1460  Ap.RestrictSet(SigmaP);
1461  Bp.RestrictSet(SigmaP);
1462 
1463  SigmaE.InsertSet(rYe);
1464  SigmaE.InsertSet(rUe);
1465  Ae.RestrictSet(SigmaE);
1466  Be.RestrictSet(SigmaE);
1467 
1468 
1469  //*************************************************************************
1470  Generator AltAB;
1471  Ap.Name("A");
1472  Bp.Name("B");
1473  CheapAltAB(Ap,Bp,Depth,AltAB);
1474  // Alt_AB.Write("tmp_Alternation_AB.gen");
1475  Parallel(parallel2, AltAB, parallel1);
1476 
1477 /* // bugfix to resolve normality problem: whenever plant A
1478  * // can send a yp-event and at the same time plant B can
1479  * // send a ye-event, then let the ye-event be sent first:
1480  * //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1481  * // Environment-first policy: If, in some state both, Yp- and Ye events are
1482  * // active, then cancel all Yp-transitions in this state, as environment has
1483  * // to be updated first.
1484  *
1485  * // loop all states
1486  * StateSet::Iterator sit = parallel1.StatesBegin();
1487  * StateSet::Iterator sit_end = parallel1.StatesEnd();
1488  *
1489  * for(; sit != sit_end; sit++)
1490  * {
1491  * // figure active Yp-events and active Ye-events
1492  * //std::cout << "End: " << *sit_end <<"...done: " << *sit << std::endl;
1493  * EventSet ActiveYe;
1494  * EventSet ActiveYp = parallel1.TransRel().ActiveEvents(*sit);
1495  * ActiveYe=ActiveYp;
1496  * ActiveYe.RestrictSet(rYe);
1497  * ActiveYp.RestrictSet(rYp);
1498  * if (!(ActiveYe.Empty())&& !(ActiveYp.Empty()))
1499  * {
1500  * TransSet TransToClear;
1501  * TransSet::Iterator tit=parallel1.TransRelBegin(*sit);
1502  * TransSet::Iterator tit_end=parallel1.TransRelEnd(*sit);
1503  * for(;tit!=tit_end;tit++)
1504  * {
1505  * //std::cout << "finding Yp-events to delete... ";
1506  * if(ActiveYp.Exists(tit->Ev))
1507  * {
1508  * TransToClear.Insert(*tit);
1509  * }
1510  * }
1511  * tit=TransToClear.Begin();
1512  * tit_end=TransToClear.End();
1513  * for(;tit!=tit_end;tit++)
1514  * {
1515  * //std::cout<<" ...deleting" <<std::endl;
1516  * parallel1.ClrTransition(*tit);
1517  * }
1518  * }
1519  * }
1520  *
1521  * //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1522  *
1523  */
1524 
1525 
1526  // Insert Error Behaviour, i.e. make UP and UE free in (YP,UP)-port of result:
1527  // free UP:
1528  HioFreeInput(parallel1, rUp, rYp, parallel2, "errYp_Ye", "errUp");
1529  //parallel1.Write("tmp_IOS4.gen");
1530  // free UE:
1531  HioFreeInput(parallel2, rUe, rYe, parallel1, "errYp_Ye", "errUe");
1532  //parallel2.Write("tmp_IOS5.gen");
1533 
1534  rIOShuffAB = parallel1;
1535 }
1536 
1537 //**********************************************************
1538 //******************** Cycles ************************
1539 //**********************************************************
1540 
1541 
1542 // ***Search for strongly connected ycless components (SCC)***
1543 // This function partitions the stateset of a generator into equivalent classes
1544 // such that states x1 and x2 are equivalent iff there is a ycless path from x1
1545 // to x2 AND a ycless path from x2 to x1.
1546 // This function implements the algorithm based on a depth first search
1547 // presented in:
1548 // -Aho, Hopcroft, Ullman: The Design and Analysis of Computer Algorithms-
1549 //
1550 // Most of the comments in this function have been literally taken from
1551 // this book!
1552 //
1553 // Parameters (an api with generator and Yc-events as input and SCCs as output
1554 // is provided right below this method.)
1555 // -state: State, from which the current recursion is started.
1556 // -rcount: denotes the current depth of the recursion.
1557 // -Yc: set of Yc-events
1558 // -UnMarkedOnly: if set true, being unmarked is an additional condition for equivalence of states
1559 // -NewStates: Set of states that up to now were not found by the depth first search
1560 // -STACK: stack of state indeces
1561 // -StackStates: set of states whose indeces are on STACK.
1562 // -DFN: map assigning to each state its Depth-First Number
1563 // -LOWLINK: map assigning to each state its LOWLINK Number
1564 // -SCCset: result - the set of strongly connected components
1565 // -UnMarkedSCCset: result - the set of strongly connected components consisting exclusively of marked states
1566 // -Roots: result - the set of states that each are root of some SCC.
1567 //
1568 // ToDo: handle exceptions.
1569 //
1570 
1572  const Idx state,
1573  int& rcount, // why is this a ref?
1574  const Generator& rGen,
1575  const EventSet& rYc,
1576  const bool UnMarkedOnly,
1577  StateSet& rNewStates,
1578  std::stack<Idx>& rSTACK,
1579  StateSet& rStackStates,
1580  std::map<const Idx, int>& rDFN,
1581  std::map<const Idx, int>& rLOWLINK,
1582  std::set<StateSet>& rSccSet,
1583  StateSet& rRoots)
1584 {
1585  FD_DF("SerchYclessScc: -- search from state "<< state << "--");
1586 
1587  // mark state "old";
1588  rNewStates.Erase(state);
1589 
1590  // DFNUMBER[state] <- count;
1591  rDFN[state]=rcount;
1592 
1593  // count <- count+1;
1594  rcount++;
1595 
1596  // LOWLINK[v] <- DFNUMBER[v];
1597  rLOWLINK[state]=rDFN[state];
1598  //cout<<"count: "<<rcount<<" state: "<<state<<" DFN: "<<rDFN[state]<<endl;
1599 
1600  // push state on STACK;
1601  rSTACK.push(state);
1602  rStackStates.Insert(state);
1603 
1604  //<<create set "L[state]" of successor states of state, without states reached via a Yc-event:
1605  StateSet SuccStates = StateSet();
1606  TransSet::Iterator it = rGen.TransRelBegin(state);
1607  TransSet::Iterator it_end = rGen.TransRelEnd(state);
1608  for (; it != it_end; ++it) {
1609  if(!rYc.Exists(it->Ev)||(UnMarkedOnly &! rGen.ExistsMarkedState(it->X2)))
1610  {
1611  SuccStates.Insert(it->X2);
1612  }
1613  }
1614 
1615  // for each vertex *sit on L[state] do
1616  StateSet::Iterator sit = SuccStates.Begin();
1617  StateSet::Iterator sit_end = SuccStates.End();
1618  for (; sit != sit_end; ++sit)
1619  {
1620  // if *sit is marked "new" then
1621  if(rNewStates.Exists(*sit))
1622  {// begin
1623 
1624  // SearchC(*sit);
1625  SearchYclessScc(*sit, rcount, rGen, rYc, UnMarkedOnly, rNewStates, rSTACK, rStackStates, rDFN, rLOWLINK, rSccSet, rRoots);
1626  // LOWLINK[state] <- MIN(LOWLINK[state],LOWLINK[*sit]);
1627  if(rLOWLINK[*sit]<rLOWLINK[state])
1628  {
1629  rLOWLINK[state]=rLOWLINK[*sit];
1630  }
1631  }//end
1632 
1633  else
1634  {
1635  // if DFNUMBER[*sit]<DFNUMBER[state] and [*sit] is on STACK then
1636  if((rDFN[*sit]<rDFN[state])&&(rStackStates.Exists(*sit)))
1637  {
1638  // LOWLINK[state]<-MIN(DFNUMBER[*sit],LOWLINK[state]);
1639  if(rDFN[*sit]<rLOWLINK[state])
1640  {
1641  rLOWLINK[state]=rDFN[*sit];
1642  }
1643  }
1644  }
1645  }//end for
1646  // if LOWLINK[state]=DFNUMBER[state] (i.e. state is root of a SCC) then
1647  if(rLOWLINK[state]==rDFN[state])
1648  {
1649  // per def., each state in a graph is element of a SCC, thus:
1650  // check if size of SCC is>1 or (else) SCC contains (non-{epsilon,yc}-)selfloops
1651  // to avoid print of trivial SCCs
1652  bool realscc=rSTACK.top()!=state; //size of SCC>1 ? if not, check for selfloops:
1653  if(!realscc)
1654  {
1655  TransSet::Iterator it = rGen.TransRelBegin(state);
1656  TransSet::Iterator it_end = rGen.TransRelEnd(state);
1657  for (; it != it_end; ++it)
1658  {
1659  if((it->X2==state)&&(!rYc.Exists(it->Ev)))
1660  {
1661  realscc=true; //at least one yc-less selfloop found -> SCC is nontrivial
1662  break;
1663  }
1664  }
1665  }
1666 
1667  //~ if(realscc) // be aware: "else" statement is NOT correct at this point, as realscc-value is changed in the above if-clause
1668  //~ {
1669  //~ // cout<<endl<<"found ycless SCC with root "<<state<<", consisting of the following states:"<<endl<<"begin"<<endl;
1670  //~ rRoots.Insert(state);
1671  //~ }
1672 
1673  //create SCC
1674  StateSet Scc;
1675  bool purelyUnMarked=true;
1676  // begin
1677  // repeat
1678  while(true)
1679  {// begin
1680  // pop x from top of STACK and print x;
1681  Idx top=rSTACK.top();
1682  if(realscc) // things outside the "if(realscc)"-clause have to be done in any case!
1683  {
1684  // cout<<top;
1685  Scc.Insert(top);
1686  if(rGen.ExistsMarkedState(top)) purelyUnMarked=false;
1687  }
1688  rStackStates.Erase(top);
1689  rSTACK.pop();
1690 
1691  // until x=state;
1692  if(top==state)
1693  {
1694  // print "end of SCC", insert SCC into SCCset;
1695  if(realscc)
1696  {
1697  // cout<<endl<<"end"<<endl;
1698  if(!purelyUnMarked || UnMarkedOnly)
1699  {
1700  rSccSet.insert(Scc);
1701  rRoots.Insert(state);
1702  }
1703  }
1704  //system("pause");
1705  break;
1706  }
1707  // cout<<", "<<endl;
1708  } //end while
1709  } // end if
1710 }
1711 
1712 // YclessScc(Generator,Yc-events, SccSet, Roots)
1713 // -> api using SearchYclessScc() from above.
1715  const Generator& rGen,
1716  const EventSet& rYc,
1717  std::set<StateSet>& rSccSet,
1718  StateSet& rRoots)
1719 {
1720  FD_DF("YclessScc(" << rGen.Name() << ")");
1721 
1722  // inititalize results:
1723  rRoots.Clear();
1724  rSccSet.clear();
1725  // initialize counter for depthfirstnumbers(DFN):
1726  int count=1;
1727 
1728  // initialize stack of states (state indeces):
1729  std::stack<Idx> STACK;
1730  // due to lack of STACK-iterator: initialize set of states that are on STACK:
1731  StateSet StackStates = StateSet();
1732 
1733  // initialize set of states to be examined:
1734  StateSet NewStates=rGen.AccessibleSet();
1735 
1736  // initialize map of state indeces to their DFN:
1737  std::map<const Idx, int> DFN;
1738  // initialize map of state indeces to their LOWLINK:
1739  std::map<const Idx, int> LOWLINK;
1740 
1741  // figure initial state:
1742  Idx InitState = *rGen.InitStatesBegin();
1743  // start recursive depth-first search for Scc's:
1744  while(!NewStates.Empty()) {
1745  // the following 'if' isn't necessary, but provokes search begin at initial state of rGen
1746  if(NewStates.Exists(InitState)) {
1747  SearchYclessScc(InitState, count, rGen, rYc, false, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
1748  } else {
1749  SearchYclessScc(*NewStates.Begin(), count, rGen, rYc, false, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
1750  }
1751  }
1752 
1753  return !rSccSet.empty();
1754 }
1755 
1756 // YclessUnMarkedScc(Generator,Yc-events, SccSet, Roots)
1757 // -> api using SearchYclessScc() from above.
1759  const Generator& rGen,
1760  const EventSet& rYc,
1761  std::set<StateSet>& rSccSet,
1762  StateSet& rRoots)
1763 {
1764  FD_DF("YclessScc(" << rGen.Name() << ")");
1765 
1766  // inititalize results:
1767  rRoots.Clear();
1768  rSccSet.clear();
1769  // initialize counter for depthfirstnumbers(DFN):
1770  int count=1;
1771 
1772  // initialize stack of states (state indeces):
1773  std::stack<Idx> STACK;
1774  // due to lack of STACK-iterator: initialize set of states that are on STACK:
1775  StateSet StackStates = StateSet();
1776 
1777  // initialize set of states to be examined:
1778  StateSet NewStates=rGen.AccessibleSet()-rGen.MarkedStates();
1779 
1780  // initialize map of state indeces to their DFN:
1781  std::map<const Idx, int> DFN;
1782  // initialize map of state indeces to their LOWLINK:
1783  std::map<const Idx, int> LOWLINK;
1784 
1785  // figure initial state:
1786  Idx InitState = *rGen.InitStatesBegin();
1787  // start recursive depth-first search for Scc's:
1788  while(!NewStates.Empty()) {
1789  // the following 'if' isn't necessary, but provokes search begin at initial state of rGen
1790  if(NewStates.Exists(InitState)) {
1791  SearchYclessScc(InitState, count, rGen, rYc, true, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
1792  } else {
1793  SearchYclessScc(*NewStates.Begin(), count, rGen, rYc, true, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
1794  }
1795  }
1796 
1797  return !rSccSet.empty();
1798 }
1799 
1800 
1801 // YclessScc(rGen,rYc,rSccSet)
1802 // -> api using YclessScc() from above.
1804  const Generator& rGen,
1805  const EventSet& rYc,
1806  std::set<StateSet>& rSccSet)
1807 {
1808  FD_DF("YclessScc(" << rGen.Name() << ")");
1809 
1810  // inititalize result:
1811  rSccSet.clear();
1812 
1813  StateSet Roots;
1814  return YclessScc(rGen,rYc,rSccSet,Roots);
1815 }
1816 
1817 // IsYcLive(rGen,rYc)
1819  const Generator& rGen,
1820  const EventSet& rYc)
1821 {
1822  FD_DF("IsYcLive(" << rGen.Name() << ")");
1823 
1824  std::set<StateSet> rSccSet;
1825 
1826  // Generator is YcLive if no YcLessScc is found
1827  YclessScc(rGen,rYc,rSccSet);
1828  return rSccSet.size()==0;
1829 }
1830 
1831 // WriteStateSets(rStateSets)
1832 // Write set of StateSet's to console.
1834  const std::set<StateSet>& rStateSets)
1835 {
1836  FD_DF("WriteStateSets()");
1837  std::cout<<std::endl;
1838  if(rStateSets.empty()) {
1839  std::cout<<"WriteStateSets: Set of state sets is empty."<<std::endl;
1840  FD_DF("WriteStateSets: Set of state sets is empty.");
1841  return;
1842  }
1843  std::cout<<">WriteStateSets: Set of state sets begin:"<< std::endl;
1844  std::set<StateSet>::iterator StateSetit = rStateSets.begin();
1845  std::set<StateSet>::iterator StateSetit_end = rStateSets.end();
1846  for (; StateSetit != StateSetit_end; ++StateSetit) {
1847  std::cout<<std::endl<<" >> State set begin:"<< std::endl;
1848  StateSet::Iterator sit = StateSetit->Begin();
1849  StateSet::Iterator sit_end = StateSetit->End();
1850  for (; sit != sit_end; ++sit) {
1851  std::cout<<" >> "<<*sit<<std::endl;
1852  }
1853  std::cout<<" >> State set end."<< std::endl;
1854  }
1855  std::cout<<std::endl<<">WriteStateSets: Set of state sets end."<<std::endl;
1856 }
1857 
1858 // WriteStateSets(rGen,rStateSets)
1859 // Write set of StateSet's to console.
1860 // Use rGen for symbolic state names
1862  const Generator& rGen,
1863  const std::set<StateSet>& rStateSets)
1864 {
1865  FD_DF("WriteStateSets()");
1866  std::cout<<std::endl;
1867  if(rStateSets.empty()) {
1868  std::cout<<"WriteStateSets: Set of state sets is empty."<<std::endl;
1869  FD_DF("WriteStateSets: Set of state sets is empty.");
1870  return;
1871  }
1872  std::cout<<">WriteStateSets: Set of state sets begin:"<< std::endl;
1873  std::set<StateSet>::iterator StateSetit = rStateSets.begin();
1874  std::set<StateSet>::iterator StateSetit_end = rStateSets.end();
1875  for (; StateSetit != StateSetit_end; ++StateSetit) {
1876  std::cout<<std::endl<<" >> State set begin:"<< std::endl;
1877  std::cout<<" "<<rGen.StateSetToString(*StateSetit)<<std::endl;
1878  std::cout<<" >> State set end."<< std::endl;
1879  }
1880  std::cout<<std::endl<<">WriteStateSets: Set of state sets end."<<std::endl;
1881 }
1882 
1883 // SccEntries(rGen,rSccSet,rEntryStates,rEntryTransSet)
1885  const Generator& rGen,
1886  const std::set<StateSet>& rSccSet,
1887  StateSet& rEntryStates,
1888  TransSetX2EvX1& rEntryTransSet) {
1889 
1890  FD_DF("SccEntries(...)");
1891 
1892  // prepare results:
1893  rEntryStates.Clear();
1894  rEntryTransSet.Clear();
1895 
1896  //extract all transitions sorted by target state X2
1897  TransSetX2EvX1 trel;
1898  rGen.TransRel(trel);
1899  FD_DF("SccEntries: Entry states of all SCCs:");
1900 
1901  //loop through all SCCs:
1902  std::set<StateSet>::iterator sccit = rSccSet.begin();
1903  std::set<StateSet>::iterator sccit_end = rSccSet.end();
1904  for (int i=0; sccit != sccit_end; ++sccit, i++) {
1905  FD_DF("SccEntries: SCC " << i << " begin:");
1906  //loop through all states:
1907  StateSet::Iterator sit = sccit->Begin();
1908  StateSet::Iterator sit_end = sccit->End();
1909  for (; sit != sit_end; ++sit) {
1910  //check if sit is initial state:
1911  if(rGen.ExistsInitState(*sit)) {
1912  rEntryStates.Insert(*sit);
1913  }
1914  //loop through all transitions with target state X2=sit:
1915  TransSetX2EvX1::Iterator tit=trel.BeginByX2(*sit);
1916  TransSetX2EvX1::Iterator tit_end=trel.EndByX2(*sit);
1917  for(;tit!=tit_end;tit++) {
1918  //if sit is successor of a state X1 that is element of a SCC different
1919  //from the current SCC "StateSetit" and if sit has not been added to
1920  //rEntryStates up to now, then add sit to EntryStates:
1921  if(!sccit->Exists(tit->X1)) {
1922  // insert entry transition:
1923  rEntryTransSet.Insert(*tit);
1924  // if new, insert entry state:
1925  if(!rEntryStates.Exists(*sit)) {
1926  // Perk: check if Insert returns false anyway if element already
1927  // existed before. if so, then write:
1928  // if(rEntryStates.Insert(*sit)) FD_DF("SccEntries: Entry state:" <<*sit);
1929  FD_DF("SccEntries: Entry state:" <<*sit);
1930  rEntryStates.Insert(*sit);
1931  }
1932  }
1933  }
1934  }
1935  FD_DF("SccEntries: SCC " << i << " end:");
1936  }
1937  FD_DF("SccEntries: done");
1938 }
1939 
1940 // CloneScc(rGen,rScc,rSccSet,rEntryState,rEntryStates,rEntryTransSet)
1942  Generator& rGen,
1943  const StateSet& rScc,
1944  std::set<StateSet>& rSccSet,
1945  const Idx EntryState,
1946  StateSet& rEntryStates,
1947  TransSetX2EvX1& rEntryTransSet)
1948 {
1949  FD_DF("CloneScc(...)");
1950  // initialize map from original SCC-states to their clones:
1951  std::map<const Idx, Idx> clone;
1952  // initialize clone-SCC:
1954  // clone SCC-states:
1955  StateSet::Iterator sit=rScc.Begin();
1956  StateSet::Iterator sit_end=rScc.End();
1957  for(;sit!=sit_end;sit++) {
1958  // if sit is marked, also mark its clone
1959  if(rGen.ExistsMarkedState(*sit)) {
1960  clone[*sit]=rGen.InsMarkedState();
1961  CloneScc.Insert(clone[*sit]);
1962  // cout<<"marked state "<<clone[*sit]<<" of "<<*sit<<" inserted.";
1963  }
1964  // or else insert unmarked state
1965  else {
1966  clone[*sit]=rGen.InsState();
1967  CloneScc.Insert(clone[*sit]);
1968  // cout<<"unmarked state "<<clone[*sit]<<" of "<<*sit<<" inserted.";
1969  }
1970  }
1971  // add clone of SCC to set of all SCCs:
1972  rSccSet.insert(CloneScc);
1973  // clone all transitions:
1974  sit=rScc.Begin();
1975  for(;sit!=sit_end;sit++) {
1976  TransSet::Iterator tit=rGen.TransRelBegin(*sit);
1977  TransSet::Iterator tit_end=rGen.TransRelEnd(*sit);
1978  for(;tit!=tit_end;tit++) {
1979  // clone all transitions within SCC:
1980  if(rScc.Exists(tit->X2)) {
1981  rGen.SetTransition(clone[*sit],tit->Ev,clone[tit->X2]);
1982  }
1983  //...and transitions leaving the SC:
1984  else {
1985  rGen.SetTransition(clone[*sit],tit->Ev,tit->X2);
1986  //**** added 06.09.2007:
1987  // If this cloned transition leads to an entry state of
1988  // some other SCC, then it is a new entry transition:
1989  if(rEntryStates.Exists(tit->X2)) {
1990  rEntryTransSet.Insert(clone[*sit],tit->Ev,tit->X2);
1991  }
1992  //****
1993  }
1994  }
1995  }
1996  // move the head of all entry transitions leading to EntryState to the clone of EntryState:
1997  TransSet TransToClear, EntryTransToInsert;
1998  TransSetX2EvX1::Iterator tit=rEntryTransSet.BeginByX2(EntryState);
1999  TransSetX2EvX1::Iterator tit_end=rEntryTransSet.EndByX2(EntryState);
2000  for(;tit!=tit_end;tit++) {
2001  // cout<<endl<<"Moving entryTransition "<<"("<<tit->X1<<","<<rGen.EventName(tit->Ev)<<","<<tit->X2<<")";
2002  // cout<<" to target state "<<clone[EntryState];
2003  rGen.SetTransition(tit->X1,tit->Ev,clone[EntryState]);
2004  //prebook new moved transition to be inserted in rEntryTransSet:
2005  EntryTransToInsert.Insert(tit->X1,tit->Ev,clone[EntryState]);
2006  //prebook transitions to former entry state to clear in rGen and rEntryTransSet:
2007  TransToClear.Insert(*tit);
2008  }
2009  //clear former transitions in rGen and rEntryTransSet:
2010  TransSet::Iterator tit2=TransToClear.Begin();
2011  TransSet::Iterator tit2_end=TransToClear.End();
2012  for(;tit2!=tit2_end;tit2++) {
2013  rGen.ClrTransition(*tit2);
2014  //erase transitions to former entry state from rEntryTransSet:
2015  rEntryTransSet.Erase(*tit2);
2016  }
2017  // update rEntryTransSet with new moved entry transitions:
2018  TransSet::Iterator tit3=EntryTransToInsert.Begin();
2019  TransSet::Iterator tit3_end=EntryTransToInsert.End();
2020  for(;tit3!=tit3_end;tit3++) {
2021  //insert new moved transitions in rEntryTransSet:
2022  rEntryTransSet.Insert(*tit3);
2023  }
2024  //update rEntryStateSet:
2025  rEntryStates.Erase(EntryState); // erase former ambiguous entry state
2026  rEntryStates.Insert(clone[EntryState]); // insert unique entry state of cloned SCC
2027 }
2028 
2029 // CloneUnMarkedScc(rGen,rScc,rSccSet,rEntryState,rEntryStates,rEntryTransSet)
2031  Generator& rGen,
2032  const StateSet& rScc,
2033  const Idx EntryState,
2034  const StateSet& rEntryStates,
2035  TransSetX2EvX1& rEntryTransSet)
2036 {
2037  FD_DF("CloneUnMarkedScc(...)");
2038  // initialize map from original SCC-states to their clones:
2039  std::map<const Idx, Idx> clone;
2040  // initialize clone-SCC:
2042  // clone all SCC-states but EntryState:
2043  StateSet::Iterator sit=rScc.Begin();
2044  StateSet::Iterator sit_end=rScc.End();
2045  for(;sit!=sit_end;sit++) {
2046  if(*sit != EntryState) {
2047  clone[*sit]=rGen.InsState();
2048  CloneScc.Insert(clone[*sit]);
2049  }
2050  else clone[*sit]=*sit; // entry state is not cloned
2051 
2052  }
2053 
2054  //*** Think about this:
2055  // // add clone of SCC to set of all SCCs:
2056  // rSccSet.insert(CloneScc);
2057  //***
2058 
2059  // clone all transitions:
2060  TransSet TransToClear;
2061  sit=rScc.Begin();
2062  bool isEntryState=false;
2063  TransSet::Iterator tit,tit_end;
2064  for(;sit!=sit_end;sit++) {
2065  isEntryState=(*sit==EntryState);
2066  tit=rGen.TransRelBegin(*sit);
2067  tit_end=rGen.TransRelEnd(*sit);
2068  for(;tit!=tit_end;tit++) {
2069  // clone all transitions within SCC:
2070  if(rScc.Exists(tit->X2)) {
2071  rGen.SetTransition(clone[*sit],tit->Ev,clone[tit->X2]);
2072  // if transition starts at entry state, only keep the clone transition
2073  if(isEntryState) {
2074  // prebook this transition to be cleared
2075  TransToClear.Insert(*tit);
2076  }
2077  }
2078  //...and transitions leaving the SCC:
2079  else {
2080  rGen.SetTransition(clone[*sit],tit->Ev,tit->X2);
2081  //**** added 06.09.2007:
2082  // If this cloned transition leads to an entry state of
2083  // some other SCC, then it is a new entry transition:
2084  if(rEntryStates.Exists(tit->X2)) {
2085  rEntryTransSet.Insert(clone[*sit],tit->Ev,tit->X2);
2086  }
2087  //****
2088  }
2089  }
2090  }
2091 
2092  // clear prebooked transitions
2093  tit=TransToClear.Begin();
2094  tit_end=TransToClear.End();
2095  for(;tit!=tit_end;tit++) {
2096  rGen.ClrTransition(*tit);
2097  }
2098 
2099 }
2100 //============================
2101 
2102 
2103 
2104 // YcAcyclic(rGen,rYc,rResGen)
2106  const Generator& rGen,
2107  const EventSet& rYc,
2108  Generator& rResGen)
2109 {
2110  FD_DF("YcAcyclic: Statesize before: "<<rGen.Size()<<" - starting...");
2111  // initialize set of ycless strongly connected components (SCCs):
2112  std::set<StateSet> SccSet,UnMarkedSccSet;
2113  // initialize set of all states that are member or root or entry state of some SCC:
2114  StateSet Scc,Roots,EntryStates,notRoots,UnMarkedRoots;
2115  // initialize set of transitions that enter some SCC from a different SCC,
2116  // sorted by target states X2 (which are entry states):
2117  TransSetX2EvX1 EntryTransSet;
2118  // take rGen as first candidate:
2119  rResGen=rGen;
2120  // counter for below while loop:
2121  // int i=0;
2122 
2123  while(true) {
2124  //++i;
2125  // check for SCCs and return if there are none -> ResGen is the result.
2126  // cout<<endl<<"Round "<<i<<": Searching for remaining Yc-less SCCs...";
2127  if(!YclessScc(rResGen,rYc,SccSet,Roots)) {
2128  //time_t *t2;
2129  //time(t2);
2130  //cout<<"...finished in "<<difftime(*t2, *t1)<<" seconds.";
2131  //rResGen.DotWrite("tmp_YcAcyclic_res");
2132  FD_DF("YcAcyclic: Statesize of result: "<<rResGen.Size());
2133 // cout<<". Statemin...";
2134 // Generator tmp;
2135 // StateMin(rResGen,tmp);
2136 // cout<<"done. New Statesize:"<<tmp.Size();
2137 // tmp.ClrStateNames();
2138 // rResGen=tmp;
2139 // tmp.Clear();
2140  //rResGen.Write("tmp_YcAcyclic.gen");
2141  return;
2142  }
2143  //cout<<endl<<"...found "<<SCCset.size()<<" Yc-less SCCs: computing entry states...";
2144 // cout<<"Found following Yc-less SCCs:"<<endl;
2145 // WriteStateSets(SCCset);
2146 // system("pause");
2147  // else figure entry states and entry transitions of the SCCs
2148  SccEntries(rResGen,SccSet,EntryStates,EntryTransSet);
2149 
2150  // root states are kept as entry states of the original SCCs, for all other
2151  // entry states clone SCCs:
2152  notRoots=EntryStates - Roots;
2153  //cout<<"...found "<<notRoots.Size()<<" entry states that are not roots. Start cloning SCCs..."<<endl;
2154 // cout<<endl<<"EntryStates before cloning:"<<endl;
2155 // EntryStates.DWrite();
2156 // cout<<endl<<"Roots before cloning:"<<endl;
2157 // Roots.DWrite();
2158 // cout<<endl<<"notRoots before cloning:"<<endl;
2159 // notRoots.DWrite();
2160 
2161  StateSet::Iterator sit=notRoots.Begin();
2162  StateSet::Iterator sit_end=notRoots.End();
2163  for(;sit!=sit_end;sit++)
2164  {
2165  // figure SCC with entry state sit:
2166  std::set<StateSet>::iterator sccit = SccSet.begin();
2167  std::set<StateSet>::iterator sccit_end = SccSet.end();
2168  for (; sccit != sccit_end; ++sccit)
2169  {
2170  if(sccit->Exists(*sit))
2171  {
2172  Scc=*sccit;
2173  break;
2174  }
2175  }
2176  // clone this SCC (and add clone to SCCset):
2177 // cout<<"cloning SCCC:"<<endl;
2178 // SCC.DWrite();
2179  CloneScc(rResGen,Scc,SccSet,*sit,EntryStates,EntryTransSet);
2180 // cout<<endl<<"New set of SCCs:"<<endl;
2181 // WriteStateSets(SccSet);
2182  }
2183  //cout<<endl<<"...done. Identifying unique entry states...";
2184 // rResGen.Write("tmp_YcAcyclic_step.gen");
2185 // rResGen.DotWrite("tmp_YcAcyclic_step");
2186 // ++i;
2187 // cout<<endl<<"Printed intermediate result "<<i<<"."<<endl;
2188 // system("pause");
2189 
2190  // Now, all SCCs have one unique entry state.
2191  // If some SCC contains a sub-SCC that a) includes the entry
2192  // state of the whole SCC and b) consists of only unmarked
2193  // states, then this sub-SCC has to be copied to resolve the
2194  // ambiguity.
2195  if( !( ((rResGen.States()-rResGen.MarkedStates())*EntryStates).Empty() ) ) {
2196  // find possible unmarked sub-SCCs including EntryState
2197  YclessUnmarkedScc(rResGen,rYc,UnMarkedSccSet,UnMarkedRoots);
2198  std::set<StateSet>::iterator sccit = UnMarkedSccSet.begin();
2199  std::set<StateSet>::iterator sccit_end = UnMarkedSccSet.end();
2200  for (; sccit != sccit_end; ++sccit) {
2201  // check if this unmarked sub-SCC includes an EntryState; if so: clone it
2202  if( !( ((*sccit)*EntryStates).Empty() ) ) {
2203  Idx EntryState=*(((*sccit)*EntryStates).Begin());
2204  CloneUnMarkedScc(rResGen,*sccit,EntryState,EntryStates,EntryTransSet);
2205  }
2206  }
2207  }
2208 
2209 
2210 
2211  //"Back transitions" leading
2212  // from a SCC to its own entry state have to be cancelled,
2213  // if they are not Yc-transitions:
2214 
2215  // 2) loop through all SCCs and find Ycless back transitions:
2216  TransSet TransToClear;
2217  std::set<StateSet>::iterator sccit = SccSet.begin();
2218  std::set<StateSet>::iterator sccit_end = SccSet.end();
2219  //cout<<endl<<"Determining non-yc-backtransitions...";
2220  for (; sccit != sccit_end; ++sccit)
2221  {
2222  //loop through all states:
2223  StateSet::Iterator sit = sccit->Begin();
2224  StateSet::Iterator sit_end = sccit->End();
2225  for (; sit != sit_end; ++sit)
2226  {
2227  //cout<<endl<<"looping state "<<*sit<<endl;
2228  // loop through all transitions:
2229  TransSet::Iterator tit=rResGen.TransRelBegin(*sit);
2230  TransSet::Iterator tit_end=rResGen.TransRelEnd(*sit);
2231  for(;tit!=tit_end;tit++)
2232  {
2233  // Check if tit leads back to entry state of current SCC
2234  // and if it is not a Yc-transition:
2235  if(sccit->Exists(tit->X2) && EntryStates.Exists(tit->X2)
2236  &&!rYc.Exists(tit->Ev))
2237  {
2238  //cout<<" - Trans to clear: "<<tit->Ev<<endl;
2239  TransToClear.Insert(*tit);
2240  }
2241  }
2242  }
2243  }
2244  //cout<<endl<<"...found "<<TransToClear.Size()<<" transitions. Deleting these transitions...";
2245  // 3) Clear back transitions:
2246  TransSet::Iterator tit=TransToClear.Begin();
2247  TransSet::Iterator tit_end=TransToClear.End();
2248  for(;tit!=tit_end;tit++)
2249  {
2250  //cout<<"clearing transition ("<<tit->X1<<","<<rResGen.EventName(tit->Ev)<<","<<tit->X2<<")"<<endl;
2251  rResGen.ClrTransition(*tit);
2252  }
2253 
2254 // ++i;
2255 // rResGen.Write("tmp_YcAcyclic_step.gen");
2256 // rResGen.DotWrite("tmp_YcAcyclic_step");
2257 // cout<<endl<<"Printed intermediate result "<<i<<"."<<endl;
2258 // system("pause");
2259 // cout<<endl<<"...transitions deletetd, next round!";
2260 // cout<<endl<<"state size of current intermediate result: "<<rResGen.Size();
2261  //cout<<endl<<". Press enter to start statemin."<<endl;
2262  //string anykey;
2263  //getline( cin, anykey );
2264 
2265 // cout<<". Statemin...";
2266 // Generator tmp;
2267 // StateMin(rResGen,tmp);
2268 // cout<<"done. New Statesize:"<<tmp.Size();
2269 // rResGen=tmp;
2270 // tmp.Clear();
2271 
2272 // system("pause");
2273  } //end while(true): resulting generator might contain SCCs within the
2274  // SCCs that have been "broken" in this step -> continue while-loop.
2275 }
2276 
2277 //**********************************************************
2278 //******************** hio synthesis ************************
2279 //**********************************************************
2280 
2281 // ConstrSynth_Beta(rPlant,rYp,rUp,rOpConstr)
2283  Generator& rPlant,
2284  const EventSet& rYp,
2285  const EventSet& rUp,
2286  const Generator& rLocConstr,
2287  Generator& rOpConstraint) {
2288 
2289  FD_DF("ConstrSynth_Beta(...)");
2290 
2291  // helper
2292  Generator tmpGen;
2293  EventSet sigmap=rYp+rUp;
2294 
2295  //prepare rsult:
2296  rOpConstraint.Clear();
2297 
2298  // respect optional local constraints
2299  Parallel(rPlant,rLocConstr,rOpConstraint);
2300 
2301  // calculate YpAcyclic sublanguage:
2302  YcAcyclic(rOpConstraint,rYp,tmpGen);
2303  rOpConstraint.Clear();
2304 
2305  // compute normal, complete, controllable and nonblocking sublanguage
2306  // note: tmpGen has role of spec
2307  NormalCompleteSynthNB(rPlant,rUp,sigmap,tmpGen,rOpConstraint);
2308  tmpGen.Clear();
2309 
2310  // project to P-Alphabet
2311  Project(rOpConstraint,sigmap,tmpGen);
2312  rOpConstraint.Clear();
2313 
2314  // minimize state space
2315  StateMin(tmpGen,tmpGen);
2316  tmpGen.StateNamesEnabled(false);
2317 
2318  // eneable symbolic state names for error states
2319  tmpGen.StateNamesEnabled(true);
2320  rOpConstraint.StateNamesEnabled(true);
2321  // make YP free in OpConstr
2322  HioFreeInput(tmpGen, rYp, rUp, rOpConstraint, "errUp","errYp");
2323 
2324  rOpConstraint.Name("ConstrSynth_Beta("+rPlant.Name()+")");
2325 
2326  return;
2327  }
2328 
2329 // HioSynthUnchecked(rPlant,rSpec,rConstr,rLocConstr,rYc,rUc,rYp,rUp,rYel,rUel,rController)
2331  const Generator& rPlant,
2332  const Generator& rSpec,
2333  const Generator& rExtConstr,
2334  const Generator& rLocConstr,
2335  const EventSet& rYc,
2336  const EventSet& rUc,
2337  const EventSet& rYp,
2338  const EventSet& rUp,
2339  const EventSet& rYel,
2340  const EventSet& rUel,
2341  Generator& rController)
2342 {
2343  FD_DF("HioSynth(...)");
2344  //prepare rsult:
2345  rController.Clear();
2346  //make copy of plant, spec for modifications
2347  Generator plant,spec;
2348  plant = rPlant;
2349  spec = rSpec;
2350 
2351  //create necessary eventsets:
2352  EventSet sigmacp;
2353  sigmacp.InsertSet(rUc + rYc + rUp + rYp);
2354  EventSet sigmace;
2355  sigmace.InsertSet(rUc + rYc + rUel + rYel);
2356 
2357  EventSet allsigma;
2358  allsigma.InsertSet(rPlant.Alphabet());
2359  allsigma.InsertSet(rSpec.Alphabet());
2360 
2361  EventSet controllable, wait;
2362  controllable.InsertSet(rUp);
2363  controllable.InsertSet(rYc);
2364 
2365  //make alphabets of plant and spec match:
2366  InvProject(plant,allsigma);
2367  InvProject(spec,allsigma);
2368 
2369  // FD_DF("******************** actual plant: composition with external constraints");
2370 
2371  // generate plant under constraint:
2372  Parallel(plant,rExtConstr,plant);
2373  //plant.Write("tmp_cplant.gen");
2374 
2375  //FD_DF("******************** mininmal hio structure, composition with plant");
2376  Generator minhio;
2377  minhio = HioSortCL(rYc,rUc,rYp,rUp,rYel,rUel);
2378  //minhio.Write("tmp_minhio.gen");
2379 
2380  // generate plant in hio structure:
2381  Parallel(plant,minhio,plant);
2382  plant.StateNamesEnabled(false);
2383  //plant.Write("tmp_hiocplant.gen");
2384 
2385  //FD_DF("******************** composition plant-specification: tmp_plantspec.gen ");
2386 
2387  // composition of plant, I/O sorting, constraint and specification:
2388  Generator plantspec;
2389  Parallel(plant,spec,plantspec);
2390  //plantspec.Write("tmp_plantspec.gen");
2391  plantspec.StateNamesEnabled(false);
2392  FD_DF("Size of plantspec: "<<plantspec.Size()<<" - Statemin...");
2393  StateMin(plantspec,plantspec);
2394  FD_DF("done. New Statesize: "<<plantspec.Size()<<".");
2395  plantspec.StateNamesEnabled(false);
2396  //plantspec.Write("results/tmp_plantspec.gen");
2397  FD_DF("******************** computing YcAcyclic(plantspec):");
2398 
2399  // calculate YcAcyclic sublanguage of plantspec:
2400  Generator yclifeplantspec;
2401  YcAcyclic(plantspec,rYc,yclifeplantspec);
2402  yclifeplantspec.StateNamesEnabled(false);
2403  //yclifeplantspec.Write("tmp_YcAcyclic.gen");
2404 
2405  //FD_DF("******************** actual spec: composition yclifeplantspec||minhio||locconstr (tmp_actualspec.gen)");
2406  //generate plantspec with closed-loop I/O sorting:
2407  Parallel(yclifeplantspec,minhio,plantspec);
2408  yclifeplantspec.Clear();
2409  //add local constraints to plantspec: the result is the actual spec for synthesis
2410  Parallel(plantspec,rLocConstr,plantspec);
2411  plantspec.StateNamesEnabled(false);
2412  plantspec.Name("actualspec");
2413  //plantspec.Write("tmp_actualspec.gen");
2414 
2415  //FD_DF("******************** closed loop synthesis: tmp_closedloop.gen/.dot");
2416 
2417  // compute normal, complete and controllable sublangugae of actualspec w.r.t. plant under constraints (cplant):
2418  Generator loop;
2419  NormalCompleteSynthNB(plant,controllable,sigmacp,plantspec,loop);
2420  plantspec.Clear();
2421  //loop.Write("tmp_closedloop.gen");
2422 
2423  FD_DF("size of closed loop before StateMin: "<<loop.Size()<<", starting StateMin...");
2424  StateMin(loop,loop);
2425  FD_DF("...size of closed loop after StateMin (tmp_closedloop.gen): "<<loop.Size());
2426  //std::cout<<"ClosedLoop.IsTrim: "<<loop.IsTrim();
2427  loop.StateNamesEnabled(false);
2428  // loop.Write("tmp_closedloop.gen");
2429  FD_DF("********* IsYcLive(closed loop): "<<IsYcLive(loop,rYc));
2430  plant.Clear();
2431 
2432  //calculate external closedloop:
2433  FD_DF("******************** external closed loop: tmp_extloop.gen");
2434  Generator extloop;
2435  Project(loop,sigmace,extloop);
2436  FD_DF("size of external closed loop: "<<extloop.Size());
2437 
2438  // // recheck if specification is met:
2439  // if(LanguageInclusion(extloop,rSpec)) {
2440  // FD_DF("External closed loop meets specification.");
2441  // } // Perk: change below to LanguageInclusion with reverse order of parameters
2442  // // and move into above bracket.
2443  // if(LanguageEquality(extloop,rSpec)) {
2444  // FD_DF("External closed loop EQUALS specification.");
2445  // }
2446 
2447  extloop.StateNamesEnabled(false);
2448  //extloop.Write("tmp_extloop.gen");
2449 
2450  FD_DF("******************** project closed loop: tmp_controller.gen");
2451 
2452  Generator controller;
2453  Project(loop,sigmacp,controller);
2454  loop.Clear();
2455  controller.StateNamesEnabled(false);
2456  //controller.Write("tmp_controller.gen");
2457 
2458  // extend to io-controller: result
2459  HioFreeInput(controller, rYp, rUp, rController, "errUp","errYp");
2460  controller.Clear();
2461  FD_DF("size of marked IO controller: "<<rController.Size()<<". PrefixClosure, StateMin...");
2462 
2463  // the following procedure erases all marking information to reduce the result's state space! This step is unproblematic as long as the specification
2464  // is a prefix-closed system, because then, all marking information comes from the plant and is restored in the closed loop. Otherwise, care has to be taken
2465  // wether this step is correct or should be omitted .
2466  if(!(rSpec.AccessibleSet()<=rSpec.MarkedStates())) {
2467  FD_WARN("Careful: marking information of the specification has been erased from the resulting controller.");
2468  }
2469  PrefixClosure(rController);
2470  StateMin(rController,rController);
2471  FD_DF("...size of prefix-closed IO controller after StateMin: "<<rController.Size());
2472  rController.StateNamesEnabled(false);
2473  rController.Name("HioSynth("+rPlant.Name()+","+rSpec.Name()+")");
2474  FD_DF("IO controller synthesis done. ******************** " );
2475 }
2476 
2477 // HioSynth(rPlant,rSpec,rConstr,rLocConstr,rYc,rUc,rYp,rUp,rYel,rUel,rController)
2479  const Generator& rPlant,
2480  const Generator& rSpec,
2481  const Generator& rExtConstr,
2482  const Generator& rLocConstr,
2483  const EventSet& rYc,
2484  const EventSet& rUc,
2485  const EventSet& rYp,
2486  const EventSet& rUp,
2487  const EventSet& rYel,
2488  const EventSet& rUel,
2489  Generator& rController)
2490 {
2491 
2492  rController.Clear();
2493 
2494  #ifdef FAUDES_CHECKED
2495  // exception on empty alphabets
2496  if (rYc.Empty()){
2497  std::stringstream errstr;
2498  errstr << "Empty Yc alphabet\n";
2499  throw Exception("HioSynth", errstr.str(), 0);
2500  }
2501  if (rUc.Empty()){
2502  std::stringstream errstr;
2503  errstr << "Empty Uc alphabet\n";
2504  throw Exception("HioSynth", errstr.str(), 0);
2505  }
2506  if (rYp.Empty()){
2507  std::stringstream errstr;
2508  errstr << "Empty Yp alphabet\n";
2509  throw Exception("HioSynth", errstr.str(), 0);
2510  }
2511  if (rUp.Empty()){
2512  std::stringstream errstr;
2513  errstr << "Empty Up alphabet\n";
2514  throw Exception("HioSynth", errstr.str(), 0);
2515  }
2516  if (rYel.Empty()){
2517  std::stringstream errstr;
2518  errstr << "Empty Ye alphabet\n";
2519  throw Exception("HioSynth", errstr.str(), 0);
2520  }
2521  if (rUel.Empty()){
2522  std::stringstream errstr;
2523  errstr << "Empty Ue alphabet\n";
2524  throw Exception("HioSynth", errstr.str(), 0);
2525  }
2526 
2527  // create resulting alphabet while checking for disjoint sets
2528  EventSet alphabet,errevents;
2529  // initialize with rYc
2530  alphabet.InsertSet(rYc);
2531  // insert remaining events one by one and check if new
2532  EventSet::Iterator evit;
2533  // rUc
2534  for (evit = rUc.Begin(); evit != rUc.End(); ++evit) {
2535  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
2536  }
2537  // rYp
2538  for (evit = rYp.Begin(); evit != rYp.End(); ++evit) {
2539  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
2540  }
2541  // rUp
2542  for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
2543  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
2544  }
2545  // rYe
2546  for (evit = rYel.Begin(); evit != rYel.End(); ++evit) {
2547  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
2548  }
2549  // rUe
2550  for (evit = rUel.Begin(); evit != rUel.End(); ++evit) {
2551  if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
2552  }
2553  // throw exception on non disjoint alphabets
2554  if (!errevents.Empty()){
2555  std::stringstream errstr;
2556  errstr << "Non-disjoint parameters; ambiguous events:\n" <<errevents.ToString();
2557  throw Exception("HioSynth", errstr.str(), 0);
2558  }
2559  // check alphabet matches:
2560  EventSet plantEvents, specEvents;
2561  plantEvents=rPlant.Alphabet();
2562  specEvents=rSpec.Alphabet();
2563  // plant and spec must share environment alphabet
2564  if (!(plantEvents*specEvents==rYel+rUel)){
2565  std::stringstream errstr;
2566  errstr << "Alphabet mismatch between plant and spec:\n";
2567  errstr << "plant: " << plantEvents.ToString() << "\n";
2568  errstr << "spec: " << specEvents.ToString() << "\n";
2569  errstr << "Yel+Uel: " << (rYel+rUel).ToString() << "\n";
2570  throw Exception("HioSynth", errstr.str(), 0);
2571  }
2572  // ExtConstr must relate to spec alphabet
2573  if (!(rExtConstr.Alphabet()<=specEvents)){
2574  std::stringstream errstr;
2575  errstr << "Alphabet mismatch between external constraints and spec.\n";
2576  throw Exception("HioSynth", errstr.str(), 0);
2577  }
2578  // LocConstr must relate to plant alphabet
2579  if (!(rLocConstr.Alphabet()<=plantEvents)){
2580  std::stringstream errstr;
2581  errstr << "Alphabet mismatch between internal constraints and plant.\n";
2582  throw Exception("HioSynth", errstr.str(), 0);
2583  }
2584 
2585  // check I/O plant form of spec (note: plant may be composed group and thus need not be in I/o plant form)
2586  HioPlant spec(rSpec,rYc,rUc,rYel,rUel);
2587  std::string report;
2588  if(!IsHioPlantForm(spec,report)){
2589  std::stringstream errstr;
2590  errstr << "Spec not in HioPlantForm:\n" << report;
2591  throw Exception("HioSynth", errstr.str(), 0);
2592  }
2593  report.clear();
2594  #endif
2595 
2596  // do hio synthesis
2597  HioSynthUnchecked(rPlant,rSpec,rExtConstr,rLocConstr,rYc,rUc,rYp,rUp,rYel,rUel,rController);
2598 }
2599 
2600 // HioSynthMonolithic(rPlant,rSpec,rSc,rSp,rSe,rController)
2602  const HioPlant& rPlant,
2603  const HioPlant& rSpec,
2604  const HioConstraint& rSc,
2605  const HioConstraint& rSp,
2606  const HioConstraint& rSe,
2607  HioController& rController) {
2608 
2609  rController.Clear();
2610 
2611  #ifdef FAUDES_CHECKED
2612  // check I/O plant form of rPlant (further parameter checks in HioSynth())
2613  // tmp non-const copy of const rPlant
2614  HioPlant plant=rPlant;
2615  std::string report;
2616  if(!IsHioPlantForm(plant,report)){
2617  std::stringstream errstr;
2618  errstr << "Plant not in HioPlantForm:\n" << report;
2619  throw Exception("HioSynthMonolithic", errstr.str(), 0);
2620  }
2621  plant.Clear();
2622  report.clear();
2623  #endif
2624 
2625  // extract alphabets
2626  EventSet yc,uc,yp,up,ye,ue;
2627  yc=rSpec.YpEvents();
2628  uc=rSpec.UpEvents();
2629  yp=rPlant.YpEvents();
2630  up=rPlant.UpEvents();
2631  ye=rSpec.YeEvents();
2632  ue=rSpec.UeEvents();
2633 
2634  // generator for composed external constraints
2635  Generator extConstr;
2636  Parallel(rSc,rSe,extConstr);
2637 
2638  // run HioSynth procedure
2639  HioSynth(rPlant,rSpec,extConstr,rSp,yc,uc,yp,up,ye,ue,rController);
2640 
2641  // set event and state attributes
2642  rController.SetYc(yc);
2643  rController.SetUc(uc);
2644  rController.SetYp(yp);
2645  rController.SetUp(up);
2646 
2647  IsHioControllerForm(rController);
2648 }
2649 
2651  const HioPlant& rHioShuffle,
2652  const HioEnvironment& rEnvironment,
2653  const HioPlant& rSpec,
2654  const Generator& rIntConstr,
2655  const HioConstraint& rSc,
2656  const HioConstraint& rSl,
2657  HioController& rController) {
2658 
2659  rController.Clear();
2660 
2661  #ifdef FAUDES_CHECKED
2662  // check I/O plant form of rPlant (further parameter checks in HioSynth())
2663  // tmp non-const copy of const rPlant
2664  HioPlant plant=rHioShuffle;
2665  std::string report;
2666  if(!IsHioPlantForm(plant,report)){
2667  std::stringstream errstr;
2668  errstr << "HioShuffle not in HioPlantForm:\n" << report;
2669  throw Exception("HioSynthHierarchical", errstr.str(), 0);
2670  }
2671  plant.Clear();
2672  report.clear();
2673 
2674  // check I/O environment form
2675  // tmp non-const copy of const rEnvironment
2676  HioEnvironment env=rEnvironment;
2677  if(!IsHioEnvironmentForm(env,report)){
2678  std::stringstream errstr;
2679  errstr << "Environment not in HioEnvironmentForm:\n" << report;
2680  throw Exception("HioSynthHierarchical", errstr.str(), 0);
2681  }
2682  env.Clear();
2683  report.clear();
2684 
2685  // check for matching alphabets between ioshuffle, environment and spec
2686  if (!(rHioShuffle.EEvents()==rEnvironment.EEvents())){
2687  std::stringstream errstr;
2688  errstr << "Alphabet mismatch between I/O-shuffle and environment.\n";
2689  throw Exception("HioSynthHierarchical", errstr.str(), 0);
2690  }
2691  // check for matching alphabets between ioshuffle, environment and spec
2692  if (!(rSpec.EEvents()==rEnvironment.LEvents())){
2693  std::stringstream errstr;
2694  errstr << "Alphabet mismatch between specification and environment.\n";
2695  throw Exception("HioSynthHierarchical", errstr.str(), 0);
2696  }
2697 
2698  //(further parameter checks in HioSynth())
2699 
2700  #endif
2701  // compose ioshuffle and environment
2702  Generator ioShuffParEnv;
2703  Parallel(rHioShuffle,rEnvironment,ioShuffParEnv);
2704 
2705  // extract alphabets
2706  EventSet yc,uc,yp,up,ye,ue;
2707  yc=rSpec.YpEvents();
2708  uc=rSpec.UpEvents();
2709  yp=rHioShuffle.YpEvents();
2710  up=rHioShuffle.UpEvents();
2711  ye=rSpec.YeEvents();
2712  ue=rSpec.UeEvents();
2713 
2714  // generator for composed external constraints
2715  Generator extConstr;
2716  Parallel(rSc,rSl,extConstr);
2717 
2718  // run HioSynth procedure
2719  HioSynth(ioShuffParEnv,rSpec,extConstr,rIntConstr,yc,uc,yp,up,ye,ue,rController);
2720 
2721  // set event and state attributes
2722  rController.SetYc(yc);
2723  rController.SetUc(uc);
2724  rController.SetYp(yp);
2725  rController.SetUp(up);
2726 
2727  IsHioControllerForm(rController);
2728 }
2729 
2730 // end of hio_functions - below just archive
2731 
2732 //######################################################
2733 //############ Special versions for HioModule - will soon be obsolete
2734 
2735 //HioShuffle_Musunoi() - Version with hio-parameters
2737  const HioPlant& rPlantA,
2738  const HioPlant& rPlantB,
2739  int depth,
2740  Generator& rIOShuffAB)
2741 {
2742  FD_DF("HioShuffle()_Musunoi");
2743 
2744  //Extract alphabets:
2745  EventSet A,B,SigmaP, Yp, Up, Ye, Ue;
2746  Yp = rPlantA.YpEvents()+rPlantB.YpEvents();
2747  Ye = rPlantA.YeEvents()+rPlantB.YeEvents();
2748  Up = rPlantA.UpEvents()+rPlantB.UpEvents();
2749  Ue = rPlantA.UeEvents()+rPlantB.UeEvents();
2750  A = rPlantA.Alphabet();
2751  B = rPlantB.Alphabet();
2752 
2753 
2754  // parallel composition of plantA and plantB (i.e. shuffle as there are no shared events)
2755  Generator parallel1, parallel2;
2756  Parallel(rPlantA,rPlantB,parallel1);
2757 
2758  // restrict to event pairs [(SigA SigA)*+(SigB SigB)*]*, which results
2759  // in correct I/O sorting L_IO.
2760  Generator EventPairs; // generator of above sorting language
2761  EventPairs.InjectAlphabet(A + B);
2762  Idx state1,state2,state3;
2763  state1=EventPairs.InsInitState("1");
2764  EventPairs.SetMarkedState(state1);
2765  state2=EventPairs.InsMarkedState("2");
2766  state3=EventPairs.InsMarkedState("3");
2767  EventSet::Iterator evit;
2768  for (evit = A.Begin(); evit != A.End(); ++evit) {
2769  EventPairs.SetTransition(state1,*evit,state2);
2770  EventPairs.SetTransition(state2,*evit,state1);
2771  }
2772  for (evit = B.Begin(); evit != B.End(); ++evit) {
2773  EventPairs.SetTransition(state1,*evit,state3);
2774  EventPairs.SetTransition(state3,*evit,state1);
2775  }
2776  Parallel(parallel1,EventPairs,parallel2);
2777 
2778  //restrict to IO-sorting structure with forced alternation:
2779 
2780  // Old Vers before Dez 4 2006: + of whole alphabets
2781  EventSet Ap, Bp, Ae, Be, SigmaE;
2782 
2783  Ap = rPlantA.Alphabet();
2784  Bp = rPlantB.Alphabet();
2785 
2786  Ae = rPlantA.Alphabet();
2787  Be = rPlantB.Alphabet();
2788 
2789 
2790 
2791  //*************************************************************************
2792  //// New Vers: Alternation of YP Events only
2793  //// -> currently leads to normality problems during superposed controller synthesis
2794  SigmaP.InsertSet(Yp);
2795  SigmaP.InsertSet(Up);
2796  Ap.RestrictSet(SigmaP);
2797  Bp.RestrictSet(SigmaP);
2798 
2799  SigmaE.InsertSet(Ye);
2800  SigmaE.InsertSet(Ue);
2801  Ae.RestrictSet(SigmaE);
2802  Be.RestrictSet(SigmaE);
2803 
2804 
2805  //*************************************************************************
2806  Generator AltAB;
2807  Ap.Name("A");
2808  Bp.Name("B");
2809  CheapAltAB(Ap,Bp,depth,AltAB);
2810  // Alt_AB.Write("tmp_Alternation_AB.gen");
2811  Parallel(parallel2, AltAB, parallel1);
2812  //parallel2.Write("tmp_IOS3.gen");
2813 
2814 
2815 
2816  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2817  //*** Environment-first policy: If, in some state both, Yp- and Ye events are
2818  //*** active, then cancel all Yp-transitions in this state, as environment has
2819  //*** to be updated first.
2820 
2821  // loop all states
2822  StateSet::Iterator sit = parallel1.StatesBegin();
2823  StateSet::Iterator sit_end = parallel1.StatesEnd();
2824 
2825  for(; sit != sit_end; sit++)
2826  {
2827  // figure active Yp-events and active Ye-events
2828  //std::cout << "End: " << *sit_end <<"...done: " << *sit << std::endl;
2829  EventSet ActiveYe;
2830  EventSet ActiveYp = parallel1.TransRel().ActiveEvents(*sit);
2831  ActiveYe=ActiveYp;
2832  ActiveYe.RestrictSet(Ye);
2833  ActiveYp.RestrictSet(Yp);
2834 
2835  if (!(ActiveYe.Empty())&& !(ActiveYp.Empty()))
2836  {
2837  TransSet TransToClear;
2838  TransSet::Iterator tit=parallel1.TransRelBegin(*sit);
2839  TransSet::Iterator tit_end=parallel1.TransRelEnd(*sit);
2840  for(;tit!=tit_end;tit++)
2841  {
2842  //std::cout << "finding Yp-events to delete... ";
2843  if(ActiveYp.Exists(tit->Ev))
2844  {
2845  TransToClear.Insert(*tit);
2846  }
2847  }
2848  tit=TransToClear.Begin();
2849  tit_end=TransToClear.End();
2850  for(;tit!=tit_end;tit++)
2851  {
2852  //std::cout<<" ...deleting" <<std::endl;
2853  parallel1.ClrTransition(*tit);
2854  }
2855  }
2856  }
2857 
2858  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2859 
2860 
2861 
2862  // Insert Error Behaviour, i.e. make UP and UE free in (YP,UP)-port of result:
2863  // free UP:
2864 
2865  HioFreeInput(parallel1, Up, Yp, parallel2, "errYp_Ye", "errUp");
2866  //parallel1.Write("tmp_IOS4.gen");
2867  // free UE:
2868  HioFreeInput(parallel2, Ue, Ye, parallel1, "errYp_Ye", "errUe");
2869  //parallel2.Write("tmp_IOS5.gen");
2870 
2871  rIOShuffAB = parallel1;
2872 }
2873 
2874 // HioSynth_Musunoi()
2875 void HioSynth_Musunoi(const Generator& rPlant, const HioPlant& rSpec,
2876  const Generator& rConstr, const Generator& rLocConstr,
2877  const EventSet& rYp, const EventSet& rUp,
2878  Generator& rController)
2879  {
2880 EventSet rYc, rUc, rYe, rUe;
2881 rYc = (rSpec.YpEvents());
2882 rUc = (rSpec.UpEvents());
2883 rYe = (rSpec.YeEvents());
2884 rUe = (rSpec.UeEvents());
2885 
2886 
2887 //make copy of plant, spec, constr and alphabets
2888 Generator plant,spec,constr,locconstr;
2889 plant = rPlant;
2890 spec = rSpec;
2891 constr = rConstr;
2892 locconstr = rLocConstr;
2893 
2894 EventSet yc,uc,yp,up,ye,ue;
2895 yc = rYc;
2896 uc = rUc;
2897 yp = rYp;
2898 up = rUp;
2899 ye = rYe;
2900 ue = rUe;
2901 
2902 //create necessary eventsets:
2903 EventSet sigmacp;
2904 sigmacp.InsertSet(rUc + rYc + rUp + rYp);
2905 EventSet sigmace;
2906 sigmace.InsertSet(rUc + rYc + rUe + rYe);
2907 
2908 EventSet allsigma;
2909 allsigma.InsertSet(rPlant.Alphabet());
2910 allsigma.InsertSet(rSpec.Alphabet());
2911 
2912 EventSet controllable;
2913 controllable.InsertSet(up);
2914 controllable.InsertSet(yc);
2915 
2916 //make alphabets of plant and spec match:
2917 InvProject(plant,allsigma);
2918 InvProject(spec,allsigma);
2919 
2920  FD_DF("******************** actual plant: composition with environment constraint: tmp_cplant.gen ");
2921 
2922 // generate plant under constraint:
2923 Generator cplant;
2924 Parallel(plant,constr,cplant);
2925 //cplant.Write("tmp_cplant.gen");
2926 
2927  FD_DF("******************** mininmal hio structure: tmp_minhio.gen, composition with plant: tmp_hioplant.gen ");
2928 Generator minhio;
2929 minhio = HioSortCL(yc,uc,yp,up,ye,ue);
2930 //minhio.Write("tmp_minhio.gen");
2931 
2932 // generate plant in hio structure:
2933 Generator hiocplant;
2934 Parallel(cplant,minhio,hiocplant);
2935 //hiocplant.Write("tmp_hiocplant.gen");
2936 
2937  FD_DF("******************** composition plant-specification: tmp_plantspec.gen ");
2938 
2939 // composition of plant, I/O sorting, constraint and specification:
2940 Generator plantspec,plantspecMin;
2941 Parallel(hiocplant,spec,plantspec);
2942 //plantspec.Write("tmp_plantspec.gen");
2943 plantspec.StateNamesEnabled(false);
2944 // plantspec.DotWrite("tmp_plantspec");
2945  FD_DF("Size of plantspec: "<<plantspec.Size()<<" - Statemin...");
2946 //string anykey;
2947 //getline(cin,anykey);
2948 StateMin(plantspec,plantspecMin);
2949  FD_DF("done. New Statesize: "<<plantspecMin.Size()<<".");
2950 plantspec=plantspecMin;
2951 plantspecMin.Clear();
2952 plantspec.StateNamesEnabled(false);
2953  FD_DF("******************** computing YcAcyclic(plantspec):");
2954 
2955 // calculate YcAcyclic sublanguage of plantspec:
2956 Generator yclifeplantspec;
2957 YcAcyclic(plantspec,yc,yclifeplantspec);
2958 Generator yclifeplantspecMin;
2959 //cout <<endl<< " StateMin(yclifeplantspec)..." << endl;
2960 //StateMin(yclifeplantspec,yclifeplantspecMin);
2961 //cout<<endl<<"Statesize of yclifeplantspec after StateMin (tmp_YcAcyclic_Min.gen): "<<yclifeplantspecMin.Size();
2962 yclifeplantspecMin=yclifeplantspec;
2963 yclifeplantspecMin.StateNamesEnabled(false);
2964 //yclifeplantspecMin.Write("tmp_YcAcyclic_Min.gen");
2965 
2966  FD_DF("******************** actual spec: composition yclifeplantspec||minhio||locconstr (tmp_actualspec.gen)");
2967 //generate plantspec with closed-loop I/O sorting:
2968 Parallel(yclifeplantspecMin,minhio,plantspec);
2969 
2970 //add local constraints to plantspec: the result is the actual spec for synthesis
2971 Generator actualspec;
2972 Parallel(plantspec,locconstr,actualspec);
2973 //actualspec.Write("tmp_actualspec.gen");
2974 
2975  FD_DF("******************** closed loop synthesis: tmp_closedloop.gen/.dot");
2976 
2977 //std::cout<<"Starting NormalCompleteSynth....";
2978 FD_DF("Starting NormalCompleteSynth....");
2979 
2980 // compute normal, complete and controllable sublangugae of actualspec w.r.t. plant under constraints (cplant):
2981 Generator loop;
2982  NormalCompleteSynth(hiocplant,controllable,yc+uc+yp+up,actualspec,loop);
2983 //loop.Write("tmp_closedloop.gen");
2984 //loop.DotWrite("tmp_closedloop");
2985 
2986  FD_DF("size of closed loop before StateMin: "<<loop.Size()<<", starting StateMin...");
2987 
2988 //std::cout<<"Starting NormalCompleteSynth....done... starting StateMin";
2989 FD_DF("Starting NormalCompleteSynth....done... starting StateMin");
2990 
2991 Generator minloop;
2992 StateMin(loop,minloop);
2993  FD_DF("...size of closed loop after StateMin (tmp_closedloop.gen): "<<minloop.Size());
2994 //minloop=loop;
2995 minloop.StateNamesEnabled(false);
2996 //minloop.Write("tmp_closedloop.gen");
2997 // test: recheck for YCless SCCs:
2998 Generator minlooptest;
2999 minlooptest=minloop;
3000  std::set<StateSet> SccSet;
3001 YclessScc(minlooptest,yc,SccSet);
3002  FD_DF("");
3003  FD_DF("*********number of Yc-less strongly connencted components in closed loop (should be zero): "
3004  <<SccSet.size());
3005 
3006 // minloop.DotWrite("tmp_minclosedloop");
3007 
3008 //calculate external closedloop:
3009  FD_DF("******************** external closed loop: tmp_extloop.gen/.dot");
3010 Generator extloop;
3011 Project(minloop,sigmace,extloop);
3012  FD_DF("size of external closed loop: "<<extloop.Size());;
3013 
3014 // recheck if specification is met:
3015 if(LanguageInclusion(extloop,rSpec)) {
3016  FD_DF("External closed loop meets specification.");
3017  }
3018 if(LanguageEquality(extloop,rSpec)) {
3019  FD_DF("External closed loop EQUALS specification.");
3020  }
3021 
3022 extloop.StateNamesEnabled(false);
3023 //extloop.Write("tmp_extloop.gen");
3024 //extloop.DotWrite("tmp_extloop");
3025 
3026  FD_DF("******************** project closed loop: tmp_controller.gen/.dot ");
3027 
3028 Generator controller;
3029 Project(minloop,sigmacp,controller);
3030 controller.StateNamesEnabled(false);
3031 //controller.Write("tmp_controller.gen");
3032 // controller.DotWrite("tmp_controller");
3033 
3034  FD_DF("******************** extend to IO controller: tmp_IOcontroller.gen/.dot ");
3035 
3036 // extend to io-controller
3037 Generator HioController, minIOcontroller;
3038  HioFreeInput(controller, yp, up, HioController, "errUp","errYp");
3039 //HioController.Write("tmp_IOcontroller.gen");
3040 // HioController.DotWrite("tmp_IOcontroller");
3041  FD_DF("size of IO controller: "<<HioController.Size()<<", StateMin...");
3042 StateMin(HioController,minIOcontroller);
3043  FD_DF("...size of IO controller after StateMin: "<<minIOcontroller.Size());
3044 minIOcontroller.StateNamesEnabled(false);
3045 //minIOcontroller.Write("tmp_IOcontroller.gen");
3046 
3047 // RESULT:
3048 rController = minIOcontroller;
3049 
3050 ////*******************************************************************
3051 // // uncomment this, if you use complete_synth, instead of
3052 // // normal_complete_synth, for controller design:
3053 
3054 //cout <<endl<< "******************** checking normality... " << endl;
3055 //
3056 //if(!isnormal(minloop,hiocplant,sigmacp))
3057 // {
3058 // cout<<endl<<"isnormal says: false! :("<<endl;
3059 // }
3060 //else
3061 // {
3062 // cout<<endl<<"isnormal says: true! :)"<<endl;
3063 // }
3064 ////*******************************************************************
3065 
3066  FD_DF("IO controller synthesis done. ******************** " );
3067 }
3068 
3069 }//namespace faudes
#define FD_WARN(message)
Debug: always report warnings.
#define FD_DF(message)
Debug: optional report on user functions.
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.
void RestrictSet(const NameSet &rOtherSet)
Restrict to elements specified by rOtherSet.
Iterator class for high-level api to TBaseSet.
Definition: cfl_baseset.h:387
EventSet UEvents(void) const
Get EventSet with U-events.
void SetErr(Idx index)
Mark state as Err-state (by index)
void SetU(Idx index)
Mark event U-event(by index)
void SetY(Idx index)
Mark event as Y-event (by index)
EventSet YEvents(void) const
Get EventSet with Y-events.
EventSet YcEvents(void) const
Get EventSet with Yc-events.
void SetErr(Idx index)
Mark state as Err-state (by index)
void SetYp(Idx index)
Mark event as Yp-event (by index)
void SetYc(Idx index)
Mark event as Yc-event (by index)
void SetUc(Idx index)
Mark event as Uc-event (by index)
EventSet UcEvents(void) const
Get EventSet with Uc-events.
EventSet YpEvents(void) const
Get EventSet with Yp-events.
void SetQYp(Idx index)
Mark state as QYP-state (by index)
THioController * New(void) const
Construct on heap.
void SetQUp(Idx index)
Mark event as QUp-state (by index)
void SetUp(Idx index)
Mark event Up-event(by index)
EventSet UpEvents(void) const
Get EventSet with Up-events.
void SetUl(Idx index)
Mark event as Ul-event (by index)
void SetYe(Idx index)
Mark event as Ye-event (by index)
void SetQUe(Idx index)
Mark event as QUe-state (by index)
void SetQYe(Idx index)
Mark event as QYe-state (by index)
EventSet UeEvents(void) const
Get EventSet with Ue-events.
void SetYl(Idx index)
Mark event as Yl-event (by index)
EventSet YeEvents(void) const
Get EventSet with Ye-events.
EventSet LEvents(void) const
Get EventSet with E-events.
EventSet UlEvents(void) const
Get EventSet with Ul-events.
void SetErr(Idx index)
Mark state as Err-state (by index)
EventSet YlEvents(void) const
Get EventSet with Yl-events.
THioEnvironment * New(void) const
Construct on heap.
EventSet EEvents(void) const
Get EventSet with P-events.
void SetUe(Idx index)
Mark event Ue-event(by index)
void SetYp(Idx index)
Mark event as Yp-event (by index)
Definition: hio_plant.h:1033
EventSet EEvents(void) const
Get EventSet with E-events.
Definition: hio_plant.h:1300
void SetErr(Idx index)
Mark state as Err-state (by index)
Definition: hio_plant.h:1559
void SetYe(Idx index)
Mark event as Ye-event (by index)
Definition: hio_plant.h:1167
EventSet UeEvents(void) const
Get EventSet with Ue-events.
Definition: hio_plant.h:1252
EventSet UpEvents(void) const
Get EventSet with Up-events.
Definition: hio_plant.h:1118
void SetUp(Idx index)
Mark event Up-event(by index)
Definition: hio_plant.h:1058
EventSet YpEvents(void) const
Get EventSet with Yp-events.
Definition: hio_plant.h:1107
EventSet YeEvents(void) const
Get EventSet with Ye-events.
Definition: hio_plant.h:1241
void SetUe(Idx index)
Mark event as Ue-event (by index)
Definition: hio_plant.h:1192
Iterator Begin(void) const
Iterator to begin of set.
Iterator End(void) const
Iterator to end of set.
EventSet ActiveEvents(Idx x1, SymbolTable *pSymTab=NULL) const
Get set of events that are active for a specified current state Since a transition set does not refer...
Iterator BeginByX2(Idx x2) const
Iterator to first Transition specified by successor state x2.
bool Insert(const Transition &rTransition)
Add a Transition.
Iterator EndByX2(Idx x2) const
Iterator to first Transition after specified successor state x2.
bool Erase(const Transition &t)
Remove a Transition.
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Iterator on transition.
Definition: cfl_transset.h:269
virtual void Clear(void)
Clear generator data.
virtual TaGenerator & Assign(const Type &rSrc)
Copy from other faudes Type (try to cast to agenerator or pass to base)
virtual void Move(TaGenerator &rGen)
Destructive copy to other TaGenerator Copy method with increased performance at the cost of invalidat...
const TaEventSet< EventAttr > & Alphabet(void) const
Return const reference to alphabet.
bool SetTransition(Idx x1, Idx ev, Idx x2)
Add a transition to generator by indices.
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Write configuration data to a string.
Definition: cfl_types.cpp:169
Base class of all FAUDES generators.
StateSet::Iterator StatesBegin(void) const
Iterator to Begin() of state set.
StateSet::Iterator InitStatesBegin(void) const
Iterator to Begin() of mInitStates.
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.
Idx InsMarkedState(void)
Create new anonymous state and set as marked state.
virtual void Move(vGenerator &rGen)
Destructive copy to other vGenerator.
bool InitStatesEmpty(void) const
Check if set of initial states are empty.
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.
bool Accessible(void)
Make generator accessible.
bool Trim(void)
Make generator trim.
virtual vGenerator * New(void) const
Construct on heap.
void InjectMarkedStates(const StateSet &rNewMarkedStates)
Replace mMarkedStates with StateSet given as parameter without consistency checks.
Idx MarkedStatesSize(void) const
Get number of marked states.
StateSet AccessibleSet(void) const
Compute set of accessible states.
bool ExistsState(Idx index) const
Test existence of state in state set.
std::string StateSetToString(const StateSet &rStateSet) const
Write a stateset to string (no re-indexing).
void Name(const std::string &rName)
Set the generator's name.
bool DelState(Idx index)
Delete a state from generator by index.
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.
StateSet TerminalStates(void) const
Compute set of terminal states.
Idx InsState(void)
Add new anonymous state to generator.
void SetMarkedState(Idx index)
Set an existing state as marked state by index.
Idx InsInitState(void)
Create new anonymous state and set as initial state.
bool StateNamesEnabled(void) const
Whether libFAUEDS functions are requested to generate state names.
bool IsTrim(void) const
Check if generator is trim.
Idx Size(void) const
Get generator size (number of states)
bool ExistsInitState(Idx index) const
Test existence of state in mInitStates.
virtual void Clear(void)
Clear generator data.
bool ExistsMarkedState(Idx index) const
Test existence of state in mMarkedStates.
std::string UniqueStateName(const std::string &rName) const
Create a new unique symbolic state name.
const StateSet & States(void) const
Return reference to state set.
void InjectAlphabet(const EventSet &rNewalphabet)
Set mpAlphabet without consistency check.
bool Empty(void) const
Test whether if the TBaseSet is Empty.
Definition: cfl_baseset.h:1824
bool Exists(const T &rElem) const
Test existence of element.
Definition: cfl_baseset.h:2115
IndexSet StateSet
Definition: cfl_indexset.h:271
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
virtual bool Erase(const T &rElem)
Erase element by reference.
Definition: cfl_baseset.h:2019
const std::string & Name(void) const
Return name of TBaseSet.
Definition: cfl_baseset.h:1755
Idx Size(void) const
Get Size of TBaseSet.
Definition: cfl_baseset.h:1819
void StateMin(const Generator &rGen, Generator &rResGen)
State set minimization.
bool LanguageInclusion(const Generator &rGen1, const Generator &rGen2)
Test language inclusion, Lm1<=Lm2.
void PrefixClosure(Generator &rGen)
Prefix Closure.
bool LanguageEquality(const Generator &rGen1, const Generator &rGen2)
Language equality, Lm1==Lm2.
void LanguageIntersection(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Language intersection.
void Project(const Generator &rGen, const EventSet &rProjectAlphabet, Generator &rResGen)
Deterministic projection.
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Parallel composition.
void InvProject(Generator &rGen, const EventSet &rProjectAlphabet)
Inverse projection.
void LanguageComplement(Generator &rGen, const EventSet &rAlphabet)
Language complement wrt specified alphabet.
bool IsNormal(const Generator &rL, const EventSet &rOAlph, const Generator &rK)
IsNormal: checks normality of a language K generated by rK wrt a language L generated by rL and the s...
void SupConClosed(const Generator &rPlantGen, const EventSet &rCAlph, const Generator &rSpecGen, Generator &rResGen)
Supremal Controllable and Closed Sublanguage.
Definition: syn_supcon.cpp:778
void CheapAltAnB(const EventSet rAset, const EventSet rBset, const int Depth, Generator &rAltAnB)
CheapAltAnB: returns Generator of the following specification: "After a maximum of n (=depth) pairs o...
void CloneScc(Generator &rGen, const StateSet &rScc, std::set< StateSet > &rSccSet, const Idx EntryState, StateSet &rEntryStates, TransSetX2EvX1 &rEntryTransSet)
cloneSCC: makes a copy (clone) of strongly connected component (rSCC) of the generator and moves all ...
void HioSynthUnchecked(const Generator &rPlant, const Generator &rSpec, const Generator &rExtConstr, const Generator &rLocConstr, const EventSet &rYc, const EventSet &rUc, const EventSet &rYp, const EventSet &rUp, const EventSet &rYel, const EventSet &rUel, Generator &rController)
HioSynthUnchecked: I/O controller synthesis procedure, no parameter check.
void ConstrSynth_Beta(Generator &rPlant, const EventSet &rYp, const EventSet &rUp, const Generator &rLocConstr, Generator &rOpConstraint)
ConstrSynth_Beta: compute operator constraint Sp for plant under environment constraint Sl such that ...
void HioSynth(const Generator &rPlant, const Generator &rSpec, const Generator &rExtConstr, const Generator &rLocConstr, const EventSet &rYc, const EventSet &rUc, const EventSet &rYp, const EventSet &rUp, const EventSet &rYel, const EventSet &rUel, Generator &rController)
HioSynthUnchecked: I/O controller synthesis procedure.
void HioShuffleTU(const Generator &rPlantA, const Generator &rPlantB, const EventSet &rUp, const EventSet &rYp, const EventSet &rYe, const EventSet &rUe, const int Depth, Generator &rIOShuffAB)
HioShuffleTU: IO-shuffle of rPlantA and rPlantB according to definition with additional forced altern...
void MarkAlternationAB(const EventSet rAset, const EventSet rBset, Generator &rAltAB)
MarkAlternationAB: returns Generator marking the alternation of Aset-transitions with Bset-transition...
void HioSynthMonolithic(const HioPlant &rPlant, const HioPlant &rSpec, const HioConstraint &rSc, const HioConstraint &rSp, const HioConstraint &rSe, HioController &rController)
HioSynthMonolithic: I/O controller synthesis procedure for monolithic plant.
void SearchYclessScc(const Idx state, int &rcount, const Generator &rGen, const EventSet &rYc, const bool UnMarkedOnly, StateSet &rNewStates, std::stack< Idx > &rSTACK, StateSet &rStackStates, std::map< const Idx, int > &rDFN, std::map< const Idx, int > &rLOWLINK, std::set< StateSet > &rSccSet, StateSet &rRoots)
SearchYclessSCC: Search for strongly connected ycless components (YC-less SCC's).
void HioFreeInput(const Generator &rGen, const EventSet &rInput, const EventSet &rOutput, Generator &rResGen, const std::string &rErrState1, const std::string &rErrState2, Idx &rErrState1Idx, Idx &rErrState2Idx)
HioFreeInput: extend generator by obviously missing input transitions.
void CheapAltAB(const EventSet rAset, const EventSet rBset, const int Depth, Generator &rAltAB)
CheapAltAB: returns Generator of the following specification: "After a maximum of n (=depth) pairs of...
void WriteStateSets(const std::set< StateSet > &rStateSets)
WriteStateSets: Write set of StateSet's to console (indeces).
Generator HioSortCL(const EventSet &rYc, const EventSet &rUc, const EventSet &rYp, const EventSet &rUp, const EventSet &rYe, const EventSet &rUe)
IoSortCL: returns IO-sorting structure required for closed loops.
void SccEntries(const Generator &rGen, const std::set< StateSet > &rSccSet, StateSet &rEntryStates, TransSetX2EvX1 &rEntryTransSet)
SCCEntries: figure entry states and entry transitions of strongly connected components rSccSet of rGe...
bool YclessUnmarkedScc(const Generator &rGen, const EventSet &rYc, std::set< StateSet > &rSccSet, StateSet &rRoots)
YclessUnmarkedSCC: Search for strongly connected ycless components (YC-less SCC's) consisting of unma...
void YcAcyclic(const Generator &rGen, const EventSet &rYc, Generator &rResGen)
YcAcyclic: Computes the supremal(?) Yc-acyclic sublanguage of L(Gen).
void CloneUnMarkedScc(Generator &rGen, const StateSet &rScc, const Idx EntryState, const StateSet &rEntryStates, TransSetX2EvX1 &rEntryTransSet)
CloneUnMarkedSCC: makes a copy (clone) of strongly connected unmarked component (rSCC) of rGen.
void HioShuffleUnchecked(const Generator &rPlantA, const Generator &rPlantB, const EventSet &rYp, const EventSet &rUp, const EventSet &rYe, const EventSet &rUe, Generator &rIOShuffAB)
HioShuffleUnchecked: IO-shuffle of rPlantA and rPlantB according to definition, no parameter check.
bool NormalCompleteSynthNB(Generator &rPlant, const EventSet &rCAlph, const EventSet &rOAlph, const Generator &rSpec, Generator &rClosedLoop)
NormalCompleteSynthNB: compute normal, complete, controllable and nonblocking sublanguage.
bool IsYcLive(const Generator &rGen, const EventSet &rYc)
IsYcLive: This function checks if generator is Yc-live.
bool NormalCompleteSynth(Generator &rPlant, const EventSet &rCAlph, const EventSet &rOAlph, const Generator &rSpec, Generator &rClosedLoop)
NormalCompleteSynth: compute normal, complete and controllable (and closed) sublanguage.
void HioSynthHierarchical(const HioPlant &rHioShuffle, const HioEnvironment &rEnvironment, const HioPlant &rSpec, const Generator &rIntConstr, const HioConstraint &rSc, const HioConstraint &rSl, HioController &rController)
HioSynthHierarchical: I/O controller synthesis procedure for I/O-shuffle of i plants and their intera...
void MarkHioShuffle(const Generator &rGen1, const Generator &rGen2, const std::map< std::pair< Idx, Idx >, Idx > &rMapOrigToResult, Generator &rShuffle)
MarkHioShuffle: marking rule for HioShuffle() in case of marked parameters rGen1 and rGen2 - UNDER CO...
bool CompleteSynth(const Generator &rPlant, const EventSet rCAlph, const Generator &rSpec, Generator &rClosedLoop)
CompleteSynth: compute supremal complete and controllable (and closed) sublanguage.
bool YclessScc(const Generator &rGen, const EventSet &rYc, std::set< StateSet > &rSccSet, StateSet &rRoots)
YclessSCC: Search for strongly connected ycless components (YC-less SCC's) - convenience api.
void HioShuffle(const Generator &rPlantA, const Generator &rPlantB, const EventSet &rYp, const EventSet &rUp, const EventSet &rYe, const EventSet &rUe, Generator &rIOShuffAB)
HioShuffle: IO-shuffle of rPlantA and rPlantB according to definition.
Algorithms for hierarchical discrete event systems with inputs and outputs.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
THioController< AttributeVoid, HioStateFlags, HioEventFlags, AttributeVoid > HioController
void NormalityConsistencyCheck(const Generator &rL, const EventSet &rOAlph, const Generator &rK)
NormalityConsistencyCheck: Consistency check for normality input data.
Definition: syn_supnorm.cpp:45
bool IsHioEnvironmentForm(HioEnvironment &rHioEnvironment, StateSet &rQYe, StateSet &rQUe, StateSet &rQUl, StateSet &rQYlUe, EventSet &rErrEvSet, TransSet &rErrTrSet, StateSet &rErrStSet, std::string &rReportStr)
IsHioEnvironmentForm: check if rHioEnvironment is in I/O-environment form and assign state attributes...
bool IsHioControllerForm(HioController &rHioController, StateSet &rQUc, StateSet &rQYP, StateSet &rQUp, StateSet &rQYcUp, EventSet &rErrEvSet, TransSet &rErrTrSet, StateSet &rErrStSet, std::string &rReportStr)
IsHioControllerForm: check if rHioController is in I/O-controller form and assign state attributes.
THioPlant< AttributeVoid, HioStateFlags, HioEventFlags, AttributeVoid > HioPlant
Definition: hio_plant.h:880
void HioSynth_Musunoi(const Generator &rPlant, const HioPlant &rSpec, const Generator &rConstr, const Generator &rLocConstr, const EventSet &rYp, const EventSet &rUp, Generator &rController)
std::string ToStringInteger(Int number)
integer to string
Definition: cfl_helper.cpp:43
bool IsHioPlantForm(HioPlant &rHioPlant, StateSet &rQYpYe, StateSet &rQUp, StateSet &rQUe, EventSet &rErrEvSet, TransSet &rErrTrSet, StateSet &rErrStSet, std::string &rReportStr)
IsHioPlantForm: check if rHioPlant is in I/O-plant form and assign state attributes.
Definition: hio_plant.cpp:16
void HioShuffle_Musunoi(const HioPlant &rPlantA, const HioPlant &rPlantB, int depth, Generator &rIOShuffAB)
bool SupNormSP(Generator &rL, const EventSet &rOAlph, const Generator &rK, Generator &rResult)
Includes all header files of the synthesis plug-in.

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