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

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