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.SetUnion(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.SetUnion(rYp);
1086 //// SigmaP.SetUnion(rUp);
1087 //// A.SetIntersection(SigmaP);
1088 //// B.SetIntersection(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.SetIntersection(rYe);
1126  ActiveYp.SetIntersection(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.SetIntersection(rYp);
1170  B.SetIntersection(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.SetUnion(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.SetUnion(rYp);
1431 ////// SigmaP.SetUnion(rUp);
1432 ////// A.SetIntersection(SigmaP);
1433 ////// B.SetIntersection(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.SetUnion(rYp);
1459  SigmaP.SetUnion(rUp);
1460  Ap.SetIntersection(SigmaP);
1461  Bp.SetIntersection(SigmaP);
1462 
1463  SigmaE.SetUnion(rYe);
1464  SigmaE.SetUnion(rUe);
1465  Ae.SetIntersection(SigmaE);
1466  Be.SetIntersection(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.SetIntersection(rYe);
1497  * ActiveYp.SetIntersection(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.SetUnion(rUc + rYc + rUp + rYp);
2354  EventSet sigmace;
2355  sigmace.SetUnion(rUc + rYc + rUel + rYel);
2356 
2357  EventSet allsigma;
2358  allsigma.SetUnion(rPlant.Alphabet());
2359  allsigma.SetUnion(rSpec.Alphabet());
2360 
2361  EventSet controllable, wait;
2362  controllable.SetUnion(rUp);
2363  controllable.SetUnion(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.SetUnion(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.SetUnion(Yp);
2795  SigmaP.SetUnion(Up);
2796  Ap.SetIntersection(SigmaP);
2797  Bp.SetIntersection(SigmaP);
2798 
2799  SigmaE.SetUnion(Ye);
2800  SigmaE.SetUnion(Ue);
2801  Ae.SetIntersection(SigmaE);
2802  Be.SetIntersection(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.SetIntersection(Ye);
2833  ActiveYp.SetIntersection(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.SetUnion(rUc + rYc + rUp + rYp);
2905 EventSet sigmace;
2906 sigmace.SetUnion(rUc + rYc + rUe + rYe);
2907 
2908 EventSet allsigma;
2909 allsigma.SetUnion(rPlant.Alphabet());
2910 allsigma.SetUnion(rSpec.Alphabet());
2911 
2912 EventSet controllable;
2913 controllable.SetUnion(up);
2914 controllable.SetUnion(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

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen